cclaw-cli 0.5.12 → 0.5.13

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.
@@ -311,106 +311,55 @@ Execution rule: complete and verify each wave before starting the next wave.
311
311
  | AC-2 (idempotency) | T-1, T-2 |
312
312
  | AC-3 (failure visibility) | T-3 |
313
313
 
314
+ ### Risk Assessment
315
+
316
+ | Task/Wave | Risk | Likelihood | Impact | Mitigation |
317
+ | --- | --- | --- | --- | --- |
318
+ | T-3 (Wave 3) | SSE reconnect logic complex | Medium | High | Spike reconnect in isolation before integrating with feed UI |
319
+ | Wave 2 → 3 | Publisher API contract may shift | Low | Medium | Pin contract in T-1 schema; T-2 integration test validates |
320
+
314
321
  ### WAIT_FOR_CONFIRM
315
322
  - Status: pending
316
323
  - Confirmed by:`,
317
- tdd: `### RED test (Vitest) — written before production code
318
-
319
- \`\`\`typescript
320
- import { describe, it, expect } from "vitest";
321
- import { summarizeDedupedFeed } from "../notificationFeed";
322
-
323
- describe("summarizeDedupedFeed", () => {
324
- it("counts unique keys and unread items", () => {
325
- const summary = summarizeDedupedFeed([
326
- { dedupeKey: "a", read: false },
327
- { dedupeKey: "a", read: true },
328
- { dedupeKey: "b", read: false },
329
- ]);
330
-
331
- expect(summary).toEqual({ uniqueKeys: 2, unread: 1 });
332
- });
333
- });
334
- \`\`\`
335
-
336
- ### Expected output (FAIL)
337
-
338
- \`\`\`bash
339
- FAIL src/notificationFeed.test.ts
340
- Error: Cannot find module '../notificationFeed' imported from src/notificationFeed.test.ts
341
- \`\`\`
342
-
343
- > **Annotation:** This test MUST fail before any production code is written.
344
-
345
- ### Iron Law verification
346
-
347
- 1. **Run** the test command (for example: \`pnpm vitest run src/notificationFeed.test.ts\`).
348
- 2. **Read output** and confirm the failure is due to the module/function not existing (or the function throwing “not implemented”), not due to a typo in assertions.
349
- 3. **Confirm** the failure reason matches the intentional gap: **missing implementation**, not a flaky environment or misconfigured test runner.
350
-
351
- ### Common mistakes to avoid
352
-
353
- - “GREEN” that secretly imports a helper that already implements the behavior (that is skipping RED).
354
- - Assertions that pass because the function returns \`undefined\` and the matcher is too loose.
355
-
356
- ### GREEN (minimal implementation to pass RED)
357
-
358
- \`\`\`typescript
359
- export type FeedItem = { dedupeKey: string; read: boolean };
324
+ tdd: `### RED Evidence
360
325
 
