go-capability-vs-version-gate
Solution written to ~/GAP-082-solution.md.
The repo wasn't present in this environment, so I built a self-contained, compiling reproduction of the exact gate at /tmp/gap082 (Go 1.26 + real git history) and verified every claim against it rather than only describing it.
The probe trusted a version string. daemonversion.go claimed v0.1.4 was the first release carrying the isolation grant, but git ls-tree v0.1.4 internal/ has no hostsetup (added by 207e0e5) and git tag --contains 207e0e5 is empty. A v0.1.4 binary self-reports 0.1.4, so versionAtLeast() passed → OK for a build that cannot isolate a spawned agent.
internal/agent/isolation.go): IsolationGrantCapability = "isolation-grant" + SpawnCapabilities(), with compile-time references to provisionIsolation/StageIsolationProvision so a stripped build can't advertise it.bunkerd --version as caps: isolation-grant.SKEWED at any version; version floor is secondary; unparseable/missing ⇒ UNKNOWN (warn, never refuse).go vet: green.v0.1.4; old probe says OK, new probe says SKEWED; new vs new OK; missing UNKNOWN.v0.2.0 carries token; lying pin v0.1.4 when only v0.2.0 carries) and passes when honest.git grep from the package dir with a root-relative pathspec matched nothing, silently turning the proof into a fixture. Anchored at git rev-parse --show-toplevel.The doc also covers the blast-radius item: the E2E host-provision section grading installed /usr/local/bin/bunkerd under continue-on-error, with the BUNKERD_BIN override + skip-with-warning + remove-continue-on-error remediation.
# Evidence - Problem class: go-capability-vs-version-gate - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-19T00:21:54.906Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Bunker GAP-082: make a safety gate PROVE a capability instead of trusting a version string. The daemon-skew probe answered OK for exactly the daemon build that had to be refused because internal/hostsetup/daemonversion.go claimed v0.1.4 is the first release carrying the spawn-side isolation grant, while `git ls-tree v0.1.4 internal/` has no hostsetup (added 207e0e5) and `git tag --contains 207e0e5` is empty; a v0.1.4 binary self-reports 0.1.4 with no grant, so versionAtLeast() passed. WHAT WORKED: (1) declare the capability token IN THE SAME CODE THAT PERFORMS THE CAPABILITY (internal/agent/isolation.go: IsolationGrantCapability=\"isolation-grant\" + SpawnCapabilities() next to provisionIsolation/StageIsolationProvision) so a build without the grant code cannot advertise it; print it in the daemon's own version block (`bunkerd --version` -> `caps: isolation-grant`); require the token in the probe and treat ABSENT as SKEWED at ANY version, keeping the version floor as a secondary check only; keep unprobeable/unknown as UNKNOWN (warn, never refuse) so installing before the daemon exists still works. (2) Coupling without an import cycle: the consumer package already imports the producer, so the consumer keeps a string literal and a test in the producer package asserts the two constants are equal. (3) Pin the honest state of the world with a BIDIRECTIONAL invariant test: a constant naming the first release tag that carries the token, empty today; the test reads `git tag` and fails if the constant and the tag list disagree in EITHER direction, skipping cleanly when git/tags are unavailable (shallow CI checkout). (4) Falsify every new test against the pre-fix source and against a REAL pre-fix binary (build the old daemon, probe it: must be SKEWED; build the new one: must be OK) \u2014 fixture-only proofs hide the class. (5) Blast radius to check when you make a gate fail-closed: any harness that grades an INSTALLED artifact rather than the candidate (here the E2E battery's host-provision section probes /usr/local/bin/bunkerd with no override) turns red inside a continue-on-error job and the run still reports success.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-capability-vs-version-gate", "provider": "openrouter", "solved_at": "2026-09-19T00:21:54.907Z", "version": ""}Solution written to ~/GAP-082-solution.md.
The repo wasn't present in this environment, so I built a self-contained, compiling reproduction of the exact gate at /tmp/gap082 (Go 1.26 + real git history) and verified every claim against it rather than only describing it.
The probe trusted a version string. daemonversion.go claimed v0.1.4 was the first release carrying the isolation grant, but git ls-tree v0.1.4 internal/ has no hostsetup (added by 207e0e5) and git tag --contains 207e0e5 is empty. A v0.1.4 binary self-reports 0.1.4, so versionAtLeast() passed → OK for a build that cannot isolate a spawned agent.
internal/agent/isolation.go): IsolationGrantCapability = "isolation-grant" + SpawnCapabilities(), with compile-time references to provisionIsolation/StageIsolationProvision so a stripped build can't advertise it.bunkerd --version as caps: isolation-grant.SKEWED at any version; version floor is secondary; unparseable/missing ⇒ UNKNOWN (warn, never refuse).go vet: green.v0.1.4; old probe says OK, new probe says SKEWED; new vs new OK; missing UNKNOWN.v0.2.0 carries token; lying pin v0.1.4 when only v0.2.0 carries) and passes when honest.git grep from the package dir with a root-relative pathspec matched nothing, silently turning the proof into a fixture. Anchored at git rev-parse --show-toplevel.The doc also covers the blast-radius item: the E2E host-provision section grading installed /usr/local/bin/bunkerd under continue-on-error, with the BUNKERD_BIN override + skip-with-warning + remove-continue-on-error remediation.
# Evidence - Problem class: go-capability-vs-version-gate - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-19T00:21:54.906Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Bunker GAP-082: make a safety gate PROVE a capability instead of trusting a version string. The daemon-skew probe answered OK for exactly the daemon build that had to be refused because internal/hostsetup/daemonversion.go claimed v0.1.4 is the first release carrying the spawn-side isolation grant, while `git ls-tree v0.1.4 internal/` has no hostsetup (added 207e0e5) and `git tag --contains 207e0e5` is empty; a v0.1.4 binary self-reports 0.1.4 with no grant, so versionAtLeast() passed. WHAT WORKED: (1) declare the capability token IN THE SAME CODE THAT PERFORMS THE CAPABILITY (internal/agent/isolation.go: IsolationGrantCapability=\"isolation-grant\" + SpawnCapabilities() next to provisionIsolation/StageIsolationProvision) so a build without the grant code cannot advertise it; print it in the daemon's own version block (`bunkerd --version` -> `caps: isolation-grant`); require the token in the probe and treat ABSENT as SKEWED at ANY version, keeping the version floor as a secondary check only; keep unprobeable/unknown as UNKNOWN (warn, never refuse) so installing before the daemon exists still works. (2) Coupling without an import cycle: the consumer package already imports the producer, so the consumer keeps a string literal and a test in the producer package asserts the two constants are equal. (3) Pin the honest state of the world with a BIDIRECTIONAL invariant test: a constant naming the first release tag that carries the token, empty today; the test reads `git tag` and fails if the constant and the tag list disagree in EITHER direction, skipping cleanly when git/tags are unavailable (shallow CI checkout). (4) Falsify every new test against the pre-fix source and against a REAL pre-fix binary (build the old daemon, probe it: must be SKEWED; build the new one: must be OK) \u2014 fixture-only proofs hide the class. (5) Blast radius to check when you make a gate fail-closed: any harness that grades an INSTALLED artifact rather than the candidate (here the E2E battery's host-provision section probes /usr/local/bin/bunkerd with no override) turns red inside a continue-on-error job and the run still reports success.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-capability-vs-version-gate", "provider": "openrouter", "solved_at": "2026-09-19T00:21:54.907Z", "version": ""}