vibe-coding-master 0.7.38 → 0.7.40

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.
Files changed (49) hide show
  1. package/README.md +12 -6
  2. package/dist/backend/adapters/claude-adapter.js +1 -0
  3. package/dist/backend/api/artifact-routes.js +72 -1
  4. package/dist/backend/api/runtime-state-routes.js +17 -5
  5. package/dist/backend/api/task-routes.js +6 -0
  6. package/dist/backend/api/workflow-control-routes.js +56 -0
  7. package/dist/backend/cli/install-vcm-harness.js +46 -22
  8. package/dist/backend/server.js +21 -5
  9. package/dist/backend/services/artifact-service.js +309 -5
  10. package/dist/backend/services/auto-memory-service.js +2 -2
  11. package/dist/backend/services/code-intelligence-service.js +5 -5
  12. package/dist/backend/services/gate-review-service.js +81 -33
  13. package/dist/backend/services/harness-feedback-service.js +11 -4
  14. package/dist/backend/services/harness-service.js +42 -26
  15. package/dist/backend/services/message-service.js +105 -37
  16. package/dist/backend/services/status-service.js +6 -0
  17. package/dist/backend/services/workflow-control-service.js +854 -0
  18. package/dist/backend/templates/handoff.js +158 -3
  19. package/dist/backend/templates/harness/architect-agent.js +3 -3
  20. package/dist/backend/templates/harness/check-scaffold-ledger.js +105 -39
  21. package/dist/backend/templates/harness/claude-root.js +9 -1
  22. package/dist/backend/templates/harness/coder-agent.js +2 -3
  23. package/dist/backend/templates/harness/coder-worker-agent.js +1 -1
  24. package/dist/backend/templates/harness/gate-review.js +4 -5
  25. package/dist/backend/templates/harness/harness-engineer-agent.js +18 -1
  26. package/dist/backend/templates/harness/project-manager-agent.js +3 -2
  27. package/dist/backend/templates/harness/tester-agent.js +1 -0
  28. package/dist/backend/templates/harness/vcm-architecture-interview-skill.js +5 -0
  29. package/dist/backend/templates/harness/vcm-code-navigation-skill.js +7 -6
  30. package/dist/backend/templates/harness/vcm-final-acceptance-skill.js +2 -2
  31. package/dist/backend/templates/harness/vcm-long-running-validation-skill.js +4 -2
  32. package/dist/backend/templates/harness/vcm-propose-memory-skill.js +4 -2
  33. package/dist/backend/templates/harness/vcm-report-harness-issue-skill.js +2 -1
  34. package/dist/backend/templates/harness/vcm-route-message-skill.js +4 -7
  35. package/dist/backend/templates/harness/vcm-task-state-skill.js +2 -13
  36. package/dist/backend/templates/harness/vcm-workflow-review-skill.js +62 -0
  37. package/dist/backend/templates/message-envelope.js +4 -4
  38. package/dist/shared/types/workflow.js +7 -1
  39. package/dist/shared/validation/artifact-check.js +99 -95
  40. package/dist/shared/validation/artifact-contract.js +9 -0
  41. package/dist/shared/validation/artifact-registry.js +211 -0
  42. package/dist-frontend/assets/{index-VillnFRo.js → index-Bocc2DWF.js} +34 -34
  43. package/dist-frontend/assets/{index-CXSOe-NN.css → index-C_XHGNBD.css} +1 -1
  44. package/dist-frontend/index.html +2 -2
  45. package/package.json +1 -1
  46. package/scripts/harness-tools/run-long-check +38 -8
  47. package/scripts/harness-tools/vcm-artifact +148 -0
  48. package/scripts/harness-tools/vcm-bash-guard +42 -47
  49. package/scripts/harness-tools/watch-job +58 -4
@@ -1,4 +1,4 @@
1
- import { ARCHITECTURE_BRIEF_STATUSES, ARCHITECTURE_PLAN_RESULTS, DOCS_SYNC_DECISIONS, FINAL_ACCEPTANCE_DECISIONS, L3_ACTIONS, L3_REQUIRED_VALUES, STRICT_NONE_VALUE, TEST_INFRASTRUCTURE_STATUSES, TEST_RESULTS, renderArtifactOptions } from "../../shared/validation/artifact-contract.js";
1
+ import { ARCHITECT_DEBUG_STATUSES, ARCHITECTURE_BRIEF_STATUSES, ARCHITECTURE_DIAGNOSIS_DISPOSITIONS, ARCHITECTURE_EVIDENCE_STATUSES, ARCHITECTURE_PLAN_RESULTS, CODER_COMPLETION_DECISIONS, DOCS_SYNC_DECISIONS, FINAL_ACCEPTANCE_DECISIONS, L3_ACTIONS, L3_REQUIRED_VALUES, PLANNING_PROGRESS_STATUSES, STRICT_NONE_VALUE, TEST_INFRASTRUCTURE_STATUSES, TEST_RESULTS, renderArtifactOptions } from "../../shared/validation/artifact-contract.js";
2
2
  const CURRENT_HANDOFF_NOTICE = "<!-- VCM current handoff: replace this file with one complete, self-contained snapshot of the current result. Restate all still-relevant evidence; do not refer to a prior revision, route message, Session, or transcript as evidence. -->";
