• pi-devbox v1.10.2 — pi 1.0.0 + pi-atelier v0.13.0, and the two harness bugs that ate v1.10.0 and v1.10.1
    Lint / hadolint (push) Successful in 10s
    Lint / skill-floor (push) Failing after 13s
    Lint / doc-drift (push) Successful in 18s
    Lint / actionlint (push) Successful in 33s
    Publish Docker Image / lint-gate (push) Successful in 32s
    Publish Docker Image / resolve-versions (push) Successful in 17s
    Publish Docker Image / base-decide (push) Successful in 13s
    Publish Docker Image / build-base (push) Has been skipped
    Publish Docker Image / smoke-studio (push) Successful in 5m38s
    Publish Docker Image / smoke (push) Successful in 8m20s
    Publish Docker Image / build-variant-studio (push) Successful in 20m34s
    Publish Docker Image / build-variant (push) Successful in 21m5s
    Publish Docker Image / update-description (push) Successful in 8s
    Publish Docker Image / promote-base-latest (push) Successful in 9s

    joakimp released this 2026-10-02 11:17:24 +02:00

    Content is unchanged from v1.10.0 (see that CHANGELOG section, kept as the
    record). This tag adds the second of two CI-harness fixes. Neither failed tag
    published anything: in both runs every publish job skipped, so no image, no
    latest and no Hub description was ever written.

    v1.10.0 run 704: smoke 100 passed / 1 FAILED, smoke-studio 103 / 1
    A smoke assertion required @mariozechner/clipboard to be installed and
    require()-able. pi 0.86.0 (#9163) replaced that external dependency with
    bundled helpers: 0.85.1 declares it, 0.87.1 and 1.0.0 declare nothing. The
    assertion was enforcing pi 0.85.1's dependency graph against a pi 1.0.0
    image. Fixed in f3b3748 by deriving the expectation from what the image's pi
    DECLARES, so it re-arms if a future pi re-adds the dependency.

    v1.10.1 run 707: smoke 101 passed / 0 failed, smoke-studio 104 / 0, both
    jobs RED with NO failing step
    ARG BASE_IMAGE has no default on purpose, which trips BuildKit's
    InvalidDefaultArgInFrom check. buildx attaches the warning's source context
    to the build metadata as buildx.build.warnings[].sourceInfo.data — the
    entire Dockerfile, base64, on ONE line. build-push-action writes that to
    $GITHUB_OUTPUT as a name<<ghadelimiter_<uuid> heredoc, and act_runner
    truncates any line at exactly 65536 chars, losing the closing delimiter:
    invalid format delimiter 'ghadelimiter_...' not found before end of file
    Fixed in 56e3742 with # check=skip=InvalidDefaultArgInFrom as line 1 of
    Dockerfile.variant (BuildKit parses # check= only before any other line).

    MEASUREMENTS, two routes each:
    logs : v1.9.4 run 695 longest metadata line 56355, 0 delimiter errors, SUCCESS
    runs 704 and 707 both 65536 (= 2^16, cut AT the cap), 1 error each
    size : Dockerfile.variant 42251 B at v1.9.4 -> base64 56335 (matches the log)
    50034 B at v1.10.1 -> base64 66712, truncated to 65536
    cap corresponds to a 49152 B Dockerfile; this cycle crossed it by 882 B
    fix : docker buildx build --check on the actual edited file ->
    "Check complete, no warnings found." Longest metadata line then drops
    to ~1936 chars, so the Dockerfile's SIZE stops gating CI.

    A WRONG FIX WAS CAUGHT BEFORE IT SHIPPED: provenance: false was committed
    (784fad7) on the theory that provenance carried the base64, then reverted after
    a real buildx showed the provenance key present in BOTH modes with a longest
    string of 71 chars. Locating the field by walking the CI log's indentation —
    rather than by reasoning about buildx — put it under buildx.build.warnings in
    both runs. Also rejected by measurement: floating action tags moving (act
    action-bundle hashes byte-identical between runs 695 and 707) and the annotation
    text changing (byte-identical).

    NEW GATE: scripts/check-dockerfile-directives.sh asserts line 1 is the directive
    AND that ARG BASE_IMAGE still has no default, so the skip cannot rot into
    guarding a check that can no longer fire. Wired into BOTH lint.yml and
    docker-publish.yml's lint-gate, because a check that gates only push lets a
    tag regress — the adoption slip that let doc-drift land 27 h after v1.9.3.
    Exit codes: present 0, removed 1, demoted to line 2 → 1, ARG defaulted 1, file
    missing 2 (a gate that cannot run must not pass).

    CONTENT (unchanged):
    pi 0.85.1 -> 1.0.0 (MAJOR; no Breaking Changes section)
    pi-atelier v0.10.3 -> v0.13.0 (commit 34d26f1, annotated tag dd06971)
    pi-studio v0.9.60 -> v0.9.61 (641aa32)
    pi-obsmem pinned 731c3d4 (PR#83 Pi 0.87 fix, merged but never released)
    mempalace-toolkit 2167a1b -> 975ab92 (dormant_unless suppression)
    base packages + sqlite3, bc, dc, bsdextrautils
    entrypoint-user.sh sets core.sshCommand (stops the recurring git push failure)
    TUI fullscreen is now pi's default; revert documented three ways

    Base layer does not rebuild: no base input has changed since 12f99c4, so
    base-decide cache-hits base-dad0f365ff24 (pushed by run 704 at 07:52:38Z).

    Gates: doc-drift 23 OK / 0 DRIFT / 0 SKIP / 0 FAIL; base-hash, workflow-shell,
    skill-floor, lint-shell (17 files), dockerfile-directives all rc=0 locally.

    Downloads