docs/architecture/cross-harness.md
ECC is the reusable workflow layer. Harnesses are execution surfaces.
The goal is to keep the durable parts of agentic work in one repo:
Claude Code, Codex, OpenCode, Cursor, Gemini, and future harnesses should adapt those assets at the edge instead of requiring a new workflow model for every tool.
For the operator-facing support matrix and scorecard workflow, see Harness Adapter Compliance Matrix. For the full-stack platform framing and product-integration loop, see ECC Platform Value Loop.
| Surface | Shared Source | Harness Adapter | Current Status |
|---|---|---|---|
| Skills | skills/*/SKILL.md | Claude plugin, Codex plugin, .agents/skills, Cursor skill copies, OpenCode plugin/config | Supported with harness-specific packaging |
| Rules and instructions | rules/, AGENTS.md, translated docs | Claude rules install, Codex AGENTS.md, Cursor rules, OpenCode instructions | Supported, but not identical across harnesses |
| Hooks | hooks/hooks.json, scripts/hooks/ | Claude native hooks, OpenCode plugin events, Cursor hook adapter | Hook-backed in Claude/OpenCode/Cursor; instruction-backed in Codex |
| MCPs | .mcp.json, mcp-configs/ | Native MCP config import per harness | Supported where the harness exposes MCP |
| Commands | commands/, CLI scripts | Claude slash commands, compatibility shims, CLI entrypoints | Supported, but command semantics vary |
| Memory | .ecc/memory/, ~/.ecc/memory/ | ecc memory CLI or opt-in ecc-memory-mcp stdio server | Supported with explicit recall and unreviewed writes |
| Sessions | ecc2/, session adapters, orchestration scripts | TUI/daemon, tmux/worktree orchestration, harness-specific runners | Alpha |
SKILL.md is the most portable unit.
A good ECC skill should:
name, description, and originThe same source skill can be installed into multiple harnesses because it is mostly instructions, constraints, and workflow shape.
Each harness has different loading and enforcement behavior:
AGENTS.md, plugin metadata, skills, and MCP config, but hook parity is instruction-driven..cursor/.Adapters should stay thin. The shared behavior belongs in skills/, rules/, hooks/, scripts/, and mcp-configs/.
ECC Memory Vault is the common knowledge-transfer surface for Claude, Codex,
Hermes, Cursor, OpenCode, and other agents. It stores portable
ecc.memory.v1 Markdown documents in three scopes:
<repo>/.ecc/memory/project/<repo>/.ecc/memory/team/~/.ecc/memory/Every harness must use the same repository working directory or the same
ECC_MEMORY_PROJECT_ROOT and ECC_MEMORY_USER_ROOT overrides. The deterministic
ecc memory CLI is the baseline interface. Harnesses with MCP support may
instead launch ecc-memory-mcp and use memory_save, memory_search,
memory_read, and memory_doctor. Normal search recall is active-only across
project and team; a direct ID read can inspect a non-active entry, and
user must be requested explicitly. The CLI target flag is a caller-selected
routing filter, not an authorization boundary.
The MCP server is opt-in. Its reference entry lives in
mcp-configs/mcp-servers.json; it is intentionally absent from the default
.mcp.json so installations do not silently gain a writable context surface
or pay its tool-schema cost. Each MCP process requires a lowercase
ECC_MEMORY_HARNESS; this server-bound identity supplies the source harness
and target filter, so a tool caller cannot select another identity. User-scope
MCP access remains blocked unless the operator launches the process with
ECC_MEMORY_ALLOW_USER_SCOPE=1.
The trust boundary is consistent across every adapter:
unreviewed;.gitignore is altered;skills/unified-memory/SKILL.md owns this workflow. Codex and Cursor receive
behavior-identical packaging copies under .agents/skills/ and
.cursor/skills/; Hermes can import the canonical skill. No harness owns a
separate authoritative memory store.
Hermes is not the public ECC runtime.
Hermes is an operator shell that can consume ECC assets:
The public repo should ship reusable patterns, not local Hermes state.
Do ship:
Do not ship:
~/.hermes exportsUse skills/hermes-imports/SKILL.md as the same skill source across harnesses.
The workflow is:
skills/hermes-imports/SKILL.md.Claude Code gets the skill through the Claude plugin surface and can enforce related hooks natively.
Codex reads the repo instructions, .codex-plugin/plugin.json, and the MCP reference config. The same skill source still describes the workflow, but hook parity is instruction-backed unless Codex adds a native hook surface.
OpenCode gets the skill through the OpenCode package/plugin surface. Event handling can reuse ECC hook logic through the adapter layer, while the skill text stays unchanged.
If a change requires editing three harness copies of the same workflow, the shared source is in the wrong place. Put the workflow back in skills/, then adapt only loading, event shape, or command routing at the harness edge.
Supported today:
skills/ecc2/ as an alpha Rust control planeStill maturing:
ecc2/When adding a workflow, put the durable behavior in ECC first.
Use harness-specific files only for:
If a workflow only works in one harness, document that boundary directly.