Skip to content

Data model

SDLC tracks 11 entity types: backlog, capability, decision, driver, milestone, principle, product, reference, standard, task, term. Each is defined by a Zod schema (schema.ts), a body template, and a definition.md.

Each entity type owns one directory under solutions/ontological/lib/model/entities/<type>/:

solutions/ontological/lib/model/entities/
_common.ts CommonFrontmatter — the shared Zod base
_registry.ts type → { schema, version } registry
<type>/
schema.ts Zod frontmatter schema + body-section contract(…)
body-template.eta Skeleton body for new instances
definition.md What this entity IS — the authoring contract
migrations/ Per-version migration notes (where present)
ops/ Entity-specific ops (e.g. task/ops/sort.ts)

Every per-type schema extends the shared CommonFrontmatter base (_common.ts) via CommonFrontmatter.extend({ … }) for the fields every entity carries — type, schema_version, id, status, related, tags. The per-type schema specializes where it must (the id pattern, the status enum, its type literal) and adds type-specific fields, then .strict() rejects unknown keys. Instance frontmatter is validated by .safeParse against the schema resolved from the registry by type (solutions/ontological/lib/model/entities/_validate.ts).

Instances live as plain markdown under docs/planning/<plural>/: backlog/, capabilities/, decisions/, drivers/, milestones/, principles/, products/, references/, standards/, tasks/, terms/. Per-instance frontmatter is validated by sdlc entities validate <file> — the generic cross-entity op that resolves the right schema and gates on exit code.

Every entity has an immutable AA-NNNN identifier (D-0002-entity-identifier-shape): a 1–3 letter type prefix plus a 4-character suffix (zero-padded incrementing for curated catalogs, base-36 for high-volume types). The id never changes once assigned, so the filename and every wikilink survive a rename. The slug after the id is optional per D-0002.

TypePrefixNumberingWikilink
backlogB-base36[[B-NNNN-<slug>]]
capabilityC-incrementing[[C-NNNN-<slug>]]
decisionD-base36[[D-NNNN-<slug>]]
driverDR-incrementing[[DR-NNNN-<slug>]]
milestoneM-base36[[M-NNNN-<slug>]]
principleP-incrementing[[P-NNNN-<slug>]]
productPR-incrementing[[PR-NNNN-<slug>]]
referenceRF-incrementing[[RF-NNNN-<slug>]]
standardS-incrementing[[S-NNNN-<slug>]]
taskT-base36[[T-NNNN-<slug>]]
termTM-incrementing[[TM-NNNN-<slug>]]

milestone ids allow a .N sub-id (M-0001.1).

For field-by-field detail — every key, type, enum, requiredness — see the Entities reference. It is regenerated from each type’s Zod schema (zodToJsonSchema in memory), so the prose can’t drift from the schema. This page is the human-facing map: how the pieces relate and why they exist.

TypeRoleKey fields beyond _common
backlogA Backlog item is a stray idea captured before triage — deliberately unstructured, cheap to write, parked until someone decides whether it becomes real work.likely_type, result
capabilityA Capability is a unit of functionality the system provides — an observable ability, described independently of the code that realizes it.kind, audience, parent_key, locations
decisionA Decision (also called ADR — Architecture Decision Record) captures a project-level design choice: the context that prompted it, the options weighed, and the resolution.supersedes, superseded_by, deprecation_note
driverA Driver is a motivating force behind a Product — a pain-point to remove, a use-case to enable, or an opportunity to capture.kind, product
milestoneA Milestone is a release-shaped grouping of work with a target date and success criteria.version, target_date, tasks, relevance_note, completion_note
principleA Principle is a broad value the project leans on for design judgment.
productA Product is a thing this project builds and ships — the SDLC plugin itself, an OSS library extracted from it, the harness.
referenceA Reference is one curated external source — documentation, research, or an artifact SDLC leans on.url
standardA Standard prescribes a rule that applies to a scoped set of paths and explains its application.applies_to, supersedes, superseded_by, deprecation_note
taskA Task is the atomic unit of executable work: one problem, one implementer, typically one PR.impact, priority, complexity, autonomy, kind, scope, scheduling, parent_key, depends_on, prs, relevance_note, completion_note, definition_gap, resolution, resolution_date, resolution_commit, readiness_verified_at, touchpoints_verified_at
termA Term is one entry of SDLC’s shared vocabulary: a named concept with a single authoritative definition.aliases

A task’s status walks four majors: planning/<stage> (spec being shaped, not pickable), open/<stage> (available now), in-progress[/blocked] (someone has it), closed/<reason> (terminal). Under the Git ref leases protocol this field is a workflow cache — the lease ref at refs/sdlc/tasks/<id> is the authoritative claim. readiness_verified_at is stamped by /sdlc:task-ensure-ready once the spec passes the implementation-ready.md gate.

Product ◀── motivates ── Driver
└── delivers ──▶ Capability
Milestone ── owns: tasks[] ──▶ Task ── depends_on ──▶ Task
│ │
└── related ── Milestone └── related ── (any entity)
Decision ── supersedes ──▶ Decision Backlog ── promotes-to ──▶ Task | Milestone
Standard ── supersedes ──▶ Standard Principle ── informs ──▶ Standard | Decision
Term ◀── defines vocabulary for ── everything
Reference ◀── cited by (related:) ── Decision | Standard | Task

The wiring is forward-linked: a milestone owns its tasks: list; a task names its depends_on:. There is no back-link in the child — membership is derived by scanning parents for the wikilink. This is deliberate: back-links double the write surface and create drift risk. related: is the loose, non-directional cross-reference any entity may carry.