cclaw-cli 0.5.7 → 0.5.9

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.
@@ -118,6 +118,22 @@ function tokensFromRule(rule) {
118
118
  }
119
119
  return [];
120
120
  }
121
+ /**
122
+ * Extract required keywords from validation rules that contain comma-separated
123
+ * concept lists. Activates only for rules with structured enumerations like
124
+ * "failure modes, error surface, data-flow paths" — not for short rules.
125
+ */
126
+ function extractRequiredKeywords(rule) {
127
+ const colonMatch = /:\s*(.+)$/u.exec(rule);
128
+ if (!colonMatch)
129
+ return [];
130
+ const tail = colonMatch[1];
131
+ const parts = tail.split(/,\s*(?:and\s+)?/u).map((p) => p.trim().replace(/\.$/u, ""));
132
+ const phrases = parts.filter((p) => p.length >= 4 && !/^(must|should|at least|if |or )/iu.test(p));
133
+ if (phrases.length < 3)
134
+ return [];
135
+ return phrases;
136
+ }
121
137
  function validateSectionBody(sectionBody, rule) {
122
138
  const bodyLines = sectionBody.split(/\r?\n/).map((line) => line.trim());
123
139
  const meaningful = meaningfulLineCount(sectionBody);
@@ -185,6 +201,19 @@ function validateSectionBody(sectionBody, rule) {
185
201
  }
186
202
  }
187
203
  }
