vibe-coding-master 0.7.45 → 0.7.47
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 +3 -1
- package/dist/backend/cli/install-vcm-harness.js +38 -0
- package/dist/backend/services/codex-bridge-integration-service.js +3 -1
- package/dist/backend/services/harness-service.js +18 -0
- package/dist/backend/templates/harness/architect-agent.js +18 -2
- package/dist/backend/templates/harness/architect-evidence-worker-agent.js +44 -0
- package/dist/backend/templates/harness/architect-scaffold-worker-agent.js +3 -1
- package/dist/backend/templates/harness/architect-validation-worker-agent.js +36 -0
- package/dist/backend/templates/harness/coder-agent.js +1 -0
- package/dist/backend/templates/harness/vcm-route-message-skill.js +2 -2
- package/package.json +1 -1
- package/scripts/harness-tools/vcm-subagent-guard +66 -0
- package/scripts/verify-package.mjs +1 -0
package/README.md
CHANGED
|
@@ -284,7 +284,9 @@ from the native child process.
|
|
|
284
284
|
Codex Bridge child processes use a hard context limit and auto-compaction window of
|
|
285
285
|
`258400` tokens. VCM sets Claude Code's proactive compaction threshold to `90%`
|
|
286
286
|
(about `232560` tokens), leaving headroom before the Codex API limit. Native
|
|
287
|
-
Claude sessions receive no VCM-owned context override.
|
|
287
|
+
Claude sessions receive no VCM-owned context override. Bridge-backed subagents
|
|
288
|
+
inherit the selected GPT model. Native Architect evidence, scaffold, and
|
|
289
|
+
validation workers use `opus` with `xhigh` effort.
|
|
288
290
|
|
|
289
291
|
Resume keeps the provider recorded by the existing Session. Use Restart when
|
|
290
292
|
switching between native Claude and Codex Bridge. If the Bridge is disabled,
|
|
@@ -8,7 +8,9 @@ import { renderArchitectHarnessRules } from "../templates/harness/architect-agen
|
|
|
8
8
|
import { CODE_ROLE_DISALLOWED_TOOLS, REVIEWER_DISALLOWED_TOOLS } from "../role-tool-policy.js";
|
|
9
9
|
import { renderCoderHarnessRules } from "../templates/harness/coder-agent.js";
|
|
10
10
|
import { renderCoderWorkerHarnessRules } from "../templates/harness/coder-worker-agent.js";
|
|
11
|
+
import { renderArchitectEvidenceWorkerHarnessRules } from "../templates/harness/architect-evidence-worker-agent.js";
|
|
11
12
|
import { renderArchitectScaffoldWorkerHarnessRules } from "../templates/harness/architect-scaffold-worker-agent.js";
|
|
13
|
+
import { renderArchitectValidationWorkerHarnessRules } from "../templates/harness/architect-validation-worker-agent.js";
|
|
12
14
|
import { renderReviewerAgentRules, renderRequestGateReviewTool, renderTranslatorAgentRules, renderVcmGateReviewSkillRules } from "../templates/harness/gate-review.js";
|
|
13
15
|
import { renderHarnessEngineerHarnessRules } from "../templates/harness/harness-engineer-agent.js";
|
|
14
16
|
import { renderRootClaudeHarnessRules } from "../templates/harness/claude-root.js";
|
|
@@ -53,11 +55,13 @@ const VCM_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM
|
|
|
53
55
|
const VCM_STOP_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM_ROLE:-}" ] || [ -z "\${VCM_API_URL:-}" ]; then exit 0; fi; node -e '"'"'let s="";process.stdin.setEncoding("utf8");process.stdin.on("data",d=>s+=d);process.stdin.on("end",()=>{let event={};try{event=s.trim()?JSON.parse(s):{};}catch{event={raw:s};}process.stdout.write(JSON.stringify({taskSlug:process.env.VCM_TASK_SLUG,role:process.env.VCM_ROLE,runtimeSessionToken:process.env.VCM_RUNTIME_SESSION_TOKEN,event}));});'"'"' | curl -fsS --retry 2 --retry-delay 1 --retry-all-errors --connect-timeout 1 --max-time 2 -X POST "\${VCM_API_URL}/api/hooks/claude-code/stop" -H "content-type: application/json" --data-binary @- || true'`;
|
|
54
56
|
const VCM_PERMISSION_REQUEST_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM_ROLE:-}" ] || [ -z "\${VCM_API_URL:-}" ]; then exit 0; fi; node -e '"'"'let s="";process.stdin.setEncoding("utf8");process.stdin.on("data",d=>s+=d);process.stdin.on("end",()=>{let event={};try{event=s.trim()?JSON.parse(s):{};}catch{event={raw:s};}process.stdout.write(JSON.stringify({taskSlug:process.env.VCM_TASK_SLUG,role:process.env.VCM_ROLE,runtimeSessionToken:process.env.VCM_RUNTIME_SESSION_TOKEN,event}));});'"'"' | curl -fsS --max-time 5 -X POST "\${VCM_API_URL}/api/hooks/claude-code/permission-request" -H "content-type: application/json" --data-binary @- || true'`;
|
|
55
57
|
const VCM_BASH_GUARD_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM_ROLE:-}" ]; then exit 0; fi; guard=""; repo="$(git rev-parse --show-toplevel 2>/dev/null || true)"; if [ -n "$repo" ] && [ -f "$repo/.ai/tools/vcm-bash-guard" ]; then guard="$repo/.ai/tools/vcm-bash-guard"; else cwd="$(pwd -P 2>/dev/null || pwd)"; dir="$cwd"; while [ -n "$dir" ] && [ "$dir" != "/" ]; do if [ -f "$dir/.ai/tools/vcm-bash-guard" ]; then guard="$dir/.ai/tools/vcm-bash-guard"; break; fi; dir="$(dirname "$dir")"; done; if [ -z "$guard" ] && [ -n "\${CLAUDE_PROJECT_DIR:-}" ] && [ -f "\${CLAUDE_PROJECT_DIR}/.ai/tools/vcm-bash-guard" ]; then guard="\${CLAUDE_PROJECT_DIR}/.ai/tools/vcm-bash-guard"; fi; fi; [ -n "$guard" ] || exit 0; python3 "$guard" || exit 0'`;
|
|
58
|
+
const VCM_SUBAGENT_GUARD_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM_ROLE:-}" ]; then exit 0; fi; guard=""; repo="$(git rev-parse --show-toplevel 2>/dev/null || true)"; if [ -n "$repo" ] && [ -f "$repo/.ai/tools/vcm-subagent-guard" ]; then guard="$repo/.ai/tools/vcm-subagent-guard"; else cwd="$(pwd -P 2>/dev/null || pwd)"; dir="$cwd"; while [ -n "$dir" ] && [ "$dir" != "/" ]; do if [ -f "$dir/.ai/tools/vcm-subagent-guard" ]; then guard="$dir/.ai/tools/vcm-subagent-guard"; break; fi; dir="$(dirname "$dir")"; done; if [ -z "$guard" ] && [ -n "\${CLAUDE_PROJECT_DIR:-}" ] && [ -f "\${CLAUDE_PROJECT_DIR}/.ai/tools/vcm-subagent-guard" ]; then guard="\${CLAUDE_PROJECT_DIR}/.ai/tools/vcm-subagent-guard"; fi; fi; [ -n "$guard" ] || { printf "%s\\n" "{\\"hookSpecificOutput\\":{\\"hookEventName\\":\\"PreToolUse\\",\\"permissionDecision\\":\\"deny\\",\\"permissionDecisionReason\\":\\"VCM subagent policy is unavailable. Refresh the VCM Harness before invoking subagents.\\"}}"; exit 0; }; python3 "$guard"'`;
|
|
56
59
|
const VCM_BASH_DEFAULT_TIMEOUT_MS = "600000";
|
|
57
60
|
const VCM_AUTO_MEMORY_ENABLED = false;
|
|
58
61
|
const VCM_HOOK_DEFINITIONS = [
|
|
59
62
|
{ eventName: "PreToolUse", matcher: "Bash", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
|
|
60
63
|
{ eventName: "PreToolUse", matcher: "Write|Edit", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
|
|
64
|
+
{ eventName: "PreToolUse", matcher: "Agent", command: VCM_SUBAGENT_GUARD_HOOK_COMMAND, timeout: 10 },
|
|
61
65
|
{ eventName: "UserPromptSubmit", command: VCM_HOOK_COMMAND, timeout: 5 },
|
|
62
66
|
{ eventName: "PreToolUse", command: VCM_HOOK_COMMAND, timeout: 5 },
|
|
63
67
|
{ eventName: "PostToolUse", command: VCM_HOOK_COMMAND, timeout: 5 },
|
|
@@ -104,10 +108,22 @@ const AGENT_FRONTMATTER = {
|
|
|
104
108
|
description: "Bounded VCM implementation worker for assigned modules, files, and VCM:CODE markers from Coder.",
|
|
105
109
|
model: "inherit"
|
|
106
110
|
},
|
|
111
|
+
"vcm-architect-evidence-worker": {
|
|
112
|
+
description: "Foreground Architect worker for bounded project evidence collection.",
|
|
113
|
+
tools: "Read, Grep, Glob, Write",
|
|
114
|
+
model: "opus",
|
|
115
|
+
effort: "xhigh"
|
|
116
|
+
},
|
|
107
117
|
"vcm-architect-scaffold-worker": {
|
|
108
118
|
description: "Foreground Architect worker for exact scaffold execution and scaffold validation.",
|
|
109
119
|
model: "opus",
|
|
110
120
|
effort: "xhigh"
|
|
121
|
+
},
|
|
122
|
+
"vcm-architect-validation-worker": {
|
|
123
|
+
description: "Foreground Architect worker for exact assigned command execution and evidence capture.",
|
|
124
|
+
tools: "Read, Grep, Glob, Bash, Write",
|
|
125
|
+
model: "opus",
|
|
126
|
+
effort: "xhigh"
|
|
111
127
|
}
|
|
112
128
|
};
|
|
113
129
|
const REQUIRED_AGENT_DISALLOWED_TOOLS = {
|
|
@@ -240,6 +256,14 @@ const MANAGED_FILES = [
|
|
|
240
256
|
category: "agent-coder-worker",
|
|
241
257
|
content: renderCoderWorkerHarnessRules()
|
|
242
258
|
},
|
|
259
|
+
{
|
|
260
|
+
path: ".claude/agents/vcm-architect-evidence-worker.md",
|
|
261
|
+
title: "VCM Architect Evidence Worker Agent",
|
|
262
|
+
agentName: "vcm-architect-evidence-worker",
|
|
263
|
+
commentStyle: "html",
|
|
264
|
+
category: "agent-architect-evidence-worker",
|
|
265
|
+
content: renderArchitectEvidenceWorkerHarnessRules()
|
|
266
|
+
},
|
|
243
267
|
{
|
|
244
268
|
path: ".claude/agents/vcm-architect-scaffold-worker.md",
|
|
245
269
|
title: "VCM Architect Scaffold Worker Agent",
|
|
@@ -247,6 +271,14 @@ const MANAGED_FILES = [
|
|
|
247
271
|
commentStyle: "html",
|
|
248
272
|
category: "agent-architect-scaffold-worker",
|
|
249
273
|
content: renderArchitectScaffoldWorkerHarnessRules()
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
path: ".claude/agents/vcm-architect-validation-worker.md",
|
|
277
|
+
title: "VCM Architect Validation Worker Agent",
|
|
278
|
+
agentName: "vcm-architect-validation-worker",
|
|
279
|
+
commentStyle: "html",
|
|
280
|
+
category: "agent-architect-validation-worker",
|
|
281
|
+
content: renderArchitectValidationWorkerHarnessRules()
|
|
250
282
|
}
|
|
251
283
|
];
|
|
252
284
|
const DURABLE_DOC_TEMPLATES = [
|
|
@@ -416,6 +448,12 @@ const WHOLE_FILES = [
|
|
|
416
448
|
mode: 0o755,
|
|
417
449
|
templatePath: "scripts/harness-tools/vcm-bash-guard"
|
|
418
450
|
},
|
|
451
|
+
{
|
|
452
|
+
path: ".ai/tools/vcm-subagent-guard",
|
|
453
|
+
category: "runtime-tool",
|
|
454
|
+
mode: 0o755,
|
|
455
|
+
templatePath: "scripts/harness-tools/vcm-subagent-guard"
|
|
456
|
+
},
|
|
419
457
|
{
|
|
420
458
|
path: ".ai/tools/vcm-artifact",
|
|
421
459
|
category: "runtime-tool",
|
|
@@ -166,6 +166,7 @@ export function createCodexBridgeIntegrationService(deps) {
|
|
|
166
166
|
CODEX_BRIDGE_CLAUDE_MODEL: modelId,
|
|
167
167
|
ANTHROPIC_SMALL_FAST_MODEL: modelId,
|
|
168
168
|
CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY: "1",
|
|
169
|
+
CLAUDE_CODE_SUBAGENT_MODEL: modelId,
|
|
169
170
|
CLAUDE_CODE_MAX_CONTEXT_TOKENS: String(CODEX_BRIDGE_EFFECTIVE_CONTEXT_TOKENS),
|
|
170
171
|
CLAUDE_CODE_AUTO_COMPACT_WINDOW: String(CODEX_BRIDGE_AUTO_COMPACT_WINDOW_TOKENS),
|
|
171
172
|
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: String(CODEX_BRIDGE_AUTO_COMPACT_PERCENT),
|
|
@@ -191,7 +192,8 @@ const BRIDGE_BASE_URL_KEYS = [
|
|
|
191
192
|
];
|
|
192
193
|
const BRIDGE_MODEL_KEYS = [
|
|
193
194
|
"ANTHROPIC_MODEL",
|
|
194
|
-
"ANTHROPIC_SMALL_FAST_MODEL"
|
|
195
|
+
"ANTHROPIC_SMALL_FAST_MODEL",
|
|
196
|
+
"CLAUDE_CODE_SUBAGENT_MODEL"
|
|
195
197
|
];
|
|
196
198
|
const BRIDGE_ONLY_ENV_KEYS = [
|
|
197
199
|
"CODEX_BRIDGE_CLAUDE_MODEL",
|
|
@@ -5,7 +5,9 @@ import { renderArchitectHarnessRules } from "../templates/harness/architect-agen
|
|
|
5
5
|
import { CODE_ROLE_DISALLOWED_TOOLS, REVIEWER_DISALLOWED_TOOLS } from "../role-tool-policy.js";
|
|
6
6
|
import { renderCoderHarnessRules } from "../templates/harness/coder-agent.js";
|
|
7
7
|
import { renderCoderWorkerHarnessRules } from "../templates/harness/coder-worker-agent.js";
|
|
8
|
+
import { renderArchitectEvidenceWorkerHarnessRules } from "../templates/harness/architect-evidence-worker-agent.js";
|
|
8
9
|
import { renderArchitectScaffoldWorkerHarnessRules } from "../templates/harness/architect-scaffold-worker-agent.js";
|
|
10
|
+
import { renderArchitectValidationWorkerHarnessRules } from "../templates/harness/architect-validation-worker-agent.js";
|
|
9
11
|
import { renderReviewerAgentRules, renderRequestGateReviewTool, renderTranslatorAgentRules, renderVcmGateReviewSkillRules } from "../templates/harness/gate-review.js";
|
|
10
12
|
import { renderHarnessEngineerHarnessRules } from "../templates/harness/harness-engineer-agent.js";
|
|
11
13
|
import { renderRootClaudeHarnessRules } from "../templates/harness/claude-root.js";
|
|
@@ -53,11 +55,13 @@ const VCM_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM
|
|
|
53
55
|
const VCM_STOP_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM_ROLE:-}" ] || [ -z "\${VCM_API_URL:-}" ]; then exit 0; fi; node -e '"'"'let s="";process.stdin.setEncoding("utf8");process.stdin.on("data",d=>s+=d);process.stdin.on("end",()=>{let event={};try{event=s.trim()?JSON.parse(s):{};}catch{event={raw:s};}process.stdout.write(JSON.stringify({taskSlug:process.env.VCM_TASK_SLUG,role:process.env.VCM_ROLE,runtimeSessionToken:process.env.VCM_RUNTIME_SESSION_TOKEN,event}));});'"'"' | curl -fsS --retry 2 --retry-delay 1 --retry-all-errors --connect-timeout 1 --max-time 2 -X POST "\${VCM_API_URL}/api/hooks/claude-code/stop" -H "content-type: application/json" --data-binary @- || true'`;
|
|
54
56
|
const VCM_PERMISSION_REQUEST_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM_ROLE:-}" ] || [ -z "\${VCM_API_URL:-}" ]; then exit 0; fi; node -e '"'"'let s="";process.stdin.setEncoding("utf8");process.stdin.on("data",d=>s+=d);process.stdin.on("end",()=>{let event={};try{event=s.trim()?JSON.parse(s):{};}catch{event={raw:s};}process.stdout.write(JSON.stringify({taskSlug:process.env.VCM_TASK_SLUG,role:process.env.VCM_ROLE,runtimeSessionToken:process.env.VCM_RUNTIME_SESSION_TOKEN,event}));});'"'"' | curl -fsS --max-time 5 -X POST "\${VCM_API_URL}/api/hooks/claude-code/permission-request" -H "content-type: application/json" --data-binary @- || true'`;
|
|
55
57
|
const VCM_BASH_GUARD_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM_ROLE:-}" ]; then exit 0; fi; guard=""; repo="$(git rev-parse --show-toplevel 2>/dev/null || true)"; if [ -n "$repo" ] && [ -f "$repo/.ai/tools/vcm-bash-guard" ]; then guard="$repo/.ai/tools/vcm-bash-guard"; else cwd="$(pwd -P 2>/dev/null || pwd)"; dir="$cwd"; while [ -n "$dir" ] && [ "$dir" != "/" ]; do if [ -f "$dir/.ai/tools/vcm-bash-guard" ]; then guard="$dir/.ai/tools/vcm-bash-guard"; break; fi; dir="$(dirname "$dir")"; done; if [ -z "$guard" ] && [ -n "\${CLAUDE_PROJECT_DIR:-}" ] && [ -f "\${CLAUDE_PROJECT_DIR}/.ai/tools/vcm-bash-guard" ]; then guard="\${CLAUDE_PROJECT_DIR}/.ai/tools/vcm-bash-guard"; fi; fi; [ -n "$guard" ] || exit 0; python3 "$guard" || exit 0'`;
|
|
58
|
+
const VCM_SUBAGENT_GUARD_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM_ROLE:-}" ]; then exit 0; fi; guard=""; repo="$(git rev-parse --show-toplevel 2>/dev/null || true)"; if [ -n "$repo" ] && [ -f "$repo/.ai/tools/vcm-subagent-guard" ]; then guard="$repo/.ai/tools/vcm-subagent-guard"; else cwd="$(pwd -P 2>/dev/null || pwd)"; dir="$cwd"; while [ -n "$dir" ] && [ "$dir" != "/" ]; do if [ -f "$dir/.ai/tools/vcm-subagent-guard" ]; then guard="$dir/.ai/tools/vcm-subagent-guard"; break; fi; dir="$(dirname "$dir")"; done; if [ -z "$guard" ] && [ -n "\${CLAUDE_PROJECT_DIR:-}" ] && [ -f "\${CLAUDE_PROJECT_DIR}/.ai/tools/vcm-subagent-guard" ]; then guard="\${CLAUDE_PROJECT_DIR}/.ai/tools/vcm-subagent-guard"; fi; fi; [ -n "$guard" ] || { printf "%s\\n" "{\\"hookSpecificOutput\\":{\\"hookEventName\\":\\"PreToolUse\\",\\"permissionDecision\\":\\"deny\\",\\"permissionDecisionReason\\":\\"VCM subagent policy is unavailable. Refresh the VCM Harness before invoking subagents.\\"}}"; exit 0; }; python3 "$guard"'`;
|
|
56
59
|
const VCM_BASH_DEFAULT_TIMEOUT_MS = "600000";
|
|
57
60
|
const VCM_AUTO_MEMORY_ENABLED = false;
|
|
58
61
|
const VCM_HOOK_DEFINITIONS = [
|
|
59
62
|
{ eventName: "PreToolUse", matcher: "Bash", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
|
|
60
63
|
{ eventName: "PreToolUse", matcher: "Write|Edit", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
|
|
64
|
+
{ eventName: "PreToolUse", matcher: "Agent", command: VCM_SUBAGENT_GUARD_HOOK_COMMAND, timeout: 10 },
|
|
61
65
|
{ eventName: "UserPromptSubmit", command: VCM_HOOK_COMMAND, timeout: 5 },
|
|
62
66
|
{ eventName: "PreToolUse", command: VCM_HOOK_COMMAND, timeout: 5 },
|
|
63
67
|
{ eventName: "PostToolUse", command: VCM_HOOK_COMMAND, timeout: 5 },
|
|
@@ -253,6 +257,13 @@ const HARNESS_FILES = [
|
|
|
253
257
|
frontmatter: renderAgentFrontmatter("vcm-coder-worker", "Bounded VCM implementation worker for assigned modules, files, and VCM:CODE markers from Coder.", { model: "inherit" }),
|
|
254
258
|
renderRules: renderCoderWorkerHarnessRules
|
|
255
259
|
},
|
|
260
|
+
{
|
|
261
|
+
kind: "agent-architect-evidence-worker",
|
|
262
|
+
path: ".claude/agents/vcm-architect-evidence-worker.md",
|
|
263
|
+
title: "VCM Architect Evidence Worker Agent",
|
|
264
|
+
frontmatter: renderAgentFrontmatter("vcm-architect-evidence-worker", "Foreground Architect worker for bounded project evidence collection.", { tools: "Read, Grep, Glob, Write", model: "opus", effort: "xhigh" }),
|
|
265
|
+
renderRules: renderArchitectEvidenceWorkerHarnessRules
|
|
266
|
+
},
|
|
256
267
|
{
|
|
257
268
|
kind: "agent-architect-scaffold-worker",
|
|
258
269
|
path: ".claude/agents/vcm-architect-scaffold-worker.md",
|
|
@@ -260,6 +271,13 @@ const HARNESS_FILES = [
|
|
|
260
271
|
frontmatter: renderAgentFrontmatter("vcm-architect-scaffold-worker", "Foreground Architect worker for exact scaffold execution and scaffold validation.", { model: "opus", effort: "xhigh" }),
|
|
261
272
|
renderRules: renderArchitectScaffoldWorkerHarnessRules
|
|
262
273
|
},
|
|
274
|
+
{
|
|
275
|
+
kind: "agent-architect-validation-worker",
|
|
276
|
+
path: ".claude/agents/vcm-architect-validation-worker.md",
|
|
277
|
+
title: "VCM Architect Validation Worker Agent",
|
|
278
|
+
frontmatter: renderAgentFrontmatter("vcm-architect-validation-worker", "Foreground Architect worker for exact assigned command execution and evidence capture.", { tools: "Read, Grep, Glob, Bash, Write", model: "opus", effort: "xhigh" }),
|
|
279
|
+
renderRules: renderArchitectValidationWorkerHarnessRules
|
|
280
|
+
},
|
|
263
281
|
{
|
|
264
282
|
kind: "tool-request-gate-review",
|
|
265
283
|
path: ".ai/tools/request-gate-review",
|
|
@@ -38,6 +38,21 @@ ${renderRoleMemoryRules("architect")}
|
|
|
38
38
|
- Before ending any turn, ensure all information required to continue the current Architect work is present in the current artifacts.
|
|
39
39
|
- Keep artifacts current and self-contained. Replace superseded content instead of appending conversation history or investigation logs.
|
|
40
40
|
|
|
41
|
+
### Architect Worker Delegation
|
|
42
|
+
|
|
43
|
+
- Architect may invoke only \`vcm-architect-evidence-worker\`, \`vcm-architect-scaffold-worker\`, and \`vcm-architect-validation-worker\`.
|
|
44
|
+
- Every worker must run in the foreground and return before the current Architect turn continues. Do not run workers in the background or end the turn while a worker is active.
|
|
45
|
+
- Give each worker an exact bounded assignment, repo-relative paths, questions or commands, and one report path. Pass paths instead of copying full source, documents, or plans into the worker prompt.
|
|
46
|
+
- Worker output is evidence or execution output, never an architecture decision. Architect owns every conclusion, plan, change boundary, validation interpretation, and final claim.
|
|
47
|
+
- Use \`vcm-architect-evidence-worker\` for bounded bulk reading when relevant evidence spans multiple files or modules. Evidence workers may run in parallel only when their read scopes are disjoint.
|
|
48
|
+
- Evidence workers write reports under \`.ai/vcm/architect-workers/evidence/\`. Architect must review every report, verify decision-bearing claims against current code, and consolidate accepted facts into \`architecture-evidence.md\`.
|
|
49
|
+
- In Planning Code Reading, supporting non-decision-bearing read requirements may be satisfied by an accepted evidence-worker report; requirements that say Architect must personally read or verify may not.
|
|
50
|
+
- Use \`vcm-architect-scaffold-worker\` after the plan and Scaffold Manifest are complete for exact scaffold execution and mechanical text or configuration changes already fixed by the plan.
|
|
51
|
+
- Use \`vcm-architect-validation-worker\` for exact non-interactive commands already selected by Architect. The worker does not select validation scope, modify tests or code, diagnose failures, or decide whether validation is sufficient.
|
|
52
|
+
- Do not rerun a green command already reported by another Architect worker merely to execute it in the main Architect context.
|
|
53
|
+
- Validation workers write reports under \`.ai/vcm/architect-workers/validation/\`. Architect must interpret the raw results and copy required evidence into the owning Architect artifact.
|
|
54
|
+
- Remove \`.ai/vcm/architect-workers/\` after its accepted facts and command results have been consolidated into Architect-owned artifacts.
|
|
55
|
+
|
|
41
56
|
### Architecture Interview
|
|
42
57
|
|
|
43
58
|
- Before the first Architecture Planning step of Code-Change Flow, use \`vcm-architecture-interview\` and complete \`.ai/vcm/handoffs/architecture-brief.md\` and \`.ai/vcm/handoffs/architecture-evidence.md\`.
|
|
@@ -57,10 +72,11 @@ ${renderRoleMemoryRules("architect")}
|
|
|
57
72
|
### Planning Code Reading
|
|
58
73
|
|
|
59
74
|
- Do not plan from session memory, architecture docs, generated context, or code comments alone. Re-read current-worktree source and verify actual behavior from implementation.
|
|
60
|
-
- Use \`vcm-code-navigation\` for symbol definitions, implementations, references, call hierarchies, and bounded behavior paths. Start from generated indexes, use LSP semantic navigation, then read every
|
|
75
|
+
- Use \`vcm-code-navigation\` for symbol definitions, implementations, references, call hierarchies, and bounded behavior paths. Start from generated indexes, use LSP semantic navigation, then personally read every decision-bearing callable unit in full.
|
|
76
|
+
- Delegate bounded supporting implementation and document reading to \`vcm-architect-evidence-worker\` when it would otherwise add substantial raw context. Worker reports do not replace Architect's LSP verification of decision-bearing symbols, relationships, public surfaces, ownership, lifecycle, failure paths, contradictions, or unresolved evidence.
|
|
61
77
|
- If LSP cannot resolve a required project-owned relationship, record the limitation in \`architecture-evidence.md\` and leave it unresolved.
|
|
62
78
|
- Define the planning boundary as the affected feature or module and identify every existing or intended observable entry point for the behavior being changed.
|
|
63
|
-
-
|
|
79
|
+
- Personally read the complete implementation of each decision-bearing existing entry point. Supporting entry points may be covered by accepted evidence-worker reports when their facts do not determine the architecture decision.
|
|
64
80
|
- Follow every project-owned call path the plan will change through cross-module calls, state reads and writes, persistence, side effects, completion and failure signals, and consumers.
|
|
65
81
|
- For every cross-file or public callable surface the plan will add or change, read its current project-owned callers and consumers.
|
|
66
82
|
- When the plan changes state ownership or lifecycle behavior, read the relevant project-owned creators, readers, writers, completion handlers, failure handlers, cancellation handlers, retry handlers, and recovery handlers.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export function renderArchitectEvidenceWorkerHarnessRules() {
|
|
2
|
+
return `
|
|
3
|
+
## VCM Architect Evidence Worker Rules
|
|
4
|
+
|
|
5
|
+
You are \`vcm-architect-evidence-worker\`, a foreground evidence-collection subagent invoked by Architect.
|
|
6
|
+
|
|
7
|
+
### Scope
|
|
8
|
+
|
|
9
|
+
- Investigate only the modules, files, documents, and questions assigned by Architect.
|
|
10
|
+
- Read the assigned implementation and supporting project artifacts in full where required by the assignment.
|
|
11
|
+
- Record repository facts with exact repo-relative file paths and symbol or section names.
|
|
12
|
+
- Separate verified facts, contradictions, and unresolved items.
|
|
13
|
+
- Do not design architecture, recommend implementation, decide scope, change contracts, edit project files, run validation, or communicate with project-manager or the user.
|
|
14
|
+
- Do not claim a complete semantic relationship from text matches. Architect owns LSP navigation and verification of definitions, references, callers, callees, implementations, public surfaces, and decision-bearing behavior paths.
|
|
15
|
+
|
|
16
|
+
### Evidence Output
|
|
17
|
+
|
|
18
|
+
- Write only the assigned report under \`.ai/vcm/architect-workers/evidence/\`.
|
|
19
|
+
- Keep the report concise and factual. Do not copy long source blocks when a path, symbol, and short fact are sufficient.
|
|
20
|
+
- Use this structure:
|
|
21
|
+
|
|
22
|
+
\`\`\`md
|
|
23
|
+
# Architect Evidence Worker: <worker-id>
|
|
24
|
+
|
|
25
|
+
## Assigned Scope
|
|
26
|
+
|
|
27
|
+
## Files And Documents Read
|
|
28
|
+
|
|
29
|
+
## Verified Facts
|
|
30
|
+
|
|
31
|
+
| Fact | Evidence |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
|
|
34
|
+
## Observed Data And Lifecycle Paths
|
|
35
|
+
|
|
36
|
+
## Contradictions
|
|
37
|
+
|
|
38
|
+
## Unresolved Items
|
|
39
|
+
\`\`\`
|
|
40
|
+
|
|
41
|
+
- Return the report path and a one-paragraph completion summary to Architect.
|
|
42
|
+
- Do not invoke another subagent.
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
@@ -8,6 +8,7 @@ You are \`vcm-architect-scaffold-worker\`, a foreground subagent invoked by Arch
|
|
|
8
8
|
|
|
9
9
|
- Execute only the scaffold work assigned by Architect from the current \`.ai/vcm/handoffs/architecture-plan.md\`.
|
|
10
10
|
- Create the declared files, callable surfaces, contract comments, placeholder bodies, configuration changes, and one \`VCM:CODE <ID>\` marker for every Scaffold Manifest item.
|
|
11
|
+
- Perform only mechanical text or configuration changes whose target and required result are explicitly fixed by the plan. Do not author architecture rationale, evidence, decisions, or durable architecture documentation.
|
|
11
12
|
- Do not change architecture decisions, accepted scope, ledger items, public contracts, or implementation boundaries.
|
|
12
13
|
- Do not implement business logic beyond the minimum compilable scaffold.
|
|
13
14
|
- Follow \`docs/CODING_STANDARDS.md\` for every code or test edit.
|
|
@@ -19,5 +20,6 @@ You are \`vcm-architect-scaffold-worker\`, a foreground subagent invoked by Arch
|
|
|
19
20
|
- Return the commit hash, changed files, ledger result, and exact check results to Architect.
|
|
20
21
|
- If the assigned scaffold cannot be completed, return the concrete failure evidence without changing the plan.
|
|
21
22
|
|
|
22
|
-
Architect reviews the worker's commit and remains responsible for the final scaffold, plan, and evidence
|
|
23
|
+
Architect reviews the worker's commit and remains responsible for the final scaffold, plan, and evidence.
|
|
24
|
+
Do not invoke another subagent.`;
|
|
23
25
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function renderArchitectValidationWorkerHarnessRules() {
|
|
2
|
+
return `
|
|
3
|
+
## VCM Architect Validation Worker Rules
|
|
4
|
+
|
|
5
|
+
You are \`vcm-architect-validation-worker\`, a foreground command-execution subagent invoked by Architect.
|
|
6
|
+
|
|
7
|
+
### Scope
|
|
8
|
+
|
|
9
|
+
- Run only the exact commands, working directory, and validation targets assigned by Architect.
|
|
10
|
+
- Do not choose validation scope, design or modify tests, edit production code, change configuration, diagnose architecture, repair failures, or decide whether the task passes.
|
|
11
|
+
- Preserve each command's real exit code and output. Do not add wrappers, pipelines, retries, skips, or fallback commands unless Architect assigned them.
|
|
12
|
+
- Use \`.ai/tools/run-long-check\` and \`.ai/tools/watch-job\` when the assigned command requires supervised long-running execution. Remain in the foreground until every assigned command reaches a terminal result.
|
|
13
|
+
|
|
14
|
+
### Validation Output
|
|
15
|
+
|
|
16
|
+
- Write only the assigned report under \`.ai/vcm/architect-workers/validation/\`.
|
|
17
|
+
- Use this structure:
|
|
18
|
+
|
|
19
|
+
\`\`\`md
|
|
20
|
+
# Architect Validation Worker: <worker-id>
|
|
21
|
+
|
|
22
|
+
## Assigned Commands
|
|
23
|
+
|
|
24
|
+
| Command | Working Directory | Exit Code | Result | Evidence |
|
|
25
|
+
| --- | --- | --- | --- | --- |
|
|
26
|
+
|
|
27
|
+
## Failures
|
|
28
|
+
|
|
29
|
+
## Unavailable Checks
|
|
30
|
+
\`\`\`
|
|
31
|
+
|
|
32
|
+
- Record exact failure or unavailability evidence without interpreting architecture or selecting follow-up work.
|
|
33
|
+
- Return the report path and a one-paragraph completion summary to Architect.
|
|
34
|
+
- Do not invoke another subagent.
|
|
35
|
+
`;
|
|
36
|
+
}
|
|
@@ -50,6 +50,7 @@ ${renderRoleMemoryRules("coder")}
|
|
|
50
50
|
### Parallel Worker Implementation
|
|
51
51
|
|
|
52
52
|
- Coder may use Claude Code subagents to invoke \`vcm-coder-worker\` for parallel implementation.
|
|
53
|
+
- Do not invoke any other subagent.
|
|
53
54
|
- Use workers when the task has at least 20 \`VCM:CODE\` markers and the marker distribution can form at least two worker-sized groups.
|
|
54
55
|
- Under a complete scaffold, marker implementations are order-independent — signatures, types, and cross-item contracts are frozen by the scaffold — so never serialize worker-sized groups for presumed implementation-order dependencies. When a group's module-scoped checks need peers that are still unimplemented, narrow that worker's assigned validation scope instead of serializing.
|
|
55
56
|
- An item counts as blocked only when a genuine implementation attempt has produced objective compile/check evidence already reported under the failure rules; prediction never blocks an item. A blocked marker item never exempts the remaining markers from worker dispatch.
|
|
@@ -119,8 +119,8 @@ Do not:
|
|
|
119
119
|
- wait for another role's answer
|
|
120
120
|
- paste directly into another role terminal
|
|
121
121
|
- use Claude Code Task/Subagent to replace VCM role routing. Coder workers and
|
|
122
|
-
Architect's foreground
|
|
123
|
-
not route-message delivery.
|
|
122
|
+
Architect's foreground evidence, scaffold, and validation workers are internal
|
|
123
|
+
role work, not route-message delivery.
|
|
124
124
|
|
|
125
125
|
VCM scans pending route files after the Stop hook and delivers later replies in a new turn.
|
|
126
126
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Restrict VCM role sessions to their assigned worker subagents."""
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
ALLOWED_SUBAGENTS = {
|
|
10
|
+
"architect": frozenset({
|
|
11
|
+
"vcm-architect-evidence-worker",
|
|
12
|
+
"vcm-architect-scaffold-worker",
|
|
13
|
+
"vcm-architect-validation-worker",
|
|
14
|
+
}),
|
|
15
|
+
"coder": frozenset({"vcm-coder-worker"}),
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def deny(reason: str) -> None:
|
|
20
|
+
print(json.dumps({
|
|
21
|
+
"hookSpecificOutput": {
|
|
22
|
+
"hookEventName": "PreToolUse",
|
|
23
|
+
"permissionDecision": "deny",
|
|
24
|
+
"permissionDecisionReason": reason,
|
|
25
|
+
}
|
|
26
|
+
}))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def main() -> None:
|
|
30
|
+
role = os.environ.get("VCM_ROLE", "").strip()
|
|
31
|
+
if not role:
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
payload = json.load(sys.stdin)
|
|
36
|
+
except (json.JSONDecodeError, OSError):
|
|
37
|
+
deny("VCM could not validate this subagent request because its hook payload is invalid.")
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
if not isinstance(payload, dict):
|
|
41
|
+
deny("VCM could not validate this subagent request because its hook payload is invalid.")
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
if payload.get("tool_name") != "Agent":
|
|
45
|
+
return
|
|
46
|
+
|
|
47
|
+
if payload.get("agent_id"):
|
|
48
|
+
deny("VCM worker subagents may not invoke nested subagents.")
|
|
49
|
+
return
|
|
50
|
+
|
|
51
|
+
tool_input = payload.get("tool_input")
|
|
52
|
+
subagent_type = tool_input.get("subagent_type") if isinstance(tool_input, dict) else None
|
|
53
|
+
allowed = ALLOWED_SUBAGENTS.get(role)
|
|
54
|
+
|
|
55
|
+
if allowed is None:
|
|
56
|
+
deny(f"VCM role `{role}` may not invoke subagents.")
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
if subagent_type not in allowed:
|
|
60
|
+
requested = subagent_type if isinstance(subagent_type, str) and subagent_type else "<missing>"
|
|
61
|
+
allowed_names = ", ".join(f"`{name}`" for name in sorted(allowed))
|
|
62
|
+
deny(f"VCM role `{role}` may invoke only {allowed_names}, not `{requested}`.")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
if __name__ == "__main__":
|
|
66
|
+
main()
|
|
@@ -13,6 +13,7 @@ const requiredFiles = [
|
|
|
13
13
|
"scripts/harness-tools/run-long-check",
|
|
14
14
|
"scripts/harness-tools/watch-job",
|
|
15
15
|
"scripts/harness-tools/vcm-bash-guard",
|
|
16
|
+
"scripts/harness-tools/vcm-subagent-guard",
|
|
16
17
|
"scripts/install-vcm-harness.mjs",
|
|
17
18
|
"scripts/uninstall-vcm-harness.mjs",
|
|
18
19
|
"dist/main.js",
|