| name | ship |
| description | Terminal full-cycle workflow: plan → implement → review → commit → push. Self-contained — execute the inlined steps directly, do NOT invoke other skills via the Skill tool. |
| disable-model-invocation | true |
| argument-hint | task description or issue URL |
| effort | high |
Task: Full-Cycle Ship — Plan, Implement, Review, Commit, Push
Overview
Single user-invoked command that drives a task end-to-end and reaches the remote in one invocation:
- Plan Phase — write a committed plan under the
tasks role resolved from AGENTS.md.
- Implement Phase — execute the Solution under TDD (RED → GREEN → REFACTOR → CHECK).
- Review Phase — QA + lead-engineer review of the diff with a structured verdict.
- Commit Phase — targeted documentation sync + Conventional Commits + task-status auto-flip.
- Push Phase — safe
git push with upstream and divergence gates.
Four explicit gates between phases:
- Plan → Implement — user MUST have selected a variant. If not, STOP.
- Implement → Review — project check MUST exit 0 AND
git status MUST be non-empty.
- Review → Commit — verdict MUST be Approve. Request Changes / Needs Discussion / crash → STOP.
- Commit → Push —
git status MUST be clean (all changes committed) AND if pushing main/master with remote-ahead, the Push Phase will ask before pushing.
Context
ship is the terminal composite of the SDLC: by the time the agent exits, work either reached the remote or the user has explicit visibility into why it did not. Each phase is FULLY INLINED below; the Push Phase's safety contract (no --force, per-push authorization for --force-with-lease, upstream-on-first-push, protected-branch divergence) is the canonical safety boundary between this session and shared infrastructure. Maintainer note (NOT for runtime): generated by `scripts/generate-skill-composites.ts` from `framework/composites.yaml`. Source-of-truth bookkeeping only.
Rules & Constraints
1. **No delegation**: All five phases are FULLY INLINED below. Execute the steps directly. Do NOT invoke any plan, implement, review, commit, or push skill via the Skill tool — they would re-enter without the composite's gate logic and the workflow would silently exit between phases.
2. **Five Phases, Strict Order**: Execute Plan fully, then Implement, then Review, then Commit, then Push. Never interleave; never skip a gate.
3. **Plan → Implement Gate**: User MUST select a variant. Decline / abort → STOP.
4. **Implement → Review Gate**: project check MUST exit 0 AND `git status` MUST be non-empty. Otherwise STOP.
5. **Verdict Gate**: only Approve proceeds to Commit. Request Changes / Needs Discussion / crash → STOP. Phase output is reported regardless.
6. **Commit → Push Gate**: `git status` MUST be clean. Push Phase's safety contract handles upstream + divergence + force decisions.
7. **No partial commit**: any earlier-phase failure (errors, crash, gate violation) STOPs the workflow.
8. **Transparency**: each phase reports its artefact (Plan path, Implement test results, Review verdict, Commit SHAs, Push remote ref).
9. **Planning**: use a task management tool (e.g. `todo_write`, `todowrite`, `Task`) to track all five phases as a single plan.
10. **Session Scope**: for Review, Commit, and Push, exclude files already modified/untracked at session start (compare to git-status snapshot from system context). Files created during Implement Phase ARE in scope. If unsure, ask before staging.
Instructions
Plan Phase
<step_by_step>
-
Initialize
- Use a task management tool (e.g.,
todo_write, todowrite) to create a plan based on these steps.
- Compute today's date in
YYYY-MM-DD format (e.g. via date +%Y-%m-%d or your environment's date primitive). Hold it as <DATE>. Derive <YYYY> and <MM> (zero-padded). Resolve the tasks role from AGENTS.md and then derive the eventual task file path from that role's layout.
-
Deep Context & Uncertainty Resolution
- Resolve
SRS and SDS from AGENTS.md. If you don't know their current content, read the resolved files now.
- Load related committed tasks: glob recursively under the resolved
tasks role. For each found file, parse its YAML frontmatter implements: field. Keep only tasks whose implements: set has a non-empty intersection with the FR-IDs you are about to put in the new task's implements:. Cap at 10 by recency (newest first by frontmatter date); if more match, list IDs in chat without bodies and ask the user which to expand. Read the full body of each kept task before drafting GODS. List the loaded tasks in chat (one bullet per task: file path + matched FR-IDs + one-line summary). If no related tasks exist, say "No prior tasks share FRs with this one — drafting from scratch."
- Follow
Proactive Resolution from AGENTS.md: analyze prompt, codebase, search for gaps.
- Use search tools (e.g.,
glob, grep, ripgrep, search, webfetch) for unknowns.
- If uncertainties remain: ask user clarifying questions. STOP and wait.
-
Draft Framework (G-O-D)
- Create the resolved task file's parent directories (use
mkdir -p or your environment's equivalent).
- Write the resolved task file with:
- Frontmatter containing ALL required keys per Rule 9. Set
status: to do initially.
- Body sections per
### GODS Format from AGENTS.md: ## Goal, ## Overview (with ### Context, ### Current State, ### Constraints), ## Definition of Done (placeholder bullets — fill in step 5a).
- For async/callback conversions, include an explicit error-handling DoD item or constraint before variant selection: how callback errors map to Promise rejection /
try-catch, and which tests prove error propagation is preserved.
- CRITICAL: Do NOT fill
## Solution section yet.
-
Strategic Analysis & Variant Selection
- Generate variants in chat following
Variant Analysis from AGENTS.md.
- For non-obvious tasks, the variant set MUST cover three distinct archetypes (the agent MAY add more, e.g. a defer/do-nothing option):
- Quick fix — minimal change within the current scope; solves the immediate problem fastest, may incur tech debt.
- Architecturally-correct — correct design within the task's current constraints/scope (not merely the fastest).
- Best long-term — strategic; optimizes maintainability over the horizon, may exceed current scope (refactor/investment).
- If two archetypes collapse into the same option for a given task, state that explicitly and still surface a distinct third — never silently drop below the three without noting the collapse.
- For EACH variant, present: Pros, Cons, Risks, and Best For (use cases/constraints it handles).
- Across all variants, analyze Trade-offs: security vs complexity, performance vs maintainability, cost vs features.
- Exception — single variant: Only offer 1 variant when the task has an obvious path (e.g., "create a text file", "add a config line") with no meaningful trade-offs. Briefly explain why alternatives don't apply.
- Ask user which variant they prefer. Wait for response.
- When user selects a variant, immediately proceed to fill the Solution section (Step 5). Do NOT stop after receiving the selection.
(Variant analysis is exempt from FR-UNIVERSAL.QA-FORMAT — see SRS scope. The format above continues to use multi-section presentation per variant.)
-
Detail Solution (S) — execute immediately after user selects a variant
- Re-read the task file you created in Step 3.
- Overwrite the
## Solution section placeholder with concrete implementation steps for the selected variant (follow ### GODS Format from AGENTS.md).
- The Solution section MUST contain: files to create/modify, implementation approach, code structure, dependencies, error handling strategy (especially for async/callback conversions), and verification commands.
- CRITICAL: You MUST write the updated content to the task file. Never leave Solution as a placeholder or comment.
5a. Acceptance Tuple Check — execute immediately, no permission needed
- Walk every entry in
## Definition of Done. For each, confirm the tuple (FR-ID, Test path or Benchmark id, Evidence command) is present and concrete (no placeholders like <TBD> or TODO). manual — <reviewer> is acceptable only with an explicit reviewer name.
- If any DoD item lacks the tuple, edit the task file to add it. Prefer reusing an existing FR (for bug fixes and small refactors) over coining a new one. Only introduce a new FR for user-visible or contract-level changes.
- If new FRs appear in
implements: that are absent from the resolved SRS, the task MUST contain an explicit DoD entry "add FR-XXX section to SRS with **Acceptance:** field filled".
- Do NOT create the test files themselves — that is the develop phase's RED step. This skill only FIXES the test location contract.
5c. Write SRS-inline
**Tasks:** Back-Pointer (FR-DOC-TASK-LINK) — execute immediately, no permission needed. This is a write step.
- For each FR-ID in the task's
implements: frontmatter, locate the heading ### <FR-ID>: in the resolved SRS.
- If the heading does not exist (new FR introduced by the same task), SKIP this FR for now and emit a chat note: "FR-XXX SRS section pending — task back-pointer deferred." The develop/commit phase will add the section AND the back-pointer atomically.
- If the heading exists, find the section's existing
**Description:** bullet (- **Description:** ...). Look at the line(s) immediately following it within the same section.
- If a
- **Tasks:** [...] bullet already exists: append , [REF:task:<YYYY>-<MM>-<slug> | <slug>] to the comma-separated list. Idempotency: if the exact SALP REF is already in the list, do nothing for that FR.
- If no
**Tasks:** bullet exists yet: insert a new line - **Tasks:** [REF:task:<YYYY>-<MM>-<slug> | <slug>] immediately AFTER the **Description:** bullet (before any other bullets in the section). The task: namespace id is <YYYY>-<MM>-<slug> (e.g. 2026-06-adopt-salp-anchors), derived from the task file's path.
- Surgical edit only: the rest of the SRS file MUST remain byte-identical. Do not re-format, do not touch other sections, do not adjust whitespace anywhere except the inserted/extended line.
5b. Update Documentation Index (FR-DOC-INDEX) — execute immediately, no permission needed. This is a write step, not a planning step.
- Resolve
index from AGENTS.md. For every FR-ID in the task's implements: frontmatter, register a row there.
- If the resolved
index file does not exist, create it with a ## FR heading (additional sections like ## SDS, ## NFR may be added by other skills; do not pre-scaffold them here).
- Within
## FR, ensure exactly one row per FR-ID. Row format (SALP):
- [REF:fr:<id> | <FR-ID>] — <one-line summary> — <status>
<id> — lower-kebab of the FR mnemonic (strip FR- prefix, lowercase, preserve . for hierarchical IDs like FR-DIST.MARKETPLACE → dist.marketplace). The reference resolves against the [ANC:fr:<id>] token next to the SRS heading. If the SRS section does not yet exist, write the REF anyway — develop/commit will add the matching ANC when the SRS section is added, at which point scripts/check-salp.ts will resolve it.
<one-line summary> — pull from the SRS **Description:** first sentence if the section exists, otherwise reuse the task title (or a short paraphrase ≤80 chars).
<status> — mirror the SRS **Status:** value if present, else [ ].
- Sort rows alphabetically by FR-ID inside
## FR before writing.
- Idempotent: if a row already exists for the FR-ID, only update its summary or status if the existing one is now stale; do NOT duplicate.
- This step is REQUIRED — it is part of execution, not the plan's Solution section. Skipping it leaves the index out of date and breaks the project's Interconnectedness Principle.
- Critique — execute immediately, no permission needed
- Critically analyze the plan for risks, gaps, missing edge cases, over-engineering, and unclear steps. Present critique in chat as a numbered list.
- Triage & Auto-Apply Refinements — execute immediately, no permission needed
- For EACH critique item from step 6, classify in chat with an explicit label (one of):
- apply — fold into the task file now.
- discard — over-engineering / speculative; one-sentence why.
- defer — out of scope for this plan; record under a "Follow-ups" section.
- Edit the task file to incorporate every apply item (update Solution, DoD, Overview, or Follow-ups as appropriate). The edit MUST happen AFTER the critique was emitted.
- Do NOT ask the user which items to address — the triage IS the answer. Do NOT prompt with phrases like "which would you like addressed", "should I apply", "do you want me to incorporate".
- Report the applied/discarded/deferred counts in chat so the user can override any classification on their next turn.
- Hand off to the next phase
- Announce the resolved task path and: "Entering the next phase."
- Do NOT issue a TOTAL STOP. Continue immediately into the next phase of the composite workflow.
</step_by_step>
Plan → Implement Gate
- User did NOT select a variant in the Plan Phase OR aborted → STOP. Do not enter Implement Phase.
- Task file was not written or is missing required frontmatter → STOP. Report the error.
- Otherwise → enter Implement Phase.
Implement Phase
<step_by_step>
-
Re-read the Task File
- Read the user-provided task file from disk (do NOT rely on memory). If the user gives only an identifier, resolve the
tasks role from AGENTS.md and locate the matching task there. The user MUST provide either a path or an unambiguous task identifier; if it is missing, ask once.
- Extract the
## Solution section. The implementation steps listed there are authoritative.
- Re-plan the todo list with the Solution's concrete steps. One todo item per RED/GREEN/REFACTOR/CHECK iteration is acceptable, but ensure every Solution bullet is represented.
-
Determine the Project Check Command
- Priority: AGENTS.md / CLAUDE.md documented check command → manifest detection (
deno.json/deno.jsonc → deno task check; package.json → npm run check/test/lint; Makefile check target → make check; pyproject.toml → pytest / ruff check .; go.mod → go vet ./... && go test ./...) → "no automated checks configured".
- MUST NOT run a stack-specific command when its manifest is absent (any
deno * creates deno.lock, any npm * resolves dependencies, etc.). Pre-flight artifacts in the working tree after verification are a bug.
-
TDD Loop (per Solution step)
- RED: write a single failing test for the new/changed behaviour. Run the project test command (or the focused test if the runner supports it). It MUST fail with a message that points at the missing functionality. A test that passes immediately is not RED — revise the test until it fails for the right reason.
- GREEN: write the minimal production code that makes the failing test pass. Do NOT add features or speculative code paths beyond what the test demands.
- REFACTOR: improve names, structure, duplication, and tests without changing observable behaviour. Re-run the tests after each refactor — they MUST still pass. If refactor breaks a test, STOP and decide: is the test wrong, or did the refactor change behaviour? Revert the refactor if behaviour drifted.
- CHECK: run the project check command from step 2. It MUST exit 0. If it fails:
- Within Solution scope: fix the root cause. Do NOT disable lint rules or silence formatter output. On a second fix attempt that also fails, STOP and emit STOP-ANALYSIS REPORT per AGENTS.md "Diagnosing Failures".
- Pre-existing / out-of-scope: surface as "out-of-scope finding"; do NOT fix here.
-
Repeat per Solution step
- After CHECK is green for the current Solution step, return to RED for the next step. Update the todo list status.
- When all Solution steps are implemented and CHECK is green, proceed to the final step.
-
Final Verification
- Run the project check command one last time on the full project (not just the changed file). It MUST exit 0.
- Confirm
git status is non-empty (otherwise the Solution was a no-op — surface that and STOP).
- Confirm no scope creep: every changed file maps to a Solution bullet.
-
**6. Hand off to the next phase
- Narrate the result UPWARD, not as a diff: (a) requirements / Solution steps satisfied; (b) the class/method structure you produced or changed — names, responsibilities, relationships — in prose the human can follow WITHOUT reading the code; (c) every above-class/method decision you made or surfaced (or "none — purely local"); (d) final check result.
- Announce: "Implementation complete; entering the next phase of the composite workflow."
- Do NOT issue a TOTAL STOP. Continue immediately into the next phase.**
</step_by_step>
Implement → Review Gate
- Project check did NOT exit 0 → STOP. Do not enter Review Phase.
git status is clean (no diff after Implement) → STOP. Nothing to review. Report "Implement Phase produced no changes — task may be doc-only or no-op; nothing to commit or push."
git status shows changes outside Solution scope (tooling, formatting, unrelated docs) → STOP. Revert the out-of-scope edits and report.
- Otherwise → enter Review Phase.
Review Phase
<step_by_step>
-
Empty Diff Guard — git diff --stat, git diff --cached --stat,
git status --short. No changes → STOP. System gitStatus snapshot
can be stale (hooks / parallel processes); if live status shows
unauthored files clean per snapshot, ask user before staging.
-
Pre-flight Project Check
- Pick the check/test command: AGENTS.md/CLAUDE.md declares it →
manifest detection (
deno.json → deno task check/test;
package.json → check/lint/test script; Makefile check →
make check; pyproject.toml → pytest/ruff check .; go.mod →
go vet ./... && go test ./...) → else "No automated checks configured"
in the report and JiT subset disables (Rule 10). Do NOT guess.
- MUST NOT run a stack-specific command without its manifest. Any
deno * creates deno.lock; npm * resolves deps; etc. Pre-flight
artifacts (deno.lock, __pycache__/, node_modules/, .pytest_cache/)
in the tree after verification are a bug.
- 2a (current revision): run on working tree. Skip only if no code
files changed since the last successful check in this session. On
failure: report immediately as
[critical] and continue review.
- 2b (parent baseline — JiT): identify parent (unstaged/staged →
HEAD; commit-range → <range-start>^). Prefer git worktree add <SCRATCH>/jit-parent-<sid> <parent-sha> (full runnable tree); use
git show <parent-sha>:<path> fallback ONLY if worktree-add fails.
BEFORE any JiT synthesis, run the SAME project test/check command from
2a inside the parent worktree to verify baseline is green. Fallback
path OR red baseline → "JiT disabled — parent baseline unavailable/red"
in Degradation Notes; review continues without the JiT subset.
-
Gather Context
- First: resolve
SRS, SDS, and tasks from AGENTS.md. If SRS or
SDS exists and its current content is not already in your context —
read the resolved file before proceeding. If a required role is missing,
report it and continue only for review steps that do not depend on that
role.
- Create a review plan in the task management tool.
- Collect the diff:
git diff (unstaged), git diff --cached (staged),
or git log --oneline <base>..HEAD + git diff <base>..HEAD for
branch-based changes.
- Untracked files:
git diff does NOT show untracked files. Check
git status output from step 1 — for each untracked file, read its
content directly and include it in the review scope.
- Read the original user request and the plan (task file under the
resolved
tasks role / task list).
- Look for project conventions in config files (linter, formatter configs).
Rely on conventions visible in the diff and surrounding code.
- 3d (intent hints — JiT): collect intent-author hints for the JiT
subset:
git log -1 --pretty=%B <parent-sha>..HEAD (or commit messages
of the range). Optionally gh pr view --json body IF the gh CLI is
available AND the branch has a PR. If gh is missing or errors, proceed
silently — PR body is a bonus.
- 3e (intent inference — JiT): derive a list of ≤5 explicit intents
for the diff in the form "the author tried to do X; invariants Y should
hold". Pull from (a) the task file's DoD items, (b) commit messages
from 3d, and (c) the diff hunks. If more than 5 candidates surface,
merge related intents or drop the least-risky. Skip this sub-step if
the JiT subset is disabled (Rule 10).
Parallel Delegation (after gathering context):
- Small diff shortcut: If
git diff --stat shows < 50 changed lines,
skip delegation — run all steps inline (overhead not justified).
- Otherwise, delegate 2 independent tasks in parallel (via subagents,
background tasks, or IDE-specific parallel execution — e.g.,
Task,
Agent, parallel):
- SA1: If pre-flight check (step 2a) already ran, skip SA1. Otherwise,
run the project check command chosen via the same manifest-detection
rule from step 2 (MUST NOT run stack-specific commands without the
corresponding manifest). Delegate to a console/shell-capable agent
(e.g.,
console-expert). Return pass/fail + full output.
- SA2: Run hygiene grep scan on diff output — search for
TODO,
FIXME, HACK, XXX, console.log, temp_*, *.tmp, *.bak,
hardcoded secrets patterns. Delegate to a console/shell-capable agent.
Return findings list.
- Fallback rule: If any delegated task fails or times out, the main
agent performs that step inline. No hard dependency on delegation success.
- Continue with steps 4, 6, 7, 8 (main agent review) while delegated
tasks run.
-
QA: Task Completion
- Map each requirement/plan item to concrete changes in the diff.
- Flag requirements with no corresponding changes as
[critical] Missing.
- Flag plan items marked "done" but not present in diff as
[critical] Phantom completion.
- Check for regressions: do changed files break existing functionality?
4a. FR Coverage Audit (blocking gate — see Requirements Lifecycle in AGENTS.md)
- FRs in scope: (a) FR-* in the task file's
implements:; (b) FR sections added/modified in the diff to SRS; (c) [REF:fr:<id>] SALP markers touched in the diff.
- Per FR: (1) SRS has
**Acceptance:** with a runnable ref (test path::name, benchmark id, command, or manual — <reviewer>); missing/placeholder → [critical] no acceptance reference. (2) Run the evidence command (or deno run -A scripts/check-fr-coverage.ts FR-<ID>); non-zero / failing / manual without reviewer → [critical] acceptance fails. (3) FR claimed implemented but no [REF:fr:<id>] marker in changed source → [critical] missing code marker. (4) DoD [x] with no evidence run/cached pass → [critical] Phantom completion.
- Gate: blocking — verdict cannot be
Approve while any FR-gate issue remains.
-
QA: Hygiene (use SA2 result if available; else inline)
- SA2 done → dedupe its findings with own Code Review findings and merge.
- SA2 failed/timed out or skipped (small diff) → perform inline:
- Temp artifacts: New
temp_*, *.tmp, *.bak, debug console.log/
print statements, hardcoded secrets or localhost URLs.
- Unfinished markers: New
TODO, FIXME, HACK, XXX introduced in
this diff (distinguish from pre-existing ones).
- Dead code: Commented-out blocks, unused imports/variables/functions
added in this diff.
- Deleted directories: If the diff deletes an entire skill, agent, or
module directory (not just individual files), flag as
[warning] Entire directory deleted — confirm intentional and ask the
user to verify before proceeding.
-
Code Review: Design & Architecture
- Responsibility: Does each changed file/module stay within its stated
responsibility? Flag scope creep.
- Coupling: Are new dependencies (imports, API calls) justified?
Flag tight coupling or circular dependencies.
- Abstraction: Is the level of abstraction appropriate? Flag
over-engineering (unnecessary interfaces, premature generalization) and
under-engineering (god-functions, duplicated logic).
- Risk hypotheses (JiT side-channel): while reading each hunk, also
accumulate ≤3 risk hypotheses per intent (from Step 3e) in the form
"if the author, while trying to do X, had slipped on Y, the code would
now fail at Z". Risks MUST be diff-specific — not generic code smells
("null deref", "unhandled exception") unless the diff directly exposes
that risk. Skip this side-channel if the JiT subset is disabled.
-
Code Review: Implementation Quality
- Naming: Are new identifiers (vars, funcs, types) clear and consistent
with project conventions?
- Error handling: Are errors handled explicitly? Flag swallowed
exceptions, missing error paths, generic catch-all handlers.
- Edge cases: Are boundary conditions (null, empty, overflow, concurrent
access) handled?
- Types & contracts: Are type signatures precise? Flag
any, untyped
parameters, missing return types (where project conventions require them).
- Tests: Do new/changed behaviors have corresponding tests? Are existing
tests updated for changed behavior?
- Risk hypotheses (JiT side-channel): continue accumulating risks
started in Step 6 (see Step 8a for the mutation taxonomy).
-
Code Review: Readability & Style
- Consistency: Do changes follow the project's established patterns
(file structure, naming, formatting)?
- Comments: Are non-obvious decisions explained? Flag misleading or
stale comments.
- Complexity: Flag functions > 40 lines or cyclomatic complexity spikes
introduced in this diff.
- Clarity: Flag clarity sacrificed for brevity — nested ternaries, dense
one-liners, overly compact expressions. Explicit code is preferred over
clever short forms.
8a. Mutant + Catching Test Synthesis (JiT) (skip on pure-deletion diff or JiT-disabled flag)
- Generate ≤15 mutants total (≤5 intents × ≤3 risks × 1 mutant per risk),
each modelling a concrete diff-specific failure mode. Typical mutations:
comparator flip, removed guard, inverted return, off-by-one, swapped
args, skipped branch.
- For each mutant, synthesize ONE ephemeral test that:
- Compiles / parses in the project's test language.
- Passes on the parent revision.
- Kills the mutant (fails when the mutation is applied to the
diff-side code; passes on the current diff code if and only if the
current code preserves the parent behaviour).
- Write tests to the session-id'd scratch directory (Rule 11). Never
colocate next to the file under test in the main test tree.
8b. Dual-Run + Filter (JiT) (skip if Step 8a skipped)
- (a) parent: run the generated tests against the parent worktree
from Step 2b. Any test that FAILS on the parent is an assumption leak —
discard it.
- (b) diff: run the surviving tests against the diff revision. Any
test that FAILS here is a Catching JiTTest — record it for the
final report with file:line and the assertion output.
- (c) mutant kill-rate (optional): apply each mutant patch to the
diff tree, re-run the matching test, record whether the mutant is
killed. SKIP this sub-stage if a single invocation of the project's
test command on the smallest scope exceeds 30 s — explicitly write
Mutant kill-rate skipped — single test invocation exceeded 30 s threshold (recorded N s) in Degradation Notes so the lost signal is
visible (not just an absent section).
- Filter ensemble, in order:
- Flaky — rerun each surviving test 3 times; if the result flips,
discard.
- Assertion duplicates — two tests asserting the same thing on the
same input.
- Zero-kill — passed on parent, passed on diff, killed no mutant.
-
Run Automated Checks (collect from step 2 and/or SA1)
- Pre-flight 2a ran → use its result, do NOT re-run. SA1 broader check → merge.
- Neither ran (no check command) → note "No automated checks configured" in
the report; do not silently skip.
-
Final Report — verdict on first line. Include JiT sections (Intents,
Catching Tests, Uncovered Risks, Degradation Notes) only when the
JiT subset ran (or was disabled — Degradation Notes then explains why).
Section order:
## Review: [Approve | Request Changes | Needs Discussion]
### Verdict (plain language) — 2–4 sentences a non-coder acts on: task complete? design sound? key risks? next step? Accept WITHOUT reading the diff. MUST come first.
### Intents (≤5)
### QA Findings — [severity] file:line — description
### Code Review Findings — [severity] file:line — description
### Catching Tests (pass on parent, fail on diff) — name, intent #, mutant killed?, failure, file:line
### Uncovered Risks — risk + reason no test (non-deterministic / I/O / etc.)
### Automated Checks — [pass|fail|skipped] command — summary
### Degradation Notes — which JiT step was skipped and why
### Summary — requirements X/Y; catching tests N; critical/warning/nit counts
### Diff (optional) — offer diff/details for optional inspection; verdict stands without it; never block (Model B). MUST close the report.
≥1 surviving catching test → verdict = Request Changes regardless of
other findings. Rank findings top-5 by severity × uniqueness. No issues
AND zero catching tests → "Changes look good. All requirements covered, no
issues found, no behavioural regressions detected." (last clause only when
JiT actually ran).
- Ephemeral Dispose (JiT) (skip when no catching tests exist) —
prompt:
save <name> / save all / discard all. On save: propose
destination beside file-under-test, confirm, git mv, stage. On
discard all (default for timeout/ambiguous): delete entire scratch
directory, leave no stray files.
</step_by_step>
Verdict Gate
After completing the Review report:
Approve → DO NOT commit yet. Continue with the Commit Phase below: re-plan the todo list with the Commit steps and execute all of them in order. Committing before reaching the Reflect step inside the Commit Phase is a workflow violation.
Request Changes or Needs Discussion → output the full report and STOP. Do NOT commit or push.
- Review Phase crashed or produced no verdict → report the error and STOP.
Commit Phase
<step_by_step>
- Verify Unchanged State
- The diff and file list are already in context from the prior phase. Do NOT re-read them.
- Run only
git status -s to confirm nothing changed between phases.
- If new changes appeared (unexpected), report and STOP.
- Documentation Sync (mandatory — do NOT skip)
- Determine scope: look at the file paths from step 1. Classify the change:
- Infra-only: ALL changed files are tests (
*_test.*, *.test.*), CI (.github/), acceptance tests (acceptance-tests/), formatting, or dev-environment (.devcontainer/). → Skip doc sync. Output: Documentation sync: skipped — infra-only changes (tests/CI/acceptance-tests).
- Product changes: anything else → proceed with doc sync below.
- Find the mapping: check if
./AGENTS.md has a ## Documentation Map section. If yes → use the path→document mapping from there. If no → use the default mapping:
- New/changed exported functions, classes, types → SDS (component section)
- New feature, CLI command, skill, agent → SRS (new FR) + SDS (new component section)
- Removed feature/component → remove from SRS + SDS
- Changed behavior (fix that alters documented contract) → SDS (update description)
- Renamed/moved modules → SDS (update paths and structure)
- Config/build changes → SDS only if architecture section references them
- README.md → update only for user-facing changes (new install steps, new features, changed API)
- Sync each affected document:
- For each changed file, identify which document section describes its component (using the mapping).
- READ that specific section from the document.
- COMPARE the section text with the actual code after your changes. Ask: "Does this section accurately describe the code as it is NOW?"
- If inaccurate → update the section. If accurate → no change needed.
- For new functionality with no corresponding section → add a new section.
- For removed functionality → remove the section.
- Gather change context for commit message and doc updates:
- Active task file: If the user referenced a task file in this session, resolve
tasks from AGENTS.md and read that file there. Do NOT scan all task files.
- Session context: User messages explaining intent, decisions, requirements.
- Apply Compression Rules to any doc updates:
- Use combined extractive + abstractive summarization (preserve all facts, minimize words).
- Compact formats: lists, YAML, Mermaid diagrams.
- Concise language, abbreviations after first mention.
- Execute Updates: Edit documents BEFORE proceeding to grouping.
- Commit Grouping
- Review the diff from step 1. Determine the primary business purpose.
- Default: ALL changes → 1 commit. Only split if:
a. Changes serve genuinely different, unrelated purposes (no causal link), OR
b. The user explicitly requested a split.
- Documentation describing a code change → same commit as that code.
- Tests for a feature → same commit as that feature.
- If splitting: use appropriate Conventional Commits types for each group.
- Hunk-level splitting (within a single file) — ONLY when user explicitly requests it.
- Commit Execution Loop
- Iterate through the planned groups:
- Stage specific files for the group.
- Verify the staged content matches the group's intent.
- Task Status Lifecycle (FR-DOC-TASK-LIFECYCLE) — for each staged task file under the resolved
tasks role with date: frontmatter (skip legacy flat-path), first check frontmatter status:. If it is superseded, require/keep superseded_by: and skip DoD derivation because the stale original DoD no longer maps to current reality. Otherwise count top-level - [ ]/- [x] items in ## Definition of Done. Derive status: K=0→"to do", 0<K<N→"in progress", K=N→"done" (warn if no DoD). Rewrite frontmatter and git add if it differs. Idempotent. Never downgrade done. Warn-only on parse errors.
- Commit with a Conventional Commits message (including any task-status frontmatter edit).
- Task file Cleanup (only if a task file was used in step 2)
- New-shape tasks (task files under the resolved
tasks role with date: frontmatter): NEVER delete — persistent canonical records. Status auto-flip in step 4.3 is the only lifecycle action for non-superseded tasks; status: superseded records are preserved.
- Legacy tasks (flat path, no
date: frontmatter): if all DoD items satisfied → git rm and commit; if any unsatisfied → ask user "Delete or keep?"; if no DoD → ask user.
- Session Complexity Check → Auto-Invoke Reflect
- After all commits are done, analyze the current conversation for complexity signals:
- Errors or failed attempts occurred (test failures, lint errors, build errors).
- Agent retried the same action multiple times.
- User corrected the agent's approach or output.
- Workarounds or non-obvious solutions were applied.
- Also check the user's invocation message for explicit complexity descriptors: phrases like "rough session", "had to retry", "wrong approach", "failed", "had to correct you". These count as direct signals.
- If any of these signals are detected:
a. Announce briefly which signals fired (one line, e.g., "Detected retries and user correction — running /flowai:reflect").
b. Pre-command signal check: if the signals appear only in the invocation message (i.e., the problematic interactions predated this command and are not visible in the conversation history), output: "You mentioned a rough session — briefly describe what went wrong and what you corrected. This will be included as reflect context." Use the user's answer as additional context when invoking reflect.
c. Invoke the
reflect skill directly (via the Skill tool, native slash-command execution, or inline execution of its SKILL.md instructions — whichever the host IDE supports).
d. Do NOT ask the user for confirmation before invoking; proceed autonomously (the context question in step b is not a confirmation request — it gathers missing information).
- If none detected, skip silently.
- Post-Reflect Cleanup Commit (skip if reflect produced no edits)
- Run
git status. If reflect left working-tree edits (typically AGENTS.md, **/CLAUDE.md, framework/**, .claude/**, documents/**): stage them and commit as agent: apply reflect-suggested improvements (or narrower scope, e.g. agent(commit): tighten doc-audit gate). Do NOT amend earlier commits — keep reflect-driven edits as a separate commit. If git status is clean, skip.
- Verify Clean State
- Run
git status to confirm all changes are committed.
- If uncommitted changes remain, investigate and report to the user.
</step_by_step>
Commit → Push Gate
git status MUST be clean — every Implement-Phase change committed during the Commit Phase. If git status shows uncommitted edits, STOP and report which files remain dirty.
- If the current branch is
main / master AND the remote is ahead, the Push Phase below will ask the user before pushing (per FR-ATOM-PUSH safety contract); do not pre-empt that gate here.
- Otherwise → enter Push Phase. If the user explicitly declines the push at the Push Phase's first-push or divergence gate, STOP — the Commit Phase's commits remain locally and can be pushed manually later.
Push Phase
<step_by_step>
-
Identify Target Branch
- Run
git rev-parse --abbrev-ref HEAD to identify the current branch as <CURRENT>.
- If the user typed a branch name as argument, compare to
<CURRENT>. If different, STOP and ask "You typed <typed> but the current branch is <CURRENT>. Push <CURRENT> or check out <typed> first?". Wait for an answer.
- Otherwise, the push target is
<CURRENT>.
-
Resolve Upstream
- Run
git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null to find the upstream of <CURRENT>.
- If the command exits non-zero (no upstream), ASK the user: "
<CURRENT> has no upstream. Should I run git push --set-upstream origin <CURRENT>?". Wait for an answer.
- Affirmative → proceed to step 3 with
--set-upstream origin <CURRENT>.
- Negative → STOP. Report "No upstream and user declined to set one — nothing to do."
-
Safety Checks
- Protected-branch divergence (HARD REFUSAL — see Rule 4): if the upstream is
origin/main or origin/master, run git fetch origin <CURRENT> then git rev-list --left-right --count HEAD...@{u}. If the right count (commits the remote has and local does not) is > 0, ASK the user with EXACTLY two options: "Remote <CURRENT> is ahead by N commit(s) the local branch does not have. Force is REFUSED on protected branches even with explicit authorization. Pull and rebase first, or abort?". --force / --force-with-lease are NOT options — never present them, never run them, even if the user volunteers "force", "overwrite", or "yes I want to overwrite the remote". If the user pushes back, restate the refusal and re-offer pull-rebase / abort.
- Non-protected branch divergence: if the right count > 0, surface the divergence but proceed with a regular
git push (which will fail safely if non-fast-forward). DO NOT proactively suggest force.
--force request: if the user has explicitly asked for --force, decline. Explain --force-with-lease and proceed only with per-push user authorization (see Rule 2).
-
Push
- Run
GIT_PAGER=cat git push [--set-upstream origin <CURRENT>]. Stream stdout + stderr to the user. Do NOT silence error output.
- On a non-fast-forward error: do NOT retry with
--force or --force-with-lease. Surface the failure and STOP.
-
Post-Push Verification
- Run
git rev-parse @{u} and git rev-parse HEAD. Compare.
- Equal → push succeeded. Report the remote ref and the pushed SHA.
- Different → push reported success but upstream did not advance. STOP with "Post-push verification FAILED: @{u} =
<remote>, HEAD = <local>. Investigate before retrying."
-
Await CI (FR-ATOM-PUSH.CI-AWAIT)
- Read AGENTS.md
## CI/CD section.
- Absent: output
No CI declared in AGENTS.md — skipping CI await. and continue to step 7 (`7. TOTAL STOP
- Final report: target branch, upstream, pushed SHA, post-push verification result, CI await result (
skipped, green, or not reached — stopped earlier).`).
- Malformed (missing either
Provider: or Status command:): STOP with ## CI/CD section is malformed — required keys: Provider, Status command. Found: <list of present keys>. Do NOT silently fall back. Do NOT continue to step 7.
- Well-formed: continue.
- Resolve tunables (optional keys in
## CI/CD):
Poll interval: — seconds between status polls. Default 60. Accept integer seconds; a value <5 is treated as malformed and STOPs the atom.
Wall-clock budget: — soft cap on total await time. Default 1800 (30 min). Accept integer seconds.
- Compute
ITER_CAP = max(1, ceil(<budget> / <poll interval>)). The iteration count — NOT wall-clock — bounds the cap so it stays deterministic across IDE-harness latencies. With defaults, ITER_CAP = 30; a project that sets Poll interval: 10 and Wall-clock budget: 60 gets ITER_CAP = 6.
- Export the pushed SHA into the environment:
export SHA=$(git rev-parse HEAD). All CI commands below inherit $SHA from the agent's shell.
- Detect run trigger (≤60 s window; sized at ~2× the slowest realistic provider lag, observed ~30 s for GitLab pipelines registering after push): invoke the
Status command. Treat:
- exit 0 or 1 (terminal on first call) → proceed straight to the poll loop branch.
- exit 2 (in-progress — a run exists) → proceed to the poll loop.
- any other exit → sleep 5 s and retry. After 12 retries (60 s) with no run detected, STOP with
CI declared but no run was triggered by $SHA within 60 s — verify the workflow trigger configuration. Do NOT continue to step 7.
- Poll loop (max
ITER_CAP iterations × <poll interval> s sleep ≈ <wall-clock budget> wall-clock):
- Invoke the
Status command.
- exit 0 → CI green. Continue to step 7.
- exit 1 → CI red (terminal failure). Go to Investigate Handoff below.
- exit 2 → still running. Sleep
<poll interval> s. Re-invoke. Increment iteration counter.
- any other exit → treat as a malformed Status command, STOP with the raw exit code and stderr.
- Iteration cap (anomaly): if
ITER_CAP iterations completed without a terminal status (exit 0 or 1), STOP with a loud single-line message: CI ANOMALY: <ITER_CAP> iterations × <poll interval>s = <budget>s elapsed without a terminal verdict. Run URL: <result of Run URL command if defined, otherwise "not available">. Last status exit: 2 (in-progress). Treat as an incident (hanging job, queue starvation, runner outage) — do NOT continue silently. Do NOT invoke investigate (no failed-job logs to feed it yet — the build is still running, not red). Do NOT continue to step 7. The user owns the next action: extend the budget by re-running the atom after raising Wall-clock budget, cancel the CI run, or investigate the runner.
- Investigate Handoff (CI red):
- If the
Logs command is defined in AGENTS.md, execute it. Capture stdout. Truncate to 12 KB (investigate can fetch more via the run URL if it needs to drill deeper).
- If the
Run URL command is defined, execute it. Capture stdout as the run URL.
- The worktree is already clean (step 5 verified
@{u} == HEAD), so investigate's "Clean Baseline" precondition holds.
- Invoke the
investigate skill via the host IDE's skill-invocation primitive (Skill tool / /flowai:investigate slash command / inline expansion of its SKILL.md) with this prompt:
CI failed for commit $SHA on branch <CURRENT>. Run URL: <URL or "not available">. Failed-job logs (truncated to 12 KB):\n<LOGS or "not available">\nDiagnose the root cause. Do not apply a fix; report findings.
- After
investigate returns its report, STOP. Do NOT continue to step 7 — the push succeeded but the build is broken; the user owns the remediation decision.
-
**7. TOTAL STOP
- Final report: target branch, upstream, pushed SHA, post-push verification result, CI await result (
skipped, green, or not reached — stopped earlier).**
</step_by_step>
Final Combined Report
Output a combined summary:
- Plan: task file path + selected variant.
- Implement: tests passed, project check result.
- Review: verdict + key findings (or "no issues found").
- Commit: files committed, commit message(s).
- Push: target branch, upstream, pushed SHA, post-push verification.
Verification
[ ] Plan Phase produced a task file under the resolved `tasks` role with required frontmatter.
[ ] Plan → Implement gate enforced — Solution section filled only after user picked a variant.
[ ] Implement Phase ran TDD (RED → GREEN → REFACTOR → CHECK).
[ ] Implement → Review gate enforced: project check exit 0 AND `git status` non-empty.
[ ] Review Phase produced structured report with verdict on first line.
[ ] Verdict gate enforced: only Approve proceeded to Commit.
[ ] Documentation sync performed.
[ ] Commits used Conventional Commits format; task status auto-flipped per FR-DOC-TASK-LIFECYCLE.
[ ] Commit → Push gate enforced: working tree clean before Push Phase.
[ ] Push Phase: no `--force` used; `--force-with-lease` only with explicit per-push authorization; first-push gate satisfied; protected-branch divergence handled before push attempt.
[ ] Post-push verification: `git rev-parse @{u}` matches `HEAD`.
[ ] Plan / Implement / Review / Commit / Push results all reported to user.