0.18.0168 goals

brand

  • ARCH-R38▲ unmarkedClaim it

    Tokens MUST be published as both tokens.css and tokens.json, with identical values.

lemonfiber

  • G1-R15▲ unmarkedArea GClaim it

    Every surface that shows pairing material, an invitation's sign-in address, join link or decline address, the front door address, a device hand-off's address or one of its clients' codes, or a minted key's secret MUST offer each as a QR code beside its text, drawn on that surface from the text exactly as the stack gave it.

  • G2-R16▲ unmarkedArea GClaim it

    A member's surface MUST NOT show a service's name, a domain term, a size, a rate, an address, a version, a stage of the pipeline, or how the stack stands, and MUST say what it says in household words, leading with what the member can do. Where it names the stack it MUST call it the house. A member's surface is any screen drawn for a household member's session on any surface, any notification sent to a member, and any text lemonfiber places where the household asks for things.

  • B2-R18▲ unmarkedArea BClaim it

    The lines the container engine writes while pulling images MUST reach the web API's event stream as pull events, for a fetch and for a start that pulls, as they reach a terminal (B2-R12, N2-R24).

  • ARCH-R9○ openClaim it

    Machine-readable output MUST carry an api_version.

  • ARCH-R35▲ unmarkedClaim it

    Platform detection MUST be a single component; per-platform behaviour MUST NOT be scattered through call sites.

  • ARCH-R38▲ unmarkedClaim it

    Tokens MUST be published as both tokens.css and tokens.json, with identical values.

  • ARCH-R42▲ unmarkedClaim it

    Every surface MUST reach behaviour through a single dispatch entry point in lemonfiber-core; a surface MUST NOT orchestrate the core's subsystems directly.

  • ARCH-R45▲ unmarkedClaim it

    Test fakes for the ports MUST have a single home reachable from both in-source and integration tests, and that home MUST NOT depend on lemonfiber-core.

  • F14-R7▲ unmarkedArea FClaim it

    Every part of the bundle MUST be a first-party plugin, installed, updated, removed and validated by the path any plugin takes, and the bundle and its first-party manifests MUST be embedded in the binary.

  • F14-R8▲ unmarkedArea FClaim it

    The vocabulary MUST name proxy.front, dashboard.show, quality.sync, archive.extract, stream.guard, invite.decline and request.gate, each with a contract, and every capability in the vocabulary MUST be asked by something in the bundle or by the core over its contract.

  • ARCH-R206▲ unmarkedClaim it

    A filler of media.serve MUST answer declared with its byte paths, each with where the item's id sits, the shape an id has and the paths under it that name no item, its question, its token presentation with the query parameters the upstream also reads a token from, its refused paths, the query parameters on each byte path that name another item, each marked refused or asked with the shape of the item an asked one names, its location templates and its ports, and a declaration that admits a byte path without a question, or whose template host is not {base}, MUST be refused at install.

  • ARCH-R207▲ unmarkedClaim it

    The core MUST give the filler of stream.guard, inside the envelope apply a guard carries (ARCH-R303), the media server filler's declaration unaltered and nothing added to it, and MUST build every location a member is given from the declared templates.

  • ARCH-R224▲ unmarkedClaim it

    lemonfiber MUST write the Compose entry of every service it runs, the stack's own and every plugin's, from the one typed service model, as one generated project, and MUST NOT read a Compose file, fragment, template or overlay from the stack or from a plugin.

  • ARCH-R225▲ unmarkedClaim it

    A first-party plugin's service, a third-party plugin's service and a stack service MUST be declared in the same closed set of container fields, with the same types and the same validation, and whether a plugin is first-party MUST NOT change which of those fields it may declare or how its entry is written.

  • ARCH-R226▲ unmarkedClaim it

    A service MUST be published at port to its listens port, or to port itself where it declares none, and at each [[service.publish]] entry alike, every one on the interface its bind tier renders; a port another service publishes MUST be refused, naming the port and both services; and the manifest MUST have no field naming an address or an interface.

  • ARCH-R227▲ unmarkedClaim it

    A service MAY mount its configuration directory read-only, MAY declare further mounts whose source is a relative path inside its own mount tree, ./mounts/<id>, which lies apart from its configuration directory, read-only where it says so, and MAY declare tmpfs paths; a source that is absolute, holds .., interpolates or lies inside another of the service's sources, and a target that is not absolute, is /, lies within /data on a service that takes data or is another of its mounts' targets, MUST be refused naming the mount, and the manifest MUST have no field by which a mount reaches any other path on the host.

  • ARCH-R228▲ unmarkedClaim it

    A service's state MUST live under its own configuration directory and its own mount tree, and lemonfiber MUST NOT write a volume the engine keeps for a service; the in-place move of a part whose entry kept state in such a volume MUST copy it into the service's mount tree once, mount it from there, and leave the volume as it was.

  • ARCH-R229▲ unmarkedClaim it

    A service's environment MUST be declared in [service.env], every value a constant, an operator setting with a default, the URL of a capability's filler, or a declared secret, and nothing else; a value of any other kind, and a manifest naming TZ, PUID or PGID there, MUST be refused naming the variable.

  • ARCH-R230▲ unmarkedClaim it

    lemonfiber MUST write every constant, every setting's value and every secret so that Compose substitutes nothing in it, and MUST NOT write any value a manifest declares as a reference to the stack's environment file.

  • ARCH-R231▲ unmarkedClaim it

    A setting MUST be one the core publishes or one in the declaring plugin's own namespace, a stack service's own id for a stack service, and any other MUST be refused naming it; lemonfiber MUST write the operator's value where one is recorded and the declared default otherwise.

  • ARCH-R232▲ unmarkedClaim it

    { url_of = "<capability>" } MUST name a core capability and MUST be an ask of one filler, narrowed by files to the filler that files that medium where it is given, one ask with every other variable or [[ask]] of the same service naming that capability and medium, held to every rule an [[ask]] is held to and settled, shown and counted as one, and a variable naming a capability its service asks each of MUST be refused; lemonfiber MUST write it as the URL of the service the ask reaches at the port that service listens on, and MUST leave the variable out, reporting the ask unfilled, while nothing fills it.

  • ARCH-R233▲ unmarkedClaim it

    user_mode MUST be image, puid-env or uid, written respectively as no user, as PUID and PGID set to the operator's uid and gid, and as the operator's uid and gid for the container's user; a service that speaks a contract or whose posture is confined MUST be uid, and one that is not MUST be refused naming the service.

  • ARCH-R234▲ unmarkedClaim it

    Every service's entry, the stack's own and every plugin's, MUST be written with posture = "standard" unless it declares confined: gaining no privilege after it starts, holding no kernel capability but CHOWN, DAC_OVERRIDE, FOWNER, SETGID, SETUID, KILL and those its shape adds, and holding at most 1024 processes; a service whose posture is confined MUST in addition be written with a read-only root, no kernel capability at all and the uid user, and a confined service declaring a shape MUST be refused naming the service.

  • ARCH-R235○ openClaim it

    mem_limit_mib MUST be written as the container's memory limit, and memory_mib MUST be an estimate that is never written as a limit.

  • ARCH-R236▲ unmarkedClaim it

    network = { via = "<capability>" } MUST name a capability from a closed set holding network.egress-guard alone and not one the service provides; lemonfiber MUST write the service into the network namespace of the service that fills it, or of the upstream that filler's adapter fronts where an adapter fills it, MUST start that filler first and start the service only once the filler reports healthy, whatever profile the filler sits in, MUST publish the service's ports on the filler's entry on the service's own tier, MUST give the service no network of its own, and MUST settle, show and count it as an ask of that capability.

  • ARCH-R237○ openClaim it

    A device, a group or an added kernel capability MUST come only from a named shape in a closed set holding egress-guard and render; render MUST be declared only by a service that provides media.serve or by the upstream an adapter of the same plugin fronts where that adapter speaks it, refused naming service <id>.shape elsewhere, and MUST be written as the host's /dev/dri device with the group that owns it on the host added, or as nothing where the host has no /dev/dri, which the reading MUST say.

  • ARCH-R240▲ unmarkedClaim it

    The data root MUST be one operator setting, the lemonfiber config key DATA_ROOT, holding an absolute host path or a path relative to the stack directory that stays inside it (a bind), or nfs://<server>/<export> (an NFS export), and MUST be ./data within the stack directory where it is unset; lemonfiber MUST write the single data mount of every service that takes data from it and from nothing else; a relative path that leaves the stack directory or names the stack directory itself, a server that is not a host name or an address, and an export that is not an absolute path or holds a character that would change the mount options written, MUST be refused naming it; the NFS server and export kept for the retired NAS overlay MUST be folded into it once, journalled; and for an NFS export the doctor MUST report the storage mode as nas and MUST say the checks that read a host path were not run rather than report them passed.

  • ARCH-R242▲ unmarkedClaim it

    Each settled ask MUST be a network of its own joining the asking service and the service the ask reaches, with no route off the host; a service given a proxy hostname MUST ask proxy.front and one whose dashboard panel reads it dashboard.show; an ask filled by a service taking via MUST join the service it is inside; and a link by name MUST join the service whose id it names, the first-party service holding that reserved id where the part has moved in place (ARCH-R301), and MUST NOT join a service filling the same capability under another id.

  • ARCH-R244▲ unmarkedClaim it

    lemonfiber MUST fix the address of the stream.guard filler on the network of its ask of media.serve, and the addresses of it and of the proxy.front filler on the network of its ask of proxy.front, each from a subnet lemonfiber holds in which the engine assigns no other address, and MUST tell the media server's filler the guard's address as the one proxy it trusts and the guard the proxy's.

  • ARCH-R246▲ unmarkedClaim it

    A stack service MUST be declared in the plugin manifest's service model, a bundled part's in the manifest of the first-party plugin the bundle pins and a --stack-dir stack's in its service file, with the fields only a stack carries beside it, and a stack MUST carry no Compose file lemonfiber reads; lemonfiber MUST still read grants, capabilities and depends_on and MUST refuse each, naming for every grant the shape that replaces it and for depends_on network.via.

  • ARCH-R247▲ unmarkedClaim it

    { secret = "<name>" } MUST name a [[secret]] the manifest declares, refused naming the variable otherwise; lemonfiber MUST write its value only to an environment file of the service's own readable by its owner alone (0600), named by the entry, MUST NOT write it into the project, and MUST show the variable and the secret's name, never its value, in every rehearsal, reading and diagnostic.

  • ARCH-R248▲ unmarkedClaim it

    A setting MUST live in the core's settings store and a secret in the secret store; the operator MUST be able to read and change a setting from the command line, the web API and the companion's operator screens alike, and each change MUST be journalled and MUST regenerate every entry that reads it.

  • ARCH-R249▲ unmarkedClaim it

    At the first run of the release that stops reading the stack's static Compose files, lemonfiber MUST file every value an assembled part or a setting the core publishes reads from the stack's environment file once, under its setting or secret, journalling each, and MUST NOT read that value from the environment file again; a part's later in-place move MUST NOT migrate any of them (ARCH-R273); and the environment file MUST stay the file lemonfiber config reads and writes for lemonfiber's own keys, such as DATA_ROOT and PUID.

  • ARCH-R268▲ unmarkedClaim it

    A bundle [[wiring]] MUST be either a choice of filler, naming by, asks, filled_by and why, where by's plugin asks that capability in its [[ask]] and not each and filled_by provides or speaks it, or a link by name, naming by, to and why; every service it names MUST be a pinned plugin's; and a wiring of any other shape, an ask without filled_by among them, MUST be refused naming the wiring.

  • ARCH-R299▲ unmarkedClaim it

    Where the stack runs a part as its own service and the bundle pins that part installed, lemonfiber update stack --confirm MUST move it in place through the plugin install path: the plugin's service takes the same container name, configuration directory, data and setting, secret and credential names (ARCH-R273), and the stack's own service is stopped and left out of the stack; the move MUST be rehearsed and shown by the update's rehearsal before anything changes, MUST take the confirmed update as its yes, and MUST be journalled as one operation and undone as one unit (F6-R9); until an update is confirmed the stack's own service MUST keep running, assembled from the pin's copy, what its deleted in-process adapter filled MUST be reported unfilled, and up and the doctor MUST name the move as not yet taken.

  • ARCH-R304▲ unmarkedClaim it

    The filler of stream.guard MUST answer 403 to a request on a declared refused path without asking anything, and to a request on a byte path carrying a query parameter that path's declaration marks refused; for one carrying a parameter marked asked, it MUST ask the declared question about the item that parameter names as well as the item in the path and forward only where both answers are "may", and MUST refuse that parameter given more than once or in a shape the question cannot take.

  • ARCH-R291▲ unmarkedClaim it

    The core MUST generate the key it issues live-stream passes with, and MUST confirm a pass only through its pass service: the lemonfiber binary of the running release, run as a service of the project with lemonfiber pass, holding the key read-only and answering only on the network it shares with the stream.guard filler (ARCH-R312); the key MUST NOT leave lemonfiber's own processes and the guard MUST NOT hold it, and the guard MUST ask the pass service about a pass on every request for a live stream's bytes (D11-R13).

  • ARCH-R314▲ unmarkedClaim it

    A live-stream pass MUST name the member it was issued to and the moment it lapses and MUST carry an HMAC-SHA256 under the core's pass key over the live stream it is for, that member and that moment, written in base64url without padding, and MUST lapse five minutes after it is issued; it MUST travel in the lfpass query parameter; the media server filler's declaration MUST carry the live-stream paths, each a path pattern with where the live stream's id sits and the shape that id has, and the core MUST hand them to the pass service; the pass service MUST answer GET /pass, asked with the forwarded request named in X-Forwarded-Uri, with 204 where the pass in that request's lfpass is good for the live stream a live-stream path places in that request's path and has not lapsed, and with 403 otherwise, a path no live-stream path covers included; it MUST run ghcr.io/lemonfiber/lemonfiber at the running release pinned by the digest resolved when the project is written, and a build no image was published for MUST write the project without it and say so.

