CI red on main: cli/sandbox security-claim tests fail on the runner; lint job red despite 0 local issues #180
Labels
No labels
burndown-2026-06
sunday-sprint
coherence-core
consult
headless
interactive
P0
P1
P2
P3
P4
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
coilyco-flight-deck/cli-guard#180
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Symptom
mainis red atc8da301(and the priorb951993): both thetestandlintjobs fail (releaseandsecretsare green). Diagnosed read-only from the aos director surface (substrate clone atc8da301, ops surface grants CI status only - no raw job logs - so confirm the rest in a writable clone).testjob - three cli/sandbox tests (reproduced locally)These assert kernel sandbox enforcement (namespace jail, gate rerouting, seccomp ptrace denial). Key facts:
git log -- cli/sandbox/shows nothing sincec154e1d(2026-06-17, thedegrade gracefullyfeature) and5d09088. The July-01 merges (b951993value-chain,c8da301fleetconfig) touch neither sandbox nor lint config. So the runner regressed, not the code.SecurityClaimtests get past theirisUserNSUnavailableskip guard (sandbox_linux_test.go:101, 132) - unprivileged namespaces are nominally available on the runner - but then fail on the deeper enforcement (gate preload / seccomp) that the runner can no longer deliver, soWrapdegrades (c154e1d) and the tests observe un-enforced behavior instead of skipping.TestSetupDenied(sandbox_degrade_linux_test.go:43) has no skip guard at all - its precondition fatal-errors the moment the jail can't engage.lintjob - not lint rules (does NOT reproduce)golangci-lint run --timeout=5m ./...at the exact CI-pinned v2.12.2 gives0 issueslocally.godoc-current.txtis fresh (check-godoc-current.shexit 0). Solintis not failing on lint findings - suspect the job's install/env step (Go or golangci-lint install, network, runner image). Do not fabricate a code fix for a green linter - pull the actual CI job log first, and if it is a transient install flake a re-run may clear it.Fix direction
TestSecurityClaim_GrandchildRoutesThroughGate,TestSecurityClaim_SeccompDeniesPtrace, andTestSetupDeniedskip when the runner cannot actually enforce the sandbox - detect the missing capability (extend theisUserNSUnavailablepattern to cover the gate-preload and seccomp-enforcement preconditions, and add a guard toTestSetupDenied, which has none). Preserve the guarantee where the capability exists: skip ONLY on a genuine can't-enforce runner, never blanket-skip - these tests must still catch a real enforcement regression on a capable runner. ASkipfnaming the missing capability, mirroring the existing lines, is the shape.lintfrom the real job log. 0 issues locally at v2.12.2 means the failure is env/install. Confirm from the log; re-run if transient.Verify in the writable clone (couldn't from read-only substrate)
go mod tidy && git diff --exit-code -- go.mod go.sum(the test job's tidy gate - I could not write go.mod to check drift).testandlintjob logs to confirm the exact failing step (my repro is a container that may not match the runner).Done condition
testjob green: sandbox security-claim tests skip cleanly on a can't-enforce runner and still assert enforcement on a capable one.lintjob green (root cause identified - env fix or re-run, not a bogus code change).Filed from the aos director surface after Kai flagged cli-guard CI red.
🔒 Reserved by
ward agent --driver claude— containerengineer-claude-cli-guard-180on hostkais-macbook-pro-2.localis carrying this issue (reserved 2026-07-01T16:24:21Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (2h0m0s TTL);--forceoverrides.— Claude (she/her), via
ward agentWARD-OUTCOME: done - sandbox security-claim tests now skip on a can't-enforce runner (positive JAILED marker + distinct probe exit codes); lint installer pinned to its release tag.
The
testhalf was the satisfying kind of bug: the tests weren't wrong about what to assert, they just had no positive signal that the jail actually engaged, so once auto-degrade (c154e1d) started silently falling back to an unsandboxed run they read that as an enforcement failure. ThreadingCLIGUARD_JAILEDinto the reroute log line and giving the ptrace probe three distinct exit codes (7 setup-failed / 8 not-jailed / 9 filter-missing) cleanly separates "runner can't deliver the jail" from "the guarantee broke" — so it skips on the former and still fails hard on the latter. I verified both directions here: opt-out and clone-denied both skip, andTestSetupDeniedstill runs fully when the sandbox isn't opted out, so it's not a blanket skip.What fought back a little: this container can't create an unprivileged userns at all, so I couldn't exercise the fully-capable path end-to-end — I'm confident by construction (a probe exit 9 inside the jail still hits Fatalf) but that branch is unverified on real hardware. The
lintred I couldn't confirm from a raw job log (no log grant from this clone), so I pinned the golangci-lintinstall.shfrom a movingmasterto theGOLANGCI_LINT_VERSIONtag — a genuine determinism fix for the exact step the issue flagged, and 0 issues reproduce locally at v2.12.2 — but if the real cause was a transient network/runner flake, the fresh CI run on this push is the real test.Follow-up worth filing: the underlying runner capability loss (unprivileged-userns / seccomp / mount perms on the docker CI runner) is an infra concern for infrastructure/ansible, out of scope for this repo and not a granted repo here, so I left it for a separate infra issue rather than filing across the wall.