9.7 KiB
MACP wiring investigation
Scope: /src/mosaic-stack inspected at HEAD b79336a8c11e2a4646a47ff8d295a226e0c71404; read-only. Existing dirty/untracked state was not touched.
Verdict
(c) STRANDED. packages/macp is exported, unit-tested, and registered as a CLI command group, but no production dispatch/execution code invokes its credential resolver, gate runner, or event emitter.
A separate MACP-named OpenClaw/orchestrator rail exists, but it redefines task/result types and gate/event logic instead of importing @mosaicstack/macp; direct mosaic yolo|claude|codex|opencode|pi also bypasses it.
1. Production call sites vs tests
Production references to @mosaicstack/macp
| Surface | Evidence | Actual use |
|---|---|---|
| Unified CLI | packages/mosaic/src/cli.ts:8,385 |
Imports and registers registerMacpCommand; no task/gate/event execution. |
| Forge | packages/forge/src/types.ts:1,17,68,79 |
Type-only imports of GateEntry and TaskResult. Pipeline calls an injected abstract executor at packages/forge/src/pipeline-runner.ts:189-190,299-300, not MACP. |
| Mosaic package metadata | packages/mosaic/package.json:36; packages/mosaic/src/runtime/update-checker.ts:172 |
Dependency/update inventory only. |
| Agent | No match under production packages/agent/src/** |
No MACP import/call. |
| Coord | No match under production packages/coord/src/**; dependency list is only @mosaicstack/types at packages/coord/package.json:25-27 |
No MACP import/call. |
| Plugins | No @mosaicstack/macp import under plugins/** |
No package use; the MACP-named plugin is an independent implementation (below). |
Repository-wide production call-site search result: excluding packages/macp/**, tests, worktrees, and build output, there are zero calls to runGate, runGates, emitEvent, appendEvent, or resolveCredentials.
packages/macp implementation is internally connected only
- Public exports:
packages/macp/src/index.ts:1-48exports Task/GateEntry/MACPEvent/TaskResult, credential resolution,runGate(s), risk-floor, and event emission. - Gate runner calls its own event emitter:
packages/macp/src/gate-runner.ts:187-236. - Event persistence implementation appends NDJSON to a caller-supplied path:
packages/macp/src/event-emitter.ts:11-27. - There is no exported programmatic
submitimplementation inpackages/macp/src/index.ts:1-48; only the CLI placeholder namedsubmit.
Test-only invocations
- Gate runner:
packages/macp/__tests__/gate-runner.test.ts:96-242invokesrunGate/runGates. - Event ledger:
packages/macp/__tests__/event-emitter.test.ts:46-133invokesappendEvent/emitEventagainst temporaryevents.ndjsonfiles. - Credential resolver:
packages/macp/__tests__/credential-resolver.test.tsexercises resolver behavior. - CLI tests only verify command registration:
packages/macp/src/cli.spec.ts:37-73;packages/mosaic/src/cli-smoke.spec.ts:8imports registration.
2. Gate on the live dispatch path
Direct Mosaic runtime launch bypasses MACP
- Runtime commands dispatch directly to harness launch:
packages/mosaic/src/commands/launch.ts:730-801. - Claude/Pi go through the lease broker, then spawn the runtime:
packages/mosaic/src/commands/launch.ts:817-843. - Commander wiring sends
mosaic yolo <runtime>and direct runtime commands tolaunchRuntime:packages/mosaic/src/commands/launch.ts:1102-1157,1165-1167. - None of those ranges imports/calls
@mosaicstack/macp,runGates, oremitEvent.
Result: a direct mosaic yolo, mosaic claude/codex/opencode/pi, or underlying exec does not create a typed MACP Task, run the package gate-runner, or append a package MACPEvent.
Coord bypasses MACP
- Coord reads/updates
docs/TASKS.md:packages/coord/src/runner.ts:6,306-386; parser/writer ispackages/coord/src/tasks-file.ts:326-377. - Coord launches a child process directly:
packages/coord/src/runner.ts:397-427. - Mission state is its own
.mosaic/orchestrator/mission.json/next-task.json:packages/coord/src/mission.ts:8-12;packages/coord/src/runner.ts:15-16,355-384.
Result: Coord task execution has no MACP Task validation, package gate runner, or event append.
Forge bypasses MACP execution
- Forge defines its own
ForgeTaskand abstractTaskExecutor:packages/forge/src/types.ts:48-80. - The production CLI injects a stub executor that immediately reports completion with empty gates:
packages/forge/src/cli.ts:13-31,167,185.
Result: even mosaic forge run does not execute MACP gates or persist MACP events.
Separate MACP-named rail is not packages/macp
- OpenClaw plugin registers an ACP backend named
macp:plugins/macp/src/index.ts:1-18,72-102. - It locally redefines
OrchestratorTask,TaskResult, and gate-result shapes instead of importing package types:plugins/macp/src/macp-runtime.ts:43-77. - It appends directly to
.mosaic/orchestrator/tasks.json, triggers an external controller, and pollsresults/<task>.json:plugins/macp/src/macp-runtime.ts:290-329,437-483. - The controller independently implements
append_event,emit_event, shell execution, gate execution, and results:packages/mosaic/framework/tools/orchestrator-matrix/controller/mosaic_orchestrator.py:29-91,126-276. - Its gate loop runs raw string gates after worker success:
mosaic_orchestrator.py:213-235; it does not support the package's structuredGateEntry/AI-review behavior. - Current checkout disables this controller:
.mosaic/orchestrator/config.json:2("enabled": false). - Plugin references
tools/macp/dispatcher/pi_runner.tsatplugins/macp/src/macp-runtime.ts:85-91, buttools/macp/does not exist in this checkout.
Result: there is a parallel, optionally enabled MACP-shaped rail, not package integration. It cannot make packages/macp the enforced path.
3. Event ledger status
- Package persistence exists only as a library primitive:
packages/macp/src/event-emitter.ts:11-27appends JSON lines to an arbitraryeventsPath. - Package event emission is reached only from package
runGates:packages/macp/src/gate-runner.ts:204-236. - No production caller invokes package
runGates/emitEvent/appendEvent; therefore no runtime destination path is configured for the package ledger. - Test-only ledgers use temp paths:
packages/macp/__tests__/event-emitter.test.ts:35-133; gate tests use tempevents.ndjson:packages/macp/__tests__/gate-runner.test.ts:171-242. - The separate Python controller writes
.mosaic/orchestrator/events.ndjson:mosaic_orchestrator.py:129-133,159-161,219-235; the Mosaic Framework plugin only reads that file for context atplugins/mosaic-framework/src/index.ts:279-316,430-438. - In this checkout,
.mosaic/orchestrator/events.ndjsonis absent and the controller is disabled (.mosaic/orchestrator/config.json:2).
Conclusion: MACPEvent from packages/macp is defined/tested but not emitted or persisted by live production call sites. The similarly shaped Python ledger is a duplicate island.
4. Coord link
packages/coordhas no@mosaicstack/macpdependency/import:packages/coord/package.json:25-27; no matches inpackages/coord/src/**.- Coord's task model is Markdown
docs/TASKS.mdplus mission/session JSON:packages/coord/src/tasks-file.ts:1-10,257-377;packages/coord/src/mission.ts:8-12;packages/coord/src/runner.ts:306-427. - It does not consume
.mosaic/orchestrator/events.ndjson, MACP Task, MACPEvent, GateEntry, or TaskResult.
Conclusion: Coord and packages/macp are disconnected islands.
Shortest wiring gap
Single integration point: replace the duplicated execution/gate/event block in mosaic_orchestrator.py::run_single_task (:126-276) with one production Node TaskExecutor backed by @mosaicstack/macp (typed Task validation + resolveCredentials + runGates + emitEvent), and make Coord/Forge/OpenClaw submit through that executor. This queue/controller choke point is where yolo|acp|exec worker outcomes can be gated and journaled before completion is recorded.