3
3
  export function renderArchitectureBriefTemplate(taskSlug) {
4
4
  return `# Architecture Brief: ${taskSlug}
@@ -109,6 +109,8 @@ error boundaries, or non-obvious logic that should remain useful after this task
109
109
  Use an ID matching \`[A-Z]{2,6}-[0-9]{1,4}\`, choose exactly one Action
110
110
  (\`create\`, \`change\`, or \`delete\`), put the repo-relative File path in
111
111
  backticks, and enumerate every implementation item explicitly.
112
+ When no scaffold item exists, replace the table with exactly \`No scaffold items.\`;
113
+ an empty table is invalid.
112
114
 
113
115
  | ID | Action | File | Symbol Or Site | Coder Work | Allowed Implementation Freedom | Behavior / Contract Proof Point |
114
116
  | --- | --- | --- | --- | --- | --- | --- |
@@ -137,6 +139,64 @@ TBD
137
139
  TBD
138
140
  `;
139
141
  }
142
+ export function renderArchitectureEvidenceTemplate(taskSlug) {
143
+ return `# Architecture Evidence: ${taskSlug}
144
+
145
+ ${CURRENT_HANDOFF_NOTICE}
146
+
147
+ Architecture Evidence Status: ${renderArtifactOptions(ARCHITECTURE_EVIDENCE_STATUSES)}
148
+
149
+ ## Planning Boundary
150
+
151
+ TBD
152
+
153
+ ## Entry Points And Behavior Paths
154
+
155
+ TBD
156
+
157
+ ## State And Lifecycle
158
+
159
+ TBD
160
+
161
+ ## Callers And Consumers
162
+
163
+ TBD
164
+
165
+ ## Existing Assumptions
166
+
167
+ TBD
168
+
169
+ ## Related Class Inventories
170
+
171
+ TBD
172
+
173
+ ## External Boundaries
174
+
175
+ TBD
176
+
177
+ ## Code And Docs Conflicts
178
+
179
+ TBD
180
+
181
+ ## Evidence Commands
182
+
183
+ TBD
184
+ `;
185
+ }
186
+ export function renderPlanningProgressTemplate(taskSlug) {
187
+ return `# Planning Progress: ${taskSlug}
188
+
189
+ ${CURRENT_HANDOFF_NOTICE}
190
+
191
+ Planning Progress Status: ${renderArtifactOptions(PLANNING_PROGRESS_STATUSES)}
192
+
193
+ ## Planning Steps
194
+
195
+ | Step | Scope | Deliverable | Done Criterion | Status | Evidence |
196
+ | --- | --- | --- | --- | --- | --- |
197
+ | Architecture Evidence Verification | TBD | TBD | TBD | pending | TBD |
198
+ `;
199
+ }
140
200
  export function renderKnownIssuesTemplate(taskSlug) {
141
201
  return `# Known Issues: ${taskSlug}
142
202
 
@@ -260,7 +320,7 @@ export function renderCoderCompletionTemplate(taskSlug) {
260
320
 
261
321
  ${CURRENT_HANDOFF_NOTICE}
262
322
 
263
- Decision: ready_for_review|incomplete|failed
323
+ Decision: ${renderArtifactOptions(CODER_COMPLETION_DECISIONS)}
264
324
 
265
325
  ## Scaffold Completion
266
326
 
@@ -306,7 +366,7 @@ export function renderArchitectDebugTemplate(taskSlug) {
306
366
 
307
367
  ${CURRENT_HANDOFF_NOTICE}
308
368
 
309
- Status: pending|completed
369
+ Status: ${renderArtifactOptions(ARCHITECT_DEBUG_STATUSES)}
310
370
 
311
371
  ## PM-Routed Failure
312
372
 
@@ -352,6 +412,77 @@ TBD
352
412
  TBD
353
413
  `;
354
414
  }
415
+ export function renderArchitectureDiagnosisTemplate(taskSlug) {
416
+ return `# Architecture Diagnosis: ${taskSlug}
417
+
418
+ ${CURRENT_HANDOFF_NOTICE}
419
+
420
+ ## Diagnosis Boundary
421
+
422
+ TBD
423
+
424
+ ## Documents And Runtime Evidence
425
+
426
+ TBD
427
+
428
+ ## Code Reading Closure
429
+
430
+ TBD
431
+
432
+ ## Current Architecture
433
+
434
+ TBD
435
+
436
+ ## Previous Debug Failure
437
+
438
+ TBD
439
+
440
+ ## Failure Trace
441
+
442
+ TBD
443
+
444
+ ## Architecture Assessment
445
+
446
+ TBD
447
+
448
+ ## Required Architecture Direction
449
+
450
+ TBD
451
+
452
+ ## Implementation And Validation
453
+
454
+ ### Changed Files And Public Surface
455
+
456
+ TBD
457
+
458
+ ### Baseline Tests
459
+
460
+ TBD
461
+
462
+ ### Diagnostic And L0/L1 Validation
463
+
464
+ TBD
465
+
466
+ ### L2/L3 Validation
467
+
468
+ | Level | Applicable | Command Or Test | Failure Path | Result | Evidence |
469
+ | --- | --- | --- | --- | --- | --- |
470
+ | L2 | TBD | TBD | TBD | TBD | TBD |
471
+ | L3 | TBD | TBD | TBD | TBD | TBD |
472
+
473
+ ### Generated Context
474
+
475
+ TBD
476
+
477
+ ### Commit
478
+
479
+ TBD
480
+
481
+ ## Final Disposition
482
+
483
+ ${renderArtifactOptions(ARCHITECTURE_DIAGNOSIS_DISPOSITIONS)}
484
+ `;
485
+ }
355
486
  export function renderDocsSyncReportTemplate(taskSlug) {
356
487
  return `# Docs Sync Report: ${taskSlug}
357
488
 
@@ -390,6 +521,30 @@ TBD
390
521
  ${renderArtifactOptions(DOCS_SYNC_DECISIONS)}
391
522
  `;
392
523
  }
