pan-wizard 3.31.0 → 3.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -24
- package/agents/pan-conductor.md +2 -2
- package/agents/pan-design-checker.md +18 -0
- package/agents/pan-document_code.md +2 -2
- package/agents/pan-executor.md +3 -3
- package/agents/pan-experiment-runner.md +7 -10
- package/agents/pan-hardener.md +15 -15
- package/agents/pan-knowledge.md +1 -1
- package/agents/pan-meta-reviewer.md +2 -2
- package/agents/pan-optimizer.md +7 -3
- package/agents/pan-phase-researcher.md +2 -2
- package/agents/pan-plan-checker.md +29 -2
- package/agents/pan-planner.md +23 -10
- package/agents/pan-project-researcher.md +10 -67
- package/agents/pan-reviewer.md +19 -0
- package/agents/pan-roadmapper.md +5 -48
- package/agents/pan-verifier.md +49 -11
- package/bin/install-lib.cjs +170 -15
- package/bin/install.js +39 -14
- package/commands/pan/army.md +2 -2
- package/commands/pan/design-phase.md +8 -0
- package/commands/pan/exec-phase.md +1 -1
- package/commands/pan/experiment.md +2 -2
- package/commands/pan/focus-auto.md +12 -8
- package/commands/pan/focus-design.md +2 -0
- package/commands/pan/focus-exec.md +1 -1
- package/commands/pan/focus-scan.md +2 -7
- package/commands/pan/git.md +2 -2
- package/commands/pan/learn.md +2 -0
- package/commands/pan/map-codebase.md +4 -4
- package/commands/pan/mcp-bridge.md +1 -1
- package/commands/pan/milestone-done.md +1 -2
- package/commands/pan/optimize.md +14 -2
- package/commands/pan/phase-tests.md +2 -2
- package/commands/pan/profile.md +2 -2
- package/commands/pan/research-phase.md +2 -4
- package/commands/pan/review-deep.md +8 -8
- package/commands/pan/todo-add.md +2 -2
- package/commands/pan/todo-check.md +2 -2
- package/hooks/dist/pan-context-monitor.js +1 -1
- package/hooks/dist/pan-cost-logger.js +63 -11
- package/hooks/dist/pan-state-reinject.js +142 -17
- package/hooks/dist/pan-stop-guard.js +2 -2
- package/hooks/dist/pan-trace-logger.js +283 -18
- package/package.json +1 -1
- package/pan-wizard-core/bin/lib/agents-md.cjs +4 -1
- package/pan-wizard-core/bin/lib/commands.cjs +95 -2
- package/pan-wizard-core/bin/lib/config.cjs +110 -0
- package/pan-wizard-core/bin/lib/constants.cjs +39 -9
- package/pan-wizard-core/bin/lib/core.cjs +27 -7
- package/pan-wizard-core/bin/lib/cost.cjs +16 -6
- package/pan-wizard-core/bin/lib/findings.cjs +385 -0
- package/pan-wizard-core/bin/lib/focus.cjs +72 -19
- package/pan-wizard-core/bin/lib/foreign-planning.cjs +24 -6
- package/pan-wizard-core/bin/lib/hygiene.cjs +12 -2
- package/pan-wizard-core/bin/lib/init.cjs +9 -2
- package/pan-wizard-core/bin/lib/optimize.cjs +349 -21
- package/pan-wizard-core/bin/lib/phase.cjs +52 -2
- package/pan-wizard-core/bin/lib/review-deep.cjs +38 -2
- package/pan-wizard-core/bin/lib/state.cjs +10 -4
- package/pan-wizard-core/bin/lib/verdict.cjs +481 -0
- package/pan-wizard-core/bin/lib/verify-drift.cjs +14 -5
- package/pan-wizard-core/bin/lib/verify-preflight.cjs +4 -2
- package/pan-wizard-core/bin/lib/verify-scope.cjs +223 -0
- package/pan-wizard-core/bin/lib/verify.cjs +111 -8
- package/pan-wizard-core/bin/pan-tools.cjs +68 -6
- package/pan-wizard-core/learnings/README.md +10 -7
- package/pan-wizard-core/mcp/server.cjs +18 -9
- package/pan-wizard-core/mcp/tool-registry.cjs +2 -0
- package/pan-wizard-core/references/checkpoints.md +4 -2
- package/pan-wizard-core/references/verdict-contract.md +102 -0
- package/pan-wizard-core/templates/discovery.md +1 -1
- package/pan-wizard-core/templates/phase-prompt.md +2 -1
- package/pan-wizard-core/templates/verification-report.md +21 -0
- package/pan-wizard-core/workflows/exec-phase.md +73 -50
- package/pan-wizard-core/workflows/health.md +3 -0
- package/pan-wizard-core/workflows/learn.md +4 -2
- package/pan-wizard-core/workflows/milestone-audit.md +15 -3
- package/pan-wizard-core/workflows/new-project.md +1 -1
- package/pan-wizard-core/workflows/optimize.md +14 -1
- package/pan-wizard-core/workflows/plan-phase.md +20 -15
- package/pan-wizard-core/workflows/quick.md +6 -6
- package/pan-wizard-core/workflows/verify-phase.md +10 -15
- package/pan-zcode/README.md +3 -3
- package/scripts/build-agent-plugin.js +19 -5
- package/scripts/git-hooks/pre-commit +2 -1
- package/scripts/test-surface.cjs +4 -0
|
@@ -50,6 +50,15 @@ const META_SERVER_INFO_KEY = 'io.modelcontextprotocol/serverInfo';
|
|
|
50
50
|
// claim to speak a version we don't. Newest first (the `server/discover` order).
|
|
51
51
|
const SUPPORTED_VERSIONS_LIST = [MODERN_PROTOCOL_VERSION, '2025-06-18', '2025-03-26', '2024-11-05'];
|
|
52
52
|
const SUPPORTED_PROTOCOL_VERSIONS = new Set(SUPPORTED_VERSIONS_LIST);
|
|
53
|
+
// The `CacheableResult` fields a modern result MUST carry where its type extends
|
|
54
|
+
// that interface: DiscoverResult, ListToolsResult, ListResourcesResult and
|
|
55
|
+
// ReadResourceResult (schema/2026-07-28/schema.ts). Claude Code 2.1.288 drops a
|
|
56
|
+
// list without them, so the server showed as connected with no tools and no
|
|
57
|
+
// resources (live check H2, 2026-10-03). The registry is fixed for the life of the
|
|
58
|
+
// process, so its lists are public and long-lived; a resource is the project's
|
|
59
|
+
// state at the moment it is read, so a read is private and stale at once.
|
|
60
|
+
const REGISTRY_CACHE = Object.freeze({ ttlMs: 3600000, cacheScope: 'public' });
|
|
61
|
+
const READ_CACHE = Object.freeze({ ttlMs: 0, cacheScope: 'private' });
|
|
53
62
|
/**
|
|
54
63
|
* The version the server reports in `initialize` / `server/discover`. Read from the
|
|
55
64
|
* package.json two levels up: the repository root in the source tree, the runtime
|
|
@@ -320,12 +329,13 @@ function createServer(opts = {}) {
|
|
|
320
329
|
{ supported: SUPPORTED_VERSIONS_LIST, requested: requestedVersion });
|
|
321
330
|
}
|
|
322
331
|
|
|
323
|
-
// Modern results MUST carry a `resultType
|
|
324
|
-
//
|
|
332
|
+
// Modern results MUST carry a `resultType`, a cacheable one its caching fields,
|
|
333
|
+
// and each SHOULD name the server in `_meta`; legacy results MUST NOT change
|
|
334
|
+
// shape (clients treat an absent resultType as "complete"). Stamp them only on
|
|
325
335
|
// the modern path.
|
|
326
|
-
const reply = (result) => rpcResult(id,
|
|
336
|
+
const reply = (result, cache) => rpcResult(id,
|
|
327
337
|
isModern && result && typeof result === 'object' && result.resultType === undefined
|
|
328
|
-
? { resultType: 'complete', ...result }
|
|
338
|
+
? { resultType: 'complete', ...cache, ...result, _meta: { ...result._meta, [META_SERVER_INFO_KEY]: SERVER_INFO } }
|
|
329
339
|
: result);
|
|
330
340
|
|
|
331
341
|
switch (method) {
|
|
@@ -339,8 +349,7 @@ function createServer(opts = {}) {
|
|
|
339
349
|
supportedVersions: SUPPORTED_VERSIONS_LIST,
|
|
340
350
|
capabilities: { tools: {}, resources: {} },
|
|
341
351
|
instructions: 'PAN Wizard engine bridge: planning, verification, and orchestration tools backed by the pan-tools CLI. All tools are read-only except the gated pan_confirm_merge.',
|
|
342
|
-
|
|
343
|
-
cacheScope: 'public',
|
|
352
|
+
...REGISTRY_CACHE,
|
|
344
353
|
_meta: { [META_SERVER_INFO_KEY]: SERVER_INFO },
|
|
345
354
|
});
|
|
346
355
|
case 'initialize': {
|
|
@@ -354,9 +363,9 @@ function createServer(opts = {}) {
|
|
|
354
363
|
case 'ping':
|
|
355
364
|
return reply({});
|
|
356
365
|
case 'tools/list':
|
|
357
|
-
return reply({ tools: reg.TOOLS.map(toMcpTool) });
|
|
366
|
+
return reply({ tools: reg.TOOLS.map(toMcpTool) }, REGISTRY_CACHE);
|
|
358
367
|
case 'resources/list':
|
|
359
|
-
return reply({ resources: reg.RESOURCES.map(toMcpResource) });
|
|
368
|
+
return reply({ resources: reg.RESOURCES.map(toMcpResource) }, REGISTRY_CACHE);
|
|
360
369
|
case 'tools/call': {
|
|
361
370
|
const out = callTool(params && params.name, params && params.arguments);
|
|
362
371
|
return out.error ? rpcError(id, out.error.code, out.error.message) : reply(out.result);
|
|
@@ -364,7 +373,7 @@ function createServer(opts = {}) {
|
|
|
364
373
|
case 'resources/read': {
|
|
365
374
|
const out = readResource(params && params.uri);
|
|
366
375
|
if (out.unknown) return rpcError(id, -32602, `Unknown resource: ${params && params.uri}`);
|
|
367
|
-
return out.error ? rpcError(id, out.error.code, out.error.message) : reply(out.result);
|
|
376
|
+
return out.error ? rpcError(id, out.error.code, out.error.message) : reply(out.result, READ_CACHE);
|
|
368
377
|
}
|
|
369
378
|
default:
|
|
370
379
|
return rpcError(id, -32601, `Method not found: ${method}`);
|
|
@@ -69,6 +69,8 @@ const RESOURCES = [
|
|
|
69
69
|
description: 'Doc↔code link graph verdict: forward links, backlink contracts, and anchor targets, with finding codes.' },
|
|
70
70
|
{ uri: 'pan://cost', name: 'Token cost', verb: 'cost', args: ['report'],
|
|
71
71
|
description: 'Aggregated token spend from the .planning/metrics ledger. Reads as zeros on a project with no recorded calls.' },
|
|
72
|
+
{ uri: 'pan://findings', name: 'Findings', verb: 'findings', args: ['list'],
|
|
73
|
+
description: 'Every finding PAN\'s judges recorded (verifier, plan checker, reviewer, design checker), with its folded status — open, fixed, deferred, dismissed or decision — and the reason given. Reads as an empty list on a project with no recorded verdicts.' },
|
|
72
74
|
];
|
|
73
75
|
|
|
74
76
|
/** Actionable pan-tools verbs → MCP tools (each spawns `node pan-tools.cjs <verb>`). */
|
|
@@ -8,7 +8,7 @@ Plans execute autonomously. Checkpoints formalize interaction points where human
|
|
|
8
8
|
2. **Claude sets up the verification environment** - Start dev servers, seed databases, configure env vars
|
|
9
9
|
3. **User only does what requires human judgment** - Visual checks, UX evaluation, "does this feel right?"
|
|
10
10
|
4. **Secrets come from user, automation comes from Claude** - Ask for API keys, then Claude uses them via CLI
|
|
11
|
-
5. **Auto-mode bypasses verification
|
|
11
|
+
5. **Auto-mode bypasses verification checkpoints, and decisions only where the planner named a default** — When `workflow.auto_advance` is true in config: human-verify auto-approves; a decision with `auto_select="<option id>"` takes that option, and a decision without it stops for a human (auto mode never takes an option because it is listed first); human-action still stops (auth gates cannot be automated)
|
|
12
12
|
</overview>
|
|
13
13
|
|
|
14
14
|
<checkpoint_types>
|
|
@@ -105,7 +105,7 @@ Plans execute autonomously. Checkpoints formalize interaction points where human
|
|
|
105
105
|
|
|
106
106
|
**Structure:**
|
|
107
107
|
```xml
|
|
108
|
-
<task type="checkpoint:decision" gate="blocking">
|
|
108
|
+
<task type="checkpoint:decision" gate="blocking" auto_select="option-a">
|
|
109
109
|
<decision>[What's being decided]</decision>
|
|
110
110
|
<context>[Why this decision matters]</context>
|
|
111
111
|
<options>
|
|
@@ -124,6 +124,8 @@ Plans execute autonomously. Checkpoints formalize interaction points where human
|
|
|
124
124
|
</task>
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
+
**`auto_select` (optional)** names the option auto mode takes. Set it only when the choice is safe to make without the user: reversible, no new paid service, no credential, no data-model lock-in. It must name an `id` from this checkpoint's options; `verify plan-structure` fails one that names no option. Leave it out when a human must choose, and auto mode stops at this checkpoint. The examples below omit it: picking a vendor or a database is the user's call.
|
|
128
|
+
|
|
127
129
|
**Example: Auth Provider Selection**
|
|
128
130
|
```xml
|
|
129
131
|
<task type="checkpoint:decision" gate="blocking">
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# The `pan-verdict` block
|
|
2
|
+
|
|
3
|
+
A judging agent ends its report with one fenced `pan-verdict` block. The block is the machine-readable form of the verdict the report already gives in prose. The orchestrator records it with `pan-tools findings record`, and that record is what the workflow branches on. It also feeds the findings ledger that milestone audits read for tech debt. The prose stays for people, and the block states the same verdict for code.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
1. **Place it last.** The block is the final element of your return. When a report holds more than one block, the recorder reads the last one.
|
|
8
|
+
2. **Valid JSON only.** No comments and no trailing commas. One line or pretty-printed are both fine.
|
|
9
|
+
3. **Same verdict as the prose.** `verdict` is the word your report already uses, and `outcome` is what that word means (see the table below). The block never disagrees with the report.
|
|
10
|
+
4. **One finding per issue.** List the findings the report lists, each as its own entry, most severe first. A clean pass has `"findings": []`.
|
|
11
|
+
5. **Plain summaries.** State each finding in one sentence of 300 characters or fewer. Put the location in `where`, not in `summary`.
|
|
12
|
+
|
|
13
|
+
````markdown
|
|
14
|
+
```pan-verdict
|
|
15
|
+
{"contract":"1.0","agent":"pan-reviewer","phase":"03","verdict":"NEEDS_FIXES","outcome":"fail","findings":[{"class":"defect","severity":"high","where":"src/utils/parser.ts:42","summary":"parse() drops the final token of every line"}]}
|
|
16
|
+
```
|
|
17
|
+
````
|
|
18
|
+
|
|
19
|
+
## Fields
|
|
20
|
+
|
|
21
|
+
| Field | Required | Value |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `contract` | yes | `"1.0"` |
|
|
24
|
+
| `agent` | yes | your agent name, e.g. `pan-reviewer` |
|
|
25
|
+
| `phase` | when you know it | the phase number you were asked about, e.g. `"03"` |
|
|
26
|
+
| `verdict` | yes | your own verdict word (table below) |
|
|
27
|
+
| `outcome` | yes | `pass`, `fail` or `needs_human` |
|
|
28
|
+
| `findings` | yes (may be empty) | a list of `{class, severity, where, summary}` |
|
|
29
|
+
| `not_checked` | when a check could not run | a list of `{check, reason}`: a check you were asked to make and could not run, and why (no test script, no browser, a file you could not read). Never fold it into `pass`: a verdict with entries here says what it did not see |
|
|
30
|
+
|
|
31
|
+
| Agent | `verdict` → `outcome` |
|
|
32
|
+
|---|---|
|
|
33
|
+
| pan-plan-checker | `passed` → `pass` · `issues_found` → `fail` |
|
|
34
|
+
| pan-reviewer | `PASS` → `pass` · `PASS_WITH_WARNINGS` → `pass` · `NEEDS_FIXES` → `fail` |
|
|
35
|
+
| pan-design-checker | `PASS` → `pass` · `GAPS` → `fail` |
|
|
36
|
+
|
|
37
|
+
The verifier does not emit this block. Its verification.md frontmatter (`status`, `gaps`, `human_verification`, `unrequested`, `test_gate`, `not_checked`) is its machine contract, and the recorder reads that directly. `test_gate` is `passed`, `failed` or `skipped`. A skipped gate is recorded as a `tests` entry in `not_checked` even when the list leaves it out, and a verification that does not record `test_gate` at all is recorded with a `test_gate_unrecorded` warning.
|
|
38
|
+
|
|
39
|
+
## `class`: what kind of finding
|
|
40
|
+
|
|
41
|
+
| Class | Use when |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `missing` | Something required is absent: a requirement with no task, a must-have not built, an unplanned key link |
|
|
44
|
+
| `partial` | Present but incomplete: a task missing its verify/done fields, a stub, a half-derived criterion |
|
|
45
|
+
| `contradicts` | It conflicts with a requirement, a locked decision (context.md) or the codebase's established architecture |
|
|
46
|
+
| `unrequested` | Work, a file or a behaviour that no plan or requirement asked for (scope creep) |
|
|
47
|
+
| `defect` | Incorrect behaviour or a code error; a broken dependency order in a plan |
|
|
48
|
+
| `risk` | A security, reliability or scale exposure; a plan whose scope will not fit its budget |
|
|
49
|
+
| `quality` | Convention, naming, style or maintainability, with no correctness impact |
|
|
50
|
+
| `human` | Cannot be settled by a check, so a person must look |
|
|
51
|
+
|
|
52
|
+
## `severity`: how much it matters
|
|
53
|
+
|
|
54
|
+
`critical` · `high` · `medium` · `low` · `info`. This is the same ladder `/pan:review-deep` uses.
|
|
55
|
+
|
|
56
|
+
## Mapping for each judge
|
|
57
|
+
|
|
58
|
+
**pan-plan-checker.**
|
|
59
|
+
- Classes by dimension:
|
|
60
|
+
- Requirement coverage, key links, test coverage, Nyquist → `missing`
|
|
61
|
+
- Task completeness, verification derivation, spec sufficiency, decision trace → `partial`
|
|
62
|
+
- Dependency correctness → `defect`
|
|
63
|
+
- Scope sanity → `risk`
|
|
64
|
+
- Context compliance → `contradicts`
|
|
65
|
+
- Standards → `quality`
|
|
66
|
+
- Severity: blocker → `high`, warning → `medium`, info → `info`.
|
|
67
|
+
- `where`: `NN-MM-plan.md` or `NN-MM-plan.md#task-N`.
|
|
68
|
+
|
|
69
|
+
**pan-reviewer.**
|
|
70
|
+
- Classes by category: Convention → `quality`, Security → `risk`, Code Quality → `defect`, work no plan asked for → `unrequested`.
|
|
71
|
+
- Severity: ERROR → `high`, WARNING → `medium`, INFO → `info`.
|
|
72
|
+
- `where`: `path:line`.
|
|
73
|
+
|
|
74
|
+
**pan-design-checker.**
|
|
75
|
+
- Classes by dimension:
|
|
76
|
+
- Requirement coverage → `missing`
|
|
77
|
+
- Architecture conformance → `contradicts`
|
|
78
|
+
- Threat coverage → `risk`
|
|
79
|
+
- Scope discipline → `unrequested`
|
|
80
|
+
- Every other dimension → `partial`
|
|
81
|
+
- Severity: each gap is `high`. A gap you report as a caveat on the final iteration is `medium`.
|
|
82
|
+
- `where`: the design section, e.g. `03-design.md#interfaces`.
|
|
83
|
+
|
|
84
|
+
## Examples
|
|
85
|
+
|
|
86
|
+
A plan check that passes:
|
|
87
|
+
|
|
88
|
+
````markdown
|
|
89
|
+
```pan-verdict
|
|
90
|
+
{"contract":"1.0","agent":"pan-plan-checker","phase":"05","verdict":"passed","outcome":"pass","findings":[]}
|
|
91
|
+
```
|
|
92
|
+
````
|
|
93
|
+
|
|
94
|
+
A design check with two gaps:
|
|
95
|
+
|
|
96
|
+
````markdown
|
|
97
|
+
```pan-verdict
|
|
98
|
+
{"contract":"1.0","agent":"pan-design-checker","phase":"05","verdict":"GAPS","outcome":"fail","findings":[
|
|
99
|
+
{"class":"missing","severity":"high","where":"05-design.md#requirements","summary":"REQ-12 (export to CSV) maps to no design element"},
|
|
100
|
+
{"class":"risk","severity":"high","where":"05-design.md#threats","summary":"the upload endpoint accepts any file type and no threat entry covers it"}]}
|
|
101
|
+
```
|
|
102
|
+
````
|
|
@@ -30,7 +30,7 @@ Discover [topic] to inform [phase name] implementation.
|
|
|
30
30
|
|
|
31
31
|
Purpose: [What decision/implementation this enables]
|
|
32
32
|
Scope: [Boundaries]
|
|
33
|
-
Output:
|
|
33
|
+
Output: discovery.md with recommendation
|
|
34
34
|
</discovery_objective>
|
|
35
35
|
|
|
36
36
|
<discovery_scope>
|
|
@@ -79,7 +79,8 @@ Output: [What artifacts will be created]
|
|
|
79
79
|
<!-- For checkpoint task examples and patterns, see @~/.claude/pan-wizard-core/references/checkpoints.md -->
|
|
80
80
|
<!-- Key rule: Claude starts dev server BEFORE human-verify checkpoints. User only visits URLs. -->
|
|
81
81
|
|
|
82
|
-
<task type="checkpoint:decision" gate="blocking">
|
|
82
|
+
<task type="checkpoint:decision" gate="blocking" auto_select="option-a">
|
|
83
|
+
<!-- auto_select: the option auto mode takes. Omit it when a human must choose. -->
|
|
83
84
|
<decision>[What needs deciding]</decision>
|
|
84
85
|
<context>[Why this decision matters]</context>
|
|
85
86
|
<options>
|
|
@@ -10,8 +10,16 @@ Template for `.planning/phases/XX-name/{phase_num}-verification.md` — phase go
|
|
|
10
10
|
---
|
|
11
11
|
phase: XX-name
|
|
12
12
|
verified: YYYY-MM-DDTHH:MM:SSZ
|
|
13
|
+
verified_commit: <sha> # git rev-parse HEAD before writing this file; `pan-tools verify stale` compares against it
|
|
13
14
|
status: passed | gaps_found | human_needed
|
|
14
15
|
score: N/M must-haves verified
|
|
16
|
+
test_gate: passed | failed | skipped
|
|
17
|
+
not_checked: # Only for checks that could not run, with why — a skipped test gate is one
|
|
18
|
+
- check: "tests"
|
|
19
|
+
reason: "no test script in package.json"
|
|
20
|
+
unrequested: # Only when the scope check (`pan-tools verify scope <phase>`) found work no plan asked for
|
|
21
|
+
- path: "src/admin/panel.tsx"
|
|
22
|
+
what: "An admin panel no plan or requirement asked for"
|
|
15
23
|
---
|
|
16
24
|
|
|
17
25
|
# Phase {X}: {Name} Verification Report
|
|
@@ -89,6 +97,19 @@ None — all verifiable items checked programmatically.
|
|
|
89
97
|
**Expected:** {What should happen}
|
|
90
98
|
**Why human:** {Why can't verify programmatically}
|
|
91
99
|
|
|
100
|
+
## Unrequested Work
|
|
101
|
+
|
|
102
|
+
{If the scope check found none:}
|
|
103
|
+
None: every change traces to a plan.
|
|
104
|
+
|
|
105
|
+
{Otherwise, one row per `unrequested:` entry:}
|
|
106
|
+
|
|
107
|
+
| File | What it adds | Why no plan covers it |
|
|
108
|
+
|------|--------------|-----------------------|
|
|
109
|
+
| src/admin/panel.tsx | An admin panel | No requirement mentions admin tooling |
|
|
110
|
+
|
|
111
|
+
Unrequested work is recorded, not blocking: the status does not change because of it.
|
|
112
|
+
|
|
92
113
|
## Gaps Summary
|
|
93
114
|
|
|
94
115
|
{If no gaps:}
|
|
@@ -256,7 +256,11 @@ Execute each wave in sequence. Within a wave: parallel if `PARALLELIZATION=true`
|
|
|
256
256
|
|
|
257
257
|
**Known Claude Code bug (classifyHandoffIfNeeded):** If an agent reports "failed" with error containing `classifyHandoffIfNeeded is not defined`, this is a Claude Code runtime bug — not a PAN or agent issue. The error fires in the completion handler AFTER all tool calls finish. In this case: run the same spot-checks as step 4 (summary.md exists, git commits present, no Self-Check: FAILED). If spot-checks PASS → treat as **successful**. If spot-checks FAIL → treat as real failure below.
|
|
258
258
|
|
|
259
|
-
For real failures: report which plan failed → ask "Continue?" or "Stop?"
|
|
259
|
+
For real failures: report which plan failed → ask "Continue?" or "Stop?". If stop, partial completion report. If continue, never run a plan that depends on a failed one; ask the engine which plans are blocked:
|
|
260
|
+
```bash
|
|
261
|
+
BLOCKED=$(node ~/.claude/pan-wizard-core/bin/pan-tools.cjs phase-plan-index "${PHASE_NUMBER}" --failed "${FAILED_PLAN_IDS}")
|
|
262
|
+
```
|
|
263
|
+
`${FAILED_PLAN_IDS}` is the comma-separated ids of every plan that failed so far. `blocked` lists each unfinished plan whose `depends_on` reaches a failed plan, directly or through another blocked plan, with the failed plans behind it. Do not spawn those plans in this or any later wave. Name them in the wave report and the final summary ("Skipped 03-03 and 03-04: they depend on 03-01, which failed"), and run every other plan as planned. The same applies after "Continue with remaining waves?" in step 4.
|
|
260
264
|
|
|
261
265
|
6. **Execute checkpoint plans between waves** — see `<checkpoint_handling>`.
|
|
262
266
|
|
|
@@ -275,7 +279,7 @@ AUTO_CFG=$(node ~/.claude/pan-wizard-core/bin/pan-tools.cjs config-get workflow.
|
|
|
275
279
|
|
|
276
280
|
When executor returns a checkpoint AND `AUTO_CFG` is `"true"`:
|
|
277
281
|
- **human-verify** → Auto-spawn continuation agent with `{user_response}` = `"approved"`. Log `⚡ Auto-approved checkpoint`.
|
|
278
|
-
- **decision** →
|
|
282
|
+
- **decision** → The executor already took the plan's `auto_select` option when the task had one, so a decision that comes back has none: present it to the user (standard flow below). If a returned decision's task does carry `auto_select` in the plan file, auto-spawn the continuation agent with `{user_response}` = that option id and log `⚡ Auto-selected: [option] (auto_select)`. Never answer with an option because it is listed first.
|
|
279
283
|
- **human-action** → Present to user (existing behavior below). Auth gates cannot be automated.
|
|
280
284
|
|
|
281
285
|
**Standard flow (not auto-mode, or human-action type):**
|
|
@@ -425,13 +429,21 @@ Task(
|
|
|
425
429
|
)
|
|
426
430
|
```
|
|
427
431
|
|
|
428
|
-
3.
|
|
432
|
+
3. **Save the report.** Use the Write tool to write the reviewer's returned text, verbatim and in full (including its closing `pan-verdict` block), to `{phase_dir}/{phase_number}-review.md`. The reviewer is read-only by design, so the orchestrator saves the report. `/pan:review-deep` and the findings ledger read this file.
|
|
433
|
+
|
|
434
|
+
4. **Record the verdict, then act on it.** The record is what this step branches on. It also adds the findings to the ledger (`.planning/findings.jsonl`) and logs the verdict to the trace, so no separate trace call is needed:
|
|
435
|
+
```bash
|
|
436
|
+
REVIEW_FILE="{phase_dir}/{phase_number}-review.md"
|
|
437
|
+
REVIEW_VERDICT=$(node ~/.claude/pan-wizard-core/bin/pan-tools.cjs findings record --phase "${PHASE_NUMBER}" --agent pan-reviewer --file "$REVIEW_FILE" --raw 2>/dev/null) \
|
|
438
|
+
|| REVIEW_VERDICT=$(grep -A1 '^### Verdict' "$REVIEW_FILE" | tail -1 | tr -d ' ')
|
|
439
|
+
```
|
|
440
|
+
The fallback reads the word under `### Verdict` when the report carries no valid `pan-verdict` block.
|
|
429
441
|
|
|
430
442
|
| Verdict | Action |
|
|
431
443
|
|---------|--------|
|
|
432
444
|
| `PASS` | Continue to verification |
|
|
433
|
-
| `PASS_WITH_WARNINGS` | Report warnings, continue to verification |
|
|
434
|
-
| `NEEDS_FIXES` | Present ERROR findings to user: "Fix before verification?" or "Continue anyway?" |
|
|
445
|
+
| `PASS_WITH_WARNINGS` | Report the warnings, then record that the phase continues past them (below), and continue to verification |
|
|
446
|
+
| `NEEDS_FIXES` | Present the ERROR findings to the user: "Fix before verification?" or "Continue anyway?" |
|
|
435
447
|
|
|
436
448
|
```
|
|
437
449
|
## Code Review Results
|
|
@@ -442,34 +454,60 @@ Task(
|
|
|
442
454
|
{If errors: list top 5 with file:line}
|
|
443
455
|
```
|
|
444
456
|
|
|
445
|
-
**
|
|
457
|
+
**Never continue past findings silently.** Whenever the phase moves on with review findings still open, record why. The reason is what a milestone audit later reports as tech debt:
|
|
458
|
+
- `PASS_WITH_WARNINGS`:
|
|
459
|
+
```bash
|
|
460
|
+
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs findings dispose --phase "${PHASE_NUMBER}" --agent pan-reviewer --open --as deferred --reason "accepted at review: PASS_WITH_WARNINGS"
|
|
461
|
+
```
|
|
462
|
+
- **The user chooses "Continue anyway"** at `NEEDS_FIXES`: the same command with `--reason "continued past NEEDS_FIXES at the user's choice"`, then proceed to verification.
|
|
463
|
+
- **The user chooses "Fix before verification"**: apply the fixes, then run the review once more (steps 2–4). The new record closes the findings it no longer reports.
|
|
446
464
|
|
|
447
|
-
|
|
465
|
+
5. **No separate trace logging.** The record logs `verdict_passed` or `verdict_failed` for the reviewer on every runtime. The `reviewer_correction` and `reviewer_warnings` trace calls that used to sit here read the error count from a shell variable nothing ever set.
|
|
448
466
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
467
|
+
6. **Deep review — only when `--deep-review` is in $ARGUMENTS.** The security pass and cross-check that `/pan:review-deep` runs, done inline right after the normal review. If the normal review was skipped (`--skip-review` or `--fast`), say that `--deep-review` needs the review it builds on, and continue without it.
|
|
468
|
+
|
|
469
|
+
a. Spawn the hardener. Its output path is `.planning/reviews/${PHASE_NUMBER}/hardener.md`:
|
|
470
|
+
```
|
|
471
|
+
Task(
|
|
472
|
+
subagent_type="pan-hardener",
|
|
473
|
+
model="$(node ~/.claude/pan-wizard-core/bin/pan-tools.cjs resolve-model pan-hardener --raw)",
|
|
474
|
+
prompt="
|
|
475
|
+
<files_to_read>
|
|
476
|
+
- {phase_dir}/{phase_number}-review.md (the first-pass review)
|
|
477
|
+
- the phase plans: {phase_dir}/*-plan.md
|
|
478
|
+
Changed files to audit:
|
|
479
|
+
${CHANGED_FILES_LIST}
|
|
480
|
+
</files_to_read>
|
|
481
|
+
<output_path>.planning/reviews/${PHASE_NUMBER}/hardener.md</output_path>
|
|
482
|
+
<framework_scope>OWASP Top 10 (2025) and STRIDE, across every changed file.</framework_scope>
|
|
483
|
+
"
|
|
484
|
+
)
|
|
460
485
|
```
|
|
461
486
|
|
|
462
|
-
|
|
463
|
-
```bash
|
|
464
|
-
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs optimize trace log \
|
|
465
|
-
--type decision --category reviewer_warnings \
|
|
466
|
-
--description "Phase ${PHASE_NUMBER} reviewer: PASS_WITH_WARNINGS — warnings present" \
|
|
467
|
-
--agent pan-reviewer --impact trivial \
|
|
468
|
-
--context "{\"phase\":\"${PHASE_NUMBER}\",\"verdict\":\"PASS_WITH_WARNINGS\"}" \
|
|
469
|
-
2>/dev/null || true
|
|
487
|
+
b. Spawn the meta-reviewer on both first-pass reports. Its output path is `.planning/reviews/${PHASE_NUMBER}/meta.md`:
|
|
470
488
|
```
|
|
489
|
+
Task(
|
|
490
|
+
subagent_type="pan-meta-reviewer",
|
|
491
|
+
model="$(node ~/.claude/pan-wizard-core/bin/pan-tools.cjs resolve-model pan-meta-reviewer --raw)",
|
|
492
|
+
prompt="
|
|
493
|
+
<files_to_read>
|
|
494
|
+
- {phase_dir}/{phase_number}-review.md
|
|
495
|
+
- .planning/reviews/${PHASE_NUMBER}/hardener.md
|
|
496
|
+
</files_to_read>
|
|
497
|
+
<output_path>.planning/reviews/${PHASE_NUMBER}/meta.md</output_path>
|
|
498
|
+
"
|
|
499
|
+
)
|
|
500
|
+
```
|
|
501
|
+
If either agent returns its report instead of writing the output path, save the returned text there with the Write tool before the merge.
|
|
471
502
|
|
|
472
|
-
|
|
503
|
+
c. Merge the three reports:
|
|
504
|
+
```bash
|
|
505
|
+
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs review-deep merge "${PHASE_NUMBER}" \
|
|
506
|
+
--reviewer-file "{phase_dir}/{phase_number}-review.md" \
|
|
507
|
+
--hardener-file ".planning/reviews/${PHASE_NUMBER}/hardener.md" \
|
|
508
|
+
--meta-file ".planning/reviews/${PHASE_NUMBER}/meta.md"
|
|
509
|
+
```
|
|
510
|
+
This writes `.planning/reviews/${PHASE_NUMBER}/deep-review.md` and prints its verdict (`ok` · `ok_with_minor` · `fix_before_merge` · `review_required` · `block`). Report the verdict and the finding count. On `review_required` or `block`, stop before verification and present the high and critical findings to the user, as with `NEEDS_FIXES`.
|
|
473
511
|
</step>
|
|
474
512
|
|
|
475
513
|
<step name="close_parent_artifacts">
|
|
@@ -533,41 +571,26 @@ Phase goal: {goal from roadmap.md}
|
|
|
533
571
|
Phase requirement IDs: {phase_req_ids}
|
|
534
572
|
Check must_haves against actual codebase.
|
|
535
573
|
Cross-reference requirement IDs from PLAN frontmatter against requirements.md — every ID MUST be accounted for.
|
|
574
|
+
Run the project's test suite as the test gate (the run_test_suite step of @~/.claude/pan-wizard-core/workflows/verify-phase.md) and record test_gate in the frontmatter.
|
|
536
575
|
Create verification.md.",
|
|
537
576
|
subagent_type="pan-verifier",
|
|
538
577
|
model="{verifier_model}"
|
|
539
578
|
)
|
|
540
579
|
```
|
|
541
580
|
|
|
542
|
-
|
|
581
|
+
Record the verification and read its status:
|
|
543
582
|
```bash
|
|
544
|
-
|
|
583
|
+
VERIF_FILE=$(ls "$PHASE_DIR"/*-verification.md 2>/dev/null | head -1)
|
|
584
|
+
VERIF_STATUS=$(node ~/.claude/pan-wizard-core/bin/pan-tools.cjs findings record --phase "${PHASE_NUMBER}" --file "$VERIF_FILE" --raw 2>/dev/null) \
|
|
585
|
+
|| VERIF_STATUS=$(grep "^status:" "$VERIF_FILE" | cut -d: -f2 | tr -d ' ')
|
|
545
586
|
```
|
|
587
|
+
`findings record` reads the verdict from the verification frontmatter (`status`, `gaps`, `human_verification`, `unrequested`) and adds its findings to the ledger. A re-verification after a fix round is the next attempt: the gaps it no longer reports are closed, and the retry is logged. Recording the same file twice is a no-op, so verify-phase recording it too is safe. The grep fallback keeps the old reading when the record cannot parse the file.
|
|
546
588
|
|
|
547
|
-
**
|
|
548
|
-
|
|
549
|
-
```bash
|
|
550
|
-
if [ "$VERIF_STATUS" = "passed" ]; then
|
|
551
|
-
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs optimize trace log \
|
|
552
|
-
--type decision --category verification_passed \
|
|
553
|
-
--description "Phase ${PHASE_NUMBER} verification passed (logged from exec-phase, P-1806)" \
|
|
554
|
-
--agent pan-verifier --impact minor 2>/dev/null || true
|
|
555
|
-
elif [ "$VERIF_STATUS" = "gaps_found" ]; then
|
|
556
|
-
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs optimize trace log \
|
|
557
|
-
--type error --category verification_gaps \
|
|
558
|
-
--description "Phase ${PHASE_NUMBER} verification found gaps" \
|
|
559
|
-
--agent pan-verifier --impact major 2>/dev/null || true
|
|
560
|
-
elif [ "$VERIF_STATUS" = "human_needed" ]; then
|
|
561
|
-
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs optimize trace log \
|
|
562
|
-
--type decision --category verification_human_needed \
|
|
563
|
-
--description "Phase ${PHASE_NUMBER} verification awaiting human review" \
|
|
564
|
-
--agent pan-verifier --impact minor 2>/dev/null || true
|
|
565
|
-
fi
|
|
566
|
-
```
|
|
589
|
+
**Trace logging happens in the record.** The record above logs the verification outcome (`verdict_passed`, `verdict_failed` or `verdict_needs_human`) here, after the verifier returns. That covers inline verification too, which is the reason P-1806 moved the trace call here (v3.7.8). No separate `optimize trace log` call is needed.
|
|
567
590
|
|
|
568
591
|
| Status | Action |
|
|
569
592
|
|--------|--------|
|
|
570
|
-
| `passed` | → update_roadmap |
|
|
593
|
+
| `passed` | → update_roadmap. If the verification frontmatter has `test_gate: skipped` or a `not_checked` list, say so when you report the phase: "passed — not checked: tests (no test script)". A pass never hides what it did not check |
|
|
571
594
|
| `human_needed` | Present items for human testing, get approval or feedback |
|
|
572
595
|
| `gaps_found` | Present gap summary, offer `/pan:plan-phase {phase} --gaps` |
|
|
573
596
|
|
|
@@ -163,6 +163,9 @@ Report final status.
|
|
|
163
163
|
| I001 | info | Plan without SUMMARY (may be in progress) | No |
|
|
164
164
|
| I002 | info | Phase in ROADMAP ahead of current phase, not planned yet | No |
|
|
165
165
|
| I003 | info | Focus-model or campaign tree — the phase-model checks do not apply | No |
|
|
166
|
+
| I004 | info | planning-with-files shares the tree — PAN leaves its files alone | No |
|
|
167
|
+
| I005 | info | The planning tree is gitignored while commit_docs is true — planning commits commit nothing | No |
|
|
168
|
+
| I006 | info | config.json holds keys PAN does not read (usually a typo); the fix names the nearest known key | No |
|
|
166
169
|
| STATE_REQ_DRIFT | warning | state.md complete but REQUIREMENTS.md has unchecked boxes | Yes |
|
|
167
170
|
| STATE_ROADMAP_DRIFT | warning | state.md complete but roadmap.md has unchecked plan boxes | Yes |
|
|
168
171
|
| VERIFICATION_GATE_MISSING | warning | Phase has completed plans but no verification record | No |
|
|
@@ -31,10 +31,10 @@ If `--session <id>` was specified, use that session ID.
|
|
|
31
31
|
|
|
32
32
|
Run:
|
|
33
33
|
```
|
|
34
|
-
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs optimize learn [--session <id>]
|
|
34
|
+
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs optimize learn [--session <id> | --sessions <n>]
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
This produces `.planning/optimization/reports/{session}-analysis.json`.
|
|
37
|
+
This produces `.planning/optimization/reports/{session}-analysis.json`. With `--sessions <n>` it pools the last n sessions into `pooled-<n>-{session}-analysis.json`: a recommendation should explain failures that recur across runs, not one run's accident.
|
|
38
38
|
|
|
39
39
|
Read the output and note:
|
|
40
40
|
- `summary.errors` — how many error events
|
|
@@ -42,6 +42,8 @@ Read the output and note:
|
|
|
42
42
|
- `summary.memory_misses` — how many memory miss events
|
|
43
43
|
- `summary.wasted_tokens` — tokens wasted on redundancies
|
|
44
44
|
- `top_error_patterns` — most frequent error categories
|
|
45
|
+
- `top_tool_error_patterns` — failed tool calls captured from the subagents' own transcripts, ranked by how many spawns hit them
|
|
46
|
+
- `verdict_stats` — each judge's pass/fail counts, retries, and the retries that resolved a failure
|
|
45
47
|
- `top_memory_misses` — most frequent memory miss topics
|
|
46
48
|
|
|
47
49
|
## Step 3 — Invoke pan-optimizer agent
|
|
@@ -82,6 +82,18 @@ From each verification.md, extract:
|
|
|
82
82
|
|
|
83
83
|
If a phase is missing verification.md, flag it as "unverified phase" — this is a blocker.
|
|
84
84
|
|
|
85
|
+
### 2b. Read the Recorded Findings
|
|
86
|
+
|
|
87
|
+
What the judges found in this milestone, and what was decided about each finding, is on record. Read it rather than reconstructing it from prose:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs findings debt --milestone "{version}"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- **`deferred`** findings were continued past on purpose, and each carries the reason recorded at the time. They are the milestone's tech debt: put every one in `tech_debt`, with its id and reason.
|
|
94
|
+
- **`open`** findings were never disposed (no fix, deferral, dismissal or decision). List them under "Undisposed findings" in the report. They are not blockers by themselves: the verification gate handles blockers. They do mean the milestone cannot be `passed`, so the status is at least `tech_debt`.
|
|
95
|
+
- A dismissal or decision is settled and not debt. `findings list --milestone "{version}" --status dismissed` shows the dismissals and their reasons when the report needs them.
|
|
96
|
+
|
|
85
97
|
## 3. Spawn Integration Checker
|
|
86
98
|
|
|
87
99
|
With phase context collected:
|
|
@@ -181,11 +193,11 @@ gaps: # Critical blockers
|
|
|
181
193
|
evidence: "{specific evidence or lack thereof}"
|
|
182
194
|
integration: [...]
|
|
183
195
|
flows: [...]
|
|
184
|
-
tech_debt: # Non-critical, deferred
|
|
196
|
+
tech_debt: # Non-critical, deferred — from `findings debt` (step 2b) plus anything the verifications list
|
|
185
197
|
- phase: 01-auth
|
|
186
198
|
items:
|
|
199
|
+
- "[f_81ab3c9d20] no password strength validation — deferred: accepted at review: PASS_WITH_WARNINGS"
|
|
187
200
|
- "TODO: add rate limiting"
|
|
188
|
-
- "Warning: no password strength validation"
|
|
189
201
|
- phase: 03-dashboard
|
|
190
202
|
items:
|
|
191
203
|
- "Deferred: mobile responsive layout"
|
|
@@ -197,7 +209,7 @@ Plus full markdown report with tables for requirements, phases, integration, tec
|
|
|
197
209
|
**Status values:**
|
|
198
210
|
- `passed` — all requirements met, no critical gaps, minimal tech debt
|
|
199
211
|
- `gaps_found` — critical blockers exist
|
|
200
|
-
- `tech_debt` — no blockers but accumulated deferred items need review
|
|
212
|
+
- `tech_debt` — no blockers but accumulated deferred items need review, or recorded findings were never disposed
|
|
201
213
|
|
|
202
214
|
## 7. Present Results
|
|
203
215
|
|
|
@@ -985,7 +985,7 @@ Use AskUserQuestion:
|
|
|
985
985
|
- .planning/roadmap.md (Current roadmap to revise)
|
|
986
986
|
</files_to_read>
|
|
987
987
|
|
|
988
|
-
Update the roadmap based on feedback
|
|
988
|
+
Update the roadmap based on feedback: rewrite each changed file with one Write.
|
|
989
989
|
Return ROADMAP REVISED with changes made.
|
|
990
990
|
</revision>
|
|
991
991
|
", subagent_type="pan-roadmapper", model="{roadmapper_model}", description="Revise roadmap")
|
|
@@ -8,6 +8,7 @@ Manage the circular optimization loop — apply reports, check stats, control tr
|
|
|
8
8
|
|------------|--------|
|
|
9
9
|
| `apply` | Apply safe recommendations from most recent report |
|
|
10
10
|
| `apply --report <file>` | Apply from a specific report |
|
|
11
|
+
| `revert <apply_id>` / `revert --last` | Undo one apply exactly |
|
|
11
12
|
| `list` | List all reports |
|
|
12
13
|
| `stats` | Show cumulative stats |
|
|
13
14
|
| `trace init` | Start a new trace session |
|
|
@@ -40,8 +41,9 @@ node ~/.claude/pan-wizard-core/bin/pan-tools.cjs optimize apply [--report <path>
|
|
|
40
41
|
|
|
41
42
|
Show the user:
|
|
42
43
|
- **Applied** — each item that was written (memory entries, notes)
|
|
43
|
-
- **Skipped** — items that already exist or had unknown types
|
|
44
|
+
- **Skipped** — items that already exist, that an earlier apply already wrote, or that had unknown types
|
|
44
45
|
- **Still needs review** — prompt/workflow suggestions in `suggestions.md`
|
|
46
|
+
- **The `apply_id`**, and how to undo the apply: `/pan:optimize revert <apply_id>`
|
|
45
47
|
|
|
46
48
|
If memory entries were written, tell the user:
|
|
47
49
|
> Memory entries have been added to `.planning/memory/`. They will be loaded on the next agent run, reducing future memory misses for these topics.
|
|
@@ -54,6 +56,17 @@ If `.planning/optimization/suggestions.md` exists, tell the user to review it fo
|
|
|
54
56
|
|
|
55
57
|
---
|
|
56
58
|
|
|
59
|
+
## revert
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs optimize revert <apply_id>
|
|
63
|
+
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs optimize revert --last
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Show the user each reverted action and each refused one, with its reason. A refusal means someone edited the file after the apply, or a later apply also wrote it. Revert that later apply first; never force it. The status is `reverted`, `partial`, `refused` or `nothing_to_revert`.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
57
70
|
## trace init
|
|
58
71
|
|
|
59
72
|
### Step 1 — Extract description
|