This is the filed review document, copied at 09:19 EDT. Its dated claims remain historical. See the current update before acting on an old sign-in request or delivery status. Reply in chat with decisions or feedback.
Mid-build review · 116 · prepared 20 October 2026 · source reads 04:20–04:34 EDT · current state added 06:21 EDT
The analysis below is dated. Its source reads predate the 05:21 EDT install of PR 320 and the later WOB-138 disposition, so the table here is the live picture. The body keeps its 04:20 evidence and marks where it has changed.
| Piece | At the 04:20–04:34 EDT reads | Now (06:21 EDT) |
|---|---|---|
| Six-domain component, WOB-115 | Built, not merged | Merged as PR 320 (8a46799; reviewed head b45306394b…) at 05:19 EDT. Installed at 05:21 EDT (receipt 20261020T091950Z-6057, exit 0, running_new). Deployed HEAD f66d4f2 (installed 05:31 EDT) contains WobOS/domains.py. |
| WOB-138 helper binding | Open; repair not started | Evidence-only draft PR 327 (head 7c8c3435423781fcb2325093d4fc34e3ce9e0a73): 34 focused cases, 27 deliberately unmet refusal contracts and 7 controls, from the local Mac run. No merge and no fix. The draft changes only new tests and evidence documents. Shared runtime files were returned unchanged to A. |
| Remote CI on PR 327 | Not applicable | Red: 28 failures, including 13 bin/domain-craft cases that fail before launch on Linux because these draft cases omit the existing macOS marker, plus 15 unmet refusal contracts. The permanent CI disposition records the breakdown. Do not treat this as the local Mac baseline. |
| Choice of boundary | Open | Still open. A's architecture question is Inbox q-cd2a2ae9 (thread msg_01M5C0DSGEW1JT9CN4KP98P3XJ): a separate OS identity or sandbox with trusted admission, as its own slice, or cooperative checks with activation held. Cooperative controls are not accepted. Toberton decides. |
| Memory switches and admission | Both flags false; Apple admission lists empty | Unchanged. At f66d4f2 both flags are false, and the memory session and account lists are empty for all six domain entries. |
| WOB-116 activation | Held | Still held. It needs the WOB-138 decision first, then a rehearsal of contribution, permission change and undo through the application. |
Nothing can read or write Apple craft in production right now. Both memory flags are false, the Apple admission lists are empty, and at the 04:20 reads the six-domain component (WOB-115) was built but not merged. PR 320 merged it at 05:19 EDT and it was installed at 05:21 EDT, so the current-state table above is the live picture. The review question is narrower. Every check in the domain path, from admission to delivery, works on the Work record it is handed. The variable that picks that record is set in the helper's own environment. That is WOB-138, and it blocks WOB-116.
My reads were taken after PR 312 merged at 08:20:06 UTC. I used source at named commits, read-only GitHub and Linear, and the local state files named below. I ran no tests, no service or model calls, no memory reads, no watcher commands and no token reads. This review extends domain-contract.md in this folder, the original boundary record, through delivery and readiness. It does not add a second approval gate.

