cclaw-cli 0.51.14 → 0.51.15
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/content/skills.js
CHANGED
|
@@ -135,6 +135,9 @@ This is the gate function for completion claims. No "done", "all good", or
|
|
|
135
135
|
"tests pass" unless fresh evidence from this turn proves it.
|
|
136
136
|
|
|
137
137
|
- Run verification commands (tests/build/lint/type-check) for the changed scope.
|
|
138
|
+
- Before \`tdd -> review\` and \`review -> ship\`, discover the real test command
|
|
139
|
+
from repo config (package scripts, pytest/go/cargo/maven/gradle signals) and
|
|
140
|
+
cite that exact command in the gate evidence.
|
|
138
141
|
- Confirm output directly; do not infer success from prior runs or green memories.
|
|
139
142
|
- If this is a bug fix, capture RED -> GREEN evidence for the regression path.
|
|
140
143
|
- If a command fails, report the failure as diagnostic evidence and stop before completion.
|
|
@@ -72,7 +72,7 @@ export const REVIEW = {
|
|
|
72
72
|
{ id: "review_layer_coverage_complete", description: "Layer coverage map in 07-review-army.json confirms spec/correctness/security/performance/architecture/external-safety tags were considered." },
|
|
73
73
|
{ id: "review_criticals_resolved", description: "No unresolved critical blockers remain." },
|
|
74
74
|
{ id: "review_army_json_valid", description: "07-review-army.json passes schema validation (validateReviewArmy)." },
|
|
75
|
-
{ id: "review_trace_matrix_clean", description: "Trace matrix has no orphaned criteria/tasks/test slices for the active run." }
|
|
75
|
+
{ id: "review_trace_matrix_clean", description: "Trace matrix has no orphaned criteria/tasks/test slices for the active run, and evidence cites a discovered real test command before ship handoff." }
|
|
76
76
|
],
|
|
77
77
|
requiredEvidence: [
|
|
78
78
|
"Artifact written to `.cclaw/artifacts/07-review.md`.",
|
|
@@ -82,6 +82,7 @@ export const REVIEW = {
|
|
|
82
82
|
"Layer 2 sections completed with findings.",
|
|
83
83
|
"Severity log includes critical/important/suggestion buckets.",
|
|
84
84
|
"Explicit final verdict: APPROVED, APPROVED_WITH_CONCERNS, or BLOCKED.",
|
|
85
|
+
"Fresh verification command discovery recorded, and the command cited in `review_trace_matrix_clean` evidence before ship handoff.",
|
|
85
86
|
"If BLOCKED: include explicit remediation route (`ROUTE_BACK_TO_TDD`) with blocking finding IDs."
|
|
86
87
|
],
|
|
87
88
|
inputs: ["implementation diff", "spec and plan artifacts", "test/build evidence"],
|
|
@@ -754,6 +754,11 @@ Execution rule: complete and verify each batch before starting the next batch.
|
|
|
754
754
|
- Orphaned tests: 0
|
|
755
755
|
- Evidence ref:
|
|
756
756
|
|
|
757
|
+
## Verification Command Discovery
|
|
758
|
+
| Source | Discovered command | Result | Evidence ref |
|
|
759
|
+
|---|---|---|---|
|
|
760
|
+
| package.json / pytest / go.mod / Cargo.toml / pom.xml / gradle | | PASS/FAIL | |
|
|
761
|
+
|
|
757
762
|
## Blocked Route
|
|
758
763
|
- ROUTE_BACK_TO_TDD: only when Final Verdict = BLOCKED
|
|
759
764
|
- Target stage: tdd
|
package/dist/gate-evidence.js
CHANGED
|
@@ -44,6 +44,64 @@ function sameStringArray(a, b) {
|
|
|
44
44
|
return false;
|
|
45
45
|
return a.every((value, index) => value === b[index]);
|
|
46
46
|
}
|
|
47
|
+
async function readJsonFile(filePath) {
|
|
48
|
+
try {
|
|
49
|
+
const parsed = JSON.parse(await fs.readFile(filePath, "utf8"));
|
|
50
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
51
|
+
? parsed
|
|
52
|
+
: null;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function discoverRealTestCommands(projectRoot) {
|
|
59
|
+
const commands = [];
|
|
60
|
+
const packageJson = await readJsonFile(path.join(projectRoot, "package.json"));
|
|
61
|
+
const scripts = packageJson?.scripts;
|
|
62
|
+
if (scripts && typeof scripts === "object" && !Array.isArray(scripts)) {
|
|
63
|
+
const scriptNames = Object.keys(scripts).filter((name) => {
|
|
64
|
+
const value = scripts[name];
|
|
65
|
+
return typeof value === "string" && (name === "test" || name.startsWith("test:"));
|
|
66
|
+
});
|
|
67
|
+
for (const name of scriptNames.sort()) {
|
|
68
|
+
commands.push(name === "test" ? "npm test" : `npm run ${name}`);
|
|
69
|
+
commands.push(name === "test" ? "pnpm test" : `pnpm ${name}`);
|
|
70
|
+
commands.push(name === "test" ? "yarn test" : `yarn ${name}`);
|
|
71
|
+
commands.push(name === "test" ? "bun test" : `bun run ${name}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (await exists(path.join(projectRoot, "pyproject.toml")))
|
|
75
|
+
commands.push("pytest");
|
|
76
|
+
if (await exists(path.join(projectRoot, "pytest.ini")))
|
|
77
|
+
commands.push("pytest");
|
|
78
|
+
if (await exists(path.join(projectRoot, "go.mod")))
|
|
79
|
+
commands.push("go test ./...");
|
|
80
|
+
if (await exists(path.join(projectRoot, "Cargo.toml")))
|
|
81
|
+
commands.push("cargo test");
|
|
82
|
+
if (await exists(path.join(projectRoot, "pom.xml")))
|
|
83
|
+
commands.push("mvn test");
|
|
84
|
+
if (await exists(path.join(projectRoot, "build.gradle")) ||
|
|
85
|
+
await exists(path.join(projectRoot, "build.gradle.kts"))) {
|
|
86
|
+
commands.push("gradle test", "./gradlew test");
|
|
87
|
+
}
|
|
88
|
+
return unique(commands);
|
|
89
|
+
}
|
|
90
|
+
async function verifyDiscoveredCommandEvidence(projectRoot, stage, gateId, flowState) {
|
|
91
|
+
if (!(stage === "tdd" && gateId === "tdd_verified_before_complete") &&
|
|
92
|
+
!(stage === "review" && gateId === "review_trace_matrix_clean")) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const commands = await discoverRealTestCommands(projectRoot);
|
|
96
|
+
if (commands.length === 0)
|
|
97
|
+
return null;
|
|
98
|
+
const evidence = flowState.guardEvidence[gateId];
|
|
99
|
+
const normalizedEvidence = typeof evidence === "string" ? evidence.toLowerCase() : "";
|
|
100
|
+
const matched = commands.some((command) => normalizedEvidence.includes(command.toLowerCase()));
|
|
101
|
+
if (matched)
|
|
102
|
+
return null;
|
|
103
|
+
return `${stage} verification gate blocked (${gateId}): guard evidence must cite one discovered real test command: ${commands.join(", ")}.`;
|
|
104
|
+
}
|
|
47
105
|
const RECONCILIATION_NOTICES_FILE = "reconciliation-notices.json";
|
|
48
106
|
const RECONCILIATION_NOTICES_SCHEMA_VERSION = 1;
|
|
49
107
|
const DESIGN_RESEARCH_REQUIRED_SECTIONS = [
|
|
@@ -203,6 +261,11 @@ export async function verifyCurrentStageGateEvidence(projectRoot, flowState) {
|
|
|
203
261
|
const evidence = flowState.guardEvidence[gateId];
|
|
204
262
|
if (typeof evidence !== "string" || evidence.trim().length === 0) {
|
|
205
263
|
issues.push(`passed gate "${gateId}" is missing guardEvidence entry.`);
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
const discoveredCommandIssue = await verifyDiscoveredCommandEvidence(projectRoot, stage, gateId, flowState);
|
|
267
|
+
if (discoveredCommandIssue) {
|
|
268
|
+
issues.push(discoveredCommandIssue);
|
|
206
269
|
}
|
|
207
270
|
}
|
|
208
271
|
for (const gateId of catalog.blocked) {
|
|
@@ -203,6 +203,15 @@ const GATE_EVIDENCE_VALIDATORS = {
|
|
|
203
203
|
}
|
|
204
204
|
return null;
|
|
205
205
|
},
|
|
206
|
+
"review:review_trace_matrix_clean": (evidence) => {
|
|
207
|
+
if (!TEST_COMMAND_HINT_PATTERN.test(evidence)) {
|
|
208
|
+
return "must include the fresh verification command that was run before ship handoff (for example `npm test`, `pytest`, `go test`, or equivalent).";
|
|
209
|
+
}
|
|
210
|
+
if (!PASS_STATUS_PATTERN.test(evidence)) {
|
|
211
|
+
return "must include explicit success status (for example `PASS` or `GREEN`).";
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
},
|
|
206
215
|
"ship:ship_finalization_executed": (evidence) => {
|
|
207
216
|
if (!SHIP_FINALIZATION_MODE_PATTERN.test(evidence)) {
|
|
208
217
|
return `must name the finalization mode that ran (for example ${SHIP_FINALIZATION_MODE_HINT}).`;
|