@mmerterden/multi-agent-pipeline 16.27.0 → 16.29.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +144 -1
  2. package/README.md +4 -4
  3. package/README.tr.md +3 -3
  4. package/docs/architecture.md +3 -3
  5. package/docs/ecosystem.md +5 -5
  6. package/install/claude.mjs +17 -0
  7. package/package.json +4 -4
  8. package/pipeline/commands/multi-agent/SKILL.md +1 -1
  9. package/pipeline/commands/multi-agent/analysis-jira/SKILL.md +93 -0
  10. package/pipeline/commands/multi-agent/doctor/SKILL.md +78 -0
  11. package/pipeline/commands/multi-agent/help/SKILL.md +2 -0
  12. package/pipeline/commands/multi-agent/issue/SKILL.md +1 -0
  13. package/pipeline/commands/multi-agent/jira/SKILL.md +3 -0
  14. package/pipeline/commands/multi-agent/log/SKILL.md +7 -1
  15. package/pipeline/commands/multi-agent/review-issue/SKILL.md +1 -0
  16. package/pipeline/commands/multi-agent/setup/SKILL.md +14 -1
  17. package/pipeline/commands/multi-agent/sync/SKILL.md +12 -9
  18. package/pipeline/commands/multi-agent/update/SKILL.md +12 -0
  19. package/pipeline/lib/_jira-auth.sh +99 -0
  20. package/pipeline/lib/analysis-jira-write.sh +203 -0
  21. package/pipeline/lib/issue-fetcher.sh +138 -9
  22. package/pipeline/lib/multi-repo-pipeline.sh +8 -0
  23. package/pipeline/multi-agent-refs/analysis/evidence.md +1 -1
  24. package/pipeline/multi-agent-refs/analysis/intake.md +11 -2
  25. package/pipeline/multi-agent-refs/analysis/locked.md +1 -0
  26. package/pipeline/multi-agent-refs/analysis/redesign.md +112 -0
  27. package/pipeline/multi-agent-refs/analysis/render.md +6 -1
  28. package/pipeline/multi-agent-refs/analysis/resolve.md +1 -0
  29. package/pipeline/multi-agent-refs/analysis/review.md +15 -0
  30. package/pipeline/multi-agent-refs/analysis/synthesis.md +1 -1
  31. package/pipeline/multi-agent-refs/analysis-template-corporate.md +3 -3
  32. package/pipeline/multi-agent-refs/analysis-template.md +36 -0
  33. package/pipeline/multi-agent-refs/cross-cli-contract.md +6 -3
  34. package/pipeline/multi-agent-refs/features/analysis-jira.md +128 -0
  35. package/pipeline/multi-agent-refs/features/doctor.md +197 -0
  36. package/pipeline/multi-agent-refs/features/jira-context.md +101 -0
  37. package/pipeline/multi-agent-refs/features/model-fallback.md +2 -2
  38. package/pipeline/multi-agent-refs/phases/phase-0-init.md +9 -7
  39. package/pipeline/multi-agent-refs/phases/phase-1-analysis.md +1 -1
  40. package/pipeline/multi-agent-refs/phases/phase-2-planning.md +1 -1
  41. package/pipeline/multi-agent-refs/phases/phase-4-review.md +1 -1
  42. package/pipeline/multi-agent-refs/picker-contract.md +35 -0
  43. package/pipeline/multi-agent-refs/readiness-review.md +1 -1
  44. package/pipeline/multi-agent-refs/tracker-contract.md +5 -1
  45. package/pipeline/preferences-template.json +1 -1
  46. package/pipeline/schemas/agent-state.schema.json +24 -0
  47. package/pipeline/schemas/analysis-spec.schema.json +336 -95
  48. package/pipeline/schemas/prefs.schema.json +86 -2
  49. package/pipeline/scripts/analysis-story-tree.mjs +441 -0
  50. package/pipeline/scripts/anonymize-findings.mjs +24 -0
  51. package/pipeline/scripts/build-references.mjs +10 -6
  52. package/pipeline/scripts/council-view.mjs +144 -0
  53. package/pipeline/scripts/doctor.mjs +758 -0
  54. package/pipeline/scripts/phase-tracker.sh +100 -3
  55. package/pipeline/scripts/scan-agent-config.sh +48 -10
  56. package/pipeline/scripts/skill-siblings.mjs +42 -9
  57. package/pipeline/scripts/validate-analysis-doc.mjs +371 -7
  58. package/pipeline/scripts/validate-analysis.mjs +7 -5
  59. package/pipeline/skills/shared/core/multi-agent-analysis-jira/SKILL.md +94 -0
  60. package/pipeline/skills/shared/core/multi-agent-doctor/SKILL.md +79 -0
  61. package/pipeline/skills/shared/core/multi-agent-issue/SKILL.md +1 -0
  62. package/pipeline/skills/shared/core/multi-agent-review-issue/SKILL.md +1 -0
  63. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +13 -0
  64. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +9 -6
  65. package/pipeline/skills/shared/core/multi-agent-update/SKILL.md +18 -0
package/CHANGELOG.md CHANGED
@@ -14,7 +14,150 @@ Internal file-layout changes that don't affect the slash-command surface are sti
14
14
 
15
15
  ---
16
16
 
