Files
stack/docs/scratchpads/1050-install-state-machine-red-fixture.md
T
be-coder-05 229f643a84
ci/woodpecker/pr/ci Pipeline failed
ci/woodpecker/pr/greenfield-install Pipeline was successful
feat(installer): add transactional P0-P9 state machine
2026-08-05 12:20:49 -05:00

7.0 KiB
Raw Blame History

#1050 — Installer P0P9 state machine and red-first fixture

Objective

Implement C1 from the canonical greenfield-install PRD v2: a transactional P0P9 installer spine, a side-effect-free P0P8 --check, and a lane-parametric Debian/glibc non-root from-zero fixture. The acceptance milestone is an attributable RED on the pre-C1 installer while preserving P3 PASS.

Authority and scope

  • Canonical requirements: jason.woltje/jarvis-brain docs/plans/2026-08-04-greenfield-install-blockers-PRD-v2.md. Currency was re-derived after compaction: authenticated fetch resolved origin/main to cb23e5fbc8a282fa967b93d7a134fa48d11b4bb1; the PRD and charters are byte-identical to the previously read remote copies.
  • Tracking: mosaicstack/stack#1050 on git.mosaicstack.dev (author read back as be-coder-05).
  • Base: origin/next 4df478cdd150fdf8d52ea109f02ade5d85017acd.
  • Out of scope: PATH, skills, headless wizard/identity, activation remediation, #869 wiring, RM-02, main promotion.
  • docs/TASKS.md is orchestrator-single-writer and is not modified by this worker.

Plan

  1. Pre-register the canonical phase/output/side-effect-free/fault-injection checks and observe RED against the base installer.
  2. Commit the immutable red-first acceptance fixture before implementation.
  3. Add the state-machine/journal/postcondition spine without repairing P4/P5/P8 symptoms.
  4. Wire the expected-RED from-zero fixture into Woodpecker using Debian/glibc and a non-root target user.
  5. Run shell/static baselines, situational container validation, code review, security review, then deliver through a PR to next under the coordinator-owned merge path.

Budget

  • Working estimate: 32K reasoning/output tokens.
  • Hard external cap: none stated.
  • Adaptation: keep implementation in shell surfaces already in scope; no package dependency install unless repository gates require it.

Pre-registered acceptance checks

ID Exact case Expected pre-fix result
C1-R1 tools/e2e-install-test.sh --lane next in a clean Debian 12 container as uid 1001 non-zero; P3 PASS; P4 NOT-MEASURED / UNDECLARED; P5/P6/P8 FAIL with own reasons
C1-R2 tools/install-state-machine.test.sh phase table case RED because base installer does not enumerate canonical P0P9 contracts
C1-R3 side-effect-free --check case over a fingerprinted HOME RED because base --check is version-only rather than P0P8 predicates
C1-R4 fault injection after each P2…P8 RED because base installer has no injectable durable journal/rollback state
C1-R5 Docker unavailable base harness incorrectly exits 0; replacement must fail non-zero
C1-R6 lane resolution bare checkout is forbidden; fixture must pass --next and assert the resolved prerelease version
C1-R7 same Debian fixture with git absent vs present absent: P1 FAIL while legacy installer exits 0 and sync degrades; present: P1 PASS and observed store/runtime containment 101/101

Progress

  • Charter, doctrine, delivery/CI/QA/docs guides read and re-anchored after compaction.
  • Canonical PRD v2/v3 addenda and charters read from fetched origin/main; numbering reconciles with the TL spec. No numbering conflict found. INV-B/C/D are binding and implemented without renumbering.
  • Target base reachability verified with merge-base --is-ancestor.
  • Issue #1050 created and provider author read back.
  • Initial RED captured; TL rejected P4's repo-root count as a false RED. Four populations disagree (framework payload 1, repo root 13, sync store 101 in the fixture, W-jarvis observation 7), so C1 now requires a checkout-free declared shipped-set artifact and reports P4 NOT-MEASURED / UNDECLARED until C5 supplies it.
  • P6 strengthens #869: the two dead enforcement hooks reproduce from zero on a clean broker-less container. C1 asserts the breach but neither wires nor unwires it.
  • P1 false pass identified from the P4 evidence row: git is absent from the Debian base and was undeclared even though skill sync shells out to it. C1 adds git to P1; the fixture matrix preserves absent/present controls. The prior claim that web1's missing runtime skills reproduce this greenfield mechanism is withdrawn by the TL and is not carried here.
  • Corrected RED transcript captured and reported, including the git-present/absent controls and strict P3 PASS.
  • State-machine implementation complete: private pre-mutation journal/snapshot, P0P8 --check, P2P8 fault seam, rollback, durable manifest/journal seal, action-status persistence, safe rollback roots, and stale-projection recovery.
  • Debian/glibc checkout fixture now packages the complete current checkout, verifies its digest in-container, and reaches the expected attributable RED without host inheritance.
  • Reviews complete. Automated review defects around Bash conditional errexit, explicit exits, P4/P6 persisted action status, dev/offline source resolution, stale locks, checkout coverage, and rollback path safety were remediated. Remaining automated objections are the charter-mandated expected RED/C5 boundary and signed provenance, which the canonical PRD explicitly defers; independent informed review is still required.

Risks / blockers

  • The deployed create wrappers do not expose --dry-run; identity preflight was performed through pr-merge.sh --dry-run on the same HOMELAB repo, which resolved git.mosaicstack.dev + be-coder-05. The issue create then fell back from tea to the API but provider read-back confirmed author be-coder-05.
  • next is an integration lane; main promotion remains #1037-owned.
  • #869 must remain staged and inactive.
  • Late sequencing input MB-BRAIN-01 is accommodated without implementation or renumbering: P2 covers installer distribution only; P5 owns requested credential capability; P7 leaves an ordered seam for credential-dependent resource provisioning after P5.

Verification log

  • bash -n and ShellCheck pass for all changed shell surfaces; git diff --check passes.
  • bash tools/install-state-machine.test.sh passes, including exact P0P8 rows, good/bad discrimination, persisted P4/P6 action failures, P2P8 rollback, unsafe/overlapping/symlink roots, stale active.json, and fatal journal initialization.
  • bash tools/install-next-lane.test.sh passes, including exact @next versions, immutable source fallback, source-build/archive-failure rollback, offline --dev, explicit refs, and prerelease suffix mismatch.
  • bash tools/e2e-install-test.sh --lane next --source checkout --git present returns the required expected RED in clean Debian/glibc as uid 1001: installer P0/P1/P2/P3/P7 PASS; P4/P5/P6/P8 and P9 blocking; no Done. claim; checkout archive digest pinned and current framework installer exercised.
  • Earlier repository gates passed: pnpm typecheck, pnpm lint, pnpm format:check, pnpm test:installer, upgrade manifest/rollback/durable-snapshot/migration suites, and focused @mosaicstack/mosaic tests with an isolated npm prefix. Full rerun is required after final edits.