7.5 KiB
model-catalog Specification
Purpose
The model catalog is the single descriptive home for the member console's as-built domain models (Decision 141, design/documents/doc-43-schema-topology-and-documentation-division.md): one card per model under docs/models/, synthesizing what a maintainer must hold to modify that model safely. Cards describe; they never decide. The designed model and its decisions live in the four normative surfaces synced under design/.
Requirements
Requirement: Catalog coverage and index
The catalog SHALL consist of docs/models/README.md plus one card file per domain model, covering: product-catalog, payments-billing, plan-ladders-transitions, entitlements, resource-pools, provider-integration, domains-registry, and identity-organization-workspace. Each card SHALL carry the standard docs front matter (title, audience, summary), the index SHALL list every card with a one-line summary, and docs/README.md SHALL link the catalog in its developer-audience group.
Scenario: A newcomer finds a model's card
- WHEN a maintainer opens
docs/README.mdlooking for how a domain model works - THEN the developer-audience group links
docs/models/README.md, and the index lists a card for each of the eight models with a summary that identifies its subject
Scenario: A model without a card
- WHEN a new domain model is introduced into the codebase after this catalog exists
- THEN the model is not considered documented until a card following this capability's requirements is added and indexed
Requirement: Card anatomy
Each card SHALL contain exactly four sections in this order: Purpose, Where this lives, Invariants, Dimensions. Purpose SHALL state in plain present tense what the model owns and why it exists. Where this lives SHALL map the model's pieces — each table, view, function, and code file with one line saying what it is — and SHALL be the home for file locations. Invariants SHALL be a numbered list in which each entry states one rule as a full sentence and carries an enforcement tag: [db] when the database schema rejects violations outright, [db-code] when the rule holds because the database functions are written to uphold it, [app] when only application code upholds the rule. The tag SHALL match the actual enforcement mechanism — a rule no constraint rejects is never tagged [db]. Dimensions SHALL name and define each orthogonal axis a maintainer must hold simultaneously. Cards SHALL introduce every table, column, view, function, and concept before or where it is first used, and SHALL NOT contain history, decision numbers, change narrative, drift bookkeeping, or open-question sections in the body.
Scenario: Reading a card before modifying a model
- WHEN a maintainer reads a card top to bottom before changing the model's code
- THEN they encounter the model's purpose, then the map of where it lives, then its load-bearing rules with their enforcement layer, then its axes, with no section missing and no other section interleaved
Scenario: A reader with zero context
- WHEN a reader who has never seen the codebase encounters any term, table, or concept in a card
- THEN the card has already introduced it, or introduces it in the same sentence, so the reader never needs an artifact outside the card to parse the card
Requirement: Citation discipline
File locations SHALL live in the card's Where this lives section; body prose SHALL reference pieces by name (for example, "the purchasability gate — see the map") rather than by path. A reader following an invariant's enforcement tag and the map SHALL reach the enforcing migration or file without searching. Citations SHALL NOT use line numbers. Cards SHALL NOT restate schema: no full table or column listings that duplicate design/data-model.md or the migrations.
Scenario: Verifying an invariant
- WHEN a maintainer doubts an invariant stated in a card
- THEN the invariant's enforcement tag plus the Where this lives map lead them to the enforcing migration or file, without searching the repository
Requirement: Drift and open-question routing
Cards SHALL NOT carry drift or open-question sections. Drift between design and code discovered while writing or maintaining a card SHALL be ledgered under "Model documentation" in status/issues.md with both ends of the divergence cited. An open question needing a normative decision SHALL be filed upstream in membcons-db as a Stage-1 issue; a member-console implementation question SHALL be recorded in status/issues.md. Cards SHALL NOT answer normative questions, and SHALL NOT cite allocated-but-unratified decisions.
Scenario: Writing a card exposes design/code drift
- WHEN writing or updating a card reveals that the designed model and the as-built model diverge
- THEN the card body describes only the as-built behavior, and the divergence is ledgered in
status/issues.mdciting the designed side (a normative surface) and the as-built side (a migration or file)
Scenario: A card surfaces a question needing a normative decision
- WHEN writing or updating a card exposes semantics the design has not decided
- THEN the question is filed upstream as a Stage-1 issue and the card states no local answer
Requirement: Card maintenance
A change that alters an invariant, dimension, or map entry recorded on a card SHALL update that card in the same change. A change that resolves a ledgered drift or open-question entry SHALL update that ledger entry in the same change.
Scenario: A code change alters a carded invariant
- WHEN a change modifies behavior that a card records as an invariant
- THEN that change's diff includes the corresponding card update, and review of the change checks the card against the new behavior
Requirement: Prose contract
docs/models/README.md SHALL state the catalog's concrete-prose rules: write for a reader with zero context; name the agent; state what the agent did to what; give each verb its own object; connect clauses with explicit causal or temporal words; replace metaphor with the literal claim it stands for. All card prose SHALL follow these rules.
Scenario: Reviewing new card prose
- WHEN card prose is added or edited
- THEN the reviewer checks it against the rules stated in the index, and prose that hides an agent, an object, or a causal relation is rewritten before the change lands
Requirement: Cards are the only descriptive home
A developer-audience document whose content re-describes a carded domain model SHALL be retired in favor of the card, with the docs index updated; it SHALL NOT be maintained in parallel. Documents that survive because they serve a different job (operator how-to, setup guides, runbooks) SHALL reference the relevant card for model description rather than restating it, and SHALL describe only their own procedures. Historical narratives a retired document carried (incidents, motivations) SHALL be preserved under status/ rather than deleted or moved into a card.
Scenario: A legacy doc duplicates a card
- WHEN a developer doc's content is model description that a card now covers
- THEN the doc is deleted, the docs index drops it, and any surviving non-descriptive residue (for example an incident history) moves to
status/
Scenario: A how-to doc needs model background
- WHEN an operator or setup guide would explain how a domain model works to motivate its procedures
- THEN it links the model's card for that background and keeps only procedure in its own body