204
+ const keywords = extractRequiredKeywords(rule);
205
+ if (keywords.length > 0) {
206
+ const bodyLower = sectionBody.toLowerCase();
207
+ const found = keywords.filter((kw) => bodyLower.includes(kw.toLowerCase()));
208
+ const threshold = Math.ceil(keywords.length * 0.5);
209
+ if (found.length < threshold) {
210
+ const missing = keywords.filter((kw) => !bodyLower.includes(kw.toLowerCase()));
211
+ return {
212
+ ok: false,
213
+ details: `Rule expects keywords (${threshold}/${keywords.length} minimum): missing ${missing.join(", ")}.`
214
+ };
215
+ }
216
+ }
188
217
  return {
189
218
  ok: true,
190
219
  details: "Section heading and content satisfy lint heuristics."
@@ -73,6 +73,14 @@ The original premise (“add notifications”) was reframed to **“ensure users
73
73
  | **12-MONTH IDEAL** | Unified notification center with reliable multi-channel fan-out and user-level routing preferences. |
74
74
  | **Alignment verdict** | Aligned: this scope builds the durability foundation without prematurely committing to channel expansion. |
75
75
 
76
+ ### Mode-Specific Analysis
77
+
78
+ **Selected mode:** SELECTIVE EXPANSION
79
+
80
+ - **Hold-scope baseline:** SSE live updates + REST fallback is the minimum that meets the "know when action is needed" reframe. Accepted as baseline.
81
+ - **Expansion evaluated — degraded-state UX (accepted):** Adding an explicit "live updates paused" banner and polling fallback turns a reliability gap into a visible, recoverable state. Low incremental effort (S), high user trust payoff.
82
+ - **Expansion evaluated — real-time channel upgrade (deferred):** WebSocket channel provides lower latency but requires new infra (connection pool, auth handshake). Not justified for current load; deferred to post-v1 validation.
83
+
76
84
  ### Implementation Alternatives
77
85
 
78
86
  | Option | Summary | Effort (S/M/L/XL) | Risk | Pros | Cons | Reuses |
@@ -120,7 +128,18 @@ The original premise (“add notifications”) was reframed to **“ensure users
120
128
  - Accepted scope: durable feed + SSE + explicit degraded UX.
121
129
  - Deferred: WebSocket channel and rich-media/search enhancements.
122
130
  - Explicitly excluded: outbound channels and marketing workflows for v1.`,
123
- design: `### Search Before Building (sample result)
131
+ design: `### Codebase Investigation (blast-radius files)
132
+
133
+ | File | Current responsibility | Patterns discovered |
134
+ | --- | --- | --- |
135
+ | \`src/api/routes/user.ts\` | User CRUD endpoints | Express router, Zod validation, throws \`AppError\` |
136
+ | \`src/services/event-bus.ts\` | In-process pub/sub | EventEmitter wrapper, typed channels, no persistence |
137
+ | \`src/middleware/auth.ts\` | JWT verification | Extracts user from token, attaches to \`req.context\` |
138
+ | \`tests/integration/user.test.ts\` | User route tests | Supertest, factory helpers, \`beforeEach\` DB reset |
139
+
140
+ Discovery: existing EventEmitter-based bus has no durability — notifications must add persistence layer on top, not replace the bus.
141
+
142
+ ### Search Before Building (sample result)
124
143
 
125
144
  | Layer | Label | What to reuse first |
126
145
  | --- | --- | --- |
@@ -128,7 +147,7 @@ The original premise (“add notifications”) was reframed to **“ensure users
128
147
  | Layer 2 | existing codebase | Existing auth middleware, existing API client wrapper, existing feature flags helper |
129
148
  | Layer 3 | npm | A small, well-maintained SSE helper (only if Layer 1–2 cannot cover framing/reconnect ergonomics) |
130
149
 
131
- ### Minimal component diagram (ASCII)
150
+ ### Architecture Diagram (mandatory)
132
151
 
133
152
  \`\`\`
134
153
  ┌─────────────┐ ┌──────────────┐ ┌────────────────┐
@@ -142,18 +161,54 @@ The original premise (“add notifications”) was reframed to **“ensure users
142
161
  └──────────────┘
143
162
  \`\`\`
144
163
 
145
- ### Unresolved Decision (sample entry)
164
+ Data flow: Gateway → Service (validate + enrich) → Publisher (fan-out) → Queue (persist) → Read Model (project).
165
+
166
+ ### What Already Exists
167
+
168
+ | Sub-problem | Existing code/library | Layer | Reuse decision |
169
+ | --- | --- | --- | --- |
170
+ | Auth context extraction | \`src/middleware/auth.ts\` | Layer 1 | Reuse as-is |
171
+ | Event fan-out | \`src/services/event-bus.ts\` | Layer 2 | Wrap with persistence adapter |
172
+ | SSE framing | None | Layer 3 | Evaluate \`better-sse\` npm package |
173
+ | Notification schema | None | — | New: define in \`src/schemas/notification.ts\` |
174
+
175
+ ### Failure Mode Table
146
176
 
147
- - **Decision:** Should the feed be modeled as append-only events or as CRUD “notification rows”?
148
- - **Status:** OPEN
149
- - **Options:** (A) append-only event log + projection, (B) mutable rows with status fields, (C) hybrid with compaction job
150
- - **Deadline:** Decide before implementation of persistence migrations (end of week)
177
+ | Failure | Trigger | Detection | Mitigation | User impact |
178
+ | --- | --- | --- | --- | --- |
179
+ | SSE connection drop | Network interruption | Client heartbeat timeout (30s) | Auto-reconnect with exponential backoff + snapshot fallback | Brief delay (≤10s), no data loss |
180
+ | Duplicate publish | Retry after timeout | Dedupe key check in outbox | Upsert with idempotency key | None (transparent) |
181
+ | Queue backpressure | Spike >1000 events/s | Queue depth metric alarm | Back-pressure signal to publisher, shed non-critical events | Delayed delivery of low-priority notifications |
182
+
183
+ ### NOT in scope
184
+
185
+ - Outbound channels (email, push, SMS) — deferred to v2.
186
+ - Admin notification management UI — separate workstream.
187
+ - Notification preferences / mute rules — requires user settings redesign.
188
+
189
+ ### Unresolved Decisions
190
+
191
+ | Decision | Status | Options | Missing info | Default if unanswered |
192
+ | --- | --- | --- | --- | --- |
193
+ | Feed storage model | OPEN | (A) append-only event log, (B) mutable rows, (C) hybrid | Load testing results on read patterns | (A) append-only — safest for audit trail |
151
194
 
152
195
  ### Interface sketch (non-binding)
153
196
 
154
197
  - **Client → server:** \`GET /api/me/notifications/snapshot?limit=50\` plus optional cursor parameters (if adopted).
155
198
  - **Server → client:** \`GET /api/me/notifications/stream\` as SSE with periodic heartbeats.
156
199
 
200
+ ### Completion Dashboard
201
+
202
+ | Review Section | Status | Issues |
203
+ | --- | --- | --- |
204
+ | Architecture Review | issues-found-resolved | Decided on outbox pattern over direct pub/sub |
205
+ | Code Quality Review | clear | — |
206
+ | Test Review | issues-found-resolved | Added integration test gap for SSE reconnect |
207
+ | Performance Review | clear | — |
208
+ | Distribution & Delivery Review | clear | — |
209
+
210
+ **Decisions made:** 4 | **Unresolved:** 1 (feed storage model)
211
+
157
212
  ### Quality bar for this stage
158
213
 
159
214
  Design output should be **reviewable by someone who did not attend brainstorming**: they can trace from constraints → components → open decisions without reading code.`,
@@ -309,10 +309,15 @@ is_plan_mode_safe_tool() {
309
309
  todowrite|todoread|todo_write|todo_read) return 0 ;;
310
310
  webfetch|websearch|web_fetch|web_search|fetchmcpresource) return 0 ;;