17
- ## [Unreleased]
17
+ ## [16.29.0] - 2026-09-11
18
+
19
+ ### Added
20
+
21
+ - **Two release guards that had stopped working, found by running them.** The sync leak backstop matched `ai-ios(-engineering)?-toolkit:`, so it fired on `ai-ios-toolkit`, the GENERIC marketplace plugin, and aborted the sync over a legitimate reference that had been in main for months. It now names the corporate plugins only, and is asserted in both directions - the corporate name still caught, the generic one ignored.
22
+
23
+ `scan-agent-config.sh` resolved its root as `$0/../..`, which is the repo from a checkout and the HOME directory from an install: from `~/.claude/scripts` it found zero shipped config files, then died on `"${TARGETS[@]}"` under bash 3.2's `set -u` rather than saying so. Same defect class as the one `skill-siblings.mjs` carried, so it gets the same two-candidate resolution, and zero targets is now a HIGH finding instead of a clean bill. The installed layout deliberately excludes `settings.json`: that file is the user's, not something the pipeline ships, and scanning it turned a personal permission choice into a release blocker.
24
+
25
+ - **`/multi-agent:doctor` - would a run work on this machine, and if not, what is the one next step.** Every failure it reports has already reached a user, and each arrived the same way: late, mid-run, after the pickers had been answered. A missing script fails at the call. Malformed preferences fail after Phase 0 has asked five questions. A token in a remote URL does not fail at all - it leaks. The pipeline's own answer to "is this set up correctly" was to start a run and find out.
26
+
27
+ **The exit code is the product**, not the report: 0 healthy, 1 degraded, 2 blocked, 3 usage, **4 indeterminate**. The fourth is the one usually collapsed into 0 or 2, and collapsing it means a resolver that could not look borrows the code for a clean bill. `/multi-agent:sync` stops on 2 and on 4 - syncing a blocked install copies one fault onto five surfaces, and the copies are what people then debug. `/multi-agent:setup` runs it first and last, so "setup complete" has evidence behind it. `/multi-agent:update` runs it after the install, because that is when the layout changed.
28
+
29
+ **BLOCK is a closed definition** - a state where a run will fail or leak, never one where it will merely be worse - and only five checks may produce it. That rule is enforced, not just written: a sixth check returning BLOCK is downgraded and the downgrade is reported, because a rule nothing enforces is a comment.
30
+
31
+ **Absence is printed.** `SKIP` is a fourth severity in the same list at the same position, and the summary always carries its count, so "healthy" and "not looked at" are never the same output. Without `--probe` the liveness check prints `SKIP` and says why; a network check is the user's decision to spend.
32
+
33
+ **It recommends, it never fixes.** A remote carrying a token may be the only credential that repo has, the remote may be a mirror a script depends on verbatim, and doctor can run inside a checkout the user does not own. For an embedded credential the honest step is not "hide it" - a token that reached `.git/config` is already burned - so the step is to revoke it at its host. The line carries the repo, the key, the host, a shape and a length bucket; never the value, and not the prefix either, since `ghp_` plus a length is already a fingerprint and this prints to a shared terminal.
34
+
35
+ Fourteen checks, each with a `### <id>` entry in `features/doctor.md`, and `--list-checks` is asserted equal to that set in **both** directions: a check cannot ship without its entry, and an entry cannot outlive its check.
36
+
37
+ Running it against this machine immediately paid for itself twice - it reported a missing git identity on a machine with two (the key is `identities[]`, a list, because work and personal both exist) and told the user to sync seven commands that are local-only and excluded from sync by design. Both were fixed before the gate was written; a health check that is wrong about a healthy machine is worse than none.
38
+
39
+ - **`/multi-agent:analysis-jira` - an analysis document, read as work.** A finished analysis already contains the breakdown: `BR-<slug>-NN` in the global profile, `FG-NN` in the corporate one, both guaranteed by Locked 31. The tree is derived from those ids, never from a reading of the prose.
40
+
41
+ **Coverage runs in both directions, and the second one is the reason.** Forward catches a dropped requirement. Backward catches an INVENTED story - a node with no requirement behind it - and no forward check can see one. `coverageOf()` is exported and tested against itself: the planner cannot emit an invented id, so a test that fabricates one and re-checks it with its own logic proves nothing about the shipped code.
42
+
43
+ **An unverifiable run is allowed; looking verified is not.** A lite document with no ids cannot be coverage-checked, so the verdict is `unverifiable` - on its own line in the preview, as a separate fourth approval option rather than a reworded `Approve`, in the writer's output, and beside every key in the ledger. Such a document still plans work from its user-story sub-sections; without that the no-atom case produced no stories at all and the `unverifiable` branch was unreachable, a state the code claimed to handle and never could.
44
+
45
+ **Identity is a label, not a title.** Each node carries a hash of the document's `evidence_digest` plus its own source ids, and a second run finds its tree back with one JQL search. Titles were the obvious key and are the wrong one: they get edited, and matching on them breaks exactly when someone improves the wording. The label is server-side, so it survives a new machine, a deleted `~/.claude`, and a second analyst - who is precisely the person positioned to open a duplicate tree.
46
+
47
+ **The write is ledgered.** An `intent` line before each POST, the key after the response; a crash between them leaves an intent with no key, and the next run searches by label before sending anything. The failure that matters is not "the run stopped" but "the run stopped and the retry made a second tree". An existing node is skipped, never updated: Jira has no backup path for fields other than description.
48
+
49
+ The marker gate runs before any network call - zero `EKLENECEK`, zero `TBD`, no open Section 20 row - because a tree built from an open question publishes the gap as work somebody is now assigned.
50
+
51
+ Every site-specific name lives in `prefs.global.issueTree` as a map VALUE, never a schema key: a key is a published literal and this schema ships to everyone. `subtaskRoles` ships empty on purpose, and `subtaskIssueType: null` means discover it from `createmeta` rather than assume a name.
52
+
53
+ - **`lib/_jira-auth.sh`** - one resolution of host and token, and one `-K` curl idiom, for Jira callers to share. The twelve lines existed twice and a third writer was about to make it three; the part most worth getting right (the token never reaching argv, a log, or `ps`) is the part most easily retyped badly. Only the new writer consumes it so far - `jira-publish.sh` and `issue-fetcher.sh` still carry their own resolution, and `issue-fetcher.sh`'s per-account token keys are not modelled here yet, so retrofitting them is a refactor rather than a rename and is not in this release. The leak property is asserted on all three independently, which is the part that has to hold either way.
54
+
55
+ - **`outputs.confluencePages[]`** records each emitted page's identity - `pageId`, `title`, `space`, `channel` - not only its URL. A write-back needs the id, and a `/display/SPACE/Title` URL cannot be parsed for one, so a URL-only record works on some sites and silently does not on others.
56
+
57
+ - **`install/templates/` now reaches the user tree.** It shipped in the tarball and was never copied, so `setup` told people to merge `install/templates/claude-hooks.json` - a path that exists only in a checkout. From an install the instruction named a file the reader did not have, and nothing said so. The doctor's `hook-coverage` check would have been a permanent `SKIP` for the same reason.
58
+
59
+
60
+ ### Fixed
61
+
62
+ - **The widget came back empty of everything except the phase name.** The native tile renders exactly one string, its subject, so whatever a reader wants from the card has to travel in that subject. It carried `Phase 1 Analysis` and nothing else, while the tracker already held the model, the elapsed time, the tokens and the cost for that phase and the fallback card printed all four. `phase-tracker.sh subjects [id]` now renders the same values in the one shape the host accepts, `tiles` builds its `TaskCreate` calls from it, and every boundary hint re-reads it so the numbers advance instead of freezing at creation time. A phase with nothing to report is still just its name - no empty separators.
63
+
64
+ - **The base branch stopped being asked.** Step 3 is marked not skippable and the run skipped it anyway, because the filter left one candidate and "there is only one option" read like a legitimate reason. It is not one: the filter is narrow by design, `Other` is a real choice on every picker, and announcing the pick in prose is the same skip with a sentence in front of it. The rule is now written where pickers are defined rather than only in this step, together with the ordering it depends on - project, then repo, then base branch, because a branch is a property of a repo and an answer given before the repo is settled cannot be told apart from a correct one.
65
+
66
+ Autopilot changed in the same pass. It resolved pickers to a sort order; it now reads `recentBranches[{projectKey}]` first and falls back to the order only when the record is empty, stale or gone from the remote, recording which rule fired. A remembered branch is evidence about this user and this repo; an option order is a guess that happens to be sorted.
67
+
68
+ - **Corporate stories all claimed every requirement.** The planner attributed `FG` ids by section containment, and the corporate template states the mapping in a COLUMN - the functional-requirement table carries a source-UC cell and the traceability matrix repeats the chain - so both of those sections name every use case and every group harvested every atom. Three use cases produced three stories with identical sources, identical titles and, since the label hashes the sources, one identical label: the second run found all three under that label and collapsed the tree onto a single issue, while coverage reported `ok` throughout because a set check cannot see misattribution. Attribution is now read from the row, which is where the template states it, with no column name hardcoded - an atom and a group sharing a table row IS the mapping, in whatever language the site writes its headers. The node's group is also in the identity hash now, because source ids alone are not an identity: two groups may legitimately cite the same atoms.
69
+
70
+ - **A failed story still wrote its sub-tasks.** `create_issue` omits the parent field when the parent key is empty, so when Jira refused a story the writer logged the error, set the exit code, and went on to POST its sub-tasks - which landed as live, parentless issues from a run that had already reported a failure.
71
+
72
+ - **Three gates that could not fail.** `smoke-analysis-jira.sh` asserted no token is interpolated into a curl argument using `[^\n]` inside a bracket expression, which BSD grep reads as the two literal characters `\` and `n`: the class excluded every header name containing an "n", `Authorization` among them, so on macOS the assertion could not fire for any header a caller would really write. The same file printed a green "no caller puts a token on a curl command line" unconditionally after the loop that checks it, so the report could contradict its own red line. And `smoke-doctor.sh` asserted the `MAY_BLOCK` downgrade with a regex over `doctor.mjs`'s own source, which a nearby comment satisfied as well as the code did - the enforcement could be deleted outright with the gate still green. The downgrade is now driven rather than read: the engine is importable behind a main guard and the gate calls `report()` with an out-of-set id and measures what comes back.
73
+
74
+ - **`smoke-command-inventory.sh` aborted instead of reporting.** It parsed the inventory block with a hardcoded `/^analysis, analysis-resolve/` trigger, so a command sorting between those two names left the parse empty - and under `set -e` the empty assignment killed the whole gate before its own "could not parse the inventory block" guard, before the shared-core counterpart check, and before it printed its tally. A publish-blocking gate that exits silently is worse than one that fails. The block is now anchored on the tree's own first and last command, and the parse failure is reported as a finding.
75
+
76
+ - **`doctor`'s script-surface check could not see one directory down.** Its pattern excluded `/` from the path segment, so a reference to `$HOME/.claude/scripts/nested/bar.mjs` was truncated to the directory; as long as that directory existed, a genuinely missing file inside it reported OK - the exact case the check exists to catch.
77
+
78
+ - **Maturity warnings named the jargon instead of the gap.** "Bug icin repro adimlari yok" tells a reader what is missing only if they already know what repro steps are. The two warnings that get read most now say what is absent in plain terms: what was done, what was expected, what happened; and, for acceptance criteria, that nothing says what "done" looks like.
79
+
80
+ - **Stale surface counts.** `docs/architecture.md` and `docs/ecosystem.md` still described Copilot CLI as carrying 51 skills while naming 53 for the other two hosts in the same diagram and the same table row; the installed tree has 53. `skill-siblings.mjs` carried the same stale number in a comment.
81
+
82
+ - **The phase widget disappeared because the task tools now depend on the model.** Claude Code provides `TaskCreate` / `TaskUpdate` by default only on Claude 3.x, Opus 4 through 4.7, Sonnet 4 through 4.6 and Haiku 4.5; on any newer model it leaves them out unless the user opts in, and that default arrived in v2.1.268. This contract named those calls in the very first release and was right for years, so nothing noticed the default change: a run wrote its tracker state correctly, advanced all eight phases, and drew nothing on screen for the whole run.
83
+
84
+ It went unnoticed because the gate asserted the wrong thing. `smoke-tracker-widget.sh` checked that `tiles` PRINTS five `TaskCreate(` lines - a claim about our own output, not about the tool existing - and no run log in the local tree has ever recorded a `TaskCreate` call. That is the same shape as the `tokens` defect described one entry below it in 16.23.0: a gate that lints prose rather than a run.
85
+
86
+ Both `tiles` and every phase boundary now name the fallback on the same output: the bordered card IS the widget there, reprinted inside the reply exactly as on Copilot CLI, and `tiles` renders the card itself so the content is already on screen. They also print the one command that brings the native widget back - `CLAUDE_CODE_ENABLE_TODO_TOOLS=1 claude` - because a user staring at a missing widget needs the command, not the diagnosis. The branch is taken by the agent, which knows its own tool list; a shell script cannot see it.
87
+
88
+ **Naming the fallback was not enough: the card came back in the wrong shape.** With the instruction reading "reprint the card", a run redrew it as two compact lines and dropped exactly what a reader watches for - the per-phase rows, the elapsed time and the running token count. The card was on screen and the information was not, which is the failure the fallback existed to prevent. Both the `tiles` banner and the per-boundary hint now say to run `render` and paste its output VERBATIM inside a code block, and forbid the three ways it was lost: redrawing it, folding phases onto one line, dropping the columns. The gate asserts the wording on both surfaces and asserts `render` itself still emits one line per phase, a token column and a total row.
89
+
90
+ ---
91
+
92
+ ## [16.28.0] - 2026-09-10
93
+
94
+ ### Added
95
+
96
+ - **The analysis sub-task the pipeline never read.** A development sub-task is usually filed with no description of its own. The fetcher already read the parent when that happened; it never read the siblings, so a board that keeps its analysis in a separate sub-task handed the pipeline an empty task and nothing said so. `issue-fetcher.sh` now reads the parent's other sub-tasks into `descriptor.relatedIssues[]`.
97
+
98
+ One search request buys all of them with their descriptions, and only when the issue has a parent, because an issue with no parent has no siblings. That cost claim is measured by `smoke-jira-context.sh` rather than asserted: it counts the requests the fetcher actually issues. The issue's own `subtasks` field lists ITS children, and the parent's lists siblings without descriptions, so either of those shapes would have cost one GET per sibling.
99
+
100
+ The payload never touches the `\x1f`-delimited parse the rest of the descriptor travels through - it arrives as one JSON argv - so the eight-field parse, its trailing-newline strip and its unfetched fallback are byte-for-byte what they were. The parent key is re-validated against an anchored pattern before it reaches the query: it comes from the API, but it goes into a URL.
101
+
102
+ It reaches `agent-state.json`, unlike the parent feature it sits next to. `/multi-agent:resume` rebuilds context from durable artefacts and never from the conversation, so an intake-only enrichment would be gone by the first resume. The task's own description and maturity are still not persisted; that asymmetry is now written into the schema so the next reader does not mistake it for an oversight.
103
+
104
+ `description_empty_sibling_available` fires only when the issue's description AND the parent's are both empty AND a sibling has content, downgrading what is today a hard blocker. The narrowness is the point: `score` loses ten points per warning and the picker only continues silently at `score >= 90`, so a warning that fired whenever an issue merely HAD siblings would turn every parented intake into a question.
105
+
106
+ - **How many reviewers actually saw a finding.** Phase 4 anonymizes findings so the judge cannot mark its own homework, but the merge stayed a pure judgement call: `validate-triage.mjs` surfaced a repeated fingerprint as a warning and left it there. `anonymize-findings.mjs` now stamps `corroboration: {count, of}` - distinct reviewers per fingerprint - computed where the whole panel is already in one payload, so it costs nothing.
107
+
108
+ It is context, not a rule. `docs/adr/0001-three-model-triage.md` rejected majority voting because the same hallucination shows up in two of three same-family reviewers, and that decision stands: the triage hedge now covers corroboration in the same sentence it covers prior art. The reading that pays is the other end - a count of 1 is the finding only one reviewer saw.
109
+
110
+ - **`council-view.mjs`** renders what each reviewer found and what triage did with it. Everything it needs was already on the state and nothing displayed it; `run-metrics.mjs` reduced it to a ratio and the rows behind the ratio were invisible. De-anonymization is safe here because it runs after triage has ruled, and the gate pins that the map reaches no prompt. `/multi-agent:log` renders it; exit 2 means the run never reached Phase 4.
111
+
112
+
113
+ - **A validator summary that says which checks ran.** `validate-analysis-doc.mjs --report` prints every check by name with a verdict each: `ok`, a finding count, or `skipped: <reason>`. The gap it closes is specific - the traceability matrix only runs in the corporate profile, so on a global document it never executed and the output was byte-identical to "ran, found nothing". Attribution is positional and reconciles by construction, so a check added without its mark misnames a finding but can never lose one; the gate asserts the printed set equals the set the file defines. Default output is unchanged for gate callers.
114
+
115
+ - **Provenance in the reports a human reads.** `evidence_digest` and `base_commit` were already in the document front-matter, on the side only a machine reads. The analysis Phase 5 report, the `review-analysis` verdict and `--report` now carry them too: a timestamp cannot separate two reports made the same day, and the first question anyone asks of an older verdict is which version of the document it judged.
116
+
117
+ - **A verdict prints its empty classes.** `review-analysis` now names all six rubric classes and every deterministic gate whether or not they fired, with `none` where the count is zero. A verdict that lists only what it found cannot be told apart from one that never looked.
118
+
119
+ - **The uncertainty marker, in both profiles.** The two-way `AS-NN` pairing between the body and Section 20 ran only under `profile: corporate`, which made the global profile the one place an inline marker could point at nothing. Two documents already said otherwise - Locked 36 makes an unstamped gap fail the dispatch gate with no profile clause, and `analysis/render.md` routes an external-dependency gap to `AS-NN` for every run - so the check was the only side that disagreed. A document carrying no markers is unaffected: every loop is empty.
120
+
121
+ - **Every open question names an owner.** "A gap with an owner is a plan; a gap without one is a defect" lived in `analysis/review.md`, which is a model's judgement. It is now a validator error. The owner column is located from the table header rather than by index, because the two profiles order Section 20 differently and an index would silently read the wrong cell in one of them.
122
+
123
+ - **`status: draft | final`, the closure gate.** Nothing stopped a document with open questions from being published. Under `final` an unresolved `AS-NN` or an open Section 20 row is now an ERROR; under `draft` it is counted and nothing blocks. The key is optional and absent means `draft`, so no document written before it starts failing. `/multi-agent:analysis-resolve` flips it at the end of a run, with a confirmation - `final` is a publication claim, and that command is built on one question per decision.
124
+
125
+ - **`not-for:` frontmatter, and a warning that shrinks.** `lint-skills.mjs` reported nine trigger-vocabulary collisions every run and the list never moved: an author read it, had nothing to do about it, and stopped reading. A skill may now name the siblings it must not be chosen for, which the model sees on the routing surface itself and the lint consumes to drop the pair. Suppression is never silent - settled pairs are counted - and a name that resolves to no sibling on the same surface is an error, because a typo would otherwise leave the pair unanswered while the author believes it is handled. `review-issue`/`review-jira` and `issue`/`jira` are tagged; the list is five.
126
+
127
+ - `ANALYSIS_CEILING` 154500 -> 155000. The report shape is defined only in `analysis/render.md` and a front-matter key is documented only where the front-matter block is, so those two additions had to land inside the count; everything else in this pass stayed outside it. Both were compressed once before measuring, and 295 bytes of headroom against 213 still owed left no way to avoid the raise.
128
+
129
+ - **Redesign mode.** `options.redesign` is an intake opt-in that adds three artefacts to the document, all of them claims about v1 rather than plans for v2: current behaviour with `CB-<slug>-NN` ids and `repo/file:line` citations, the v1 to v2 endpoint mapping, and a difference list over a closed status vocabulary (`Moved / Partial / Missing / New / Out of scope`). Every `Missing` and `Partial` owes a Section 20 row by `AS-NN` - a behaviour v2 drops with no decision is the thing a redesign loses and production finds.
130
+
131
+ It is an option, not a third `mode` value. `mode` says how many sections, `redesign` says which content, and since `mode === "full"` branches in four places inside the validator, a `mode: redesign` would have switched off the traceability matrix, the Test Plan requirement and the rule-to-test cross-check in exactly the documents that need them most. A small screen can also have a lite redesign.
132
+
133
+ Eight validator checks, of which two are worth naming: a `CB-` id present in one table and absent from the other fails in **both** directions, and the three sections must exist before any row check is trusted, because row checks over a missing section pass over nothing and show the gate green. Evidence and certainty are derived by the renderer from `repoEvidence`, never graded by the writer, which is Locked 24 applied to a second table. `options.redesign` is an `evidence_digest` input: without that one line, a redesign started within a day of a normal run on the same feature would reuse that cache, skip Phase 1b and render an empty behaviour table that all eight checks then pass over.
134
+
135
+ The contract, its reasoning and the check table live in `analysis/redesign.md`, which `analysis/SKILL.md` does not name and which therefore loads only on a redesign run.
136
+
137
+ - `ANALYSIS_CEILING` 155000 -> 158500, the largest single raise it has taken. What could not be moved out is the argument: the section skeletons belong in `analysis-template.md`, where every other conditional section (15.6, 16.2) is already defined; Locked 37 belongs in `analysis/locked.md`, because a decision recorded only where it is implemented is not locked; and the intake question belongs in `analysis/intake.md`, because the option is chosen before anything knows the run is a redesign. 5.9 kB stayed outside the count. Everything was compressed twice before the number was picked.
138
+ ### Fixed
139
+
140
+ - `learn-from-transcripts.mjs` called `process.exit(0)` on the line after writing its `--json` result, so a large mining result was cut at the 64 KB pipe buffer - the exact defect the gate added in 16.27.0 exists to prevent, in the file that motivated it. The gate caught it; the two sites it named are now a `main()` with a return.
141
+
142
+ - `skill-siblings.mjs` resolved its trees from the script's own location with no fallback, so from an install (`~/.claude/scripts`) it looked for `~/pipeline/commands/multi-agent`, found nothing, and exited 1. `observations.mjs` caught that and wrote the note `"<target>: not a skill surface"` about files that are skill surfaces - a friction log silently keeping a false record. Resolution is now two-candidate, repo first then the install, and from an install the authored surfaces are reported as not applicable rather than absent: `--audit` says the authored side was not checked instead of borrowing the repo's verdict.
143
+
144
+ - The stdout-exit detector in `smoke-consumer-smoke-surface.sh` only matched a literal `process.stdout.write` on the line, so `console.log` and any one-line helper wrapping either (`emit()`) were invisible to it. It now resolves same-file helpers one level, skips declaration lines and stops the lookahead at a control-flow terminator. The three analysis validators are on the watch list and converted to `process.exitCode`.
145
+
146
+ - `smoke-install-layout.sh` fixture regenerated: `council-view.mjs` and `features/jira-context.md` moved the installed counts.
147
+
148
+ - **The closure gate read the wrong row, and then read it wrongly.** `status: final` decided whether an `AS-NN` was still open by taking the first table row in the document that mentioned the id. The corporate template writes `| **Request** | EKLENECEK (AS-NN) |` in the body, so that row won and a final document shipped with live placeholders. Openness now comes from the Section 20 row only, and from its status CELL located by header - and where there is no status column (the corporate Section 20 has none) an `EKLENECEK` still stamped with the id is itself the signal.
149
+
150
+ The second half of the same line was a substring search: `açıklama` contains `Açık`, so a correctly closed Turkish row reading `Karar verildi / Decided` whose question text said "hata açıklaması" was reported as open and blocked. The status vocabulary is now matched per token across the bilingual `/`, never as a substring. English had the same trap in "reopened".
151
+
152
+ - **A finding that arrived inside a skipped check vanished from `--report`.** `mark()` printed the skip label whenever one was passed, so a malformed `status` value (caught by the closure gate, which then reports "draft document") and the redesign drift warning (raised by the branch that reports "not a redesign") were both on stderr and absent from the report. A count now outranks a skip label, which is what makes the registry's own claim - that a finding can be misnamed but never lost - true.
153
+
154
+ - **`council-view.mjs` rendered every ruled-out finding as `unruled`.** `triage-output.schema.json` defines a deferred or rejected item as `{finding, reason}` - the reason is the point of those buckets - while `accepted[]` is a flat finding. The view read the id off the wrapper. Its own fixture used the flat shape, so the gate passed; the fixture is now checked against the schema it represents.
155
+
156
+ - `council-view.mjs --iteration` with no value made the filter compare against `NaN` and exited 2 on a state full of iterations. `/multi-agent:log` reads exit 2 as "the run never reached Phase 4" and omits the section, so a usage error looked like an empty run. It is now exit 64.
157
+
158
+ - The endpoint-mapping column check counted raw `|` segments, so a valid GFM row without the optional trailing pipe was reported as short.
159
+
160
+ - The redesign drift warning fired on prose that merely used the words. `sectionBody` matches its keyword as a raw substring of the heading, deliberately, because Locked 2 re-flows section numbers - so `### 4.9 Notes on the old Current Behaviour audit process` matched, and Phase 4 runs `--strict`, which turned that warning into a blocked document. The rendered artefact is the honest signal: a current-behaviour table always carries `CB-<slug>-NN` ids and a paragraph using the words never does.
18
161
 
19
162
  ## [16.27.0] - 2026-09-10
20
163
 
package/README.md CHANGED
@@ -89,7 +89,7 @@ Depth, autopilot and `--local` are the only knobs on the run itself; everything
89
89
 
90
90
  ## Commands
91
91
 
92
- `/multi-agent` plus 51 sub-commands. `/multi-agent:help` renders the same catalog in your terminal, in your `outputLanguage`.
92
+ `/multi-agent` plus 53 sub-commands. `/multi-agent:help` renders the same catalog in your terminal, in your `outputLanguage`.
93
93
 
94
94
  ### Pipeline entries
95
95
 
@@ -207,13 +207,13 @@ This enables the matching plugin (+ the shared `ai-common` plugin) in the repo's
207
207
 
208
208
  ## Tool support
209
209
 
210
- The pipeline runs natively on **Claude Code**, **Copilot CLI** and **Codex CLI** - all three install from the same `pipeline/` source and get the same 51 commands.
210
+ The pipeline runs natively on **Claude Code**, **Copilot CLI** and **Codex CLI** - all three install from the same `pipeline/` source and get the same 53 commands.
211
211
 
212
212
  | Tool | Flag | What it installs |
213
213
  |---|---|---|
214
214
  | Claude Code | `--claude` (default) | slash commands + skills + agents + three `PreToolUse` hooks (secret scan, agent-guard, read-size gate) |
215
- | Copilot CLI | `--copilot` | instructions + 51 sub-command skills + scripts |
216
- | Codex CLI | `--codex` | one router skill + 51 specs as refs + 8 agent TOML + `AGENTS.md` block + `codex mcp add` |
215
+ | Copilot CLI | `--copilot` | instructions + 53 sub-command skills + scripts |
216
+ | Codex CLI | `--codex` | one router skill + 53 specs as refs + 8 agent TOML + `AGENTS.md` block + `codex mcp add` |
217
217
 
218
218
  Filter skills by stack with `--platform=ios\|android\|all`.
219
219
 
package/README.tr.md CHANGED
@@ -207,13 +207,13 @@ Bu, ilgili plugin'i (+ ortak `ai-common` plugin'ini) repo'nun `.claude/settings.
207
207
 
