cclaw-cli 0.10.1 → 0.11.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/dist/config.js +83 -3
- package/dist/content/hooks.js +81 -11
- package/dist/content/meta-skill.d.ts +0 -8
- package/dist/content/meta-skill.js +51 -341
- package/dist/content/next-command.js +2 -1
- package/dist/content/protocols.d.ts +7 -0
- package/dist/content/protocols.js +95 -0
- package/dist/content/skills.js +183 -313
- package/dist/content/stage-common-guidance.d.ts +2 -0
- package/dist/content/stage-common-guidance.js +71 -0
- package/dist/content/stage-schema.d.ts +8 -0
- package/dist/content/stage-schema.js +135 -1
- package/dist/content/start-command.js +19 -13
- package/dist/doctor.js +21 -23
- package/dist/flow-state.d.ts +4 -0
- package/dist/flow-state.js +4 -1
- package/dist/gate-evidence.d.ts +9 -1
- package/dist/gate-evidence.js +121 -17
- package/dist/install.js +10 -0
- package/dist/policy.js +16 -13
- package/dist/runs.js +21 -4
- package/dist/track-heuristics.d.ts +12 -0
- package/dist/track-heuristics.js +144 -0
- package/dist/types.d.ts +26 -3
- package/dist/types.js +6 -3
- package/package.json +1 -1
package/dist/content/skills.js
CHANGED
|
@@ -1,116 +1,34 @@
|
|
|
1
1
|
import { RUNTIME_ROOT } from "../constants.js";
|
|
2
2
|
import { STAGE_EXAMPLES_REFERENCE_DIR, stageDomainExamples, stageExamples, stageGoodBadExamples } from "./examples.js";
|
|
3
|
-
import {
|
|
3
|
+
import { STAGE_COMMON_GUIDANCE_REL_PATH } from "./stage-common-guidance.js";
|
|
4
4
|
import { stageAutoSubagentDispatch, stageSchema } from "./stage-schema.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
${schema.rationalizations.map((e) => `| ${e.claim} | ${e.reality} |`).join("\n")}`;
|
|
10
|
-
}
|
|
11
|
-
function cognitivePatternsList(stage) {
|
|
12
|
-
const schema = stageSchema(stage);
|
|
13
|
-
if (schema.cognitivePatterns.length === 0)
|
|
14
|
-
return "";
|
|
15
|
-
const items = schema.cognitivePatterns
|
|
16
|
-
.map((p, i) => `${i + 1}. **${p.name}** — ${p.description}`)
|
|
17
|
-
.join("\n");
|
|
18
|
-
return `## Cognitive Patterns\n\nThese are thinking instincts, not a checklist. Let them shape your perspective throughout the stage.\n\n${items}\n`;
|
|
19
|
-
}
|
|
20
|
-
function reviewSectionsBlock(stage) {
|
|
5
|
+
const VERIFICATION_STAGES = ["tdd", "review", "ship"];
|
|
6
|
+
const DECISION_PROTOCOL_PATH = `${RUNTIME_ROOT}/references/protocols/decision.md`;
|
|
7
|
+
const COMPLETION_PROTOCOL_PATH = `${RUNTIME_ROOT}/references/protocols/completion.md`;
|
|
8
|
+
function whenNotToUseBlock(stage) {
|
|
21
9
|
const schema = stageSchema(stage);
|
|
22
|
-
if (schema.
|
|
23
|
-
return "";
|
|
24
|
-
const sections = schema.reviewSections.map((sec) => {
|
|
25
|
-
const points = sec.evaluationPoints.map((p) => `- ${p}`).join("\n");
|
|
26
|
-
const stop = sec.stopGate
|
|
27
|
-
? "\n\n**STOP.** Present the most important question from this section to the user, even if your recommendation is clear. If no issues are found, state your assessment in one sentence and ask the user to confirm before moving on. If issues exist, present them ONE AT A TIME: describe the problem concretely, present 2-3 options, state your recommendation, and explain WHY."
|
|
28
|
-
: "";
|
|
29
|
-
return `### ${sec.title}\n\nEvaluate:\n${points}${stop}`;
|
|
30
|
-
}).join("\n\n");
|
|
31
|
-
return `## Review Sections\n\n**Anti-skip rule:** Never condense, abbreviate, or skip any review section. If a section genuinely has zero findings, say "No issues found" and move on — but you must evaluate it.\n\n${sections}\n`;
|
|
32
|
-
}
|
|
33
|
-
function crossStageTraceBlock(stage) {
|
|
34
|
-
const trace = stageSchema(stage).crossStageTrace;
|
|
35
|
-
const reads = trace.readsFrom.length > 0
|
|
36
|
-
? trace.readsFrom.map((r) => `- ${r}`).join("\n")
|
|
37
|
-
: "- (first stage — no upstream artifacts)";
|
|
38
|
-
const writes = trace.writesTo.length > 0
|
|
39
|
-
? trace.writesTo.map((w) => `- ${w}`).join("\n")
|
|
40
|
-
: "- (final stage — no downstream artifacts)";
|
|
41
|
-
return `## Cross-Stage Traceability\n\n**Reads from:**\n${reads}\n\n**Writes to:**\n${writes}\n\n**Rule:** ${trace.traceabilityRule}\n`;
|
|
42
|
-
}
|
|
43
|
-
function artifactValidationBlock(stage) {
|
|
44
|
-
const validations = stageSchema(stage).artifactValidation;
|
|
45
|
-
if (validations.length === 0)
|
|
46
|
-
return "";
|
|
47
|
-
const rows = validations.map((v) => {
|
|
48
|
-
const req = v.required ? "REQUIRED" : "optional";
|
|
49
|
-
return `| ${v.section} | ${req} | ${v.validationRule} |`;
|
|
50
|
-
}).join("\n");
|
|
51
|
-
return `## Artifact Validation\n\n| Section | Status | Validation Rule |\n|---|---|---|\n${rows}\n`;
|
|
52
|
-
}
|
|
53
|
-
function completionStatusBlock(stage) {
|
|
54
|
-
const statuses = stageSchema(stage).completionStatus;
|
|
55
|
-
const items = statuses.map((s) => `- **${s}**`).join("\n");
|
|
56
|
-
return `## Completion Status\n\nWhen this stage ends, report one of:\n${items}\n`;
|
|
57
|
-
}
|
|
58
|
-
function namedAntiPatternBlock(stage) {
|
|
59
|
-
const nap = stageSchema(stage).namedAntiPattern;
|
|
60
|
-
if (!nap)
|
|
61
|
-
return "";
|
|
62
|
-
return `## Anti-Pattern: "${nap.title}"\n\n${nap.description}\n`;
|
|
63
|
-
}
|
|
64
|
-
function decisionRecordBlock(stage) {
|
|
65
|
-
const fmt = stageSchema(stage).decisionRecordFormat;
|
|
66
|
-
if (!fmt)
|
|
67
|
-
return "";
|
|
68
|
-
return `## Decision Record Template\n\nUse this format for every non-trivial architecture or scope decision made during this stage:\n\n\`\`\`\n${fmt}\n\`\`\`\n`;
|
|
69
|
-
}
|
|
70
|
-
function visualCommunicationBlock(stage) {
|
|
71
|
-
if (stage !== "design")
|
|
10
|
+
if (schema.whenNotToUse.length === 0) {
|
|
72
11
|
return "";
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
1. **Concrete names, never generic.** "Service A → Service B" is not a diagram; it is a shape. Every node must name a real component the team will build or touch (\`NotificationPublisher\`, \`FeedReadModel\`, \`Stripe webhook handler\`). If you cannot name it concretely, the design is not ready.
|
|
78
|
-
2. **Every arrow is labeled.** Label with the message, action, or protocol it carries (\`publishEvent(user_id, payload)\`, \`GET /snapshot\`, \`dedupe-key upsert\`). Unlabeled arrows silently lose the contract between components.
|
|
79
|
-
3. **Direction is explicit.** Use arrowheads, not bare lines; draw the flow of *data* (not "dependency") unless the diagram type is explicitly a dependency graph, in which case say so in a one-line caption.
|
|
80
|
-
4. **Distinguish sync vs async.** Use a convention and state it once in a legend: e.g. solid arrow = synchronous request/response, dashed arrow = async message via queue/bus, double arrow = two-way. Async edges always name the queue or topic.
|
|
81
|
-
5. **Show at least one failure edge.** Every non-trivial diagram needs one branch that represents the degraded or error path (timeout, reconnect, fallback to cache, poison-message routing). A diagram with only the happy path hides the interesting half of the design.
|
|
82
|
-
6. **One level of detail per diagram.** Do not mix "service-level" and "class-level" on the same canvas. If you need both, produce two diagrams — one at the system boundary, one at the internal module — and cross-reference them.
|
|
83
|
-
7. **Caption, not decoration.** Each diagram gets a one-sentence caption below it stating what the reader should take away ("*Publish path with idempotent outbox; SSE stream reads the projection, not the bus directly*"). If you cannot write the caption in one sentence, the diagram is doing two things at once.
|
|
84
|
-
8. **Prefer text-based formats** (Mermaid, ASCII) over binary images in \`.cclaw/artifacts/\` so diffs stay reviewable. Binary/SVG is allowed when the diagram is already the source of truth elsewhere (e.g. \`docs/architecture/\`) and the artifact embeds a link plus a text-based summary.
|
|
12
|
+
}
|
|
13
|
+
return `## When Not to Use
|
|
14
|
+
${schema.whenNotToUse.map((item) => `- ${item}`).join("\n")}
|
|
85
15
|
|
|
86
|
-
If a diagram cannot satisfy rules 1–5, do NOT include it — a missing diagram is honest; a misleading diagram is worse. Surface the gap in **Unresolved Decisions** and proceed without the diagram until the decisions that would populate it are locked.
|
|
87
16
|
`;
|
|
88
17
|
}
|
|
89
18
|
function contextLoadingBlock(stage) {
|
|
90
19
|
const trace = stageSchema(stage).crossStageTrace;
|
|
91
20
|
const readLines = trace.readsFrom.length > 0
|
|
92
|
-
? trace.readsFrom
|
|
93
|
-
.map((value) => `- \`${value}\``)
|
|
94
|
-
.join("\n")
|
|
21
|
+
? trace.readsFrom.map((value) => `- \`${value}\``).join("\n")
|
|
95
22
|
: "- (first stage — no upstream artifacts)";
|
|
96
23
|
return `## Context Loading
|
|
97
24
|
|
|
98
|
-
Before
|
|
25
|
+
Before execution:
|
|
99
26
|
1. Read \`.cclaw/state/flow-state.json\`.
|
|
100
|
-
2.
|
|
27
|
+
2. Load active artifacts from \`.cclaw/artifacts/\`.
|
|
101
28
|
3. Load upstream artifacts required by this stage:
|
|
102
29
|
${readLines}
|
|
103
|
-
4.
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
function whenNotToUseBlock(stage) {
|
|
107
|
-
const schema = stageSchema(stage);
|
|
108
|
-
if (!schema.whenNotToUse || schema.whenNotToUse.length === 0) {
|
|
109
|
-
return "";
|
|
110
|
-
}
|
|
111
|
-
return `## When Not to Use
|
|
112
|
-
${schema.whenNotToUse.map((item) => `- ${item}`).join("\n")}
|
|
113
|
-
|
|
30
|
+
4. Use the injected knowledge digest from session-start; only fall back to full
|
|
31
|
+
\`.cclaw/knowledge.jsonl\` when the digest is insufficient.
|
|
114
32
|
`;
|
|
115
33
|
}
|
|
116
34
|
function autoSubagentDispatchBlock(stage) {
|
|
@@ -120,60 +38,179 @@ function autoSubagentDispatchBlock(stage) {
|
|
|
120
38
|
const rows = rules
|
|
121
39
|
.map((rule) => {
|
|
122
40
|
const userGate = rule.requiresUserGate ? "required" : "not required";
|
|
123
|
-
return `| ${rule.agent} | ${rule.mode} | ${
|
|
41
|
+
return `| ${rule.agent} | ${rule.mode} | ${userGate} | ${rule.when} |`;
|
|
124
42
|
})
|
|
125
43
|
.join("\n");
|
|
126
44
|
const mandatory = stageSchema(stage).mandatoryDelegations;
|
|
127
|
-
const mandatoryList = mandatory.length > 0 ? mandatory.map((a) => `\`${a}\``).join(", ") : "
|
|
45
|
+
const mandatoryList = mandatory.length > 0 ? mandatory.map((a) => `\`${a}\``).join(", ") : "none";
|
|
128
46
|
const delegationLogRel = `${RUNTIME_ROOT}/state/delegation-log.json`;
|
|
129
47
|
return `## Automatic Subagent Dispatch
|
|
130
48
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
| Agent | Mode | When | Purpose | User Gate |
|
|
134
|
-
|---|---|---|---|---|
|
|
49
|
+
| Agent | Mode | User Gate | Trigger |
|
|
50
|
+
|---|---|---|---|
|
|
135
51
|
${rows}
|
|
136
52
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
53
|
+
Mandatory delegations for this stage: ${mandatoryList}.
|
|
54
|
+
Record completion/waiver in \`${delegationLogRel}\` before stage completion.
|
|
55
|
+
`;
|
|
56
|
+
}
|
|
57
|
+
function reviewSectionsBlock(stage) {
|
|
58
|
+
const schema = stageSchema(stage);
|
|
59
|
+
if (schema.reviewSections.length === 0)
|
|
60
|
+
return "";
|
|
61
|
+
const sections = schema.reviewSections
|
|
62
|
+
.map((sec) => {
|
|
63
|
+
const points = sec.evaluationPoints.map((p) => `- ${p}`).join("\n");
|
|
64
|
+
const stop = sec.stopGate
|
|
65
|
+
? "\n\n**STOP:** resolve findings in this section before moving forward."
|
|
66
|
+
: "";
|
|
67
|
+
return `### ${sec.title}\n${points}${stop}`;
|
|
68
|
+
})
|
|
69
|
+
.join("\n\n");
|
|
70
|
+
return `## Review Sections
|
|
140
71
|
|
|
141
|
-
|
|
72
|
+
${sections}
|
|
73
|
+
`;
|
|
74
|
+
}
|
|
75
|
+
function verificationBlock(stage) {
|
|
76
|
+
if (!VERIFICATION_STAGES.includes(stage))
|
|
77
|
+
return "";
|
|
78
|
+
return `## Verification Before Completion
|
|
142
79
|
|
|
143
|
-
|
|
80
|
+
Provide fresh, stage-local verification evidence from this turn:
|
|
144
81
|
|
|
145
|
-
|
|
82
|
+
1. Run verification commands (tests/build/lint/type-check) for the changed scope.
|
|
83
|
+
2. Confirm output, do not infer success from prior runs.
|
|
84
|
+
3. If this is a bug fix, capture RED -> GREEN evidence for the regression path.
|
|
146
85
|
`;
|
|
147
86
|
}
|
|
148
|
-
const VERIFICATION_STAGES = ["tdd", "review", "ship"];
|
|
149
|
-
/**
|
|
150
|
-
* Short inline summary of Wave Execution Mode. The detailed 3-task
|
|
151
|
-
* walkthrough (RED/GREEN/REFACTOR transcript per slice) lives in the
|
|
152
|
-
* companion reference file so the always-rendered skill body stays under
|
|
153
|
-
* the 400-line soft budget.
|
|
154
|
-
*/
|
|
155
87
|
function waveExecutionModeBlock(stage) {
|
|
156
88
|
const schema = stageSchema(stage);
|
|
157
|
-
if (!schema.waveExecutionAllowed)
|
|
89
|
+
if (!schema.waveExecutionAllowed)
|
|
158
90
|
return "";
|
|
159
|
-
}
|
|
160
91
|
return `## Wave Execution Mode
|
|
161
92
|
|
|
162
|
-
|
|
93
|
+
Execute the current dependency wave task-by-task (RED -> GREEN -> REFACTOR).
|
|
94
|
+
Stop on BLOCKED status or when user input is required.
|
|
163
95
|
|
|
164
|
-
|
|
96
|
+
Detailed walkthrough:
|
|
97
|
+
\`.cclaw/${STAGE_EXAMPLES_REFERENCE_DIR}/tdd-wave-walkthrough.md\`
|
|
98
|
+
`;
|
|
99
|
+
}
|
|
100
|
+
function crossStageTraceBlock(stage) {
|
|
101
|
+
const trace = stageSchema(stage).crossStageTrace;
|
|
102
|
+
const reads = trace.readsFrom.length > 0
|
|
103
|
+
? trace.readsFrom.map((r) => `- ${r}`).join("\n")
|
|
104
|
+
: "- (first stage — no upstream artifacts)";
|
|
105
|
+
const writes = trace.writesTo.length > 0
|
|
106
|
+
? trace.writesTo.map((w) => `- ${w}`).join("\n")
|
|
107
|
+
: "- (terminal stage)";
|
|
108
|
+
return `## Cross-Stage Traceability
|
|
165
109
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
3. Only then declare the wave complete. The next wave cannot start until this step.
|
|
110
|
+
Reads from:
|
|
111
|
+
${reads}
|
|
169
112
|
|
|
170
|
-
|
|
113
|
+
Writes to:
|
|
114
|
+
${writes}
|
|
171
115
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
116
|
+
Rule: ${trace.traceabilityRule}
|
|
117
|
+
`;
|
|
118
|
+
}
|
|
119
|
+
function artifactValidationBlock(stage) {
|
|
120
|
+
const validations = stageSchema(stage).artifactValidation;
|
|
121
|
+
if (validations.length === 0)
|
|
122
|
+
return "";
|
|
123
|
+
const rows = validations
|
|
124
|
+
.map((v) => {
|
|
125
|
+
const req = v.required ? "REQUIRED" : "recommended";
|
|
126
|
+
return `| ${v.section} | ${req} | ${v.validationRule} |`;
|
|
127
|
+
})
|
|
128
|
+
.join("\n");
|
|
129
|
+
return `## Artifact Validation
|
|
130
|
+
|
|
131
|
+
| Section | Tier | Validation rule |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
${rows}
|
|
134
|
+
`;
|
|
135
|
+
}
|
|
136
|
+
function mergedAntiPatterns(schema) {
|
|
137
|
+
const merged = [];
|
|
138
|
+
const seen = new Set();
|
|
139
|
+
for (const item of [...schema.antiPatterns, ...schema.blockers, ...schema.redFlags]) {
|
|
140
|
+
const key = item.trim().toLowerCase();
|
|
141
|
+
if (seen.has(key))
|
|
142
|
+
continue;
|
|
143
|
+
seen.add(key);
|
|
144
|
+
merged.push(item);
|
|
145
|
+
}
|
|
146
|
+
return merged.map((item) => `- ${item}`).join("\n");
|
|
147
|
+
}
|
|
148
|
+
function stageSpecificSeeAlso(stage) {
|
|
149
|
+
const refs = {
|
|
150
|
+
brainstorm: [
|
|
151
|
+
`- \`${RUNTIME_ROOT}/skills/learnings/SKILL.md\``,
|
|
152
|
+
`- \`${RUNTIME_ROOT}/references/stages/brainstorm-examples.md\``
|
|
153
|
+
],
|
|
154
|
+
scope: [
|
|
155
|
+
`- \`${RUNTIME_ROOT}/skills/learnings/SKILL.md\``,
|
|
156
|
+
`- \`${RUNTIME_ROOT}/references/stages/scope-examples.md\``
|
|
157
|
+
],
|
|
158
|
+
design: [
|
|
159
|
+
`- \`${RUNTIME_ROOT}/skills/security/SKILL.md\``,
|
|
160
|
+
`- \`${RUNTIME_ROOT}/skills/performance/SKILL.md\``
|
|
161
|
+
],
|
|
162
|
+
spec: [
|
|
163
|
+
`- \`${RUNTIME_ROOT}/skills/docs/SKILL.md\``,
|
|
164
|
+
`- \`${RUNTIME_ROOT}/references/stages/spec-examples.md\``
|
|
165
|
+
],
|
|
166
|
+
plan: [
|
|
167
|
+
`- \`${RUNTIME_ROOT}/skills/subagent-dev/SKILL.md\``,
|
|
168
|
+
`- \`${RUNTIME_ROOT}/skills/parallel-dispatch/SKILL.md\``
|
|
169
|
+
],
|
|
170
|
+
tdd: [
|
|
171
|
+
`- \`${RUNTIME_ROOT}/skills/debugging/SKILL.md\``,
|
|
172
|
+
`- \`${RUNTIME_ROOT}/references/stages/tdd-wave-walkthrough.md\``
|
|
173
|
+
],
|
|
174
|
+
review: [
|
|
175
|
+
`- \`${RUNTIME_ROOT}/skills/security/SKILL.md\``,
|
|
176
|
+
`- \`${RUNTIME_ROOT}/skills/parallel-dispatch/SKILL.md\``
|
|
177
|
+
],
|
|
178
|
+
ship: [
|
|
179
|
+
`- \`${RUNTIME_ROOT}/skills/ci-cd/SKILL.md\``,
|
|
180
|
+
`- \`${RUNTIME_ROOT}/skills/docs/SKILL.md\``
|
|
181
|
+
]
|
|
182
|
+
};
|
|
183
|
+
return refs[stage];
|
|
184
|
+
}
|
|
185
|
+
function completionParametersBlock(schema) {
|
|
186
|
+
const gateList = schema.requiredGates.map((g) => `\`${g.id}\``).join(", ");
|
|
187
|
+
const mandatory = schema.mandatoryDelegations.length > 0
|
|
188
|
+
? schema.mandatoryDelegations.map((a) => `\`${a}\``).join(", ")
|
|
189
|
+
: "none";
|
|
190
|
+
const nextStage = schema.next === "done" ? "done" : schema.next;
|
|
191
|
+
const nextDescription = schema.next === "done"
|
|
192
|
+
? "flow complete"
|
|
193
|
+
: stageSchema(schema.next).skillDescription;
|
|
194
|
+
return `## Completion Parameters
|
|
195
|
+
|
|
196
|
+
- \`stage\`: \`${schema.stage}\`
|
|
197
|
+
- \`next\`: \`${nextStage}\` (${nextDescription})
|
|
198
|
+
- \`gates\`: ${gateList}
|
|
199
|
+
- \`artifact\`: \`${RUNTIME_ROOT}/artifacts/${schema.artifactFile}\`
|
|
200
|
+
- \`mandatory delegations\`: ${mandatory}
|
|
201
|
+
|
|
202
|
+
Apply shared completion logic from:
|
|
203
|
+
\`${COMPLETION_PROTOCOL_PATH}\`
|
|
204
|
+
`;
|
|
205
|
+
}
|
|
206
|
+
function quickStartBlock(stage) {
|
|
207
|
+
const schema = stageSchema(stage);
|
|
208
|
+
const gatePreview = schema.requiredGates.slice(0, 3).map((g) => `\`${g.id}\``).join(", ");
|
|
209
|
+
return `## Quick Start
|
|
175
210
|
|
|
176
|
-
|
|
211
|
+
1. Obey HARD-GATE and Iron Law.
|
|
212
|
+
2. Execute checklist in order and persist \`${RUNTIME_ROOT}/artifacts/${schema.artifactFile}\`.
|
|
213
|
+
3. Satisfy gates (${gatePreview}${schema.requiredGates.length > 3 ? ` +${schema.requiredGates.length - 3}` : ""}).
|
|
177
214
|
`;
|
|
178
215
|
}
|
|
179
216
|
/**
|
|
@@ -229,143 +266,9 @@ After T-3 REFACTOR, before declaring Wave 1 done:
|
|
|
229
266
|
- A GREEN step would require touching code outside the task's acceptance criterion → **pause**, the task is scoped wrong; adjust the plan or open a follow-up task.
|
|
230
267
|
- The same RED failure reappears after a GREEN change → **escalate** per the 3-attempts rule; do not keep patching.
|
|
231
268
|
`;
|
|
232
|
-
function stageCompletionProtocol(schema) {
|
|
233
|
-
const stage = schema.stage;
|
|
234
|
-
const gateIds = schema.requiredGates.map((g) => g.id);
|
|
235
|
-
const gateList = gateIds.map((id) => `\`${id}\``).join(", ");
|
|
236
|
-
const nextStage = schema.next === "done" ? "done" : schema.next;
|
|
237
|
-
const mandatory = schema.mandatoryDelegations;
|
|
238
|
-
const mandatoryList = mandatory.length > 0 ? mandatory.map((a) => `\`${a}\``).join(", ") : "none";
|
|
239
|
-
const nextDescription = schema.next === "done"
|
|
240
|
-
? "flow complete — release cut and handoff signed off"
|
|
241
|
-
: (() => {
|
|
242
|
-
const nextSchema = stageSchema(schema.next);
|
|
243
|
-
return nextSchema.skillDescription.charAt(0).toLowerCase() + nextSchema.skillDescription.slice(1);
|
|
244
|
-
})();
|
|
245
|
-
return `## Stage Completion Protocol
|
|
246
|
-
|
|
247
|
-
Apply the **Shared Stage Completion Protocol** from \`.cclaw/skills/using-cclaw/SKILL.md\` with these parameters — do NOT re-derive the generic steps here.
|
|
248
|
-
|
|
249
|
-
**Completion Parameters**
|
|
250
|
-
- \`stage\` — \`${stage}\`
|
|
251
|
-
- \`next\` — \`${nextStage}\` (${nextDescription})
|
|
252
|
-
- \`gates\` — ${gateList}
|
|
253
|
-
- \`artifact\` — \`${RUNTIME_ROOT}/artifacts/${schema.artifactFile}\`
|
|
254
|
-
- \`mandatory\` — ${mandatoryList}
|
|
255
|
-
|
|
256
|
-
When all required gates are satisfied and the artifact is written, execute the shared procedure (delegation pre-flight → flow-state update → artifact persistence → \`npx cclaw doctor\` → user handoff → STOP) using the parameters above. If any check fails, resolve the issue and re-run before proceeding.
|
|
257
|
-
|
|
258
|
-
## Resume Protocol
|
|
259
|
-
|
|
260
|
-
When resuming this stage in a NEW session (artifact exists but not all of ${gateList} are passed), follow the **Shared Resume Protocol** in \`.cclaw/skills/using-cclaw/SKILL.md\` — confirm one gate at a time, update \`guardEvidence\` for each, never batch confirmations.
|
|
261
|
-
`;
|
|
262
|
-
}
|
|
263
|
-
function stageTransitionAutoAdvanceBlock(schema) {
|
|
264
|
-
return stageCompletionProtocol(schema);
|
|
265
|
-
}
|
|
266
|
-
function progressiveDisclosureBlock(stage) {
|
|
267
|
-
const schema = stageSchema(stage);
|
|
268
|
-
const stageSpecificRefs = {
|
|
269
|
-
brainstorm: [
|
|
270
|
-
"- `.cclaw/skills/learnings/SKILL.md` — to capture durable framing insights early"
|
|
271
|
-
],
|
|
272
|
-
scope: [
|
|
273
|
-
"- `.cclaw/skills/learnings/SKILL.md` — to persist rejected assumptions and constraints"
|
|
274
|
-
],
|
|
275
|
-
design: [
|
|
276
|
-
"- `.cclaw/skills/performance/SKILL.md` — when architectural choices carry perf trade-offs",
|
|
277
|
-
"- `.cclaw/skills/security/SKILL.md` — when design choices touch auth/secrets/trust boundaries"
|
|
278
|
-
],
|
|
279
|
-
spec: [
|
|
280
|
-
"- `.cclaw/skills/docs/SKILL.md` — for API/contract wording quality and ADR-style decision capture",
|
|
281
|
-
"- `.cclaw/skills/learnings/SKILL.md` — to preserve acceptance criteria traps and edge-case learnings"
|
|
282
|
-
],
|
|
283
|
-
plan: [
|
|
284
|
-
"- `.cclaw/skills/subagent-dev/SKILL.md` — for specialist delegation prompts by task slice",
|
|
285
|
-
"- `.cclaw/skills/parallel-dispatch/SKILL.md` — for multi-agent review planning and reconciliation setup"
|
|
286
|
-
],
|
|
287
|
-
tdd: [
|
|
288
|
-
"- `.cclaw/skills/debugging/SKILL.md` — when RED behavior is unclear, flakes appear, or implementation fails tests",
|
|
289
|
-
"- `.cclaw/skills/subagent-dev/SKILL.md` — for machine-only test-slice delegation",
|
|
290
|
-
"- `.cclaw/skills/performance/SKILL.md` — when implementation choices impact latency/throughput"
|
|
291
|
-
],
|
|
292
|
-
review: [
|
|
293
|
-
"- `.cclaw/skills/security/SKILL.md` — mandatory lens for exploitable risk detection",
|
|
294
|
-
"- `.cclaw/skills/parallel-dispatch/SKILL.md` — for review-army dispatch and reconciliation discipline"
|
|
295
|
-
],
|
|
296
|
-
ship: [
|
|
297
|
-
"- `.cclaw/skills/ci-cd/SKILL.md` — for release gates, pipeline health, and deployment guardrails",
|
|
298
|
-
"- `.cclaw/skills/docs/SKILL.md` — for release docs, migration notes, and ADR/public API updates"
|
|
299
|
-
]
|
|
300
|
-
};
|
|
301
|
-
return `## Progressive Disclosure
|
|
302
|
-
|
|
303
|
-
### Depth
|
|
304
|
-
- Primary stage procedure (this file): \`.cclaw/skills/${schema.skillFolder}/SKILL.md\`
|
|
305
|
-
- Orchestrator contract (gate language and handoff): \`.cclaw/commands/${stage}.md\`
|
|
306
|
-
- Artifact structure baseline: \`.cclaw/templates/${schema.artifactFile}\`
|
|
307
|
-
- Runtime state truth source: \`.cclaw/state/flow-state.json\` + \`.cclaw/artifacts/\` + \`.cclaw/knowledge.jsonl\`
|
|
308
|
-
|
|
309
|
-
### See also
|
|
310
|
-
- Meta routing and activation rules: \`.cclaw/skills/using-cclaw/SKILL.md\`
|
|
311
|
-
- Session continuity and checkpoint behavior: \`.cclaw/skills/session/SKILL.md\`
|
|
312
|
-
${stageSpecificRefs[stage].join("\n")}
|
|
313
|
-
- Progression command: \`/cc-next\` (reads flow-state, loads the next stage)
|
|
314
|
-
`;
|
|
315
|
-
}
|
|
316
|
-
function verificationBlock(stage) {
|
|
317
|
-
if (!VERIFICATION_STAGES.includes(stage))
|
|
318
|
-
return "";
|
|
319
|
-
return `## Verification Before Completion
|
|
320
|
-
|
|
321
|
-
**Iron law:** Do not claim this stage is complete without fresh verification evidence from THIS message.
|
|
322
|
-
|
|
323
|
-
### Gate Function
|
|
324
|
-
For every completion claim, follow this sequence:
|
|
325
|
-
1. **Identify** the verification command (test suite, build, lint, type-check).
|
|
326
|
-
2. **Run** the full command — not a subset, not a cached result.
|
|
327
|
-
3. **Read** the complete output — do not summarize without reading.
|
|
328
|
-
4. **Verify** the output matches the expected success state.
|
|
329
|
-
5. **Only then** make the completion claim with the evidence.
|
|
330
|
-
|
|
331
|
-
### Evidence Requirements
|
|
332
|
-
| Claim | Requires | NOT Sufficient |
|
|
333
|
-
|---|---|---|
|
|
334
|
-
| "Tests pass" | Fresh test run output showing all pass | "I believe tests pass" or prior run |
|
|
335
|
-
| "Build succeeds" | Fresh build output with exit code 0 | "Should build fine" |
|
|
336
|
-
| "No lint errors" | Fresh linter output | "I didn't introduce any" |
|
|
337
|
-
| "Bug is fixed" | Regression test: remove fix → fails, restore → passes | "The fix looks correct" |
|
|
338
|
-
|
|
339
|
-
### Forbidden Language
|
|
340
|
-
Do not use these phrases before verification:
|
|
341
|
-
- "Everything works," "All good," "Done," "Successfully completed"
|
|
342
|
-
- "Should be fine," "I'm confident that," "This will work"
|
|
343
|
-
- "Tests should pass," "The build should succeed"
|
|
344
|
-
|
|
345
|
-
### Regression Test Pattern
|
|
346
|
-
When fixing a bug:
|
|
347
|
-
1. Write a test that reproduces the bug → verify it **fails**.
|
|
348
|
-
2. Apply the fix → verify the test **passes**.
|
|
349
|
-
3. Revert the fix → verify the test **fails again**.
|
|
350
|
-
4. Restore the fix → verify the full suite passes.
|
|
351
|
-
`;
|
|
352
|
-
}
|
|
353
269
|
export function stageSkillFolder(stage) {
|
|
354
270
|
return stageSchema(stage).skillFolder;
|
|
355
271
|
}
|
|
356
|
-
function quickStartBlock(stage) {
|
|
357
|
-
const schema = stageSchema(stage);
|
|
358
|
-
const topGates = schema.requiredGates.slice(0, 3).map((g) => `\`${g.id}\``).join(", ");
|
|
359
|
-
return `## Quick Start (minimum compliance)
|
|
360
|
-
|
|
361
|
-
> **Even if you read nothing else, do these 3 things:**
|
|
362
|
-
> 1. Obey the HARD-GATE below — violating it invalidates the entire stage.
|
|
363
|
-
> 2. Complete every checklist step in order and write the artifact to \`.cclaw/artifacts/${schema.artifactFile}\`.
|
|
364
|
-
> 3. Do not claim completion without satisfying gates: ${topGates}${schema.requiredGates.length > 3 ? ` (+${schema.requiredGates.length - 3} more)` : ""}.
|
|
365
|
-
>
|
|
366
|
-
> **After this stage:** update \`flow-state.json\` and tell the user to run \`/cc-next\`.
|
|
367
|
-
`;
|
|
368
|
-
}
|
|
369
272
|
export function stageSkillMarkdown(stage) {
|
|
370
273
|
const schema = stageSchema(stage);
|
|
371
274
|
const gateList = schema.requiredGates
|
|
@@ -377,6 +280,7 @@ export function stageSkillMarkdown(stage) {
|
|
|
377
280
|
const checklistItems = schema.checklist
|
|
378
281
|
.map((item, i) => `${i + 1}. ${item}`)
|
|
379
282
|
.join("\n");
|
|
283
|
+
const stageRefs = stageSpecificSeeAlso(stage);
|
|
380
284
|
return `---
|
|
381
285
|
name: ${schema.skillName}
|
|
382
286
|
description: "${schema.skillDescription}"
|
|
@@ -393,6 +297,7 @@ If you are about to violate the Iron Law, STOP. No amount of urgency, partial pr
|
|
|
393
297
|
</EXTREMELY-IMPORTANT>
|
|
394
298
|
|
|
395
299
|
${quickStartBlock(stage)}
|
|
300
|
+
|
|
396
301
|
## Overview
|
|
397
302
|
${schema.purpose}
|
|
398
303
|
|
|
@@ -408,6 +313,7 @@ ${schema.requiredContext.length > 0 ? schema.requiredContext.map((item) => `- ${
|
|
|
408
313
|
|
|
409
314
|
${contextLoadingBlock(stage)}
|
|
410
315
|
${autoSubagentDispatchBlock(stage)}
|
|
316
|
+
|
|
411
317
|
## Outputs
|
|
412
318
|
${schema.outputs.map((item) => `- ${item}`).join("\n")}
|
|
413
319
|
|
|
@@ -423,12 +329,12 @@ ${checklistItems}
|
|
|
423
329
|
${stageGoodBadExamples(stage)}
|
|
424
330
|
${stageDomainExamples(stage)}
|
|
425
331
|
${stageExamples(stage)}
|
|
426
|
-
|
|
427
|
-
${cognitivePatternsList(stage)}
|
|
332
|
+
|
|
428
333
|
## Interaction Protocol
|
|
429
334
|
${schema.interactionProtocol.map((item, i) => `${i + 1}. ${item}`).join("\n")}
|
|
430
335
|
|
|
431
|
-
|
|
336
|
+
Shared decision/ask-user protocol:
|
|
337
|
+
\`${DECISION_PROTOCOL_PATH}\`
|
|
432
338
|
|
|
433
339
|
${waveExecutionModeBlock(stage)}
|
|
434
340
|
## Required Gates
|
|
@@ -444,60 +350,24 @@ ${reviewSectionsBlock(stage)}
|
|
|
444
350
|
${verificationBlock(stage)}
|
|
445
351
|
${crossStageTraceBlock(stage)}
|
|
446
352
|
${artifactValidationBlock(stage)}
|
|
447
|
-
${visualCommunicationBlock(stage)}
|
|
448
|
-
${decisionRecordBlock(stage)}
|
|
449
|
-
## Common Rationalizations
|
|
450
|
-
${rationalizationTable(stage)}
|
|
451
353
|
|
|
452
354
|
## Anti-Patterns & Red Flags
|
|
355
|
+
${mergedAntiPatterns(schema)}
|
|
453
356
|
|
|
454
|
-
> One consolidated list of observable failure modes for this stage. Mix of
|
|
455
|
-
> behavioural anti-patterns (things you might do wrong) and red-flag
|
|
456
|
-
> signals (things you might notice going wrong). Dedup-merged so no item
|
|
457
|
-
> appears twice.
|
|
458
|
-
|
|
459
|
-
${(() => {
|
|
460
|
-
const merged = [];
|
|
461
|
-
const seen = new Set();
|
|
462
|
-
for (const item of [...schema.antiPatterns, ...schema.blockers, ...schema.redFlags]) {
|
|
463
|
-
const key = item.trim().toLowerCase();
|
|
464
|
-
if (seen.has(key))
|
|
465
|
-
continue;
|
|
466
|
-
seen.add(key);
|
|
467
|
-
merged.push(item);
|
|
468
|
-
}
|
|
469
|
-
return merged.map((item) => `- ${item}`).join("\n");
|
|
470
|
-
})()}
|
|
471
|
-
|
|
472
|
-
${completionStatusBlock(stage)}
|
|
473
357
|
## Verification
|
|
474
358
|
${schema.exitCriteria.map((item) => `- [ ] ${item}`).join("\n")}
|
|
475
359
|
|
|
476
|
-
${
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
-
|
|
488
|
-
- **B) Revise this stage** — stay on the current stage; apply the user's feedback, then re-ask for handoff.
|
|
489
|
-
- **C) Pause / park** — save state; stop here. Useful when the user wants to share the artifact with a human reviewer before continuing.
|
|
490
|
-
- **D) Rewind** — move to a prior stage (user names which). Use when downstream work revealed that an earlier stage was wrong.
|
|
491
|
-
- **E) Abandon** — mark the flow as cancelled; no further stages will run. Artifacts remain on disk.
|
|
492
|
-
|
|
493
|
-
Recommendation rules:
|
|
494
|
-
- If all required gates are satisfied AND the stage's completion status is \`DONE\`, recommend **A (Advance)**.
|
|
495
|
-
- If completion status is \`DONE_WITH_CONCERNS\`, recommend **B (Revise)** and name the concern.
|
|
496
|
-
- If completion status is \`BLOCKED\`, recommend **B (Revise)** or **C (Pause)** depending on whether the blocker is internal or external.
|
|
497
|
-
|
|
498
|
-
Reference data for the user:
|
|
499
|
-
- Next command: \`/cc-next\` (loads whatever stage is current in flow-state)
|
|
500
|
-
- Required artifact: \`.cclaw/artifacts/${schema.artifactFile}\`
|
|
501
|
-
- Stage stays blocked if any required gate is unsatisfied
|
|
360
|
+
${completionParametersBlock(schema)}
|
|
361
|
+
## Shared Stage Guidance
|
|
362
|
+
See:
|
|
363
|
+
- \`${STAGE_COMMON_GUIDANCE_REL_PATH}\`
|
|
364
|
+
- \`${DECISION_PROTOCOL_PATH}\`
|
|
365
|
+
- \`${COMPLETION_PROTOCOL_PATH}\`
|
|
366
|
+
|
|
367
|
+
## See Also
|
|
368
|
+
- \`${RUNTIME_ROOT}/skills/using-cclaw/SKILL.md\`
|
|
369
|
+
- \`${RUNTIME_ROOT}/skills/session/SKILL.md\`
|
|
370
|
+
${stageRefs.join("\n")}
|
|
371
|
+
- \`${RUNTIME_ROOT}/commands/${stage}.md\`
|
|
502
372
|
`;
|
|
503
373
|
}
|