311
311
  switchmode|switch_mode) return 0 ;;
312
+ task|delegate) return 0 ;;
312
313
  *) return 1 ;;
313
314
  esac
314
315
  }
315
316
 
317
+ is_cclaw_cli_payload() {
318
+ printf '%s' "$1" | grep -Eq '(cclaw |npx cclaw |/cc-|/cc[^[:alnum:]_-])'
319
+ }
320
+
316
321
  is_preimplementation_stage() {
317
322
  case "$1" in
318
323
  brainstorm|scope|design|spec|plan) return 0 ;;
@@ -370,7 +375,7 @@ fi
370
375
 
371
376
  if is_preimplementation_stage "$CURRENT_STAGE" && ! is_plan_mode_safe_tool "$TOOL_LOWER"; then
372
377
  if ! is_mutating_tool "$TOOL_LOWER"; then
373
- if ! printf '%s' "$PAYLOAD_LOWER" | grep -Eq '\.cclaw/'; then
378
+ if ! printf '%s' "$PAYLOAD_LOWER" | grep -Eq '\.cclaw/' && ! is_cclaw_cli_payload "$PAYLOAD_LOWER"; then
374
379
  if [ -n "$REASONS" ]; then
375
380
  REASONS="$REASONS,non_safe_tool_in_plan_stage_\${CURRENT_STAGE}"
376
381
  else
@@ -393,9 +398,10 @@ fi
393
398
  SHOULD_RECORD_FLOW_READ=0
394
399
  case "$TOOL_LOWER" in
395
400
  read|readfile|open|view|cat) SHOULD_RECORD_FLOW_READ=1 ;;
401
+ shell|runcommand|run_command|execcommand|exec_command|terminal) SHOULD_RECORD_FLOW_READ=1 ;;
396
402
  esac
397
403
 
398
- if [ "$SHOULD_RECORD_FLOW_READ" -eq 1 ] && printf '%s' "$PAYLOAD_LOWER" | grep -Eq '\.cclaw/state/flow-state\.json'; then
404
+ if [ "$SHOULD_RECORD_FLOW_READ" -eq 1 ] && printf '%s' "$PAYLOAD_LOWER" | grep -Eq '(\.cclaw/state/flow-state\.json|cclaw doctor|cclaw sync)'; then
399
405
  TMP_STATE_FILE="$GUARD_STATE_FILE.tmp.$$"
400
406
  if command -v jq >/dev/null 2>&1 && [ -f "$GUARD_STATE_FILE" ]; then
401
407
  jq --arg ts "$TS" --argjson epoch "$NOW_EPOCH" '
