andyl/testing registry runbook
This runbook owns every routine operation for the experimental hosted registry.
The registry is public but uses experimental build and release infrastructure
and may be rebuilt from scratch. It supports edge, candidate, and stable;
these classify software maturity, not pipeline provenance. The default is edge.
Its signing material remains separate from andyl/main.
andyl/testing does not use an HSM. The intended key management for
andyl/main is documented in Registry key management.
The public key inventory records separate testing and production Hub receipt authorities. A prepared key is not an activated release authority: signed trust metadata and the applicable release gates still establish where it is accepted. Custody and recovery records are maintained separately from the public inventory.
configured means the production registry or Hub has loaded the public anchor
or signing configuration. It does not claim that release metadata has been
published or that a prepared release-signing authority has been activated.
Use the shared qualification contract and release checklist. This runbook owns registry-specific identity and lifecycle operations, not a separate testing qualification process.
The package-manager delivery endpoint baked into testing disk images and OCI
containers is https://cdn.aos.andyl.org/andyl/testing/, with alias
andyl-testing and the epoch-one trust key below. The Hub management API stays
at https://aos.andyl.org. A CDN attachment alone does not activate delivery:
the explicit delivery workflow must verify the storage publication and route
before advertising that URL.
While a requested CDN destination is pending, browse pages withhold consumer setup commands instead of enrolling new clients on the outgoing Hub route. After activation, public OCI blob GETs may redirect to the CDN when the exact object has matching publication and placement evidence. Distribution control, manifests, private requests, and conditional requests continue through the Hub.
#Preconditions
- Use the designated maintainer machine and a clean checkout of the current
origin/mastercommit. - Complete the contributor-authorization check in
contributor-licensing.md. - Deploy and validate that exact Hub build in staging and production using
aos-hub-deployment.md. An empty testing-only Hub reset may use that runbook's direct-production setup procedure; it does not substitute for the staging evidence required by release publication. - Take and verify the backup set in
aos-hub-backup-recovery.md, unless this is an explicitly approved empty rebuild. - Load only testing credentials. Main-registry signing keys and production Hub tokens must not be present during testing authoring or staging.
Record the source commit, Hub deployment identities, registry base commit and generation, testing root epoch, operator, UTC start time, and intended release version in the operation log.
#Inspect live state
Run these read-only checks before and after every mutation:
aos hub registry show --hub https://aos.andyl.org andyl/testing
aos hub registry releases --hub https://aos.andyl.org andyl/testing
aos hub registry cache-stack show --hub https://aos.andyl.org andyl/testing
aos hub registry cache-stack validate --hub https://aos.andyl.org andyl/testing
aos hub registry mirror show --hub https://aos.andyl.org andyl/testing
Repeat them against staging when the operation has a staging phase. Treat a configured mirror or consumer cache stack as part of the signed release and recovery inventory; follow the generic registry hosting guide for those subresources.
#Create epoch one
The epoch-one image is pinned to this prepared public anchor:
andyl-testing:Ed25519:AAAAC3NzaC1lZDI1NTE5AAAAID1J77zx10Z/VmgFa5qab2phnJEJ2JEp8mS2HnBAnzbH
Before release, retrieve the testing-v1 private key from operator custody,
prove that its derived public key is exactly the line above, and test recovery
from an encrypted independent backup. The previous prepared anchor was replaced
before production use; the image definition and this runbook carry the same new
epoch-one anchor. Do not regenerate a different key under the epoch-one identity
after publishing images. A later abandoned root follows the destructive epoch
reset procedure below.
Verify the restored private key with the AOS-built OpenSSH tool before loading it into APR:
openssh="$(nix build .#pkg-openssh --no-link --print-out-paths)"
derived_public="$("$openssh/bin/ssh-keygen" -y -f "$ANDYL_TESTING_REGISTRY_KEY")"
test "andyl-testing:Ed25519:${derived_public#ssh-ed25519 }" = \
"$ANDYL_TESTING_TRUST_KEY"
For a future registry or trust-root epoch, mint the dedicated OpenSSH Ed25519 registry key before baking its printed public line into the matching profile:
apr keys generate <epoch-key-id> --registry <slash-free-epoch-alias>
Create the epoch-one slash-free authoring clone with the pinned public trust line and its matching private key, then retain its SHA-256 Git root commit as the first canonical registry base:
apr create andyl-testing \
--trust-key "$ANDYL_TESTING_TRUST_KEY" \
--trust-key-id testing-v1 \
--key "$ANDYL_TESTING_REGISTRY_KEY"
The Hub slug and signed release identity are andyl/testing; the clone name and
trust-line prefix are andyl-testing. Generate threshold-signed bootstrap
intents for the exact staging and production deployment identities and run
aos release bootstrap once per environment as documented in
canonical-releases.md. Bootstrap refuses a destination
that already contains a publication.
After the andyl organization exists in staging, create the public registry
topology there with the ordinary reviewed Hub plan/apply protocol. Plan first:
aos hub registry create \
--hub https://aos.staging.andyl.org \
--org andyl \
--name testing \
--visibility public \
--trust-key "$ANDYL_TESTING_TRUST_KEY" \
--if-version absent \
--idempotency-key create-andyl-testing-v1 \
--plan
Review the returned effect manifest, then apply only that exact plan:
aos hub registry create \
--hub https://aos.staging.andyl.org \
--plan-id <plan-id> \
--confirm-hash <effect-manifest-hash> \
--yes
aos hub registry show \
--hub https://aos.staging.andyl.org \
andyl/testing
Bootstrap and qualify the empty base in staging. Only then repeat the topology
plan/apply/show and bootstrap against https://aos.andyl.org, using the
production access profile, deployment identity, plan, and idempotency key. The
topology row and aos release bootstrap publication are separate: create and
inspect the row first, then install the independently approved empty base.
#Publish the first or a later edge release
The prepared first-release profile uses
2026.9.0-dev.20260904.1. For every later edge release, update
aos.system.version in the testing profile to the next calendar SemVer
YYYY.M.P-dev.YYYYMMDD.N through the reviewed source-update workflow before
building. That value is the disk version and the OCI signed release identity;
the aos package version remains separate provenance.
Before freezing the epoch-one public .1 plan, create and retain the
non-public qualification predecessor
at 2026.9.0-dev.20260904.0. Its protected source revision carries the .0
testing profile and uses the reserved snapshot release id and source tag. After
offline verification, advance the profile to .1 in a later reviewed protected
source revision. Do not upload the .0 snapshot or use its isolated registry
commit as the public registry base. The .1 request names the snapshot's
verified release id and manifest digest while retaining the approved empty Hub
base commit and generation.
The public plan request must use the exact prepared version and contain:
registry: "andyl/testing"(or the active epoch identity);- a release class matching the software version (
edgefor this example); - intended channels matching the software class (
edgefor this example); - the exact current testing registry base commit and generation;
- the staging and production deployment identities already verified above;
- complete package and image decisions and all required signer roles.
Follow the release checklist, using
canonical-releases.md for command arguments.
For the testing OCI artifact, externally finalize the exact Nix publication
inputs before prepare-registry. The signing key must be the active testing
registry key, never a main-registry key:
nix build .#container-aos-testing-publication-inputs
openssh="$(nix build .#pkg-openssh --no-link --print-out-paths)"
aos container prepare-signature ./result \
--output container-signature.pae
"$openssh/bin/ssh-keygen" -Y sign \
-f "$ANDYL_TESTING_REGISTRY_KEY" \
-n aos-container-signature-dsse-v1 \
container-signature.pae
aos container finalize-signature ./result \
--signer "$ANDYL_TESTING_TRUST_KEY" \
--signature container-signature.pae.sig \
--output final-testing-container
Upload the immutable OCI graph without a tag or Hub mutation before registry finalization:
aos container publish aos "$TESTING_OCI_REFERENCE" \
--release final-testing-container/container-release.json \
--release-layout final-testing-container/layout \
--signature-input final-testing-container/signature-input.json \
--registry andyl/testing \
--idempotency-key "testing-${AOS_RELEASE_VERSION}-oci-stage" \
--registry-origin "$TESTING_OCI_ORIGIN" \
--registry-token "$TESTING_OCI_TOKEN" \
--stage-only
Include those exact container-release.json and signature-input.json paths in
both aos release prepare-registry and aos release finalize-registry. The
generated transaction's reviewed catalog digest includes the sidecar, and
finalization verifies its exact bytes again. After the signed registry release
is promoted and the Hub has indexed it, rerun the same aos container publish
command without --stage-only, add the production Hub credentials, and use a
new stable idempotency key. Record the returned verified root and tag resource
version. Do not use a generic OCI push for the release tag.
Do not omit staging qualification even though testing data is disposable. Each
command consumes the prior phase's exact evidence, refuses replacement outputs,
and binds andyl/testing into the signed values. Preserve the closed release
bundle, plan request, plan, journal, receipts, TUF set, source checkout identity,
and signer audit records.
After publication, verify anonymously from a clean client that has only the testing image's baked anchor:
apm update --registry andyl-testing
apm search aos --registry andyl-testing
Also boot the published disk image, confirm /etc/aos/release-profile, the
console/SSH warning, and AOS_REGISTRY=andyl/testing in /etc/os-release. Run
the OCI image and check the same profile and warning files before recording the
rollout complete.
#Update packages
Use aos maintain to prepare source updates, not to mutate the registry:
aos maintain scan --repology-fallback --repology-limit 400
aos maintain report --outdated
aos maintain report --advisory
aos maintain report --vulnerable
aos maintain report --license-change
aos maintain plan <unit>
# Or plan one atomic update cohort:
aos maintain plan --campaign <cohort>
# For a manually edited package without complete artifact contracts:
aos maintain refresh-hashes <unit> --check
aos maintain refresh-hashes <unit>
aos maintain run --plan <plan> --confirm-plan <plan-digest>
aos maintain diff <run> --patch
aos maintain accept <run> --confirm <patch-digest>
aos maintain commit <run> --confirm <run>
aos maintain test <run> --final
aos maintain evidence <run>
aos maintain prepare-pr <run>
aos maintain publish-pr <run> \
--expected-remote-head absent \
--confirm <publication-request-digest>
aos maintain observe-pr <run> \
--authorization-check <required-check-name>
aos maintain handoff <run> --confirm <protected-merge-commit>
The fallback probes a same-named Repology project only when the package does not already declare a reviewed Repology mapping. It is a first-signal source: newer-version, vulnerable-version, and license-drift records enter the maintainer report, but they cannot select or materialize an update. A declared direct provider must still identify the exact release, and the source URL, hash, and any required signature checks must succeed before a candidate can be accepted. Review fallback mappings that do not corroborate the package's current version before promoting them into package metadata.
Repology requests are cached for 24 hours, paced to at most one request per
second, and bounded by --repology-limit. Use a smaller limit for a quick
sample. Re-running the command reuses fresh cached observations and can extend
an earlier bounded scan without repeating those requests.
If the remote branch already exists, replace absent with its exact expected
head. prepare-pr prints the publication request and confirmation digest;
publication fails closed if either the local candidate or remote head changed.
Merge only after required review and contributor authorization, and record the
observed protected merge with handoff. Then create a new edge release from
that merge commit. Do not edit a previous release, tag, immutable TUF metadata
version, or content-addressed Hub object. Channel and timestamp pointers
advance only through their dedicated aos release operations.
#Rotate keys without resetting trust
Use the signed APR roster transition for an ordinary registry key rotation:
apr keys generate <new-id> --registry andyl-testing --add
apr keys list --registry andyl-testing
Publish an overlap release, verify a clean client can sync from the old baked anchor and learn the new active key, and only then retire the old key with the survivor-vouched APR operation. TUF, release-evidence, qualification, Hub receipt, Secure Boot, module, PCR, and cache roles follow their own threshold rotation procedures; never collapse them into the APR key merely because one machine holds the credentials.
If the Hub registry resource's publication trust set changes, update it with
the complete overlap set, never only the newly generated key. Capture the exact
resource version with registry show, plan the update, and apply its returned
plan exactly:
aos hub registry update \
--hub https://aos.andyl.org \
andyl/testing \
--trust-key "$OLD_TRUST_KEY" \
--trust-key "$NEW_TRUST_KEY" \
--if-version <exact-resource-version> \
--idempotency-key overlap-andyl-testing-keys \
--plan
aos hub registry update \
--hub https://aos.andyl.org \
andyl/testing \
--plan-id <plan-id> \
--confirm-hash <effect-manifest-hash> \
--yes
Repeat in staging first. Removing the retired key is a second reviewed update after the overlap release and clean-client verification.
Other registry configuration changes use the same exact-version plan/apply
contract. Supply only reviewed fields such as --visibility, --crawl-policy,
--llms-txt-body, or --clear-llms-txt; review and apply in staging before
repeating against production. Testing remains public. A configuration change
does not authorize a release, key rotation, mirror, cache-stack, or channel
mutation.
#Destructive root reset
Use this only when the testing history or out-of-band root can no longer be trusted or intentionally becomes incompatible.
- Stop new testing release work and retain the old public evidence.
- Select the next unused identity, for example
andyl/testing-v2, and matching alias such asandyl-testing-v2. - Generate a new root and all role keys. Do not sign the new root with a compromised or intentionally abandoned old root.
- Update the testing profile's identity,
rootEpoch, URL, alias, and public anchor; build new disk and OCI artifacts. - Bootstrap the new empty registry in staging, qualify an edge release, then bootstrap and publish it in production.
- Verify old images reject the new registry and new images use only the new epoch.
- Mark the old registry read-only, retain it for the recorded migration window, then remove its Hub data according to the approved destructive plan.
Changing only the bytes behind andyl/testing is forbidden.
Delete a retired testing registry only after its evidence and object-retention
decision are recorded. Capture its exact resource version with registry show,
then use the same two-step mutation contract:
aos hub registry delete \
--hub https://aos.andyl.org \
andyl/testing \
--if-version <exact-resource-version> \
--idempotency-key retire-andyl-testing-v1 \
--plan
aos hub registry delete \
--hub https://aos.andyl.org \
andyl/testing \
--plan-id <plan-id> \
--confirm-hash <effect-manifest-hash> \
--yes
Repeat independently in staging. Registry deletion is not an R2 backup or garbage-collection command; reconcile retained objects under the reviewed Hub storage-retention procedure.
#Audit, rollback, and retirement
Use aos release verify with independently supplied public keys for every
retained release bundle. Compare the public deployment probe, registry release,
channel partitions, timestamp, and object digests to the operation log. A bad
edge release is fixed forward with a new immutable release; channel rollback is
an explicit signed channel operation, never an overwrite of release bytes.
For Hub corruption or deletion, follow
aos-hub-backup-recovery.md. Because testing is
disposable, an approved full reset may instead create a new trust-root epoch and
redeploy from empty state. Revoke tokens, archive public evidence, remove the
old image outputs from discovery, and record the terminal registry generation
when retiring an epoch.