Skip to content

Diagnose the Alpine trust failure, fix two container-matrix defects - #5

Merged
itsvedantkumar merged 2 commits into
mainfrom
diagnose-alpine-trust
Sep 1, 2026
Merged

Diagnose the Alpine trust failure, fix two container-matrix defects#5
itsvedantkumar merged 2 commits into
mainfrom
diagnose-alpine-trust

Conversation

@itsvedantkumar

Copy link
Copy Markdown
Owner

Opened to get CI evidence without touching main or the v1.61.0 tag, which has now been destroyed three times.

  • check 63 skipped in every container because tests/container-matrix.sh never installs python3. Provisioned it rather than adding python3 not on PATH to the credential-skip keyword list, which would have been a false label.
  • the pre-tag carve-out could never fire: bin/doctor:1292 prints DRIFT ✖ as a generic summary for any non-zero fail count, and it survived the filter, so the residual was non-empty even when the allowed finding was the only failure.
  • check 61 on Alpine now reports rc and stderr instead of swallowing them. This PR does not fix that defect. It makes the next red run say what it is.

🤖 Generated with Claude Code

itsvedantkumar and others added 2 commits September 1, 2026 17:13
…out, and make check 61 say what failed

Three defects, all shipped in v1.61.0, all found by CI on the first commit where the pre-tag red
was not masking them.

CONTAINER MATRIX, check 63's skip. tests/container-matrix.sh installs bash git jq curl
ca-certificates shellcheck and never python3, so check 63 was guaranteed to skip in every image.
The skip classifier accepts a reason only if it matches 'plugin manifest|authenticat|claude CLI',
so all three lanes failed on the classification -- debian's gate printed VERIFIED and the lane
still failed, which is the classifier working. Adding "python3 not on PATH" to that keyword list
would have been a lie about what the skip is, and laundering a skip under a credentials
explanation is the exact regression tests/container-skip-classify.sh's PROOF 4 was added to stop.
Provision the tool instead.

CONTAINER MATRIX, the carve-out that could never fire. bin/doctor:1292 prints `DRIFT ✖` as its
generic summary whenever the fail count is non-zero. It name-collides with a real drift banner and
carries no diagnostic content. The carve-out stripped the allowed finding's own line but not that
one, so with "declared release is fetchable" as the SOLE failure the residual was still non-empty
and every image reported `doctor exit=1; DRIFT ✖`. The carve-out I shipped yesterday was
unreachable by construction. Row 62b proved the list and the doctor branch; nothing proved the
filter against real output, which is the third time in this repository that the two halves were
each tested and the join was not.

Dropping the banner softens nothing -- every individual finding prints its own ✖ -- but the banner
was accidentally acting as a guard, so the guard it was standing in for is now explicit: the
allowed finding must actually appear in the output, or a doctor that fails while printing no
findings would pass.

Debian passing while alpine and ubuntu failed was not an OS difference. Debian ran at 10:48 with
the tag still on origin; alpine and ubuntu at 10:50 and 10:53, after cleanup-on-failed-gate
removed it. A live-network race across a seven-minute matrix, both dash images on opposite sides.

CHECK 61 on Alpine. It goes red there and nowhere else, and reported only "vstack trust failed"
because the command ran with `>/dev/null 2>&1`. A check that knows something is wrong and has
discarded the only sentence saying what. Two reproduction attempts against a byte-identical image
could not make it fail, which is precisely when the swallowed stderr is the whole investigation.
It now keeps rc and stderr and puts both in the failure body. This commit does not claim to fix
that defect; it makes the next red report it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Alpine stderr, once the check stopped discarding it: `vstack: no vstack repo found (checked
$VSTACK_DIR, ~/.vstack, and this script's git root)`, rc=1, all three lanes. Not a portability
defect in `vstack trust` and nothing to do with shasum, which was ruled out against a
byte-identical image.

Check 61 redirects HOME so each lane writes its own trust store instead of the operator's. That
also hides ~/.vstack and the global gitconfig. bin/vstack resolves its repo from $VSTACK_DIR, then
~/.vstack, then `git rev-parse --show-toplevel`; under a foreign HOME the first two are gone, and
in the Alpine container the third fails as well, because actions/checkout writes its safe.directory
exemption into the runner HOME's gitconfig and the override hides it, so git refuses the checkout
as dubiously owned. bin/vstack exits before `trust` runs.

Proven: the message, the rc, and that it is Alpine-only. Inferred: that the git-root lane lost on
dubious ownership specifically -- the message does not say which of the three failed. Naming
$VSTACK_DIR settles it either way and is what the error text tells you to do.

The check's own environment, not a defect in what it measures. A user does not run vstack under a
substituted HOME. What made it expensive is that the invocation threw away stderr, so one
platform went red with a sentence that could not distinguish this from a broken hasher.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@itsvedantkumar
itsvedantkumar merged commit 61bd63b into main Sep 1, 2026
3 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant