fediversity core Constitution
Core Principles
I. Downward-Only Leaf
core is the library leaf of the fediversity monorepo. It MUST NOT know the
api or panel sub-projects. Code, tests, names and comments in core/
MUST NOT import from api/ or panel/, read their files, or refer to their
components, nodes, roles, modules or source files. A front-end adds its own
components and data-model modules to the groups of core through the public
fold helpers (principle IV), and then renders the result.
core MAY use shared infrastructure of the repository root that is not a
sub-project (for example npins/, the contracts library under nix/, the
overlays).
Rationale: the cli <-> api import cycle was the origin of the old cli and
core split. That split was an accident, and it was merged away. api and
panel depend on core, so knowledge in the other direction makes a cycle
again, and a change in a front-end can then break core. A second front-end
must be able to use core without the first one.
II. Agnostic to Front-End Business Logic
core gives three things: stateless deployment programs, the application
catalog and the configuration model. It MUST NOT contain the business logic of
a front-end: authentication of end users, multi-tenancy of accounts, billing,
or queueing and authorization of deployment requests. These belong to the
front-ends.
Authentication inside a deployment (for example the single sign-on of the
deployed applications) is part of the product that core deploys, and is in
scope.
III. Stateless Deployment Programs
A deployment program MUST get all its coordinates from environment variables
that a module declares. core MUST publish the set of these variables, so a
caller knows what to forward. A program MUST NOT keep state of its own between
runs. The state of a deployment lives in the state backend that the caller
gives. A program MUST refuse to continue when it finds that this state is
lost, and MUST NOT silently create a new deployment over it.
Rationale: api runs the programs as jobs and keeps the state per deployment.
Hidden state in core makes two runs of the same program give different
results.
IV. Everything Is a Module
A consumer extends or changes the data model only with modules of the module system (components, resources, environments, policies). There MUST be one extension seam, not special override parameters. A value from the hosting configuration of a provider MUST have the type of the option it sets.
Rationale: the separate override paths (environmentsOverride,
resolveEnvironments, resourcesOverride) were removed in favor of one
seam. Each of them had its own rules, and none checked types.
V. Decide by Capability, Not by Name
A decision about wiring (DNS, TLS, secrets, resource routing, trust) MUST depend on what a component declares that it provides or needs, not on the name of a node or component. A want of a contract that no provider in the deployment satisfies MUST fail the evaluation.
Rationale: node-name checks break when a node is renamed, split or moved, and a missing provider made a deployment hang without an error.
VI. One Entrypoint
core/default.nix is the single source of truth for all outputs.
core/flake.nix is a thin wrapper that adds the ${system} layer and MUST
NOT add, remove or change outputs. The attribute names of the deployment
programs follow one grammar, and core MUST publish the list of names that
exist.
VII. Tested Decisions
Each pure decision function of the wiring MUST have a nix-unit test that
asserts on the same expression that the deployment uses. Each check MUST have
a description and a CI runner route. A check that has no route fails.
Constraints
- All inputs are pinned with npins. The pinned nixpkgs is upstream nixpkgs, not a fork.
- The public surface is the attributes of
core/default.nix: the rendered outputs (nixosConfigurations,packages,apps,devShells,checks,formatter,legacyPackages,deploymentAttributeNames,attributeFamilies) andlib(render,foldGroupComponents,foldGroupModules,baseGroups,applications-type, the environment key sets,testers). A change to a name or the shape of this surface is a breaking change forapiandpanel, and MUST be named as such in the pull request. - The JSON Schema of the configuration uses draft 2020-12.
Development Workflow
- Changes go through pull requests on git.fediversity.eu, with the title prefix
core:. Thetreefmtcheck and the checks that CI routes for the change MUST pass. - A pull request that changes behavior updates the matching specification under
core/specs/in the same pull request. - Prose in comments, commit messages and pull requests uses ASD-STE100, US English and ASCII punctuation, with backticks around code.
- Documentation describes the current state of the code. The description of an environment variable is next to the code that reads it.
Governance
This constitution has priority over other practices in core/. An amendment
is a pull request that changes this file, updates the version and the Sync
Impact Report, and updates any specification that the amendment affects.
Versions follow semantic versioning: MAJOR for a removed or redefined
principle, MINOR for a new principle or section, PATCH for clarifications.
Version: 1.0.0 | Ratified: 2026-09-22 | Last Amended: 2026-09-22