Skip to content

smaug ready for its drives: build-the-nas, stacks/media, and the rule ports ADR-0040 got wrong - #478

Merged
Gerrrt merged 3 commits into
mainfrom
gerrrt/smaug-ready-for-drives
Sep 16, 2026
Merged

Gerrrt merged 3 commits into
mainfrom
gerrrt/smaug-ready-for-drives

Conversation

@Gerrrt

@Gerrrt Gerrrt commented Sep 16, 2026 •

Copy link
Copy Markdown
Owner

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 and
assumed administration over SSH. smaug runs TrueNAS, administered over
HTTPS. 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:

Dataset Holds Backed up
hoard/media the library no
hoard/apps Jellyfin's database and config yes

ADR-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

  • §0.6 tests that Winterfell still CANNOT reach 443. A success there would
    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.
  • §6 puts ADR-0040's reopen condition where it belongs: Quick Sync reaching
    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_counts required rather than the
author remembering.

make validate passes; check_docs green at 10 assertions.

Refs #413 #138 #223

🤖 Generated with Claude Code


Since opened: the pool is erebor, and stacks/media exists

Pool renamed hoard → erebor. 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. Renamed while it costs a find-and-replace rather than an export and
an import.

stacks/media is authored — the thing §6 deploys. One service, because
ADR-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:

  • /health answers 200 with a body reading Degraded on a fresh
    instance. A check requiring Healthy would mark the container unhealthy from
    first boot until somebody finished the setup wizard — on
    restart: unless-stopped, a restart loop. The check keys on the status
    code and says in the file that it ignores the body on purpose.
  • curl is present; wget, busybox and nc are not — which decides a
    healthcheck this repo otherwise writes with busybox wget.

Also: the image declares no user and would run as root; /config and /cache
are mode 777, which is what lets it run as 65534 with no chown sidecar; and
65 MiB idle RSS is what the 2 GiB ceiling is a ceiling over.

The digest came from scripts/pin-digests.sh via the registry API. That script
rewrites image references in comments too, so the verification command uses
a placeholder — the same reason stacks/sensitive writes <caddy image>.

Mechanics

docs/architecture.md gains the host-and-stack row check_host_stack_table
requires, marked not built yet — true of both the stack and the pool, and what
keeps that assertion on its planned branch while smaug is absent from
network.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.

Gerrrt and others added 3 commits September 16, 2026 14:15
…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>
@Gerrrt Gerrrt changed the title docs(runbook): build-the-nas, and the rule ports ADR-0040 got wrong (#413) smaug ready for its drives: build-the-nas, stacks/media, and the rule ports ADR-0040 got wrong Sep 16, 2026
@Gerrrt
Gerrrt merged commit 5bf616e into main Sep 16, 2026
3 checks passed
@Gerrrt
Gerrrt deleted the gerrrt/smaug-ready-for-drives branch September 16, 2026 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant