Skip to content

mcp tests: keep the real Zulip adapter out of above-port tests - #9

Merged
GraemeF merged 1 commit into
mainfrom
comms-e5vm.4
Jun 13, 2026
Merged

GraemeF merged 1 commit into
mainfrom
comms-e5vm.4

Conversation

@GraemeF

@GraemeF GraemeF commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What

Audits the above-the-port unit tests (server.test.ts, server.integration.test.ts, tools tests) and the disconnect-exit fixture to confirm the real Zulip adapter does not appear in them — they drive the substrate through hand-rolled port fakes and the in-memory adapter only. Documents the rule and concentrates the residual Zulip coupling into a single seam.

Audit finding

These tests were already compliant behaviourally: only server.live.test.ts constructs zulipAdapter() (the live suite, out of scope), and bootstrap.test.ts wires the real adapter from config (it tests wiring, not I/O — exempt). The above-port targets exercise only buildFakeAdapter / harness overrides and the real memoryAdapter().

The residual @commy/zulip references were the ZulipAdapter type (the SubstrateAdapter port is currently typed as ZulipAdapter) and the UserUploadPath brand (decodeUserUploadPathSync) — type/brand coupling, not adapter behaviour — duplicated across three sites that each completed an AgentComms core to the Zulip-shaped aggregate.

Change

  • packages/mcp/memory-substrate.ts (new) — completeAsSubstrate(base, overrides?), the single seam that completes an AgentComms core (in-memory adapter or a port fake) to the ZulipAdapter shape. It owns the lone UserUploadPath brand mint and re-exports the ZulipAdapter type, so @commy/zulip now appears in exactly one test-side module.
  • The three completion sites (server.test.ts ×2, server.integration.test.ts, disconnect-exit.fixture.ts) now call the helper instead of inlining the Zulip-shaped members.
  • docs/architecture.md — new Test architecture section documenting the rule (above-port unit tests use the memory adapter / port fakes only, never the real Zulip adapter), why the memory adapter is a proven contract-equivalent, and the two legitimate exceptions.

Substrate-neutralising the SubstrateAdapter port itself (so above-port code names no Zulip type at all) is epic-level and tracked separately; this keeps the boundary self-enforcing in the meantime.

Closes comms-e5vm.4 (epic comms-e5vm).

The above-port unit tests (server.test.ts, server.integration.test.ts)
and the disconnect-exit fixture drive the substrate through hand-rolled
port fakes and the in-memory adapter only — never the real Zulip adapter.
That was already true behaviourally (only server.live.test.ts constructs
zulipAdapter(); bootstrap.test.ts wires it from config), but the residual
coupling — the ZulipAdapter type and the UserUploadPath brand the
SubstrateAdapter port carries — was duplicated across three sites that
each completed an AgentComms core to the Zulip-shaped aggregate.

Concentrate that completion into one seam, completeAsSubstrate in
memory-substrate.ts: it owns the lone UserUploadPath brand mint and
re-exports the ZulipAdapter type, so @commy/zulip now appears in exactly
one test-side module. The rule (above-port unit tests use the memory
adapter / port fakes only) is documented in docs/architecture.md under a
new Test architecture section, making it self-enforcing rather than a
convention people must remember.

comms-e5vm.4
@GraemeF
GraemeF merged commit 8b9843b into main Jun 13, 2026
2 checks passed
@GraemeF
GraemeF deleted the comms-e5vm.4 branch June 13, 2026 09:22
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