cclaw-cli 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.js +83 -3
- package/dist/content/examples.js +88 -0
- package/dist/content/hooks.js +81 -11
- package/dist/content/meta-skill.d.ts +0 -8
- package/dist/content/meta-skill.js +51 -341
- package/dist/content/next-command.js +2 -1
- package/dist/content/protocols.d.ts +7 -0
- package/dist/content/protocols.js +95 -0
- package/dist/content/skills.js +183 -313
- package/dist/content/stage-common-guidance.d.ts +2 -0
- package/dist/content/stage-common-guidance.js +71 -0
- package/dist/content/stage-schema.d.ts +8 -0
- package/dist/content/stage-schema.js +135 -1
- package/dist/content/start-command.js +19 -13
- package/dist/doctor.js +21 -23
- package/dist/flow-state.d.ts +4 -0
- package/dist/flow-state.js +4 -1
- package/dist/gate-evidence.d.ts +9 -1
- package/dist/gate-evidence.js +121 -17
- package/dist/install.js +10 -0
- package/dist/policy.js +16 -13
- package/dist/runs.js +21 -4
- package/dist/track-heuristics.d.ts +12 -0
- package/dist/track-heuristics.js +144 -0
- package/dist/types.d.ts +26 -3
- package/dist/types.js +6 -3
- package/package.json +1 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { RUNTIME_ROOT } from "../constants.js";
|
|
2
|
+
export const STAGE_COMMON_GUIDANCE_REL_PATH = `${RUNTIME_ROOT}/references/stages/common-guidance.md`;
|
|
3
|
+
export function stageCommonGuidanceMarkdown() {
|
|
4
|
+
return `# Common Stage Guidance
|
|
5
|
+
|
|
6
|
+
Shared guidance loaded by every stage skill. Keep this file concise and stable so
|
|
7
|
+
per-stage skills can stay focused on stage-specific work.
|
|
8
|
+
|
|
9
|
+
## Shared completion protocol
|
|
10
|
+
|
|
11
|
+
- Stage-specific skills expose **Completion Parameters** only.
|
|
12
|
+
- Generic execution steps live in \`.cclaw/references/protocols/completion.md\`.
|
|
13
|
+
- Do not restate the protocol in each stage file.
|
|
14
|
+
|
|
15
|
+
## Shared decision protocol
|
|
16
|
+
|
|
17
|
+
- Decision wording, ask-tool format, retry budget, and escalation rules live in
|
|
18
|
+
\`.cclaw/references/protocols/decision.md\`.
|
|
19
|
+
- Stage files should reference that path, not duplicate the full text.
|
|
20
|
+
|
|
21
|
+
## Shared handoff menu
|
|
22
|
+
|
|
23
|
+
Use this same closeout menu for every stage:
|
|
24
|
+
|
|
25
|
+
- **A) Advance** — run \`/cc-next\` and continue.
|
|
26
|
+
- **B) Revise this stage** — stay on current stage and apply feedback.
|
|
27
|
+
- **C) Pause / park** — stop now and resume later.
|
|
28
|
+
- **D) Rewind** — move to a prior stage explicitly chosen by the user.
|
|
29
|
+
- **E) Abandon** — cancel this flow; artifacts remain on disk.
|
|
30
|
+
|
|
31
|
+
Recommendation defaults:
|
|
32
|
+
|
|
33
|
+
- Completion status \`DONE\` -> recommend **A**.
|
|
34
|
+
- Completion status \`DONE_WITH_CONCERNS\` -> recommend **B**.
|
|
35
|
+
- Completion status \`BLOCKED\` -> recommend **B** or **C**.
|
|
36
|
+
|
|
37
|
+
## Completion status vocabulary
|
|
38
|
+
|
|
39
|
+
- \`DONE\` — all required gates and checks satisfied.
|
|
40
|
+
- \`DONE_WITH_CONCERNS\` — required gates pass, but recommended items remain.
|
|
41
|
+
- \`BLOCKED\` — one or more required/triggered conditions fail.
|
|
42
|
+
|
|
43
|
+
## Decision record template
|
|
44
|
+
|
|
45
|
+
Use when a stage makes a non-trivial architecture/scope/testing decision.
|
|
46
|
+
|
|
47
|
+
\`\`\`
|
|
48
|
+
Decision: <one-line title>
|
|
49
|
+
Context: <what forced this decision>
|
|
50
|
+
Options considered:
|
|
51
|
+
- A: ...
|
|
52
|
+
- B: ...
|
|
53
|
+
Chosen option: <A/B/...>
|
|
54
|
+
Why: <short rationale>
|
|
55
|
+
Risk: <main downside>
|
|
56
|
+
Rollback / fallback: <if decision proves wrong>
|
|
57
|
+
\`\`\`
|
|
58
|
+
|
|
59
|
+
## Self-improvement reminder
|
|
60
|
+
|
|
61
|
+
If a reusable lesson appears during the stage, append one strict-schema JSONL
|
|
62
|
+
entry via \`/cc-learn add\`. Do not keep operational lessons only in chat.
|
|
63
|
+
|
|
64
|
+
## Progressive disclosure baseline
|
|
65
|
+
|
|
66
|
+
- Start with the current stage skill.
|
|
67
|
+
- Load deeper references only when required by a blocker or gate.
|
|
68
|
+
- Prefer \`.cclaw/references/stages/<stage>-examples.md\` and protocol files over
|
|
69
|
+
copying large instruction blocks into stage skills.
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
@@ -2,6 +2,9 @@ import type { FlowStage, TransitionRule } 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
8
|
}
|
|
6
9
|
export interface StageRationalization {
|
|
7
10
|
claim: string;
|
|
@@ -24,6 +27,9 @@ export interface CrossStageTrace {
|
|
|
24
27
|
export interface ArtifactValidation {
|
|
25
28
|
section: string;
|
|
26
29
|
required: boolean;
|
|
30
|
+
tier?: "required" | "recommended" | "conditional";
|
|
31
|
+
/** Optional predicate for conditional validations. */
|
|
32
|
+
condition?: string;
|
|
27
33
|
validationRule: string;
|
|
28
34
|
}
|
|
29
35
|
export interface StageAutoSubagentDispatch {
|
|
@@ -106,6 +112,8 @@ export declare function conditionalDispatchesForStage(stage: FlowStage): StageAu
|
|
|
106
112
|
export declare function stageSchema(stage: FlowStage): StageSchema;
|
|
107
113
|
export declare function orderedStageSchemas(): StageSchema[];
|
|
108
114
|
export declare function stageGateIds(stage: FlowStage): string[];
|
|
115
|
+
export declare function stageRecommendedGateIds(stage: FlowStage): string[];
|
|
116
|
+
export declare function stageConditionalGateIds(stage: FlowStage): string[];
|
|
109
117
|
export declare function nextCclawCommand(stage: FlowStage): string;
|
|
110
118
|
export declare function buildTransitionRules(): TransitionRule[];
|
|
111
119
|
export declare function stagePolicyNeedles(stage: FlowStage): string[];
|
|
@@ -1,4 +1,122 @@
|
|
|
1
1
|
import { COMMAND_FILE_ORDER } from "../constants.js";
|
|
2
|
+
/**
|
|
3
|
+
* Gate tiers:
|
|
4
|
+
* - required: blocking for stage completion.
|
|
5
|
+
* - recommended: quality signal; unmet -> DONE_WITH_CONCERNS, not BLOCKED.
|
|
6
|
+
* - conditional: becomes blocking only when triggered.
|
|
7
|
+
*/
|
|
8
|
+
const REQUIRED_GATE_IDS = {
|
|
9
|
+
brainstorm: [
|
|
10
|
+
"brainstorm_approaches_compared",
|
|
11
|
+
"brainstorm_direction_approved",
|
|
12
|
+
"brainstorm_artifact_reviewed"
|
|
13
|
+
],
|
|
14
|
+
scope: [
|
|
15
|
+
"scope_mode_selected",
|
|
16
|
+
"scope_contract_written",
|
|
17
|
+
"scope_user_approved"
|
|
18
|
+
],
|
|
19
|
+
design: [
|
|
20
|
+
"design_architecture_locked",
|
|
21
|
+
"design_data_flow_mapped",
|
|
22
|
+
"design_failure_modes_mapped",
|
|
23
|
+
"design_test_and_perf_defined"
|
|
24
|
+
],
|
|
25
|
+
spec: [
|
|
26
|
+
"spec_acceptance_measurable",
|
|
27
|
+
"spec_testability_confirmed",
|
|
28
|
+
"spec_user_approved"
|
|
29
|
+
],
|
|
30
|
+
plan: [
|
|
31
|
+
"plan_tasks_sliced_2_5_min",
|
|
32
|
+
"plan_dependency_waves_defined",
|
|
33
|
+
"plan_acceptance_mapped",
|
|
34
|
+
"plan_wait_for_confirm"
|
|
35
|
+
],
|
|
36
|
+
tdd: [
|
|
37
|
+
"tdd_red_test_written",
|
|
38
|
+
"tdd_green_full_suite",
|
|
39
|
+
"tdd_refactor_completed",
|
|
40
|
+
"tdd_traceable_to_plan"
|
|
41
|
+
],
|
|
42
|
+
review: [
|
|
43
|
+
"review_layer1_spec_compliance",
|
|
44
|
+
"review_layer2_security",
|
|
45
|
+
"review_criticals_resolved",
|
|
46
|
+
"review_army_json_valid"
|
|
47
|
+
],
|
|
48
|
+
ship: [
|
|
49
|
+
"ship_review_verdict_valid",
|
|
50
|
+
"ship_preflight_passed",
|
|
51
|
+
"ship_rollback_plan_ready",
|
|
52
|
+
"ship_finalization_executed"
|
|
53
|
+
]
|
|
54
|
+
};
|
|
55
|
+
const CONDITIONAL_GATE_RULES = {
|
|
56
|
+
review: {
|
|
57
|
+
review_security_audit_swept: "diff_lines_gt:100||files_touched_gt:10||trust_boundary_changed"
|
|
58
|
+
},
|
|
59
|
+
ship: {
|
|
60
|
+
ship_post_merge_tests: "files_touched_gt:10||release_blast_radius_high"
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const REQUIRED_ARTIFACT_SECTIONS = {
|
|
64
|
+
brainstorm: ["Context", "Problem", "Approaches", "Selected Direction"],
|
|
65
|
+
scope: ["Scope Mode", "In Scope / Out of Scope", "Completion Dashboard", "Scope Summary"],
|
|
66
|
+
design: ["Architecture Boundaries", "Architecture Diagram", "Failure Mode Table", "Completion Dashboard"],
|
|
67
|
+
spec: ["Acceptance Criteria", "Edge Cases", "Testability Map", "Approval"],
|
|
68
|
+
plan: ["Task List", "Dependency Waves", "Acceptance Mapping", "WAIT_FOR_CONFIRM"],
|
|
69
|
+
tdd: ["RED Evidence", "GREEN Evidence", "REFACTOR Notes", "Traceability"],
|
|
70
|
+
review: ["Layer 1 Verdict", "Review Army Contract", "Severity Summary", "Final Verdict"],
|
|
71
|
+
ship: ["Preflight Results", "Release Notes", "Rollback Plan", "Finalization"]
|
|
72
|
+
};
|
|
73
|
+
const CONDITIONAL_ARTIFACT_RULES = {
|
|
74
|
+
review: {
|
|
75
|
+
"Review Readiness Dashboard": "diff_lines_gt:100||files_touched_gt:10||trust_boundary_changed"
|
|
76
|
+
},
|
|
77
|
+
ship: {
|
|
78
|
+
Monitoring: "release_blast_radius_high"
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
function tieredStageGates(stage, gates) {
|
|
82
|
+
const requiredSet = new Set(REQUIRED_GATE_IDS[stage]);
|
|
83
|
+
const conditional = CONDITIONAL_GATE_RULES[stage] ?? {};
|
|
84
|
+
return gates.map((gate) => {
|
|
85
|
+
const condition = conditional[gate.id];
|
|
86
|
+
if (condition) {
|
|
87
|
+
return {
|
|
88
|
+
...gate,
|
|
89
|
+
tier: "conditional",
|
|
90
|
+
condition
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
...gate,
|
|
95
|
+
tier: requiredSet.has(gate.id) ? "required" : "recommended"
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function tieredArtifactValidation(stage, rows) {
|
|
100
|
+
const requiredSections = new Set(REQUIRED_ARTIFACT_SECTIONS[stage]);
|
|
101
|
+
const conditional = CONDITIONAL_ARTIFACT_RULES[stage] ?? {};
|
|
102
|
+
return rows.map((row) => {
|
|
103
|
+
const condition = conditional[row.section];
|
|
104
|
+
if (condition) {
|
|
105
|
+
return {
|
|
106
|
+
...row,
|
|
107
|
+
tier: "conditional",
|
|
108
|
+
condition,
|
|
109
|
+
required: false
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const required = requiredSections.has(row.section);
|
|
113
|
+
return {
|
|
114
|
+
...row,
|
|
115
|
+
tier: required ? "required" : "recommended",
|
|
116
|
+
required
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
}
|
|
2
120
|
const BRAINSTORM = {
|
|
3
121
|
stage: "brainstorm",
|
|
4
122
|
skillFolder: "brainstorming",
|
|
@@ -1689,8 +1807,12 @@ export function conditionalDispatchesForStage(stage) {
|
|
|
1689
1807
|
}
|
|
1690
1808
|
export function stageSchema(stage) {
|
|
1691
1809
|
const base = STAGE_SCHEMA_MAP[stage];
|
|
1810
|
+
const tieredGates = tieredStageGates(stage, base.requiredGates);
|
|
1811
|
+
const tieredValidation = tieredArtifactValidation(stage, base.artifactValidation);
|
|
1692
1812
|
return {
|
|
1693
1813
|
...base,
|
|
1814
|
+
requiredGates: tieredGates,
|
|
1815
|
+
artifactValidation: tieredValidation,
|
|
1694
1816
|
mandatoryDelegations: mandatoryDelegationsForStage(stage)
|
|
1695
1817
|
};
|
|
1696
1818
|
}
|
|
@@ -1698,7 +1820,19 @@ export function orderedStageSchemas() {
|
|
|
1698
1820
|
return COMMAND_FILE_ORDER.map((stage) => stageSchema(stage));
|
|
1699
1821
|
}
|
|
1700
1822
|
export function stageGateIds(stage) {
|
|
1701
|
-
return stageSchema(stage).requiredGates
|
|
1823
|
+
return stageSchema(stage).requiredGates
|
|
1824
|
+
.filter((gate) => gate.tier === "required")
|
|
1825
|
+
.map((gate) => gate.id);
|
|
1826
|
+
}
|
|
1827
|
+
export function stageRecommendedGateIds(stage) {
|
|
1828
|
+
return stageSchema(stage).requiredGates
|
|
1829
|
+
.filter((gate) => gate.tier === "recommended")
|
|
1830
|
+
.map((gate) => gate.id);
|
|
1831
|
+
}
|
|
1832
|
+
export function stageConditionalGateIds(stage) {
|
|
1833
|
+
return stageSchema(stage).requiredGates
|
|
1834
|
+
.filter((gate) => gate.tier === "conditional")
|
|
1835
|
+
.map((gate) => gate.id);
|
|
1702
1836
|
}
|
|
1703
1837
|
export function nextCclawCommand(stage) {
|
|
1704
1838
|
const next = stageSchema(stage).next;
|
|
@@ -25,7 +25,7 @@ This is the **recommended way to start** working with cclaw. Use \`/cc-next\` fo
|
|
|
25
25
|
## HARD-GATE
|
|
26
26
|
|
|
27
27
|
- **Do not** skip reading \`${flowPath}\` — always check current state before acting.
|
|
28
|
-
- **Do not** start implementation stages directly from \`/cc <prompt>\` — always begin at the first stage of the resolved track (brainstorm for standard, spec for quick).
|
|
28
|
+
- **Do not** start implementation stages directly from \`/cc <prompt>\` — always begin at the first stage of the resolved track (brainstorm for medium/standard, spec for quick).
|
|
29
29
|
- **Do not** start a stage pipeline for a task that is not a software change (pure question, non-software task, conversation).
|
|
30
30
|
|
|
31
31
|
## Algorithm
|
|
@@ -40,6 +40,7 @@ This is the **recommended way to start** working with cclaw. Use \`/cc-next\` fo
|
|
|
40
40
|
| **pure-question** | "how does X work?", "explain Y", "what are the trade-offs of Z?" | Answer directly, do NOT open a stage. |
|
|
41
41
|
| **trivial** | typo, one-liner, rename, config tweak, copy change, version bump with zero behavior change | Fast-path: skip \`brainstorm\` and \`scope\`, seed \`00-idea.md\`, move straight to \`design\` or \`spec\` depending on whether an interface change is involved. |
|
|
42
42
|
| **software — bug fix with repro** | regression / hotfix / named symptom + repro steps | Fast-path: set track to \`quick\`, seed \`04-spec.md\` with the reproduction, enter \`tdd\` with a RED reproduction test first. |
|
|
43
|
+
| **software — medium** | additive feature following existing architecture | medium track (\`brainstorm → spec → plan → tdd → review → ship\`). |
|
|
43
44
|
| **software — standard** | feature, refactor, migration, integration, architecture change | Full 8-stage flow starting at \`brainstorm\`. |
|
|
44
45
|
|
|
45
46
|
Record the chosen class in \`.cclaw/artifacts/00-idea.md\` on the \`Class:\` line. Do NOT silently treat a non-software task as software.
|
|
@@ -63,20 +64,23 @@ This is the **recommended way to start** working with cclaw. Use \`/cc-next\` fo
|
|
|
63
64
|
4. Read \`${flowPath}\`.
|
|
64
65
|
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.
|
|
65
66
|
6. **Track heuristic** — classify the idea text and **recommend** a track (the user can override before any state mutation):
|
|
67
|
+
- First, load \`${RUNTIME_ROOT}/config.yaml\`. If \`trackHeuristics\` is defined, apply those per-track rules (\`priority\`, \`fallback\`, \`tracks.<id>.{triggers,patterns,veto}\`) before built-in defaults.
|
|
66
68
|
- **quick** (\`spec → tdd → review → ship\`) — single-purpose work where the spec is essentially already known.
|
|
67
69
|
Triggers (case-insensitive substring or close variant): \`bug\`, \`bugfix\`, \`fix\`, \`hotfix\`, \`patch\`, \`typo\`, \`regression\`, \`copy change\`, \`rename\`, \`bump\`, \`upgrade dep\`, \`config tweak\`, \`docs only\`, \`comment\`, \`lint\`, \`format\`, \`small\`, \`tiny\`, \`one-liner\`, \`revert\`.
|
|
68
|
-
- **
|
|
69
|
-
Triggers: \`
|
|
70
|
-
-
|
|
70
|
+
- **medium** (\`brainstorm → spec → plan → tdd → review → ship\`) — additive work that fits existing architecture and still needs product framing.
|
|
71
|
+
Triggers: \`add endpoint\`, \`add field\`, \`extend existing\`, \`wire integration\`, \`small migration\`, \`new screen following existing patterns\`.
|
|
72
|
+
- **standard** (full 8 stages — default fallback) — anything that introduces a new capability with architecture uncertainty, touches many modules, or has unclear scope.
|
|
73
|
+
Triggers: \`new feature\`, \`refactor\`, \`migration\`, \`platform\`, \`architecture\`, \`schema\`, \`integrate\`, \`workflow\`, \`onboarding\`, or any prompt that does not match quick/medium confidently.
|
|
74
|
+
- When triggers conflict, prefer **standard** over **medium**, and **medium** over **quick**.
|
|
71
75
|
7. Present the recommendation as a single decision with explicit options:
|
|
72
|
-
> \`Recommended track: <quick|standard>\` because \`<one-line reason citing matched triggers>\`.
|
|
73
|
-
> Override? (A) keep \`<recommended>\` (B) switch
|
|
76
|
+
> \`Recommended track: <quick|medium|standard>\` because \`<one-line reason citing matched triggers>\`.
|
|
77
|
+
> Override? (A) keep \`<recommended>\` (B) switch track (C) cancel.
|
|
74
78
|
If \`AskQuestion\`/\`AskUserQuestion\` is available, send exactly ONE question; on schema error, fall back to plain text.
|
|
75
|
-
8. Persist the chosen track to \`${flowPath}\` (\`track\` field). Compute \`skippedStages\` from the track and write that too. Use the **first stage of the chosen track** as \`currentStage\` (quick → \`spec\`, standard → \`brainstorm\`, trivial fast-path → \`design\` or \`spec\` per Phase 0).
|
|
79
|
+
8. Persist the chosen track to \`${flowPath}\` (\`track\` field). Compute \`skippedStages\` from the track and write that too. Use the **first stage of the chosen track** as \`currentStage\` (quick → \`spec\`, medium/standard → \`brainstorm\`, trivial fast-path → \`design\` or \`spec\` per Phase 0).
|
|
76
80
|
9. Write the prompt to \`.cclaw/artifacts/00-idea.md\` with the following header lines: \`Class:\` (from Phase 0), \`Track:\` (chosen track + matched heuristic), \`Stack:\` (from Phase 2 detection, or \`unknown\`), and a \`Discovered context\` section if Phase 1 found origin docs.
|
|
77
81
|
10. Load the **first-stage skill for the chosen track** and its command file:
|
|
78
82
|
- quick → \`.cclaw/skills/specification-authoring/SKILL.md\` + \`.cclaw/commands/spec.md\`
|
|
79
|
-
- standard → \`.cclaw/skills/brainstorming/SKILL.md\` + \`.cclaw/commands/brainstorm.md\`
|
|
83
|
+
- medium/standard → \`.cclaw/skills/brainstorming/SKILL.md\` + \`.cclaw/commands/brainstorm.md\`
|
|
80
84
|
- trivial fast-path → design or spec skill per Phase 0 decision.
|
|
81
85
|
11. Execute that stage with the prompt + Phase 1/Phase 2 context as initial input.
|
|
82
86
|
|
|
@@ -136,19 +140,21 @@ Do **not** silently discard an existing flow when the user provides a prompt. If
|
|
|
136
140
|
- Ask: "Continue with reset? (A) Yes, start fresh (B) No, resume current flow"
|
|
137
141
|
- If (B) → switch to Path B behavior.
|
|
138
142
|
6. **Classify the idea** using the heuristic below and present a single track recommendation. Wait for explicit confirmation or override before mutating any state.
|
|
143
|
+
- If \`${RUNTIME_ROOT}/config.yaml\` defines \`trackHeuristics\`, apply that override first (priority/fallback/rules), then use built-in defaults only as fallback.
|
|
139
144
|
|
|
140
145
|
**Track heuristic** (lowercase substring match against the user prompt):
|
|
141
146
|
|
|
142
147
|
| Track | Triggers | Use when |
|
|
143
148
|
|---|---|---|
|
|
144
149
|
| \`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 |
|
|
145
|
-
| \`
|
|
150
|
+
| \`medium\` | \`add endpoint\`, \`add field\`, \`extend existing\`, \`wire integration\`, \`small migration\`, \`new screen following existing pattern\` | Additive work with existing architecture |
|
|
151
|
+
| \`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 |
|
|
146
152
|
|
|
147
|
-
- On conflict, prefer \`standard\`
|
|
148
|
-
- Always state the recommendation as a one-line reason citing
|
|
149
|
-
7. Persist the chosen track in \`${flowPath}\` (\`track\` + \`skippedStages\`). Set \`currentStage\` to the first stage of the chosen track (\`quick\` → \`spec\`, \`standard\` → \`brainstorm\`, trivial fast-path → \`design\` or \`spec\`). Reset gate catalog.
|
|
153
|
+
- On conflict, prefer \`standard\` over \`medium\`, and \`medium\` over \`quick\`.
|
|
154
|
+
- Always state the recommendation as a one-line reason citing matched triggers.
|
|
155
|
+
7. Persist the chosen track in \`${flowPath}\` (\`track\` + \`skippedStages\`). Set \`currentStage\` to the first stage of the chosen track (\`quick\` → \`spec\`, \`medium\`/ \`standard\` → \`brainstorm\`, trivial fast-path → \`design\` or \`spec\`). Reset gate catalog.
|
|
150
156
|
8. Write \`${RUNTIME_ROOT}/artifacts/00-idea.md\` with the user's prompt plus header lines: \`Class:\`, \`Track:\`, \`Stack:\`, and a \`Discovered context\` section from Phase 1.
|
|
151
|
-
9. Load and execute the **first stage skill of the chosen track** (\`brainstorming\` for standard, \`specification-authoring\` for quick) plus its matching command file.
|
|
157
|
+
9. Load and execute the **first stage skill of the chosen track** (\`brainstorming\` for medium/standard, \`specification-authoring\` for quick) plus its matching command file.
|
|
152
158
|
|
|
153
159
|
### Reclassification on discovery
|
|
154
160
|
|
package/dist/doctor.js
CHANGED
|
@@ -278,8 +278,8 @@ export async function doctorChecks(projectRoot, options = {}) {
|
|
|
278
278
|
{ id: "iron_law", pattern: /^\*\*IRON LAW — [A-Z]+:\*\* .+$/m, label: "Iron Law punchcard (<EXTREMELY-IMPORTANT> wrapper)" },
|
|
279
279
|
{ id: "hard_gate", pattern: /^## HARD-GATE$/m, label: "## HARD-GATE" },
|
|
280
280
|
{ id: "checklist", pattern: /^## Checklist$/m, label: "## Checklist" },
|
|
281
|
-
{ id: "
|
|
282
|
-
{ id: "
|
|
281
|
+
{ id: "completion_parameters", pattern: /^## Completion Parameters$/m, label: "## Completion Parameters" },
|
|
282
|
+
{ id: "shared_guidance", pattern: /^## Shared Stage Guidance$/m, label: "## Shared Stage Guidance" },
|
|
283
283
|
{ id: "good_vs_bad", pattern: /Good vs Bad/i, label: "Good vs Bad examples" },
|
|
284
284
|
{ id: "anti_patterns", pattern: /^## Anti-Patterns & Red Flags$/m, label: "## Anti-Patterns & Red Flags" }
|
|
285
285
|
];
|
|
@@ -303,14 +303,12 @@ export async function doctorChecks(projectRoot, options = {}) {
|
|
|
303
303
|
const metaContent = await fs.readFile(metaSkillPath, "utf8");
|
|
304
304
|
const requiredSignals = [
|
|
305
305
|
{ id: "instruction_priority", pattern: /Instruction Priority/i, label: "Instruction Priority" },
|
|
306
|
-
{ id: "
|
|
307
|
-
{ id: "
|
|
308
|
-
{ id: "
|
|
309
|
-
{ id: "
|
|
310
|
-
{ id: "
|
|
311
|
-
{ id: "
|
|
312
|
-
{ id: "engineering_ethos", pattern: /Engineering Ethos/i, label: "Engineering Ethos" },
|
|
313
|
-
{ id: "task_classification", pattern: /Task Classification/i, label: "Task Classification" }
|
|
306
|
+
{ id: "routing_flow", pattern: /Routing flow/i, label: "Routing flow" },
|
|
307
|
+
{ id: "task_classification", pattern: /Task classification/i, label: "Task classification" },
|
|
308
|
+
{ id: "stage_map", pattern: /Stage quick map/i, label: "Stage quick map" },
|
|
309
|
+
{ id: "protocol_refs", pattern: /Protocol references/i, label: "Protocol references" },
|
|
310
|
+
{ id: "knowledge_guidance", pattern: /Knowledge guidance/i, label: "Knowledge guidance" },
|
|
311
|
+
{ id: "failure_guardrails", pattern: /Failure guardrails/i, label: "Failure guardrails" }
|
|
314
312
|
];
|
|
315
313
|
const missingMeta = requiredSignals
|
|
316
314
|
.filter((signal) => !signal.pattern.test(metaContent))
|
|
@@ -782,6 +780,11 @@ export async function doctorChecks(projectRoot, options = {}) {
|
|
|
782
780
|
ok: await exists(path.join(projectRoot, RUNTIME_ROOT, "knowledge.jsonl")),
|
|
783
781
|
details: `${RUNTIME_ROOT}/knowledge.jsonl must exist`
|
|
784
782
|
});
|
|
783
|
+
checks.push({
|
|
784
|
+
name: "knowledge:digest_exists",
|
|
785
|
+
ok: await exists(path.join(projectRoot, RUNTIME_ROOT, "state", "knowledge-digest.md")),
|
|
786
|
+
details: `${RUNTIME_ROOT}/state/knowledge-digest.md must exist`
|
|
787
|
+
});
|
|
785
788
|
// There must be NO legacy markdown knowledge store — JSONL is the only store.
|
|
786
789
|
const legacyKnowledgeMdPath = path.join(projectRoot, RUNTIME_ROOT, "knowledge.md");
|
|
787
790
|
const legacyExists = await exists(legacyKnowledgeMdPath);
|
|
@@ -968,9 +971,16 @@ export async function doctorChecks(projectRoot, options = {}) {
|
|
|
968
971
|
name: "gates:evidence:current_stage",
|
|
969
972
|
ok: gateEvidence.ok,
|
|
970
973
|
details: gateEvidence.ok
|
|
971
|
-
? `stage "${gateEvidence.stage}" gate evidence is consistent (required=${gateEvidence.requiredCount}, passed=${gateEvidence.passedCount}, blocked=${gateEvidence.blockedCount})`
|
|
974
|
+
? `stage "${gateEvidence.stage}" gate evidence is consistent (required=${gateEvidence.requiredCount}, recommended=${gateEvidence.recommendedCount}, conditional=${gateEvidence.conditionalCount}, triggered=${gateEvidence.triggeredConditionalCount}, passed=${gateEvidence.passedCount}, blocked=${gateEvidence.blockedCount})`
|
|
972
975
|
: gateEvidence.issues.join(" ")
|
|
973
976
|
});
|
|
977
|
+
checks.push({
|
|
978
|
+
name: "warning:gates:recommended:current_stage",
|
|
979
|
+
ok: true,
|
|
980
|
+
details: gateEvidence.missingRecommended.length > 0
|
|
981
|
+
? `warning: stage "${gateEvidence.stage}" has unmet recommended gates: ${gateEvidence.missingRecommended.join(", ")}`
|
|
982
|
+
: `no unmet recommended gates for stage "${gateEvidence.stage}"`
|
|
983
|
+
});
|
|
974
984
|
const completedClosure = verifyCompletedStagesGateClosure(flowState);
|
|
975
985
|
checks.push({
|
|
976
986
|
name: "gates:closure:completed_stages",
|
|
@@ -981,18 +991,6 @@ export async function doctorChecks(projectRoot, options = {}) {
|
|
|
981
991
|
: `all ${flowState.completedStages.length} completed stages have every required gate passed`
|
|
982
992
|
: completedClosure.issues.join(" ")
|
|
983
993
|
});
|
|
984
|
-
// Self-improvement block in stage skills
|
|
985
|
-
for (const stage of COMMAND_FILE_ORDER) {
|
|
986
|
-
const skillPath = path.join(projectRoot, RUNTIME_ROOT, "skills", stageSkillFolder(stage), "SKILL.md");
|
|
987
|
-
if (await exists(skillPath)) {
|
|
988
|
-
const content = await fs.readFile(skillPath, "utf8");
|
|
989
|
-
checks.push({
|
|
990
|
-
name: `skill:${stage}:self_improvement`,
|
|
991
|
-
ok: content.includes("## Operational Self-Improvement"),
|
|
992
|
-
details: `${skillPath} must contain self-improvement block`
|
|
993
|
-
});
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
994
|
const isRepo = await isGitRepo(projectRoot);
|
|
997
995
|
checks.push({
|
|
998
996
|
name: "git:cclaw_ignored_runtime",
|
package/dist/flow-state.d.ts
CHANGED
|
@@ -2,6 +2,10 @@ import type { FlowStage, FlowTrack, TransitionRule } from "./types.js";
|
|
|
2
2
|
export declare const TRANSITION_RULES: TransitionRule[];
|
|
3
3
|
export interface StageGateState {
|
|
4
4
|
required: string[];
|
|
5
|
+
recommended: string[];
|
|
6
|
+
conditional: string[];
|
|
7
|
+
/** Conditional gates currently considered active for blocking checks. */
|
|
8
|
+
triggered: string[];
|
|
5
9
|
passed: string[];
|
|
6
10
|
blocked: string[];
|
|
7
11
|
}
|
package/dist/flow-state.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { COMMAND_FILE_ORDER } from "./constants.js";
|
|
2
|
-
import { buildTransitionRules, orderedStageSchemas, stageGateIds } from "./content/stage-schema.js";
|
|
2
|
+
import { buildTransitionRules, orderedStageSchemas, stageConditionalGateIds, stageGateIds, stageRecommendedGateIds } from "./content/stage-schema.js";
|
|
3
3
|
import { FLOW_STAGES, FLOW_TRACKS, TRACK_STAGES } from "./types.js";
|
|
4
4
|
export const TRANSITION_RULES = buildTransitionRules();
|
|
5
5
|
export function isFlowTrack(value) {
|
|
@@ -27,6 +27,9 @@ export function createInitialFlowState(activeRunIdOrOptions = "active", maybeTra
|
|
|
27
27
|
for (const schema of orderedStageSchemas()) {
|
|
28
28
|
stageGateCatalog[schema.stage] = {
|
|
29
29
|
required: stageGateIds(schema.stage),
|
|
30
|
+
recommended: stageRecommendedGateIds(schema.stage),
|
|
31
|
+
conditional: stageConditionalGateIds(schema.stage),
|
|
32
|
+
triggered: [],
|
|
30
33
|
passed: [],
|
|
31
34
|
blocked: []
|
|
32
35
|
};
|
package/dist/gate-evidence.d.ts
CHANGED
|
@@ -5,12 +5,19 @@ export interface GateEvidenceCheckResult {
|
|
|
5
5
|
stage: FlowStage;
|
|
6
6
|
issues: string[];
|
|
7
7
|
requiredCount: number;
|
|
8
|
+
recommendedCount: number;
|
|
9
|
+
conditionalCount: number;
|
|
10
|
+
triggeredConditionalCount: number;
|
|
8
11
|
passedCount: number;
|
|
9
12
|
blockedCount: number;
|
|
10
|
-
/** True only when
|
|
13
|
+
/** True only when required + triggered conditional gates are passed and unblocked. */
|
|
11
14
|
complete: boolean;
|
|
12
15
|
/** Required gate ids that are neither passed nor blocked. */
|
|
13
16
|
missingRequired: string[];
|
|
17
|
+
/** Recommended gates not yet passed (does not block). */
|
|
18
|
+
missingRecommended: string[];
|
|
19
|
+
/** Triggered conditional gates that are not yet passed. */
|
|
20
|
+
missingTriggeredConditional: string[];
|
|
14
21
|
}
|
|
15
22
|
export interface CompletedStagesClosureResult {
|
|
16
23
|
ok: boolean;
|
|
@@ -18,6 +25,7 @@ export interface CompletedStagesClosureResult {
|
|
|
18
25
|
openStages: Array<{
|
|
19
26
|
stage: FlowStage;
|
|
20
27
|
missingRequired: string[];
|
|
28
|
+
missingTriggeredConditional: string[];
|
|
21
29
|
blocked: string[];
|
|
22
30
|
}>;
|
|
23
31
|
}
|