@mmerterden/multi-agent-pipeline 16.23.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 +22 -0
- package/package.json +1 -1
- 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/features/visual-evidence.md +172 -0
- package/pipeline/multi-agent-refs/generate-issue.md +3 -3
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +2 -0
- package/pipeline/multi-agent-refs/phases/phase-3-dev.md +4 -0
- 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/schemas/agent-state.schema.json +268 -41
- package/pipeline/schemas/prefs.schema.json +45 -19
- package/pipeline/schemas/token-budget.json +2 -2
- package/pipeline/scripts/capture-evidence.sh +187 -0
- package/pipeline/scripts/jira-attach.sh +85 -0
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,28 @@ Internal file-layout changes that don't affect the slash-command surface are sti
|
|
|
16
16
|
|
|
17
17
|
## [Unreleased]
|
|
18
18
|
|
|
19
|
+
## [16.24.0] - 2026-09-09
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **A UI fix now carries its picture.** Three changed files in a diff do not tell a reviewer what was wrong, and they do not tell a tester what to look for. When `taskType` is `bugfix` and a UI file changed, the run produces a before/after pair; when the work is design (a `component` task, a Figma reference, or a UI file that did not exist before), it produces the after. The verdict comes from `taskType` plus the changed-file list, mechanically, not from the model's reading of the task - the UI-file test is per stack and written down.
|
|
24
|
+
|
|
25
|
+
**Before is the reporter's screenshot, or nothing.** Rebuilding the pre-fix state to photograph it costs a second build and a second launch on every UI bug, to recreate evidence the reporter usually attached already. So Phase 0 keeps the issue's own image attachments and that is the whole of it; no image on the ticket is a recorded gap, not a search.
|
|
26
|
+
|
|
27
|
+
**After is captured in Phase 3, not Phase 5.** Phase 5 is the natural home - the simulator is already up - and it is dropped by every `autopilot` and `--local` entry, so a capture living only there produces nothing for exactly the runs nobody watched. It happens instead right after the build+test gate goes green, which is in every mode's phase set. `capture-evidence.sh` owns the naming, cleans the status bar (two shots of one screen otherwise differ by the clock, which makes every "after" look like a change) and downscales to 1242px.
|
|
28
|
+
|
|
29
|
+
- **The flow video, in three tiers, so no repo is excluded by not having a test target.** Tier 1 runs the repo's own XCUITest/Espresso target when it can be seeded with test data - the most faithful record, and it is a test that already runs in CI. Tier 2 drives the flow with `agent_run_steps` and records with `ios_record_video` / `android_record_screen`, needing nothing but a launchable build. Tier 3 is the honest skip for a library or a backend, with the reason recorded. The flow itself comes from the ticket when someone wrote one there, and from the Phase 5 test scenarios otherwise: human-written beats generated, the same rule the before follows.
|
|
30
|
+
|
|
31
|
+
- **Where they land.** The artefacts are Jira attachments. The Phase 7 comment renders them _inside_ its existing sections rather than adding a fourth - the section order is fixed and the contract says so - with the before/after thumbnails under the work summary and the flow video under the scenario it demonstrates. The PR body gains a `visuals` section that names the filenames and the ticket, deliberately not the URLs: a Jira attachment URL is auth-gated and renders as a broken image for anyone reading the PR outside a Jira session.
|
|
32
|
+
|
|
33
|
+
- **Degrading quality is allowed; dropping the artefact is not.** Jira's ceiling is an instance setting, so it is a preference (`visualEvidence.maxAttachmentMb`, default 10). Over it, a video re-encodes to 720p and a screenshot to JPEG q80; still over, the video becomes a four-frame contact sheet that says why. Phase 6 Step 3 blocks when a required artefact is neither attached nor explained - the gate is against silence, not against an honest "the ticket carries no image".
|
|
34
|
+
|
|
35
|
+
- **`smoke-visual-evidence.sh`** - 32 checks, most of them about stated absence being as required as stated presence: both scripts refuse bad input rather than guessing, the size ladder never returns an empty path, all four phases act, both renderers know where pictures go, the schemas declare the fields, and no ref re-implements the attachment POST.
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- **One Jira uploader instead of two.** `generate-issue.md` carried its own attachment `curl`; visual evidence would have been the second copy, and two copies is two places for `X-Atlassian-Token: no-check` to go missing - which fails as a 403 that reads like an auth problem. Both now call `jira-attach.sh`, which resolves host and token from prefs, keeps the token out of argv, and prints `<filename>\t<url>` per file.
|
|
40
|
+
|
|
19
41
|
## [16.23.0] - 2026-09-09
|
|
20
42
|
|
|
21
43
|
### Fixed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmerterden/multi-agent-pipeline",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.24.0",
|
|
4
4
|
"description": "8-phase AI development pipeline with full orchestration on Claude Code, Copilot CLI and Codex CLI. Analysis, planning, TDD, CLI-aware parallel review with consensus surfacing + Fable triage, default-FAIL evidence gates, secret + intent guards, per-phase cost ledger, persistent learnings memory, wiki generation, commit automation. Token-preserving uninstall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -20,6 +20,13 @@ Every Jira comment posted by this adapter follows the same section order. Sectio
|
|
|
20
20
|
|
|
21
21
|
**`summary`** - 2-5 sentences in `outputLanguage`. What changed, why, and the user-visible impact. No "we", no marketing tone. Past tense (the work is done at the time the comment goes up).
|
|
22
22
|
|
|
23
|
+
**Visual evidence inside these two sections.** When `state.visualEvidence` carries artefacts, they render INSIDE `summary` and `test_scenarios` - never as a fourth section, which the fixed section order forbids. Upload first (`jira-attach.sh <issue> <file>...`), then reference by the returned filename:
|
|
24
|
+
|
|
25
|
+
- `summary`, after its sentences: one line naming the pair in `outputLanguage` (`Düzeltme öncesi / Düzeltme sonrası`), then the thumbnails on the next line - `!<file>-before.png|thumbnail! !<file>-after.png|thumbnail!`.
|
|
26
|
+
- `test_scenarios`, under the scenario the recording demonstrates: `!<file>-flow.mp4!` plus one line stating the tier used.
|
|
27
|
+
|
|
28
|
+
A `gaps[]` entry prints its reason on the line where the artefact would have been (`Düzeltme öncesi: ticket'ta görsel yok`). Never an empty thumbnail, never a silent omission. Contract: `$HOME/.claude/multi-agent-refs/features/visual-evidence.md`.
|
|
29
|
+
|
|
23
30
|
**`test_scenarios`** - Given/When/Then numbered list. One scenario per acceptance criterion. The heading and scenario text are rendered in `outputLanguage` at write-time; the template itself (this file) shows the English skeleton:
|
|
24
31
|
|
|
25
32
|
```markdown
|
|
@@ -14,9 +14,10 @@ The PR description targets code reviewers - it stays technical. Every adapter
|
|
|
14
14
|
| 2 | `changes` | `## Değişiklikler` | `## Changes` | always |
|
|
15
15
|
| 3 | `architecture` | `## Mimari Kararlar` | `## Architecture Decisions` | when a non-trivial design choice was made |
|
|
16
16
|
| 4 | `verification` | `## Doğrulama` | `## Verification` | always |
|
|
17
|
-
| 5 | `
|
|
18
|
-
| 6 | `
|
|
19
|
-
| 7 | `
|
|
17
|
+
| 5 | `visuals` | `## Görsel Kanıt` | `## Visual Evidence` | when `state.visualEvidence.required` |
|
|
18
|
+
| 6 | `risk` | `## Risk ve Güvenlik` | `## Risk and Security` | when `state.diffRisk.signals` carries a high-stakes signal (`security_path`, `migration`, `public_api`, `no_test_change`, `test_lines_removed`) |
|
|
19
|
+
| 7 | `dependencies` | `## Bağımlılıklar` | `## Dependencies` | when deps added/removed/bumped |
|
|
20
|
+
| 8 | `related` | `## İlgili` | `## Related` | always (Jira/issue ref; never `Closes/Fixes`) |
|
|
20
21
|
|
|
21
22
|
### Section content rules
|
|
22
23
|
|
|
@@ -62,6 +63,18 @@ Multi-repo PRs (one PR per repo) emit verification commands for that repo's stac
|
|
|
62
63
|
- Rollback: feature flag <name> | git revert <sha> | none, and why
|
|
63
64
|
```
|
|
64
65
|
|
|
66
|
+
**`visuals`** - only when `state.visualEvidence.required`. The images live on the Jira issue as attachments; this section exists so a reviewer opening the PR knows they are there and what each one shows. Filenames, not raw URLs - a Jira attachment URL is auth-gated and renders as a broken image for anyone reading the PR outside a Jira session.
|
|
67
|
+
|
|
68
|
+
```markdown
|
|
69
|
+
## Visual Evidence
|
|
70
|
+
|
|
71
|
+
- Before: `<before-filename>` (attached to PROJ-XXXXX)
|
|
72
|
+
- After: `<after-filename>` (attached to PROJ-XXXXX)
|
|
73
|
+
- Flow video: `<flow-filename>`, tier <N> (attached to PROJ-XXXXX)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Every `state.visualEvidence.gaps[]` entry becomes its own line with the reason instead of a filename (`- Before: none - the ticket carries no image attachment`). Phase 6 Step 3 blocks on a required artefact that is neither listed nor explained. Contract: `$HOME/.claude/multi-agent-refs/features/visual-evidence.md`.
|
|
77
|
+
|
|
65
78
|
**`dependencies`** - only when `Package.swift` / `Podfile` / `build.gradle` / `package.json` changed. Each entry: `package@old → new - reason`.
|
|
66
79
|
|
|
67
80
|
**`related`** - flat list, plain text. Examples:
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Visual evidence - before/after screenshots and the UI flow video
|
|
2
|
+
|
|
3
|
+
A UI fix that reads as three changed files in a diff is not reviewable. The
|
|
4
|
+
reviewer cannot see what was wrong, and the tester cannot see what to look for.
|
|
5
|
+
This contract makes the pipeline carry the picture: the state the reporter saw,
|
|
6
|
+
the state the fix produces, and where possible a recording of the flow running.
|
|
7
|
+
|
|
8
|
+
The artefacts live as **Jira attachments** and are referenced from two places -
|
|
9
|
+
the Phase 7 Jira comment, where the picture belongs next to the work summary and
|
|
10
|
+
the test scenarios, and the PR body, which tells the reviewer they exist.
|
|
11
|
+
|
|
12
|
+
Consumers: Phase 3 (capture), Phase 5 (video, preferred host), Phase 6 (blocker),
|
|
13
|
+
`channels/jira.md` and `channels/pr.md` (render). Gate: `smoke-visual-evidence.sh`.
|
|
14
|
+
|
|
15
|
+
## 1. When it is required
|
|
16
|
+
|
|
17
|
+
Decided mechanically from `taskType` plus the changed-file list, never from the
|
|
18
|
+
model's reading of the task. A file counts as UI by stack:
|
|
19
|
+
|
|
20
|
+
| Stack | UI file test |
|
|
21
|
+
|---|---|
|
|
22
|
+
| iOS | `.swift` declaring `: View`, `: ViewController`, or under a `Views/` path |
|
|
23
|
+
| Android | `.kt` with `@Composable`, or declaring `: Activity` / `: Fragment` |
|
|
24
|
+
| Web | `.tsx` / `.jsx` / `.vue` / `.svelte` |
|
|
25
|
+
|
|
26
|
+
| Case | Before | After | Video |
|
|
27
|
+
|---|---|---|---|
|
|
28
|
+
| `taskType` is `bugfix` AND a UI file changed | required | required | when a tier allows |
|
|
29
|
+
| Design work: `taskType` is `component`, or Figma was referenced, or a UI file was **added** | not applicable | required | when a tier allows |
|
|
30
|
+
| Anything else | - | - | - |
|
|
31
|
+
|
|
32
|
+
`state.visualEvidence.required` records the verdict and which rule produced it.
|
|
33
|
+
Nothing about this section is optional-by-omission: when it is required and an
|
|
34
|
+
artefact is absent, the absence is written down with its reason (section 5).
|
|
35
|
+
|
|
36
|
+
## 2. Before - the reporter's screenshot, or nothing
|
|
37
|
+
|
|
38
|
+
**The pipeline does not build the old state to photograph it.** Reproducing a
|
|
39
|
+
pre-fix screen costs a second build and a second launch on every UI bug, to
|
|
40
|
+
recreate evidence the reporter has usually already attached.
|
|
41
|
+
|
|
42
|
+
So: Phase 0 already fetches the issue. Any image attachment on it (`.png`,
|
|
43
|
+
`.jpg`, `.jpeg`, `.gif`, `.heic`) is downloaded to `$WORKTREE/.pipeline/evidence/`
|
|
44
|
+
and recorded as `state.visualEvidence.before[]`. More than one is kept - a bug
|
|
45
|
+
reported on two platforms has two.
|
|
46
|
+
|
|
47
|
+
No image on the ticket means no "before". Record the gap
|
|
48
|
+
(`before_missing: "ticket carries no image attachment"`) and continue. The
|
|
49
|
+
section still renders, saying so.
|
|
50
|
+
|
|
51
|
+
## 3. After - Phase 3, not Phase 5
|
|
52
|
+
|
|
53
|
+
Phase 5 is the natural home: the simulator is already up. It is also **dropped by
|
|
54
|
+
every `autopilot` and `--local` entry** (`phase-5-test.md` TLDR), so a capture
|
|
55
|
+
that lives only there produces nothing for unattended runs - which are exactly
|
|
56
|
+
the runs where nobody watched the screen.
|
|
57
|
+
|
|
58
|
+
The capture therefore happens in **Phase 3, after the build+test gate passes**,
|
|
59
|
+
which is in every mode's phase set. Phase 5 may add richer evidence on top; it is
|
|
60
|
+
never the only source.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
bash $HOME/.claude/scripts/capture-evidence.sh after \
|
|
64
|
+
--task "$TASK_ID" --platform "$PLATFORM" --label "<screen-slug>"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The script boots the device if needed, launches the built app, cleans the status
|
|
68
|
+
bar (`ios_status_bar preset:clean` / the Android equivalent) so the frame carries
|
|
69
|
+
no clock, carrier or battery noise, captures at device resolution, downscales to
|
|
70
|
+
at most 1242px wide, and writes
|
|
71
|
+
`$WORKTREE/.pipeline/evidence/<TASK_ID>-<label>-after.png`.
|
|
72
|
+
|
|
73
|
+
A clean status bar is not cosmetic: without it two captures of the same screen
|
|
74
|
+
differ by the clock, which makes every "after" look like a change.
|
|
75
|
+
|
|
76
|
+
## 4. Video - three tiers, resolved once per repo
|
|
77
|
+
|
|
78
|
+
The flow source, in order: a UI test flow written on the ticket wins; otherwise
|
|
79
|
+
the Phase 5 test scenarios are the flow. Human-written beats generated, the same
|
|
80
|
+
rule the "before" follows.
|
|
81
|
+
|
|
82
|
+
The tier is probed once and stored in `state.visualEvidence.videoTier`:
|
|
83
|
+
|
|
84
|
+
| Tier | Condition | Mechanism |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| 1 | The repo has a UI test target (XCUITest / Espresso) **and** it can be seeded with test data | Run that test, record the screen for its duration. Most faithful, and it is a test that already runs in CI |
|
|
87
|
+
| 2 | A runnable build exists | Drive the flow with `mcp__multi-agent-toolkit__agent_run_steps` and record with `ios_record_video` / `android_record_screen`. **No test target needed** |
|
|
88
|
+
| 3 | No runnable build (library / SPM package / backend) | Skip, with the reason recorded |
|
|
89
|
+
|
|
90
|
+
Tier 2 is why "can every repo do this" answers yes in practice: any app that can
|
|
91
|
+
be launched can be driven. A repo without a UI test target loses fidelity, not
|
|
92
|
+
the recording.
|
|
93
|
+
|
|
94
|
+
Preferred host is **Phase 5** - the device is already up and a human is present
|
|
95
|
+
to confirm the flow is the right one. In a mode without Phase 5, tier 2 runs at
|
|
96
|
+
the end of Phase 3 instead. Tier 1 always runs where the test runs.
|
|
97
|
+
|
|
98
|
+
Duration is capped by `visualEvidence.maxVideoSeconds` (default 60), read via
|
|
99
|
+
`capture-evidence.sh limits` so the number lives in one place rather than in two
|
|
100
|
+
documents. A flow that needs longer is not a review artefact, it is a debugging
|
|
101
|
+
session.
|
|
102
|
+
|
|
103
|
+
`visualEvidence.enabled` turns the whole feature off - capture, upload, both
|
|
104
|
+
render sections and the Phase 6 blocker with it.
|
|
105
|
+
|
|
106
|
+
## 5. Size, and what happens when it does not fit
|
|
107
|
+
|
|
108
|
+
Jira's attachment ceiling is an instance setting, so it is a preference:
|
|
109
|
+
`visualEvidence.maxAttachmentMb` (default `10`).
|
|
110
|
+
|
|
111
|
+
Order of attempts, each one recorded:
|
|
112
|
+
|
|
113
|
+
1. Upload as captured.
|
|
114
|
+
2. On `413` or a local size overrun: re-encode. Video drops to 720p and a lower
|
|
115
|
+
bitrate; PNG converts to JPEG at quality 80. **Reducing quality is allowed;
|
|
116
|
+
dropping the artefact is not.**
|
|
117
|
+
3. Still over: replace the video with a four-frame contact sheet (start, two
|
|
118
|
+
midpoints, end) as a single PNG, and say in the caption that the recording
|
|
119
|
+
exceeded the limit.
|
|
120
|
+
|
|
121
|
+
Never silently attach nothing.
|
|
122
|
+
|
|
123
|
+
## 6. Rendering
|
|
124
|
+
|
|
125
|
+
### Jira comment (`channels/jira.md`)
|
|
126
|
+
|
|
127
|
+
The comment's section order is fixed and nothing may be inserted between the
|
|
128
|
+
three sections. The evidence goes **inside** two of them:
|
|
129
|
+
|
|
130
|
+
- `summary` - after the summary sentences, the before/after pair as a Jira wiki
|
|
131
|
+
thumbnail row: `!<TASK>-<label>-before.png|thumbnail! !<TASK>-<label>-after.png|thumbnail!`
|
|
132
|
+
preceded by one line naming which is which in `outputLanguage`
|
|
133
|
+
(`Düzeltme öncesi / Düzeltme sonrası`).
|
|
134
|
+
- `test_scenarios` - the flow video attached under the scenario it demonstrates:
|
|
135
|
+
`!<TASK>-flow.mp4!`, one line stating the tier used.
|
|
136
|
+
|
|
137
|
+
Missing artefacts print their reason on the same line, never an empty frame.
|
|
138
|
+
|
|
139
|
+
### PR body (`channels/pr.md`)
|
|
140
|
+
|
|
141
|
+
A `visuals` section whose job is to tell the reviewer the evidence exists and
|
|
142
|
+
where it lives - the images themselves stay on the ticket:
|
|
143
|
+
|
|
144
|
+
```markdown
|
|
145
|
+
## Görsel Kanıt
|
|
146
|
+
|
|
147
|
+
- Düzeltme öncesi: <before-filename> (PROJ-123 ekinde)
|
|
148
|
+
- Düzeltme sonrası: <after-filename> (PROJ-123 ekinde)
|
|
149
|
+
- Akış videosu: <flow-filename>, tier <N> (PROJ-123 ekinde)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## 7. Blocker
|
|
153
|
+
|
|
154
|
+
When section 1 says required and `state.visualEvidence` carries neither an
|
|
155
|
+
artefact nor a recorded reason for its absence, **Phase 6 Step 3 blocks** - the
|
|
156
|
+
same shape as the `risk` section blocker. A recorded reason is enough to pass:
|
|
157
|
+
the gate is against silence, not against an honest "no image on the ticket".
|
|
158
|
+
|
|
159
|
+
## 8. State
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
"visualEvidence": {
|
|
163
|
+
"required": true,
|
|
164
|
+
"requiredBy": "bugfix + ui-file-changed",
|
|
165
|
+
"platform": "ios",
|
|
166
|
+
"before": [{"file": "...", "source": "ticket", "jiraFilename": "...", "url": "..."}],
|
|
167
|
+
"after": [{"file": "...", "capturedAt": "phase-3", "jiraFilename": "...", "url": "..."}],
|
|
168
|
+
"videoTier": 2,
|
|
169
|
+
"video": {"file": "...", "seconds": 41, "jiraFilename": "...", "url": "..."},
|
|
170
|
+
"gaps": [{"what": "before", "reason": "ticket carries no image attachment"}]
|
|
171
|
+
}
|
|
172
|
+
```
|
|
@@ -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
|
```
|
|
@@ -93,6 +93,8 @@ Probe order:
|
|
|
93
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`.
|
|
94
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.
|
|
95
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`.
|
|
96
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.
|
|
97
99
|
|
|
98
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).
|
|
@@ -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
|
|