vibe-coding-master 0.7.6 → 0.7.8
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 +22 -1
- package/dist/backend/api/harness-routes.js +7 -0
- package/dist/backend/cli/install-vcm-harness.js +7 -0
- package/dist/backend/services/harness-feedback-service.js +28 -0
- package/dist/backend/services/harness-service.js +8 -0
- package/dist/backend/services/job-guard-service.js +4 -4
- package/dist/backend/templates/handoff.js +12 -8
- package/dist/backend/templates/harness/architect-agent.js +28 -9
- package/dist/backend/templates/harness/check-scaffold-ledger.js +226 -0
- package/dist/backend/templates/harness/coder-agent.js +19 -8
- package/dist/backend/templates/harness/coder-worker-agent.js +14 -11
- package/dist/backend/templates/harness/gate-review.js +55 -0
- package/dist/backend/templates/harness/project-coding-standards.js +1 -1
- package/dist/backend/templates/harness/project-manager-agent.js +5 -3
- package/dist/shared/validation/artifact-check.js +10 -0
- package/dist-frontend/assets/{index-BO2AuF-q.js → index-42EpETgd.js} +24 -24
- package/dist-frontend/assets/{index-C2etsYlK.css → index-D65x2x0F.css} +1 -1
- package/dist-frontend/index.html +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -181,6 +181,12 @@ By default:
|
|
|
181
181
|
Roles for the same task share the same task worktree. VCM does not create one
|
|
182
182
|
worktree per role.
|
|
183
183
|
|
|
184
|
+
Project Manager may record an advisory task checkpoint under
|
|
185
|
+
`.ai/vcm/workflow/state.json`. VCM restores and displays this context after a
|
|
186
|
+
restart, but it does not infer transitions or choose the next role. Current
|
|
187
|
+
artifacts, Gate Review state, Round/Turn state, and the role rules remain
|
|
188
|
+
authoritative.
|
|
189
|
+
|
|
184
190
|
Typical flow:
|
|
185
191
|
|
|
186
192
|
```text
|
|
@@ -412,10 +418,16 @@ Post-task processing is ordered by the backend:
|
|
|
412
418
|
```text
|
|
413
419
|
Final Acceptance
|
|
414
420
|
-> Review Task Harness
|
|
415
|
-
->
|
|
421
|
+
-> Workflow-role memory proposals, when Auto Memory is enabled
|
|
422
|
+
-> Harness Engineer memory review, when Auto Memory is enabled
|
|
416
423
|
-> Task Harness Retrospective
|
|
417
424
|
```
|
|
418
425
|
|
|
426
|
+
Memory proposal prompts sent to Project Manager, Architect, Coder, Tester, and
|
|
427
|
+
an enabled Gate Reviewer use their normal task sessions and participate in
|
|
428
|
+
Round/Turn tracking. Harness Engineer review and retrospective work remain tool
|
|
429
|
+
role activity and do not participate in Round completion.
|
|
430
|
+
|
|
419
431
|
When Auto Memory is disabled, Review Task Harness does not collect proposals or
|
|
420
432
|
ask Harness Engineer to update memory. When enabled, both automatic and manual
|
|
421
433
|
review requests complete the memory phase before retrospective analysis. A
|
|
@@ -430,6 +442,11 @@ It stops every running session owned by the task, including Translator and
|
|
|
430
442
|
Harness Engineer, then removes task-owned worktree/branch state. Commit or
|
|
431
443
|
preserve anything important before closing.
|
|
432
444
|
|
|
445
|
+
Uncommitted changes, unmerged commits, and cleanup failures are reported as
|
|
446
|
+
warnings; they do not block logical task closure. VCM may discard the task
|
|
447
|
+
worktree and task branch even when they contain commits that are not present on
|
|
448
|
+
the connected repository branch.
|
|
449
|
+
|
|
433
450
|
## Troubleshooting
|
|
434
451
|
|
|
435
452
|
### The page does not open
|
|
@@ -517,7 +534,11 @@ npm start
|
|
|
517
534
|
## Documentation
|
|
518
535
|
|
|
519
536
|
- `docs/ARCHITECTURE.md`: repository architecture
|
|
537
|
+
- `docs/CODING_STANDARDS.md`: shared implementation and test standards
|
|
538
|
+
- `docs/GLOSSARY.md`: allowed durable abbreviations
|
|
520
539
|
- `docs/TESTING.md`: validation strategy
|
|
540
|
+
- `docs/known-issues.md`: current unresolved durable issues
|
|
541
|
+
- `src/backend/gateway/ARCHITECTURE.md`: mobile gateway sub-area architecture
|
|
521
542
|
- `docs/vcm-cc-best-practices.md`: current VCM Claude Code harness practice
|
|
522
543
|
- `docs/v0.5-custom-workflow-plan.md`: deferred custom workflow proposal
|
|
523
544
|
- `docs/cc-best-practices.md`: archived generic Claude Code harness notes
|
|
@@ -142,6 +142,13 @@ export function registerHarnessRoutes(app, deps) {
|
|
|
142
142
|
const taskSlug = await normalizeOptionalTaskSlug(deps, project.repoRoot, request.query.taskSlug);
|
|
143
143
|
return deps.harnessFeedbackService.getState(project.repoRoot, taskSlug);
|
|
144
144
|
});
|
|
145
|
+
app.post("/api/projects/harness/feedback/send", async (request) => {
|
|
146
|
+
const { project, task } = await requireHarnessTaskContext(deps, request.body?.taskSlug);
|
|
147
|
+
return deps.harnessFeedbackService.sendPendingFeedback(project.repoRoot, {
|
|
148
|
+
taskSlug: task.taskSlug,
|
|
149
|
+
feedbackPath: request.body?.feedbackPath ?? ""
|
|
150
|
+
});
|
|
151
|
+
});
|
|
145
152
|
app.post("/api/projects/harness/task-retrospective", async (request) => {
|
|
146
153
|
const { project, task } = await requireHarnessTaskContext(deps, request.body?.taskSlug);
|
|
147
154
|
const trigger = request.body?.trigger === "auto" ? "auto" : "manual";
|
|
@@ -26,6 +26,7 @@ import { renderVcmProposeMemorySkillRules } from "../templates/harness/vcm-propo
|
|
|
26
26
|
import { renderVcmReportHarnessIssueSkillRules } from "../templates/harness/vcm-report-harness-issue-skill.js";
|
|
27
27
|
import { renderVcmRouteMessageSkillRules } from "../templates/harness/vcm-route-message-skill.js";
|
|
28
28
|
import { renderUpdateTaskStateTool, renderVcmTaskStateSkillRules } from "../templates/harness/vcm-task-state-skill.js";
|
|
29
|
+
import { renderCheckScaffoldLedgerTool } from "../templates/harness/check-scaffold-ledger.js";
|
|
29
30
|
import { readVcmPackageVersion } from "../app-version.js";
|
|
30
31
|
const CLI_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
31
32
|
const APP_ROOT = path.resolve(CLI_DIR, "../../..");
|
|
@@ -295,6 +296,12 @@ const WHOLE_FILES = [
|
|
|
295
296
|
mode: 0o755,
|
|
296
297
|
content: renderUpdateTaskStateTool()
|
|
297
298
|
},
|
|
299
|
+
{
|
|
300
|
+
path: ".ai/tools/check-scaffold-ledger",
|
|
301
|
+
category: "runtime-tool",
|
|
302
|
+
mode: 0o755,
|
|
303
|
+
content: renderCheckScaffoldLedgerTool()
|
|
304
|
+
},
|
|
298
305
|
{
|
|
299
306
|
path: ".ai/tools/run-long-check",
|
|
300
307
|
category: "runtime-tool",
|
|
@@ -21,6 +21,23 @@ export function createHarnessFeedbackService(deps) {
|
|
|
21
21
|
warnings: []
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
+
async function sendPendingFeedback(repoRoot, input) {
|
|
25
|
+
await cleanupLegacyState(repoRoot);
|
|
26
|
+
const feedbackPath = input.feedbackPath.trim();
|
|
27
|
+
const pending = await listPendingFeedback(repoRoot);
|
|
28
|
+
const feedback = pending.find((item) => item.path === feedbackPath);
|
|
29
|
+
if (!feedback) {
|
|
30
|
+
throw new VcmError({
|
|
31
|
+
code: "HARNESS_FEEDBACK_NOT_PENDING",
|
|
32
|
+
message: "The selected Harness Feedback is no longer pending.",
|
|
33
|
+
statusCode: 404,
|
|
34
|
+
hint: "Refresh Harness Studio and select a feedback item that is still listed in the Inbox."
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
const session = await ensureIdleHarnessEngineer(repoRoot, input.taskSlug);
|
|
38
|
+
await submitTerminalInput(deps.runtime, session.id, buildPendingFeedbackPrompt(repoRoot, feedback.path));
|
|
39
|
+
return session;
|
|
40
|
+
}
|
|
24
41
|
async function startTaskRetrospective(repoRoot, input) {
|
|
25
42
|
await cleanupLegacyState(repoRoot);
|
|
26
43
|
const taskSlug = input.taskSlug.trim();
|
|
@@ -155,6 +172,16 @@ export function createHarnessFeedbackService(deps) {
|
|
|
155
172
|
"End your turn after writing the result."
|
|
156
173
|
].join("\n");
|
|
157
174
|
}
|
|
175
|
+
function buildPendingFeedbackPrompt(repoRoot, feedbackPath) {
|
|
176
|
+
return [
|
|
177
|
+
"[VCM Harness Feedback]",
|
|
178
|
+
"",
|
|
179
|
+
"Review this feedback:",
|
|
180
|
+
resolveRepoPath(repoRoot, feedbackPath),
|
|
181
|
+
"",
|
|
182
|
+
"Verify the issue against the current harness and project evidence. Report your findings and proposed changes to the user."
|
|
183
|
+
].join("\n");
|
|
184
|
+
}
|
|
158
185
|
async function loadTaskRetrospectiveMarker(repoRoot, taskSlug) {
|
|
159
186
|
const markerPath = resolveRepoPath(repoRoot, getTaskRetrospectiveMarkerPath(taskSlug));
|
|
160
187
|
if (!(await deps.fs.pathExists(markerPath))) {
|
|
@@ -185,6 +212,7 @@ export function createHarnessFeedbackService(deps) {
|
|
|
185
212
|
}
|
|
186
213
|
return {
|
|
187
214
|
getState,
|
|
215
|
+
sendPendingFeedback,
|
|
188
216
|
startTaskRetrospective,
|
|
189
217
|
assertHarnessEngineerAvailable
|
|
190
218
|
};
|
|
@@ -23,6 +23,7 @@ import { renderVcmProposeMemorySkillRules } from "../templates/harness/vcm-propo
|
|
|
23
23
|
import { renderVcmReportHarnessIssueSkillRules } from "../templates/harness/vcm-report-harness-issue-skill.js";
|
|
24
24
|
import { renderVcmRouteMessageSkillRules } from "../templates/harness/vcm-route-message-skill.js";
|
|
25
25
|
import { renderUpdateTaskStateTool, renderVcmTaskStateSkillRules } from "../templates/harness/vcm-task-state-skill.js";
|
|
26
|
+
import { renderCheckScaffoldLedgerTool } from "../templates/harness/check-scaffold-ledger.js";
|
|
26
27
|
import { submitTerminalInput } from "../runtime/terminal-submit.js";
|
|
27
28
|
import { VcmError } from "../errors.js";
|
|
28
29
|
import { bumpHarnessRevision, readHarnessRevisionState } from "./harness-revision.js";
|
|
@@ -215,6 +216,13 @@ const HARNESS_FILES = [
|
|
|
215
216
|
ownership: "raw-file",
|
|
216
217
|
renderRules: renderUpdateTaskStateTool
|
|
217
218
|
},
|
|
219
|
+
{
|
|
220
|
+
kind: "tool-check-scaffold-ledger",
|
|
221
|
+
path: ".ai/tools/check-scaffold-ledger",
|
|
222
|
+
title: "Check Scaffold Ledger Tool",
|
|
223
|
+
ownership: "raw-file",
|
|
224
|
+
renderRules: renderCheckScaffoldLedgerTool
|
|
225
|
+
},
|
|
218
226
|
{
|
|
219
227
|
kind: "agent-project-manager",
|
|
220
228
|
path: ".claude/agents/project-manager.md",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
const ACTIVE_JOB_STATUSES = new Set(["queued", "starting", "running"]);
|
|
4
|
-
const ACTIVE_CODER_WORKER_STATUSES = new Set(["
|
|
4
|
+
const ACTIVE_CODER_WORKER_STATUSES = new Set(["running", "completed"]);
|
|
5
5
|
const QUEUED_JOB_FRESH_MS = 120_000;
|
|
6
6
|
export const MAX_CONSECUTIVE_STOP_BLOCKS = 3;
|
|
7
7
|
export function createJobGuardService(deps = {}) {
|
|
@@ -147,7 +147,6 @@ async function findActiveCoderWorkerTasks(taskRepoRoot) {
|
|
|
147
147
|
workerId: typeof state.workerId === "string" ? state.workerId : path.basename(entry, ".json"),
|
|
148
148
|
status,
|
|
149
149
|
reportPath: typeof state.reportPath === "string" ? state.reportPath : undefined,
|
|
150
|
-
error: typeof state.error === "string" ? state.error : undefined,
|
|
151
150
|
stateMtimeMs
|
|
152
151
|
});
|
|
153
152
|
}
|
|
@@ -177,9 +176,10 @@ function buildCoderWorkerBlockReason(tasks) {
|
|
|
177
176
|
const reports = tasks
|
|
178
177
|
.map((task) => task.reportPath)
|
|
179
178
|
.filter((reportPath) => Boolean(reportPath));
|
|
180
|
-
const reportHint = reports.length > 0 ? `
|
|
179
|
+
const reportHint = reports.length > 0 ? ` Worker report(s): ${reports.join(", ")}.` : "";
|
|
181
180
|
return `VCM: coder worker task ${listing} is still unhandled. Do not end the Coder turn while worker tasks are unhandled. `
|
|
182
|
-
+ `Wait for
|
|
181
|
+
+ `Wait for running workers; inspect every completed worker report, implementation result, item disposition, and commit; `
|
|
182
|
+
+ `then set \`handled: true\` in each worker state and continue.${reportHint}`;
|
|
183
183
|
}
|
|
184
184
|
function latestMtime(...values) {
|
|
185
185
|
return values.reduce((latest, value) => value !== undefined && (latest === undefined || value > latest) ? value : latest, undefined);
|
|
@@ -101,9 +101,15 @@ Task-specific context and coder guidance go here, not in source-code comments.
|
|
|
101
101
|
Source-code comments should only describe durable behavior, contracts, invariants,
|
|
102
102
|
error boundaries, or non-obvious logic that should remain useful after this task.
|
|
103
103
|
|
|
104
|
-
| ID |
|
|
105
|
-
| --- | --- | --- | --- | --- | --- | --- |
|
|
106
|
-
|
|
|
104
|
+
| ID | Action | File | Symbol Or Site | Coder Work | Allowed Implementation Freedom | Behavior / Contract Proof Point |
|
|
105
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
106
|
+
| TBD | TBD | TBD | TBD | TBD | TBD | TBD |
|
|
107
|
+
|
|
108
|
+
## Scaffold Build Evidence
|
|
109
|
+
|
|
110
|
+
| Check | Command | Result | Scaffold Commit |
|
|
111
|
+
| --- | --- | --- | --- |
|
|
112
|
+
| TBD | TBD | TBD | TBD |
|
|
107
113
|
|
|
108
114
|
## Tester Coverage Hints
|
|
109
115
|
|
|
@@ -187,11 +193,9 @@ Decision: ready_for_review|incomplete|failed
|
|
|
187
193
|
|
|
188
194
|
## Scaffold Completion
|
|
189
195
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
TBD
|
|
196
|
+
| ID | Action | Result | Marker State | Proof Evidence |
|
|
197
|
+
| --- | --- | --- | --- | --- |
|
|
198
|
+
| TBD | TBD | TBD | TBD | TBD |
|
|
195
199
|
|
|
196
200
|
## Changed Files
|
|
197
201
|
|
|
@@ -54,20 +54,37 @@ ${renderRoleMemoryRules("architect")}
|
|
|
54
54
|
- Do not begin Architecture Decision, Code Scaffolding, or a complete architecture plan unless \`architecture-brief.md\` has \`Architecture Brief Status: confirmed\`.
|
|
55
55
|
- Treat the confirmed brief as the user-owned behavior and contract input. Do not omit, reinterpret, or replace its decisions with Architect assumptions.
|
|
56
56
|
- Before coder work starts, write \`.ai/vcm/handoffs/architecture-plan.md\`, choose the minimum necessary code scaffolding, and include a Scaffold Manifest for task-specific context and coder guidance.
|
|
57
|
-
- The architecture-plan handoff is not complete until
|
|
57
|
+
- The architecture-plan handoff is not complete until every \`create\`, \`change\`, and \`delete\` ledger item, every new or changed non-private callable surface, contract comments, and all \`VCM:CODE\` placeholders have been scaffolded and committed, and the scaffolded workspace passes the project's compile/typecheck L0 check.
|
|
58
|
+
- Do not defer scaffold creation to the coder turn anywhere in the plan: every signature, placeholder, and ledger item the plan needs must exist at \`Planning Result: complete\`. If something cannot be scaffolded yet, the plan is incomplete or needs user clarification.
|
|
59
|
+
|
|
60
|
+
#### Planning Work Plan
|
|
61
|
+
|
|
62
|
+
- When starting architecture planning for a confirmed brief, first write a \`Current Code Reality / Scope Discovery\` row to \`.ai/vcm/handoffs/planning-progress.md\`, with its scope, deliverable, done criterion, and status. Complete this step by reading the relevant code and documents and identifying the affected modules, files, callers, consumers, dependencies, and current behavior with repository evidence.
|
|
63
|
+
- After \`Current Code Reality / Scope Discovery\` is complete, add the remaining planning steps: one head step for cross-module work (architecture decision, boundaries, ownership, invariants, build-configuration proofs), one middle step per affected module from the module index in dependency order — split a module into per-file steps when it exceeds one round — and one tail step for cross-module wiring, whole-plan ledger reconciliation, and final build evidence. A small task degrades to head, one middle step, and tail.
|
|
64
|
+
- Bind every step to repository facts and machine checks: scope is module or file paths from the module index; deliverable is plan sections or ledger ID ranges; done criterion is a tool output or recorded check result — never a self-assessment.
|
|
65
|
+
- Update \`planning-progress.md\` at the end of every planning round: mark completed steps with their evidence and leave remaining steps unchanged. Do not shrink, merge, or drop a remaining step without recording the change and its reason.
|
|
66
|
+
- If the round ends before all steps are done, report \`Planning Result: incomplete\` with the progress record; project-manager routes continuation. Never compress remaining enumeration or scaffolding into summary rows to reach \`Planning Result: complete\` within the current round — an honest \`incomplete\` with recorded progress is the required outcome.
|
|
67
|
+
- \`planning-progress.md\` is task-runtime state for continuation and routing, not part of the reviewed plan; \`architecture-plan.md\` alone remains the executable plan of record.
|
|
58
68
|
|
|
59
69
|
#### Plan Document
|
|
60
70
|
|
|
61
|
-
- \`architecture-plan.md\` must start with \`Planning Result: complete|incomplete|user clarification required\` and use these sections: Accepted Scope, Current Code Reality, Architecture Decision, Module/File Plan, Public Surface Impact, Scaffold Manifest, Tester Coverage Hints, Docs Impact, Known Risks, and Coder Handoff Notes.
|
|
62
|
-
- Use \`Planning Result: complete\` only when the plan document
|
|
71
|
+
- \`architecture-plan.md\` must start with \`Planning Result: complete|incomplete|user clarification required\` and use these sections: Accepted Scope, Current Code Reality, Architecture Decision, Module/File Plan, Public Surface Impact, Scaffold Manifest, Scaffold Build Evidence, Tester Coverage Hints, Docs Impact, Known Risks, and Coder Handoff Notes.
|
|
72
|
+
- Use \`Planning Result: complete\` only when: the plan document is complete; the Scaffold Manifest ledger reconciles one to one against the committed markers; and \`Scaffold Build Evidence\` records a green compile/typecheck run at the current scaffold commit hash. Include the same Planning Result in the route message to project-manager; do not select the next route.
|
|
63
73
|
- \`architecture-plan.md\` is the current executable plan, not a changelog. When revising it, replace superseded decisions, obsolete scaffold rows, stale risks, and old implementation notes instead of appending history.
|
|
64
74
|
- \`Accepted Scope\`: state the PM-routed task scope and the confirmed brief's required user-visible outcome and decisions, plus any explicit non-scope that prevents accidental expansion.
|
|
65
|
-
- \`Current Code Reality\`: use the required Planning Boundary, Code Reading Evidence, Existing Behavior Trace, and Code / Docs Conflicts subsections. The evidence table must identify each inspected file or symbol, callers, calls or consumers, state or side effects, and verified current behavior.
|
|
75
|
+
- \`Current Code Reality\`: use the required Planning Boundary, Code Reading Evidence, Existing Behavior Trace, and Code / Docs Conflicts subsections. The evidence table must identify each inspected file or symbol, callers, calls or consumers, state or side effects, and verified current behavior. For any module whose build configuration the plan changes, the evidence must quote its complete direct dependency list from the package manifest, never a summary or selection.
|
|
76
|
+
- Any enumeration the plan presents as complete over the codebase — call-site inventories, module or file lists, symbol sets — must either record the deterministic, repository-local command that generates it (run at the scaffold commit, the set transcribed from its output) or be explicitly marked as judgment-derived with the evidence basis for its completeness. A complete-claimed enumeration with neither is not evidence.
|
|
66
77
|
- \`Architecture Decision\`: use the required Changed Behavior Flow, Ownership, Data Flow, Lifecycle, Boundaries, Invariants, Failure Model, and Decision Rationale subsections. Describe why the design fits verified current code.
|
|
67
|
-
- \`Module/File Plan\`: list each affected module, changed or created file, file responsibility, why it is in scope, expected change, dependency direction, user-visible behavior change, and every non-private callable surface intended for use outside its file.
|
|
78
|
+
- \`Module/File Plan\`: list each affected module, changed or created file, file responsibility, why it is in scope, expected change, dependency direction, user-visible behavior change, durable comment needs, and every non-private callable surface intended for use outside its file.
|
|
68
79
|
- \`Public Surface Impact\`: state changed APIs, routes, commands, events, exports, storage formats, configuration, UI behavior, visibility changes, side effects, error boundaries, expected callers, or explicitly state none.
|
|
69
|
-
- \`Scaffold Manifest\`:
|
|
70
|
-
-
|
|
80
|
+
- \`Scaffold Manifest\`: an item ledger — one entry per implementation item. An item is one of: a created body or surface (\`create\`), one required change site — one contiguous edit region inside an existing body or surface (\`change\`), or one deletion of a body, site, or file (\`delete\`). An item not in the ledger is not in the plan; coder must not implement it.
|
|
81
|
+
- Each ledger entry carries, in this column order: a unique stable ID such as \`SCF-001\`, action, exact file path, symbol or site, coder work, allowed implementation freedom, and a behavior/contract proof point. Per-file evidence, why-in-scope, and durable-comment needs live in the Module/File Plan, not in the ledger. Open-ended coverage language ("as work proceeds", "replicate", "etc.", "and others") is forbidden anywhere in the ledger.
|
|
82
|
+
- IDs and markers correspond one to one: every \`create\`, \`change\`, and \`delete\` entry has exactly one \`VCM:CODE <ID>\` marker pre-placed at its declared file and site; a \`delete\` marker sits on the code to be removed and leaves with it.
|
|
83
|
+
- The Scaffold Manifest is complete only when the ledger ID set and the tree's \`VCM:CODE\` ID set are equal, each ID appears exactly once on each side, and each marker sits in its declared file (\`.ai/tools/check-scaffold-ledger\` automates the check). Any mismatch means the plan is not complete.
|
|
84
|
+
- \`Scaffold Build Evidence\`: the exact compile/typecheck commands run on the committed scaffold, their results, and the scaffold commit hash. A missing, red, or stale-hash result means the plan is not complete.
|
|
85
|
+
- When the plan introduces or changes a build configuration — a new compilation target, a feature-gated or restricted-runtime variant, a new artifact type, or a build-environment constraint — scaffold that configuration and add to \`Scaffold Build Evidence\` one named check per configuration that fails when the claim is false, run green at the scaffold commit; choose proving checks from the project coding standards when defined there. A build-configuration claim without its named green check means the plan is not complete.
|
|
86
|
+
- The compile/typecheck and build-configuration checks in \`Scaffold Build Evidence\` must cover every wired exemplar, so each new cross-module call path is proven compilable at the scaffold stage. A call path that exists only in plan prose, over stub scaffold that never names the surfaces it will invoke, is not proven and the plan is not complete.
|
|
87
|
+
- Plan-stage build checks prove dependency closure and build shape only; full artifact builds and environment validation that require implemented bodies are implementation-stage proof and must be listed as proof points on the corresponding ledger items instead.
|
|
71
88
|
- \`Tester Coverage Hints\`: list behavior scenarios, edge conditions, public-contract risks, or runtime paths tester should consider. Do not design test cases, validation levels, commands, coverage matrices, or final validation strategy.
|
|
72
89
|
- \`Docs Impact\`: list every touched module and state whether its \`<module>/ARCHITECTURE.md\` is expected to change, stay unchanged, or require code-diff review before deciding; also state whether changes belong in \`docs/ARCHITECTURE.md\`, \`.ai/generated/public-surface.json\`, or no durable architecture doc.
|
|
73
90
|
- \`Known Risks\`: state concrete remaining technical risks, uncertainty, or validation risks that coder or tester must pay attention to.
|
|
@@ -77,7 +94,9 @@ ${renderRoleMemoryRules("architect")}
|
|
|
77
94
|
|
|
78
95
|
#### Code Scaffolding
|
|
79
96
|
|
|
80
|
-
- Create or update only the minimum module/file scaffolding needed to make boundaries, callable surfaces, and placeholders unambiguous.
|
|
97
|
+
- Create or update only the minimum module/file scaffolding needed to make boundaries, callable surfaces, and placeholders unambiguous. Minimum limits depth (no business implementation), never breadth: every \`create\`, \`change\`, and \`delete\` item must be scaffolded.
|
|
98
|
+
- When a required configuration, package manifest, or build-definition change cannot safely contain a \`VCM:CODE\` marker, complete and commit it directly as Architect-owned scaffold work. Record it in the Module/File Plan and Scaffold Build Evidence. Do not add it to the Scaffold Manifest.
|
|
99
|
+
- When the plan introduces a new cross-module call path or seam — a module invoking surfaces it does not invoke today — scaffold one wired exemplar that materializes the full path shape: the imports, interface implementations, and conditional-compilation gating the intended body needs, with placeholder bodies only. Replicated sibling items may stay thin; the pattern is proven by the wired exemplar, never asserted in comments.
|
|
81
100
|
- Source-code comments must describe durable behavior, contracts, invariants, error boundaries, or non-obvious logic that should remain useful after the task is complete.
|
|
82
101
|
- Do not put task-specific context, task labels, implementation-order notes, handoff instructions, temporary plan rationale, or coder guidance in source-code comments.
|
|
83
102
|
- Task labels such as \`RP<n>\`, \`SCF-<n>\`, \`KI-<n>\`, \`Phase <n>\`, or temporary task/round/PR labels must not appear in durable source comments.
|
|
@@ -85,7 +104,7 @@ ${renderRoleMemoryRules("architect")}
|
|
|
85
104
|
- Define every new or changed non-private callable surface directly in code with its signature shape and contract comment.
|
|
86
105
|
- When changing an existing non-private callable surface, update its signature and contract comment in code before coder work starts; leave \`VCM:CODE\` only where implementation must change.
|
|
87
106
|
- Non-private callable surface includes any function, method, type, trait, enum, constant, re-export, or similar symbol that another file can call or depend on.
|
|
88
|
-
-
|
|
107
|
+
- Place exactly one \`VCM:CODE <ID>\` marker per ledger item: on each incomplete implementation body, at each required change site inside an existing body, and on each body or site to be deleted. Coder implements or deletes each item and removes its marker when it completes green; a failed item keeps its marker over the committed attempt.
|
|
89
108
|
- Architect scaffolding may include modules, files, signatures, type shapes, durable comments, and placeholder bodies, but not real business implementation beyond minimal scaffold code.
|
|
90
109
|
- Coder may add private implementation helpers, but must not add or change cross-file callable surface without architect replan.
|
|
91
110
|
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
export function renderCheckScaffoldLedgerTool() {
|
|
2
|
+
return `#!/usr/bin/env python3
|
|
3
|
+
"""Scaffold-ledger reconciliation — machine enforcement of the Scaffold Manifest bijection.
|
|
4
|
+
|
|
5
|
+
The architecture plan's Scaffold Manifest is an item ledger: one entry per implementation
|
|
6
|
+
item, one unique ID per entry, and exactly one \`VCM:CODE <ID>\` marker in the tree per
|
|
7
|
+
\`create\`/\`change\`/\`delete\` entry. This tool checks:
|
|
8
|
+
|
|
9
|
+
1. the ledger header follows the mandated column order (\`ID | Action | File | ...\`),
|
|
10
|
+
every ledger ID is unique, classified by its whole-cell action column
|
|
11
|
+
(create/change/delete), and bound to a declared file path in the file column;
|
|
12
|
+
2. the ledger ID set equals the tree marker ID set, each ID exactly once on each side;
|
|
13
|
+
3. every marker sits in its entry's declared file;
|
|
14
|
+
4. the manifest contains no open-ended coverage language ("as work proceeds",
|
|
15
|
+
"replicate", "etc.", "and others").
|
|
16
|
+
|
|
17
|
+
Markers are scanned in git-tracked source files only (\`.md\` files and \`.ai/\` are excluded:
|
|
18
|
+
prose may quote markers legitimately). Pure read; findings go to stderr; exit 0 clean,
|
|
19
|
+
1 on findings. \`--plan <path>\` overrides the default plan location. No plan file at all
|
|
20
|
+
means there is nothing to check (exit 0) — a docs-only or planning-free task.
|
|
21
|
+
"""
|
|
22
|
+
import argparse
|
|
23
|
+
import re
|
|
24
|
+
import subprocess
|
|
25
|
+
import sys
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
|
|
28
|
+
PLAN = ".ai/vcm/handoffs/architecture-plan.md"
|
|
29
|
+
MANIFEST_HEADING = re.compile(r"^##\\s+Scaffold Manifest\\s*$")
|
|
30
|
+
SECTION_HEADING = re.compile(r"^##\\s+\\S")
|
|
31
|
+
ID_TOKEN = re.compile(r"\\b([A-Z]{2,6}-\\d{1,4})\\b")
|
|
32
|
+
# Mandated column order: ID | action | file | symbol/site | work | freedom | proof.
|
|
33
|
+
# The action is read from its own cell as a whole-cell verb — never sniffed from the
|
|
34
|
+
# row text, so paths or prose containing action words cannot flip an item's class.
|
|
35
|
+
ACTIONS = frozenset({"create", "change", "delete"})
|
|
36
|
+
PATH_TOKEN = re.compile(r"\`([^\`\\s]+/[^\`\\s]+|[^\`\\s]+\\.[A-Za-z0-9]{1,8})\`")
|
|
37
|
+
MARKER_ID = re.compile(r"VCM:CODE[:\\s]\\s*([A-Za-z]{2,6}-\\d{1,4})")
|
|
38
|
+
MARKER_ANY = re.compile(r"VCM:CODE")
|
|
39
|
+
FORBIDDEN = [
|
|
40
|
+
re.compile(r"as work proceeds", re.IGNORECASE),
|
|
41
|
+
re.compile(r"\\breplicate\\b", re.IGNORECASE),
|
|
42
|
+
re.compile(r"\\betc\\.", re.IGNORECASE),
|
|
43
|
+
re.compile(r"\\band others\\b", re.IGNORECASE),
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def manifest_section(plan_text: str) -> tuple[int, list[str]] | None:
|
|
48
|
+
"""(start line number, section lines) of the Scaffold Manifest section, or None."""
|
|
49
|
+
lines = plan_text.splitlines()
|
|
50
|
+
start = None
|
|
51
|
+
for index, line in enumerate(lines):
|
|
52
|
+
if start is None:
|
|
53
|
+
if MANIFEST_HEADING.match(line):
|
|
54
|
+
start = index + 1
|
|
55
|
+
elif SECTION_HEADING.match(line):
|
|
56
|
+
return (start, lines[start : index])
|
|
57
|
+
return None if start is None else (start, lines[start:])
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def parse_ledger(section_start: int, section: list[str], plan: str) -> tuple[dict, list[str]]:
|
|
61
|
+
"""{id: {"path", "action", "line"}} plus parse findings. Positional parsing per the
|
|
62
|
+
mandated column order; the first non-entry table row is validated as the header."""
|
|
63
|
+
entries: dict[str, dict] = {}
|
|
64
|
+
findings: list[str] = []
|
|
65
|
+
header_checked = False
|
|
66
|
+
for offset, line in enumerate(section):
|
|
67
|
+
line_no = section_start + offset + 1
|
|
68
|
+
stripped = line.strip()
|
|
69
|
+
if not stripped.startswith("|"):
|
|
70
|
+
continue
|
|
71
|
+
cells = [cell.strip() for cell in stripped.strip("|").split("|")]
|
|
72
|
+
if not cells or set(cells[0]) <= {"-", ":", " "}:
|
|
73
|
+
continue # separator row
|
|
74
|
+
id_match = ID_TOKEN.search(cells[0])
|
|
75
|
+
if not id_match:
|
|
76
|
+
if not header_checked:
|
|
77
|
+
header_checked = True
|
|
78
|
+
head = [cell.lower() for cell in cells[:3]] + ["", "", ""]
|
|
79
|
+
if not (
|
|
80
|
+
"id" in head[0]
|
|
81
|
+
and "action" in head[1]
|
|
82
|
+
and ("file" in head[2] or "path" in head[2])
|
|
83
|
+
):
|
|
84
|
+
findings.append(
|
|
85
|
+
f"{plan}:{line_no} [ledger] header columns must be "
|
|
86
|
+
f"\`ID | Action | File | ...\` -> fix the ledger column order"
|
|
87
|
+
)
|
|
88
|
+
continue
|
|
89
|
+
entry_id = id_match.group(1)
|
|
90
|
+
if entry_id in entries:
|
|
91
|
+
findings.append(
|
|
92
|
+
f"{plan}:{line_no} [ledger] duplicate ledger ID {entry_id} "
|
|
93
|
+
f"(first at line {entries[entry_id]['line']}) -> one entry per item"
|
|
94
|
+
)
|
|
95
|
+
continue
|
|
96
|
+
action_cell = cells[1].lower() if len(cells) > 1 else ""
|
|
97
|
+
action = action_cell if action_cell in ACTIONS else None
|
|
98
|
+
declared = None
|
|
99
|
+
if len(cells) > 2:
|
|
100
|
+
path_match = PATH_TOKEN.search(cells[2])
|
|
101
|
+
declared = path_match.group(1) if path_match else None
|
|
102
|
+
if action is None:
|
|
103
|
+
findings.append(
|
|
104
|
+
f"{plan}:{line_no} [ledger] {entry_id} action column is not exactly "
|
|
105
|
+
f"one of create/change/delete -> classify the item in column 2"
|
|
106
|
+
)
|
|
107
|
+
if declared is None:
|
|
108
|
+
findings.append(
|
|
109
|
+
f"{plan}:{line_no} [ledger] {entry_id} has no declared file path in "
|
|
110
|
+
f"column 3 -> bind the item to its exact file"
|
|
111
|
+
)
|
|
112
|
+
entries[entry_id] = {"path": declared, "action": action, "line": line_no}
|
|
113
|
+
return entries, findings
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def forbidden_language(section_start: int, section: list[str], plan: str) -> list[str]:
|
|
117
|
+
findings = []
|
|
118
|
+
for offset, line in enumerate(section):
|
|
119
|
+
for pattern in FORBIDDEN:
|
|
120
|
+
if pattern.search(line):
|
|
121
|
+
findings.append(
|
|
122
|
+
f"{plan}:{section_start + offset + 1} [ledger] open-ended coverage "
|
|
123
|
+
f"language ({pattern.pattern}) -> enumerate every item explicitly"
|
|
124
|
+
)
|
|
125
|
+
return findings
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def tree_markers(root: Path) -> tuple[dict[str, list[tuple[str, int]]], list[str]]:
|
|
129
|
+
"""{id: [(path, line)]} for tracked source markers, plus malformed-marker findings."""
|
|
130
|
+
result = subprocess.run(
|
|
131
|
+
["git", "grep", "-In", "VCM:CODE", "--", ".", ":!*.md", ":!.ai"],
|
|
132
|
+
capture_output=True,
|
|
133
|
+
text=True,
|
|
134
|
+
cwd=root,
|
|
135
|
+
)
|
|
136
|
+
markers: dict[str, list[tuple[str, int]]] = {}
|
|
137
|
+
findings: list[str] = []
|
|
138
|
+
for raw in result.stdout.splitlines():
|
|
139
|
+
parts = raw.split(":", 2)
|
|
140
|
+
if len(parts) < 3:
|
|
141
|
+
continue
|
|
142
|
+
path, line_no, content = parts[0], int(parts[1]), parts[2]
|
|
143
|
+
id_match = MARKER_ID.search(content)
|
|
144
|
+
if id_match:
|
|
145
|
+
markers.setdefault(id_match.group(1), []).append((path, line_no))
|
|
146
|
+
elif MARKER_ANY.search(content):
|
|
147
|
+
findings.append(
|
|
148
|
+
f"{path}:{line_no} [ledger] marker without a parseable ID -> "
|
|
149
|
+
f"use \`VCM:CODE <ID>\`"
|
|
150
|
+
)
|
|
151
|
+
return markers, findings
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def main() -> int:
|
|
155
|
+
parser = argparse.ArgumentParser(
|
|
156
|
+
description="Scaffold Manifest ledger <-> VCM:CODE marker bijection check."
|
|
157
|
+
)
|
|
158
|
+
parser.add_argument("--plan", default=None, help=f"plan path (default {PLAN})")
|
|
159
|
+
args = parser.parse_args()
|
|
160
|
+
|
|
161
|
+
root = Path(__file__).resolve().parents[2]
|
|
162
|
+
plan_path = Path(args.plan) if args.plan else root / PLAN
|
|
163
|
+
plan = str(plan_path)
|
|
164
|
+
if not plan_path.is_file():
|
|
165
|
+
print(f"no architecture plan at {plan_path}; nothing to check")
|
|
166
|
+
return 0
|
|
167
|
+
|
|
168
|
+
findings: list[str] = []
|
|
169
|
+
section = manifest_section(plan_path.read_text(errors="replace"))
|
|
170
|
+
if section is None:
|
|
171
|
+
sys.stderr.write(f"{plan_path}:1 [ledger] no \`## Scaffold Manifest\` section\\n")
|
|
172
|
+
return 1
|
|
173
|
+
entries, parse_findings = parse_ledger(*section, str(plan_path))
|
|
174
|
+
findings += parse_findings
|
|
175
|
+
findings += forbidden_language(*section, str(plan_path))
|
|
176
|
+
|
|
177
|
+
markers, marker_findings = tree_markers(root)
|
|
178
|
+
findings += marker_findings
|
|
179
|
+
|
|
180
|
+
for entry_id, sites in sorted(markers.items()):
|
|
181
|
+
if len(sites) > 1:
|
|
182
|
+
where = ", ".join(f"{p}:{n}" for p, n in sites)
|
|
183
|
+
findings.append(
|
|
184
|
+
f"[ledger] {entry_id} has {len(sites)} markers ({where}) -> exactly one per item"
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
ledger_ids = set(entries)
|
|
188
|
+
tree_ids = set(markers)
|
|
189
|
+
for entry_id in sorted(ledger_ids - tree_ids):
|
|
190
|
+
findings.append(
|
|
191
|
+
f"{plan}:{entries[entry_id]['line']} [ledger] {entry_id} has no marker "
|
|
192
|
+
f"in the tree -> pre-place \`VCM:CODE {entry_id}\` in its declared file"
|
|
193
|
+
)
|
|
194
|
+
for entry_id in sorted(tree_ids - ledger_ids):
|
|
195
|
+
path, line_no = markers[entry_id][0]
|
|
196
|
+
findings.append(
|
|
197
|
+
f"{path}:{line_no} [ledger] marker {entry_id} has no ledger entry "
|
|
198
|
+
f"-> every item must be manifested"
|
|
199
|
+
)
|
|
200
|
+
for entry_id in sorted(ledger_ids & tree_ids):
|
|
201
|
+
entry = entries[entry_id]
|
|
202
|
+
if entry["path"]:
|
|
203
|
+
declared = entry["path"]
|
|
204
|
+
for path, line_no in markers[entry_id]:
|
|
205
|
+
if not (path == declared or path.endswith("/" + declared) or declared.endswith("/" + path)):
|
|
206
|
+
findings.append(
|
|
207
|
+
f"{path}:{line_no} [ledger] marker {entry_id} is outside its "
|
|
208
|
+
f"declared file \`{declared}\`"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
for finding in findings:
|
|
212
|
+
sys.stderr.write(finding + "\\n")
|
|
213
|
+
if findings:
|
|
214
|
+
sys.stderr.write(f"ledger reconciliation failed with {len(findings)} finding(s)\\n")
|
|
215
|
+
return 1
|
|
216
|
+
print(
|
|
217
|
+
f"ledger reconciliation clean: {len(ledger_ids)} ledger item(s), "
|
|
218
|
+
f"{len(tree_ids)} marker(s)"
|
|
219
|
+
)
|
|
220
|
+
return 0
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
if __name__ == "__main__":
|
|
224
|
+
raise SystemExit(main())
|
|
225
|
+
`;
|
|
226
|
+
}
|
|
@@ -17,7 +17,7 @@ ${renderRoleMemoryRules("coder")}
|
|
|
17
17
|
- Before editing production code or tests, read and follow \`docs/CODING_STANDARDS.md\`.
|
|
18
18
|
- Project-specific additions in \`docs/CODING_STANDARDS.md\` are binding when they make the shared baseline more precise.
|
|
19
19
|
- Keep the implementation inside the approved architecture plan, scaffold, and role message.
|
|
20
|
-
- Implement every assigned \`VCM:CODE\` placeholder, track completion by Scaffold Manifest ID when present
|
|
20
|
+
- Implement every assigned \`VCM:CODE\` placeholder, track completion by Scaffold Manifest ID when present; remove a marker when its item completes green — a failed item keeps its marker per the failure rules.
|
|
21
21
|
|
|
22
22
|
### Inputs
|
|
23
23
|
|
|
@@ -44,21 +44,24 @@ ${renderRoleMemoryRules("coder")}
|
|
|
44
44
|
|
|
45
45
|
- Coder may use Claude Code subagents to invoke \`vcm-coder-worker\` for parallel implementation.
|
|
46
46
|
- Use workers when the task has at least 20 \`VCM:CODE\` markers and the marker distribution can form at least two worker-sized groups.
|
|
47
|
-
-
|
|
47
|
+
- Under a complete scaffold, marker implementations are order-independent — signatures, types, and cross-item contracts are frozen by the scaffold — so never serialize worker-sized groups for presumed implementation-order dependencies. When a group's module-scoped checks need peers that are still unimplemented, narrow that worker's assigned validation scope instead of serializing.
|
|
48
|
+
- An item counts as blocked only when a genuine implementation attempt has produced objective compile/check evidence already reported under the failure rules; prediction never blocks an item. A blocked marker item never exempts the remaining markers from worker dispatch.
|
|
49
|
+
- Before invoking workers, count \`VCM:CODE\` markers by module and create one runtime state file per worker under \`.ai/vcm/coder-workers/tasks/<worker-id>.json\` with \`status: running\`.
|
|
48
50
|
- Create one worker task for each module with more than 10 \`VCM:CODE\` markers.
|
|
49
51
|
- Group modules with 10 or fewer \`VCM:CODE\` markers into one small-modules worker when their combined marker count is more than 10.
|
|
50
52
|
- If the combined small-module marker count is 10 or fewer, Coder handles those modules directly after worker results return.
|
|
51
53
|
- Each worker prompt must include task worktree, architecture plan path, worker state path, report path, assigned modules/files/markers, allowed implementation scope, validation scope, and commit requirement.
|
|
52
54
|
- Invoke worker subagents in parallel only through \`vcm-coder-worker\`.
|
|
53
|
-
- Stay in the same Coder turn until
|
|
54
|
-
-
|
|
55
|
+
- Stay in the same Coder turn until every worker state is \`completed\` and Coder has reviewed and integrated all reports and commits. Do not end the turn to wait for worker callbacks.
|
|
56
|
+
- A completed worker reports \`Implementation Result: success|has_failed_items\`; \`completed\` means the full assigned sweep and handoff finished, not that every item passed.
|
|
57
|
+
- After workers finish, inspect each item disposition and commit, integrate successful work and committed failure scenes, resolve integration conflicts or invalid edits, and verify that every remaining marker corresponds to a failed disposition. Only then mark \`handled: true\` in each worker state.
|
|
55
58
|
- Run coder-level baseline validation, summarize worker reports and commits in \`.ai/vcm/handoffs/coder-completion.md\`, and clean \`.ai/vcm/coder-workers/\`.
|
|
56
59
|
|
|
57
60
|
### Handoff
|
|
58
61
|
|
|
59
62
|
- Write \`.ai/vcm/handoffs/coder-completion.md\` before routing back to project-manager. This file is the current implementation completion evidence, not a log; replace stale content instead of appending history.
|
|
60
63
|
- \`coder-completion.md\` must include \`Decision: ready_for_review | incomplete | failed\`.
|
|
61
|
-
- \`coder-completion.md\` must report
|
|
64
|
+
- \`coder-completion.md\` must report every Scaffold Manifest item disposition in the fixed Scaffold Completion table, plus changed files, private helpers added, manifest deviations as report-only facts, generated context status, baseline tests added or updated, L0/L1 commands and results, worker commits and integration status when workers were used, and compile/typecheck or L0/L1 failures.
|
|
62
65
|
- Use this structure:
|
|
63
66
|
|
|
64
67
|
\`\`\`md
|
|
@@ -68,7 +71,9 @@ Decision: ready_for_review|incomplete|failed
|
|
|
68
71
|
|
|
69
72
|
## Scaffold Completion
|
|
70
73
|
|
|
71
|
-
|
|
74
|
+
| ID | Action | Result | Marker State | Proof Evidence |
|
|
75
|
+
| --- | --- | --- | --- | --- |
|
|
76
|
+
| <ID> | <create/change/delete> | <done/failed> | <removed/present> | <evidence> |
|
|
72
77
|
|
|
73
78
|
## Changed Files
|
|
74
79
|
|
|
@@ -88,7 +93,9 @@ Decision: ready_for_review|incomplete|failed
|
|
|
88
93
|
\`\`\`
|
|
89
94
|
|
|
90
95
|
- In the route message back to project-manager, include the \`coder-completion.md\` path, the same \`Decision\`, and a \`Scaffold Completion\` section when the architecture plan contains a Scaffold Manifest.
|
|
91
|
-
- The
|
|
96
|
+
- The Scaffold Completion ID set must equal the Scaffold Manifest ID set, with every ID appearing exactly once.
|
|
97
|
+
- \`done\` requires \`Marker State: removed\` and green proof evidence. \`failed\` requires \`Marker State: present\` and objective failure evidence.
|
|
98
|
+
- Use \`Decision: ready_for_review\` only when every item is \`done\`, \`Decision: failed\` only after the complete sweep contains at least one \`failed\` item, and \`Decision: incomplete\` when the sweep is unfinished.
|
|
92
99
|
|
|
93
100
|
### Generated Context
|
|
94
101
|
|
|
@@ -103,7 +110,7 @@ Decision: ready_for_review|incomplete|failed
|
|
|
103
110
|
- Coder validation is limited to baseline unit-level and fast L0/L1 checks; do not run L2/L3/L4, smoke, integration, or E2E validation unless the role message explicitly assigns a targeted fast L2 check.
|
|
104
111
|
- Run available L0/L1 validation after implementation.
|
|
105
112
|
- Compile, typecheck, or L0/L1 failure is the signal to report; predicted failure is not.
|
|
106
|
-
- If required compile/typecheck/L0/L1 validation cannot run or cannot complete,
|
|
113
|
+
- If required compile/typecheck/L0/L1 validation cannot run or cannot complete, record it as the affected items' failure disposition; the turn-end decision follows the sweep rules. If the user explicitly approved continuing without the exact check, record the approval and reason; the approval does not change Coder's decision.
|
|
107
114
|
- Do not make tests pass by weakening assertions, skipping tests, hardcoding success, bypassing real behavior paths, or adding test-only production behavior.
|
|
108
115
|
|
|
109
116
|
### Failure Reporting And Continuation
|
|
@@ -111,6 +118,10 @@ Decision: ready_for_review|incomplete|failed
|
|
|
111
118
|
- Report failure only from objective implementation evidence: compile/typecheck fails, L0/L1 fails, or required compile/typecheck/L0/L1 validation cannot run or complete.
|
|
112
119
|
- Do not report failure based on predicted design failure, public-contract disagreement, architecture disagreement, or validation prediction.
|
|
113
120
|
- Do not stop because of workload, session length, or context size.
|
|
121
|
+
- Never revert implemented work. Commit the actual state at turn end — including failing or non-compiling attempts — as its own commit whose message names the failing checks or errors. The committed failing state is the reproduction scene the fix is verified against.
|
|
122
|
+
- A blocker never ends the turn. Work every assigned ledger item to a terminal state. A completed item has green proof and its marker removed. A failed item has a genuine attempt committed with objective failure evidence and its marker retained. "Cannot proceed", "cannot compile", or "missing dependency" on one item never exempts the others — the scaffold froze every signature and contract, so every remaining item stays attemptable.
|
|
123
|
+
- A failure decision is valid only after the full sweep: every assigned item in a terminal state, and the report carrying a per-item disposition — completed items, and each failed item with its objective evidence and suspected cause. Problems are reported once, consolidated, after the sweep.
|
|
124
|
+
- A turn-budget interruption mid-sweep is \`Decision: incomplete\` with sweep progress for continuation; it is never a vehicle for returning a problem early.
|
|
114
125
|
- Compile/typecheck/L0/L1 failure is not terminal until Coder has attempted to fix implementation-caused failures within the assigned scope.
|
|
115
126
|
- \`Decision: incomplete\` is only for actual interruption or inability to continue the turn; it must not be used for architecture concerns, questions, or predicted risk.
|
|
116
127
|
- If execution is interrupted or the turn must end unexpectedly before all assigned scaffold items are done, write \`coder-completion.md\` with \`Decision: incomplete\`, include completed items, remaining implementation work, validation state, and why continuation is needed. PM decides whether to continue the same route.
|