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:
+23
-1
@@ -53,6 +53,14 @@ requirement and no fixture-generation step, unlike `scene-actor-extraction`.
|
||||
server list and its per-server trust settings, with the community instance
|
||||
pre-configured but disabled. The fetch path that consumes it does not exist yet.
|
||||
|
||||
> **The two registers disagree about this and the disagreement is unresolved.**
|
||||
> `jRay` JR-025 is recorded `Done` and claims to satisfy UR-007, but `jRay`
|
||||
> JR-031 — the fetch endpoints that would exercise the ordered list — is still
|
||||
> `Planned`. Either JR-025 is scoped to the *selection* logic alone (in which
|
||||
> case UR-007 stays open until JR-031 lands) or it over-claims. **Settle this
|
||||
> before either register is trusted for coverage**; it is the only cross-repo
|
||||
> status conflict currently outstanding.
|
||||
|
||||
**UR-008 is `Done` for the replication surface**: change feed, fetch by
|
||||
`content_id`, batch `have`, the peer directory, and a pull worker that
|
||||
re-validates everything it ingests. Peer *administration* — adding and enabling
|
||||
@@ -107,10 +115,18 @@ make the test suite hermetic.
|
||||
|---|---|---|
|
||||
| **T1 — unit** | Yes | Pure logic: validation, cut matching, cast-check scoring, canonicalisation, rate limiting |
|
||||
| **T2 — integration** | Yes | End-to-end through the real router against a temporary on-disk database |
|
||||
| **static** | Yes | Build and dependency properties no runtime test can assert — `cargo deny check`, the musl release build, architectural greps |
|
||||
|
||||
There is no tier that does not run. A requirement here is either verified or
|
||||
visibly not.
|
||||
|
||||
**`static` is a real tier, not an exemption.** `ci_executable_tiers` in
|
||||
[`../traceability.toml`](../traceability.toml) already lists it, and the checks it
|
||||
names execute in CI like any other. It exists because a handful of requirements
|
||||
are properties of the *build* rather than of the running program — DR-007's single
|
||||
binary, DR-012's licence and advisory policy — and asserting those from a unit
|
||||
test would be theatre.
|
||||
|
||||
**Integration tests use an on-disk temporary database, not `:memory:`.** DR-003
|
||||
specifies one writer connection plus a read pool, and in-memory SQLite is
|
||||
per-connection — the readers would see an empty database. Testing the real
|
||||
@@ -126,7 +142,7 @@ topology is the point, so this is a deliberate choice rather than an oversight.
|
||||
| UR-004 | T1 + T2 | Limits engage and carry the documented headers | Window reset; a rejected request does not extend its own lockout; surfaces have independent budgets |
|
||||
| UR-005 | T1 + T2 | Prank manifests rejected; no free-text channel | Uncredited cast rejected; name-only matches capped; automatic revocation needs a minimum sample |
|
||||
| UR-006 | T2 | Bundle accepted per-episode, non-atomically | One bad episode rejected while its neighbours are accepted; envelope errors are whole-request `400` |
|
||||
| UR-007 | — | *No server-side test.* Plugin-side (`jRay` JR-025); the register there carries it | — |
|
||||
| UR-007 | **external** | *No server-side test, and cannot have one.* The obligation is the plugin's: `jRay` JR-025, which is `Done` and tagged in that register | Verified there, not here — counted as covered by cross-reference, never by a test in this repo. **See the status note: JR-025 being `Done` does not by itself close UR-007**, because the fetch path (`jRay` JR-031) is still `Planned` |
|
||||
| UR-008 | T1 + T2 | Feed, fetch-by-hash, batch have, peer directory | **Cursor is strictly monotonic** — a ULID would sort out of write order within a millisecond and silently skip entries; a peer retraction flags rather than delists; only the opt-in abuse channel delists; `pending` is never replicated; **no endpoint can create a peering** |
|
||||
| UR-009 | T1 | Signature structurally validated | Fixed length; reserved high bit; **media < 120 s must send no signature at all** |
|
||||
| UR-010 | T1 + T2 | Actors persist as TMDB person ids | A name the upload invented does not round-trip |
|
||||
@@ -136,7 +152,10 @@ topology is the point, so this is a deliberate choice rather than an oversight.
|
||||
| UR-014 | T1 | Unknown `jmanifest_version` rejected | Version `2` and version `0` both refused, naming the field |
|
||||
| UR-019 | T2 | `POST /tokens` returns the licence and its terms | The terms **bound the grant to the manifest** — a reading that covers the underlying work is the failure, not a missing field |
|
||||
| DR-001 | T1 | Unknown field at any nesting depth fails to parse | `movie` and `jellyfin_id` named in the error |
|
||||
| DR-002 | T1 | Every manifest field lands in a typed column; no JSON blob on the write path | A round-trip through storage reconstructs the manifest from columns alone |
|
||||
| DR-003 | T1 | Concurrent writes serialize rather than returning `SQLITE_BUSY` | Failed transaction rolls back fully |
|
||||
| DR-004 | T1 | Handlers reach the database only through `db::repo` | No `Connection` or raw SQL outside the repository layer |
|
||||
| DR-006 | T1 | Rate-limit counters live in process memory | Counters reset on restart — the documented trade-off, not a bug |
|
||||
| DR-005 | T1 | Jobs lease once, reschedule with backoff, survive restart | Stranded lease released at startup; future job not leased early |
|
||||
| DR-008 | T2 | Forged `X-Forwarded-For` cannot mint a fresh budget | Untrusted peer ignored; trusted proxy honoured; client-supplied entries to the left cannot spoof |
|
||||
| DR-009 | T2 | Oversized body rejected as `413` | **A lying `Content-Length` does not bypass the cap**; per-route limits differ |
|
||||
@@ -147,6 +166,9 @@ topology is the point, so this is a deliberate choice rather than an oversight.
|
||||
| UR-017 | T1 + T2 | Windows carry belief and route through storage | Belief outside `[0, 1]` rejected; an invented `route` rejected |
|
||||
| UR-018 | **T1** | Belief and route absent from `content_id` | Same windows at different belief hash identically; **a real timing change still does not**, so the test cannot pass vacuously |
|
||||
| DR-013 | T1 | Schema mismatch is `400`, not the framework's `422` | §4 names `400` for a forbidden field, and a client checking for it would mishandle `422` |
|
||||
| DR-007 | **static** | The musl release target builds and links one binary needing only a database file | Build property, not a runtime one — a unit test asserting it would assert nothing |
|
||||
| DR-012 | **static** | `cargo deny check` passes advisories, licences and sources | A copyleft-incompatible transitive dependency must fail the build, not be discovered later |
|
||||
| DR-014 | **static** | `schema.sql` uses no SQLite-specific form where a standard one exists | `INSERT OR REPLACE` must not reappear in place of `INSERT ... ON CONFLICT` |
|
||||
|
||||
Three are worth singling out, because each verifies a claim that would otherwise
|
||||
be an assertion:
|
||||
|
||||
Reference in New Issue
Block a user