vibe-coding-master 0.7.33 → 0.7.35

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 (27) hide show
  1. package/README.md +25 -12
  2. package/dist/backend/adapters/git-adapter.js +21 -0
  3. package/dist/backend/api/gate-review-routes.js +5 -0
  4. package/dist/backend/services/auto-memory-service.js +115 -81
  5. package/dist/backend/services/ccr-integration-service.js +2 -1
  6. package/dist/backend/services/claude-hook-service.js +11 -0
  7. package/dist/backend/services/gate-review-service.js +354 -107
  8. package/dist/backend/services/harness-feedback-service.js +6 -3
  9. package/dist/backend/services/session-service.js +42 -52
  10. package/dist/backend/templates/handoff.js +17 -0
  11. package/dist/backend/templates/harness/architect-agent.js +5 -2
  12. package/dist/backend/templates/harness/claude-root.js +8 -0
  13. package/dist/backend/templates/harness/coder-agent.js +1 -1
  14. package/dist/backend/templates/harness/gate-review.js +2 -0
  15. package/dist/backend/templates/harness/harness-engineer-agent.js +14 -9
  16. package/dist/backend/templates/harness/tester-agent.js +1 -1
  17. package/dist/backend/templates/harness/vcm-final-acceptance-skill.js +2 -0
  18. package/dist/backend/templates/harness/vcm-long-running-validation-skill.js +3 -1
  19. package/dist/backend/templates/harness/vcm-route-message-skill.js +1 -1
  20. package/dist/shared/types/session.js +1 -0
  21. package/dist-frontend/assets/index-DN9kwoOt.css +32 -0
  22. package/dist-frontend/assets/{index-Cmr9W7-n.js → index-DhLRhgSV.js} +35 -35
  23. package/dist-frontend/index.html +2 -2
  24. package/package.json +1 -1
  25. package/scripts/harness-tools/vcm-bash-guard +62 -8
  26. package/dist/backend/services/memory-review-validation.js +0 -286
  27. package/dist-frontend/assets/index-CguKU8Q5.css +0 -32
