Skip to content

Harness-agnostic

SDLC runs today inside Claude Code’s plugin mechanism. That’s a convenient bootstrap, not the destination. This page is the constraint that keeps the distinction honest.

The op registry is the system. The CLI is one adapter over it. The data (markdown + frontmatter on disk) and the deterministic ops are portable: they don’t depend on Claude Code, or on any single door, to be meaningful.

A future MCP server, HTTP service, or other agent harness operates on the same registry. Claude remains a front door — not the front door.

Every deterministic operation is declared once in the registry as a defineOp descriptor and projected into each door. The contract is restated nowhere: add a conforming module and the op appears in every adapter with no hand-wiring (D-0007-deterministic-op-substrate §2/§5).

solutions/ontological/lib/registry.ts
one defineOp descriptor
path · input · output · handler
┌───────────────┼───────────────┐
▼ ▼ ▼
CLI (sdlc) MCP HTTP
shipped derived derived
segments tool name = route =
verbatim underscore-join /<seg>/<seg>[/<seg>]
method by verb class

Adapter projection is a pure function of the path (D-H7FS-op-substrate-surface §5):

DoorProjectionExample
CLIpath segments verbatim; interior segments are description-only group subcommandssdlc quality baseline capture
MCPtool name = underscore-join, intra-segment hyphens kept; a forward map, uniqueness enforced by project-checkquality_baseline_capture, gate_worktree-scope
HTTP/<seg>/<seg>[/<seg>]; method by verb class (create/update/start → POST; get-schema/list/scan → GET)POST /quality/baseline/capture

The CLI is the one shipped door (solutions/ontological/cli/registry_adapter.ts); it builds a recursive command trie from the paths and dispatches each leaf through invokeOp. MCP and HTTP are bound to the rules above — tool names and routes are derived, never hand-assigned — but building them is later work, not part of the full sweep.

Three things have to stay true.

Tasks, milestones, decisions, standards, and the rest are plain markdown with YAML frontmatter under docs/planning/<plural>/. No database, no service, no Claude-specific format. Anything that can read a directory of markdown can read the data. The moment the canonical state lives in a proprietary store, the system is welded to whatever wrote it.

A handler runs against an injected ctx{ projectRoot, dryRun, io, git, gh } — and reads no ambient cwd or env (OpCtx in solutions/ontological/lib/registry.ts). That DI seam is exactly what makes an op callable off-process: an MCP or HTTP caller has no working directory to inherit. The same seam makes ops testable with fake io/git/gh, and lets --dry-run and --output be applied once by the adapter rather than re-coded per verb.

3. Long-running work has a lifecycle, not a request/response

Section titled “3. Long-running work has a lifecycle, not a request/response”

A server or a heartbeat loop never returns a single result object, so it can’t be a plain op — its handler would hang invokeOp’s await-then-validate. defineService is the registry sibling for these: same path-keyed index and help surface, but a lifecycle (start/stop?/list?) dispatched outside the output-parse pipeline (defineService in solutions/ontological/lib/registry.ts, §3). Lifecycle failures map to the SERVICE_ERROR exit tier — already-running, stale pidfile, port-in-use. The dashboard and the lease heartbeat loop are the two services shipped today.

defineService({ path, lifecycle })
┌───────────────────┼───────────────────┐
▼ ▼ ▼
start stop? list?
may never returns releases the reports running
(server / loop) pidfile/port instances
└─ dispatched OUTSIDE invokeOp's await-then-output.safeParse
(a non-returning loop would hang it) — exit via SERVICE_ERROR

It does not mean the LLM is interchangeable with a non-LLM today. The parts of the workflow that genuinely need judgment — readiness verification, backlog triage, semantic doc-drift — are LLM-shaped right now, and live in solutions/ontological/skills/, outside the substrate. A pure-machine door reaches every op; it does not reach the skills that compose them with judgment.

The point is narrower and already true: the data and the deterministic ops don’t require the LLM. One registry, projected into many doors, means a capability is reachable identically from a shell, CI, a Claude session, or a non-Claude agent — with no per-adapter contract drift.