docs: tag the untagged verifications, and record the UR-007 conflict
Five tests and the schema constant implemented requirements without carrying a tag, so those requirements read as uncovered when they were not. No behaviour changes here — every edit is a comment. Also documents `static` as a real tier rather than an exemption: it is already in `ci_executable_tiers` and its checks run in CI, and it exists because DR-007's single binary and DR-012's licence policy are properties of the build that a unit test could only assert as theatre. The UR-007 note records a cross-repo status conflict rather than resolving it. `jRay` JR-025 is `Done` and claims UR-007, but the fetch path that would exercise it (`jRay` JR-031) is still `Planned`. Either JR-025 is scoped to selection alone or it over-claims; until that is settled neither register should be trusted for UR-007 coverage. The gate reports 0 orphan tags and 19/19 UR coverage. TRACES: DR-001, DR-014, UR-015, UR-016, UR-018 | SR-003, SR-004
This commit is contained in:
+63
-22
@@ -3,7 +3,7 @@
|
||||
<!-- GENERATED FILE - do not edit by hand. -->
|
||||
<!-- Regenerate: scripts/traceability/traceability-gate.sh -->
|
||||
|
||||
**Generated:** 2026-07-31T08:06:49+00:00
|
||||
**Generated:** 2026-07-31T14:25:51+00:00
|
||||
|
||||
Denominators are read from [`requirements.md`](requirements.md) at run time, never hardcoded. Coverage counts a requirement only when it is tagged in source **and** has a verification tier this repo's CI host can execute (`T1, T2, static`).
|
||||
|
||||
@@ -12,12 +12,12 @@ Denominators are read from [`requirements.md`](requirements.md) at run time, nev
|
||||
| Metric | Value |
|
||||
|---|---|
|
||||
| Source files scanned | 29 |
|
||||
| TRACES tags found | 43 |
|
||||
| TRACES tags found | 50 |
|
||||
| EXCEPTION tags found | 0 |
|
||||
| Requirements defined | 33 |
|
||||
| Requirements covered | 26 |
|
||||
| **Coverage** | **78.8%** (26/33) |
|
||||
| Coverage of CI-executable scope | 78.8% (26/33) |
|
||||
| Requirements covered | 31 |
|
||||
| **Coverage** | **93.9%** (31/33) |
|
||||
| Coverage of CI-executable scope | 93.9% (31/33) |
|
||||
| Tagged but unexecuted in CI | 0 |
|
||||
| Orphan tags | 0 |
|
||||
|
||||
@@ -25,8 +25,8 @@ Denominators are read from [`requirements.md`](requirements.md) at run time, nev
|
||||
|
||||
| Type | Covered | Tagged but unexecuted | Defined |
|
||||
|---|---|---|---|
|
||||
| UR | 16 | 0 | 19 |
|
||||
| DR | 10 | 0 | 14 |
|
||||
| UR | 19 | 0 | 19 |
|
||||
| DR | 12 | 0 | 14 |
|
||||
|
||||
- **PR** tags present (separate taxonomy, not counted in coverage): PR-004, PR-005, PR-006
|
||||
- **SR** tags present (separate taxonomy, not counted in coverage): SR-001, SR-002, SR-003, SR-004, SR-005
|
||||
@@ -73,28 +73,35 @@ _None._
|
||||
| UR-012 | Done | T2 | SR-005 | covered | `src/db/repo.rs`, `src/ingest.rs` | Never accept, store, or serve gallery data — reference faces or embed… |
|
||||
| UR-013 | Done | T1 | SR-002 | covered | `src/api/fetch.rs`, `src/model.rs`, `src/validate.rs` | Windows are scene-scoped claims; never reinterpret their boundaries |
|
||||
| UR-014 | Done | T1 | SR-003 | covered | `src/api/federation.rs`, `src/model.rs`, `src/validate.rs` | Reject an unknown `jmanifest_version` outright, never guess |
|
||||
| UR-015 | Done | T2 | SR-003 | untagged | - | Accept `extraction.extinction_sec` in place of `anneal_sec` |
|
||||
| UR-016 | Done | T2 | SR-003 | untagged | - | Accept and store `extraction.gallery_scope`; rank on it (§7) |
|
||||
| UR-015 | Done | T2 | SR-003 | covered | `src/validate.rs`, `tests/api.rs` | Accept `extraction.extinction_sec` in place of `anneal_sec` |
|
||||
| UR-016 | Done | T2 | SR-003 | covered | `src/validate.rs`, `tests/api.rs` | Accept and store `extraction.gallery_scope`; rank on it (§7) |
|
||||
| UR-017 | Done | T1, T2 | SR-003 | covered | `src/model.rs` | Accept per-window belief and identification route; `scenes` are objec… |
|
||||
| UR-018 | Done | T1 | SR-003 | untagged | - | Exclude belief and route from `content_id`, replicating them as attri… |
|
||||
| UR-018 | Done | T1 | SR-003 | covered | `src/ingest.rs` | Exclude belief and route from `content_id`, replicating them as attri… |
|
||||
| UR-019 | Done | T2 | PR-006 | covered | `src/api/upload.rs` | Contributed manifests are CC0 1.0; the grant is delivered with the to… |
|
||||
| DR-001 | Done | T1 | SR-004 | untagged | - | Strict parse boundary: unknown fields rejected structurally, not by v… |
|
||||
| DR-002 | Done | unset | SR-004 | covered | `src/api/fetch.rs`, `src/db/repo.rs` | Fully relational storage — no JSON blob on the write path |
|
||||
| DR-001 | Done | T1 | SR-004 | covered | `src/model.rs`, `tests/api.rs` | Strict parse boundary: unknown fields rejected structurally, not by v… |
|
||||
| DR-002 | Done | T1 | SR-004 | covered | `src/api/fetch.rs`, `src/db/repo.rs` | Fully relational storage — no JSON blob on the write path |
|
||||
| DR-003 | Done | T1 | PR-004 | covered | `src/db/mod.rs` | Single serialized writer connection, with a read pool alongside |
|
||||
| DR-004 | Done | unset | PR-004 | covered | `src/db/repo.rs` | All database access behind a repository layer, not scattered through … |
|
||||
| DR-004 | Done | T1 | PR-004 | covered | `src/db/repo.rs` | All database access behind a repository layer, not scattered through … |
|
||||
| DR-005 | Done | T1 | PR-004 | covered | `src/db/repo.rs` | Background work in-process, with the job queue as a table so it survi… |
|
||||
| DR-006 | Done | unset | PR-004 | covered | `src/ratelimit.rs` | Rate-limit counters in process memory; no external counter store |
|
||||
| DR-007 | Done | unset | PR-004 | untagged | - | Ship a single static binary plus one database file; container optional |
|
||||
| DR-006 | Done | T1 | PR-004 | covered | `src/ratelimit.rs` | Rate-limit counters in process memory; no external counter store |
|
||||
| DR-007 | Done | static | PR-004 | untagged | - | Ship a single static binary plus one database file; container optional |
|
||||
| DR-008 | Done | T2 | SR-004 | covered | `src/auth.rs`, `src/config.rs` | `X-Forwarded-For` honoured only from explicitly configured proxies |
|
||||
| DR-009 | Done | T2 | SR-004 | covered | `src/app.rs` | Body caps enforced while streaming, before parsing, per route |
|
||||
| DR-010 | Done | T1 | SR-003 | covered | `src/api/json.rs` | Request bodies are UTF-8 only, rejected with a diagnosable error othe… |
|
||||
| DR-011 | Done | T1 | SR-003 | covered | `src/content_id.rs`, `src/validate.rs` | `content_id` canonical form is byte-stable and cross-implementation t… |
|
||||
| DR-012 | Done | unset | PR-004 | untagged | - | Dependency audit: advisories, licence policy, source policy |
|
||||
| DR-012 | Done | static | PR-004 | untagged | - | Dependency audit: advisories, licence policy, source policy |
|
||||
| DR-013 | Done | T1 | SR-003 | covered | `src/api/json.rs`, `src/app.rs`, `src/error.rs` | API errors use the status codes the spec names, not the framework's d… |
|
||||
| DR-014 | Done | unset | PR-004 | untagged | - | Portable SQL — no SQLite-specific form where a standard one exists |
|
||||
| DR-014 | Done | static | PR-004 | covered | `src/db/mod.rs` | Portable SQL — no SQLite-specific form where a standard one exists |
|
||||
|
||||
## Detailed mapping
|
||||
|
||||
### DR-001
|
||||
|
||||
**Locations:** 2
|
||||
|
||||
- [`src/model.rs:323`](../src/model.rs#L323) — `fn unknown_field_at_top_level_is_rejected()`
|
||||
- [`tests/api.rs:278`](../tests/api.rs#L278) — `async fn unknown_field_anywhere_is_rejected_with_400()`
|
||||
|
||||
### DR-002
|
||||
|
||||
**Locations:** 3
|
||||
@@ -107,7 +114,7 @@ _None._
|
||||
|
||||
**Locations:** 1
|
||||
|
||||
- [`src/db/mod.rs:30`](../src/db/mod.rs#L30) — `struct ReadPool`
|
||||
- [`src/db/mod.rs:36`](../src/db/mod.rs#L36) — `struct ReadPool`
|
||||
|
||||
### DR-004
|
||||
|
||||
@@ -162,12 +169,19 @@ _None._
|
||||
- [`src/app.rs:26`](../src/app.rs#L26) — `pub fn router(state: AppState) -> Router`
|
||||
- [`src/error.rs:8`](../src/error.rs#L8) — `Unknown`
|
||||
|
||||
### DR-014
|
||||
|
||||
**Locations:** 1
|
||||
|
||||
- [`src/db/mod.rs:30`](../src/db/mod.rs#L30) — `pub mod repo;`
|
||||
|
||||
### PR-004
|
||||
|
||||
**Locations:** 3
|
||||
**Locations:** 4
|
||||
|
||||
- [`src/config.rs:10`](../src/config.rs#L10) — `Unknown`
|
||||
- [`src/db/mod.rs:30`](../src/db/mod.rs#L30) — `struct ReadPool`
|
||||
- [`src/db/mod.rs:30`](../src/db/mod.rs#L30) — `pub mod repo;`
|
||||
- [`src/db/mod.rs:36`](../src/db/mod.rs#L36) — `struct ReadPool`
|
||||
- [`src/db/repo.rs:702`](../src/db/repo.rs#L702) — `pub fn lease_jobs(tx: &Transaction<'_>, now: &str, limit: usize) -> anyhow::Result<Vec<Jo…`
|
||||
|
||||
### PR-005
|
||||
@@ -215,23 +229,27 @@ _None._
|
||||
|
||||
### SR-003
|
||||
|
||||
**Locations:** 11
|
||||
**Locations:** 15
|
||||
|
||||
- [`src/api/federation.rs:258`](../src/api/federation.rs#L258) — `pub async fn get_capabilities(State(state): State<AppState>) -> ApiResult<Response>`
|
||||
- [`src/api/json.rs:100`](../src/api/json.rs#L100) — `fn require_utf8(bytes: &[u8]) -> Result<&str, ApiError>`
|
||||
- [`src/content_id.rs:57`](../src/content_id.rs#L57) — `pub fn canonical_json(`
|
||||
- [`src/content_id.rs:132`](../src/content_id.rs#L132) — `pub fn content_id(`
|
||||
- [`src/error.rs:8`](../src/error.rs#L8) — `Unknown`
|
||||
- [`src/ingest.rs:387`](../src/ingest.rs#L387) — `fn content_id_excludes_belief_and_route()`
|
||||
- [`src/model.rs:191`](../src/model.rs#L191) — `Unknown`
|
||||
- [`src/model.rs:232`](../src/model.rs#L232) — `pub fn from_stored(s: &str) -> Option<Self>`
|
||||
- [`src/model.rs:258`](../src/model.rs#L258) — `Unknown`
|
||||
- [`src/validate.rs:102`](../src/validate.rs#L102) — `pub fn to_centiseconds(secs: f64) -> i64`
|
||||
- [`src/validate.rs:227`](../src/validate.rs#L227) — `pub fn validate_manifest(mut m: Jmanifest) -> VResult<ValidManifest>`
|
||||
- [`src/validate.rs:364`](../src/validate.rs#L364) — `pub fn validate_audio_signature(sig: &str, runtime_sec: f64) -> VResult<()>`
|
||||
- [`src/validate.rs:731`](../src/validate.rs#L731) — `fn extinction_sec_replaces_anneal_sec()`
|
||||
- [`tests/api.rs:323`](../tests/api.rs#L323) — `async fn the_withdrawn_anneal_sec_field_is_rejected()`
|
||||
- [`tests/api.rs:347`](../tests/api.rs#L347) — `async fn the_schema_bump_fields_round_trip()`
|
||||
|
||||
### SR-004
|
||||
|
||||
**Locations:** 16
|
||||
**Locations:** 18
|
||||
|
||||
- [`src/api/report.rs:56`](../src/api/report.rs#L56) — `pub async fn post_report(`
|
||||
- [`src/api/upload.rs:29`](../src/api/upload.rs#L29) — `pub async fn post_manifest(`
|
||||
@@ -244,11 +262,13 @@ _None._
|
||||
- [`src/db/repo.rs:331`](../src/db/repo.rs#L331) — `pub fn insert_manifest(tx: &Transaction<'_>, m: &NewManifest<'_>) -> anyhow::Result<()>`
|
||||
- [`src/model.rs:150`](../src/model.rs#L150) — `Unknown`
|
||||
- [`src/model.rs:258`](../src/model.rs#L258) — `Unknown`
|
||||
- [`src/model.rs:323`](../src/model.rs#L323) — `fn unknown_field_at_top_level_is_rejected()`
|
||||
- [`src/ratelimit.rs:93`](../src/ratelimit.rs#L93) — `impl Default for RateLimiter`
|
||||
- [`src/validate.rs:136`](../src/validate.rs#L136) — `fn is_allowed_text_char(c: char) -> bool`
|
||||
- [`src/validate.rs:227`](../src/validate.rs#L227) — `pub fn validate_manifest(mut m: Jmanifest) -> VResult<ValidManifest>`
|
||||
- [`src/validate.rs:364`](../src/validate.rs#L364) — `pub fn validate_audio_signature(sig: &str, runtime_sec: f64) -> VResult<()>`
|
||||
- [`src/worker.rs:150`](../src/worker.rs#L150) — `async fn run_cast_check(&self, payload: &str) -> Result<(), JobError>`
|
||||
- [`tests/api.rs:278`](../tests/api.rs#L278) — `async fn unknown_field_anywhere_is_rejected_with_400()`
|
||||
|
||||
### SR-005
|
||||
|
||||
@@ -374,6 +394,21 @@ _None._
|
||||
- [`src/model.rs:258`](../src/model.rs#L258) — `Unknown`
|
||||
- [`src/validate.rs:227`](../src/validate.rs#L227) — `pub fn validate_manifest(mut m: Jmanifest) -> VResult<ValidManifest>`
|
||||
|
||||
### UR-015
|
||||
|
||||
**Locations:** 3
|
||||
|
||||
- [`src/validate.rs:731`](../src/validate.rs#L731) — `fn extinction_sec_replaces_anneal_sec()`
|
||||
- [`tests/api.rs:323`](../tests/api.rs#L323) — `async fn the_withdrawn_anneal_sec_field_is_rejected()`
|
||||
- [`tests/api.rs:347`](../tests/api.rs#L347) — `async fn the_schema_bump_fields_round_trip()`
|
||||
|
||||
### UR-016
|
||||
|
||||
**Locations:** 2
|
||||
|
||||
- [`src/validate.rs:731`](../src/validate.rs#L731) — `fn extinction_sec_replaces_anneal_sec()`
|
||||
- [`tests/api.rs:347`](../tests/api.rs#L347) — `async fn the_schema_bump_fields_round_trip()`
|
||||
|
||||
### UR-017
|
||||
|
||||
**Locations:** 2
|
||||
@@ -381,6 +416,12 @@ _None._
|
||||
- [`src/model.rs:191`](../src/model.rs#L191) — `Unknown`
|
||||
- [`src/model.rs:232`](../src/model.rs#L232) — `pub fn from_stored(s: &str) -> Option<Self>`
|
||||
|
||||
### UR-018
|
||||
|
||||
**Locations:** 1
|
||||
|
||||
- [`src/ingest.rs:387`](../src/ingest.rs#L387) — `fn content_id_excludes_belief_and_route()`
|
||||
|
||||
### UR-019
|
||||
|
||||
**Locations:** 1
|
||||
|
||||
Reference in New Issue
Block a user