cclaw-cli 0.46.0 → 0.46.2

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.
@@ -17,6 +17,7 @@ export type LearningEntryType = "rule" | "pattern" | "lesson" | "compound";
17
17
  export type LearningConfidence = "high" | "medium" | "low";
18
18
  export type LearningUniversality = "project" | "personal" | "universal";
19
19
  export type LearningMaturity = "raw" | "lifted-to-rule" | "lifted-to-enforcement";
20
+ export type LearningSource = "stage" | "retro" | "compound" | "ideate" | "manual";
20
21
  export interface LearningSeedEntry {
21
22
  type: LearningEntryType;
22
23
  trigger: string;
@@ -33,6 +34,7 @@ export interface LearningSeedEntry {
33
34
  first_seen_ts?: string;
34
35
  last_seen_ts?: string;
35
36
  project?: string | null;
37
+ source?: LearningSource | null;
36
38
  }
37
39
  export interface LearningsParseResult {
38
40
  ok: boolean;
@@ -43,7 +45,6 @@ export interface LearningsParseResult {
43
45
  }
44
46
  export declare function parseLearningsSection(sectionBody: string): LearningsParseResult;
45
47
  export declare function lintArtifact(projectRoot: string, stage: FlowStage): Promise<LintResult>;
46
- export declare function lintAllArtifacts(projectRoot: string): Promise<LintResult[]>;
47
48
  export declare function validateReviewArmy(projectRoot: string): Promise<{
48
49
  valid: boolean;
49
50
  errors: string[];
@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { RUNTIME_ROOT } from "./constants.js";
4
4
  import { exists } from "./fs-utils.js";
5
- import { orderedStageSchemas, stageSchema } from "./content/stage-schema.js";
5
+ import { stageSchema } from "./content/stage-schema.js";
6
6
  import { FLOW_STAGES } from "./types.js";
7
7
  async function resolveArtifactPath(projectRoot, fileName) {
8
8
  const relPath = path.join(RUNTIME_ROOT, "artifacts", fileName);
@@ -223,6 +223,13 @@ const LEARNING_TYPE_SET = new Set(["rule", "pattern", "lesson", "compound"]);
223
223
  const LEARNING_CONFIDENCE_SET = new Set(["high", "medium", "low"]);
224
224
  const LEARNING_UNIVERSALITY_SET = new Set(["project", "personal", "universal"]);
225
225
  const LEARNING_MATURITY_SET = new Set(["raw", "lifted-to-rule", "lifted-to-enforcement"]);
226
+ const LEARNING_SOURCE_SET = new Set([
227
+ "stage",
228
+ "retro",
229
+ "compound",
230
+ "ideate",
231
+ "manual"
232
+ ]);
226
233
  const FLOW_STAGE_SET = new Set(FLOW_STAGES);
227
234
  const LEARNING_ALLOWED_KEYS = new Set([
228
235
  "type",
@@ -239,7 +246,8 @@ const LEARNING_ALLOWED_KEYS = new Set([
239
246
  "created",
240
247
  "first_seen_ts",
241
248
  "last_seen_ts",
242
- "project"
249
+ "project",
250
+ "source"
243
251
  ]);
244
252
  function isIsoUtcTimestamp(value) {
245
253
  return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/u.test(value);
@@ -312,6 +320,14 @@ function parseLearningSeedEntry(raw, index) {
312
320
  if (obj.project !== undefined && !isNullableString(obj.project)) {
313
321
  return { ok: false, error: `Learnings bullet #${index} field "project" must be string or null.` };
314
322
  }
323
+ if (obj.source !== undefined &&
324
+ obj.source !== null &&
325
+ (typeof obj.source !== "string" || !LEARNING_SOURCE_SET.has(obj.source))) {
326
+ return {
327
+ ok: false,
328
+ error: `Learnings bullet #${index} field "source" must be stage|retro|compound|ideate|manual or null.`
329
+ };
330
+ }
315
331
  if (obj.frequency !== undefined &&
316
332
  (typeof obj.frequency !== "number" || !Number.isInteger(obj.frequency) || obj.frequency < 1)) {
317
333
  return { ok: false, error: `Learnings bullet #${index} field "frequency" must be an integer >= 1.` };
@@ -822,13 +838,6 @@ export async function lintArtifact(projectRoot, stage) {
822
838
  const passed = findings.every((f) => !f.required || f.found);
823
839
  return { stage, file: relFile, passed, findings };
824
840
  }
825
- export async function lintAllArtifacts(projectRoot) {
826
- const out = [];
827
- for (const schema of orderedStageSchemas()) {
828
- out.push(await lintArtifact(projectRoot, schema.stage));
829
- }
830
- return out;
831
- }
832
841
  function isNonEmptyString(v) {
833
842
  return typeof v === "string" && v.length > 0;
834
843
  }
@@ -18,7 +18,7 @@ function tierDescription(tier) {
18
18
  return "full native automation";
19
19
  if (tier === "tier2")
20
20
  return "partial automation with waivers";
21
- return "manual fallback only";
21
+ return "compatibility shim";
22
22
  }
23
23
  export function harnessIntegrationDocMarkdown() {
24
24
  const harnesses = Object.keys(HARNESS_ADAPTERS);
@@ -67,7 +67,6 @@ ${hookRows}
67
67
 
68
68
  - \`tier1\`: full native delegation + structured asks + full hook surface.
69
69
  - \`tier2\`: usable flow with capability gaps; mandatory delegation can require waivers.
70
- - \`tier3\`: manual-only fallback; no native automation guarantees.
71
70
  - Codex-specific ceiling: \`PreToolUse\` can only intercept \`Bash\`. Direct
72
71
  \`Write\`/\`Edit\` to \`.cclaw/state/flow-state.json\` cannot be hard-blocked
73
72
  at hook level, so the canonical path is
@@ -82,7 +81,6 @@ All harnesses receive the same utility commands:
82
81
  - \`/cc-next\` - stage progression
83
82
  - \`/cc-ideate\` - discovery mode for ranked repo-improvement backlog
84
83
  - \`/cc-view\` - read-only router for status/tree/diff
85
- - \`/cc-learn\` - knowledge capture/lookup
86
84
  - \`/cc-ops\` - operations router for feature/tdd-log/retro/compound/archive/rewind
87
85
 
88
86
  Read-only subcommands:
@@ -1,9 +1,2 @@
1
1
  export declare function ideateCommandContract(): string;
2
2
  export declare function ideateCommandSkillMarkdown(): string;
3
- /**
4
- * Exposed for tests and docs that need to mention the artifact convention
5
- * without hard-coding the path string in two places.
6
- */
7
- export declare const IDEATION_ARTIFACT_PATH_PATTERN = ".cclaw/artifacts/ideation-<YYYY-MM-DD-slug>.md";
8
- export declare const IDEATION_ARTIFACT_GLOB_PATTERN = ".cclaw/artifacts/ideation-*.md";
9
- export declare const IDEATION_RESUME_WINDOW = 30;
@@ -208,10 +208,3 @@ lettered list with the same four labels. Do not invent extra options.
208
208
  option in the handoff prompt must reference a concrete command.
209
209
  `;
210
210
  }
211
- /**
212
- * Exposed for tests and docs that need to mention the artifact convention
213
- * without hard-coding the path string in two places.
214
- */
215
- export const IDEATION_ARTIFACT_PATH_PATTERN = IDEATION_ARTIFACT_PATTERN;
216
- export const IDEATION_ARTIFACT_GLOB_PATTERN = IDEATION_ARTIFACT_GLOB;
217
- export const IDEATION_RESUME_WINDOW = IDEATION_RESUME_WINDOW_DAYS;
@@ -1,6 +1,7 @@
1
1
  /**
2
- * Canonical JSONL field order (matches the reference spec).
3
- * Exported for tests and any programmatic writer that wants the exact shape.
2
+ * Canonical required JSONL field order (matches strict validator keys).
3
+ * Optional keys (for now: `source`) may be appended after these required fields.
4
+ * Exported for tests and any programmatic writer that wants a stable base shape.
4
5
  */
5
6
  export declare const KNOWLEDGE_JSONL_FIELDS: readonly ["type", "trigger", "action", "confidence", "domain", "stage", "origin_stage", "origin_feature", "frequency", "universality", "maturity", "created", "first_seen_ts", "last_seen_ts", "project"];
6
7
  export declare function learnSkillMarkdown(): string;
@@ -10,8 +10,9 @@ const KNOWLEDGE_ARCHIVE_PATH = ".cclaw/knowledge.archive.jsonl";
10
10
  const LEARN_SKILL_NAME = "learnings";
11
11
  const LEARN_SKILL_DESCRIPTION = "Project-scoped knowledge store: append and query rule/pattern/lesson/compound entries in the canonical JSONL file at .cclaw/knowledge.jsonl. Strict schema, append-only, machine-queryable.";
12
12
  /**
13
- * Canonical JSONL field order (matches the reference spec).
14
- * Exported for tests and any programmatic writer that wants the exact shape.
13
+ * Canonical required JSONL field order (matches strict validator keys).
14
+ * Optional keys (for now: `source`) may be appended after these required fields.
15
+ * Exported for tests and any programmatic writer that wants a stable base shape.
15
16
  */
16
17
  export const KNOWLEDGE_JSONL_FIELDS = [
17
18
  "type",
@@ -71,8 +72,9 @@ Do not invent alternate stores (no markdown mirror, no SQLite, no per-stage file
71
72
 
72
73
  ## Entry format — strict JSONL schema
73
74
 
74
- Exactly one JSON object per line. Fields must appear in the order:
75
+ Exactly one JSON object per line. Required fields must appear in the order:
75
76
  \`type, trigger, action, confidence, domain, stage, origin_stage, origin_feature, frequency, universality, maturity, created, first_seen_ts, last_seen_ts, project\`.
77
+ Optional field \`source\` may be appended after \`project\`.
76
78
 
77
79
  \`\`\`json
78
80
  {"type":"pattern","trigger":"when reviewing external payloads","action":"parse through zod before touching service layer","confidence":"high","domain":"api","stage":"review","origin_stage":"review","origin_feature":"payload-hardening","frequency":1,"universality":"project","maturity":"raw","created":"2026-04-14T12:00:00Z","first_seen_ts":"2026-04-14T12:00:00Z","last_seen_ts":"2026-04-14T12:00:00Z","project":"cclaw"}
@@ -95,9 +97,10 @@ Exactly one JSON object per line. Fields must appear in the order:
95
97
  | \`first_seen_ts\` | ISO 8601 UTC string | yes | First observed timestamp (usually equals \`created\`). |
96
98
  | \`last_seen_ts\` | ISO 8601 UTC string | yes | Last re-confirmed timestamp. |
97
99
  | \`project\` | string \\| null | yes | Repo or scope name. Use \`null\` when the entry crosses projects. |
100
+ | \`source\` | \`"stage" \\| "retro" \\| "compound" \\| "ideate" \\| "manual" \\| null\` | no | Origin channel for the entry when known. |
98
101
 
99
102
  Rules:
100
- - No other fields. Extra keys are forbidden and MUST be rejected by any writer.
103
+ - No other fields beyond the table above. Extra keys are forbidden and MUST be rejected by any writer.
101
104
  - Every required-null field must be emitted explicitly as \`null\` (not omitted). This keeps the file grep-friendly.
102
105
  - Append-only: never rewrite or delete a historical line. Corrections are new
103
106
  entries whose \`trigger\` clearly supersedes the earlier one.
@@ -167,7 +170,7 @@ Do not edit source code from this command. Only operate on \`${KNOWLEDGE_PATH}\`
167
170
  |---|---|---|
168
171
  | (default) | — | Show recent knowledge entries (tail of JSONL, pretty-printed). |
169
172
  | \`search\` | \`<query>\` | Stream-filter the JSONL for matching \`trigger\`, \`action\`, \`domain\`, \`project\`. |
170
- | \`add\` | — | Append one JSON line (\`rule\` / \`pattern\` / \`lesson\` / \`compound\`) with the strict 15-field schema. |
173
+ | \`add\` | — | Append one JSON line (\`rule\` / \`pattern\` / \`lesson\` / \`compound\`) with the strict JSONL schema (15 required fields + optional \`source\`). |
171
174
  | \`curate\` | — | Hand off to the **knowledge-curation** skill: read-only audit + soft-archive plan when the file exceeds the curation threshold. |
172
175
  `;
173
176
  }
@@ -58,7 +58,7 @@ in the structured ask; there is no \`--skip\` flag.
58
58
  - \`skip\` — record \`retroSkipped: true\` + one-line reason, no compound entry required.
59
59
  6. On **accept**:
60
60
  - append >=1 strict-schema JSONL line to \`${knowledgePath()}\` with
61
- \`type: "compound"\` and \`stage: "retro"\`,
61
+ \`type: "compound"\`, \`source: "retro"\`, and \`stage: null\`,
62
62
  - set \`retro.required = true\`, \`retro.completedAt = <ISO>\`,
63
63
  \`retro.compoundEntries = <count>\`,
64
64
  - set \`closeout.retroAcceptedAt = <ISO>\`,
@@ -121,7 +121,7 @@ Do not silently skip. Do not finalize without updating \`flow-state.json\`.
121
121
  > - **skip** — no retro this run (requires one-line reason).
122
122
 
123
123
  4. Apply the state transition for the chosen option:
124
- - \`accept\` → append \`{ "type": "compound", "stage": "retro", ... }\` line
124
+ - \`accept\` → append \`{ "type": "compound", "source": "retro", "stage": null, ... }\` line
125
125
  to \`${knowledgePath()}\`; set \`retro.completedAt\`, \`retro.compoundEntries\`,
126
126
  \`closeout.retroAcceptedAt\`; set \`closeout.shipSubstate = "compound_review"\`.
127
127
  - \`edit\` → leave \`shipSubstate = "retro_review"\`; announce resume path.
@@ -3,13 +3,10 @@ import type { StageAutoSubagentDispatch, StageSchema } from "./stages/schema-typ
3
3
  export type { ArtifactValidation, CrossStageTrace, ReviewSection, StageAutoSubagentDispatch, StageGate, StageSchema, StageSchemaInput } from "./stages/schema-types.js";
4
4
  /** Transition guard: agents with `mode: "mandatory"` in auto-subagent dispatch for this stage. */
5
5
  export declare function mandatoryDelegationsForStage(stage: FlowStage): string[];
6
- /** Conditional dispatches that become mandatory only when their `condition` predicate evaluates true. */
7
- export declare function conditionalDispatchesForStage(stage: FlowStage): StageAutoSubagentDispatch[];
8
6
  export declare function stageSchema(stage: FlowStage): StageSchema;
9
7
  export declare function orderedStageSchemas(): StageSchema[];
10
8
  export declare function stageGateIds(stage: FlowStage): string[];
11
9
  export declare function stageRecommendedGateIds(stage: FlowStage): string[];
12
- export declare function stageConditionalGateIds(stage: FlowStage): string[];
13
10
  export declare function nextCclawCommand(stage: FlowStage): string;
14
11
  export declare function buildTransitionRules(): TransitionRule[];
15
12
  export declare function stagePolicyNeedles(stage: FlowStage): string[];
@@ -10,7 +10,6 @@ import { BRAINSTORM, SCOPE, DESIGN, SPEC, PLAN, TDD, REVIEW, SHIP } from "./stag
10
10
  * Gate tiers:
11
11
  * - required: blocking for stage completion.
12
12
  * - recommended: quality signal; unmet -> DONE_WITH_CONCERNS, not BLOCKED.
13
- * - conditional: becomes blocking only when triggered.
14
13
  */
15
14
  const REQUIRED_GATE_IDS = {
16
15
  brainstorm: [
@@ -196,8 +195,7 @@ const STAGE_AUTO_SUBAGENT_DISPATCH = {
196
195
  },
197
196
  {
198
197
  agent: "reviewer",
199
- mode: "conditional",
200
- condition: "diff_lines_gt:100||files_touched_gt:10||trust_boundary_changed",
198
+ mode: "proactive",
201
199
  when: "When the diff exceeds 100 changed lines, touches more than 10 files, or modifies trust boundaries — dispatch a SECOND, independent reviewer with the adversarial-review skill loaded so the review army has at least two voices on a high-blast-radius change.",
202
200
  purpose: "Adversarial second-opinion review on large or trust-sensitive diffs. The second reviewer treats the implementation as hostile and tries to break it (hostile-user, future-maintainer, competitor lenses) instead of sympathetically explaining it.",
203
201
  requiresUserGate: false,
@@ -227,10 +225,6 @@ export function mandatoryDelegationsForStage(stage) {
227
225
  .filter((d) => d.mode === "mandatory")
228
226
  .map((d) => d.agent);
229
227
  }
230
- /** Conditional dispatches that become mandatory only when their `condition` predicate evaluates true. */
231
- export function conditionalDispatchesForStage(stage) {
232
- return STAGE_AUTO_SUBAGENT_DISPATCH[stage].filter((d) => d.mode === "conditional");
233
- }
234
228
  export function stageSchema(stage) {
235
229
  const base = STAGE_SCHEMA_MAP[stage];
236
230
  const tieredGates = tieredStageGates(stage, base.requiredGates);
@@ -255,11 +249,6 @@ export function stageRecommendedGateIds(stage) {
255
249
  .filter((gate) => gate.tier === "recommended")
256
250
  .map((gate) => gate.id);
257
251
  }
258
- export function stageConditionalGateIds(stage) {
259
- // Conditional gate DSL removed in favor of explicit required/recommended tiers.
260
- void stage;
261
- return [];
262
- }
263
252
  export function nextCclawCommand(stage) {
264
253
  const next = stageSchema(stage).next;
265
254
  return next === "done" ? "none" : `/cc-${next}`;
@@ -54,8 +54,6 @@ export const BRAINSTORM = {
54
54
  "Handoff to scope only after approval is explicit."
55
55
  ],
56
56
  requiredGates: [
57
- { id: "brainstorm_context_explored", description: "Project context (files, docs, existing patterns) was checked before asking questions." },
58
- { id: "brainstorm_idea_understood", description: "Agent and user share the same understanding of the problem, constraints, and success criteria." },
59
57
  { id: "brainstorm_approaches_compared", description: "2-3 architecturally distinct approaches were compared with real trade-offs and a recommendation." },
60
58
  { id: "brainstorm_direction_approved", description: "User approved a concrete direction and what exactly was approved is stated." },
61
59
  { id: "brainstorm_artifact_reviewed", description: "User reviewed the written brainstorm artifact and confirmed readiness." }
@@ -123,10 +121,10 @@ export const BRAINSTORM = {
123
121
  artifactValidation: [
124
122
  { section: "Context", required: true, validationRule: "Must reference project state and relevant existing code or patterns." },
125
123
  { section: "Problem", required: true, validationRule: "Must define what we're solving, success criteria, and constraints." },
126
- { section: "Clarifying Questions", required: true, validationRule: "Must capture question, answer, and decision impact for each clarifying question." },
124
+ { section: "Clarifying Questions", required: false, validationRule: "Must capture question, answer, and decision impact for each clarifying question." },
127
125
  { section: "Approaches", required: true, validationRule: "Must compare 2-3 architecturally distinct options with real trade-offs and recommendation." },
128
126
  { section: "Selected Direction", required: true, validationRule: "Must include the selected approach, rationale, and explicit approval marker." },
129
- { section: "Design", required: true, validationRule: "Must cover architecture, key components, and data flow scaled to complexity." },
130
- { section: "Assumptions and Open Questions", required: true, validationRule: "Must capture unresolved assumptions/open questions, or explicitly state none." }
127
+ { section: "Design", required: false, validationRule: "Must cover architecture, key components, and data flow scaled to complexity." },
128
+ { section: "Assumptions and Open Questions", required: false, validationRule: "Must capture unresolved assumptions/open questions, or explicitly state none." }
131
129
  ]
132
130
  };
@@ -62,8 +62,6 @@ export const DESIGN = {
62
62
  "Write design lock artifact for downstream spec/plan."
63
63
  ],
64
64
  requiredGates: [
65
- { id: "design_codebase_investigated", description: "Blast-radius files read and current patterns catalogued." },
66
- { id: "design_scope_challenge_done", description: "Step 0 scope challenge completed with existing-code mapping." },
67
65
  { id: "design_architecture_locked", description: "Architecture boundaries are explicit and approved." },
68
66
  { id: "design_data_flow_mapped", description: "Data/state flow includes edge-case paths." },
69
67
  { id: "design_failure_modes_mapped", description: "Failure modes and mitigations are documented." },
@@ -193,16 +191,16 @@ export const DESIGN = {
193
191
  traceabilityRule: "Every architecture decision must trace to a scope boundary. Every downstream spec requirement must trace to a design decision."
194
192
  },
195
193
  artifactValidation: [
196
- { section: "Codebase Investigation", required: true, validationRule: "Must list blast-radius files with current responsibilities and discovered patterns." },
197
- { section: "Search Before Building", required: true, validationRule: "For each technical choice: Layer 1 (exact match), Layer 2 (partial match), Layer 3 (inspiration), EUREKA labels with reuse-first default." },
194
+ { section: "Codebase Investigation", required: false, validationRule: "Must list blast-radius files with current responsibilities and discovered patterns." },
195
+ { section: "Search Before Building", required: false, validationRule: "For each technical choice: Layer 1 (exact match), Layer 2 (partial match), Layer 3 (inspiration), EUREKA labels with reuse-first default." },
198
196
  { section: "Architecture Boundaries", required: true, validationRule: "Must list component boundaries with ownership." },
199
197
  { section: "Architecture Diagram", required: true, validationRule: "At least one diagram (ASCII, Mermaid, or image) showing component boundaries and data flow direction. Diagram must: (1) label every node with a concrete component name (no generic 'Service A/B'), (2) label every arrow with the action or message (no unlabeled arrows), (3) mark direction of data flow explicitly, (4) distinguish synchronous from asynchronous edges (e.g. solid vs dashed, or `sync:` / `async:` prefix), (5) include at least one failure/degraded edge line that contains an arrow plus a failure keyword (`timeout`, `error`, `fallback`, `degraded`, `retry`, etc.)." },
200
- { section: "Data Flow", required: true, validationRule: "Must include happy path, nil input, empty input, upstream error paths." },
198
+ { section: "Data Flow", required: false, validationRule: "Must include happy path, nil input, empty input, upstream error paths." },
201
199
  { section: "Failure Mode Table", required: true, validationRule: "Each failure mode has: trigger, detection, mitigation, user impact." },
202
- { section: "Test Strategy", required: true, validationRule: "Must define unit/integration/e2e expectations with coverage targets." },
203
- { section: "Performance Budget", required: true, validationRule: "For each critical path: metric name, target threshold, and measurement method." },
204
- { 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." },
205
- { section: "NOT in scope", required: true, validationRule: "Work considered and explicitly deferred with one-line rationale." },
200
+ { section: "Test Strategy", required: false, validationRule: "Must define unit/integration/e2e expectations with coverage targets." },
201
+ { section: "Performance Budget", required: false, validationRule: "For each critical path: metric name, target threshold, and measurement method." },
202
+ { section: "What Already Exists", required: false, validationRule: "For each sub-problem: existing code/library found (Layer 1-3/EUREKA label), reuse decision, and adaptation needed." },
203
+ { section: "NOT in scope", required: false, validationRule: "Work considered and explicitly deferred with one-line rationale." },
206
204
  { section: "Parallelization Strategy", required: false, validationRule: "If multi-module: dependency table, parallel lanes, conflict flags." },
207
205
  { section: "Unresolved Decisions", required: false, validationRule: "If any: what info is missing, who provides it, default if unanswered." },
208
206
  { section: "Interface Contracts", required: false, validationRule: "If present: for each module boundary list produces (outputs) and consumes (inputs) with data types." },
@@ -51,9 +51,7 @@ export const PLAN = {
51
51
  ],
52
52
  requiredGates: [
53
53
  { id: "plan_tasks_sliced_2_5_min", description: "Tasks are small, executable slices." },
54
- { id: "plan_dependency_graph_written", description: "Dependency graph and order are explicit." },
55
54
  { id: "plan_dependency_batches_defined", description: "Tasks are grouped into executable batches with gate checks." },
56
- { id: "plan_verification_steps_defined", description: "Each task has verification guidance." },
57
55
  { id: "plan_acceptance_mapped", description: "Each task maps to a spec acceptance criterion." },
58
56
  { id: "plan_wait_for_confirm", description: "Execution blocked until explicit user confirmation." }
59
57
  ],
@@ -143,7 +141,7 @@ export const PLAN = {
143
141
  traceabilityRule: "Every task must trace to a spec acceptance criterion. Every locked scope decision (D-XX) must trace to at least one plan task or explicit defer rationale. Every downstream RED test must trace to a plan task."
144
142
  },
145
143
  artifactValidation: [
146
- { section: "Dependency Graph", required: true, validationRule: "Ordering and parallel opportunities explicit. No circular dependencies." },
144
+ { section: "Dependency Graph", required: false, validationRule: "Ordering and parallel opportunities explicit. No circular dependencies." },
147
145
  { section: "Dependency Batches", required: true, validationRule: "Every task belongs to a batch. Each batch has an exit gate and dependency statement." },
148
146
  { section: "Task List", required: true, validationRule: "Each task row includes ID, description, acceptance criterion, verification command, and effort estimate (S/M/L). Every task must also carry a minutes estimate within the 2-5 minute budget. When the sliceReview feature is enabled in the cclaw config, each task row additionally declares touchCount, touchPaths, and an optional highRisk flag so the TDD stage can decide whether a Per-Slice Review pass is required." },
149
147
  { section: "Acceptance Mapping", required: true, validationRule: "Every spec criterion is covered by at least one task." },
@@ -56,15 +56,9 @@ export const REVIEW = {
56
56
  ],
57
57
  requiredGates: [
58
58
  { id: "review_layer1_spec_compliance", description: "Spec compliance check completed with per-criterion verdict." },
59
- { id: "review_layer2_correctness", description: "Correctness review completed." },
60
59
  { id: "review_layer2_security", description: "Security review completed." },
61
- { id: "review_layer2_performance", description: "Performance review completed." },
62
- { id: "review_layer2_architecture", description: "Architecture fit review completed." },
63
- { id: "review_severity_classified", description: "All findings are severity-tagged." },
64
60
  { id: "review_criticals_resolved", description: "No unresolved critical blockers remain." },
65
- { id: "review_army_json_valid", description: "07-review-army.json passes schema validation (validateReviewArmy)." },
66
- { id: "review_completeness_scored", description: "Completeness score is computed and recorded (AC coverage, task coverage, slice coverage, adversarial pass)." },
67
- { id: "review_security_audit_swept", description: "The security-audit utility skill was run against the diff scope and the modules it touches. Finding count (0 if clean) recorded in the review army with file:line evidence for every Critical." }
61
+ { id: "review_army_json_valid", description: "07-review-army.json passes schema validation (validateReviewArmy)." }
68
62
  ],
69
63
  requiredEvidence: [
70
64
  "Artifact written to `.cclaw/artifacts/07-review.md`.",
@@ -205,10 +199,10 @@ export const REVIEW = {
205
199
  },
206
200
  artifactValidation: [
207
201
  { section: "Layer 1 Verdict", required: true, validationRule: "Per-criterion pass/fail with references." },
208
- { section: "Layer 2 Findings", required: true, validationRule: "Each finding has severity, description, and resolution status." },
202
+ { section: "Layer 2 Findings", required: false, validationRule: "Each finding has severity, description, and resolution status." },
209
203
  { section: "Review Army Contract", required: true, validationRule: "Structured findings include id/severity/confidence/fingerprint/reportedBy/status with dedup reconciliation summary." },
210
- { section: "Review Readiness Dashboard", required: true, validationRule: "Includes a per-pass table (Layer 1 / Layer 2 / Adversarial / Schema) with a 'Completed at' column, a Delegation log snapshot block (path .cclaw/state/delegation-log.json with required/completed/waived/pending), a Staleness signal block (commit at last review pass and current commit), and a Headline with open critical blockers + ship recommendation. At minimum, the section text must contain the substrings 'Completed at', 'delegation-log.json', 'commit at last review pass', and 'Ship recommendation'." },
211
- { section: "Completeness Score", required: true, validationRule: "Records AC coverage, task coverage, test-slice coverage, and adversarial-review pass status as numeric or boolean values. At minimum, a line like 'AC coverage: N/M' or 'AC coverage: 100%'." },
204
+ { section: "Review Readiness Dashboard", required: false, validationRule: "Includes a per-pass table (Layer 1 / Layer 2 / Adversarial / Schema) with a 'Completed at' column, a Delegation log snapshot block (path .cclaw/state/delegation-log.json with required/completed/waived/pending), a Staleness signal block (commit at last review pass and current commit), and a Headline with open critical blockers + ship recommendation. At minimum, the section text must contain the substrings 'Completed at', 'delegation-log.json', 'commit at last review pass', and 'Ship recommendation'." },
205
+ { section: "Completeness Score", required: false, validationRule: "Records AC coverage, task coverage, test-slice coverage, and adversarial-review pass status as numeric or boolean values. At minimum, a line like 'AC coverage: N/M' or 'AC coverage: 100%'." },
212
206
  { section: "Severity Summary", required: true, validationRule: "Per-severity count lines for critical, important, and suggestion buckets." },
213
207
  { section: "Final Verdict", required: true, validationRule: "Exactly one of: APPROVED, APPROVED_WITH_CONCERNS, BLOCKED." }
214
208
  ]
@@ -2,9 +2,7 @@ import type { FlowStage } from "../../types.js";
2
2
  export interface StageGate {
3
3
  id: string;
4
4
  description: string;
5
- tier?: "required" | "recommended" | "conditional";
6
- /** Used when tier=conditional. Predicate syntax mirrors conditional delegation rules. */
7
- condition?: string;
5
+ tier?: "required" | "recommended";
8
6
  }
9
7
  export interface ReviewSection {
10
8
  title: string;
@@ -19,9 +17,7 @@ export interface CrossStageTrace {
19
17
  export interface ArtifactValidation {
20
18
  section: string;
21
19
  required: boolean;
22
- tier?: "required" | "recommended" | "conditional";
23
- /** Optional predicate for conditional validations. */
24
- condition?: string;
20
+ tier?: "required" | "recommended";
25
21
  validationRule: string;
26
22
  }
27
23
  export interface StageAutoSubagentDispatch {
@@ -29,20 +25,11 @@ export interface StageAutoSubagentDispatch {
29
25
  /**
30
26
  * - `mandatory` — must be dispatched (or explicitly waived) before stage transition.
31
27
  * - `proactive` — should be dispatched automatically when context matches `when`.
32
- * - `conditional` — dispatched only when `condition` evaluates true at runtime; counted as
33
- * mandatory **only when the condition holds**.
34
28
  */
35
- mode: "mandatory" | "proactive" | "conditional";
29
+ mode: "mandatory" | "proactive";
36
30
  when: string;
37
31
  purpose: string;
38
32
  requiresUserGate: boolean;
39
- /**
40
- * Optional machine-friendly trigger expression for `conditional` rows.
41
- * Supported predicates: `diff_lines_gt:<N>`, `files_touched_gt:<N>`,
42
- * `trust_boundary_changed`, `release_blast_radius_high`.
43
- * Multiple predicates joined by `||` mean ANY trigger satisfies the condition.
44
- */
45
- condition?: string;
46
33
  /** Optional skill folder the dispatched agent should load as additional context. */
47
34
  skill?: string;
48
35
  }
@@ -55,11 +55,8 @@ export const SCOPE = {
55
55
  "Produce scope summary plus completion dashboard (checklist findings, number of resolved decisions, unresolved items or `None`)."
56
56
  ],
57
57
  requiredGates: [
58
- { id: "scope_premise_challenged", description: "Problem framing and assumptions were challenged." },
59
- { id: "scope_alternatives_produced", description: "At least 2 implementation alternatives were evaluated with explicit effort/risk and reuse fields." },
60
58
  { id: "scope_mode_selected", description: "One scope mode was explicitly selected." },
61
59
  { id: "scope_contract_written", description: "In-scope/out-of-scope contract is documented." },
62
- { id: "scope_discretion_documented", description: "Discretion areas are documented (or explicitly marked as none)." },
63
60
  { id: "scope_user_approved", description: "User approved the final scope direction." }
64
61
  ],
65
62
  requiredEvidence: [
@@ -172,17 +169,17 @@ export const SCOPE = {
172
169
  traceabilityRule: "Every scope boundary must be traceable to a brainstorm decision. Every downstream design choice must stay within the scope contract."
173
170
  },
174
171
  artifactValidation: [
175
- { 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." },
176
- { section: "Premise Challenge", required: true, validationRule: "Must contain explicit answers to: right problem? direct path? what if nothing?" },
177
- { 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`." },
172
+ { section: "Prime Directives", required: false, validationRule: "For each scoped capability: named failure modes, explicit error surface, four data-flow paths, interaction edge cases, observability expectations, and deferred-item handling." },
173
+ { section: "Premise Challenge", required: false, validationRule: "Must contain explicit answers to: right problem? direct path? what if nothing?" },
174
+ { section: "Requirements", required: false, 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`." },
178
175
  { 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." },
179
- { 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." },
176
+ { section: "Implementation Alternatives", required: false, validationRule: "2-3 options with Name, Summary, Effort, Risk, Pros, Cons, and Reuses. Must include minimal viable and ideal architecture options." },
180
177
  { section: "Scope Mode", required: true, validationRule: "Must state selected mode and rationale with default heuristic justification." },
181
- { 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)." },
178
+ { section: "Mode-Specific Analysis", required: false, 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)." },
182
179
  { section: "In Scope / Out of Scope", required: true, validationRule: "Two separate explicit lists. Out-of-scope must not be empty." },
183
- { section: "Discretion Areas", required: true, validationRule: "Explicit list of implementer decision zones, or 'None' if scope is fully locked." },
184
- { section: "Deferred Items", required: true, validationRule: "Each item has one-line rationale. If empty, state 'None' explicitly." },
185
- { section: "Error & Rescue Registry", required: true, validationRule: "Each scoped capability has: failure mode, detection method, fallback decision." },
180
+ { section: "Discretion Areas", required: false, validationRule: "Explicit list of implementer decision zones, or 'None' if scope is fully locked." },
181
+ { section: "Deferred Items", required: false, validationRule: "Each item has one-line rationale. If empty, state 'None' explicitly." },
182
+ { section: "Error & Rescue Registry", required: false, validationRule: "Each scoped capability has: failure mode, detection method, fallback decision." },
186
183
  { section: "Completion Dashboard", required: true, validationRule: "Lists checklist findings, count of resolved decisions, and unresolved decisions (or 'None')." },
187
184
  { section: "Scope Summary", required: true, validationRule: "Clean summary: mode, strongest challenges, recommended path, accepted scope, deferred, excluded." },
188
185
  { section: "Dream State Mapping", required: false, validationRule: "If present (complex projects): CURRENT STATE, THIS PLAN, 12-MONTH IDEAL, and alignment verdict." },
@@ -50,11 +50,8 @@ export const SHIP = {
50
50
  requiredGates: [
51
51
  { id: "ship_review_verdict_valid", description: "Review verdict is APPROVED or APPROVED_WITH_CONCERNS." },
52
52
  { id: "ship_preflight_passed", description: "Preflight checks passed or exceptions documented and approved." },
53
- { id: "ship_release_notes_written", description: "Release notes are complete and accurate." },
54
53
  { id: "ship_rollback_plan_ready", description: "Rollback trigger, steps, and verification are documented." },
55
- { id: "ship_finalization_mode_selected", description: "Exactly one finalization action is selected." },
56
- { id: "ship_finalization_executed", description: "Selected finalization action was executed and verified." },
57
- { id: "ship_post_merge_tests", description: "Full test suite re-run on the merged result (not just the branch). Post-merge failures caught before release." }
54
+ { id: "ship_finalization_executed", description: "Selected finalization action was executed and verified." }
58
55
  ],
59
56
  requiredEvidence: [
60
57
  "Artifact written to `.cclaw/artifacts/08-ship.md`.",
@@ -46,8 +46,6 @@ export const SPEC = {
46
46
  ],
47
47
  requiredGates: [
48
48
  { id: "spec_acceptance_measurable", description: "Acceptance criteria are measurable and observable." },
49
- { id: "spec_edge_cases_documented", description: "Boundary and error conditions are defined for each criterion." },
50
- { id: "spec_constraints_documented", description: "Constraints and assumptions are explicit." },
51
49
  { id: "spec_testability_confirmed", description: "Each criterion has a described test method." },
52
50
  { id: "spec_user_approved", description: "User approved the final written spec." }
53
51
  ],
@@ -125,7 +123,7 @@ export const SPEC = {
125
123
  artifactValidation: [
126
124
  { section: "Acceptance Criteria", required: true, validationRule: "Each criterion is observable, measurable, and falsifiable. Table must include a Requirement Ref column linking to R# IDs in 02-scope.md and a Design Decision Ref column tracing back to design artifact. AC IDs (AC-1, AC-2…) are stable across revisions — dropped ACs stay with Priority `DROPPED`." },
127
125
  { section: "Edge Cases", required: true, validationRule: "At least one boundary and one error condition per criterion." },
128
- { section: "Constraints and Assumptions", required: true, validationRule: "All implicit assumptions surfaced. Constraints have sources." },
126
+ { section: "Constraints and Assumptions", required: false, validationRule: "All implicit assumptions surfaced. Constraints have sources." },
129
127
  { section: "Testability Map", required: true, validationRule: "Each criterion maps to a concrete test description with verification approach (unit, integration, e2e, manual) and command or manual steps." },
130
128
  { section: "Vague to Fixed", required: false, validationRule: "If present: table with original vague wording and rewritten observable/testable version for each ambiguous requirement." },
131
129
  { section: "Non-Functional Requirements", required: false, validationRule: "If present: performance thresholds, security constraints, scalability limits, reliability targets with measurable values." },
@@ -57,12 +57,8 @@ export const TDD = {
57
57
  ],
58
58
  requiredGates: [
59
59
  { id: "tdd_red_test_written", description: "Failing tests exist before implementation changes." },
60
- { id: "tdd_red_failure_captured", description: "Failure output is captured as evidence." },
61
- { id: "tdd_trace_to_acceptance", description: "RED tests trace to explicit acceptance criteria." },
62
- { id: "tdd_red_failure_reason_verified", description: "Failure is for the expected reason, not an unrelated error." },
63
60
  { id: "tdd_green_full_suite", description: "Full relevant suite passes in GREEN state." },
64
61
  { id: "tdd_refactor_completed", description: "Refactor pass completed with behavior preservation verified." },
65
- { id: "tdd_refactor_notes_written", description: "Refactor decisions and outcomes are documented." },
66
62
  { id: "tdd_traceable_to_plan", description: "Change traceability to plan slice is explicit." }
67
63
  ],
68
64
  requiredEvidence: [
@@ -173,8 +169,8 @@ export const TDD = {
173
169
  },
174
170
  artifactValidation: [
175
171
  { section: "RED Evidence", required: true, validationRule: "Failing test output captured per slice." },
176
- { section: "Acceptance Mapping", required: true, validationRule: "Each RED test links to a plan task and spec criterion." },
177
- { section: "Failure Analysis", required: true, validationRule: "Failure reason matches expected missing behavior." },
172
+ { section: "Acceptance Mapping", required: false, validationRule: "Each RED test links to a plan task and spec criterion." },
173
+ { section: "Failure Analysis", required: false, validationRule: "Failure reason matches expected missing behavior." },
178
174
  { section: "GREEN Evidence", required: true, validationRule: "Full suite pass output captured." },
179
175
  { section: "REFACTOR Notes", required: true, validationRule: "What changed, why, behavior preservation confirmed." },
180
176
  { section: "Traceability", required: true, validationRule: "Plan task ID and spec criterion linked." },
@@ -19,7 +19,7 @@ export function startCommandContract() {
19
19
  **The unified entry point for the cclaw flow.**
20
20
 
21
21
  - \`/cc\` (no arguments) → behaves exactly like \`/cc-next\`: reads flow state and resumes the current stage, or starts brainstorm if the flow is fresh.
22
- - \`/cc <prompt>\` (with an idea/description) → saves the prompt as brainstorm context and begins the brainstorm stage, regardless of current flow state.
22
+ - \`/cc <prompt>\` (with an idea/description) → saves the prompt as idea context and starts the first stage of the resolved track.
23
23
 
24
24
  This is the **recommended way to start** working with cclaw. Use \`/cc-next\` for subsequent stage progression.
25
25
 
@@ -63,7 +63,7 @@ This is the **recommended way to start** working with cclaw. Use \`/cc-next\` fo
63
63
  Skip detection quietly if no markers are found — do NOT invent a stack.
64
64
 
65
65
  4. Read \`${flowPath}\`.
66
- 5. If flow already has completed stages beyond brainstorm, warn the user that starting a new brainstorm will reset progress. Ask for confirmation before proceeding.
66
+ 5. If flow already has completed stages, warn the user that starting a new tracked flow will reset progress. Ask for confirmation before proceeding.
67
67
  6. **Track heuristic** — classify the idea text and **recommend** a track (the user can override before any state mutation):
68
68
  - First, load \`${RUNTIME_ROOT}/config.yaml\`. If \`trackHeuristics\` is defined, apply those per-track vocabulary hints (\`fallback\`, \`tracks.<id>.{triggers,veto}\`) on top of the built-in defaults. Evaluation order is always \`standard -> medium -> quick\` (narrow-to-broad).
69
69
  - **quick** (\`spec → tdd → review → ship\`) — single-purpose work where the spec is essentially already known.
@@ -137,7 +137,7 @@ Do **not** silently discard an existing flow when the user provides a prompt. If
137
137
  3. **Stack detection (Phase 2).** Inspect \`package.json\` engines, \`pyproject.toml\`, \`go.mod\`, \`Cargo.toml\`, \`pom.xml\`, \`build.gradle*\`, \`Dockerfile\`, \`docker-compose*.yml\`, and CI configs. Record stack + versions on the \`Stack:\` line. Do not invent stack details.
138
138
  4. Read \`${flowPath}\`.
139
139
  5. If \`completedStages\` is non-empty:
140
- - Inform: "You have an active flow at stage **{currentStage}** with {N} completed stages. Starting a new brainstorm will reset progress."
140
+ - Inform: "You have an active flow at stage **{currentStage}** with {N} completed stages. Starting a new tracked flow will reset progress."
141
141
  - Ask: "Continue with reset? (A) Yes, start fresh (B) No, resume current flow"
142
142
  - If (B) → switch to Path B behavior.
143
143
  6. **Classify the idea** using the heuristic below and present a single track recommendation. Wait for explicit confirmation or override before mutating any state.
@@ -149,7 +149,7 @@ Do **not** silently discard an existing flow when the user provides a prompt. If
149
149
  |---|---|---|
150
150
  | \`quick\` | \`bug\`, \`bugfix\`, \`fix\`, \`hotfix\`, \`patch\`, \`typo\`, \`regression\`, \`rename\`, \`bump\`, \`upgrade dep\`, \`docs only\`, \`comment\`, \`lint\`, \`format\`, \`small\`, \`tiny\`, \`one-liner\`, \`revert\`, \`copy change\` | Single-purpose, spec is essentially known, low blast radius |
151
151
  | \`medium\` | \`add endpoint\`, \`add field\`, \`extend existing\`, \`wire integration\`, \`small migration\`, \`new screen following existing pattern\` | Additive work with existing architecture |
152
- | \`standard\` | \`new feature\`, \`build\`, \`design\`, \`refactor\`, \`migration\`, \`platform\`, \`architecture\`, \`schema\`, \`api\`, \`integrate\`, \`workflow\`, \`onboarding\` (or no confident quick/medium match) | New or uncertain multi-module work |
152
+ | \`standard\` | \`new feature\`, \`refactor\`, \`migration\`, \`platform\`, \`architecture\`, \`schema\`, \`integrate\`, \`workflow\`, \`onboarding\` (or no confident quick/medium match) | New or uncertain multi-module work |
153
153
 
154
154
  - On conflict, prefer \`standard\` over \`medium\`, and \`medium\` over \`quick\`.
155
155
  - Always state the recommendation as a one-line reason citing matched triggers.
@@ -180,6 +180,6 @@ Delegate entirely to \`/cc-next\` behavior:
180
180
  | Progressing after completing a stage | \`/cc-next\` |
181
181
  | Starting with a specific idea | \`/cc <idea>\` |
182
182
 
183
- Both commands read the same \`flow-state.json\`. The difference is that \`/cc <prompt>\` always targets brainstorm, while \`/cc\` and \`/cc-next\` follow the state.
183
+ Both commands read the same \`flow-state.json\`. The difference is that \`/cc <prompt>\` resolves class + track and starts that track's first stage, while \`/cc\` and \`/cc-next\` follow the current state.
184
184
  `;
185
185
  }