security: remove all infrastructure and internal process material from the repo
Demo images / Build & push demo images (push) Failing after 2m13s

The repo is source code and guidelines only. Nothing about how Archipelago's
own fleet is run, or how the team works, stays in it.

Untracked (kept on disk, gitignored) — 250 files:
- .planning/ (199) and loop/ — internal development process
- fleet operations tooling that targets specific nodes: deploy-to-target,
  deploy-tailscale, deploy-config-defaults, setup-target-dev, setup-aiui-server,
  setup-https-dev, debug-frontend, node-profile, fleet-fips-pair/unpair,
  image-recipe/sync-from-live.sh
- image-recipe/INTEGRATION-GUIDE.md and docs/multinode-testing-plan.md, both of
  which are live-server workflow and fleet node inventories
- the Phase 10 on-node verification and evidence records, which cite .planning/
  as their evidence base

KEY-05-ENTROPY-ENFORCEMENT.md was initially moved out with the other Phase 10
docs and then put back: it is cited as normative rationale from ten places in
the codebase, including core/clippy.toml, which bans rand::thread_rng and
points at it for the reason. That makes it a guideline, not an internal record.

Node names removed from source (48 occurrences across comments, manifests and
test fixtures): archi-dev-box, archy-x250*, shorty-s, framework-pt,
zaza-optiplex, archi-thinkpad. Comments keep the engineering context and the
date, which is what carried the meaning; the machine name did not.

Three of those were live test values rather than comments and were replaced
with valid stand-ins, not prose: two mDNS hostnames and a mesh peer name.
An earlier pass substituted "a test node" into a hostname assertion, producing
an invalid hostname; caught and fixed as test-node.local.

Wipe mechanism: .local-only/manifest.txt inventories every local-only path and
.local-only/wipe.sh deletes them on one confirmation, refusing to touch
anything git still tracks. Both are themselves untracked, so the public repo
does not carry a map of internal filenames.

