cclaw-cli 0.51.8 → 0.51.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/artifact-linter.js
CHANGED
|
@@ -252,7 +252,7 @@ function meaningfulLineCount(sectionBody) {
|
|
|
252
252
|
.filter((line) => line.length > 0)
|
|
253
253
|
.filter((line) => !line.startsWith("<!--"))
|
|
254
254
|
.filter((line) => !/^[-:| ]+$/u.test(line))
|
|
255
|
-
.filter((line) => /[
|
|
255
|
+
.filter((line) => /[\p{L}\p{N}]/u.test(line))
|
|
256
256
|
.length;
|
|
257
257
|
}
|
|
258
258
|
function lineHasToken(line, token) {
|
|
@@ -366,11 +366,16 @@ function getMarkdownTableRows(sectionBody) {
|
|
|
366
366
|
}
|
|
367
367
|
function getApproachRows(sectionBody) {
|
|
368
368
|
const tableRows = getMarkdownTableRows(sectionBody).map((row) => row.join(" "));
|
|
369
|
+
const headingRows = sectionBody
|
|
370
|
+
.split(/\r?\n/u)
|
|
371
|
+
.map((line) => line.trim())
|
|
372
|
+
.filter((line) => /^#{3,6}\s+\S/u.test(line))
|
|
373
|
+
.map((line) => line.replace(/^#{3,6}\s+/u, ""));
|
|
369
374
|
const bulletRows = sectionBody
|
|
370
375
|
.split(/\r?\n/u)
|
|
371
376
|
.map((line) => line.trim())
|
|
372
377
|
.filter((line) => /^(?:[-*]|\d+\.)\s+\S/u.test(line));
|
|
373
|
-
return [...tableRows, ...bulletRows];
|
|
378
|
+
return [...tableRows, ...headingRows, ...bulletRows];
|
|
374
379
|
}
|
|
375
380
|
function hasSemanticChallenger(row) {
|
|
376
381
|
const normalized = row
|
|
@@ -46,31 +46,31 @@ export const SCOPE = {
|
|
|
46
46
|
executionModel: {
|
|
47
47
|
checklist: [
|
|
48
48
|
"**Compact CEO pass first** — read brainstorm, name the job-to-be-done, challenge whether this is the right product slice, and propose the highest-leverage scope in one pass. For simple apps, keep this to a tight scope contract instead of a full strategy workshop.",
|
|
49
|
-
"**Pick one of four gstack modes** — SCOPE EXPANSION, SELECTIVE EXPANSION, HOLD SCOPE, or SCOPE REDUCTION.
|
|
49
|
+
"**Pick one of four gstack modes with the user** — SCOPE EXPANSION, SELECTIVE EXPANSION, HOLD SCOPE, or SCOPE REDUCTION. Recommend one, state why and what signal would change it, then STOP for the user's mode/scope approval before writing the final artifact.",
|
|
50
50
|
"**Draft the 10-star vs current-slice boundary** — show what would make the product meaningfully better, then explicitly choose what ships now, what is deferred, and what is excluded without using vague `later/for now` placeholders.",
|
|
51
51
|
"**Premise and leverage check** — test right problem, direct path, no-action outcome, existing-code leverage, and reversibility before asking the user anything.",
|
|
52
52
|
"**Compare implementation alternatives** — include minimum viable, product-grade, and ideal architecture options with effort/risk/reuse, then recommend one.",
|
|
53
|
-
"**Run outside voice before final approval** — for simple/low-risk scope, record one concise adversarial self-check row; for complex/high-risk/configured scope, iterate until threshold. Record the loop summary in `## Spec Review Loop
|
|
53
|
+
"**Run outside voice before final approval** — for simple/low-risk scope, record one concise adversarial self-check row; for complex/high-risk/configured scope, iterate until threshold. Record the loop summary in `## Spec Review Loop`, but do not treat it as user approval.",
|
|
54
54
|
"**Ask only one decision-changing question** — if the user rejects the contract but is unsure, offer 3-4 concrete scope moves instead of open-ended interrogation.",
|
|
55
|
-
"**Write the scope contract** — include in-scope/out-of-scope, discretion areas, deferred items, locked decisions, error/rescue notes, completion dashboard, scope summary, next-stage handoff, and explicit approval."
|
|
55
|
+
"**Write the scope contract after approval** — include in-scope/out-of-scope, discretion areas, deferred items, locked decisions, error/rescue notes, completion dashboard, scope summary, next-stage handoff, and explicit approval evidence."
|
|
56
56
|
],
|
|
57
57
|
interactionProtocol: [
|
|
58
58
|
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"),
|
|
59
|
-
"Do not walk the full checklist by default. Lead with
|
|
60
|
-
"For simple web-app flows, default to HOLD SCOPE or SELECTIVE EXPANSION, show the exact in/out/deferred contract, and
|
|
59
|
+
"Do not walk the full checklist by default. Lead with a proposed scope contract and the one decision that matters most; label the mode as recommended, not selected, until the user answers.",
|
|
60
|
+
"For simple web-app flows, default to HOLD SCOPE or SELECTIVE EXPANSION, show the exact in/out/deferred contract as a proposal, and STOP for one explicit approval before writing the final scope artifact or completing the stage.",
|
|
61
61
|
"Challenge premise first, take a firm position, and name one concrete condition that would change it.",
|
|
62
62
|
"Push back on weak framing: vague scope needs a specific user/problem, platform vision needs a narrow wedge, social proof needs behavioral evidence.",
|
|
63
63
|
"Resolve one structural scope issue at a time; otherwise state the assumption and move on.",
|
|
64
64
|
"If the user says no but cannot name the change, offer concrete moves: keep scope, add one obvious adjacent capability, reduce to wedge, or re-open stack/product direction.",
|
|
65
65
|
`Before final approval, record outside-voice findings and a \`## Spec Review Loop\` table using ${reviewLoopPolicySummary("scope")}`,
|
|
66
|
-
"**STOP.** Wait for explicit approval of the scope contract before advancing.",
|
|
67
|
-
"**STOP BEFORE ADVANCE.** Mandatory delegation `planner` must be completed or explicitly waived. If no isolated planner is available, use `--waive-delegation=planner --waiver-reason=\"role-switch scope self-review completed\"`. Then close with `node .cclaw/hooks/stage-complete.mjs scope --passed=scope_mode_selected,scope_contract_written,scope_user_approved --evidence-json '{\"scope_mode_selected\":\"<mode + rationale>\",\"scope_contract_written\":\"<artifact path + sections>\"}'`.
|
|
66
|
+
"**STOP.** Wait for explicit user approval of the scope mode and scope contract before writing final approval language or advancing.",
|
|
67
|
+
"**STOP BEFORE ADVANCE.** Mandatory delegation `planner` must be completed or explicitly waived. If no isolated planner is available, use `--waive-delegation=planner --waiver-reason=\"role-switch scope self-review completed\"`. Then close with `node .cclaw/hooks/stage-complete.mjs scope --passed=scope_mode_selected,scope_contract_written,scope_user_approved --evidence-json '{\"scope_mode_selected\":\"<user-approved mode + rationale>\",\"scope_contract_written\":\"<artifact path + sections>\",\"scope_user_approved\":\"<explicit user approval quote or summary>\"}'`. `scope_user_approved` must cite the user's approval; review-loop evidence alone is not approval."
|
|
68
68
|
],
|
|
69
69
|
process: [
|
|
70
70
|
"Run configured pre-scope audit only when enabled.",
|
|
71
71
|
"Run the gstack-style CEO scope pass scaled to risk: job-to-be-done, premise challenge, 10-star upside, smallest useful wedge, and what would change the recommendation.",
|
|
72
72
|
"Compare minimum viable, product-grade, and ideal architecture scope alternatives with explicit reuse/effort/risk.",
|
|
73
|
-
"
|
|
73
|
+
"Recommend a scope mode with explicit rationale, then ask for user opt-in before treating it as selected.",
|
|
74
74
|
"Run outside voice / adversarial self-check before final approval and record a valid `## Spec Review Loop` table.",
|
|
75
75
|
"Write explicit scope contract, discretion areas, deferred items, error/rescue registry, and D-XX locked decisions.",
|
|
76
76
|
"Produce scope summary, completion dashboard, and exact next-stage handoff before asking final approval."
|
|
@@ -89,7 +89,7 @@ export const SCOPE = {
|
|
|
89
89
|
"Locked Decisions section lists stable D-XX IDs for non-negotiable boundaries.",
|
|
90
90
|
"Premise challenge findings documented.",
|
|
91
91
|
"Outside Voice findings and dispositions are recorded (accept/reject/defer with rationale) before final approval.",
|
|
92
|
-
`Spec review loop summary includes a table with columns Iteration, Quality Score, Findings, plus Stop reason, Target score, and Max iterations.
|
|
92
|
+
`Spec review loop summary includes a table with columns Iteration, Quality Score, Findings, plus Stop reason, Target score, and Max iterations. This is outside-voice evidence only; it does not satisfy user approval. ${reviewLoopPolicySummary("scope")}`,
|
|
93
93
|
reviewLoopSecondOpinionSummary("scope"),
|
|
94
94
|
"Deferred items list with one-line rationale for each.",
|
|
95
95
|
"When an upside deferred idea is parked, a seed file is created under `.cclaw/seeds/` and referenced in the artifact.",
|
|
@@ -70,7 +70,7 @@ ${conversationLanguagePolicyMarkdown()}
|
|
|
70
70
|
Skip detection quietly if no markers are found — do NOT invent a stack.
|
|
71
71
|
|
|
72
72
|
5. Read \`${flowPath}\`.
|
|
73
|
-
6. If flow already has completed stages, warn the user that starting a new tracked flow will reset progress. Ask for confirmation before proceeding.
|
|
73
|
+
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.
|
|
74
74
|
7. **Track heuristic** — classify the idea text and **recommend** a track (the user can override before any state mutation):
|
|
75
75
|
- 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).
|
|
76
76
|
- **quick** (\`spec → tdd → review → ship\`) — single-purpose work where the spec is essentially already known.
|
|
@@ -152,7 +152,7 @@ description: "Unified entry point for the cclaw flow. No args = resume/next. Wit
|
|
|
152
152
|
|
|
153
153
|
## HARD-GATE
|
|
154
154
|
|
|
155
|
-
Do **not** silently discard an existing flow when the user provides a prompt. If completed stages exist, inform and confirm before resetting.
|
|
155
|
+
Do **not** silently discard an existing flow when the user provides a prompt. If completed stages exist, inform and confirm before resetting. A freshly initialized placeholder state with \`completedStages: []\`, no passed gates, and no \`${RUNTIME_ROOT}/artifacts/00-idea.md\` is not an active flow; classify the prompt and start normally.
|
|
156
156
|
|
|
157
157
|
${conversationLanguagePolicyMarkdown()}
|
|
158
158
|
## Protocol
|
|
@@ -168,6 +168,7 @@ ${conversationLanguagePolicyMarkdown()}
|
|
|
168
168
|
- Inform: "You have an active flow at stage **{currentStage}** with {N} completed stages. Starting a new tracked flow will reset progress."
|
|
169
169
|
- Ask: "Continue with reset? (A) Yes, start fresh (B) No, resume current flow"
|
|
170
170
|
- If (B) → switch to Path B behavior.
|
|
171
|
+
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.
|
|
171
172
|
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.
|
|
172
173
|
- 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.)
|
|
173
174
|
|
|
@@ -19,7 +19,6 @@ import { runTddLoopStatusCommand } from "./tdd-loop-status.js";
|
|
|
19
19
|
import { runTddRedEvidenceCommand } from "./tdd-red-evidence.js";
|
|
20
20
|
import { extractReviewLoopEnvelopeFromArtifact } from "../content/review-loop.js";
|
|
21
21
|
const AUTO_REVIEW_LOOP_GATE_BY_STAGE = {
|
|
22
|
-
scope: "scope_user_approved",
|
|
23
22
|
design: "design_architecture_locked"
|
|
24
23
|
};
|
|
25
24
|
function unique(values) {
|
|
@@ -163,6 +162,30 @@ function validateReviewLoopGateEvidence(stage, evidence) {
|
|
|
163
162
|
}
|
|
164
163
|
return null;
|
|
165
164
|
}
|
|
165
|
+
function validateUserApprovalEvidence(evidence) {
|
|
166
|
+
const normalized = evidence.trim();
|
|
167
|
+
if (normalized.length === 0) {
|
|
168
|
+
return "must cite explicit user approval.";
|
|
169
|
+
}
|
|
170
|
+
const reviewLoopEnvelope = (() => {
|
|
171
|
+
try {
|
|
172
|
+
return pickReviewLoopEnvelope(JSON.parse(normalized));
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
})();
|
|
178
|
+
if (reviewLoopEnvelope) {
|
|
179
|
+
return "must cite explicit user approval; review-loop evidence is outside-voice evidence, not user approval.";
|
|
180
|
+
}
|
|
181
|
+
if (/\b(?:approved|approval|user approved|confirmed|accepted|yes|ok)\b/iu.test(normalized)) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
if (/\b(?:утвержд(?:аю|ено|ен|ена)|подтвержд(?:аю|ено|ен|ена)|соглас(?:ен|на|овано)|да|ок|принято)\b/iu.test(normalized)) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
return "must cite explicit user approval (for example `user approved the scope contract` or `пользователь утвердил scope`).";
|
|
188
|
+
}
|
|
166
189
|
// Per-gate validators keyed by `${stage}:${gateId}`. Returning a non-null
|
|
167
190
|
// string surfaces the reason as an `advance-stage` failure so evidence is
|
|
168
191
|
// guaranteed to carry the structural breadcrumbs downstream tooling
|
|
@@ -186,7 +209,7 @@ const GATE_EVIDENCE_VALIDATORS = {
|
|
|
186
209
|
}
|
|
187
210
|
return null;
|
|
188
211
|
},
|
|
189
|
-
"scope:scope_user_approved": (evidence) =>
|
|
212
|
+
"scope:scope_user_approved": (evidence) => validateUserApprovalEvidence(evidence),
|
|
190
213
|
"design:design_architecture_locked": (evidence) => validateReviewLoopGateEvidence("design", evidence)
|
|
191
214
|
};
|
|
192
215
|
function validateGateEvidenceShape(stage, gateId, evidence) {
|