524
+ export function renderWorkflowProgressTemplate(taskSlug) {
525
+ return `# Workflow Progress: ${taskSlug}
526
+
527
+ Revision: 0
528
+ Flow: none
529
+ Status: not-started
530
+
531
+ ## Dispatch History
532
+
533
+ none
534
+
535
+ ## Proposed Dispatch
536
+
537
+ Requested Flow: none
538
+ Target Role: none
539
+ Evidence: none
540
+
541
+ ## User Override
542
+
543
+ Authorization ID: none
544
+ Authorization Quote: none
545
+ Violated Rule: none
546
+ `;
547
+ }
393
548
  export function renderFinalAcceptanceTemplate(taskSlug) {
394
549
  return `# Final Acceptance: ${taskSlug}
395
550
 
@@ -21,14 +21,14 @@ ${renderRoleMemoryRules("architect")}
21
21
 
22
22
  ### Semantic Code Navigation
23
23
 
24
- - Use \`vcm-code-navigation\` whenever work requires code definitions, implementations, references, callers, callees, or behavior paths. This applies in every Architect mode and in direct user communication.
24
+ - Follow the preloaded \`vcm-code-navigation\` skill whenever work requires code definitions, implementations, references, callers, callees, or behavior paths. This applies in every Architect mode and in direct user communication.
25
25
  - Use LSP for semantic relationships. Use Glob to locate files, Read to inspect complete code, and generated context, architecture documents, or runtime evidence for boundaries LSP does not model.
26
- - Do not use the Grep tool or shell text-search commands such as \`grep\`, \`rg\`, or \`git grep\`.
27
26
  - If LSP cannot resolve a required project-owned relationship, record it as unresolved. Do not replace semantic evidence with text matches.
28
27
 
29
28
  ### Work Persistence
30
29
 
31
30
  - Treat Architect artifacts, not Session memory, as continuation state.
31
+ - Write each owned artifact to a candidate outside \`.ai/vcm\`, then submit it with \`.ai/tools/vcm-artifact <artifact-kind> --file <candidate> --mode draft|final\`. Only an accepted submission updates the authoritative artifact.
32
32
  - Write each verified code fact, confirmed user decision, architecture decision, root cause, and validation result to its owning artifact as soon as it becomes an input to later work.
33
33
  - Before ending any turn, ensure all information required to continue the current Architect work is present in the current artifacts.
34
34
  - Keep artifacts current and self-contained. Replace superseded content instead of appending conversation history or investigation logs.
@@ -102,7 +102,7 @@ ${renderRoleMemoryRules("architect")}
102
102
  - When the repeated-workaround threshold is met, \`Architecture Decision\` must explicitly fix the owning behavior, confirm that local handling is intended and correct the owning documentation, or record the unresolved issue and affected call sites through Known Issues Sync. Extracting the workaround into a helper is not an upstream disposition.
103
103
  - \`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. For every ledger item that consumes or sources cross-module data, name the module and symbol that owns or produces the data, trace the source-to-consumer path, and identify every field, parameter, accessor, trait method, command field, dependency, or other cross-file surface required by that path.
104
104
  - \`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.
105
- - \`Scaffold Manifest\`: an item ledger — one entry per implementation item. Use columns in the exact order \`ID | Action | File | ...\`; use an ID matching \`AA-1\` through \`AAAAAA-9999\`, an Action of exactly \`create\`, \`change\`, or \`delete\`, and a backticked repo-relative File path. An item is one created body or surface, one required change site — one contiguous edit region inside an existing body or surface — or one deletion of a body, site, or file. An item not in the ledger is not in the plan; coder must not implement it.
105
+ - \`Scaffold Manifest\`: an item ledger — one entry per implementation item. Use columns in the exact order \`ID | Action | File | ...\`; use an ID matching \`AA-1\` through \`AAAAAA-9999\`, an Action of exactly \`create\`, \`change\`, or \`delete\`, and a backticked repo-relative File path. An item is one created body or surface, one required change site — one contiguous edit region inside an existing body or surface — or one deletion of a body, site, or file. An item not in the ledger is not in the plan; coder must not implement it. When no scaffold item exists, omit the table and write exactly \`No scaffold items.\`; an empty table is invalid.
106
106
  - 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.
107
107
  - 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.
108
108
  - 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.
@@ -7,7 +7,8 @@ item, one unique ID per entry, and exactly one \`VCM:CODE <ID>\` marker in the t
7
7
  \`create\`/\`change\`/\`delete\` entry. This tool checks:
8
8
 
9
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
10
+ every data-row ID matches the documented grammar as a complete cell and is unique,
11
+ classified by its whole-cell action column
11
12
  (create/change/delete), and bound to a declared file path in the file column;
12
13
  2. the ledger ID set equals the tree marker ID set, each ID exactly once on each side;
13
14
  3. every marker sits in its entry's declared file;
@@ -28,14 +29,15 @@ from pathlib import Path
28
29
  PLAN = ".ai/vcm/handoffs/architecture-plan.md"
29
30
  MANIFEST_HEADING = re.compile(r"^##\\s+Scaffold Manifest\\s*$")
30
31
  SECTION_HEADING = re.compile(r"^##\\s+\\S")
31
- ID_TOKEN = re.compile(r"\\b([A-Z]{2,6}-\\d{1,4})\\b")
32
+ ID_PATTERN = re.compile(r"[A-Z]{2,6}-\\d{1,4}")
33
+ EMPTY_MANIFEST = "No scaffold items."
34
+ TABLE_SEPARATOR_CELL = re.compile(r":?-{3,}:?")
32
35
  # Mandated column order: ID | action | file | symbol/site | work | freedom | proof.
33
36
  # The action is read from its own cell as a whole-cell verb — never sniffed from the
34
37
  # row text, so paths or prose containing action words cannot flip an item's class.
35
38
  ACTIONS = frozenset({"create", "change", "delete"})
36
39
  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")
40
+ MARKER_ANY = re.compile(r"VCM:CODE(?![A-Za-z0-9_])")
39
41
  FORBIDDEN = [
40
42
  re.compile(r"as work proceeds", re.IGNORECASE),
41
43
  re.compile(r"\\breplicate\\b", re.IGNORECASE),
@@ -57,36 +59,66 @@ def manifest_section(plan_text: str) -> tuple[int, list[str]] | None:
57
59
  return None if start is None else (start, lines[start:])
58
60
 
59
61
 
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."""
62
+ def is_separator_row(cells: list[str]) -> bool:
63
+ return bool(cells) and all(TABLE_SEPARATOR_CELL.fullmatch(cell.replace(" ", "")) for cell in cells)
64
+
65
+
66
+ def parse_ledger(section_start: int, section: list[str], plan: str) -> tuple[dict, list[str], bool]:
67
+ """{id: {"path", "action", "line"}}, parse findings, and explicit-empty state."""
63
68
  entries: dict[str, dict] = {}
64
69
  findings: list[str] = []
65
- header_checked = False
70
+ header_line = None
71
+ separator_seen = False
72
+ explicit_empty_line = None
66
73
  for offset, line in enumerate(section):
67
74
  line_no = section_start + offset + 1
68
75
  stripped = line.strip()
76
+ if stripped == EMPTY_MANIFEST:
77
+ if explicit_empty_line is not None:
78
+ findings.append(
79
+ f"{plan}:{line_no} [ledger] duplicate \`{EMPTY_MANIFEST}\` declaration "
80
+ f"(first at line {explicit_empty_line})"
81
+ )
82
+ else:
83
+ explicit_empty_line = line_no
84
+ continue
69
85
  if not stripped.startswith("|"):
70
86
  continue
71
87
  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
+
89
+ if header_line is None:
90
+ header_line = line_no
91
+ head = [cell.lower() for cell in cells[:3]]
92
+ if head != ["id", "action", "file"]:
93
+ findings.append(
94
+ f"{plan}:{line_no} [ledger] header columns must begin exactly "
95
+ f"\`ID | Action | File | ...\` -> fix the ledger column order"
96
+ )
88
97
  continue
89
- entry_id = id_match.group(1)
98
+
99
+ if not separator_seen:
100
+ if is_separator_row(cells):
101
+ separator_seen = True
102
+ continue
103
+ findings.append(
104
+ f"{plan}:{line_no} [ledger] missing Markdown separator row after "
105
+ f"the Scaffold Manifest header"
106
+ )
107
+ separator_seen = True
108
+ elif is_separator_row(cells):
109
+ findings.append(
110
+ f"{plan}:{line_no} [ledger] unexpected separator row inside Scaffold Manifest data"
111
+ )
112
+ continue
113
+
114
+ id_cell = cells[0] if cells else ""
115
+ if not ID_PATTERN.fullmatch(id_cell):
116
+ findings.append(
117
+ f"{plan}:{line_no} [ledger] ID cell \`{id_cell}\` must match "
118
+ f"\`[A-Z]{{2,6}}-[0-9]{{1,4}}\` exactly"
119
+ )
120
+ continue
121
+ entry_id = id_cell
90
122
  if entry_id in entries:
91
123
  findings.append(
92
124
  f"{plan}:{line_no} [ledger] duplicate ledger ID {entry_id} "
@@ -110,7 +142,30 @@ def parse_ledger(section_start: int, section: list[str], plan: str) -> tuple[dic
110
142
  f"column 3 -> bind the item to its exact file"
111
143
  )
112
144
  entries[entry_id] = {"path": declared, "action": action, "line": line_no}
113
- return entries, findings
145
+ if explicit_empty_line is not None:
146
+ if header_line is not None:
147
+ findings.append(
148
+ f"{plan}:{explicit_empty_line} [ledger] \`{EMPTY_MANIFEST}\` cannot be "
149
+ f"combined with a Scaffold Manifest table"
150
+ )
151
+ return entries, findings, True
152
+
153
+ if header_line is None:
154
+ findings.append(
155
+ f"{plan}:{section_start + 1} [ledger] Scaffold Manifest must contain the "
156
+ f"required table or the exact line \`{EMPTY_MANIFEST}\`"
157
+ )
158
+ return entries, findings, False
159
+ if not separator_seen:
160
+ findings.append(
161
+ f"{plan}:{header_line} [ledger] Scaffold Manifest table is missing its separator row"
162
+ )
163
+ if not entries:
164
+ findings.append(
165
+ f"{plan}:{header_line} [ledger] Scaffold Manifest contains no valid entries; "
166
+ f"use the exact line \`{EMPTY_MANIFEST}\` only when no scaffold item exists"
167
+ )
168
+ return entries, findings, False
114
169
 
115
170
 
116
171
  def forbidden_language(section_start: int, section: list[str], plan: str) -> list[str]:
@@ -140,14 +195,22 @@ def tree_markers(root: Path) -> tuple[dict[str, list[tuple[str, int]]], list[str
140
195
  if len(parts) < 3:
141
196
  continue
142
197
  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
- )
198
+ for occurrence in MARKER_ANY.finditer(content):
199
+ token_match = re.match(r"\\s+(\\S+)", content[occurrence.end():])
200
+ if token_match is None:
201
+ findings.append(
202
+ f"{path}:{line_no} [ledger] marker without an ID -> "
203
+ f"use \`VCM:CODE <ID>\`"
204
+ )
205
+ continue
206
+ marker_id = token_match.group(1)
207
+ if not ID_PATTERN.fullmatch(marker_id):
208
+ findings.append(
209
+ f"{path}:{line_no} [ledger] marker ID \`{marker_id}\` must match "
210
+ f"\`[A-Z]{{2,6}}-[0-9]{{1,4}}\` exactly"
211
+ )
212
+ continue
213
+ markers.setdefault(marker_id, []).append((path, line_no))
151
214
  return markers, findings
152
215
 
153
216
 
@@ -170,7 +233,7 @@ def main() -> int:
170
233
  if section is None:
171
234
  sys.stderr.write(f"{plan_path}:1 [ledger] no \`## Scaffold Manifest\` section\\n")
172
235
  return 1
173
- entries, parse_findings = parse_ledger(*section, str(plan_path))
236
+ entries, parse_findings, explicit_empty = parse_ledger(*section, str(plan_path))
174
237
  findings += parse_findings
175
238
  findings += forbidden_language(*section, str(plan_path))
176
239
 
@@ -213,10 +276,13 @@ def main() -> int:
213
276
  if findings:
214
277
  sys.stderr.write(f"ledger reconciliation failed with {len(findings)} finding(s)\\n")
215
278
  return 1
216
- print(
217
- f"ledger reconciliation clean: {len(ledger_ids)} ledger item(s), "
218
- f"{len(tree_ids)} marker(s)"
219
- )
279
+ if explicit_empty:
280
+ print("ledger explicitly empty: 0 ledger item(s), 0 marker(s)")
281
+ else:
282
+ print(
283
+ f"ledger reconciliation clean: {len(ledger_ids)} ledger item(s), "
284
+ f"{len(tree_ids)} marker(s)"
285
+ )
220
286
  return 0
221
287
 
222
288
 
@@ -4,13 +4,21 @@ export function renderRootClaudeHarnessRules() {
4
4
  - Use the durable project docs below as role-relevant project truth.
5
5
  - Read module-local \`CLAUDE.md\` before editing a subdirectory if one exists.
6
6
  - \`vcm-route-message\` is the only channel for PM-hub dispatch and reporting among project-manager, architect, coder, and tester. Gate Review and tool-role work use their dedicated VCM skills and controllers. Follow the route skill's write-then-stop rule.
7
- - Project-manager uses \`vcm-task-state\` to declare the current workflow checkpoint. This state is recoverable context only; flow rules and task artifacts remain authoritative.
7
+ - Before every PM dispatch to Architect, Coder, or Tester, project-manager must use \`vcm-workflow-review\`. Only an accepted Workflow Progress transition grants the next route.
8
+ - \`vcm-task-state\` is recoverable context only. Workflow permission comes only from accepted \`workflow-progress.md\` submissions.
8
9
  - Use \`vcm-long-running-validation\` for long-running validation. Follow the background job limits below.
9
10
  - Use \`vcm-report-harness-issue\` when you notice a reusable VCM harness problem. Record feedback; do not contact Harness Engineer directly.
10
11
  - The root \`<VCM-memory>\` block is shared project memory. Treat every \`<VCM-memory>\` block as read-only and use \`vcm-propose-memory\` only when VCM assigns an exact memory proposal or candidate path.
11
12
  - Only the user may approve scope reduction, skipped required validation, Gate Review skip or override, skipped required docs sync, accepted unresolved task-scope risk, or weakening of baseline Harness rules. PM may record and route the user's approval but cannot grant it.
12
13
  - Project-manager runs \`vcm-gate-review\` unconditionally at every Gate Review trigger point and on VCM Gate Review callbacks; the tool reports the authoritative enable state.
13
14
 
15
+ ## VCM Managed Artifacts
16
+
17
+ - VCM-managed Markdown under \`.ai/vcm/handoffs/\`, Coder Worker reports, request-scoped Gate Review reports, route messages, memory proposals, Harness Feedback, and retrospective reports must be submitted with \`.ai/tools/vcm-artifact\`; never write or edit the authoritative path directly.
18
+ - Write the candidate outside \`.ai/vcm/\`, then run \`.ai/tools/vcm-artifact <kind> --file <candidate> --mode <draft|final>\`. Dynamic artifacts also require the exact VCM-assigned \`--path\`.
19
+ - Use \`draft\` while an allowed lifecycle remains incomplete. Use \`final\` before routing or consuming a terminal artifact. A failed submission leaves the authoritative artifact unchanged; correct every reported violation and submit again.
20
+ - Do not route, review, or rely on a candidate file. Only the VCM-written authoritative path is workflow evidence.
21
+
14
22
  ## VCM Harness Scope
15
23
 
16
24
  VCM harness includes root \`CLAUDE.md\`, \`.claude/agents/**\`, \`.claude/skills/**\`, \`.ai/tools/**\`, \`.claude/settings.json\`, VCM managed blocks, generated-context tooling, bootstrap rules, routing rules, validation rules, Gate Review rules, tool-role rules, and Harness Engineer rules.
@@ -14,9 +14,8 @@ ${renderRoleMemoryRules("coder")}
14
14
 
15
15
  ### Semantic Code Navigation
16
16
 
17
- - Use \`vcm-code-navigation\` whenever implementation requires code definitions, implementations, references, callers, callees, or behavior paths.
17
+ - Follow the preloaded \`vcm-code-navigation\` skill whenever implementation requires code definitions, implementations, references, callers, callees, or behavior paths.
18
18
  - Use LSP for semantic relationships. Use Glob to locate files and Read to inspect complete code.
19
- - Do not use the Grep tool or shell text-search commands such as \`grep\`, \`rg\`, or \`git grep\`.
20
19
  - If LSP cannot resolve a required project-owned relationship, record it as unresolved in the completion evidence. Do not replace semantic evidence with text matches.
21
20
 
22
21
  ### Shared Coding Standards
@@ -78,7 +77,7 @@ ${renderRoleMemoryRules("coder")}
78
77
 
79
78
  ### Handoff
80
79
 
81
- - Write \`.ai/vcm/handoffs/coder-completion.md\` before routing back to project-manager. This file is the complete, self-contained current implementation completion evidence, not a log. Each revision must restate every Scaffold Manifest disposition, changed file, helper, deviation, generated-context result, baseline-test change, L0/L1 command and result, worker result, commit, and objective failure still needed to review the current implementation without a prior revision. Replace stale content instead of appending history.
80
+ - Submit \`.ai/vcm/handoffs/coder-completion.md\` before routing back to project-manager: write a candidate outside \`.ai/vcm\`, then run \`.ai/tools/vcm-artifact coder-completion --file <candidate> --mode draft|final\`. This file is the complete, self-contained current implementation completion evidence, not a log. Each revision must restate every Scaffold Manifest disposition, changed file, helper, deviation, generated-context result, baseline-test change, L0/L1 command and result, worker result, commit, and objective failure still needed to review the current implementation without a prior revision. Replace stale content instead of appending history.
82
81
  - \`coder-completion.md\` must include \`Decision: ready_for_review | incomplete | failed\`.
83
82
  - \`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.
84
83
  - Use this structure:
@@ -25,7 +25,7 @@ You are \`vcm-coder-worker\`, a bounded implementation worker invoked by Coder.
25
25
  }
26
26
  \`\`\`
27
27
 
28
- - 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.
28
+ - After the sweep of assigned items and their assigned checks, commit the assigned files. After the commit succeeds, write the assigned report to a candidate outside \`.ai/vcm\`, submit it with \`.ai/tools/vcm-artifact coder-worker-report --file <candidate> --path <assigned-report-path> --mode final\`, then update only the assigned worker state to \`completed\` with the same \`commitHash\` as the final step.
29
29
  - The completed state must retain \`workerId\`, \`reportPath\`, and \`handled: false\`, set \`status\` to \`completed\`, and add \`"commitHash": "<exact-report-commit-hash>"\`.
30
30
  - 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\`.
31
31
  - 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.
@@ -17,12 +17,11 @@ Use only these decisions:
17
17
 
18
18
  ## Semantic Code Navigation
19
19
 
20
- Use \`vcm-code-navigation\` whenever a gate requires code definitions,
20
+ Follow the preloaded \`vcm-code-navigation\` skill whenever a gate requires code definitions,
21
21
  implementations, references, callers, callees, or behavior paths. Use LSP for
22
22
  semantic relationships, Glob to locate files, Read to inspect complete code,
23
23
  and generated context, architecture documents, or runtime evidence for
24
- boundaries LSP does not model. Do not use the Grep tool or shell text-search
25
- commands such as \`grep\`, \`rg\`, or \`git grep\`. If LSP cannot resolve
24
+ boundaries LSP does not model. If LSP cannot resolve
26
25
  a required project-owned relationship, treat that evidence as unresolved and
27
26
  return \`request_changes\`; do not replace semantic evidence with text matches.
28
27
 
@@ -338,7 +337,7 @@ evidence.
338
337
 
339
338
  ## Output
340
339
 
341
- For an active VCM Gate Review request, write only the assigned report under \`.ai/vcm/gate-reviews/\`. Start with:
340
+ For an active VCM Gate Review request, write only the assigned report under \`.ai/vcm/gate-reviews/\`. Write a candidate outside \`.ai/vcm\`, then submit it with \`.ai/tools/vcm-artifact gate-review-report --file <candidate> --path <assigned-report-path> --mode final\`. Start with:
342
341
 
343
342
  \`\`\`text
344
343
  Gate: <gate>
@@ -472,7 +471,7 @@ If there are no findings, write:
472
471
  None.
473
472
  \`\`\`
474
473
 
475
- Use Bash only for read-only inspection such as \`git diff\`, \`git status\`, \`git show\`, \`ls\`, \`sed\`, or \`cat\`. Do not run shell text-search commands, tests, builds, formatters, generators, package managers, or commands that modify files.
474
+ Use Bash only for read-only inspection such as \`git diff\`, \`git status\`, \`git show\`, \`ls\`, \`sed\`, or \`cat\`. Do not run tests, builds, formatters, generators, package managers, or commands that modify files.
476
475
 
477
476
  Review only code, architecture, and documents; do not perform validation. Do not edit code, tests, durable docs, role files, route files, or handoff artifacts. Do not assign findings or remediation work to VCM roles, choose fixes, decide Replan, or decide whether user intervention is needed.
478
477
 
@@ -131,7 +131,7 @@ For each pending feedback:
131
131
  Process every assigned feedback before completing the retrospective. A
132
132
  feedback item is processed even when it is rejected or already covered.
133
133
 
134
- Write the complete retrospective report before deleting any feedback file.
134
+ Write the complete retrospective report to a candidate outside \`.ai/vcm\` and submit it with \`.ai/tools/vcm-artifact retrospective-report --file <candidate> --path <assigned-report-path> --mode final\` before deleting any feedback file.
135
135
  After the report contains a disposition for every assigned feedback, delete
136
136
  those feedback files from \`.ai/vcm/harness-feedback/pending/\`.
137
137
 
@@ -158,6 +158,23 @@ Do not edit harness files during retrospective analysis. Write a concise analysi
158
158
  - affected roles, skills, tools, or docs
159
159
  - pending feedback path and disposition
160
160
 
161
+ Use this report structure:
162
+
163
+ \`\`\`md
164
+ # Task Harness Retrospective: <task>
165
+
166
+ ## Findings
167
+
168
+ ## Feedback Dispositions
169
+
170
+ ## Recommended Harness Changes
171
+
172
+ ## VCM Issue Drafts
173
+
174
+ <!-- Include Memory Review only when VCM assigns Auto Memory Review. -->
175
+ ## Memory Review
176
+ \`\`\`
177
+
161
178
  ## VCM Feedback
162
179
 
163
180
  If the issue is a VCM product, installer, UI, or fixed template problem, draft a
@@ -52,7 +52,7 @@ PM Managed Mode applies only when the user explicitly asks to complete the curre
52
52
 
53
53
  PM owns task flow selection. Every user request that asks VCM to perform delivery work must enter one of these flows or branches:
54
54
 
55
- - After selecting a flow, use \`vcm-task-state\` to declare the flow and first step before the first role dispatch.
55
+ - Before every dispatch to Architect, Coder, or Tester, use \`vcm-workflow-review\` and obtain an accepted Workflow Progress transition for that exact target. A rejection keeps PM in the current turn.
56
56
 
57
57
  - Code-change flow: use the complete Code-Change Flow defined below.
58
58
  - Architect Debug Flow or Branch: use Architect Debug Flow And Branch below.
@@ -113,7 +113,7 @@ The flow completes only when Final Acceptance returns:
113
113
  ### Routing
114
114
 
115
115
  - Use the PM-hub routes allowed by the \`vcm-route-message\` skill.
116
- - Include the current \`vcm-task-state\` declaration in every PM route file. At a checkpoint without a role route, declare the new step with \`.ai/tools/update-task-state\`.
116
+ - Write a PM route file only after \`vcm-workflow-review\` accepts the matching target. The approval is one-time and contains the workflow state; do not duplicate workflow metadata in the route file.
117
117
  - Keep only one active role handoff at a time.
118
118
  - Route user-originated or flow-required architecture, scope, contract, dependency, public surface, durable docs, and implementation-plan questions to Architect.
119
119
  - Do not treat Coder architecture doubts, design concerns, scaffold objections, or validation predictions as architecture questions.
@@ -300,6 +300,7 @@ Communication-Only Flow does not run Gate Review, validation, docs sync, Final A
300
300
 
301
301
  ### Dispatch
302
302
 
303
+ - Use \`vcm-workflow-review\` before every dispatch to Architect, Coder, or Tester. Only the user may authorize one exact rejected transition through VCM's Workflow Override dialog.
303
304
  - Use the \`vcm-route-message\` skill for every role dispatch, question, result, blocker, or finding.
304
305
  - Formal route messages contain PM-owned routing context only.
305
306
  - PM dispatch messages must include: target role, accepted task scope, current task repo root and branch, reason for this route, source artifact or evidence, required output artifact, next gate, stop conditions, and user constraints.
@@ -14,6 +14,7 @@ ${renderRoleMemoryRules("tester")}
14
14
  ### Inputs
15
15
 
16
16
  - Read tester role message, the VCM task record or durable plan, architecture plan, \`docs/CODING_STANDARDS.md\`, \`docs/TESTING.md\`, relevant tests, fixtures, and validation docs.
17
+ - Write \`test-report.md\` to a candidate outside \`.ai/vcm\`, then submit it with \`.ai/tools/vcm-artifact test-report --file <candidate> --mode draft|final\`. Use draft only for \`Test Result: incomplete\`; pass or fail must use final.
17
18
  - Read affected production code only as needed to design tests, understand public contracts, and identify validation coverage gaps.
18
19
  - Use \`.ai/generated/module-index.json\` and \`.ai/generated/public-surface.json\` to identify affected modules, test files, public API changes, and source evidence.
19
20
 
@@ -47,6 +47,11 @@ Routine technical architecture decisions remain Architect-owned; do not turn ord
47
47
 
48
48
  ## Artifact
49
49
 
50
+ Write brief and evidence candidates outside \`.ai/vcm\`. Submit updates with
51
+ \`.ai/tools/vcm-artifact architecture-brief --file <candidate> --mode draft|final\`
52
+ and \`.ai/tools/vcm-artifact architecture-evidence --file <candidate> --mode draft|final\`.
53
+ Use final only for confirmed brief and complete evidence.
54
+
50
55
  Maintain exactly this structure:
51
56
 
52
57
  \`\`\`md
@@ -6,17 +6,18 @@ Use this skill when Architect, Coder, or Reviewer must establish symbol definiti
6
6
  ## Navigation Order
7
7
 
8
8
  1. Define the affected feature or module boundary and locate entry symbols with \`.ai/generated/module-index.json\` and \`.ai/generated/public-surface.json\` when available.
9
- 2. Use LSP workspace or file symbols, definitions, implementations, references, and incoming or outgoing call hierarchy to resolve project-owned relationships.
10
- 3. Read the complete project-owned callable unit at every resolved location.
11
- 4. Expand one project-owned dependency hop at a time until the required behavior path has no unresolved symbol.
12
- 5. Use Glob, generated context, architecture documents, and runtime evidence to locate dynamic registrations, configuration or string edges, macros, documentation, and external boundaries that LSP does not model.
9
+ 2. Start each navigation run with LSP \`documentSymbol\` on a known affected project source file. This initializes the actual role-session language server and proves that it can parse that file; an executable version probe is not workspace readiness.
10
+ 3. Use LSP workspace or file symbols, definitions, implementations, references, and incoming or outgoing call hierarchy to resolve project-owned relationships.
11
+ 4. If an initial workspace-symbol request is empty or reports indexing, do not conclude that the symbol is absent. After a successful file-symbol request, retry the same bounded workspace query at most two more times. If it still cannot resolve, record the operation and result as unresolved.
12
+ 5. Read the complete project-owned callable unit at every resolved location.
13
+ 6. Expand one project-owned dependency hop at a time until the required behavior path has no unresolved symbol.
14
+ 7. Use Glob, generated context, architecture documents, and runtime evidence to locate dynamic registrations, configuration or string edges, macros, documentation, and external boundaries that LSP does not model.
13
15
 
14
16
  ## Evidence
15
17
 
16
18
  - Record each resolved relationship and whether it came from LSP, runtime evidence, an external boundary, or a generated boundary.
17
19
  - When an empty LSP result contradicts a direct call in the code, another LSP result, or runtime evidence, treat the relationship as unresolved. Record the contradiction and use exact fallback evidence.
18
- - If LSP is unavailable or cannot resolve a required project-owned relationship, record that limitation and leave the relationship unresolved. Do not substitute text search for semantic navigation.
19
- - Do not use the Grep tool or shell text-search commands such as \`grep\`, \`rg\`, or \`git grep\`.
20
+ - If LSP is unavailable or cannot resolve a required project-owned relationship, record that limitation and leave the relationship unresolved.
20
21
  - Generated indexes and architecture docs locate likely code; reading current-worktree implementation establishes behavior.
21
22
 
22
23
  ## Context Boundary