agent-desktop/docs
Lahfir b8a5b60248 docs(phases): codify command-surface DRY invariant — MCP is global, never per-platform
Add a dedicated "Command Surface Architecture (DRY invariant)" section at
the top of the document (right after Phase Overview, before Phase 1) that
states the layering contract once and is referenced by every phase that
adds commands or transports:

- Every command lives exactly once in crates/core/src/commands/<name>.rs
  and operates on &dyn PlatformAdapter. No transport has per-platform
  code; no platform has per-transport code.
- A shared compile-time registry (inventory::submit! { CommandDescriptor })
  is the single source of truth. CLI, FFI, and MCP each walk it.
- schemars derives JSON Schema from the same clap-parsed Args struct, so
  CLI + MCP get matching types for free; rmcp's #[tool] macro accepts
  JsonSchema-derived args directly.
- Per-platform work is exclusively PlatformAdapter trait method bodies
  in crates/{macos,windows,linux}/.

New section contents:
- ASCII layering diagram showing command flow from core → transports →
  platforms
- Concrete cost table per layer (per-command vs per-platform)
- Worked example: what "text select-range" (Phase 2) looks like across
  1 core file + 3 adapter impls + 0 transport changes
- Full registration-pattern code snippet with CommandDescriptor +
  inventory::submit!
- Explicit statement that MCP is one platform-agnostic crate and the
  tool surface tables are registry snapshots, not hand-written

Phase-level updates to reinforce the invariant:
- Phase 2 intro: adds a paragraph stating that new P2 commands
  (watch, text select-range, etc.) auto-flow to CLI + FFI + MCP via the
  registry; only the PlatformAdapter trait method bodies are written
  three times.
- Phase 2 P2-O16 reworded: FFI migration from hand-written wrappers to
  build.rs codegen that walks the registry. After migration, adding a
  CLI command also emits the FFI entry automatically.
- Phase 3 intro: states Phase 3 is "pure PlatformAdapter trait
  implementation code, nothing else" — no command files, no CLI
  dispatch, no FFI wrappers, no MCP tool registrations.
- Phase 4 intro: leads with "zero per-tool and zero per-platform code
  in crates/mcp/". The MCP crate walks the shared registry at startup.
- Phase 4 "New Crate" section: full crates/mcp/src/ layout (6 files
  total, ~80 lines of bootstrap in server.rs). Shows the actual
  inventory::iter::<CommandDescriptor>() loop and the capability-gated
  dispatch. Makes it unmistakable that the MCP surface is not
  hand-enumerated.
- Cross-Phase Requirements: new "Command Surface DRYness" rule
  restates the invariant and declares it enforced at PR review time.

No objectives, tests, or tool tables were removed — the invariant
section adds a global statement of the pattern the phases already
follow, and reframes ambiguous wording (P2-O16, Phase 4 tool surface)
so nothing implies per-transport or per-platform duplication.

File: 1787 → 1963 lines (+176). One new top-level section (11 total).
2026-04-17 05:16:33 -07:00
..
solutions feat(ffi): ship C-ABI cdylib with review hardening and release pipeline (#26) 2026-04-17 04:00:43 -07:00
architecture.excalidraw docs: add architecture diagram to README 2026-02-24 06:22:52 -08:00
architecture.png docs: add architecture diagram to README 2026-02-24 06:22:52 -08:00
phases.md docs(phases): codify command-surface DRY invariant — MCP is global, never per-platform 2026-04-17 05:16:33 -07:00