208
208
  ## Araç desteği
209
209
 
210
- Pipeline **Claude Code**, **Copilot CLI** ve **Codex CLI** üzerinde native çalışır - üçü de aynı `pipeline/` kaynağından kurulur ve aynı 51 komutu alır.
210
+ Pipeline **Claude Code**, **Copilot CLI** ve **Codex CLI** üzerinde native çalışır - üçü de aynı `pipeline/` kaynağından kurulur ve aynı 53 komutu alır.
211
211
 
212
212
  | Araç | Bayrak | Ne kurar |
213
213
  |---|---|---|
214
214
  | Claude Code | `--claude` (varsayılan) | slash komutları + skill'ler + agent'lar + üç `PreToolUse` hook'u (secret scan, agent-guard, okuma-boyutu geçidi) |
215
- | Copilot CLI | `--copilot` | talimatlar + 51 alt-komut skill'i + script'ler |
216
- | Codex CLI | `--codex` | bir router skill + ref olarak 51 spec + 8 agent TOML + `AGENTS.md` bloğu + `codex mcp add` |
215
+ | Copilot CLI | `--copilot` | talimatlar + 53 alt-komut skill'i + script'ler |
216
+ | Codex CLI | `--codex` | bir router skill + ref olarak 53 spec + 8 agent TOML + `AGENTS.md` bloğu + `codex mcp add` |
217
217
 
