cclaw-cli 0.46.13 → 0.46.14
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.
|
@@ -102,6 +102,42 @@ Summarize citable domain practices for a narrow design decision.
|
|
|
102
102
|
|
|
103
103
|
- Cite authoritative sources (official docs/standards).
|
|
104
104
|
- State uncertainty explicitly when consensus is weak.
|
|
105
|
+
`,
|
|
106
|
+
"research-fleet.md": `# Parallel Research Fleet Playbook
|
|
107
|
+
|
|
108
|
+
## Purpose
|
|
109
|
+
|
|
110
|
+
Run a four-lens investigation before design lock so architecture choices are grounded
|
|
111
|
+
in current ecosystem data, not intuition.
|
|
112
|
+
|
|
113
|
+
## Dispatch Lenses (fan-out)
|
|
114
|
+
|
|
115
|
+
Launch four independent investigation threads in parallel when the harness supports it
|
|
116
|
+
(or sequentially with explicit role-switch logs when it does not):
|
|
117
|
+
|
|
118
|
+
1. **stack-researcher** — dependency compatibility, alternatives, deprecations.
|
|
119
|
+
2. **features-researcher** — domain conventions and product/UX patterns.
|
|
120
|
+
3. **architecture-researcher** — architecture options and trade-off matrix.
|
|
121
|
+
4. **pitfalls-researcher** — known failure modes, CVEs, and operational traps.
|
|
122
|
+
|
|
123
|
+
## Output Contract
|
|
124
|
+
|
|
125
|
+
Write findings to \`.cclaw/artifacts/02a-research.md\` with these sections:
|
|
126
|
+
|
|
127
|
+
- \`## Stack Analysis\`
|
|
128
|
+
- \`## Features & Patterns\`
|
|
129
|
+
- \`## Architecture Options\`
|
|
130
|
+
- \`## Pitfalls & Risks\`
|
|
131
|
+
- \`## Synthesis\`
|
|
132
|
+
|
|
133
|
+
Each section must contain concrete notes and at least one evidence reference
|
|
134
|
+
(source URL, file path, or command output anchor).
|
|
135
|
+
|
|
136
|
+
## Guardrails
|
|
137
|
+
|
|
138
|
+
- Investigate first; no production code edits in this playbook.
|
|
139
|
+
- Keep lenses independent during fan-out; merge only in synthesis.
|
|
140
|
+
- If any lens is incomplete, record it explicitly in \`## Synthesis\` as a blocker.
|
|
105
141
|
`,
|
|
106
142
|
"git-history.md": `# Git History Playbook
|
|
107
143
|
|
|
@@ -13,6 +13,7 @@ const REQUIRED_GATE_IDS = {
|
|
|
13
13
|
"scope_user_approved"
|
|
14
14
|
],
|
|
15
15
|
design: [
|
|
16
|
+
"design_research_complete",
|
|
16
17
|
"design_architecture_locked",
|
|
17
18
|
"design_data_flow_mapped",
|
|
18
19
|
"design_failure_modes_mapped",
|
|
@@ -53,7 +54,13 @@ const REQUIRED_GATE_IDS = {
|
|
|
53
54
|
const REQUIRED_ARTIFACT_SECTIONS = {
|
|
54
55
|
brainstorm: ["Context", "Problem", "Approaches", "Selected Direction"],
|
|
55
56
|
scope: ["Scope Mode", "In Scope / Out of Scope", "Completion Dashboard", "Scope Summary"],
|
|
56
|
-
design: [
|
|
57
|
+
design: [
|
|
58
|
+
"Research Fleet Synthesis",
|
|
59
|
+
"Architecture Boundaries",
|
|
60
|
+
"Architecture Diagram",
|
|
61
|
+
"Failure Mode Table",
|
|
62
|
+
"Completion Dashboard"
|
|
63
|
+
],
|
|
57
64
|
spec: ["Acceptance Criteria", "Edge Cases", "Testability Map", "Approval"],
|
|
58
65
|
plan: ["Task List", "Dependency Batches", "Acceptance Mapping", "WAIT_FOR_CONFIRM"],
|
|
59
66
|
tdd: ["RED Evidence", "GREEN Evidence", "REFACTOR Notes", "Traceability", "Verification Ladder"],
|
|
@@ -21,6 +21,7 @@ export const DESIGN = {
|
|
|
21
21
|
],
|
|
22
22
|
checklist: [
|
|
23
23
|
"Trivial-Change Escape Hatch — If scope artifact shows ≤3 files, zero new interfaces, and no cross-module data flow, skip full review sections. Produce a mini-design: one paragraph of rationale, list of changed files, one risk to watch. Proceed to spec.",
|
|
24
|
+
"Parallel Research Fleet — run `research/research-fleet.md` before architecture lock. Record 4-lens findings in `.cclaw/artifacts/02a-research.md` and summarize resulting decisions in `## Research Fleet Synthesis`.",
|
|
24
25
|
"Design Doc Check — read existing design docs, scope artifact, brainstorm artifact. If a design doc exists that covers this area, check for 'Supersedes:' and use the latest. Use upstream artifacts as source of truth.",
|
|
25
26
|
"Codebase Investigation — Before any design decision, read the actual code in the blast radius. List every file that will be touched, its current responsibilities, and existing patterns (error handling, naming, test style). Design must conform to discovered patterns, not impose new ones without justification.",
|
|
26
27
|
"Step 0: Scope Challenge — what existing code solves sub-problems? Minimum change set? Complexity check: 8+ files or 2+ new services = complexity smell → flag for possible scope reduction.",
|
|
@@ -50,6 +51,7 @@ export const DESIGN = {
|
|
|
50
51
|
],
|
|
51
52
|
process: [
|
|
52
53
|
"Read upstream artifacts (brainstorm, scope).",
|
|
54
|
+
"Run the research fleet playbook and write `.cclaw/artifacts/02a-research.md` before locking architecture choices.",
|
|
53
55
|
"Investigate codebase: read files in blast radius, catalogue current patterns and responsibilities.",
|
|
54
56
|
"Run Step 0 scope challenge: existing code leverage, minimum change set, complexity check.",
|
|
55
57
|
"Walk through each review section interactively.",
|
|
@@ -62,12 +64,14 @@ export const DESIGN = {
|
|
|
62
64
|
"Write design lock artifact for downstream spec/plan."
|
|
63
65
|
],
|
|
64
66
|
requiredGates: [
|
|
67
|
+
{ id: "design_research_complete", description: "Parallel research artifact is complete and synthesized into design decisions." },
|
|
65
68
|
{ id: "design_architecture_locked", description: "Architecture boundaries are explicit and approved." },
|
|
66
69
|
{ id: "design_data_flow_mapped", description: "Data/state flow includes edge-case paths." },
|
|
67
70
|
{ id: "design_failure_modes_mapped", description: "Failure modes and mitigations are documented." },
|
|
68
71
|
{ id: "design_test_and_perf_defined", description: "Test strategy and performance budget are defined." }
|
|
69
72
|
],
|
|
70
73
|
requiredEvidence: [
|
|
74
|
+
"Research artifact written to `.cclaw/artifacts/02a-research.md` with stack/features/architecture/pitfalls sections plus synthesis.",
|
|
71
75
|
"Artifact written to `.cclaw/artifacts/03-design.md`.",
|
|
72
76
|
"Failure-mode table exists with mitigations.",
|
|
73
77
|
"Test strategy includes unit/integration/e2e expectations.",
|
|
@@ -77,15 +81,18 @@ export const DESIGN = {
|
|
|
77
81
|
],
|
|
78
82
|
inputs: ["scope contract", "system constraints", "non-functional requirements"],
|
|
79
83
|
requiredContext: [
|
|
84
|
+
"parallel research synthesis from `.cclaw/artifacts/02a-research.md`",
|
|
80
85
|
"existing architecture and boundaries",
|
|
81
86
|
"operational constraints",
|
|
82
87
|
"security and reliability expectations"
|
|
83
88
|
],
|
|
84
89
|
researchPlaybooks: [
|
|
90
|
+
"research/research-fleet.md",
|
|
85
91
|
"research/framework-docs-lookup.md",
|
|
86
92
|
"research/best-practices-lookup.md"
|
|
87
93
|
],
|
|
88
94
|
outputs: [
|
|
95
|
+
"parallel research synthesis artifact",
|
|
89
96
|
"architecture lock",
|
|
90
97
|
"risk and failure map",
|
|
91
98
|
"test and performance baseline",
|
|
@@ -110,17 +117,14 @@ export const DESIGN = {
|
|
|
110
117
|
"Missing data-flow edge cases",
|
|
111
118
|
"No performance budget for critical path",
|
|
112
119
|
"Batching multiple design issues into one question",
|
|
113
|
-
"Skipping review sections because plan seems simple",
|
|
114
120
|
"Agreeing with user's architecture choice without evaluating alternatives",
|
|
115
121
|
"Hedging every recommendation with 'it depends' instead of taking a position",
|
|
116
|
-
"No explicit architecture boundary section",
|
|
117
|
-
"No failure recovery strategy",
|
|
118
|
-
"No defined test/perf baseline",
|
|
119
122
|
"No NOT-in-scope output section",
|
|
120
123
|
"No What-already-exists output section",
|
|
121
124
|
"Design decisions made without reading the actual code first"
|
|
122
125
|
],
|
|
123
126
|
policyNeedles: [
|
|
127
|
+
"Parallel Research Fleet",
|
|
124
128
|
"Architecture",
|
|
125
129
|
"Data Flow",
|
|
126
130
|
"Failure Modes and Mitigation",
|
|
@@ -186,11 +190,16 @@ export const DESIGN = {
|
|
|
186
190
|
],
|
|
187
191
|
completionStatus: ["DONE", "DONE_WITH_CONCERNS", "BLOCKED"],
|
|
188
192
|
crossStageTrace: {
|
|
189
|
-
readsFrom: [
|
|
193
|
+
readsFrom: [
|
|
194
|
+
".cclaw/artifacts/01-brainstorm.md",
|
|
195
|
+
".cclaw/artifacts/02-scope.md",
|
|
196
|
+
".cclaw/artifacts/02a-research.md"
|
|
197
|
+
],
|
|
190
198
|
writesTo: [".cclaw/artifacts/03-design.md"],
|
|
191
199
|
traceabilityRule: "Every architecture decision must trace to a scope boundary. Every downstream spec requirement must trace to a design decision."
|
|
192
200
|
},
|
|
193
201
|
artifactValidation: [
|
|
202
|
+
{ section: "Research Fleet Synthesis", required: true, validationRule: "Must summarize all four lenses (stack/features/architecture/pitfalls) and map findings to concrete design decisions." },
|
|
194
203
|
{ section: "Codebase Investigation", required: false, validationRule: "Must list blast-radius files with current responsibilities and discovered patterns." },
|
|
195
204
|
{ section: "Search Before Building", required: false, validationRule: "For each technical choice: Layer 1 (exact match), Layer 2 (partial match), Layer 3 (inspiration), EUREKA labels with reuse-first default." },
|
|
196
205
|
{ section: "Architecture Boundaries", required: true, validationRule: "Must list component boundaries with ownership." },
|
|
@@ -152,6 +152,47 @@ inputs_hash: sha256:pending
|
|
|
152
152
|
- Deferred:
|
|
153
153
|
- Explicitly excluded:
|
|
154
154
|
|
|
155
|
+
## Learnings
|
|
156
|
+
- None this stage.
|
|
157
|
+
`,
|
|
158
|
+
"02a-research.md": `---
|
|
159
|
+
stage: design
|
|
160
|
+
schema_version: 1
|
|
161
|
+
version: 0.18.0
|
|
162
|
+
feature: <feature-id>
|
|
163
|
+
locked_decisions: []
|
|
164
|
+
inputs_hash: sha256:pending
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
# Research Report
|
|
168
|
+
|
|
169
|
+
## Stack Analysis
|
|
170
|
+
| Topic | Finding | Evidence |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| Dependency compatibility | | |
|
|
173
|
+
| Alternatives/deprecations | | |
|
|
174
|
+
|
|
175
|
+
## Features & Patterns
|
|
176
|
+
| Topic | Finding | Evidence |
|
|
177
|
+
|---|---|---|
|
|
178
|
+
| Domain conventions | | |
|
|
179
|
+
| UX/product patterns | | |
|
|
180
|
+
|
|
181
|
+
## Architecture Options
|
|
182
|
+
| Option | Trade-offs | Recommendation | Evidence |
|
|
183
|
+
|---|---|---|---|
|
|
184
|
+
| A | | | |
|
|
185
|
+
| B | | | |
|
|
186
|
+
|
|
187
|
+
## Pitfalls & Risks
|
|
188
|
+
| Risk | Impact | Mitigation | Evidence |
|
|
189
|
+
|---|---|---|---|
|
|
190
|
+
| | | | |
|
|
191
|
+
|
|
192
|
+
## Synthesis
|
|
193
|
+
- Key decisions informed by research:
|
|
194
|
+
- Open questions:
|
|
195
|
+
|
|
155
196
|
## Learnings
|
|
156
197
|
- None this stage.
|
|
157
198
|
`,
|
|
@@ -178,6 +219,14 @@ inputs_hash: sha256:pending
|
|
|
178
219
|
| Layer 2 | | |
|
|
179
220
|
| Layer 3 | | |
|
|
180
221
|
|
|
222
|
+
## Research Fleet Synthesis
|
|
223
|
+
| Lens | Key findings | Design impact | Evidence |
|
|
224
|
+
|---|---|---|---|
|
|
225
|
+
| stack-researcher | | | |
|
|
226
|
+
| features-researcher | | | |
|
|
227
|
+
| architecture-researcher | | | |
|
|
228
|
+
| pitfalls-researcher | | | |
|
|
229
|
+
|
|
181
230
|
## Architecture Boundaries
|
|
182
231
|
| Component | Responsibility | Owner |
|
|
183
232
|
|---|---|---|
|
package/dist/gate-evidence.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { checkReviewVerdictConsistency, lintArtifact, validateReviewArmy } from "./artifact-linter.js";
|
|
3
|
+
import { checkReviewVerdictConsistency, extractMarkdownSectionBody, lintArtifact, validateReviewArmy } from "./artifact-linter.js";
|
|
4
4
|
import { RUNTIME_ROOT } from "./constants.js";
|
|
5
5
|
import { stageSchema } from "./content/stage-schema.js";
|
|
6
6
|
import { ensureDir, exists, writeFileSafe } from "./fs-utils.js";
|
|
@@ -26,6 +26,23 @@ async function currentStageArtifactExists(projectRoot, stage, track) {
|
|
|
26
26
|
return false;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
+
async function readArtifactMarkdown(projectRoot, artifactFile) {
|
|
30
|
+
const candidates = [
|
|
31
|
+
path.join(projectRoot, RUNTIME_ROOT, "artifacts", artifactFile),
|
|
32
|
+
path.join(projectRoot, artifactFile)
|
|
33
|
+
];
|
|
34
|
+
for (const candidate of candidates) {
|
|
35
|
+
if (!(await exists(candidate)))
|
|
36
|
+
continue;
|
|
37
|
+
try {
|
|
38
|
+
return await fs.readFile(candidate, "utf8");
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Try next location.
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
29
46
|
function unique(values) {
|
|
30
47
|
return [...new Set(values)];
|
|
31
48
|
}
|
|
@@ -36,6 +53,13 @@ function sameStringArray(a, b) {
|
|
|
36
53
|
}
|
|
37
54
|
const RECONCILIATION_NOTICES_FILE = "reconciliation-notices.json";
|
|
38
55
|
const RECONCILIATION_NOTICES_SCHEMA_VERSION = 1;
|
|
56
|
+
const DESIGN_RESEARCH_REQUIRED_SECTIONS = [
|
|
57
|
+
"Stack Analysis",
|
|
58
|
+
"Features & Patterns",
|
|
59
|
+
"Architecture Options",
|
|
60
|
+
"Pitfalls & Risks",
|
|
61
|
+
"Synthesis"
|
|
62
|
+
];
|
|
39
63
|
export const RECONCILIATION_NOTICES_REL_PATH = `${RUNTIME_ROOT}/state/${RECONCILIATION_NOTICES_FILE}`;
|
|
40
64
|
function isFlowStageValue(value) {
|
|
41
65
|
return typeof value === "string" && FLOW_STAGES.includes(value);
|
|
@@ -222,6 +246,37 @@ export async function verifyCurrentStageGateEvidence(projectRoot, flowState) {
|
|
|
222
246
|
}
|
|
223
247
|
}
|
|
224
248
|
}
|
|
249
|
+
if (stage === "design") {
|
|
250
|
+
const researchGateRequired = schema.requiredGates.some((gate) => gate.id === "design_research_complete" && gate.tier === "required");
|
|
251
|
+
if (researchGateRequired) {
|
|
252
|
+
const researchMarkdown = await readArtifactMarkdown(projectRoot, "02a-research.md");
|
|
253
|
+
if (!researchMarkdown) {
|
|
254
|
+
issues.push("design research gate blocked (design_research_complete): missing `.cclaw/artifacts/02a-research.md`.");
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
const missingSections = [];
|
|
258
|
+
for (const section of DESIGN_RESEARCH_REQUIRED_SECTIONS) {
|
|
259
|
+
const body = extractMarkdownSectionBody(researchMarkdown, section);
|
|
260
|
+
if (body === null) {
|
|
261
|
+
missingSections.push(section);
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
const meaningfulLines = body
|
|
265
|
+
.split(/\r?\n/gu)
|
|
266
|
+
.map((line) => line.trim())
|
|
267
|
+
.filter((line) => line.length > 0)
|
|
268
|
+
.filter((line) => !/^\|?(?:[-:\s|])+$/u.test(line));
|
|
269
|
+
const nonPlaceholder = meaningfulLines.filter((line) => !/\b(?:TODO|TBD|FIXME|pending|<fill-in>)\b/iu.test(line));
|
|
270
|
+
if (nonPlaceholder.length === 0) {
|
|
271
|
+
missingSections.push(`${section} (empty or placeholder)`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (missingSections.length > 0) {
|
|
275
|
+
issues.push(`design research gate blocked (design_research_complete): ${missingSections.join(", ")}.`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
225
280
|
}
|
|
226
281
|
const passedSet = new Set(catalog.passed);
|
|
227
282
|
const missingRequired = required.filter((gateId) => !passedSet.has(gateId));
|