No description
  • Nix 95.2%
  • Shell 4.8%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
vnprc 718c6cf89f Validate Pi provider metadata structurally, and export the validator
Provider metadata is Pi's configuration format. The framework's reconciler
merges these objects into models.json verbatim, so Pi already accepts or
rejects an adapter name, a model field, or an unreachable endpoint at the first
request. Mirroring that format here as a closed-world schema means every field
Pi adds needs a change in this repo, a lock bump, and a rebuild before any
deployment can use it, and buys nothing in exchange.

Keep only what this framework keys off and cannot recover from: the provider ID
that joins the catalog to the credential registry and keys the ownership
manifest, and a non-empty model list whose entries carry a non-empty id. Keep
one property Pi cannot enforce for us: baseUrl must be https, because the
credential a provider selects is a bearer token. Everything else passes through
untouched, pinned by a new passthrough witness so a future tightening cannot
reintroduce a closed schema unnoticed.

Export validatePiProviders so a profiles repo that replaces this input can run
its own catalog through the same function instead of re-exporting this one or
copying it. Refs allod/profiles#7
2026-08-22 00:21:02 -04:00
hooks Populate example machine profile definitions 2026-07-17 21:02:51 +00:00
hosts/dev/allod-dev Populate example machine profile definitions 2026-07-17 21:02:51 +00:00
modules Populate example machine profile definitions 2026-07-17 21:02:51 +00:00
.gitignore Populate example machine profile definitions 2026-07-17 21:02:51 +00:00
flake.lock Populate example machine profile definitions 2026-07-17 21:02:51 +00:00
flake.nix Validate Pi provider metadata structurally, and export the validator 2026-08-22 00:21:02 -04:00
LICENSE Add LICENSE (GPL-3.0-or-later) 2026-07-17 20:58:45 +00:00
pi-providers.json Add validated Pi provider catalog contract 2026-08-21 02:02:57 +00:00
README.md Validate Pi provider metadata structurally, and export the validator 2026-08-22 00:21:02 -04:00
setup.sh Populate example machine profile definitions 2026-07-17 21:02:51 +00:00

profiles

Allod example machine profile definitions — the single owner of which NixOS and Home Manager modules compose each machine, keyed by archetype. The archetypes framework composes these definitions with the vm/nexus framework modules plus inventory and secrets data to build machines.

This repo ships synthetic example definitions. A deploy flake redirects the framework's profiles input at an operator's own definitions repo — exporting this same contract — to describe real machines.

Ownership

This repo owns:

  • per-profile NixOS modules under hosts/<archetype>/<name>/configuration.nix
  • per-profile Home Manager modules under hosts/<archetype>/<name>/home.nix
  • shared profile Home Manager modules under modules/ (e.g. preferences.nix)
  • Pi provider endpoint, protocol, and model metadata in pi-providers.json
  • the profiles input contract: lib.profileDefinitions, the optional per-machine lib.profileData, lib.piProviders, lib.validatePiProviders, and homeModules.preferences

This repo does not own:

  • the archetype merge, builders, shared framework modules, vmFacts, and checks: archetypes
  • VM framework modules, disk layout, or base guest policy: vm
  • hypervisor framework modules and lifecycle scripts: nexus
  • machine inventory, VM specs, repository registry, IPs, MACs, and platforms: inventory
  • identity data, credential inventory, Forge hosts/users, token paths, and git policy data: secrets

Provider credentials, target machines, and recipient keys stay in secrets. The provider catalog never contains bearer values or machine selection.

The profiles input contract

flake.nix exports, as a literal attrset (no directory-derived magic):

lib.profileDefinitions = {
  <archetype> = {                 # dev | privacy | hypervisor
    <definition-name> = {
      override ? false;           # consumed only by the framework's compose layering
      nixosModules ? [ <module> ... ];
      homeModules  ? [ <module> ... ];
    };
  };
};
lib.profileData = {               # optional; absent machine keys are legal
  <machine-name> = { <builder-arg overrides> };
};
homeModules.preferences = <home-manager module>;

Archetype-name validity (dev/privacy/hypervisor) is asserted by the archetypes framework, the fact's owner — not here. This flake's own check validates only the structure and field types of its exports and needs no input beyond nixpkgs. It must never grow inputs on secrets or inventory: definitions reference behavior, not identity or machine facts.

Pi provider catalog

pi-providers.json is an object keyed by provider ID. The committed public catalog is empty. A private profiles input may populate it with provider metadata while preserving the same contract:

{
  "example-router": {
    "baseUrl": "https://router.example.invalid/v1",
    "api": "openai-responses",
    "models": [
      {
        "id": "example/model",
        "name": "Example model",
        "reasoning": true,
        "maxTokens": 32768
      }
    ]
  }
}

Validation is deliberately structural. Provider metadata is Pi's configuration format, and the framework's reconciler merges these objects into the agent's models.json verbatim, so Pi is what accepts or rejects an adapter name, a model field, or an endpoint it cannot reach — at the first request, with its own diagnostics. A closed-world schema here would mean every field Pi adds needs a change in this repo, a lock bump, and a rebuild before any deployment could use it, while buying nothing.

Three rules hold, and nothing else:

  • Provider IDs match ^[a-z0-9][a-z0-9-]*$. This is the join key between the catalog and the credential registry in secrets, and the key the reconciler's ownership manifest records, so a malformed one breaks the join rather than a request.
  • models is a non-empty array of objects, each with a non-empty string id. A provider Pi cannot route to is never a deliberate declaration.
  • baseUrl is a string beginning with https://. The credential a provider selects is a bearer token, so a plaintext scheme would put it on the wire. This is a property of the framework's credential handling, not of Pi's format.

Every other field — including adapter names and model fields this repo has never heard of — passes through unchanged. Provider api is optional and is defaulted to openai-completions when absent, the one value this repo supplies rather than checks.

Consumers read the normalized, validated catalog from lib.piProviders. Validation is attached to that exported value, so downstream composition fails closed even though a flake does not run its inputs' own checks. A profiles repo that replaces this input and holds its own catalog calls lib.validatePiProviders on its own data rather than copying the function.

Common commands

nix flake check                                        # validate the export shape
nix eval .#lib.profileDefinitions --json | jq 'keys'   # dev, hypervisor, privacy
nix eval .#lib.piProviders --json                      # normalized Pi providers
nix build .#checks.x86_64-linux.pi-provider-catalog   # schema + sabotage witness

Adding a profile definition

  1. Add the module files under hosts/<archetype>/<name>/.
  2. Add the definition to lib.profileDefinitions.<archetype>.<name> in flake.nix.
  3. Add the machine's facts in inventory and identity/credentials in secrets (separate repos).

History

This repo has fresh history. The example definitions and the preferences module were previously carried in the framework repo (allod/profiles, renamed to allod/archetypes) and the secrets template; the framework's pre-rename commits remain fetchable at the allod/archetypes URL.