test(ci-flake): M3 — gatelint legibility lint + AC10 egress posture probe - #597
Merged
Conversation
…robe (incl. D5=A residual)
Closes AC8 and AC10 of m-ci-flake-systemic-fix. Pure Go, zero workflow edits.
internal/testutil/gatelint — a legibility lint for the three known test-gating
offenders, running as a plain Go test on every CI leg and every `make test`:
R1 `testing.Short(` R2 `Getenv("CI")`/`Getenv("GITHUB_ACTIONS")`
R3 `httpbin.org`/`ailang-packages` outside a live-network gate or the allowlist
The walker matches *_test.go only, skips dot-dirs and testdata/, and excludes its
own package — all three are measured-necessary (6 production files carry R3's
tokens; an unscoped R3 would flag gatelint's own source and red CI on the very
commit that introduces it, which was a blocking quorum objection).
internal/testutil/egress_posture_test.go — AC10 (a) poison sentinel denies HTTP
egress, (b) loopback bypasses the lane poison, (c) raw TCP stays open, and
(d) the D5=Option-A residual asserted as OPEN: a nil-Proxy transport built the
way internal/effects builds them bypasses the poison, with a
ProxyFromEnvironment transport failing in the same run as the control that makes
(d) non-vacuous. (d) is the tripwire that reds when Option B lands.
Allowlist seed re-measured at 78f30e0 AFTER M2 (the plan's seed predated it):
R1 empty (M1/M2 removed all 7), R2 one entry using the reason M2 authored in
provider_script_test.go, R3 five entries. net_test.go and gitcache_test.go are
gated by M2 and deliberately NOT allowlisted.
Verified outside the sandbox: gatelint 941 files/0 violations; AC10 (a)-(d) pass
in the default, poisoned, live and poisoned+live lanes; full suite 108 ok/0 FAIL;
gofmt/vet/golangci-lint clean. Six mutations each proven landed and reverted
byte-identical: R1 branch, walker suffix, dot-dir skip (executor); R3 gating
check -> flags the 2 gated files, allowlist emptied -> flags exactly the 5 seeds,
AC10(d) poison env stripped -> control catches it (controller). AC8 falsification
drill fired: 942 files scanned, the scratch file named, removed, back to green.
Co-Authored-By: codex gpt-5.6-sol <noreply@openai.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s worded it differently CI caught what no local gate could: `test-windows` and `Build windows-latest` both failed on the M3 commit because Go reports a refused TCP connect as `connectex: No connection could be made because the target machine actively refused it.` on Windows, versus `connect: connection refused` on Unix. The assertion required the literal `connection refused`, so it could never pass there — the production behavior was correct; only the assertion was parochial. Requires `refused` instead. All three tokens must still match, so the check stays discriminating; verified against four verbatim error strings — Unix refused and Windows refused (the latter copied from the failing CI log) pass, a DNS failure and a proxy hang both fail. Mutation-proved by removing the sentinel proxy wiring (with `go vet` confirming it still compiled, so the run was informative): the assertion redded with "request through poison proxy unexpectedly succeeded". This is the second Windows-only defect in this package that local gates cannot see; M1's was env-var case-insensitivity. Found by the sprint evaluator (sonnet) and reproduced first-party against the job log before applying. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
sunholo-voight-kampff
added a commit
that referenced
this pull request
Aug 5, 2026
…plan had gone stale against its own design doc M3 landed as 13c5700 (PR #597): internal/testutil/gatelint (R1/R2/R3, 941 files, 0 violations) + egress_posture_test.go closing AC8 and AC10(a-d). Find: iteration 145 applied Mark's D5 ruling by editing the design doc — adding AC10(d) — and nothing updated the sprint plan, whose M3 task list still said AC10 (a)(b)(c). Routed as written, M3 would have shipped without the tripwire whose whole purpose is to red when the queued Option-B item lands. The rot runs both ways: the doc still bundles M3 with workflow edits the newer plan split into M4, and still says "5 CI legs" in 6 places though its own V34 measured 6. Skill edit (>=2 instances, both inside this iteration): Gate 2 gains 3b(vii) — a design doc and its sprint plan are two documents describing one sprint, and revising either silently rots the other. Diff the plan's milestone section against the doc's acceptance criteria at pick time, because quorum reviews the doc, the planner reads it once, and nothing re-diffs them afterwards. Applying that edit deleted rule 3c's header line — the anchor included it and the replacement did not restore it, and the script reported success. Caught by treating the post-edit grep's 0 as a claim (rule 3a) with a control in the same call; repaired from origin and proven purely additive (29 insertions, 0 deletions; 3c body word count 418 == origin's 418). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Milestone M3 of
m-ci-flake-systemic-fix. Closes AC8 and AC10. Pure Go, zero workflow edits — revert is deleting one directory and one file.What lands
internal/testutil/gatelint— a legibility lint for the three known test-gating offenders, run as a plain Go test on every CI leg and everymake test. R1testing.Short(· R2Getenv("CI")/Getenv("GITHUB_ACTIONS")· R3httpbin.org/ailang-packagesoutside a live-network gate or the allowlist.internal/testutil/egress_posture_test.go— AC10 (a)–(d), including (d), theD5=Option-A residual asserted as open.The allowlist seed was re-measured after M2
The sprint plan's seed predated M2. Re-measured at
78f30e053: R1 empty (M1/M2 removed all 7), R2 one entry reusing the reason M2 authored inprovider_script_test.go, R3 five.net_test.goandgitcache_test.goare gated by M2 and deliberately not allowlisted — allowlisting them would make the gate inert for the very files the sprint just fixed.AC10(d) — the tripwire that retires itself
The plan's M3 section predates Mark's
D5decision and omits (d); the design doc is current and wins. (d) builds a transport the wayinternal/effectsdoes (Proxynil), proves it bypasses the poison, and asserts in the same run that aProxyFromEnvironmenttransport fails — that second half is the control. When Option B lands, (d) reds, which is the intended signal.Verification (all outside the sandbox — in-sandbox verdicts here are uninformative by construction)
go vet,golangci-lint(0 issues),check-file-sizesclean🤖 Generated with Claude Code