From 70b7281182111866a0e5db0a04675c0f4ddc0307 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Fri, 9 Oct 2026 22:45:52 -0700 Subject: [PATCH] ops(albok): vh joins every albok read group; macOS withdrawal-test run staged Prime, 2026-10-09: "vh gets albok-everything". playbooks/nh3-albok-vh-viewer.yaml joins vh to albok-read, albok-personal and albok-feedback on nh3-albok and authorizes his four Macs' public keys for vh; verified at a fresh login that every wing's .browse/ lists and reads. The withdrawal harness gains a macOS driver (run-mac.sh: every mountable FUSE backend, a read-only smoke of the real wings, results copied back), env overrides for a non-container client, and summarize.py. Sanity-checked as vh from the Linux container before staging. --- persistent-memory.md | 4 +- playbooks/nh3-albok-vh-viewer.yaml | 47 +++++++++++ .../oneoff/albok-browse-withdrawal/README.md | 10 +++ .../albok-browse-withdrawal/manifest-mac.json | 1 + .../oneoff/albok-browse-withdrawal/run-mac.sh | 79 +++++++++++++++++++ .../albok-browse-withdrawal/run-trials.py | 18 +++-- .../albok-browse-withdrawal/setup-replica.py | 4 +- .../albok-browse-withdrawal/summarize.py | 41 ++++++++++ stacks/albok-service/README.md | 11 +-- 9 files changed, 202 insertions(+), 13 deletions(-) create mode 100644 playbooks/nh3-albok-vh-viewer.yaml create mode 100644 scripts/oneoff/albok-browse-withdrawal/manifest-mac.json create mode 100644 scripts/oneoff/albok-browse-withdrawal/run-mac.sh create mode 100644 scripts/oneoff/albok-browse-withdrawal/summarize.py diff --git a/persistent-memory.md b/persistent-memory.md index b396aed..dc63302 100644 --- a/persistent-memory.md +++ b/persistent-memory.md @@ -125,7 +125,7 @@ _As of 2026-10-09 ~1955 PT. The newest subsection is first; older subsections ca - **Watching: Worldtree memory gate.** 10-09 FAILED on filing/user (9, 11, 8 of 12; median 0.75 < 0.80), the first fail that is not #416. Bootstrap from 27 prior runs puts P(median ≤ 9) ≈ 0.06 per batch, and the misses are the habitual fixtures, so it is not called a regression yet. But per-run means drifted 10.6 → 10.0 → 9.7 → 9.3 since the 10-08 fv-ml1 patch (writer + judge = flash-next on GPU 2). If the 10-10 batch also fails filing, infra-hermes frames it as a possible regression after that patch and sends it to me; then investigate flash-next. ⚠ worldtree-dev has not read mail in 6+ days, so the reports dead-end there (Prime's call, below). - **Watching: jekyll on `sec-reasoning` (cyberprev, GPU 0)** since ~1435 10-06 (Prime moved it off gen-large). sec holds 337k KV tokens. jekyll's ~180k context plus a long sec prompt (up to 192k) can overflow it, as gen-large did (preemptions; decode down to 2–16 tok/s). jekyll's context grows ~1k/call toward the 262k ceiling. It runs on the shared all-agents-local key; a key of its own would make its traffic attributable. - **Waiting on Prime:** - - albok `.browse/` share: the sshfs withdrawal test PASSED (Linux client). Before a share: which wings his nh3-albok user (`vh`) gets (`albok-read` = fleet + library, `albok-personal` = notes; `albok-feedback` stays default-deny), and, if the workstation is macOS, a re-run of `scripts/oneoff/albok-browse-withdrawal/` on it. + - albok `.browse/` share: vh holds every albok read group since 10-09 2244 (Prime: "vh gets albok-everything"; four Mac keys authorized for vh). The macOS run of the withdrawal test is staged on nh3-albok and waits on Prime running the one-liner in `scripts/oneoff/albok-browse-withdrawal/README.md`; then read `~vh/albok-browse-test/results/`, report to albok-dev, remove the replica. - Who sees Worldtree gate failures while worldtree-dev is not reading mail (Prime, Miranda, or keep waiting). - Rotate the fv-ml1 BMC password? It was printed into a local session transcript on 10-08 (never left nh3-dev); infra-ops leans no. - albok's 200-object load check, 2.01× against a 2× bar (albok-dev: the ruling is the operator's). @@ -186,6 +186,8 @@ Every vLLM seat on a shared card (GPU 0, GPU 1) has byte-pinned KV (`--kv-cache- ## Recent decisions +- `[2026-10-09]` **vh gets every albok read group (Prime 2244: "vh gets albok-everything")**: albok-read, albok-personal and albok-feedback (the restricted wing's default-deny ends for vh only), plus his four Macs' keys on vh (`playbooks/nh3-albok-vh-viewer.yaml`). No net new root path: those Macs already reach root there via lkraven@nh3-dev and the infra-ops key. Later restricted groups (1513+) are NOT included. +- `[2026-10-09]` **nh3-dev: orphaned svos pytest killed 2242** (14.4 GB RSS, +2.3 GB/h, swap 100%, Beszel 90% alert; SIGTERM ignored, SIGKILL; used 25.4 → 11.3 GB). highseat-dev's retry-loop test with an instant fake sleep; they added pytest-timeout 300 s and a 50-attempt bound. - `[2026-10-09]` **Post-clear checks closed (2015–2025 PT):** albok `.browse/` sshfs pathname-withdrawal test PASSED (replica on nh3-albok, Linux sshfs 3.7.3 client in a container; fresh open ENOENT 5/5 default and 5/5 hour-long caches; null + positive controls ok; failed rename = path served; reported to albok-dev) → `scripts/oneoff/albok-browse-withdrawal/README.md`. fv-ml1 plateau (Beszel 120m, 42 h after the 0034 10-08 restart): GPU 0 flat at 5,606 MiB free (~3.9 GB at parakeet's cap), GPU 1 median 9,459 free (~3.3 GB at intern-decision's 32k peak), no creep; GPU 2 643 MiB free = flash-next util 0.96, single tenant, by design. nh3-nas `/volume1` 71% (79% on 10-07). The "sfsrv-ana pre-pbs4" item was a mislabel: the pre-pbs4 snapshots were pfi-pve VM 100 and nh3-pve VM 105, dropped by infra-hermes 10-05 and read gone 10-09. - `[2026-10-09]` **albok `library` building (fiction, nonfiction) live for unit 4.5; Nemi + albok-dev re-minted with library grants (token grants are immutable), old tokens revoked 1555 by albok-dev.** → `stacks/albok-service/README.md` - `[2026-10-09]` **Homepage: The High Seat's description no longer says "SVOS" (Prime: author it yourself); SVOS's now says "Internal network + mesh".** diff --git a/playbooks/nh3-albok-vh-viewer.yaml b/playbooks/nh3-albok-vh-viewer.yaml new file mode 100644 index 0000000..6f4cce6 --- /dev/null +++ b/playbooks/nh3-albok-vh-viewer.yaml @@ -0,0 +1,47 @@ +# vh on nh3-albok as the operator's albok viewer (Prime, 2026-10-09: "vh gets albok-everything"). +# scripts/elway infra-ops@10.100.50.44 --playbook playbooks/nh3-albok-vh-viewer.yaml --var keys_file= +# Idempotent. Joins vh to every albok read group that exists (albok-read 1510 = fleet + library, +# albok-personal 1511 = personal/notes, albok-feedback 1512 = personal/agent-feedback, which had been +# default-deny until this ruling) and authorizes the operator's workstation public keys for vh, so a +# workstation can sshfs-mount a wing's .browse/ (see stacks/albok-service/README.md). +# A later restricted group (1513+, e.g. the vault wing) is NOT included: add it here deliberately. +# Group membership is read at login, so it applies to new SSH sessions only. +vars: + keys_file: "" + groups: albok-read,albok-personal,albok-feedback + +steps: + - name: vh joins {{ groups }} + sudo: true + shell: usermod -aG {{ groups }} vh + when: "! (for g in $(echo {{ groups }} | tr , ' '); do id -nG vh | tr ' ' '\\n' | grep -qx \"$g\" || exit 1; done)" + + - name: stage the workstation public keys + upload: + src: "{{ keys_file }}" + dest: /tmp/vh-workstation-keys.pub + mode: "0644" + + - name: append each key to vh's authorized_keys if absent + sudo: true + shell: | + set -e + added=0 + while IFS= read -r k; do + [ -n "$k" ] || continue + grep -qxF "$k" /home/vh/.ssh/authorized_keys || { printf '%s\n' "$k" >> /home/vh/.ssh/authorized_keys; added=$((added+1)); } + done < /tmp/vh-workstation-keys.pub + rm -f /tmp/vh-workstation-keys.pub + echo "added $added" + +verify: + - name: vh holds every group + shell: | + for g in $(echo {{ groups }} | tr , ' '); do + id -nG vh | tr ' ' '\n' | grep -qx "$g" || { echo "missing $g"; exit 1; } + done + changed_when: "false" + - name: authorized_keys still vh-owned and 600 + sudo: true + shell: test "$(stat -c '%U %a' /home/vh/.ssh/authorized_keys)" = "vh 600" + changed_when: "false" diff --git a/scripts/oneoff/albok-browse-withdrawal/README.md b/scripts/oneoff/albok-browse-withdrawal/README.md index a39b056..fac77e8 100644 --- a/scripts/oneoff/albok-browse-withdrawal/README.md +++ b/scripts/oneoff/albok-browse-withdrawal/README.md @@ -50,6 +50,16 @@ the server in the clean state (`.browse/` present, no `.browse.withheld`). - **Failed rename:** the path remains and is served. The service cannot deny opens it could not withdraw; its `BROWSE_WITHHELD` marker only stops publication. +## macOS run (staged 2026-10-09 2245, not yet run) + +`run-mac.sh` runs the same trials from the operator's Mac, as `vh`, against a vh-owned replica at +`~vh/albok-browse-test/wing` (`manifest-mac.json`). It tries every FUSE backend the Mac can mount with +(the default, plus `backend=smb` / `backend=fskit` where fuse-t or macFUSE offers them), smoke-tests every +real wing's view as vh (counts only), and copies its results to `~vh/albok-browse-test/results/`. The vh +path was sanity-checked first from the Linux container (N=1 per condition, all four as expected). + + mkdir -p ~/albok-browse-test && cd ~/albok-browse-test && scp 'vh@10.100.50.44:albok-browse-test/harness/*' . && zsh run-mac.sh + ## Limits - **Proven for the Linux kernel FUSE client only.** A macOS workstation runs a different FUSE diff --git a/scripts/oneoff/albok-browse-withdrawal/manifest-mac.json b/scripts/oneoff/albok-browse-withdrawal/manifest-mac.json new file mode 100644 index 0000000..936e729 --- /dev/null +++ b/scripts/oneoff/albok-browse-withdrawal/manifest-mac.json @@ -0,0 +1 @@ +{"root": "/home/vh/albok-browse-test/wing", "size": 1048576, "objects": [{"i": 0, "id": "0b186b727dfd4d3e8b15ed1899609a8e", "name": "doc00.md", "size": 1048576, "sha256": "991c44b0a23fdcb688d85003689269d8bd5dfeadb9c73b5e0ed615fd77502462"}, {"i": 1, "id": "6a4f081794514e2f809139a5c5916227", "name": "doc01.md", "size": 1048576, "sha256": "1b4e92f8b2a53c95cbb5f9016d950b627cfc45763c4c0e1f27117abb71eb2bfb"}, {"i": 2, "id": "bf936b6ae3e5492b9c90ed272fb63b0b", "name": "doc02.md", "size": 1048576, "sha256": "f2828ebf25ca22dfb3ce7c17a034c9767a0a3498127c34ff32cbba98e584d92d"}, {"i": 3, "id": "58a4ff762b3d409c8cdcf2223d1541f2", "name": "doc03.md", "size": 1048576, "sha256": "52e4fb0a553a3427987da614cfa4b2004a974686714deed420a939dff88fb008"}, {"i": 4, "id": "f700a02fbabf439c991504f037ac3b97", "name": "doc04.md", "size": 1048576, "sha256": "f97af609857d0c278a37396aa406b3b2b09c8d433ddd2d49c3fda3d19b7ea5bb"}, {"i": 5, "id": "145b2686c9194b3fb2eca6ff0a314b9a", "name": "doc05.md", "size": 1048576, "sha256": "12fc5f21816d944be3b3d0fe43e47078beab2611b28dc72906d1027c4eb4a1fc"}, {"i": 6, "id": "f13ea48b50424093a943b7737ed55b1d", "name": "doc06.md", "size": 1048576, "sha256": "e41870bcfbd3a966645fb7a00cb0c501fa30fd710855d306e414cfe067fba4ca"}, {"i": 7, "id": "3f52a86e955241849820ce94a7354e02", "name": "doc07.md", "size": 1048576, "sha256": "30f7fe9109db64a5ec459f2dd3fd0a2683b0a833e3a4ff693d5c8cfb1c11bca7"}, {"i": 8, "id": "c9e8e31f1a2f4d2885248014afbfef32", "name": "doc08.md", "size": 1048576, "sha256": "4781a00a554b50ca0a9b67e3db52891adf12fd8738b7c320376b84bfadb3af86"}, {"i": 9, "id": "93a48d4477a148e89736d035ecf05e34", "name": "doc09.md", "size": 1048576, "sha256": "6792929268825555ee662a272832c7e8234e39f6ca8719e23403a234d7edf2d9"}, {"i": 10, "id": "bf39d375e78d48d6bc06a7621fe922b8", "name": "doc10.md", "size": 1048576, "sha256": "c8fce9ee9a620a8565daa79bde4fa245381dede67f13ceadf3b833c404a9b3fe"}, {"i": 11, "id": "c1b3bbd5d6db4d76a7387e027698d050", "name": "doc11.md", "size": 1048576, "sha256": "c7374cf2e2b9ef38004c963015e7e383caafad451fc2f750fcbe1bc9fc50c5fd"}, {"i": 12, "id": "3d21f86d4a2942ef9de64a7d2c28f2bc", "name": "doc12.md", "size": 1048576, "sha256": "36a30ce983971cf8e625a369be3d2a2ce6d26b0966f0a06160842a5a893029f6"}, {"i": 13, "id": "1e9537fa14d340d69bd2a5965579abfd", "name": "doc13.md", "size": 1048576, "sha256": "b148a8b7b9977ac47b2eab1850fd99e3c6760011751c55bdffb5a60a335d2ba3"}, {"i": 14, "id": "ca3584fe4cbb40198fe036c1434496fc", "name": "doc14.md", "size": 1048576, "sha256": "57003d5b5a95fa8c9583679a39f5d494c47afe9cb4ff9d5a720d3312889ff20a"}, {"i": 15, "id": "764e7654a6934fe1a33e6c9c1b7abe0a", "name": "doc15.md", "size": 1048576, "sha256": "25f60761717bab66327b3cf565347b3316e6af02eb1133cf8aaad95bff8fcd2c"}, {"i": 16, "id": "92769920b116452c8c50c5b36cf7fc50", "name": "doc16.md", "size": 1048576, "sha256": "6ef56f27a029b3885b784534c130139bfd6d09a9b72e5dd93ac17e0fdc2dbba9"}, {"i": 17, "id": "a8f755d3533447af907e4931f9049c0d", "name": "doc17.md", "size": 1048576, "sha256": "64e4ca357dd705a95f678ffd7167dd0ffb90d072655857859b14fc5f0796acbe"}, {"i": 18, "id": "dadb52ad55c74e109966a3a5ed5a85af", "name": "doc18.md", "size": 1048576, "sha256": "2e2355a6f3be20d1977d47e7cacc86b2206c8fc935a14290c428c8fe543cb1a0"}, {"i": 19, "id": "02dd7a34401347adb5e1bd06f31b7ed6", "name": "doc19.md", "size": 1048576, "sha256": "42ab5d93214a48efc85ea9147166b689a56032f9af68a4f1e68b24332ad944e7"}, {"i": 20, "id": "e68a6b6f49574ec78a28b7b8f7b5284f", "name": "doc20.md", "size": 1048576, "sha256": "69349028e5f774cdf4bed4225f4c23f7fea0c50fb807de1264c2f4f2cbce28b7"}, {"i": 21, "id": "a61ec887f1fc48a49ad43dab4260605a", "name": "doc21.md", "size": 1048576, "sha256": "9eba85a5c2f9b98c8ddbacc88ec6a4a97cb906c39b26ebaec58c8737e3bd5824"}, {"i": 22, "id": "29909485c4724e00bd44aba69e63e2e2", "name": "doc22.md", "size": 1048576, "sha256": "e7f0ad23f29bb648cd38cd22e16ca1fcf9d3e4b3f3518685be253db8dbadccfe"}, {"i": 23, "id": "d94a9936a398471c9a16e2c271d5179c", "name": "doc23.md", "size": 1048576, "sha256": "9ebaf3bb9291984801837b4aaf8ea0c5d35c3616e1734549a2761223d5d4eca0"}, {"i": 24, "id": "64efc998d7b54eaca77f9cb307986090", "name": "doc24.md", "size": 1048576, "sha256": "4c6acfd64fc9a2100f509799f7b63f5b307a95ccf17810837a2820e47075c0f6"}, {"i": 25, "id": "1ce5b1b37630450784071607514bdf12", "name": "doc25.md", "size": 1048576, "sha256": "90e238003331122f1d2667fd26d0b35bfb95a20de0cb2d1166516d15d7b666c4"}, {"i": 26, "id": "48f317bfa1db44188a30f67f31cc1bda", "name": "doc26.md", "size": 1048576, "sha256": "38d49e2fcff7563f4031495813b88b7623dc16780d055a1ba0cd00efc05e025a"}, {"i": 27, "id": "4c439d0cc12043b787098adda1459815", "name": "doc27.md", "size": 1048576, "sha256": "110131d7518f4dd93a8a2b59c30e30d3bca376af3a2a9c21f2270f76429cfaf9"}, {"i": 28, "id": "6412cea6e35044428695f551be4f13bc", "name": "doc28.md", "size": 1048576, "sha256": "d490bbf1671fee6b60787447f3165dcedfb6657cbb14cf40ed22e5ea44dd4b47"}, {"i": 29, "id": "c616b3c38b3442e784016b8efccfec1a", "name": "doc29.md", "size": 1048576, "sha256": "2f3f0cef33c0166f07ccc6c5061e2d4ada1cf3b3606975f8bc297cba278c532c"}, {"i": 30, "id": "139b694fae904738a3d4959c3fb810b9", "name": "doc30.md", "size": 1048576, "sha256": "9d179960ba43671ddf34b6b99255b56097efa72b35164b8fca906a75d26011d8"}, {"i": 31, "id": "8f4a471a82fa4b0a9399dd79a3cda1af", "name": "doc31.md", "size": 1048576, "sha256": "6870e9365c4e6f43fd902274381f984d69a7947f738ce62790f6999eb1953654"}, {"i": 32, "id": "ec50dea464ba4fcfb75857cb09f08a0b", "name": "doc32.md", "size": 1048576, "sha256": "78761c234db440af8e7cfacab30f7bff94597ac139e477f1bd42c81608932a5c"}, {"i": 33, "id": "8d937fec3b05475295d646a8ea8f723c", "name": "doc33.md", "size": 1048576, "sha256": "0f5ba1d242f11cadd7183019e2bdcaef43b2141bd965b28e3fbe99ce3f9883af"}, {"i": 34, "id": "d7b943d9fd7944609087830791a36e7c", "name": "doc34.md", "size": 1048576, "sha256": "a5f1a3901d62d78ea9637cb8ed29f4c62f63cd7310b0d6a33e66562018773605"}, {"i": 35, "id": "e1e292b3bc6c489eb67ea7d8a3529be4", "name": "doc35.md", "size": 1048576, "sha256": "1a361f543fbee6e14fba320683c00450cc3ea7e4fcb3fc24047f102e1f89f831"}, {"i": 36, "id": "adec9a5a38b1457082f19f8b977cf9f0", "name": "doc36.md", "size": 1048576, "sha256": "38e01fbca1007bd64564071ef731419a11a838bdf29ada613cac0c237a8dd10d"}, {"i": 37, "id": "84b18d43c14d480ea4acd6f4f56132f0", "name": "doc37.md", "size": 1048576, "sha256": "94dd4c2eec36e15e2e4f6e5e0d37a47acd92703b025e0b90ee68a6a5baee49df"}, {"i": 38, "id": "7d5b03c6a3aa43fabeaa0c0c0ca8c47a", "name": "doc38.md", "size": 1048576, "sha256": "18d3689693489dc07c8a761212f8cb95f6725531a83c6817c582e85c700943fb"}, {"i": 39, "id": "431db66907874da394008b7d4f6842fc", "name": "doc39.md", "size": 1048576, "sha256": "f0c08b9d4a38aa89d41c54b13dc8ca36e7533d71a62f6551201796ae49eb639b"}, {"i": 40, "id": "1eb23c090982401998098bd252730c74", "name": "doc40.md", "size": 1048576, "sha256": "92c0b1d6790c56a95c5d8b8bc055cf37742a29adef603d9bd6b2b11ba9f7873a"}, {"i": 41, "id": "b58dec464a654dd2a21deb9869667623", "name": "doc41.md", "size": 1048576, "sha256": "28a856ec2ecb05c468c90b419e1cd889dcbd4c2b4dc0f3a17b963dec0a1fd398"}, {"i": 42, "id": "deae9cb4416c45e89ab0d8641ac46a13", "name": "doc42.md", "size": 1048576, "sha256": "b7b4301fbb0b5df87405bee066cc58d515c677ade7689d9c68dba62ca9e3696b"}, {"i": 43, "id": "d945270dd99744e5916b84b343ddc3e9", "name": "doc43.md", "size": 1048576, "sha256": "15ae540c2a091f8b2e319ce9319917371b5ab84e4854d79bfaf70e12e9ceaf29"}, {"i": 44, "id": "11be051331e1432eacf40dd0a2216b7b", "name": "doc44.md", "size": 1048576, "sha256": "8b971216cd442397aeb1be39d90216e7ea328fb27a8f44c8aede7956dcf1eb9d"}, {"i": 45, "id": "2ddd3332f741446bbe34f822d444b777", "name": "doc45.md", "size": 1048576, "sha256": "08c9f8c6df08a7e4d79040904f84557195a040a54a70222cd9c94b099b086a16"}, {"i": 46, "id": "6b8e25f73ee14acc8468fe2e82875df0", "name": "doc46.md", "size": 1048576, "sha256": "f2bbd44a0670b399a5e456e70d618f80cd3865782783c4004cbc200ed632c561"}, {"i": 47, "id": "0878965f1baf46738f7402991b5a4e7a", "name": "doc47.md", "size": 1048576, "sha256": "ca546aa46e30794750f9339a6bdf2cf98d26197513766bf4549391d4bc103350"}, {"i": 48, "id": "a597aee84d5a4dfeae08911f445936b1", "name": "doc48.md", "size": 1048576, "sha256": "b310a28d6b5aa929dd639bbdf47e0f6c0832f389e60e35753b042cab94552914"}, {"i": 49, "id": "56c578272ee342e38c0bb5b466f64a31", "name": "doc49.md", "size": 1048576, "sha256": "be980e219ec4f79c50f78db790394d845e5649c47e4ef8ef4eb2c52ddd079bb4"}, {"i": 50, "id": "0289cf1b0fb4411caf2cc764a1aeaf53", "name": "doc50.md", "size": 1048576, "sha256": "2dd44816710021df204854d704609124844fe7df041f3b6942dbcafb065f786a"}, {"i": 51, "id": "9af6b9d8664a4cc8899a37b8b247216e", "name": "doc51.md", "size": 1048576, "sha256": "82a9ee619a41dd57cac6f806ef563b83409f7fe30919a5c20e12f893d514647f"}, {"i": 52, "id": "d3f833aa7fff41799fbb9da5334600ec", "name": "doc52.md", "size": 1048576, "sha256": "da58fc314d8a7a42e4932819a590f1069e7afda5662964fd9694960dbf90af13"}, {"i": 53, "id": "69954f256a514722b9b175c794e07694", "name": "doc53.md", "size": 1048576, "sha256": "84bddc7dda7ce2ddbbbc9ff9f7adabdf2b62033817d01a5501483264dedd718c"}, {"i": 54, "id": "3e702d86fc5b4f66bb6e818aa97ab8bc", "name": "doc54.md", "size": 1048576, "sha256": "c0c2272747da1d8085ce3bbd9ecc881a3e370a01ce27d83cb635f28dfee41606"}, {"i": 55, "id": "82596f821c264004838605d268f3aa06", "name": "doc55.md", "size": 1048576, "sha256": "c3cf82e29be050b920322d317fc500814c76ce0739c60d38c0007f575ffd18e7"}, {"i": 56, "id": "5074e6b7c81d41fd90d789a63980b231", "name": "doc56.md", "size": 1048576, "sha256": "940ddd0fa6ab55b3167955dc0b68ae11bd7a6486b8eb1e12032dd58e9a2954e0"}, {"i": 57, "id": "d955f47664e047f9b0905bd19cf40b43", "name": "doc57.md", "size": 1048576, "sha256": "5cacdc8ca4f83653e73d715a18b7cdf4bb648384a40d5538424ae69235552cd8"}, {"i": 58, "id": "ea46533061b2405c90a185748fba6c18", "name": "doc58.md", "size": 1048576, "sha256": "e94761d984916f70ffed8162dd5437f8224a8e88a8dbfd5cf980ce24398b4247"}, {"i": 59, "id": "ff62373d58f84ece833fb22499f12fa5", "name": "doc59.md", "size": 1048576, "sha256": "b610b9496e0de567efd206702d39021afb3ae2cd5d3e56fcf29ceea16fba725a"}]} diff --git a/scripts/oneoff/albok-browse-withdrawal/run-mac.sh b/scripts/oneoff/albok-browse-withdrawal/run-mac.sh new file mode 100644 index 0000000..ffa670c --- /dev/null +++ b/scripts/oneoff/albok-browse-withdrawal/run-mac.sh @@ -0,0 +1,79 @@ +#!/bin/zsh +# macOS client run of the albok browse-view withdrawal test (unit 4.3 exposure gate). +# Staged on nh3-albok under ~vh/albok-browse-test/harness/ with a vh-owned replica beside it. +# On the Mac: +# mkdir -p ~/albok-browse-test && cd ~/albok-browse-test && scp 'vh@10.100.50.44:albok-browse-test/harness/*' . && zsh run-mac.sh +# It tests every FUSE backend this Mac can mount with (the backend decides whether a rename +# withdraws access), smoke-tests the real wings as vh, and copies the results back to nh3-albok. +set -u +cd "${0:A:h}" +SRV=vh@10.100.50.44 +MNT=$PWD/mnt +N=${N:-5} +stamp=$(date +%Y%m%d-%H%M) +mkdir -p "$MNT" results + +unmount() { umount "$MNT" 2>/dev/null || diskutil unmount force "$MNT" >/dev/null 2>&1; } + +{ + echo "date: $(date '+%F %H%M %Z') host: $(scutil --get LocalHostName 2>/dev/null)" + sw_vers + echo "arch: $(uname -m)" + echo "sshfs: $(command -v sshfs || echo MISSING)" + command -v sshfs >/dev/null && { sshfs -V 2>&1 | head -5; otool -L "$(command -v sshfs)" 2>/dev/null | grep -i fuse; } + [[ -d /Library/Filesystems/macfuse.fs ]] && echo "macFUSE: $(defaults read /Library/Filesystems/macfuse.fs/Contents/Info CFBundleShortVersionString 2>/dev/null)" + pkgutil --pkgs 2>/dev/null | grep -i fuse +} 2>&1 | tee "results/client-$stamp.txt" + +if ! command -v sshfs >/dev/null; then + print "\nNo sshfs on this Mac. Install fuse-t (no kernel extension), then re-run this script:" + print " brew install macos-fuse-t/homebrew-cask/fuse-t macos-fuse-t/homebrew-cask/fuse-t-sshfs" + exit 2 +fi + +# Candidate backends: "" = whatever this sshfs mounts with by default. +candidates=("") +if pkgutil --pkgs 2>/dev/null | grep -qi fuse-t || [[ -e /usr/local/lib/libfuse-t.dylib ]]; then + candidates+=("backend=smb" "backend=fskit") +fi +[[ -d /Library/Filesystems/macfuse.fs ]] && candidates+=("backend=fskit") +candidates=("${(@u)candidates}") # dedupe, keeping the empty "default" entry + +working=() +for c in "${candidates[@]}"; do + label=${c:-default}; label=${label#backend=} + o="ro,follow_symlinks${c:+,$c}" + if sshfs "$SRV:albok-browse-test/wing/.browse" "$MNT" -o "$o" 2>>"results/client-$stamp.txt" \ + && ls "$MNT/stash" >/dev/null 2>&1; then + print "backend $label: mounts"; working+=("$c") + else + print "backend $label: does not mount here (skipped)" + fi + unmount +done +(( ${#working} )) || { print "No backend mounted; send results/client-$stamp.txt to infra-ops."; exit 3; } + +for c in "${working[@]}"; do + label=${c:-default}; label=${label#backend=} + print "\n== trials, backend $label (N=$N per condition; ~3 min)" + ALBOK_TEST_SRV=$SRV ALBOK_TEST_KEY= ALBOK_TEST_KNOWN_HOSTS= ALBOK_TEST_MNT=$MNT \ + ALBOK_TEST_EXTRA_OPTS=$c python3 run-trials.py manifest.json $N > "results/trials-$label-$stamp.json" + python3 summarize.py "results/trials-$label-$stamp.json" +done + +# Smoke test of the REAL views as vh (read-only; prints counts, never content). +first=${working[1]} +print "\n== real wings as vh" | tee "results/smoke-$stamp.txt" +for w in fleet/memory fleet/stash library/fiction library/nonfiction personal/notes personal/agent-feedback; do + if sshfs "$SRV:/srv/albok/store/$w/.browse" "$MNT" -o "ro,follow_symlinks${first:+,$first}" 2>/dev/null; then + n=$(find "$MNT" -type f 2>/dev/null | wc -l | tr -d ' ') + f=$(find "$MNT" -type f 2>/dev/null | head -1) + b=$([[ -n $f ]] && head -c 4096 "$f" | wc -c | tr -d ' ' || echo -) + print "$w: mount ok, files=$n, first-file bytes read=$b" + else + print "$w: MOUNT FAILED" + fi | tee -a "results/smoke-$stamp.txt" + unmount +done + +scp -q results/*-$stamp.* "$SRV:albok-browse-test/results/" && print "\nResults copied to nh3-albok; tell infra-ops it is done." diff --git a/scripts/oneoff/albok-browse-withdrawal/run-trials.py b/scripts/oneoff/albok-browse-withdrawal/run-trials.py index b3a6162..1874113 100755 --- a/scripts/oneoff/albok-browse-withdrawal/run-trials.py +++ b/scripts/oneoff/albok-browse-withdrawal/run-trials.py @@ -34,11 +34,16 @@ SRV = os.environ.get("ALBOK_TEST_SRV", "infra-ops@10.100.50.44") KEY = os.environ.get("ALBOK_TEST_KEY", "/keys/id") KH = os.environ.get("ALBOK_TEST_KNOWN_HOSTS", "/keys/known_hosts") MNT = os.environ.get("ALBOK_TEST_MNT", "/mnt/browse") -SSH_OPTS = ["-i", KEY, "-o", "BatchMode=yes", "-o", f"UserKnownHostsFile={KH}", - "-o", "StrictHostKeyChecking=yes", "-o", "ControlMaster=auto", - "-o", "ControlPath=/tmp/cm-%r@%h", "-o", "ControlPersist=900"] -SSHFS_BASE = ["ro", "follow_symlinks", f"IdentityFile={KEY}", f"UserKnownHostsFile={KH}", - "StrictHostKeyChecking=yes", "BatchMode=yes"] +# An empty KEY / KNOWN_HOSTS means "use the client's own ssh config" (a workstation run). +_id = (["-i", KEY] if KEY else []) + (["-o", f"UserKnownHostsFile={KH}"] if KH else []) +SSH_OPTS = _id + ["-o", "BatchMode=yes", "-o", "StrictHostKeyChecking=yes", + "-o", "ControlMaster=auto", "-o", "ControlPath=/tmp/cm-%r@%h", + "-o", "ControlPersist=900"] +SSHFS_BASE = (["ro", "follow_symlinks"] + ([f"IdentityFile={KEY}"] if KEY else []) + + ([f"UserKnownHostsFile={KH}"] if KH else []) + + ["StrictHostKeyChecking=yes", "BatchMode=yes"] + # e.g. backend=fskit on macOS: the FUSE backend under test + + [o for o in os.environ.get("ALBOK_TEST_EXTRA_OPTS", "").split(",") if o]) AGGRESSIVE = ["kernel_cache", "entry_timeout=3600", "attr_timeout=3600", "dir_cache=yes", "dcache_timeout=3600"] CONDITIONS = [("null", [], None), ("default", [], "ok"), @@ -157,7 +162,8 @@ def trial(cond, extra, rename, k, slot): finally: if fd_b is not None: os.close(fd_b) - for um in (["fusermount3", "-u", MNT], ["fusermount", "-u", MNT], ["umount", MNT]): + for um in (["fusermount3", "-u", MNT], ["fusermount", "-u", MNT], ["umount", MNT], + ["diskutil", "unmount", "force", MNT]): try: if subprocess.run(um, capture_output=True).returncode == 0: break diff --git a/scripts/oneoff/albok-browse-withdrawal/setup-replica.py b/scripts/oneoff/albok-browse-withdrawal/setup-replica.py index 31b0e27..5bbaeff 100755 --- a/scripts/oneoff/albok-browse-withdrawal/setup-replica.py +++ b/scripts/oneoff/albok-browse-withdrawal/setup-replica.py @@ -18,9 +18,11 @@ fetching a reference copy. import hashlib import json import os +import sys import uuid -ROOT = "/home/infra-ops/albok-browse-test/wing" +# Optional argv[1] places the replica elsewhere (python3 - < setup-replica.py). +ROOT = sys.argv[1] if len(sys.argv) > 1 else "/home/infra-ops/albok-browse-test/wing" COUNT = 60 SIZE = 1 << 20 # 1 MiB: larger than FUSE readahead, so a late read must reach the server diff --git a/scripts/oneoff/albok-browse-withdrawal/summarize.py b/scripts/oneoff/albok-browse-withdrawal/summarize.py new file mode 100644 index 0000000..870ecc5 --- /dev/null +++ b/scripts/oneoff/albok-browse-withdrawal/summarize.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +"""Print one line per condition from a run-trials.py result file, and the gate verdict. + + python3 summarize.py results-*.json +""" +import json +import sys +from collections import Counter + + +def c_outcome(t): + c = t.get("post_open_C", {}) + if not c.get("opened"): + return f"open {c.get('errno')}" + if "read_errno" in c: + return f"opened, read {c['read_errno']}" + return "opened, bytes ok" if c.get("content_ok") else "opened, BYTES WRONG" + + +for path in sys.argv[1:]: + d = json.load(open(path)) + print(f"== {path} sshfs -o {','.join(o for o in d['sshfs_base'] if not o.startswith(('IdentityFile', 'UserKnownHosts')))}") + by = {} + for t in d["trials"]: + by.setdefault(t["cond"], []).append(t) + verdict = [] + for cond, ts in by.items(): + aborted = [t["aborted"] for t in ts if "aborted" in t] + ok = [t for t in ts if "aborted" not in t] + oc = Counter(c_outcome(t) for t in ok) + held = Counter("ok" if t["post_held_B"].get("content_ok") else str(t["post_held_B"]) for t in ok) + lst = Counter(str(t["post_list"].get("n", t["post_list"].get("errno"))) for t in ok) + print(f" {cond:14} n={len(ok)} aborted={len(aborted)} open C: {dict(oc)} held B: {dict(held)} " + f"cached list: {dict(lst)}" + (f" abort: {aborted[0][:80]}" if aborted else "")) + if cond in ("default", "aggressive") and ok: + denied = sum(1 for t in ok if not t["post_open_C"].get("opened") + or "read_errno" in t["post_open_C"]) + verdict.append(f"{cond}: C denied {denied}/{len(ok)}") + if cond == "null" and ok: + verdict.append(f"null: C served {sum(1 for t in ok if c_outcome(t) == 'opened, bytes ok')}/{len(ok)}") + print(" verdict:", "; ".join(verdict) or "no usable trials") diff --git a/stacks/albok-service/README.md b/stacks/albok-service/README.md index fcdffd7..7520cf1 100644 --- a/stacks/albok-service/README.md +++ b/stacks/albok-service/README.md @@ -26,9 +26,10 @@ The FastAPI process that owns Albok's buildings-and-wings store (`vh/albok`, **[2026-10-09] PASSED on sshfs `ro,follow_symlinks` with a Linux client** (SSHFS 3.7.3 / libfuse 3.14): fresh open ENOENT 5/5 with sshfs defaults and 5/5 with hour-long client caches, while the cached listing and stat still showed the child; null and positive controls behaved (`scripts/oneoff/albok-browse-withdrawal/`). Reported to albok-dev. - Still before any share: the workstation's own client must re-run that harness if it is macOS (different FUSE - backend), and no user is in `albok-read`/`albok-personal` yet, so the operator's user needs those groups (the - operator's call; `albok-feedback` stays default-deny). Rollback: `compose.yaml.pre-0.1.14` (0.1.13) is free, because no + **[2026-10-09 2244] vh holds every albok read group** (Prime: "vh gets albok-everything"; his four Macs' keys are + authorized for vh; verified at a fresh login, every wing's view lists and reads). Still before he browses from a Mac: + the macOS re-run of that harness (staged in `~vh/albok-browse-test/`, `run-mac.sh`), because the FUSE backend differs. + Rollback: `compose.yaml.pre-0.1.14` (0.1.13) is free, because no sidecar shape changed. Prior: 0.1.13 @ `sha256:bea95617…` (2026-10-07 1135 – 1804) (healthy 1136:17, between walks). infra-ops deployed it at albok-dev's ask (althing 8413), from a clean archive of vh/albok `70b55ad7` @@ -107,8 +108,8 @@ The FastAPI process that owns Albok's buildings-and-wings store (`vh/albok`, **Identities (fixed numeric ids, created by `playbooks/albok-service-host.yaml`):** user and group `albok` 1500:1500 (the image's user), read groups `albok-read` **1510** (building `fleet`) and -`albok-personal` **1511** (building `personal`). **`albok-feedback` 1512** = restricted wing `personal/agent-feedback` (2026-10-03, default-deny: no viewer is -in it). Reserve 1513+ for the vault wing and any later restricted wing; add each to the host, `conf/group` and `group_add`. +`albok-personal` **1511** (building `personal`). **`albok-feedback` 1512** = restricted wing `personal/agent-feedback` (2026-10-03, default-deny: no viewer was +in it until Prime's 2026-10-09 ruling "vh gets albok-everything": vh now holds 1510, 1511 and 1512, `playbooks/nh3-albok-vh-viewer.yaml`). Reserve 1513+ for the vault wing and any later restricted wing; add each to the host, `conf/group` and `group_add`. **Why the group file and `group_add`:** the service resolves group NAMES with `grp.getgrnam()` inside the container and `chgrp`s wing dirs as uid 1500. Without the names in the container's