Repository navigation
smaug ready for its drives: build-the-nas, stacks/media, and the rule ports ADR-0040 got wrong - #478
Merged
Merged
Conversation
…413) The Exos drives arrive today. This is the runbook that makes their arrival a twenty-minute job instead of an evening of decisions, and it is split so that everything independent of the drives can be done before they turn up. Writing it found an error in ADR-0040, which I wrote yesterday. That ADR says the address, the three rules and the scrape direction "were never OS decisions". The ports in ADR-0016's Hicks rule were. That table reads 22,8096 — port 22 because ADR-0016 had chosen Ubuntu Server and assumed administration over SSH. smaug runs TrueNAS, which is administered over HTTPS, so the admin port is 443. Created as written, the rule would have left the NAS unreachable from a Hicks workstation in a way that presents as a firewall fault rather than a stale assumption. Port 22 stays on the Winterfell rule, which is prometheus pulling the metadata backup and not administration — and TrueNAS ships SSH disabled, so that rule is inert until the service is deliberately switched on. Neither ADR is edited, per ADR-0001 and ADR-0038's fourth decision. ADR-0040 gains a note saying which of its own claims is wrong and where the correction lives; ADR-0016's existing banner gains the port consequence, so a reader who arrives at that rule table is warned at the table rather than after creating it. The backup question #138 demanded a deliberate answer to is answered in §4, as a dataset split rather than a yes or a no. The media library is not backed up — ADR-0008 already ruled it replaceable and "annoying rather than catastrophic", and backing up 18 TB of re-downloadable files would spend the mirror's capacity contradicting a decision already taken. Jellyfin's database is, because watch history, resume positions and how the library is organised are the part that re-acquiring a series does not restore, and they are megabytes. hoard/media and hoard/apps carry that split into the layout so it cannot be drifted away from. Two checks in here exist because passing them is not the same as being right. §0.6 tests that Winterfell still CANNOT reach 443 — a success there would mean the rule is wider than it reads — and reads the #223 tripwire counter, which must still be zero because ADR-0016's terminal-outward property is what the whole segment rests on. §6 puts ADR-0040's reopen condition where it belongs: Quick Sync reaching a container, checked before the library exists, because a live P630 and a P630 a container can use are different claims and moving a populated library is a weekend. README goes from 24 runbooks to 25, which check_counts required rather than the author remembering. Refs #413 #138 #223 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A hoard is what Smaug sits on; Erebor is what he took and occupies. A pool is a container, so it takes the name of the container rather than of the contents — and erebor/media and erebor/apps read as places, where hoard/media read as a pile with a subdivision. It also keeps the Tolkien line the host's own name started, rather than landing on a generic ZFS-ism. Renamed now because the pool does not exist yet; after creation a zpool rename is an export, an import and a chance to mistype. Refs #413 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
) The stack build-the-nas.md §6 deploys, authored ahead of the pool the way stacks/sensitive was authored ahead of trinity. One service, because ADR-0016 builds Jellyfin alone and defers Plex against a test nobody has run. No reverse proxy, and that is the decision rather than an omission. The sensitive tier puts twelve services behind Caddy and publishes one port because it holds the data whose loss hurts; this tier is the other half of ADR-0008's bargain — "a failure of the media box costs a film night" — and its clients are televisions, which reach 8096 on their own broadcast domain with no firewall rule involved at all. A proxy would add a hop, a certificate every television would have to trust, and a second thing to be down. Everything non-obvious in the compose file was read off the pinned image on 2026-09-16 rather than out of upstream's documentation, and two of the five changed what got written: The image declares no user and would run as root. /config and /cache are 0:0 mode 777, which is what lets it run as 65534 with no chown sidecar — the dance this repository documents for Caddy is not needed here, and the compose file carries the stat command to re-check when the image moves. curl is present and wget, busybox and nc are not, which decides a healthcheck this repository otherwise writes with busybox wget. And /health answers 200 with a body reading "Degraded" on a fresh instance. A check requiring the body to read "Healthy" would therefore mark the container unhealthy from first boot until somebody finished the setup wizard — on restart: unless-stopped, a restart loop. So the check keys on the status code and says in the file that it is deliberately ignoring the body, because that looks like an oversight otherwise. 65 MiB idle RSS is what the 2g ceiling is a ceiling over. The library is mounted read-only: Jellyfin keeps metadata in /config, so it has no need to write there, and a media server on the segment with the game consoles should not be able to delete the thing it serves. That also carries #138's backup question into the layout rather than a policy sentence — jellyfin-config is backed up because re-acquiring a series does not restore which episode anyone was on; the library is not, because ADR-0008 already ruled it replaceable. The digest came from scripts/pin-digests.sh through the registry API, not from a guess. That script rewrites every image reference in the file, comments included, so the stat command above uses the <the jellyfin image> placeholder — the same reason stacks/sensitive writes <caddy image> in the same position. docs/architecture.md gains the host and stack mapping row check_host_stack_table requires; it is marked not built yet, which is true of both the stack and the pool and is what keeps that assertion on its planned branch while smaug is absent from network.md. Also here: the boot disk's self-test finished. Extended offline, completed without error, at lifetime hour 13,183 — the first ever logged on that drive. It took far longer than its own two-minute estimate because it advertises "Suspend Offline collection upon new command" and TrueNAS was live underneath it, which is worth writing down before somebody reads a slow self-test as a sick disk. Refs #413 #138 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Sep 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Exos drives arrive today. This is the runbook that makes their arrival a
twenty-minute job, split so everything independent of the drives can be done
before they turn up — §0 is the BIOS, the AMT check, the static address, the
Kea reservation and the three firewall rules.
It found an error in ADR-0040, which I wrote yesterday
That ADR claims the address, the three rules and the scrape direction "were
never OS decisions". The ports in ADR-0016's Hicks rule were.
That table reads
22,8096— port 22 because ADR-0016 chose Ubuntu Server andassumed administration over SSH.
smaugruns TrueNAS, administered overHTTPS. Created as written, the rule would have left the NAS unreachable
from a Hicks workstation in a way that presents as a firewall fault rather
than a stale assumption.
Corrected table is in §0.5:
443,8096. Port 22 stays on the Winterfell rule,which is prometheus pulling the metadata backup — and TrueNAS ships SSH
disabled, so that rule is inert until the service is deliberately enabled.
Neither ADR is edited, per ADR-0001 and ADR-0038's fourth decision.
ADR-0040 gains a note naming which of its own claims is wrong; ADR-0016's
existing banner gains the port consequence, so a reader arriving at that rule
table is warned at the table rather than after creating it.
The backup question #138 demanded, answered
Not a yes or a no — a dataset split, carried into the layout so it can't be
drifted away from:
hoard/mediahoard/appsADR-0008 already ruled the library replaceable and its loss "annoying rather
than catastrophic"; backing up 18 TB of re-downloadable files would spend the
mirror's capacity contradicting a decision already taken. But watch history,
resume positions and library organisation are what re-acquiring a series
doesn't restore — and they're megabytes.
Two checks that exist because passing isn't the same as being right
mean the rule is wider than it reads. It also reads the TerminalSegmentReachedInternalNetwork cannot fire — the firewall logs blocks only #223 tripwire
counter, which must still be zero — terminal-outward is what the whole
segment rests on.
a container, checked before the library exists. A live P630 and a P630 a
container can use are different claims, and moving a populated library is a
weekend.
Mechanics
README goes 24 → 25 runbooks, which
check_countsrequired rather than theauthor remembering.
make validatepasses;check_docsgreen at 10 assertions.Refs #413 #138 #223
🤖 Generated with Claude Code
Since opened: the pool is
erebor, andstacks/mediaexistsPool renamed
hoard→erebor. A hoard is what Smaug sits on; Erebor iswhat he took and occupies. A pool is a container, so it takes the name of the
container. Renamed while it costs a find-and-replace rather than an export and
an import.
stacks/mediais authored — the thing §6 deploys. One service, becauseADR-0016 builds Jellyfin alone and defers Plex against a test nobody has run.
No reverse proxy, deliberately
The sensitive tier puts twelve services behind Caddy and publishes one port
because it holds the data whose loss hurts. This tier is the other half of
ADR-0008's bargain — "a failure of the media box costs a film night" — and its
clients are televisions, which reach 8096 on their own broadcast domain with
no firewall rule involved at all. A proxy would add a hop, a certificate every
television must trust, and a second thing to be down.
Measured on the pinned image, not read from upstream docs
Two of the five findings changed what got written:
/healthanswers200with a body readingDegradedon a freshinstance. A check requiring
Healthywould mark the container unhealthy fromfirst boot until somebody finished the setup wizard — on
restart: unless-stopped, a restart loop. The check keys on the statuscode and says in the file that it ignores the body on purpose.
curlis present;wget,busyboxandncare not — which decides ahealthcheck this repo otherwise writes with busybox wget.
Also: the image declares no user and would run as root;
/configand/cacheare mode
777, which is what lets it run as65534with no chown sidecar; and65 MiB idle RSS is what the 2 GiB ceiling is a ceiling over.
The digest came from
scripts/pin-digests.shvia the registry API. That scriptrewrites image references in comments too, so the verification command uses
a placeholder — the same reason
stacks/sensitivewrites<caddy image>.Mechanics
docs/architecture.mdgains the host-and-stack rowcheck_host_stack_tablerequires, marked not built yet — true of both the stack and the pool, and what
keeps that assertion on its planned branch while
smaugis absent fromnetwork.md.The boot disk's self-test also finished: extended offline, completed without
error, at lifetime hour 13,183 — the first ever logged on that drive. It ran
far past its own two-minute estimate because it advertises Suspend Offline
collection upon new command and TrueNAS was live underneath it, which is worth
recording before somebody reads a slow self-test as a sick disk.