@@ -143,6 +143,8 @@ function stageCompletionProtocol(schema) {
143
143
  const gateIds = schema.requiredGates.map((g) => g.id);
144
144
  const gateList = gateIds.map((id) => `\`${id}\``).join(", ");
145
145
  const nextStage = schema.next === "done" ? null : schema.next;
146
+ const mandatory = schema.mandatoryDelegations;
147
+ const delegationLogRel = `${RUNTIME_ROOT}/state/delegation-log.json`;
146
148
  const stateUpdate = nextStage
147
149
  ? ` - Set \`currentStage\` to \`"${nextStage}"\`
148
150
  - Add \`"${stage}"\` to \`completedStages\` array
@@ -151,23 +153,33 @@ function stageCompletionProtocol(schema) {
151
153
  : ` - Add \`"${stage}"\` to \`completedStages\` array
152
154
  - Move all gate IDs for this stage (${gateList}) into \`stageGateCatalog.${stage}.passed\`
153
155
  - Clear \`stageGateCatalog.${stage}.blocked\``;
156
+ const delegationBlock = mandatory.length > 0
157
+ ? `0. **Delegation pre-flight** (BLOCKING):
158
+ - Mandatory agents for this stage: ${mandatory.map((a) => `\`${a}\``).join(", ")}.
159
+ - For each mandatory agent: confirm it was dispatched (via Task/delegate) and completed, OR record an explicit waiver with reason in \`${delegationLogRel}\`.
160
+ - Write a JSON entry per agent: \`{ "stage": "${stage}", "agent": "<name>", "mode": "mandatory", "status": "completed"|"waived", "waiverReason": "<if waived>", "ts": "<ISO timestamp>" }\`.
161
+ - If the harness does not support delegation, record status \`"waived"\` with reason \`"harness_limitation"\`.
162
+ - **Do NOT proceed to step 1 until every mandatory agent has an entry in the delegation log.**
163
+ `
164
+ : "";
154
165
  let nextAction;
155
166
  if (nextStage) {
156
167
  const nextSchema = stageSchema(nextStage);
157
168
  const nextDescription = nextSchema.skillDescription.charAt(0).toLowerCase() + nextSchema.skillDescription.slice(1);
158
- nextAction = `3. Tell the user:\n\n > **Stage \`${stage}\` complete.** Next: **${nextStage}** — ${nextDescription}\n >\n > Run \`/cc-next\` to continue.`;
169
+ nextAction = `4. Tell the user:\n\n > **Stage \`${stage}\` complete.** Next: **${nextStage}** — ${nextDescription}\n >\n > Run \`/cc-next\` to continue.`;
159
170
  }
160
171
  else {
161
- nextAction = `3. Tell the user:\n\n > **Flow complete.** All stages finished. The project is ready for release.`;
172
+ nextAction = `4. Tell the user:\n\n > **Flow complete.** All stages finished. The project is ready for release.`;
162
173
  }
