Conversation
The handoff is version 4: target.image is the bound image's id (sha256:<64 hex>) and target.tag carries its recipe tag, whose target and pin segments must be the handoff's own. The builder's dockerSandbox predicate (isFactoryImageId) admits only ids. Dispatch hands the capture the binding's id and tag; `factory builder-handoff` takes --image-id, or reads <FACTORY_STATE_DIR>/images.sqlite through the new read-only openImageRegistryReader, and refuses rather than guess. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t they prove The reader creates no registry and writes nothing to it, but SQLite may leave -wal/-shm beside a quiescent WAL registry; the JSDoc and the test title say so. A new case proves a file with no schema version is refused and left unmigrated (sqlite_master stays empty), and the reader test now checks the absent path is not created and the record is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s handoff Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e docker CLI it calls The config's own thread resolver is exercised with node:child_process mocked: the argv (with -- before the id), the thread's abort signal, and a refusal for every malformed or mismatched answer. Label values and daemon stderr are quoted and capped in refusals. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed image is refused With the devkit recipe tag moved onto the pinned node base, a thread handed the bound image id still runs the bound id; a version-3 handoff naming the tag is refused by the schema, and a held id the factory did not build (the base) is refused by its labels. Each refusal is pinned to its own reason: without the label check the base is admitted and fails later, at workspace preparation, which a bare "refused" assertion would have accepted. The tag is put back on the bound image in a finally. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ing to what they claim Dispatch's kept-binding test now asserts the builder handoff names the bound image and tag, not the registry's newer build of the same key (mutation-checked). FACTORY_LABELS is exported from the image builder, which writes its labels through it, and a test pins the builder's copy to the same three names. builder-handoff's refusal for a missing or unreadable image registry carries the --image-id hint, and its usage says it reads images.sqlite read-only unless --image-id is given. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pgrade both together The README says builder-handoff names the image the registry records now (pass --image-id from a work order's image_bound event to reproduce its builder), states the label rule as the full pin and a key matching the tag's prefix, and that the controller and the builder must be upgraded together. The plan records the final-review fixes and the full-recipe-key follow-up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
This branch was successfully deployed
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.
Framework-gaps item 4, PR 2 of 2 (plan
docs/superpowers/plans/2026-09-25-images-built-on-demand.md, Tasks 18-21). Follows #852. The builder now runs the work order's bound image by Docker ID, just as the verifier already does. The builder and the verifier now provably run the same image.What changes
target.imageis the bound image ID (sha256:<64 hex>), andtarget.tagcarries the recipe tag. The tag's target and pin must be the handoff's own. Version 3 handoffs are refused at first admission. Threads admitted before the upgrade keep the image they recorded.dockerSandbox({ images })predicate isisFactoryImageId.docker image inspect -- <id>, with a 30 s timeout and the thread's abort signal). It refuses unless the image'sb4.factory.target,b4.factory.pinandb4.factory.keylabels name the handoff's own target, the full pin, and a key matching the tag's key prefix. It fails closed. Labels sit in the config the ID content-addresses, so nothing changes between the check and the run. Anyone who can load images on the daemon can still forge labels, and the README says so.factory builder-handofftakes--image-id, or reads<FACTORY_STATE_DIR>/images.sqliteread-only. It refuses to guess.Closes the per-thread-sandbox plan's controller-side identity follow-up.
Upgrade note. The controller and the builder must be upgraded together. A mismatched pair refuses each new work order at its builder's first run, and each refusal spends one candidate attempt. Threads already admitted keep running.
Recorded follow-up: carry the full recipe key in the handoff, so the label check compares all 64 hex characters instead of the tag's 12.
Review
Each task had a spec review and a quality review, then the branch had a final review. The "As landed" notes in the plan record every fix. The most important ones:
dockerbinary.Verification (local, Node 24)
test:sandbox, the Docker lane: 11 files passed and 1 skipped (the opt-inclitarget); 30 tests passed and 4 skipped. The new proof covers three cases:pnpm lint,node scripts/check-docs.mjsand the factory packages' typechecks pass.Examples only, so there is no changeset.
🤖 Generated with Claude Code