@mmerterden/multi-agent-pipeline 20.23.2 → 20.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/README.md +8 -6
- package/README.tr.md +7 -5
- package/docs/architecture.md +3 -3
- package/docs/ecosystem.md +5 -5
- package/docs/facts.json +7 -6
- package/docs/features.md +9 -4
- package/install/catalog-history.json +1 -1
- package/install/templates/claude-hooks.json +14 -1
- package/install/templates/codex-hooks.json +18 -0
- package/manifest.json +126 -98
- package/package.json +1 -1
- package/pipeline/agents/task-clarifier.md +1 -1
- package/pipeline/commands/multi-agent/analysis-jira/SKILL.md +4 -2
- package/pipeline/commands/multi-agent/deps/SKILL.md +61 -0
- package/pipeline/commands/multi-agent/model/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/postmortem/SKILL.md +90 -0
- package/pipeline/commands/multi-agent/review/SKILL.md +5 -5
- package/pipeline/commands/multi-agent/route-on/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/setup/SKILL.md +7 -5
- package/pipeline/commands/multi-agent/sync/SKILL.md +4 -4
- package/pipeline/commands/multi-agent/testflight-validation/SKILL.md +2 -3
- package/pipeline/contract/fixtures/runs-failed.json +1 -1
- package/pipeline/contract/fixtures/runs-old-schema.json +1 -1
- package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +1 -1
- package/pipeline/contract/fixtures/runs-pr-opened.json +1 -1
- package/pipeline/contract/fixtures/runs-running.json +1 -1
- package/pipeline/lib/analysis-jira-write.sh +70 -0
- package/pipeline/lib/credential-inventory.sh +5 -5
- package/pipeline/lib/decisions.mjs +130 -0
- package/pipeline/lib/fetch-crashlytics.sh +6 -8
- package/pipeline/lib/model-rung.sh +1 -1
- package/pipeline/lib/plan-todos.sh +177 -37
- package/pipeline/lib/post-pr-review.sh +4 -6
- package/pipeline/lib/route-state.sh +1 -1
- package/pipeline/lib/shadow-git.sh +4 -5
- package/pipeline/lib/task-graph.mjs +446 -0
- package/pipeline/lib/tdd-evidence.mjs +579 -0
- package/pipeline/multi-agent-refs/analysis-template-corporate.md +2 -0
- package/pipeline/multi-agent-refs/analysis-template.md +4 -2
- package/pipeline/multi-agent-refs/cross-cli-contract.md +10 -11
- package/pipeline/multi-agent-refs/features/analysis-jira.md +42 -0
- package/pipeline/multi-agent-refs/features/autopilot-decisions.md +34 -0
- package/pipeline/multi-agent-refs/features/cost-analysis.md +4 -0
- package/pipeline/multi-agent-refs/features/dep-bump.md +176 -0
- package/pipeline/multi-agent-refs/features/model-fallback.md +21 -14
- package/pipeline/multi-agent-refs/features/mutation-probe.md +58 -0
- package/pipeline/multi-agent-refs/features/plan-checks.md +67 -0
- package/pipeline/multi-agent-refs/features/plan-todos.md +40 -1
- package/pipeline/multi-agent-refs/features/rework-escalation.md +49 -0
- package/pipeline/multi-agent-refs/features/scope-check.md +1 -0
- package/pipeline/multi-agent-refs/help/en.md +2 -0
- package/pipeline/multi-agent-refs/help/tr.md +2 -0
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-1-plan.md +2 -3
- package/pipeline/multi-agent-refs/phases/phase-2-dev.md +7 -7
- package/pipeline/multi-agent-refs/phases/phase-3-review.md +18 -16
- package/pipeline/multi-agent-refs/phases/phase-5-report.md +3 -3
- package/pipeline/multi-agent-refs/picker-contract.md +3 -2
- package/pipeline/multi-agent-refs/response-shape.md +65 -0
- package/pipeline/multi-agent-refs/tracker-contract.md +6 -6
- package/pipeline/rules/response-shape.md +18 -0
- package/pipeline/schemas/agent-state.schema.json +36 -1
- package/pipeline/schemas/phases.json +4 -0
- package/pipeline/schemas/plan-todos.schema.json +104 -3
- package/pipeline/schemas/planning-output.schema.json +46 -0
- package/pipeline/schemas/prefs.schema.json +122 -3
- package/pipeline/scripts/_code-graph.mjs +2 -2
- package/pipeline/scripts/_jsonl.mjs +151 -0
- package/pipeline/scripts/_plan-overlap.mjs +231 -0
- package/pipeline/scripts/_redact.mjs +124 -10
- package/pipeline/scripts/_transcript-hosts.mjs +406 -0
- package/pipeline/scripts/analysis-story-tree.mjs +153 -8
- package/pipeline/scripts/autopilot-publish.mjs +12 -1
- package/pipeline/scripts/build-stack-plugins.mjs +3 -3
- package/pipeline/scripts/capture-flush.sh +7 -7
- package/pipeline/scripts/code-graph-rules/android.json +1 -1
- package/pipeline/scripts/cost-analyze.mjs +32 -43
- package/pipeline/scripts/cost-table.json +35 -19
- package/pipeline/scripts/decisions-log.mjs +118 -0
- package/pipeline/scripts/dep-bump.mjs +1556 -0
- package/pipeline/scripts/edit-syntax-gate.mjs +362 -0
- package/pipeline/scripts/edit-syntax-gate.sh +32 -0
- package/pipeline/scripts/find-polluter.mjs +281 -0
- package/pipeline/scripts/gate-ledger.mjs +46 -13
- package/pipeline/scripts/gc-abandoned.sh +2 -2
- package/pipeline/scripts/gen-mode-dispatch.mjs +3 -3
- package/pipeline/scripts/git-path.mjs +1 -2
- package/pipeline/scripts/host-hooks.mjs +265 -0
- package/pipeline/scripts/jira-attach.sh +1 -1
- package/pipeline/scripts/keychain.py +3 -3
- package/pipeline/scripts/mutation-probe.mjs +484 -0
- package/pipeline/scripts/output-quality-check.sh +1 -1
- package/pipeline/scripts/phase-tracker.sh +5 -6
- package/pipeline/scripts/phase0-exit-gate.mjs +3 -3
- package/pipeline/scripts/plan-complexity.mjs +259 -0
- package/pipeline/scripts/pre-push-check.sh +3 -6
- package/pipeline/scripts/review-decision-gate.mjs +33 -1
- package/pipeline/scripts/rework-escalation.mjs +264 -0
- package/pipeline/scripts/test-strength.mjs +5 -3
- package/pipeline/scripts/transcript-index.mjs +1131 -0
- package/pipeline/scripts/uninstall.mjs +90 -4
- package/pipeline/scripts/update-issue-progress.sh +4 -6
- package/pipeline/scripts/usage-report.mjs +2 -2
- package/pipeline/scripts/validate-planning.mjs +48 -6
- package/pipeline/skills/.skill-manifest.json +20 -12
- package/pipeline/skills/.skills-index.json +23 -1
- package/pipeline/skills/shared/README.md +5 -3
- package/pipeline/skills/shared/core/multi-agent/SKILL.md +6 -6
- package/pipeline/skills/shared/core/multi-agent-analysis-jira/SKILL.md +4 -2
- package/pipeline/skills/shared/core/multi-agent-deps/SKILL.md +60 -0
- package/pipeline/skills/shared/core/multi-agent-model/SKILL.md +2 -2
- package/pipeline/skills/shared/core/multi-agent-postmortem/SKILL.md +69 -0
- package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +5 -5
- package/pipeline/skills/shared/core/multi-agent-route-on/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +7 -5
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +4 -4
- package/pipeline/skills/shared/core/multi-agent-testflight-validation/SKILL.md +2 -3
- package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +15 -0
- package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +13 -0
- package/pipeline/skills/shared/external/debugging-strategies/SKILL.md +8 -0
- package/pipeline/skills/shared/external/ios-coding-standard/references/rules.yml +2 -2
- package/pipeline/skills/skills-index.md +3 -1
|
@@ -61,6 +61,7 @@ Pipeline entries:
|
|
|
61
61
|
|
|
62
62
|
/multi-agent "task" Worktree
|
|
63
63
|
/multi-agent:autopilot "task" Worktree, no questions
|
|
64
|
+
/multi-agent:deps [pkg[@ver]] [--major] Bump one dependency, fix only what the bump broke, review, PR; rolls back past depBump.maxFixRounds
|
|
64
65
|
|
|
65
66
|
Phase 0 Step 5b asks where the branch lives; there is no flag for it.
|
|
66
67
|
autopilot skips every confirmation INCLUDING the plan gate and the workspace
|
|
@@ -103,6 +104,7 @@ Post-Hoc & Side-Channel:
|
|
|
103
104
|
/multi-agent:build-optimize iOS-only Xcode build perf wrapper → benchmark + analyze + recommend-first .build-benchmark/optimization-plan.md
|
|
104
105
|
/multi-agent:create-jira ["desc"] [figma-url] [swagger-url] Create a Jira Task/Bug/Story matching team conventions (type, sprint, preview + approval)
|
|
105
106
|
/multi-agent:diff-explain Map a Phase 3 triage finding back to specific diff lines
|
|
107
|
+
/multi-agent:postmortem [#id|file.jsonl] Post-mortem of a run from its transcripts: loops, stalls, root-cause hypotheses on file:line (read-only, redacted)
|
|
106
108
|
/multi-agent:estimate <doc|text> Effort range from similar closed work: P25-P75 per role, with the tickets behind it
|
|
107
109
|
/multi-agent:scenario-audit <csv> Test scenarios vs the code: PRESENT / PARTIAL / ABSENT / UNCLEAR, each PRESENT on a resolving file:line
|
|
108
110
|
/multi-agent:graph Build and query the repo code graph (symbols, imports, references), LLM-free
|
|
@@ -61,6 +61,7 @@ Pipeline girişleri:
|
|
|
61
61
|
|
|
62
62
|
/multi-agent "task" Worktree var
|
|
63
63
|
/multi-agent:autopilot "task" Worktree var, soru yok
|
|
64
|
+
/multi-agent:deps [paket[@sürüm]] [--major] Tek bağımlılığı yükselt, yalnızca yükseltmenin kırdığını düzelt, review, PR; depBump.maxFixRounds aşılınca geri alır
|
|
64
65
|
|
|
65
66
|
Faz 0 Adım 5b branch'in nerede yaşayacağını sorar; bayrağı yok.
|
|
66
67
|
autopilot plan kapısı ve çalışma alanı sorusu dahil her onayı atlar, otomatik
|
|
@@ -102,6 +103,7 @@ Post-Hoc & Side-Channel:
|
|
|
102
103
|
/multi-agent:build-optimize iOS-only Xcode build performance wrapper → benchmark + analiz + recommend-first .build-benchmark/optimization-plan.md
|
|
103
104
|
/multi-agent:create-jira ["açıklama"] [figma-url] [swagger-url] Takım standartlarına uygun Jira Task/Bug/Story oluştur (tip, sprint, önizleme + onay)
|
|
104
105
|
/multi-agent:diff-explain Phase 3 triage bulgusunu diff satırlarına eşle
|
|
106
|
+
/multi-agent:postmortem [#id|dosya.jsonl] Koşunun transkriptlerinden post-mortem: döngüler, takılmalar, dosya:satır dayanaklı kök-neden hipotezleri (salt-okunur, redakte)
|
|
105
107
|
/multi-agent:estimate <doc|metin> Benzer kapanmış işlerden efor aralığı: rol başına P25-P75, dayandığı ticket'larla
|
|
106
108
|
/multi-agent:scenario-audit <csv> Test senaryolarını koda karşı denetle: VAR / KISMEN / YOK / BELİRSİZ, her VAR çözülen bir dosya:satır ile
|
|
107
109
|
/multi-agent:graph Repo kod grafiğini kur ve sorgula (semboller, import'lar, referanslar), LLM'siz
|
|
@@ -652,7 +652,7 @@ Log: `Phase 0 Step 7.7: testDepth = {unit|unit+ui|unit+mcp} (source {user|autopi
|
|
|
652
652
|
|
|
653
653
|
5. Phase 1 Analysis reads `state.clarification.userAnswers` (when present) as additional context - fold answers into the Explore prompt so downstream phases inherit the resolution.
|
|
654
654
|
|
|
655
|
-
**Reference:** `$HOME/.claude/agents/task-clarifier.md` - scoring rubric, question-quality rules and the ~$0.
|
|
655
|
+
**Reference:** `$HOME/.claude/agents/task-clarifier.md` - scoring rubric, question-quality rules and the ~$0.0004-per-call cost note.
|
|
656
656
|
|
|
657
657
|
#### Telemetry
|
|
658
658
|
|
|
@@ -402,6 +402,8 @@ Progress line: ` → checking validator validate-planning`
|
|
|
402
402
|
|
|
403
403
|
Non-zero exit fails CLOSED: emit the validator stderr + `errors[]` verbatim, attempt ONE self-correction rework (re-invoke the planner with the errors quoted, overwrite `$PLAN_FILE`), re-run the validator. If it fails again -> HALT the phase (never enter Phase 2 with an invalid plan) with recovery hint: `ERR: plan output failed validate-planning.mjs twice. Inspect $PLAN_FILE against $HOME/.claude/schemas/planning-output.schema.json, then resume with /multi-agent:resume #N.` Record `agent-state.phases["1"].validator` (`pass` | `pass-after-rework` | `halted`).
|
|
404
404
|
|
|
405
|
+
Then `plan-complexity.mjs "$PLAN_FILE" --graph "$GRAPH_PATH" --write` (`$GRAPH_PATH` as in `features/code-graph.md`; unset, the default graph path); split `split[]` tasks (`features/plan-checks.md`).
|
|
406
|
+
|
|
405
407
|
Log: "Phase 1: Plan - {N} tasks created, {M} with architecture review, validator:pass"
|
|
406
408
|
|
|
407
409
|
#### Step 10 - Put the plan on the widget (required)
|
|
@@ -423,9 +425,6 @@ and stored, only invisible.
|
|
|
423
425
|
printf '%s' "$PLAN_JSON" | bash "$HOME/.claude/lib/plan-todos.sh" set "$TASK_ID" -
|
|
424
426
|
```
|
|
425
427
|
|
|
426
|
-
`set` converts a planning-output document itself, so the `tasks[]`-to-`todos[]`
|
|
427
|
-
mapping has one definition, the tested one.
|
|
428
|
-
|
|
429
428
|
Phase 2 (Dev) then iterates with `plan-todos.sh next "$TASK_ID"` until empty, calling `start` before each step and `complete` (with notes) or `fail`/`skip` after. Phase 3 (Review) reads the Todo list to verify all `completed` items map to diff hunks. Phase 5 (Report) renders `list` into the agent-log + PR body.
|
|
430
429
|
|
|
431
430
|
**Why opt-in:** `planning-output.schema.json` already drives Phase 2 dependency order; `plan.todos[]` adds notes, durations and status transitions at the cost of a state write per step. Flip on for visibility into long features.
|
|
@@ -47,16 +47,18 @@ The analysis document is the SOLE design source in Phase 2. Variant choices, pad
|
|
|
47
47
|
|
|
48
48
|
<!-- progress-contract: applied -->
|
|
49
49
|
|
|
50
|
-
**Progress (per `$HOME/.claude/multi-agent-refs/progress-contract.md`):** every non-trivial step emits one `→ <verb> <object>` line at immediate flush. Canonical set for standard TDD: `→ reading <file>`, `→ writing test <name>`, `→ running xcodebuild RED`, `→ writing code <file>`, `→ running xcodebuild GREEN`, `→ committing WIP <summary>`. Component-task dispatch emits the line `→ dispatching create-component <componentName>`
|
|
50
|
+
**Progress (per `$HOME/.claude/multi-agent-refs/progress-contract.md`):** every non-trivial step emits one `→ <verb> <object>` line at immediate flush. Canonical set for standard TDD: `→ reading <file>`, `→ writing test <name>`, `→ running xcodebuild RED`, `→ writing code <file>`, `→ running xcodebuild GREEN`, `→ committing WIP <summary>`. Component-task dispatch emits the line `→ dispatching create-component <componentName>` before the Skill-tool call, then relays the plugin skill's progress lines verbatim under indent ` →`.
|
|
51
51
|
|
|
52
52
|
#### Input contract
|
|
53
53
|
|
|
54
54
|
Phase 2 consumes the Phase 1 output object conforming to `$HOME/.claude/schemas/planning-output.schema.json` - the task graph (`tasks[]` with `id`, `title`, `type`, `files`, and optional `dependsOn` / `acceptanceCriteria`) plus the architecture review notes. Tasks execute in dependency order; the schema's `dependsOn` field drives the ready-task picker.
|
|
55
55
|
|
|
56
|
-
**Plan Todo iteration (opt-in)**: gated by `prefs.global.planTodos.enabled` (default
|
|
56
|
+
**Plan Todo iteration (opt-in)**: gated by `prefs.global.planTodos.enabled` (default `false`). When enabled and Phase 1 Step 11 emitted `plan.todos[]`, iterate via `$HOME/.claude/lib/plan-todos.sh next/start/complete/fail/drift`; disabled, walk `tasks[]`, same TDD contract. Each todo records RED and GREEN runs (`tdd-red` / `tdd-green`); `complete` checks them per `prefs.global.tddEvidence.mode`. Loop + exemptions: `$HOME/.claude/multi-agent-refs/features/plan-todos.md`. A todo with `sourceTag: Reuse` binds the file analysis already found; `Modify` edits in place. Writing a new file over a `Reuse` step is a Locked 11 violation and Phase 3 flags it.
|
|
57
57
|
|
|
58
58
|
**Shadow-Git checkpoints (opt-in)**: gated by `prefs.global.shadowGit.enabled` (default: `false`). When enabled, the orchestrator snapshots the worktree via `$HOME/.claude/lib/shadow-git.sh` so sub-phase rollback is possible without touching the project's real `.git` history. Lifecycle: `shadow-git.sh init` (Phase 0 baseline), `shadow-git.sh snapshot` (per step after `plan-todos complete`), `shadow-git.sh restore <sha> --files` (rollback). Modes: `per-todo-step` (default) or `per-tool-call`. Full wiring + storage cap: `$HOME/.claude/multi-agent-refs/features/shadow-git.md`.
|
|
59
59
|
|
|
60
|
+
**Dependency bump** (`state.mode == "deps"`): `dep-bump.mjs apply` first, then capped fix rounds: `$HOME/.claude/multi-agent-refs/features/dep-bump.md`.
|
|
61
|
+
|
|
60
62
|
#### Component tasks - delegated dispatch (taskType === "component")
|
|
61
63
|
|
|
62
64
|
When Phase 0 Step 7 classified the task as `component`, Phase 2 delegates the entire phase to the enabled `ai-<platform>-toolkit` marketplace plugin's component skill (`create-component`, fallback `create-ui-component`) via the Skill tool and does NOT run the TDD loop below. The dispatch layer passes the plugin skill the analysis Section 6 (Bileşen Envanteri) entry + Section 13.1 conventions for the named component as context. Because plugin skills do not write pipeline state, the **dispatch layer** (not the skill) owns `state.phases["2"].subphases[]`, recording a coarse component-build row - multi-agent's `phase-tracker` reads that array with no special case. Plugin resolution (dual-name), dispatch call, failure/resume, multi-repo, and the intentional cross-CLI divergence live in `$HOME/.claude/multi-agent-refs/component-dispatch.md` - read it before editing component-task behaviour here. Phase 2 still owns: progress line `-> dispatching create-component <name>`, `retryCount` cap at 3, and fallthrough to the TDD path when dispatch prerequisites are missing (`taskType` absent OR the plugin is not enabled in this repo -> log anomaly, halt or run TDD per component-dispatch.md).
|
|
@@ -88,6 +90,7 @@ When re-entering from Phase 3:
|
|
|
88
90
|
5. `rejected` items are never touched. Log their IDs + triage reasons for audit only.
|
|
89
91
|
6. After rework, increment `state.phases["2"].retryCount`; hard-kill at `retryCount === 3` and escalate to the user. Do not loop indefinitely. When `prefs.global.autopilotCircuitBreaker.enabled` is true (default), record the hard-kill before escalating as `state.circuitBreaker = {tripped: true, trigger: 3, detail: "rework cycles exhausted", checkpoint: {phase: 3, step: "re-entry", iteration: <n>}, trippedAt, counters: {reworkCycles: <n>}}`: the rework-storm trigger; `autopilotCircuitBreaker.maxReworkCycles` (default 3) is bounded above by this cap.
|
|
90
92
|
7. When `state.reviewIterations[-1].delta` exists, `stillPresent[]` findings come first in the task list, quoted `STILL PRESENT after round N-1's fix`; repeating the previous attempt is the loop the circuit-breaker stops.
|
|
93
|
+
8. Before each rework dispatch, `rework-escalation.mjs` picks the rung; findings and the prior report go as files (`features/rework-escalation.md`).
|
|
91
94
|
|
|
92
95
|
If the latest iteration has `triage.approved === true` AND `accepted === []`, Phase 2 was entered by mistake - log the anomaly and return to Phase 3.
|
|
93
96
|
|
|
@@ -103,7 +106,7 @@ $HOME/.claude/scripts/log-metric.sh "$TASK_ID" 2 rework.started \
|
|
|
103
106
|
For each task (respecting dependency order), on start and on end: `bash $HOME/.claude/scripts/phase-tracker.sh sub 2 <task_id> "<title>" in_progress|completed|failed`.
|
|
104
107
|
|
|
105
108
|
1. **Update task status: `in_progress` (required - do not skip or defer)**
|
|
106
|
-
- **Why
|
|
109
|
+
- **Why**: the board shows "Todo" until this runs, and status reports and swimlanes read it.
|
|
107
110
|
- **Where it applies**:
|
|
108
111
|
- Jira: transition issue to "In Progress" via REST API (`/rest/api/2/issue/{id}/transitions`)
|
|
109
112
|
- GitHub Projects V2: `updateProjectV2ItemFieldValue` on the Status field (singleSelectOptionId)
|
|
@@ -112,10 +115,7 @@ For each task (respecting dependency order), on start and on end: `bash $HOME/.c
|
|
|
112
115
|
- Re-read the Status field after mutation.
|
|
113
116
|
- If the value is NOT `In Progress` (Jira) / `In Develop` (Projects V2), re-fetch current option IDs and retry ONCE.
|
|
114
117
|
- If verify still fails after retry → log error, do NOT proceed to TDD. The mutation silently failed and continuing would leave the task mis-tracked.
|
|
115
|
-
2. **Multi-submodule awareness**:
|
|
116
|
-
- New types/tokens in the **common** submodule
|
|
117
|
-
- The component itself in the **uicomponents** submodule
|
|
118
|
-
- Work in BOTH submodules in the same task - this is normal and expected
|
|
118
|
+
2. **Multi-submodule awareness**: a task may span the submodules Phase 0 Step 7 detected (e.g. tokens in **common**, the component in **uicomponents**); that is expected.
|
|
119
119
|
3. **TDD cycle** (Launch Agent with `model: "sonnet"`) - gated by `state.testPolicy`: `tdd` = the loop below; `tests-after` = skip RED, author the same tests once green; `none` = author no tests (existing ones never weakened), report "tests not written - project policy" rather than a gap.
|
|
120
120
|
|
|
121
121
|
**RED - Write ONE failing test first:**
|
|
@@ -100,9 +100,9 @@ Persist the totals as `state.diffRisk` (Phase 4 `risk` section, Phase 5, `run-me
|
|
|
100
100
|
| `ui_critical` | 1.5 | path matches `*View.swift`, `*Screen.kt`, `*Configuration.swift`, etc. |
|
|
101
101
|
| `loc_changed` | 1.0 | base sensitivity to total `+/-` lines |
|
|
102
102
|
|
|
103
|
-
**Reviewer prompt injection**: when `$RISK_JSON` is non-empty, the orchestrator builds a `${PRIORITY_FILES}` block (numbered list of top-N files with their score + signals) and injects it once per reviewer.
|
|
103
|
+
**Reviewer prompt injection**: when `$RISK_JSON` is non-empty, the orchestrator builds a `${PRIORITY_FILES}` block (numbered list of top-N files with their score + signals) and injects it once per reviewer. Reviewers (`code-reviewer.md`) treat it as advisory and do not echo it back. Triage does not see the priority list.
|
|
104
104
|
|
|
105
|
-
**Gate behavior**:
|
|
105
|
+
**Gate behavior**: if risk scoring fails (git, parse, validator), continue with no priority hint: reviewers get the full diff in default order. Failures are logged:
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
108
|
[ -z "$RISK_JSON" ] && $HOME/.claude/scripts/log-metric.sh "$TASK_ID" 3 review.diff_risk_skipped reason=$REASON
|
|
@@ -119,11 +119,11 @@ $HOME/.claude/scripts/log-metric.sh "$TASK_ID" 3 review.diff_risk \
|
|
|
119
119
|
files=$(jq '.totals.files' <<< "$RISK_JSON")
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
-
**Opt-out**: `prefs.global.diffRiskAdvisory = false` skips this step
|
|
122
|
+
**Opt-out**: `prefs.global.diffRiskAdvisory = false` skips this step. Default `true`.
|
|
123
123
|
|
|
124
124
|
#### Step 1.76 - Test-integrity gate (produces BLOCKING findings)
|
|
125
125
|
|
|
126
|
-
Step 1.75's `test_lines_removed` hint is too weak for
|
|
126
|
+
Step 1.75's `test_lines_removed` hint is too weak for a suite made green by deleting tests, so this makes it blocking findings triage must adjudicate. Pure function of the full report. `--out` always writes the file, the empty result included.
|
|
127
127
|
|
|
128
128
|
```bash
|
|
129
129
|
TI_FILE="$WORKTREE/.pipeline/test-integrity.json"
|
|
@@ -136,6 +136,8 @@ TI_COUNT=$(jq -r '.count // 0' "$TI_FILE" 2>/dev/null || echo 0)
|
|
|
136
136
|
|
|
137
137
|
The gate never blocks the phase; it *emits* blocking findings (unreadable input: zero). Feed it the FULL report: `--top` hides a shrinking test file below the cut. **No opt-out**: a run that can switch off its own anti-reward-hacking control cannot be trusted to report a pass.
|
|
138
138
|
|
|
139
|
+
**TDD evidence**: `node $HOME/.claude/lib/tdd-evidence.mjs unverified --state "$STATE_FILE"` lists todos closed without RED/GREEN or by `--no-tests`, as reviewer notes, not findings.
|
|
140
|
+
|
|
139
141
|
#### Step 1.761 - Owned-path gate (BLOCKING findings)
|
|
140
142
|
|
|
141
143
|
Phase 2 Gate 0 again, same base:
|
|
@@ -146,7 +148,7 @@ node $HOME/.claude/scripts/owned-path-gate.mjs --repo "$WORKTREE" --base "origin
|
|
|
146
148
|
--state "$STATE_FILE" --out "$OP_FILE"
|
|
147
149
|
```
|
|
148
150
|
|
|
149
|
-
`--out` drops the old file; exit 2 writes none. A missing `$OP_FILE` is a gate error, never "no findings" (`review-decision-gate.mjs` exit 3 under the gates). Findings merge at Step 3.0. Contract: `features/repo-profile.md`. Step 1.762: `features/valven.md`.
|
|
151
|
+
`--out` drops the old file; exit 2 writes none. A missing `$OP_FILE` is a gate error, never "no findings" (`review-decision-gate.mjs` exit 3 under the gates). Findings merge at Step 3.0. Contract: `features/repo-profile.md`. Step 1.762: `features/valven.md`; opt-in 1.763: `features/mutation-probe.md`.
|
|
150
152
|
|
|
151
153
|
#### Step 1.77 - Reviewer scope (cost gate)
|
|
152
154
|
|
|
@@ -235,10 +237,10 @@ Launch Agent instances **in parallel** using the shared `code-reviewer` subagent
|
|
|
235
237
|
|
|
236
238
|
| Reviewer | subagent_type | Claude Code | Copilot CLI | Codex CLI | Focus | Skills Referenced |
|
|
237
239
|
| ---------- | --------------- | --- | --- | --- | --- | --- |
|
|
238
|
-
| Reviewer 1 | `code-reviewer` | `claude-fable-5` | `claude-opus-
|
|
239
|
-
| Reviewer 2 | `code-reviewer` | `claude-opus-5` | `gpt-5.4` | `gpt-5.4` @ `high` | Edge cases, different perspective | cross-model diversity |
|
|
240
|
-
| Reviewer 3 | `code-reviewer` | `claude-sonnet-5` | `claude-sonnet-
|
|
241
|
-
| Triage | triage persona | `claude-fable-5` | `claude-opus-
|
|
240
|
+
| Reviewer 1 | `code-reviewer` | `claude-fable-5-1` | `claude-opus-4.7` | `gpt-5.6` @ `xhigh` | Deep security + architecture | `api-security-best-practices`, `architecture` |
|
|
241
|
+
| Reviewer 2 | `code-reviewer` | `claude-opus-5-5` | `gpt-5.4` | `gpt-5.4` @ `high` | Edge cases, different perspective | cross-model diversity |
|
|
242
|
+
| Reviewer 3 | `code-reviewer` | `claude-sonnet-5-5` | `claude-sonnet-4.6` | `gpt-5.6` @ `medium` | Quality + correctness + naming | `ai-backend-toolkit:clean-code`, stack-specific skill |
|
|
243
|
+
| Triage | triage persona | `claude-fable-5-1` | `claude-opus-4.7` | `gpt-5.6` @ `max` | Filter false positives + out-of-scope | - |
|
|
242
244
|
|
|
243
245
|
Reviewer count per host: **Claude Code 3, Copilot CLI 3, Codex CLI 3** - **2** on Claude Code with the fable rung off, per `$HOME/.claude/multi-agent-refs/features/model-fallback.md`.
|
|
244
246
|
|
|
@@ -263,7 +265,7 @@ borderline finding. Where the diversity budget goes instead:
|
|
|
263
265
|
|
|
264
266
|
Each reviewer inherits the `code-reviewer` agent's focus areas (Security, Architecture, Quality, Performance) and output contract. The orchestrator overrides only the model and the stack-specific skill per-reviewer - no prompt duplication.
|
|
265
267
|
|
|
266
|
-
**Model override wiring:** `code-reviewer.md` declares `preferredModel: fable`, so Reviewer 1 uses the persona default (Fable 5). Reviewer 2 (`claude-opus-5` on Claude Code, `gpt-5.4` elsewhere) and Reviewer 3 (
|
|
268
|
+
**Model override wiring:** `code-reviewer.md` declares `preferredModel: fable`, so Reviewer 1 uses the persona default (Fable 5.1). Reviewer 2 (`claude-opus-5-5` on Claude Code, `gpt-5.4` elsewhere) and Reviewer 3 (sonnet rung, per host above) set `PHASE_MODEL_OVERRIDE=<model>` before dispatch - the orchestrator exports `CLAUDE_CODE_SUBAGENT_MODEL` on Claude Code, or passes `--model` on Copilot CLI. Full precedence rule: `skills/shared/core/multi-agent/SKILL.md#agent-dispatch--per-persona-model-routing`. Fable dispatches are subject to the fallback contract (`$HOME/.claude/multi-agent-refs/features/model-fallback.md`): dispatch-error retry walks `fable -> opus -> sonnet` and budget-ceiling downgrade.
|
|
267
269
|
|
|
268
270
|
**Stack-specific skills loaded per reviewer** (from Phase 1 `detectedStack`). All three columns are used on every host; Reviewer 2 reads them as Opus on Claude Code and as GPT-5.4 elsewhere.
|
|
269
271
|
|
|
@@ -378,11 +380,11 @@ ANON=$(jq -n --argjson r "$REVIEWERS_JSON" --arg t "$TASK_ID" --argjson i "$ITER
|
|
|
378
380
|
|
|
379
381
|
`$REVIEWERS_JSON` is `state.reviewIterations[i].reviewers`. Findings come back with `foundBy: "Source A|B|C"` and every identity key removed. Persist the map to `state.reviewIterations[i].anonymizationMap` for Phase 5 per-reviewer telemetry, and **never put the map in a prompt**.
|
|
380
382
|
|
|
381
|
-
Then append the deterministic findings (Steps 1.76
|
|
383
|
+
Then append the deterministic findings (Steps 1.76-1.763, 2.7):
|
|
382
384
|
|
|
383
385
|
```bash
|
|
384
386
|
SA_FILE="$WORKTREE/.pipeline/security-audit-$ITERATION.json"
|
|
385
|
-
MERGED=$(printf '%s' "$ANON" | cat - "$TI_FILE" "$OP_FILE" "$VG_FILE" "$SA_FILE" 2>/dev/null \
|
|
387
|
+
MERGED=$(printf '%s' "$ANON" | cat - "$TI_FILE" "$OP_FILE" "$VG_FILE" "$MP_FILE" "$SA_FILE" 2>/dev/null \
|
|
386
388
|
| jq -s '.[0] + ([.[1:][] | .findings // []] | add // [])')
|
|
387
389
|
```
|
|
388
390
|
|
|
@@ -390,7 +392,7 @@ Deterministic findings keep their `tag` (`test_integrity`, `owned_path`, `valven
|
|
|
390
392
|
|
|
391
393
|
##### 3.1 Short-circuit: no findings
|
|
392
394
|
|
|
393
|
-
If **merged** findings `length === 0`, **skip triage**: write empty result `{"accepted": [], "deferred": [], "rejected": [], "approved": true}`, log, proceed to Phase 3.
|
|
395
|
+
If **merged** findings `length === 0`, **skip triage**: write empty result `{"accepted": [], "deferred": [], "rejected": [], "approved": true}`, log, proceed to Phase 3. This is the merged count from 3.0: zero reviewer findings plus any gate finding must NOT short-circuit.
|
|
394
396
|
|
|
395
397
|
**Autopilot** (or `MULTI_AGENT_UNATTENDED=1`): the triage output, this empty one too, goes through `verify-citations.mjs "$TRIAGE_FILE" --repo "$WORKTREE" --worktree --state "$STATE_FILE"` (every bucket, each `quote` against its line, pre-existing claims against the base commit): `$HOME/.claude/multi-agent-refs/features/unattended-gates.md` section 5. Then `review-decision-gate.mjs` (end of 3.7).
|
|
396
398
|
|
|
@@ -574,11 +576,11 @@ Merge the JSON into `state.reviewIterations[-1].delta` via `write-state.mjs`; em
|
|
|
574
576
|
|
|
575
577
|
#### Step 4 - Consensus + Action (triage-driven)
|
|
576
578
|
|
|
577
|
-
If `triage.consensus.verdict` is `split` or `unverified`, surface `consensus.disagreements[]` to the user before acting: interactive modes show the split and ask whether to treat the unverified agreement as a pass (picker-contract: Trust / Re-review / Treat-as-blocking); autopilot logs `review.consensus=<verdict
|
|
579
|
+
If `triage.consensus.verdict` is `split` or `unverified`, surface `consensus.disagreements[]` to the user before acting: interactive modes show the split and ask whether to treat the unverified agreement as a pass (picker-contract: Trust / Re-review / Treat-as-blocking); autopilot logs `review.consensus=<verdict>`, proceeds on the triage verdict, recorded per `features/autopilot-decisions.md`. Never silently average a split into a pass.
|
|
578
580
|
|
|
579
581
|
Act **only on triage.accepted**:
|
|
580
582
|
|
|
581
|
-
- **accepted.blocking** → back to Phase 2 (max 3 iterations,
|
|
583
|
+
- **accepted.blocking** → back to Phase 2 (max 3 iterations, rung per `features/rework-escalation.md`, reflection prompt cites only accepted items). The reflection prompt names findings by `fingerprint` and quotes `delta.stillPresent` first, marked `STILL PRESENT after round N-1's fix`. When Step 3.7 ran and `state.reviewIterations[-1].verifyByTest.redTests[]` is non-empty, the reflection prompt cites each red test: "a failing repro test already exists at <testRef>; make it green; do not delete or weaken it."
|
|
582
584
|
- **accepted.important** → fix and re-review
|
|
583
585
|
- **accepted.suggestion** → apply if reasonable
|
|
584
586
|
- **deferred** → append to Phase 5 report as "follow-up items" (do not block)
|
|
@@ -595,7 +597,7 @@ node $HOME/.claude/scripts/learnings-ledger.mjs add --kind fact \
|
|
|
595
597
|
--scope "<file-or-area glob from the finding>" --task "$TASK_ID"
|
|
596
598
|
```
|
|
597
599
|
|
|
598
|
-
Statement
|
|
600
|
+
Statement: the root cause, not the symptom ("force-unwrapped optional in async callback path", not "fixed crash in LoginView"). Always pass `--diagnosis`, the causal why: a bare outcome does not prevent recurrence. Dedup built in (exit 2 = already stored). Lessons re-enter Phase 1 + triage via `learnings-ledger.mjs brief` (renders diagnosis as "(why: ...)").
|
|
599
601
|
|
|
600
602
|
Progress line: ` → writing lesson to learnings ledger ({N} entries)`
|
|
601
603
|
|
|
@@ -170,6 +170,8 @@ Skipped sections: when `planTodos.enabled` is false or no `plan.todos[]` was emi
|
|
|
170
170
|
|
|
171
171
|
(the last three columns come from `reviewIterations[i].delta.counts` (Phase 3 Step 3.8) and read `-` on iteration 1 and on runs that predate the delta; a tripped circuit-breaker is one extra line under the table: `Circuit-breaker tripped: trigger {n}, {detail}`)
|
|
172
172
|
|
|
173
|
+
(autopilot: `decisions-log.mjs render --state "$STATE_FILE"` output verbatim; own heading, nothing when empty)
|
|
174
|
+
|
|
173
175
|
## Files Changed
|
|
174
176
|
|
|
175
177
|
(git diff --stat output)
|
|
@@ -317,8 +319,6 @@ bash $HOME/.claude/scripts/memory-save.sh "$PROJECT_ROOT" --from-json memory-syn
|
|
|
317
319
|
- **user**: only if the user disclosed new context about their role, expertise, or team layout
|
|
318
320
|
- **Otherwise return `[]`** - blank is the correct default. Do not save derivable facts (code structure, git history, command outputs).
|
|
319
321
|
|
|
320
|
-
Zero new memories is normal and expected. A typical run produces one or none.
|
|
321
|
-
|
|
322
322
|
Tracker: `phase-tracker.sh sub 5 3 "Knowledge+Memory" completed`.
|
|
323
323
|
|
|
324
324
|
Log: "Phase 5: Knowledge captured ({N} entries to {files})"
|
|
@@ -335,7 +335,7 @@ If user does not respond at the channels multi-select menu within 30 minutes (wa
|
|
|
335
335
|
4. Session exits cleanly. State persisted: `state.currentPhase=7, state.waitingFor="user-channels-choice", state.channelsTimeout=true`.
|
|
336
336
|
5. Resume contract: `/multi-agent:resume <task-id>` re-opens the channels menu with the original state bundle (pipeline log, PR metadata, prefs pre-ticks).
|
|
337
337
|
|
|
338
|
-
Rationale:
|
|
338
|
+
Rationale: posting defaults after a timeout would publish text nobody approved.
|
|
339
339
|
|
|
340
340
|
---
|
|
341
341
|
|
|
@@ -156,7 +156,8 @@ longer exists. A remembered choice is evidence about this user and this repo; an
|
|
|
156
156
|
order is a guess that happens to be sorted. Where the two agree nothing changes, and
|
|
157
157
|
where they disagree the remembered one is the answer with a reason behind it.
|
|
158
158
|
|
|
159
|
-
The run records which rule fired (`remembered` or `
|
|
159
|
+
The run records which rule fired (`remembered`, `default`, or `derived` when the answer follows from the task itself) and lists the choice in
|
|
160
|
+
`state.decisions[]` (`features/autopilot-decisions.md`). An autopilot run cannot be
|
|
160
161
|
asked anything, so the only thing that keeps it accountable is being readable afterwards.
|
|
161
162
|
|
|
162
163
|
## Background (unattended, not autopilot) contract
|
|
@@ -189,6 +190,6 @@ park it writes `agent-state.json` beside its tracker with `taskId`,
|
|
|
189
190
|
|
|
190
191
|
## Deterministic gates note
|
|
191
192
|
|
|
192
|
-
Claude Code's `PreToolUse` exit-2 hooks are the HARD blocking gates. Three ship, none needing run-specific arguments so they are naturally hookable: (1) `pre-commit-check.sh` scans the staged diff on every `git commit` and blocks on a detected secret; (2) `agent-guard.sh` runs on `git commit` + `git push` and blocks AI/assistant attribution in a commit message and force-push to a protected branch (main/master/develop); (3) `check-read-size.sh` runs on `Read` and on the shell commands that read a file whole, and routes an oversized read to a cheap worker (`bulk-read.sh`) instead of the caller's own rung. The first two inspect what a run WRITES; the third inspects what it pays to READ, and it is inert until `bulkRead.mode` is set to `observe` or `enforce`, so merging the block changes nothing until the user opts in. Its `observe` mode blocks nothing and only logs, which is how the baseline is measured before anything is routed. All three are self-contained and never execute the inspected command. On an internal error they let the call through in an attended session; `agent-guard.sh` blocks instead under `MULTI_AGENT_UNATTENDED=1`, where nobody is watching to notice a gap. Three capture hooks ship in the same block and block nothing: `SessionEnd` runs `capture-flush.sh --if-stale` (writing a killed run's findings into the per-repo stores, so they do not depend on the run reaching Phase 5) plus `note-session.sh` (the mechanical shape of a non-pipeline session: tools used, commands that failed, calls the user refused - never an argument, never any output), `PreCompact` runs `capture-flush.sh` without `--if-stale` (a compaction summarizes a long phase mid-flight, so it is the moment unflushed findings are at risk; the staleness test exists only so a session exit does not re-flush a finished run, and both store writes are idempotent), and `SessionStart` runs `capture-resume.sh`, at most two lines about an unfinished run and a stale observation queue. None of them calls a model; all exit 0 on every path. The recommended hook block ships at `install/templates/claude-hooks.json`; `multi-agent:setup` offers to merge it into `~/.claude/settings.json`. The other deterministic gates (evidence, consensus, intent, learnings) are invoked by the pipeline phases with per-run arguments (a build-log path, the triage JSON, the free-text input), so they are phase-enforced by contract, not OS-hookable.
|
|
193
|
+
Claude Code's `PreToolUse` exit-2 hooks are the HARD blocking gates. Three ship, none needing run-specific arguments so they are naturally hookable: (1) `pre-commit-check.sh` scans the staged diff on every `git commit` and blocks on a detected secret; (2) `agent-guard.sh` runs on `git commit` + `git push` and blocks AI/assistant attribution in a commit message and force-push to a protected branch (main/master/develop); (3) `check-read-size.sh` runs on `Read` and on the shell commands that read a file whole, and routes an oversized read to a cheap worker (`bulk-read.sh`) instead of the caller's own rung. The first two inspect what a run WRITES; the third inspects what it pays to READ, and it is inert until `bulkRead.mode` is set to `observe` or `enforce`, so merging the block changes nothing until the user opts in. Its `observe` mode blocks nothing and only logs, which is how the baseline is measured before anything is routed. All three are self-contained and never execute the inspected command. On an internal error they let the call through in an attended session; `agent-guard.sh` blocks instead under `MULTI_AGENT_UNATTENDED=1`, where nobody is watching to notice a gap. Three capture hooks ship in the same block and block nothing: `SessionEnd` runs `capture-flush.sh --if-stale` (writing a killed run's findings into the per-repo stores, so they do not depend on the run reaching Phase 5) plus `note-session.sh` (the mechanical shape of a non-pipeline session: tools used, commands that failed, calls the user refused - never an argument, never any output), `PreCompact` runs `capture-flush.sh` without `--if-stale` (a compaction summarizes a long phase mid-flight, so it is the moment unflushed findings are at risk; the staleness test exists only so a session exit does not re-flush a finished run, and both store writes are idempotent), and `SessionStart` runs `capture-resume.sh`, at most two lines about an unfinished run and a stale observation queue. None of them calls a model; all exit 0 on every path. One `PostToolUse` hook ships in the same block and blocks nothing either: `edit-syntax-gate.sh` on `Edit|Write|MultiEdit` parses the file the edit just wrote (`swiftc -parse`, `node --check`, `py_compile` into a temp dir, `JSON.parse`, `bash -n`; Kotlin is skipped, no parser answers inside its 2 s deadline) and hands a syntax error to the model as `additionalContext`; it is silent when a parser is missing or slow, and inert until `editSyntaxGate.enabled` is true. The syntax gate also runs on Codex, on `PostToolUse` for `apply_patch` (every file the patch adds, updates or moves to). `multi-agent:setup` Step 8 asks once and registers it there with `host-hooks.mjs install --host codex` from `install/templates/codex-hooks.json`: idempotent, leaving every other hook alone, `status` reports it and uninstall removes it. Codex runs it only after the user trusts it in `/hooks`, which the helper says. Copilot CLI gets no registration: as of 1.0.45 it discards a `postToolUse` hook's output and applies no matcher, so the gate would cost a spawn per tool call and say nothing. Every other registration here is Claude Code's. The recommended hook block ships at `install/templates/claude-hooks.json`; `multi-agent:setup` offers to merge it into `~/.claude/settings.json`. The other deterministic gates (evidence, consensus, intent, learnings) are invoked by the pipeline phases with per-run arguments (a build-log path, the triage JSON, the free-text input), so they are phase-enforced by contract, not OS-hookable.
|
|
193
194
|
|
|
194
195
|
Copilot CLI has no `PreToolUse` equivalent, so the secret scan there is workflow-enforced (run as a phase step, not OS-blocked) plus a CI smoke-gate step.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Reply shape
|
|
2
|
+
|
|
3
|
+
> Loaded on demand by `rules/response-shape.md`, which carries only the rules.
|
|
4
|
+
> This file holds the reasons, the word lists and the examples.
|
|
5
|
+
|
|
6
|
+
A reply is read by someone switching in from other work. The shape below lets
|
|
7
|
+
them act after reading the first and the last line, and find the detail in
|
|
8
|
+
between when they need it.
|
|
9
|
+
|
|
10
|
+
## Where it applies
|
|
11
|
+
|
|
12
|
+
| Output | Governed by |
|
|
13
|
+
|---|---|
|
|
14
|
+
| A reply in a conversation, inside or outside a run | this file |
|
|
15
|
+
| Run progress lines | the progress contract (`progress-contract.md`) |
|
|
16
|
+
| Phase 5 reports, PR bodies, Jira and Confluence text | their templates, then the humanizer skill |
|
|
17
|
+
|
|
18
|
+
The language is `prefs.global.outputLanguage`; nothing here depends on it.
|
|
19
|
+
|
|
20
|
+
## The rules, with their reasons
|
|
21
|
+
|
|
22
|
+
1. **Lead with the answer or the next action.** The first line is the one that
|
|
23
|
+
is always read. Openers that only announce the reply ("Great question",
|
|
24
|
+
"Let me take a look", "Sure! Here is...", "Harika soru", "Hemen bakıyorum")
|
|
25
|
+
spend it on nothing.
|
|
26
|
+
2. **Numbered steps, one action each.** A step that hides two actions is the
|
|
27
|
+
one that gets half done.
|
|
28
|
+
3. **At most five items per group, the rest as a count** ("and 7 more, listed
|
|
29
|
+
in the report"). This is display only. A finding, a failed check or a
|
|
30
|
+
verification caveat is never cut to fit; when they do not fit, they go to a
|
|
31
|
+
file and the reply names it. The verification rule in `CLAUDE.md` wins over
|
|
32
|
+
this one every time.
|
|
33
|
+
4. **Errors as cause, then fix.** "The build failed because X; fixed by Y" or
|
|
34
|
+
"...; needs Z from you". No apology paragraph.
|
|
35
|
+
5. **Finished work in concrete terms.** What changed (file, commit, version)
|
|
36
|
+
and how it was checked (which tests, which counts). "Done" alone is not a
|
|
37
|
+
report.
|
|
38
|
+
6. **Tangents at the end, one line.** Something noticed on the way is offered
|
|
39
|
+
("Also noticed X; want it fixed?"), not woven into the answer.
|
|
40
|
+
7. **Close with what happens next or what the user decides.** Not "Let me know
|
|
41
|
+
if you need anything else", "Hope this helps", "Başka bir şey olursa
|
|
42
|
+
söyle".
|
|
43
|
+
|
|
44
|
+
## When the task wins
|
|
45
|
+
|
|
46
|
+
- An explanation the user asked for runs as long as it needs, with headings.
|
|
47
|
+
- A destructive or outward-facing step is confirmed before it runs, whatever
|
|
48
|
+
that does to the shape.
|
|
49
|
+
- Real ambiguity gets one question, not a guess and not a questionnaire.
|
|
50
|
+
- Inside a run, the phase files and their templates decide the format; this
|
|
51
|
+
file only shapes the conversation around them.
|
|
52
|
+
|
|
53
|
+
## Example
|
|
54
|
+
|
|
55
|
+
Too long to act on:
|
|
56
|
+
|
|
57
|
+
> Great question! I looked into the failing build. It seems there might be an
|
|
58
|
+
> issue with the signing configuration, which could be caused by several
|
|
59
|
+
> things... Let me know if you want me to look further!
|
|
60
|
+
|
|
61
|
+
Shaped:
|
|
62
|
+
|
|
63
|
+
> The build fails on signing: the provisioning profile expired on 12.10.
|
|
64
|
+
> Renew it in the developer portal, then rerun `xcodebuild archive`.
|
|
65
|
+
> I can retry the archive once the new profile is installed.
|
|
@@ -146,11 +146,11 @@ acted on, not read.
|
|
|
146
146
|
#### Accounting is a gate, not a request
|
|
147
147
|
|
|
148
148
|
`update <N> completed` exits **3** for phases 1-4 when nothing was recorded via
|
|
149
|
-
`tokens`.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
a runtime omission; the tool that would have received the call can.
|
|
149
|
+
`tokens`. A doc that asks for the call, and a lint
|
|
150
|
+
(`smoke-tracker-tokens-invocation.sh`) that checks the doc *mentions* it, cannot
|
|
151
|
+
see a run that skips it: every phase would price at `-` and every completion line
|
|
152
|
+
would print without numbers while every gate passes. A lint over prose cannot
|
|
153
|
+
observe a runtime omission; the tool that would have received the call can.
|
|
154
154
|
|
|
155
155
|
The refusal is recoverable and loses no work:
|
|
156
156
|
|
|
@@ -160,7 +160,7 @@ phase-tracker.sh tokens <N> <in> <out> [cached]
|
|
|
160
160
|
phase-tracker.sh update <N> completed
|
|
161
161
|
```
|
|
162
162
|
|
|
163
|
-
`model` resolves a full model id to its cost-table family (`claude-opus-5` →
|
|
163
|
+
`model` resolves a full model id to its cost-table family (`claude-opus-5-5` →
|
|
164
164
|
`opus`) and says so out loud when it cannot, because an unpriced name is the
|
|
165
165
|
other way a phase silently costs nothing. A phase that truly ran no LLM call
|
|
166
166
|
completes with `--no-llm`, which is recorded and keeps it out of the run
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## Reply shape
|
|
2
|
+
|
|
3
|
+
For replies in a conversation. Reports, PR, Jira and Confluence bodies keep
|
|
4
|
+
their own templates; the humanizer governs their wording.
|
|
5
|
+
|
|
6
|
+
- First line: the answer or the next action. No preamble, no recap of the ask.
|
|
7
|
+
- Steps: numbered, one action each. Items: at most five shown, the rest named
|
|
8
|
+
as a count. That limit shapes the display only; never drop a finding, a
|
|
9
|
+
failure or a verification note to fit it.
|
|
10
|
+
- Errors: the cause, then the fix. Finished work: what changed, how it was
|
|
11
|
+
checked.
|
|
12
|
+
- Tangents wait for the end, as one line.
|
|
13
|
+
- Last line: what happens next, or what the user has to decide. No closing
|
|
14
|
+
pleasantries.
|
|
15
|
+
- An explanation asked for runs as long as it needs; a destructive step is
|
|
16
|
+
confirmed first; real ambiguity gets one question.
|
|
17
|
+
|
|
18
|
+
Detail and examples: `$HOME/.claude/multi-agent-refs/response-shape.md`.
|
|
@@ -782,9 +782,14 @@
|
|
|
782
782
|
"enum": ["component", "bugfix", "feature", "refactor", "chore"],
|
|
783
783
|
"description": "Phase 0 Step 7 classification. Phase 2 branches on it, and phase0-exit-gate.mjs fails a run that reaches Phase 1 without it. A Figma reference forces component."
|
|
784
784
|
},
|
|
785
|
+
"depBump": {
|
|
786
|
+
"type": ["object", "null"],
|
|
787
|
+
"additionalProperties": true,
|
|
788
|
+
"description": "A /multi-agent:deps run (state.mode \"deps\"): the bump dep-bump.mjs applied (ecosystem, name, manifest, from, to, risk, lock, alsoMoves, commitMessage), the fix rounds taken against depBump.maxFixRounds, the scope verdict and, when the cap was reached, rolledBack plus what still failed. Contract: multi-agent-refs/features/dep-bump.md."
|
|
789
|
+
},
|
|
785
790
|
"plan": {
|
|
786
791
|
"type": ["object", "null"],
|
|
787
|
-
"description": "The Phase 1 plan as a Todo list, written by plan-todos.sh when prefs.global.planTodos.enabled is true. Shape: plan-todos.schema.json, which plan-todos.sh validates on write; absent when the opt-in is off."
|
|
792
|
+
"description": "The Phase 1 plan as a Todo list, written by plan-todos.sh when prefs.global.planTodos.enabled is true. Shape: plan-todos.schema.json, which plan-todos.sh validates on write, including the optional todos[].type, the todos[].tdd evidence record, the drift record (the todo ended off-plan) and the needsReplan flag (a step it depends on drifted; it does not start until confirm-replan); absent when the opt-in is off."
|
|
788
793
|
},
|
|
789
794
|
"analysis": {
|
|
790
795
|
"type": ["object", "null"],
|
|
@@ -1246,6 +1251,20 @@
|
|
|
1246
1251
|
"type": "string",
|
|
1247
1252
|
"enum": ["fix", "accept", "escalate"]
|
|
1248
1253
|
},
|
|
1254
|
+
"reworkEscalation": {
|
|
1255
|
+
"type": "object",
|
|
1256
|
+
"additionalProperties": false,
|
|
1257
|
+
"required": ["escalate", "fromTier", "toTier", "trigger", "reason"],
|
|
1258
|
+
"description": "Written by rework-escalation.mjs --state before the rework dispatch this review sent back: the rung it ran on and why, a refusal included (multi-agent-refs/features/rework-escalation.md).",
|
|
1259
|
+
"properties": {
|
|
1260
|
+
"escalate": { "type": "boolean" },
|
|
1261
|
+
"fromTier": { "type": "string" },
|
|
1262
|
+
"toTier": { "type": "string" },
|
|
1263
|
+
"trigger": { "enum": ["last-round", "still-present", null] },
|
|
1264
|
+
"reason": { "type": "string" },
|
|
1265
|
+
"at": { "type": "string", "format": "date-time" }
|
|
1266
|
+
}
|
|
1267
|
+
},
|
|
1249
1268
|
"delta": {
|
|
1250
1269
|
"type": "object",
|
|
1251
1270
|
"additionalProperties": true,
|
|
@@ -2084,6 +2103,22 @@
|
|
|
2084
2103
|
"sha": { "type": "string" }
|
|
2085
2104
|
}
|
|
2086
2105
|
},
|
|
2106
|
+
"decisions": {
|
|
2107
|
+
"type": "array",
|
|
2108
|
+
"description": "Choices an autopilot run made where an attended run would have asked (multi-agent-refs/features/autopilot-decisions.md): parks (gate-ledger.mjs), blockers lowered to important (review-decision-gate.mjs), rework escalations (rework-escalation.mjs), pickers resolved without asking, split consensus taken on the triage verdict, a date-gate model fallback (decisions-log.mjs add). Written only while the quality gates are active. Rendered, redacted, in the Phase 5 report and appended to the autopilot PR body; an empty or absent list renders nothing.",
|
|
2109
|
+
"items": {
|
|
2110
|
+
"type": "object",
|
|
2111
|
+
"additionalProperties": false,
|
|
2112
|
+
"required": ["what", "why", "costIfWrong", "at", "phase"],
|
|
2113
|
+
"properties": {
|
|
2114
|
+
"what": { "type": "string", "minLength": 1, "maxLength": 200 },
|
|
2115
|
+
"why": { "type": "string", "minLength": 1, "maxLength": 500 },
|
|
2116
|
+
"costIfWrong": { "type": "string", "minLength": 1, "maxLength": 300 },
|
|
2117
|
+
"at": { "type": "string", "format": "date-time" },
|
|
2118
|
+
"phase": { "type": "integer", "minimum": 0, "maximum": 5 }
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
2121
|
+
},
|
|
2087
2122
|
"verificationFailed": {
|
|
2088
2123
|
"type": "object",
|
|
2089
2124
|
"additionalProperties": false,
|