cclaw-cli 6.1.1 → 6.3.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/README.md +2 -2
- package/dist/artifact-linter/brainstorm.js +13 -13
- package/dist/artifact-linter/design.js +5 -5
- package/dist/artifact-linter/scope.js +3 -3
- package/dist/artifact-linter/shared.d.ts +18 -19
- package/dist/artifact-linter/shared.js +34 -31
- package/dist/artifact-linter.js +4 -0
- package/dist/content/hooks.js +154 -2
- package/dist/content/skills-elicitation.js +8 -19
- package/dist/content/skills.js +1 -0
- package/dist/content/stage-schema.d.ts +3 -3
- package/dist/content/stage-schema.js +31 -6
- package/dist/content/stages/brainstorm.js +5 -5
- package/dist/content/stages/design.js +1 -1
- package/dist/content/stages/schema-types.d.ts +6 -0
- package/dist/content/stages/scope.js +2 -2
- package/dist/content/start-command.d.ts +2 -2
- package/dist/content/start-command.js +23 -18
- package/dist/content/subagents.js +1 -1
- package/dist/content/templates.d.ts +1 -1
- package/dist/content/templates.js +1 -0
- package/dist/delegation.js +2 -2
- package/dist/flow-state.d.ts +14 -1
- package/dist/flow-state.js +6 -1
- package/dist/gate-evidence.js +4 -3
- package/dist/internal/advance-stage/advance.js +20 -4
- package/dist/internal/advance-stage/parsers.d.ts +2 -1
- package/dist/internal/advance-stage/parsers.js +12 -1
- package/dist/internal/advance-stage/proactive-delegation-trace.d.ts +21 -0
- package/dist/internal/advance-stage/proactive-delegation-trace.js +60 -0
- package/dist/internal/advance-stage/start-flow.d.ts +3 -1
- package/dist/internal/advance-stage/start-flow.js +81 -2
- package/dist/internal/advance-stage/verify.d.ts +0 -8
- package/dist/internal/advance-stage/verify.js +2 -30
- package/dist/run-persistence.js +37 -2
- package/dist/track-heuristics.d.ts +2 -2
- package/dist/track-heuristics.js +11 -6
- package/dist/types.d.ts +2 -0
- package/dist/types.js +1 -0
- package/package.json +1 -1
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { RUNTIME_ROOT } from "../constants.js";
|
|
2
2
|
import { questionBudgetHint } from "../track-heuristics.js";
|
|
3
|
-
import { FLOW_TRACKS } from "../types.js";
|
|
4
3
|
const ELICITATION_STAGES = ["brainstorm", "scope", "design"];
|
|
5
4
|
function renderQuestionBudgetHintTable() {
|
|
6
5
|
const rows = [];
|
|
7
|
-
for (const
|
|
6
|
+
for (const mode of ["lean", "guided", "deep"]) {
|
|
8
7
|
for (const stage of ELICITATION_STAGES) {
|
|
9
|
-
const hint = questionBudgetHint(
|
|
10
|
-
rows.push(`| \`${
|
|
8
|
+
const hint = questionBudgetHint(mode, stage);
|
|
9
|
+
rows.push(`| \`${mode}\` | \`${stage}\` | ${hint.min} | ${hint.recommended} | ${hint.hardCapWarning} |`);
|
|
11
10
|
}
|
|
12
11
|
}
|
|
13
|
-
return `|
|
|
12
|
+
return `| Discovery mode | Stage | Min | Recommended | Hard cap warning |
|
|
14
13
|
|---|---|---|---|---|
|
|
15
14
|
${rows.join("\n")}`;
|
|
16
15
|
}
|
|
@@ -47,7 +46,7 @@ These behaviors are the exact reason this skill exists. The linter will block yo
|
|
|
47
46
|
- Ask exactly one question per turn and wait for the answer before asking the next one.
|
|
48
47
|
- Use harness-native question tools first; prose fallback is allowed only when the tool is unavailable.
|
|
49
48
|
- Keep a running Q&A trace in the active artifact under \`## Q&A Log\` in \`${RUNTIME_ROOT}/artifacts/\` as append-only rows.
|
|
50
|
-
- **Convergence floor**: do NOT advance the stage (do NOT call \`stage-complete.mjs\`) until Q&A converges.
|
|
49
|
+
- **Convergence floor**: do NOT advance the stage (do NOT call \`stage-complete.mjs\`) until Q&A converges. The machine contract matches \`evaluateQaLogFloor\` in \`src/artifact-linter/shared.ts\` (rule \`qa_log_unconverged\`). Pass when ANY holds: (a) every forcing-question topic id is tagged \`[topic:<id>]\` on at least one \`## Q&A Log\` row; (b) the Ralph-Loop detector fires (last 2 substantive rows are non-decision-changing: \`skip\`/\`continue\`/\`no-change\`/\`done\`/etc.) **and** the log has at least \`max(2, questionBudgetHint(discoveryMode, stage).min)\` substantive rows — **unless** \`discoveryMode\` is \`guided\` or \`deep\` with pending forcing-topic ids (then Ralph-Loop alone cannot pass until topics are tagged, a stop-signal is recorded, or \`--skip-questions\` downgrades the finding to advisory); (c) an explicit user stop-signal row; or (d) \`--skip-questions\` was persisted (unconverged is advisory only). Wave 24 (v6.0.0) made \`[topic:<id>]\` mandatory (no English keyword fallback).
|
|
51
50
|
- **NEVER run shell hash commands** (\`shasum\`, \`sha256sum\`, \`md5sum\`, \`Get-FileHash\`, \`certutil\`, etc.) to compute artifact hashes. If a linter ever asks you for a hash, that is a linter bug — report failure and stop, do not auto-fix in bash.
|
|
52
51
|
- **NEVER paste cclaw command lines into chat** (e.g. \`node .cclaw/hooks/stage-complete.mjs ... --evidence-json '{...}'\`). Run them via the tool layer; report only the resulting summary. The user does not run cclaw manually and seeing the command line is noise.
|
|
53
52
|
|
|
@@ -103,23 +102,13 @@ Each grill question follows the same Core Protocol: ask one, wait, log, self-eva
|
|
|
103
102
|
|
|
104
103
|
Do not ask extra questions "for theater" on simple low-risk work.
|
|
105
104
|
|
|
106
|
-
## Question Budget Hint (
|
|
105
|
+
## Question Budget Hint (\`questionBudgetHint\` — min rows feed the convergence floor)
|
|
107
106
|
|
|
108
|
-
Source of truth: \`questionBudgetHint(
|
|
109
|
-
**soft hints** for harness UI and elicitation pacing; gate blocking is done
|
|
110
|
-
by the \`qa_log_unconverged\` rule (Ralph-Loop convergence detector), NOT by
|
|
111
|
-
a fixed count.
|
|
107
|
+
Source of truth: \`questionBudgetHint(discoveryMode, stage)\`. The \`Min\` column is **not advisory** for the Ralph-Loop exit: \`evaluateQaLogFloor\` requires at least \`max(2, Min)\` substantive rows before the no-new-decisions path can converge (other exits — full topic coverage, stop-signal, \`--skip-questions\` advisory — ignore that minimum). \`Recommended\` and \`Hard cap warning\` remain pacing hints for the harness.
|
|
112
108
|
|
|
113
109
|
${budgetTable}
|
|
114
110
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
How to use the columns:
|
|
118
|
-
- \`Min\` — soft minimum to surface forcing questions; not a blocking gate.
|
|
119
|
-
- \`Recommended\` — target for normal flows.
|
|
120
|
-
- \`Hard cap warning\` — point at which to stop or compress remaining forcing questions into one final batched ask. Not skip.
|
|
121
|
-
|
|
122
|
-
## Stage Forcing Questions (walk in order, one per turn)
|
|
111
|
+
Default mapping note: \`lean\` maps to a lightweight specialist tier on early stages, \`guided\` to standard, \`deep\` to deep; risk signals can escalate further.
|
|
123
112
|
|
|
124
113
|
**Walk the forcing questions list one-by-one in order, asking each as a separate turn.** Do NOT batch. Do NOT pick favorites — go in order. For each question record one of:
|
|
125
114
|
- \`asked\` — question was asked and answered.
|
package/dist/content/skills.js
CHANGED
|
@@ -389,6 +389,7 @@ function completionParametersBlock(schema, track) {
|
|
|
389
389
|
- Fill \`## Learnings\` before closeout: either \`- None this stage.\` or JSON bullets with required keys \`type\`, \`trigger\`, \`action\`, \`confidence\` (knowledge-schema compatible).
|
|
390
390
|
- Record mandatory delegation lifecycle in \`${RUNTIME_ROOT}/state/delegation-log.json\` and append proof events to \`${RUNTIME_ROOT}/state/delegation-events.jsonl\`; the ledger is current state, the event log is audit proof.${mandatoryAgents.length > 0 ? ` If a mandatory delegation cannot run in this harness, use \`--waive-delegation=${mandatoryAgents.join(",")} --waiver-reason="<why safe>"\` on the completion helper.` : ""} If proactive delegations were intentionally skipped, rerun only with \`--accept-proactive-waiver\` (optionally \`--accept-proactive-waiver-reason="<why safe>"\`) after explicit user approval.
|
|
391
391
|
- Never edit raw \`flow-state.json\` to complete a stage, even in advisory mode; that bypasses validation, gate evidence, and Learnings harvest. If a helper fails, report a one-line human-readable failure plus fenced JSON diagnostics; never echo the invoking command line or apply a manual state workaround.
|
|
392
|
+
- Stage completion claim requires \`stage-complete\` exit 0 in the current turn. Quote the success line; do not paraphrase, do not infer success from skipped retries.
|
|
392
393
|
- Completion protocol: verify required gates, update the artifact, then use the completion helper with \`--evidence-json\` and \`--passed\` for every satisfied gate.
|
|
393
394
|
`;
|
|
394
395
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FlowStage, FlowTrack, TransitionRule } from "../types.js";
|
|
1
|
+
import type { DiscoveryMode, FlowStage, FlowTrack, TransitionRule } from "../types.js";
|
|
2
2
|
import type { StageComplexityTier, StageAutoSubagentDispatch, StageSchema } from "./stages/schema-types.js";
|
|
3
3
|
export type { ArtifactValidation, CrossStageTrace, ReviewSection, StageComplexityTier, StageExecutionModel, StagePhilosophy, StageArtifactRules, StageReviewLoop, StageReviewLens, StageAutoSubagentDispatch, StageGate, StageSchemaLegacyInput, StageSchema, StageSchemaInput, StageSchemaV2Input } from "./stages/schema-types.js";
|
|
4
4
|
export declare const SKILL_ENVELOPE_KINDS: readonly ["stage-output", "gate-result", "delegation-record"];
|
|
@@ -83,7 +83,7 @@ export declare function mandatoryDelegationsForStage(stage: FlowStage, complexit
|
|
|
83
83
|
* boundary.
|
|
84
84
|
*/
|
|
85
85
|
export type MandatoryDelegationTaskClass = "software-standard" | "software-trivial" | "software-bugfix";
|
|
86
|
-
export declare function mandatoryAgentsFor(stage: FlowStage, track: FlowTrack, taskClass?: MandatoryDelegationTaskClass | null, complexityTier?: StageComplexityTier): string[];
|
|
86
|
+
export declare function mandatoryAgentsFor(stage: FlowStage, track: FlowTrack, taskClass?: MandatoryDelegationTaskClass | null, complexityTier?: StageComplexityTier, discoveryMode?: DiscoveryMode): string[];
|
|
87
87
|
/**
|
|
88
88
|
* Wave 25 (v6.1.0) — track-aware artifact validation demotion.
|
|
89
89
|
*
|
|
@@ -107,7 +107,7 @@ export declare function mandatoryAgentsFor(stage: FlowStage, track: FlowTrack, t
|
|
|
107
107
|
* `delegation-events.jsonl` once per stage advance for traceability.
|
|
108
108
|
*/
|
|
109
109
|
export declare function shouldDemoteArtifactValidationByTrack(track: FlowTrack, taskClass?: MandatoryDelegationTaskClass | null): boolean;
|
|
110
|
-
export declare function stageSchema(stage: FlowStage, track?: FlowTrack): StageSchema;
|
|
110
|
+
export declare function stageSchema(stage: FlowStage, track?: FlowTrack, discoveryMode?: DiscoveryMode, taskClass?: MandatoryDelegationTaskClass | null): StageSchema;
|
|
111
111
|
export declare function orderedStageSchemas(track?: FlowTrack): StageSchema[];
|
|
112
112
|
export declare function stageGateIds(stage: FlowStage, track?: FlowTrack): string[];
|
|
113
113
|
export declare function stageRecommendedGateIds(stage: FlowStage, track?: FlowTrack): string[];
|
|
@@ -81,6 +81,20 @@ function dedupeAgentsInOrder(agents) {
|
|
|
81
81
|
}
|
|
82
82
|
return out;
|
|
83
83
|
}
|
|
84
|
+
function discoveryModeTier(mode) {
|
|
85
|
+
if (mode === "lean")
|
|
86
|
+
return "lightweight";
|
|
87
|
+
if (mode === "deep")
|
|
88
|
+
return "deep";
|
|
89
|
+
return "standard";
|
|
90
|
+
}
|
|
91
|
+
function resolvedStageComplexityTier(params) {
|
|
92
|
+
const base = params.defaultTier ?? "standard";
|
|
93
|
+
const earlyStage = params.stage === "brainstorm" || params.stage === "scope" || params.stage === "design";
|
|
94
|
+
if (!earlyStage || params.discoveryMode === undefined)
|
|
95
|
+
return base;
|
|
96
|
+
return discoveryModeTier(params.discoveryMode);
|
|
97
|
+
}
|
|
84
98
|
function defaultReturnSchemaForAgent(agent) {
|
|
85
99
|
switch (agent) {
|
|
86
100
|
case "researcher":
|
|
@@ -484,7 +498,8 @@ const STAGE_AUTO_SUBAGENT_DISPATCH = {
|
|
|
484
498
|
runPhase: "post-elicitation",
|
|
485
499
|
when: "When repository, market, docs, or prior-art context changes the approach set. Runs only after the adaptive elicitation Q&A loop converges.",
|
|
486
500
|
purpose: "Provide search-before-read summaries and context-readiness evidence before large reads or decisions.",
|
|
487
|
-
requiresUserGate: false
|
|
501
|
+
requiresUserGate: false,
|
|
502
|
+
dependsOnInternalRepoSignals: true
|
|
488
503
|
}
|
|
489
504
|
],
|
|
490
505
|
scope: [
|
|
@@ -521,7 +536,8 @@ const STAGE_AUTO_SUBAGENT_DISPATCH = {
|
|
|
521
536
|
runPhase: "post-elicitation",
|
|
522
537
|
when: "When churn, prior attempts, reference patterns, or external constraints may change scope boundaries. Runs only after the adaptive elicitation Q&A loop converges.",
|
|
523
538
|
purpose: "Summarize search/context findings before the scope contract locks accepted/rejected/deferred ideas.",
|
|
524
|
-
requiresUserGate: false
|
|
539
|
+
requiresUserGate: false,
|
|
540
|
+
dependsOnInternalRepoSignals: true
|
|
525
541
|
},
|
|
526
542
|
{
|
|
527
543
|
agent: "product-discovery",
|
|
@@ -811,12 +827,17 @@ export function mandatoryDelegationsForStage(stage, complexityTier = "standard")
|
|
|
811
827
|
.find((row) => row.stage === stage);
|
|
812
828
|
return summary ? summary.mandatoryAgents : [];
|
|
813
829
|
}
|
|
814
|
-
export function mandatoryAgentsFor(stage, track, taskClass, complexityTier = "standard") {
|
|
830
|
+
export function mandatoryAgentsFor(stage, track, taskClass, complexityTier = "standard", discoveryMode) {
|
|
815
831
|
if (track === "quick")
|
|
816
832
|
return [];
|
|
817
833
|
if (taskClass === "software-bugfix")
|
|
818
834
|
return [];
|
|
819
|
-
|
|
835
|
+
const effectiveTier = resolvedStageComplexityTier({
|
|
836
|
+
stage,
|
|
837
|
+
defaultTier: complexityTier,
|
|
838
|
+
discoveryMode
|
|
839
|
+
});
|
|
840
|
+
return mandatoryDelegationsForStage(stage, effectiveTier);
|
|
820
841
|
}
|
|
821
842
|
/**
|
|
822
843
|
* Wave 25 (v6.1.0) — track-aware artifact validation demotion.
|
|
@@ -847,7 +868,7 @@ export function shouldDemoteArtifactValidationByTrack(track, taskClass) {
|
|
|
847
868
|
return true;
|
|
848
869
|
return false;
|
|
849
870
|
}
|
|
850
|
-
export function stageSchema(stage, track = "standard") {
|
|
871
|
+
export function stageSchema(stage, track = "standard", discoveryMode, taskClass) {
|
|
851
872
|
const rawInput = stage === "tdd" ? tddStageForTrack(track) : STAGE_SCHEMA_MAP[stage];
|
|
852
873
|
const base = normalizeStageSchemaInput(rawInput);
|
|
853
874
|
const tieredGates = tieredStageGates(stage, base.requiredGates, track);
|
|
@@ -856,7 +877,11 @@ export function stageSchema(stage, track = "standard") {
|
|
|
856
877
|
...base.crossStageTrace,
|
|
857
878
|
readsFrom: readsFromForTrack(base.crossStageTrace.readsFrom, track)
|
|
858
879
|
};
|
|
859
|
-
const complexityTier =
|
|
880
|
+
const complexityTier = resolvedStageComplexityTier({
|
|
881
|
+
stage,
|
|
882
|
+
defaultTier: base.complexityTier ?? "standard",
|
|
883
|
+
discoveryMode
|
|
884
|
+
});
|
|
860
885
|
const mandatoryDelegations = mandatoryDelegationsForStage(stage, complexityTier);
|
|
861
886
|
const philosophy = {
|
|
862
887
|
hardGate: base.hardGate,
|
|
@@ -7,7 +7,7 @@ export const BRAINSTORM = {
|
|
|
7
7
|
complexityTier: "standard",
|
|
8
8
|
skillFolder: "brainstorm",
|
|
9
9
|
skillName: "brainstorm",
|
|
10
|
-
skillDescription: "Problem-discovery stage. Build a concise Problem Decision Record,
|
|
10
|
+
skillDescription: "Problem-discovery stage. Build a concise Problem Decision Record, compare distinct directions under the run's discovery mode (lean / guided / deep), and hand approved decisions to scope.",
|
|
11
11
|
philosophy: {
|
|
12
12
|
hardGate: "Do NOT invoke implementation skills, write code, scaffold projects, or mutate product behavior until a concrete direction is approved by the user.",
|
|
13
13
|
ironLaw: "NO ARTIFACT IS COMPLETE WITHOUT AN EXPLICITLY APPROVED DIRECTION — SILENCE IS NOT APPROVAL.",
|
|
@@ -39,7 +39,7 @@ export const BRAINSTORM = {
|
|
|
39
39
|
"**ADAPTIVE ELICITATION COMES FIRST (no exceptions, no subagent dispatch before).** Load `.cclaw/skills/adaptive-elicitation/SKILL.md`. Walk the brainstorm forcing questions one-at-a-time via the harness-native question tool, append one row to `## Q&A Log` (`Turn | Question | User answer (1-line) | Decision impact`) after each user answer **and stamp the row's `Decision impact` cell with the matching `[topic:<id>]` tag** (e.g. `[topic:pain]`). Continue until every forcing-question topic id is tagged on a row OR Ralph-Loop convergence detector says no new decision-changing rows in last 2 iterations OR user records an explicit stop-signal row. Only then proceed to delegations, drafts, or analysis. The linter `qa_log_unconverged` rule will block `stage-complete` if convergence is not reached.",
|
|
40
40
|
"**Explore project context** — after the elicitation loop converges, inspect existing files/docs/recent activity to refine the Discovered context section; capture matching files/patterns/seeds in `Context > Discovered context` so downstream stages don't redo discovery.",
|
|
41
41
|
"**Brainstorm forcing questions (must be covered or explicitly waived)** — `pain: what pain are we solving`; `direct-path: what is the direct path`; `do-nothing: what happens if we do nothing`; `operator: who is the first operator/user affected`; `no-go: what no-go boundaries are non-negotiable`. Tag the matching `## Q&A Log` row's `Decision impact` cell with `[topic:<id>]` (e.g. `[topic:pain]`) so the linter can verify coverage in any natural language. Tags are MANDATORY for forcing-question rows; un-tagged rows do NOT count toward coverage.",
|
|
42
|
-
"**
|
|
42
|
+
"**Discovery posture (flow-state `discoveryMode`)** — follow `lean` / `guided` / `deep` from the active run. Use lean for smallest safe discovery pass; guided as the default balanced pass; escalate to deep when ambiguity, architecture, external dependency, security/data risk, or explicit think-bigger requests warrant fuller option pressure and mandatory specialist coverage.",
|
|
43
43
|
"**Write the Problem Decision Record** — pick a free-form `Frame type` label that names how this work is framed (examples: product, technical-maintenance, research-spike, ops-incident, infrastructure), then fill the universal Framing fields: affected user/role/operator, current state/failure mode/opportunity, desired observable outcome, evidence/signal, why now, do-nothing consequence, and non-goals.",
|
|
44
44
|
"**Premise check (one pass)** — answer the three gstack-style questions in the artifact body: *Right problem? Direct path? What if we do nothing?* Take a position; do not hedge.",
|
|
45
45
|
"**Reframe with How Might We** — write a single `How Might We …?` line that names the user/operator, the desired outcome, and the constraint. This is the altitude check before approaches.",
|
|
@@ -61,7 +61,7 @@ export const BRAINSTORM = {
|
|
|
61
61
|
interactionProtocol: [
|
|
62
62
|
"\"If something is unclear, stop. Name what's confusing. Ask.\"",
|
|
63
63
|
"Start from observed project context; if the idea is vague, first narrow the project type with **one** structured question, then keep going.",
|
|
64
|
-
"
|
|
64
|
+
"Honor the run's `discoveryMode` (`lean` | `guided` | `deep`) from flow-state: lean stays fastest, guided is the default breadth, deep pulls in fuller critique and mandatory delegations when the run is classified that way.",
|
|
65
65
|
"Lead with the premise check (right problem / direct path / what if nothing) and the `How Might We` reframing before approaches; both go in the artifact, not just the chat.",
|
|
66
66
|
"Ask at most one question per turn, only when decision-changing; if using a structured question tool, send exactly one question object, not a multi-question form.",
|
|
67
67
|
"Run the shared adaptive elicitation cycle from `.cclaw/skills/adaptive-elicitation/SKILL.md`, including stop-signal handling (RU/EN/UA), smart-skip, conditional grilling triggers, and append-only `## Q&A Log` updates.",
|
|
@@ -72,7 +72,7 @@ export const BRAINSTORM = {
|
|
|
72
72
|
"State exactly what is being approved, then **STOP** until the user explicitly approves the artifact."
|
|
73
73
|
],
|
|
74
74
|
process: [
|
|
75
|
-
"Explore project context and
|
|
75
|
+
"Explore project context and align work to the run's discovery mode (lean / guided / deep).",
|
|
76
76
|
"Use compact discovery for simple apps, short-circuit implementation-only asks, or ask one decision-changing question at a time.",
|
|
77
77
|
"Compare 2-3 distinct approaches, including a higher-upside challenger.",
|
|
78
78
|
"Collect reaction, then recommend with rationale tied to that reaction.",
|
|
@@ -145,7 +145,7 @@ export const BRAINSTORM = {
|
|
|
145
145
|
{ section: "Clarity Gate", required: false, validationRule: "Recommended before recommendation lock: include ambiguity score (0.00-1.00), decision boundaries, reaffirmed non-goals, and residual-risk handoff for scope." },
|
|
146
146
|
{ section: "Sharpening Questions", required: false, validationRule: "Recommended only when needed: one decision-changing question per turn with explicit `Decision impact`; compact tasks may record `None - early exit` with rationale." },
|
|
147
147
|
{ section: "Clarifying Questions", required: false, validationRule: "Must capture question, answer, and decision impact for each clarifying question." },
|
|
148
|
-
{ section: "Approach Tier", required: true, validationRule: "Must
|
|
148
|
+
{ section: "Approach Tier", required: true, validationRule: "Must record how much discovery/evidence breadth is warranted in discoveryMode terms (`lean`, `guided`, or `deep`) relative to flow-state—and explain what risk or uncertainty drives that calibration (not merely the label)." },
|
|
149
149
|
{ section: "Short-Circuit Decision", required: false, validationRule: "Must include Status/Why/Scope handoff lines when short-circuit is discussed; compact stubs are valid for concrete asks." },
|
|
150
150
|
{ section: "Reference Pattern Candidates", required: false, validationRule: "Recommended when examples influence direction: list pattern/source, reusable invariant, accept/reject/defer disposition, and reason before approaches are finalized." },
|
|
151
151
|
{ section: "Idea Evidence Carry-forward", required: false, validationRule: "Wave 23 (v5.0.0): when `flow-state.interactionHints.brainstorm.fromIdeaArtifact` is set, this section MUST cite the idea artifact path and the chosen `I-#`, list reused fields (Title, Why-now, Expected impact, Risk, Counter-argument), and explicitly state that only challenger row(s) were newly generated. Honors `/cc-ideate` handoff so divergent + critique + rank work is reused, not redone." },
|
|
@@ -78,7 +78,7 @@ export const DESIGN = {
|
|
|
78
78
|
"Run compact research by default; write `.cclaw/artifacts/02a-research.md` only when deep/high-risk uncertainty requires a separate research artifact.",
|
|
79
79
|
"Run investigator pass plus scope challenge/search-before-building.",
|
|
80
80
|
"Walk review sections interactively and lock boundaries, data flow, state transitions, edge cases, and failure modes.",
|
|
81
|
-
"Cover security, observability, deployment, tests, and performance for
|
|
81
|
+
"Cover security, observability, deployment, tests, and performance for guided/deep-shaped design work; lean slices may omit heavy add-ons only when scope and risk justify the compact path.",
|
|
82
82
|
"Run stale-diagram audit (enabled by default unless explicitly disabled).",
|
|
83
83
|
"Produce required outputs: blast-radius diff (scope owns full repo audit), tier diagrams, failure table, completion dashboard. Out-of-scope is carried from scope via Upstream Handoff — do NOT re-author it.",
|
|
84
84
|
"Plant high-upside deferred ideas when useful and reconcile critic/outside-voice findings.",
|
|
@@ -53,6 +53,12 @@ export interface StageAutoSubagentDispatch {
|
|
|
53
53
|
returnSchema?: StageSubagentReturnSchema;
|
|
54
54
|
/** Optional skill folder the dispatched agent should load as additional context. */
|
|
55
55
|
skill?: string;
|
|
56
|
+
/**
|
|
57
|
+
* When true, proactive trace requirements for this row may be skipped on an
|
|
58
|
+
* empty/sparse repo (see `ensureProactiveDelegationTrace`). Used for
|
|
59
|
+
* `researcher` on early elicitation stages in deep discovery mode.
|
|
60
|
+
*/
|
|
61
|
+
dependsOnInternalRepoSignals?: boolean;
|
|
56
62
|
}
|
|
57
63
|
export type StageComplexityTier = "lightweight" | "standard" | "deep";
|
|
58
64
|
export interface StagePhilosophy {
|
|
@@ -52,7 +52,7 @@ export const SCOPE = {
|
|
|
52
52
|
"**Premise carry-forward (do NOT re-author)** — brainstorm OWNS the premise check (right problem / direct path / what if nothing). Cite brainstorm's `## Premise Check` section in `## Upstream Handoff > Decisions carried forward`. Add a row to `## Premise Drift` only when the scope-stage Q&A surfaced NEW evidence that materially changes the brainstorm answer (e.g. new constraint, new user signal). Otherwise mark `Premise Drift: None` — do not duplicate the brainstorm premise table.",
|
|
53
53
|
"**Conditional 10-star boundary** — for deep/high-risk/product-strategy work, show what would make the product meaningfully better, then explicitly choose what ships now, what is deferred, and what is excluded without vague `later/for now` placeholders. Skip this for straightforward repair work and record `not needed: compact scope`.",
|
|
54
54
|
"**Pick one operational mode with the user** — HOLD SCOPE preserves focus; SELECTIVE EXPANSION cherry-picks high-leverage reference ideas; SCOPE EXPANSION explores ambitious alternatives; SCOPE REDUCTION cuts to the essential wedge. Recommend one, state why and what signal would change it, then keep elicitation focused until the user either approves or asks to proceed with draft boundaries.",
|
|
55
|
-
"**Run mode-specific analysis only to needed depth** —
|
|
55
|
+
"**Run mode-specific analysis only to needed depth** — lean discovery keeps the selected-mode row compact; guided adds the standard contract rows; deep may add Landscape Check, Taste Calibration, Reference Pattern Registry, Reference Pull, Ambitious Alternatives, and Ruthless Minimum Slice evidence when mode/risk warrants it.",
|
|
56
56
|
"**Decision-driver contract** — list weighted decision drivers (value, risk, reversibility, effort, timeline) and score candidate scope moves so the selected mode and boundaries are evidence-backed, not preference-led.",
|
|
57
57
|
"**Architecture handoff (do NOT pick architecture tier here)** — design OWNS architecture choice (minimum-viable / product-grade / ideal). Scope only picks the SCOPE MODE (HOLD/SELECTIVE/EXPAND/REDUCE) and boundary; record in `## Scope Contract > Design handoff` what design must decide (e.g. `architecture-tier`, `framework`, `data-model`). Do NOT enumerate Implementation Alternatives in scope.",
|
|
58
58
|
"**Constraints (carry-forward from brainstorm/external sources)** — record explicit external/regulatory/system/integration constraints in `## Scope Contract > Constraints`. Spec OWNS testable assumptions (`## Assumptions Before Finalization`); do NOT duplicate constraint material as assumption material.",
|
|
@@ -65,7 +65,7 @@ export const SCOPE = {
|
|
|
65
65
|
"\"Strong success criteria let you loop independently. Weak criteria require constant clarification.\"",
|
|
66
66
|
decisionProtocolInstruction("scope mode selection", "present expand/selective/hold/reduce as labeled options with trade-offs and mark one as (recommended)", "recommend the option that best covers the prime-directive failure modes, four data-flow paths, observability, and deferred handling for the in-scope set with the smallest blast radius. Base your recommendation on default heuristics: greenfield -> expand, enhancement -> selective, bugfix/hotfix/refactor -> hold, broad blast radius -> reduce"),
|
|
67
67
|
"Run the shared adaptive elicitation cycle from `.cclaw/skills/adaptive-elicitation/SKILL.md`, including stop-signal handling (RU/EN/UA), smart-skip, conditional grilling triggers, and append-only `## Q&A Log` updates.",
|
|
68
|
-
"**Lead with adaptive elicitation, not with a proposed contract.** First walk scope forcing questions one-at-a-time per `adaptive-elicitation` skill. Only AFTER the Q&A loop converges (forcing-Qs answered/waived OR user stop-signal row recorded) propose the scope contract draft for approval.
|
|
68
|
+
"**Lead with adaptive elicitation, not with a proposed contract.** First walk scope forcing questions one-at-a-time per `adaptive-elicitation` skill. Only AFTER the Q&A loop converges (forcing-Qs answered/waived OR user stop-signal row recorded) propose the scope contract draft for approval. Lean discovery may compress: ask the smallest forcing-Q set that satisfies the convergence floor, then propose contract.",
|
|
69
69
|
"For low-risk concrete asks, keep the proposal compact but still explicit: recommend (do not auto-select) one mode, show exact in/out/deferred boundaries, and request explicit approval before finalizing the artifact or completing the stage.",
|
|
70
70
|
"Cite brainstorm's premise via `## Upstream Handoff` and take a firm position on whether scope-stage Q&A surfaced any premise drift; do NOT re-author the brainstorm Premise Check table.",
|
|
71
71
|
"Push back on weak framing: vague scope needs a specific user/problem, platform vision needs a narrow wedge, social proof needs behavioral evidence.",
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Command contract for /cc — the unified entry point.
|
|
3
3
|
* No args → reads existing flow state and progresses it when a tracked flow
|
|
4
4
|
* already exists; missing state/fresh placeholder state blocks with
|
|
5
|
-
* init/start guidance. With prompt → classifies the idea,
|
|
6
|
-
* starts the first stage of that track (brainstorm for medium/standard, spec for quick).
|
|
5
|
+
* init/start guidance. With prompt → classifies the idea, asks for one discovery mode,
|
|
6
|
+
* resolves the internal track, and starts the first stage of that track (brainstorm for medium/standard, spec for quick).
|
|
7
7
|
*/
|
|
8
8
|
export declare function startCommandContract(): string;
|
|
9
9
|
/**
|
|
@@ -9,8 +9,8 @@ function flowStatePath() {
|
|
|
9
9
|
* Command contract for /cc — the unified entry point.
|
|
10
10
|
* No args → reads existing flow state and progresses it when a tracked flow
|
|
11
11
|
* already exists; missing state/fresh placeholder state blocks with
|
|
12
|
-
* init/start guidance. With prompt → classifies the idea,
|
|
13
|
-
* starts the first stage of that track (brainstorm for medium/standard, spec for quick).
|
|
12
|
+
* init/start guidance. With prompt → classifies the idea, asks for one discovery mode,
|
|
13
|
+
* resolves the internal track, and starts the first stage of that track (brainstorm for medium/standard, spec for quick).
|
|
14
14
|
*/
|
|
15
15
|
export function startCommandContract() {
|
|
16
16
|
const flowPath = flowStatePath();
|
|
@@ -21,7 +21,7 @@ export function startCommandContract() {
|
|
|
21
21
|
**The unified entry point for the cclaw flow.**
|
|
22
22
|
|
|
23
23
|
- \`/cc\` (no arguments) → reads existing flow state and resumes/progresses the active flow. If flow state is missing or still a fresh init placeholder, stop and guide the user to run \`/cc <prompt>\` or \`npx cclaw-cli init\`; do not silently create a brainstorm run.
|
|
24
|
-
- \`/cc <prompt>\` (with an idea/description) → saves the prompt as idea context and starts the first stage of the resolved track.
|
|
24
|
+
- \`/cc <prompt>\` (with an idea/description) → saves the prompt as idea context, asks for one discovery mode, and starts the first stage of the resolved internal track.
|
|
25
25
|
|
|
26
26
|
This is the **recommended way to start, resume, and continue** working with cclaw.
|
|
27
27
|
|
|
@@ -72,7 +72,7 @@ ${conversationLanguagePolicyMarkdown()}
|
|
|
72
72
|
|
|
73
73
|
5. Read \`${flowPath}\`.
|
|
74
74
|
6. If flow already has completed stages, warn the user that starting a new tracked flow will reset progress. Ask for confirmation before proceeding. A fresh init placeholder state with \`completedStages: []\`, no passed gates, and no \`00-idea.md\` is **not** an active flow; do not ask the user to resume it.
|
|
75
|
-
7. **
|
|
75
|
+
7. **Internal track heuristic** — classify the idea text and compute an internal track recommendation before any state mutation:
|
|
76
76
|
- 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).
|
|
77
77
|
- **quick** (\`spec → tdd → review → ship\`) — single-purpose work where the spec is essentially already known. Quick skips ceremony, not safety: spec approval, TDD evidence, review, and ship gates remain mandatory.
|
|
78
78
|
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\`.
|
|
@@ -82,14 +82,16 @@ ${conversationLanguagePolicyMarkdown()}
|
|
|
82
82
|
Triggers: \`new feature\`, \`refactor\`, \`migration\`, \`platform\`, \`architecture\`, \`schema\`, \`integrate\`, \`workflow\`, \`onboarding\`, or any prompt that does not match quick/medium confidently.
|
|
83
83
|
- When triggers conflict, prefer **standard** over **medium**, and **medium** over **quick**.
|
|
84
84
|
- Report **track selection confidence** as high/medium/low with the matched trigger or fallback reason, plus one sentence explaining what the selected track skips and what safety gates remain. Be explicit that this recommendation is advisory until the user accepts and the managed helper writes state; after that, \`/cc\` follows the configured track.
|
|
85
|
-
8. Present one compact **Start framing** summary: class,
|
|
86
|
-
9.
|
|
87
|
-
> \`
|
|
88
|
-
> \`
|
|
89
|
-
>
|
|
85
|
+
8. Present one compact **Start framing** summary: class, internal track recommendation, track selection confidence, stack, origin docs, seed recalls, and the recommended next action. Ask a single confirmation question only when there is a destructive reset, a real contradiction, or ambiguous software/non-software classification.
|
|
86
|
+
9. Ask one explicit **discovery mode** question and make it the only normal start-of-run user choice:
|
|
87
|
+
> \`Choose discovery mode: Lean / Guided / Deep\`.
|
|
88
|
+
> \`Lean\` = compact shaping, \`Guided\` = recommended default with enough questions and key specialists before drafting, \`Deep\` = stronger probing and broader specialist/research passes.
|
|
89
|
+
> Mention the internal track recommendation only as context, not as the primary decision. Offer track override only when reset, contradiction, or reclassification evidence makes the internal recommendation suspect.
|
|
90
|
+
Normalize the user's answer before calling the start helper: \`trim\`, lower-case, map UI labels to \`lean\` / \`guided\` / \`deep\` only; if the answer is not one of those three, re-ask the same question once with the compact definitions. In \`flow-state.json\`, persist only the canonical lowercase token (never \`Deep\`/\`Guided\` casing).
|
|
91
|
+
If the user prompt is one short line (at most 12 words) and the workspace matches an empty-repo signal set — either \`flow-state.repoSignals\` from the last successful \`start-flow\` shows \`fileCount < 5\` with \`hasReadme\` and \`hasPackageManifest\` both false, OR (before any \`start-flow\` yet) a shallow scan finds no root \`README.md\`, no root \`package.json\`/\`pyproject.toml\`/\`Cargo.toml\`, and fewer than five relevant files excluding \`node_modules\`/\`.git\` — recommend \`guided\` and ask for explicit confirmation before defaulting to \`deep\`.
|
|
90
92
|
If the harness's native ask tool is available (\`AskUserQuestion\` / \`AskQuestion\` / \`question\` / \`request_user_input\`), send exactly ONE question; on schema error, fall back to a plain-text lettered list.
|
|
91
93
|
10. Start the tracked flow only through the managed helper:
|
|
92
|
-
\`node .cclaw/hooks/start-flow.mjs --track=<quick|medium|standard> --class=<class> --prompt=<prompt> --stack=<stack> --reason=<matched heuristic>\`
|
|
94
|
+
\`node .cclaw/hooks/start-flow.mjs --track=<quick|medium|standard> --discovery-mode=<lean|guided|deep> --class=<class> --prompt=<prompt> --stack=<stack> --reason=<matched heuristic>\`
|
|
93
95
|
If this helper fails, STOP. Report one human-readable failure line from the JSON \`error\` field, include the helper JSON payload in a fenced \`json\` block, and never echo the invoking command line. Do **not** manually edit \`${flowPath}\`.
|
|
94
96
|
11. The helper persists \`${flowPath}\`, computes \`skippedStages\`, sets the first stage for the track, resets the gate catalog, and writes \`.cclaw/artifacts/00-idea.md\`.
|
|
95
97
|
12. Load the **first-stage skill for the chosen track** and its command file:
|
|
@@ -103,9 +105,9 @@ ${conversationLanguagePolicyMarkdown()}
|
|
|
103
105
|
If during any stage the agent discovers evidence that contradicts the initial Phase 0 / track decision (e.g. a supposedly \`trivial\` change turns out to require schema migration, a \`quick\` bug fix turns out to need design discussion, an origin doc reveals scope 3× larger than the prompt), STOP and re-classify:
|
|
104
106
|
|
|
105
107
|
1. Surface the new evidence in plain text.
|
|
106
|
-
2. Propose the updated \`Class
|
|
108
|
+
2. Propose the updated \`Class\`, internal \`Track\`, and (when discovery posture should change) \`Discovery mode\` with a one-line reason.
|
|
107
109
|
3. Use the Decision Protocol to let the user accept, override, or cancel.
|
|
108
|
-
4. On acceptance: run \`node .cclaw/hooks/start-flow.mjs --reclassify --track=<new-track> --class=<new-class> --reason=<why>\`. The helper appends a \`Reclassification:\` entry to \`00-idea.md\` and updates flow state atomically. If it fails, STOP and report one human-readable line plus the helper JSON payload in a fenced \`json\` block; never echo the invoking command line. Do NOT manually edit \`flow-state.json\`.
|
|
110
|
+
4. On acceptance: run \`node .cclaw/hooks/start-flow.mjs --reclassify --track=<new-track> --discovery-mode=<lean|guided|deep> --class=<new-class> --reason=<why>\`. The helper appends a \`Reclassification:\` entry to \`00-idea.md\` and updates flow state atomically. If it fails, STOP and report one human-readable line plus the helper JSON payload in a fenced \`json\` block; never echo the invoking command line. Do NOT manually edit \`flow-state.json\`.
|
|
109
111
|
|
|
110
112
|
### Without prompt (\`/cc\`)
|
|
111
113
|
|
|
@@ -153,7 +155,7 @@ description: "Unified entry point for the cclaw flow. No args = resume/next. Wit
|
|
|
153
155
|
\`/cc\` is the **starting command** for cclaw. It intelligently routes:
|
|
154
156
|
|
|
155
157
|
- **No arguments** → resumes or progresses an existing tracked flow; missing/fresh placeholder state blocks with start guidance
|
|
156
|
-
- **With a prompt** → classifies the task,
|
|
158
|
+
- **With a prompt** → classifies the task, asks for one discovery mode (lean/guided/deep), resolves an internal track (quick/medium/standard), and starts the **first stage of that track** (not always brainstorm — e.g. the \`quick\` track starts at \`spec\`)
|
|
157
159
|
|
|
158
160
|
## HARD-GATE
|
|
159
161
|
|
|
@@ -174,7 +176,7 @@ ${conversationLanguagePolicyMarkdown()}
|
|
|
174
176
|
- Ask: "Continue with reset? (A) Yes, start fresh (B) No, resume current flow"
|
|
175
177
|
- If (B) → switch to Path B behavior.
|
|
176
178
|
If \`completedStages\` is empty, all gate \`passed\` arrays are empty, and \`${RUNTIME_ROOT}/artifacts/00-idea.md\` is missing, treat it as a fresh init placeholder — do **not** ask whether to continue the current flow.
|
|
177
|
-
7. **Classify the idea** using the heuristic below and present one compact Start framing summary (class, track, stack, origin docs, seed recalls, next action). Wait for explicit confirmation or override before mutating any state only when reset/conflict/ambiguity makes it necessary.
|
|
179
|
+
7. **Classify the idea** using the heuristic below and present one compact Start framing summary (class, internal track recommendation, stack, origin docs, seed recalls, next action). Wait for explicit confirmation or override before mutating any state only when reset/conflict/ambiguity makes it necessary.
|
|
178
180
|
- If \`${RUNTIME_ROOT}/config.yaml\` defines \`trackHeuristics\`, apply those vocabulary hints (\`fallback\`, \`tracks.<id>.{triggers,veto}\`) on top of built-in defaults. Evaluation order is fixed: \`standard -> medium -> quick\`. (Honest note: this is advisory prose; the LLM applies it, not a Node-level router.)
|
|
179
181
|
|
|
180
182
|
**Track heuristic** (lowercase substring match against the user prompt):
|
|
@@ -187,12 +189,15 @@ ${conversationLanguagePolicyMarkdown()}
|
|
|
187
189
|
|
|
188
190
|
- On conflict, prefer \`standard\` over \`medium\`, and \`medium\` over \`quick\`.
|
|
189
191
|
- Always state the recommendation as a one-line reason citing matched triggers and a high/medium/low track selection confidence. Clarify that the heuristic is advisory until the managed helper writes state; after that, \`/cc\` follows the selected track. Include override guidance: switch to standard when architecture, schema, migration, security, or unclear scope appears; switch to medium when product framing is needed but architecture is known.
|
|
190
|
-
8.
|
|
191
|
-
|
|
192
|
+
8. Ask for the single explicit start choice: \`Lean / Guided / Deep\`. Use \`Guided\` as the recommended default unless the user clearly wants compact shaping or unusually deep probing. Keep track internal unless contradiction/reset/reclassification requires surfacing an override.
|
|
193
|
+
Normalize the answer (\`trim\`, lower-case) to exactly \`lean\` / \`guided\` / \`deep\` before invoking the start helper; re-ask once if the reply is not one of those. Pass only canonical lowercase tokens to \`--discovery-mode\`.
|
|
194
|
+
If the prompt is one short line (at most 12 words) and the workspace matches an empty-repo signal set — either persisted \`repoSignals\` has \`fileCount < 5\` with \`hasReadme\` and \`hasPackageManifest\` false, OR a shallow scan before the first \`start-flow\` shows the same — recommend \`guided\` and confirm before defaulting to \`deep\`.
|
|
195
|
+
9. Run the managed start helper: \`node .cclaw/hooks/start-flow.mjs --track=<quick|medium|standard> --discovery-mode=<lean|guided|deep> --class=<class> --prompt=<prompt> --stack=<stack> --reason=<matched heuristic>\`. The helper writes \`${flowPath}\`, including \`discoveryMode\`, computes \`skippedStages\`, resets the gate catalog, and writes \`${RUNTIME_ROOT}/artifacts/00-idea.md\`. If it fails, STOP, report one human-readable failure line from the JSON \`error\` field, and include the helper JSON payload in a fenced \`json\` block; do not echo the invoking command line, and do not manually edit flow state.
|
|
196
|
+
10. Load and execute the **first stage skill of the chosen track** (\`brainstorm\` for medium/standard, \`spec\` for quick) plus its matching command file.
|
|
192
197
|
|
|
193
198
|
### Reclassification on discovery
|
|
194
199
|
|
|
195
|
-
If mid-stage evidence contradicts the initial Class/Track decision (the "trivial" change needs a migration, the "quick" bug fix needs architecture work, an origin doc multiplies scope), STOP and re-classify using the Decision Protocol. On acceptance, run \`node .cclaw/hooks/start-flow.mjs --reclassify --track=<new-track> --class=<new-class> --reason=<why>\`; the helper records \`Reclassification:\` in \`00-idea.md\` and updates state atomically. If it fails, report one human-readable line plus the helper JSON payload in a fenced \`json\` block, never echo the invoking command line, and do not rewrite prior artifacts or manually edit flow-state.
|
|
200
|
+
If mid-stage evidence contradicts the initial Class/Track/Discovery decision (the "trivial" change needs a migration, the "quick" bug fix needs architecture work, an origin doc multiplies scope), STOP and re-classify using the Decision Protocol. On acceptance, run \`node .cclaw/hooks/start-flow.mjs --reclassify --track=<new-track> --discovery-mode=<lean|guided|deep> --class=<new-class> --reason=<why>\`; the helper records \`Reclassification:\` in \`00-idea.md\` and updates state atomically. If it fails, report one human-readable line plus the helper JSON payload in a fenced \`json\` block, never echo the invoking command line, and do not rewrite prior artifacts or manually edit flow-state.
|
|
196
201
|
|
|
197
202
|
### Path B: \`/cc\` (no arguments)
|
|
198
203
|
|
|
@@ -217,6 +222,6 @@ Use \`/cc\` for the happy path:
|
|
|
217
222
|
| Progressing after completing a stage | \`/cc\` |
|
|
218
223
|
| Starting with a specific idea | \`/cc <idea>\` |
|
|
219
224
|
|
|
220
|
-
\`/cc <prompt>\` resolves class + track and starts
|
|
225
|
+
\`/cc <prompt>\` resolves class + internal track, asks for one discovery mode, and starts the selected track's first stage; \`/cc\` without a prompt follows the current \`flow-state.json\`.
|
|
221
226
|
`;
|
|
222
227
|
}
|
|
@@ -18,7 +18,7 @@ function automaticStageDelegationTable() {
|
|
|
18
18
|
|---|---|---|
|
|
19
19
|
${rows}
|
|
20
20
|
|
|
21
|
-
> **Track-aware skip (Wave 24, v6.0.0):** mandatory agents are skipped entirely when \`track === "quick"\` OR \`taskClass === "software-bugfix"\`. Use \`mandatoryAgentsFor(stage, track, taskClass)\` from \`src/content/stage-schema.ts\` for the authoritative list at runtime. Proactive agents
|
|
21
|
+
> **Track-aware skip (Wave 24, v6.0.0):** mandatory agents are skipped entirely when \`track === "quick"\` OR \`taskClass === "software-bugfix"\`. Use \`mandatoryAgentsFor(stage, track, taskClass)\` from \`src/content/stage-schema.ts\` for the authoritative list at runtime. Proactive agents are trigger-driven opportunities, not a blanket completion gate, and lean/lightweight early-stage runs may intentionally record none.`;
|
|
22
22
|
}
|
|
23
23
|
function stageSummary(stage) {
|
|
24
24
|
return stageDelegationSummary("standard").find((row) => row.stage === stage)
|
|
@@ -7,5 +7,5 @@ export declare const RULEBOOK_MARKDOWN = "# Cclaw Rulebook\n\n## MUST_ALWAYS\n-
|
|
|
7
7
|
* (premature draft, premature subagent dispatch, command-line echo to chat).
|
|
8
8
|
*/
|
|
9
9
|
export declare const CURSOR_GUIDELINES_RULE_MDC = "---\ndescription: cclaw zero-install behavior baseline (always-on)\nglobs:\n - \"**/*\"\nalwaysApply: true\n---\n\n<!-- cclaw-managed-cursor-guidelines-rule -->\n\n# Cclaw Baseline Guidelines\n\nThese three rules apply to every Cursor agent session in this project,\nregardless of whether stage skills loaded.\n\n## 1. Q&A floor before drafting (brainstorm/scope/design)\n\nBefore drafting any `.cclaw/artifacts/01-brainstorm-*.md`,\n`02-scope-*.md`, or `03-design-*.md`, verify that the artifact's\n`## Q&A Log` table demonstrates Ralph-Loop convergence: every\nforcing-question topic id is tagged `[topic:<id>]` on at least one row\n(see the stage's forcing-questions checklist for the id list), the last\n2 turns produce no new decision-changing impact, OR an explicit user\nstop-signal row is recorded. Walk the stage forcing questions one at a\ntime via the `AskQuestion` tool. If you find yourself proposing a\ndraft after 1-2 questions while forcing topic ids remain untagged, STOP\nand continue the loop.\n\nThe `qa_log_unconverged` linter rule will block `stage-complete` when\nconvergence has not been reached. Wave 24 (v6.0.0) made `[topic:<id>]`\ntagging mandatory; the English keyword fallback was removed because it\nmis-reported convergence on RU/UA Q&A logs.\n\n## 2. Mandatory subagents run after Q&A approval\n\nFor brainstorm / scope / design, mandatory subagents (\n`product-discovery`, `critic`, `planner`, `architect`,\n`test-author`) run **only AFTER the user approves the elicitation\noutcome**, never before the Q&A loop converges. Dispatching them early\npreempts the user dialogue and violates the elicitation contract \u2014 the\nlinter will block stage-complete.\n\nSee each stage's \"Run Phase: post-elicitation\" rows in the materialized\nAutomatic Subagent Dispatch table.\n\n## 3. Never echo cclaw command lines to chat\n\nThe user does not run cclaw helpers (`node .cclaw/hooks/...`) manually.\nNEVER paste full command lines, `--evidence-json '{...}'` payloads,\n`--waive-delegation=...`, or shell hash commands (`shasum`,\n`sha256sum`, `Get-FileHash`, `certutil`, etc.) into chat. Run the\nhelper via the tool layer and report only the resulting summary. On\nfailure, report a compact human-readable summary plus the helper JSON in\na single fenced `json` block.\n";
|
|
10
|
-
export declare const CURSOR_WORKFLOW_RULE_MDC = "---\ndescription: cclaw workflow guardrails for Cursor agent sessions\nglobs:\n - \"**/*\"\nalwaysApply: true\n---\n\n<!-- cclaw-managed-cursor-workflow-rule -->\n\n# Cclaw Workflow Guardrails\n\n## Activation Rule\n\nBefore responding to coding work:\n1. Read `.cclaw/state/flow-state.json`.\n2. Start with `/cc` or continue with `/cc`.\n3. If no software-stage flow applies, respond normally.\n\n## Stage Order\n\n`brainstorm -> scope -> design -> spec -> plan -> tdd -> review -> ship`\n\nTrack-specific skips are allowed only when `flow-state.track` + `skippedStages` explicitly say so.\n\n## Task Classification\n\n| Class | Route |\n|---|---|\n| non-trivial software work | `/cc <idea>` |\n| trivial software fix | `/cc <idea>` (quick track) |\n| bugfix with repro | `/cc <idea>` and enforce RED-first in tdd |\n| pure question / non-software | direct answer (no stage flow) |\n\n## Command Surface\n\n- `/cc` = entry and resume.\n- `/cc` = only progression path.\n- Knowledge capture and recall use the `learnings` skill when requested.\n\n## Verification Discipline\n\n- No completion claim without fresh command evidence in this turn.\n- Do not mark gates passed from memory.\n- Keep evidence in `.cclaw/artifacts/`; archive through closeout via `/cc` or cancel early via `node .cclaw/hooks/cancel-run.mjs`.\n\n## Delegation And Approvals\n\n- Machine-only checks in design/plan/tdd/review/ship should auto-dispatch when tooling supports it.\n- **For brainstorm / scope / design stages**: ask user input continuously via adaptive elicitation (one question per turn through the harness-native question tool \u2014 `AskQuestion` in Cursor). Walk the stage forcing-questions list one-by-one. **Tag each Q&A Log row's `Decision impact` cell with `[topic:<id>]`** (the id is given in the stage's forcing-questions checklist) so the linter can verify coverage in any natural language. Do NOT batch and do NOT defer to a single approval gate at the end. The `qa_log_unconverged` linter rule will block `stage-complete` when convergence is not reached (forcing topic ids untagged AND last 2 turns still produce decision-changing rows AND no stop-signal).\n- **For other stages** (spec/plan/tdd/build/review/ship): ask user input only at explicit approval gates (scope mode, plan approval, challenge resolution, ship finalization), not for routine progress updates.\n- If you find yourself proposing a draft after 1-2 questions in brainstorm/scope/design, STOP \u2014 go back to the forcing-questions list and continue.\n- Mandatory subagents in brainstorm/scope/design run only AFTER the user approves the elicitation outcome (see each stage's \"Run Phase: post-elicitation\" rows). Dispatching them before the Q&A loop converges violates the contract.\n- Never echo cclaw command lines (`node .cclaw/hooks/...`, `--evidence-json '{...}'`) to chat \u2014 the user does not run cclaw manually. Run helpers via the tool layer; report only the resulting summary.\n- If harness capabilities are partial, record waiver reasons in delegation logs.\n\n## Routing Source Of Truth\n\n- Primary router: `.cclaw/skills/using-cclaw/SKILL.md`.\n- Stage behavior: current stage skill plus `.cclaw/state/flow-state.json`.\n- Preamble budget: keep role/status announcements brief and avoid repeating\n them unless the stage or role changes.\n";
|
|
10
|
+
export declare const CURSOR_WORKFLOW_RULE_MDC = "---\ndescription: cclaw workflow guardrails for Cursor agent sessions\nglobs:\n - \"**/*\"\nalwaysApply: true\n---\n\n<!-- cclaw-managed-cursor-workflow-rule -->\n\n# Cclaw Workflow Guardrails\n\n## Activation Rule\n\nBefore responding to coding work:\n1. Read `.cclaw/state/flow-state.json`.\n2. Start with `/cc` or continue with `/cc`.\n3. If no software-stage flow applies, respond normally.\n\n## Stage Order\n\n`brainstorm -> scope -> design -> spec -> plan -> tdd -> review -> ship`\n\nTrack-specific skips are allowed only when `flow-state.track` + `skippedStages` explicitly say so.\n\n## Task Classification\n\n| Class | Route |\n|---|---|\n| non-trivial software work | `/cc <idea>` |\n| trivial software fix | `/cc <idea>` (quick track) |\n| bugfix with repro | `/cc <idea>` and enforce RED-first in tdd |\n| pure question / non-software | direct answer (no stage flow) |\n\n## Command Surface\n\n- `/cc` = entry and resume.\n- `/cc` = only progression path.\n- Knowledge capture and recall use the `learnings` skill when requested.\n\n## Verification Discipline\n\n- No completion claim without fresh command evidence in this turn.\n- Stage completion claim requires `stage-complete` exit 0 in the current turn. Quote the success line; do not paraphrase, do not infer success from skipped retries.\n- Do not mark gates passed from memory.\n- Keep evidence in `.cclaw/artifacts/`; archive through closeout via `/cc` or cancel early via `node .cclaw/hooks/cancel-run.mjs`.\n\n## Delegation And Approvals\n\n- Machine-only checks in design/plan/tdd/review/ship should auto-dispatch when tooling supports it.\n- **For brainstorm / scope / design stages**: ask user input continuously via adaptive elicitation (one question per turn through the harness-native question tool \u2014 `AskQuestion` in Cursor). Walk the stage forcing-questions list one-by-one. **Tag each Q&A Log row's `Decision impact` cell with `[topic:<id>]`** (the id is given in the stage's forcing-questions checklist) so the linter can verify coverage in any natural language. Do NOT batch and do NOT defer to a single approval gate at the end. The `qa_log_unconverged` linter rule will block `stage-complete` when convergence is not reached (forcing topic ids untagged AND last 2 turns still produce decision-changing rows AND no stop-signal).\n- **For other stages** (spec/plan/tdd/build/review/ship): ask user input only at explicit approval gates (scope mode, plan approval, challenge resolution, ship finalization), not for routine progress updates.\n- If you find yourself proposing a draft after 1-2 questions in brainstorm/scope/design, STOP \u2014 go back to the forcing-questions list and continue.\n- Mandatory subagents in brainstorm/scope/design run only AFTER the user approves the elicitation outcome (see each stage's \"Run Phase: post-elicitation\" rows). Dispatching them before the Q&A loop converges violates the contract.\n- Never echo cclaw command lines (`node .cclaw/hooks/...`, `--evidence-json '{...}'`) to chat \u2014 the user does not run cclaw manually. Run helpers via the tool layer; report only the resulting summary.\n- If harness capabilities are partial, record waiver reasons in delegation logs.\n\n## Routing Source Of Truth\n\n- Primary router: `.cclaw/skills/using-cclaw/SKILL.md`.\n- Stage behavior: current stage skill plus `.cclaw/state/flow-state.json`.\n- Preamble budget: keep role/status announcements brief and avoid repeating\n them unless the stage or role changes.\n";
|
|
11
11
|
export declare function buildRulesJson(): Record<string, unknown>;
|
|
@@ -1565,6 +1565,7 @@ Track-specific skips are allowed only when \`flow-state.track\` + \`skippedStage
|
|
|
1565
1565
|
## Verification Discipline
|
|
1566
1566
|
|
|
1567
1567
|
- No completion claim without fresh command evidence in this turn.
|
|
1568
|
+
- Stage completion claim requires \`stage-complete\` exit 0 in the current turn. Quote the success line; do not paraphrase, do not infer success from skipped retries.
|
|
1568
1569
|
- Do not mark gates passed from memory.
|
|
1569
1570
|
- Keep evidence in \`.cclaw/artifacts/\`; archive through closeout via \`/cc\` or cancel early via \`node .cclaw/hooks/cancel-run.mjs\`.
|
|
1570
1571
|
|
package/dist/delegation.js
CHANGED
|
@@ -481,9 +481,9 @@ export async function checkMandatoryDelegations(projectRoot, stage, options = {}
|
|
|
481
481
|
// via `flow-state.json`. Forward-typed `null` callers still suppress
|
|
482
482
|
// the lookup explicitly; only `undefined` triggers the fallback.
|
|
483
483
|
const resolvedTaskClass = options.taskClass !== undefined ? options.taskClass : flowState.taskClass ?? null;
|
|
484
|
-
const mandatory = mandatoryAgentsFor(stage, flowState.track, resolvedTaskClass);
|
|
484
|
+
const mandatory = mandatoryAgentsFor(stage, flowState.track, resolvedTaskClass, "standard", flowState.discoveryMode);
|
|
485
485
|
const skippedByTrack = mandatory.length === 0 &&
|
|
486
|
-
stageSchema(stage, flowState.track).mandatoryDelegations.length > 0;
|
|
486
|
+
stageSchema(stage, flowState.track, flowState.discoveryMode, resolvedTaskClass).mandatoryDelegations.length > 0;
|
|
487
487
|
if (skippedByTrack) {
|
|
488
488
|
await recordMandatorySkippedByTrack(projectRoot, {
|
|
489
489
|
stage,
|
package/dist/flow-state.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import type { FlowStage, FlowTrack, TransitionRule } from "./types.js";
|
|
1
|
+
import type { DiscoveryMode, FlowStage, FlowTrack, TransitionRule } from "./types.js";
|
|
2
2
|
export declare const TRANSITION_RULES: TransitionRule[];
|
|
3
3
|
export declare const FLOW_STATE_SCHEMA_VERSION = 1;
|
|
4
|
+
/** Snapshot from `collectRepoSignals` at last successful `start-flow` (optional on older states). */
|
|
5
|
+
export interface RepoSignals {
|
|
6
|
+
fileCount: number;
|
|
7
|
+
hasReadme: boolean;
|
|
8
|
+
hasPackageManifest: boolean;
|
|
9
|
+
capturedAt: string;
|
|
10
|
+
}
|
|
4
11
|
export interface StageGateState {
|
|
5
12
|
required: string[];
|
|
6
13
|
recommended: string[];
|
|
@@ -76,6 +83,8 @@ export interface FlowState {
|
|
|
76
83
|
stageGateCatalog: Record<FlowStage, StageGateState>;
|
|
77
84
|
/** Active flow track (determines which stages are in the critical path for this run). */
|
|
78
85
|
track: FlowTrack;
|
|
86
|
+
/** Run-level upstream shaping mode chosen once at start (`lean` / `guided` / `deep`). */
|
|
87
|
+
discoveryMode: DiscoveryMode;
|
|
79
88
|
/**
|
|
80
89
|
* Wave 25 (v6.1.0) — optional task class for the active run.
|
|
81
90
|
*
|
|
@@ -102,6 +111,8 @@ export interface FlowState {
|
|
|
102
111
|
retro: RetroState;
|
|
103
112
|
/** Ship → post_ship_review → archive substate for resumable closeout. */
|
|
104
113
|
closeout: CloseoutState;
|
|
114
|
+
/** Repo shape signals captured at last successful start-flow (omit on legacy files). */
|
|
115
|
+
repoSignals?: RepoSignals;
|
|
105
116
|
}
|
|
106
117
|
export interface StageInteractionHint {
|
|
107
118
|
skipQuestions?: boolean;
|
|
@@ -123,8 +134,10 @@ export interface StageInteractionHint {
|
|
|
123
134
|
export interface InitialFlowStateOptions {
|
|
124
135
|
activeRunId?: string;
|
|
125
136
|
track?: FlowTrack;
|
|
137
|
+
discoveryMode?: DiscoveryMode;
|
|
126
138
|
}
|
|
127
139
|
export declare function isFlowTrack(value: unknown): value is FlowTrack;
|
|
140
|
+
export declare function isDiscoveryMode(value: unknown): value is DiscoveryMode;
|
|
128
141
|
export declare function trackStages(track: FlowTrack): FlowStage[];
|
|
129
142
|
export declare function skippedStagesForTrack(track: FlowTrack): FlowStage[];
|
|
130
143
|
export declare function firstStageForTrack(track: FlowTrack): FlowStage;
|
package/dist/flow-state.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildTransitionRules, orderedStageSchemas, stageGateIds, stageRecommendedGateIds } from "./content/stage-schema.js";
|
|
2
|
-
import { FLOW_STAGES, FLOW_TRACKS, TRACK_STAGES } from "./types.js";
|
|
2
|
+
import { DISCOVERY_MODES, FLOW_STAGES, FLOW_TRACKS, TRACK_STAGES } from "./types.js";
|
|
3
3
|
export const TRANSITION_RULES = buildTransitionRules();
|
|
4
4
|
export const FLOW_STATE_SCHEMA_VERSION = 1;
|
|
5
5
|
/**
|
|
@@ -47,6 +47,9 @@ export function createInitialCloseoutState() {
|
|
|
47
47
|
export function isFlowTrack(value) {
|
|
48
48
|
return typeof value === "string" && FLOW_TRACKS.includes(value);
|
|
49
49
|
}
|
|
50
|
+
export function isDiscoveryMode(value) {
|
|
51
|
+
return typeof value === "string" && DISCOVERY_MODES.includes(value);
|
|
52
|
+
}
|
|
50
53
|
export function trackStages(track) {
|
|
51
54
|
return [...TRACK_STAGES[track]];
|
|
52
55
|
}
|
|
@@ -67,6 +70,7 @@ export function createInitialFlowState(activeRunIdOrOptions = {}, maybeTrack) {
|
|
|
67
70
|
: activeRunIdOrOptions;
|
|
68
71
|
const activeRunId = options.activeRunId ?? createRunId();
|
|
69
72
|
const track = options.track ?? "standard";
|
|
73
|
+
const discoveryMode = options.discoveryMode ?? "guided";
|
|
70
74
|
const skippedStages = skippedStagesForTrack(track);
|
|
71
75
|
const stageGateCatalog = {};
|
|
72
76
|
for (const schema of orderedStageSchemas(track)) {
|
|
@@ -87,6 +91,7 @@ export function createInitialFlowState(activeRunIdOrOptions = {}, maybeTrack) {
|
|
|
87
91
|
guardEvidence: {},
|
|
88
92
|
stageGateCatalog,
|
|
89
93
|
track,
|
|
94
|
+
discoveryMode,
|
|
90
95
|
skippedStages,
|
|
91
96
|
staleStages: {},
|
|
92
97
|
rewinds: [],
|
package/dist/gate-evidence.js
CHANGED
|
@@ -210,7 +210,7 @@ const DESIGN_RESEARCH_REQUIRED_SECTIONS = [
|
|
|
210
210
|
];
|
|
211
211
|
export async function verifyCurrentStageGateEvidence(projectRoot, flowState, options = {}) {
|
|
212
212
|
const stage = flowState.currentStage;
|
|
213
|
-
const schema = stageSchema(stage, flowState.track);
|
|
213
|
+
const schema = stageSchema(stage, flowState.track, flowState.discoveryMode, flowState.taskClass ?? null);
|
|
214
214
|
const catalog = flowState.stageGateCatalog[stage];
|
|
215
215
|
const required = schema.requiredGates
|
|
216
216
|
.filter((gate) => gate.tier === "required")
|
|
@@ -462,6 +462,7 @@ export async function verifyCurrentStageGateEvidence(projectRoot, flowState, opt
|
|
|
462
462
|
const skipQuestionsHint = flowState.interactionHints?.[stage]?.skipQuestions === true ||
|
|
463
463
|
(options.extraStageFlags ?? []).includes("--skip-questions");
|
|
464
464
|
const floor = evaluateQaLogFloor(qaLogBody, flowState.track, stage, {
|
|
465
|
+
discoveryMode: flowState.discoveryMode,
|
|
465
466
|
skipQuestions: skipQuestionsHint
|
|
466
467
|
});
|
|
467
468
|
qaLogFloor = {
|
|
@@ -498,7 +499,7 @@ export function verifyCompletedStagesGateClosure(flowState) {
|
|
|
498
499
|
const issues = [];
|
|
499
500
|
const openStages = [];
|
|
500
501
|
for (const stage of flowState.completedStages) {
|
|
501
|
-
const schema = stageSchema(stage, flowState.track);
|
|
502
|
+
const schema = stageSchema(stage, flowState.track, flowState.discoveryMode, flowState.taskClass ?? null);
|
|
502
503
|
const catalog = flowState.stageGateCatalog[stage];
|
|
503
504
|
const required = schema.requiredGates
|
|
504
505
|
.filter((gate) => gate.tier === "required")
|
|
@@ -526,7 +527,7 @@ export function verifyCompletedStagesGateClosure(flowState) {
|
|
|
526
527
|
}
|
|
527
528
|
export function reconcileCurrentStageGateCatalog(flowState) {
|
|
528
529
|
const stage = flowState.currentStage;
|
|
529
|
-
const schema = stageSchema(stage, flowState.track);
|
|
530
|
+
const schema = stageSchema(stage, flowState.track, flowState.discoveryMode, flowState.taskClass ?? null);
|
|
530
531
|
const required = schema.requiredGates
|
|
531
532
|
.filter((gate) => gate.tier === "required")
|
|
532
533
|
.map((gate) => gate.id);
|