cclaw-cli 6.10.0 → 6.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.
@@ -976,10 +976,14 @@ ${renderBehaviorAnchorTemplateLine("tdd")}
976
976
  - Open questions:
977
977
  - Drift from upstream (or \`None\`):
978
978
 
979
+ <!-- auto-start: slices-index -->
980
+ ## Slices Index
981
+
982
+ _Auto-rendered from \`tdd-slices/S-*.md\` once slice-documenter or controller writes per-slice files. Do not edit by hand._
983
+ <!-- auto-end: slices-index -->
984
+
979
985
  ## Test Discovery
980
- | Slice | Existing tests / helpers / fixtures | Exact command(s) | Pattern to extend |
981
- |---|---|---|---|
982
- | S-1 | | | |
986
+ > Overall narrative for how this stage discovered the existing test surface. Per-slice details live in \`tdd-slices/S-<id>.md\`.
983
987
 
984
988
  ## System-Wide Impact Check
985
989
  | Slice | Callbacks/state/interfaces/contracts affected | Coverage decision |
@@ -987,20 +991,17 @@ ${renderBehaviorAnchorTemplateLine("tdd")}
987
991
  | S-1 | | covered/out-of-scope because |
988
992
 
989
993
  ## RED Evidence
990
- | Slice | Test name | Command | Failure output summary |
991
- |---|---|---|---|
992
- | S-1 | | | |
994
+ > From v6.11.0 the per-slice RED rows are auto-satisfied by \`phase=red\` events in \`delegation-events.jsonl\` (controller dispatches \`test-author --slice S-<id> --phase red\`). Legacy hand-filled tables continue to validate as a fallback. Use \`Evidence: <path>\` or \`Evidence: spanId:<id>\` pointers if you prefer a manual reference.
993
995
 
994
996
  ## Acceptance & Failure Map
995
997
  | Slice | Source ID | AC ID | Expected behavior | RED-link |
996
998
  |---|---|---|---|---|
997
999
  | S-1 | SRC-1 | AC-1 | | |
998
1000
 
999
- > Each slice maps to the active track's source item (plan slice on standard/medium, or the \`Quick Reproduction Contract\` bug slice / spec acceptance item on quick) and to a spec criterion. The RED-link column is satisfied by either a \`spanId:<id>\` from the delegation ledger, an \`<artifacts-dir>/<file>\` evidence pointer, or a \`redOutputRef\` recorded via \`cclaw-cli internal tdd-slice-record\` in the sidecar ledger.
1001
+ > Each slice maps to the active track's source item (plan slice on standard/medium, or the \`Quick Reproduction Contract\` bug slice / spec acceptance item on quick) and to a spec criterion. The RED-link column is satisfied by either a \`spanId:<id>\` from the delegation ledger or an \`<artifacts-dir>/<file>\` evidence pointer. From v6.11.0 the column is auto-derivable: a \`phase=red\` event in \`delegation-events.jsonl\` with non-empty evidenceRefs auto-satisfies the row.
1000
1002
 
1001
1003
  ## GREEN Evidence
1002
- - Full suite command:
1003
- - Full suite result:
1004
+ > From v6.11.0 GREEN rows are auto-satisfied by \`phase=green\` events in \`delegation-events.jsonl\` (controller dispatches \`slice-implementer --slice S-<id> --phase green\`). Legacy hand-filled tables continue to validate as a fallback. Use \`Evidence: <path>\` or \`Evidence: spanId:<id>\` pointers if you prefer a manual reference.
1004
1005
 
1005
1006
  ## REFACTOR Notes
1006
1007
  - What changed:
@@ -1017,19 +1018,11 @@ ${renderBehaviorAnchorTemplateLine("tdd")}
1017
1018
  - Acknowledged: yes — code that landed before its test will be deleted and rewritten from the test.
1018
1019
  - Exceptions invoked (or \`- None.\`):
1019
1020
 
1020
- ## Watched-RED Proof
1021
- > Required for every new test in this stage. Each row proves the test was *observed* failing before any production code was written.
1022
-
1023
- | Slice | Test name | Observed at (ISO ts) | Failure reason snippet | Source command/log |
1024
- |---|---|---|---|---|
1025
- | S-1 | | | | |
1026
-
1021
+ <!-- auto-start: tdd-slice-summary -->
1027
1022
  ## Vertical Slice Cycle
1028
- > Per slice: RED -> GREEN -> REFACTOR within the same cycle (refactor not deferred). The linter checks structural presence of all three phases.
1029
1023
 
1030
- | Slice | RED ts | GREEN ts | REFACTOR ts (or \`deferred because <reason>\`) |
1031
- |---|---|---|---|
1032
- | S-1 | | | |
1024
+ _Auto-rendered from \`delegation-events.jsonl\` once \`test-author\` and \`slice-implementer\` are dispatched with \`--slice <id> --phase red|green|refactor|refactor-deferred\`. Do not edit by hand._
1025
+ <!-- auto-end: tdd-slice-summary -->
1033
1026
 
1034
1027
  ## Assertion Correctness Notes
1035
1028
  > For each new test assertion, name a *plausible subtle bug* that would still pass it (mental mutation test). If you cannot, the assertion is too coarse — strengthen it.
@@ -1623,6 +1616,31 @@ Track-specific skips are allowed only when \`flow-state.track\` + \`skippedStage
1623
1616
  - Preamble budget: keep role/status announcements brief and avoid repeating
1624
1617
  them unless the stage or role changes.
1625
1618
  `;
1619
+ /**
1620
+ * v6.11.0 (S2) — per-slice prose file written by `slice-documenter`
1621
+ * (or the controller) to `<artifacts-dir>/tdd-slices/S-<id>.md`. The
1622
+ * main `06-tdd.md` is auto-indexed via `## Slices Index`.
1623
+ */
1624
+ export function tddSliceFileTemplate(sliceId) {
1625
+ return `# Slice ${sliceId}
1626
+
1627
+ ## Plan unit
1628
+ T-...
1629
+
1630
+ ## Acceptance criteria
1631
+ AC-...
1632
+
1633
+ ## Why this slice
1634
+
1635
+ ## What was tested
1636
+
1637
+ ## What was implemented
1638
+
1639
+ ## REFACTOR notes
1640
+
1641
+ ## Learnings
1642
+ `;
1643
+ }
1626
1644
  export function buildRulesJson() {
1627
1645
  return {
1628
1646
  version: 1,
@@ -140,7 +140,34 @@ export type DelegationEntry = {
140
140
  * `src/content/hooks.ts::delegationRecordScript`.
141
141
  */
142
142
  claimedPaths?: string[];
143
+ /**
144
+ * v6.11.0 (D1) — TDD slice identifier, e.g. `"S-1"`. Recorded by the
145
+ * controller when dispatching `test-author` / `slice-implementer` /
146
+ * `slice-documenter` so the artifact linter can auto-derive the
147
+ * Watched-RED Proof + Vertical Slice Cycle tables from
148
+ * `delegation-events.jsonl` instead of requiring agents to maintain
149
+ * the markdown by hand. Optional: legacy and non-TDD rows omit it.
150
+ *
151
+ * keep in sync with the inline copy in
152
+ * `src/content/hooks.ts::delegationRecordScript`.
153
+ */
154
+ sliceId?: string;
155
+ /**
156
+ * v6.11.0 (D1) — explicit phase tag for TDD slice events. Combined
157
+ * with `sliceId`, the linter validates RED -> GREEN -> REFACTOR
158
+ * monotonicity per slice. `refactor-deferred` requires a rationale
159
+ * either via `--refactor-rationale` (recorded into evidenceRefs[0])
160
+ * or an `evidenceRefs` entry that contains the rationale text.
161
+ * `doc` is reserved for the parallel `slice-documenter` subagent
162
+ * (Phase C). Optional: legacy and non-TDD rows omit it.
163
+ *
164
+ * keep in sync with the inline copy in
165
+ * `src/content/hooks.ts::delegationRecordScript`.
166
+ */
167
+ phase?: "red" | "green" | "refactor" | "refactor-deferred" | "doc";
143
168
  };
169
+ export declare const DELEGATION_PHASES: readonly ["red", "green", "refactor", "refactor-deferred", "doc"];
170
+ export type DelegationPhase = (typeof DELEGATION_PHASES)[number];
144
171
  export declare const DELEGATION_LEDGER_SCHEMA_VERSION: 3;
145
172
  export type DelegationLedger = {
146
173
  runId: string;
@@ -38,6 +38,13 @@ export const DELEGATION_DISPATCH_SURFACE_PATH_PREFIXES = {
38
38
  "role-switch": [],
39
39
  "manual": []
40
40
  };
41
+ export const DELEGATION_PHASES = [
42
+ "red",
43
+ "green",
44
+ "refactor",
45
+ "refactor-deferred",
46
+ "doc"
47
+ ];
41
48
  export const DELEGATION_LEDGER_SCHEMA_VERSION = 3;
42
49
  function delegationLogPath(projectRoot) {
43
50
  return path.join(projectRoot, RUNTIME_ROOT, "state", "delegation-log.json");
@@ -226,7 +233,12 @@ function isDelegationEntry(value) {
226
233
  (o.allowParallel === undefined || typeof o.allowParallel === "boolean") &&
227
234
  (o.supersededBy === undefined || typeof o.supersededBy === "string") &&
228
235
  (o.claimedPaths === undefined ||
229
- (Array.isArray(o.claimedPaths) && o.claimedPaths.every((item) => typeof item === "string"))));
236
+ (Array.isArray(o.claimedPaths) && o.claimedPaths.every((item) => typeof item === "string"))) &&
237
+ (o.sliceId === undefined ||
238
+ (typeof o.sliceId === "string" && o.sliceId.length > 0)) &&
239
+ (o.phase === undefined ||
240
+ (typeof o.phase === "string" &&
241
+ DELEGATION_PHASES.includes(o.phase))));
230
242
  }
231
243
  function isDelegationDispatchSurface(value) {
232
244
  return typeof value === "string" && DELEGATION_DISPATCH_SURFACES.includes(value);
package/dist/install.js CHANGED
@@ -168,6 +168,14 @@ const DEPRECATED_STATE_FILES = [
168
168
  // now reads cycle phase progression directly from the artifact table.
169
169
  "tdd-cycle-log.jsonl"
170
170
  ];
171
+ // v6.11.0 (R5): files under `<runtime>/artifacts/` that previous releases
172
+ // generated and v6.11.0 removed. `cclaw-cli sync` deletes each so existing
173
+ // installs lose the obsolete sidecar without requiring manual cleanup.
174
+ const DEPRECATED_ARTIFACT_FILES = [
175
+ // v6.10.0 sidecar — replaced in v6.11.0 by phase events in
176
+ // delegation-events.jsonl + auto-rendered tables in 06-tdd.md.
177
+ "06-tdd-slices.jsonl"
178
+ ];
171
179
  const DEPRECATED_HOOK_FILES = [
172
180
  "observe.sh",
173
181
  "summarize-observations.sh",
@@ -851,6 +859,7 @@ async function cleanLegacyArtifacts(projectRoot) {
851
859
  ...DEPRECATED_COMMAND_FILES.map((file) => runtimePath(projectRoot, "commands", file)),
852
860
  ...DEPRECATED_SKILL_FILES.map((segments) => runtimePath(projectRoot, "skills", ...segments)),
853
861
  ...DEPRECATED_STATE_FILES.map((file) => runtimePath(projectRoot, "state", file)),
862
+ ...DEPRECATED_ARTIFACT_FILES.map((file) => runtimePath(projectRoot, "artifacts", file)),
854
863
  ...DEPRECATED_RUNTIME_ROOT_FILES.map((file) => runtimePath(projectRoot, file)),
855
864
  ...DEPRECATED_HOOK_FILES.map((file) => runtimePath(projectRoot, "hooks", file))
856
865
  ]) {
@@ -15,7 +15,6 @@ import { parseFlowStateRepairArgs, runFlowStateRepair } from "./flow-state-repai
15
15
  import { parseWaiverGrantArgs, runWaiverGrant } from "./waiver-grant.js";
16
16
  import { FlowStateGuardMismatchError, verifyFlowStateGuard } from "../run-persistence.js";
17
17
  import { DelegationTimestampError, DispatchCapError, DispatchDuplicateError, DispatchOverlapError } from "../delegation.js";
18
- import { parseTddSliceRecordArgs, runTddSliceRecord } from "../tdd-slices.js";
19
18
  import { parsePlanSplitWavesArgs, runPlanSplitWaves } from "./plan-split-waves.js";
20
19
  /**
21
20
  * Subcommands that mutate or consult flow-state.json via the CLI runtime.
@@ -34,7 +33,7 @@ const GUARD_ENFORCED_SUBCOMMANDS = new Set([
34
33
  export async function runInternalCommand(projectRoot, argv, io) {
35
34
  const [subcommand, ...tokens] = argv;
36
35
  if (!subcommand) {
37
- io.stderr.write("cclaw internal requires a subcommand: advance-stage | start-flow | cancel-run | rewind | verify-flow-state-diff | verify-current-state | envelope-validate | tdd-red-evidence | tdd-loop-status | tdd-slice-record | early-loop-status | compound-readiness | runtime-integrity | hook | flow-state-repair | waiver-grant | plan-split-waves\n");
36
+ io.stderr.write("cclaw internal requires a subcommand: advance-stage | start-flow | cancel-run | rewind | verify-flow-state-diff | verify-current-state | envelope-validate | tdd-red-evidence | tdd-loop-status | early-loop-status | compound-readiness | runtime-integrity | hook | flow-state-repair | waiver-grant | plan-split-waves\n");
38
37
  return 1;
39
38
  }
40
39
  try {
@@ -86,13 +85,10 @@ export async function runInternalCommand(projectRoot, argv, io) {
86
85
  if (subcommand === "waiver-grant") {
87
86
  return await runWaiverGrant(projectRoot, parseWaiverGrantArgs(tokens), io);
88
87
  }
89
- if (subcommand === "tdd-slice-record") {
90
- return await runTddSliceRecord(projectRoot, parseTddSliceRecordArgs(tokens), io);
91
- }
92
88
  if (subcommand === "plan-split-waves") {
93
89
  return await runPlanSplitWaves(projectRoot, parsePlanSplitWavesArgs(tokens), io);
94
90
  }
95
- io.stderr.write(`Unknown internal subcommand: ${subcommand}. Expected advance-stage | start-flow | cancel-run | rewind | verify-flow-state-diff | verify-current-state | envelope-validate | tdd-red-evidence | tdd-loop-status | tdd-slice-record | early-loop-status | compound-readiness | runtime-integrity | hook | flow-state-repair | waiver-grant | plan-split-waves\n`);
91
+ io.stderr.write(`Unknown internal subcommand: ${subcommand}. Expected advance-stage | start-flow | cancel-run | rewind | verify-flow-state-diff | verify-current-state | envelope-validate | tdd-red-evidence | tdd-loop-status | early-loop-status | compound-readiness | runtime-integrity | hook | flow-state-repair | waiver-grant | plan-split-waves\n`);
96
92
  return 1;
97
93
  }
98
94
  catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cclaw-cli",
3
- "version": "6.10.0",
3
+ "version": "6.11.0",
4
4
  "description": "Installer-first flow toolkit for coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,90 +0,0 @@
1
- /**
2
- * v6.10.0 — sidecar ledger that replaces the per-slice markdown tables in
3
- * `06-tdd.md` (Watched-RED Proof, Vertical Slice Cycle, RED/GREEN Evidence).
4
- *
5
- * The file lives next to the TDD artifact (`<artifacts-dir>/06-tdd-slices.jsonl`)
6
- * and is append-only — every CLI call writes a new row, and consumers fold
7
- * rows by `sliceId` taking the latest entry (by file order). Markdown tables
8
- * remain a legacy fallback when this sidecar is absent or empty.
9
- */
10
- export interface TddSliceLedgerEntry {
11
- runId: string;
12
- sliceId: string;
13
- status: "red" | "green" | "refactor-deferred" | "refactor-done";
14
- testFile: string;
15
- testCommand: string;
16
- redObservedAt?: string;
17
- redOutputRef?: string;
18
- greenAt?: string;
19
- greenOutputRef?: string;
20
- refactorAt?: string;
21
- refactorRationale?: string;
22
- claimedPaths: string[];
23
- acceptanceCriterionId?: string;
24
- planUnitId?: string;
25
- schemaVersion: 1;
26
- }
27
- export declare const TDD_SLICE_LEDGER_FILENAME = "06-tdd-slices.jsonl";
28
- export declare const TDD_SLICE_LEDGER_SCHEMA_VERSION: 1;
29
- export declare const TDD_SLICE_STATUSES: readonly ["red", "green", "refactor-deferred", "refactor-done"];
30
- export type TddSliceStatus = (typeof TDD_SLICE_STATUSES)[number];
31
- /**
32
- * Resolve `<artifacts-dir>/06-tdd-slices.jsonl`. Mirrors the convention used
33
- * by the rest of the runtime (see `artifact-paths.ts::searchRoots`): the
34
- * sidecar always lives under `.cclaw/artifacts/` regardless of the active
35
- * topic slug for the TDD artifact.
36
- */
37
- export declare function tddSliceLedgerPath(projectRoot: string): string;
38
- export declare function isTddSliceLedgerEntry(value: unknown): value is TddSliceLedgerEntry;
39
- export declare function readTddSliceLedger(projectRoot: string): Promise<{
40
- entries: TddSliceLedgerEntry[];
41
- corruptLines: number[];
42
- }>;
43
- /**
44
- * Latest-row-wins fold by `sliceId`. Returns one entry per slice, ordered by
45
- * the index of its latest row. Mirrors the pattern used by
46
- * `computeActiveSubagents` for the delegation ledger.
47
- */
48
- export declare function foldTddSliceLedger(entries: TddSliceLedgerEntry[]): TddSliceLedgerEntry[];
49
- /**
50
- * Atomic append under a directory lock — reuses the same `withDirectoryLock`
51
- * primitive that `appendDelegation` uses so concurrent CLI invocations don't
52
- * tear a half-written JSON line.
53
- */
54
- export declare function appendSliceEntry(projectRoot: string, entry: TddSliceLedgerEntry): Promise<void>;
55
- export interface TddSliceRecordArgs {
56
- sliceId: string;
57
- status: TddSliceStatus;
58
- testFile?: string;
59
- testCommand?: string;
60
- claimedPaths?: string[];
61
- redOutputRef?: string;
62
- greenOutputRef?: string;
63
- redObservedAt?: string;
64
- greenAt?: string;
65
- refactorAt?: string;
66
- refactorRationale?: string;
67
- acceptanceCriterionId?: string;
68
- planUnitId?: string;
69
- json: boolean;
70
- }
71
- export declare function parseTddSliceRecordArgs(tokens: string[]): TddSliceRecordArgs;
72
- interface TddSliceRecordIo {
73
- stdout: {
74
- write(chunk: string): boolean;
75
- };
76
- stderr: {
77
- write(chunk: string): boolean;
78
- };
79
- }
80
- /**
81
- * Consume parsed CLI flags, fold against the existing sidecar to inherit
82
- * fields recorded on earlier rows of the same slice, auto-stamp the
83
- * status-relevant timestamp when not provided, and append the new row.
84
- *
85
- * The CLI surface is intentionally lenient: only the very first call for a
86
- * slice (status=red) needs `--test-file`, `--command`, `--paths`. Subsequent
87
- * green/refactor calls inherit those values from the latest prior row.
88
- */
89
- export declare function runTddSliceRecord(projectRoot: string, args: TddSliceRecordArgs, io: TddSliceRecordIo): Promise<number>;
90
- export {};