@mstar-harness/dsh 3.8.0 → 3.8.2
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 +142 -194
- package/README.zh.md +29 -17
- package/bundle/README.md +83 -171
- package/dist/client/index.d.ts +17 -8
- package/dist/client/panel/MstarPanelTitle.d.ts +13 -0
- package/dist/client/panel/PanelView.d.ts +56 -52
- package/dist/client/panel/TabNav.d.ts +17 -14
- package/dist/client/panel/definition.d.ts +23 -0
- package/dist/client/panel/engine-status-client.d.ts +84 -6
- package/dist/client/panel/graph/project-graph.d.ts +35 -64
- package/dist/client/panel/graph/schema.d.ts +1 -2
- package/dist/client/panel/guards.d.ts +41 -1
- package/dist/client/panel/locale.d.ts +1 -1
- package/dist/client/panel/mstar-glyph.d.ts +22 -0
- package/dist/client/panel/pages/AgentListPage.d.ts +71 -0
- package/dist/client/panel/pages/EventLogPage.d.ts +7 -4
- package/dist/client/panel/pages/IterationInfoSection.d.ts +16 -13
- package/dist/client/panel/pages/IterationTaskPage.d.ts +13 -14
- package/dist/client/panel/panel-store.d.ts +28 -0
- package/dist/client/panel/sidebar.d.ts +13 -7
- package/dist/client/panel/state-section.d.ts +25 -3
- package/dist/client/panel/use-mstar-engine-status.d.ts +39 -14
- package/dist/client/panel/zones/Legend.d.ts +5 -3
- package/dist/client/panel/zones/TaskBoard.d.ts +13 -9
- package/dist/client.js +1038 -1242
- 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 +59 -38
- 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 +1208 -394
- package/dist/types.d.ts +50 -18
- package/harness-commands/amazing-pr-review.md +2 -0
- package/harness-commands/codebase-audit.md +2 -0
- package/harness-skills/mstar-host/SKILL.md +3 -1
- package/harness-skills/mstar-host/references/dsh-workflow-scripts.md +424 -0
- package/harness-skills/mstar-host/references/dsh.md +259 -266
- package/harness-skills/mstar-roles/references/project-manager.md +2 -0
- package/harness-skills/mstar-sdd/SKILL.md +2 -0
- package/package.json +66 -64
- package/dist/client/panel/pages/AgentCanvasPage.d.ts +0 -345
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `mstar-engine
|
|
2
|
+
* `mstar-engine` catalog source + payload: the durable `catalog`-form
|
|
3
3
|
* MessageSource the plugin appends to every composed step at
|
|
4
4
|
* `agent/pre-step`, so the model-visible engine-status row is
|
|
5
5
|
* reconstructable from the session log without re-parsing its prose
|
|
@@ -25,15 +25,22 @@ import type { EnforcementFlag } from '@mstar-harness/engine';
|
|
|
25
25
|
* `plugin` arm with a CLOSED member set — exactly these three keys, never a
|
|
26
26
|
* fourth.
|
|
27
27
|
*
|
|
28
|
-
* `plugin` carries the plugin's identity
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
28
|
+
* `plugin` carries the plugin's identity and `form: 'catalog'` the row's
|
|
29
|
+
* first-party presentation; both are opaque, already-admitted vocabulary at
|
|
30
|
+
* every released session-format edge. Everything the row publishes about the
|
|
31
|
+
* workspace lives in {@link MstarEngineStatusPayload}, which never rides
|
|
32
|
+
* `source`.
|
|
33
|
+
*
|
|
34
|
+
* The `plugin` union is the PERSISTED-LOG vocabulary, not a write-time
|
|
35
|
+
* choice: the plugin emits `mstar-engine`, while rows emitted by shipped
|
|
36
|
+
* builds before 2026-09-11 persist `mstar-engine-status` in already-written
|
|
37
|
+
* session logs. Both are valid persisted rows; the panel's anchor reader
|
|
38
|
+
* accepts both (data compat for persisted session logs, not a code-compat
|
|
39
|
+
* layer).
|
|
33
40
|
*/
|
|
34
41
|
export interface MstarEngineStatusSource {
|
|
35
42
|
readonly kind: 'plugin';
|
|
36
|
-
readonly plugin: 'mstar-engine-status';
|
|
43
|
+
readonly plugin: 'mstar-engine' | 'mstar-engine-status';
|
|
37
44
|
readonly form: 'catalog';
|
|
38
45
|
}
|
|
39
46
|
/**
|
|
@@ -172,20 +179,25 @@ export interface MstarHarnessProject {
|
|
|
172
179
|
}
|
|
173
180
|
/**
|
|
174
181
|
* The catalog's workflow selection result (compass v3.0.0 § Catalog
|
|
175
|
-
* selection rule): the lifecycle the state section aggregates
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
182
|
+
* selection rule): the lifecycle the state section aggregates, resolved by
|
|
183
|
+
* the locked binding order — lease (an `execution_lease` holder match or a
|
|
184
|
+
* `worktree_path` containing the session cwd) → cwd (a
|
|
185
|
+
* `control_worktree_path` containing it) → the session's durable
|
|
186
|
+
* `selectedWorkflowId` → the only active entry. `terminal` = the latest
|
|
187
|
+
* terminal snapshot by mtime (history view; reachable only when the active
|
|
188
|
+
* registry is EMPTY); `error` = a clear selection failure (v1/unmigrated
|
|
189
|
+
* root, no snapshots, or N>1 active lifecycles with no binding — then
|
|
190
|
+
* `activeWorkflowIds` carries the picker rows) — never a root v1 read and
|
|
191
|
+
* never the registry's first entry. Structured and panel-renderable (not
|
|
192
|
+
* only a log line).
|
|
181
193
|
*/
|
|
182
194
|
export type WorkflowSelectionView = {
|
|
183
195
|
readonly kind: 'active';
|
|
184
|
-
/** The selected active lifecycle id (root v2 `workflows[]`
|
|
196
|
+
/** The selected active lifecycle id (a root v2 `workflows[]` entry). */
|
|
185
197
|
readonly workflowId: string;
|
|
186
198
|
/** Harness-relative workflow dir (e.g. `workflows/<id>`). */
|
|
187
199
|
readonly dir: string;
|
|
188
|
-
/**
|
|
200
|
+
/** Structured warning attached by a resolver, when it has one. */
|
|
189
201
|
readonly warning?: {
|
|
190
202
|
readonly code: string;
|
|
191
203
|
readonly message: string;
|
|
@@ -198,6 +210,11 @@ export type WorkflowSelectionView = {
|
|
|
198
210
|
readonly kind: 'error';
|
|
199
211
|
readonly code: string;
|
|
200
212
|
readonly message: string;
|
|
213
|
+
/**
|
|
214
|
+
* Present on the multi-active-unbound error: the validated active ids,
|
|
215
|
+
* in registry order — the actionable rows of the operator's picker.
|
|
216
|
+
*/
|
|
217
|
+
readonly activeWorkflowIds?: readonly string[];
|
|
201
218
|
};
|
|
202
219
|
/**
|
|
203
220
|
* The workspace-state digest section of the unified engine-status row: the
|
|
@@ -291,7 +308,7 @@ export interface MstarHarnessState {
|
|
|
291
308
|
*/
|
|
292
309
|
export interface AgentFlowEventView {
|
|
293
310
|
readonly ts: number;
|
|
294
|
-
readonly kind: 'dispatch' | 'settle' | 'workflow-run' | 'workflow-agent' | 'workflow-run-end' | 'workflow-verdict';
|
|
311
|
+
readonly kind: 'dispatch' | 'settle' | 'subagent-link' | 'workflow-run' | 'workflow-agent' | 'workflow-run-end' | 'workflow-verdict';
|
|
295
312
|
/** The session's stable id; null when the event carried none. */
|
|
296
313
|
readonly agent: string | null;
|
|
297
314
|
/** Assignment `Execute as` ('' for settle rows without a paired identity). */
|
|
@@ -321,12 +338,27 @@ export interface AgentFlowEventView {
|
|
|
321
338
|
readonly name?: string;
|
|
322
339
|
/** Run-member 1-based sequence within the run (workflow-agent events only). */
|
|
323
340
|
readonly seq?: number;
|
|
324
|
-
/** Run-member display label (workflow-agent events
|
|
341
|
+
/** Run-member display label (workflow-agent events), or the delegation label a `subagent-link` correlated (link events). */
|
|
325
342
|
readonly label?: string;
|
|
326
343
|
/** Run-member phase — workflow-agent events only, when carried. */
|
|
327
344
|
readonly phase?: string;
|
|
328
|
-
/**
|
|
345
|
+
/**
|
|
346
|
+
* The child session identity the row carries, when its source supplied one:
|
|
347
|
+
* workflow-agent rows — the published member's child; settle rows — the
|
|
348
|
+
* returned foreground `runId`, or a background child id the catalog join
|
|
349
|
+
* supplied (OMITTED when the completion knew none); `subagent-link` rows —
|
|
350
|
+
* the required catalog child id. Never a registry job id (that is
|
|
351
|
+
* `taskRef`) and never fabricated.
|
|
352
|
+
*/
|
|
329
353
|
readonly childId?: string;
|
|
354
|
+
/**
|
|
355
|
+
* Settle + `subagent-link` rows: the registry background-job id the row
|
|
356
|
+
* carries (`jobs.onJobDone` → `recordJobSettle`; the post-execute
|
|
357
|
+
* background branch for a link). A jobs-registry key (`<kind>-N`), never a
|
|
358
|
+
* child session id and never the Assignment `Task N` tag. A continuable
|
|
359
|
+
* link omits it (that path starts no registry job).
|
|
360
|
+
*/
|
|
361
|
+
readonly taskRef?: string;
|
|
330
362
|
/** Terminal workflow run reason (workflow-run-end events only). */
|
|
331
363
|
readonly stopReason?: 'completed' | 'cancelled' | 'error';
|
|
332
364
|
/** The matched workflow/ralph tool name (workflow-verdict events only). */
|
|
@@ -29,4 +29,6 @@ Execute **`mstar-audit` § `pr` variant end to end**(`references/pr-review.md`
|
|
|
29
29
|
3. **Synthesize (main agent)** — dedupe + tiered three-way vet (full for must-fix/should-fix; evidence-verify for nits) → tally/verdict(**§ Tally and derived score**)→ persist the **`mstar.review/v1` envelope**(mandatory)→ report + GitHub Review POST per **§ Comment posting**(`posted: yes` / `n/a-no-pr` / `failed`;event fixed `COMMENT`)→ save local report + evidence files per **§ Local report archive**(all three posting branches;write `elapsed` into the report frontmatter — measured minutes since the step-2 worktree-setup start time)→ **then** worktree cleanup(`mstar pr-review worktree-cleanup`).
|
|
30
30
|
4. **Batch** — one session = one PR per **§ Batch sibling PRs**;其余 PR → `mstar status backlog-register` 登记为 audit todos,建议各自独立 session.
|
|
31
31
|
|
|
32
|
+
**dsh host only.** On dsh the `deep` tier's seats go through the native **`workflow`** tool, not `subagent`: after `/amazing-pr-review deep`, take the `script` + `meta` (`meta.name: mstar-pr-seats`) from skill **`mstar-host`** → `references/dsh-workflow-scripts.md` (§ `mstar-pr-seats`) — 2–3 domain seats plus the optional cross-domain security seat, each `agent()` prompt opening with the Assignment header (`Execute as:` / `Delegation: forbidden`), all read-only, findings only (no verdict, no posting). The `default` tier (2 seats) and `quick` (1 seat) keep `subagent` — cards, no `workflow-run` node (expected). Other hosts unchanged.
|
|
33
|
+
|
|
32
34
|
Findings that need fixing → self-contained plans per **`mstar-audit` SKILL.md `## Plan output (all variants)`**(normal Prepare → Execute flow). Report the verdict + findings + posted review URL; the `tier:` declaration and any downgrade/upgrade `- notes:` follow **§ Review depth (tiers)** report contract.
|
|
@@ -27,6 +27,8 @@ Run a read-only codebase audit that discovers what is worth doing and writes sel
|
|
|
27
27
|
| **Large repo** (parallel categories needed) | `@code-reviewer` fans out read-only `scout` / `explore` subagents per category via Assignment `Delegation: allowed (scout/explore only, read-only)`, then vets and writes plans |
|
|
28
28
|
| **Specialist depth needed** | PM orchestrates an `@architect` consult for architecture/tech-debt depth (separate dispatch, or folded into the audit delegation brief) |
|
|
29
29
|
|
|
30
|
+
**dsh host only.** On dsh the large-repo fan-out goes through the native **`workflow`** tool, not `subagent`: after the operator types `/codebase-audit`, take the `script` + `meta` (`meta.name: mstar-audit-fanout`) from skill **`mstar-host`** → `references/dsh-workflow-scripts.md` (§ `mstar-audit-fanout`) — N≥3 read-only category seats, each `agent()` prompt opening with the Assignment header (`Execute as:` / `Delegation: forbidden`), one conversation `workflow-run` node. Other hosts unchanged (they keep their own invoke tool: `task` / Task).
|
|
31
|
+
|
|
30
32
|
This command is the PM entry point; the audit execution body is `code-reviewer`(PM dispatch).
|
|
31
33
|
|
|
32
34
|
The audit is **advisory** — it does not enter the per-plan state machine (`Todo → InProgress → InReview → Done`). Its output is plan *candidates*.
|
|
@@ -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").
|
|
@@ -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 whole-branch 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 the whole-branch diff for the review range above against that plan. 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 the whole-branch diff for the review range above against that plan, 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 the whole-branch diff for the review range above against that plan, 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
|
+
```
|