# Skill-led development workflow plan **Status:** Accepted **Date:** 03SEP2026 **Working skill name:** `develop-workflow` ## Decision summary Replace the custom workflow engine with a model-invoked workflow skill that composes Pi's existing tools and repository evidence. Do not build a new extension in the first version. The workflow activates by default for feature work and other multi-step code changes, while questions and trivial edits stay lightweight. The parent Pi agent owns orchestration and judgment. It uses standard subagents for bounded assignments, `ask_user` for explicit human decisions, todo-herdr for session progress, Git worktrees for isolation, repository Markdown for recovery, project commands for verification, and independent subagents for review. Full-path work always pauses for: 1. Implementation-plan approval before production edits. 2. Direction approval before implementing non-trivial UI work. 3. Risk approval immediately before a risky or destructive action. Light-path work skips plan, UI, and independent-review gates. Risk gates apply to every path; discovering meaningful risk promotes the change to the full path before editing. After plan approval, it proceeds automatically through implementation, verification, independent review, remediation, and local integration unless it encounters a gate or cannot prove a completion criterion. Workflow records remain in project history. Successful work is committed and integrated locally; pushing and production deployment remain separate user actions unless explicitly requested. A skill can make these gates explicit and testable, but cannot technically prevent an agent from skipping them. The first version therefore offers procedural guardrails, not sandbox enforcement. Pilot evaluation must measure gate compliance directly. Reconsider a narrow enforcement mechanism only if repeated real failures remain after tightening the skill. ## Why replace the extension The current extension encoded useful policy, but coupled policy to a large orchestration runtime. `extensions/workflow` and `extensions/_workflows` contain roughly 30,000 lines of TypeScript and JavaScript. `extensions/workflow/engine.ts` alone is nearly 5,000 lines. The initial implementation added more than 20,000 lines, followed by a usability and recovery change exceeding 4,000 added lines. The documented failure evidence is more important than size: - Run `512d6c31-5bde-4e93-8164-5d31fb684b00` failed before implementation because design prose described prototyping but omitted the exact prototype assignment required by the state machine. - Run `51b0c1cb-f5b2-47f9-8c0c-b323307b720b` was interrupted during discovery. - Run `ecb11e1e-fe38-4076-862e-739498dbe33b` stalled in design until interrupted. - Recovery, leases, context handoffs, notification delivery, profile adaptation, restricted script execution, custom TUI surfaces, and exact structured outputs created many interacting failure paths unrelated to producing correct code. The replacement keeps the policies that matter and removes the custom execution engine that made the policy brittle. ## Design principles ### Evidence over ceremony Require observable evidence at each boundary: an approved plan, a real diff, actual command results, target-interface evidence for UI, and independent review findings. Do not require an exact model-authored graph or schema merely to advance. ### Fail closed at gates, adapt within phases Human approval is categorical and must never be inferred. Inside an approved phase, let the parent agent adapt task order, retry a failed check, narrow scope, or reassign work without satisfying a custom state-machine transition. ### One orchestrator The parent Pi agent owns the workflow record, task tree, worktree, decisions, integration, and final report. Subagents receive bounded assignments and return evidence. They do not own workflow state, ask the user, integrate branches, or delegate mutation. A worker may use its available read-only scout or researcher children within its assigned boundary, but the parent remains responsible for their results and known delivery failures. ### Repository state is the recovery boundary Session state improves usability but is not authoritative after interruption. Git, the retained workflow record, the approved plan, and generated artifacts provide enough evidence for a new session to reconstruct the next safe action. ### Independence is identity-based An agent that authored or mutated a reviewed diff cannot review it. Record mutator and reviewer display names plus stable task or child-session IDs when the tool exposes them. If stable IDs are unavailable, treat the entire ambiguous profile/run as a mutator and exclude it. A reviewer stays read-only and never remediates its own findings. The original implementer or another non-reviewer performs remediation, followed by a fresh review. ### Automation must remain reversible Automate research, implementation, tests, review, remediation, commits, rebases, and clean local fast-forward integration. Stop when the next action is ambiguous, destructive, production-facing, or cannot be reversed safely. ## Components ### 1. Model-invoked `develop-workflow` skill Create `skills/develop/develop-workflow/SKILL.md` with a precise description that triggers on feature work and non-trivial bug fixes, refactors, migrations, and UI changes. Explicitly exclude questions, research-only requests, and trivial edits. Keep the main skill short and sequential. Put branch-specific detail behind pointers: ```text skills/develop/develop-workflow/ ├── SKILL.md ├── references/ │ ├── evidence-and-recovery.md │ ├── git-and-integration.md │ └── review-and-remediation.md ├── assets/ │ └── workflow-record.md └── scripts/ └── checkpoint-record.mjs ``` `SKILL.md` owns phase order, gates, and completion criteria. References own detailed recovery, Git, and review rules. The asset is the default retained workflow-record template. The dependency-free checkpoint script validates required headings, writes through a same-directory temporary file, flushes, and atomically renames it; it does not orchestrate phases or make decisions. ### 2. Existing Pi primitives Reuse rather than wrap: - `ask_user`: explicit requirements, plan, UI, and risk decisions. - `set_tasks`, `patch_tasks`, and `list_task`: session-local execution progress and post-compaction recovery. - `subagent` and `subagent_message`: fresh, bounded research, implementation, verification, and review contexts. - `code-review`: parallel specification and repository-standards review. - `prototype` and `browser-harness`: non-trivial UI alternatives and real application validation. - `tdd`, `diagnosing-bugs`, `code-research`, and project-specific skills: phase-specific procedures. - `artifact-presenter`: plan and long-artifact review. - Git worktrees and normal project commands: isolation, commits, verification, rebase, and integration. Known harness defects are workflow constraints, not footnotes. Until fixed, launch subagents directly rather than through `multi_tool_use.parallel`; never park the parent solely on an expected callback; and verify that each result was delivered. `@jbcode/pi-bash-cwd` adds validated per-call Bash working directories on Pi 0.84.x. Shell mutations inside hidden worktrees still use explicit `cd && ...` or `git -C ...`, followed by `pwd` or Git top-level verification, as defense-in-depth. Before starting the full path, preflight required capabilities. Git worktree operations, a writable retained record, an explicit human interaction channel, target-interface validation when applicable, and a Git-capable independent reviewer are mandatory. Todo-herdr and artifact-presenter may degrade to the retained record and a reported artifact path, but their absence cannot bypass a gate. In print or JSON mode, or whenever a mandatory gate or validator cannot run, emit the pending decision or validation instructions and stop before product mutation. ### 3. Retained workflow record Use the repository's established plan location. Fall back to `docs/plans/.md` when no convention exists. Require the path to be unique before creation. Keep one concise Markdown record per active workflow and retain it after completion. The record contains: - status and current phase; - request, scope, and out-of-scope items; - source branch, base commit, feature branch, and worktree; - acceptance criteria; - approved implementation plan and explicit gate decisions; - mutating assignment ownership; - verification matrix and actual command outcomes; - review scope, reviewer identities, findings, and remediation outcome; - integration result; - blockers and the exact next safe action. Do not store transcripts, process leases, heartbeats, notification receipts, complete command output, or a model-authored execution graph. Link to durable artifacts or commits instead. Update the record only at meaningful checkpoints through the atomic checkpoint script. Commit the initial record before any product mutation and commit every approved human-gate decision before dependent product mutation. The last committed record is the durable fallback if a process stops during a later update. Todo-herdr remains the high-frequency progress view. ## Workflow ### Phase 0: Classify Choose the smallest sufficient path. - **Answer path:** questions and read-only explanations. Make no changes. - **Light path:** one obvious, low-risk edit with at most two distinct steps. Inspect, edit, run focused checks, and summarize without plan, UI, or independent-review gates. Promote to the full path before editing if discovery exposes meaningful risk or scope. - **Full path:** feature work or any change with three or more steps, ambiguity, multiple files or modules, architectural impact, non-trivial UI, dependencies, migration, security implications, or meaningful regression risk. When uncertain, use the full path. Record why the light path is safe when a change is near the boundary. **Completion criterion:** the selected path matches the observed scope and risk. ### Phase 1: Establish isolation and evidence 1. Read repository instructions, relevant docs, ADRs, tests, and current Git state. 2. Record the source branch and exact base commit. 3. Create `./.worktrees/` on a descriptive feature branch before feature edits. 4. Prove every subsequent shell command's location with explicit `cd` or `git -C`; treat the Bash cwd override as protection against fallback execution, not a replacement for the location proof. 5. If the source checkout is dirty, explain exactly which changes the new worktree omits and ask before proceeding. 6. Atomically create the unique workflow record in the worktree and create a task tree in the session. 7. Run applicable documentation checks, then commit the initial record as a pre-mutation recovery checkpoint. Treat branch collisions, record collisions, unmerged paths, unexpected worktree ownership, or an unignored worktree directory as blockers. Do not silently rename, reset, clean, stash, or copy source changes. **Completion criterion:** the isolated worktree identity is proven, the initial record is committed, and the record names the next action. ### Phase 2: Discover and resolve requirements Use read-only subagents in parallel when they can investigate independent concerns. Typical lanes are architecture/data flow, tests and precedents, and integration/blast radius. Give every child a self-contained prompt and state that no files are owned because the work is read-only. The parent reconciles evidence, identifies contradictions and unknowns, and uses `ask_user` only for decisions that repository evidence cannot answer. Persist answers in the workflow record. **Completion criterion:** requirements, constraints, acceptance criteria, affected surfaces, risks, and unresolved questions are explicit. ### Phase 3: Design and approve Draft an implementation plan that includes: - acceptance criteria mapped to implementation slices; - concrete file or directory ownership for every mutating assignment; - existing seams and patterns to reuse; - focused and full verification commands; - realistic test-data requirements; - UI-impact classification; - dependencies, migrations, production effects, and other risk gates; - the review fixed point and specification source; - integration and rollback strategy. Present the complete plan through artifact-presenter. Use `ask_user` to approve or request revision. Record the decision. Production edits cannot begin before explicit approval. If prototyping or later evidence materially revises scope, acceptance criteria, ownership, verification, or architecture, present the revised plan and obtain approval again before production edits continue. **Completion criterion:** the user explicitly approved the exact recorded plan. ### Phase 4: Prototype non-trivial UI For non-trivial UI, create three structurally different static or throwaway variants before editing production components. If three meaningful alternatives are impossible, ask the user to approve a smaller explicit count rather than failing on a schema. Prefer realistic host context and data. Validate each candidate in its actual interface: browser-harness for web UI, a real PTY/application session for TUI or native surfaces, and representative responsive sizes where the interface supports them. Follow the existing prototype skill's throwaway policy: capture all candidates on a dedicated throwaway branch, retain its commit reference in the workflow record, and keep prototype-only routes, switchers, and losing candidates out of the product branch. Present the candidates and use `ask_user` to select or refine a direction. Record and checkpoint the accepted direction before production mutation. Do not promote prototype code directly as production code. Treat the direction decision as approval only for the recorded UI choice; return to plan approval for any other material plan revision. Minor or non-visual UI changes may skip this phase only when the record states why. **Completion criterion:** the user approved the required number of target-interface-validated candidates, the throwaway source is retained by commit, and the production plan reflects the selected direction. ### Phase 5: Implement in slices The parent assigns each mutating slice to one implementer with exclusive file ownership. The parent itself counts as an implementer whenever it edits. State ownership before parallel work begins. Serialize mutation by default; parallelize only when ownership is disjoint and integration risk is demonstrably low. Each implementer receives the approved plan, relevant decisions, owned paths, acceptance criteria, test seam, commands it may run, and an explicit assignment deadline recorded in the workflow record. Default mutating assignments to 15 minutes; choose and approve a different bound in the plan when the task shape requires it. Instruct workers to stop at the deadline and not to commit, integrate, or delegate mutation. Use TDD at pre-agreed seams where practical. Run focused tests after each behavioral slice. Keep unrelated cleanup out of scope. Because the standard worker profile technically permits shell commands, commits, and read-only nested subagents, capture branch, `HEAD`, status, changed paths, and a patch artifact before and after every mutating assignment. The parent rejects unexpected commits or out-of-ownership paths and recovers from observed Git state rather than trusting prompt compliance. On an ownership or Git-invariant failure, stop all mutation, preserve the before/after evidence and worker result, mark that worker identity as a mutator ineligible for review, and open an explicit recovery decision with inspect, accept-and-replan, restore-with-a-non-destructive-patch, or abort choices. Resume only after the user selects an evidence-backed action. A deadline or missing terminal delivery never triggers automatic retry. Ask the child to stop through the available control surface, freeze the worktree, and prove the child process/session reached a terminal state before reassignment. Use the subagent UI or status/cancel tools when available. If liveness cannot be proven after parent interruption, keep the workflow blocked for human termination or takeover; do not launch another mutating agent into that worktree. The parent inspects returned diffs and evidence before marking a slice complete. A subagent's success claim is not proof. **Completion criterion:** every acceptance criterion has corresponding code and test evidence, and all changed paths are owned and intentional. ### Phase 6: Verify the integrated change Run verification from the worktree, not from a child transcript: 1. Inspect the complete diff and Git status. 2. Run focused behavioral tests. 3. Run typecheck, lint, build, and the full test suite required by the repository. 4. Exercise E2E behavior with realistic data when changed behavior crosses process or UI boundaries. 5. Validate UI in the browser/application at required responsive sizes. 6. Update documentation affected by behavior. 7. Record exact commands, exit codes, and concise outcomes. Never report a command successful unless it actually ran to completion. A flaky or environmental failure remains visible until explained and resolved or escalated. **Completion criterion:** the approved verification matrix passes with recorded evidence. ### Phase 7: Commit, synchronize, and independently review Create focused commits only after their appropriate checks pass. Before final review: 1. Fetch the latest source branch when a remote exists. 2. Rebase the feature branch onto the latest source branch. 3. If the rebase changes the effective tree or requires conflict resolution, rerun the affected checks and full required verification. 4. Pin the review base, product `HEAD`, clean status, tree hash, commit list, and diff fingerprint in a parent-generated review brief retained inside the workflow record. 5. Generate the exact review bytes with `git diff --binary --full-index --find-renames ... --` and hash those bytes with SHA-256. Record the command and digest. The integrated base and product commits are the durable artifact; regenerate the bytes from those commits instead of committing a duplicate patch. Launch specification and standards reviewers as separate direct subagent calls using profiles that have repository read access plus Git-capable `bash`, but no `edit` or `write` tool. A scout without Git access is not an eligible reviewer. Supply the same review brief, approved plan or workflow record as the specification source, repository standards, and exact diff command. The workflow record is a valid specification even when `docs/agents/issue-tracker.md` is absent; update the existing `code-review` skill so this path does not require issue-tracker configuration. Reviewers independently regenerate the pinned diff, confirm its SHA-256 digest, remain read-only, and differ from every recorded mutator identity. Capture Git status and tree state before and after review; any reviewer mutation invalidates its verdict and marks that identity as a mutator. For findings: - bind each finding to evidence and severity; - send valid fixes to an implementer, never the reviewer; - rerun affected checks and the full required suite; - run another fresh independent review; - escalate to the user after two unsuccessful remediation cycles or when a finding requires scope or architecture changes. Bind approval to the reviewed base, product `HEAD`, clean status, tree hash, and diff fingerprint. A later metadata-only workflow-record closure commit is outside the product-review fingerprint and must be proven to touch only that record. **Completion criterion:** both review axes approve the exact verified product diff. ### Phase 8: Integrate and close Integrate locally without another routine human pause when all prior evidence remains valid. 1. Confirm the source branch still points to the commit used for the final rebase. 2. If it advanced, return to synchronize, verify, and review. 3. Confirm the source checkout is clean and safe to update. A dirty or missing checkout blocks automatic integration. 4. Fast-forward the source branch to the reviewed feature branch. Do not create a merge commit. 5. In the source checkout, update only the workflow record with the bound review and completed integration evidence. Prove the closure diff touches no product file, run applicable documentation checks, and create one metadata-only closure commit. 6. Run a final cheap sanity check appropriate to the project. 7. Remove the completed worktree, then delete the feature branch only after proving both the reviewed product commit and closure commit are reachable from the source branch. 8. Mark all tasks complete and report the reviewed product commit, metadata closure commit, review command and SHA-256 digest, reviewer identities, workflow-record path, and verification evidence. Ask before conflict resolution that changes approved behavior, force operations, destructive cleanup, pushing, publishing, deployment, production access, or any non-fast-forward integration. **Completion criterion:** the reviewed commit is reachable from the intended local source branch, the retained record is complete, and temporary worktree state is removed safely. ## Recovery procedure A fresh session must not trust the workflow record blindly. Reconstruct reality in this order: 1. Read repository instructions, then inspect worktrees, branches, current refs, status, commits, and diff. 2. Discover candidate workflow records from observed branches/worktrees and repository conventions; do not assume the current checkout contains the active record. A workflow-created branch/worktree without a record is an orphan, not disposable state. 3. For an orphan, preserve the worktree, inspect its branch, base, reflog, status, commits, and diff, then ask whether to adopt it by creating an initial record, leave it quarantined, or remove it after separate cleanup approval. Never delete an orphan automatically. 4. Read a discovered record and compare its base, branch, and last completed checkpoint with observed Git evidence. 5. If an atomic-update temporary file remains, preserve it for inspection and use the last committed valid record as authoritative until the user approves recovery. 6. Rebuild todo-herdr tasks from completed evidence and the recorded next action. 7. Treat interrupted mutating assignments as unknown outcomes. Freeze mutation, inspect their diff, and prove the prior child is terminal before rerunning or reassigning work. 8. Treat prior subagents as gone only after terminal state is proven. A completed UI indicator without a delivered result is not evidence of either output or liveness. 9. Resume from the last proven checkpoint, not the most optimistic status line. 10. Ask the user when evidence conflicts, approved scope may have changed, child liveness is unknown, or recovery would require a risky action. The workflow record is a recovery map, not a transaction log. ## Risk gates Ask just in time, with concrete evidence and a recommended option, before: - adding, removing, or materially upgrading dependencies; - schema or data migration; - production or live-database access; - public API or compatibility breaks; - destructive Git or filesystem operations, except narrowly pre-authorized cleanup of the workflow's own worktree and feature branch after the reachability and clean-state checks in Phase 8 pass; - force push, history rewrite of shared work, or non-fast-forward integration; - conflict resolution that changes approved behavior; - materially expanded scope or acceptance criteria; - security posture changes; - publishing or deployment. Record the decision and its scope. One approval does not authorize later, broader risk. ## What the first version deliberately removes - Custom workflow state machine and transition engine. - Custom agent-profile loader and planner-selection schema. - Custom child-session runtime, scheduler, leases, and heartbeat recovery. - Model-authored JavaScript workflow DSL. - Custom dashboard, notification outbox, and context-handoff engine. - Exact structured assignment graphs required before implementation. - Automatic replay of interrupted mutating work. - A new workflow extension of any kind. Keep the current extension as historical reference during the pilot, but do not expose it as the default workflow. ## Implementation phases ### Slice 1: Skill and record contract - Add `skills/develop/develop-workflow/` with the progressive-disclosure structure above. - Write a compact workflow-record template and dependency-free atomic checkpoint script. - Add focused `node:test` coverage for valid creation and replacement, malformed or missing required sections, interrupted writes preserving the prior record, stale temporary files, concurrent or stale updates, flush/rename failure, and cleanup that never discards the last valid checkpoint. - Add a concise ADR superseding the custom-engine decision while preserving human gates, isolation, verification, and reviewer independence. - Audit every old-workflow reference with repository search. At minimum, add explicit `superseded-by` links or historical banners to `docs/workflow/README.md`, `docs/workflow/design.md`, `docs/workflow/dashboard-mocks.md`, the workflow and package ADRs, `README.md`, `extensions/workflow/README.md`, and `docs/nono-dynamic-permissions-plan.md`; resolve the replacement TODO in `docs/todos.md` only after the pilot succeeds. - Ensure managed Pi skill links expose the skill without exposing the old workflow extension. **Success criteria:** Pi discovers the skill; its description selects full versus light work correctly in fresh sessions; `node --test skills/develop/develop-workflow/tests/checkpoint-record.test.mjs` passes every failure-path case; the initial and post-gate records are atomic and committed before dependent product mutation; and every stale document points explicitly to the superseding ADR. ### Slice 2: Review and recovery integration - Align `develop-workflow` with `code-review`, `prototype`, `artifact-presenter`, todo-herdr, and direct subagent contracts. - Update `code-review` to accept the workflow record as its specification without an issue-tracker prerequisite. - Add the exact reviewer-independence, remediation, parent-generated review brief, record fingerprint, recovery, and local integration procedures. - Remove contradictory instructions from `implement` or replace it with a pointer to the new workflow where appropriate. **Success criteria:** no skill tells an implementer to self-review; a fresh session can resume a fixture using only repository evidence; reviewers cannot become remediators. ### Slice 3: Scenario evaluation Run the skill in fresh Pi sessions against disposable repositories or worktrees: 1. A question and a trivial edit that must avoid full-workflow ceremony. 2. An ambiguous multi-file feature that must research and ask before planning. 3. Non-trivial web and TUI changes that must prototype, validate in the target interface, and wait for human selection. 4. A dependency or migration change that must open a just-in-time risk gate. 5. A failed test, expired assignment, missing terminal delivery, and interrupted implementer that must freeze until diff and child liveness are proven. 6. Review findings that must be remediated by a non-reviewer and reviewed again. 7. A session restart that must reconstruct tasks from the retained record. 8. A source branch advancing before integration that must force rebase, verification, and review again. 9. Hidden-worktree shell execution that must prove its actual cwd before mutation. 10. Direct and wrapped subagent completion where missing delivery must remain visible and block dependent progress. 11. A crash after worktree creation but before record commit that must preserve and explicitly adopt, quarantine, or approve removal of the orphan. 12. Print/JSON or missing-tool execution that must emit pending instructions and stop before product mutation. Capture omissions and friction in `docs/todos.md` as required by this repository. **Success criteria:** all twelve scenarios reach the correct gate, blocker, or completion state without custom workflow code, and no scenario claims unexecuted verification, undelivered subagent evidence, or unknown child liveness as complete. ### Slice 4: Pilot and retirement decision Use the skill on at least three real changes of different shapes. Measure: - whether it activates appropriately; - time from request to approved plan and first implementation edit; - missed or unnecessary gates; - unverified success claims; - review findings caught before integration; - recovery time after a fresh session; - human interventions caused by workflow mechanics rather than product decisions. After the pilot, either tune the skill or document one narrow, repeated deterministic gap. Build a helper extension only if evidence shows that prompts and existing primitives cannot close that gap. Any helper may record or validate evidence but must not own stage orchestration or launch agents. Once the pilot passes, remove the old extension from managed exposure, archive its implementation and tests in a separate cleanup change, and retain its ADRs as superseded history. **Success criteria:** three real changes complete without orchestration failures; the user approves retirement; no replacement extension is added without a demonstrated repeated failure. ## Acceptance criteria - Feature and multi-step work activate the workflow by default; questions and trivial changes do not. - Full-path production edits never begin before explicit approval of the recorded plan; light-path edits remain low-risk and promote to the full path when that assumption changes. - Non-trivial UI never reaches production implementation before target-interface validation and human direction approval. - Risky actions receive scoped just-in-time approval. - Every mutating assignment has one named owner and deadline; observed Git state is checked before and after it; unknown child liveness freezes reassignment; and reviewers never overlap with mutators. - Verification evidence comes from commands run against the integrated worktree state. - Standards and specification reviews remain separate and both must approve. - Review remediation is implemented by a non-reviewer and causes verification plus review to repeat. - A fresh session discovers the active worktree and last committed valid record, preserves orphan worktrees, proves prior mutating children are terminal, then recovers the next safe action without custom persisted runtime state. - Successful work is rebased, reverified, independently reviewed, committed, fast-forward integrated locally, and cleaned up without a routine final approval gate. - Push, publish, deploy, production access, unsafe cleanup, other destructive operations, and unsafe integration remain explicit human gates; deletion of the workflow-owned worktree and branch is pre-authorized only after Phase 8's exact safety checks pass. - Missing human-interaction, target-validation, Git-review, or worktree capabilities stop full-path work before product mutation; optional UI conveniences may degrade without bypassing gates. - The first version adds no extension and no dependency. ## Future extension threshold Consider a minimal extension only after at least two real failures share the same deterministic cause and a skill revision cannot make the completion criterion observable. Acceptable candidates are atomic workflow-record updates or a read-only readiness check. Stage engines, custom schedulers, child runtimes, dashboards, and hidden automatic transitions remain out of scope.