Skip to content

fix(harness): let adapters own their global context path - #3

Merged
hungthai1401 merged 1 commit into
mainfrom
fix/harness-global-context-path
Aug 21, 2026
Merged

hungthai1401 merged 1 commit into
mainfrom
fix/harness-global-context-path

Conversation

@hungthai1401

Copy link
Copy Markdown
Owner

The bug

mom doctor looked for pi's global context at ~/.pi/AGENTS.md, but the pi adapter writes ~/.pi/agent/AGENTS.md — which is the path pi's own docs name for global instructions (docs/usage.md: ~/.pi/agent/AGENTS.md for global instructions).

So a working Pi-only install failed the harness context check, and anyone who trusted doctor's path over the adapter's put the MOM block somewhere pi never reads.

ingress/cli/doctor.go:113   "pi": filepath.Join(home, ".pi", "AGENTS.md")
ingress/harness/pi.go:84    homePath(".pi", "agent", "AGENTS.md")

Root cause

Doctor kept its own hand-maintained copy of the per-harness home-file list instead of asking the code that wrote the block. Removing that list surfaced two more symptoms of the same duplication:

  • ingress/cli/uninstall.go:127 omitted pi entirely, so mom uninstall left the managed block behind in ~/.pi/agent/AGENTS.md.
  • Doctor hardcoded ~/.codex/AGENTS.md while the codex adapter honours CODEX_HOME, so a relocated Codex home read as absent.

The fix

GlobalAdapter now requires GlobalContextPath() (string, error). Each adapter returns the path it writes to, and its own GenerateGlobalContextFile resolves through that accessor — the write and the read cannot diverge.

Registry.GlobalContextPaths() collects those paths keyed by harness name, and both doctor and uninstall consume it. One definition per harness, held by the adapter.

Verification

go test ./... passes.

ingress/harness/global_context_path_test.go pins the invariant the old list was missing: write the block through each adapter, then assert it lands at the path that adapter advertises. Reintroducing the original bug (pointing pi's GlobalContextPath back at .pi/AGENTS.md) fails the test at the pi subtest.

Against a real install, doctor now reports all four harnesses instead of silently dropping pi:

✔ harness context: MOM block present (claude, codex, droid, pi)

Not included

~/.agents/AGENTS.md came up as a possible shared location for pi, codex, and droid. Pi does not read it as global instructions — ~/.agents/ is the skills.sh directory, and pi only reads ~/.agents/skills/ from it (docs/sdk.md). Consolidating onto one file would mean MOM writing there and symlinking each harness path to it, which is a feature rather than a fix and needs codex/droid behaviour confirmed first.

`mom doctor` read pi's global context from ~/.pi/AGENTS.md while the pi
adapter writes ~/.pi/agent/AGENTS.md, the path pi's own docs name for
global instructions. A working Pi-only install therefore failed the
harness context check, and anyone who followed doctor's path instead of
the adapter's put the MOM block somewhere pi never reads.

The mismatch came from doctor keeping its own copy of the home-file list
rather than asking the code that wrote the block. GlobalAdapter now
requires GlobalContextPath, each adapter returns the path it writes to,
and GenerateGlobalContextFile goes through that same accessor — so the
two cannot drift apart again.

Registry.GlobalContextPaths collects those paths per harness, and doctor
and uninstall both read it. That fixes two more symptoms of the
duplicated list: uninstall omitted pi entirely and left the managed block
behind in ~/.pi/agent/AGENTS.md, and doctor hardcoded ~/.codex/AGENTS.md
where the codex adapter honours CODEX_HOME.

The new test writes the block through each adapter and asserts it lands
at the path that adapter advertises, which is the assertion the old
hardcoded list was missing.
@hungthai1401
hungthai1401 merged commit b82366d into main Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant