vibe-coding-master 0.7.7 → 0.7.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.
@@ -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",
@@ -144,6 +144,7 @@ export function createClaudeHookService(deps) {
144
144
  }
145
145
  await deps.harnessService?.recordHarnessBootstrapHook(context.project.repoRoot, {
146
146
  eventName,
147
+ taskSlug: input.taskSlug,
147
148
  sessionId: session?.id,
148
149
  claudeSessionId: stringOrUndefined(input.event.session_id)
149
150
  });
@@ -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",
@@ -414,7 +422,6 @@ export function createHarnessService(deps) {
414
422
  await persistHarnessBootstrapRunState(deps.fs, repoRoot, {
415
423
  version: 1,
416
424
  status: "running",
417
- taskSlug,
418
425
  targetRepoRoot,
419
426
  sessionId: session.id,
420
427
  claudeSessionId: session.claudeSessionId,
@@ -436,7 +443,7 @@ export function createHarnessService(deps) {
436
443
  async recordHarnessBootstrapHook(repoRoot, input) {
437
444
  const state = await loadPersistedHarnessBootstrapRunState(deps.fs, repoRoot);
438
445
  if (state?.status !== "running" || !matchesBootstrapRunState(state, input)) {
439
- return getHarnessBootstrapStatus(deps, repoRoot, state?.targetRepoRoot ?? repoRoot, now, vcmVersion, state?.taskSlug);
446
+ return getHarnessBootstrapStatus(deps, repoRoot, state?.targetRepoRoot ?? repoRoot, now, vcmVersion, input.taskSlug);
440
447
  }
441
448
  const timestamp = now();
442
449
  if (input.eventName === "Stop" && state.targetRepoRoot) {
@@ -449,7 +456,7 @@ export function createHarnessService(deps) {
449
456
  updatedAt: timestamp,
450
457
  lastHookEvent: input.eventName
451
458
  });
452
- return getHarnessBootstrapStatus(deps, repoRoot, state.targetRepoRoot ?? repoRoot, now, vcmVersion, state.taskSlug);
459
+ return getHarnessBootstrapStatus(deps, repoRoot, state.targetRepoRoot ?? repoRoot, now, vcmVersion, input.taskSlug);
453
460
  }
454
461
  };
455
462
  }
@@ -1498,15 +1505,13 @@ async function getHarnessBootstrapStatus(deps, repoRoot, targetRepoRoot, now, vc
1498
1505
  await checkFilledMarkdown(deps.fs, targetRepoRoot, "docs/TESTING.md", "Testing doc", "testing-doc")
1499
1506
  ];
1500
1507
  const persistedRunState = await loadPersistedHarnessBootstrapRunState(deps.fs, repoRoot);
1501
- const runState = taskSlug && persistedRunState?.taskSlug !== taskSlug
1502
- ? undefined
1503
- : persistedRunState;
1508
+ const runState = persistedRunState;
1504
1509
  const session = await getCurrentHarnessEngineerBootstrapSession(deps, repoRoot, taskSlug);
1505
1510
  const fixedHarnessReady = checks[0]?.status === "ok";
1506
1511
  const projectChecks = checks.slice(1);
1507
1512
  const projectComplete = projectChecks.every((check) => check.status === "ok");
1508
1513
  const projectStarted = projectChecks.some((check) => check.status === "ok" || check.status === "incomplete");
1509
- const runActive = runState?.status === "running" && session?.status === "running";
1514
+ const runActive = isActiveHarnessBootstrapRun(runState, session, targetRepoRoot);
1510
1515
  const status = !fixedHarnessReady
1511
1516
  ? "not_ready"
1512
1517
  : runActive
@@ -1751,7 +1756,6 @@ async function loadPersistedHarnessBootstrapRunState(fs, repoRoot) {
1751
1756
  return {
1752
1757
  version: 1,
1753
1758
  status,
1754
- taskSlug: typeof payload.taskSlug === "string" ? payload.taskSlug : undefined,
1755
1759
  targetRepoRoot: typeof payload.targetRepoRoot === "string" ? payload.targetRepoRoot : undefined,
1756
1760
  sessionId: typeof payload.sessionId === "string" ? payload.sessionId : undefined,
1757
1761
  claudeSessionId: typeof payload.claudeSessionId === "string" ? payload.claudeSessionId : undefined,
@@ -1779,6 +1783,13 @@ function matchesBootstrapRunState(state, input) {
1779
1783
  }
1780
1784
  return true;
1781
1785
  }
1786
+ function isActiveHarnessBootstrapRun(state, session, targetRepoRoot) {
1787
+ return state?.status === "running"
1788
+ && session?.status === "running"
1789
+ && state.sessionId === session.id
1790
+ && state.targetRepoRoot === targetRepoRoot
1791
+ && (!state.claudeSessionId || state.claudeSessionId === session.claudeSessionId);
1792
+ }
1782
1793
  async function readOptionalText(fs, repoRoot, relativePath) {
1783
1794
  const absolutePath = resolveHarnessPath(repoRoot, relativePath);
1784
1795
  try {
@@ -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(["planned", "running", "completed", "failed"]);
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 ? ` Test report(s): ${reports.join(", ")}.` : "";
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 worker subagents, test reports and commits, resolve failed or incomplete workers, set \`handled: true\` in each worker state, and continue.${reportHint}`;
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 | File / Action | Current Evidence / Why In Scope | Coder Work | Allowed Freedom | Expected VCM:CODE | Durable Comment Needs | Behavior / Contract Proof Points |
105
- | --- | --- | --- | --- | --- | --- | --- | --- |
106
- | SCF-001 | TBD | TBD | TBD | TBD | TBD | TBD | TBD |
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
- TBD
191
-
192
- ## Remaining Markers
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 required code scaffolding, callable surfaces, contract comments, and \`VCM:CODE\` placeholders have been written.
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 and required code scaffold are complete and consistent. Include the same Planning Result in the route message to project-manager; do not select the next route.
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\`: provide one stable row per implementation unit or file context that coder must complete: row ID, file action, current code or integration-point evidence and why the file is in scope, coder work, allowed implementation freedom, expected \`VCM:CODE\` placeholders, durable code comment needs, and behavior/contract proof points.
70
- - Give each Scaffold Manifest row a stable ID such as \`SCF-001\`; use that ID in any related \`VCM:CODE\` marker so coder can report completion by ID.
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
- - Mark incomplete implementation bodies with \`VCM:CODE <Scaffold Manifest ID>\`; coder must implement them and remove the markers before handoff.
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, and remove all \`VCM:CODE\` markers before handoff.
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
- - 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\`.
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 all worker subagents finish and Coder has reviewed and integrated their reports and commits. Do not end the turn to wait for worker callbacks.
54
- - After workers finish, inspect each report and commit for assigned completion and integration, resolve missing implementation, conflicts, invalid edits, and remaining \`VCM:CODE\` markers, then mark \`handled: true\` in each worker state.
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 completed Scaffold Manifest IDs or \`VCM:CODE\` IDs, remaining markers if any, 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.
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
- ## Remaining Markers
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 \`Scaffold Completion\` section must report completed Scaffold Manifest IDs or \`VCM:CODE\` IDs, remaining markers if any, private helpers added, manifest deviations, and compile/typecheck or L0/L1 failures.
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, write \`Decision: failed\`. If the user explicitly approved continuing without the exact check, record the approval and reason; the approval does not change Coder's decision.
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.
@@ -13,11 +13,11 @@ You are \`vcm-coder-worker\`, a bounded implementation worker invoked by Coder.
13
13
 
14
14
  ### Worker Runtime State
15
15
 
16
- - Coder assigns a worker state path and report path.
17
- - Before editing, read the assigned worker state file and update only that file from \`planned\` to \`running\`.
18
- - After implementation and assigned checks, commit the assigned files. After the commit succeeds, write the assigned report with the commit hash, then update only the assigned worker state to \`completed\` with the same \`commitHash\` as the final step.
19
- - If blocked or failed, update only the assigned worker state to \`failed\`, write the reason in \`error\`, and write the report with remaining work.
20
- - Use \`completed\` only after assigned implementation is complete, assigned markers are removed, required assigned checks pass or have a Coder-recorded exception in the worker task, the report is written, and commit succeeds.
16
+ - Worker runtime status is only \`running\` or \`completed\`.
17
+ - Coder creates the assigned worker state with \`status: running\` and assigns its state path and report path.
18
+ - After the sweep of assigned items and their assigned checks, commit the assigned files. After the commit succeeds, write the assigned report with the commit hash and \`Implementation Result: success|has_failed_items\`, then update only the assigned worker state to \`completed\` with the same \`commitHash\` as the final step.
19
+ - Use \`completed\` only after every assigned item reached a terminal state. A successful item has green assigned proof and its marker removed. A failed item has a genuine attempt committed with objective failure evidence and its marker retained. Use \`success\` only when every item succeeded; otherwise use \`has_failed_items\`.
20
+ - If execution is interrupted before the sweep, commit, or report completes, leave the worker state as \`running\`. Coder must resume the worker or take over the remaining work.
21
21
  - Do not set \`handled: true\`; only Coder may do that after reviewing and integrating the worker result.
22
22
 
23
23
  ### Inputs
@@ -34,7 +34,8 @@ You are \`vcm-coder-worker\`, a bounded implementation worker invoked by Coder.
34
34
  ### Implementation Discipline
35
35
 
36
36
  - Follow \`docs/CODING_STANDARDS.md\`.
37
- - Implement the assigned \`VCM:CODE\` markers completely and remove those markers before completion.
37
+ - Never revert implemented work; a blocker on one assigned item never ends the assignment every remaining assigned item stays attemptable under the frozen scaffold.
38
+ - Implement every assigned \`VCM:CODE\` marker: remove a marker when its item completes green; a failed item keeps its marker over the committed attempt, with the failing checks or errors named in the commit message and the report.
38
39
  - Preserve architect-defined file responsibilities, callable-surface signatures, visibility, exports, contracts, and error boundaries.
39
40
  - Do not add or change cross-file callable surface unless the architecture plan explicitly defines it.
40
41
  - Keep changes limited to the assigned module or files.
@@ -48,11 +49,11 @@ You are \`vcm-coder-worker\`, a bounded implementation worker invoked by Coder.
48
49
  - Run assigned L0/L1 checks in the foreground. Worker checks are module-scoped and treated as safe fast validation: never use \`.ai/tools/run-long-check\` or \`.ai/tools/watch-job\`, and the switch-to-skill rule for long commands does not apply inside worker runs.
49
50
  - Do not make tests pass by weakening assertions, skipping tests, hardcoding success, bypassing real behavior paths, or adding test-only production behavior.
50
51
  - Report failure only from compile/typecheck failure, assigned L0/L1 failure, or a concrete inability to run assigned-module tests.
51
- - If required assigned compile/typecheck/L0/L1 checks cannot run or cannot complete, update worker state to \`failed\`. If the user explicitly approved continuing without the exact check, record the approval and reason; the approval does not change the worker state.
52
+ - An assigned check that fails or cannot complete on one item is that item's failure disposition, not a worker failure: record it and continue the sweep. If the user explicitly approved continuing without an exact check, record the approval and reason in the report.
52
53
 
53
54
  ### Git
54
55
 
55
- - Commit the worker's completed changes before returning to Coder.
56
+ - Commit the worker's actual final state of the assigned files — including failing attempts — before returning to Coder.
56
57
  - Commit only changes made for the assigned module or files.
57
58
  - Stage only assigned files; do not use \`git add -A\`, \`git add .\`, \`git commit -a\`, or broad path staging.
58
59
  - Commit with an explicit assigned-file pathspec: \`git commit --only -m "<message>" -- <assigned-paths>\`. Do not use \`git commit\` without assigned paths.
@@ -65,7 +66,8 @@ You are \`vcm-coder-worker\`, a bounded implementation worker invoked by Coder.
65
66
  Return a concise completion report with:
66
67
 
67
68
  - assigned module/files
68
- - completed Scaffold Manifest IDs or \`VCM:CODE\` markers
69
+ - implementation result: \`success\` or \`has_failed_items\`
70
+ - per-item disposition: ID, action, result, marker state, proof evidence, and suspected cause for failures
69
71
  - files changed
70
72
  - tests added or updated
71
73
  - L0/L1 checks run
@@ -78,11 +80,12 @@ Use this structure:
78
80
  \`\`\`md
79
81
  # Coder Worker Report: <worker-id>
80
82
 
81
- Worker Result: completed|failed
83
+ Worker State: completed
84
+ Implementation Result: success|has_failed_items
82
85
 
83
86
  ## Assigned Scope
84
87
 
85
- ## Completed Markers
88
+ ## Item Dispositions
86
89
 
87
90
  ## Files Changed
88
91
 
@@ -13,11 +13,54 @@ Use only these decisions:
13
13
  - \`approve\`: required gate evidence is present, current, internally consistent, sufficient for that gate, and has no gate-blocking finding.
14
14
  - \`request_changes\`: evidence is missing, stale, contradictory, incomplete, insufficient, not reviewable, or unsafe.
15
15
 
16
+ Every Gate Review is a complete review of the current gate inputs. Review all
17
+ required evidence and rerun every required mechanical check before deciding.
18
+ Do not carry forward prior conclusions, closed checks, or partial verification.
19
+ Resolving prior findings does not replace the complete review. Return \`approve\`
20
+ or \`request_changes\` only after the review is complete.
21
+
16
22
  ## Architecture Plan Gate
17
23
 
18
24
  Format is necessary but not sufficient. Do not approve an architecture plan
19
25
  only because required sections exist.
20
26
 
27
+ Treat \`architecture-plan.md\` as the complete current executable plan, not
28
+ revision history. Review the entire current plan and scaffold, not only changed
29
+ sections or prior findings. Return \`request_changes\` if the plan retains
30
+ superseded decisions, obsolete ledger items, resolved findings, prior-round
31
+ notes, stale risks, or outdated implementation guidance.
32
+
33
+ Before any other architecture-plan analysis, reconcile the Scaffold Manifest
34
+ ledger against the committed scaffold (\`.ai/tools/check-scaffold-ledger\`
35
+ automates it). Run this on every review round, including revision rounds:
36
+
37
+ - Extract the ledger ID set from \`architecture-plan.md\` and the \`VCM:CODE\` ID
38
+ set from the worktree. They must be equal, every ID exactly once on each
39
+ side, and every marker in its declared file. Every ledger item must have its
40
+ marker pre-placed.
41
+ - Any set mismatch, duplicated or missing ID, marker outside its declared
42
+ file, deferred-placeholder or open-ended coverage language ("as work
43
+ proceeds", "replicate", "etc.", "and others"), or ledger entry without a
44
+ marker is \`request_changes\` regardless of plan prose quality. Record both
45
+ ID sets (or their exact diff) in the report.
46
+ - Verify \`Scaffold Build Evidence\` names the compile/typecheck commands, a
47
+ green result, and the scaffold commit hash, and that the hash matches the
48
+ reviewed scaffold commits. Missing, red, or hash-mismatched evidence is
49
+ \`request_changes\`.
50
+ - For every module whose build configuration the plan changes, open its package
51
+ manifest and verify the evidence table's dependency claims match it exactly,
52
+ and verify each claimed configuration has its own named proving check, green
53
+ at the scaffold hash, in \`Scaffold Build Evidence\`. A dependency claim that
54
+ contradicts the manifest, or a build-configuration claim without a named
55
+ green check, is \`request_changes\`.
56
+ - For every new cross-module call path the plan's design describes, verify the
57
+ scaffold materializes it in a wired exemplar — imports, interface
58
+ implementations, and gating present, placeholder bodies — covered by a named
59
+ green check, and that every symbol the path requires is reachable from the
60
+ consuming module's declared dependencies. A call path that exists only in
61
+ prose over stub-only scaffold is \`request_changes\`.
62
+ - Record each of these pre-checks and its result in the report.
63
+
21
64
  For \`architecture-plan\`, reconstruct the proposed architecture and look for
22
65
  design flaws before checking formatting. Read the confirmed
23
66
  \`.ai/vcm/handoffs/architecture-brief.md\`, \`.ai/vcm/handoffs/architecture-plan.md\`,
@@ -40,6 +83,17 @@ direction, public surface and callers, architecture invariants, state or durable
40
83
  failure/retry/restart/cancellation/concurrency behavior, docs/generated-context
41
84
  impact, and whether Coder is left to make architecture decisions.
42
85
 
86
+ For every exhaustiveness claim the design depends on — "only", "all", "none",
87
+ "never", or an item count — reconstruct the claimed set independently. When
88
+ the plan records a generating command, re-run it at the reviewed commit, diff
89
+ its output against the claimed set, and then judge whether the query itself is
90
+ adequate (what the pattern could miss); a clean diff with an adequate query
91
+ closes the item. When the claim is marked judgment-derived, reconstruct it
92
+ from the source (search, package manifests, or the relevant catalogue) instead
93
+ of verifying only the cited instances. A claimed-complete enumeration with
94
+ neither a recorded command nor a judgment-derived basis, or one that fails
95
+ reconstruction, is unsupported by code evidence and is \`request_changes\`.
96
+
43
97
  Request changes when the plan is structurally complete but architecturally
44
98
  under-specified, logically inconsistent, unsupported by code evidence, unsafe
45
99
  for boundary cases, conflicts with current project architecture, or leaves key
@@ -227,6 +281,7 @@ If there are no findings, write:
227
281
  ## Architecture Analysis
228
282
 
229
283
  - Evidence Read:
284
+ - Architecture Brief Fit:
230
285
  - End-To-End Flow:
231
286
  - Scope Fit:
232
287
  - Code Reality:
@@ -12,7 +12,7 @@ Project-specific rules may be added outside the VCM managed block when they make
12
12
 
13
13
  - Coder and Coder Worker follow the accepted task scope, role message, architecture plan, and scaffold. Architect Debug Mode and Architecture Diagnosis Mode follow their confirmed root cause and PM-routed evidence.
14
14
  - Coder and Coder Worker must not change file responsibilities, callable-surface signatures, visibility, exports, contracts, or architect-defined intent unless the approved plan allows it. In Debug Mode or Architecture Diagnosis Mode, Architect may change file responsibilities and callable surfaces after confirming the root cause, and must update affected callers, contracts, and tests.
15
- - Complete assigned \`VCM:CODE\` placeholders and remove them before handoff.
15
+ - Remove each \`VCM:CODE\` marker when its item completes successfully. If implementation fails after a genuine attempt, keep the failed item's marker on the committed attempt and report the objective failure evidence. A successful implementation handoff must not contain remaining assigned markers.
16
16
  - Do not fake completion: no hardcoded success, disabled logic, swallowed errors, test-only shortcuts, or silent fallback that hides failure.
17
17
  - Implement behavior from the approved architecture, existing domain model, real inputs, and project runtime flow.
18
18
  - Do not derive logic from visible test fixtures, fixed sample values, snapshot text, or special branches that only satisfy known tests.
@@ -89,8 +89,8 @@ PM may leave this path only through the allowed branches below.
89
89
  #### Allowed Branches
90
90
 
91
91
  - **Architecture Interview Continuation:** Keep Architect Interview active while \`.ai/vcm/handoffs/architecture-brief.md\` is \`interviewing\`. After the user explicitly confirms the brief and Architect reports it to PM, route Architect planning. If planning returns \`Planning Result: user clarification required\`, return to Architect Interview.
92
- - **Architecture Plan Revision:** If Architect planning is incomplete, route Architect again. If the architecture-plan Gate returns \`request_changes\`, route the report to Architect, then rerun the architecture-plan Gate after the plan and scaffold are revised.
93
- - **Coder Continuation:** If Coder returns \`Decision: incomplete\`, lacks the required completion artifact, or has not completed implementation and L0/L1 validation, route Coder again.
92
+ - **Architecture Plan Revision:** If Architect planning is incomplete, route Architect again to continue the recorded planning work plan; multi-round planning against \`.ai/vcm/handoffs/planning-progress.md\` is the normal path for large plans, and PM must not press for completion within one round or accept summary-row compression in place of remaining steps. If the architecture-plan Gate returns \`request_changes\`, route the complete report to Architect, then rerun the full architecture-plan Gate after the plan and scaffold are revised.
93
+ - **Coder Continuation:** If Coder returns \`Decision: incomplete\`, lacks the required completion artifact, or has not completed implementation and L0/L1 validation, route Coder again — this is the only route for an in-progress sweep. Problems recorded inside an incomplete report are sweep state, not routable failures; PM routes problems onward only from a post-sweep \`failed\` report carrying the consolidated per-item disposition.
94
94
  - **Coder Failure Debug:** If Coder returns \`Decision: failed\` with compile, typecheck, or L0/L1 failure evidence after implementation, suspend the main flow and enter Architect Debug Branch.
95
95
  - **Code-Diff Correction:** If the code-diff Gate returns \`request_changes\`, suspend the main flow and enter Architect Debug Branch with the Gate report.
96
96
  - **Tester Failure:** If Tester returns \`Test Result: fail\` for the original Coder implementation, enter Architect Debug Branch.
@@ -299,7 +299,9 @@ PM may lightly rewrite the user's words to:
299
299
  - Once PM starts routing an accepted delivery request, drive the accepted scope to completion unless the user explicitly changes it.
300
300
  - Do not allow requested work to be deferred, converted into follow-up scope, reduced, or returned to the user because of workload, session length, context size, task size, predicted difficulty, or role preference.
301
301
  - PM must not route Coder concerns to Architect before Coder completes the assigned scaffold and reports objective implementation evidence.
302
- - Coder feedback that stops before implementation, compile/typecheck, or L0/L1 evidence is incomplete work, not a valid architecture signal.
302
+ - Coder feedback that stops before the full sweep of assigned items is incomplete work, not a valid failure or architecture signal.
303
+ - Before acting on any Coder decision, verify that every Scaffold Manifest item appears exactly once in Scaffold Completion, each disposition is consistent with its marker state in the tree, and the reported Decision matches the dispositions.
304
+ - Return any missing, duplicate, unswept, marker-inconsistent, or decision-inconsistent result to Coder as incomplete work regardless of the reported Decision.
303
305
  - If Coder returns questions, concerns, predictions, architecture doubts, or validation worries before completing the assigned implementation, route Coder back to finish the work.
304
306
  - PM must not forward Coder critique of the architecture plan, scaffold, module boundaries, public contracts, or validation strategy to Architect before Coder submits \`coder-completion.md\` with compile/typecheck/L0/L1 evidence.
305
307
  - Before that evidence exists, any Coder architecture critique is incomplete work; route Coder back to finish implementation.
@@ -25,6 +25,7 @@ const REQUIRED_HEADINGS = {
25
25
  "Module/File Plan",
26
26
  "Public Surface Impact",
27
27
  "Scaffold Manifest",
28
+ "Scaffold Build Evidence",
28
29
  "Tester Coverage Hints",
29
30
  "Docs Impact",
30
31
  "Known Risks",
@@ -110,6 +111,15 @@ export function checkMarkdownArtifact(kind, artifactPath, content) {
110
111
  };
111
112
  }
112
113
  function validateArtifactFields(kind, content) {
114
+ if (kind === "architecture-plan") {
115
+ const result = /^\s*Planning Result\s*:\s*(.+?)\s*$/im.exec(content)?.[1]?.trim().toLowerCase();
116
+ if (!result) {
117
+ return ["Planning Result is required and must be complete."];
118
+ }
119
+ return result === "complete"
120
+ ? []
121
+ : [`Planning Result must be complete; received "${result}".`];
122
+ }
113
123
  if (kind === "architecture-brief") {
114
124
  const status = /^\s*Architecture Brief Status\s*:\s*(\S+)\s*$/im.exec(content)?.[1]?.toLowerCase();
115
125
  const invalidFields = status === "interviewing" || status === "confirmed"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-coding-master",
3
- "version": "0.7.7",
3
+ "version": "0.7.9",
4
4
  "description": "Local GUI session cockpit for Claude Code role sessions.",
5
5
  "type": "module",
6
6
  "files": [