The module reference
One module's overview, actors, domain model, open decisions and normative functional requirements in a stable reading order.
A module reference says what one module means and must do. It is readable by someone who has never opened the code, and realisable in another technology without changing a rule.
The product reference owns the cross-module picture. The module reference owns field-level domain meaning and functional requirements. Its separate work register owns delivery grouping and progress.
The module reference
Every module uses the same five sections, in this order:
- Overview — purpose, owned facts, boundaries and public surface.
- Actors — the subset of product actors who act in this module.
- Domain model — module-owned entities, value objects, states and invariants.
- Open questions or decisions — unresolved module-local matters and the assumption held meanwhile.
- Functional requirements — normative behaviour grouped by stable domain clusters.
The stable shape is deliberately repetitive. A developer who opens a ninth module should already know where its states, rules and uncertainties live.
Cut by ownership, then by rule
Start with the module that writes the fact. Inside that module, group requirements by stable domain concept or user journey — never by controller, database table, screen, priority or delivery status.
A transition carries its starting state, authorised actor, preconditions, resulting state, permanent trace and observable consequence. Keep those outcomes under one requirement. Cutting them by technical layer produces several partial copies of one rule.
If a rule genuinely spans modules, each module owns its own behaviour and the cross-module scenario links them. There is still no master copy made from pasted requirements.
The shape of a requirement
Each requirement has one stable identifier, an imperative title and three fields:
BKG-001 — Reserve available equipment
Statement The customer can reserve available equipment for a hire period.
Rationale A confirmed reservation prevents conflicting allocation.
Observable The reservation is visible with its equipment and hire period.Use a nested Detailed outcomes (N) section when the observable contract has several cases. Keep it subordinate to the rule; do not flatten every outcome into a peer requirement.
Worked example
BKG-001 — Reserve available equipment
The reader sees the rule first. Detail stays available without turning the specification into a wall of text.
BKG-001 Reserve available equipment
- Statement
- The customer can reserve available equipment for a hire period.
- Rationale
- A confirmed reservation prevents conflicting allocation.
- Observable
- The reservation is visible with its equipment and hire period.
Detailed outcomes (3)
- Overlapping confirmed reservations are refused.
- The quoted price is retained with the reservation.
- Cancellation releases the equipment for the same period.
View source
<details id="bkg-001">
<summary><strong>BKG-001 — Reserve available equipment</strong></summary>
<p><strong>Statement.</strong> The customer can reserve available equipment for a hire period.</p>
<p><strong>Rationale.</strong> A confirmed reservation prevents conflicting allocation.</p>
<p><strong>Observable.</strong> The reservation is visible with its equipment and hire period.</p>
<details>
<summary>Detailed outcomes (3)</summary>
<!-- Observable cases, not additional requirements -->
</details>
</details>Presentation — one shape everywhere
Present each requirement as a collapsed ID + title row. Expansion always
reveals Statement / Rationale / Observable, in that order. The title is an
imperative verb phrase: Register carriers, Quote a reservation, Close a
handover.
The module reference contains no implementation links and no delivery status. That is an authority boundary, not a visual preference.
Identifiers
Use PREFIX-nnn, where the prefix identifies the module or stable requirement
family. Declare the small prefix set once.
An identifier is definitive: never renumber it, never reuse it. When a rule is replaced, mark it superseded and create another identifier. When it is withdrawn, leave the identifier and its history visible.
Requirement IDs are the traceability join used by work registers, code, tests, commits and decisions. A WBS story number is positional delivery structure; it must never replace the durable requirement ID.
Document maturity is not delivery status
| Maturity | Means |
|---|---|
Draft | the document does not yet carry authority |
Accepted | the rules carry authority |
Superseded | another version replaced this document |
planned, in progress, shipped and withdrawn describe delivery and appear
only in the work register. First-release selection also belongs to delivery
planning. Moving it into the specification makes a deferred rule look optional.
Say what is not known
An acknowledged question beats an invented rule. Section 4 keeps module-local open decisions and the assumption held meanwhile. Product-wide questions move to the product reference; technical means move to a proposed decision record.
Run each candidate through the questions pass. Many supposed questions are values that should become configuration.
Rules of writing
- No implementation. No path, symbol, test, library or data structure.
- One rule, one owner. Other documents cite the identifier.
- Present tense. State what the product does, not what it should be able to do.
- The client's language in prose. Code identifiers remain English and the vocabulary carries the normative mapping.
- No dates, estimates, gates or delivery status. They belong to delivery.
- Every observable is testable from outside the implementation.
How this fails
The module page becomes a status dashboard. A shipped badge next to a requirement makes progress look normative and guarantees frequent edits to the source of truth.
Requirements are grouped by endpoints or screens. One business transition then appears in several groups and no longer has one owner.
The root document duplicates module detail. The same actor rule or entity contract now has two accepted copies. The root should name the owner and link.
A work story restates the observable. The stable requirement and the moving
plan will eventually disagree. The story cites BKG-001; it does not paraphrase
it.