feat(crosscheck): carry the Pi reviewer closure in the Azure model image - #246
Conversation
|
Adversarial review returned DO NOT MERGE. Fixed in The important finding: three of my four headline properties were pinned by no test. The new assertion checked that each closure parameter appeared somewhere in the build. That is a proxy, and an
The One claim was false. "Digest-pinned closure" is not true for Pi. Also fixed:
Correction to the PR description: it claimed a Pi reviewer "reached a live model VM, ran, and died on Credential staging is the remaining half of the Pi lane and is out of scope here: |
d7efbe2 to
99f63e4
Compare
The Azure Crosscheck model guest has had a working `pi` branch and the adapter has admitted `pi` reviewers for weeks, and docs/azure-crosscheck.md already claimed the image pins "the supported Codex, Claude, or Pi reviewer CLI". The tracked build contract installed only the Codex and Claude CLIs, so every Pi reviewer that reached a live model VM died on `pi: command not found` after the VM was already paid for. Pin the Pi closure the same way the crewmate cell image does, with the same tarball, so a Pi reviewer and a Pi author run one identical agent. Pi is an npm package with a `#!/usr/bin/env node` entrypoint rather than a static binary, so its Node runtime is pinned by the same URL/size/SHA-256 contract instead of being pulled from a distribution repository mid-build, and PATH is named explicitly because every other closure check in this build runs an absolute path and would pass with a PATH that cannot resolve `node`. Two things the previous contract could not prove, now proven: - `pi --version` exits 0 for any version, so it cannot show that the digest-pinned tarball is what reached PATH. The exact version is a tracked parameter and the build asserts it. - Every closure check ran before the ambient-credential purge, which is a broad `find / -exec rm -rf` and therefore the one step capable of taking a CLI back out. The closure is re-verified as the build's last act. The declaration test gains an assertion that every closure parameter is actually referenced by a build step: parameter presence alone cannot tell a carried closure apart from a declared one. Verification: five mutations applied to the template, each confirmed to change the file before running, each red -- dropped parameter, dropped version assertion, a nodesource install replacing the pinned runtime, the dropped `.pi` purge, and a declared `piTarballSha256` whose verification step was replaced by an echo (the case parameter-presence cannot catch). tests/fm-crosscheck-azure.test.sh and shellcheck pass. This is the tracked declaration only. Building the image, promoting it into the Compute Gallery, and repointing `model_image_id` stay operator lanes.
…erclaiming Pi An adversarial review of this branch found that three of its four headline properties were held by no test, and that one claim was simply false. The new assertion checked that each closure parameter appeared somewhere in the build. "Appears somewhere" is a proxy, and an `echo` naming the parameter satisfies it. Five mutations survived green: the Pi digest check replaced by an echo that kept the reference, both version comparisons downgraded to an echo, the entire post-purge re-verification deleted, `xz-utils` dropped while the build still ran `tar -xJ` (a guaranteed billable bake failure), and the PATH export deleted. The assertions now pin the steps rather than the mentions: each pinned digest must be consumed by exactly one `sha256sum -c` step, the Pi version must be consumed by a comparison against its tracked parameter twice, the closure must be re-verified at an index after the purge, `xz-utils` must be installed whenever the build untars an xz archive, and the build must fix a PATH. All five mutations are red, plus one that removes only the post-purge block while leaving the version comparisons in place. The false claim was "digest-pinned closure". `npm install -g` is a network install: the digest pins the published Pi tarball, and the agent then arrives as roughly 127 separately fetched packages. Pi's own six sibling packages carry a `resolved` URL and no `integrity` hash in its shipped shrinkwrap, so a republished `@earendil-works/pi-*@0.84.1` would enter this credentialed image with every digest check passing and `pi --version` still printing 0.84.1. That is the same exposure the crewmate cell image already accepts for the same package. It is now recorded as what it is instead of described as pinning. Also from the same review: - The config example still showed the managed-image form of `model_image_id`, 22 lines below the new paragraph explaining it must be a gallery version. An operator following the example fails at VM create, because the reviewer SKUs need a DiskControllerTypes feature a managed image cannot carry. - Admission never checks that the configured image carries the harness it admits. The build writes a `pi-tarball-sha256` tag and nothing reads it, so this branch does not by itself stop the next Pi reviewer from failing inside a paid VM. Recorded as an open gap rather than implied to be covered. - The model guest launches `pi` without `--offline` against a deny-all egress policy, so its startup update and telemetry calls are dropped and each waits out its timeout on a paid VM. Recorded; the guest is not changed here. - The npm install was the only network step in this build with no timeout. A registry stall burned the full 60-minute build timeout and then billed a failed bake. Bounded at 900s, matching the curl bounds beside it. Two documented phrasings of the same fact were reconciled.
99f63e4 to
40d98f6
Compare
A verification pass found ten findings against this section, three of them merge-blocking. All ten are addressed here, docs only, one file. The image claim is refuted rather than softened. The current fm-ccm image does carry pi. Config model_image_id names gallery version 1.0.1787092687, whose source managed image img-fm7c799d-ccm-1.0.1787091895 carries the pi-tarball-sha256 and node-tarball-sha256 tags that only a build from the Pi-carrying declaration (#246) can write, its Image Builder run succeeded on 2026-08-18 between 22:26:20Z and 22:36:46Z, after #246 landed on main at 20:51:35Z, and that declaration asserts pi --version against a tracked version twice, before and after the credential purge. The digests match docs/azure-crosscheck/model-image-closure.json for pi-coding-agent 0.84.1 and Node v22.23.2. The old finding was correct about 1.0.1786915905, which the config stopped naming on 2026-08-18, and it was already stale when it was written into docs/azure-crosscheck.md on 2026-08-20. The dangling "ledger M29" provenance is dropped. The operative fact the section omitted is now stated: the lane is off because crosscheck-azure.json has enabled:false. The status line no longer overclaims. BUILT AND SERVING becomes BUILT 2026-08-20 with the fact that matters first: zero GLM reviews have ever completed, six attempts on 2026-08-20 all recorded tool-failure, and the lane's only verdict came from the pi-codex fallback. The current roster state is reflected, including the restored fallback entries with crosscheck-same-model on. Other corrections: 510K tokens was one hour reported as a day, and the measured total is 727,136; the reasoning_effort probe is restated as an unretained observation; the five-tool-turns figure is removed because no run record carries a turn count; both per-minute limits are stated and the token attribution is labelled inference; the account of what killed each attempt is replaced with what the ledger records; the C1 forward reference is dropped; the zeroed GLM cost table is recorded as a spend-visibility gap; the Cost Management implication is dropped while keeping the fact; and three Work items that appeared in neither list are now covered. R9 is left alone: it already says a pi review on the current image is unproven, which stays true and is consistent with the corrected text.
A verification pass found ten findings against this section, three of them merge-blocking. All ten are addressed here, docs only, one file. The image claim is refuted rather than softened. The current fm-ccm image does carry pi. Config model_image_id names gallery version 1.0.1787092687, whose source managed image img-fm7c799d-ccm-1.0.1787091895 carries the pi-tarball-sha256 and node-tarball-sha256 tags that only a build from the Pi-carrying declaration (#246) can write, its Image Builder run succeeded on 2026-08-18 between 22:26:20Z and 22:36:46Z, after #246 landed on main at 20:51:35Z, and that declaration asserts pi --version against a tracked version twice, before and after the credential purge. The digests match docs/azure-crosscheck/model-image-closure.json for pi-coding-agent 0.84.1 and Node v22.23.2. The old finding was correct about 1.0.1786915905, which the config stopped naming on 2026-08-18, and it was already stale when it was written into docs/azure-crosscheck.md on 2026-08-20. The dangling "ledger M29" provenance is dropped. The operative fact the section omitted is now stated: the lane is off because crosscheck-azure.json has enabled:false. The status line no longer overclaims. BUILT AND SERVING becomes BUILT 2026-08-20 with the fact that matters first: zero GLM reviews have ever completed, six attempts on 2026-08-20 all recorded tool-failure, and the lane's only verdict came from the pi-codex fallback. The current roster state is reflected, including the restored fallback entries with crosscheck-same-model on. Other corrections: 510K tokens was one hour reported as a day, and the measured total is 727,136; the reasoning_effort probe is restated as an unretained observation; the five-tool-turns figure is removed because no run record carries a turn count; both per-minute limits are stated and the token attribution is labelled inference; the account of what killed each attempt is replaced with what the ledger records; the C1 forward reference is dropped; the zeroed GLM cost table is recorded as a spend-visibility gap; the Cost Management implication is dropped while keeping the fact; and three Work items that appeared in neither list are now covered. R9 is left alone: it already says a pi review on the current image is unproven, which stays true and is consistent with the corrected text.
… owed (#275) * docs(azure): make the R6 status true to what landed and what is still owed R6 still read NOT DONE with a work list describing work that merged in #264 and is now serving. Records what landed, what is genuinely still owed (the live end-to-end GLM review, blocked on a 25K token-per-minute Fireworks quota that is an owner portal action; the startup-credit decrement check; the compartment lane's image rebake), and leaves the acceptance sentence unmet because it is. * docs(azure): correct the R6 status to what the artifacts actually show A verification pass found ten findings against this section, three of them merge-blocking. All ten are addressed here, docs only, one file. The image claim is refuted rather than softened. The current fm-ccm image does carry pi. Config model_image_id names gallery version 1.0.1787092687, whose source managed image img-fm7c799d-ccm-1.0.1787091895 carries the pi-tarball-sha256 and node-tarball-sha256 tags that only a build from the Pi-carrying declaration (#246) can write, its Image Builder run succeeded on 2026-08-18 between 22:26:20Z and 22:36:46Z, after #246 landed on main at 20:51:35Z, and that declaration asserts pi --version against a tracked version twice, before and after the credential purge. The digests match docs/azure-crosscheck/model-image-closure.json for pi-coding-agent 0.84.1 and Node v22.23.2. The old finding was correct about 1.0.1786915905, which the config stopped naming on 2026-08-18, and it was already stale when it was written into docs/azure-crosscheck.md on 2026-08-20. The dangling "ledger M29" provenance is dropped. The operative fact the section omitted is now stated: the lane is off because crosscheck-azure.json has enabled:false. The status line no longer overclaims. BUILT AND SERVING becomes BUILT 2026-08-20 with the fact that matters first: zero GLM reviews have ever completed, six attempts on 2026-08-20 all recorded tool-failure, and the lane's only verdict came from the pi-codex fallback. The current roster state is reflected, including the restored fallback entries with crosscheck-same-model on. Other corrections: 510K tokens was one hour reported as a day, and the measured total is 727,136; the reasoning_effort probe is restated as an unretained observation; the five-tool-turns figure is removed because no run record carries a turn count; both per-minute limits are stated and the token attribution is labelled inference; the account of what killed each attempt is replaced with what the ledger records; the C1 forward reference is dropped; the zeroed GLM cost table is recorded as a spend-visibility gap; the Cost Management implication is dropped while keeping the fact; and three Work items that appeared in neither list are now covered. R9 is left alone: it already says a pi review on the current image is unproven, which stays true and is consistent with the corrected text. * docs(azure): keep the quota wording consistent with the inference caveat * docs(azure): retire the fm-ccm no-pi claim at its source and in C1 Scope expansion approved by the coordinator: the requirement doc corrected this claim while the component doc it originated in still asserted it, and C1 (merged in #274 while this branch was open) had since built five further claims on top of it. docs/azure-crosscheck.md, where the sentence originated, now records the corrected limit with the evidence chain: the current fm-ccm image carries pi, and the lane is off because crosscheck-azure.json has enabled:false. The 2026-08-16 measurement is kept and attributed, since M29 is not a dangling reference, only one that lives in the owner's mutation ledger outside this repository, which is now said explicitly. Two neighbouring sentences depended on the false one: the instrumentation follow-up described as bound to an image rebake, and the phases paragraph attributing the lane's silence to a missing image capability. Both now name the flag. C1 depended on it five times and one of those dependencies was independently wrong: it stated the operator home has no config/crosscheck-azure.json. The file exists, carries enabled:false, and names a current model_image_id. Also corrected: the status line and order-of-work entry no longer say the phases wait on a rebake; the argument that the 75 minutes cannot have come from a compartment run after 2026-08-16 is withdrawn rather than restated, since its premise was the false claim; and unmeasurable becomes unmeasured, which is a reversible condition. C1's "known contradiction" paragraph is resolved rather than left stale: R6's status line no longer reads NOT DONE. It now carries the correction that matters to C1, which is that GLM has never completed a review, so the pi-codex fallback is what served the one measured run.
What was broken
The Azure Crosscheck model guest has had a working
pibranch since early August,bin/fm-crosscheck-azure.pyadmitspireviewers (provider host,auth.jsoncredential name,PI_CODING_AGENT_DIR), anddocs/azure-crosscheck.md:62already told operators the image pins "the supported Codex, Claude, or Pi reviewer CLI".The tracked build contract installed only the Codex and Claude CLIs. So a Pi reviewer reached a live model VM, ran, and died on
pi: command not foundafter the VM was already paid for. Documentation described a closure the image did not carry.What this changes
Adds the Pi closure to
docs/azure-crosscheck/model-image.json, pinned exactly the waybin/fm-azure-cell-image.shpins it for crewmates, and against the same tarball, so a Pi reviewer and a Pi author run one identical agent rather than two versions that could disagree for reasons a review would report as a finding.Pi is an npm package with a
#!/usr/bin/env nodeentrypoint, not a static binary, so:deb.nodesource.com/add-apt-repositoryinstall;PATHis exported explicitly, because every other closure check in this build invokes an absolute path and would pass on an image whereenv nodecannot resolve.Two gaps the previous contract could not catch, closed for all three CLIs:
pi --versionexits 0 for any version, so running it cannot show the digest-pinned tarball is what reachedPATH.piVersionis a tracked parameter and the build compares against it.find / -exec rm -rfand therefore the one step capable of removing a CLI. The closure is now re-verified as the build's last act..pijoins the ambient-credential purge, and npm's build-time state is removed, so the image still ships with no ambient credential.Test
The declaration test gains an assertion that every closure parameter is referenced by a build step. Parameter presence alone cannot distinguish a closure the image carries from one it merely declares.
Five mutations, each confirmed to change the file before the run:
piTarballSha256parameter.pifrom the credential purgepiTarballSha256declared, replace its verification step with anechotests/fm-crosscheck-azure.test.shpasses;shellcheck -xon the touched test passes;bin/fm-behavior-shards.sh --check 8passes.Scope
Tracked declaration only.
image-build, promoting the managed image into the Compute Gallery (the reviewer SKUs need aDiskControllerTypesfeature a managed image cannot carry), and repointingmodel_image_idremain operator lanes. The docs now record that gallery promotion is the one step of this contract the bounded command does not own, which is why a rebuilt image does not reach reviews until it is promoted.