vibe-coding-master 0.7.37 → 0.7.39

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 CHANGED
@@ -455,7 +455,7 @@ Harness Studio is the UI for VCM harness maintenance.
455
455
  Use it to:
456
456
 
457
457
  - inspect fixed harness status
458
- - inspect detected project languages and verified language-server readiness
458
+ - inspect detected project languages and language-server availability
459
459
  - run bootstrap
460
460
  - open Harness Engineer
461
461
  - review harness files
@@ -471,8 +471,12 @@ VCM bundles the Claude Code LSP bridge and loads it for Architect, Coder, and
471
471
  Reviewer sessions, including CCR launches. The project environment must still
472
472
  provide the language server for each detected language: `rust-analyzer`,
473
473
  `typescript-language-server`, `pyright-langserver`, `gopls`, `clangd`, or
474
- `jdtls`. Harness Studio reports a missing executable or failed startup probe
475
- with the backend diagnostic.
474
+ `jdtls`. Their Agent definitions preload `vcm-code-navigation`, and their
475
+ launches explicitly enable Glob while leaving Grep unavailable. The Harness
476
+ guard also rejects shell text-search commands for those roles so unresolved
477
+ semantic relationships cannot be hidden by textual fallback. Harness Studio
478
+ reports whether the server executable and plugin can run; the role Session
479
+ performs the real workspace warm-up and semantic query retries.
476
480
 
477
481
  Harness Engineer is task-scoped and runs from the active task worktree. The
478
482
  backend automatically starts a fresh Harness Engineer for each active task or
@@ -20,6 +20,7 @@ export function createClaudeAdapter(runner) {
20
20
  },
21
21
  buildRoleStartCommand(role, command = "claude", permissionMode = "default", claudeSessionId, resume = false, model = "default", effort = "default", settingsOverride, appendSystemPrompt, pluginDirs = []) {
22
22
  const args = pluginDirs.flatMap((pluginDir) => ["--plugin-dir", pluginDir]);
23
+ args.push("--allowedTools", roleSearchToolOptIns(role).join(","));
23
24
  args.push("--agent", role);
24
25
  const sessionSettings = { ...settingsOverride };
25
26
  if (claudeSessionId) {
@@ -51,6 +52,11 @@ export function createClaudeAdapter(runner) {
51
52
  }
52
53
  };
53
54
  }