The card shows one contribution through the path. The two red steps are where the variable matters.
A's 08:13:56 UTC report had PR 312 open at baa5f324. It has since merged as 8972cd5 and, per A's report, was installed in window 4 at 04:21 EDT. Root read the install receipt directly: from 6c14a9b to 8972cd5, outcome installed, watcher running_new, finished 08:22:19 UTC. I did not read that receipt, and I did not check the watcher myself, because the brief bars watcher commands. My own evidence is narrower. The deployed checkout's reflog shows a fast-forward to 8972cd5 at 04:21:10 EDT, and the committed flags are both false. Those agree with root's reading. The earlier window-3 claim for 6c14a9b matches a reflog fast-forward at 04:00:03 EDT. A's "revision 7" is routing.revision in the deployed settings, which reads 7 in my local read of the working copy.
These readings are dated. Deployed HEAD moved after them, and the receipts show the chain: PR 319 (41d870cc) at 08:57Z (04:57 EDT, receipt 20261020T085547Z-4734), PR 320 (8a467995) at 09:21Z (05:21 EDT, receipt 20261020T091950Z-6057), and PR 318 (f66d4f2) at 09:31Z (05:31 EDT, receipt 20261020T093017Z-23597). So 8972cd5 is no longer deployed HEAD. It is an ancestor of the current one.
PR 306 (WOB-112) merged at 06:51:05 UTC as 06ad669 from reviewed head bdf1b75, and it is in the deployed history. Its description still says "not merged or installed" in its pre-merge text, so that line is stale. The disposition file at bdf1b75 records the limits that matter for WOB-116. The broader prompt rescore is still pending. The shell correction route was instructed in the proof rather than chosen unprompted. Its first shell attempt understood the correction but could not save it, and the cause was driver accounting, not a memory result. The model chose whole originals rather than the narrow clauses, so passage minimality remains a quality limit. WOB-114's diagnostic also overlapped the same shared test workspace around 06:08 UTC, and the disposition says it cannot make an unconditional claim that the overlapping run held no foreign message. WOB-112 is Done, but these are not an all-real-tests-green result.
PR 312's body header says it was installed at 04:21 EDT. A subsequently filed the permanent exact-head review record, which root read at 04:32 EDT. It records the actual Haiku LSP passes, Sonnet's blocking review, repairs through baa5f324, the nonblocking delta review and green CI. The earlier live proof predates the final PATH and notice repairs; those later changes have focused regression evidence, rather than a repeated live proof. WOB-138 and WOB-116's application rehearsal remain open.
WOB-113 is Done, and WOB-45 records its PR 299 as merged and installed on 20 October. I did not check that install independently.
The local state I did read: ~/.local/state/WobOS/memory-mode.json reads revision 1 with both flags false. The committed config/settings.json at 8972cd5 has memory.enabled and memory.remote_enabled both false. The deployed working copy carries an uncommitted diff of 28 added and 1 removed lines, which matches the preserved patch the runbook describes. At f66d4f2, the deployed HEAD now, the committed config/settings.json still has both flags false (lines 542–543).
| Piece | Built | Tested | Application proof | Installed |
|---|---|---|---|---|
Apple craft component (WOB-114, 368f92f) |
Yes | 42 offline passed, 1 live skipped (attributed to the 114 evidence). One live run saved a lesson and recalled it from a second Work. The cleanup assertion failed on timing, and a later readback showed the workspace gone. | Claimed by PR 312's body: a disposable proof through worker --domain apple, with limits in docs/evidence/wob-114-wiring.md. I did not read that note. |
Installed in window 4 (A's report; root read the receipt: outcome installed, watcher running_new). Deployed HEAD read by me. |
Six-domain component (WOB-115, 093c7a4 / 667cbda, merged through PR 320 8a46799) |
Yes | Initial component: 108 offline passed, 1 live skipped. Later integration: A's WOB-115 outcome, read directly by the lead, reports 398 focused checks and actual LSP. | The same outcome records a later isolated rehearsal: a JA assignment got bounded Workspace evidence, saved/recalled domain craft, refused a cross-domain read, held a revoked return and read the workspace back empty. This does not complete WOB-116's activation/change/undo rehearsal. | Yes, from 05:21 EDT (receipt 20261020T091950Z-6057). |
| WOB-138 binding | No fix. Evidence-only draft PR 327, not merged | At the 04:20 read no test refused a forged id. PR 327 holds 34 focused cases: 27 deliberately unmet refusal contracts and 7 controls, from the local Mac run. Remote CI is separately red with the breakdown above. | No | No. Blocks WOB-116. |
| Base memory switch (M03) | Runbook written | M01–M03 offline checks (attributed) | Never executed | No. Both flags false. |
| Per-domain activation and undo (WOB-116) | No | No | No | No |
| JA seed | Proposal files merged in JR PR 79 (213dc1f8) |
Collector checks (attributed) | No | No seed written |
| Personal catch jobs | Config exists. personal-instagram-review carries a 17 September hold in its config/jobs.json note, which says the job was disabled in launchd |
Not checked by me | No | Both jobs are named in the 20 October grant. A records the enable and its readback. Activation not verified by me. |
| WOB-112 dispositions (PR 306) | Yes | Focused checks reused, not a combined run (per PR body) | Disposable workspace only, with the limits listed above | Merged in deployed history; memory stays off |
A helper runs as a worker process. At launch, the worker writes that process's own Work id into its environment as WOBOS_TASK_ID. Three places read that variable. I read them at PR 312's head (baa5f324), fetched read-only, because the 115 checkout predates PR 312.
# WobOS/worker.py:511-512 at baa5f324
if (args.domain or args.domain_sources) and os.environ.get('WOBOS_TASK_ID'):
raise Failure(7, 'only the chief can admit a domain assignment or sources')
The chief is whoever has no such variable in its environment. The helper's shell controls its own environment, so the variable is a claim about the caller, not a verified identity. Unsetting it passes the gate. That is a reading of the source. I did not run it.
# WobOS/domain_craft.py:37-39 at baa5f324
task_id = os.environ.get('WOBOS_TASK_ID')
if not task_id:
code, error = USAGE, 'domain craft requires WOBOS_TASK_ID'
Whatever id arrives here becomes the Work record that the rest of the path trusts. WobOS/memory_runtime.py:2293 and :2315 read the same variable for the older explicit lookup, which returns another Work's saved memory_context. That lookup refuses first unless selective memory is on.
Those line numbers are from PR 312's head. PR 320 changed worker.py, domain_craft.py and work.py after that point. At deployed HEAD f66d4f2 the same logic sits at WobOS/worker.py:552–553 (the chief gate), WobOS/domain_craft.py:45–47 (the Work id), WobOS/memory_runtime.py:2293 and :2315 (same line numbers), and WobOS/work.py:367 (domain_context_current), which is called for the delivery stage at line 568.
| Layer | What it decides | What it trusts | Holds today? |
|---|---|---|---|
| Peer naming | Which Honcho peer a read or write lands in. DOMAIN_PEERS maps apple to apple, and jr to justanother (WobOS/domains.py:38-45). |
The record's domain field, which the chief sets at admission |
Yes, for the record it is given. A peer is a storage identity and authorizes nothing by itself. |
| App access checks | Whether this record may be used: generation equal to current, boundary valid, audience acceptable, re-read before and after (work.memory_permitted, _boundary, _checked, and the delivery check) |
The record it is handed | Yes, for that record |
| Helper binding | Which record the call is about | WOBOS_TASK_ID, which the helper controls |
No. This is the break. |
So the access checks are sound about the record they receive. A forged id names a different record, and the checks pass on that record. From the source, a helper that named an assignment whose domain is jr would be read through justanother, with that record's sessions and audience. I have not run that. It is a reading.
Several conditions keep this latent today. domain_boundary raises PermissionError while the Apple lists are empty. Its caller refuses when selective memory is on or --domain-sources is requested (worker.py:560-563), and _boundary refuses as well. The older remember path refuses while both flags are false. Latent is not fixed, so A's activation must not happen before this closes.
The delivery check is different. domain_context_current (work.py:321 at PR 312's head, work.py:367 at f66d4f2) receives its task id from its caller (line 495 at PR 312's head, line 568 at f66d4f2), not from the environment. Whether that caller's id is trustworthy depends on the upstream delivery caller, which I did not trace. PR 312's own "Still open" notes say the JA-scope return hold applies only when a Work holds a craft packet, which matches the early return described under the undo notes below.
No test at PR 312's head sets a forged WOBOS_TASK_ID (none in tests/test_domains.py or tests/test_worker.py), and none unsets it to test the chief gate. At the 04:20 reads A owned this narrow repair, and root's update said it had not started. The current status is in the handoff at the end of this document. PR 312's own "Still open" section names the same blocker and calls it latent while admission is empty and memory is off. The repair needs three things:
--domain chief gate.The older remember path uses the same variable, so the fix should cover it too, or record why it doesn't need to.
The runbook (captain-workbench/integration/plan-2/m03-activation-runbook-2026-10-19.md) covers only base memory. The per-domain, JA seed and job scopes are separate effects. The 20 October authority names the two catch jobs, keeps the memory switches false, and holds JR deployment and seed writes. The older conditional WOB-45 instruction from 19 October, "if every real test passes, turn memory on", does not override that. The 20 October instruction is later, and it says the switches stay false.
| Scope | Current mapping and prerequisites | Evidence and remaining acceptance |
|---|---|---|
| Base phone memory | memory.remote_enabled and memory.enabled. Selective memory needs both (runbook §1). Record at revision 1, generation d5c25e845e63199863646413. Prerequisites (runbook §2): Toberton's explicit yes for activation (the 18 October grants do not cover it), A4 evidence, W03 merged and installed or a recorded decision not to wait, a deployed main containing M01–M03, an idle watcher, and a Keychain item present. |
Evidence: M01–M03 offline checks (attributed). WOB-112's three rows were rerun in the disposable workspace, with the limits listed above. WOB-45 records that three of four real cases did not pass before the WOB-112 dispositions. Remaining: the switch-on window (not executed), its readback, one observed natural exchange, and the W03 sequencing decision. |
| Each domain | settings.domains.<domain>.memory.{personal, ja}, with sessions, write_session, accounts and audiences. At 8972cd5 the committed config had only apple, with every list empty, profile: helper-general and timeout_seconds: 300. The 115 component added research, mercury, workspace, instagram and jr (to justanother). It is merged through PR 320, and at f66d4f2 all six entries have empty memory session and account lists. Launch copies the admitted boundary onto the Work as domain_memory. Prerequisites: base switch on; WOB-138 closed; Toberton's approval of each admission's exact accounts and sessions, because that is a permission change. |
Evidence: 114 live run in the disposable workspace (attributed); 115 offline, 108 checks (attributed). Remaining: the WOB-138 decision, which must close first, and WOB-116's rehearsal of contribution, permission change and undo through the app. The 115 integration is merged (PR 320). |
| JA seed | ja_sessions is empty in settings. The seed content sits in JR's proposal files, merged in JustAnother PR 79. The status counts are ten card strings, nine conclusions and five held candidates. I did not open those files. Prerequisites: approval of the actual seed write (activation readiness), admitted JA sessions, and JR deployment and seed writes held under the 20 October authority. |
Evidence: proposal and collector checks (attributed). No seed written. Remaining: approval, decisions on the five held candidates, the write, and its readback. |
| Two personal catch jobs | personal-imessage-review (memory scope personal; delivery to results log and phone; weekday and weekend hours) and personal-instagram-review (memory scope personal; every hour; delivery to results log), per committed config/jobs.json. ja-instagram-review stays on demand and is out of scope. Prerequisites: the 20 October authority names exactly these two, and A's order is its consumer-window signal, then the personal Instagram run, then activation. The personal-instagram-review note in config/jobs.json records a 17 September hold, with the job disabled in launchd. The 20 October grant names this job, so it covers the re-enable. I did not check launchd. |
Evidence: none checked by me. I did not read schedule status. Remaining: apply with readback of trigger, timezone and command, then one normal run observed. |
Each scope is independent. Activating a catch job does not turn memory on. With the flags off, the personal scope's recall is not admitted, so the job runs without memory.
scripts/memory/export.py takes snapshots, and scripts/memory/delete.py deletes one approved export. The runbook describes delete as a dry run unless --apply is given.work.py:321-347), so removal is caught when packets exist. When a Work has no packets, the function returns early, so I cannot say removal is caught for a fresh Work. WOB-116 must test that.apply refuses an owner-disabled job and does not clear holds (WobOS/schedule.py:301-305). Disabling goes through launchctl disable (schedule.py:319). A will record the exact supported named-job disable and hold-restoration commands with the activation receipt. This is part of the already authorized catch-job delivery, not a new dependency on memory activation or a new approval gate.The common thread is that disabling a scope stops future reads and writes, and it holds work stamped under that scope. It does not remove remote data, and it does not revive old permissions.
Each command below comes from the current source or runbook. I did not run any of them.
| Purpose | Command | Checked against | Status |
|---|---|---|---|
| Read the flag record | cat ~/.local/state/WobOS/memory-mode.json |
runbook §1 | Read by me: revision 1, both false |
| Watcher profile before a window | scripts/WobOS-phone-watcher.zsh --profile-status --json |
runbook §2 step 0 | Not run, because it is a watcher command |
| Schedule status for catch jobs | scripts/WobOS-schedule.zsh status --json |
WobOS/schedule.py argparse |
Not run |
| Catch-job dry run | scripts/WobOS-schedule.zsh apply --job personal-imessage-review --dry-run --json |
schedule.py argparse; --dry-run skips the write |
Not run |
| Domain entry without launch | bin/worker --domain apple --brief <file> --dry-run --json |
PR 312 worker.py:680-691: the dry run returns before domain recall at 707. The chief gate at 511 (552 at f66d4f2) still applies, and admission at 560 (PR 312's head) can refuse first. |
Not run |
| Test command | .venv/bin/python -B -P -m pytest -q -p no:cacheprovider tests/test_domains.py |
README.md:37 |
Not run by me. At the 04:20 read the WOB-138 tests did not exist; the draft tests are in PR 327, which is not merged. |
| Remote census | scripts/memory/export.py --census --json |
export.py argparse | Not run, because it reads memory |
| Remote delete preview | scripts/memory/delete.py <export> --dry-run |
delete.py argparse | Not run; needs an approved export |
Written at 06:21 EDT. It replaces the 04:20 list kept below.
q-cd2a2ae9 asks whether to build a separate OS identity or sandbox with trusted admission as its own slice, or to keep cooperative checks. Until that is answered, do not accept cooperative controls, and keep WOB-116 activation and both memory switches held.
- WOB-138 blocks WOB-116. You own the narrow trusted-binding repair, which has not started. Make no admission change and no base switch until it closes. The lines involved are
worker.py:511-512,domain_craft.py:37-39, andmemory_runtime.py:2293and:2315, atbaa5f324. Keep it to that scope and do not widen it into general hardening.- Add the two tests described above. Neither exists at PR 312's head.
- Do not mark cooperative controls accepted. Root and Toberton decide that.
- In the 115 integration, from your separate worktree on
8972cd5, test admission removal on a Work that has no packets. Admission edits do not move the generation.- PR 312's permanent review record is now filed and root has read it. Carry its remaining limitations into the integration and morning handoff.
Initial render checked: source at named commits; reflog ancestry; Linear and GitHub read-only; the earlier card rendered at 1080 pixels wide (2160×1200 PNG) and inspected, with no clipping. Phone width was checked inside a 390-pixel frame (780×3000 PNG), because headless Chrome will not shrink its window below its own minimum. The layout is one column there, with nothing clipped.
Re-rendered at 06:21 EDT with scripts/render-card after the card update. The desktop card is 1080 px wide (2160×1272 PNG). Dark mode was checked with a scratch copy that sets data-theme="dark". Phone width was checked in a 390-px iframe frame (780×3000 PNG, scratch only). All three read clean, with nothing clipped.
Not checked: the loaded watcher; launchd hold state; schedule status; Honcho state; any test run.
The source reviewer ran no tests, service or model calls, memory reads, watcher commands, token reads, Linear or GitHub writes, or PRs. Temporary fetch files were removed. The reviewer read the install receipt only through the lead's update, not its directory. At the 04:20 read, the three files in this folder were committed. The 06:21 update was then incorporated into the 15-file candidate 022671e5ced50ce1aef2d37d7feb55e2366ba19c, reviewed and merged through agent-setup PR125. Render scratch files remain in the session scratchpad. The 20 October authority in astra-status.md is the current grant; earlier approval records were not edited.