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.
- package/README.md +25 -12
- package/dist/backend/adapters/git-adapter.js +21 -0
- package/dist/backend/api/gate-review-routes.js +5 -0
- package/dist/backend/services/auto-memory-service.js +115 -81
- package/dist/backend/services/ccr-integration-service.js +2 -1
- package/dist/backend/services/claude-hook-service.js +11 -0
- package/dist/backend/services/gate-review-service.js +354 -107
- package/dist/backend/services/harness-feedback-service.js +6 -3
- package/dist/backend/services/session-service.js +42 -52
- package/dist/backend/templates/handoff.js +17 -0
- package/dist/backend/templates/harness/architect-agent.js +5 -2
- package/dist/backend/templates/harness/claude-root.js +8 -0
- package/dist/backend/templates/harness/coder-agent.js +1 -1
- package/dist/backend/templates/harness/gate-review.js +2 -0
- package/dist/backend/templates/harness/harness-engineer-agent.js +14 -9
- package/dist/backend/templates/harness/tester-agent.js +1 -1
- package/dist/backend/templates/harness/vcm-final-acceptance-skill.js +2 -0
- package/dist/backend/templates/harness/vcm-long-running-validation-skill.js +3 -1
- package/dist/backend/templates/harness/vcm-route-message-skill.js +1 -1
- package/dist/shared/types/session.js +1 -0
- package/dist-frontend/assets/index-DN9kwoOt.css +32 -0
- package/dist-frontend/assets/{index-Cmr9W7-n.js → index-DhLRhgSV.js} +35 -35
- package/dist-frontend/index.html +2 -2
- package/package.json +1 -1
- package/scripts/harness-tools/vcm-bash-guard +62 -8
- package/dist/backend/services/memory-review-validation.js +0 -286
- 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
|
-
"
|
|
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
|
|
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(
|
|
35
|
-
return (await readHarnessRevisionState(deps.fs,
|
|
34
|
+
async function readCurrentHarnessRevision(harnessRepoRoot) {
|
|
35
|
+
return (await readHarnessRevisionState(deps.fs, harnessRepoRoot)).revision;
|
|
36
36
|
}
|
|
37
|
-
async function withHarnessRevisionView(
|
|
38
|
-
const currentRevision = await readCurrentHarnessRevision(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
280
|
+
return withHarnessRevisionView(taskContext.taskRepoRoot, migrated);
|
|
281
281
|
}
|
|
282
|
-
return withHarnessRevisionView(
|
|
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(
|
|
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(
|
|
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(
|
|
395
|
+
return withHarnessRevisionView(taskContext.taskRepoRoot, migrated);
|
|
396
396
|
}
|
|
397
|
-
return withHarnessRevisionView(
|
|
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
|
|
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(
|
|
633
|
+
const currentRevision = await readCurrentHarnessRevision(harnessRepoRoot);
|
|
634
634
|
const timestamp = now();
|
|
635
635
|
await submitTerminalInput(deps.runtime, session.id, buildHarnessRefreshPrompt(session.role));
|
|
636
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
49
|
-
|
|
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
|
|
56
|
-
|
|
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
|
|
96
|
-
|
|
97
|
-
|
|
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
|
|
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
|
|
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
|
}
|