Files
ssmithxandClaude Opus 5.5 05cb17b67c docs: make ngit the source of truth and add the archy integration skill
The canonical repo is now nostr://npub1krldcq2laqxeslseue8uyk24vg6mhmv0ra6ldc52hyfwdx5azd8se5j65x/relay.ngit.dev/podsteadr,
with Gitea kept as a mirror. The archy-integration skill maps each file here
that Archipelago's manifests depend on to the archy files that must follow
it, plus the release, regenerate/check and node-test steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 19:42:27 +00:00

8.7 KiB

name, description
name description
archy-integration Use when changing podsteadr or podsteadr-player in a way Archipelago (the archy repo) depends on — Dockerfile, env vars/config, ports, routes, health check, data paths, container names, blossom/mediamtx config or image versions, the player's nginx/FIPS gateway — or when releasing a new podsteadr version to Archipelago nodes. Lists which archy files follow which files here, how to regenerate and check them, and how to push both sides.

podsteadr ↔ archy integration

podsteadr ships on Archipelago as a four-container app packaged in the archy repo. Archy holds no podsteadr source: it runs images built from this repo and from podsteadr-player, described by manifests. When something here changes that the manifests describe, archy has to change too, or nodes run the new image with stale settings.

Repos and remotes

Repo Local Source of truth (origin) Mirror
podsteadr ~/podsteadr nostr://npub1krldcq2laqxeslseue8uyk24vg6mhmv0ra6ldc52hyfwdx5azd8se5j65x/relay.ngit.dev/podsteadr gitea
podsteadr-player ~/podsteadr-player nostr://npub1krldcq2laqxeslseue8uyk24vg6mhmv0ra6ldc52hyfwdx5azd8se5j65x/relay.ngit.dev/podsteadr-player gitea
archy ~/archy Gitea origin for branches/PRs (see below) ngit
  • ngit is the source of truth for both app repos. Push every branch to origin (ngit) first, then to gitea so the mirror stays current: git push origin <branch> && git push gitea <branch>.
  • The ngit account on this machine (npub1krld…j65x) owns the two app repos but is not a maintainer of archy's ngit repo, so archy branches go to Gitea (git push origin <branch>) and PRs are opened through the Gitea API (token is in the remote URL). Pushing archy to ngit is rejected until that npub is added as a maintainer.
  • Follow archy's own CLAUDE.md when editing it: work on a branch, stage by path (never git add -A — ~/archy often has other people's uncommitted work), commit and push each unit of work, no node hostnames or IPs in archy.

What in archy follows what here

Until archy PR #163 (branch feat/podsteadr-app) is merged, the four-container package — the player manifest, the stack registration in core, the build scripts — exists only on that branch, so base archy work on it rather than on main.

Archy paths are relative to ~/archy. "Manifest" means apps/<app>/manifest.yml.

podsteadr (this repo)

