Skip to content

test(headless): read both ways an adapter names a mounted repo file - #2316

Merged
Astro-Han merged 2 commits into
mainfrom
test/headless-mount-declaration-authority
Aug 6, 2026
Merged

test(headless): read both ways an adapter names a mounted repo file#2316
Astro-Han merged 2 commits into
mainfrom
test/headless-mount-declaration-authority

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

Each arm is mounted exactly the repo files it declares, and the check that holds those declarations to what the adapters actually read is the only thing standing between a missed entry and a trial that aborts inside the container. #2298 added that check for the Maka adapter after run-host-cell.mjs — probed by install() in every cell-mode branch — was left out of the declaration. It left the competitor half as it was.

The competitor half saw less than it looked like it saw. It scanned adapter sources for bare filenames and resolved them against packages/headless/harbor, so it could only ever notice a read of a file in that one directory. A competitor adapter reaching for packages/headless/dist/index.js — a path the Maka adapter already reads — matched nothing and passed. It was also matching by coincidence in the other direction: any string literal equal to some filename under harbor/ counted as a read of it.

Both halves now share one reader that matches the two forms adapters actually write:

  • the mounted path spelled out in full (codex_agent.py's _DEEPSEEK_MODELS_PATH),
  • the same path built by joining segments onto the mount root (opencode_agent.py, maka_agent.py).

Bare-filename matching is gone; both forms above cover every read in the adapters today, so nothing is lost with it. The reader is also exercised directly, so it is no longer worth only what today's adapters happen to spell.

Refs #2298.

Verification

  • Red: pointed opencode_agent.py at packages/headless/dist/index.js (a path outside harbor/, undeclared, unmounted). On main all 19 mount tests pass — the gap, reproduced. With this change: opencode_agent.py names packages/headless/dist/index.js, which opencode is not mounted.
  • Green: @maka/headless 1431 pass / 0 fail. npm run lint and npm run format clean.

Not run: desktop E2E and Storybook — test-only change in headless.

Review focus

The reader is a regex over Python source, which is a heuristic, not a parser: an adapter that builds a container path through a variable or an f-string is still invisible to it. That limit is unchanged from #2298; what changes here is that the limit is now the same on both sides and is stated in one place instead of being an accident of which directory the matcher scanned.

The check that holds the mount declarations to what the adapters actually
read is worth exactly what its reader sees, and the competitor half of it
saw less than it looked. It scanned for bare filenames and resolved them
against `packages/headless/harbor`, so a read of any repo file outside
that one directory matched nothing and passed — `dist/index.js`, which
the Maka adapter already reads, would have been invisible had a
competitor adapter reached for it.

This is the gap that cost `run-host-cell.mjs`: the Maka side had no
authority check at all, `install()` probed for a file nobody declared,
and a missing probe target aborts the trial before the arm runs. Closing
it for Maka left the same weakness on the other side.

Both halves now share one reader that matches the two forms adapters
actually write — the mounted path spelled out in full, and the same path
joined onto the mount root — and it is exercised directly rather than
only through whichever forms today's adapters happen to use.
…nothing

Two gaps the first round left, both of the same kind: a regex guard that
stops matching still passes.

The reader recognised the join form only when it hung off `maka_repo`,
and `maka_agent.py` hangs its own headless CLI path off a
`Path("/opt/maka-agent")` constant instead — that read was invisible, and
covered only by the directory mount it happens to fall inside. Match the
chain rather than what it hangs off: the root expression varies per
adapter and nothing stops the next one from binding its own name, while
a repo path necessarily starts at a repo directory.

And nothing held the reader to seeing anything at all. Rewriting the
adapters into a form it does not parse left the read set empty and the
suite green — the check silently no longer checking, which is exactly how
its predecessor rotted. An adapter with files declared for it is one
whose source names them, so an empty read set there is now a failure.
@Astro-Han
Astro-Han marked this pull request as ready for review August 6, 2026 07:11
@Astro-Han
Astro-Han merged commit 397f44a into main Aug 6, 2026
21 of 23 checks passed
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