@mstar-harness/dsh 3.8.1 → 3.8.3
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/README.i18n.yaml +2 -2
- package/README.md +16 -6
- package/README.zh.md +16 -6
- package/dist/client/panel/engine-status-client.d.ts +84 -6
- package/dist/client/panel/graph/project-graph.d.ts +26 -13
- package/dist/client/panel/guards.d.ts +41 -1
- package/dist/client/panel/locale.d.ts +1 -1
- package/dist/client/panel/pages/AgentListPage.d.ts +1 -1
- package/dist/client/panel/sidebar.d.ts +3 -2
- package/dist/client/panel/state-section.d.ts +25 -3
- package/dist/client/panel/use-mstar-engine-status.d.ts +28 -4
- package/dist/client.js +346 -48
- package/dist/engine-status-endpoint.d.ts +85 -8
- package/dist/engine-status-store.d.ts +91 -1
- package/dist/engine-status-wire.d.ts +9 -0
- package/dist/gates/_shared.d.ts +61 -9
- package/dist/gates/adapter.d.ts +32 -2
- package/dist/gates/agent-flow.d.ts +312 -60
- package/dist/gates/catalog.d.ts +58 -37
- package/dist/gates/dispatch.d.ts +11 -2
- package/dist/gates/goal-bridge.d.ts +10 -130
- package/dist/gates/plan-mode-bridge.d.ts +20 -11
- package/dist/gates/role-persona.d.ts +16 -0
- package/dist/gates/steering.d.ts +41 -0
- package/dist/gates/workflow-ledger.d.ts +31 -4
- package/dist/gates/workflow-selection.d.ts +41 -20
- package/dist/index.js +1206 -392
- package/dist/types.d.ts +36 -11
- package/harness-commands/amazing-e2e-check.md +10 -0
- package/harness-commands/amazing-pr-review.md +2 -0
- package/harness-commands/codebase-audit.md +2 -0
- package/harness-commands/iteration-drive.md +1 -1
- package/harness-skills/mstar-artifacts/references/plan-files-and-reports.md +2 -2
- package/harness-skills/mstar-artifacts/references/plan-quality-bar.md +14 -12
- package/harness-skills/mstar-artifacts/templates/plan.main.md +19 -6
- package/harness-skills/mstar-audit/SKILL.md +5 -5
- package/harness-skills/mstar-coding-behavior/SKILL.md +8 -8
- package/harness-skills/mstar-dispatch-gates/SKILL.md +9 -7
- package/harness-skills/mstar-e2e/SKILL.md +40 -0
- package/harness-skills/mstar-e2e/references/report-template.md +32 -0
- package/harness-skills/mstar-engine-legacy/references/qc-seat-n-restatements.md +3 -3
- package/harness-skills/mstar-harness-core/SKILL.md +14 -1
- package/harness-skills/mstar-host/SKILL.md +3 -1
- package/harness-skills/mstar-host/references/_shared/host-role-binding-core.md +1 -1
- package/harness-skills/mstar-host/references/cursor.md +1 -1
- package/harness-skills/mstar-host/references/dsh-workflow-scripts.md +424 -0
- package/harness-skills/mstar-host/references/dsh.md +180 -51
- package/harness-skills/mstar-host/references/kimi.md +3 -3
- package/harness-skills/mstar-host/references/omp.md +3 -3
- package/harness-skills/mstar-host/references/parallel-dispatch.md +6 -6
- package/harness-skills/mstar-host/references/zcode.md +4 -4
- package/harness-skills/mstar-iteration/SKILL.md +1 -1
- package/harness-skills/mstar-iteration/references/phase-1-prepare.md +2 -2
- package/harness-skills/mstar-iteration/references/phase-2-worktree-lease.md +3 -3
- package/harness-skills/mstar-review-qc/SKILL.md +4 -4
- package/harness-skills/mstar-review-qc/references/review-responsibility-boundaries.md +9 -7
- package/harness-skills/mstar-roles/SKILL.md +2 -0
- package/harness-skills/mstar-roles/references/_shared/leaf-executor-core.md +9 -0
- package/harness-skills/mstar-roles/references/ops-engineer.md +3 -0
- package/harness-skills/mstar-roles/references/project-manager/dispatch-and-assignment.md +12 -9
- package/harness-skills/mstar-roles/references/project-manager/qa-trigger-matrix.md +7 -5
- package/harness-skills/mstar-roles/references/project-manager/qc-and-residuals.md +2 -2
- package/harness-skills/mstar-roles/references/project-manager/routing-and-dev-allocation.md +2 -2
- package/harness-skills/mstar-roles/references/project-manager.md +4 -2
- package/harness-skills/mstar-roles/references/qa-engineer/acceptance-gate.md +12 -13
- package/harness-skills/mstar-roles/references/qa-engineer.md +5 -4
- package/harness-skills/mstar-roles/references/qc-specialist/deep-review-lenses.md +5 -5
- package/harness-skills/mstar-roles/references/qc-specialist/report-template.md +2 -0
- package/harness-skills/mstar-roles/references/qc-specialist/reviewer-checklist.md +1 -1
- package/harness-skills/mstar-roles/references/qc-specialist/reviewer-workflow.md +5 -4
- package/harness-skills/mstar-roles/references/qc-specialist-shared.md +3 -1
- package/harness-skills/mstar-sdd/SKILL.md +17 -9
- package/harness-skills/mstar-sdd/references/file-handoffs.md +40 -20
- package/harness-skills/mstar-sdd/references/implementer-continuation-prompt.md +9 -4
- package/harness-skills/mstar-sdd/references/implementer-prompt.md +11 -6
- package/harness-skills/mstar-sdd/references/sticky-implementer-session.md +4 -2
- package/harness-skills/mstar-sdd/references/task-reviewer-prompt.md +8 -4
- package/package.json +2 -2
|
@@ -48,9 +48,11 @@ Order matters: check `cursor` → `opencode` → `omp` → `dsh` → `kimi` →
|
|
|
48
48
|
|
|
49
49
|
When PM dispatches **N >= 2** concurrent assignees (QC tri-review, dual-track implement, etc.) and the host exposes actual invoke / Task / subagent tools, read **`references/parallel-dispatch.md`** in the dispatch round (shared with `mstar-dispatch-gates`). Without a callable invoke tool when dispatch is required → **`Blocked`**; Assignment Markdown alone is not dispatch.
|
|
50
50
|
|
|
51
|
+
On **dsh** only, read-only fan-out of **N ≥ 3** seats runs through the native **`workflow`** tool instead of N `subagent` invokes (1–2 delegations keep `subagent`; writable fan-out never uses it) — scripts + operator path: `references/dsh.md` § Read-only fan-out via the `workflow` tool.
|
|
52
|
+
|
|
51
53
|
## `/goal` directive (host-agnostic)
|
|
52
54
|
|
|
53
|
-
**Applicability is by capability, not host identity**: any host that exposes a `/goal` command (currently Codex Goal Mode and omp; other code agents may add it later) attaches a persistent objective to the thread. Rule — **always set the goal to running the complete flow to the end**, never a sub-stage:
|
|
55
|
+
**Applicability is by capability, not host identity**: any host that exposes a `/goal` command (currently Codex Goal Mode and omp; other code agents may add it later) attaches a persistent objective to the thread. **Exception — dsh:** mstar **stops arming** a goal there and never uses a `/goal` objective or a goal round loop as the progression driver — dsh runs on the native workflow (workflow snapshot phases + dispatch gates + **subagent settle notifications**; Phase 2 is a PM-local dispatch → wait for the child's settle notification → next dispatch, and a manually armed `/goal` stays outside mstar's flow). Full rule → `references/dsh.md`. Rule — **always set the goal to running the complete flow to the end**, never a sub-stage:
|
|
54
56
|
|
|
55
57
|
- **Advancing an iteration**: set the goal to **complete the entire iteration flow** (`iteration-start → per-plan cycles → iteration-close → PR delivery → PR merge-ready loop`). Do not set a sub-stage goal (e.g. "finish Phase 1 only").
|
|
56
58
|
- **Advancing non-iteration work** (single plan / hotfix / one-off task): set the goal to **complete the entire per-plan flow** (`specify → clarify → plan → tasks → implement → plan QC tri + QA gate → Done`). Do not set a sub-stage goal (e.g. "write the plan" or "implement one task").
|
|
@@ -29,7 +29,7 @@ Paste-only Assignment **without** an invoke call is **not** dispatch.
|
|
|
29
29
|
- **1 Assignment ⇒ 1 invoke**: one invoke call carrying the full Assignment body per assignee.
|
|
30
30
|
- **Parallel batch N**: **N** invocations in **one** assistant message (mechanics → **`parallel-dispatch.md`**).
|
|
31
31
|
- **No invoke call** → **Not dispatched** — paste-only / `dispatch incomplete`.
|
|
32
|
-
- **Anti-recursion NEVER**: leaf executors are already `Execute as` — **no** recursive invoke of the same role; Assignment wins (`Delegation: forbidden` unless stated).
|
|
32
|
+
- **Anti-recursion NEVER**: leaf executors are already `Execute as` — **no** recursive invoke of the same role; Assignment wins (`Delegation: forbidden` unless stated). Independent ready implementers may run concurrently after isolation; scheduling → **`parallel-dispatch.md`** § SDD implement.
|
|
33
33
|
|
|
34
34
|
## Assignment / prompt template
|
|
35
35
|
|
|
@@ -45,7 +45,7 @@ Enforcement: `rules/mstar-cursor-plan-mode.mdc` when plugin active.
|
|
|
45
45
|
|
|
46
46
|
- **`Execution mode: sdd`**: **N=3** Tasks (`qc-specialist`, `qc-specialist-2`, `qc-specialist-3`) + branch review-package path (N rules → `parallel-dispatch.md`).
|
|
47
47
|
- **`inline`**: **N=1** per `parallel-dispatch.md`.
|
|
48
|
-
- SDD implement/reviewer:
|
|
48
|
+
- SDD implement/reviewer: ready-task scheduling per **`mstar-sdd`** — implementer Task per task id with `subagent_type` matching the implementer role when listed; task reviewer = new Task with `subagent_type: "code-reviewer"` (Cursor L2 review; not qc-specialist*) when listed, else generic fallback per C5 — no `resume` for reviewers. See **`mstar-sdd`**.
|
|
49
49
|
|
|
50
50
|
## SDD sticky implementer (Cursor Task resume)
|
|
51
51
|
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
# dsh workflow scripts — canonical read-only fan-out templates
|
|
2
|
+
|
|
3
|
+
Copy-paste templates for the dsh **`workflow`** tool (`@deepseek-ai/dsh-tool-workflow`, mounted by the
|
|
4
|
+
shipped agent presets; the `ptc` preset disables it). Use them for **read-only** fan-out of **N ≥ 3**
|
|
5
|
+
seats — plan QC tri, large-repo audit categories, `/amazing-pr-review deep` seats. House rules and the
|
|
6
|
+
operator path live in skill **`mstar-host`** → `references/dsh.md` § Read-only fan-out via the `workflow`
|
|
7
|
+
tool; this file holds only the scripts, their `meta`, and their `args`.
|
|
8
|
+
|
|
9
|
+
## How to call
|
|
10
|
+
|
|
11
|
+
One `workflow` tool call carries three JSON/JS parameters:
|
|
12
|
+
|
|
13
|
+
- `script` — a plain-JavaScript body (NOT TypeScript, NO `export const meta` statement), top-level
|
|
14
|
+
`await` allowed, ending with `return <JSON value>`.
|
|
15
|
+
- `meta` — plain JSON identity: `name` (short kebab-case), `description`, optional `whenToUse`,
|
|
16
|
+
optional `phases[] = { title, detail? }`. `phase()` calls and `agent({ phase })` strings match
|
|
17
|
+
`phases[].title` by exact string.
|
|
18
|
+
- `args` — plain JSON object exposed to the script verbatim as the `args` global.
|
|
19
|
+
|
|
20
|
+
Script hooks: `agent(prompt, opts?)`, `parallel(thunks)`, `pipeline(items, ...stages)`, `phase(title)`,
|
|
21
|
+
`log(message)`, `args`. `agent()` opts are exactly `label`, `phase`, `schema`, `provider`, `model` —
|
|
22
|
+
anything else (including the deferred agent-type selector and `effort` / `isolation`) is rejected
|
|
23
|
+
loudly and kills the script. With `schema` the child resolves to the validated object; on child
|
|
24
|
+
failure `agent()` resolves `null` (`parallel()` maps a throwing thunk to `null` the same way). No
|
|
25
|
+
filesystem, network, timers or Node APIs; concurrency and total-agent caps apply; the parent turn
|
|
26
|
+
blocks until the whole run settles.
|
|
27
|
+
|
|
28
|
+
Supported `schema` subset (object-rooted): `type`, `properties`, `required`, `additionalProperties`,
|
|
29
|
+
`items`, `enum`, `const`, `oneOf`, plus the ignored annotations `description` / `title` / `default` /
|
|
30
|
+
`examples`. Anything else (`pattern`, `format`, numeric bounds) is fatal.
|
|
31
|
+
|
|
32
|
+
Every `agent()` prompt below opens with the Assignment header (`## Assignment` + `Execute as` /
|
|
33
|
+
`Delegation` / `Task category`) — header first, because the engine reads only the header region, and
|
|
34
|
+
the role persona is resolved from `Execute as` (`packages/dsh/src/gates/role-persona.ts`). Children are
|
|
35
|
+
delegated children: approval is pinned to `never`, so a seat must never depend on writing files —
|
|
36
|
+
return everything in the result payload.
|
|
37
|
+
|
|
38
|
+
| Operator path | Script | `meta.name` | Seats |
|
|
39
|
+
|---|---|---|---|
|
|
40
|
+
| Plan QC tri (`Execution mode: sdd`) | § 1 | `mstar-qc-tri` | 3 (`qc-specialist`, `qc-specialist-2`, `qc-specialist-3`) |
|
|
41
|
+
| `/codebase-audit` large-repo category fan-out | § 2 | `mstar-audit-fanout` | 9 (one per audit category) |
|
|
42
|
+
| `/amazing-pr-review deep` | § 3 | `mstar-pr-seats` | 3–4 (2–3 domain + optional cross-domain security) |
|
|
43
|
+
| Any 1–2 read-only delegation | — | — | keep `subagent` — no script, no `workflow-run` node |
|
|
44
|
+
|
|
45
|
+
## 1. `mstar-qc-tri` — plan QC tri-review
|
|
46
|
+
|
|
47
|
+
Three independent read-only QC seats over one review range; each returns a verdict envelope. The
|
|
48
|
+
returned envelopes are the seat reports' content source: the caller persists
|
|
49
|
+
`{SDD_DIR}/review/qc1.md` … `qc3.md` from them (a seat may also write its own file best-effort when
|
|
50
|
+
its sandbox permits).
|
|
51
|
+
|
|
52
|
+
**`meta`**
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"name": "mstar-qc-tri",
|
|
57
|
+
"description": "Plan QC tri-review: three independent read-only QC seats over one review range, each returning a verdict envelope.",
|
|
58
|
+
"whenToUse": "dsh host, Execution mode: sdd — the changed-scope plan QC tri instead of three subagent dispatches.",
|
|
59
|
+
"phases": [
|
|
60
|
+
{ "title": "qc-tri", "detail": "Three concurrent read-only QC seats over the same review range." }
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**`args`**
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"planId": "<plan-id>",
|
|
70
|
+
"planPath": "<absolute path to the main plan file>",
|
|
71
|
+
"range": "<base>..<head>",
|
|
72
|
+
"reviewCwd": "<absolute review worktree path>",
|
|
73
|
+
"branch": "feature/<plan-id>",
|
|
74
|
+
"sddDir": "<absolute path to the SDD dir>"
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**`script`**
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
const a = args ?? {}
|
|
82
|
+
const missing = ['planId', 'planPath', 'range', 'reviewCwd', 'branch', 'sddDir']
|
|
83
|
+
.filter((key) => typeof a[key] !== 'string' || a[key].length === 0)
|
|
84
|
+
if (missing.length > 0) throw new Error('mstar-qc-tri missing args: ' + missing.join(', '))
|
|
85
|
+
|
|
86
|
+
const sddDir = a.sddDir.replace(/\/$/, '')
|
|
87
|
+
|
|
88
|
+
const VERDICT = {
|
|
89
|
+
type: 'object',
|
|
90
|
+
description: 'One QC seat verdict envelope.',
|
|
91
|
+
required: ['seat', 'verdict', 'summary', 'findings'],
|
|
92
|
+
properties: {
|
|
93
|
+
seat: {
|
|
94
|
+
type: 'string',
|
|
95
|
+
enum: ['qc-specialist', 'qc-specialist-2', 'qc-specialist-3'],
|
|
96
|
+
description: 'The seat that produced this envelope.',
|
|
97
|
+
},
|
|
98
|
+
verdict: {
|
|
99
|
+
type: 'string',
|
|
100
|
+
enum: ['Approve', 'Request Changes', 'Needs Discussion', 'Unconfirmed'],
|
|
101
|
+
},
|
|
102
|
+
summary: {
|
|
103
|
+
type: 'string',
|
|
104
|
+
description: 'Two or three sentences; state the critical/warning counts.',
|
|
105
|
+
},
|
|
106
|
+
findings: {
|
|
107
|
+
type: 'array',
|
|
108
|
+
items: {
|
|
109
|
+
type: 'object',
|
|
110
|
+
required: ['severity', 'title', 'verification', 'expectedVsObserved'],
|
|
111
|
+
properties: {
|
|
112
|
+
severity: { type: 'string', enum: ['Critical', 'Warning', 'Suggestion', 'Unconfirmed'] },
|
|
113
|
+
title: { type: 'string', description: 'Short imperative title.' },
|
|
114
|
+
location: { type: 'string', description: 'path/file.ts:123 evidence anchor.' },
|
|
115
|
+
verification: { type: 'string', description: 'The cross-check used (diff/read/grep anchor or repro).' },
|
|
116
|
+
expectedVsObserved: { type: 'string' },
|
|
117
|
+
fix: { type: 'string', description: 'One line.' },
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const opts = { phase: 'qc-tri', schema: VERDICT }
|
|
125
|
+
|
|
126
|
+
phase('qc-tri')
|
|
127
|
+
|
|
128
|
+
const seats = await parallel([
|
|
129
|
+
() => agent(`## Assignment
|
|
130
|
+
|
|
131
|
+
Execute as: qc-specialist
|
|
132
|
+
Delegation: forbidden
|
|
133
|
+
Task category: audit
|
|
134
|
+
|
|
135
|
+
plan_id: ${a.planId}
|
|
136
|
+
Review range: ${a.range}
|
|
137
|
+
Review cwd: ${a.reviewCwd}
|
|
138
|
+
Working branch: ${a.branch}
|
|
139
|
+
Report path: ${sddDir}/review/qc1.md
|
|
140
|
+
Reviewer focus: architecture coherence and maintainability risk (reviewer_index 1)
|
|
141
|
+
|
|
142
|
+
You are the first of three INDEPENDENT read-only QC seats over the same review range. Do not consult or wait for the other seats.
|
|
143
|
+
|
|
144
|
+
Load in order: skill mstar-roles then references/qc-specialist-shared.md (identity first), then references/qc-specialist/report-template.md and references/qc-specialist/reviewer-checklist.md; the plan at ${a.planPath}.
|
|
145
|
+
|
|
146
|
+
Review only changed hunks and directly affected interfaces in the review range above against that plan. Reuse unchanged task-review evidence; for re-review inspect only assigned findings and fix delta. Every finding needs a verification cross-check and an expected-vs-observed line; prefer omission to fabrication. Do not run build or test suites (they are not your evidence channel). Never edit the worktree, never post, never merge, never touch project registers.
|
|
147
|
+
|
|
148
|
+
Return ONLY the JSON object matching the provided schema (seat, verdict, summary, findings). If your sandbox permits, also write the full report to the report path above — never depend on being able to write.`, { ...opts, label: 'qc1-architecture' }),
|
|
149
|
+
() => agent(`## Assignment
|
|
150
|
+
|
|
151
|
+
Execute as: qc-specialist-2
|
|
152
|
+
Delegation: forbidden
|
|
153
|
+
Task category: audit
|
|
154
|
+
|
|
155
|
+
plan_id: ${a.planId}
|
|
156
|
+
Review range: ${a.range}
|
|
157
|
+
Review cwd: ${a.reviewCwd}
|
|
158
|
+
Working branch: ${a.branch}
|
|
159
|
+
Report path: ${sddDir}/review/qc2.md
|
|
160
|
+
Reviewer focus: security and correctness risk (reviewer_index 2)
|
|
161
|
+
|
|
162
|
+
You are the second of three INDEPENDENT read-only QC seats over the same review range. Do not consult or wait for the other seats.
|
|
163
|
+
|
|
164
|
+
Load in order: skill mstar-roles then references/qc-specialist-shared.md (identity first), then references/qc-specialist/report-template.md, references/qc-specialist/reviewer-checklist.md and references/qc-specialist/deep-review-lenses.md; the plan at ${a.planPath}.
|
|
165
|
+
|
|
166
|
+
Review only changed hunks and directly affected interfaces in the review range above against that plan. Reuse unchanged task-review evidence; for re-review inspect only assigned findings and fix delta, with the security and correctness lenses. Every finding needs a verification cross-check and an expected-vs-observed line; prefer omission to fabrication. Do not run build or test suites. Never edit the worktree, never post, never merge, never touch project registers.
|
|
167
|
+
|
|
168
|
+
Return ONLY the JSON object matching the provided schema (seat, verdict, summary, findings). If your sandbox permits, also write the full report to the report path above — never depend on being able to write.`, { ...opts, label: 'qc2-security-correctness' }),
|
|
169
|
+
() => agent(`## Assignment
|
|
170
|
+
|
|
171
|
+
Execute as: qc-specialist-3
|
|
172
|
+
Delegation: forbidden
|
|
173
|
+
Task category: audit
|
|
174
|
+
|
|
175
|
+
plan_id: ${a.planId}
|
|
176
|
+
Review range: ${a.range}
|
|
177
|
+
Review cwd: ${a.reviewCwd}
|
|
178
|
+
Working branch: ${a.branch}
|
|
179
|
+
Report path: ${sddDir}/review/qc3.md
|
|
180
|
+
Reviewer focus: performance and reliability risk (reviewer_index 3)
|
|
181
|
+
|
|
182
|
+
You are the third of three INDEPENDENT read-only QC seats over the same review range. Do not consult or wait for the other seats.
|
|
183
|
+
|
|
184
|
+
Load in order: skill mstar-roles then references/qc-specialist-shared.md (identity first), then references/qc-specialist/report-template.md, references/qc-specialist/reviewer-checklist.md and references/qc-specialist/deep-review-lenses.md; the plan at ${a.planPath}.
|
|
185
|
+
|
|
186
|
+
Review only changed hunks and directly affected interfaces in the review range above against that plan. Reuse unchanged task-review evidence; for re-review inspect only assigned findings and fix delta, with the performance and reliability lenses. Every finding needs a verification cross-check and an expected-vs-observed line; prefer omission to fabrication. Do not run build or test suites. Never edit the worktree, never post, never merge, never touch project registers.
|
|
187
|
+
|
|
188
|
+
Return ONLY the JSON object matching the provided schema (seat, verdict, summary, findings). If your sandbox permits, also write the full report to the report path above — never depend on being able to write.`, { ...opts, label: 'qc3-perf-reliability' }),
|
|
189
|
+
])
|
|
190
|
+
|
|
191
|
+
// A null entry is a seat whose child failed: its verdict is missing and the caller
|
|
192
|
+
// must re-dispatch that seat (or report Blocked) — never synthesize a verdict for it.
|
|
193
|
+
return seats
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## 2. `mstar-audit-fanout` — large-repo category fan-out
|
|
197
|
+
|
|
198
|
+
One read-only audit seat per category (the nine `mstar-audit` categories), each returning findings in
|
|
199
|
+
the audit finding format. Scope comes from `args.categories` (default: all nine); the reconciling,
|
|
200
|
+
vetting and plan-writing stay with the audit executor (main agent).
|
|
201
|
+
|
|
202
|
+
**`meta`**
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"name": "mstar-audit-fanout",
|
|
207
|
+
"description": "Large-repo codebase audit: one read-only audit seat per category, each returning findings in the audit finding format.",
|
|
208
|
+
"whenToUse": "dsh host, /codebase-audit on a repo large enough to need per-category parallel read-only fan-out (N >= 3).",
|
|
209
|
+
"phases": [
|
|
210
|
+
{ "title": "bug" },
|
|
211
|
+
{ "title": "security" },
|
|
212
|
+
{ "title": "perf" },
|
|
213
|
+
{ "title": "tests" },
|
|
214
|
+
{ "title": "tech-debt" },
|
|
215
|
+
{ "title": "migration" },
|
|
216
|
+
{ "title": "dx" },
|
|
217
|
+
{ "title": "docs" },
|
|
218
|
+
{ "title": "direction" }
|
|
219
|
+
]
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**`args`**
|
|
224
|
+
|
|
225
|
+
```json
|
|
226
|
+
{
|
|
227
|
+
"repo": "<absolute path to the repo under audit>",
|
|
228
|
+
"auditRef": "<absolute path to the mstar-audit skill references dir>",
|
|
229
|
+
"recon": "<recon facts: languages, frameworks, key directories, what to skip, decided tradeoffs>",
|
|
230
|
+
"categories": ["bug", "security", "perf"]
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
`categories` is optional — omit it for all nine. Keep the batch at one seat per category (concurrency
|
|
235
|
+
caps apply above the fan-out width).
|
|
236
|
+
|
|
237
|
+
**`script`**
|
|
238
|
+
|
|
239
|
+
```js
|
|
240
|
+
const a = args ?? {}
|
|
241
|
+
const missing = ['repo', 'auditRef', 'recon']
|
|
242
|
+
.filter((key) => typeof a[key] !== 'string' || a[key].length === 0)
|
|
243
|
+
if (missing.length > 0) throw new Error('mstar-audit-fanout missing args: ' + missing.join(', '))
|
|
244
|
+
|
|
245
|
+
const ALL = ['bug', 'security', 'perf', 'tests', 'tech-debt', 'migration', 'dx', 'docs', 'direction']
|
|
246
|
+
const categories = Array.isArray(a.categories) && a.categories.length > 0 ? a.categories : ALL
|
|
247
|
+
|
|
248
|
+
const FINDING = {
|
|
249
|
+
type: 'object',
|
|
250
|
+
description: 'One audit category seat payload.',
|
|
251
|
+
required: ['category', 'findings'],
|
|
252
|
+
properties: {
|
|
253
|
+
category: { type: 'string', enum: ALL },
|
|
254
|
+
findings: {
|
|
255
|
+
type: 'array',
|
|
256
|
+
items: {
|
|
257
|
+
type: 'object',
|
|
258
|
+
required: ['title', 'evidence', 'impact', 'effort', 'risk', 'confidence', 'fix'],
|
|
259
|
+
properties: {
|
|
260
|
+
title: { type: 'string', description: 'Short imperative title.' },
|
|
261
|
+
evidence: { type: 'string', description: 'path/file.ts:123 plus one sentence (2-5 strongest locations).' },
|
|
262
|
+
impact: { type: 'string', description: 'What goes wrong / what is being paid.' },
|
|
263
|
+
effort: { type: 'string', enum: ['XS', 'S', 'M', 'L', 'XL'] },
|
|
264
|
+
risk: { type: 'string', enum: ['LOW', 'MED', 'HIGH'], description: 'What the fix could break, plus one line why.' },
|
|
265
|
+
confidence: { type: 'string', enum: ['HIGH', 'MED', 'LOW'] },
|
|
266
|
+
fix: { type: 'string', description: 'One to three sentences — a sketch, not the plan.' },
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
notes: { type: 'string', description: 'Truncated coverage declaration and leads that are not findings.' },
|
|
271
|
+
},
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const seatPrompt = (category) => `## Assignment
|
|
275
|
+
|
|
276
|
+
Execute as: code-reviewer
|
|
277
|
+
Delegation: forbidden
|
|
278
|
+
Task category: audit
|
|
279
|
+
|
|
280
|
+
Audit category: ${category}
|
|
281
|
+
Repo under audit: ${a.repo}
|
|
282
|
+
Reference root: ${a.auditRef}
|
|
283
|
+
|
|
284
|
+
Read-only audit seat (one category of a parallel fan-out; the audit executor reconciles, vets and writes plans — you do not).
|
|
285
|
+
|
|
286
|
+
Recon facts already established: ${a.recon}
|
|
287
|
+
|
|
288
|
+
Load in order: ${a.auditRef}/audit-playbook.md section for your category plus the section "Finding format" (read it first — findings must match that shape exactly); for the security category also read ${a.auditRef}/security-review.md. Open every location you cite yourself, in ${a.repo}.
|
|
289
|
+
|
|
290
|
+
Report only what you can evidence: exact file:line anchors, a concrete impact, an honest effort on the XS-XL scale, the risk of the fix, and a HIGH/MED/LOW confidence. LOW-confidence items are allowed but are leads, not plan candidates. Do not edit any file, do not run project-wide suites, never reproduce secret values.
|
|
291
|
+
|
|
292
|
+
Return ONLY the JSON object matching the provided schema (category, findings, notes). Put the truncated-coverage declaration and any non-finding leads in notes.`
|
|
293
|
+
|
|
294
|
+
const seats = await parallel(categories.map((category) => () =>
|
|
295
|
+
agent(seatPrompt(category), { label: category, phase: category, schema: FINDING })))
|
|
296
|
+
|
|
297
|
+
// A null entry is a category whose seat failed — the caller reports the uncollected
|
|
298
|
+
// category as such; it is never reported as "no findings".
|
|
299
|
+
return seats
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## 3. `mstar-pr-seats` — `/amazing-pr-review deep` seats
|
|
303
|
+
|
|
304
|
+
Domain seats (2–3) plus an optional independent cross-domain security seat, all read-only, all
|
|
305
|
+
returning findings with a merge class and **no verdict** — synthesis (dedupe, tiered vet, tally,
|
|
306
|
+
verdict, posting) stays with the main agent, exactly as the `pr` variant requires. Do not use this
|
|
307
|
+
script for the `default` tier (two seats → `subagent`) or `quick` (one seat).
|
|
308
|
+
|
|
309
|
+
**`meta`**
|
|
310
|
+
|
|
311
|
+
```json
|
|
312
|
+
{
|
|
313
|
+
"name": "mstar-pr-seats",
|
|
314
|
+
"description": "Deep PR review: read-only domain review seats (2-3) plus an optional independent cross-domain security seat, each returning findings with a merge class and no verdict.",
|
|
315
|
+
"whenToUse": "dsh host, /amazing-pr-review deep (3-4 seats) after the review worktree and diff basis are resolved.",
|
|
316
|
+
"phases": [
|
|
317
|
+
{ "title": "pr-seats", "detail": "Domain review seats plus the cross-domain security seat." }
|
|
318
|
+
]
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**`args`**
|
|
323
|
+
|
|
324
|
+
```json
|
|
325
|
+
{
|
|
326
|
+
"worktree": "<absolute review worktree path>",
|
|
327
|
+
"target": "<owner>/<repo>#<n> or branch:<slug> or diff:<short-sha>",
|
|
328
|
+
"diffBase": "<base>..<head>",
|
|
329
|
+
"diffFile": "<absolute path to the pinned diff snapshot, when worktree-setup produced one>",
|
|
330
|
+
"reportsDir": "<absolute directory for the stage-2 evidence files>",
|
|
331
|
+
"auditRef": "<absolute path to the mstar-audit skill references dir>",
|
|
332
|
+
"domains": ["code", "tests"],
|
|
333
|
+
"security": true
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
`domains` holds 2–3 domain labels (business domain / change surface / tech stack); with
|
|
338
|
+
`security: true` (the default) the seat count is 3 or 4.
|
|
339
|
+
|
|
340
|
+
**`script`**
|
|
341
|
+
|
|
342
|
+
```js
|
|
343
|
+
const a = args ?? {}
|
|
344
|
+
const missing = ['worktree', 'target', 'diffBase', 'reportsDir', 'auditRef']
|
|
345
|
+
.filter((key) => typeof a[key] !== 'string' || a[key].length === 0)
|
|
346
|
+
if (missing.length > 0) throw new Error('mstar-pr-seats missing args: ' + missing.join(', '))
|
|
347
|
+
|
|
348
|
+
const domains = Array.isArray(a.domains) ? a.domains : []
|
|
349
|
+
if (domains.length < 2 || domains.length > 3) {
|
|
350
|
+
throw new Error('mstar-pr-seats: args.domains must hold 2-3 domain labels (deep tier) — got ' + domains.length)
|
|
351
|
+
}
|
|
352
|
+
const withSecurity = a.security !== false
|
|
353
|
+
const diffHint = typeof a.diffFile === 'string' && a.diffFile.length > 0
|
|
354
|
+
? 'the pinned diff snapshot at ' + a.diffFile + ', plus ' + a.diffBase + ' in ' + a.worktree
|
|
355
|
+
: a.diffBase + ' in ' + a.worktree
|
|
356
|
+
|
|
357
|
+
const SEAT = {
|
|
358
|
+
type: 'object',
|
|
359
|
+
description: 'One read-only PR review seat payload (findings only — the seat produces no verdict).',
|
|
360
|
+
required: ['domain', 'findings'],
|
|
361
|
+
properties: {
|
|
362
|
+
domain: { type: 'string', description: 'The seat domain label.' },
|
|
363
|
+
findings: {
|
|
364
|
+
type: 'array',
|
|
365
|
+
items: {
|
|
366
|
+
type: 'object',
|
|
367
|
+
required: ['title', 'evidence', 'impact', 'effort', 'risk', 'confidence', 'mergeClass', 'fix'],
|
|
368
|
+
properties: {
|
|
369
|
+
title: { type: 'string', description: 'Short imperative title.' },
|
|
370
|
+
evidence: { type: 'string', description: 'path/file.ts:123 — code you opened yourself.' },
|
|
371
|
+
impact: { type: 'string' },
|
|
372
|
+
effort: { type: 'string', enum: ['XS', 'S', 'M', 'L', 'XL'] },
|
|
373
|
+
risk: { type: 'string', enum: ['LOW', 'MED', 'HIGH'] },
|
|
374
|
+
confidence: { type: 'string', enum: ['HIGH', 'MED', 'LOW'] },
|
|
375
|
+
mergeClass: { type: 'string', enum: ['must-fix', 'should-fix', 'nit'] },
|
|
376
|
+
fix: { type: 'string', description: 'One line.' },
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
leads: { type: 'array', items: { type: 'string' }, description: 'MEDIUM/unverified observations — leads, not findings.' },
|
|
381
|
+
notes: { type: 'string', description: 'Truncated-coverage declaration and cross-domain notes.' },
|
|
382
|
+
},
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const seatPrompt = (domain, extra) => `## Assignment
|
|
386
|
+
|
|
387
|
+
Execute as: code-reviewer
|
|
388
|
+
Delegation: forbidden
|
|
389
|
+
Task category: audit
|
|
390
|
+
|
|
391
|
+
Review target: ${a.target}
|
|
392
|
+
Review worktree: ${a.worktree}
|
|
393
|
+
Domain: ${domain}
|
|
394
|
+
Diff basis: ${a.diffBase}
|
|
395
|
+
Stage: Stage 2 domain review — read-only, you never post and never produce the verdict.
|
|
396
|
+
|
|
397
|
+
Read-only audit seat in the three-stage PR review pipeline; the main agent synthesizes one verdict and posts.
|
|
398
|
+
|
|
399
|
+
Load in order: skill mstar-audit then SKILL.md and references/pr-review-seat-evidence.md; ${a.auditRef}/pr-review.md sections "Review pipeline", "Merge class" and "Verdict synthesis"; ${a.auditRef}/finding-format.md for the finding fields. Then read ${diffHint}. Open the cited code yourself — a relayed claim from another seat is not evidence.
|
|
400
|
+
|
|
401
|
+
Conclude ONLY on your own domain (${domain}).${extra} Return findings with merge class must-fix | should-fix | nit, an XS-XL effort, a risk level, a confidence and a one-line fix sketch. Cross-domain boundary issues go to notes, not findings. Do not edit the worktree, do not run project-wide suites, never reproduce secret values.
|
|
402
|
+
|
|
403
|
+
Return ONLY the JSON object matching the provided schema (domain, findings, leads, notes). No verdict.`
|
|
404
|
+
|
|
405
|
+
phase('pr-seats')
|
|
406
|
+
|
|
407
|
+
const thunks = domains.map((domain, index) => () => agent(
|
|
408
|
+
seatPrompt(domain, ''),
|
|
409
|
+
{ label: 'domain-' + (index + 1), phase: 'pr-seats', schema: SEAT },
|
|
410
|
+
))
|
|
411
|
+
|
|
412
|
+
if (withSecurity) {
|
|
413
|
+
thunks.push(() => agent(
|
|
414
|
+
seatPrompt('security (cross-domain)', ' Run the security lens from ' + a.auditRef + '/security-review.md across the whole diff, independent of the domain seats: trace data flow to its origin, never invent an attacker, never record secret values.'),
|
|
415
|
+
{ label: 'security-cross-domain', phase: 'pr-seats', schema: SEAT },
|
|
416
|
+
))
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const seats = await parallel(thunks)
|
|
420
|
+
|
|
421
|
+
// A null entry is an uncollected domain (seat crashed or returned nothing) — the caller
|
|
422
|
+
// declares it as uncollected under the report notes and never reads it as "no findings".
|
|
423
|
+
return seats
|
|
424
|
+
```
|