Ports JellyTau's traceability tooling to Rust, carrying across the bug it was repaired for. That gate divided a traced count by frozen literal denominators; the requirements file outgrew them and it reported 158% coverage, so it could never fail its own threshold. Two rules, both enforced by the extractor's own tests: - denominators parsed from docs/requirements.md at run time - coverage is |traced ∩ defined| / |defined|, never a raw traced count The gate additionally fails hard on a misconfigured run — zero requirements parsed or zero files scanned — rather than reporting a plausible 0%, and on any orphan tag naming a requirement that does not exist. Adapted for DarkRoom: IDs are FR-CAT-1 / NFR-P13 / FR-DEV-3a shapes rather than JellyTau's fixed three digits, and decisions (D), spikes (S), milestone items (M) and test ids remain taggable while being excluded from the denominator — counting them inflated it by 25. Also adds dr-sync: the RemoteBackend trait and capability model, so the Nextcloud connector is one implementation rather than the only shape the engine understands. No mature Nextcloud crate exists (reqwest_dav is too thin), so the connector will be hand-rolled over reqwest per D7. Gitea workflows follow the same style: containerised, commented with the reasoning, desktop and Android on every push, plus a CI check that no core/ crate depends on the UI toolkit (ARCH §6.5a). Coverage today: 13.3% (19/143). 50 tests passing.
4.2 KiB
4.2 KiB
Requirements traceability matrix
Denominators are parsed from requirements.md at run time, never hardcoded. Coverage is the intersection of tagged and defined IDs over defined IDs, so it cannot exceed 100%.
Summary
| Metric | Value |
|---|---|
| Source files scanned | 16 |
| TRACES tags found | 16 |
| Requirements defined | 143 |
| Requirements covered | 19 |
| Coverage | 13.3% (19/143) |
By type
| Type | Covered | Defined |
|---|---|---|
| FR | 13 | 90 |
| NFR | 4 | 47 |
| R | 2 | 6 |
Orphan tags
A tag naming an ID requirements.md does not define — what renumbering produces, and what a typo produces.
None.
Tagged requirements
| ID | Tagged in |
|---|---|
| FR-CAT-1 | tools/traceability/src/lib.rs:473, tools/traceability/src/lib.rs:505 |
| FR-CAT-1a | core/dr-types/src/lib.rs:23 |
| FR-CAT-2 | tools/traceability/src/lib.rs:473 |
| FR-DEV-4 | core/dr-gpu/src/lib.rs:119 |
| FR-DSP-1 | ui/dr-ui/src/lib.rs:167 |
| FR-NC-12 | core/dr-sync/src/lib.rs:127, core/dr-sync/src/lib.rs:33 |
| FR-NC-3 | core/dr-sync/src/capability.rs:41 |
| FR-NC-4 | core/dr-sync/src/capability.rs:6, core/dr-sync/src/lib.rs:127 |
| FR-NC-6c | core/dr-types/src/lib.rs:111 |
| FR-PLAT-AND-1 | core/dr-types/src/lib.rs:23 |
| FR-RAW-1 | core/dr-types/src/lib.rs:70 |
| FR-UI-1 | ui/dr-ui/src/lib.rs:188 |
| FR-UI-2 | ui/dr-ui/src/lib.rs:188 |
| NFR-OPS-1 | tools/traceability/src/lib.rs:266 |
| NFR-P1 | tools/traceability/src/lib.rs:473 |
| NFR-R7 | core/dr-gpu/src/error.rs:1 |
| NFR-R8 | core/dr-gpu/src/error.rs:1 |
| R1 | tools/traceability/src/lib.rs:489, tools/traceability/src/lib.rs:493 |
| R4 | core/dr-gpu/src/lib.rs:119 |
Not yet tagged
124 of 143 requirements have no implementation tag. Expected while the codebase is young; each should gain one as it is built.
Show untagged requirements
- FR-CAT-10
- FR-CAT-11
- FR-CAT-12
- FR-CAT-13
- FR-CAT-14
- FR-CAT-3
- FR-CAT-4
- FR-CAT-5
- FR-CAT-6
- FR-CAT-7
- FR-CAT-8
- FR-CAT-9
- FR-CULL-1
- FR-CULL-2
- FR-CULL-3
- FR-CULL-4
- FR-CULL-5
- FR-CULL-6
- FR-CULL-7
- FR-DEV-1
- FR-DEV-2
- FR-DEV-3
- FR-DEV-3a
- FR-DEV-3b
- FR-DEV-3c
- FR-DEV-3d
- FR-DEV-3e
- FR-DEV-3f
- FR-DEV-3g
- FR-DEV-5
- FR-DEV-6
- FR-DEV-7
- FR-DEV-8
- FR-DSP-2
- FR-DSP-3
- FR-DSP-4
- FR-DSP-5
- FR-DSP-6
- FR-DSP-7
- FR-DSP-8
- FR-EXP-1
- FR-EXP-2
- FR-EXP-3
- FR-EXP-4
- FR-EXP-5
- FR-EXP-6
- FR-EXP-7
- FR-EXP-8
- FR-EXP-9
- FR-NC-1
- FR-NC-10
- FR-NC-11
- FR-NC-2
- FR-NC-5
- FR-NC-6
- FR-NC-6a
- FR-NC-6b
- FR-NC-7
- FR-NC-8
- FR-NC-9
- FR-PLAT-AND-2
- FR-PLAT-AND-3
- FR-PLAT-AND-4
- FR-PLAT-AND-5
- FR-PLAT-AND-6
- FR-PLAT-LIN-1
- FR-PLAT-LIN-2
- FR-PLAT-LIN-3
- FR-RAW-2
- FR-RAW-3
- FR-RAW-4
- FR-RAW-5
- FR-UI-3
- FR-UI-4
- FR-UI-5
- FR-UI-6
- FR-UI-7
- NFR-A11Y-1
- NFR-A11Y-2
- NFR-A11Y-3
- NFR-ARCH-1
- NFR-ARCH-2
- NFR-ARCH-3
- NFR-ARCH-4
- NFR-COMPAT-1
- NFR-COMPAT-2
- NFR-OPS-2
- NFR-OPS-3
- NFR-OPS-4
- NFR-P10
- NFR-P11
- NFR-P12
- NFR-P13
- NFR-P14
- NFR-P15
- NFR-P2
- NFR-P3
- NFR-P4
- NFR-P5
- NFR-P6
- NFR-P7
- NFR-P8
- NFR-P9
- NFR-PORT-1
- NFR-PORT-2
- NFR-PORT-3
- NFR-R1
- NFR-R2
- NFR-R3
- NFR-R4
- NFR-R5
- NFR-R6
- NFR-RES-1
- NFR-RES-2
- NFR-RES-3
- NFR-RES-4
- NFR-SEC-1
- NFR-SEC-2
- NFR-SEC-3
- NFR-SEC-4
- R2
- R3
- R5
- R6