lemonfiber-media-stack

  • ARCH-R246▲ unmarkedClaim it

    A stack service MUST be declared in the plugin manifest's service model, a bundled part's in the manifest of the first-party plugin the bundle pins and a --stack-dir stack's in its service file, with the fields only a stack carries beside it, and a stack MUST carry no Compose file lemonfiber reads; lemonfiber MUST still read grants, capabilities and depends_on and MUST refuse each, naming for every grant the shape that replaces it and for depends_on network.via.

  • REPO-R93▲ unmarkedClaim it

    The stack's CI MUST run each service's pinned image under the posture its manifest declares, standard unless it declares confined (ARCH-R234), and MUST refuse a change under which one fails to start or to pass its health check; the version that first writes the stack's services from the model MUST NOT ship before every image has passed.

lemonfiber-plugins

  • REPO-R91▲ unmarkedClaim it

    The default bundle MUST be bundle/bundle.toml at schema = 2, as the bundle contract states it (ARCH-R265, ARCH-R266); and the catalogue MUST hold each pinned plugin's tree, copied byte for byte from the pinned revision, at bundle/plugins/<id>/ (ARCH-R267).

  • OPS-R86▲ unmarkedClaim it

    The train MUST tag the repository of each first-party plugin that builds an image at the core's version before it tags the core's release, MUST NOT tag one that builds none, and MUST NOT tag any at a pre-release's tag. Once the plugin's manifest names what that tag published, the train MUST move the plugin's pin and copy in the catalogue's bundle with one rolling pull request. The bundle MAY pin a first-party plugin that builds no image by revision and tree digest alone, with no release. The core's release tag MUST embed the bundle at a catalogue commit whose bundle pins every first-party plugin that builds an image at that version, and none of them by revision alone. A pre-release MAY embed a bundle that pins a first-party plugin that builds an image by revision alone, and MUST NOT record the bundle pin, or anything else, as an unmet goal: a pre-release with an unmet goal is refused (OPS-R66).

  • ARCH-R268▲ unmarkedClaim it

    A bundle [[wiring]] MUST be either a choice of filler, naming by, asks, filled_by and why, where by's plugin asks that capability in its [[ask]] and not each and filled_by provides or speaks it, or a link by name, naming by, to and why; every service it names MUST be a pinned plugin's; and a wiring of any other shape, an ask without filled_by among them, MUST be refused naming the wiring.

  • ARCH-R269○ openClaim it

    The ids, published ports and proxy hostnames of every service a pinned plugin declares, assembled and installed alike, and every hostname the proxy's configuration in its copy answers on, MUST be reserved; a service of any other plugin taking one MUST be refused naming it and the plugin holding it, except a first-party service whose replaces names that id.

