Architecture overview
SDLC has a few deliberate seams. This page maps them so the rest of the docs make sense.
The deterministic core is an entity-oriented TypeScript library
(solutions/ontological/lib/). Every deterministic capability is declared once in a
single op registry; the sdlc CLI is a thin door generated from that
registry. There is no second copy of any contract.
Repo layout at a glance
Section titled “Repo layout at a glance”plugin/ The distributable Claude Code plugin .claude-plugin/ Plugin + marketplace manifests cli/ sdlc.ts — the generated CLI door over the registry conventions/ Shared prose referenced from SKILL.md files lib/ The deterministic substrate (see below) schemas/ sdlc.yaml JSON Schema skills/ LLM-orchestrated workflows (one dir per skill)docs/ This project's own planning corpus (dogfooded) planning/ tasks · milestones · decisions · standards · …sites/df-docs/ This Astro Starlight documentation site (you are here)For local development, sdlc harness install claude --dev links the live
checkout into the harness (config routed to .claude/settings.local.json),
so edits land in version control automatically; project doctor reports the
active mode. Consumers install the built @sksizer/sdlc artifact instead
(--mode copy | node-modules).
The substrate: solutions/ontological/lib/
Section titled “The substrate: solutions/ontological/lib/”One file plus four directories, organized by what each part knows about
(solutions/ontological/lib/registry.ts, per D-0007-deterministic-op-substrate §1):
| Path | Holds | Knows about entities? |
|---|---|---|
registry.ts | defineOp / defineService + the runtime registry | — it is the registry |
config/ | sdlc.yaml resolution + validation | no — config is not an entity |
util/ | entity-agnostic infra: yaml, schema, git, gh, prose, fs, naming | no |
model/ops/ | generic cross-entity ops off schema.json: create · validate · audit · migrate | over any entity |
model/entities/<type>/ | schema.json · body-template.eta · migrations/ · ops/ | one entity, behavior co-located |
services/<svc>/ | capabilities that span entities or aren’t about one (lease, quality, dashboard, …) | compose entity ops |
An operation lives with the entity it acts on. That generalizes the
precedent model/entities/<type>/migrations/ already set: behavior is
co-located with its schema, not promoted to a shared bucket on a second
caller. Capabilities that span entities — or aren’t about an entity at
all — are services/.
The registry is the source of truth
Section titled “The registry is the source of truth”Every deterministic operation is one defineOp descriptor: a command
path (2–3 kebab segments), a Zod input and output contract, CLI
flag hints, and a handler. Long-running capabilities (the dashboard,
the lease heartbeat loop) are defineService siblings — a lifecycle
(start/stop?/list?) instead of request/response.
The registry composes itself at process start from two sources
(solutions/ontological/cli/sdlc.ts):
solutions/ontological/lib/registry.ts (defineOp · defineService) ▲ ┌────────────────────┴────────────────────┐ discovery walk (discoverOps) explicit defineOp / barrel ───────────────────────────── ────────────────────────── model/entities/<type>/ops/*.ts model/ops/*.ts (cross-entity: services/<svc>/ops/*.ts audit · validate · migrate · services/<svc>/ops/<group>/*.ts check-identifiers — imported (one sub-level: depth-3 paths) as a barrel at CLI bootstrap) services/<svc>/*-service.ts + project-level ops that fit no (service peers) discovered module shape │ ▼ one path-keyed index │ ┌──────────────┼──────────────┐ ▼ ▼ ▼ CLI (sdlc) MCP HTTP shipped derived derivedThe discovery walk imports every conforming module under
model/entities/<type>/ops/ and services/<svc>/ops/, plus a bounded
one-level descent into ops/<group>/ for depth-3 paths and a second
traversal over services/<svc>/*-service.ts peers for services. A
module’s default export is its descriptor. Generic cross-entity ops live
in model/ops/, which is not a walk root — the explicit
import "@lib/model/ops" barrel in sdlc.ts registers all four at
bootstrap. A malformed module is a reported problem, never a silently
dropped command: project-check-op-modules turns it into a failing
check.
Adapters are generated from the composed index. The CLI ships today; MCP and HTTP are bound to the same projection contract (see Harness-agnostic) but not yet built.
The four moving parts
Section titled “The four moving parts”1. Entities
Section titled “1. Entities”The nouns. Each entity type is defined by a schema.json (its
frontmatter contract), a body-template.eta for new instances, and a
definition.md. Instances live as plain markdown under
docs/planning/<plural>/ with YAML frontmatter validated against the
schema. See Data model for the entity map.
2. Ops
Section titled “2. Ops”The deterministic verbs. Generic cross-entity ops (create, validate,
audit, migrate) read off schema.json and work over any entity;
entity-specific ops (task sort, task inflight) co-locate under the
entity. Each is one registry descriptor with typed I/O. The
Ops reference lists every registered path.
3. Services
Section titled “3. Services”Cross-entity and long-running capabilities. lease, quality,
project, commit, report, index, pr, plugin, and gate are
services that compose entity ops; the dashboard and the lease heartbeat
loop are defineService lifecycles.
4. Skills
Section titled “4. Skills”LLM-orchestrated workflows. Each skill is a SKILL.md under
solutions/ontological/skills/<name>/ with a contract and procedural prose the model
follows. A skill calls ops — it is never an op; the substrate stays
LLM-agnostic. Skills carry only the judgment glue: “is this task spec
coherent?”, “should this review comment be acted on?”, “is this docs page
still true?”. See the Skills reference.
How a single task flows through the system
Section titled “How a single task flows through the system”| Step | Skill | Deterministic op(s) it calls |
|---|---|---|
| Created | /sdlc:task-new | sdlc task create (mints T-NNNN, valid frontmatter) |
| Defined | /sdlc:task-define | — fills sections to entities/task/implementation-ready.md |
| Verified ready | /sdlc:task-ensure-ready | sdlc task update (stamps readiness_verified_at) |
| Worked | /sdlc:task-work | acquires a lease, spins a worktree, opens a PR |
| Closed | /sdlc:task-close-out | sdlc task update (flips to closed/done), tears down |
Every step writes plain markdown; every transition is schema-validated. The LLM never holds state the filesystem doesn’t already record.
Continue
Section titled “Continue”- Deterministic-first — the principle in long form, the output contract, and the render hook.
- Harness-agnostic — why the CLI is an adapter, not the system, and what the projection contract binds.
- Data model — entities, their fields, their relationships.