cclaw-cli 0.15.1 → 0.21.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/artifact-linter.js +154 -0
- package/dist/cli.js +2 -1
- package/dist/constants.d.ts +2 -2
- package/dist/constants.js +4 -3
- package/dist/content/compound-command.d.ts +2 -0
- package/dist/content/compound-command.js +72 -0
- package/dist/content/contracts.js +1 -1
- package/dist/content/doctor-references.js +7 -6
- package/dist/content/feature-command.js +54 -51
- package/dist/content/harnesses-doc.js +5 -3
- package/dist/content/hooks.js +2 -2
- package/dist/content/ideate-command.d.ts +2 -0
- package/dist/content/ideate-command.js +73 -0
- package/dist/content/learnings.d.ts +1 -1
- package/dist/content/learnings.js +22 -5
- package/dist/content/meta-skill.js +6 -3
- package/dist/content/next-command.js +5 -5
- package/dist/content/observe.js +3 -2
- package/dist/content/ops-command.js +4 -4
- package/dist/content/protocols.js +27 -38
- package/dist/content/retro-command.js +2 -1
- package/dist/content/rewind-command.d.ts +0 -1
- package/dist/content/rewind-command.js +19 -33
- package/dist/content/skills.js +14 -8
- package/dist/content/stage-schema.js +3 -38
- package/dist/content/stages/plan.js +16 -5
- package/dist/content/stages/review.js +20 -0
- package/dist/content/stages/scope.js +9 -3
- package/dist/content/stages/ship.js +1 -0
- package/dist/content/stages/tdd.js +5 -4
- package/dist/content/templates.js +105 -9
- package/dist/content/utility-skills.d.ts +3 -1
- package/dist/content/utility-skills.js +91 -1
- package/dist/delegation.d.ts +33 -3
- package/dist/delegation.js +56 -3
- package/dist/doctor.js +269 -88
- package/dist/feature-system.d.ts +22 -5
- package/dist/feature-system.js +267 -126
- package/dist/harness-adapters.js +17 -1
- package/dist/install.js +10 -8
- package/dist/policy.js +13 -4
- package/package.json +1 -1
|
@@ -168,6 +168,26 @@ export const REVIEW = {
|
|
|
168
168
|
],
|
|
169
169
|
stopGate: true
|
|
170
170
|
},
|
|
171
|
+
{
|
|
172
|
+
title: "Specialist Lens: Data & Migration Safety",
|
|
173
|
+
evaluationPoints: [
|
|
174
|
+
"Schema/data migrations are reversible and include backfill/rollback strategy",
|
|
175
|
+
"Idempotency expectations are explicit for retryable flows",
|
|
176
|
+
"Data-loss scenarios (truncate/overwrite/drop) are guarded by checks or dry-runs",
|
|
177
|
+
"Boundary contracts (API/schema/event payload) maintain backward compatibility or are versioned"
|
|
178
|
+
],
|
|
179
|
+
stopGate: false
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
title: "Specialist Lens: Developer Experience",
|
|
183
|
+
evaluationPoints: [
|
|
184
|
+
"New behavior includes discoverable docs/usage notes where needed",
|
|
185
|
+
"Error messages are actionable for on-call and local debugging",
|
|
186
|
+
"Default configuration remains safe and unsurprising",
|
|
187
|
+
"Change footprint stays minimal and avoids hidden coupling"
|
|
188
|
+
],
|
|
189
|
+
stopGate: false
|
|
190
|
+
},
|
|
171
191
|
{
|
|
172
192
|
title: "Meta-Review: Verify the Verification",
|
|
173
193
|
evaluationPoints: [
|
|
@@ -50,6 +50,7 @@ export const SCOPE = {
|
|
|
50
50
|
"Run mode-specific analysis that matches the selected scope mode.",
|
|
51
51
|
"Walk through scope review sections one at a time.",
|
|
52
52
|
"Write explicit scope contract, discretion areas, and deferred items.",
|
|
53
|
+
"Freeze non-negotiable boundaries as stable Locked Decisions (D-XX IDs).",
|
|
53
54
|
"Produce scope summary plus completion dashboard (checklist findings, number of resolved decisions, unresolved items or `None`)."
|
|
54
55
|
],
|
|
55
56
|
requiredGates: [
|
|
@@ -65,6 +66,7 @@ export const SCOPE = {
|
|
|
65
66
|
"In-scope and out-of-scope lists are explicit.",
|
|
66
67
|
"Discretion areas are explicit (or marked as `None`).",
|
|
67
68
|
"Selected mode and rationale are documented.",
|
|
69
|
+
"Locked Decisions section lists stable D-XX IDs for non-negotiable boundaries.",
|
|
68
70
|
"Premise challenge findings documented.",
|
|
69
71
|
"Deferred items list with one-line rationale for each.",
|
|
70
72
|
"Completion dashboard lists checklist findings, decision count, and unresolved items (or `None`)."
|
|
@@ -90,6 +92,7 @@ export const SCOPE = {
|
|
|
90
92
|
"discretion areas recorded explicitly",
|
|
91
93
|
"required gates marked satisfied",
|
|
92
94
|
"deferred list recorded explicitly",
|
|
95
|
+
"locked decisions captured with stable D-XX IDs",
|
|
93
96
|
"completion dashboard produced",
|
|
94
97
|
"scope summary produced"
|
|
95
98
|
],
|
|
@@ -100,7 +103,8 @@ export const SCOPE = {
|
|
|
100
103
|
"Sycophantic agreement without evidence-based pushback",
|
|
101
104
|
"Hedged recommendations that avoid taking a position",
|
|
102
105
|
"Batching multiple scope issues into one question",
|
|
103
|
-
"Re-arguing for smaller scope after user rejects reduction"
|
|
106
|
+
"Re-arguing for smaller scope after user rejects reduction",
|
|
107
|
+
"Using scope-reduction placeholders (`v1`, `for now`, `we can do later`) instead of explicit user-approved boundaries"
|
|
104
108
|
],
|
|
105
109
|
redFlags: [
|
|
106
110
|
"No selected mode in artifact",
|
|
@@ -109,9 +113,10 @@ export const SCOPE = {
|
|
|
109
113
|
"No deferred/not-in-scope section",
|
|
110
114
|
"No user approval marker",
|
|
111
115
|
"Premise challenge missing or superficial",
|
|
112
|
-
"No implementation alternatives evaluated"
|
|
116
|
+
"No implementation alternatives evaluated",
|
|
117
|
+
"Missing Locked Decisions section or decisions without D-XX IDs"
|
|
113
118
|
],
|
|
114
|
-
policyNeedles: ["Scope mode", "In Scope", "Out of Scope", "Discretion Areas", "NOT in scope", "Premise Challenge"],
|
|
119
|
+
policyNeedles: ["Scope mode", "In Scope", "Out of Scope", "Discretion Areas", "NOT in scope", "Premise Challenge", "Locked Decisions"],
|
|
115
120
|
artifactFile: "02-scope.md",
|
|
116
121
|
next: "design",
|
|
117
122
|
reviewSections: [
|
|
@@ -173,6 +178,7 @@ export const SCOPE = {
|
|
|
173
178
|
{ section: "Prime Directives", required: true, validationRule: "For each scoped capability: named failure modes, explicit error surface, four data-flow paths, interaction edge cases, observability expectations, and deferred-item handling." },
|
|
174
179
|
{ section: "Premise Challenge", required: true, validationRule: "Must contain explicit answers to: right problem? direct path? what if nothing?" },
|
|
175
180
|
{ section: "Requirements", required: true, validationRule: "Table of stable requirement IDs (R1, R2, R3…) one per row with observable outcome, priority, and source. IDs are assigned once and never renumbered across scope/design/spec/plan/review; dropped requirements stay with Priority `DROPPED`." },
|
|
181
|
+
{ section: "Locked Decisions (D-XX)", required: false, validationRule: "List of stable locked decisions with IDs D-01, D-02... Each ID appears once, includes rationale, and is intended for downstream cross-stage traceability." },
|
|
176
182
|
{ section: "Implementation Alternatives", required: true, validationRule: "2-3 options with Name, Summary, Effort, Risk, Pros, Cons, and Reuses. Must include minimal viable and ideal architecture options." },
|
|
177
183
|
{ section: "Scope Mode", required: true, validationRule: "Must state selected mode and rationale with default heuristic justification." },
|
|
178
184
|
{ section: "Mode-Specific Analysis", required: true, validationRule: "Must document the analysis matching the selected scope mode: EXPAND (10x and delight opportunities), SELECTIVE (hold-scope baseline then cherry-picked expansions), HOLD (minimum-change-set hardening), REDUCE (ruthless cuts and follow-up split)." },
|
|
@@ -26,6 +26,7 @@ export const SHIP = {
|
|
|
26
26
|
"Re-run tests on merged result — if merging locally, run the full test suite AFTER the merge, not just before. Post-merge failures are common.",
|
|
27
27
|
"Generate release notes — summarize what changed, why, and what it affects. Reference spec criteria. Include: breaking changes, new dependencies, migration steps if any.",
|
|
28
28
|
"Write rollback plan — trigger conditions (what tells you it is broken), rollback steps (exact commands/git operations), and verification (how to confirm rollback worked).",
|
|
29
|
+
"Load utility skills — `verification-before-completion` for fresh evidence and `finishing-a-development-branch` for finalization workflow.",
|
|
29
30
|
"Monitoring checklist — what should be watched after deploy? Error rates, latency, key business metrics. If no monitoring exists, flag it as a risk.",
|
|
30
31
|
"Select finalization mode — exactly ONE enum: (A) FINALIZE_MERGE_LOCAL, (B) FINALIZE_OPEN_PR, (C) FINALIZE_KEEP_BRANCH, (D) FINALIZE_DISCARD_BRANCH. For discard: list what will be deleted, require typed confirmation.",
|
|
31
32
|
"Execute finalization — perform the selected action. For merge: verify clean merge. For PR: include structured body (summary, test plan, rollback). For discard: verify deletion.",
|
|
@@ -22,9 +22,9 @@ export const TDD = {
|
|
|
22
22
|
checklist: [
|
|
23
23
|
"Select plan slice — pick one task from the plan. Do not batch multiple tasks.",
|
|
24
24
|
"Map to acceptance criterion — identify the specific spec criterion this test proves.",
|
|
25
|
-
"
|
|
25
|
+
"Dispatch mandatory `test-author` subagent in `TEST_RED_ONLY` mode — produce failing behavior tests and RED evidence only (no production edits).",
|
|
26
26
|
"RED: Capture failure output — copy the exact failure output as RED evidence. Record in artifact.",
|
|
27
|
-
"
|
|
27
|
+
"Dispatch `test-author` subagent in `BUILD_GREEN_REFACTOR` mode — minimal implementation + full-suite GREEN + refactor notes.",
|
|
28
28
|
"GREEN: Run full suite — execute ALL tests, not just the ones you wrote. The full suite must be GREEN.",
|
|
29
29
|
"GREEN: Verify no regressions — if any existing test breaks, fix the regression before proceeding.",
|
|
30
30
|
"REFACTOR: Improve code quality — without changing behavior. Document what you changed and why.",
|
|
@@ -34,6 +34,7 @@ export const TDD = {
|
|
|
34
34
|
],
|
|
35
35
|
interactionProtocol: [
|
|
36
36
|
"Pick one planned slice at a time.",
|
|
37
|
+
"Controller owns orchestration; execution runs through the mandatory `test-author` delegation for RED then GREEN/REFACTOR modes.",
|
|
37
38
|
"Write behavior-focused tests before changing implementation (RED).",
|
|
38
39
|
"Capture and store failing output as RED evidence.",
|
|
39
40
|
"Apply minimal change to satisfy RED tests (GREEN).",
|
|
@@ -44,9 +45,9 @@ export const TDD = {
|
|
|
44
45
|
],
|
|
45
46
|
process: [
|
|
46
47
|
"Select slice and map to acceptance criterion.",
|
|
47
|
-
"
|
|
48
|
+
"Dispatch `test-author` in TEST_RED_ONLY mode and produce failing test(s) for expected reason (RED).",
|
|
48
49
|
"Run tests and capture failure output.",
|
|
49
|
-
"
|
|
50
|
+
"Dispatch `test-author` in BUILD_GREEN_REFACTOR mode and implement smallest change needed for GREEN.",
|
|
50
51
|
"Run full tests and build checks.",
|
|
51
52
|
"Perform refactor pass preserving behavior.",
|
|
52
53
|
"Record RED, GREEN, and REFACTOR evidence in artifact.",
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { COMMAND_FILE_ORDER } from "../constants.js";
|
|
2
2
|
import { orderedStageSchemas } from "./stage-schema.js";
|
|
3
3
|
export const ARTIFACT_TEMPLATES = {
|
|
4
|
-
"01-brainstorm.md":
|
|
4
|
+
"01-brainstorm.md": `---
|
|
5
|
+
stage: brainstorm
|
|
6
|
+
schema_version: 1
|
|
7
|
+
version: 0.18.0
|
|
8
|
+
feature: <feature-id>
|
|
9
|
+
locked_decisions: []
|
|
10
|
+
inputs_hash: sha256:pending
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Brainstorm Artifact
|
|
5
14
|
|
|
6
15
|
## Context
|
|
7
16
|
- **Project state:**
|
|
@@ -37,7 +46,16 @@ export const ARTIFACT_TEMPLATES = {
|
|
|
37
46
|
- **Assumptions:**
|
|
38
47
|
- **Open questions (or "None"):**
|
|
39
48
|
`,
|
|
40
|
-
"02-scope.md":
|
|
49
|
+
"02-scope.md": `---
|
|
50
|
+
stage: scope
|
|
51
|
+
schema_version: 1
|
|
52
|
+
version: 0.18.0
|
|
53
|
+
feature: <feature-id>
|
|
54
|
+
locked_decisions: []
|
|
55
|
+
inputs_hash: sha256:pending
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
# Scope Artifact
|
|
41
59
|
|
|
42
60
|
## Prime Directives
|
|
43
61
|
- Zero silent failures:
|
|
@@ -94,6 +112,11 @@ export const ARTIFACT_TEMPLATES = {
|
|
|
94
112
|
> is later dropped, keep the row and mark Priority \`DROPPED\`; if a new one is
|
|
95
113
|
> added mid-flow, append with the next free R-number — do NOT reuse numbers.
|
|
96
114
|
|
|
115
|
+
## Locked Decisions (D-XX)
|
|
116
|
+
| Decision ID | Decision | Why locked now | Downstream impact |
|
|
117
|
+
|---|---|---|---|
|
|
118
|
+
| D-01 | | | |
|
|
119
|
+
|
|
97
120
|
## In Scope / Out of Scope
|
|
98
121
|
|
|
99
122
|
### In Scope
|
|
@@ -126,7 +149,16 @@ export const ARTIFACT_TEMPLATES = {
|
|
|
126
149
|
- Deferred:
|
|
127
150
|
- Explicitly excluded:
|
|
128
151
|
`,
|
|
129
|
-
"03-design.md":
|
|
152
|
+
"03-design.md": `---
|
|
153
|
+
stage: design
|
|
154
|
+
schema_version: 1
|
|
155
|
+
version: 0.18.0
|
|
156
|
+
feature: <feature-id>
|
|
157
|
+
locked_decisions: []
|
|
158
|
+
inputs_hash: sha256:pending
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
# Design Artifact
|
|
130
162
|
|
|
131
163
|
## Codebase Investigation
|
|
132
164
|
| File | Current responsibility | Patterns discovered |
|
|
@@ -210,7 +242,16 @@ export const ARTIFACT_TEMPLATES = {
|
|
|
210
242
|
|
|
211
243
|
**Decisions made:** 0 | **Unresolved:** 0
|
|
212
244
|
`,
|
|
213
|
-
"04-spec.md":
|
|
245
|
+
"04-spec.md": `---
|
|
246
|
+
stage: spec
|
|
247
|
+
schema_version: 1
|
|
248
|
+
version: 0.18.0
|
|
249
|
+
feature: <feature-id>
|
|
250
|
+
locked_decisions: []
|
|
251
|
+
inputs_hash: sha256:pending
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
# Specification Artifact
|
|
214
255
|
|
|
215
256
|
## Acceptance Criteria
|
|
216
257
|
| ID | Requirement Ref (R#) | Criterion (observable/measurable/falsifiable) | Design Decision Ref |
|
|
@@ -254,7 +295,16 @@ export const ARTIFACT_TEMPLATES = {
|
|
|
254
295
|
- Approved by:
|
|
255
296
|
- Date:
|
|
256
297
|
`,
|
|
257
|
-
"05-plan.md":
|
|
298
|
+
"05-plan.md": `---
|
|
299
|
+
stage: plan
|
|
300
|
+
schema_version: 1
|
|
301
|
+
version: 0.18.0
|
|
302
|
+
feature: <feature-id>
|
|
303
|
+
locked_decisions: []
|
|
304
|
+
inputs_hash: sha256:pending
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
# Plan Artifact
|
|
258
308
|
|
|
259
309
|
## Dependency Graph
|
|
260
310
|
-
|
|
@@ -282,6 +332,7 @@ Execution rule: complete and verify each wave before starting the next wave.
|
|
|
282
332
|
**Rules (apply before writing rows):**
|
|
283
333
|
- Every task fits the **2-5 minute budget**. If \`[~Nm]\` is >5, split the task.
|
|
284
334
|
- **No placeholders.** Forbidden tokens anywhere in this table: \`TODO\`, \`TBD\`, \`FIXME\`, \`<fill-in>\`, \`<your-*-here>\`, \`xxx\`, bare ellipsis. Every file path, test, and verification command must be copy-pasteable as written.
|
|
335
|
+
- **No silent scope reduction.** Forbidden phrasing when locked decisions exist: \`v1\`, \`for now\`, \`later\`, \`temporary\`, \`placeholder\`, \`mock for now\`, \`hardcoded for now\`, \`will improve later\`.
|
|
285
336
|
- If an estimate is genuinely uncertain (new library, unfamiliar subsystem), add a **spike task in wave 0** to de-risk — do NOT hide the uncertainty inside a large estimate.
|
|
286
337
|
|
|
287
338
|
| Task ID | Description | Acceptance criterion | Verification command | Effort (S/M/L) | Minutes |
|
|
@@ -293,6 +344,11 @@ Execution rule: complete and verify each wave before starting the next wave.
|
|
|
293
344
|
|---|---|
|
|
294
345
|
| AC-1 | T-1 |
|
|
295
346
|
|
|
347
|
+
## Locked Decision Coverage
|
|
348
|
+
| Decision ID | Source section | Plan tasks implementing decision | Status |
|
|
349
|
+
|---|---|---|---|
|
|
350
|
+
| D-01 | 02-scope.md > Locked Decisions | T-1 | covered |
|
|
351
|
+
|
|
296
352
|
## Risk Assessment
|
|
297
353
|
| Task/Wave | Risk | Likelihood | Impact | Mitigation |
|
|
298
354
|
|---|---|---|---|---|
|
|
@@ -307,11 +363,24 @@ Execution rule: complete and verify each wave before starting the next wave.
|
|
|
307
363
|
- Scanned tokens: \`TODO\`, \`TBD\`, \`FIXME\`, \`<fill-in>\`, \`<your-*-here>\`, \`xxx\`, bare ellipsis in task rows.
|
|
308
364
|
- Hits: 0 (required for WAIT_FOR_CONFIRM to resolve).
|
|
309
365
|
|
|
366
|
+
## No Scope Reduction Language Scan
|
|
367
|
+
- Scanned phrases: \`v1\`, \`for now\`, \`later\`, \`temporary\`, \`placeholder\`, \`mock for now\`, \`hardcoded for now\`, \`will improve later\`.
|
|
368
|
+
- Hits: 0 (required when Locked Decisions section is non-empty).
|
|
369
|
+
|
|
310
370
|
## WAIT_FOR_CONFIRM
|
|
311
371
|
- Status: pending
|
|
312
372
|
- Confirmed by:
|
|
313
373
|
`,
|
|
314
|
-
"06-tdd.md":
|
|
374
|
+
"06-tdd.md": `---
|
|
375
|
+
stage: tdd
|
|
376
|
+
schema_version: 1
|
|
377
|
+
version: 0.18.0
|
|
378
|
+
feature: <feature-id>
|
|
379
|
+
locked_decisions: []
|
|
380
|
+
inputs_hash: sha256:pending
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
# TDD Artifact
|
|
315
384
|
|
|
316
385
|
## RED Evidence
|
|
317
386
|
| Slice | Test name | Command | Failure output summary |
|
|
@@ -366,7 +435,16 @@ Execution rule: complete and verify each wave before starting the next wave.
|
|
|
366
435
|
|---|---|---|---|---|
|
|
367
436
|
| S-1 | | | | |
|
|
368
437
|
`,
|
|
369
|
-
"07-review.md":
|
|
438
|
+
"07-review.md": `---
|
|
439
|
+
stage: review
|
|
440
|
+
schema_version: 1
|
|
441
|
+
version: 0.18.0
|
|
442
|
+
feature: <feature-id>
|
|
443
|
+
locked_decisions: []
|
|
444
|
+
inputs_hash: sha256:pending
|
|
445
|
+
---
|
|
446
|
+
|
|
447
|
+
# Review Artifact
|
|
370
448
|
|
|
371
449
|
## Layer 1 Verdict
|
|
372
450
|
| Criterion | Verdict | Evidence |
|
|
@@ -444,7 +522,16 @@ Execution rule: complete and verify each wave before starting the next wave.
|
|
|
444
522
|
}
|
|
445
523
|
}
|
|
446
524
|
`,
|
|
447
|
-
"08-ship.md":
|
|
525
|
+
"08-ship.md": `---
|
|
526
|
+
stage: ship
|
|
527
|
+
schema_version: 1
|
|
528
|
+
version: 0.18.0
|
|
529
|
+
feature: <feature-id>
|
|
530
|
+
locked_decisions: []
|
|
531
|
+
inputs_hash: sha256:pending
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
# Ship Artifact
|
|
448
535
|
|
|
449
536
|
## Preflight Results
|
|
450
537
|
- Review verdict:
|
|
@@ -485,7 +572,16 @@ Execution rule: complete and verify each wave before starting the next wave.
|
|
|
485
572
|
- Retro artifact path: \`.cclaw/artifacts/09-retro.md\`
|
|
486
573
|
- Archive remains blocked until retro gate is complete.
|
|
487
574
|
`,
|
|
488
|
-
"09-retro.md":
|
|
575
|
+
"09-retro.md": `---
|
|
576
|
+
stage: retro
|
|
577
|
+
schema_version: 1
|
|
578
|
+
version: 0.18.0
|
|
579
|
+
feature: <feature-id>
|
|
580
|
+
locked_decisions: []
|
|
581
|
+
inputs_hash: sha256:pending
|
|
582
|
+
---
|
|
583
|
+
|
|
584
|
+
# Retro Artifact
|
|
489
585
|
|
|
490
586
|
## Run Summary
|
|
491
587
|
- Flow track:
|
|
@@ -10,6 +10,8 @@ export declare function ciCdSkill(): string;
|
|
|
10
10
|
export declare function docsSkill(): string;
|
|
11
11
|
export declare function executingPlansSkill(): string;
|
|
12
12
|
export declare function contextEngineeringSkill(): string;
|
|
13
|
+
export declare function verificationBeforeCompletionSkill(): string;
|
|
14
|
+
export declare function finishingDevelopmentBranchSkill(): string;
|
|
13
15
|
export declare function sourceDrivenDevelopmentSkill(): string;
|
|
14
16
|
export declare function frontendAccessibilitySkill(): string;
|
|
15
17
|
export declare function landscapeCheckSkill(): string;
|
|
@@ -44,5 +46,5 @@ export declare const LANGUAGE_RULE_PACK_GENERATORS: Record<string, () => string>
|
|
|
44
46
|
* clean them up after the move to `.cclaw/rules/lang/`.
|
|
45
47
|
*/
|
|
46
48
|
export declare const LEGACY_LANGUAGE_RULE_PACK_FOLDERS: readonly ["language-typescript", "language-python", "language-go"];
|
|
47
|
-
export declare const UTILITY_SKILL_FOLDERS: readonly ["security", "debugging", "performance", "ci-cd", "docs", "executing-plans", "context-engineering", "source-driven-development", "frontend-accessibility", "landscape-check", "adversarial-review", "security-audit", "knowledge-curation", "retrospective", "document-review"];
|
|
49
|
+
export declare const UTILITY_SKILL_FOLDERS: readonly ["security", "debugging", "performance", "ci-cd", "docs", "executing-plans", "verification-before-completion", "finishing-a-development-branch", "context-engineering", "source-driven-development", "frontend-accessibility", "landscape-check", "adversarial-review", "security-audit", "knowledge-curation", "retrospective", "document-review"];
|
|
48
50
|
export declare const UTILITY_SKILL_MAP: Record<string, () => string>;
|
|
@@ -594,6 +594,92 @@ Modes are stored in \`.cclaw/contexts/\`:
|
|
|
594
594
|
- Shipping decisions based on stale pre-compaction context.
|
|
595
595
|
`;
|
|
596
596
|
}
|
|
597
|
+
export function verificationBeforeCompletionSkill() {
|
|
598
|
+
return `---
|
|
599
|
+
name: verification-before-completion
|
|
600
|
+
description: "Final verification discipline before stage closeout or ship. Use when preparing a completion claim."
|
|
601
|
+
---
|
|
602
|
+
|
|
603
|
+
# Verification Before Completion
|
|
604
|
+
|
|
605
|
+
## Announce at start
|
|
606
|
+
|
|
607
|
+
"Using verification-before-completion to validate fresh evidence before completion."
|
|
608
|
+
|
|
609
|
+
## HARD-GATE
|
|
610
|
+
|
|
611
|
+
Do not claim completion from memory. Every pass claim requires fresh, in-turn evidence.
|
|
612
|
+
|
|
613
|
+
## Protocol
|
|
614
|
+
|
|
615
|
+
1. Identify changed scope (files, modules, user-facing behaviors).
|
|
616
|
+
2. Run the smallest command set that still proves the scope:
|
|
617
|
+
- tests for changed area
|
|
618
|
+
- typecheck/build/lint if the stack requires it
|
|
619
|
+
3. Capture exact command + pass/fail output in the artifact.
|
|
620
|
+
4. If this is a bug fix, include RED -> GREEN regression evidence.
|
|
621
|
+
5. If any check fails, stop completion and return to fix loop.
|
|
622
|
+
|
|
623
|
+
## Completion claim checklist
|
|
624
|
+
|
|
625
|
+
- [ ] Commands were run in this turn (not reused from earlier output).
|
|
626
|
+
- [ ] Output corresponds to the actual changed scope.
|
|
627
|
+
- [ ] Failures (if any) are resolved or explicitly escalated.
|
|
628
|
+
- [ ] Artifact includes evidence references.
|
|
629
|
+
- [ ] Completion status reflects evidence (DONE / DONE_WITH_CONCERNS / BLOCKED).
|
|
630
|
+
|
|
631
|
+
## Anti-patterns
|
|
632
|
+
|
|
633
|
+
- "Tests passed earlier today" without rerunning.
|
|
634
|
+
- Reporting only "PASS" without command context.
|
|
635
|
+
- Running unrelated checks while skipping changed scope checks.
|
|
636
|
+
- Marking DONE while blockers still fail.
|
|
637
|
+
`;
|
|
638
|
+
}
|
|
639
|
+
export function finishingDevelopmentBranchSkill() {
|
|
640
|
+
return `---
|
|
641
|
+
name: finishing-a-development-branch
|
|
642
|
+
description: "Finalize implementation branch after review: verify, choose integration mode, execute safely, and clean up."
|
|
643
|
+
---
|
|
644
|
+
|
|
645
|
+
# Finishing a Development Branch
|
|
646
|
+
|
|
647
|
+
## Announce at start
|
|
648
|
+
|
|
649
|
+
"Using finishing-a-development-branch to complete this branch safely."
|
|
650
|
+
|
|
651
|
+
## HARD-GATE
|
|
652
|
+
|
|
653
|
+
Do not merge, open PR, or discard branch until verification and rollback notes are explicit.
|
|
654
|
+
|
|
655
|
+
## Protocol
|
|
656
|
+
|
|
657
|
+
1. Verify readiness:
|
|
658
|
+
- review verdict is APPROVED or APPROVED_WITH_CONCERNS
|
|
659
|
+
- verification-before-completion checklist is satisfied
|
|
660
|
+
2. Choose one finalization mode:
|
|
661
|
+
- FINALIZE_MERGE_LOCAL
|
|
662
|
+
- FINALIZE_OPEN_PR
|
|
663
|
+
- FINALIZE_KEEP_BRANCH
|
|
664
|
+
- FINALIZE_DISCARD_BRANCH
|
|
665
|
+
3. Execute only the chosen mode and record exact result.
|
|
666
|
+
4. If merge or discard happened in a feature worktree, clean the worktree.
|
|
667
|
+
5. Update ship artifact with release notes, rollback, and finalization evidence.
|
|
668
|
+
|
|
669
|
+
## Rollback minimum
|
|
670
|
+
|
|
671
|
+
- Trigger: what tells us release is wrong.
|
|
672
|
+
- Steps: exact revert/reset/rollback commands.
|
|
673
|
+
- Verification: how we confirm rollback worked.
|
|
674
|
+
|
|
675
|
+
## Anti-patterns
|
|
676
|
+
|
|
677
|
+
- Multiple finalization modes in one run.
|
|
678
|
+
- Merge without rollback section.
|
|
679
|
+
- PR without test/verification summary.
|
|
680
|
+
- Discarding branch without explicit user confirmation.
|
|
681
|
+
`;
|
|
682
|
+
}
|
|
597
683
|
export function sourceDrivenDevelopmentSkill() {
|
|
598
684
|
return `---
|
|
599
685
|
name: source-driven-development
|
|
@@ -1271,7 +1357,7 @@ For each lens, write either a knowledge entry **or** the explicit string
|
|
|
1271
1357
|
## Output protocol
|
|
1272
1358
|
|
|
1273
1359
|
For every harvested insight, append one strict-schema JSON line to
|
|
1274
|
-
\`.cclaw/knowledge.jsonl\` (fields: \`type, trigger, action, confidence, domain, stage, created, project\`).
|
|
1360
|
+
\`.cclaw/knowledge.jsonl\` (fields: \`type, trigger, action, confidence, domain, stage, origin_stage, origin_feature, frequency, universality, maturity, created, first_seen_ts, last_seen_ts, project\`).
|
|
1275
1361
|
See the \`learnings\` skill for the canonical shape. Choose \`type\`:
|
|
1276
1362
|
|
|
1277
1363
|
- \`compound\` for process/speed accelerators.
|
|
@@ -1524,6 +1610,8 @@ export const UTILITY_SKILL_FOLDERS = [
|
|
|
1524
1610
|
"ci-cd",
|
|
1525
1611
|
"docs",
|
|
1526
1612
|
"executing-plans",
|
|
1613
|
+
"verification-before-completion",
|
|
1614
|
+
"finishing-a-development-branch",
|
|
1527
1615
|
"context-engineering",
|
|
1528
1616
|
"source-driven-development",
|
|
1529
1617
|
"frontend-accessibility",
|
|
@@ -1541,6 +1629,8 @@ export const UTILITY_SKILL_MAP = {
|
|
|
1541
1629
|
"ci-cd": ciCdSkill,
|
|
1542
1630
|
docs: docsSkill,
|
|
1543
1631
|
"executing-plans": executingPlansSkill,
|
|
1632
|
+
"verification-before-completion": verificationBeforeCompletionSkill,
|
|
1633
|
+
"finishing-a-development-branch": finishingDevelopmentBranchSkill,
|
|
1544
1634
|
"context-engineering": contextEngineeringSkill,
|
|
1545
1635
|
"source-driven-development": sourceDrivenDevelopmentSkill,
|
|
1546
1636
|
"frontend-accessibility": frontendAccessibilitySkill,
|
package/dist/delegation.d.ts
CHANGED
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
import type { FlowStage } from "./types.js";
|
|
2
|
+
export type DelegationMode = "mandatory" | "proactive" | "conditional";
|
|
3
|
+
export type DelegationStatus = "scheduled" | "completed" | "failed" | "waived";
|
|
4
|
+
export interface DelegationTokenUsage {
|
|
5
|
+
input: number;
|
|
6
|
+
output: number;
|
|
7
|
+
model: string;
|
|
8
|
+
}
|
|
2
9
|
export type DelegationEntry = {
|
|
3
10
|
stage: string;
|
|
4
11
|
agent: string;
|
|
5
|
-
mode:
|
|
6
|
-
status:
|
|
12
|
+
mode: DelegationMode;
|
|
13
|
+
status: DelegationStatus;
|
|
14
|
+
/**
|
|
15
|
+
* Span identifier for this delegation unit. Multiple status transitions for
|
|
16
|
+
* the same delegated unit should reuse the same spanId.
|
|
17
|
+
*/
|
|
18
|
+
spanId?: string;
|
|
19
|
+
/** Parent span id when this delegation was spawned from another span. */
|
|
20
|
+
parentSpanId?: string;
|
|
21
|
+
/** ISO timestamp when the delegation span started. */
|
|
22
|
+
startTs?: string;
|
|
23
|
+
/** ISO timestamp when the delegation span ended (for terminal statuses). */
|
|
24
|
+
endTs?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Legacy timestamp used by historical ledgers. New writers set both `ts` and
|
|
27
|
+
* `startTs` for backward compatibility.
|
|
28
|
+
*/
|
|
7
29
|
taskId?: string;
|
|
8
30
|
waiverReason?: string;
|
|
9
|
-
ts
|
|
31
|
+
ts?: string;
|
|
10
32
|
/**
|
|
11
33
|
* Run id the entry belongs to. Older ledgers written before 0.5.17 may omit this;
|
|
12
34
|
* consumers treat missing runId as unscoped (conservatively excluded from current-run checks).
|
|
@@ -17,6 +39,14 @@ export type DelegationEntry = {
|
|
|
17
39
|
* Recorded for audit so reviewers can see why the second pass was required.
|
|
18
40
|
*/
|
|
19
41
|
conditionTrigger?: string;
|
|
42
|
+
/** Optional token usage captured from the delegated run. */
|
|
43
|
+
tokens?: DelegationTokenUsage;
|
|
44
|
+
/** Number of retries attempted for this span. */
|
|
45
|
+
retryCount?: number;
|
|
46
|
+
/** Optional references to evidence anchors in artifacts. */
|
|
47
|
+
evidenceRefs?: string[];
|
|
48
|
+
/** Schema version marker for span-compatible delegation logs. */
|
|
49
|
+
schemaVersion?: 1;
|
|
20
50
|
};
|
|
21
51
|
export type DelegationLedger = {
|
|
22
52
|
runId: string;
|
package/dist/delegation.js
CHANGED
|
@@ -12,6 +12,20 @@ function delegationLogPath(projectRoot) {
|
|
|
12
12
|
function delegationLockPath(projectRoot) {
|
|
13
13
|
return path.join(projectRoot, RUNTIME_ROOT, "state", ".delegation.lock");
|
|
14
14
|
}
|
|
15
|
+
function createSpanId() {
|
|
16
|
+
return `dspan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
17
|
+
}
|
|
18
|
+
function isDelegationTokenUsage(value) {
|
|
19
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
20
|
+
return false;
|
|
21
|
+
const o = value;
|
|
22
|
+
return (typeof o.input === "number" &&
|
|
23
|
+
Number.isFinite(o.input) &&
|
|
24
|
+
typeof o.output === "number" &&
|
|
25
|
+
Number.isFinite(o.output) &&
|
|
26
|
+
typeof o.model === "string" &&
|
|
27
|
+
o.model.trim().length > 0);
|
|
28
|
+
}
|
|
15
29
|
function isDelegationEntry(value) {
|
|
16
30
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
17
31
|
return false;
|
|
@@ -21,15 +35,30 @@ function isDelegationEntry(value) {
|
|
|
21
35
|
o.status === "completed" ||
|
|
22
36
|
o.status === "failed" ||
|
|
23
37
|
o.status === "waived";
|
|
38
|
+
const timestampOk = typeof o.ts === "string" ||
|
|
39
|
+
typeof o.startTs === "string";
|
|
40
|
+
const retryOk = o.retryCount === undefined ||
|
|
41
|
+
(typeof o.retryCount === "number" &&
|
|
42
|
+
Number.isFinite(o.retryCount) &&
|
|
43
|
+
Number.isInteger(o.retryCount) &&
|
|
44
|
+
o.retryCount >= 0);
|
|
24
45
|
return (typeof o.stage === "string" &&
|
|
25
46
|
typeof o.agent === "string" &&
|
|
26
47
|
modeOk &&
|
|
27
48
|
statusOk &&
|
|
28
|
-
|
|
49
|
+
timestampOk &&
|
|
50
|
+
(o.spanId === undefined || typeof o.spanId === "string") &&
|
|
51
|
+
(o.parentSpanId === undefined || typeof o.parentSpanId === "string") &&
|
|
52
|
+
(o.startTs === undefined || typeof o.startTs === "string") &&
|
|
53
|
+
(o.endTs === undefined || typeof o.endTs === "string") &&
|
|
29
54
|
(o.taskId === undefined || typeof o.taskId === "string") &&
|
|
30
55
|
(o.waiverReason === undefined || typeof o.waiverReason === "string") &&
|
|
31
56
|
(o.runId === undefined || typeof o.runId === "string") &&
|
|
32
|
-
(o.conditionTrigger === undefined || typeof o.conditionTrigger === "string")
|
|
57
|
+
(o.conditionTrigger === undefined || typeof o.conditionTrigger === "string") &&
|
|
58
|
+
(o.tokens === undefined || isDelegationTokenUsage(o.tokens)) &&
|
|
59
|
+
retryOk &&
|
|
60
|
+
(o.evidenceRefs === undefined || (Array.isArray(o.evidenceRefs) && o.evidenceRefs.every((item) => typeof item === "string"))) &&
|
|
61
|
+
(o.schemaVersion === undefined || o.schemaVersion === 1));
|
|
33
62
|
}
|
|
34
63
|
function parseLedger(raw, runId) {
|
|
35
64
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
@@ -41,7 +70,18 @@ function parseLedger(raw, runId) {
|
|
|
41
70
|
if (Array.isArray(entriesRaw)) {
|
|
42
71
|
for (const item of entriesRaw) {
|
|
43
72
|
if (isDelegationEntry(item)) {
|
|
44
|
-
|
|
73
|
+
const ts = item.startTs ?? item.ts ?? new Date().toISOString();
|
|
74
|
+
entries.push({
|
|
75
|
+
...item,
|
|
76
|
+
spanId: item.spanId ?? createSpanId(),
|
|
77
|
+
startTs: ts,
|
|
78
|
+
ts,
|
|
79
|
+
retryCount: typeof item.retryCount === "number" && Number.isInteger(item.retryCount) && item.retryCount >= 0
|
|
80
|
+
? item.retryCount
|
|
81
|
+
: 0,
|
|
82
|
+
evidenceRefs: Array.isArray(item.evidenceRefs) ? item.evidenceRefs : [],
|
|
83
|
+
schemaVersion: 1
|
|
84
|
+
});
|
|
45
85
|
}
|
|
46
86
|
}
|
|
47
87
|
}
|
|
@@ -67,7 +107,20 @@ export async function appendDelegation(projectRoot, entry) {
|
|
|
67
107
|
await withDirectoryLock(delegationLockPath(projectRoot), async () => {
|
|
68
108
|
const filePath = delegationLogPath(projectRoot);
|
|
69
109
|
const prior = await readDelegationLedger(projectRoot);
|
|
110
|
+
const startTs = entry.startTs ?? entry.ts ?? new Date().toISOString();
|
|
70
111
|
const stamped = { ...entry, runId: entry.runId ?? activeRunId };
|
|
112
|
+
stamped.spanId = entry.spanId ?? createSpanId();
|
|
113
|
+
stamped.startTs = startTs;
|
|
114
|
+
stamped.ts = startTs;
|
|
115
|
+
stamped.schemaVersion = 1;
|
|
116
|
+
if (stamped.retryCount === undefined ||
|
|
117
|
+
!Number.isInteger(stamped.retryCount) ||
|
|
118
|
+
stamped.retryCount < 0) {
|
|
119
|
+
stamped.retryCount = 0;
|
|
120
|
+
}
|
|
121
|
+
if (!Array.isArray(stamped.evidenceRefs)) {
|
|
122
|
+
stamped.evidenceRefs = [];
|
|
123
|
+
}
|
|
71
124
|
const ledger = {
|
|
72
125
|
runId: activeRunId,
|
|
73
126
|
entries: [...prior.entries, stamped]
|