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.
772 lines
39 KiB
Markdown
772 lines
39 KiB
Markdown
# 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](./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 in
|
||
`post-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 config
|
||
- `docs/research/*.md` (5 files) — ai-coding-best-practices,
|
||
human-llm-interpretation-overlap, intent-interpretation-action-plan,
|
||
llm-intent-interpretation, text-communication-interpretation
|
||
- `docs/explorations/text-intent-interpretation-research.md`
|
||
- `docs/ai_architectures.md`
|
||
- `docs/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 in
|
||
`post-tool-use.sh`)
|
||
- Nested `AGENTS.md` files in `apps/`, `packages/`
|
||
- `verification.md`, `docs/TODO.md`, `docs/projects/*` (other than the
|
||
agent-infrastructure split-off)
|
||
- The two `.modelfile` files — leave in `.agents/` with a `MODELFILES.md` note
|
||
|
||
---
|
||
|
||
## Verification gates (Phase 0 — COMPLETE)
|
||
|
||
1. ✅ **OpenCode plugin coexistence** — additive; all hooks run in sequence.
|
||
Global dir: `~/.config/opencode/plugins/` (not `~/.opencode/plugins/`).
|
||
|
||
2. ✅ **OpenCode MCP merge** — configs merge (not replace). Global `mcp` entries
|
||
- project `mcp` entries both load; project-level keys win on conflicts.
|
||
|
||
3. ✅ **Copilot global hook support** — EXISTS. User-level hooks dir:
|
||
`~/.copilot/hooks/` (macOS/Linux) per
|
||
[GitHub Copilot hooks reference](https://docs.github.com/en/copilot/reference/hooks-reference).
|
||
Load order is additive: repo `.github/hooks/*.json` → user
|
||
`~/.copilot/hooks/*.json` → repo `settings.json` inline → user
|
||
`~/.copilot/settings.json` inline → 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.)_
|
||
|
||
4. ✅ **VS Code global MCP** — `~/.vscode-server/data/User/mcp.json` (create via
|
||
`MCP: Open Remote User Configuration` command or directly).
|
||
|
||
5. ✅ **OpenCode hook overlay** — BFF reminder ships as a separate project-local
|
||
plugin file. No merged copy of `post-tool-use.sh` needed.
|
||
|
||
---
|
||
|
||
## 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
|
||
|
||
1. Copy (not move) shareable files from `remnant/.agents/` into
|
||
`~/dotfiles/.agents/`. Add a **"Research Discipline" section** to
|
||
`~/dotfiles/.agents/AGENTS.md` for 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 (OpenCode
|
||
`instructions:` config, VS Code `.instructions.md` files) for guidance that
|
||
belongs in AGENTS.md.
|
||
2. Copy `docs/research/*.md` (5 files),
|
||
`docs/explorations/text-intent-interpretation-research.md`,
|
||
`docs/ai_architectures.md`, `docs/infra/LLAMA-SERVER-CUDA-WSL2.md` into
|
||
`~/dotfiles/.agents/docs/`.
|
||
3. 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.md` only" + the `api/`/`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.json` paths — generalize for shared doc;
|
||
keep concrete Remnant examples as a Remnant section)
|
||
4. Refactor `mcp/index.ts`: auto-discover `agents/*.md` and `skills/*.md`
|
||
relative to the script location, instead of a hand-maintained registry.
|
||
Removes a friction point when adding new agents/skills.
|
||
5. Rename MCP server `remnant-agents` → `all-agents` in `mcp/index.ts`.
|
||
6. 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").
|
||
7. 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.json` with absolute paths to
|
||
`~/dotfiles/.agents/hooks/*.sh` (not a symlink — avoids needing per-project
|
||
hook stubs for relative-path resolution).
|
||
- Merges `all-agents` MCP entry into `~/.config/opencode/opencode.json` via
|
||
`jq`.
|
||
- Writes `~/.vscode-server/data/User/mcp.json` with the `all-agents` MCP
|
||
entry.
|
||
8. 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` (not `run_in_terminal`);
|
||
`pre-tool-use.sh` case statement updated in both repos.
|
||
|
||
### Phase 4 — Strip Remnant ✅ DONE
|
||
|
||
1. ✅ Deleted `agents/`, `skills/`, `frameworks/`, `mcp/`, `AGENTS.md` from
|
||
`.agents/`
|
||
2. ✅ `.agents/hooks/` reduced to `post-tool-use-remnant.sh` only
|
||
3. ⚠️ `MODELFILES.md` stub not created (skipped — low value)
|
||
4. ✅ `.vscode/mcp.json`: `remnant-agents` dropped, `exa` retained
|
||
5. ✅ `opencode.json`: `mcp.remnant-agents` removed, permission overrides kept
|
||
6. ✅ `AGENTS.md` updated to reference `~/dotfiles/.agents/AGENTS.md`
|
||
7. ✅ Docs deleted from `remnant/docs/` (research/, ai_architectures.md, etc.)
|
||
8. ✅ `agent-infrastructure.md` rewritten as thin pointer
|
||
9. ✅ `.agents/README.md` added
|
||
10. ✅ 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:strict` passes (2 scripts ran, 15 skipped via wireit cache)
|
||
- ✅ All 6 shared hook scripts pass `bash -n` syntax check
|
||
- ✅ `post-tool-use-remnant.sh` passes `bash -n`
|
||
- ✅ `~/.config/opencode/agents/` wired with 4 symlinks → dotfiles
|
||
- ✅ `~/.copilot/hooks/agent-support.json` present (generated, absolute paths)
|
||
- ✅ Remnant `.agents/` contains only: README.md, hooks/, omnicoder\*.modelfile
|
||
- ⏳ Live session checks (require manual restart): `/research` etc. slash
|
||
commands, hook block in live session, BFF reminder injection, VS Code MCP
|
||
`all-agents` connect
|
||
|
||
---
|
||
|
||
## Notes (post-execution)
|
||
|
||
- All rename touch points done: `remnant-agents` → `all-agents` in 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 (see `post-tool-use.sh` line ~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*.modelfile` content 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** — the
|
||
`additionalIgnores` bypass added in Phase 2 is a shortcut, not a solution.
|
||
`.agents/mcp/index.ts` and `.agents/frameworks/opencode/plugin.ts` use
|
||
`import.meta.url` directly (blocked by `no-restricted-syntax`) and have minor
|
||
unused-var patterns. Options: (a) replace `import.meta.url` usages with the
|
||
approved `findNearestPackageRoot` / `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
|
||
own `tsconfig.json` and relaxed rules. Remove `.agents/**` from
|
||
`additionalIgnores` once 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. The `compaction` agent is a hidden system agent; its behavior
|
||
after summarizing context is not specified. There is no `/docs/compaction`
|
||
page — 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.md` are both
|
||
always-on per-request — equivalent. The ban on `.instructions.md` files 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)
|
||
|
||
1. **Extend `pre-compact.sh`**: Before summarization fires, scan the current
|
||
context for `read_file` calls on `AGENTS.md` paths and emit their content
|
||
into the compaction context so the summary captures them explicitly.
|
||
|
||
2. **Session-start hook re-read**: If `session-start.sh` can detect it is
|
||
running post-compaction (e.g. a state file exists from a prior
|
||
`pre-compact.sh` run), re-inject the full root `AGENTS.md` content
|
||
immediately.
|
||
|
||
3. **PostToolUse periodic re-injection**: The current `post-tool-use.sh`
|
||
self-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.
|
||
|
||
4. **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.
|
||
|
||
5. **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-safe `chat.message`
|
||
injection) ✅
|
||
- `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 + global `AGENTS.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}.md`
|
||
symlinks ✅
|
||
- `~/.config/opencode/opencode.json` — has `all-agents` MCP entry ✅
|
||
- `~/.vscode-server/data/User/mcp.json` — has both `all-agents` and `exa` ✅
|
||
- `~/.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.md` warning file ✅
|
||
|
||
### ⚠️ Gaps and bugs in dotfiles (pre-push)
|
||
|
||
These should be fixed before squashing/pushing the dotfiles commits.
|
||
|
||
1. **`~/dotfiles/.agents/AGENTS.md` references 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.json` and `.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.json` and
|
||
`~/.config/opencode/plugins/agent-support.ts`, (b) at Remnant the project
|
||
symlink files are named `hooks.json` and `hooks.ts`, not `agent-support.*`.
|
||
The doc was written for the pre-split layout and never updated.
|
||
|
||
2. **`~/dotfiles/.agents/AGENTS.md` links 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.md` and
|
||
`./docs/ai-coding-best-practices.md` (the docs moved into `.agents/docs/`,
|
||
not `docs/research/`).
|
||
|
||
3. **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.
|
||
|
||
4. **`frameworks/github/AGENTS.md` and `frameworks/opencode/AGENTS.md` are
|
||
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 global
|
||
`frameworks/opencode/plugin.ts` won't see them.
|
||
|
||
5. **`install.sh` location.** Currently `~/dotfiles/.agents/install.sh`.
|
||
Recommendation: move to `~/dotfiles/install.sh` so the dotfiles repo has a
|
||
discoverable bootstrap entry point (and to leave room for installing other
|
||
dotfiles content beyond `.agents/`). The script uses
|
||
`DOTFILES_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.
|
||
|
||
6. **`install.sh` does not symlink anything into `~/.copilot/` beyond
|
||
`hooks/`.** 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.
|
||
|
||
7. **`install.sh` doesn'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.md` files from dotfiles.
|
||
|
||
8. **`install.sh` has no uninstall counterpart.** Low-priority. Useful if we
|
||
start moving the script around and want clean state for testing.
|
||
|
||
9. **Exa MCP has an undocumented rate limit; agents fan out parallel
|
||
`mcp_exa_web_search_exa` calls 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
|
||
any `mcp_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.md` entry** under a new "External service quirks" section listing
|
||
per-service constraints (Exa rate limit, GitHub API limits when
|
||
`mcp_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-count` file (reset on `user-prompt-submit`); warn (don't
|
||
deny) past N=2.
|
||
|
||
### 🧹 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 `2d58147` as 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.md` stub (Phase 4 item 3) — explicitly skipped; consider whether
|
||
the two `omnicoder*.modelfile` files 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-agents` connect) — 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](./dotfiles-agent-infra-roadmap.md).
|
||
The short version:
|
||
|
||
- Inheriting the global infra is automatic once `install.sh` has run on the
|
||
machine — no per-project setup beyond an `AGENTS.md` and (optionally) an
|
||
overlay hook.
|
||
- The blocker for full MFE adoption is that `stop.sh` hardcodes Remnant's task
|
||
layout (`docs/TODO.md`, `docs/projects/COMPLETED.md`, `docs/explorations/`).
|
||
This is part of the
|
||
[hook audit](#-full-hook-script-remnant-isms-audit-may-23-2026--addendum)
|
||
below and is addressed by the `project.config.js` extraction tracked in the
|
||
roadmap.
|
||
|
||
### 🆕 Future task — unify kanban/task doc structure across projects
|
||
|
||
Moved to
|
||
[dotfiles-agent-infra-roadmap.md → Kanban / task-doc unification](./dotfiles-agent-infra-roadmap.md#4-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:**
|
||
|
||
1. **Policy 5 — hardcoded ports 3000/3001** for dev-server detection:
|
||
|
||
```bash
|
||
ss -tlnp 2>/dev/null | grep -qE ':300[01]\s'
|
||
```
|
||
|
||
These are Remnant's `apps/api` (3000) and `apps/client` Vite HMR (3001). MFE
|
||
uses different ports (likely 5173 for Vite, plus app-specific). Fix: read
|
||
ports from a per-project config (`.agents/project.json` with a `devPorts`
|
||
array) or from `package.json` script scraping, default to common ports if
|
||
unset.
|
||
|
||
2. **Policy 8 — error message references `npm run build:core`** (Remnant has a
|
||
`packages/core` package 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.ts`
|
||
> block 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").
|
||
|
||
3. **Policies 9 & 10 — assume wireit is the build tool.** Both error messages
|
||
reference wireit cache/fingerprint behavior and tell the agent to edit
|
||
`wireit` config in `package.json`. Remnant uses wireit; MFE may not. The
|
||
blocks themselves (`rm .wireit`, `-- --force` with npm run) are still useful
|
||
— they fire on the literal string `.wireit` and the `--force` flag — 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.
|
||
|
||
4. **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 of `workspaces` field in root `package.json`.
|
||
|
||
5. **Policy 14 — hardcoded `apps/*/package.json` and `packages/*/package.json`
|
||
paths.** This is the exact Remnant monorepo layout (`apps/api`,
|
||
`apps/client`, `packages/core`, etc.). MFE may use `apps/` + `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 from `package.json` `workspaces` field; drop the
|
||
model-size number or make it configurable.
|
||
|
||
**`post-tool-use.sh` — mostly generic, one cosmetic issue:**
|
||
|
||
6. **`vscode_renameSymbol` reminder 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 like
|
||
`oldName: newName` in 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.
|
||
|
||
7. **`opencode agent list` shell-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 on
|
||
`command -v opencode`.
|
||
|
||
**`pre-compact.sh`:**
|
||
|
||
8. **`docs/explorations/` hardcoded** (same path issue as `stop.sh`). Already
|
||
covered by the kanban-unification task above — fold into that work.
|
||
|
||
**`session-start.sh`:**
|
||
|
||
9. **`docs/explorations/` hardcoded** (same — fold into kanban-unification).
|
||
|
||
10. **`.session/dead-ends.md` and `.session/pre-compact-state.md` paths** appear
|
||
in both `session-start.sh`, `pre-compact.sh`, and `stop.sh`. This is a
|
||
convention `.agents/AGENTS.md` should 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.md` listing these paths.
|
||
|
||
11. **"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):**
|
||
|
||
12. `docs/TODO.md`, `docs/projects/COMPLETED.md`, `docs/explorations/` — kanban
|
||
task.
|
||
|
||
13. **Ports 3000/3001** dev-server check (same as Policy 5 — fold fix together).
|
||
|
||
14. **`npm run build:strict`** referenced as the recommended verification
|
||
command. This is a Remnant-specific custom script name. Other projects use
|
||
`npm run build` or `npm run check` or `npm 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](./dotfiles-agent-infra-roadmap.md#1-projectconfigjs-extraction).
|
||
|
||
### 🆕 Future task — per-session tmp file capture
|
||
|
||
Moved to
|
||
[dotfiles-agent-infra-roadmap.md → Per-session tmp file capture](./dotfiles-agent-infra-roadmap.md#2-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).
|