Filtered to Repository lemonfiber
Read at · spec at 76d46f3
Every repository's revision read
- brand@c2c6485
- integration-home-assistant@1ffa24e
- integration-mcp@71b97a7
- lemonfiber@8371555
- lemonfiber-companion@168bfe9
- lemonfiber-decline@21e9fe7
- lemonfiber-media-stack@a1d36db
- lemonfiber-plugins@7d88bbd
- lemonfiber-request-gate@fa76259
- lemonfiber-web@cfd74f7
- plugin-jellyfin@58fffca
- sdk-php@663b0b4
- sdk-python@645404a
- sdk-ts@eac8964
- spec@76d46f3
- tool-lfdev@93a3c56
0.18.038 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.
lemonfiber-plugins
- 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.
0.19.00 goals
Every goal of this version is met or claimed.