Change here Update in archy
Dockerfile apps/podsteadr/Dockerfile is a vendored copy: keep its header comment, replace everything from # ---- frontend ---- down with this repo's file. Check with diff <(sed -n '/^# ---- frontend/,$p' ~/archy/apps/podsteadr/Dockerfile) <(sed -n '/^# ---- frontend/,$p' Dockerfile).
New/renamed env var in server/src/config.ts apps/podsteadr/manifest.yml environment (fixed values) or derived_env (values built from the node's address, e.g. PUBLIC_URL). Keep docker-compose.yml here in step too.
Default ports, or a new listening port Manifest ports (every port needs auth:; auth: none needs an auth_rationale), interfaces if it's a UI/API, apps/PORTS.md, add auth: none ports to the allowlist in the unauthenticated-endpoint test in core/container/src/manifest.rs, then regenerate (the FIPS firewall list in core/archipelago/src/fips/app_ports.rs comes from the manifests).
MESH_BLOSSOM_PORT / blossom's public port Must equal blossom's host port (8098) in apps/podsteadr-blossom/manifest.yml and its interfaces.main.port.
Health route (/api/health) Manifest health_check.path.
Data layout under DATA_DIR (/data) or RECORDINGS_DIR (/recordings), or the runtime user (node, uid 1000) Manifest volumes, data_uid, and the "Data" section of apps/podsteadr/README.md. Never change a path in a way that strands existing data: archy's rule is that migrations never destroy data.
Where the vendored nostr-provider.js lives in the image (/app/public/nostr-provider.js) Manifest hooks.post_install copy_from_host.dest.
blossom/config.yml The config embedded under files: in apps/podsteadr-blossom/manifest.yml. It's a copy, not identical: keep archy's paths and comments.
mediamtx/mediamtx.yml (including the auth webhook URL http://podsteadr-app:8095/...) The config embedded under files: in apps/podsteadr-mediamtx/manifest.yml.
blossom or mediamtx image version in docker-compose.yml container.image in the matching archy manifest.
Service DNS names the app uses (mediamtx, blossom, podsteadr-app), container names, or adding/removing a container Network aliases in the manifests, and the stack registration in core: core/archipelago/src/app_ops.rs (stack_member_app_ids, owning_package), api/rpc/package/stacks.rs, install.rs, runtime.rs (orchestrator_uninstall_app_ids), config.rs (all_container_names), dependencies.rs (startup_order), crash_recovery.rs (auto-start list and the podsteadr StackRecoverySpec aliases), container/docker_packages.rs (excluded_services). Grep core/ for podsteadr to find them all.
User-facing description, features, screenshots Manifest description and apps/podsteadr/README.md.

podsteadr-player (~/podsteadr-player)

Change there Update in archy
Listening port (8097) in nginx.conf / Dockerfile apps/podsteadr-player/manifest.yml ports, interfaces, health_check.endpoint, apps/PORTS.md, the ("podsteadr-player", 8097) entry in the unauthenticated-endpoint test in core/container/src/manifest.rs, then regenerate.
Ports or hosts the /fips/ gateway relays (nginx.conf, njs/fips.js, src/lib/net.ts) The player manifest's auth_rationale describes them, and every relayed port must be opened over FIPS by some manifest's interfaces (8095 and 8098 today).
Files nginx writes (pid, temp paths in /tmp) The root filesystem is read-only; only the /tmp tmpfs in the manifest is writable.
/healthz Player manifest health_check.path.
Base image or anything needing more capabilities or egress Player manifest security/network. It uses network: pasta because the gateway needs IPv6 egress to the mesh; bridge networks can't reach FIPS addresses.

Shipping a new version to nodes

Manifests pin images with pull_policy: if-not-present, so a node that already has a tag will never pick up a rebuilt image under the same tag. Every release needs a new tag.

  1. Merge the change in this repo (and/or the player) and push to origin and gitea.
  2. In archy, on a branch: bump version and the container.image tag in apps/podsteadr/manifest.yml and/or apps/podsteadr-player/manifest.yml, plus VERSION in apps/podsteadr/build-from-prototype.sh.
  3. Build and publish the images from ~/archy: ./apps/podsteadr/push-to-registry.sh <version> (registry source.archipelago-foundation.org/lfg2025; needs podman login). To test on a node without publishing, run build-from-prototype.sh ~/podsteadr ~/podsteadr-player on that node instead.
  4. Regenerate and check (below), commit by path, push, open or update the archy PR.

podsteadr is not in archy's per-app OTA update mapping (scripts/image-versions.sh, core/archipelago/src/container/image_versions.rs, scripts/generate-app-catalog.sh), so new versions reach nodes with an Archipelago release, not through the App Store "Update" button.

Regenerate and check (run in ~/archy)

python3 scripts/generate-app-catalog.py           # catalogs, app_ports.rs, app-session config
python3 scripts/generate-app-catalog.py           # second run must report total_updated=0
python3 scripts/check-app-catalog-drift.py
python3 scripts/check-app-build-contexts.py .
for a in podsteadr podsteadr-blossom podsteadr-mediamtx podsteadr-player; do
  ./scripts/validate-app-manifest.sh apps/$a/manifest.yml
done
cd core && cargo test -p archipelago-container manifest

If you touched core: cargo test -p archipelago (from core/). It needs a recent stable toolchain; if the system rustc fails on atomic_try_update, put the rustup stable toolchain first on PATH. If you touched neode-ui/: cd neode-ui && npx vitest run src/views/apps src/views/appSession.

Testing on a node

Before an archy release: build both images on a test node with build-from-prototype.sh (it works around rootless podman seeing /var/tmp read-only), deploy the archy branch, install podsteadr from the App Store, and run tests/lifecycle/run-gate.sh on the node (install, stop/start/restart, reinstall, reboot and archipelago-restart survival, uninstall with all four containers removed). Installing, stopping and uninstalling need a dashboard login, so the node's owner clicks those.