218
218
  Skill'leri stack'e göre filtrele: `--platform=ios\|android\|all`.
219
219
 
@@ -117,7 +117,7 @@ graph TB
117
117
  end
118
118
 
119
119
  subgraph "Pipeline Specs"
120
- CMD[commands/<br/>51 command files]
120
+ CMD[commands/<br/>53 command files]
121
121
  AGT[agents/<br/>8 agent personas]
122
122
  RUL[rules/<br/>12 domain rules]
123
123
  PHS[multi-agent-refs/phases/<br/>phase specs + contracts]
@@ -169,8 +169,8 @@ revisions of this diagram - Codex CLI and the two independently-shipped repos
169
169
  ```mermaid
170
170
  graph TD
171
171
  CC["Claude Code<br/>(source of truth)"]
172
- COP["Copilot CLI<br/>(instructions + 51 skills)"]
173
- COD["Codex CLI<br/>(1 router skill + 51 refs)"]
172
+ COP["Copilot CLI<br/>(instructions + 53 skills)"]
173
+ COD["Codex CLI<br/>(1 router skill + 53 refs)"]
174
174
  REPO["Pipeline Repo<br/>(npm package)"]
175
175
  WEB["Website"]
176
176
  PLUGREPO["multi-agent-plugins<br/>(5 stack plugins, own repo)"]
package/docs/ecosystem.md CHANGED
@@ -5,7 +5,7 @@ separately, wired together at install time and at run time:
5
5
 
6
6
  | Repo | What it owns | Ships as |
7
7
  |---|---|---|
8
- | **`multi-agent-pipeline`** (this repo) | Orchestration: the 8-phase flow, the 51 slash commands, quality gates, review/triage, cross-CLI parity | npm package (`@mmerterden/multi-agent-pipeline`), installs itself onto Claude Code / Copilot CLI / Codex CLI |
8
+ | **`multi-agent-pipeline`** (this repo) | Orchestration: the 8-phase flow, the 53 slash commands, quality gates, review/triage, cross-CLI parity | npm package (`@mmerterden/multi-agent-pipeline`), installs itself onto Claude Code / Copilot CLI / Codex CLI |
9
9
  | **`multi-agent-plugins`** | Stack knowledge: per-platform component/lifecycle skills (iOS, Android, Frontend, Backend) + shared knowledge | Claude Code marketplace, 5 independently-versioned plugins |
10
10
  | **`multi-agent-toolkit-mcp`** | The pipeline's hands on devices and browsers: 80 MCP tools across 6 categories (simulator/emulator control, accessibility audit, store compliance, web automation, Figma-vs-mock design audit, an agent-DSL batch runner) | npm package, registered as a standard stdio MCP server on every host |
11
11
 
@@ -18,7 +18,7 @@ Either can be swapped or removed without touching the other two's source.
18
18
  graph LR
19
19
  subgraph PIPE ["multi-agent-pipeline (orchestrator)"]
20
20
  direction TB
21
- PHASES["8 phases · 51 commands"]
21
+ PHASES["8 phases · 53 commands"]
22
22
  GATES["deterministic gates + review triage"]
23
23
  end
24
24
 
@@ -64,8 +64,8 @@ only those:
64
64
  graph TD
65
65
  CC["Claude Code<br/>~/.claude/commands/multi-agent/<br/>(source of truth)"]
66
66
 
67
- CC -->|"Step 2: copy + reformat<br/>51 sub-command skills"| COP["Copilot CLI<br/>~/.copilot/skills/"]
68
- CC -->|"Step 2b: transform<br/>(install.js --codex)"| COD["Codex CLI<br/>1 router skill + 51 refs<br/>+ 8 agent TOML"]
67
+ CC -->|"Step 2: copy + reformat<br/>53 sub-command skills"| COP["Copilot CLI<br/>~/.copilot/skills/"]
68
+ CC -->|"Step 2b: transform<br/>(install.js --codex)"| COD["Codex CLI<br/>1 router skill + 53 refs<br/>+ 8 agent TOML"]
69
69
  CC -->|"Step 3: genericize<br/>(strip personal data)"| REPO["multi-agent-pipeline repo<br/>pipeline/"]
70
70
  CC -->|"Step 4: version + feature sync"| WEB["Website<br/>projects.ts / i18n.tsx"]
71
71
 
@@ -153,7 +153,7 @@ measurements behind this table):
153
153
 
154
154
  | | Claude Code | Copilot CLI | Codex CLI |
155
155
  |---|---|---|---|
156
- | **Pipeline commands** | 51 slash-command skills, native | 51 skills, `multi-agent-{cmd}` naming, copied in | 1 router skill (`multi-agent`) + 51 command specs as reference files - Codex silently truncates its skills block past a few dozen entries, so sub-commands are not peer skills here |
156
+ | **Pipeline commands** | 53 slash-command skills, native | 53 skills, `multi-agent-{cmd}` naming, copied in | 1 router skill (`multi-agent`) + 53 command specs as reference files - Codex silently truncates its skills block past a few dozen entries, so sub-commands are not peer skills here |
157
157
  | **Stack plugins** | Marketplace plugin, loaded natively, resolved by `.claude/settings.json` enabled-list | Enabled plugin's authored skills copied flat into `~/.copilot/skills/`; `knowledge/` **not** re-copied (already delivered via `shared/external`) | Copied as reference files under `~/.codex/multi-agent-refs/skills/`, plugin-prefixed on name clash (e.g. `architecture` → `ai-ios-toolkit-architecture`) |
158
158
  | **Component dispatch (Phase 3)** | Marketplace plugin's `create-component`/`create-screen` skill via the Skill tool | No plugin loader - the enabled stack plugin's authored skills (incl. `create-component`) are copied flat into `~/.copilot/skills/` at install time (the old frozen `figma-*` copies are pruned, they were never a fallback) | Not part of the enforced parity axis; classification + state-shape must match, skill *inventory* does not |
159
159
  | **multi-agent-toolkit-mcp** | `claude mcp add multi-agent-toolkit -- npx -y @mmerterden/multi-agent-toolkit-mcp` | `copilot mcp add multi-agent-toolkit -- npx -y @mmerterden/multi-agent-toolkit-mcp` | `codex mcp add multi-agent-toolkit -- npx -y @mmerterden/multi-agent-toolkit-mcp` (skipped with a warning if `codex` isn't on `PATH`) |
@@ -80,6 +80,7 @@ export function installClaude(ctx) {
80
80
  const CLAUDE_SCHEMAS = join(home, ".claude", "schemas");
81
81
  const CLAUDE_LIB = join(home, ".claude", "lib");
82
82
  const CLAUDE_MA_REFS = join(home, ".claude", "multi-agent-refs");
83
+ const CLAUDE_TEMPLATES = join(home, ".claude", "templates");
83
84
 
84
85
  // Before laying anything down: drop trees an older install created that no
85
86
  // current installer manages. Wipe-before-copy only protects trees still being
@@ -96,6 +97,7 @@ export function installClaude(ctx) {
96
97
  installRules(pipelineSrc, CLAUDE_RULES, useSymlinks);
97
98
  installSchemas(pipelineSrc, CLAUDE_SCHEMAS, useSymlinks);
98
99
  installLib(pipelineSrc, CLAUDE_LIB, useSymlinks);
100
+ installTemplates(pipelineSrc, CLAUDE_TEMPLATES, useSymlinks);
99
101
  runPreDeployScans(pipelineSrc);
100
102
  installSkills({
101
103
  pipelineSrc,
@@ -324,6 +326,21 @@ function installLib(pipelineSrc, dest, useSymlinks) {
324
326
  console.log(` -> ${countFiles(libSrc)} files copied to ${dest}`);
325
327
  }
326
328
 
329
+ function installTemplates(pipelineSrc, dest, useSymlinks) {
330
+ // The templates shipped in the tarball but never reached the user tree, so
331
+ // `setup` told people to merge `install/templates/claude-hooks.json` - a path
332
+ // that exists only in a checkout. From an install the instruction named a file
333
+ // the reader did not have, and nothing said so.
334
+ console.log(" [Claude Code] Installing templates...");
335
+ const templatesSrc = join(dirname(pipelineSrc), "install", "templates");
336
+ if (!existsSync(templatesSrc)) return;
337
+ // Wipe-before-copy - templates/ is a 100% pipeline-managed tree.
338
+ if (!useSymlinks) ensureRealDir(dest);
339
+ wipeDir(dest);
340
+ copyDir(templatesSrc, dest, { useSymlinks });
341
+ console.log(` -> ${countFiles(templatesSrc)} files copied to ${dest}`);
342
+ }
343
+
327
344
  function runPreDeployScans(pipelineSrc) {
328
345
  // Pre-deploy security scan - warn-only, never halts install on its own.
329
346
  const scanScript = join(pipelineSrc, "scripts", "scan-skills.sh");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmerterden/multi-agent-pipeline",
3
- "version": "16.27.0",
3
+ "version": "16.29.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",
@@ -101,10 +101,10 @@
101
101
  "ajv": "^8.20.0",
102
102
  "ajv-formats": "^3.0.1",
103
103
  "c8": "^12.0.0",
104
- "eslint": "^10.8.0",
104
+ "eslint": "^10.10.0",
105
105
  "eslint-config-prettier": "^10.1.8",
106
- "eslint-plugin-n": "^18.2.2",
106
+ "eslint-plugin-n": "^18.3.0",
107
107
  "prettier": "^3.9.6",
108
- "publint": "0.3.22"
108
+ "publint": "0.3.24"
109
109
  }
110
110
  }
@@ -203,7 +203,7 @@ When the user supplies an ID/URL/free-text:
203
203
  2. **Pick account** - always asked (autopilot picks default)
204
204
  3. **Fetch issue** - `lib/issue-fetcher.sh "$INPUT"` (Jira/GitHub fetch + maturity)
205
205
  4. **Repo picker** - only for `gh-num` (e.g. `316`) when repo is ambiguous, multi-select
206
- 5. **Maturity check** - blocker halts (autopilot too), warning prompt/log. For a Jira input specifically, an empty own description with a non-empty parent surfaces as `description_empty_parent_available` (warning, not blocker) - ask the tailored parent-description question from `jira/SKILL.md`'s maturity section instead of the generic "Continue?" prompt.
206
+ 5. **Maturity check** - blocker halts (autopilot too), warning prompt/log. For a Jira input specifically, an empty own description with a non-empty parent surfaces as `description_empty_parent_available` (warning, not blocker) - ask the tailored parent-description question from `jira/SKILL.md`'s maturity section instead of the generic "Continue?" prompt. When the parent is empty too, `description_empty_sibling_available` says a sibling sub-task carries the content; `descriptor.relatedIssues[]` holds them either way.
207
207
  6. **Dev context** - always runs, empty submit allowed
208
208
  7. → Interactive Launcher → Phase 0
209
209
 
@@ -0,0 +1,93 @@
1
+ ---
2
+ description: "Turn a rendered analysis document into a Jira story tree: derive stories from the document's own rule ids, check coverage both ways, preview every byte, then create only what does not already exist. Use when an analysis is final and the work needs tickets."
3
+ description-tr: "Yazılmış bir analiz dokümanını Jira story ağacına çevirir: story'leri dokümanın kendi kural kimliklerinden türetir, kapsamı iki yönlü kontrol eder, yazılacak her baytı önizler, sonra yalnız var olmayanı açar."
4
+ allowed-tools: Bash, Read, AskUserQuestion
5
+ argument-hint: "[analysis.md] [--project KEY] - optional; with no argument, pick from the documents this run emitted"
6
+ not-for: create-jira, jira
7
+ ---
8
+
9
+ # multi-agent analysis-jira
10
+
11
+ **Input**: $ARGUMENTS
12
+
13
+ Reads an analysis document as a work breakdown and creates the tree. It never
14
+ invents a story: every node comes from an id the document defines.
15
+
16
+ Contract, severities and reasoning:
17
+ `$HOME/.claude/multi-agent-refs/features/analysis-jira.md`.
18
+
19
+ ## Phase 1 - Plan, offline
20
+
21
+ ```bash
22
+ node "$HOME/.claude/scripts/analysis-story-tree.mjs" "<analysis.md>" --json > /tmp/ma-plan.json
23
+ node "$HOME/.claude/scripts/analysis-story-tree.mjs" "<analysis.md>"
24
+ ```
25
+
26
+ Exit 4 means the document still carries an open placeholder. Stop and report it:
27
+ the step is `/multi-agent:analysis-resolve`, and a tree built from an open
28
+ question publishes the gap as work somebody is now assigned.
29
+
30
+ Exit 2 means nothing could be derived. Say so; do not improvise a tree.
31
+
32
+ ## Phase 2 - Preview, in full
33
+
34
+ Show the human-readable output verbatim, in `outputLanguage`. It already carries
35
+ what makes a preview meaningful:
36
+
37
+ - every node, its source ids and its identity label
38
+ - the coverage verdict **on its own line**
39
+ - every field beside the pref key it came from, so a wrong setting shows here
40
+ rather than in Jira afterwards
41
+ - the write count
42
+
43
+ Then the dry run, which is what proves the writer agrees with the plan:
44
+
45
+ ```bash
46
+ bash "$HOME/.claude/lib/analysis-jira-write.sh" \
47
+ --plan /tmp/ma-plan.json --project "<KEY>" --dry-run
48
+ ```
49
+
50
+ ## Phase 3 - Approve
51
+
52
+ One `AskUserQuestion`. When the verdict is `ok` or `incomplete`:
53
+
54
+ - **Create the tree** - proceed
55
+ - **Show a node in full** - print one node's body, ask again
56
+ - **Cancel** - stop, write nothing
57
+
58
+ When the verdict is `unverifiable`, the approve option is **replaced**, never
59
+ reworded:
60
+
61
+ - **Create it, unverified** - the tree will be written and recorded as unchecked
62
+ - **Show a node in full**
63
+ - **Cancel**
64
+
65
+ A run that could not be checked is allowed. One that looks checked when it was
66
+ not is the defect, so the approval has to name it and a plain "Approve" must not
67
+ be reachable.
68
+
69
+ `incomplete` prints its uncovered and invented ids before the question. An
70
+ invented id means the plan cites something the document does not define - treat
71
+ that as a defect in the plan, not a warning to click past.
72
+
73
+ ## Phase 4 - Write
74
+
75
+ ```bash
76
+ bash "$HOME/.claude/lib/analysis-jira-write.sh" \
77
+ --plan /tmp/ma-plan.json --project "<KEY>"
78
+ ```
79
+
80
+ It searches by label first and skips what exists. Re-running is safe and is the
81
+ intended recovery from any failure: the ledger makes a half-written tree
82
+ findable rather than duplicable.
83
+
84
+ **Never pass `--force`-like flags, and never update an existing node.** Jira has
85
+ no backup path for fields other than description.
86
+
87
+ ## Phase 5 - Report
88
+
89
+ Keys created, keys skipped, the coverage verdict, and the ledger path. If the
90
+ verdict was `unverifiable`, say that in the report too - not only at approval
91
+ time, because the report is what gets pasted elsewhere.
92
+
93
+ **Stop. No worktree, no branch, no dev chain.**
@@ -0,0 +1,78 @@
1
+ ---
2
+ description: "Health check for the installed pipeline: layout, preferences, credentials, hooks and host capabilities, each with one actionable step. Exit code is the verdict. Use when a run failed for an environmental reason, before a sync, or after an update."
3
+ description-tr: "Kurulu pipeline için sağlık kontrolü: yerleşim, tercihler, kimlik bilgileri, hook'lar ve host yetenekleri; her biri tek uygulanabilir adımla. Çıkış kodu verdiktin kendisi."
4
+ allowed-tools: Bash, Read
5
+ argument-hint: "[--probe] [--explain] [--json] [--list-checks] - optional; --probe also makes one network request per configured service"
6
+ not-for: scan, setup
7
+ ---
8
+
9
+ # multi-agent doctor
10
+
11
+ **Input**: $ARGUMENTS
12
+
13
+ Answers one question about this machine: **would a run work here, and if not,
14
+ what is the single next step?**
15
+
16
+ Every failure it reports has already reached a user, and each one arrived the
17
+ same way - late, mid-run, after the pickers had been answered. A missing script
18
+ fails at the call. Malformed preferences fail after Phase 0 has asked five
19
+ questions. A token in a remote URL does not fail at all; it leaks.
20
+
21
+ ## Run it
22
+
23
+ ```bash
24
+ node "$HOME/.claude/scripts/doctor.mjs" $ARGUMENTS
25
+ ```
26
+
27
+ Then report the output in `outputLanguage`. Do not re-word the steps: each line
28
+ already carries one imperative step, and paraphrasing is how a step turns into
29
+ advice.
30
+
31
+ **Answer the one check a script cannot.** `task-tools` asks whether THIS session
32
+ carries `TaskCreate` / `TaskUpdate`, and only the agent can see its own tool
33
+ list. Pass what you know:
34
+
35
+ ```bash
36
+ node "$HOME/.claude/scripts/doctor.mjs" --task-tools=yes # they are in your tools
37
+ node "$HOME/.claude/scripts/doctor.mjs" --task-tools=no # they are not
38
+ ```
39
+
40
+ Without the flag that check prints `SKIP`, which is correct - reporting "absent"
41
+ from a script that never looked is the defect this check is about.
42
+
43
+ ## The exit code is the product
44
+
45
+ | Code | Meaning |
46
+ |---|---|
47
+ | 0 | healthy |
48
+ | 1 | degraded - at least one WARN |
49
+ | 2 | blocked - a run will fail or leak |
50
+ | 3 | usage error |
51
+ | 4 | indeterminate - the layout did not resolve, so nothing was checked |
52
+
53
+ 4 matters as much as 2. Without it, "I could not look" borrows the code for
54
+ "I looked and it is fine".
55
+
56
+ ## What it does not do
57
+
58
+ It recommends; it never fixes. It does not rewrite a remote URL, edit
59
+ `settings.json`, or touch a credential. A remote carrying a token may be the only
60
+ credential that repo has, the remote may be a mirror a script depends on
61
+ verbatim, and this can run inside a checkout the user does not own.
62
+
63
+ For an embedded credential the honest step is **not** "hide it". A token that
64
+ reached `.git/config` is already burned - it is in the shell history and readable
65
+ by anything that can read the working tree. The step is to revoke it at its host.
66
+
67
+ ## Flags
68
+
69
+ | Flag | Effect |
70
+ |---|---|
71
+ | `--probe` | also make one authenticated request per configured service, and start the MCP server to count its tools. Off by default: a network check is the user's decision to spend. |
72
+ | `--explain` | print the detail behind a finding (which scripts, which repos) |
73
+ | `--json` | the same verdict in machine form, same exit code |
74
+ | `--list-checks` | the check ids, one per line |
75
+ | `--task-tools=yes\|no` | answer the check only the caller can see |
76
+
77
+ Every check, its severity and its reasoning:
78
+ `$HOME/.claude/multi-agent-refs/features/doctor.md`.
@@ -119,6 +119,7 @@ Post-Hoc & Side-Channel:
119
119
  /multi-agent:analysis ["analysis-name"] Feature-spec analysis (Figma + Swagger + Confluence + repos). Asks the standard first: global (23-section dev handoff) or corporate (IG→UC→FG requirements doc). Stack optional; References built from the evidence record
120
120
  /multi-agent:analysis-resolve [doc] Resolve Section 20 open questions of an analysis doc, one at a time with source-labeled candidates
121
121
  /multi-agent:review-analysis [doc] Review a written analysis; findings cite the rule they break
122
+ /multi-agent:analysis-jira [doc] A final analysis -> a Jira story tree; coverage two-way, existing nodes skipped
122
123
  /multi-agent:complaint-analysis ["run-name"] [--file path] Customer-complaint triage: Graylog evidence per trx/conv id + read-only repo correlation → client/bff root cause + fix plan + dev prompt, or core routing recommendation
123
124
  /multi-agent:build-optimize iOS-only Xcode build perf wrapper → benchmark + analyze + recommend-first .build-benchmark/optimization-plan.md
124
125
  /multi-agent:create-jira ["desc"] [figma-url] [swagger-url] Create a Jira Task/Bug/Story matching team conventions (asks type + mining + active sprint + auto-sizing sections + preview & approval)
@@ -126,6 +127,7 @@ Post-Hoc & Side-Channel:
126
127
  /multi-agent:graph Build and query the repo code graph (symbols, imports, references), LLM-free
127
128
  /multi-agent:search Cross-task log search with smart ranking; --semantic queries triage corpus
128
129
  /multi-agent:scan Skill security scan against tiered pattern catalog
130
+ /multi-agent:doctor Would a run work here? Layout, prefs, credentials, hooks; exit code is the verdict
129
131
  /multi-agent:refactor Best practices + bug hunt + upstream drift + toolkit MCP research -> one plan, approval, dev + sync
130
132
  /multi-agent:refactor backlog Decide the friction already recorded about the pipeline itself, nothing re-derived
131
133
  /multi-agent:store-ready [repo] [--archive=|--ipa=|--aab=|--apk=] [--skip-sweep] Pre-submission store readiness, iOS + Android, local-only: three symmetric gates per platform plus the running-app sweep. A skipped gate is never a pass. Validates only, never uploads.
@@ -2,6 +2,7 @@
2
2
  description: "List unassigned GitHub issues, pick one, auto-assign, and launch the multi-agent pipeline. Use when a GitHub issue should be picked up and started without knowing its number in advance."
3
3
  description-tr: "Atanmamış GitHub issue'larını listeler, birini seçtirir, otomatik atar ve multi-agent pipeline'ı başlatır."
4
4
  argument-hint: "[autopilot] - optional: run the pipeline without confirmations"
5
+ not-for: jira
5
6
  ---
6
7
 
7
8
  # multi-agent issue - 4-Step Picker (Account → Repos → Issue → Dev Context)
@@ -85,11 +85,14 @@ After issue selection, inspect `maturity` from `~/.claude/lib/issue-fetcher.sh`:
85
85
  > - **Accept** → set the working `description` to `parentDescription` for every later phase (analysis/dev/review all read this one substituted value); log the substitution (source issue + parent key) to `agent-log.md`.
86
86
  > - **Decline** → same as a `description_empty` blocker: halt, advise fixing the issue's own description.
87
87
  > - **Autopilot**: auto-accepts "Use parent's description" (same "warnings auto-continue" rule as any other warning), logs the auto-accept + parent key to `agent-log.md`.
88
+ >
89
+ > **Sibling sub-tasks**: the fetcher also reads the parent's other sub-tasks into `descriptor.relatedIssues[]`. Show them as their own labelled block, never substituted into `description`. When the issue's description and the parent's are both empty but a sibling has content, `description_empty_sibling_available` replaces the `description_empty` blocker - same question, sibling key. Contract: `$HOME/.claude/multi-agent-refs/features/jira-context.md`.
88
90
 
89
91
  | Outcome | Behavior |
90
92
  |---|---|
91
93
  | `blockers` non-empty | **Halt** (autopilot too): show summary, advise "fix the issue first" |
92
94
  | `warnings` contains `description_empty_parent_available` | Tailored parent-description question above (not the generic one) |
95
+ | `warnings` contains `description_empty_sibling_available` | Same question, sibling key substituted for the parent's |
93
96
  | other `warnings` only | AskUserQuestion: show summary + "Continue?". Autopilot auto-continues; warnings logged to `agent-log.md` |
94
97
  | both empty (score ≥ 90) | Continue silently |
95
98
 
@@ -29,4 +29,10 @@ Show the task's detailed agent-log.md report.
29
29
  ```
