mirror of
https://github.com/ulpi-io/skills.git
synced 2026-09-19 03:35:17 +08:00
ship-playbook: dialable review gates to cut token cost (reorder intake, skippable reviews, per-merge worktree removal)
The skill ran every gate every time and burned tokens. Each expensive gate is now independently
dialable from full-rigor down to skip; defaults are lighter (but the user can still go full swing).
1. Reorder intake to execution order (7 questions, two AskUserQuestion calls): second harness → plan
review → build handoff → per-task review → impl review → go-live audit → map refresh.
2. Per-task review skippable — taskReview ∈ skip|native|harness. 'skip' removes the per-task reviewer
AND the fix loop (biggest save); task passes on engineer validate.
3. Final impl review skippable — implReview ∈ skip|claude|claude+harness.
4. Plan/founder review — planReview ∈ skip|claude|claude+harness.
+ harness is now ONE global external review harness (none|codex|kiro) used by any claude+harness gate
or taskReview=harness; buildHarness (who writes) stays a separate axis.
+ MUSTs preserved: full-swing config (everything + harness + goLive) and delegating build AND
per-task review to codex/kiro both supported.
+ Guardrail: warn (not block) when taskReview AND implReview are both skipped — nothing checks the
build; return surfaces noReviewGate + reviewConfig and Phase 3 caveats the verdict.
5. Worktrees: integrate now removes each merged worktree IMMEDIATELY (per-merge, not batch); preflight
and final dangling-sweep kept.
Reconciled across SKILL.md (intake, rules 2/3/5/6, Phase 2 steps, Phase 3, success criteria, output
contract, description), workflow-template.js (config, gating, handoff routing, return), harness-routing.md,
playbook-state.md, build-loop.md. Removed MAX_ROUNDS/maxRounds remnants. JS syntax verified.
This commit is contained in:
+103
-77
@@ -6,11 +6,12 @@ description: |
|
||||
plan, build it task by task, review the build, and optionally audit it for launch — then return the
|
||||
verified findings as feedback (one pass, no autonomous loop; the user decides on any fix round). It
|
||||
chains the existing skills as one runnable Workflow:
|
||||
plan-to-task-list-with-dag (plan + assign a specialist agent per task) → plan-founder-review (loop
|
||||
to APPROVE) → a specialist engineer/reviewer build across the DAG → a full claude ∥ codex/kiro
|
||||
cross-review → go-live-audit. Up front it asks two things — which harness cross-reviews
|
||||
(claude / codex / kiro / none) and whether to run a go-live audit at the end — then executes every
|
||||
step end to end. Use when the user wants "prompt → planned, built, reviewed, audited" in one go
|
||||
plan-to-task-list-with-dag (plan + assign a specialist agent per task) → plan-founder-review →
|
||||
a specialist engineer/reviewer build across the DAG → a full claude ∥ codex/kiro cross-review →
|
||||
go-live-audit. Up front it asks which gates to run and at what depth — every review is independently
|
||||
dialable from full rigor (claude + a second harness everywhere, build/review delegated to codex/kiro)
|
||||
down to skip, so the user controls token cost. Use when the user wants "prompt → planned, built,
|
||||
reviewed, audited" in one go
|
||||
instead of running each phase by hand.
|
||||
allowed-tools:
|
||||
- Skill
|
||||
@@ -47,24 +48,28 @@ This skill drives a long-running, multi-agent delivery Workflow. Non-negotiable
|
||||
skill (Phase 3) presents them and the USER decides whether to run a fix round. The Workflow executes
|
||||
steps 3–14 as real phases; the skill performs steps 1, 2, 2.1 (the prompt + the intake questions)
|
||||
and feeds them in as `args`.
|
||||
2. ALWAYS ask the intake questions first (plan-review harness + go-live audit, plus the optional
|
||||
end-of-run project-map refresh). The first two are Workflow inputs, not steps it can skip; the map
|
||||
refresh is a Phase-3 action the skill runs after the Workflow returns.
|
||||
2. ALWAYS ask the intake questions first (the seven: second harness, plan review, build handoff,
|
||||
per-task review, impl review, go-live audit, project-map refresh). These select which gates run and
|
||||
at what depth; they are Workflow inputs (except the map refresh, a Phase-3 action). Honor the
|
||||
choices — the user may dial to full rigor or skip gates to save tokens.
|
||||
3. The BUILD is a Workflow phase, not a description. Per task across the DAG layers: the ENGINEER
|
||||
implements on a task branch in an isolated worktree, an in-workflow INTEGRATE agent git-merges it
|
||||
onto the working branch, the REVIEWER reviews the integrated state, and a bounded fix loop runs
|
||||
until the task passes. Engineer and reviewer default to the plan's matched specialist agents; when
|
||||
the user chose a build/review handoff they route to `codex` or `kiro` instead (`buildHarness` /
|
||||
`taskReviewHarness`).
|
||||
onto the working branch AND removes each merged worktree, the REVIEWER reviews the integrated state
|
||||
(unless `taskReview skip`), and a bounded fix loop runs until the task passes. Engineer routes per
|
||||
`buildHarness` (native specialist / `codex` / `kiro`); reviewer routes per `taskReview` (native
|
||||
`-reviewer` / the second harness / none).
|
||||
4. The build picks the closest AVAILABLE specialist per task; it falls back to `general-purpose` ONLY
|
||||
with the user's consent after the skill notified them a specialist is missing — never silently. When
|
||||
a task's stack skill is installed, the engineer MUST use it (`/nextjs`, `/laravel`, `/rust`, …).
|
||||
(This applies to the native path; when the user handed building/reviewing to `codex` or `kiro`,
|
||||
those tasks route there instead.)
|
||||
5. Gates are real. The founder-review loops review → FIX → re-review until APPROVE / no issues; the
|
||||
build loops engineer → reviewer → fix until the task passes. Never wave a gate through.
|
||||
6. Codex delegation goes through the codex plugin (`codex:codex-rescue` agentType). Kiro via the
|
||||
kiro path. "claude" = native. "none" = skip the external cross-review. (See `harness-routing.md`.)
|
||||
5. Gates that ARE enabled are real — never wave one through or fake a clean verdict to exit. But the
|
||||
user controls WHICH gates run: a skipped gate (`planReview skip`, `taskReview skip`, `implReview
|
||||
skip`, `goLive no`) is a deliberate choice, not a gate to sneak back in. Warn (don't block) when
|
||||
both per-task and impl review are off — nothing checks the build then.
|
||||
6. The `harness` is ONE global external review harness: `none` (claude/native only), `codex` (the
|
||||
`codex:codex-rescue` plugin), or `kiro` (the kiro path). It is the second opinion any `claude+harness`
|
||||
gate or `taskReview harness` uses. `buildHarness` (who writes) is a separate axis. (See `harness-routing.md`.)
|
||||
7. There is no autonomous recursion. After one pass, surface the verified findings honestly and let
|
||||
the user choose to run a fix round (re-invoke with the findings as the prompt) — NEVER fake a clean
|
||||
verdict, and never silently loop.
|
||||
@@ -89,32 +94,45 @@ plan-vs-implementation gate), and an optional go-live audit — then it RETURNS
|
||||
feedback. It runs ONE pass and does not loop on its own; if findings remain, the user decides whether
|
||||
to run a fix round.
|
||||
|
||||
The 14 steps map to the Workflow phases: **step 3 → Plan · steps 4–9 → Plan review (native ∥ selected
|
||||
harness, one bounded loop) · steps 10–11 → Build · step 12 → Impl review (plan-vs-implementation) ·
|
||||
step 14 → Verify (dedup + adversarial verify → feedback) · step 13 → Audit (only if build+impl
|
||||
verified-clean)**. Steps 1, 2, 2.1 are the prompt and the questions the skill collects up front. There
|
||||
is no automatic recursion — the workflow returns its findings and stops.
|
||||
The 14 steps map to the Workflow phases: **step 3 → Plan · steps 4–9 → Plan review (optional, bounded
|
||||
loop) · steps 10–11 → Build (per-task review optional) · step 12 → Impl review (optional,
|
||||
plan-vs-implementation) · step 14 → Verify (dedup + adversarial verify → feedback) · step 13 → Audit
|
||||
(only if `goLive` AND build+impl verified-clean)**. Steps 1, 2, 2.1 are the prompt and the questions
|
||||
the skill collects up front. Each review gate runs at the depth the user chose (skip / claude /
|
||||
claude+harness); there is no automatic recursion — the workflow returns its findings and stops.
|
||||
|
||||
## Phase 1 — Intake (steps 1, 2, 2.1)
|
||||
|
||||
The prompt is `$request` (step 1). Ask the governing questions up front (in one or two
|
||||
`AskUserQuestion` calls — the tool allows up to 4 questions each), unless `$request` already pins them:
|
||||
The prompt is `$request` (step 1). Ask the governing questions up front (in two `AskUserQuestion` calls
|
||||
— the tool allows up to 4 each), in execution order so they make sense, unless `$request` already pins
|
||||
them. Each review gate is independently dialable so the user controls token cost — defaults are LIGHT;
|
||||
the user can dial every gate UP to full rigor, or DOWN to skip. The questions:
|
||||
|
||||
1. **Plan/impl cross-review harness** (step 2) — which second harness cross-reviews the PLAN and the
|
||||
full implementation: `claude`, `codex`, `kiro`, or `none`. (This is the review cross-check; it is
|
||||
separate from who builds/reviews each task below.)
|
||||
2. **Go-live audit at the end** (step 2.1) — `yes` adds the go-live audit after the build, `no` stops
|
||||
at the implementation review.
|
||||
3. **Refresh the project map at the end** — whether to regenerate the `CLAUDE.md` context map after
|
||||
the build lands so it reflects the new code: `map-project` (single project),
|
||||
`map-project-monorepo` (workspace), or `no`. Detect the repo layout and offer the matching default
|
||||
(a workspace/monorepo → `map-project-monorepo`, otherwise `map-project`). Run only in Phase 3 on a
|
||||
real, non-aborted run.
|
||||
4. **Build handoff** — who WRITES the code for each task: `native` (the plan's specialist engineer
|
||||
agents — default), `codex` (the codex plugin), or `kiro` (the Kiro CLI). Passed as `buildHarness`.
|
||||
5. **Per-task review handoff** — who REVIEWS each task: `native` (the matched `-reviewer` agent —
|
||||
default), `codex`, or `kiro`. Passed as `taskReviewHarness`. Independent of #1 (which is the
|
||||
one-shot plan/impl cross-review) — this is the per-task reviewer in the build loop.
|
||||
1. **Second harness** — the ONE external review harness used wherever a gate below is set to
|
||||
"claude + harness": `none` (default), `codex`, or `kiro`. (claude/native always runs its own side;
|
||||
this is the optional second opinion.) Passed as `harness`.
|
||||
2. **Plan (founder) review** — `skip`, `claude` (native founder review only — default), or
|
||||
`claude + harness` (native ∥ the second harness). Passed as `planReview`.
|
||||
3. **Build handoff** — who WRITES the code for each task: `native` (the plan's specialist engineer
|
||||
agents — default), `codex`, or `kiro`. Passed as `buildHarness`.
|
||||
4. **Per-task review** — who REVIEWS each built task: `skip` (no per-task reviewer or fix loop —
|
||||
biggest token save), `native` (the matched `-reviewer` agent — default), or `harness` (the second
|
||||
harness). Passed as `taskReview`.
|
||||
5. **Final implementation review** — the plan-vs-implementation review after the build: `skip`,
|
||||
`claude` (native — default), or `claude + harness`. Passed as `implReview`.
|
||||
6. **Go-live audit at the end** — `no` (default) adds nothing; `yes` runs the go-live audit (only if
|
||||
build+impl come back verified-clean). Passed as `goLive`.
|
||||
7. **Refresh the project map at the end** — regenerate the `CLAUDE.md` context map after the build:
|
||||
`no` (default), `map-project` (single project), or `map-project-monorepo` (workspace). Detect the
|
||||
repo layout and offer the matching default. Run only in Phase 3 on a real, non-aborted run.
|
||||
|
||||
**Defaults** (lighter than full, kept safe): `harness none`, `planReview claude`, `buildHarness native`,
|
||||
`taskReview native`, `implReview claude`, `goLive no`, map `no`. The user can choose **full swing** —
|
||||
`planReview claude+harness`, `taskReview harness`, `implReview claude+harness`, `buildHarness codex|kiro`,
|
||||
`goLive yes`, with `harness codex|kiro` — or delegate building and per-task review to codex/kiro
|
||||
(`buildHarness` + `taskReview harness`). **Warn (do not block)** if the user sets BOTH `taskReview skip`
|
||||
AND `implReview skip`: nothing then checks the build, so a clean verdict only means the engineer
|
||||
validates passed — say so before launching.
|
||||
|
||||
Then gather the project facts the Workflow needs (do not ask the user — read the repo): `root`
|
||||
(absolute repo path), `workingBranch` (the current branch to build on — never build on a protected
|
||||
@@ -147,21 +165,23 @@ that wasn't installed):
|
||||
|
||||
Never silently substitute `general-purpose` for a missing specialist without telling the user first.
|
||||
|
||||
**Verify the chosen build/review handoff harness is installed, and notify if not.** If `buildHarness`
|
||||
or `taskReviewHarness` is not `native`, confirm its tooling exists before launching:
|
||||
- **kiro build** needs the `hand-over-to-kiro` skill (by Sabeur Thabti, @thabti) **and** `kiro-cli`
|
||||
(`kiro-cli --version`); **kiro review** needs the `kiro-review` skill **and** `kiro-cli`.
|
||||
- **codex** (build or review) needs the codex plugin (`codex:codex-rescue`).
|
||||
**Verify any chosen harness tooling is installed, and notify if not.** Whenever `harness` is `codex`
|
||||
or `kiro`, or `buildHarness` is `codex`/`kiro`, confirm its tooling exists before launching:
|
||||
- **codex** (the `harness` second opinion, or `buildHarness codex`) needs the codex plugin (`codex:codex-rescue`).
|
||||
- **kiro build** (`buildHarness kiro`) needs the `hand-over-to-kiro` skill (by Sabeur Thabti, @thabti)
|
||||
**and** `kiro-cli` (`kiro-cli --version`); **kiro as the `harness`** (used by any `claude+harness`
|
||||
gate or `taskReview harness`) needs the `kiro-review` skill **and** `kiro-cli`.
|
||||
|
||||
If a chosen handoff's tool is missing, NOTIFY the user with `AskUserQuestion` — offer to **install it**
|
||||
If a chosen harness's tool is missing, NOTIFY the user with `AskUserQuestion` — offer to **install it**
|
||||
(for kiro: `hand-over-to-kiro` via `npx skills add …` + kiro-cli from <https://kiro.dev/docs/cli>) or
|
||||
**switch that handoff to `native`** (or another available harness). Do not silently fall back.
|
||||
**fall back** (drop the `+harness` to `claude`, set `harness none`, or `buildHarness native`). Do not
|
||||
silently degrade.
|
||||
|
||||
Open a master `TodoWrite` mirroring the phases in `references/playbook-state.md`.
|
||||
|
||||
**Success criteria**: `harness`, `goLive`, `mapRefresh`, `buildHarness`, `taskReviewHarness`, `root`
|
||||
(a confirmed git work tree), `workingBranch`, `validate`, `hardRules`, and `availableAgents`
|
||||
(+ `allowGeneralFallback` if any specialist is missing) are all resolved.
|
||||
**Success criteria**: `harness`, `planReview`, `buildHarness`, `taskReview`, `implReview`, `goLive`,
|
||||
`mapRefresh`, `root` (a confirmed git work tree), `workingBranch`, `validate`, `hardRules`, and
|
||||
`availableAgents` (+ `allowGeneralFallback` if any specialist is missing) are all resolved.
|
||||
|
||||
## Phase 2 — Run the playbook Workflow (steps 3–14)
|
||||
|
||||
@@ -174,9 +194,9 @@ Then launch `references/workflow-template.js` via the **Workflow** tool, passing
|
||||
|
||||
```
|
||||
Workflow({ scriptPath: ".../references/workflow-template.js",
|
||||
args: { prompt, harness, goLive, root, workingBranch, validate, hardRules,
|
||||
auditScriptPath, availableAgents, allowGeneralFallback,
|
||||
buildHarness, taskReviewHarness } })
|
||||
args: { prompt, root, workingBranch, validate, hardRules, goLive,
|
||||
harness, planReview, buildHarness, taskReview, implReview,
|
||||
auditScriptPath, availableAgents, allowGeneralFallback } })
|
||||
```
|
||||
|
||||
**Pass `args` as a real JSON object, NOT a JSON-encoded string.** A stringified blob reaches the
|
||||
@@ -185,26 +205,28 @@ script as one string, fails its `typeof args === 'object'` check, and every inpu
|
||||
`claude|codex|kiro|none`) instead of returning a fake `converged:true`, so a stringified-args launch
|
||||
errors loudly — if you hit it, relaunch as a FRESH run (no resume) with `args` as an object.
|
||||
|
||||
The Workflow then executes the rest of the playbook, in order, as real phases — there is no step it
|
||||
skips:
|
||||
The Workflow then executes the playbook in one pass, running each gate at the level the user chose:
|
||||
|
||||
- **Plan (step 3)** — a planning agent follows the plan-to-task-list-with-dag methodology unattended
|
||||
(mode auto-selected), grounds every path in the real repo, assigns a specialist engineer +
|
||||
`-reviewer` + stack skill to each task, writes `.ulpi/plans/<name>.md`+`.json`, returns `{tasks, layers}`.
|
||||
- **Plan review (steps 4–9)** — ONE bounded loop: native founder review (∥ the selected harness when
|
||||
`harness != none`) → fix the plan (JSON-first, re-render MD) → re-review. Exits as soon as no
|
||||
BLOCK/CONCERN remain (OBSERVATIONs never block) OR a fix round stops reducing the blocking count —
|
||||
- **Plan review (steps 4–9)** — per `planReview`: `skip` (no review), `claude` (native founder review),
|
||||
or `claude+harness` (native ∥ the second harness). ONE bounded loop → fix the plan (JSON-first,
|
||||
re-render MD) → re-review; exits on no BLOCK/CONCERN (OBSERVATIONs never block) OR non-convergence,
|
||||
capped at `MAX_REVIEW` (2).
|
||||
- **Build (steps 10–11)** — walk the DAG layers; per task: engineer (worktree, task branch) →
|
||||
in-workflow integrate agent (`git merge` onto the working branch) → reviewer → bounded fix loop
|
||||
until it passes; barrier between layers. Engineer/reviewer = the native specialist by default, or
|
||||
`codex`/`kiro` per the `buildHarness`/`taskReviewHarness` handoff.
|
||||
- **Impl review (step 12)** — full implementation review (plan vs implementation), native ∥ selected harness.
|
||||
in-workflow integrate agent (`git merge` onto the working branch, then removes each merged worktree)
|
||||
→ reviewer (unless `taskReview skip`) → bounded fix loop until it passes; barrier between layers.
|
||||
Engineer = native specialist / `codex` / `kiro` per `buildHarness`; reviewer = native `-reviewer` or
|
||||
the second harness per `taskReview` (or none if `skip`).
|
||||
- **Impl review (step 12)** — per `implReview`: `skip`, `claude`, or `claude+harness`. The
|
||||
plan-vs-implementation review of everything built.
|
||||
- **Verify (step 14)** — dedup + adversarially verify the build+impl findings. These become the
|
||||
returned `openRegister` — the feedback. No automatic re-plan/re-build; the workflow returns and stops.
|
||||
- **Audit (step 13)** — runs only when build+impl are verified-clean: if `goLive`, COMPOSE the proven
|
||||
`go-live-audit` workflow inline via the `workflow()` hook (`auditScriptPath`) — gates → finders →
|
||||
dedup → dual-lens verify → critic — ∥ a selected-harness audit lane; its findings become `openRegister`.
|
||||
- **Audit (step 13)** — runs only when `goLive` AND build+impl come back verified-clean: COMPOSE the
|
||||
proven `go-live-audit` workflow inline via the `workflow()` hook (`auditScriptPath`) — gates →
|
||||
finders → dedup → dual-lens verify → critic — ∥ a second-harness audit lane; its findings become
|
||||
`openRegister`.
|
||||
|
||||
Watch progress via `/workflows`. To iterate on the script, edit the saved `scriptPath` the tool
|
||||
returns and re-invoke with `{scriptPath}` (and `resumeFromRunId` to reuse cached agent results).
|
||||
@@ -213,7 +235,7 @@ the script re-executes from the top, so omitting `args` empties `CFG` and the sc
|
||||
`FILL:` guard. Always include the full `args` object you launched with.
|
||||
|
||||
**Success criteria**: The Workflow runs to completion and returns
|
||||
`{ converged, ranReal, plan, build, openRegister, missingAgents }`.
|
||||
`{ converged, ranReal, plan, build, openRegister, missingAgents, reviewConfig, noReviewGate }`.
|
||||
|
||||
## Phase 3 — Report and escalate
|
||||
|
||||
@@ -226,8 +248,11 @@ Read the Workflow result:
|
||||
- **If `missingAgents` is non-empty**, some tasks ran on `general-purpose` because the assigned
|
||||
specialist isn't installed here. Surface the list (which agents, how to install) so the user can
|
||||
decide whether to install them and re-run for higher-quality output.
|
||||
- **If `noReviewGate: true`** (the user skipped BOTH per-task review and impl review), CAVEAT any
|
||||
clean verdict: it only means the engineer validates passed, nothing reviewed the build. Report
|
||||
`reviewConfig` so the user sees which gates ran.
|
||||
- **`converged: true`** (real run, `openRegister` empty) → DONE. Report the build outcome per task,
|
||||
the review/audit verdicts, and where the plan landed.
|
||||
the review/audit verdicts (per `reviewConfig`), and where the plan landed.
|
||||
- **`openRegister` non-empty** → PRESENT the feedback and let the user decide. List the verified
|
||||
BLOCK/CONCERN findings (file:line, issue, suggested fix, which gate found them). Then offer the next
|
||||
move: **run a fix round** (re-invoke the workflow with the findings as the prompt — same intake),
|
||||
@@ -239,16 +264,17 @@ aborted), run it last** — invoke the chosen skill (`map-project` or `map-proje
|
||||
`CLAUDE.md` context map reflects the code the build just landed. Skip it on an aborted/false-clean run
|
||||
(there's nothing new to map). This is the final step, after reporting.
|
||||
|
||||
**Success criteria**: Either the gates are genuinely clean, or the user is handed an honest list of
|
||||
what still blocks, with the round budget respected; and the project map is refreshed if requested.
|
||||
**Success criteria**: Either the enabled gates are genuinely clean (caveated by `reviewConfig` /
|
||||
`noReviewGate`), or the user is handed an honest list of what still blocks plus next moves; and the
|
||||
project map is refreshed if requested.
|
||||
|
||||
## Guardrails
|
||||
|
||||
- Do not run proactively; this is explicit-user-only (it spawns many agents across rounds).
|
||||
- Round 1 runs the full cycle; recursion rounds are a fix loop (decompose → build → impl review) and
|
||||
deliberately skip founder plan review. Do not re-introduce plan review on recursion, and do not skip
|
||||
Impl review on any round — it is the plan-vs-implementation gate. The Workflow owns 3–14, the skill
|
||||
owns 1–2.1.
|
||||
- The workflow runs ONE pass and never loops on its own; a fix round is a deliberate user choice
|
||||
(re-invoke with the findings as the prompt). Review gates are user-selected per run — honor the
|
||||
user's `planReview`/`taskReview`/`implReview` choices, and warn (don't block) when both per-task and
|
||||
impl review are skipped. The Workflow owns 3–14, the skill owns 1–2.1.
|
||||
- Do not hand-roll the plan — the Workflow's plan phase follows the plan-to-task-list-with-dag
|
||||
methodology and assigns a specialist agent per task.
|
||||
- The build assigns the closest AVAILABLE specialist per task; fall back to `general-purpose` only with
|
||||
@@ -287,9 +313,9 @@ what still blocks, with the round budget respected; and the project map is refre
|
||||
|
||||
Report:
|
||||
|
||||
1. intake — selected harness and go-live choice, resolved working branch
|
||||
2. rounds run and convergence status
|
||||
3. per-round plan name + build outcome per task (passed / fixes / blocked)
|
||||
4. implementation review — native + harness findings (confirmed vs rejected)
|
||||
5. go-live audit — verdict and blockers (or "skipped")
|
||||
6. final state — clean, or the honest remaining-findings list with the round budget status
|
||||
1. intake — the review config used (`reviewConfig`: harness + which gates ran at what depth), go-live
|
||||
choice, resolved working branch
|
||||
2. plan name + build outcome per task (passed / fixes / blocked)
|
||||
3. plan review and implementation review — findings by enabled gate (confirmed vs rejected), or "skipped"
|
||||
4. go-live audit — verdict and blockers (or "skipped")
|
||||
5. final state — clean (caveated if `noReviewGate`), or the honest remaining-findings list + next moves
|
||||
|
||||
@@ -89,8 +89,10 @@ Spawn the task's assigned specialist agent (the plan's `Agent` field) via the Ag
|
||||
|
||||
### 2. Review — the reviewer agent
|
||||
|
||||
When the engineer reports done, spawn the MATCHED specialist reviewer (the engineer's name +
|
||||
`-reviewer`) read-only over that task's diff:
|
||||
This step is gated by `taskReview`: `skip` (no per-task reviewer or fix loop — the task passes on its
|
||||
engineer validate alone), `native` (the matched `-reviewer` below), or `harness` (the global review
|
||||
harness — codex/kiro). When review is enabled, on engineer-done spawn the reviewer read-only over the
|
||||
task's diff:
|
||||
|
||||
- `isolation: "worktree"` against the engineer's branch/worktree; do NOT let it edit.
|
||||
- Brief: read the task's diff + surrounding context, verify each acceptance criterion is actually
|
||||
|
||||
@@ -1,35 +1,40 @@
|
||||
# Harness routing
|
||||
|
||||
The intake question picks ONE second harness: `claude`, `codex`, `kiro`, or `none`. "claude" is
|
||||
always the native side (this orchestrator IS claude). The selected harness is the *external
|
||||
cross-check* that runs alongside native claude. `none` skips the external cross-check entirely.
|
||||
The `harness` intake picks ONE global external review harness: `none`, `codex`, or `kiro`. Native
|
||||
claude (this orchestrator) always runs its own side of any enabled review; the harness is the optional
|
||||
*external cross-check* run alongside it. It is used wherever a gate is set to **`claude+harness`**
|
||||
(`planReview`, `implReview`) or `taskReview` is **`harness`**. `none` = native only, no external lane.
|
||||
|
||||
This file pins how each choice maps to a concrete invocation for the three review surfaces the
|
||||
playbook uses: **plan review** (a markdown/JSON plan, not a diff), **code review** (a branch diff),
|
||||
and **go-live audit** (the whole repo).
|
||||
This file pins how each choice maps to a concrete invocation for the review surfaces the playbook uses:
|
||||
**plan review** (a markdown/JSON plan), **code review** (a branch diff), and **go-live audit** (the repo).
|
||||
|
||||
## The matrix
|
||||
|
||||
| Surface | `claude` (native, always runs) | `codex` | `kiro` | `none` |
|
||||
|---|---|---|---|---|
|
||||
| Plan review (Phase C) | `plan-founder-review <plan>` (forked) | `codex:codex-rescue` agent, read-only founder-review brief | `kiro-review` adapted to the plan files | native only |
|
||||
| Code review (Phase F, impl review) | `claude-review` over the branch (or a `general-purpose` reviewer in a worktree) | `codex-review` over the branch | `kiro-review` over the branch | native only |
|
||||
| Go-live audit (Phase G) | `go-live-audit` (multi-agent workflow) | `codex:codex-rescue` agent, read-only launch-audit brief | `kiro-review` whole-repo | native audit only |
|
||||
| Surface | native (claude, always runs its side) | `codex` | `kiro` |
|
||||
|---|---|---|---|
|
||||
| Plan review (`planReview claude+harness`) | `plan-founder-review <plan>` (forked) | `codex:codex-rescue` agent, read-only founder-review brief | `kiro-review` adapted to the plan files |
|
||||
| Impl review (`implReview claude+harness`) | `claude-review` over the branch (or a `general-purpose` reviewer in a worktree) | `codex-review` over the branch | `kiro-review` over the branch |
|
||||
| Go-live audit (Phase G) | `go-live-audit` (multi-agent workflow) | `codex:codex-rescue` agent, read-only launch-audit brief | `kiro-review` whole-repo |
|
||||
|
||||
Native claude always runs its side. When `harness != none`, the selected column runs **in
|
||||
parallel** with the native side. Plan review (Phase C) is a bounded loop (exits clean or
|
||||
non-converging); impl review and audit run once and their findings are returned as feedback.
|
||||
Native always runs its side when the gate is enabled. With `claude+harness` AND `harness != none`, the
|
||||
harness column runs **in parallel** with native. Plan review is a bounded loop (exits clean or
|
||||
non-converging); impl review and audit run once and their findings are returned as feedback. Any gate
|
||||
can be `skip`ped — then neither lane runs.
|
||||
|
||||
## Per-task build & review handoff (separate from the cross-review harness)
|
||||
## Per-task build & review handoff
|
||||
|
||||
The `harness` above is the one-shot cross-review of the plan and the full implementation. Two
|
||||
**independent** selectors decide who does the per-task work inside the build loop — `buildHarness`
|
||||
(who WRITES each task) and `taskReviewHarness` (who REVIEWS each task), each `native | codex | kiro`:
|
||||
Two selectors decide who does the per-task work inside the build loop — `buildHarness` (who WRITES each
|
||||
task) and `taskReview` (who REVIEWS each task). `buildHarness` ∈ `native | codex | kiro` is an
|
||||
independent axis; `taskReview` ∈ `skip | native | harness`, where `harness` routes to the ONE global
|
||||
`harness` (codex or kiro):
|
||||
|
||||
| Handoff | `native` (default) | `codex` | `kiro` |
|
||||
|---|---|---|---|
|
||||
| Build (write) — `buildHarness` | the plan's specialist engineer agent (`resolveAgent(t.agent)`, in a worktree) | `codex:codex-rescue` agent (write-capable), worktree, brief allows edits | a `general-purpose` agent that runs the **`hand-over-to-kiro`** skill (by Sabeur Thabti, @thabti) to delegate the build to `kiro-cli`; if that skill or the CLI is absent it implements directly |
|
||||
| Per-task review — `taskReviewHarness` | the matched `-reviewer` agent (`resolveAgent(t.reviewer)`) | `codex:codex-rescue` agent, READ-ONLY brief | the **`kiro-review`** skill via the Kiro CLI, READ-ONLY; if unavailable it says so and returns empty findings (never substitutes a native review) |
|
||||
| Build (write) — `buildHarness` | the plan's specialist engineer agent (`resolveAgent(t.agent)`, in a worktree) | `codex:codex-rescue` agent (write-capable), worktree, brief allows edits | a `general-purpose` agent that runs the **`hand-over-to-kiro`** skill (by Sabeur Thabti, @thabti) to delegate the build to `kiro-cli` (autonomous); if that skill or the CLI is absent it implements directly |
|
||||
| Per-task review — `taskReview` (`harness` → global) | the matched `-reviewer` agent (`resolveAgent(t.reviewer)`) | `codex:codex-rescue` agent, READ-ONLY brief | the **`kiro-review`** skill via the Kiro CLI, READ-ONLY; if unavailable it says so and returns empty findings (never substitutes a native review) |
|
||||
|
||||
`taskReview skip` runs no per-task reviewer at all (and no per-task fix loop) — the task passes on its
|
||||
engineer validate alone.
|
||||
|
||||
These are wired in `workflow-template.js` (`buildSpawn` / `taskReviewSpawn`). The native path keeps the
|
||||
specialist-agent availability handling (`resolveAgent` + `missingAgents` reporting); the codex/kiro
|
||||
|
||||
@@ -28,11 +28,13 @@ A intake ──> B plan ──> C plan-review loop (native ∥ harness, bounded)
|
||||
DONE user decides: fix round / hand-fix / accept
|
||||
```
|
||||
|
||||
- B (plan) and C (plan review) run ONCE. C is a plan-QUALITY gate (scope, decomposition, phantom
|
||||
paths): ONE bounded loop (native ∥ selected harness; native-only when `harness == none`), exits on no
|
||||
BLOCK/CONCERN (OBSERVATIONs never block) OR non-convergence, capped at `MAX_REVIEW` (2).
|
||||
- E barriers between DAG layers; each task loops engineer↔reviewer until it passes.
|
||||
- F is the plan-vs-implementation gate.
|
||||
- B (plan) runs once. C (plan review) runs per `planReview`: `skip` (omitted), `claude` (native), or
|
||||
`claude+harness` (native ∥ the global harness). When it runs it's a plan-QUALITY gate (scope,
|
||||
decomposition, phantom paths): ONE bounded loop, exits on no BLOCK/CONCERN (OBSERVATIONs never block)
|
||||
OR non-convergence, capped at `MAX_REVIEW` (2).
|
||||
- E barriers between DAG layers; each task loops engineer↔reviewer until it passes — unless `taskReview
|
||||
skip`, then there is no per-task reviewer/fix loop and a task passes on its engineer validate alone.
|
||||
- F (impl review) runs per `implReview` (`skip` / `claude` / `claude+harness`) — the plan-vs-implementation gate.
|
||||
- V dedups + adversarially verifies the build+impl findings. Survivors are `openRegister`.
|
||||
- If `openRegister` is empty and `goLive`, G (the heaviest phase) runs; otherwise the workflow RETURNS
|
||||
`openRegister` as feedback. There is NO automatic loop back to B/E — a fix round is a deliberate
|
||||
|
||||
@@ -15,9 +15,16 @@
|
||||
// the playbook; the skill just supplies them as inputs to this script. Everything else runs here.
|
||||
//
|
||||
// HOW TO USE: the skill launches this with
|
||||
// args = { prompt, harness, goLive, root, workingBranch, validate, hardRules, auditScriptPath,
|
||||
// availableAgents, allowGeneralFallback, buildHarness, taskReviewHarness }
|
||||
// args = { prompt, root, workingBranch, validate, hardRules, goLive,
|
||||
// harness, // 'none' | 'codex' | 'kiro' (one global external review harness)
|
||||
// planReview, // 'skip' | 'claude' | 'claude+harness'
|
||||
// buildHarness, // 'native' | 'codex' | 'kiro' (who WRITES each task)
|
||||
// taskReview, // 'skip' | 'native' | 'harness' (who REVIEWS each task)
|
||||
// implReview, // 'skip' | 'claude' | 'claude+harness'
|
||||
// auditScriptPath, availableAgents, allowGeneralFallback }
|
||||
// (auditScriptPath is optional — see the comment at its CFG read below.)
|
||||
// Every review gate is independently dialable: from full-rigor (planReview+implReview claude+harness,
|
||||
// taskReview harness, goLive) down to fast (everything skip). Lighter is the default; skip nothing for max.
|
||||
// Or fill the FILL: fallbacks and run directly. Keep `meta` a pure literal or the Workflow tool
|
||||
// rejects it. Build agents have Bash, so the in-workflow integrate agent does the git merges.
|
||||
|
||||
@@ -43,13 +50,28 @@ if (args && typeof args === 'object') CFG = args
|
||||
else if (typeof args === 'string' && args.trim()) { try { CFG = JSON.parse(args) } catch { CFG = {} } }
|
||||
const ROOT = CFG.root || 'FILL: absolute repo path'
|
||||
const WORKING_BRANCH = CFG.workingBranch || 'FILL: branch to build on (e.g. main or a feature branch)'
|
||||
const HARNESS = CFG.harness || 'FILL: claude | codex | kiro | none'
|
||||
const GO_LIVE = CFG.goLive === true
|
||||
const MAX_REVIEW = 2 // bounded plan-review iterations (a plan isn't code; non-convergence also early-exits)
|
||||
const MAX_FIX = 3 // bounded per-task engineer↔reviewer fix iterations
|
||||
const VALIDATE_ALL = CFG.validate || 'FILL: workspace validate, e.g. pnpm -w exec tsc --noEmit && pnpm lint'
|
||||
const HARD_RULES = CFG.hardRules || `FILL: load-bearing invariants (import boundaries, Node strip-only,
|
||||
money is BIGINT/string, RLS fail-closed, append-only ActivityLog, route-barrel wiring, …)`
|
||||
let PROMPT = CFG.prompt || 'FILL: the feature request'
|
||||
const GO_LIVE = CFG.goLive === true
|
||||
const MAX_REVIEW = 2 // bounded plan-review iterations (a plan isn't code; non-convergence also early-exits)
|
||||
const MAX_FIX = 3 // bounded per-task engineer↔reviewer fix iterations
|
||||
|
||||
// ── review controls (each expensive gate is independently dialable to save tokens) ──
|
||||
// HARNESS is the ONE global external review harness used wherever a gate is set to "claude+harness"
|
||||
// (claude/native always runs its own side; this is the optional second opinion). 'none' = no external.
|
||||
const HARNESS = ['none', 'codex', 'kiro'].includes(CFG.harness) ? CFG.harness : 'none'
|
||||
// PLAN_REVIEW: founder review of the plan — 'skip' | 'claude' (native only) | 'claude+harness'.
|
||||
const PLAN_REVIEW = ['skip', 'claude', 'claude+harness'].includes(CFG.planReview) ? CFG.planReview : 'claude'
|
||||
// TASK_REVIEW: who reviews each built task — 'skip' (no per-task reviewer/fix loop) | 'native' | 'harness'.
|
||||
const TASK_REVIEW = ['skip', 'native', 'harness'].includes(CFG.taskReview) ? CFG.taskReview : 'native'
|
||||
// IMPL_REVIEW: final plan-vs-implementation review after build — 'skip' | 'claude' | 'claude+harness'.
|
||||
const IMPL_REVIEW = ['skip', 'claude', 'claude+harness'].includes(CFG.implReview) ? CFG.implReview : 'claude'
|
||||
// BUILD_HARNESS: who WRITES each task — 'native' (plan's specialist agent) | 'codex' | 'kiro'.
|
||||
const BUILD_HARNESS = ['codex', 'kiro'].includes(CFG.buildHarness) ? CFG.buildHarness : 'native'
|
||||
const useHarness = (gate) => gate === 'claude+harness' && HARNESS !== 'none' // does this gate add the external lane?
|
||||
|
||||
// step 13: path to a FILLED go-live-audit workflow script (the skill authors it via the go-live-audit
|
||||
// skill and passes its scriptPath). When set, the Audit phase COMPOSES that proven workflow inline via
|
||||
// the workflow() hook; when unset, it falls back to an inline finder pass.
|
||||
@@ -60,23 +82,15 @@ const AUDIT_SCRIPT_PATH = CFG.auditScriptPath || null
|
||||
// specialist to general-purpose (the skill NOTIFIES the user before setting this).
|
||||
const AVAILABLE_AGENTS = Array.isArray(CFG.availableAgents) ? CFG.availableAgents : null
|
||||
const ALLOW_GENERAL_FALLBACK = CFG.allowGeneralFallback !== false // default true: degrade, don't crash
|
||||
// Per-task work handoff (independent of the plan/impl cross-review HARNESS): who WRITES each task and
|
||||
// who REVIEWS each task — 'native' (the plan's specialist agent), 'codex', or 'kiro'. Default native.
|
||||
const BUILD_HARNESS = ['codex', 'kiro'].includes(CFG.buildHarness) ? CFG.buildHarness : 'native'
|
||||
const TASK_REVIEW_HARNESS = ['codex', 'kiro'].includes(CFG.taskReviewHarness) ? CFG.taskReviewHarness : 'native'
|
||||
let PROMPT = CFG.prompt || 'FILL: the feature request'
|
||||
|
||||
// Fail LOUD if inputs never reached the script. Without this, the values above stay at their FILL:
|
||||
// placeholders, the plan agent is handed "FILL: the feature request", returns no tasks, and the run
|
||||
// reports a fake converged:true. Refuse to start on placeholders rather than emit a false clean.
|
||||
const _missing = Object.entries({ ROOT, WORKING_BRANCH, HARNESS, VALIDATE_ALL, PROMPT })
|
||||
const _missing = Object.entries({ ROOT, WORKING_BRANCH, VALIDATE_ALL, PROMPT })
|
||||
.filter(([, v]) => typeof v !== 'string' || v.startsWith('FILL:')).map(([k]) => k)
|
||||
if (_missing.length) {
|
||||
throw new Error(`ship-playbook: inputs did not reach the script — ${_missing.join(', ')} still at FILL: placeholder (typeof args="${typeof args}"). Pass args as a real JSON object per the skill's Phase 2 contract, NOT a stringified blob, then relaunch as a FRESH run.`)
|
||||
}
|
||||
if (!['claude', 'codex', 'kiro', 'none'].includes(HARNESS)) {
|
||||
throw new Error(`ship-playbook: harness="${HARNESS}" is invalid — expected one of claude | codex | kiro | none.`)
|
||||
}
|
||||
|
||||
const harnessAgentType = HARNESS === 'codex' ? 'codex:codex-rescue' : 'general-purpose'
|
||||
// The harness lane's brief prefix. codex routes via its plugin agentType (codex:codex-rescue); kiro
|
||||
@@ -213,13 +227,14 @@ Implement ONLY this task.`
|
||||
}
|
||||
function integrateBrief(branches) {
|
||||
return `On ${WORKING_BRANCH} in ${ROOT}, integrate these task branches IN ORDER: ${branches.join(', ')}.
|
||||
For each: \`git merge --no-edit <branch>\`. If one conflicts: \`git merge --abort\`, record it under
|
||||
conflicted[], continue with the rest. Never force-resolve a conflict.
|
||||
|
||||
AFTER merging, CLEAN UP this workflow's transient build worktrees BEFORE validating — they are full
|
||||
checkouts of the repo and will otherwise pollute the validate. For each merged branch: find its
|
||||
worktree path via \`git -C ${ROOT} worktree list --porcelain\`, run \`git -C ${ROOT} worktree remove --force <path>\`,
|
||||
then \`git -C ${ROOT} branch -D <branch>\`. Finish with \`git -C ${ROOT} worktree prune\`.
|
||||
Process them ONE AT A TIME — merge a branch, then IMMEDIATELY remove its worktree, then move to the
|
||||
next. For each branch:
|
||||
1. \`git merge --no-edit <branch>\` (on conflict: \`git merge --abort\`, record it under conflicted[],
|
||||
skip to the next branch — never force-resolve).
|
||||
2. As soon as it merges, REMOVE its transient build worktree so it can't pollute anything: find the
|
||||
path via \`git -C ${ROOT} worktree list --porcelain\`, \`git -C ${ROOT} worktree remove --force <path>\`,
|
||||
then \`git -C ${ROOT} branch -D <branch>\`.
|
||||
Finish with \`git -C ${ROOT} worktree prune\` to clear stale admin entries.
|
||||
|
||||
THEN run ${VALIDATE_ALL} once. The validate must cover ONLY the project at ${ROOT} — it must NOT scan
|
||||
\`.claude/worktrees/**\` or sibling agent dirs (\`.factory\`, \`.gemini\`, \`.opencode\`, \`.trae\`, \`.vibe\`).
|
||||
@@ -253,10 +268,11 @@ const auditBrief = `READ-ONLY launch-readiness (go-live) audit of ${ROOT}. Check
|
||||
(${HARD_RULES}), build/test/lint honesty, secrets (redact values), tenancy/security, dead wiring,
|
||||
placeholder/TODO in shipping code. verdict + findings BLOCK/CONCERN/OBSERVATION with file:line + evidence.`
|
||||
|
||||
// run native ∥ selected-harness for a read-only review surface; tag each finding's source
|
||||
async function reviewBoth(label, phaseTitle, brief) {
|
||||
// run native (∥ the external harness when withHarness) for a read-only review surface; tag each
|
||||
// finding's source. withHarness = the caller's gate is "claude+harness" AND a harness is configured.
|
||||
async function reviewBoth(label, phaseTitle, brief, withHarness) {
|
||||
const lanes = [{ source: 'native', run: () => agent(`${brief}\n(native claude)`, { label: `${label}:native`, phase: phaseTitle, schema: FINDINGS }) }]
|
||||
if (HARNESS !== 'none') {
|
||||
if (withHarness && HARNESS !== 'none') {
|
||||
lanes.push({ source: HARNESS, run: () => agent(`${harnessRoute}\n${brief}`, { label: `${label}:${HARNESS}`, phase: phaseTitle, schema: FINDINGS, agentType: harnessAgentType }) })
|
||||
}
|
||||
const out = await parallel(lanes.map(l => l.run))
|
||||
@@ -345,11 +361,11 @@ Never delete non-worktree files and never remove the main checkout. Report remov
|
||||
}
|
||||
|
||||
// ── build/review handoff: who WRITES & who REVIEWS each task ─────────────────────
|
||||
// Independent of the plan/impl cross-review HARNESS. buildHarness / taskReviewHarness each ∈
|
||||
// native|codex|kiro. native = the plan's specialist agent (via resolveAgent + missingAgents reporting);
|
||||
// codex = the codex plugin agent (write-capable); kiro = the kiro-review skill for review and the
|
||||
// hand-over-to-kiro skill (which wraps the Kiro CLI, run autonomously) for build, each with a
|
||||
// self-implementation fallback if the skill/CLI is absent.
|
||||
// buildHarness (who WRITES) ∈ native|codex|kiro — independent of the global review HARNESS.
|
||||
// taskReview (who REVIEWS) ∈ skip|native|harness; 'harness' routes to the ONE global HARNESS.
|
||||
// native = the plan's specialist agent (resolveAgent + missingAgents); codex = the codex plugin agent;
|
||||
// kiro = the hand-over-to-kiro skill (build) / kiro-review skill (review) wrapping the Kiro CLI, each
|
||||
// with a self-implementation fallback if the skill/CLI is absent.
|
||||
function buildSpawn(t, brief, label) {
|
||||
if (BUILD_HARNESS === 'codex')
|
||||
return spawnSpecialist(`You MAY edit files to implement this task.\n${brief}`, { label, phase: 'Build', schema: TASK_RESULT, agentType: 'codex:codex-rescue', isolation: 'worktree' })
|
||||
@@ -357,12 +373,13 @@ function buildSpawn(t, brief, label) {
|
||||
return spawnSpecialist(`Use the hand-over-to-kiro skill (\`/hand-over-to-kiro\`) to delegate implementing this task to kiro-cli — it builds an injection-safe prompt, runs kiro in this worktree, and verifies the diff. This is UNATTENDED: tell it to run kiro autonomously (\`--trust-all-tools\`), since no human can approve tool calls. If the hand-over-to-kiro skill or kiro-cli is unavailable, say so and implement the task yourself.\n${brief}`, { label, phase: 'Build', schema: TASK_RESULT, agentType: 'general-purpose', isolation: 'worktree' })
|
||||
return spawnSpecialist(brief, { label, phase: 'Build', schema: TASK_RESULT, agentType: resolveAgent(t.agent), isolation: 'worktree' })
|
||||
}
|
||||
// only called when TASK_REVIEW !== 'skip' (the skip case is handled in buildPlan, no reviewer spawned).
|
||||
function taskReviewSpawn(t, brief, label) {
|
||||
if (TASK_REVIEW_HARNESS === 'codex')
|
||||
if (TASK_REVIEW === 'harness' && HARNESS === 'codex')
|
||||
return spawnSpecialist(`READ-ONLY review — do NOT edit.\n${brief}`, { label, phase: 'Build', schema: FINDINGS, agentType: 'codex:codex-rescue' })
|
||||
if (TASK_REVIEW_HARNESS === 'kiro')
|
||||
if (TASK_REVIEW === 'harness' && HARNESS === 'kiro')
|
||||
return spawnSpecialist(`Use the kiro-review skill (\`/kiro-review\`) to review this task via the Kiro CLI, READ-ONLY; if the Kiro CLI is unavailable, say so and return empty findings — do not substitute a native review.\n${brief}`, { label, phase: 'Build', schema: FINDINGS, agentType: 'general-purpose' })
|
||||
return spawnSpecialist(brief, { label, phase: 'Build', schema: FINDINGS, agentType: resolveAgent(t.reviewer) })
|
||||
return spawnSpecialist(brief, { label, phase: 'Build', schema: FINDINGS, agentType: resolveAgent(t.reviewer) }) // native (or harness=none fallback)
|
||||
}
|
||||
|
||||
// ── steps 10–11: build across DAG layers, engineer → integrate → reviewer → fix ──
|
||||
@@ -381,8 +398,14 @@ async function buildPlan(plan) {
|
||||
// engineer-failed tasks are blocked outright
|
||||
for (const b of built.filter(b => b && (!b.r || b.r.status !== 'passed')))
|
||||
log.push({ task: b.t.id, status: 'blocked', reason: 'engineer validate failed', fixes: 0, findings: [] })
|
||||
// initial per-task reviews are READ-ONLY → run them in PARALLEL across the layer
|
||||
const passed = built.filter(b => b && b.r && b.r.status === 'passed')
|
||||
// TASK_REVIEW === 'skip' (#2): no per-task reviewer / fix loop — a task passes on its engineer
|
||||
// validate alone. Biggest token saver; the user opted out of per-task review.
|
||||
if (TASK_REVIEW === 'skip') {
|
||||
for (const b of passed) log.push({ task: b.t.id, status: 'passed', fixes: 0, findings: [] })
|
||||
continue
|
||||
}
|
||||
// initial per-task reviews are READ-ONLY → run them in PARALLEL across the layer
|
||||
const reviewed = await parallel(passed.map(b => () =>
|
||||
taskReviewSpawn(b.t, reviewerBrief(b.t), `review:${b.t.id}`)
|
||||
.then(r => ({ t: b.t, review: r || { verdict: 'concerns', findings: [] } }))))
|
||||
@@ -447,17 +470,23 @@ if (!plan || !plan.tasks || !plan.tasks.length) {
|
||||
return { converged: false, ranReal: false, aborted: 'no tasks were planned — aborted before any build (verify args/PROMPT reached the script)', harness: HARNESS, goLive: GO_LIVE }
|
||||
}
|
||||
|
||||
// Plan review (steps 4–9): plan-QUALITY gate (scope, decomposition, phantom paths). ONE bounded loop,
|
||||
// native ∥ selected harness; exits on no BLOCK/CONCERN or non-convergence (capped at MAX_REVIEW).
|
||||
phase('Plan review')
|
||||
if (HARNESS === 'none') await nativeReviewLoop(plan)
|
||||
else await harnessReviewLoop(plan)
|
||||
// Plan review (steps 4–9) — #4: 'skip' | 'claude' (native only) | 'claude+harness'. Plan-QUALITY gate
|
||||
// (scope, decomposition, phantom paths). ONE bounded loop; exits on no BLOCK/CONCERN or non-convergence.
|
||||
if (PLAN_REVIEW !== 'skip') {
|
||||
phase('Plan review')
|
||||
if (useHarness(PLAN_REVIEW)) await harnessReviewLoop(plan)
|
||||
else await nativeReviewLoop(plan)
|
||||
}
|
||||
|
||||
phase('Build') // steps 10–11
|
||||
const buildLog = await buildPlan(plan)
|
||||
|
||||
phase('Impl review') // step 12 — the plan-vs-implementation gate
|
||||
const implFindings = await reviewBoth('impl', 'Impl review', implBrief(plan))
|
||||
// Impl review (step 12) — #3: the plan-vs-implementation gate. 'skip' | 'claude' | 'claude+harness'.
|
||||
let implFindings = []
|
||||
if (IMPL_REVIEW !== 'skip') {
|
||||
phase('Impl review')
|
||||
implFindings = await reviewBoth('impl', 'Impl review', implBrief(plan), useHarness(IMPL_REVIEW))
|
||||
}
|
||||
|
||||
// Verify (step 14): dedup + adversarially verify the build+impl findings → this is the feedback.
|
||||
phase('Verify')
|
||||
@@ -473,7 +502,7 @@ if (openRegister.length === 0 && GO_LIVE) { // step 13 — only w
|
||||
if (AUDIT_SCRIPT_PATH) {
|
||||
lanes.push(async () => ingestGoLive(await workflow({ scriptPath: AUDIT_SCRIPT_PATH }))) // go-live-audit as a sub-workflow
|
||||
} else {
|
||||
lanes.push(async () => await reviewBoth('audit', 'Audit', auditBrief)) // fallback
|
||||
lanes.push(async () => await reviewBoth('audit', 'Audit', auditBrief, false)) // native inline fallback (harness lane added below)
|
||||
}
|
||||
if (HARNESS !== 'none') {
|
||||
lanes.push(async () => {
|
||||
@@ -497,6 +526,11 @@ return {
|
||||
build: buildLog.map(b => ({ task: b.task, status: b.status, fixes: b.fixes })),
|
||||
openRegister, // verified findings = the feedback to show the user
|
||||
missingAgents: [...missingAgents], // specialist agent types the plan wanted that aren't installed here → skill notifies the user
|
||||
// the review configuration this run used (so the skill can report it honestly and caveat the verdict)
|
||||
reviewConfig: { harness: HARNESS, planReview: PLAN_REVIEW, taskReview: TASK_REVIEW, implReview: IMPL_REVIEW, buildHarness: BUILD_HARNESS },
|
||||
// TRUE when NOTHING checked the build: no per-task reviewer AND no impl review. converged then means
|
||||
// "engineer validates passed", not "reviewed clean" — the skill must caveat this.
|
||||
noReviewGate: TASK_REVIEW === 'skip' && IMPL_REVIEW === 'skip',
|
||||
harness: HARNESS,
|
||||
goLive: GO_LIVE,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user