plex-server¶
The home server itself: Ubuntu 24.04 on a Dell OptiPlex 7050, hostname Plex, 192.168.5.15. SnapRAID (3 data + 1 parity) under mergerfs, ~36 docker containers, Immich, Plex/Jellyfin, the Garmin→Calendar scheduler.
Repo: not a repo — the working directory is /home/angel itself.
The notes for this machine are not in this vault. They live in an ICM system map at ~/Notes/map/ (its own git repo), because they document a live machine rather than a codebase: object cards for the nouns, process cards for the verbs, and a change-impact index.
Status¶
- 2026-09-08: storage hardening at v9 — 15 of 21 items done. Item 05 (off-box copy of photos + EmbeddedEra) is the only remaining permanent-loss risk. Items 15, 16B, 17 run unattended this week from
~/maintenance/.
Decisions¶
- Version history is a restic repo on the pool, not rsnapshot's tree in parity: 3.5M hardlinks rotating hourly can never be parity-protected (45k-file array, 500-deletion precheck limit); a few thousand immutable pack files can. Same repo replicates off-box unchanged. 2026-09-08.
- Server facts live in
~/Notes/map/cards, one home per fact; this vault keeps user/project context and links to them. Memory under~/.claude/projects/-home-angel/memory/stays for user and feedback facts only. - Root work goes through a scoped, revocable
/etc/sudoers.dgrant the human installs, then revokes — never blanket NOPASSWD. See~/Notes/map/processes/root-maintenance.md. - Long maintenance runs as root systemd one-shot timers writing markdown reports, not as agent sessions — zero tokens, survives a dropped SSH connection.
Gotchas¶
- History protection is "any one drive, from 2026-09-09 forward": the restic repo enters parity at the first 03:30 sync after each snapshot; pre-2026-09-08 history (rsnapshot, back to March) is still disk1-only; same-day writes are unprotected until 02:20/02:50/03:30; the NVMe case needs the restic password in the password manager. map/objects/storage/history-repo has the table.
sudoneeds a password and tool shells have no tty:sudofails silently in agent calls, and interactive commands likegh auth loginhang forever rather than erroring.- Claude Code's background-Bash memory supervisor kills long jobs here —
freereads ~300 MB because qbittorrent and page cache hold ~11 GB reclaimable. Run long things in the foreground or from cron. - Never a bare
docker compose up -d(thesambaservice has drifted from the livesamba-nascontainer) and never a baresnapraid sync(the guard + precheck exist to stop a mass delete reaching parity). - Read SMART history from
/var/lib/smartmontools/attrlog.*.csv— world-readable, no root, and it does not wake a sleeping disk. - Ponytail (v4.9.0):
/plugincommands must be typed at the Claude prompt; typed into bash they fail withNo such file or directory. Its hooks arenode-based and only load on a fresh session.
Open¶
-
erp-sandbox tokenprints a token but does not write it into~/.config/assistant/env.sandbox(its header says it does). Every sandbox reset leaves the assistant-sandbox with a dead token until someone pastes it. Makeerp-sandbox tokenrewrite the ERP_TOKEN_* lines (all five reuse one token today). - Kanboard project membership drift: the task migration (2026-09-13) made both people members of every project, so Yara can open Administration/Engineering/Finance/Production boards.
onboard kanboard-synconly ADDS members by department; make it also remove membership a person's departments do not grant (keep the assignee rule: a task can only be assigned to a member). Found 2026-09-14 while scoping the intake close-out picker, which now uses departments.yml instead of membership.
See ~/Notes/tasks.md — this section is now generated from the task register.
Log¶
- 2026-09-11: Listmonk added to the torrentvpn stack for the EmbeddedEra newsletter (
listmonk+listmonk-db, postgres:16-alpine) — LAN-only by design, never exposed to the internet:127.0.0.1:9000loopback only,list.lanvia NPM (host id 25) for admin access. Creds in~/.config/credentials/listmonk.txt(admin login, db password, and an API-user token forlist-syncscoped to just the "Engineering notes" list, id 3). Backup:docker-compose.yml.bak.20260911-listmonk. Site side (embeddedera-site-apple:functions/api/subscribe.ts,SubscribeBlock.astro, i18n) writes signups to R2subscribers/;~/.local/bin/list-sync(cron candidate, not yet installed — line printed for review, not added) pulls them in every 15 min and deletes the R2 object on success. Blocked on Angel: a Resend API key (or Workspace SMTP) before Listmonk can actually send the double opt-in confirmation — seeNotes/projects/growth-plan.md§1.2. - 2026-09-10: Server secrets imported into Vaultwarden (Bitwarden JSON import, 12 items, folder "Plex server"); import file shredded. Only copies of
~/.config/{tesla,restic,credentials}are now NVMe + the vault (vault data in docker-backup nightly). - 2026-09-10: Vaultwarden LIVE at https://vault.embeddedera.com — Cloudflare A record (DNS-only, 192.168.5.15), Let's Encrypt via DNS-01 (Cloudflare token stored in NPM), NPM proxy host → vaultwarden:80 (websockets, force SSL). First account angelgdo7@gmail.com; SIGNUPS_ALLOWED=false. NPM admin password was lost → new
~/.local/bin/npmpasshelper (needs sudo, data dir is root-owned); creds in~/.config/credentials/npm.txt. - 2026-09-10: Added Vaultwarden (self-hosted Bitwarden) to the torrentvpn stack —
vault.embeddedera.com, NPM-only, no host ports, data in~/torrentvpn/vaultwarden/data(nightly docker-backup). Chosen over Bitwarden cloud/1Password (free rule) and KeePassXC (no sync). Map cardmap/objects/containers/vaultwarden.md. Angel still has to do DNS + cert + first account. - 2026-09-10:
build-index.shno longer hard-codes/home/angel(the Mac's silent-data-loss finding) —$HOME, no-op elsewhere;bin/notes-syncis now the single implementation (dry-run + auto message merged in),~/.local/bin/notes-syncsymlinks to it; weekly prompt adopts delete-not-tick; item 17 removed from Open per that rule (closed clean 09-09). - 2026-09-09 22:10:
bin/notes-sync.cmdadded for Windows. Chose PATH-plus-setxover symlinks so Developer Mode is never required;restore.shstays Mac/Linux-only..gitattributesadded to keep*.cmdCRLF and the extensionlessbin/scripts LF. Not yet run onDESKTOP-1LK2GJK. - 2026-09-09 22:00: new-machine setup fixed.
notes-syncandpart-lookupexisted only on the Mac in~/.local/binand were never tracked, sorestore.shhanded every new machine rules it could not follow. Both are now vendored tobin/and symlinked in byrestore.sh(symlink, not copy, so a vault pull updates them); added a PATH check and split the mangled ponytail/i-have-adhdecho. Verified by runningrestore.shon the Mac. Windows symlink support still unresolved. - 2026-09-09 16:30:
notes-weeklyinstalled (Sun 19:30, Opus, branch + PR gate, usage-limit retry until 22:30). Deadline for the race-week override removal: after 09-14. - 2026-09-09 16:15: routes repo created (github.com/angelEmbeddedEra/routes, private) with both Sandling bike courses; both loaded on the Garmin (courses 512961452/512962555) and the Magene C606 V2. Sunday multisport RACE PRACTICE workout 1693043006 with per-section speed/cadence.
~/maintenance/output->map/reports/symlink;notes-nightlycron 23:55. Tonight 23:00 badblocks; Fri 08:00 dedupe. - 2026-09-09 11:00: parity drill PASSED. Found and fixed the precheck waking the parity disk via SMART (sdb sat at 55 °C for 2.5 h doing nothing); hd-idle cannot see SMART spin-ups.
- 2026-09-09: history repo is in parity (03:30 sync clean). False "SnapRAID FAILED" push at 23:00 was
maint-badblocks's guard matching its own subshell — fixed, alert renamed, installer re-dates timers. - 2026-09-08: restic 0.19.1 installed user-space; history repo initialised on the pool; nightly 02:50 + Sunday 05:30 jobs in angel's crontab (duplicate 02:20 precious-sync line removed). Initial backup done 17:03: 27 min, 90 G / 5,399 packs, restore drill PASS. Parity covers it from the 09-09 03:30 sync.
- 2026-09-08: built
~/Notes/map(15 object cards, 8 process cards); confirmed the WD idle3 fix latched; scheduled hardening items 15/16B/17; installed Obsidian and theicm-architectskill; linked these global rules. - 2026-09-14 Grafana landing pages:
ee-start(links only) is the org default,ee-home(System folder, headline stat from every report) for Administration, per-team homes viareports-syncHOME_BY_TEAM. Verified through the auth proxy as adiaz (→ ee-home) and yrosado (→ ee-sales, 403 on System/Quality). See grafana. - 2026-09-14 Close-out loop live: Review column + close-on-Done in all projects (onboard kanboard-sync), SOP-017 v1.1 published, task-verify every 5 min (first real pass: task 177), sop-tasks and intake write Verify: blocks, sop-audit check renamed closed-unverified, Waiting on you shows human checks. See kanboard.
- 2026-09-14 SOP-017 v1.2: every task needs assignee, due date, concept, Deliverables + Verify. 86 unowned tasks assigned to department defaults (Sales/Purchasing → Yara, rest → Angel);
tasks-deliverables(Haiku, ~$0.004/task) backfills the blocks; audit checks open-unassigned / open-no-due / open-no-deliverables now read Kanboard over the API. - 2026-09-14 Intake gained New task (AI scrub to SOP-017 form) and Idea (Ideas project, no due/deliverables). Deliverables backfilled on 121 tasks; 30-day default due on 122. Open: tasks 72 and 128 still lack deliverables (Haiku could not parse them, write by hand).
- 2026-09-14 Resend quota blown (200 emails: Kanboard per-event mail during the bulk assign). Kanboard email OFF for all;
_mailbudget.py(60/day) now fronts tasks-digest, tasks-notify and the assistant mailer;tasks-notifyhourly batched per person. SOP-017 v1.4. Books queue no longer shows intake tasks/ideas (intake_kind filter). - 2026-09-14 "Waiting on you" moved from home.embeddedera.com to the notebook front page (notebook-build waiting_section: proposals, drafted site notes, pending human checks; notebook-publish also watches those two sources). Home page API kept; approve/reject buttons retired — decide by editing the Status line or
publish-note. - 2026-09-14 Opening stock count: intake "Stock count" (barcode → OCR → Haiku) + /stock queue confirming into the ERP; SOP-023 published, SOP-005 v1.6 cross-refs it. Sandbox token note:
erp-sandbox tokenonly prints; env.sandbox ERP_TOKEN_* must be pasted by hand (to-do below). - 2026-09-14 Stock queue complete: create-part-and-add-stock, New bin, direct Zebra printing (192.168.5.16:9100), label QR = ERP page URL, INVENTREE_BASE_URL fixed to the public host. Resistor row #184 ready for one press.
- 2026-09-14 First real stock count (22 parts, 19 stock items). Faults fixed: task-verify erp: check used the public host (Access login → cannot tell) → local URL; create-part left orphans when the manufacturer step 403d → reuse same-name part, manufacturer/supplier best-effort, company POST falls back to the owner token; Verify line now follows the chosen part. Deleted duplicate parts EE-C-0156/0161/0168 (no stock). Labels tool live; camera scan in progress.