361
- export function summarizeDedupedFeed(items: FeedItem[]) {
362
- // Last write wins per dedupeKey (stable ordering: later items override earlier ones).
363
- const latestReadByKey = new Map<string, boolean>();
364
-
365
- for (const item of items) {
366
- latestReadByKey.set(item.dedupeKey, item.read);
367
- }
368
-
369
- let unread = 0;
370
- for (const read of latestReadByKey.values()) {
371
- if (!read) unread += 1;
372
- }
373
-
374
- return { uniqueKeys: latestReadByKey.size, unread };
375
- }
376
- \`\`\`
377
-
378
- ### REFACTOR (keep tests green)
326
+ | Slice | Test name | Command | Failure output summary |
327
+ | --- | --- | --- | --- |
328
+ | S-1 (event schema + dedupe) | counts unique keys and unread items | \`\`\`pnpm vitest run tests/unit/dedupe-feed.test.ts\`\`\` | Cannot find module '../notificationFeed' |
329
+ | S-2 (publisher outbox) | publishes event to outbox with dedupe key | \`\`\`pnpm vitest run tests/integration/publisher.test.ts\`\`\` | publishToOutbox is not a function |
330
+ | S-3 (client feed + fallback) | shows notification within 5s via SSE | \`\`\`pnpm playwright test tests/e2e/notification-feed.spec.ts\`\`\` | Element [data-testid="feed-item"] not found |
379
331
 
380
- Keep semantics identical, but make the merge step explicit and easier to unit test in isolation:
332
+ ### Acceptance Mapping
381
333
 
382
- \`\`\`typescript
383
- export type FeedItem = { dedupeKey: string; read: boolean };
334
+ | Slice | Plan task ID | Spec criterion ID |
335
+ | --- | --- | --- |
336
+ | S-1 | T-1 | AC-1, AC-2 |
337
+ | S-2 | T-2 | AC-1 |
338
+ | S-3 | T-3 | AC-1, AC-2, AC-3 |
384
339
 
385
- function mergeLatestByDedupeKey(items: FeedItem[]) {
386
- const latestReadByKey = new Map<string, boolean>();
387
- for (const item of items) latestReadByKey.set(item.dedupeKey, item.read);
388
- return latestReadByKey;
389
- }
340
+ ### Failure Analysis
390
341
 
391
- export function summarizeDedupedFeed(items: FeedItem[]) {
392
- const latestReadByKey = mergeLatestByDedupeKey(items);
342
+ | Slice | Expected missing behavior | Actual failure reason |
343
+ | --- | --- | --- |
344
+ | S-1 | notificationFeed module does not exist yet | Module import fails — correct: implementation missing |
345
+ | S-2 | publishToOutbox function not implemented | Function not found — correct: write path missing |
346
+ | S-3 | Feed UI not rendered, SSE not connected | DOM element missing — correct: client component not built |
393
347
 
394
- let unread = 0;
395
- for (const read of latestReadByKey.values()) {
396
- if (!read) unread += 1;
397
- }
348
+ ### GREEN Evidence
398
349
 
399
- return { uniqueKeys: latestReadByKey.size, unread };
400
- }
401
- \`\`\`
350
+ - Full suite command: \`\`\`pnpm vitest run && pnpm playwright test\`\`\`
351
+ - Full suite result: 47 tests passed (3 new + 44 existing), 0 failed, 0 skipped
402
352
 
403
- ### Sample terminal output (GREEN)
353
+ ### REFACTOR Notes
404
354
 
405
- \`\`\`bash
406
- RUN v2.1.0 /Users/dev/app
355
+ - What changed: Extracted \`\`\`mergeLatestByDedupeKey\`\`\` helper from inline loop in \`\`\`summarizeDedupedFeed\`\`\`; moved SSE reconnect logic into \`\`\`useSSEConnection\`\`\` hook.
356
+ - Why: Dedupe merge logic is reused by both publisher and client; reconnect logic was duplicated across components.
357
+ - Behavior preserved: Full suite re-run confirms 47/47 pass after refactor.
407
358
 
408
- ✓ src/notificationFeed.test.ts (1 test) 12ms
359
+ ### Traceability
409
360
 
410
- Test Files 1 passed (1)
411
- Tests 1 passed (1)
412
- Tests: 1 passed.
413
- \`\`\``,
361
+ - Plan task IDs: T-1, T-2, T-3
362
+ - Spec criterion IDs: AC-1, AC-2, AC-3`,
414
363
  review: `### Layer 1 — Spec compliance (per-criterion)
415
364
 
416
365
  | Criterion | Status | Evidence |
@@ -905,6 +905,7 @@ const PLAN = {
905
905
  { section: "Task List", required: true, validationRule: "Each task: ID, description, acceptance criterion link, verification command, and effort estimate (S/M/L)." },
906
906
  { section: "Acceptance Mapping", required: true, validationRule: "Every spec criterion is covered by at least one task." },
907
907
  { section: "Risk Assessment", required: false, validationRule: "If present: per-task or per-wave risk identification with likelihood, impact, and mitigation strategy." },
908
+ { section: "Boundary Map", required: false, validationRule: "If present: per-wave or per-task interface contracts listing what each task produces (exports) and consumes (imports) from other tasks." },
908
909
  { section: "WAIT_FOR_CONFIRM", required: true, validationRule: "Explicit marker present. Status: pending until user approves." }
909
910
  ],
