@mmerterden/multi-agent-pipeline 16.21.0 → 16.24.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 +230 -103
- package/README.md +5 -7
- package/README.tr.md +5 -7
- package/docs/architecture.md +3 -3
- package/docs/ecosystem.md +5 -5
- package/install/templates/copilot-instructions.md +17 -2
- package/package.json +1 -1
- package/pipeline/commands/multi-agent/SKILL.md +0 -5
- package/pipeline/commands/multi-agent/help/SKILL.md +0 -10
- package/pipeline/commands/multi-agent/ios-coding-standard/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/local-autopilot/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/resume-local/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/sync/SKILL.md +13 -13
- package/pipeline/multi-agent-refs/channels/jira.md +7 -0
- package/pipeline/multi-agent-refs/channels/pr.md +16 -3
- package/pipeline/multi-agent-refs/cross-cli-contract.md +10 -12
- package/pipeline/multi-agent-refs/features/visual-evidence.md +172 -0
- package/pipeline/multi-agent-refs/generate-issue.md +3 -3
- package/pipeline/multi-agent-refs/phases/modes.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +9 -2
- package/pipeline/multi-agent-refs/phases/phase-3-dev.md +5 -1
- package/pipeline/multi-agent-refs/phases/phase-5-test.md +1 -0
- package/pipeline/multi-agent-refs/phases/phase-6-commit.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-7-report.md +8 -1
- package/pipeline/multi-agent-refs/tracker-contract.md +46 -0
- package/pipeline/schemas/agent-state.schema.json +269 -42
- package/pipeline/schemas/prefs.schema.json +45 -19
- package/pipeline/schemas/token-budget.json +3 -3
- package/pipeline/scripts/capture-evidence.sh +187 -0
- package/pipeline/scripts/jira-attach.sh +85 -0
- package/pipeline/scripts/phase-tracker.sh +245 -3
- package/pipeline/skills/.skill-manifest.json +8 -24
- package/pipeline/skills/.skills-index.json +2 -46
- package/pipeline/skills/shared/README.md +4 -8
- package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +0 -8
- package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-resume-local/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +12 -12
- package/pipeline/skills/skills-index.md +2 -6
- package/pipeline/commands/multi-agent/dev/SKILL.md +0 -17
- package/pipeline/commands/multi-agent/dev-autopilot/SKILL.md +0 -23
- package/pipeline/commands/multi-agent/dev-local/SKILL.md +0 -17
- package/pipeline/commands/multi-agent/dev-local-autopilot/SKILL.md +0 -21
- package/pipeline/skills/shared/core/multi-agent-dev/SKILL.md +0 -19
- package/pipeline/skills/shared/core/multi-agent-dev-autopilot/SKILL.md +0 -25
- package/pipeline/skills/shared/core/multi-agent-dev-local/SKILL.md +0 -19
- package/pipeline/skills/shared/core/multi-agent-dev-local-autopilot/SKILL.md +0 -23
|
@@ -241,11 +241,11 @@ curl -sS -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application
|
|
|
241
241
|
```
|
|
242
242
|
4. **Screenshot / image attachments** (only when opted in during preview - Figma render and/or user-pasted images):
|
|
243
243
|
```bash
|
|
244
|
-
|
|
245
|
-
-F "file=@/tmp/generate-issue-$$-figma.png" \
|
|
246
|
-
"https://$ACCOUNT_JIRA_HOST/rest/api/2/issue/${NEW_KEY}/attachments"
|
|
244
|
+
bash "$HOME/.claude/scripts/jira-attach.sh" "$NEW_KEY" /tmp/generate-issue-$$-figma.png
|
|
247
245
|
```
|
|
248
246
|
|
|
247
|
+
One uploader, shared with visual evidence: two copies of this call is two places for `X-Atlassian-Token: no-check` to go missing, which fails as a 403 that reads like an auth problem. It prints `<filename>\t<url>` per file.
|
|
248
|
+
|
|
249
249
|
### [12/12] Report
|
|
250
250
|
|
|
251
251
|
```
|
|
@@ -73,7 +73,7 @@ Bu is icin hangi pipeline? / Which pipeline for this task?
|
|
|
73
73
|
|
|
74
74
|
**Who is asked.** `/multi-agent` and `/multi-agent:local`. Both autopilot entries always run Full without asking.
|
|
75
75
|
|
|
76
|
-
**Why there is no fast-and-unattended combination.** It existed until v16.0.0
|
|
76
|
+
**Why there is no fast-and-unattended combination.** It existed until v16.0.0, and removing it was a real behaviour change, not a rename. Autopilot may not ask, so something has to choose, and unattended is the worst place to drop analysis and planning: nobody is watching to notice what the shortcut lost. A cron job or script that wants both now has to pick - stay unattended and pay for the full pipeline, or stay fast and have a person present.
|
|
77
77
|
|
|
78
78
|
**Pipeline in a Short run:**
|
|
79
79
|
|
|
@@ -12,16 +12,21 @@ $HOME/.claude/scripts/phase-tracker.sh init "$TASK_ID"
|
|
|
12
12
|
for p in 0:Init 1:Analysis 2:Planning 3:Dev 4:Review 5:Test 6:Commit 7:Report; do
|
|
13
13
|
$HOME/.claude/scripts/phase-tracker.sh add "${p%%:*}" "${p#*:}"
|
|
14
14
|
done
|
|
15
|
+
$HOME/.claude/scripts/phase-tracker.sh tiles
|
|
15
16
|
$HOME/.claude/scripts/phase-tracker.sh update 0 in_progress
|
|
16
17
|
```
|
|
17
18
|
|
|
19
|
+
`tiles` prints this host's widget-registration calls: **make them before continuing.** The card alone lands in collapsed tool output, so a run that skips them runs in silence. Contract: `tracker-contract.md`, "The card is not the widget".
|
|
20
|
+
|
|
18
21
|
If `INPUT_TASK_ID` isn't known yet (free-text, project not selected), use a placeholder; rename later via `mv` once parsed in Step 1.
|
|
19
22
|
|
|
20
|
-
Every subsequent phase (1-7) MUST call `phase-tracker.sh update <N> in_progress` on entry and `phase-tracker.sh update <N> completed|failed|skipped` on exit. Sub-phase milestones use `phase-tracker.sh sub <N> <subN> "<name>" <status>`. See `$HOME/.claude/multi-agent-refs/phases.md` "Visual Phase Tracker" for the full contract.
|
|
23
|
+
Every subsequent phase (1-7) MUST call `phase-tracker.sh update <N> in_progress` on entry and `phase-tracker.sh update <N> completed|failed|skipped` on exit. Each `update` prints a `-- NEXT (required) --` block: act on it. Sub-phase milestones use `phase-tracker.sh sub <N> <subN> "<name>" <status>`. See `$HOME/.claude/multi-agent-refs/phases.md` "Visual Phase Tracker" for the full contract.
|
|
24
|
+
|
|
25
|
+
`update <N> completed` **exits 3** for phases 1-4 with no recorded spend: record `model` + `tokens`, or pass `--no-llm`, then re-run it. Contract: `tracker-contract.md`, "Accounting is a gate".
|
|
21
26
|
|
|
22
27
|
##### TaskCreate ordering on Claude Code (strict)
|
|
23
28
|
|
|
24
|
-
On Claude Code, fire all `TaskCreate` calls in strict phase-number order (0 → 7) BEFORE any `TaskUpdate
|
|
29
|
+
On Claude Code, fire all `TaskCreate` calls in strict phase-number order (0 → 7) BEFORE any `TaskUpdate` - which is the order `tiles` prints them in. Full contract: `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "TaskCreate ordering (strict)".
|
|
25
30
|
|
|
26
31
|
---
|
|
27
32
|
|
|
@@ -88,6 +93,8 @@ Probe order:
|
|
|
88
93
|
1. **Tier 1 (Figma MCP)**: check the host serves `mcp__claude_ai_Figma__*` before probing. Absent → set `state.figmaAccess.tier1Unavailable = "host"` and fall through to Tier 2 with no probe, no re-auth retry, no MCP-token question. Present → probe `get_metadata(fileKey, nodeId)` on the first frame; on auth failure run `authenticate` + `complete_authentication` and retry once, and only a *second* failure raises the recreate-or-continue question. Success → `state.figmaAccess.tier = 1`.
|
|
89
94
|
2. **Tier 2 (Figma REST)**: when Tier 1 fails, resolve the PAT via `~/.claude/lib/credential-store.sh get <logical-key>` where `<logical-key>` = `prefs.global.keychainMapping.figma`. Probe `GET https://api.figma.com/v1/files/{fileKey}/nodes?ids={nodeId}` with header `X-Figma-Token: $TOKEN`. HTTP 200 → `state.figmaAccess.tier = 2`. Token missing / 401 / 403 → fall through.
|
|
90
95
|
3. **Tier 3 (User-attached screenshot)**: when Tiers 1 + 2 both fail, scan the task payload for inline screenshots or attachments. Present → `state.figmaAccess.tier = 3` and `state.figmaAccess.reviewBlocking = true` (Phase 4 enforces this).
|
|
96
|
+
|
|
97
|
+
Save the issue's image attachments to `$WORKTREE/.pipeline/evidence/` as `state.visualEvidence.before[]`: pre-fix evidence, never re-photographed, and none present is a recorded gap rather than a search. See `$HOME/.claude/multi-agent-refs/features/visual-evidence.md`.
|
|
91
98
|
4. **Halt**: all three tiers fail → emit a single AskUserQuestion asking the user how to proceed (provide PAT, paste a screenshot, abort). Never proceed with text-derived guesses.
|
|
92
99
|
|
|
93
100
|
Record the cause, not just the downshift. `tier1Unavailable = "host"` means the tier never existed here - routine on Copilot and Codex, where the installer registers only `multi-agent-toolkit`. `"auth"` means it existed and the credential failed, which on Claude Code points at a dead `figma_mcp` token worth surfacing in Phase 7. Conflating them costs two wasted MCP round trips and a question the user cannot act on. On those two hosts a mapped `figma` PAT is the primary path, not a fallback.
|
|
@@ -234,6 +234,10 @@ Gated by `prefs.global.devCritic.enabled` (default: `false`). When enabled, afte
|
|
|
234
234
|
|
|
235
235
|
---
|
|
236
236
|
|
|
237
|
+
#### Step 3.55 - Visual evidence capture (UI changes only)
|
|
238
|
+
|
|
239
|
+
When `state.visualEvidence.required`, capture the fixed state with the build that just went green: `capture-evidence.sh after --task "$TASK_ID" --platform "$PLATFORM" --label <slug>`. Here, not Phase 5, which every autopilot and `--local` entry drops. Exit 4 is a gap, not a failure. See `$HOME/.claude/multi-agent-refs/features/visual-evidence.md`.
|
|
240
|
+
|
|
237
241
|
#### Step 3.6 - Code-simplifier pass (required diff shrink, before Phase 4 handoff)
|
|
238
242
|
|
|
239
243
|
After the build/test green step and BEFORE Phase 4 handoff, run one diff-shrink round (bloated diffs waste Phase 4 reviewer tokens and unfocus the PR).
|
|
@@ -298,7 +302,7 @@ Set by the Phase 0 Step 7.5 depth picker, or by autopilot never (autopilot alway
|
|
|
298
302
|
|
|
299
303
|
Because the agent determines its own scope here, Phase 4 is the only place that checks the result against anything external. Record every skill, plugin skill and guide consulted during this phase into `state.telemetry.skillCalls[]` with the files it was applied to - Phase 4 resolves the criteria set independently, and this record is what lets it tell "applied and honoured" from "never opened".
|
|
300
304
|
|
|
301
|
-
**Never combined with autopilot.** Autopilot skips the depth question and runs Full, so `onlyDevelop` is false in every unattended run. "Fast plus unattended" was
|
|
305
|
+
**Never combined with autopilot.** Autopilot skips the depth question and runs Full, so `onlyDevelop` is false in every unattended run. "Fast plus unattended" was removed in v16.0.0 and no longer exists: something has to choose when nobody is asked, and unattended is the worst place to drop analysis and planning.
|
|
302
306
|
|
|
303
307
|
**Tracker visibility during Opus dispatch**: on Claude Code the model switch to Opus happens via subagent dispatch, and the parent widget cannot move while an Agent call is in flight. Dispatch per task from the self-generated task list (never one monolithic call for the whole phase), set the pre-dispatch `activeForm` marker, and record tokens between chunks - full rules in `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "Delegated phases".
|
|
304
308
|
|
|
@@ -138,6 +138,7 @@ Before or during user testing, run device-level audits via Bash if user requests
|
|
|
138
138
|
|
|
139
139
|
| Check | When | Command |
|
|
140
140
|
| ------------------- | ----------------- | ----------------------------------------- |
|
|
141
|
+
| UI flow video | `state.visualEvidence.required` | 3 tiers, cap from `capture-evidence.sh limits` (`visualEvidence.maxVideoSeconds`) - `$HOME/.claude/multi-agent-refs/features/visual-evidence.md` |
|
|
141
142
|
| Accessibility audit | UI changes | `mcp__multi-agent-toolkit__{ios,android}_accessibility_audit` |
|
|
142
143
|
| Biometric test | Auth flow changes | ios: `mcp__multi-agent-toolkit__ios_biometric` (android: manual) |
|
|
143
144
|
| Launch time | Perf-sensitive changes | ios: app-launch instrument · android: `mcp__multi-agent-toolkit__android_launch_time` |
|
|
@@ -136,7 +136,7 @@ Branch **deterministically**, no implicit fallback. Read `agent-state.json` and
|
|
|
136
136
|
|
|
137
137
|
Generate a structured PR description based on task type. The PR body targets **code reviewers** - it should be technical: what changed, why, architecture decisions, how to verify.
|
|
138
138
|
|
|
139
|
-
Two inputs are read from state and the worktree before writing, not recalled from the conversation: `$WORKTREE/.pipeline/scope-check.json` (Phase 3 Step 3.7) supplies the `## Changes` bullets from `files[].reason` and the "Follow-ups not done in this PR" list under `## Related` from `notDone[]`; `state.diffRisk.signals` (Phase 4 Step 1.75) decides whether the conditional `## Risk and Security` section is required. When a high-stakes signal is present and the section is missing, this step blocks until it is written; a placeholder answer ("TBD") counts as missing.
|
|
139
|
+
Two inputs are read from state and the worktree before writing, not recalled from the conversation: `$WORKTREE/.pipeline/scope-check.json` (Phase 3 Step 3.7) supplies the `## Changes` bullets from `files[].reason` and the "Follow-ups not done in this PR" list under `## Related` from `notDone[]`; `state.diffRisk.signals` (Phase 4 Step 1.75) decides whether the conditional `## Risk and Security` section is required. When a high-stakes signal is present and the section is missing, this step blocks until it is written; a placeholder answer ("TBD") counts as missing. `state.visualEvidence.required` blocks the same way: every required artefact is either attached or carries a recorded reason in `gaps[]` - the gate is against silence, not against an honest "no image on the ticket".
|
|
140
140
|
|
|
141
141
|
**required**: Run all generated text (PR body, commit message) through the `humanizer` skill before posting. This removes AI-generated patterns (inflated language, filler phrases, repetitive structure) and makes the output sound like a developer wrote it.
|
|
142
142
|
|
|
@@ -251,7 +251,14 @@ fi
|
|
|
251
251
|
|
|
252
252
|
The ledger is JSONL at `~/.claude/memory/multi-agent/<repo-slug>/learnings-ledger.jsonl`, next to the triage corpus, per-repo isolated. Its brief is replayed into Phase 1 analysis and Phase 4 triage on future runs.
|
|
253
253
|
|
|
254
|
-
Print
|
|
254
|
+
Print the closing report to the terminal. Two blocks, in this order - what the pipeline spent, then what it changed:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
bash $HOME/.claude/scripts/phase-tracker.sh report
|
|
258
|
+
bash $HOME/.claude/scripts/render-work-summary.sh "$TASK_ID" --worktree "$WORKTREE_PATH"
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
`report` prices the run phase by phase; `render-work-summary.sh` says what changed on disk. Both land in tool output, which the host collapses, so **reprint them in your reply** followed by this line:
|
|
255
262
|
|
|
256
263
|
```
|
|
257
264
|
{jiraId} complete
|
|
@@ -103,6 +103,52 @@ For each phase in the current mode, IN PHASE-NUMBER ORDER (0 → 1 → 2 → ...
|
|
|
103
103
|
|
|
104
104
|
The `tasklist_id` meta field is persisted so that `:resume` can rebuild the TaskList from the state file in a fresh session.
|
|
105
105
|
|
|
106
|
+
#### The card is not the widget
|
|
107
|
+
|
|
108
|
+
`phase-tracker.sh render` prints a bordered ANSI card to stdout, and every
|
|
109
|
+
supported host collapses tool output into a one-line summary (`Ran 8 shell
|
|
110
|
+
commands`). A run whose only progress signal is that card is a run the user
|
|
111
|
+
watches in silence - which is exactly what happened: the card was correct on
|
|
112
|
+
disk and invisible on screen.
|
|
113
|
+
|
|
114
|
+
So each host has a widget, and the tracker names the calls rather than assuming
|
|
115
|
+
the agent remembers them:
|
|
116
|
+
|
|
117
|
+
| Host | Widget | How it is registered |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| Claude Code | native TaskList tiles | `TaskCreate` per phase, then `TaskUpdate` per boundary |
|
|
120
|
+
| Codex CLI | native plan steps | one `update_plan` carrying the FULL step list, resent per boundary |
|
|
121
|
+
| Copilot CLI | none exists | the card itself, reprinted inside the agent's reply |
|
|
122
|
+
|
|
123
|
+
`phase-tracker.sh tiles` prints the registration calls for the host it runs on,
|
|
124
|
+
read from the phase set already registered by `add`. Every `update` then prints
|
|
125
|
+
a `-- NEXT (required) --` block with that host's mirror call and, on completion,
|
|
126
|
+
the narration line built from what was actually recorded. Both are printed to be
|
|
127
|
+
acted on, not read.
|
|
128
|
+
|
|
129
|
+
#### Accounting is a gate, not a request
|
|
130
|
+
|
|
131
|
+
`update <N> completed` exits **3** for phases 1-4 when nothing was recorded via
|
|
132
|
+
`tokens`. The alternative is what shipped for months: the docs asked for the
|
|
133
|
+
call, `smoke-tracker-tokens-invocation.sh` linted that the docs *mention* the
|
|
134
|
+
call, and no run made it - every phase priced at `-`, every completion line
|
|
135
|
+
printed without numbers, and every gate green. A lint over prose cannot observe
|
|
136
|
+
a runtime omission; the tool that would have received the call can.
|
|
137
|
+
|
|
138
|
+
The refusal is recoverable and loses no work:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
phase-tracker.sh model <N> <model_name>
|
|
142
|
+
phase-tracker.sh tokens <N> <in> <out> [cached]
|
|
143
|
+
phase-tracker.sh update <N> completed
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`model` resolves a full model id to its cost-table family (`claude-opus-5` →
|
|
147
|
+
`opus`) and says so out loud when it cannot, because an unpriced name is the
|
|
148
|
+
other way a phase silently costs nothing. A phase that truly ran no LLM call
|
|
149
|
+
completes with `--no-llm`, which is recorded and keeps it out of the run
|
|
150
|
+
report's cost-unavailable list.
|
|
151
|
+
|
|
106
152
|
#### TaskCreate ordering (strict)
|
|
107
153
|
|
|
108
154
|
**The native TaskList widget renders tiles in TaskCreate creation order, NOT by phase-number metadata.** Therefore:
|
|
@@ -244,7 +244,7 @@
|
|
|
244
244
|
"onlyDevelop": {
|
|
245
245
|
"type": "boolean",
|
|
246
246
|
"default": false,
|
|
247
|
-
"description": "Short pipeline - phases 1 and 2 are skipped. Set by the Phase 0 Step 7.5 depth picker as of v16.0.0
|
|
247
|
+
"description": "Short pipeline - phases 1 and 2 are skipped. Set by the Phase 0 Step 7.5 depth picker as of v16.0.0; the key and every reader of it are unchanged. Phase 4 Review still runs (v14.0.0+). Always false in an autopilot run, which never asks the depth question."
|
|
248
248
|
},
|
|
249
249
|
"localMode": {
|
|
250
250
|
"type": "boolean",
|
|
@@ -272,7 +272,9 @@
|
|
|
272
272
|
},
|
|
273
273
|
"docPath": {
|
|
274
274
|
"type": "array",
|
|
275
|
-
"items": {
|
|
275
|
+
"items": {
|
|
276
|
+
"type": "string"
|
|
277
|
+
},
|
|
276
278
|
"description": "One emitted path per selected platform."
|
|
277
279
|
},
|
|
278
280
|
"frontMatter": {
|
|
@@ -604,7 +606,9 @@
|
|
|
604
606
|
},
|
|
605
607
|
"failing": {
|
|
606
608
|
"type": "array",
|
|
607
|
-
"items": {
|
|
609
|
+
"items": {
|
|
610
|
+
"type": "string"
|
|
611
|
+
},
|
|
608
612
|
"description": "Identifiers of tests already failing before this run. Empty on a red status means the output could not be parsed into names: the evidence is then the logPath alone, and Phase 4 reports 'inherited red, not attributable' rather than inventing a set."
|
|
609
613
|
},
|
|
610
614
|
"logPath": {
|
|
@@ -655,17 +659,28 @@
|
|
|
655
659
|
"additionalProperties": true,
|
|
656
660
|
"description": "Written by Phase 4 Step 3.8 from review-delta.mjs: how this round's accepted findings relate to the previous round's rework mandate. Absent on iteration 1 and on runs from before the delta existed.",
|
|
657
661
|
"properties": {
|
|
658
|
-
"previousIteration": {
|
|
662
|
+
"previousIteration": {
|
|
663
|
+
"type": "integer",
|
|
664
|
+
"minimum": 1
|
|
665
|
+
},
|
|
659
666
|
"new": {
|
|
660
667
|
"type": "array",
|
|
661
668
|
"items": {
|
|
662
669
|
"type": "object",
|
|
663
670
|
"additionalProperties": true,
|
|
664
671
|
"properties": {
|
|
665
|
-
"fingerprint": {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
"
|
|
672
|
+
"fingerprint": {
|
|
673
|
+
"type": "string"
|
|
674
|
+
},
|
|
675
|
+
"severity": {
|
|
676
|
+
"type": ["string", "null"]
|
|
677
|
+
},
|
|
678
|
+
"file": {
|
|
679
|
+
"type": ["string", "null"]
|
|
680
|
+
},
|
|
681
|
+
"issue": {
|
|
682
|
+
"type": ["string", "null"]
|
|
683
|
+
}
|
|
669
684
|
}
|
|
670
685
|
}
|
|
671
686
|
},
|
|
@@ -675,10 +690,18 @@
|
|
|
675
690
|
"type": "object",
|
|
676
691
|
"additionalProperties": true,
|
|
677
692
|
"properties": {
|
|
678
|
-
"fingerprint": {
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
"
|
|
693
|
+
"fingerprint": {
|
|
694
|
+
"type": "string"
|
|
695
|
+
},
|
|
696
|
+
"severity": {
|
|
697
|
+
"type": ["string", "null"]
|
|
698
|
+
},
|
|
699
|
+
"file": {
|
|
700
|
+
"type": ["string", "null"]
|
|
701
|
+
},
|
|
702
|
+
"issue": {
|
|
703
|
+
"type": ["string", "null"]
|
|
704
|
+
}
|
|
682
705
|
}
|
|
683
706
|
}
|
|
684
707
|
},
|
|
@@ -688,10 +711,18 @@
|
|
|
688
711
|
"type": "object",
|
|
689
712
|
"additionalProperties": true,
|
|
690
713
|
"properties": {
|
|
691
|
-
"fingerprint": {
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
"
|
|
714
|
+
"fingerprint": {
|
|
715
|
+
"type": "string"
|
|
716
|
+
},
|
|
717
|
+
"severity": {
|
|
718
|
+
"type": ["string", "null"]
|
|
719
|
+
},
|
|
720
|
+
"file": {
|
|
721
|
+
"type": ["string", "null"]
|
|
722
|
+
},
|
|
723
|
+
"issue": {
|
|
724
|
+
"type": ["string", "null"]
|
|
725
|
+
}
|
|
695
726
|
}
|
|
696
727
|
}
|
|
697
728
|
},
|
|
@@ -701,10 +732,18 @@
|
|
|
701
732
|
"type": "object",
|
|
702
733
|
"additionalProperties": true,
|
|
703
734
|
"properties": {
|
|
704
|
-
"fingerprint": {
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
"
|
|
735
|
+
"fingerprint": {
|
|
736
|
+
"type": "string"
|
|
737
|
+
},
|
|
738
|
+
"severity": {
|
|
739
|
+
"type": ["string", "null"]
|
|
740
|
+
},
|
|
741
|
+
"file": {
|
|
742
|
+
"type": ["string", "null"]
|
|
743
|
+
},
|
|
744
|
+
"issue": {
|
|
745
|
+
"type": ["string", "null"]
|
|
746
|
+
}
|
|
708
747
|
}
|
|
709
748
|
}
|
|
710
749
|
},
|
|
@@ -714,24 +753,40 @@
|
|
|
714
753
|
"type": "object",
|
|
715
754
|
"additionalProperties": true,
|
|
716
755
|
"properties": {
|
|
717
|
-
"fingerprint": {
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
"
|
|
756
|
+
"fingerprint": {
|
|
757
|
+
"type": "string"
|
|
758
|
+
},
|
|
759
|
+
"severity": {
|
|
760
|
+
"type": ["string", "null"]
|
|
761
|
+
},
|
|
762
|
+
"file": {
|
|
763
|
+
"type": ["string", "null"]
|
|
764
|
+
},
|
|
765
|
+
"issue": {
|
|
766
|
+
"type": ["string", "null"]
|
|
767
|
+
}
|
|
721
768
|
}
|
|
722
769
|
}
|
|
723
770
|
},
|
|
724
771
|
"recurrence": {
|
|
725
772
|
"type": "object",
|
|
726
|
-
"additionalProperties": {
|
|
773
|
+
"additionalProperties": {
|
|
774
|
+
"type": "integer",
|
|
775
|
+
"minimum": 1
|
|
776
|
+
},
|
|
727
777
|
"description": "fingerprint -> consecutive rework cycles the finding has survived."
|
|
728
778
|
},
|
|
729
779
|
"plateau": {
|
|
730
780
|
"type": "boolean",
|
|
731
781
|
"description": "The still-present set is unchanged from the previous delta and non-empty."
|
|
732
782
|
},
|
|
733
|
-
"tripped": {
|
|
734
|
-
|
|
783
|
+
"tripped": {
|
|
784
|
+
"type": "boolean"
|
|
785
|
+
},
|
|
786
|
+
"computedAt": {
|
|
787
|
+
"type": "string",
|
|
788
|
+
"format": "date-time"
|
|
789
|
+
}
|
|
735
790
|
}
|
|
736
791
|
},
|
|
737
792
|
"reviewers": {
|
|
@@ -768,7 +823,9 @@
|
|
|
768
823
|
},
|
|
769
824
|
"labelToModel": {
|
|
770
825
|
"type": "object",
|
|
771
|
-
"additionalProperties": {
|
|
826
|
+
"additionalProperties": {
|
|
827
|
+
"type": "string"
|
|
828
|
+
},
|
|
772
829
|
"description": "Source A|B|C -> model name. \"unknown\" for a reviewer entry that declared no model."
|
|
773
830
|
}
|
|
774
831
|
}
|
|
@@ -789,25 +846,51 @@
|
|
|
789
846
|
"description": "Autopilot circuit-breaker record (refs/features/autopilot-circuit-breaker.md). Written only when a trigger trips: trigger 2 by Phase 4 Step 3.8 (a mandate finding survived identicalFindingCycles rework cycles), trigger 3 by the Phase 3 re-entry hard-kill. /multi-agent:resume clears tripped and keeps counters.",
|
|
790
847
|
"required": ["tripped"],
|
|
791
848
|
"properties": {
|
|
792
|
-
"tripped": {
|
|
793
|
-
|
|
794
|
-
|
|
849
|
+
"tripped": {
|
|
850
|
+
"type": "boolean"
|
|
851
|
+
},
|
|
852
|
+
"trigger": {
|
|
853
|
+
"type": ["integer", "null"],
|
|
854
|
+
"minimum": 1,
|
|
855
|
+
"maximum": 5
|
|
856
|
+
},
|
|
857
|
+
"detail": {
|
|
858
|
+
"type": "string"
|
|
859
|
+
},
|
|
795
860
|
"checkpoint": {
|
|
796
861
|
"type": "object",
|
|
797
862
|
"additionalProperties": false,
|
|
798
863
|
"properties": {
|
|
799
|
-
"phase": {
|
|
800
|
-
|
|
801
|
-
|
|
864
|
+
"phase": {
|
|
865
|
+
"type": "integer",
|
|
866
|
+
"minimum": 0,
|
|
867
|
+
"maximum": 7
|
|
868
|
+
},
|
|
869
|
+
"step": {
|
|
870
|
+
"type": "string"
|
|
871
|
+
},
|
|
872
|
+
"iteration": {
|
|
873
|
+
"type": "integer",
|
|
874
|
+
"minimum": 1
|
|
875
|
+
}
|
|
802
876
|
}
|
|
803
877
|
},
|
|
804
|
-
"trippedAt": {
|
|
878
|
+
"trippedAt": {
|
|
879
|
+
"type": "string",
|
|
880
|
+
"format": "date-time"
|
|
881
|
+
},
|
|
805
882
|
"counters": {
|
|
806
883
|
"type": "object",
|
|
807
884
|
"additionalProperties": false,
|
|
808
885
|
"properties": {
|
|
809
|
-
"identicalFindingCycles": {
|
|
810
|
-
|
|
886
|
+
"identicalFindingCycles": {
|
|
887
|
+
"type": "integer",
|
|
888
|
+
"minimum": 0
|
|
889
|
+
},
|
|
890
|
+
"reworkCycles": {
|
|
891
|
+
"type": "integer",
|
|
892
|
+
"minimum": 0
|
|
893
|
+
}
|
|
811
894
|
}
|
|
812
895
|
}
|
|
813
896
|
}
|
|
@@ -817,13 +900,26 @@
|
|
|
817
900
|
"additionalProperties": true,
|
|
818
901
|
"description": "Totals from diff-risk-score.mjs, persisted by Phase 4 Step 1.75 so Phase 6 (PR risk section), Phase 7 and run-metrics.mjs read the same numbers the review scope decision used.",
|
|
819
902
|
"properties": {
|
|
820
|
-
"files": {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
903
|
+
"files": {
|
|
904
|
+
"type": "integer",
|
|
905
|
+
"minimum": 0
|
|
906
|
+
},
|
|
907
|
+
"loc_added": {
|
|
908
|
+
"type": "integer",
|
|
909
|
+
"minimum": 0
|
|
910
|
+
},
|
|
911
|
+
"loc_removed": {
|
|
912
|
+
"type": "integer",
|
|
913
|
+
"minimum": 0
|
|
914
|
+
},
|
|
915
|
+
"max_score": {
|
|
916
|
+
"type": "number"
|
|
917
|
+
},
|
|
824
918
|
"signals": {
|
|
825
919
|
"type": "array",
|
|
826
|
-
"items": {
|
|
920
|
+
"items": {
|
|
921
|
+
"type": "string"
|
|
922
|
+
},
|
|
827
923
|
"description": "Distinct signal names seen across files (security_path, migration, public_api, no_test_change, test_lines_removed, ...)."
|
|
828
924
|
}
|
|
829
925
|
}
|
|
@@ -1001,6 +1097,137 @@
|
|
|
1001
1097
|
"artifactsPath": {
|
|
1002
1098
|
"type": ["string", "null"],
|
|
1003
1099
|
"description": "Directory the worktree's artefacts were salvaged into before removal (agent-state, phase-tracker, triage-output, .pipeline/, build+test logs, review diff). Phase 7 and :resume read from here when worktreePath is gone."
|
|
1100
|
+
},
|
|
1101
|
+
"visualEvidence": {
|
|
1102
|
+
"type": ["object", "null"],
|
|
1103
|
+
"additionalProperties": false,
|
|
1104
|
+
"description": "Before/after screenshots and the UI flow video for a UI change, attached to the Jira issue and rendered in the Phase 7 comment and the PR body. Required decided mechanically from taskType plus the changed-file list. Contract: multi-agent-refs/features/visual-evidence.md.",
|
|
1105
|
+
"properties": {
|
|
1106
|
+
"required": {
|
|
1107
|
+
"type": "boolean"
|
|
1108
|
+
},
|
|
1109
|
+
"requiredBy": {
|
|
1110
|
+
"type": "string",
|
|
1111
|
+
"description": "Which rule made it required, e.g. 'bugfix + ui-file-changed'."
|
|
1112
|
+
},
|
|
1113
|
+
"platform": {
|
|
1114
|
+
"type": "string",
|
|
1115
|
+
"enum": ["ios", "android", "web", "other"]
|
|
1116
|
+
},
|
|
1117
|
+
"before": {
|
|
1118
|
+
"type": "array",
|
|
1119
|
+
"items": {
|
|
1120
|
+
"type": "object",
|
|
1121
|
+
"additionalProperties": true,
|
|
1122
|
+
"properties": {
|
|
1123
|
+
"file": {
|
|
1124
|
+
"type": "string",
|
|
1125
|
+
"description": "Local path under $WORKTREE/.pipeline/evidence/."
|
|
1126
|
+
},
|
|
1127
|
+
"source": {
|
|
1128
|
+
"type": "string",
|
|
1129
|
+
"enum": ["ticket", "capture"]
|
|
1130
|
+
},
|
|
1131
|
+
"capturedAt": {
|
|
1132
|
+
"type": "string",
|
|
1133
|
+
"description": "Phase that produced it, e.g. 'phase-3'."
|
|
1134
|
+
},
|
|
1135
|
+
"jiraFilename": {
|
|
1136
|
+
"type": "string",
|
|
1137
|
+
"description": "Attachment filename the Jira comment references."
|
|
1138
|
+
},
|
|
1139
|
+
"url": {
|
|
1140
|
+
"type": "string",
|
|
1141
|
+
"description": "Jira attachment content URL."
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
},
|
|
1145
|
+
"description": "Images taken from the issue's own attachments. The pipeline never rebuilds the pre-fix state to photograph it; no ticket image means no before, recorded as a gap."
|
|
1146
|
+
},
|
|
1147
|
+
"after": {
|
|
1148
|
+
"type": "array",
|
|
1149
|
+
"items": {
|
|
1150
|
+
"type": "object",
|
|
1151
|
+
"additionalProperties": true,
|
|
1152
|
+
"properties": {
|
|
1153
|
+
"file": {
|
|
1154
|
+
"type": "string",
|
|
1155
|
+
"description": "Local path under $WORKTREE/.pipeline/evidence/."
|
|
1156
|
+
},
|
|
1157
|
+
"source": {
|
|
1158
|
+
"type": "string",
|
|
1159
|
+
"enum": ["ticket", "capture"]
|
|
1160
|
+
},
|
|
1161
|
+
"capturedAt": {
|
|
1162
|
+
"type": "string",
|
|
1163
|
+
"description": "Phase that produced it, e.g. 'phase-3'."
|
|
1164
|
+
},
|
|
1165
|
+
"jiraFilename": {
|
|
1166
|
+
"type": "string",
|
|
1167
|
+
"description": "Attachment filename the Jira comment references."
|
|
1168
|
+
},
|
|
1169
|
+
"url": {
|
|
1170
|
+
"type": "string",
|
|
1171
|
+
"description": "Jira attachment content URL."
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
},
|
|
1175
|
+
"description": "Captured in Phase 3 after the build+test gate, because Phase 5 is dropped by every autopilot and --local entry."
|
|
1176
|
+
},
|
|
1177
|
+
"videoTier": {
|
|
1178
|
+
"type": ["integer", "null"],
|
|
1179
|
+
"enum": [1, 2, 3, null],
|
|
1180
|
+
"description": "1 = the repo's own UI test target drove the flow, 2 = MCP-driven flow, 3 = no runnable build."
|
|
1181
|
+
},
|
|
1182
|
+
"video": {
|
|
1183
|
+
"type": "object",
|
|
1184
|
+
"additionalProperties": true,
|
|
1185
|
+
"properties": {
|
|
1186
|
+
"file": {
|
|
1187
|
+
"type": "string",
|
|
1188
|
+
"description": "Local path under $WORKTREE/.pipeline/evidence/."
|
|
1189
|
+
},
|
|
1190
|
+
"source": {
|
|
1191
|
+
"type": "string",
|
|
1192
|
+
"enum": ["ticket", "capture"]
|
|
1193
|
+
},
|
|
1194
|
+
"capturedAt": {
|
|
1195
|
+
"type": "string",
|
|
1196
|
+
"description": "Phase that produced it, e.g. 'phase-3'."
|
|
1197
|
+
},
|
|
1198
|
+
"jiraFilename": {
|
|
1199
|
+
"type": "string",
|
|
1200
|
+
"description": "Attachment filename the Jira comment references."
|
|
1201
|
+
},
|
|
1202
|
+
"url": {
|
|
1203
|
+
"type": "string",
|
|
1204
|
+
"description": "Jira attachment content URL."
|
|
1205
|
+
},
|
|
1206
|
+
"seconds": {
|
|
1207
|
+
"type": "number",
|
|
1208
|
+
"description": "Recorded duration; capped at 60."
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
},
|
|
1212
|
+
"gaps": {
|
|
1213
|
+
"type": "array",
|
|
1214
|
+
"description": "Every artefact that is required and absent, with its reason. A recorded reason satisfies the Phase 6 blocker; silence does not.",
|
|
1215
|
+
"items": {
|
|
1216
|
+
"type": "object",
|
|
1217
|
+
"additionalProperties": false,
|
|
1218
|
+
"properties": {
|
|
1219
|
+
"what": {
|
|
1220
|
+
"type": "string",
|
|
1221
|
+
"enum": ["before", "after", "video"]
|
|
1222
|
+
},
|
|
1223
|
+
"reason": {
|
|
1224
|
+
"type": "string"
|
|
1225
|
+
}
|
|
1226
|
+
},
|
|
1227
|
+
"required": ["what", "reason"]
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1004
1231
|
}
|
|
1005
1232
|
}
|
|
1006
1233
|
}
|