Specifications
What the Digital Twin service must do. Everything here is a requirement: a statement about behaviour that a test can be pointed at.
The rest of docs/ describes and teaches. This directory constrains. Where a description
elsewhere disagrees with a requirement here, the requirement is the one that was checked.
The documents
| Document | Covers |
|---|---|
| runtime.md | domain registration, route mounting, entity resolution, authentication, discovery and API documentation, startup, the access audit |
| values.md | value fetcher registration, execution, validation, pagination; the service identity a fetcher may declare, and what the Digital Twin logs; the reference-boundary fetchers |
| query-templates.md | the two rendering phases and the boundary between them |
| grid.md | the it-grid domain: its fetchers, which operator's network every read names, and who may name it |
| participant.md | the it-participant domain: whose twin a caller reads, and which meters it may name |
| community.md | the it-energy-community domain: every REC read names the community in the URL |
Identifiers
Requirements are numbered REQ-####, the harness default.
Numbers are allocated in blocks from REQ-1000 upward (ADR-0001), and a retired requirement's number is never reused:
| Block | Subject |
|---|---|
REQ-10xx |
runtime: registration, routing, entity resolution, authentication, discovery, startup, access audit |
REQ-11xx |
values |
REQ-12xx |
query templates |
REQ-13xx |
grid domain fetchers |
REQ-14xx |
participant domain scoping |
REQ-15xx |
community domain scoping |
Starting at 1000 is not arbitrary. AGENTS.md and the harness rulebook are issued by the
agent harness and cite its own rule identifiers in the same four-digit form — REQ-0003
for the closed directory set, REQ-0012 for an altered standard file, REQ-0303 for a home
path in committed material. Those constrain this repository's structure; the ones here
constrain the service. Keeping this repository's block above them means one number never
means two things.
How a requirement is verified
A test declares what it covers with a @verifies tag in its docstring or in a comment
directly above it:
def test_entity_resolution_reject(self):
"""@verifies REQ-1031"""
...
The mapping from requirement to test is generated from these tags, never written down. A hand-maintained matrix is stale within a week, which is the whole reason the tag lives next to the assertion instead.
Two consequences worth stating, because both are easy to get wrong:
- A requirement with no tag is unverified, and that is a finding rather than a
formatting slip.
tests/test_traceability.pyfails on it, unless the requirement is marked planned (below). - A tag naming a requirement that does not exist is also a failure. Renumbering a requirement without moving its tags breaks the trace silently otherwise.
tests/test_traceability.py enforces both directions in the ordinary suite, so the answer
to "is this verified?" is available from uv run pytest alone — the harness checker
(python -m harness .) is not installed in every checkout.
Planned requirements
A requirement may be written ahead of the code, marked planned
(ADR-0002): a line
**Status:** planned directly under its heading, and no @verifies tag yet. The change that
makes it true lands its tests with their tags and removes the status line in the same change.
A requirement with no status line is implemented. A planned one is a design commitment, not
something a caller may use yet.
tests/test_traceability.py exempts a planned requirement from the "no tag" check, fails on
a tag naming one, and fails on a status line that says anything but planned. The harness
checker does not read the status line and reports a planned requirement as uncovered, which
is the honest reading: nothing verifies it yet.
Writing one
- State behaviour, not implementation. "An unknown fetcher id answers 404", not
"
fetch_values_getcatchesKeyError". The implementation is free to move; the requirement is what must survive the move. - One testable claim per requirement. If a statement needs "and" to hold two independent behaviours, it is two requirements.
- MUST is the only modal. A requirement that something should happen cannot fail.
- If it cannot be tested, it is not a requirement — it is a description, and belongs in the document that describes.