MCP tools don't populate output.output in the tool.execute.after hook — the MCP content flows through OpenCode's internal parts pipeline instead. This caused a crash: undefined is not an object (evaluating 'text.length') in the truncate function.
39 KiB
Agent Infra Extraction — Handoff Plan
Status: ✅ Complete through Phase 5. Remnant reduced to BFF-overlay only. All phases executed and committed. See per-phase status below.
Goal: Move repo-agnostic agent infrastructure out of Remnant into
~/dotfiles/.agents/ (existing dotfiles repo), wire it into each tool's
global config so every project inherits it automatically, and reduce
Remnant's footprint to a small project-specific overlay (BFF reminder, project
AGENTS.md). After this work, Remnant can get back to being a Remnant codebase
instead of an agent-infra lab.
Forward-looking work (MFE bootstrap, kanban unification, per-session tmp
capture, project.config.js extraction, llama-server module, MemPalace, eval
scaffolding, agentic-framework research) has moved to
dotfiles-agent-infra-roadmap.md. This doc
now covers only the extraction itself and the post-extraction validation
findings.
Decisions (confirmed with user)
| Decision | Value |
|---|---|
| Shared infra location | ~/dotfiles/.agents/ (existing repo, matches user's dotfiles naming) |
| Sharing mechanism | Inherit via global tool config; verify global+project plugins/hooks coexist additively |
| MCP server name | Rename remnant-agents → all-agents (safe — only 4 string refs, no permission impacts) |
| Uncommitted files | Already committed as-is on main (Phase 1 done) |
| Research docs | Move to shared infra (general-purpose, useful to any project) |
| Modelfiles | Leave for now; address later |
| Global Copilot config | Yes — create ~/.vscode-server/data/User/prompts/ and add global MCP entry |
| Project-specific bits | Only Remnant's root AGENTS.md + the BFF/apps/client/src/pages/ reminder |
agent-infrastructure.md split |
Lossless — ~95% to shared, thin pointer + Remnant tradeoffs stay |
What's shareable vs. project-specific
Shareable (moves to ~/dotfiles/.agents/):
.agents/AGENTS.md— agent-infra design principles.agents/agents/*.md— brainstorm, build, orchestrator, research.agents/skills/research.md— research methodology.agents/hooks/*.sh— all six hook scripts (pre/post-tool-use, session-start, stop, pre-compact, user-prompt-submit) except the BFF reminder block inpost-tool-use.sh.agents/mcp/index.ts— MCP server (will be refactored to auto-discover agents/skills from sibling dirs).agents/frameworks/opencode/plugin.ts— OpenCode plugin harness.agents/frameworks/github/hooks.json— Copilot harness configdocs/research/*.md(5 files) — ai-coding-best-practices, human-llm-interpretation-overlap, intent-interpretation-action-plan, llm-intent-interpretation, text-communication-interpretationdocs/explorations/text-intent-interpretation-research.mddocs/ai_architectures.mddocs/projects/agent-infrastructure.md— almost entirely shared knowledge (see "Lossless split" below)docs/infra/LLAMA-SERVER-CUDA-WSL2.md— general llama.cpp/CUDA setup notes
Project-specific (stays in Remnant):
- Root
AGENTS.md(Remnant overview, package pointers, monorepo rules) - BFF reminder +
apps/client/src/pages/path checks (currently embedded inpost-tool-use.sh) - Nested
AGENTS.mdfiles inapps/,packages/ verification.md,docs/TODO.md,docs/projects/*(other than the agent-infrastructure split-off)- The two
.modelfilefiles — leave in.agents/with aMODELFILES.mdnote
Verification gates (Phase 0 — COMPLETE)
-
✅ OpenCode plugin coexistence — additive; all hooks run in sequence. Global dir:
~/.config/opencode/plugins/(not~/.opencode/plugins/). -
✅ OpenCode MCP merge — configs merge (not replace). Global
mcpentries- project
mcpentries both load; project-level keys win on conflicts.
- project
-
✅ Copilot global hook support — EXISTS. User-level hooks dir:
~/.copilot/hooks/(macOS/Linux) per GitHub Copilot hooks reference. Load order is additive: repo.github/hooks/*.json→ user~/.copilot/hooks/*.json→ reposettings.jsoninline → user~/.copilot/settings.jsoninline → plugins. Symlink~/.copilot/hooks/agent-support.json→ dotfiles hooks.json = global coverage. No per-project stub needed. (Initial finding was wrong — VS Code docs don't cover Copilot's own config surface; always check docs.github.com first.) -
✅ VS Code global MCP —
~/.vscode-server/data/User/mcp.json(create viaMCP: Open Remote User Configurationcommand or directly). -
✅ OpenCode hook overlay — BFF reminder ships as a separate project-local plugin file. No merged copy of
post-tool-use.shneeded.
Target layout
~/dotfiles/.agents/ ← canonical shared infra
├── AGENTS.md ← from remnant/.agents/AGENTS.md
│ + "Research Discipline" section
│ for global lessons/practices
│ (framework-agnostic: Copilot,
│ OpenCode, Claude Code all load
│ AGENTS.md natively — no
│ tool-specific config needed)
├── INSTALL-NOTES.md ← Phase 0 findings
├── install.sh ← one-time setup script (idempotent)
├── agents/
│ ├── brainstorm.md
│ ├── build.md
│ ├── orchestrator.md
│ └── research.md
├── skills/
│ └── research.md
├── hooks/
│ ├── pre-tool-use.sh
│ ├── post-tool-use.sh ← BFF block removed
│ ├── session-start.sh
│ ├── stop.sh
│ ├── pre-compact.sh
│ └── user-prompt-submit.sh
├── frameworks/
│ ├── opencode/plugin.ts
│ └── github/hooks.json
├── mcp/
│ └── index.ts ← auto-discovers agents/skills/
└── docs/
├── agent-infrastructure.md ← the moved 855-line doc
├── ai-coding-best-practices.md ← from docs/research/
├── ai_architectures.md
├── human-llm-interpretation-overlap.md
├── intent-interpretation-action-plan.md
├── llm-intent-interpretation.md
├── text-communication-interpretation.md
├── text-intent-interpretation-research.md
└── llama-server-cuda-wsl2.md
Global wiring (created/modified by install.sh):
~/.config/opencode/opencode.json ← merge MCP entry
~/.config/opencode/AGENTS.md ← symlink → dotfiles AGENTS.md (OpenCode global rules)
~/.config/opencode/plugins/agent-support.ts ← symlink → dotfiles plugin
~/.config/opencode/agents/ ← symlinks → dotfiles agents/*.md (added in post-Phase-4 fix)
~/.copilot/hooks/agent-support.json ← generated by install.sh with absolute dotfiles paths (not a symlink)
~/.vscode-server/data/User/prompts/ ← create dir (currently missing)
~/.vscode-server/data/User/mcp.json ← global VS Code MCP registration
Remnant (post-extraction, actual):
remnant/
├── AGENTS.md ← unchanged
├── .agents/
│ ├── README.md ← "shared infra: ~/dotfiles/.agents"
│ ├── hooks/
│ │ └── post-tool-use-remnant.sh ← BFF reminder only
│ ├── omnicoder.modelfile ← archived
│ └── omnicoder2.modelfile ← archived
│ ⚠️ MODELFILES.md not created (planned but skipped)
├── .github/hooks/agent-support.json ← gitignored; BFF PostToolUse only
├── .vscode/mcp.json ← exa only (remnant-agents removed)
└── opencode.json ← mcp.remnant-agents removed;
permission overrides retained
Note: .opencode/ was gitignored; deleted from filesystem (agents now global).
Phases
Phase 0 — Verify coexistence ✅ DONE
Resolved all five gates. INSTALL-NOTES.md not produced (findings inline
above).
Phase 1 — Checkpoint Remnant ✅ DONE
Already committed on main.
Phase 2 — Populate ~/dotfiles/.agents/ ✅ DONE
- Copy (not move) shareable files from
remnant/.agents/into~/dotfiles/.agents/. Add a "Research Discipline" section to~/dotfiles/.agents/AGENTS.mdfor cross-tool meta-guidance (e.g. check docs.github.com first for Copilot configuration questions). This is the canonical home for global lessons — AGENTS.md is natively loaded by Copilot, OpenCode, and Claude Code. Never use tool-specific mechanisms (OpenCodeinstructions:config, VS Code.instructions.mdfiles) for guidance that belongs in AGENTS.md. - Copy
docs/research/*.md(5 files),docs/explorations/text-intent-interpretation-research.md,docs/ai_architectures.md,docs/infra/LLAMA-SERVER-CUDA-WSL2.mdinto~/dotfiles/.agents/docs/. - Split
docs/projects/agent-infrastructure.md(lossless):- Moves to
~/dotfiles/.agents/docs/agent-infrastructure.md: the entire current doc minus the items below. This includes hook architecture, model scale profiles, MCP protocol status, OpenCode verified facts, the testing plan, open issues — all general infra knowledge. - Stays in
remnant/docs/projects/agent-infrastructure.md(rewritten to a thin pointer):- Reference link to the shared doc
- Remnant-specific "Known Tradeoffs" row: "Instructions glob trimmed to
root
AGENTS.mdonly" + theapi//client//core/mitigation - Mention of BFF reminder hook and its Remnant scope
- Any items currently open that have Remnant-specific test cases (e.g. item
31 mentions
apps/api/package.jsonpaths — generalize for shared doc; keep concrete Remnant examples as a Remnant section)
- Moves to
- Refactor
mcp/index.ts: auto-discoveragents/*.mdandskills/*.mdrelative to the script location, instead of a hand-maintained registry. Removes a friction point when adding new agents/skills. - Rename MCP server
remnant-agents→all-agentsinmcp/index.ts. - Refactor
hooks/post-tool-use.sh: remove the BFF +apps/client/src/pages/block. Document the extension point (comment: "project-local additions live in a sibling hook file or repo-local override"). - Write
install.sh:- Detects existing global config (idempotent re-run safe).
- Creates missing dirs (
~/.vscode-server/data/User/prompts/,~/.copilot/hooks/,~/.config/opencode/plugins/). - Symlinks plugin into
~/.config/opencode/plugins/agent-support.ts. - Generates
~/.copilot/hooks/agent-support.jsonwith absolute paths to~/dotfiles/.agents/hooks/*.sh(not a symlink — avoids needing per-project hook stubs for relative-path resolution). - Merges
all-agentsMCP entry into~/.config/opencode/opencode.jsonviajq. - Writes
~/.vscode-server/data/User/mcp.jsonwith theall-agentsMCP entry.
- Commit to dotfiles repo. (Push wherever; local-only is fine.)
Divergences from plan: jq replaced with node (not universally
available); install.sh step 1 generates Copilot hooks JSON with absolute paths
(not a symlink) to avoid per-project relative-path resolution issues. Step 3
added post-Phase-4 to wire ~/.config/opencode/agents/.
Phase 3 — Run install.sh ✅ DONE
- Symlinks and generated files verified.
- Smoke tests passed:
RESEARCH_PROMPT: OK,HOOK_BLOCK: OK. - Bug found and fixed: OpenCode uses tool name
bash(notrun_in_terminal);pre-tool-use.shcase statement updated in both repos.
Phase 4 — Strip Remnant ✅ DONE
- ✅ Deleted
agents/,skills/,frameworks/,mcp/,AGENTS.mdfrom.agents/ - ✅
.agents/hooks/reduced topost-tool-use-remnant.shonly - ⚠️
MODELFILES.mdstub not created (skipped — low value) - ✅
.vscode/mcp.json:remnant-agentsdropped,exaretained - ✅
opencode.json:mcp.remnant-agentsremoved, permission overrides kept - ✅
AGENTS.mdupdated to reference~/dotfiles/.agents/AGENTS.md - ✅ Docs deleted from
remnant/docs/(research/, ai_architectures.md, etc.) - ✅
agent-infrastructure.mdrewritten as thin pointer - ✅
.agents/README.mdadded - ✅ Committed (
daf53a3,8a61128)
Post-phase fix: .opencode/ had dead symlinks (pointed to deleted
.agents/frameworks/ and .agents/agents/). Was gitignored so not in git
history. Fixed by wiring agents globally via install.sh step 3
(~/.config/opencode/agents/), then deleting .opencode/ from the filesystem.
Phase 5 — Verify Remnant still works ✅ DONE (automated checks)
- ✅
npm run build:strictpasses (2 scripts ran, 15 skipped via wireit cache) - ✅ All 6 shared hook scripts pass
bash -nsyntax check - ✅
post-tool-use-remnant.shpassesbash -n - ✅
~/.config/opencode/agents/wired with 4 symlinks → dotfiles - ✅
~/.copilot/hooks/agent-support.jsonpresent (generated, absolute paths) - ✅ Remnant
.agents/contains only: README.md, hooks/, omnicoder*.modelfile - ⏳ Live session checks (require manual restart):
/researchetc. slash commands, hook block in live session, BFF reminder injection, VS Code MCPall-agentsconnect
Notes (post-execution)
- All rename touch points done:
remnant-agents→all-agentsin mcp/index.ts, opencode.json, .vscode/mcp.json, AGENTS.md. <PostToolUse-context>block working as designed — injected to model only, not shown in chat transcript (seepost-tool-use.shline ~137).- Global Copilot hook mechanism confirmed:
~/.copilot/hooks/exists and is additive with repo hooks. No per-project stubs needed when paths are absolute.
Out of scope (do later)
- Salvaging
omnicoder*.modelfilecontent into shared system-prompt references — user chose "leave for now." - Publishing dotfiles as a public agent-infra repo / npm package.
- Refactoring hooks to be platform-agnostic (item 22 in the migrated
agent-infrastructure.md) — track in the shared repo after extraction. - Make
.agents/TypeScript files conform to Remnant's ESLint rules — theadditionalIgnoresbypass added in Phase 2 is a shortcut, not a solution..agents/mcp/index.tsand.agents/frameworks/opencode/plugin.tsuseimport.meta.urldirectly (blocked byno-restricted-syntax) and have minor unused-var patterns. Options: (a) replaceimport.meta.urlusages with the approvedfindNearestPackageRoot/new URL('./sibling', import.meta.url)patterns where valid, (b) introduce a per-file exception comment for the genuinely exceptional cases (e.g. portable hook resolution in a symlinked global plugin), (c) move all.agents/TS into a proper subpackage with its owntsconfig.jsonand relaxed rules. Remove.agents/**fromadditionalIgnoresonce resolved.
Rollback
Single revert: each phase is a separate commit. Phase 4 (strip Remnant) is the
only destructive one, and Phase 2's copies survive. Worst case:
git revert <phase-4-commit> restores Remnant, dotfiles copies stay.
WIP: AGENTS.md context survival after compaction
Status: problem noted; solution not designed. Break out into a separate project doc when ready to act on it.
The problem
AGENTS.md loading is a session-start event. Once loaded, the content sits in
the context window as a regular document — it does not re-inject. After
compaction/summarization, the summary may preserve high-level framing but can
silently drop specific rules, enforcement hierarchy details, or lessons added
mid-session. The "Lost in the Middle" effect applies even before compaction:
guidance in the middle of a long context receives less model attention than
content at the tail (hooks inject at the tail specifically to counter this).
The .agents/AGENTS.md enforcement hierarchy already acknowledges this: "Root
AGENTS.md sections: Context-start only. Subject to 'lost in the middle.'" The
user confirmed this happened: .agents/AGENTS.md was read before compaction
this session, but its content was not reliably carried through.
What the research says (verified + falsified + re-corrected May 2026)
VS Code Copilot — correction was itself over-corrected. Final answer:
VS Code docs group copilot-instructions.md, AGENTS.md, and CLAUDE.md as
"always-on instructions" injected per-request — but this only applies to
files at the workspace root. The docs explicitly note: "Support of
AGENTS.md files outside of the workspace root is currently turned off by
default."
This session is direct evidence. .agents/AGENTS.md is a subdirectory file,
not the workspace-root AGENTS.md. It was read_file'd during this session and
entered the context as a regular document. After compaction the summary dropped
the specific content — enforcement hierarchy, forbidden patterns.
Post-compaction, the Copilot model then proposed .instructions.md files and
OpenCode instructions: config — exactly the approaches the forbidden patterns
section bans — because that guidance was no longer in the effective context.
Root-level AGENTS.md (workspace root) = always-on, survives compaction.
Nested AGENTS.md in subdirectories = not always-on, read once on explicit
read_file, lost on compaction.
The problem is real for both tools for any AGENTS.md that isn't the workspace
root file. This repo's enforcement lives in .agents/AGENTS.md, not the
workspace root — which means it is compaction-vulnerable in VS Code Copilot too.
OpenCode (opencode.ai/docs/rules + config):
- AGENTS.md loaded at session start via directory traversal + global
~/.config/opencode/AGENTS.md. No re-injection after compaction is documented. Thecompactionagent is a hidden system agent; its behavior after summarizing context is not specified. There is no/docs/compactionpage — no public spec exists for what happens to AGENTS.md content in the compacted summary. - Whether OpenCode re-injects even the root AGENTS.md after compaction is unknown. Needs live testing.
Summary of the asymmetry:
| File | Copilot VS Code | OpenCode |
|---|---|---|
Root AGENTS.md (workspace root) |
always-on per-request ✅ | session-start only ⚠️ |
Nested AGENTS.md (subdirectory) |
off by default, read-once ⚠️ | session-start traversal, read-once ⚠️ |
| Both after compaction | root survives; nested lost | unknown (undocumented) |
Key implication for this repo: the enforcement hierarchy and forbidden
patterns live in .agents/AGENTS.md, not the workspace-root AGENTS.md. That
makes them compaction-vulnerable in VS Code Copilot. None of the candidate
mitigations below have been evaluated yet — this problem is unsolved.
Instruction files vs AGENTS.md (revised):
- VS Code Copilot: root AGENTS.md and root
copilot-instructions.mdare both always-on per-request — equivalent. The ban on.instructions.mdfiles is about path-scoping being non-portable, not injection frequency. - OpenCode:
instructions:config field is session-start — same vulnerability as nested AGENTS.md in OpenCode.
Open questions (narrowed after falsification)
- Does OpenCode re-inject root AGENTS.md after compaction, or is it also lost? (Needs live testing — not documented.)
- Does OpenCode's
instructions:config field content survive in the compacted summary, or is it lost by the same mechanism? - Does Claude Code (invoked directly, not via VS Code) have per-request injection for root AGENTS.md like VS Code Copilot?
Candidate mitigations (not yet chosen)
-
Extend
pre-compact.sh: Before summarization fires, scan the current context forread_filecalls onAGENTS.mdpaths and emit their content into the compaction context so the summary captures them explicitly. -
Session-start hook re-read: If
session-start.shcan detect it is running post-compaction (e.g. a state file exists from a priorpre-compact.shrun), re-inject the full rootAGENTS.mdcontent immediately. -
PostToolUse periodic re-injection: The current
post-tool-use.shself-check fires every 15 tool calls. A similar counter could re-inject a condensed version of critical AGENTS.md sections (enforcement hierarchy, forbidden patterns) at the same cadence. -
Track and replay: Maintain a list of AGENTS.md files read this session (via PostToolUse file-path check). On
pre-compact.sh, emit the paths as a "re-read these after compaction" instruction so the post-compaction agent gets them back. -
Stop relying solely on AGENTS.md for critical rules: Move critical, never-forget rules out of AGENTS.md into PreToolUse hard blocks or PostToolUse reminders. Reserve AGENTS.md for architecture/rationale that is worth losing under compaction. This is partly already the design intent — this is a reminder to be strict about it.
Post-Extraction Validation (May 23, 2026)
Validation pass over the extraction work. No code changes made — findings and recommendations only.
✅ Verified working
Dotfiles ~/dotfiles/.agents/ payload is complete:
AGENTS.md(289 lines) ✅agents/—AGENTS.md,brainstorm.md,build.md,orchestrator.md,research.md✅skills/research.md✅hooks/— all six shared hooks (pre-tool-use,post-tool-use,session-start,stop,pre-compact,user-prompt-submit) ✅mcp/index.ts+package.json+package-lock.json✅frameworks/opencode/plugin.ts(319 lines, with the Jinja-safechat.messageinjection) ✅frameworks/github/hooks.json(full six-hook registration) ✅docs/— all nine moved docs present (agent-infrastructure.md,ai-coding-best-practices.md,ai_architectures.md,human-llm-interpretation-overlap.md,intent-interpretation-action-plan.md,llm-intent-interpretation.md,text-communication-interpretation.md,text-intent-interpretation-research.md,llama-server-cuda-wsl2.md) ✅install.sh— generates Copilot global hooks JSON with absolute paths, symlinks OpenCode plugin + agents + globalAGENTS.md, merges OpenCode and VS Code MCP entries, installs MCP server deps ✅
Global wiring on this machine is live:
~/.copilot/hooks/agent-support.json— generated, absolute paths ✅~/.config/opencode/AGENTS.md→~/dotfiles/.agents/AGENTS.md✅~/.config/opencode/plugins/agent-support.ts→~/dotfiles/.agents/frameworks/opencode/plugin.ts✅~/.config/opencode/agents/{brainstorm,build,orchestrator,research}.mdsymlinks ✅~/.config/opencode/opencode.json— hasall-agentsMCP entry ✅~/.vscode-server/data/User/mcp.json— has bothall-agentsandexa✅~/.vscode-server/data/User/prompts/— exists (empty) ✅
Remnant overlay is correctly scoped:
.agents/AGENTS.md(Remnant-specific) ✅.agents/README.md✅.agents/hooks/post-tool-use-remnant.sh(BFF only) ✅.agents/frameworks/github/{AGENTS.md, hooks.json}— project Copilot hook registration ✅.agents/frameworks/opencode/{AGENTS.md, hooks.ts}— project OpenCode plugin ✅.github/hooks/hooks.json→../../.agents/frameworks/github/hooks.json✅.opencode/plugins/hooks.ts→../../.agents/frameworks/opencode/hooks.ts✅.opencode/AGENTS.mdwarning file ✅
⚠️ Gaps and bugs in dotfiles (pre-push)
These should be fixed before squashing/pushing the dotfiles commits.
-
~/dotfiles/.agents/AGENTS.mdreferences stale paths from the pre-extraction layout. Three places reference.agents/github/and.agents/opencode/but the canonical paths are now.agents/frameworks/github/and.agents/frameworks/opencode/:- "The Copilot harness (
.agents/github/hooks.json) and OpenCode plugin (.agents/opencode/plugin.ts) both delegate…" (Hook Files section) - "
.agents/opencode/plugin.ts— OpenCode plugin harness (canonical)" (Tool-Specific Entry Points section) - "
.agents/github/hooks.json— Copilot harness config (canonical)" (same section) - Also: the surrounding sentences claim symlinks point from
.github/hooks/agent-support.jsonand.opencode/plugins/agent-support.ts"those directories are gitignored." In dotfiles this is wrong on two counts: (a) global wiring uses~/.copilot/hooks/agent-support.jsonand~/.config/opencode/plugins/agent-support.ts, (b) at Remnant the project symlink files are namedhooks.jsonandhooks.ts, notagent-support.*. The doc was written for the pre-split layout and never updated.
- "The Copilot harness (
-
~/dotfiles/.agents/AGENTS.mdlinks into../docs/research/...— Remnant-relative paths that don't resolve in dotfiles. Two link targets:[docs/research/intent-interpretation-action-plan.md](../docs/research/intent-interpretation-action-plan.md)[docs/research/ai-coding-best-practices.md](../docs/research/ai-coding-best-practices.md)Should be./docs/intent-interpretation-action-plan.mdand./docs/ai-coding-best-practices.md(the docs moved into.agents/docs/, notdocs/research/).
-
No "Research Discipline" section in
~/dotfiles/.agents/AGENTS.md. Plan Phase 2 step 1 specifically called for adding one (replacing the Copilot-only memory at~/memories/research-discipline.md). The Copilot memory still exists as a stopgap because the dotfiles AGENTS.md doesn't carry the equivalent guidance. -
frameworks/github/AGENTS.mdandframeworks/opencode/AGENTS.mdare missing from dotfiles. Remnant added rich, generic API-facts AGENTS.md files for each framework dir (62ee78c) — the content is not Remnant-specific (verified VS Code hooks output formats, OpenCode plugin API facts, Jinja constraint, overconfidence warnings). These belong in dotfiles alongside the framework configs; right now an agent editing the globalframeworks/opencode/plugin.tswon't see them. -
install.shlocation. Currently~/dotfiles/.agents/install.sh. Recommendation: move to~/dotfiles/install.shso the dotfiles repo has a discoverable bootstrap entry point (and to leave room for installing other dotfiles content beyond.agents/). The script usesDOTFILES_AGENTS="$(cd "$(dirname "$0")" && pwd)"— moving it requires changing that one line to e.g.DOTFILES_AGENTS="$(cd "$(dirname "$0")" && pwd)/.agents". No other path math in the script needs to change. -
install.shdoes not symlink anything into~/.copilot/beyondhooks/. Copilot also supports user-level inline settings at~/.copilot/settings.json. Not required, just noting it's a future extension point if more global Copilot config becomes shareable. -
install.shdoesn't create the~/.vscode-server/data/User/prompts/dir as part of the run on this machine — directory exists but is empty. Confirmed step 6 ran (mkdir -p). Working as intended; the dir is the surface for VS Code prompt files but none have been authored yet. No action needed unless we plan to ship.prompt.mdfiles from dotfiles. -
install.shhas no uninstall counterpart. Low-priority. Useful if we start moving the script around and want clean state for testing. -
Exa MCP has an undocumented rate limit; agents fan out parallel
mcp_exa_web_search_exacalls and hit it. Observed May 23, 2026: 8 parallel searches in one turn → all cancelled. Two complementary fixes, both in dotfiles:- PostToolUse nudge in
~/dotfiles/.agents/hooks/post-tool-use.sh: after anymcp_exa_*call, inject a reminder ("Exa rate-limits parallel calls — issue web searches serially, max ~2 per turn") so the model learns the pattern without a hard block. AGENTS.mdentry under a new "External service quirks" section listing per-service constraints (Exa rate limit, GitHub API limits whenmcp_github_*lands, etc.). Loaded at session start so the model has it before issuing the first call.- Optional PreToolUse soft-warn: count
mcp_exa_*calls per turn via a/tmp/.exa-turn-countfile (reset onuser-prompt-submit); warn (don't deny) past N=2.
- PostToolUse nudge in
🧹 Commit-history cleanup recommendations
Sonnet committed in tiny increments. Both repos have a series of unpushed "fix(install)/fix(plugin)/fix(hooks)" commits that should be squashed before publishing.
~/dotfiles — 10 unpushed commits on main past 4a44460 (origin/main).
Suggested single squashed commit:
feat(.agents): shared agent infrastructure + install.sh
- Hooks, agents, skills, MCP server, OpenCode plugin, Copilot hook config
- install.sh wires global Copilot hooks (absolute paths), OpenCode plugin
+ agents + AGENTS.md (symlinks), MCP entries for OpenCode and VS Code
- See .agents/docs/agent-infrastructure.md for design rationale
Constituent commits to fold in:
6b07e4c 690178d 88435d6 f4017ab 5c12257 f0d21e9 2949981 3738732 9544b4e 14c132a.
Suggested workflow: git reset --soft 4a44460 && git commit -m '…' (or
interactive rebase with s on every commit after the first). Address items 1–4
above first so the squash captures clean state.
~/code/remnant — many unpushed commits past 0d0a3a8 (origin/main); the
agent-infra-related ones form a contiguous block from 2d58147 through
78c8449. Suggested squash boundary:
- Keep
2d58147as the first commit of the block, or replace it with a new "feat: extract shared agent infra to ~/dotfiles/.agents" message that covers the full final state. - Fold in:
5a7d220 c41c142 daf53a3 8a61128 2b0ea1e e9f3529 9191a44 fc2a944 62ee78c dc3ec9c 78c8449.
The non-agent-infra commits before 2d58147 (the older "chore: more agentic
coding updates …" block) are pre-extraction and can be left as-is or squashed
separately depending on taste.
📋 Pending work that's still extraction-scoped
MODELFILES.mdstub (Phase 4 item 3) — explicitly skipped; consider whether the twoomnicoder*.modelfilefiles in Remnant should be moved to~/dotfiles/.agents/modelfiles/and dropped from Remnant entirely. They aren't Remnant-specific..agents/TypeScript ESLint conformance (Out-of-scope list, item 4) — still tracked; no movement.- Item 22 in
agent-infrastructure.md(platform-agnostic hook scripts) — unchanged. - Live-session smoke tests from Phase 5 (slash commands, BFF reminder injection,
VS Code MCP
all-agentsconnect) — still marked ⏳. Should be retired or confirmed after the next session restart.
🚀 Starting a new project on the extracted infra (MFE)
Moved to dotfiles-agent-infra-roadmap.md. The short version:
- Inheriting the global infra is automatic once
install.shhas run on the machine — no per-project setup beyond anAGENTS.mdand (optionally) an overlay hook. - The blocker for full MFE adoption is that
stop.shhardcodes Remnant's task layout (docs/TODO.md,docs/projects/COMPLETED.md,docs/explorations/). This is part of the hook audit below and is addressed by theproject.config.jsextraction tracked in the roadmap.
🆕 Future task — unify kanban/task doc structure across projects
Moved to
dotfiles-agent-infra-roadmap.md → Kanban / task-doc unification.
Driver recorded here for context: stop.sh hardcodes Remnant's task layout, and
the path forward (after project.config.js lands) is for the hook to support
multiple shapes driven by config rather than a single hardcoded one.
🔎 Full hook-script Remnant-isms audit (May 23, 2026 — addendum)
Re-read every hook in ~/dotfiles/.agents/hooks/ line-by-line after the
stop.sh miss. Findings below — anything not listed is reviewed and verified
generic.
pre-tool-use.sh — multiple hardcodes that bite non-Remnant projects:
-
Policy 5 — hardcoded ports 3000/3001 for dev-server detection:
ss -tlnp 2>/dev/null | grep -qE ':300[01]\s'These are Remnant's
apps/api(3000) andapps/clientVite HMR (3001). MFE uses different ports (likely 5173 for Vite, plus app-specific). Fix: read ports from a per-project config (.agents/project.jsonwith adevPortsarray) or frompackage.jsonscript scraping, default to common ports if unset. -
Policy 8 — error message references
npm run build:core(Remnant has apackages/corepackage that owns the codegen step; other projects don't):"Edit the source files (controller.ts, routes.ts, business-logic.ts) instead and run 'npm run build:core' to regenerate." The
.generated.tsblock itself is generic, but the message and example filenames are Remnant-specific. Fix: parameterize the rebuild command via project config, or genericize the message ("run the generator script for the affected package"). -
Policies 9 & 10 — assume wireit is the build tool. Both error messages reference wireit cache/fingerprint behavior and tell the agent to edit
wireitconfig inpackage.json. Remnant uses wireit; MFE may not. The blocks themselves (rm .wireit,-- --forcewith npm run) are still useful — they fire on the literal string.wireitand the--forceflag — but the messages will be confusing for non-wireit projects. Fix: detect wireit presence (grep -q '"wireit"' package.json) and skip the block when not present, or rewrite messages to be tool-agnostic. -
Policy 11 — assumes npm workspaces (
npm run format -- <file>propagation issue). True for any npm-workspaces monorepo; false for single-package projects (where the arg works fine). Low-impact: even in a single-package repo, the block just prevents a working command. Fix: gate on presence ofworkspacesfield in rootpackage.json. -
Policy 14 — hardcoded
apps/*/package.jsonandpackages/*/package.jsonpaths. This is the exact Remnant monorepo layout (apps/api,apps/client,packages/core, etc.). MFE may useapps/+packages/too but the underlying concern — that reading workspace package.json files auto-injects nested AGENTS.md and exhausts context — applies to any monorepo with nested AGENTS.md files, regardless of directory names. Also: the message hardcodes "32K context window", which is a specific assumption about the local model (qwen3-coder-30b on llama-server). Cloud models have 200K+. Fix: discover workspace dirs frompackage.jsonworkspacesfield; drop the model-size number or make it configurable.
post-tool-use.sh — mostly generic, one cosmetic issue:
-
vscode_renameSymbolreminder uses Remnant-flavored example strings:deleteX: archiveX,openDialog('delete-item'),AppDialog handle='delete-item',deleteSuccess/Loading/Error. These are illustrative patterns from Remnant's Solid.js store + AppDialog component. They're not incorrect for other projects, just visibly Remnant-coded. Low-priority: either genericize ("e.g. aliased store keys likeoldName: newNamein a returned object") or leave as concrete examples — they still teach the right habit. The header comment correctly notes that project-specific reminders "belong in a sibling project-local hook file," but this one snuck in. -
opencode agent listshell-out assumes OpenCode CLI is installed. Fires only when editing agent definitions, so the blast radius is small (a Copilot user who never edits agents won't see it). The fallback ("opencode agent list failed") is graceful. Acceptable as-is, but worth noting: Copilot-only environments will hit the failure path every time. Could gate oncommand -v opencode.
pre-compact.sh:
docs/explorations/hardcoded (same path issue asstop.sh). Already covered by the kanban-unification task above — fold into that work.
session-start.sh:
-
docs/explorations/hardcoded (same — fold into kanban-unification). -
.session/dead-ends.mdand.session/pre-compact-state.mdpaths appear in bothsession-start.sh,pre-compact.sh, andstop.sh. This is a convention.agents/AGENTS.mdshould formally document so it's not just "magic paths the hooks know about." Not Remnant-specific (no Remnant code references these), but undocumented. Fix: add a "Session conventions" section to~/dotfiles/.agents/AGENTS.mdlisting these paths. -
"Ordered markdown lists are auto-renumbered by the editor on save" reminder — this is VS Code + Prettier behavior, generic enough to keep, but worth flagging that it assumes the project uses Prettier with that setting (Remnant does; others may not).
stop.sh (already covered, restated for completeness):
-
docs/TODO.md,docs/projects/COMPLETED.md,docs/explorations/— kanban task. -
Ports 3000/3001 dev-server check (same as Policy 5 — fold fix together).
-
npm run build:strictreferenced as the recommended verification command. This is a Remnant-specific custom script name. Other projects usenpm run buildornpm run checkornpm run ci. Fix: same parameterize approach (read from.agents/project.json).
user-prompt-submit.sh: clean. No Remnant-isms found.
Suggested fix pattern (rather than a string of patches):
Introduce a per-project config file at <repo>/.agents/project.config.js (or
.ts) so each hook can read its values instead of hardcoding them. Full design
— file shape, loader notes, dropped fields (modelContextWindow),
recommendation — is in
dotfiles-agent-infra-roadmap.md → project.config.js extraction.
🆕 Future task — per-session tmp file capture
Moved to
dotfiles-agent-infra-roadmap.md → Per-session tmp file capture.
Driver recorded here for the validation trail: user-prompt-submit.sh writes to
a globally-named /tmp/.last-user-prompt.txt, so concurrent sessions clobber
one another's capture. The same issue affects
/tmp/.opencode-tool-count-${REPO_ID} in post-tool-use.sh (keyed by repo, not
session — concurrent sessions in the same repo share the self-check counter).