910
911
  namedAntiPattern: {
@@ -1033,14 +1034,38 @@ const TDD = {
1033
1034
  { name: "Failure-First Thinking", description: "The failing test IS the specification. Until you see the right failure, you do not understand what you are building. Wrong failures are information." },
1034
1035
  { name: "Minimal Viable Change", description: "The best implementation is the smallest one that passes all RED tests. Every extra line is risk. Resist the urge to 'improve while you are here.'" },
1035
1036
  { name: "Regression Paranoia", description: "Assume every change breaks something until the full suite proves otherwise. Partial test runs are lies of omission." },
1036
- { name: "Refactor-as-Hygiene", description: "Refactoring is not optional cleanup — it is the third leg of TDD. GREEN without REFACTOR accumulates mess. REFACTOR without GREEN breaks things." }
1037
+ { name: "Refactor-as-Hygiene", description: "Refactoring is not optional cleanup — it is the third leg of TDD. GREEN without REFACTOR accumulates mess. REFACTOR without GREEN breaks things." },
1038
+ { name: "Evidence Over Anecdote", description: "Every claim about test state must be backed by captured output. 'It passed' without terminal evidence is not evidence. 'I saw it fail' without the failure output is not RED. Capture commands, outputs, and results — not summaries from memory." }
1039
+ ],
1040
+ reviewSections: [
1041
+ {
1042
+ title: "RED Evidence Audit",
1043
+ evaluationPoints: [
1044
+ "Does every slice have a captured failing test output?",
1045
+ "Does each failure reason match the expected missing behavior (not a typo or config error)?",
1046
+ "Were tests written BEFORE any production code for that slice?",
1047
+ "Does each RED test assert observable behavior, not implementation details?",
1048
+ "Is there a test for each acceptance criterion mapped in the plan?"
1049
+ ],
1050
+ stopGate: true
1051
+ },
1052
+ {
1053
+ title: "GREEN/REFACTOR Audit",
1054
+ evaluationPoints: [
1055
+ "Does GREEN evidence show a FULL suite pass (not partial)?",
1056
+ "Is the GREEN implementation minimal — no features beyond what RED tests require?",
1057
+ "Does the REFACTOR step preserve all existing behavior (no new failures)?",
1058
+ "Are REFACTOR notes documented with rationale?",
1059
+ "Is traceability complete: every change links to plan task ID and spec criterion?"
1060
+ ],
1061
+ stopGate: true
1062
+ }
1037
1063
  ],
1038
- reviewSections: [],
1039
1064
  completionStatus: ["DONE", "DONE_WITH_CONCERNS", "BLOCKED"],
1040
1065
  crossStageTrace: {
1041
- readsFrom: [".cclaw/artifacts/05-plan.md", ".cclaw/artifacts/04-spec.md"],
1066
+ readsFrom: [".cclaw/artifacts/05-plan.md", ".cclaw/artifacts/04-spec.md", ".cclaw/artifacts/03-design.md"],
1042
1067
  writesTo: [".cclaw/artifacts/06-tdd.md"],
1043
- traceabilityRule: "Every RED test traces to a plan task. Every GREEN change traces to a RED test. Every plan task traces to a spec criterion. Evidence chain must be unbroken."
1068
+ traceabilityRule: "Every RED test traces to a plan task. Every GREEN change traces to a RED test. Every plan task traces to a spec criterion. Design decisions inform test strategy. Evidence chain must be unbroken."
1044
1069
  },
1045
1070
  artifactValidation: [
1046
1071
  { section: "RED Evidence", required: true, validationRule: "Failing test output captured per slice." },
@@ -1048,8 +1073,14 @@ const TDD = {
1048
1073
  { section: "Failure Analysis", required: true, validationRule: "Failure reason matches expected missing behavior." },
1049
1074
  { section: "GREEN Evidence", required: true, validationRule: "Full suite pass output captured." },
1050
1075
  { section: "REFACTOR Notes", required: true, validationRule: "What changed, why, behavior preservation confirmed." },
1051
- { section: "Traceability", required: true, validationRule: "Plan task ID and spec criterion linked." }
1076
+ { section: "Traceability", required: true, validationRule: "Plan task ID and spec criterion linked." },
1077
+ { section: "Verification Ladder", required: false, validationRule: "If present: per-slice verification tier (static, command, behavioral, human) with evidence for highest tier reached." },
1078
+ { section: "Coverage Targets", required: false, validationRule: "If present: per-module or per-code-type coverage thresholds with current values and measurement commands." }
1052
1079
  ],
1080
+ namedAntiPattern: {
1081
+ title: "Code Before Failing Test",
1082
+ description: "Production code written before a failing test is not TDD — it is guessing validated after the fact. Tests written after implementation confirm assumptions, not behavior. If you wrote code first, delete it and start with RED. Delete means delete — not 'keep as reference.' The failing test IS the specification."
1083
+ },
1053
1084
  waveExecutionAllowed: true
1054
1085
  };
1055
1086
  // ---------------------------------------------------------------------------
@@ -278,6 +278,11 @@ Execution rule: complete and verify each wave before starting the next wave.
278
278
  |---|---|---|---|---|
279
279
  | | | | | |
280
280
 
281
+ ## Boundary Map
282
+ | Task/Wave | Produces (exports) | Consumes (imports from) |
283
+ |---|---|---|
284
+ | | | |
285
+
281
286
  ## WAIT_FOR_CONFIRM
282
287
  - Status: pending
283
288
  - Confirmed by:
@@ -311,6 +316,17 @@ Execution rule: complete and verify each wave before starting the next wave.
311
316
  ## Traceability
312
317
  - Plan task IDs:
313
318
  - Spec criterion IDs:
319
+
320
+
321
+ ## Verification Ladder
322
+ | Slice | Tier reached | Evidence |
323
+ |---|---|---|
324
+ | S-1 | | |
325
+
326
+ ## Coverage Targets
327
+ | Code type | Target | Current | Command |
328
+ |---|---|---|---|
329
+ | | | | |
314
330
  `,
315
331
  "07-review.md": `# Review Artifact
316
332
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cclaw-cli",
3
- "version": "0.5.12",
3
+ "version": "0.5.13",
4
4
  "description": "Installer-first flow toolkit for coding agents",
5
5
  "type": "module",
6
6
  "bin": {