Skip to content

🐛 Run and plan through this build's own ACP adapters (#672) - #673

Merged
taras merged 2 commits into
mainfrom
agent/issue-672-plan-adapters
Aug 31, 2026
Merged

🐛 Run and plan through this build's own ACP adapters (#672)#673
taras merged 2 commits into
mainfrom
agent/issue-672-plan-adapters

Conversation

@taras

@taras taras commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Why

xmd plan in 0.10.0 fails with both providers on a machine where codex and
claude are installed and authenticated (#672). The plan path builds its Agent
provider without an agent registry, so ACPX's own table answers — and that table
pins published adapters (codex: ^0.0.44, claude: ^0.37.0) rather than the
patched snapshots this build carries. xmd run assembles its provider the same
way and has the same gap.

What changes

Before:

  • xmd plan "…" — the probe spawns npx @agentclientprotocol/codex-acp@0.0.44,
    which runs its own bundled @openai/codex and reports
    Codex process has exited with code 1; the installed codex is never used.
  • xmd plan … --default-agent=claude — the turn runs against a stock adapter
    that never publishes executablemd.session-materialization/v1, so the
    invocation ends with this session still awaits first-turn materialization.
  • xmd run on a document naming either agent resolves the same stock pins.

After:

  • Both commands resolve codex and claude to the snapshot under
    packages/acp/vendor/adapters, materialized under ~/.xmd/adapters/<sha256>
    at the provider's availability probe. Every other agent resolves to the ACPX
    command it always did.

How it works

resolveAgentStack → AgentStack.adapters → hostAcpDependencies → createAcpxProvider
                                                    ↘ authorshipCeiling (xmd plan)
                                                    ↘ installRunAgentStack (xmd run)

The registry and the preparation are one statement, embeddedAdapterDependencies
in packages/acp/src/adapter-snapshots.ts: the overlaid registry says Codex and
Claude resolve to this build's snapshot, and prepareAgent is what puts that
snapshot on disk before anything spawns it. The workflow attachment — which
already stated both inline — now states them the same way, so all three profiles
resolve through one mechanism rather than three that happen to agree.

The adapters are part of the settled AgentStack, so the assistant that writes a
Plan and the run of the approved Plan launch from the same snapshot.

Review guide

Start with: packages/cli/src/agent-stack.ts

Then review:

  1. embeddedAdapterDependencies — the two clauses a carrying host states.
  2. hostAcpDependencies — now unconditional, and first, so a host assembly that
    states nothing about machine sessions still resolves this build's adapters.
  3. authorshipCeiling — the plan path's exact dependencies, now exported so a
    test can read what the provider was built from.
  4. packages/cli/tests/agent-adapters.test.ts.

Look carefully at:

  • Nothing is materialized eagerly. prepareAgent runs only when an agent is
    actually resolved, and only for an agent this build carries a snapshot for, so
    a document that asks for no agent creates no directory.

What must stay true

  • An embedded provider never falls through to ACPX's pins — enforced by
    overlaidAdapterRegistry and checked by AE1/AE3.
  • The overlay is not a replacement: an agent this build carries nothing for
    resolves as it always did — checked by AE2.
  • The plan ceiling's other clauses survive beside the registry — checked by AE3.

How to verify it

  • AE1 proves the run path's provider resolves codex and claude to this
    build's adapter command, and fails if a stock npx pin comes back.
  • AE3 proves the plan path's ceiling hands its provider the same registry, and
    fails if the ceiling is assembled without it — the exact defect in 🐛 xmd plan resolves agents through ACPX's stock registry instead of the embedded adapters #672.
  • AE4 proves asking about a non-embedded agent writes nothing, and fails if
    preparation stopped consulting carriesEmbeddedAdapter.
  • AE5 proves a settled stack carries this host's own adapter root, and fails if
    the resolution stops supplying adapters and leaves the provider a fallback.

Focused evidence run at caeff5d8:

deno task test packages/cli/tests/agent-adapters.test.ts packages/cli/tests/plan.test.ts \
  packages/cli/tests/plan-cli.test.ts packages/cli/tests/plan-command-document.test.ts \
  packages/cli/tests/workflow-agent.test.ts packages/cli/tests/workflow-agent-sessions.test.ts \
  packages/cli/tests/agent-cli.test.ts packages/cli/tests/agent-config.test.ts \
  packages/acp/tests/adapter-materialization.test.ts scripts/tests/adapter-vendor.test.ts

All passed, plus deno task check, deno task lint and deno task check:jsr.

Scope

Included

  • The registry and preparation on the xmd run and xmd plan provider paths.
  • The workflow profile restated through the shared clause pair (no behavior
    change there).
  • The patch bump to 0.10.1, in its own commit.

Intentionally unchanged

  • ACPX's registry for every other agent, and the workflow path's own adapter root
    beside its run store.
  • Retained-session identity: the workflow path already keys an embedded agent by
    snapshot identity rather than by launch path, and that is untouched.

Risks and limitations

  • A first xmd run/xmd plan naming Codex or Claude now installs the snapshot
    (one npm install of the vendored tarball) at the availability probe; later
    invocations reuse it. A snapshot that cannot be verified refuses the agent
    rather than falling back.
  • Not reproduced end to end against a live agent in this session: doing so needs
    an authenticated Codex or Claude. The evidence here pins the dependencies each
    path hands its provider.

Scope confirmation

  • Every changed file supports the purpose described above.
  • Unrelated cleanup and formatting changes are excluded.
  • Generated or mechanical changes are clearly identified.
  • The description matches the final diff and test results.

Fixes #672

https://claude.ai/code/session_01TNJwcFmnt3kYSn9gGsx9u7

taras added 2 commits August 30, 2026 22:04
`xmd plan` failed with both providers on a machine where Codex and Claude are
installed and authenticated. Its provider was built without an agent registry, so
ACPX's own table answered: `codex` spawned an `npx` of the published adapter that
build pins, which runs its own bundled agent, and `claude` ran a stock adapter
that never publishes the session-materialization signal a first turn waits for.

`xmd run` assembled its provider the same way and had the same gap.

Both now resolve agents through the overlay the workflow attachment uses — ACPX's
registry with this build's two patched snapshots over the top — and materialize
one at the availability probe, under `~/.xmd/adapters`. An agent this build
carries no snapshot for resolves exactly as it did.

The registry and the preparation are stated together by
`embeddedAdapterDependencies`, so a host cannot take one without the other, and
the adapters are part of the settled Agent stack: the assistant that writes a
Plan and the run of the approved Plan launch from the same snapshot.

Claude-Session: https://claude.ai/code/session_01TNJwcFmnt3kYSn9gGsx9u7
A patch bump: this release fixes `xmd plan` and `xmd run` resolving Codex and
Claude through ACPX's stock adapter pins instead of the adapters this build
carries (#672). No surface changes.

Stamps every publishable manifest and restamps the matching workspace entries in
bun.lock, which the bump task deliberately leaves alone. Only the ten
@executablemd members move.

Claude-Session: https://claude.ai/code/session_01TNJwcFmnt3kYSn9gGsx9u7
@github-actions

Copy link
Copy Markdown

PR #673: 🐛 Run and plan through this build's own ACP adapters (#672)

32 files, +338 / -71

Scope

🟡 409 lines changed. PRs under 400 receive more thorough review.

🟡 32 files changed. Are all changes related?

🟡 Changes span 12 directories.

🟡 PR mixes config and source changes.

Structural

Oxlint structural signals:

  • no-empty-function ×2: packages/acp/src/adapter-snapshots.ts

Slop

✅ Slop indicators look low.

Static Analysis

Oxlint: 8 diagnostics across 3 files (6 rules)
Density: 0.024 violations/added-line

no-array-sort (2): packages/acp/src/adapter-snapshots.ts
no-empty-function (2): packages/acp/src/adapter-snapshots.ts
consistent-function-scoping (1): packages/cli/src/authorship-profile.ts
no-unnecessary-template-expression (1): packages/acp/src/adapter-snapshots.ts
unbound-method (1): packages/cli/tests/support/plan-harness.ts
no-base-to-string (1): packages/cli/src/authorship-profile.ts

Correctness

No extraneous code patterns detected.

@taras
taras marked this pull request as ready for review August 31, 2026 02:07
@taras
taras merged commit d8e4c96 into main Aug 31, 2026
30 checks passed
@taras
taras deleted the agent/issue-672-plan-adapters branch August 31, 2026 02:18
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.

🐛 xmd plan resolves agents through ACPX's stock registry instead of the embedded adapters

1 participant