@@ -250,13 +250,14 @@ export function createHarnessFeedbackService(deps) {
250
250
  "Auto Memory Review:",
251
251
  `Role drafts: ${memoryReview.roleDraftsPath}`,
252
252
  `Current memory snapshot: ${memoryReview.currentMemoryPath}`,
253
+ "Active memory files:",
254
+ ...memoryReview.activeMemoryPaths.map((memoryPath) => `- ${memoryPath}`),
253
255
  ...(memoryReview.planningCandidatePath
254
256
  ? [`Architect planning-session candidate: ${memoryReview.planningCandidatePath}`]
255
257
  : []),
256
- `Write the complete reviewed memory set to: ${memoryReview.reviewedMemoryPath}`,
257
258
  "",
258
259
  "Review every memory candidate against final task evidence while performing this retrospective.",
259
- "Each snapshot file contains only the matching <VCM-memory> block content. Edit every existing reviewed-memory file in place.",
260
+ "The snapshot files contain only the matching pre-review <VCM-memory> block content.",
260
261
  "Before evaluating proposals, review every substantive entry in every current memory snapshot against current code, documentation, and final task evidence.",
261
262
  "For each existing entry, decide retain, update, remove, or move-to-durable-doc. Record the decision reason, the impact of removing it, and whether memory or a durable document is the correct source.",
262
263
  "Complete this full existing-memory review even when every proposal says no-change.",
@@ -265,12 +266,14 @@ export function createHarnessFeedbackService(deps) {
265
266
  "Do not copy the proposer rationale as the review. Verify it against current code, durable documentation, and final task evidence.",
266
267
  "Keep only verified, durable, reusable project knowledge. Merge duplicates and keep role-specific knowledge in the matching role file.",
267
268
  "Do not record task narrative, temporary state, unverified conclusions, or Harness rules in memory.",
268
- "Final content must be one exact line written to the selected reviewed-memory file. Use none when the decision does not keep memory.",
269
+ "Final content must be one exact line written to the selected active <VCM-memory> block. Use none when the decision does not keep memory.",
269
270
  "For keep-in-memory use Durable doc disposition: memory. For keep-memory-reference use memory-reference. For move-to-durable-doc use durable-doc.",
270
271
  "Existing-memory Target must be shared or the exact role name. Decision must be retain, update, remove, or move-to-durable-doc.",
271
272
  "Durable doc disposition must be memory, durable-doc, or memory-reference. Use Durable doc path: none with memory and an actual path with the other dispositions.",
272
273
  "Do not keep full content in memory when durable-doc is correct. Use memory-reference only when an ongoing role needs the document pointer.",
273
274
  "Use none as the complete Existing Memory Decisions body only when no substantive existing memory entry exists.",
275
+ "Apply the reviewed result directly to the <VCM-memory> blocks in the listed active memory files. Do not change any content outside those blocks.",
276
+ "If memory changes, commit only the changed active memory files before ending the turn. Use commit message: chore: update VCM memory. If memory is unchanged, do not create a commit.",
274
277
  "Use this exact block in the retrospective report and replace each option or placeholder with one allowed value or a concise summary:",
275
278
  "",
276
279
  "## Memory Review",
@@ -31,11 +31,11 @@ const SESSION_READY_MAX_POLLS = 60;
31
31
  export function createSessionService(deps) {
32
32
  const now = deps.now ?? (() => new Date().toISOString());
33
33
  const isProcessAlive = deps.isProcessAlive ?? defaultIsProcessAlive;
34
- async function readCurrentHarnessRevision(repoRoot) {
35
- return (await readHarnessRevisionState(deps.fs, repoRoot)).revision;
34
+ async function readCurrentHarnessRevision(harnessRepoRoot) {
35
+ return (await readHarnessRevisionState(deps.fs, harnessRepoRoot)).revision;
36
36
  }
37
- async function withHarnessRevisionView(repoRoot, record) {
38
- const currentRevision = await readCurrentHarnessRevision(repoRoot);
37
+ async function withHarnessRevisionView(harnessRepoRoot, record) {
38
+ const currentRevision = await readCurrentHarnessRevision(harnessRepoRoot);
39
39
  const sessionRevision = normalizeHarnessRevision(record.harnessRevision);
40
40
  return {
41
41
  ...record,
@@ -45,13 +45,13 @@ export function createSessionService(deps) {
45
45
  };
46
46
  }
47
47
  async function launchRoleSession(repoRoot, taskSlug, role, input, launchMode) {
48
- const live = toRoleSessionRecordView(getRegisteredRoleSession(deps.registry, deps.runtime, taskSlug, role), deps.runtime);
49
- if (live && live.status === "running") {
50
- return withHarnessRevisionView(repoRoot, live);
51
- }
52
48
  const config = await deps.projectService.loadConfig(repoRoot);
53
49
  const task = await deps.taskService.loadTask(repoRoot, taskSlug);
54
50
  const taskRepoRoot = getTaskRuntimeRepoRoot(task);
51
+ const live = toRoleSessionRecordView(getRegisteredRoleSession(deps.registry, deps.runtime, taskSlug, role), deps.runtime);
52
+ if (live && live.status === "running") {
53
+ return withHarnessRevisionView(taskRepoRoot, live);
54
+ }
55
55
  const paths = deps.artifactService.getHandoffPaths(taskRepoRoot, task.handoffDir);
56
56
  const persisted = await loadPersistedRoleRecordForRole(deps.fs, repoRoot, taskRepoRoot, config.stateRoot, taskSlug, role);
57
57
  const permissionMode = normalizeClaudePermissionMode(input.permissionMode ?? persisted?.permissionMode);
@@ -106,7 +106,7 @@ export function createSessionService(deps) {
106
106
  rows: input.rows
107
107
  });
108
108
  const timestamp = now();
109
- const harnessRevision = await readCurrentHarnessRevision(repoRoot);
109
+ const harnessRevision = await readCurrentHarnessRevision(taskRepoRoot);
110
110
  const record = {
111
111
  id: runtimeSession.id,
112
112
  runtimeSessionToken,
@@ -139,7 +139,7 @@ export function createSessionService(deps) {
139
139
  if (role === "project-manager") {
140
140
  await restoreProjectManagerWorkflowContext(record, taskRepoRoot, config.stateRoot);
141
141
  }
142
- return withHarnessRevisionView(repoRoot, record);
142
+ return withHarnessRevisionView(taskRepoRoot, record);
143
143
  }
144
144
  async function restoreProjectManagerWorkflowContext(record, taskRepoRoot, stateRoot) {
145
145
  if (!deps.taskWorkflowService || record.status !== "running") {
@@ -165,7 +165,7 @@ export function createSessionService(deps) {
165
165
  const taskContext = await resolveProjectToolTaskContext(repoRoot, input, "Translator");
166
166
  const live = toRoleSessionRecordView(getRegisteredProjectTranslatorSession(deps.registry, deps.runtime), deps.runtime);
167
167
  if (live && live.status === "running") {
168
- return withHarnessRevisionView(repoRoot, await migrateRunningProjectToolSessionCwd(repoRoot, live, taskContext.taskRepoRoot));
168
+ return withHarnessRevisionView(taskContext.taskRepoRoot, await migrateRunningProjectToolSessionCwd(repoRoot, live, taskContext.taskRepoRoot));
169
169
  }
170
170
  const config = await deps.projectService.loadConfig(repoRoot);
171
171
  const persisted = await loadPersistedTranslatorSession(deps.fs, repoRoot);
@@ -236,7 +236,7 @@ export function createSessionService(deps) {
236
236
  rows: input.rows
237
237
  });
238
238
  const timestamp = now();
239
- const harnessRevision = await readCurrentHarnessRevision(repoRoot);
239
+ const harnessRevision = await readCurrentHarnessRevision(taskContext.taskRepoRoot);
240
240
  const record = {
241
241
  id: runtimeSession.id,
242
242
  runtimeSessionToken,
@@ -277,15 +277,15 @@ export function createSessionService(deps) {
277
277
  await clearPersistedTranslatorSession(deps.fs, repoRoot);
278
278
  return launchProjectTranslatorSession(repoRoot, input, "fresh");
279
279
  }
280
- return withHarnessRevisionView(repoRoot, migrated);
280
+ return withHarnessRevisionView(taskContext.taskRepoRoot, migrated);
281
281
  }
282
- return withHarnessRevisionView(repoRoot, await migrateRunningProjectToolSessionCwd(repoRoot, record, taskContext.taskRepoRoot));
282
+ return withHarnessRevisionView(taskContext.taskRepoRoot, await migrateRunningProjectToolSessionCwd(repoRoot, record, taskContext.taskRepoRoot));
283
283
  }
284
284
  async function launchProjectHarnessEngineerSession(repoRoot, input, launchMode) {
285
285
  const taskContext = await resolveProjectToolTaskContext(repoRoot, input, "Harness Engineer");
286
286
  const live = toRoleSessionRecordView(getRegisteredProjectHarnessEngineerSession(deps.registry, deps.runtime), deps.runtime);
287
287
  if (live && live.status === "running") {
288
- return withHarnessRevisionView(repoRoot, await migrateRunningProjectToolSessionCwd(repoRoot, live, taskContext.taskRepoRoot));
288
+ return withHarnessRevisionView(taskContext.taskRepoRoot, await migrateRunningProjectToolSessionCwd(repoRoot, live, taskContext.taskRepoRoot));
289
289
  }
290
290
  const config = await deps.projectService.loadConfig(repoRoot);
291
291
  const persisted = await loadPersistedHarnessEngineerSession(deps.fs, repoRoot);
@@ -352,7 +352,7 @@ export function createSessionService(deps) {
352
352
  rows: input.rows
353
353
  });
354
354
  const timestamp = now();
355
- const harnessRevision = await readCurrentHarnessRevision(repoRoot);
355
+ const harnessRevision = await readCurrentHarnessRevision(taskContext.taskRepoRoot);
356
356
  const record = {
357
357
  id: runtimeSession.id,
358
358
  runtimeSessionToken,
@@ -392,9 +392,9 @@ export function createSessionService(deps) {
392
392
  await clearPersistedHarnessEngineerSession(deps.fs, repoRoot);
393
393
  return launchProjectHarnessEngineerSession(repoRoot, input, "fresh");
394
394
  }
395
- return withHarnessRevisionView(repoRoot, migrated);
395
+ return withHarnessRevisionView(taskContext.taskRepoRoot, migrated);
396
396
  }
397
- return withHarnessRevisionView(repoRoot, await migrateRunningProjectToolSessionCwd(repoRoot, record, taskContext.taskRepoRoot));
397
+ return withHarnessRevisionView(taskContext.taskRepoRoot, await migrateRunningProjectToolSessionCwd(repoRoot, record, taskContext.taskRepoRoot));
398
398
  }
399
399
  async function resolveProjectToolTaskContext(repoRoot, input, roleLabel) {
400
400
  const taskSlug = input.taskSlug?.trim();
@@ -620,7 +620,7 @@ export function createSessionService(deps) {
620
620
  await persistHarnessEngineerSession(deps.fs, repoRoot, session);
621
621
  }
622
622
  }
623
- async function notifyHarnessUpdatedForSession(repoRoot, session) {
623
+ async function buildHarnessUpdatedSession(harnessRepoRoot, session) {
624
624
  const runtimeSession = deps.runtime.getSession(session.id);
625
625
  if (!runtimeSession || runtimeSession.status !== "running") {
626
626
  throw new VcmError({
@@ -630,10 +630,10 @@ export function createSessionService(deps) {
630
630
  hint: "Resume or restart the role to load the latest harness settings."
631
631
  });
632
632
  }
633
- const currentRevision = await readCurrentHarnessRevision(repoRoot);
633
+ const currentRevision = await readCurrentHarnessRevision(harnessRepoRoot);
634
634
  const timestamp = now();
635
635
  await submitTerminalInput(deps.runtime, session.id, buildHarnessRefreshPrompt(session.role));
636
- const updated = {
636
+ return {
637
637
  ...session,
638
638
  harnessRevision: currentRevision,
639
639
  harnessCurrentRevision: currentRevision,
@@ -641,28 +641,6 @@ export function createSessionService(deps) {
641
641
  lastHarnessNotifyAt: timestamp,
642
642
  updatedAt: timestamp
643
643
  };
644
- deps.registry.upsert(normalizeProjectScopedRecordForPersistence(updated));
645
- await persistNotifiedHarnessSession(repoRoot, updated);
646
- return withHarnessRevisionView(repoRoot, updated);
647
- }
648
- async function persistNotifiedHarnessSession(repoRoot, session) {
649
- if (session.role === TRANSLATOR_ROLE) {
650
- await persistTranslatorSession(deps.fs, repoRoot, {
651
- ...session,
652
- taskSlug: PROJECT_TRANSLATOR_SCOPE
653
- });
654
- return;
655
- }
656
- if (session.role === HARNESS_ENGINEER_ROLE) {
657
- await persistHarnessEngineerSession(deps.fs, repoRoot, {
658
- ...session,
659
- taskSlug: PROJECT_HARNESS_ENGINEER_SCOPE
660
- });
661
- return;
662
- }
663
- const config = await deps.projectService.loadConfig(repoRoot);
664
- const task = await deps.taskService.loadTask(repoRoot, session.taskSlug);
665
- await persistRoleSessionRecord(deps.fs, repoRoot, getTaskRuntimeRepoRoot(task), config.stateRoot, session);
666
644
  }
667
645
  async function getProjectToolSessionView(repoRoot, role) {
668
646
  const record = role === TRANSLATOR_ROLE
@@ -671,7 +649,7 @@ export function createSessionService(deps) {
671
649
  : getRegisteredProjectHarnessEngineerSession(deps.registry, deps.runtime)
672
650
  ?? await loadPersistedHarnessEngineerSession(deps.fs, repoRoot);
673
651
  const view = toRoleSessionRecordView(record, deps.runtime);
674
- return view ? withHarnessRevisionView(repoRoot, view) : undefined;
652
+ return view ? withHarnessRevisionView(view.cwd, view) : undefined;
675
653
  }
676
654
  async function markProjectToolActivityIdle(repoRoot, current, persist) {
677
655
  const timestamp = now();
@@ -692,7 +670,7 @@ export function createSessionService(deps) {
692
670
  const record = getRegisteredRoleSession(deps.registry, deps.runtime, taskSlug, role)
693
671
  ?? await loadPersistedRoleRecordForRole(deps.fs, repoRoot, taskRepoRoot, config.stateRoot, taskSlug, role);
694
672
  const view = toRoleSessionRecordView(record, deps.runtime);
695
- return view ? withHarnessRevisionView(repoRoot, view) : undefined;
673
+ return view ? withHarnessRevisionView(taskRepoRoot, view) : undefined;
696
674
  }
697
675
  async function markTaskRoleActivityIdle(repoRoot, taskSlug, role, expectedSessionId) {
698
676
  const current = await getTaskRoleSessionView(repoRoot, taskSlug, role);
@@ -816,7 +794,7 @@ export function createSessionService(deps) {
816
794
  const record = getRegisteredProjectTranslatorSession(deps.registry, deps.runtime)
817
795
  ?? await loadPersistedTranslatorSession(deps.fs, repoRoot);
818
796
  const view = toRoleSessionRecordView(record, deps.runtime);
819
- return view ? withHarnessRevisionView(repoRoot, view) : undefined;
797
+ return view ? withHarnessRevisionView(view.cwd, view) : undefined;
820
798
  },
821
799
  async ensureProjectTranslatorSession(repoRoot, input = {}) {
822
800
  const existing = await this.getProjectTranslatorSession(repoRoot);
@@ -878,7 +856,10 @@ export function createSessionService(deps) {
878
856
  statusCode: 404
879
857
  });
880
858
  }
881
- return notifyHarnessUpdatedForSession(repoRoot, current);
859
+ const updated = await buildHarnessUpdatedSession(current.cwd, current);
860
+ deps.registry.upsert(normalizeProjectScopedRecordForPersistence(updated));
861
+ await persistTranslatorSession(deps.fs, repoRoot, updated);
862
+ return withHarnessRevisionView(current.cwd, updated);
882
863
  },
883
864
  startProjectHarnessEngineerSession(repoRoot, input = {}) {
884
865
  return launchProjectHarnessEngineerSession(repoRoot, input, "fresh");
@@ -942,7 +923,7 @@ export function createSessionService(deps) {
942
923
  const record = getRegisteredProjectHarnessEngineerSession(deps.registry, deps.runtime)
943
924
  ?? await loadPersistedHarnessEngineerSession(deps.fs, repoRoot);
944
925
  const view = toRoleSessionRecordView(record, deps.runtime);
945
- return view ? withHarnessRevisionView(repoRoot, view) : undefined;
926
+ return view ? withHarnessRevisionView(view.cwd, view) : undefined;
946
927
  },
947
928
  async ensureProjectHarnessEngineerSession(repoRoot, input = {}) {
948
929
  const existing = await this.getProjectHarnessEngineerSession(repoRoot);
@@ -1004,7 +985,10 @@ export function createSessionService(deps) {
1004
985
  statusCode: 404
1005
986
  });
1006
987
  }
1007
- return notifyHarnessUpdatedForSession(repoRoot, current);
988
+ const updated = await buildHarnessUpdatedSession(current.cwd, current);
989
+ deps.registry.upsert(normalizeProjectScopedRecordForPersistence(updated));
990
+ await persistHarnessEngineerSession(deps.fs, repoRoot, updated);
991
+ return withHarnessRevisionView(current.cwd, updated);
1008
992
  },
1009
993
  startRoleSession(repoRoot, taskSlug, role, input = {}) {
1010
994
  return launchRoleSession(repoRoot, taskSlug, role, input, "fresh");
@@ -1061,7 +1045,7 @@ export function createSessionService(deps) {
1061
1045
  return undefined;
1062
1046
  }
1063
1047
  const view = toRoleSessionRecordView(record, deps.runtime);
1064
- return view ? withHarnessRevisionView(repoRoot, view) : undefined;
1048
+ return view ? withHarnessRevisionView(taskRepoRoot, view) : undefined;
1065
1049
  },
1066
1050
  async listRoleSessions(repoRoot, taskSlug) {
1067
1051
  const sessions = [];
@@ -1077,7 +1061,7 @@ export function createSessionService(deps) {
1077
1061
  sessions.push(session);
1078
1062
  }
1079
1063
  }
1080
- return Promise.all(sessions.map((session) => withHarnessRevisionView(repoRoot, session)));
1064
+ return Promise.all(sessions.map((session) => withHarnessRevisionView(taskRepoRoot, session)));
1081
1065
  },
1082
1066
  async notifyRoleHarnessUpdated(repoRoot, taskSlug, role) {
1083
1067
  const current = await this.getRoleSession(repoRoot, taskSlug, role);
@@ -1088,7 +1072,13 @@ export function createSessionService(deps) {
1088
1072
  statusCode: 404
1089
1073
  });
1090
1074
  }
1091
- return notifyHarnessUpdatedForSession(repoRoot, current);
1075
+ const config = await deps.projectService.loadConfig(repoRoot);
1076
+ const task = await deps.taskService.loadTask(repoRoot, taskSlug);
1077
+ const taskRepoRoot = getTaskRuntimeRepoRoot(task);
1078
+ const updated = await buildHarnessUpdatedSession(taskRepoRoot, current);
1079
+ deps.registry.upsert(updated);
1080
+ await persistRoleSessionRecord(deps.fs, repoRoot, taskRepoRoot, config.stateRoot, updated);
1081
+ return withHarnessRevisionView(taskRepoRoot, updated);
1092
1082
  },
1093
1083
  async recordRoleHookEvent(repoRoot, input) {
1094
1084
  const current = await this.getRoleSession(repoRoot, input.taskSlug, input.role);
@@ -1,7 +1,10 @@
1
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";
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. -->";
2
3
  export function renderArchitectureBriefTemplate(taskSlug) {
3
4
  return `# Architecture Brief: ${taskSlug}
4
5
 
6
+ ${CURRENT_HANDOFF_NOTICE}
7
+
5
8
  Architecture Brief Status: ${renderArtifactOptions(ARCHITECTURE_BRIEF_STATUSES)}
6
9
 
7
10
  ## Accepted Outcome
@@ -28,6 +31,8 @@ TBD
28
31
  export function renderArchitecturePlanTemplate(taskSlug) {
29
32
  return `# Architecture Plan: ${taskSlug}
30
33
 
34
+ ${CURRENT_HANDOFF_NOTICE}
35
+
31
36
  Planning Result: ${renderArtifactOptions(ARCHITECTURE_PLAN_RESULTS)}
32
37
 
33
38
  ## Accepted Scope
@@ -135,6 +140,8 @@ TBD
135
140
  export function renderKnownIssuesTemplate(taskSlug) {
136
141
  return `# Known Issues: ${taskSlug}
137
142
 
143
+ ${CURRENT_HANDOFF_NOTICE}
144
+
138
145
  ## Task Issues
139
146
 
140
147
  No unresolved task issues recorded yet.
@@ -147,6 +154,8 @@ At task close, promote still-relevant confirmed issues to \`docs/known-issues.md
147
154
  export function renderTestReportTemplate(taskSlug) {
148
155
  return `# Test Report: ${taskSlug}
149
156
 
157
+ ${CURRENT_HANDOFF_NOTICE}
158
+
150
159
  Test Result: ${renderArtifactOptions(TEST_RESULTS)}
151
160
 
152
161
  ## Evidence Reviewed
@@ -249,6 +258,8 @@ ${STRICT_NONE_VALUE}
249
258
  export function renderCoderCompletionTemplate(taskSlug) {
250
259
  return `# Coder Completion: ${taskSlug}
251
260
 
261
+ ${CURRENT_HANDOFF_NOTICE}
262
+
252
263
  Decision: ready_for_review|incomplete|failed
253
264
 
254
265
  ## Scaffold Completion
@@ -293,6 +304,8 @@ TBD
293
304
  export function renderArchitectDebugTemplate(taskSlug) {
294
305
  return `# Architect Debug: ${taskSlug}
295
306
 
307
+ ${CURRENT_HANDOFF_NOTICE}
308
+
296
309
  Status: pending|completed
297
310
 
298
311
  ## PM-Routed Failure
@@ -342,6 +355,8 @@ TBD
342
355
  export function renderDocsSyncReportTemplate(taskSlug) {
343
356
  return `# Docs Sync Report: ${taskSlug}
344
357
 
358
+ ${CURRENT_HANDOFF_NOTICE}
359
+
345
360
  ## Summary
346
361
 
347
362
  TBD
@@ -378,6 +393,8 @@ ${renderArtifactOptions(DOCS_SYNC_DECISIONS)}
378
393
  export function renderFinalAcceptanceTemplate(taskSlug) {
379
394
  return `# Final Acceptance: ${taskSlug}
380
395
 
396
+ ${CURRENT_HANDOFF_NOTICE}
397
+
381
398
  ## Decision
382
399
 
383
400
  ${renderArtifactOptions(FINAL_ACCEPTANCE_DECISIONS)}
@@ -74,7 +74,7 @@ ${renderRoleMemoryRules("architect")}
74
74
 
75
75
  - \`architecture-plan.md\` must start with \`Planning Result: complete|incomplete|user clarification required\` and use these sections: Accepted Scope, Current Code Reality, Existing Assumptions And Class Coverage, Architecture Decision, Module/File Plan, Public Surface Impact, Scaffold Manifest, Scaffold Build Evidence, Tester Coverage Hints, Docs Impact, Known Risks, and Coder Handoff Notes.
76
76
  - 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.
77
- - \`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.
77
+ - \`architecture-plan.md\` is the complete, self-contained current executable plan, not a changelog. Each revision must restate every still-current decision, constraint, evidence reference, scaffold row, risk, and implementation instruction needed to execute and review the plan without a prior revision. Replace superseded decisions, obsolete scaffold rows, stale risks, and old implementation notes instead of appending history.
78
78
  - \`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.
79
79
  - \`Current Code Reality\`: cite \`architecture-evidence.md\` and summarize only the verified facts that constrain the architecture decision. Do not duplicate the full evidence inventory. For any module whose build configuration the plan changes, the evidence artifact must quote its complete direct dependency list from the package manifest, never a summary or selection.
80
80
  - 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.
@@ -149,7 +149,7 @@ ${renderRoleMemoryRules("architect")}
149
149
  - Before handing off an architect-completed Debug Mode fix, run the smallest relevant L0 fast checks for the touched files or changed modules: format, lint, typecheck, boundary, dependency, or project-defined equivalents. If a check cannot run, report the exact reason.
150
150
  - If the Debug Mode fix changes module structure, source/test file lists, public APIs, routes, exports, re-exports, or other externally consumed surface, run \`.ai/tools/generate-module-index\` / \`.ai/tools/generate-public-surface\` or their \`--check\` mode as applicable.
151
151
  - After an architect-completed Debug Mode fix, report the completed result and evidence path to project-manager. Do not select the next route.
152
- - Before reporting a completed Debug Mode code fix, replace \`.ai/vcm/handoffs/architect-debug.md\` with current evidence. Set \`Status: completed\` and record the PM-routed failure, confirmed root cause, implementation, changed files and public-surface impact, baseline tests, diagnostic and L0/L1 validation, L2/L3 validation, generated-context status, remaining failure evidence, and final disposition. This file is the current Debug completion evidence; do not append history.
152
+ - Before reporting a completed Debug Mode code fix, replace \`.ai/vcm/handoffs/architect-debug.md\` with complete, self-contained current evidence. Set \`Status: completed\` and restate the PM-routed failure, confirmed root cause, implementation, changed files and public-surface impact, baseline tests, diagnostic and L0/L1 validation, L2/L3 validation, generated-context status, remaining failure evidence, and final disposition needed to review the result without a prior revision. Remove superseded evidence instead of appending history.
153
153
  - Final disposition must be one of: local fix completed, normal architecture plan required, or user clarification required.
154
154
  - Report root cause, changed files, scope and public-surface impact, L0/L1 results, applicable L2/L3 results, baseline tests added or skipped with reason, generated-context regeneration or freshness check when applicable, final disposition, and the Debug completion evidence path when code was changed.
155
155
 
@@ -219,6 +219,8 @@ Small diff, minimum change, localized fix, or preserving the current implementat
219
219
  9. \`Implementation And Validation\`
220
220
  10. \`Final Disposition\`
221
221
 
222
+ Each rewritten \`architecture-diagnosis.md\` must be a complete, self-contained current diagnosis and implementation result. Restate all still-relevant code-reading closure, evidence, architecture findings, changes, validation, and remaining failure evidence; do not refer to a prior round or superseded diagnosis as evidence.
223
+
222
224
  \`Implementation And Validation\` must use these subsections: \`Changed Files And Public Surface\`, \`Baseline Tests\`, \`Diagnostic And L0/L1 Validation\`, \`L2/L3 Validation\`, \`Generated Context\`, and \`Commit\`.
223
225
 
224
226
  \`L2/L3 Validation\` must use this table:
@@ -307,6 +309,7 @@ Small diff, minimum change, localized fix, or preserving the current implementat
307
309
  - Write \`.ai/vcm/handoffs/docs-sync-report.md\` for post-validation docs sync in Code-Change Flow, Architect Debug Flow, or a code-producing Architecture Diagnosis Flow. Do not write it for Docs-Only Flow or a Debug/Diagnosis Branch.
308
310
  - In Docs-Only Flow, the Architect role result must record the decision, changed documents, evidence reviewed, checks performed, and commit.
309
311
  - The report records decision, evidence reviewed, current-truth reconciliation, generated-context freshness, cross-document consistency, architecture docs, active plans, testing-doc consistency, known-issues disposition, durable-doc audit command and result, docs updated, docs left unchanged, remaining documentation risks, and handoff notes.
312
+ - Each rewritten \`docs-sync-report.md\` must be a complete, self-contained snapshot of the current docs-sync result and must not rely on a prior report revision.
310
313
  - \`Decision\` must be \`synced\`, \`unchanged\`, or \`blocked\`.
311
314
 
312
315
  ### Background Jobs
@@ -66,6 +66,14 @@ If a reusable harness problem is suspected, it is enough to record a concise fee
66
66
  - Runtime task records and handoffs under \`.ai/vcm/\` are temporary. Durable facts must move into code, tests, PR text, commit history, or long-term docs.
67
67
  - Only architect writes \`.ai/vcm/handoffs/known-issues.md\`; other roles report unresolved findings back through their own handoff artifacts.
68
68
 
69
+ ## VCM Current Handoff Contract
70
+
71
+ - A role-owned handoff under \`.ai/vcm/handoffs/\` is the complete current result for that artifact, not an append-only log or a pointer to an earlier revision.
72
+ - Whenever a handoff is rewritten, make the new revision self-contained: restate every still-relevant decision, evidence item, command, result, coverage mapping, finding, approval, and remaining action needed to interpret the current result without another round's artifact.
73
+ - Remove or replace superseded content. Do not use a prior round, prior report revision, consumed route message, role Session, or transcript as a substitute for evidence in the current handoff.
74
+ - A handoff may cite current code, durable docs, commits, preserved job output, or request-scoped Gate Review evidence that still exists at the cited path.
75
+ - Before routing an artifact reference, confirm the referenced handoff satisfies this contract.
76
+
69
77
  ## User Communication
70
78
 
71
79
  - A message without a VCM marker is user communication.
@@ -70,7 +70,7 @@ ${renderRoleMemoryRules("coder")}
70
70
 
71
71
  ### Handoff
72
72
 
73
- - 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.
73
+ - 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.
74
74
  - \`coder-completion.md\` must include \`Decision: ready_for_review | incomplete | failed\`.
75
75
  - \`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.
76
76
  - Use this structure:
@@ -8,6 +8,8 @@ ${renderRoleMemoryRules("reviewer")}
8
8
 
9
9
  Review only the gate in the VCM prompt. Use the task and worktree paths named there. Project memory may orient you, but only current worktree evidence can decide the gate.
10
10
 
11
+ When the VCM prompt maps a task-evidence path to an immutable request snapshot, review that snapshot as the handoff or prior-Gate input for this request. Do not substitute a later rewritten live handoff. Continue to inspect current code, tests, durable docs, generated context, and the named commit range wherever the gate requires current-worktree evidence.
12
+
11
13
  Use only these decisions:
12
14
 
13
15
  - \`approve\`: required gate evidence is present, current, internally consistent, sufficient for that gate, and has no gate-blocking finding.
@@ -39,21 +39,22 @@ You are not part of the task workflow round state.
39
39
  yourself.
40
40
  - Retrospective Mode: analyze a completed task for reusable harness problems.
41
41
  When the assigned prompt includes Auto Memory Review, also review the memory
42
- proposals and write only the reviewed-memory output files assigned by VCM.
42
+ proposals, update the active \`<VCM-memory>\` blocks, and commit those memory
43
+ changes yourself.
43
44
  - VCM Feedback Mode: draft VCM product, installer, UI, or fixed-template issue
44
45
  feedback. Do not submit without explicit in-session user authorization.
45
46
 
46
47
  ## Change Policy
47
48
 
48
- - Apply edits only in Bootstrap Apply Mode, to assigned reviewed-memory output
49
- files during Retrospective Mode, or when VCM explicitly asks you to apply an
50
- approved harness change.
49
+ - Apply edits only in Bootstrap Apply Mode, to active \`<VCM-memory>\` blocks
50
+ during an assigned Auto Memory Retrospective, or when VCM explicitly asks you
51
+ to apply an approved harness change.
51
52
  - When applying edits, work only in the active task worktree named by VCM. Do not
52
53
  edit the base repository root unless VCM explicitly says so.
53
54
  - In Proposal Mode, do not edit files.
54
55
  - In Retrospective Mode, write the assigned retrospective report and, only when
55
- Auto Memory Review is included in the prompt, the assigned reviewed-memory
56
- output files. After every assigned pending feedback has a recorded
56
+ Auto Memory Review is included in the prompt, directly update the assigned
57
+ active memory blocks. After every assigned pending feedback has a recorded
57
58
  disposition, delete those processed feedback files.
58
59
  - Commit every applied harness change yourself before ending your turn.
59
60
  - Do not overwrite VCM fixed managed blocks.
@@ -92,9 +93,13 @@ You are not part of the task workflow round state.
92
93
  assigned by VCM.
93
94
  - Do not record task narrative, temporary state, unverified conclusions, or
94
95
  Harness rules in memory.
95
- - Edit only the review output paths assigned by VCM. Do not edit active
96
- \`<VCM-memory>\` blocks directly. VCM applies the reviewed output, records the
97
- diff, and commits the changed host files.
96
+ - Edit only the \`<VCM-memory>\` blocks in the active memory files assigned by
97
+ VCM. Do not change surrounding role definitions, project context, or managed
98
+ Harness blocks during Auto Memory Review.
99
+ - If the reviewed memory changes, commit only the changed active memory files
100
+ with commit message \`chore: update VCM memory\` before ending the turn. If
101
+ memory is unchanged, do not create a commit. VCM records the committed result,
102
+ diff, and review history; it does not apply or commit the memory for you.
98
103
 
99
104
  ## Task Harness Retrospective
100
105
 
@@ -179,7 +179,7 @@ L3 Required: yes|no
179
179
  - When \`L3 Required: yes\`, include at least one complete flow-to-case mapping. \`Action\` must be \`run-existing\`, \`updated\`, or \`added\`.
180
180
  - When \`L3 Required: no\`, use \`Not-Required Evidence\` to prove every condition in the L3 not-required rule.
181
181
  - In every flow, if tests, fixtures, test-only helpers, or \`docs/TESTING.md\` changed, commit those changes before reporting a terminal result and record the changed files and commit in \`test-report.md\`. If no tracked files changed, record that no commit was required.
182
- - \`test-report.md\` is the current validation evidence, not a log; when rewriting it, carry forward still-unresolved findings or explicitly mark them resolved instead of dropping them.
182
+ - \`test-report.md\` is the complete, self-contained current validation evidence, not a log. Each revision must independently support its current \`Test Result\` by restating every still-relevant test or external check, coverage mapping, command and result, test-infrastructure fact, failed expectation, skipped check, gap, approval, blocking issue, and remaining validation needed to review that result without a prior revision. Remove superseded evidence, but never replace current evidence with “as recorded in the prior round”, a prior report reference, or a Session/transcript reference.
183
183
  - In \`Coverage Mapping\`, map each accepted changed behavior or relevant risk to its validation level, actual test file and case or external evidence, exercised entry path and key assertions, result, and any remaining gap.
184
184
  - In \`Validation Progress\`, record \`Completed Validation\` and \`Remaining Validation\`. A final \`pass\` report must set remaining validation to \`None\`.
185
185
  - Use \`pass\` only when required validation completed and no blocking test failure, missing required coverage, unacceptable test weakness, or unresolved validation risk remains.
@@ -123,6 +123,8 @@ accepted|accepted-with-known-risks|needs-coder-follow-up|needs-architect-follow-
123
123
  ## Final User Summary
124
124
  \`\`\`
125
125
 
126
+ Each rewrite must be a complete, self-contained snapshot of the current acceptance decision and supporting evidence. Restate every still-relevant evidence result, file classification, validation result, Gate decision, docs-sync result, known-issues disposition, cleanup result, risk, and next action; do not rely on a prior acceptance revision, route message, Session, or transcript.
127
+
126
128
  The final user summary should be concise and include files changed, validation, docs updates, open risks, and next action.
127
129
  `;
128
130
  }
@@ -7,12 +7,14 @@ Never run the Bash tool with \`run_in_background: true\`, and never detach a pro
7
7
 
8
8
  The only sanctioned long-running mechanism is \`.ai/tools/run-long-check\` plus \`.ai/tools/watch-job\` through this skill.
9
9
 
10
+ Each run-long-check or watch-job invocation must be the only top-level command in its Bash tool call. Do not pipe it, append or prepend another command, place it in a conditional chain or subshell, capture it with command substitution, or invoke it through a shell command string. Ordinary redirection is allowed. A directly passed script such as \`-- bash /tmp/check.sh\` is allowed; \`-- bash -c '...'\` is not.
11
+
10
12
  The hard ceiling is 60 minutes per job, enforced by the job worker itself. No approval can raise this ceiling; split larger operations into jobs that each fit within it.
11
13
 
12
14
  ## Protocol
13
15
 
14
16
  1. Start the command with an explicit ceiling: \`.ai/tools/run-long-check --timeout <duration> -- <command>\`. Pass the validation executable and its arguments directly. Do not use a shell command-string wrapper, pipeline its output, or append another command: run-long-check already captures stdout/stderr, and shell wrappers can hide the validation exit code. Pick the ceiling from \`docs/TESTING.md\` guidance or a realistic estimate, never above 60m. The tool prints the job id and creates job state under \`.ai/vcm/jobs/<job-id>/\`.
15
- 2. In the same turn, run \`.ai/tools/watch-job <job-id>\`. The default watch window is 8 minutes.
17
+ 2. In the same turn, run \`.ai/tools/watch-job <job-id>\` as its own Bash tool call. The default watch window is 8 minutes.
16
18
  3. If watch-job exits 125, the job is still running: run \`.ai/tools/watch-job <job-id>\` again immediately. Do not end the turn between windows.
17
19
  4. Repeat until watch-job reports a terminal result.
18
20
  5. Read the final status and the relevant log tail.
@@ -44,7 +44,7 @@ If the same route file already contains a not-yet-delivered message, update that
44
44
 
45
45
  ## Message Format
46
46
 
47
- Use the smallest body that is complete. Include artifact refs instead of copying long documents.
47
+ Use the smallest body that is complete. Include artifact refs instead of copying long documents. Reference a role handoff only after confirming its current revision is complete and self-contained; never use an artifact ref to stand in for evidence that exists only in a prior revision, consumed route message, Session, or transcript.
48
48
 
49
49
  For simple user relay, use a lightweight body instead of the formal dispatch format.
50
50
 
@@ -61,6 +61,7 @@ export const CCR_GATEWAY_BASE_URLS = [
61
61
  ];
62
62
  export const CCR_GPT_MODEL_ID = "Codex API/gpt-5.6-sol";
63
63
  export const CCR_GPT_SESSION_MODEL = `ccr:${CCR_GPT_MODEL_ID}`;
64
+ export const CCR_GPT_EFFECTIVE_CONTEXT_TOKENS = 258_400;
64
65
  export function isCcrSessionModel(model) {
65
66
  return model === CCR_GPT_SESSION_MODEL;
66
67
  }