feat(audio): store, serve and match the v1 audio signature
Completes UR-009. The register recorded the signature as stored; it was not. `ingest` validated `cut.audio_signature` and wrote NULL, so every served manifest came back without one — which also meant the plugin's own alignment (jRay JR-047, Done) had nothing to align against and could never run. That is the failure mode a status field is least able to catch: every validation test passed and the feature delivered nothing. Now stored, coarse-indexed and served back byte-identically, with a held manifest adopting an incoming signature it lacked (§9a). `audio`-tier matching runs on every read endpoint via an `audio_signature` parameter, and `POST /manifests/search` answers the unknown-providence case with a runtime prefilter, a bounded scan and honest truncation reporting. Three rules §3 did not previously state, now normative: - **±1 frame of slack in the score.** scene-actor-extraction VR-014 measured the exact-frame rule demoting 27 of 40 correctly aligned releases to `loose`, because the two windows are cut on their own file's frame grid and those grids do not coincide. With ±1 frame all 40 reach `audio` (worst 0.906) and the strongest false match is unmoved at 0.16. - **The offset has two terms.** Both windows are anchored at their own file's runtime/2, so the slide alone is wrong by half the runtime difference on every shifted release. A signature without a runtime therefore cannot align, and is refused by name rather than answered at a lower tier. - **A signature verdict is final**, including its refusals. Falling back to the runtime tier after the audio declined would let a coincidence overturn direct evidence, inverting the ordering the tier table exists to state. The slide precomputes each frame's neighbourhood as a 32-bit bin set rather than re-deriving it across 1201 slides — 3.3 ms to 1.1 ms per candidate, with a test asserting exact equivalence to the rule written the obvious way. The 1000-candidate search cap follows from that measurement as a ~1.1 s ceiling per request, not a round number. jRay's matcher still implements the pre-slack rule and will label some alignments `loose` that this server calls `audio`. Nothing misaligns — JR-047 makes the local answer win — but that register now carries the follow-up. TRACES: UR-008, UR-009 | SR-003
This commit is contained in:
@@ -94,13 +94,18 @@ Reconciled with the system spec (see `docs/requirements.md` for the detail):
|
||||
caller-varying length is the property SR-004 forbids. Items under 120 s now
|
||||
send no signature at all.
|
||||
|
||||
Deferred:
|
||||
- **Audio signatures are complete (UR-009).** The field is accepted, validated,
|
||||
stored and **served back**, `content_id` still excludes it, `audio`-tier
|
||||
matching runs on every read endpoint, and `POST /manifests/search` answers
|
||||
the unknown-providence case. §3's scoring rule gained ±1 frame of tolerance
|
||||
on `scene-actor-extraction` VR-014's measurement — the exact-frame rule
|
||||
demoted correctly aligned releases to `loose` because the two windows' frame
|
||||
grids do not coincide.
|
||||
|
||||
The signature stays optional throughout: a manifest without one is matched by
|
||||
the runtime tiers exactly as before. This is an enhancement, and §3 requires
|
||||
that it never be able to break a fetch.
|
||||
|
||||
- §3 audio signatures — the field is **accepted, validated and stored**, and
|
||||
`content_id` already excludes it, but `audio`-tier matching and
|
||||
`POST /manifests/search` are not wired up. This follows §3's own recommended
|
||||
sequencing: ship the plugin-side computation first, let signatures accumulate,
|
||||
then enable matching once coverage is useful.
|
||||
(Federation landed — see below.)
|
||||
|
||||
## Running
|
||||
@@ -120,6 +125,7 @@ Configuration is entirely environment variables:
|
||||
| `JRAY_TRUSTED_PROXIES` | — | Comma-separated proxy IPs whose `X-Forwarded-For` is honoured. **Not default-on**: §5 rate limiting and report attribution key on client IP, so a spoofable header defeats both |
|
||||
| `JRAY_SERVER_ID` | `localhost` | This server's identity, used as manifest `origin` and as the report IP-hash salt |
|
||||
| `JRAY_REQUEST_TIMEOUT_SEC` | `30` | Request timeout so a slow bundle query fails fast |
|
||||
| `JRAY_AUDIO_SEARCH` | `1` | `POST /manifests/search`. §3 makes it optional for a server to implement because it is the most expensive read surface; set `0` to withdraw it, and `GET /federation/capabilities` stops advertising it. `audio`-tier matching on the ordinary reads is unaffected |
|
||||
| `JRAY_JOB_BATCH` | `8` | Cast-check jobs leased per worker tick |
|
||||
| `JRAY_JOB_POLL_SEC` | `5` | Worker poll interval |
|
||||
| `JRAY_LOG` | `info` | `tracing` filter |
|
||||
|
||||
Reference in New Issue
Block a user