feat(albok): personal/inbox wing on nh3-albok + /srv/nemi/inbox capture root on nh3-dev (unit 4.4 slice C, gate 2)
Prime ruled albok subsumes note intake (1530). The wing is like personal/notes (albok-personal 1511, not service-restricted); health reads 7 wings ready. Nemi's token was re-minted with read+write on the new wing and vaulted over albok/token-nemi. /srv/nemi/inbox is lkraven:nemi-drop 2770 with a default ACL, plus u:lkraven:rx on /srv/nemi, so Nemi reaches it from lkraven's user manager, whose groups predate nemi-drop. Both paths are verified by the playbook.
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# nh3-albok: the personal/inbox wing (unit 4.4 slice C's capture target; albok-dev 2026-10-13, after Prime's 1530 ruling
|
||||
# that albok subsumes library/note intake). Like personal/notes: building personal, default_group albok-personal (1511),
|
||||
# not service-restricted. Run between two Nemi walks (albok-nemi.timer on nh3-dev fires hourly at ~:01).
|
||||
# scripts/elway infra-ops@10.100.50.44 --playbook playbooks/albok-personal-inbox.yaml
|
||||
steps:
|
||||
- name: Back up the live config
|
||||
sudo: true
|
||||
shell: cp -p /srv/albok/etc/albok.yaml /srv/albok/etc/albok.yaml.pre-inbox
|
||||
creates: /srv/albok/etc/albok.yaml.pre-inbox
|
||||
- name: Add wing personal/inbox after personal/notes
|
||||
sudo: true
|
||||
shell: |
|
||||
python3 - <<'PY'
|
||||
import os, grp
|
||||
p = "/srv/albok/etc/albok.yaml"; s = open(p).read()
|
||||
if " - id: inbox" in s:
|
||||
print("already present"); raise SystemExit(0)
|
||||
old = " wings:\n - id: notes\n"
|
||||
assert s.count(old) == 1, s.count(old)
|
||||
s = s.replace(old, old + " - id: inbox # unit 4.4 capture wing (Nemi's drop-box /srv/nemi/inbox on nh3-dev); like notes (2026-10-13)\n")
|
||||
t = p + ".tmp"
|
||||
fd = os.open(t, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o640)
|
||||
with os.fdopen(fd, "w") as f: f.write(s)
|
||||
os.chown(t, 0, grp.getgrnam("albok").gr_gid); os.replace(t, p); print("edited")
|
||||
PY
|
||||
- name: Restart the service (config is read at start) and wait for health
|
||||
sudo: true
|
||||
shell: |
|
||||
docker restart albok-service >/dev/null
|
||||
for i in $(seq 1 60); do
|
||||
h=$(curl -s -m 3 http://127.0.0.1:8392/health) && echo "$h" | grep -q '"status":"ok"' && break; sleep 2
|
||||
done
|
||||
echo "$h" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('status'), d.get('wings'), d.get('leaks'))"
|
||||
verify:
|
||||
- name: Seven wings ready, none degraded
|
||||
shell: curl -s -m 5 http://127.0.0.1:8392/health | python3 -c "import json,sys; w=json.load(sys.stdin)['wings']; print(w); assert w['ready']==7 and w['degraded']==0 and w['locked']==0"
|
||||
changed_when: "false"
|
||||
- name: The wing's store dir carries the personal group
|
||||
sudo: true
|
||||
shell: stat -c '%A %U:%G %n' /srv/albok/store/personal/inbox* | head -3
|
||||
changed_when: "false"
|
||||
@@ -0,0 +1,38 @@
|
||||
# nh3-dev: /srv/nemi/inbox, the capture root Nemi walks into albok's personal/inbox wing (unit 4.4 slice C; albok-dev
|
||||
# 2026-10-13 after Prime's 1530 intake ruling). People and agents drop markdown here; Nemi ingests each file once
|
||||
# (capture mode never tombstones on absence, so a walked file may be moved away).
|
||||
# scripts/elway infra-ops@10.100.10.50 --playbook playbooks/nh3-dev-nemi-inbox.yaml
|
||||
# Writers: group nemi-drop (lkraven, infra-ops). Nemi runs as lkraven from the user manager, whose groups were fixed
|
||||
# at its start, so lkraven's access does not depend on the new group: the dir is lkraven-owned and a DEFAULT ACL gives
|
||||
# lkraven and nemi-drop rw on everything created inside, whoever drops it and whatever their umask.
|
||||
steps:
|
||||
- name: Group nemi-drop with lkraven and infra-ops
|
||||
sudo: true
|
||||
shell: |
|
||||
getent group nemi-drop >/dev/null || groupadd nemi-drop
|
||||
usermod -aG nemi-drop lkraven; usermod -aG nemi-drop infra-ops
|
||||
getent group nemi-drop
|
||||
- name: /srv/nemi (root:nemi-drop 0750) and /srv/nemi/inbox (lkraven:nemi-drop 2770, default ACL)
|
||||
sudo: true
|
||||
shell: |
|
||||
install -d -o root -g nemi-drop -m 0750 /srv/nemi
|
||||
setfacl -m u:lkraven:rx /srv/nemi # traversal for lkraven's user manager, whose groups predate nemi-drop
|
||||
install -d -o lkraven -g nemi-drop -m 2770 /srv/nemi/inbox
|
||||
setfacl -m u:lkraven:rwx,g:nemi-drop:rwx /srv/nemi/inbox
|
||||
setfacl -d -m u::rwX,u:lkraven:rwX,g::rwX,g:nemi-drop:rwX,o::--- /srv/nemi/inbox
|
||||
getfacl -p /srv/nemi/inbox
|
||||
verify:
|
||||
- name: Nemi's own context (lkraven's systemd user manager, groups fixed at boot) can list the inbox
|
||||
shell: runuser -u lkraven -- env XDG_RUNTIME_DIR=/run/user/1000 systemd-run --user --wait --pipe -q ls -ld /srv/nemi/inbox
|
||||
sudo: true
|
||||
changed_when: "false"
|
||||
- name: A file dropped by infra-ops is readable and removable by lkraven
|
||||
sudo: true
|
||||
shell: |
|
||||
set -e
|
||||
f=/srv/nemi/inbox/.acl-probe-$$
|
||||
runuser -u infra-ops -g nemi-drop -- sh -c "umask 077; echo probe > $f"
|
||||
runuser -u lkraven -- cat "$f" >/dev/null
|
||||
runuser -u lkraven -- rm -f "$f"
|
||||
test ! -e "$f" && echo "infra-ops drop -> lkraven read+remove: ok"
|
||||
changed_when: "false"
|
||||
Reference in New Issue
Block a user