Contributed manifests were in no declared condition at all, which left §9a
replication with no grant flowing through it: peers mirror each other's
catalogues wholesale, and every hop of that was unlicensed.
CC0 rather than a share-alike licence, because a share-alike works by asserting
a right in the data and then conditioning its use. The position in
docs/legal-posture.md §3 is that presence timings are facts rather than
protectable expression — asserting copyright in them in order to license them
would contradict that argument in the same repository, and that contradiction is
worth more to an opponent than the licence is worth to us. CC0 also waives the
sui generis database right by name, closing the EU-specific residual exposure
from the contributor's side.
The grant is taken at token issuance, and that is not incidental. There are no
accounts, so there is no sign-up to attach terms to, and a manifest arrives over
POST /manifests with no channel to negotiate over. Acquiring the contribute
capability is the only moment a grant can be made, so POST /tokens now returns
the licence and its terms alongside the token — a licence the server publishes
but never delivers is one no contributor agreed to.
The test pins the scope limit as well as the identifier. Bounding the grant to
the manifest is the half that can fail silently: a reworded term reading onto
the underlying work would purport to grant what no contributor can.
Also records the settled code-licence position across all four repositories in
the legal posture, correcting an earlier claim there that the plugin and
extraction repos declared nothing. Both already carried LICENSE files.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
TRACES: UR-019 | PR-006
Adds jray-project as a submodule at scripts/vendor/jray-project, so this repo
runs the same extractor as every other component rather than its own copy, and
gains the system spec that defines the PR/SR requirements its register traces
up to.
scripts/traceability-gate.sh is a thin wrapper holding only what is specific to
this repo: UR/DR prefixes, .rs sources, and REPO_ROOT — which the shared gate
cannot infer once vendored, since its default resolves to the submodule itself.
Each override fails silently in a way that looks like "no work done" rather
than "misconfigured", so the wrapper documents why each is needed.
Annotates 35 units with TRACES tags, on the code that decides rather than every
helper it calls. Coverage is 23/32 (71.9%) with no orphan tags. The nine
untraced are genuinely unimplemented: UR-007 is plugin-side, UR-008 is
federation, and UR-015..018 are the pending SR-003 schema bump.
The gate caught a real error in the first pass: several tags separated IDs of
different types with commas. A comma joins IDs within one type; a pipe
separates types. Fixed, and the diagnostics are now clean.
MIN_COVERAGE stays 0 deliberately. The gate still fails on orphan tags, a >100%
ratio, a register parsing to nothing, or an empty source scan — raise the
threshold as a ratchet once the remaining work lands.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Implements the core of SPEC.md — the manifest exchange, less audio-tier
matching (§3) and federation (§9a), both of which the spec sequences as
later work.
- §2 Jmanifest format and series bundles
- §3 cut matching: exact / runtime / loose tiers
- §4 API, less POST /manifests/search
- §5 rate limiting; §5a trust model, anonymous bearer tokens
- §6 upload validation, all four stages
- §7 relational storage, no JSON blob on the write path
- §8 Rust + Axum + SQLite, single serialized writer, in-process job queue
- §9a content addressing, computed on upload
Reconciled against the system spec:
- anneal_sec removed, withdrawn upstream by AR-012/AR-013. Presence follows
track extent, so a track survives its own gaps and there is nothing to
anneal. Its successor extinction_sec and the new gallery_scope are accepted
and stored; scope enters the §7 ranking. A manifest still carrying
anneal_sec is a hard 400, not silently ignored — it came from a pipeline
whose window semantics differ from what this server assumes.
- Audio signature: media under 120 s now emits no signature at all, matching
scene-actor-extraction IR-007. The earlier §3 draft allowed a shortened
window under 150 s, which was the weaker rule — a caller-varying length is
the property SR-004 forbids.
- UR IDs regularised to UR-nnn; docs/requirements.md registers 32
requirements, each tracing to an SR-nnn or PR-nnn.
189 tests: unit, end-to-end through the real router, and an injection suite
covering SQL, JSON, header and Unicode payloads. Writing that suite found two
real gaps, both fixed here: compatibility homoglyphs passed the §5a character
class, and a one-frame audio signature was accepted on a feature-length item.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>