163
174
  return `## Stage Completion Protocol
164
175
 
165
176
  When all required gates are satisfied and the artifact is written:
166
177
 
167
- 1. **Update \`${RUNTIME_ROOT}/state/flow-state.json\`:**
178
+ ${delegationBlock}1. **Update \`${RUNTIME_ROOT}/state/flow-state.json\`:**
168
179
  ${stateUpdate}
169
180
  - For each passed gate, add an entry to \`guardEvidence\`: \`"<gate_id>": "<artifact path or excerpt proving the gate>"\`. Do NOT leave \`guardEvidence\` empty.
170
181
  2. **Persist artifact** at \`${RUNTIME_ROOT}/artifacts/${schema.artifactFile}\`. Do NOT manually copy into \`${RUNTIME_ROOT}/runs/\`; archival is handled by \`cclaw archive\`.
182
+ 3. **Doctor pre-flight** — Run \`npx cclaw doctor\` (or the installed cclaw binary). If any check fails, resolve the issue (missing delegation entry, artifact section, gate evidence) and re-run until all checks pass. Do NOT proceed to the next step while doctor reports failures.
171
183
  ${nextAction}
172
184
 
173
185
  **STOP.** Do not load the next stage skill yourself. The user will run \`/cc-next\` when ready (same session or new session).
@@ -352,12 +352,15 @@ const SCOPE = {
352
352
  { section: "Premise Challenge", required: true, validationRule: "Must contain explicit answers to: right problem? direct path? what if nothing?" },
353
353
  { 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." },
354
354
  { section: "Scope Mode", required: true, validationRule: "Must state selected mode and rationale with default heuristic justification." },
355
+ { 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)." },
355
356
  { section: "In Scope / Out of Scope", required: true, validationRule: "Two separate explicit lists. Out-of-scope must not be empty." },
356
357
  { section: "Discretion Areas", required: true, validationRule: "Explicit list of implementer decision zones, or 'None' if scope is fully locked." },
357
358
  { section: "Deferred Items", required: true, validationRule: "Each item has one-line rationale. If empty, state 'None' explicitly." },
358
359
  { section: "Error & Rescue Registry", required: true, validationRule: "Each scoped capability has: failure mode, detection method, fallback decision." },
359
360
  { section: "Completion Dashboard", required: true, validationRule: "Lists checklist findings, count of resolved decisions, and unresolved decisions (or 'None')." },
360
- { section: "Scope Summary", required: true, validationRule: "Clean summary: mode, strongest challenges, recommended path, accepted scope, deferred, excluded." }
361
+ { section: "Scope Summary", required: true, validationRule: "Clean summary: mode, strongest challenges, recommended path, accepted scope, deferred, excluded." },
362
+ { section: "Dream State Mapping", required: false, validationRule: "If present (complex projects): CURRENT STATE, THIS PLAN, 12-MONTH IDEAL, and alignment verdict." },
363
+ { section: "Temporal Interrogation", required: false, validationRule: "If present (complex projects): timeline simulation table with decision pressures and lock-now vs defer verdicts." }
361
364
  ],
362
365
  namedAntiPattern: {
363
366
  title: "Scope Is Obvious From Context",
@@ -385,28 +388,35 @@ const DESIGN = {
385
388
  "Implementation has already started and requires review instead of design lock"
386
389
  ],
387
390
  checklist: [
391
+ "Trivial-Change Escape Hatch — If scope artifact shows ≤3 files, zero new interfaces, and no cross-module data flow, skip full review sections. Produce a mini-design: one paragraph of rationale, list of changed files, one risk to watch. Proceed to spec.",
388
392
  "Design Doc Check — read existing design docs, scope artifact, brainstorm artifact. If a design doc exists that covers this area, check for 'Supersedes:' and use the latest. Use upstream artifacts as source of truth.",
393
+ "Codebase Investigation — Before any design decision, read the actual code in the blast radius. List every file that will be touched, its current responsibilities, and existing patterns (error handling, naming, test style). Design must conform to discovered patterns, not impose new ones without justification.",
389
394
  "Step 0: Scope Challenge — what existing code solves sub-problems? Minimum change set? Complexity check: 8+ files or 2+ new services = complexity smell → flag for possible scope reduction.",
390
395
  "Search Before Building — For each technical choice (library, pattern, architecture), search for existing solutions. Label findings: Layer 1 (exact match), Layer 2 (partial match, needs adaptation), Layer 3 (inspiration only), EUREKA (unexpected perfect solution). Default to existing before custom.",
391
- "Architecture Review — system design, component boundaries, data flow, scaling, security architecture. For each new codepath: one realistic production failure scenario.",
396
+ "Architecture Review — system design, component boundaries, data flow, scaling, security architecture. For each new codepath: one realistic production failure scenario. **Mandatory:** produce at least one architecture diagram (ASCII, Mermaid, or tool-generated) showing component boundaries and data flow direction.",
392
397
  "Code Quality Review — code organization, DRY violations, error handling patterns, over/under-engineering assessment.",
393
398
  "Test Review — diagram every new flow, data path, error path. For each: what test type covers it? Does one exist? What is the gap? Produce test plan artifact.",
394
399
  "Performance Review — N+1 queries, memory concerns, caching opportunities, slow code paths. What breaks at 10x load? At 100x?",
395
400
  "Parallelization Strategy — If multiple independent modules, produce dependency table: which can be built in parallel? Where are conflict risks? Flag shared-state modules.",
396
401
  "Unresolved Decisions — List any design decisions that could not be resolved in this session. For each: what information is missing? Who can provide it? What is the default if no answer comes?",
397
- "Distribution Check — If the plan creates new artifact types (packages, CLI tools, configs), document the build/publish story. How does it reach the user?"
402
+ "Distribution Check — If the plan creates new artifact types (packages, CLI tools, configs), document the build/publish story. How does it reach the user?",
403
+ "Deferred Items Cross-Reference — Collect every item explicitly deferred during design review. Each must appear in the Unresolved Decisions table or in the upstream scope artifact's deferred list. No deferred item may exist only in conversation — it must be written down."
398
404
  ],
399
405
  interactionProtocol: [
400
406
  "Review architecture decisions section-by-section.",
401
407
  "For EACH issue found in a review section, present it ONE AT A TIME. Do NOT batch multiple issues.",
402
- "For each issue: use the Decision Protocol — describe concretely with file/line references, present labeled options (A/B/C) with trade-offs and mark one as (recommended). If AskQuestion/AskUserQuestion is available, send exactly ONE question per call, validate fields against runtime schema, and on schema error immediately fall back to plain-text question instead of retrying guessed payloads.",
408
+ "For each issue: use the Decision Protocol — describe concretely with file/line references, present labeled options (A/B/C) with trade-offs, effort estimate (S/M/L/XL), risk level (Low/Med/High), and mark one as (recommended). If AskQuestion/AskUserQuestion is available, send exactly ONE question per call, validate fields against runtime schema, and on schema error immediately fall back to plain-text question instead of retrying guessed payloads.",
403
409
  "Only proceed to the next review section after ALL issues in the current section are resolved.",
404
410
  "If a section has no issues, say 'No issues found' and move on.",
405
411
  "Do not skip failure-mode mapping.",
406
- "For design baseline approval: present the full baseline. **STOP.** Do NOT proceed until user explicitly approves the design."
412
+ "For design baseline approval: present the full baseline. **STOP.** Do NOT proceed until user explicitly approves the design.",
413
+ "Take a firm position on every recommendation. Do NOT hedge with 'it depends' or 'you could do either'. State your opinion, then justify it.",
414
+ "Use pushback patterns for weak framing: if the user says 'it's just a small change', respond with 'small changes to shared interfaces have outsized blast radius — let's map it'. If 'we'll refactor later', respond with 'later never comes — show me the refactor ticket or do it now'.",
415
+ "When the user's proposed architecture is suboptimal, say so directly. Offer the alternative with concrete trade-offs, do not bury criticism in praise."
407
416
  ],
408
417
  process: [
409
418
  "Read upstream artifacts (brainstorm, scope).",
419
+ "Investigate codebase: read files in blast radius, catalogue current patterns and responsibilities.",
410
420
  "Run Step 0 scope challenge: existing code leverage, minimum change set, complexity check.",
411
421
  "Walk through each review section interactively.",
412
422
  "Define architecture boundaries and ownership.",
@@ -414,9 +424,11 @@ const DESIGN = {
414
424
  "Map failure modes and recovery strategy.",
415
425
  "Define test coverage strategy and performance budget.",
416
426
  "Produce required outputs: NOT-in-scope section, What-already-exists section, diagrams, failure mode table.",
427
+ "Produce completion dashboard: list every review section with status (clear / issues-found-resolved / issues-open), count of decisions made, and list of unresolved items.",
417
428
  "Write design lock artifact for downstream spec/plan."
418
429
  ],
419
430
  requiredGates: [
431
+ { id: "design_codebase_investigated", description: "Blast-radius files read and current patterns catalogued." },
420
432
  { id: "design_scope_challenge_done", description: "Step 0 scope challenge completed with existing-code mapping." },
421
433
  { id: "design_architecture_locked", description: "Architecture boundaries are explicit and approved." },
422
434
  { id: "design_data_flow_mapped", description: "Data/state flow includes edge-case paths." },
@@ -428,7 +440,8 @@ const DESIGN = {
428
440
  "Failure-mode table exists with mitigations.",
429
441
  "Test strategy includes unit/integration/e2e expectations.",
430
442
  "NOT-in-scope section produced.",
431
- "What-already-exists section produced."
443
+ "What-already-exists section produced.",
444
+ "Completion dashboard lists every review section status, decision count, and unresolved items (or 'None')."
432
445
  ],
433
446
  inputs: ["scope contract", "system constraints", "non-functional requirements"],
434
447
  requiredContext: [
@@ -441,7 +454,8 @@ const DESIGN = {
441
454
  "risk and failure map",
442
455
  "test and performance baseline",
443
456
  "NOT-in-scope section",
444
- "What-already-exists section"
457
+ "What-already-exists section",
458
+ "design completion dashboard"
445
459
  ],
446
460
  blockers: [
447
461
  "architecture ambiguity remains",
@@ -452,6 +466,7 @@ const DESIGN = {
452
466
  "design baseline approved",
453
467
  "all review sections completed",
454
468
  "required gates marked satisfied",
469
+ "completion dashboard present with all review-section statuses",
455
470
  "artifact complete for spec handoff"
456
471
  ],
457
472
  antiPatterns: [
@@ -459,20 +474,26 @@ const DESIGN = {
459
474
  "Missing data-flow edge cases",
460
475
  "No performance budget for critical path",
461
476
  "Batching multiple design issues into one question",
462
- "Skipping review sections because plan seems simple"
477
+ "Skipping review sections because plan seems simple",
478
+ "Agreeing with user's architecture choice without evaluating alternatives",
479
+ "Hedging every recommendation with 'it depends' instead of taking a position"
463
480
  ],
464
481
  rationalizations: [
465
482
  { claim: "Architecture can emerge incrementally while coding.", reality: "Unplanned architecture decisions cause incompatible module boundaries." },
466
483
  { claim: "Failure modes are edge cases we can ignore for now.", reality: "Production incidents usually come from unplanned edge paths." },
467
484
  { claim: "Performance can be optimized after launch.", reality: "Missing performance budgets make regressions invisible until late." },
468
- { claim: "This is a strategy doc so implementation sections do not apply.", reality: "Implementation details are where strategy breaks down. Every section must be evaluated." }
485
+ { claim: "This is a strategy doc so implementation sections do not apply.", reality: "Implementation details are where strategy breaks down. Every section must be evaluated." },
486
+ { claim: "The user preferred approach A, so we should go with it.", reality: "User preference is an input, not a conclusion. Evaluate on engineering merit. If approach B is objectively better, recommend B with evidence." },
487
+ { claim: "Both options are roughly equivalent.", reality: "Options are never equivalent once you quantify effort (S/M/L/XL) and risk (Low/Med/High). If you cannot distinguish them, you have not investigated deeply enough." }
469
488
  ],
470
489
  redFlags: [
471
490
  "No explicit architecture boundary section",
472
491
  "No failure recovery strategy",
473
492
  "No defined test/perf baseline",
474
493
  "Review sections skipped or condensed",
475
- "No NOT-in-scope output section"
494
+ "No NOT-in-scope output section",
495
+ "No What-already-exists output section",
496
+ "Design decisions made without reading the actual code first"
476
497
  ],
477
498
  policyNeedles: [
478
499
  "Architecture",
@@ -490,7 +511,10 @@ const DESIGN = {
490
511
  { name: "Essential vs Accidental Complexity", description: "Before adding anything: is this solving a real problem or one we created? Distinguish essential complexity from accidental." },
491
512
  { name: "Blast Radius Instinct", description: "Every decision evaluated through: what is the worst case and how many systems/people does it affect?" },
492
513
  { name: "Completeness Push", description: "AI effort is cheap. Push for completeness in plans: cover all files in blast radius, all edge cases in touched code, all affected tests. Favor doing it now over creating a TODO." },
493
- { name: "Owner Preference Alignment", description: "Every recommendation must align with project conventions (DRY, test style, minimal diff, edge-case rigor). Read existing patterns before recommending new ones." }
514
+ { name: "Owner Preference Alignment", description: "Every recommendation must align with project conventions (DRY, test style, minimal diff, edge-case rigor). Read existing patterns before recommending new ones." },
515
+ { name: "Failure Is Information", description: "A design that fails fast and visibly is better than one that silently degrades. Map every failure mode and make it observable. Undetected failures compound." },
516
+ { name: "Search Breadth Before Depth", description: "Before committing to a design path, survey the full solution space: stdlib, existing code, open-source, prior art. A 30-minute search can save a 30-hour custom build." },
517
+ { name: "Outside Voice", description: "When confidence is high and options seem obvious, that is exactly when to seek contradiction. Ask: what would a skeptical reviewer challenge here? What assumption am I not questioning?" }
494
518
  ],
495
519
  reviewSections: [
496
520
  {
@@ -555,12 +579,15 @@ const DESIGN = {
555
579
  },
556
580
  artifactValidation: [
557
581
  { section: "Architecture Boundaries", required: true, validationRule: "Must list component boundaries with ownership." },
582
+ { section: "Architecture Diagram", required: true, validationRule: "At least one diagram (ASCII, Mermaid, or image) showing component boundaries and data flow direction." },
558
583
  { section: "Data Flow", required: true, validationRule: "Must include happy path, nil input, empty input, upstream error paths." },
559
584
  { section: "Failure Mode Table", required: true, validationRule: "Each failure mode has: trigger, detection, mitigation, user impact." },
560
585
  { section: "Test Strategy", required: true, validationRule: "Must define unit/integration/e2e expectations with coverage targets." },
586
+ { section: "What Already Exists", required: true, validationRule: "For each sub-problem: existing code/library found (Layer 1-3/EUREKA label), reuse decision, and adaptation needed." },
561
587
  { section: "NOT in scope", required: true, validationRule: "Work considered and explicitly deferred with one-line rationale." },
562
588
  { section: "Parallelization Strategy", required: false, validationRule: "If multi-module: dependency table, parallel lanes, conflict flags." },
563
- { section: "Unresolved Decisions", required: false, validationRule: "If any: what info is missing, who provides it, default if unanswered." }
589
+ { section: "Unresolved Decisions", required: false, validationRule: "If any: what info is missing, who provides it, default if unanswered." },
590
+ { section: "Completion Dashboard", required: true, validationRule: "Lists every review section with status (clear / issues-found-resolved / issues-open), decision count, and unresolved items (or 'None')." }
564
591
  ],
565
592
  namedAntiPattern: {
566
593
  title: "Architecture Will Emerge While Coding",
@@ -76,6 +76,14 @@ export const ARTIFACT_TEMPLATES = {
76
76
  - [ ] hold
77
77
  - [ ] reduce
78
78
 
79
+ ## Mode-Specific Analysis
80
+ - **Selected mode:**
81
+ - **Analysis:**
82
+ - (EXPAND: 10x opportunities, delight features)
83
+ - (SELECTIVE: hold-scope baseline, cherry-picked expansions)
84
+ - (HOLD: minimum-change-set hardening)
85
+ - (REDUCE: ruthless cuts, follow-up split)
86
+
79
87
  ## In Scope / Out of Scope
80
88
 
81
89
  ### In Scope
@@ -110,11 +118,34 @@ export const ARTIFACT_TEMPLATES = {
110
118
  `,
