feat(rebuild): one-command fresh-machine flow from a capture bundle or manifest#146
Merged
Conversation
Author the OpenSpec change for `endstate rebuild --from <bundle.zip|manifest.jsonc>`: proposal, design, the endstate-rebuild delta spec, a capture-bundle-zip MODIFIED delta, and tasks. Documents the restore-path resolution chain (payload -> configs rewriting at capture, ManifestDir-relative source resolution at apply), the refuse-before-mutation confirmation gate (new CONFIRMATION_REQUIRED code), temp-dir lifetime, verify-as-data semantics, and URL input as a v0 non-goal. The MODIFIED delta reframes capture-bundle-zip's "Apply from zip" requirement so the Go engine's supported zip-consumption path is `rebuild`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WjiYqx7LVvR2Yr883PMKYr
Add `endstate rebuild --from <bundle.zip|manifest.jsonc>` composing the existing plan -> install -> restore -> verify pipeline into one command, and wire the previously-dead bundle extraction (bundle.ExtractBundle/IsBundle) into production so a capture zip is finally consumable by the Go engine (fulfilling the PowerShell-only "apply from zip" behavior in openspec/specs/capture-bundle-zip.md). - RunRebuild (new commands/rebuild.go): validate --from (empty -> MANIFEST_VALIDATION_ERROR; URL -> NOT_SUPPORTED; missing -> MANIFEST_NOT_FOUND; bad zip -> MANIFEST_PARSE_ERROR); confirmation gate before any mutation; extract bundle with deferred temp cleanup spanning the whole pipeline; delegate to RunApply then RunVerify. Bundle restore sources resolve from configs/<module>/ inside the extraction dir with zero apply-side rewriting. - Restore is on by default; a live run (not --dry-run/--no-restore) requires --confirm, refused via the new CONFIRMATION_REQUIRED code. Verify failures are data: success envelope, exit 0. - CLI wiring (main.go: --from/--no-restore parse, usage, dispatch), capability advert (capabilities.go), and docs (cli-json-contract rebuild section + CONFIRMATION_REQUIRED; event-contract composition note; readme quickstart + command row). - Hermetic tests (rebuild_test.go): capture->rebuild round-trip, bare manifest, confirmation gate, dry-run/no-restore lanes, input validation, temp cleanup (success + mid-pipeline error), event ordering, verify-failure-is-data, capabilities advert. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WjiYqx7LVvR2Yr883PMKYr
Dual-review follow-ups: MODIFIED delta for restore-opt-in naming rebuild's --confirm as the consent primitive (Core Invariant #6 kept: consent is explicit, command-line-only, refused before mutation); flat capture-bundle-zip spec updated to name rebuild as the Go engine's zip-consumption path; design notes for the accepted double verification and the capture-bundle-zip archive-ordering dependency; event-contract wording caveats the empty-stream early-error lane; restore field documented as posture, not execution. Tests: no-confirm refusal now proven against a zip (no extraction dir created) and a post-extraction manifest-parse-error lane locks temp cleanup on the envelope-error return path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WjiYqx7LVvR2Yr883PMKYr
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.
Implements OpenSpec change
endstate-rebuild— wedge blocker #2 from the 2026-07 market brief. The capture zip the engine produces was not consumable by the Go engine at all: the "apply from zip" behavior inopenspec/specs/capture-bundle-zip.mdwas only ever implemented in the retired PowerShell engine, andbundle.ExtractBundle/IsBundlewere dead code. This wires them into a single command.What
endstate rebuild --from <bundle.zip|manifest.jsonc>— composes the existing plan → install → restore → verify pipeline in one command. A.zipextracts to a temp dir whose lifetime spans the full pipeline (deferred cleanup covers every return path); a bare.jsoncruns the same pipeline without extraction.CreateBundlerewrites restore sources to./configs/<module>/<leaf>at capture time and apply resolves them against the extraction dir. The resolution chain is now documented in design.md and locked by a capture→rebuild round-trip test (restored bytes == captured bytes).--confirm, refused before any mutation with the newCONFIRMATION_REQUIREDerror code.--dry-run/--no-restoreneed no confirmation. A MODIFIED delta forrestore-opt-inreconciles Core Invariant chore(main): release 1.6.0 #6: consent stays explicit, command-line-only, never defaulted or supplied by bundle content.schedule run); only infrastructure/input errors flipsuccess.commands.rebuildwith its flag set (the GUI's one-click-rebuild gate); URL input rejectedNOT_SUPPORTED(v0 is local-file only).Review
Dual-pass review (ContractGuard + code review, both Opus). ContractGuard's MAJOR — restore-by-default vs the governed
restore-opt-inspec with no reconciling delta — is fixed via the MODIFIED delta + design rationale. All MINORs addressed: stale flatcapture-bundle-zipspec updated to name rebuild as the zip path, double-verification documented as accepted v0 cost, archive-ordering dependency noted, refusal-precedes-extraction now proven against a real zip, and a post-extraction manifest-parse-error lane locks temp cleanup on the envelope-error return path.Tests
12 hermetic tests: round-trip restore-content match, bare-manifest lane, confirmation gate (zero installs + no extraction), dry-run, no-restore, input-validation quartet, temp cleanup ×3 (success / install error / parse-error envelope return), event phase-first/summary-last, capabilities advert, verify-failure-is-data. Full suite green;
npm run openspec:validatepasses.Note for merge sequencing: independent of #145 (
capture --pin) — branched off main; rebuild consumes pinned manifests when present but does not require them. Archivecapture-bundle-zipbefore archiving this change (MODIFIED-delta ordering).🤖 Generated with Claude Code
https://claude.ai/code/session_01WjiYqx7LVvR2Yr883PMKYr