30
30
  Exit 2 means no tracker data exists - say so in one line (`cost unavailable: no token telemetry recorded`) instead of leaving the section out silently.
31
31
 
32
- 5. **Provide a summary** - when the log is long, show only the Timeline table + Review Consensus + the cost block, and give the file path for the full log.
32
+ 5. **Council view** - the log records the verdict, not who found what. Render the panel from the state:
33
+ ```bash
34
+ node $HOME/.claude/scripts/council-view.mjs "<artifacts>/agent-state.json"
35
+ ```
36
+ Exit 2 means the run never reached Phase 4 - omit the section rather than reporting an error. The `Seen by` column is how many distinct reviewers raised that finding; it is information, not a verdict.
37
+
38
+ 6. **Provide a summary** - when the log is long, show only the Timeline table + Review Consensus + the cost block, and give the file path for the full log.
@@ -2,6 +2,7 @@
2
2
  description: "Assess whether a GitHub issue is ready for multi-agent development: fetch it, grade scope / acceptance criteria / repro / design / API / stack readiness, then (after confirm) post the gaps as an issue comment. Read-only on code. Use when deciding whether a GitHub issue is specified well enough to hand to development."
3
3
  description-tr: "Bir GitHub issue'sunun multi-agent geliştirmeye hazır olup olmadığını değerlendirir: getirir; kapsam / kabul kriterleri / repro / tasarım / API / stack hazırlığını puanlar, sonra (onay sonrası) eksikleri issue yorumu olarak gönderir. Kodda salt-okunur."
4
4
  argument-hint: "[#N | repo#N | GitHub issue URL] - optional; with no argument, pick from open issues"
5
+ not-for: review-jira
5
6
  ---
6
7
 
7
8
  # multi-agent review-issue - GitHub issue readiness review