Verified: cargo check -p archipelago --all-features clean; archipelago-container
75/75 tests pass; appOrigin vitest 7/7; audit-secrets 5/5; every relative link
in tracked markdown resolves (0 broken).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-08-07 10:37:20 -04:00
co-authored by Claude Opus 5
parent cc00884b98
commit 6ba0599639
282 changed files with 119 additions and 58845 deletions
@@ -225,7 +225,7 @@ pub fn catalog_manifest_values() -> Vec<(String, serde_json::Value)> {
/// same origin. They diverged once — the orchestrator published containers
/// from the catalog while the gate classified from stale disk manifests, and
/// the gate externally bound a port the catalog had declared `auth: local`
/// (nbxplorer 32838, archi-dev-box 2026-08-04).
/// (nbxplorer 32838, a test node 2026-08-04).
pub fn catalog_manifest_overlay(
app_id: &str,
value: serde_json::Value,
@@ -31,7 +31,7 @@ server {
# on the fips0 mesh allowlist (fips/app_ports.rs), so any mesh peer, LAN
# host or Tailscale peer could POST authenticated Bitcoin Core RPC —
# including wallet methods, with a wallet loaded. Verified live on
# archi-dev-box 2026-08-02.
# a test node 2026-08-02.
#
# `Access-Control-Allow-Origin *` is also removed: paired with a proxy that
# injects credentials it let any web page a user visited drive this RPC.
@@ -122,7 +122,7 @@ impl BootReconciler {
// A failed repair can involve registry pulls and full
// image builds; retrying every 30s hammered unreachable
// registries ~174×/image/day on an offline node
// (archy-x250-dev log sweep, 2026-07-22). Back off
// (a test node log sweep, 2026-07-22). Back off
// exponentially while rounds keep failing — 30s doubling
// to a 1h cap — and reset the moment a round is clean.
failure_rounds = if failures.is_empty() {
+2 -2
View File
@@ -40,7 +40,7 @@ const COMPANION_PULL_TIMEOUT: Duration = Duration::from_secs(300);
/// After a failed repair (image build/pull included), leave the companion
/// alone for this long. Without it, a node under IO pressure retried a 900s
/// image build every 30s reconcile tick — each build pegging the disk that
/// made the probes fail in the first place (live-diagnosed on zaza-optiplex
/// made the probes fail in the first place (live-diagnosed on a test node
/// 2026-07-28: load 50, podman scans starved, apps page stuck).
const REPAIR_COOLDOWN: Duration = Duration::from_secs(600);
@@ -219,7 +219,7 @@ pub async fn install_one(spec: &CompanionSpec) -> Result<()> {
// `ensure_image_present` rebuilds in place under the same tag, so the unit
// body is byte-identical, `write_if_changed` reports no change, and
// `enable_now` is a no-op on a running service — the container keeps the
// old layers indefinitely. That is exactly how archi-dev-box kept serving
// old layers indefinitely. That is exactly how a test node kept serving
// the LND, FIPS, Electrs and Guardian screens on 0.0.0.0 after v1.7.123
// rebuilt every one of those images to bind loopback: the images were
// correct on disk and the running containers were three days old
@@ -292,7 +292,7 @@ async fn chown_for_rootless_container(uid_gid: &str, path: &str) -> Result<()> {
// the subuid range first: `sudo chown 999` writes literal host uid 999,
// which maps to nobody inside the userns — the app then can't open its
// own files while the chown reported success (botfights SQLITE_CANTOPEN
// crash-loop, framework-pt 2026-08-06). Container uid N (N>=1) lives at
// crash-loop, a test node 2026-08-06). Container uid N (N>=1) lives at
// subuid_base + N - 1; the fleet provisions base 100000. uid 0 and
// already-mapped ids (>=100000) pass through untouched.
let host_uid_gid = if uid > 0 && uid < 100_000 {
@@ -2035,7 +2035,7 @@ impl ProdContainerOrchestrator {
// The marker says "removed", but the container can still be
// RUNNING: a Quadlet unit is owned by systemd, which starts it
// on boot entirely independently of this reconciler. On
// archi-dev-box (2026-08-02) `bitcoin-ui` sat in this exact
// a test node (2026-08-02) `bitcoin-ui` sat in this exact
// state — marker set, `archy-bitcoin-ui.service` active, port
// 8334 published — and so it never received the /bitcoin-rpc/
// auth_request gate that a05956c4 shipped INSIDE the binary.
@@ -3423,7 +3423,7 @@ impl ProdContainerOrchestrator {
// Mark the app so the drift check below recreates it even though
// it is restart-sensitive. Without this the unit is rewritten but
// never restarted, and the gateway keeps serving the compromised
// credential indefinitely (observed on archi-dev-box 2026-08-01).
// credential indefinitely (observed on a test node 2026-08-01).
self.credential_rotated
.lock()
.await
@@ -5430,7 +5430,7 @@ app:
/// holding the old value, so the rotation must flag the app for recreate.
/// Without the flag the drift check skips it as restart-sensitive and the
/// gateway keeps serving the published default forever — observed on
/// archi-dev-box 2026-08-01 before this was wired up.
/// a test node 2026-08-01 before this was wired up.
#[tokio::test]
async fn rotating_a_compromised_credential_flags_the_app_for_recreate() {
let rt = Arc::new(MockRuntime::default());
@@ -6238,7 +6238,7 @@ app:
#[tokio::test]
async fn reconcile_rewrites_security_config_for_a_user_uninstalled_but_running_app() {
// Regression, archi-dev-box 2026-08-02: `bitcoin-ui` carried a durable
// Regression, a test node 2026-08-02: `bitcoin-ui` carried a durable
// user-uninstalled marker WHILE systemd/Quadlet kept archy-bitcoin-ui
// running and publishing :8334. Reconcile returned on the marker before
// reaching the pre-start hook, so the /bitcoin-rpc/ auth_request gate