From e887c6a4bc50ec23d048c3a53a9ed1f312a0533f Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Sat, 3 Oct 2026 05:57:54 -0700 Subject: [PATCH] feat(albok-nemi): hourly Nemi walk timer on nh3-dev (albok-dev ask), with OnFailure hook --- services/albok-nemi/README.md | 38 ++++++++++++++++++++++++++ services/albok-nemi/albok-nemi.service | 22 +++++++++++++++ services/albok-nemi/albok-nemi.timer | 10 +++++++ 3 files changed, 70 insertions(+) create mode 100644 services/albok-nemi/README.md create mode 100644 services/albok-nemi/albok-nemi.service create mode 100644 services/albok-nemi/albok-nemi.timer diff --git a/services/albok-nemi/README.md b/services/albok-nemi/README.md new file mode 100644 index 0000000..b0f43c8 --- /dev/null +++ b/services/albok-nemi/README.md @@ -0,0 +1,38 @@ +# albok-nemi — hourly Nemi walk on nh3-dev + +**Nemi** is albok's ingest walker (vh/albok, `packages/albok-nemi`, owned by **albok-dev**). Each run walks the +three-wing manifest into albok-service on nh3-docker (`stacks/albok-service/`): +- `fleet/memory`: every repo's persistent memory; +- `fleet/stash`; +- `personal/agent-feedback`: Claude Code auto-memory, a restricted wing. + +The unit and timer here belong to infra-ops. Installed 2026-10-03 at albok-dev's request (thread +`01M40JGV4BEVXC9NQVTPX82BV8`), after albok-dev measured the steady state. + +| | | +|---|---| +| Units | `~/.config/systemd/user/albok-nemi.{service,timer}` (lkraven user manager, linger on), copies of this dir | +| Failure hook | `albok-nemi.service.d/10-onfailure-althing.conf`, which mails the infra-ops inbox (`services/althing-notify-failure`) | +| Runs | `uv run nemi run` in `/home/lkraven/development/albok` (albok-dev's working tree), `NEMI_CONFIG=~/.config/albok/nemi.yaml` (0600; holds `albok/token-nemi` + LiteLLM key `albok-nemi`) | +| Schedule | hourly, `RandomizedDelaySec=5min`, `Persistent=true`; `TimeoutStartSec=2h`; Nice 10, I/O priority 7 | +| Exit codes | 0 ok; **1** a wing failed (cause in the report); **2** albok-service unreachable, nothing walked. Both 1 and 2 trip OnFailure | +| Reports | `nemi status` prints the last one; files in `~/.local/state/albok-nemi/reports/` | + +**Cost (albok-dev, fleet instance, n=3):** steady-state walk 658 / 594 / 573 s, median 594 s (about 10 min, a +sixth of the interval). An unchanged object costs 0.042 s to submit, in batches of 200. The first full ingest +(11,404 objects, about 1 h 48 m plus tagging) was run by hand before the timer existed. + +## ⚠ Two walks must never overlap on one wing + +Each run is its own ingest run id, and a full walk tombstones whatever the other run did not send. The timer +gives this for free: it never starts a oneshot that is still active. **For a manual walk, use +`systemctl --user start albok-nemi.service`**, which joins or waits on the running one. Never run a bare +`uv run nemi run` alongside the timer. + +## Notes + +- It runs albok-dev's **working tree**, not a pinned release. A broken edit there fails the next walk, and + OnFailure mails infra-ops. Forward that to albok-dev. +- ⚠ **The reports grow without limit:** about 2.3 MB per run, roughly 55 MB a day. Retention is albok-dev's to add + in nemi (flagged 2026-10-03). Until then, watch nh3-dev's root disk. +- Uninstall: `systemctl --user disable --now albok-nemi.timer`, then remove the two units and the `.d` dir. diff --git a/services/albok-nemi/albok-nemi.service b/services/albok-nemi/albok-nemi.service new file mode 100644 index 0000000..80bfaa4 --- /dev/null +++ b/services/albok-nemi/albok-nemi.service @@ -0,0 +1,22 @@ +# Nemi: walks albok's three-wing manifest (fleet/memory, fleet/stash, personal/agent-feedback) into +# albok-service on nh3-docker. Code and config belong to albok-dev (vh/albok, packages/albok-nemi); +# this unit and its timer belong to infra-ops. Installed 2026-10-03 at albok-dev's request (thread +# 01M40JGV4BEVXC9NQVTPX82BV8). See README.md beside this file. +# +# ⚠ Two walks must never overlap on one wing (each run tombstones what the other did not send). A +# oneshot behind a timer gives that: the timer never starts the unit while it is active. Start a +# manual walk with `systemctl --user start albok-nemi.service`, not a bare `uv run nemi run`. +# Exit 1 = a wing failed (cause in the report), 2 = service unreachable; both trip OnFailure. +[Unit] +Description=Nemi walk: albok manifest -> albok-service (albok-dev) +Documentation=file:///home/lkraven/development/eshpfi-management/services/albok-nemi/README.md + +[Service] +Type=oneshot +WorkingDirectory=/home/lkraven/development/albok +Environment=NEMI_CONFIG=/home/lkraven/.config/albok/nemi.yaml +ExecStart=/home/lkraven/bin/uv run nemi run +TimeoutStartSec=2h +Nice=10 +IOSchedulingClass=best-effort +IOSchedulingPriority=7 diff --git a/services/albok-nemi/albok-nemi.timer b/services/albok-nemi/albok-nemi.timer new file mode 100644 index 0000000..c8c6fe0 --- /dev/null +++ b/services/albok-nemi/albok-nemi.timer @@ -0,0 +1,10 @@ +[Unit] +Description=Hourly Nemi walk (albok) + +[Timer] +OnCalendar=hourly +RandomizedDelaySec=5min +Persistent=true + +[Install] +WantedBy=timers.target