Files
dtourolleandClaude Opus 5 a848750a65
CI / fmt, clippy, test (push) Failing after 2m46s
CI / static musl binary (push) Has been skipped
CI / advisories and licences (push) Successful in 4m22s
Initial implementation: core vertical slice
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>
2026-07-30 18:14:02 +02:00

92 lines
3.4 KiB
TOML

# cargo-deny configuration.
#
# This crate is GPLv3 (it shares a licence with the JRay Jellyfin plugin), and it
# is a long-lived network service whose main risks are hostile input and operator
# friction (§8). So two checks matter most here:
#
# - `advisories` — a public-facing service must not ship known-vulnerable
# dependencies.
# - `licenses` — GPLv3 is compatible with permissive licences, but *not* with
# everything. A copyleft-incompatible dependency arriving transitively would
# be a licensing problem discovered far too late.
#
# Run with `cargo deny check`.
[graph]
# Check the targets an operator actually deploys. §8 ships a single static binary
# (musl target), so both glibc and musl Linux are in scope.
targets = [
"x86_64-unknown-linux-gnu",
"x86_64-unknown-linux-musl",
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-musl",
]
all-features = true
[advisories]
version = 2
# Fail on any RustSec advisory. Unmaintained crates are a warning rather than an
# error: `sled` was rejected in §8 partly on maintenance grounds, so the signal is
# worth surfacing, but it should not break a build on its own.
yanked = "deny"
unmaintained = "workspace"
ignore = []
[licenses]
version = 2
# Permissive licences, all GPLv3-compatible. Deliberately a closed allow-list
# rather than a deny-list: a licence nobody vetted should stop the build, in the
# same spirit as §6's "no additional fields anywhere".
#
# Kept to licences actually present in the tree, so `cargo deny` stays quiet in
# CI and an added allowance is a visible decision. Adding a dependency that needs
# a new licence should be a deliberate edit here.
allow = [
"Apache-2.0",
"MIT",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"Zlib",
"Unicode-3.0",
# `webpki-roots` — Mozilla's trusted CA certificate set. This is a *data*
# licence, not a code licence, which is why it is not on the usual permissive
# list: the crate ships certificates rather than logic. CDLA-Permissive-2.0
# imposes no copyleft and no attribution burden on a binary that embeds it, so
# it is compatible with distributing this server under GPLv3.
#
# It arrives via reqwest's rustls stack, which §8's single static musl binary
# depends on (bundling roots is what lets the binary verify TLS without a
# system trust store).
"CDLA-Permissive-2.0",
# This crate's own licence.
"GPL-3.0-or-later",
]
confidence-threshold = 0.9
# `ring` ships a bespoke licence file that no SPDX expression describes; it is
# a permissive OpenSSL/ISC-style licence and is GPL-compatible. Clarify it rather
# than widening the allow-list.
[[licenses.clarify]]
crate = "ring"
expression = "MIT AND ISC AND OpenSSL"
license-files = [{ path = "LICENSE", hash = 0xbd0eed23 }]
[bans]
multiple-versions = "warn"
wildcards = "deny"
# Nothing is banned outright yet. The obvious future entries are alternative TLS
# stacks: reqwest is pinned to rustls (`default-features = false`) so that a
# static musl binary needs no system OpenSSL, and an accidental openssl-sys
# dependency would silently break that deployment story.
deny = []
skip = []
skip-tree = []
[sources]
unknown-registry = "deny"
unknown-git = "deny"
# Only crates.io. A git dependency in a service that hobbyist operators build
# from source is a supply-chain and reproducibility problem.
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
allow-git = []