plugin-jellyfin

  • F14-R6○ openArea FClaim it

    A plugin MUST NOT fill a capability unless its adapter conforms to that capability's contract, proved by recordings against its pinned upstream and by a live conformance pass at install, and first-party adapters MUST be held to the same suite; a first-party plugin the bundle assembles, which has no adapter, MUST fill a capability only through its claims, each proved against its recordings as F9-R2 holds a bundled service's.

  • F14-R15○ openArea FClaim it

    Every first-party plugin MUST live in a repository of its own, every first-party adapter MUST be built on the adapter kit, and every image a first-party plugin builds MUST be published from every commit on its repository's main and by the release train (OPS-R90).

sdk-php

  • ARCH-R129▲ unmarkedClaim it

    A definition in the contract artefact MUST NOT take a name an SDK's generator writes itself, and SDK generation MUST refuse such an artefact, naming the definition and the kind that carries it, rather than emit one name describing two shapes.

  • ARCH-R258■ uncitedClaim it

    POST /api/device-keys MUST take name, public_key (a P-256 SubjectPublicKeyInfo in base64url), attestation (an object tagged by platform: {"platform": "android", "chain": […]}, the key attestation chain as each certificate's DER in base64url, the key's own certificate first, or {"platform": "ios", "object": …}, the App Attest attestation object's CBOR in base64url, attested with the SHA-256 of exactly the bytes public_key decodes to as its client data hash, hashed once) and password from an operator session, and MUST answer the device-key envelope with the name, the public half's fingerprint, its backing (strongbox, enclave or tee) and the registration time; a missing attestation, one that does not verify, one placing the key in software and one naming an app the core does not trust MUST each be refused with a code of its own listed among the artefact's refusals (C10-R23).

  • ARCH-R259■ uncitedClaim it

    GET /api/device-keys MUST answer device-keys, listing each device key by name, fingerprint, backing, registration time and last use, and DELETE /api/device-keys/{name} MUST revoke one; both MUST be refused to a member session and to a key (C10-R26).

  • ARCH-R260■ uncitedClaim it

    POST /api/device-keys/{name}/challenge MUST answer device-challenge with a fresh challenge and when it expires, from an operator session for a registered device key (C10-R24).

  • ARCH-R293■ uncitedClaim it

    The keys envelope MUST carry proved_by on each key minted with a device key's signature, naming that device key, and MUST leave it out of a key minted any other way (C10-R33).

sdk-python

  • ARCH-R129▲ unmarkedClaim it

    A definition in the contract artefact MUST NOT take a name an SDK's generator writes itself, and SDK generation MUST refuse such an artefact, naming the definition and the kind that carries it, rather than emit one name describing two shapes.

  • ARCH-R258■ uncitedClaim it

    POST /api/device-keys MUST take name, public_key (a P-256 SubjectPublicKeyInfo in base64url), attestation (an object tagged by platform: {"platform": "android", "chain": […]}, the key attestation chain as each certificate's DER in base64url, the key's own certificate first, or {"platform": "ios", "object": …}, the App Attest attestation object's CBOR in base64url, attested with the SHA-256 of exactly the bytes public_key decodes to as its client data hash, hashed once) and password from an operator session, and MUST answer the device-key envelope with the name, the public half's fingerprint, its backing (strongbox, enclave or tee) and the registration time; a missing attestation, one that does not verify, one placing the key in software and one naming an app the core does not trust MUST each be refused with a code of its own listed among the artefact's refusals (C10-R23).

  • ARCH-R259■ uncitedClaim it

    GET /api/device-keys MUST answer device-keys, listing each device key by name, fingerprint, backing, registration time and last use, and DELETE /api/device-keys/{name} MUST revoke one; both MUST be refused to a member session and to a key (C10-R26).

  • ARCH-R260■ uncitedClaim it

    POST /api/device-keys/{name}/challenge MUST answer device-challenge with a fresh challenge and when it expires, from an operator session for a registered device key (C10-R24).

  • ARCH-R293■ uncitedClaim it

    The keys envelope MUST carry proved_by on each key minted with a device key's signature, naming that device key, and MUST leave it out of a key minted any other way (C10-R33).

sdk-ts

  • ARCH-R129▲ unmarkedClaim it

    A definition in the contract artefact MUST NOT take a name an SDK's generator writes itself, and SDK generation MUST refuse such an artefact, naming the definition and the kind that carries it, rather than emit one name describing two shapes.

  • ARCH-R258■ uncitedClaim it

    POST /api/device-keys MUST take name, public_key (a P-256 SubjectPublicKeyInfo in base64url), attestation (an object tagged by platform: {"platform": "android", "chain": […]}, the key attestation chain as each certificate's DER in base64url, the key's own certificate first, or {"platform": "ios", "object": …}, the App Attest attestation object's CBOR in base64url, attested with the SHA-256 of exactly the bytes public_key decodes to as its client data hash, hashed once) and password from an operator session, and MUST answer the device-key envelope with the name, the public half's fingerprint, its backing (strongbox, enclave or tee) and the registration time; a missing attestation, one that does not verify, one placing the key in software and one naming an app the core does not trust MUST each be refused with a code of its own listed among the artefact's refusals (C10-R23).

  • ARCH-R259■ uncitedClaim it

    GET /api/device-keys MUST answer device-keys, listing each device key by name, fingerprint, backing, registration time and last use, and DELETE /api/device-keys/{name} MUST revoke one; both MUST be refused to a member session and to a key (C10-R26).

  • ARCH-R260■ uncitedClaim it

    POST /api/device-keys/{name}/challenge MUST answer device-challenge with a fresh challenge and when it expires, from an operator session for a registered device key (C10-R24).

  • ARCH-R293■ uncitedClaim it

    The keys envelope MUST carry proved_by on each key minted with a device key's signature, naming that device key, and MUST leave it out of a key minted any other way (C10-R33).

Not in any tracker yet

  • F8-R6■ uncitedArea FClaim it

    The flow check MUST be performed statically, before any of the recipe's calls is made.

  • A5-R14○ openArea AClaim it

    The survey's migration envelope MUST carry, for each service it found, where that service's configuration is read from and where its library is, or MUST say that either could not be read, so that no surface works them out from a service's name or ports (A5-R2, N7-R11).

  • ARCH-R132▲ unmarkedClaim it

    Work ended before it finished MUST be answered, when its name is redeemed or released, with whether the name was released or the work was let go because nothing asked about it, and MUST be told apart from work that finished, work that stopped on a failure and work still in flight (N23-R13).

  • G4-R16▲ unmarkedArea GClaim it

    Every refusal and every obstacle the core answers to a household member's session MUST carry a sentence written for the household, and a remedy the member can act on, beside its code (ARCH-R138). The sentence MUST name no service, size, address or state of the stack (G2-R16), and a fault of the stack MUST read as not working right now with the operator told (N3-R10).

  • D2-R15○ openArea DClaim it

    The upgrade envelope MUST state, for each kind of media, what upgrading it costs in total, worked out by the stack from what the library holds, or MUST say that the cost could not be worked out; it MUST NOT leave a surface to derive a total from a rate per hour (D2-R7, N24-R4).

  • C6-R18■ uncitedArea CClaim it

    A service an installed plugin adds MUST be bound by the tier lemonfiber assigns from the classification the plugin declared, and a plugin MUST NOT be able to declare an address, an interface or a published port mapping.

  • G8-R16○ openArea GClaim it

    A plugin's declared reach MUST be refusable on its own, the consequence MUST be stated as what stops working, and a refused reach MUST be reported as nothing having been asked rather than as a failure of the destination.

  • A2-R16○ openArea AClaim it

    The web API MUST serve what setup settled — the data root, the protocols and the service user — read from the configuration as it stands, together with whether this stack is set up, on a read that offers no setup and changes nothing (N15-R1, N15-R2).

  • ARCH-R173○ openClaim it

    The contract artefact MUST describe the event stream: every event kind GET /api/events emits, with the schema of its payload, and the heartbeat's interval, generated from the types the stream serialises.

  • ARCH-R174○ openClaim it

    The contract artefact MUST carry one example of each kind, each read and each action, drawn from the core's golden test fixtures, and CI MUST refuse an example that does not validate against its schema.

  • ARCH-R176○ openClaim it

    release-contract MUST attach contract-diff.json to each release, naming every kind, definition, read, action, refusal and event kind that release's contract artefact added, removed or changed against the previous release's.

  • ARCH-R177○ openClaim it

    The core MUST generate contract/web-api.openapi.json, an OpenAPI document of the web API, from the contract artefact, and CI MUST refuse it when it differs from what the artefact generates.

  • ARCH-R2■ uncitedClaim it

    schema_version MUST be a monotonic integer, not semver.

  • ARCH-R10■ uncitedClaim it

    Configuration written by a newer binary MUST be refused, never modified.

  • ARCH-R15○ openClaim it

    The render loop MUST NOT await I/O or hold a lock across a frame.

  • ARCH-R18○ openClaim it

    Service clients MUST be selected by manifest api.kind, never by hardcoded service name.

  • ARCH-R19■ uncitedClaim it

    Web assets MUST be embedded in the binary; no runtime toolchain MAY be required.

  • ARCH-R25○ openClaim it

    A slow or failed observation source MUST NOT delay unrelated panels.

  • ARCH-R96▲ unmarkedClaim it

    A first-party plugin's services MUST be placed in the profile the bundle assigns it, whatever its stage; any other plugin's service MUST be placed in a profile of its own, added to the closure of each form the manifest declares; and naming a form the stack does not declare MUST be refused by name.

  • ARCH-R103■ uncitedClaim it

    lemonfiber MUST generate the stack's own proxy and dashboard wiring for a plugin's service from what the manifest declares, on the same terms as a bundled service in the same binding tier, and MUST NOT accept a proxy stanza, dashboard entry or any other wiring fragment from a plugin.

  • ARCH-R104■ uncitedClaim it

    A plugin MUST NOT be able to obtain a proxy hostname for a service bound to loopback, and the binding tier alone MUST decide whether a service is reachable by name.

  • N20-R4■ uncitedArea NClaim it

    Where a call was refused because an external name answered from inside the network, the app MUST show that refusal and its reason, and MUST NOT render it as a network error to retry.

  • N20-R5■ uncitedArea NClaim it

    A rehearsed recipe MUST show every step in the order the recipe gives, labelled as a rehearsal (N6-R1), and MUST NOT be summarised into an outcome.

  • N20-R6■ uncitedArea NClaim it

    Where a plugin names an adapter, the app MUST show which one, and that it is lemonfiber's rather than the plugin's.

  • N20-R7■ uncitedArea NClaim it

    The app MUST NOT execute content a plugin supplied, MUST NOT offer to, and MUST NOT present any opt-in, sandbox or capability grant that would (F3-R6).

  • N20-R8■ uncitedArea NClaim it

    A plugin declaring native or executable content MUST be shown as refused with the reason, and MUST NOT be offered for installation (F3-R7).

  • N20-R9■ uncitedArea NClaim it

    A refusal the core gave about a plugin MUST carry the core's own reason (N5-R10).

  • N20-R10■ uncitedArea NClaim it

    Recipes, pairs, destinations or adapters that could not be read MUST be told apart from there being none.

  • N25-R2■ uncitedArea NClaim it

    A proof that was not asked MUST NOT be shown as passed, and a check the stack could conclude nothing about MUST NOT be shown as failed.

  • N25-R4■ uncitedArea NClaim it

    Where an install was put back, the app MUST show what went back and what did not, with the reason each is still standing, and MUST NOT present a partial reversal as complete (F6-R5, F6-R6, N6-R6).

  • N25-R8■ uncitedArea NClaim it

    Every installed plugin MUST be shown with the source it was installed from, its version and whether it was reviewed, and an unreviewed plugin MUST be shown as unreviewed wherever it appears (F5-R5, F5-R7).

  • N25-R9■ uncitedArea NClaim it

    A rehearsed install, update or removal MUST be labelled as a rehearsal (N6-R1).

  • N25-R10■ uncitedArea NClaim it

    A plugin record that could not be read MUST be told apart from there being no plugins installed.

  • ARCH-R186■ uncitedClaim it

    At start the program MUST log which mode it serves and who can check its certificate, and in private-ca and pinned MUST say that an assistant reached through its provider's servers cannot connect; its documentation MUST say the same of each mode.

  • ARCH-R187■ uncitedClaim it

    In files, the operator's certificate and key MUST be refused at start, by name, where either is unreadable, the key does not match, the certificate has expired, or it does not cover every name in LEMONFIBER_NAMES where that is set, and MUST be read again without a restart when either changes.

  • ARCH-R192■ uncitedClaim it

    In private-ca, the program MUST make an ECDSA P-384 root valid for ten years with a path length of 0 and critical name constraints permitting exactly the names and addresses in LEMONFIBER_NAMES and excluding every address (0.0.0.0/0 and ::/0) where none is given and every host name (an empty DNS name) where none is, and an extended key usage of TLS server alone; MUST issue the served certificate from it, valid for 30 days and renewed once ten days are left and named by a common name that is none of the names; MUST write the root to the state directory, print its fingerprint at start and serve it at GET /root.pem over TLS; and MUST NOT serve or log the root's key.

  • ARCH-R193■ uncitedClaim it

    A private root MUST be replaced on the operator's command, when LEMONFIBER_NAMES gains a name it does not cover, and when a year of its life is left: the new root MUST be made beside the old and announced with its fingerprint at every start until the switch; the program MUST serve from the old root until the operator switches or, where the old root expires first, until 30 days before it does; and the old root's key MUST be deleted after the switch.

  • ARCH-R194■ uncitedClaim it

    In pinned, the program MUST make its own certificate for LEMONFIBER_NAMES, valid for ten years, MUST print its fingerprint at every start as SHA-256 over its DER encoding in lower-case hex, MUST NOT renew it, and MUST replace it only on the operator's command or when LEMONFIBER_NAMES changes, saying at start that every client must be given the new fingerprint.

  • ARCH-R196■ uncitedClaim it

    Every failed renewal MUST be logged as an error with what failed and the time left; inside seven days of expiry while renewal fails it MUST be logged as critical hourly; and GET /health, over TLS and without a credential, MUST answer the mode, the expiry and the last attempt and its outcome, 503 while renewal fails inside seven days and 200 otherwise, carrying no other data.

  • F14-R1▲ unmarkedArea FClaim it

    Every capability in the vocabulary MUST have a published, versioned contract generated from the core's port types, and the core MUST reach every service only through a contract it speaks.

  • F14-R2▲ unmarkedArea FClaim it

    The core MUST hold no code specific to any service, and an architecture check MUST refuse a bundled service's name in core code outside the bundle.

  • F14-R3○ openArea FClaim it

    A service MUST declare the contracts it speaks, and a manifest MUST NOT name an in-process adapter.

  • F14-R11○ openArea FClaim it

    Substituting a filler MUST stop the part it replaces and take it out of its form while keeping its data, undoing it MUST bring that part back with its data, and the rehearsal MUST say what does not carry over.

  • F14-R13▲ unmarkedArea FClaim it

    An adapter MUST declare the upstream releases it supports, each proved by its own recordings, and the core MUST NOT compare versions.

  • F14-R14○ openArea FClaim it

    Every capability MUST be proved by a substitute other than its first-party filler, run end to end against its pinned upstream through install, its first-run flow, conformance, substitution, the features the capability serves, and undo.

  • F14-R19▲ unmarkedArea FClaim it

    A plugin MUST be first-party only where the build embeds its id, the digest of its manifest and the digest of its tree in its first-party set, as the signed default bundle names them at the release the build pins; any other plugin MUST be third-party however it was installed.

  • F14-R20▲ unmarkedArea FClaim it

    A third-party plugin MAY be granted one named credential for a capability it fills; the grant MUST be part of the install or update offer and approved by the operator, MUST be journalled and revocable, and MUST be shown on the credentials surface, and without a grant no credential MUST cross to it.

  • F14-R26▲ unmarkedArea FClaim it

    Where the media server is a plugin's service that speaks identity.source, its first-run setup MUST go over that contract with an administrator's password lemonfiber mints and keeps under that server's own setting, and the request service's identity setup MUST be given that password with the stack-network address and the native API of the service the adapter fronts; where that service declares no native API, the setup MUST NOT be attempted and the run MUST say so, naming the plugin.

  • OPS-R90▲ unmarkedClaim it

    A first-party plugin's repository, lemonfiber-decline and lemonfiber-request-gate included, MUST build and publish each image it builds from every commit on its main as a train tag builds it — each platform on a runner of its own architecture, one multi-architecture index carrying BuildKit's SBOM and provenance, and a build-provenance attestation and an SBOM attestation per platform — tagged main- followed by the first twelve characters of the commit, and MUST NOT move that tag. A commit whose change from the commit before it on main touches nothing of the plugin but plugin.toml, proofs.json, targets.toml and what is under recordings/ MUST NOT publish an image, so merging a pin's pull request never starts another. A commit image MUST NOT be announced and is not a release.

  • OPS-R91▲ unmarkedClaim it

    Each commit image's publish MUST update one rolling pull request on the plugin's repository setting the digest of each service that runs the image to what it published and its tag to the commit tag, so the manifest pins a published build by digest, with every recording the manifest names taken again from that image by lemonfiber plugin record at the lemonfiber its targets.toml names and proofs.json written from them in the same commit (ARCH-R285). The image MUST run and lemonfiber MUST be built in a job holding no secret, and the job holding the release App's token MUST run nothing that job wrote, MUST work the move out again from the manifest on main and what was published, and MUST commit only plain files, read through no link: that manifest with exactly that move, proofs.json, and recordings the manifest names taken from exactly that pin. The pull request MUST be disarmed, naming each, where a recording still names the image it replaces (OPS-R87). Merging that pull request MUST NOT move the bundle's pin, which only a train tag's pin moves (OPS-R86).

  • ARCH-R222▲ unmarkedClaim it

    replaces MUST name an id the bundle reserves (ARCH-R269) and MUST equal the id of the service declaring it; that service MAY take the reserved service's id, port and hostname, every other service MUST still be refused any of the three, and a manifest declaring replaces anywhere else MUST be refused, naming service <id>.replaces.

  • ARCH-R200▲ unmarkedClaim it

    A manifest's speaks MUST name only capabilities and majors listed in contract/capabilities/index.json, and an unlisted one MUST be refused by name.

  • ARCH-R201▲ unmarkedClaim it

    Every operation MUST be at /lemonfiber/<capability>/v<major>/<operation> on the adapter's listens port, and every request MUST carry the plugin's key as a bearer token.

  • ARCH-R202▲ unmarkedClaim it

    The core MUST mint each plugin's key from its own random source, write it to the adapter's configuration directory before the adapter starts, and use it for no other plugin.

  • ARCH-R203▲ unmarkedClaim it

    An answer outside its operation's schema, status set, size bound or time bound MUST be refused, MUST NOT be read, and MUST be recorded against the plugin's conformance standing.

  • ARCH-R204▲ unmarkedClaim it

    A refusal MUST be a problem document whose type the contract declares, and the core MUST map it to a code without reading its prose.

  • ARCH-R205▲ unmarkedClaim it

    Every adapter MUST answer about and ready, and about MUST list the upstream releases it supports, each with the digest its recordings were taken from.

  • ARCH-R208▲ unmarkedClaim it

    A plugin MUST hold a recording for every case its capabilities' conformance lists, taken at the digest its adapter declares, and lemonfiber plugin conform MUST judge them without running anything.

  • ARCH-R209▲ unmarkedClaim it

    Install MUST run the live conformance cases against the running adapter, and a failed case MUST keep the plugin from filling the capability and MUST be named.

  • ARCH-R210▲ unmarkedClaim it

    No capability type MUST name a product, and a curator MUST be referred to by the media type it files.

  • ARCH-R211○ openClaim it

    A contract's major MUST change only when an operation is removed or its meaning changes, and the core MUST speak every major its index lists.

  • ARCH-R212▲ unmarkedClaim it

    An adapter's listens port MUST be published on 127.0.0.1 alone with no host port named, and the core MUST read the host port the engine gave it from the engine and MUST NOT reach an adapter at any other address.

  • ARCH-R213▲ unmarkedClaim it

    A service that speaks a capability's contract MUST also provide that capability, and a manifest where one does not MUST be refused by name; that capability MUST be demonstrated by its contract and MUST NOT require a [[claim]]. A facet (ARCH-R331) is spoken and never provided.

  • ARCH-R214▲ unmarkedClaim it

    Where the service filling a capability speaks that capability's contract, the core MUST ask it over the contract alone and MUST NOT reach it through an adapter of its own.

  • ARCH-R215▲ unmarkedClaim it

    The web API MUST answer POST /api/actions/plugin-prove, taking plugin, dry_run and offer, with a job and then the plugins envelope, running the live proof lemonfiber plugin prove runs, and a passing proof MUST clear the plugin's nonconforming records while a failing one MUST keep them and name each failed case.

  • ARCH-R216▲ unmarkedClaim it

    A service that speaks a contract MUST name in fronts one other service of the same plugin that speaks none, and a manifest where it names none, itself, a service the plugin does not declare or one that speaks a contract MUST be refused by name.

  • ARCH-R221▲ unmarkedClaim it

    native MUST be one lowercase word and MUST be declared only on a service another service of the same plugin fronts, and a manifest declaring it anywhere else MUST be refused, naming the service.

  • ARCH-R217▲ unmarkedClaim it

    A plugin's conformance recordings MUST sit at conformance/<capability>@<major>/<case>.json beside its manifest, one per case of each contract it speaks, each in the recording format of ARCH-R120 and naming the digest the manifest pins for the service its adapter fronts, and lemonfiber plugin conform MUST judge each recorded answer as the core reads a live one and MUST name each case whose recording is absent, unreadable, of another request or of another digest.

  • ARCH-R238○ openClaim it

    An install or update whose plugin takes any shape MUST state in its reading each service taking it with what the shape gives, and MUST NOT act unless the operator approved that shape for that service apart from the offer, written <shape>@<service>, as F14-R21 holds for the egress guard's.

  • ARCH-R239○ openClaim it

    The manifest MUST have no field by which a service could mount the engine's socket, run privileged, join the host's network, PID or IPC namespace, name an entrypoint or a command, or obtain a kernel capability, a device or a group other than through a shape.

  • ARCH-R245○ openClaim it

    Choosing which service fills an ask MUST regenerate the project in the same journalled change as the setting.

  • ARCH-R250▲ unmarkedClaim it

    A plugin's CI MUST run each of its images under the posture its manifest declares, standard included, and a manifest MAY declare posture = "confined" only where that run passes under it; lemonfiber MUST write the posture a manifest declares and MUST NOT refuse to install, update or start a service on account of its posture.

  • ARCH-R253▲ unmarkedClaim it

    An ask and a url_of MUST reach the service that speaks the capability's contract, the filler itself where the filler speaks none, and the upstream that filler's adapter fronts only where the asker names that upstream's declared API in native; an ask naming an API the filler's upstream does not declare MUST be reported unfilled, naming the API.

  • C10-R24■ uncitedArea CClaim it

    An operator session MUST be able to ask for a challenge for a registered device key. The core MUST issue a fresh random value of at least 32 bytes, keep it only in memory, bound to that session and that device key, and accept it for one request within one minute; using it, its lapsing, the session ending and the device key's revocation MUST end it.

  • C10-R25■ uncitedArea CClaim it

    A mint carrying a device key's name, a challenge and a signature in place of the password MUST be admitted only where the device key is registered, the challenge stands for that session and that device key, and the signature verifies against the device key's public half over the challenge and the mint's name, scope, purpose and whether it is a claim, in the form the contract publishes. An unregistered or revoked device key MUST be refused with a code of its own; a challenge that does not stand, for any reason, with one code; and a signature that does not verify with a code of its own, counted against the same surface-wide limit as wrong passwords (C10-R13).

  • C10-R26■ uncitedArea CClaim it

    Device keys MUST be listed by name, the fingerprint of their public half, their backing, registration time and last use, and MUST be revocable by name, over the web API, with effect at the next challenge. Every revoke MUST be journaled as not reversible and MUST raise an operator alert naming the device key.

  • C10-R27■ uncitedArea CClaim it

    Changing the operator password MUST revoke every device key, journaled and alerted as C10-R26 says.

  • C10-R28■ uncitedArea CClaim it

    A device key's signature MUST prove the operator for the one mint it was made for and nothing else: it MUST NOT admit a request, stand in for a session or the password anywhere else, or be accepted without an operator session.

  • C10-R29■ uncitedArea CClaim it

    The core MUST register a device key only where its attestation names an app identity the core trusts: the package and the SHA-256 digest of its signing certificate on Android, the Team ID and bundle ID on iOS. The build MUST ship the official NightWorksIO companion's identities, and an attestation naming any other app MUST be refused with a code of its own, naming the identity. Until the companion's first store release the official list MUST be empty, so only the identities the operator adds are trusted, and the core release that follows the companion's first store release MUST ship its identities (releasing).

  • C10-R30■ uncitedArea CClaim it

    The operator MUST be able to add and remove the identities of their own builds as a setting, at the command line and over the web API (ARCH-R262); each change MUST be journaled and MUST raise an operator alert naming the identity, the official identities MUST NOT be removable, and removing an identity MUST revoke every device key registered from it.

  • C10-R31■ uncitedArea CClaim it

    The core MUST verify an attestation against the platform roots shipped in its build and MUST NOT send any request to verify one, a revocation list included.

  • ARCH-R262■ uncitedClaim it

    The identities of the operator's own builds MUST be the core setting LEMONFIBER_DEVICE_KEY_APPS, read by GET /api/settings and written by settings-set and settings-clear as every setting is: a comma-separated list of android:<package>@<SHA-256 of the signing certificate, in hex> and ios:<Team ID>.<bundle ID>. A value naming an identity in neither form MUST be refused, naming it; the official identities the build ships MUST be read alongside and MUST NOT be part of the value (C10-R30).

  • C10-R32■ uncitedArea CClaim it

    Restoring a configuration backup MUST revoke every device key once the restore lands, each journaled as not reversible and alerted as C10-R26 says.

  • C10-R33■ uncitedArea CClaim it

    A key minted with a device key's signature MUST record that device key, and the listing MUST show it beside the key (ARCH-R293). Revoking a device key MUST NOT revoke the keys it proved, and its alert MUST name each active key it proved.

  • C10-R34■ uncitedArea CClaim it

    The core MUST refuse, with a code of its own whose words name no key material, an Android key attestation any certificate of which carries a serial number that the build's snapshot of Google's attestation status list lists as revoked or suspended. Each build MUST embed that snapshot, taken at release time and recording where it was read from and when; the core MUST NOT fetch the list at run time (C10-R31), and MUST report when its snapshot was taken in the version it answers with (ARCH-R294, releasing).

  • ARCH-R294■ uncitedClaim it

    The version envelope MUST carry attestation_status, the instant the build's snapshot of Google's attestation status list was taken, and the refusal of an attestation whose chain that snapshot lists as revoked or suspended MUST carry a code of its own listed among the artefact's refusals (C10-R34).

  • ARCH-R263▲ unmarkedClaim it

    lemonfiber MUST assemble the stack it ships from the bundle it embeds and the plugin trees it pins, and from nothing else, but the pass service, which it writes itself (ARCH-R291), and the media server's service, its claims and their recordings, which it MUST read from the media stack as frozen at the source switch until the release that moves the media server in place (ARCH-R299); and it MUST NOT carry or materialise a stack.toml, an include list or a services/ file for it.

  • ARCH-R264○ openClaim it

    A stack manifest read from a directory named with --stack-dir MUST declare each service in a file of its own, services/<id>.toml, named by the root manifest's include list, which alone decides membership. lemonfiber MUST refuse, naming it, an entry that is not of that form, names no file, or appears twice; a file in services/ no entry names; a service file holding anything but one [[service]] whose id matches its name; and a [[service]] in the root manifest.

  • ARCH-R271▲ unmarkedClaim it

    A plugin MAY ship starting files for a service it declares under config/<service id>/ in its source, and lemonfiber MUST write each into that service's configuration directory at the same relative path as a materialised file held to F1-R4; a file outside config/<id>/ of a declared service, a symbolic link anywhere in the tree, and a service whose files number more than 64 or weigh more than 1 MiB in all MUST be refused, naming the path or the service.

  • ARCH-R273▲ unmarkedClaim it

    A first-party plugin's service whose replaces names a reserved id MUST be given the setting, secret and credential names the stack gives the service of that id, and moving a part in place MUST NOT rename or migrate any of them.

  • ARCH-R274○ openClaim it

    Every instant the web API reads or writes, in a request, a response, an event or a link the core builds, MUST be a whole number of seconds since the Unix epoch: a JSON integer in a body, and its decimal digits in a link's query. It MUST NOT be written as a string, with a fraction, or with a zone or an offset; a command's --json output MUST write instants alike; and a stamp lemonfiber passes on verbatim from a service's own output MUST NOT be presented as one of its instants.

  • ARCH-R276○ openClaim it

    The journal MUST record a change to a secret by the fingerprint of its value before and after the change, and MUST NOT hold a secret's value, sealed or otherwise; the secret store MUST keep each secret's one previous value, and undoing the change MUST restore it only while the values the store holds match the fingerprints the entry recorded, and otherwise MUST say the secret must be replaced at the terminal, naming it.

  • ARCH-R298▲ unmarkedClaim it

    The up of a form whose closure holds the profile of an installed pin, where neither that plugin nor a stack service of its id is present, MUST offer installing the plugin from its embedded tree, offline, through the plugin path as any install is (F6-R1); the offer MUST be rehearsable, and without the operator's yes nothing of the form MUST be written or started.

  • ARCH-R310■ uncitedClaim it

    lemonfiber MUST name the subnet of every network of the project, so the engine draws none from its own address pools: each a /29 of 10.80.0.0/16, chosen from the network's name alone so that it does not move when another network comes or goes, and none inside a fixed subnet ARCH-R244 names; one machine runs one lemonfiber stack, since a second project there names the same subnets.

  • ARCH-R315▲ unmarkedClaim it

    A [[secret]] declaring minted = true MUST have its value made by lemonfiber at install, before any service of the plugin first starts, as 32 lowercase hexadecimal characters from the operating system's random source, held in the secret store as <plugin id>:<secret id>, journalled by fingerprint (ARCH-R276) and never shown; one whose of names no service of the plugin, or named by a capture, MUST be refused naming the secret; where the plugin's service replaces a reserved id whose credential lemonfiber reads from that service's configuration, the move MUST file that value under the secret once and MUST NOT mint one; and plugin record and a proof MUST mint a throwaway value for their own run.

  • ARCH-R316▲ unmarkedClaim it

    lemonfiber MUST write a starting file's {{secret:<id>}} as the secret's value and {{secret:<id>\

  • ARCH-R317▲ unmarkedClaim it

    A service that speaks MAY declare upstream, each field to { secret = "<id>" }; lemonfiber MUST write exactly those fields, each with its secret's value, to the adapter's upstream.json (F14-R28) at install and whenever one of them changes, and MUST refuse upstream on a service that speaks no contract, a field name that is not lowercase letters, digits and _ starting with a letter, and a secret the manifest does not declare or declares as another service's, naming the service, the field and the secret.

  • ARCH-R318▲ unmarkedClaim it

    lemonfiber MUST keep, as shipped, the starting files of every service whose files name a minted secret; replacing a minted secret MUST mint and hold a new value and, before it is called replaced, write it to every environment file and upstream.json that names it and, in every starting file whose kept copy names it, in place of the value on the line the text around the placeholder finds, keeping the rest of the file and deriving the hashed form afresh for \

  • ARCH-R319▲ unmarkedClaim it

    request.intake@1 MUST declare establish, taking the identity source configure_identity takes and answering 204 once the upstream holds an owner and answers the adapter's upstream credential, 204 where it already did, and a refusal as configure_identity is refused otherwise; the core MUST ask it each time it sets up the request service's identity, before any other operation of the contract, and lemonfiber plugin record MUST ask it as the contract's first case.

  • ARCH-R320▲ unmarkedClaim it

    An operation of library.curate@1 that takes a kind of media MUST publish one conformance case per media type it takes, named <operation>-answers-<media type>, and an adapter MUST be asked and judged on exactly the cases of the media types its upstream's media_types names.

  • ARCH-R321▲ unmarkedClaim it

    register_download_client MUST save the client it is handed, and its conformance case MUST name the client's protocol as the native API of the download filler the bundle ships, sabnzbd; while it records a curator, lemonfiber plugin record MUST answer at the host the case names, reachable from the upstream's container alone, the queries a curator tests a SABnzbd client with, and nothing more.

  • ARCH-R322▲ unmarkedClaim it

    A [[secret]] whose of names a service outside its plugin MAY declare for, naming a capability a service of the same plugin provides; a third-party plugin's such secret MUST declare it, and an install or update MUST be refused, naming the secret, where a third-party plugin declares two such secrets for one capability or a for names a capability none of its services provides.

  • ARCH-R323▲ unmarkedClaim it

    An install or update of a third-party plugin MUST name in its reading each credential that would cross to it as <setting>@<plugin>, with the capability it is for and the service whose credential it is, MUST NOT act unless each was approved in that act, and MUST NOT let a credential cross that the act did not approve; each grant given or ended MUST be journalled with the operation that gives or ends it, by credential and plugin and never by value, so undoing the operation ends or restores the grant.

  • ARCH-R324▲ unmarkedClaim it

    lemonfiber credentials revoke <plugin> <credential> and the credentials-revoke action MUST end one grant by writing every entry and connection of the plugin again without the credential and restarting the plugin's services that read it, journalled as one operation undo reverses and taking an offer as a plugin write does (ARCH-R146); the plugin MUST stay installed with each capability the credential was for reported unfilled for that reason, and a plugin and credential with no grant between them MUST be refused, naming the grants the plugin holds.

  • ARCH-R325▲ unmarkedClaim it

    The credentials read MUST list every grant with the credential it crosses: the plugin, the capability it is for and when it was approved, and no value.

  • ARCH-R326▲ unmarkedClaim it

    A conformance case that hands the upstream an identity source MUST name its protocol as jellyfin, and one that hands it a curator MUST name the curator of series; while it records, lemonfiber plugin record MUST answer at each host and port the cases name, each party on a port of its own, reachable from the upstream's container alone, in that party's native API: for the identity source, the sign-in of the owner the case names, a key made and listed under the name it was asked to make one for, what server it is, and a list of accounts holding that owner and the member the cases link; for the curator, the queries an upstream tests a curator with before it saves one, its release in every answer; and nothing more.

  • ARCH-R327▲ unmarkedClaim it

    Each operation whose answer holds a credential the upstream issues MUST name every place its answer holds one as a JSON pointer, "" where the whole answer is one, its contract document MUST publish them as x-lemonfiber-secret, and lemonfiber plugin record MUST scrub the value at each as a credential its run read (ARCH-R297).

  • ARCH-R328▲ unmarkedClaim it

    owner.claim@1 MUST declare owner, answering Open, Settling, Ours or Theirs, and claim, which claims an Open part with the credential in the adapter's upstream.json and answers what the part then is, and MUST NOT change a part that is Ours or Theirs; the credential MUST be the plugin's minted secret and MUST NOT cross a call.

  • ARCH-R329○ openClaim it

    The core MUST ask claim of every service speaking owner.claim@1 at install's first run and on every seed, waiting out Settling within its patience, MUST report a part Open after a claim it recorded as drift and a part Theirs as refused naming the plugin's secret, MUST ask owner of every speaker in one doctor check, and reset MUST put a claim back.

  • ARCH-R330▲ unmarkedClaim it

    lemonfiber plugin record MUST ask claim of a service whose adapter speaks owner.claim@1 before any other case.

  • ARCH-R331▲ unmarkedClaim it

    owner.claim and indexer.pull are facets: each MUST be asked by the core of every service that speaks it and MUST NOT be chosen among fillers, MUST be proved by its speakers' conformance, and has no substitute; a facet MUST be spoken and MUST NOT be provided, so it has no entry in the capability vocabulary, and a manifest naming one in provides MUST be refused by name.

  • ARCH-R332▲ unmarkedClaim it

    indexer.pull@1 MUST declare aggregators, listing the aggregators a curator reads its indexers from, and add_aggregator, adding one by name, address, protocol and key, the protocol being the aggregator's native API.

  • ARCH-R333▲ unmarkedClaim it

    Where an indexer's app sync serves a curator's media, the core MUST tell the indexer about the curator; otherwise it MUST tell a curator speaking indexer.pull@1 about the indexer whose native API matches, and MUST leave the two unpaired where either answers unsupported; while it records, lemonfiber plugin record MUST answer the aggregator at the host the case names in its native API.

  • ARCH-R334▲ unmarkedClaim it

    An operation the upstream an adapter fronts cannot perform MUST be answered unsupported; conformance MUST pass it, and the core MUST treat the operation as not offered for that filler, by the answer's type alone; a case whose placeholder reads the answer to a case answered unsupported, or to a case of a contract the adapter does not speak, MUST NOT be asked, MUST be recorded as answered unsupported, and MUST NOT be asked by install's live pass.

  • G11-R1▲ unmarkedArea GClaim it

    Where an install or update of a third-party plugin names a credential of another service that would cross to it, the console's reading MUST show each one with the setting it is held under, the service whose credential it is and the capability of the plugin's own it is for, and never its value. The operator MUST approve each one apart from the offer, on a switch of its own that is off until turned on; agreeing to the offer MUST approve none of them, and the yes MUST carry each approved one exactly as the reading names it (ARCH-R323, F14-R20). Every update MUST ask again, and a grant the plugin already holds MUST NOT be taken as approved. Where the stack refuses the act for a grant left off, the refusal MUST be drawn in the stack's words.

  • G11-R2▲ unmarkedArea GClaim it

    The console MUST list, for each installed plugin, the grants it holds, each with the setting the credential is held under, the service whose credential it is, the capability it fills and when it was approved, and never a value (ARCH-R323).

  • G11-R3▲ unmarkedArea GClaim it

    The console MUST offer revoking each grant a plugin holds. The revoke MUST be read first, labelled as nothing ended yet, showing the grant it ends and the plugin's services it would restart; the yes MUST carry back the offer the stack named (ARCH-R324). Afterwards the console MUST show whether the grant was ended, the services that restarted and, where they did not, the stack's reason, and MUST say that the plugin stays installed and that rotating the credential is what takes back a value already handed (ARCH-R324).

  • G11-R4▲ unmarkedArea GClaim it

    A plugin's grants, and revoking them, MUST be shown to the operator alone and MUST NOT appear anywhere a member is shown (G10-R9).

  • G11-R5▲ unmarkedArea GClaim it

    The console's credentials panel MUST list every grant beside the credential it crosses, with the plugin it is granted to, the capability it is for and when it was approved, and never a value (ARCH-R325, F14-R20).