Context
Fresh git worktrees created under .claude/worktrees/<name>/ (Claude Code's default) cannot run any script that imports ai/services.mjs. Reproducer:
cd .claude/worktrees/<some-name>
node -e "import('./ai/services.mjs')"
<h1 class="neo-h1" data-record-id="3">Error [ERR_MODULE_NOT_FOUND]: Cannot find module '.../ai/mcp/server/github-workflow/config.mjs'</h1>Root cause: .gitignore excludes ai/mcp/server/*/config.mjs (these are copy-from-template files for local overrides). Worktrees inherit the tracked tree but none of the ignored files, so every config.mjs is missing.
Attempting symlinks from the main checkout triggers a SECOND bug:
ln -s /main/checkout/.../config.mjs ai/mcp/server/<srv>/config.mjs
<h1 class="neo-h1" data-record-id="4">Running any Playwright test that imports via the service chain:</h1>
<h1 class="neo-h1" data-record-id="5">Error: Namespace collision in unitTestMode for Neo.core.Base</h1>
The symlinked config.mjs imports Base.mjs via a relative path, which Node resolves against the real (canonical) path of the symlink target — the main checkout's src/core/Base.mjs. When the worktree-local src/core/Base.mjs ALSO gets imported (by the test itself), Neo.setupClass sees the same namespace registered from two different file paths and throws under unitTestMode: true. Copies (not symlinks) work because Node resolves relatives against the copy's own location.
Impact
Every Claude Code session in a new worktree that touches ai/scripts/, ai/services.mjs, or any SDK-consuming code hits this wall. Discovered during #10090 and #10092 work — fixed both times by manually copying four config.mjs files. That's institutional tax per session.
The Ask
Add a bootstrap script and a startup note:
ai/scripts/bootstrapWorktree.mjs — copies ai/mcp/server/{github-workflow,knowledge-base,memory-core,neural-link}/config.mjs from the repo's main checkout (resolved via git worktree list --porcelain) into the current worktree. Idempotent; skips files that already exist. Refuses to run if CWD is the main checkout itself.
AGENTS_STARTUP.md §Harness-Memory-Wiring — append a Claude Code note:
Worktree bootstrap: ai/mcp/server/*/config.mjs is gitignored and does not travel into new worktrees. Before running any SDK-consuming script or test-unit that imports ai/services.mjs, run node ai/scripts/bootstrapWorktree.mjs. Do NOT use symlinks — they break under unitTestMode due to realpath-based resolution of Base.mjs.
Acceptance Criteria
Origin Session ID
d9eb5e76-5430-45f7-b3ea-8600664d28f9
Context
Fresh git worktrees created under
.claude/worktrees/<name>/(Claude Code's default) cannot run any script that importsai/services.mjs. Reproducer:cd .claude/worktrees/<some-name> node -e "import('./ai/services.mjs')" <h1 class="neo-h1" data-record-id="3">Error [ERR_MODULE_NOT_FOUND]: Cannot find module '.../ai/mcp/server/github-workflow/config.mjs'</h1>Root cause:
.gitignoreexcludesai/mcp/server/*/config.mjs(these are copy-from-template files for local overrides). Worktrees inherit the tracked tree but none of the ignored files, so everyconfig.mjsis missing.Attempting symlinks from the main checkout triggers a SECOND bug:
ln -s /main/checkout/.../config.mjs ai/mcp/server/<srv>/config.mjs <h1 class="neo-h1" data-record-id="4">Running any Playwright test that imports via the service chain:</h1> <h1 class="neo-h1" data-record-id="5">Error: Namespace collision in unitTestMode for Neo.core.Base</h1>The symlinked
config.mjsimportsBase.mjsvia a relative path, which Node resolves against the real (canonical) path of the symlink target — the main checkout'ssrc/core/Base.mjs. When the worktree-localsrc/core/Base.mjsALSO gets imported (by the test itself),Neo.setupClasssees the same namespace registered from two different file paths and throws underunitTestMode: true. Copies (not symlinks) work because Node resolves relatives against the copy's own location.Impact
Every Claude Code session in a new worktree that touches
ai/scripts/,ai/services.mjs, or any SDK-consuming code hits this wall. Discovered during #10090 and #10092 work — fixed both times by manually copying fourconfig.mjsfiles. That's institutional tax per session.The Ask
Add a bootstrap script and a startup note:
ai/scripts/bootstrapWorktree.mjs— copiesai/mcp/server/{github-workflow,knowledge-base,memory-core,neural-link}/config.mjsfrom the repo's main checkout (resolved viagit worktree list --porcelain) into the current worktree. Idempotent; skips files that already exist. Refuses to run if CWD is the main checkout itself.AGENTS_STARTUP.md §Harness-Memory-Wiring— append a Claude Code note:Acceptance Criteria
ai/scripts/bootstrapWorktree.mjs— resolves main checkout via git, copies fourconfig.mjsfiles, idempotentAGENTS_STARTUP.mdupdated with the worktree bootstrap note under Harness-Memory-WiringOrigin Session ID
d9eb5e76-5430-45f7-b3ea-8600664d28f9