aslice Repositories — Sources, Trust Levels, and Signing Keys

State, identity, privilege, and recovery contracts: STATE-AND-RECOVERY. Protected-volume patching: SYSTEM-VOLUMES. These specifications do not establish completed implementation or platform validation.


Contents - [1. Axioms](#axioms) - [2. The shipped source list](#the-shipped-source-list) - [3. Trust levels](#trust-levels) - [4. Adding a third-party repository](#adding-a-third-party-repository) - [5. Signing keys: two schemes, one verification pipeline](#signing-keys-two-schemes-one-verification-pipeline) - [6. Repository tree addition: `keys/`](#repository-tree-addition-keys) - [7. `aslice repo` command surface, completed](#aslice-repo-command-surface-completed) - [8. Failure and edge cases](#failure-and-edge-cases) - [9. Amendments carried into the other documents](#amendments-carried-into-the-other-documents) - [10. Overlapping packages across repositories](#overlapping-packages-across-repositories) - [11. The state database's role](#the-state-databases-role)

1. Axioms

  1. Trust is per-repository, never global (DESIGN §9.6). When you add a repository, it acquires the capabilities of its trust level, and nothing beyond them.
  2. Trust levels are inherent, not labels. A level is a set of enforced capabilities: which namespaces the repo may serve, whether its binaries may install, whether it may serve [system] packages. The checks live in the solver and the verifier, in code — not in documentation. A repository cannot talk its way into a higher level; only the user (or the project's countersignature, for verified repos) can raise one.
  3. Every served artifact is signed. No trust level permits unsigned binaries to install. What varies between levels is whose signature is required and what the repo is allowed to offer; what never varies is that verification happens.
  4. No repository can execute code at install time outside the graft mechanism, regardless of level (DESIGN §10.1 and DESIGN §12.15). The only package code that can ever run is a declared, approved, manifest-sandboxed graft — and §3's table says who may serve even that. Trust levels govern distribution, not the structural guarantees.
  5. The official list is data, signed and versioned — not hardcoded logic. aslice ships a source list file; you can inspect it, diff it, and — if you are the paranoid sort — replace it wholesale with a pinned copy.

2. The shipped source list

An aslice installation carries /opt/aslice/etc/sources.toml. The file is part of the bootstrap package and updates through the normal TUF channel — it is a TUF target like any other metadata: versioned, rollback-protected, and diffable with aslice repo list --sources-diff.

# aslice official source list — ships with the bootstrap, updated via TUF.
# Schema versioned; unknown fields rejected.

[sources.core]
url          = "https://repo.aslice.sh/core"
mirrors      = ["https://ghcr.io/aslice/core", "https://mirror.example.org/core"]
trust        = "official"
namespace    = "core"
tuf_root_fingerprint = "ed25519:ROOT0…" # initial TUF anchor
key_fingerprint = "ed25519:RWQ0…"       # separate package-signing key
enabled      = true

[sources.extended]
url          = "https://repo.aslice.sh/extended"
trust        = "official"
namespace    = "extended"
tuf_root_fingerprint = "ed25519:ROOT1…"
key_fingerprint = "ed25519:RWQ1…"
enabled      = true

[sources.audio-lab]
url          = "https://repo.audio-lab.example/aslice"
trust        = "verified"           # project-countersigned community repo (§3)
namespace    = "audiolab"
tuf_root_fingerprint = "ed25519:ROOT2…"
key_fingerprint = "openpgp:9F3C 77AA …"
countersigned_by = "ed25519:RWQ0…"  # the core key vouches for this repo's key
enabled      = false                # listed for discovery; off until the user opts in

The properties that matter:

3. Trust levels

Four levels, ordered by what a repository is permitted to do:

Level Admission Binaries System effects System patches Grafts
official Bootstrap-pinned project authority Yes Yes Yes Rehearsed, signed manifest
verified Project countersignature and explicit enable Yes Yes Explicit per-repo grant Manifest signed by vouched authority
third-party User-added, initial trust verified/pinned Yes No No Unsigned manifest; fresh approval each time
local Explicit local development tree Source only unless signed and pinned Own machine, consent required Own machine, consent required Same containment and consent rules

Every repository serving binaries uses Ed25519 TUF metadata. Package signatures are additionally verified: minisign-format Ed25519 for official releases, or the declared supported package-signature scheme for other repositories. An OpenPGP package key never replaces a TUF root (STATE-AND-RECOVERY §7). Unsigned local recipes remain a separate local-only source-build path. The rules below define capabilities and their conditions; a short table cell does not waive them.

Some rules hold at every level:

4. Adding a third-party repository

All orchards, including third-party orchards, follow the shared environment and promotion contract: dev → develop, staging → beta, prod → master. These branches belong to one repository identity, replicated by its mirrors; environment selection changes the branch pointer, not the repository or mirror URL. Production is the default, and dev/staging require explicit selection with no automatic cross-environment fallback. Each environment has isolated cached metadata and rollback-protection state. Promotion reuses immutable artifacts under the release-version rules. Third-party publishers use their own authorities; this workflow does not alter trust levels or capabilities. Maintenance promotion records follow ORCHARD-POLICY; implementation remains pending. TUF metadata itself is unchanged.

$ aslice repo add https://repo.example.org/aslice
Fetching TUF root metadata…
Repository:  example.org community repo
Namespace:   example
TUF root:    ed25519:ROOT…
Package key: openpgp:7A3F 19C2 88E4 0D1B …
Trust level: third-party (binaries allowed; cannot shadow core packages)

Verify this fingerprint out-of-band — project website, release notes,
a signed email. Anyone can serve a repository; the fingerprint IS the
identity. Pin it? [y/N]

5. Signing keys: two schemes, one verification pipeline

5.1 Why two schemes

The canonical scheme is Ed25519 in minisign-compatible format under TUF (DESIGN §10.2). The virtues are practical: tiny keys, tiny signatures, a verification routine small enough to audit in an afternoon, and no dependency on the GnuPG ecosystem. This remains the scheme for the official repositories and for aslice's own releases.

Repositories exist, however, so that other ecosystems can distribute through aslice — and those ecosystems already sign with OpenPGP: upstream release tarballs, vendor checksum files, existing project keyrings. Telling every third-party operator to re-key into minisign would amount to telling the platform's most valuable niche communities (audio, lab, retro) to change their release process for our sake. OpenPGP verification is therefore a first-class, built-in scheme:

5.2 Where each signature lives

Layer Scheme Checked when
TUF repo metadata (root/snapshot/timestamp/targets) Ed25519 (spec-native), initially 1-of-1 per official role Every index update
Slice signatures minisign-format Ed25519 (official) or OpenPGP detached signature (third-party), scheme recorded per-repo in its TUF targets Before extraction, always (DESIGN §6.2)
verified countersignature Ed25519, core key over the repo's root key fingerprint At enable time and on every source-list update
Vendor artifacts Apple code-signing identity pin (unchanged, DESIGN §12.4) — orthogonal layer Before payload extraction
Upstream source tarballs in formulas sha256 pins always; OpenPGP verification where the formula declares [source.pgp] — key_url plus pinned fingerprint (PACKAGE-FORMAT §3.4; BUILD-INFRA §3 "PGP where declared") At fetch/verify phase of builds

The client's rule is uniform: the scheme is a property of the repository, the fingerprint is a property of the pin, and both are enforced before content is trusted. A mixed ecosystem — an OpenPGP vendor repo alongside the Ed25519 official repos — is the expected steady state, not an edge case.

5.3 Rotation and revocation

6. Repository tree addition: keys/

The repository tree of DESIGN §9.6 gains one directory:

repo.example.org/
 ├── tuf/
 ├── index/
 ├── formulas/
 ├── keys/           # full public keys for every fingerprint the repo asks clients to pin
 └── blobs/sha256/

One characterization covers keys/: convenience distribution, not authority. Its contents verify against the pinned fingerprint or are rejected. For verified repos, keys/ additionally holds the project's countersignature file, refreshed by source-list updates.

7. aslice repo command surface, completed

aslice repo list [--json]                 # namespaces, levels, key fingerprints, health
aslice repo add <url|file://> [--trust local]
aslice repo remove <name>
aslice repo enable / disable <name>       # verified repos ship disabled; user opts in
aslice repo re-pin <name>                 # guided fingerprint change with transition proof
aslice repo keys <name>                   # show the pinned keyring, scheme, countersignatures
aslice repo audit <name>                  # signature coverage report: every target signed? by which key?
aslice repo allow-system-patch / deny-system-patch <name>  # the per-repo verified grant (§3)
aslice repo build / sign / publish        # authoring side (DESIGN §9.6); --sign-with ed25519|openpgp
aslice repo list --sources-diff           # what the last source-list TUF update changed

Official authoring retains repo build / sign / publish: after owner-approved merge and all gates, the publisher sends an authenticated candidate to the dedicated networked release Pi for automatic signing, verifies the returned signatures and complete staged content, then publishes atomically. KEY-RUNBOOK §2.1 defines authorization, serialized activation, signing-state persistence, stale-candidate reconciliation, and idempotent retries. Root metadata is valid for one year, targets/snapshot for 90 days, and timestamps for 48 hours with daily refresh. Targets/snapshot renew automatically when fewer than 30 days remain using the last approved content; root renewal and top-level key replacement remain deliberate offline operations. Timestamp refresh cannot extend targets/snapshot expiry. Normal client metadata refresh discovers published slices for search, install, and upgrade; publication forces no installation. These services remain implementation work; no client signature-format, schema, or command-group change is introduced.

aslice repo audit re-verifies the signature over every target in a repo's current snapshot and reports scheme, key, and coverage. It exists so that an operator can prove "everything is signed" is true today — not at some ceremony in the past.

7.1 Authenticated index refresh

Fetch indexes by immutable SHA-256 address and authenticated byte length. TUF targets authorize the compressed object and a version-1 index-diff record binding repository/environment, base and result index digests and lengths, and ordered patch objects. Index digest means the exact uncompressed JSON bytes; parse only after reconstruction verifies that identity. The full compressed object's authenticated record also binds expanded digest and length. Reject duplicate JSON keys and unsupported snapshot formats.

Initial client limits are 16 patches, 64 MiB total patch transfer, 256 MiB expanded index, 512 MiB reconstruction memory, and 30 seconds reconstruction time. Enforce each bound during streaming, with checked arithmetic. A bad/missing base, unsupported patch codec, digest/length mismatch, or exceeded limit discards staged reconstruction and falls back once to the full authenticated index, under the same expanded-size/memory bounds. Version 1 uses byte-splice-v1 payloads described by the index-patch schema. Each payload binds its exact base/result and at most 100,000 ordered operations: copy appends a positive-length range from the verified base (checked offset plus length); insert appends decoded lowercase hexadecimal bytes. Output is append-only in staging. Reject overflow, out-of-range reads, unknown operations, duplicate JSON keys, excess output, or a chain whose next base differs from the preceding result. Reconstruction budgets include base, patch, and output memory. Patch instructions never name files or execute code. A failed full fetch leaves the previous snapshot active and reports failure.

Stage the new snapshot and every object required by the refresh transaction before activation; verify identity, length, signatures, schema, freshness, and cross-references, then switch the local current-snapshot pointer atomically. Missing objects during mirror publication cannot activate a partial snapshot. Lazy payloads outside the refresh set remain subject to complete transaction preparation before installation.

Try at most three configured mirrors, at most two attempts per mirror, with finite time/byte budgets (30 seconds per attempt by default). All attempts request the same authenticated identities and selected release. Retain and report integrity failures even if another mirror succeeds. A mirror never changes the trust anchor, repository identity, environment, or selected version. If refresh is required for freshness, a retained expired snapshot cannot authorize an update.

An unrelated unavailable repository does not block a transaction whose complete input closure is independently authorized and available. A required unavailable repository blocks that transaction: no silent package omission, repository substitution, or downgrade. Explicit whole-repository refresh still reports each failure. APT by-hash and PDiff controls motivate stable object retrieval; these bounds and activation semantics are aslice's contract.

8. Failure and edge cases

Case Behavior
Source-list update fails/tampered Client keeps the last good list; core/extended keep working; warning surfaced by doctor
Repo serves a key that doesn't match the pin Hard refusal before any content is fetched; event logged
verified repo's countersignature revoked Repo frozen at last good snapshot, updates refused, persistent banner until re-pin/remove
local repo contains binary targets Binaries refused (source-build formulas only) unless the local repo is signed and the machine's user pinned its key
A third-party repo serves a [system] package Solve-time refusal naming the trust level and the remedy; the system capability is never granted to third-party (§3)
A third-party repo serves a graft-bearing package Only effects permitted to third-party repositories are allowed; privileged categories are refused even with graft consent. The manifest is unsigned: the client shows the unsigned-graft warning with the full declared behavior, and approval is per decision, never persisted (§3; DESIGN §12.15)
A third-party repo declares domain = "system" in [service] Solve-time refusal naming the trust level and the remedy; user-domain agents from third-party repos remain allowed (§3)
A third-party repo — or a verified repo without the per-repo grant — serves a [system-patch] package Solve-time refusal naming the trust level and the remedy (aslice repo allow-system-patch <name> for a verified repo; the capability is never available to third-party) (§3)
Two third-party repos claim the same namespace Second add is refused; namespaces are unique per client
GPG key uses SHA-1 self-signatures / legacy packets outside the supported subset Clear rejection message naming the unsupported feature; the answer is a modern key, not a looser verifier
User deletes sources.toml Bootstrap-embedded defaults regenerate it at next run (user edits are in sources.toml.d/-style drop-ins, so deletion loses nothing)

9. Amendments carried into the other documents


10. Overlapping packages across repositories

Only core packages can be addressed by a bare name. Every other repository requires its registered namespace, including extended:package. Names are resolved exactly; enabling another repository never changes what a bare name means.

10.1 When overlap is detected

A duplicate complete package identity within a repository is an index error. The same suffix in two repositories is permitted because audiolab:convolver and plugins:convolver are distinct identities. Registering a second repository with an existing namespace is refused.

10.2 The prompt

There is no overlap prompt. A bare name absent from core fails with an actionable error. Search may list qualified alternatives, but installing one requires the user to name it explicitly.

10.3 Decisions are remembered — in the state database

No repository-resolution preference is stored. Plans, locks, request roots, and dependency bindings retain the repository identity and qualified package name. Installing or enabling a repository cannot reparent existing packages.

10.4 Pre-seeding and fleets

Machine files, recipes, and scripts use the same naming rule. Use extended:vendorcli or audiolab:convolver explicitly. The previously proposed preference/resolution commands and table are superseded; they are not part of the current interface.

Virtual providers, aliases, and replacements obey the same namespace boundary as concrete package names. A declaration cannot make other:provider satisfy a core request implicitly. Cross-namespace selection requires an explicit choice naming the requested identity, selected namespace/name, repository identity, and selection kind (provider, alias, or replacement). Retain that choice in requests, plans, and locks and revalidate its authority on replay. Removing a repository or reusing its namespace cannot transfer a choice to another identity. A same-namespace alias still requires authenticated metadata from that namespace's authority.

11. The state database's role

SQLite separates client state from the disposable cache. Protected system state, the farm coordinator, publisher, and release signer have distinct owner databases. DATABASE owns their executable schemas, lifecycles, maintenance commands, and disaster recovery; this section summarizes repository interactions.

Projection Contents Written by
Client artifacts, bindings, members, requests Exact installed origins, generation membership, dependency bindings, and requested roots Journaled install/uninstall/rollback/mark
Client holds, runtime_defaults, profile_priorities, history Durable choices, collision-provider priorities, and compact operation history Journaled mutations, including those without a generation change
Cache snapshots, packages, solve_cache, solve_inputs Verified index and recipe projections and solves bound to their complete inputs Authenticated refresh and solver
Cache trust_projections Non-authoritative descriptions of retained trust records Authenticated trust-state reconciliation

History

Document revision history | Version | Date | Changes | |---|---|---| | v1.17 | September 2026 | Classify FFmpeg as extended and align affected package references and examples. | | v1.16 | September 2026 | Replace inline navigation with a collapsible Contents list; preserve section labels, links, and order. | | v1.15 | September 2026 | Specify dependency-driven security remediation, explicit update and origin decisions, and the applicable farm, maintenance, and evidence contracts. Supersedes ABI-only rebuild and cost-first selection policies where previously stated; runtime and measured acceptance remain pending. | | v1.14 | September 2026 | Remove retired comparison references and competitive framing; retain aslice requirements and link their owning specifications. Align affected contract summaries where applicable. | | v1.13 | September 2026 | Replace the single-file database summary with six owner roles, durable choices, disposable cache, and DATABASE command/recovery contracts; public formats and trust boundaries are unchanged. | | v1.12 | September 2026 | Documentation audit repairs: contract summaries aligned; owner-approved namespace, rollback, GC, naming, prefix, and graft decisions applied where relevant; semantic anchors and explicit citations added. Runtime implementation and platform acceptance remain pending. | | v1.11 | September 2026 | Consolidate revision notes into a collapsible history table; no specification changes. | | v1.9 | September 2026 | owner merge becomes the final human release approval, with automatic signing on a dedicated networked Pi and serialized atomic publication. Automatic targets/snapshot renewal replaces manual renewal; the root remains offline. The manual-release design above is superseded. Services and acceptance drills remain implementation work (KEY-RUNBOOK §2.1, §7); schemas and client signature formats are unchanged. | | v1.8 | September 2026 | **Superseded design record:** initial signing uses a single owner, separate offline root and release Pis, encrypted backups, and manual release batches. The Mac Pro VM prepares and publishes; multi-party custody and hardware tokens are deferred. KEY-RUNBOOK defines renewal, rotation, recovery, and pre-launch drills; prior custody requirements are superseded. | | v1.7 | Not recorded | prose-fix pass — one meta-announcement removed (§3); gems kept deliberately ('the binary pin is the root of the root', 'that way lies prompt fatigue', 'no warning flow makes a stranger's kernel extension acceptable'); companion versions refreshed (DESIGN v1.20, PACKAGE-FORMAT v0.15, BUILD-INFRA v0.14, ORCHARD-POLICY v1.8); no semantic or trust-model changes | | v1.6 | Not recorded | grafts gain their trust-level row — the §3 table answers "may serve grafts?" per level, and graft behavior manifests become signed index metadata: farm-rehearsed and project-signed for official, own-key-signed for verified, unsigned-only under the client's loud per-decision warning for third-party, own-machine for local (mechanism DESIGN v1.19 §12.15; schema PACKAGE-FORMAT v0.15 §3.11; acceptance ORCHARD-POLICY v1.7 §12) — owner decision, September 2026. | | v1.5 | Not recorded | the canonical endpoint moves to repo.aslice.sh — the project domain (aslice.sh) carries the homepage, documentation, dashboard, installer, repository, and farm, with human pages as paths on the apex and machine endpoints as subdomains (owner decision, September 2026); companion versions refreshed (DESIGN v1.17, PACKAGE-FORMAT v0.13, BUILD-INFRA v0.12, ORCHARD-POLICY v1.6); no trust-model changes. | | v1.4 | Not recorded | companion versions refreshed (DESIGN v1.16, PACKAGE-FORMAT v0.12, BUILD-INFRA v0.11, ORCHARD-POLICY v1.4); no semantic or trust-model changes. | | v1.3 | Not recorded | NOMENCLATURE.md vocabulary reference added to the header; companion versions refreshed (DESIGN v1.15, PACKAGE-FORMAT v0.12, BUILD-INFRA v0.10, ORCHARD-POLICY v1.3); no semantic or trust-model changes. | | v1.2 | Not recorded | review pass — companion versions refreshed; no semantic or trust-model changes. | | v1.1 | Not recorded | prose rewrite throughout — chapters reworded in the project's technical-writing voice; no semantic or trust-model changes. | | v1.0 | Not recorded | editorial pass — prose revised for directness; no semantic or trust-model changes. | | v0.9 | Not recorded | review corrections — §5.2 names the declared PGP schema (`[source.pgp]` with `key_url` plus pinned `fingerprint`, PACKAGE-FORMAT §3.4) instead of a loose `pgp_fingerprint`; §7's command block gains the overlap-resolution and grant commands (`prefer`, `resolutions` / `forget`, `re-resolve`, `allow-system-patch` / `deny-system-patch`, `list --overlaps`). | | v0.8 | Not recorded | the tree's vendored-source role made explicit — every fetched source artifact lives in `blobs/sha256/`, mirrors replicate it, and the client fetch order is upstream → formula `mirrors` → the repository's own blob area (DESIGN v1.9 §9.6); companions refreshed. | | v0.7 | Not recorded | DESIGN open question #10 **resolved** — a `verified` repository may receive the `system-patch` capability through an explicit per-repo grant (`aslice repo allow-system-patch `, refused by default, recorded in the state DB, revocable); third-party still never — §3, §8; mechanism in DESIGN v1.8 §12.11. | | v0.6 | Not recorded | the **`system-patch` capability** — serving `[system-patch]` packages (flagged replacement of Apple-provided files) is the strictest gate in the system: official and local repositories only, verified and third-party never — §3, §8; mechanism in DESIGN v1.7 §12.11, schema in PACKAGE-FORMAT v0.6 §3.16. | | v0.5 | Not recorded | the same capability gates **root-domain services** (`domain = "system"` in PACKAGE-FORMAT v0.4's `[service]` table); user-domain agents stay ungated — §3; mechanism in DESIGN v1.3 §12.8. | | v0.4 | Not recorded | the `system` capability — serving `[system]` packages (kexts, SIP-off development tools) is gated by trust level; third-party repositories never may — §3; mechanism in DESIGN v1.2 §12.7. | | v0.3 | Not recorded | `history` rows carry the operation ID that correlates with the operation log — DESIGN §12.5. | | v0.2 | Not recorded | cross-repository overlap resolution with remembered decisions — §10; the state database's role — §11. | | Not recorded | September 2026 | corpus review corrections: artifact identity, protected execution, durable recovery, trust persistence, replay, platform limits, and examples aligned with STATE-AND-RECOVERY and SYSTEM-VOLUMES. These are specification changes; runtime acceptance remains pending. |

Source document