111
119
  "03-design.md": `# Design Artifact
112
120
 
121
+ ## Codebase Investigation
122
+ | File | Current responsibility | Patterns discovered |
123
+ |---|---|---|
124
+ | | | |
125
+
126
+ ## Search Before Building
127
+ | Layer | Label | What to reuse first |
128
+ |---|---|---|
129
+ | Layer 1 | | |
130
+ | Layer 2 | | |
131
+ | Layer 3 | | |
132
+
113
133
  ## Architecture Boundaries
114
134
  | Component | Responsibility | Owner |
115
135
  |---|---|---|
116
136
  | | | |
117
137
 
138
+ ## Architecture Diagram
139
+
140
+ \\\`\\\`\\\`
141
+ (ASCII, Mermaid, or tool-generated diagram showing component boundaries and data flow direction)
142
+ \\\`\\\`\\\`
143
+
144
+ ## What Already Exists
145
+ | Sub-problem | Existing code/library | Layer | Reuse decision |
146
+ |---|---|---|---|
147
+ | | | | |
148
+
118
149
  ## Data Flow
119
150
  - Happy path:
120
151
  - Nil/empty input path:
@@ -142,6 +173,17 @@ export const ARTIFACT_TEMPLATES = {
142
173
  | Decision | Missing info | Owner | Default |
143
174
  |---|---|---|---|
144
175
  | | | | |
176
+
177
+ ## Completion Dashboard
178
+ | Review Section | Status | Issues |
179
+ |---|---|---|
180
+ | Architecture Review | | |
181
+ | Code Quality Review | | |
182
+ | Test Review | | |
183
+ | Performance Review | | |
184
+ | Distribution & Delivery Review | | |
185
+
186
+ **Decisions made:** 0 | **Unresolved:** 0
145
187
  `,
146
188
  "04-spec.md": `# Specification Artifact
147
189
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cclaw-cli",
3
- "version": "0.5.7",
3
+ "version": "0.5.9",
4
4
  "description": "Installer-first flow toolkit for coding agents",
5
5
  "type": "module",
6
6
  "bin": {