55
+ function roleSearchToolOptIns(role) {
56
+ return role === "architect" || role === "coder" || role === "reviewer"
57
+ ? ["Glob"]
58
+ : ["Glob", "Grep"];
59
+ }
54
60
  function formatDisplayArg(value) {
55
61
  if (/^[A-Za-z0-9_./:=@+-]+$/.test(value)) {
56
62
  return value;
@@ -53,6 +53,7 @@ const VCM_BASH_DEFAULT_TIMEOUT_MS = "600000";
53
53
  const VCM_AUTO_MEMORY_ENABLED = false;
54
54
  const VCM_HOOK_DEFINITIONS = [
55
55
  { eventName: "PreToolUse", matcher: "Bash", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
56
+ { eventName: "PreToolUse", matcher: "Grep", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
56
57
  { eventName: "UserPromptSubmit", command: VCM_HOOK_COMMAND, timeout: 5 },
57
58
  { eventName: "Stop", command: VCM_STOP_HOOK_COMMAND, timeout: 10 },
58
59
  { eventName: "StopFailure", command: VCM_HOOK_COMMAND, timeout: 5 },
@@ -65,18 +66,21 @@ const AGENT_FRONTMATTER = {
65
66
  },
66
67
  architect: {
67
68
  description: "VCM architecture role for plans, module boundaries, public contracts, verifiable behavior, and docs sync.",
68
- tools: "Read, Grep, Glob, Bash, Edit, Write, Agent, LSP"
69
+ tools: "Read, Glob, Bash, Edit, Write, Agent, LSP",
70
+ skills: ["vcm-code-navigation"]
69
71
  },
70
72
  coder: {
71
73
  description: "VCM implementation role for scoped code changes and focused tests.",
72
- tools: "Read, Grep, Glob, Bash, Edit, Write, Agent, LSP"
74
+ tools: "Read, Glob, Bash, Edit, Write, Agent, LSP",
75
+ skills: ["vcm-code-navigation"]
73
76
  },
74
77
  tester: {
75
78
  description: "VCM testing role for validation, test adequacy, approved-scope validation, and risk findings."
76
79
  },
77
80
  reviewer: {
78
81
  description: "VCM independent gate review role for architecture plans, validation adequacy, and code diffs.",
79
- tools: "Read, Grep, Glob, Bash, Write, LSP"
82
+ tools: "Read, Glob, Bash, Write, LSP",
83
+ skills: ["vcm-code-navigation"]
80
84
  },
81
85
  translator: {
82
86
  description: "VCM task-scoped translation tool role for conversation translation, file translation, bootstrap, and memory updates."
@@ -99,6 +103,16 @@ const REQUIRED_AGENT_TOOLS = {
99
103
  coder: ["Agent", "LSP"],
100
104
  reviewer: ["LSP"]
101
105
  };
106
+ const FORBIDDEN_AGENT_TOOLS = {
107
+ architect: ["Grep"],
108
+ coder: ["Grep"],
109
+ reviewer: ["Grep"]
110
+ };
111
+ const REQUIRED_AGENT_SKILLS = {
112
+ architect: ["vcm-code-navigation"],
113
+ coder: ["vcm-code-navigation"],
114
+ reviewer: ["vcm-code-navigation"]
115
+ };
102
116
  const MANAGED_FILES = [
103
117
  {
104
118
  path: "CLAUDE.md",
@@ -266,7 +280,7 @@ const WHOLE_FILES = [
266
280
  path: ".claude/skills/vcm-code-navigation/SKILL.md",
267
281
  category: "skill",
268
282
  mode: 0o644,
269
- content: renderSkillFile("VCM Code Navigation Skill", "vcm-code-navigation", "Use when Architect or Reviewer must resolve code symbols, references, implementations, call hierarchies, or bounded dependency paths.", renderVcmCodeNavigationSkillRules())
283
+ content: renderSkillFile("VCM Code Navigation Skill", "vcm-code-navigation", "Use when Architect, Coder, or Reviewer must resolve code symbols, references, implementations, call hierarchies, or bounded dependency paths.", renderVcmCodeNavigationSkillRules())
270
284
  },
271
285
  {
272
286
  path: ".claude/skills/vcm-final-acceptance/SKILL.md",
@@ -672,6 +686,12 @@ async function installManagedFile({ projectRoot, definition, dryRun, operations
672
686
  for (const requiredTool of REQUIRED_AGENT_TOOLS[definition.agentName] ?? []) {
673
687
  nextContent = ensureAgentTool(nextContent, requiredTool);
674
688
  }
689
+ for (const forbiddenTool of FORBIDDEN_AGENT_TOOLS[definition.agentName] ?? []) {
690
+ nextContent = removeAgentTool(nextContent, forbiddenTool);
691
+ }
692
+ for (const requiredSkill of REQUIRED_AGENT_SKILLS[definition.agentName] ?? []) {
693
+ nextContent = ensureAgentSkill(nextContent, requiredSkill);
694
+ }
675
695
  await writeIfChanged({
676
696
  targetPath,
677
697
  relativePath: definition.path,
@@ -714,7 +734,10 @@ function renderNewManagedFile(definition, block) {
714
734
  const tools = frontmatter.tools ?? "Read, Grep, Glob, Bash, Edit, Write";
715
735
  const model = frontmatter.model ? `\nmodel: ${frontmatter.model}` : "";
716
736
  const effort = frontmatter.effort ? `\neffort: ${frontmatter.effort}` : "";
717
- return `---\nname: ${definition.agentName}\ndescription: ${frontmatter.description}\ntools: ${tools}${model}${effort}\n---\n\n# ${definition.title}\n\n${block}${suffix ? `\n\n${suffix}` : ""}\n`;
737
+ const skills = frontmatter.skills?.length
738
+ ? `\nskills:\n${frontmatter.skills.map((skill) => ` - ${skill}`).join("\n")}`
739
+ : "";
740
+ return `---\nname: ${definition.agentName}\ndescription: ${frontmatter.description}\ntools: ${tools}${model}${effort}${skills}\n---\n\n# ${definition.title}\n\n${block}${suffix ? `\n\n${suffix}` : ""}\n`;
718
741
  }
719
742
  return `# ${definition.title}\n\n${block}${suffix ? `\n\n${suffix}` : ""}\n`;
720
743
  }
@@ -734,6 +757,42 @@ function ensureAgentTool(content, requiredTool) {
734
757
  const nextTools = [...tools, requiredTool].join(", ");
735
758
  return content.replace(frontmatterMatch[0], frontmatterMatch[0].replace(toolsMatch[0], `tools: ${nextTools}`));
736
759
  }
760
+ function removeAgentTool(content, forbiddenTool) {
761
+ const frontmatterMatch = content.match(/^---\r?\n[\s\S]*?\r?\n---/);
762
+ if (!frontmatterMatch) {
763
+ return content;
764
+ }
765
+ const toolsMatch = frontmatterMatch[0].match(/^tools:\s*(.*)$/m);
766
+ if (!toolsMatch) {
767
+ return content;
768
+ }
769
+ const tools = toolsMatch[1].split(",").map((tool) => tool.trim()).filter(Boolean);
770
+ const nextTools = tools.filter((tool) => tool !== forbiddenTool);
771
+ if (nextTools.length === tools.length) {
772
+ return content;
773
+ }
774
+ return content.replace(frontmatterMatch[0], frontmatterMatch[0].replace(toolsMatch[0], `tools: ${nextTools.join(", ")}`));
775
+ }
776
+ function ensureAgentSkill(content, requiredSkill) {
777
+ const frontmatterMatch = content.match(/^---\r?\n[\s\S]*?\r?\n---/);
778
+ if (!frontmatterMatch) {
779
+ return content;
780
+ }
781
+ const frontmatter = frontmatterMatch[0];
782
+ const skillsMatch = frontmatter.match(/^skills:[ \t]*(?:\r?\n((?:\s+-\s+[^\r\n]+\r?\n?)*))?/m);
783
+ if (!skillsMatch) {
784
+ return content.replace(frontmatter, frontmatter.replace(/\r?\n---$/, `\nskills:\n - ${requiredSkill}\n---`));
785
+ }
786
+ const listedSkills = (skillsMatch[1] ?? "")
787
+ .split(/\r?\n/)
788
+ .map((line) => line.match(/^\s+-\s+(.+)$/)?.[1]?.trim())
789
+ .filter(Boolean);
790
+ if (listedSkills.includes(requiredSkill)) {
791
+ return content;
792
+ }
793
+ const nextSkills = `${skillsMatch[0].trimEnd()}\n - ${requiredSkill}`;
794
+ return content.replace(frontmatter, frontmatter.replace(skillsMatch[0], nextSkills));
795
+ }
737
796
  function migrateLegacyManagedFile(definition, currentContent, block) {
738
797
  const legacyContent = definition.legacyWholeFile?.trimEnd();
739
798
  if (!legacyContent) {
@@ -127,13 +127,13 @@ async function detectCodeIntelligence(fs, repoRoot, options, probe) {
127
127
  return status;
128
128
  }));
129
129
  const languages = detectedLanguages.filter((language) => language !== undefined);
130
- const readyCount = languages.filter((language) => language.state === "ready").length;
130
+ const runnableCount = languages.filter((language) => language.state === "server_runnable").length;
131
131
  return {
132
132
  state: languages.length === 0
133
133
  ? "not_detected"
134
- : readyCount === languages.length
135
- ? "ready"
136
- : readyCount === 0
134
+ : runnableCount === languages.length
135
+ ? "available"
136
+ : runnableCount === 0
137
137
  ? "missing"
138
138
  : "partial",
139
139
  languages
@@ -149,7 +149,7 @@ function languageState(pluginReady, serverFound, serverRunnable, probeCompleted)
149
149
  if (!probeCompleted) {
150
150
  return "server_unverified";
151
151
  }
152
- return serverRunnable ? "ready" : "server_failed";
152
+ return serverRunnable ? "server_runnable" : "server_failed";
153
153
  }
154
154
  function languageError(state, command, probeResult) {
155
155
  if (state === "plugin_missing") {
@@ -53,6 +53,7 @@ const VCM_BASH_DEFAULT_TIMEOUT_MS = "600000";
53
53
  const VCM_AUTO_MEMORY_ENABLED = false;
54
54
  const VCM_HOOK_DEFINITIONS = [
55
55
  { eventName: "PreToolUse", matcher: "Bash", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
56
+ { eventName: "PreToolUse", matcher: "Grep", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
56
57
  { eventName: "UserPromptSubmit", command: VCM_HOOK_COMMAND, timeout: 5 },
57
58
  { eventName: "Stop", command: VCM_STOP_HOOK_COMMAND, timeout: 10 },
58
59
  { eventName: "StopFailure", command: VCM_HOOK_COMMAND, timeout: 5 },
@@ -116,7 +117,7 @@ const HARNESS_FILES = [
116
117
  kind: "skill-vcm-code-navigation",
117
118
  path: ".claude/skills/vcm-code-navigation/SKILL.md",
118
119
  title: "VCM Code Navigation Skill",
119
- frontmatter: renderSkillFrontmatter("vcm-code-navigation", "Use when Architect or Reviewer must resolve code symbols, references, implementations, call hierarchies, or bounded dependency paths."),
120
+ frontmatter: renderSkillFrontmatter("vcm-code-navigation", "Use when Architect, Coder, or Reviewer must resolve code symbols, references, implementations, call hierarchies, or bounded dependency paths."),
120
121
  ownership: "whole-file",
121
122
  renderRules: renderVcmCodeNavigationSkillRules
122
123
  },
@@ -198,7 +199,9 @@ const HARNESS_FILES = [
198
199
  title: "Reviewer Agent",
199
200
  memoryBlock: true,
200
201
  requiredTools: ["LSP"],
201
- frontmatter: renderAgentFrontmatter("reviewer", "VCM independent gate review role for architecture plans, validation adequacy, and code diffs.", { tools: "Read, Grep, Glob, Bash, Write, LSP" }),
202
+ forbiddenTools: ["Grep"],
203
+ requiredSkills: ["vcm-code-navigation"],
204
+ frontmatter: renderAgentFrontmatter("reviewer", "VCM independent gate review role for architecture plans, validation adequacy, and code diffs.", { tools: "Read, Glob, Bash, Write, LSP", skills: ["vcm-code-navigation"] }),
202
205
  renderRules: renderReviewerAgentRules
203
206
  },
204
207
  {
@@ -272,8 +275,10 @@ const HARNESS_FILES = [
272
275
  title: "Architect Agent",
273
276
  memoryBlock: true,
274
277
  requiredTools: ["Agent", "LSP"],
278
+ forbiddenTools: ["Grep"],
279
+ requiredSkills: ["vcm-code-navigation"],
275
280
  blankLineBeforeEnd: true,
276
- frontmatter: renderAgentFrontmatter("architect", "VCM architecture role for plans, module boundaries, public contracts, verifiable behavior, and docs sync.", { tools: "Read, Grep, Glob, Bash, Edit, Write, Agent, LSP" }),
281
+ frontmatter: renderAgentFrontmatter("architect", "VCM architecture role for plans, module boundaries, public contracts, verifiable behavior, and docs sync.", { tools: "Read, Glob, Bash, Edit, Write, Agent, LSP", skills: ["vcm-code-navigation"] }),
277
282
  renderRules: renderArchitectHarnessRules
278
283
  },
279
284
  {
@@ -282,7 +287,9 @@ const HARNESS_FILES = [
282
287
  title: "Coder Agent",
283
288
  memoryBlock: true,
284
289
  requiredTools: ["Agent", "LSP"],
285
- frontmatter: renderAgentFrontmatter("coder", "VCM implementation role for scoped code changes and focused tests.", { tools: "Read, Grep, Glob, Bash, Edit, Write, Agent, LSP" }),
290
+ forbiddenTools: ["Grep"],
291
+ requiredSkills: ["vcm-code-navigation"],
292
+ frontmatter: renderAgentFrontmatter("coder", "VCM implementation role for scoped code changes and focused tests.", { tools: "Read, Glob, Bash, Edit, Write, Agent, LSP", skills: ["vcm-code-navigation"] }),
286
293
  renderRules: renderCoderHarnessRules
287
294
  },
288
295
  {
@@ -1220,7 +1227,7 @@ async function analyzeHarnessFile(fs, repoRoot, definition) {
1220
1227
  const migratedContent = migrateLegacyHarnessFile(definition, currentContent, expectedBlock);
1221
1228
  if (migratedContent) {
1222
1229
  const memoryUpdatedContent = definition.memoryBlock ? ensureVcmMemoryBlock(migratedContent) : migratedContent;
1223
- const nextContent = ensureAgentTools(memoryUpdatedContent, definition.requiredTools);
1230
+ const nextContent = normalizeAgentFrontmatter(memoryUpdatedContent, definition);
1224
1231
  return {
1225
1232
  definition,
1226
1233
  status: {
@@ -1239,7 +1246,7 @@ async function analyzeHarnessFile(fs, repoRoot, definition) {
1239
1246
  };
1240
1247
  }
1241
1248
  const insertedContent = `${currentContent.trimEnd()}\n\n${expectedBlock}\n`;
1242
- const nextContent = ensureAgentTools(insertedContent, definition.requiredTools);
1249
+ const nextContent = normalizeAgentFrontmatter(insertedContent, definition);
1243
1250
  return {
1244
1251
  definition,
1245
1252
  status: {
@@ -1261,7 +1268,7 @@ async function analyzeHarnessFile(fs, repoRoot, definition) {
1261
1268
  const currentBlock = match[0];
1262
1269
  const blockUpdatedContent = currentContent.replace(managedBlockPattern, expectedBlock);
1263
1270
  const memoryUpdatedContent = definition.memoryBlock ? ensureVcmMemoryBlock(blockUpdatedContent) : blockUpdatedContent;
1264
- const nextContent = ensureAgentTools(memoryUpdatedContent, definition.requiredTools);
1271
+ const nextContent = normalizeAgentFrontmatter(memoryUpdatedContent, definition);
1265
1272
  const action = currentContent === nextContent ? "ok" : "update";
1266
1273
  return {
1267
1274
  definition,
@@ -1392,6 +1399,50 @@ function ensureAgentTool(content, requiredTool) {
1392
1399
  function ensureAgentTools(content, requiredTools) {
1393
1400
  return (requiredTools ?? []).reduce(ensureAgentTool, content);
1394
1401
  }
1402
+ function removeAgentTool(content, forbiddenTool) {
1403
+ const frontmatterMatch = content.match(/^---\r?\n[\s\S]*?\r?\n---/);
1404
+ if (!frontmatterMatch) {
1405
+ return content;
1406
+ }
1407
+ const toolsMatch = frontmatterMatch[0].match(/^tools:\s*(.*)$/m);
1408
+ if (!toolsMatch) {
1409
+ return content;
1410
+ }
1411
+ const tools = toolsMatch[1].split(",").map((tool) => tool.trim()).filter(Boolean);
1412
+ const nextTools = tools.filter((tool) => tool !== forbiddenTool);
1413
+ if (nextTools.length === tools.length) {
1414
+ return content;
1415
+ }
1416
+ return content.replace(frontmatterMatch[0], frontmatterMatch[0].replace(toolsMatch[0], `tools: ${nextTools.join(", ")}`));
1417
+ }
1418
+ function normalizeAgentTools(content, requiredTools, forbiddenTools) {
1419
+ const required = ensureAgentTools(content, requiredTools);
1420
+ return (forbiddenTools ?? []).reduce(removeAgentTool, required);
1421
+ }
1422
+ function normalizeAgentFrontmatter(content, definition) {
1423
+ const toolsUpdated = normalizeAgentTools(content, definition.requiredTools, definition.forbiddenTools);
1424
+ return (definition.requiredSkills ?? []).reduce(ensureAgentSkill, toolsUpdated);
1425
+ }
1426
+ function ensureAgentSkill(content, requiredSkill) {
1427
+ const frontmatterMatch = content.match(/^---\r?\n[\s\S]*?\r?\n---/);
1428
+ if (!frontmatterMatch) {
1429
+ return content;
1430
+ }
1431
+ const frontmatter = frontmatterMatch[0];
1432
+ const skillsMatch = frontmatter.match(/^skills:[ \t]*(?:\r?\n((?:\s+-\s+[^\r\n]+\r?\n?)*))?/m);
1433
+ if (!skillsMatch) {
1434
+ return content.replace(frontmatter, frontmatter.replace(/\r?\n---$/, `\nskills:\n - ${requiredSkill}\n---`));
1435
+ }
1436
+ const listedSkills = (skillsMatch[1] ?? "")
1437
+ .split(/\r?\n/)
1438
+ .map((line) => line.match(/^\s+-\s+(.+)$/)?.[1]?.trim())
1439
+ .filter((skill) => Boolean(skill));
1440
+ if (listedSkills.includes(requiredSkill)) {
1441
+ return content;
1442
+ }
1443
+ const nextSkills = `${skillsMatch[0].trimEnd()}\n - ${requiredSkill}`;
1444
+ return content.replace(frontmatter, frontmatter.replace(skillsMatch[0], nextSkills));
1445
+ }
1395
1446
  function migrateLegacyHarnessFile(definition, currentContent, block) {
1396
1447
  const legacyContent = definition.legacyWholeFile?.trimEnd();
1397
1448
  if (!legacyContent) {
@@ -1479,7 +1530,7 @@ function withVcmClaudeHooks(settings) {
1479
1530
  ? hooks[definition.eventName]
1480
1531
  : [];
1481
1532
  hooks[definition.eventName] = [
1482
- ...existingMatchers.filter((entry) => !isVcmHookMatcher(entry)),
1533
+ ...existingMatchers,
1483
1534
  {
1484
1535
  ...(definition.matcher ? { matcher: definition.matcher } : {}),
1485
1536
  hooks: [
@@ -1524,7 +1575,10 @@ function renderAgentFrontmatter(name, description, options = {}) {
1524
1575
  const tools = options.tools ?? "Read, Grep, Glob, Bash, Edit, Write";
1525
1576
  const model = options.model ? `\nmodel: ${options.model}` : "";
1526
1577
  const effort = options.effort ? `\neffort: ${options.effort}` : "";
1527
- return `---\nname: ${name}\ndescription: ${description}\ntools: ${tools}${model}${effort}\n---`;
1578
+ const skills = options.skills?.length
1579
+ ? `\nskills:\n${options.skills.map((skill) => ` - ${skill}`).join("\n")}`
1580
+ : "";
1581
+ return `---\nname: ${name}\ndescription: ${description}\ntools: ${tools}${model}${effort}${skills}\n---`;
1528
1582
  }
1529
1583
  function renderSkillFrontmatter(name, description) {
1530
1584
  return `---\nname: ${name}\ndescription: ${description}\n---`;
@@ -19,6 +19,13 @@ ${renderRoleMemoryRules("architect")}
19
19
  - In Debug Mode and Architecture Diagnosis Mode, writing baseline unit tests for changed code and running required L0/L1 plus applicable L2/L3 checks are part of the implementation duty; tester still owns final validation.
20
20
  - Do not make product priority or approval decisions; route those questions back to project-manager.
21
21
 
22
+ ### Semantic Code Navigation
23
+
24
+ - Follow the preloaded \`vcm-code-navigation\` skill whenever work requires code definitions, implementations, references, callers, callees, or behavior paths. This applies in every Architect mode and in direct user communication.
25
+ - Use LSP for semantic relationships. Use Glob to locate files, Read to inspect complete code, and generated context, architecture documents, or runtime evidence for boundaries LSP does not model.
26
+ - Do not use the Grep tool or shell text-search commands such as \`grep\`, \`rg\`, or \`git grep\`.
27
+ - If LSP cannot resolve a required project-owned relationship, record it as unresolved. Do not replace semantic evidence with text matches.
28
+
22
29
  ### Work Persistence
23
30
 
24
31
  - Treat Architect artifacts, not Session memory, as continuation state.
@@ -45,9 +52,8 @@ ${renderRoleMemoryRules("architect")}
45
52
  ### Planning Code Reading
46
53
 
47
54
  - 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.
48
- - Use \`vcm-code-navigation\` for symbol definitions, implementations, references, call hierarchies, and bounded behavior paths. Start from generated indexes, use LSP semantic navigation when available, then read every resolved callable unit in full.
49
- - Use structural search when available and Grep for dynamic registrations, configuration or string edges, macros not resolved by LSP, documentation, and explicit fallback discovery. When LSP is available, do not treat Grep as proof of a complete symbol, caller, implementation, or reference set.
50
- - If LSP is unavailable or cannot resolve a required relationship, record the limitation and exact fallback evidence in \`architecture-evidence.md\`; do not claim compiler-accurate completeness from text search alone.
55
+ - 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 resolved callable unit in full.
56
+ - If LSP cannot resolve a required project-owned relationship, record the limitation in \`architecture-evidence.md\` and leave it unresolved.
51
57
  - Define the planning boundary as the affected feature or module and identify every existing or intended observable entry point for the behavior being changed.
52
58
  - Read the complete implementation of each relevant existing entry point.
53
59
  - 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.
@@ -202,7 +208,7 @@ The code-reading phase is complete only when:
202
208
  - every indirect callback, event, hook, queue, route, and dynamic dispatch path has been resolved
203
209
  - every relevant state reader and writer has been read
204
210
  - every relevant cross-file surface caller and consumer has been read
205
- - every semantic relationship records LSP, structural-search, Grep-fallback, runtime, external-boundary, or generated-boundary evidence
211
+ - every semantic relationship records LSP, runtime, external-boundary, or generated-boundary evidence
206
212
  - no unresolved project-owned symbol remains
207
213
 
208
214
  Do not diagnose the root cause or choose a fix before the Code Reading Closure is complete.
@@ -12,6 +12,13 @@ ${renderRoleMemoryRules("coder")}
12
12
  - Implement assigned file/function-level scaffold items; do not analyze, review, dispute, or redesign architecture, module boundaries, public contracts, dependency direction, durable docs strategy, validation strategy, or final test adequacy.
13
13
  - Treat the architecture plan and scaffold as execution instructions, not review targets. Do not critique, reinterpret, or challenge them during Coder work.
14
14
 
15
+ ### Semantic Code Navigation
16
+
17
+ - Follow the preloaded \`vcm-code-navigation\` skill whenever implementation requires code definitions, implementations, references, callers, callees, or behavior paths.
18
+ - Use LSP for semantic relationships. Use Glob to locate files and Read to inspect complete code.
19
+ - Do not use the Grep tool or shell text-search commands such as \`grep\`, \`rg\`, or \`git grep\`.
20
+ - If LSP cannot resolve a required project-owned relationship, record it as unresolved in the completion evidence. Do not replace semantic evidence with text matches.
21
+
15
22
  ### Shared Coding Standards
16
23
 
17
24
  - Before editing production code or tests, read and follow \`docs/CODING_STANDARDS.md\`.
@@ -26,7 +33,7 @@ ${renderRoleMemoryRules("coder")}
26
33
  - Do not stop before editing because of predicted architecture, design, contract, validation, or test failure; implement the assigned scaffold first.
27
34
  - Use \`.ai/generated/module-index.json\` to locate approved module source and test files.
28
35
  - Use \`.ai/generated/public-surface.json\` to avoid accidental public API drift.
29
- - When LSP is available, use definitions and references to locate assigned callable surfaces precisely. Use Grep for text or dynamic edges, not to broaden or reinterpret the approved implementation scope.
36
+ - Use LSP definitions and references to locate assigned callable surfaces precisely.
30
37
 
31
38
  ### Implementation
32
39
 
@@ -15,20 +15,23 @@ Use only these decisions:
15
15
  - \`approve\`: required gate evidence is present, current, internally consistent, sufficient for that gate, and has no gate-blocking finding.
16
16
  - \`request_changes\`: evidence is missing, stale, contradictory, incomplete, insufficient, not reviewable, or unsafe.
17
17
 
18
+ ## Semantic Code Navigation
19
+
20
+ Follow the preloaded \`vcm-code-navigation\` skill whenever a gate requires code definitions,
21
+ implementations, references, callers, callees, or behavior paths. Use LSP for
22
+ semantic relationships, Glob to locate files, Read to inspect complete code,
23
+ and generated context, architecture documents, or runtime evidence for
24
+ boundaries LSP does not model. Do not use the Grep tool or shell text-search
25
+ commands such as \`grep\`, \`rg\`, or \`git grep\`. If LSP cannot resolve
26
+ a required project-owned relationship, treat that evidence as unresolved and
27
+ return \`request_changes\`; do not replace semantic evidence with text matches.
28
+
18
29
  Every Gate Review is a complete review of the current gate inputs. Review all
19
30
  required evidence and rerun every required mechanical check before deciding.
20
31
  Do not carry forward prior conclusions, closed checks, or partial verification.
21
32
  Resolving prior findings does not replace the complete review. Return \`approve\`
22
33
  or \`request_changes\` only after the review is complete.
23
34
 
24
- Use \`vcm-code-navigation\` whenever a gate requires definitions, implementations,
25
- references, call hierarchies, or a bounded behavior path. Use LSP semantic
26
- navigation when available and read every resolved callable unit in full. Use
27
- structural search when available and Grep for dynamic or textual edges and
28
- explicit fallback discovery. Do not treat Grep as proof of a complete symbol,
29
- caller, implementation, or reference set when LSP is available. If LSP cannot
30
- resolve required evidence, record the limitation and exact fallback basis.
31
-
32
35
  ## Architecture Plan Gate
33
36
 
34
37
  Format is necessary but not sufficient. Do not approve an architecture plan
@@ -469,7 +472,7 @@ If there are no findings, write:
469
472
  None.
470
473
  \`\`\`
471
474
 
472
- Use Bash only for read-only inspection such as \`git diff\`, \`git status\`, \`git show\`, \`ls\`, \`rg\`, \`sed\`, or \`cat\`. Do not run tests, builds, formatters, generators, package managers, or commands that modify files.
475
+ Use Bash only for read-only inspection such as \`git diff\`, \`git status\`, \`git show\`, \`ls\`, \`sed\`, or \`cat\`. Do not run shell text-search commands, tests, builds, formatters, generators, package managers, or commands that modify files.
473
476
 
474
477
  Review only code, architecture, and documents; do not perform validation. Do not edit code, tests, durable docs, role files, route files, or handoff artifacts. Do not assign findings or remediation work to VCM roles, choose fixes, decide Replan, or decide whether user intervention is needed.
475
478
 
@@ -1,22 +1,24 @@
1
1
  export function renderVcmCodeNavigationSkillRules() {
2
2
  return `## Purpose
3
3
 
4
- Use this skill when Architect or Reviewer must establish symbol definitions, implementations, references, callers, callees, or a bounded behavior path from current-worktree evidence.
4
+ Use this skill when Architect, Coder, or Reviewer must establish symbol definitions, implementations, references, callers, callees, or a bounded behavior path from current-worktree evidence.
5
5
 
6
6
  ## Navigation Order
7
7
 
8
8
  1. Define the affected feature or module boundary and locate entry symbols with \`.ai/generated/module-index.json\` and \`.ai/generated/public-surface.json\` when available.
9
- 2. When LSP is available, use workspace or file symbols, definitions, implementations, references, and incoming or outgoing call hierarchy to resolve project-owned relationships.
10
- 3. Read the complete project-owned callable unit at every resolved location.
11
- 4. Expand one project-owned dependency hop at a time until the required behavior path has no unresolved symbol.
12
- 5. Use structural search when available, and use Grep for dynamic registrations, configuration or string edges, macros not resolved by LSP, documentation, and explicit fallback discovery.
9
+ 2. Start each navigation run with LSP \`documentSymbol\` on a known affected project source file. This initializes the actual role-session language server and proves that it can parse that file; an executable version probe is not workspace readiness.
10
+ 3. Use LSP workspace or file symbols, definitions, implementations, references, and incoming or outgoing call hierarchy to resolve project-owned relationships.
11
+ 4. If an initial workspace-symbol request is empty or reports indexing, do not conclude that the symbol is absent. After a successful file-symbol request, retry the same bounded workspace query at most two more times. If it still cannot resolve, record the operation and result as unresolved.
12
+ 5. Read the complete project-owned callable unit at every resolved location.
13
+ 6. Expand one project-owned dependency hop at a time until the required behavior path has no unresolved symbol.
14
+ 7. Use Glob, generated context, architecture documents, and runtime evidence to locate dynamic registrations, configuration or string edges, macros, documentation, and external boundaries that LSP does not model.
13
15
 
14
16
  ## Evidence
15
17
 
16
- - Record each resolved relationship and whether it came from LSP, structural search, Grep fallback, runtime evidence, or a generated boundary.
17
- - Do not treat a Grep result as proof of a complete definition, caller, implementation, or reference set when LSP is available.
18
+ - Record each resolved relationship and whether it came from LSP, runtime evidence, an external boundary, or a generated boundary.
18
19
  - When an empty LSP result contradicts a direct call in the code, another LSP result, or runtime evidence, treat the relationship as unresolved. Record the contradiction and use exact fallback evidence.
19
- - If LSP is unavailable or cannot resolve a relationship, record that limitation and the exact fallback evidence. Do not describe text-search results as compiler-accurate or complete.
20
+ - If LSP is unavailable or cannot resolve a required project-owned relationship, record that limitation and leave the relationship unresolved. Do not substitute text search for semantic navigation.
21
+ - Do not use the Grep tool or shell text-search commands such as \`grep\`, \`rg\`, or \`git grep\`.
20
22
  - Generated indexes and architecture docs locate likely code; reading current-worktree implementation establishes behavior.
21
23
 
22
24
  ## Context Boundary