← The specification

Repo: lemonfiber-decline

Rendered from spec at76d46f3 (2026-10-25) · its source · Edit this page

Status: Accepted

The decline service: the one image that answers an invitation’s decline address. Rust, one crate, one image.

Implements: ADR-0029, for D6-R15, D6-R16, D6-R21 and G5-R14. Its place in the organisation is ADR-0033.


What this repo is

The source of ghcr.io/lemonfiber/decline, which the stack runs as the service decline. It answers three routes on its own origin, a page naming what would be declined, the refusal, and its health. Once a minute it takes back every invitation whose window has closed. It makes five fixed Jellyfin calls with the one API key minted for it alone, and changes an account in one of two ways: it switches it off, or, under the guards ADR-0029 §2a states, removes it.

What it holds, and what it does not

Holds Does not hold
One Rust binary crate, with the core’s lints, deny policy and coverage floor, depending on the core’s crates at a pinned core commit The compose entry, which is lemonfiber-media-stack’s
One Dockerfile, ending on a distroless static base as a non-root user Any credential: the key and the invitation table arrive as files the core writes
Recordings of its Jellyfin calls on every supported line (ADR-0028) Code shared with lemonfiber-request-gate
The containment ADR-0029 §6 requires, stated as what it needs from the stack

Releasing

On the train (ADR-0033 §3–§4). Its entry in repos.toml carries service = "decline", which is how the train knows it. A version that lists this repository in repos tags it before the core: at v<version>, and at v<version>-<identifier> for each pre-release. Each signed tag builds linux/amd64 and linux/arm64 under one index with a software bill of materials and a provenance attestation, and opens a pull request on lemonfiber-media-stack setting the service’s tag and digest. The core is tagged at the same tag once the stack it embeds pins that digest. Every commit on main is published too, as main-<commit>, and where the repository holds its plugin.toml that manifest’s pin moves to it on a rolling pull request, with every recording the manifest names taken again from the new image and proofs.json written from them; a commit image is not a release and the stack is never told of it (OPS-R90, OPS-R91). A commit that changes nothing but that pin, its recordings, its proofs and its targets.toml publishes nothing. Nothing else is published from a branch.