# Deterministic phase machine plan ## Goal Add a small deterministic execution machine for real task work in `pi-config`, especially repo work, without turning the whole system into Case. ## Why Current system has strong pieces: - task docs - task folders - `pi-loop` - `pi-job-*` - `ralph-loop-run` - validation-first doctrine But the execution loop is still too prompt-shaped. We need a file-truth state machine that says: - what phase the task is in - what can happen next - what evidence is required to advance - what counts as blocked vs done ## Design principle Deterministic orchestration. LLM does the work inside a phase. Files and runner decide allowed next phase. ## Scope This is for meaningful execution tasks, mainly: - repo implementation - migrations - audits/hardening - multi-pass truth-sensitive work Not for: - tiny one-off questions - loose brainstorming - personal reflection chats ## Canonical task-folder files For phase-machine tasks, use: - `README.md` - `STATE.md` - `TASKS.md` optional when substeps matter - `EVIDENCE.md` - `artifacts/` ## Core phases Use a small fixed set. 1. `intake` 2. `shape` 3. `implement` 4. `verify` 5. `review` 6. `repair` 7. `done` 8. `blocked` 9. `needs_user_decision` ## Phase meanings ### `intake` Task exists but objective/frame is not yet locked. Exit condition: - enough info to state objective, done gate, exclusions, reality constraints ### `shape` Intent frame is being locked and translated into execution criteria. Required outputs: - objective - done gate - exclusions - reality constraints - validation plan - visible feature checklist if user-facing Exit condition: - kickoff frame complete in `STATE.md` ### `implement` Main execution phase. Can repeat. Allowed actions: - edit code/docs/scripts - create artifacts - run exploratory checks - update substeps Exit condition: - candidate solution exists - candidate evidence path exists ### `verify` Truth-first validation of the claimed outcome. Allowed actions: - run tests - run scenario checks - inspect outputs - collect evidence - mark failed categories Not allowed: - broad new feature work Exit condition: - all required gates pass -> `review` - safe bounded fixes needed -> `repair` - scope/risk/user ambiguity -> `needs_user_decision` - impossible with current truth/env -> `blocked` ### `review` Diff/result quality pass. Checks: - matches objective - no fake backend truth - no visible ambiguous half-working feature - docs/artifacts consistent - change is minimal enough / sensible enough Exit condition: - pass -> `done` - fixable issue -> `repair` - unclear product tradeoff -> `needs_user_decision` ### `repair` Bounded fix after verification/review failure. Not a new open-ended build phase. Allowed actions: - fix known failed checks - tighten docs/evidence - hide/disable untruthful feature Exit condition: - after repair, must go back to `verify` ### terminal phases - `done` - `blocked` - `needs_user_decision` No other terminal states. ## Deterministic transitions ```text intake -> shape shape -> implement | blocked | needs_user_decision implement -> verify | blocked | needs_user_decision verify -> review | repair | blocked | needs_user_decision review -> done | repair | needs_user_decision repair -> verify | blocked | needs_user_decision ``` Forbidden transitions: - `implement -> done` - `shape -> done` - `repair -> done` - `verify -> implement` directly Reason: - no skipping proof - no skipping revalidation after repair ## Required STATE.md fields For phase-machine tasks, `STATE.md` should have at least: - Phase: - Status: - Objective: - Done gate: - Not doing: - Reality constraints: - Validation plan: - Current result: - Next step: - Blockers: - Evidence location: - Evidence link: - Candidate done: yes|no - Validator status: pending|pass|fail - Repair applied: yes|no - Revalidation status: pending|pass|fail - Last updated: Important: - assume the user often reviews by opening files remotely, not by running commands on the machine - `STATE.md` should always include a clickable evidence link when artifacts exist - prefer full clickable URLs, not local-only paths - for complex multi-artifact evidence, generate one HTML index that links screenshots, text files, logs, and other outputs ## Visible feature checklist When user-facing work is involved, track each feature as: - `real_working` - `real_read_only` - `blocked_hidden` - `unknown_do_not_show` This belongs in `STATE.md` or `EVIDENCE.md`. ## Evidence gates Minimum generic gates before `done`: - objective matched - required validation command(s) run - required manual/scenario evidence captured when relevant - visible features have truthful state labels - no fake backend/local placeholder presented as real - next operator can inspect proof from files - `STATE.md` includes a clickable evidence link - complex evidence bundles should prefer one HTML index page over scattered raw files Repo-specific gates can extend this later. ## Runner plan Do not mutate `pi-loop` itself for this. Build a separate helper. Artifact exposure rule: - runner should prefer generating evidence files that are easy to open remotely - simple case: link directly to one `.txt`, `.md`, image, or exported artifact - complex case: generate `artifacts/evidence.html` as the canonical joinery page and put that URL in `STATE.md` Suggested command: - `bin/task-phase-run --task-dir /home/sebas/work/tasks/T-123 --repo /path/repo` Responsibilities: 1. read `STATE.md` 2. detect current phase 3. build a phase-specific prompt 4. run one bounded Pi pass 5. require file updates 6. parse next phase from `STATE.md` 7. reject invalid transition 8. stop only on: - `done` - `blocked` - `needs_user_decision` - no material progress ## Phase-specific prompts Prompt should include: - current phase - allowed actions - forbidden actions - exact required file updates - allowed next phases only Example: - if phase is `repair`, prompt must explicitly ban open-ended implementation and require return to `verify` ## Progress rule Each pass must create at least one: - code/doc change - state change - evidence gain - blocker clarification - risk reduction If not, runner stops as blocked or needs replan. ## Best first implementation slice ### slice 1 Doc + template only. - define phase-machine `STATE.md` template - define transitions - define gates ### slice 2 Add `bin/task-phase-init` - create phase-machine files for a task ### slice 3 Add `bin/task-phase-run` - one-pass deterministic orchestrator over `STATE.md` ### slice 4 Optionally add looping wrapper - continue bounded passes until terminal phase ## Relation to existing tools - `pi-job-*`: detached execution transport - `pi-loop`: repeated generic passes - `ralph-loop-run`: closest current ancestor, but too prompt-hardcoded and run-dir scoped - new phase runner: task-folder scoped deterministic orchestrator ## Recommendation Build this in order: 1. upgrade docs/template first 2. add `task-phase-init` 3. add `task-phase-run` 4. later decide whether to reuse `pi-job-*` underneath for detached mode This should stay narrow. Do not make a general workflow engine. Make it a truthful task-phase harness for your actual repo work.