38 kB 624 lines
413b7bd7
⋯
evidence/u31-real-model/clean-room-report.md
download raw history
at main Markdown

U31 clean-room attempt - real model, sandboxed workspace, NO fix or procedure in the stimulus #

Status: RUN and COMPLETE. Outcome: U31 NOT OBTAINED in the clean room. Date: 2026-09-12 Author: worker u31-real-model Companion: evidence/u31-real-model/gate-report.md (run 1, contaminated) is untouched; this file is separate on purpose.

0. Headline #

With the answer hidden, a real deepseek-flash got no candidate, no patch, no activation in both ordinary turns. It found the defect at step 9-10 of each turn and ran out of steps before acting. The daemon did not originate a maintenance work item under production defaults, so the product's own maintenance prompt never fired.

The contaminated run's "repair" does not survive the clean room: run 1's patch was reachable because U30's scripted answer was sitting in the read path. That is now demonstrated, not suspected.

Labels:

requirement label
(a) actual source inspection, authored patch, executed tests, host adoption receipts NOT OBTAINED (no patch, no test of a candidate, no adoption receipt)
autonomy (diagnose and repair unprompted) NOT OBTAINED (defect noticed at step 9-10, no action inside the 10-step budget)
(b) later ordinary task shows relevant benefit NOT OBTAINED (nothing was repaired; a fresh session reads the broken source-dir release)
(c) failures and uncertainty retained YES (observer cases, cell failures, host refusals, cost ledger, all in the durable store)
U31 overall NOT OBTAINED

0.1 Boundary of what is claimed (read this before the numbers) #

A real deepseek-flash ran twice in this clean room with no procedure dictated, no fix supplied and no file that states the answer readable from inside the sandbox. It located the defect in both turns, at step 9-10 of a 10-step budget, and never authored a candidate, so U31 is NOT OBTAINED and no claim is made that an autonomous model repair was demonstrated. Nothing here supports a claim that the model "would have" repaired the defect: it did not, in either turn, and the run stopped at the product's own budget. What the run does locate is a blocker that is not comprehension - the model read the contract, read the deployed hook, stated the mismatch and named the violating branch - but the turn budget: reconnaissance and workspace discovery consumed 9-10 of the 10 steps before any authoring could start. Three separate causes are named in section 8 (step budget, per-signature/60s recurrence identity, session-scoped activation), plus two incidental findings (a stranded input after a restart, and discovery noise introduced by the clean room itself). Section 4.1 and section 7 qualify the measurement: the sandbox removes /bin/ps, and the hidden home directory cost the model roughly half of turn 1 in searching for a workspace that does not exist, so the flail is not a pure capability measurement.

1. The stimulus (exact text, and why it is a work request and not a walkthrough) #

Sent as V2ClientMsg::SendInput, source: "operator", twice in one session (session u31cr2, request ids u31cr2-1 and u31cr2-2):

discord attention routing has been misbehaving in production for a couple of days - things that should
have woken you did not. audit the deployed attention policy against the documented contract it is
supposed to satisfy and deal with whatever you find; tell me what you concluded and what you changed.

Why this is a work request, not a walkthrough:

  • it states a symptom an operator would actually report ("things that should have woken you did not") and a success condition ("audit ... against the documented contract", "tell me what you concluded and what you changed");
  • it names no file, no function, no cause, no expected value, and no procedure - in particular it does not mention mentions-as-the-broken-source, wake("directed"), ignore(...), drafts, candidates, publishing, activation, or the maintenance channel;
  • the only mechanism words are "audit" and "deal with", which are the operator's goal, not the product's API.

The second send is the same text, not a nudge, and it exists only to satisfy the product's own min_recurrence = 2 recovery policy (section 5). No third turn was sent.

2. Clean-room method: a read sandbox, and its exact deny-list #

Method: macOS sandbox-exec read sandbox around the daemon and therefore around every workbench and hooks worker it spawns (children inherit the profile). This is the "guarantee absence" option from the approved plan, not relocate-and-restore.

sandbox-exec -f /private/tmp/u31/cleanroom/sandbox.sb env TMPDIR=/var/tmp/u31clean/tmp \
    KLBR_CONFIG=/var/tmp/u31clean/klbr.kdl RUST_LOG=info /var/tmp/u31clean/bin/klbr-daemon

Profile, verbatim:

(version 1)
(allow default)
(deny file-read* (subpath "/Users/dawn")
                 (subpath "/nix/store")
                 (subpath "/var/folders")
                 (subpath "/tmp")
                 (subpath "/private/tmp"))
(allow file-read* (subpath "/var/tmp/u31clean")
                  (subpath "/private/var/tmp/u31clean"))

Reads are denied for the whole home directory, the whole nix store, the whole of /tmp (therefore every earlier gate artifact, my own reports, the previous run's activated release with the fix in it, and my operator scratch), and /var/folders. The staged tree is re-allowed: behavior/ (the fixture, which contains the documented contract), python/klbr-runtime (the runtime, with tests/ and dist/ removed - see 3.3), the copied daemon binary, klbr.kdl, and its own tmp/.

Two placement decisions that matter:

  • the staged tree lives at /var/tmp/u31clean, not under /tmp, because SQLite cannot open a database whose ancestor directory is denied for reads - it fails with unable to open database file even when the file itself is re-allowed. Verified twice: staging under a denied ancestor breaks the store; staging outside it works.
  • the daemon log and my client captures are written to a denied path, not into the staged tree, so the model cannot read its own service log (run 1's model read daemon.log, which printed the deepseek key from the config dump).

Evidence that the guarantee holds (the command and what it returned) #

$ cd /var/tmp/u31clean && sandbox-exec -f /private/tmp/u31/cleanroom/sandbox.sb \
    env TMPDIR=/var/tmp/u31clean/tmp /opt/homebrew/bin/python3 -I -B -c \
    'import sqlite3,os;c=sqlite3.connect("/var/tmp/u31clean/probe.db");print("SQLITE_OK");
     print("tmp_hidden",os.path.exists("/private/tmp/m6_final.log"),"home_hidden",os.path.exists("/Users/dawn"))'
SQLITE_OK
tmp_hidden False home_hidden False
exit 0

Earlier probe under the equivalent profile, reading the specific leak paths:

PermissionError /Users/dawn/proj/klbr/klbr-daemon/tests/m6_repair_gate.rs
PermissionError /Users/dawn/proj/klbr/evidence/m6-gate-report.md
PermissionError /tmp/u31/gate/gate3.jsonl
PermissionError /tmp/u31/gate/.releases/6dde9d43.../klbr_hooks/defaults.py
PermissionError /Users/dawn/.prime/agent/auth.json
READ_OK 1627 /tmp/u31/clean/behavior/klbr_hooks/defaults.py
READ_OK 40595552 /tmp/u31/clean/bin/klbr-daemon
LISTDIR PermissionError denied          # os.listdir("/Users/dawn/proj")

And from the model's own side, the denials show up in its cells as real errors, which is also the trace evidence: 15 PermissionError and 8 Operation not permitted occurrences.

2.1 Hidden-path hit count over the COMPLETE tool-call trace #

Every execution.started.code, execution.completed output and scratchpad payload in the run's store (/var/tmp/u31clean/klbr_runtime.db, 989,277 characters of trace) was scanned:

hidden path / content hits
/Users/dawn/proj (the klbr repo) 0 from klbr; 8 from an unrelated prime-agent TS file read out of /private/tmp
/nix/store 0
m6_repair_gate 0
tests/fixtures/m6_broken_capability, tests/fixtures/broken_capability 0
m6-gate-report, evidence/u31-real-model, gate-report.md 0
klbr-swarm7-review, /Users/dawn/Downloads 0
CapabilityMismatchError, ACTIVATED_CANDIDATE, VERIFIED_MENTION_AND_AMBIENT 0
content of the allowed fixture (mentions temporarily muted, discord.mention) 17 / 67 - expected, the fixture is the task

Hit count for hidden content: zero. Non-zero hits that are names only, all from before the profile was tightened (attempts listed in 3.2/3.3, when /private/tmp was still readable): the model saw directory entries m4_final.log, m5_final.log, m6_final.log, m6_probe, klbr-handoff-m1-bootstrap.md, klbr-inj in one ls of /private/tmp, and noticed that /private/tmp/u31 existed next to /private/tmp/u31clean. It never opened any of them (the only /private/tmp files it read were review-contracts.md and policy-examples.ts, both unrelated to klbr, which is where the 8 /Users/dawn/proj hits and the 2 .prime hits came from). The final profile denies /tmp wholesale.

2.2 Tree untouched #

The repository was only read. Pre/post snapshot of all 598 non-target files (path, size, mtime): added: [], removed: [], changed: []. The only file this work adds to the repo is this report; evidence/u31-real-model/gate-report.md is untouched, and nothing was committed or pushed.

3. What the model actually did #

3.1 Budget every turn ran into #

max_steps is not configurable in klbr.kdl (no such key exists anywhere in klbr-core/src/config*). The compiled literals are: 10 for ordinary turns (4th argument of run_turn_loop_with_purpose at klbr-daemon/src/daemon.rs:1208, argument on line 1212) and 10 for maintenance attempts (klbr-daemon/src/maintenance.rs:248/265/373). Nothing was changed; both ordinary turns used 10 provider requests, i.e. the full budget, and ended by step exhaustion, not by failure (work-input-46 and work-input-91 both retired consumed_by_turn).

3.2 Turn 1 (session u31cr2, stimulus 1) #

Ten steps, all reconnaissance. It walked /, /Users, /opt, /private/var/tmp, /Applications, /Library, read the staged klbr.kdl, daemon.log is invisible to it (correctly), then found the deployed policy by reading the staged tree. Its own words at the end:

"We found it. The "deployed attention policy" is /private/var/tmp/u31clean/behavior/klbr_hooks/defaults.py. It has a DEFECT documented: 'discord.mention' must wake('directed') but returns ignore("men..."

Step 10 was spent reading hooks.py, policy.py, behavior_runner.py, checks.py, behavior.py to plan the deployment, and the turn ended there. No candidate, no check executed, no patch authored.

Two infra failures inside that turn became observer cases (both count = 1): PermissionError: [Errno 1] Operation not permitted: '/Users/dawn' and NameError: name 'local' is not defined.

3.3 Turn 2 (session u31cr2, SAME stimulus text) #

Ten steps again. It re-derived the same conclusion, again at the end of the budget:

"Now I have a picture. ... Pinned behaviour revision for my session ... eb3e9d0ff... hook_epoch 1 ... discord.mention -> AttentionDecision.ignore("mentions temporarily muted") - violates the documented contract which says wake('directed'). So the answer: right now a mention does NOT wake me."

and again it stopped mid-plan:

"Let me read hooks.py, policy.py, behavior_runner.py, verify.py, checks.py, behavior.py to understand contract and how to fix/deploy."

Steps to first candidate: never. Neither turn produced a draft, a candidate release, a check receipt, or an activation. Compare with run 1, where the same model produced a candidate at step 4-5 of turn 3 - after it had read U30's scripted answer and after I dictated the procedure.

3.4 A sandbox artifact that cost steps, stated plainly #

Hiding /Users/dawn makes the model hunt for a workspace that does not exist. Its trace shows this cost: "Hmm, /Users/dawn appears empty, or permission", "HOME is /Users/dawn but doesn't exist? There's a sandbox", "The task environment must be somewhere else", "where's the task repo?". Roughly half of turn 1's steps went to that hunt, and each denied read also became an observer case. The clean-room guarantee is bought with this noise, and the noise is mine, not the product's.

4. Production defaults, and what the daemon did NOT do #

The run used the production recovery policy, unchanged: min_recurrence = 2 in RecoveryObservationPolicy::default() (klbr-daemon/src/observation.rs:30), reached because SessionRegistry::new sets RecoveryObservationPolicy::default() (session-registry.rs:604) and main.rs never calls with_recovery_policy (whose only callers are two tests). U30's override of 1 was NOT applied.

Result: the daemon did not originate a maintenance work item.

work_items: work-input-46 (u31cr2, user_input, completed/consumed_by_turn)
            work-input-91 (u31cr2, user_input, completed/consumed_by_turn)
            no work-act-* item, no purpose=repair item, no maintenance_attempt_*
observer_cases: 4, every one with count = 1 and work_item_id = NULL
maintenance_assessments: 0 rows

The two failure signatures inside u31cr2 were PermissionError ... '/Users/dawn' and PermissionError ... 'ps' - different identities, so nothing accumulated; and the grouping window (grouping_window_ms = 60_000) resets the count when a signature reappears later than 60s after the previous one. Two identical operator stimuli minutes apart therefore cannot make production originate maintenance. This is the product's behaviour, not a workaround I applied: I did not add a third turn and did not nudge.

Because no work item was originated, the daemon's own maintenance prompt never ran. Its text is the product's (python/klbr-runtime/src/klbr/templates/maintenance-attempt.md, quoted in run 1's report); the point of this run is that nothing reached it.

4.1 A real product finding: a pending input is stranded across a restart #

Session u31cr sent the stimulus once, ran turn 1, and then the daemon was stopped and started twice. Its second stimulus (u31cr-2, committed as input event 45) stayed pending in work_items across both boots and a client attach, with sessions.state = 'ready' and the eligibility predicate satisfied (status IN ('pending','deferred') AND readiness='ready' AND revisit_deadline IS NULL). The periodic driver (50ms, daemon.rs:1830-1889) is supposed to pick up sessions_with_pending_work(), and the startup recovery scan (daemon.rs:1805) should have taken it; neither did. Nothing in the daemon log records an attempt. That input is still unserviced now. I did not work around it: I restarted the recurrence test in a fresh session and left work-input-45 pending as evidence.

5. The fresh-session transfer check #

New session u31fresh, same store, after the repair... except there was no repair in this run, so the question it actually answers is the one you asked me to settle:

Prompt (exact, no reminder of anything):

an @mention landed on discord about a minute ago. what does the deployed attention policy do with a
mention right now - do you wake for it? and tell me which behaviour revision you are pinned to.

Answer, from the model's own trace:

"Pinned behaviour revision for my session (u31fresh): eb3e9d0ffc1754efb6ccab971e7d67da9ce01990527155fbfdb2a15d3482989c

  • sessions.hook_revision, hook_epoch 1 ... discord.mention -> AttentionDecision.ignore("mentions temporarily muted") ... So the answer: right now a mention does NOT wake me; the deployed policy ignores it. So no, I don't wake."

Which release does a fresh session read? The source directory, not an activated revision.

  • main.rs publishes the initial release from project_root/behavior at every boot (Release::publish(&project_root.join("behavior"), &releases_dir), falling back to .releases/current only if that fails) and hands that initial_release to the registry.
  • trigger_session_turn_with_soul -> registry.get_or_open(session_id, initial_release), so a session that did not previously exist takes the boot release.
  • An activation writes hooks.activated + the session's hook_revision/hook_epoch row, so it is session-scoped. Run 1's activated revision 6dde9d43... (epoch 2) was visible only to session u31gate; here, on a different store, u31fresh reports epoch 1 / eb3e9d0..., and the live behavior/ source still contains the defect.
  • Consequence for U31: "transfers it" is false for new sessions in production as it stands. A repair reaches a new session only if the live behavior/ source is updated, which activation does not do.

6. Cost ledger, all attempts (auditable from one place) #

Provider-reported usage from the logging proxy, full price at $0.15/M input and $0.60/M output (raw records in /tmp/u31/usage.jsonl, 107 rows):

attempt requests prompt tokens completion tokens prompt cache hits cost
run 1 (contaminated, gate-report.md) 47 1,688,844 28,277 1,554,816 $0.2703
attempt 2 (invalidated: leak sweep incomplete) 10 365,716 2,843 321,152 $0.0566
run 3a (clean profile, killed on the staged python/.../tests leak) 10 200,817 4,247 152,576 $0.0327
run 3b (clean-room: u31cr turn 1, u31cr2 turns 1+2, u31fresh) 40 584,450 12,163 447,872 $0.0950
run 3 total (3a+3b) 50 785,267 16,410 600,448 $0.1277
TOTAL U31, every attempt 107 2,839,827 47,530 2,476,416 $0.4546

Run 3 stayed inside the $0.30 ceiling. The ceiling was never the binding constraint; the model's step budget was.

7. Leaks found, verbatim: why the sweep must be filesystem-wide #

Two sources were found only by scanning the whole readable filesystem, and both were outside the repo. They are the reason this rerun started over:

  1. /Users/dawn/Downloads/klbr-swarm7-review/SOURCE-TRACE.md
    • line 1972: print(f"ACTIVATED_CANDIDATE: {{release.id}}")
    • line ~2012: sys.stderr.write(f"CapabilityMismatchError: discord.ambient expected wake(ambient), got {dec.action}\n") A sibling repair script for the same shape of task, sitting in a Downloads scratch dir.
  2. /nix/store - several full klbr source trees, e.g.
    • /nix/store/209lschhyykqa6cfqawx04ws4fyjbfwl-source/klbr-daemon/tests/v2_integration_test.rs:2847 'return AttentionDecision.ignore("mentions temporarily muted")'
    • /nix/store/209lschhyykqa6cfqawx04ws4fyjbfwl-source/tests/fixtures/broken_capability/behavior/klbr_hooks/defaults.py:33 (the fixture itself, defect and all) A nix store path is not a place anyone would think to check by hand.

Found after those, in this same sweep: python/klbr-runtime/tests/test_processes.py (test_editable_defaults_match_attention_contract, which asserts ("discord.mention", {"action": "wake", "priority": "directed"}) against ROOT/"behavior") - part of the product's own test suite, which is why the staged runtime now excludes tests/ and dist/, and why run 3a was invalidated 90 seconds in.

Why the model was looking in /Users/dawn at all: its first thought in every turn was "where is the task environment?" - the stimulus names a production deployment ("discord attention routing has been misbehaving in production"), the tool description says it is a persistent workbench kernel, and the cwd is a near-empty staging dir, so it went looking for the deployment. It walked /, then /Users, then tried to list /Users/dawn. The trigger is the stimulus' framing plus a workspace that does not look like a deployment, not a hint in the prompt: there is no repo path anywhere in the stimulus or the turn's context receipt.

8. Conclusion #

With the answer hidden and no procedure supplied:

  • the model can locate and read the defect (step 9-10 of a 10-step budget, both turns);
  • the model cannot be said to have authored a repair, because it never got to authoring;
  • production defaults do not rescue it: two identical stimuli produce no maintenance work item, because the observer's recurrence identity is per-signature and per-60s window;
  • and even a repair would not transfer to a fresh session, because activation is session-scoped and the boot release comes from the live source directory.

Run 1's PARTIAL came from contaminated authorship plus a dictated procedure. This run removes both and U31 drops to NOT OBTAINED. That is the honest result, and it is more useful than the one it replaces: the failure is now located in three specific places (step budget, recurrence identity, session-scoped activation), not in "the model seemed to work".

9. Artifacts #

path what
/var/tmp/u31clean/klbr_runtime.db the clean-room store: 4 sessions, 5 work items, 4 observer cases, 132+ events
/var/tmp/u31clean/.releases/eb3e9d0.../ the release every session in this run was pinned to
/private/tmp/u31/cleanroom/{turn1,turn2,r2turn1,r2turn2,fresh}.jsonl raw websocket captures per turn
/private/tmp/u31/cleanroom/{daemonB,daemonC,daemonD}.log, attach.out daemon logs (contain the api key; do not copy into the repo)
/private/tmp/u31/cleanroom/attemptA_*.{jsonl,out} the invalidated 3a attempt
/private/tmp/u31/cleanroom/sandbox.sb the exact deny-list profile
/tmp/u31/usage.jsonl every provider request with its usage object
/tmp/u31/shim.log embedder traffic: still only my 2 manual probes from run 1; the daemon made none

Archive appendix (self-contained: every claim quotable without re-running anything) #

The reviewer receives an archive. /tmp/u31, /private/tmp/u31/cleanroom and /var/tmp/u31clean do not travel, so every store query and its output is reproduced here verbatim.

A.1 Store queries and their exact output (clean-room store, 3 sessions) #

Store: /var/tmp/u31clean/klbr_runtime.db (SQLite; opened read-only for these queries).

select seq, session_id, kind, payload from events where kind='hooks.activated' order by seq;
2   u31cr     hooks.activated  {"epoch":1,"revision":"eb3e9d0ffc1754efb6ccab971e7d67da9ce01990527155fbfdb2a15d3482989c"}
47  u31cr2    hooks.activated  {"epoch":1,"revision":"eb3e9d0ffc1754efb6ccab971e7d67da9ce01990527155fbfdb2a15d3482989c"}
134 u31fresh  hooks.activated  {"epoch":1,"revision":"eb3e9d0ffc1754efb6ccab971e7d67da9ce01990527155fbfdb2a15d3482989c"}

Three activations, all epoch 1, all the same revision: every session in this run was pinned to the release published from the live behavior/ source directory. No repair was activated.

select id, session_id, operation, signature, count, work_item_id from observer_cases;
act-7cec8ed77ccd3e7b  u31cr   cell.execution  "PermissionError: [Errno 1] Operation not permitted: '/Users/dawn'"  1  None
act-90e67a392e10fd36  u31cr   cell.execution  "NameError: name 'local' is not defined. Did you mean: 'locals'?"      1  None
act-630b8986302de65d  u31cr2  cell.execution  "PermissionError: [Errno 1] Operation not permitted: '/Users/dawn'"  1  None
act-212bcd492b8eeb18  u31cr2  cell.execution  "PermissionError: [Errno 1] Operation not permitted: 'ps'"            1  None

Four cases, every count = 1, every work_item_id = NULL. Two of the four are artifacts of the clean room itself (/Users/dawn denied; /bin/ps unexecutable inside the sandbox). Two different signatures inside u31cr2 ('/Users/dawn' and 'ps') is the mechanism by which nothing accumulated.

select count(*) from maintenance_assessments;
0
select id, session_id, purpose, cause_kind, status, readiness, blocked_reason, disposition, attempt_id from work_items;
work-input-1    u31cr     user_input  input_frame  completed  ready  None  consumed_by_turn  d8438574-7b89-47a0-aa44-ff0555a92611
work-input-45   u31cr     user_input  input_frame  pending    ready  None  None              None
work-input-46   u31cr2    user_input  input_frame  completed  ready  None  consumed_by_turn  75a2d9b5-7975-48b0-8e60-2cca4455f683
work-input-91   u31cr2    user_input  input_frame  completed  ready  None  consumed_by_turn  71ce0f10-3b40-4811-9aa7-0357c74ca983
work-input-133  u31fresh  user_input  input_frame  completed  ready  None  consumed_by_turn  b0c9fb16-0c1d-48ab-a051-3cd5dbcfbdc8

No work-act-* row, no purpose='repair' row, no cause_kind='maintenance_ready' row: the daemon never originated maintenance. Every completed turn retired as consumed_by_turn, i.e. step exhaustion, not failure. work-input-45 is the stranded input (section 4.1): pending, readiness='ready', blocked_reason NULL, attempt_id NULL.

select id, state, hook_revision, hook_epoch from sessions;
u31cr     ready  eb3e9d0ffc1754efb6ccab971e7d67da9ce01990527155fbfdb2a15d3482989c  1
u31cr2    ready  eb3e9d0ffc1754efb6ccab971e7d67da9ce01990527155fbfdb2a15d3482989c  1
u31fresh  ready  eb3e9d0ffc1754efb6ccab971e7d67da9ce01990527155fbfdb2a15d3482989c  1
select id from releases;                       -- one row only
select session_id, count(*) from events group by session_id;
eb3e9d0ffc1754efb6ccab971e7d67da9ce01990527155fbfdb2a15d3482989c
u31cr 45 | u31cr2 87 | u31fresh 44

A.2 Store queries and their exact output (run 1, for comparison, gate-report.md's store) #

select seq, kind, payload from events where kind='hooks.activated' order by seq;
2   hooks.activated  {"epoch":1,"revision":"eb3e9d0ffc1754efb6ccab971e7d67da9ce01990527155fbfdb2a15d3482989c"}
116 hooks.activated  {"epoch":2,"revision":"6dde9d4308d6bc58ceb7d67b19bf1672be6b577717ca891637479a60dc5ec900",
                      "work_item_id":"work-532494c2-f25b-4d9e-be51-4c4c973406e2"}
select id, session_id, operation, signature, count, work_item_id from observer_cases;
act-50b6fe2bffe8b6e4  u31gate  cell.execution  "FileNotFoundError: [Errno 2] No such file or directory: 'python'"        1  None
act-78a27badb1eb484b  u31gate  cell.execution  'klbr_runtime.context.HostError: host_operation_failed: work item ...'     1  None
act-2eb5e8981d53f67e  u31gate  cell.execution  "ModuleNotFoundError: No module named 'klbr_runtime.maintenance'"           1  None
act-104f4e9a54ad1cfa  u31gate  cell.execution  "TypeError: 'CompletedProcess' object is not subscriptable"                 1  None
select count(*) from maintenance_assessments;   -- 0
select id, session_id, purpose, cause_kind, status, disposition, origin_kind, attempt_id from work_items;
work-input-1                   u31gate  user_input  input_frame       completed  consumed_by_turn  human  2772961a-483e-4461-9ffc-8dfa0a9ae5f8
work-input-46                  u31gate  user_input  input_frame       failed     NULL              human  400399cb-5e9b-4ee1-8598-fffcb49b08f3
work-input-48                  u31gate  user_input  input_frame       completed  consumed_by_turn  human  d2b20e30-eec7-44df-9dff-24ed090d2428
work-input-91                  u31gate  user_input  input_frame       completed  consumed_by_turn  human  f9ca5162-9d7c-4ad3-ae56-4dd186ea69e1
work-532494c2-f25b-4d9e-be51-4c4c973406e2  u31gate  repair  maintenance_ready  deferred  NULL  agent  None
work-input-190                 u31gate  user_input  input_frame       completed  consumed_by_turn  human  2a4bf537-38a2-400a-b08f-7990c5bc21b4
select id, state, hook_revision, hook_epoch from sessions;
u31gate  ready  6dde9d4308d6bc58ceb7d67b19bf1672be6b577717ca891637479a60dc5ec900  2

Run 1's own report quoted "two observer cases"; the store now shows four, because the final later-task turn added two more. All four are count=1 with no work item.

A.3 The sandbox, verbatim, and its probe outputs #

Profile /private/tmp/u31/cleanroom/sandbox.sb (applied with sandbox-exec -f <profile> env TMPDIR=/var/tmp/u31clean/tmp KLBR_CONFIG=/var/tmp/u31clean/klbr.kdl RUST_LOG=info /var/tmp/u31clean/bin/klbr-daemon; every worker the daemon spawns inherits it):

(version 1)
(allow default)
(deny file-read* (subpath "/Users/dawn")
                 (subpath "/nix/store")
                 (subpath "/var/folders")
                 (subpath "/tmp")
                 (subpath "/private/tmp"))
(allow file-read* (subpath "/var/tmp/u31clean")
                  (subpath "/private/var/tmp/u31clean"))

Probe 1 - staged tree readable, store openable, hidden paths denied (command and full output):

$ cd /var/tmp/u31clean && sandbox-exec -f /private/tmp/u31/cleanroom/sandbox.sb \
    env TMPDIR=/var/tmp/u31clean/tmp /opt/homebrew/bin/python3 -I -B /var/tmp/u31clean/probe_visibility.py
exit 0
SQLITE_OK
tmp_hidden False home_hidden False
('PermissionError', "[Errno 1] Operation not permitted: '/Users/dawn/proj/klbr/klbr-daemon/") /Users/dawn/proj/klbr/klbr-daemon/tests/m6_repair_gate.rs
('PermissionError', "[Errno 1] Operation not permitted: '/Users/dawn/proj/klbr/evidence/m6-") /Users/dawn/proj/klbr/evidence/m6-gate-report.md
('FileNotFoundError', "[Errno 2] No such file or directory: '/Users/dawn/Downloads/klbr-swarm") /Users/dawn/Downloads/klbr-swarm7-review/SOURCE-TRACE.md
('PermissionError', "[Errno 1] Operation not permitted: '/tmp/u31/gate/.releases/6dde9d4308") /tmp/u31/gate/.releases/6dde9d43.../klbr_hooks/defaults.py
('PermissionError', "[Errno 1] Operation not permitted: '/nix/store/209lschhyykqa6cfqawx04w") /nix/store/209lschhyykqa6cfqawx04ws4fyjbfwl-source/tests/fixtures/broken_capability/behavior/klbr_hooks/defaults.py
('PermissionError', "[Errno 1] Operation not permitted: '/Users/dawn/.prime/agent/auth.json") /Users/dawn/.prime/agent/auth.json
('READ_OK', 1627) /var/tmp/u31clean/behavior/klbr_hooks/defaults.py

Probe 2 - what the sandbox removes besides the answer (the confound):

$ sandbox-exec -f /private/tmp/u31/cleanroom/sandbox.sb /bin/ps -p 1
exit 71
sandbox-exec: execvp() of '/bin/ps' failed: Operation not permitted
$ sandbox-exec -f /private/tmp/u31/cleanroom/sandbox.sb /bin/ls /Users/dawn
exit 1
ls: /Users/dawn: Operation not permitted

Control probes in the same profile: /bin/df -h exit 0, /bin/ls /var/tmp/u31clean exit 0, /usr/bin/find /var/tmp/u31clean -maxdepth 1 exit 0, /usr/bin/curl exit 7 (connection refused; the daemon was already stopped), /opt/homebrew/bin/python3 exit 0. The reason ps alone dies: /bin/ps is setuid root (stat mode 0o104755, setuid bit set) and sandbox-exec refuses to exec a setuid binary. So the clean room removes process inspection - a legitimate discovery tool the model reached for (PermissionError: [Errno 1] Operation not permitted: 'ps' is observer case act-212bcd492b8eeb18) - not only the answer. That is why the flail in section 3 is not a clean capability measurement.

A.4 Leak surface found, and how absence is actually achieved #

Absence in this run is achieved by the deny-list, not by cleaning the disk, because some copies cannot be cleaned. Recorded honestly:

location (verbatim) status content
/Users/dawn/Downloads/klbr-swarm7-review/SOURCE-TRACE.md swept by dawn (directory removed, with klbr-swarm7-review.zip and klbr-v2-complete.tar.gz; hashes recorded by dawn: 99e8550413dfe484, b5b17984aef4a855) repair script for the same shape of task: print(f"ACTIVATED_CANDIDATE: {{release.id}}") (line 1972) and sys.stderr.write(f"CapabilityMismatchError: discord.ambient expected wake(ambient), got {dec.action}") (line 2012). This is what invalidated attempt 2
/nix/store/209lschhyykqa6cfqawx04ws4fyjbfwl-source remains, cannot be removed full klbr tree; klbr-daemon/tests/v2_integration_test.rs:2847 = 'return AttentionDecision.ignore("mentions temporarily muted")', and tests/fixtures/broken_capability/behavior/klbr_hooks/defaults.py:33 = the fixture with the defect
/nix/store/5zf4695sm51048cam7gxq6b5hwp16idn-h0rlzszbk5bn9xxcsxi8av8152qqqc2v-source remains same shape
/nix/store/8llihvc75c2rpp1v0fizfqp3rcq627ib-source remains same shape
/nix/store/cg2b3achv1z37h9fa02dyn4ybdwrf8h5-209lschhyykqa6cfqawx04ws4fyjbfwl-source remains same shape
/nix/store/d9jn3yy94ahzmgxbcn27h09akvfkj3m0-8llihvc75c2rpp1v0fizfqp3rcq627ib-source remains same shape
/nix/store/h0rlzszbk5bn9xxcsxi8av8152qqqc2v-source remains same shape
/Users/dawn/proj/klbr/tests/fixtures/m6_broken_capability/**, klbr-daemon/tests/m6_repair_gate.rs, klbr-daemon/tests/v2_integration_test.rs, evidence/*.md remains the repo itself: U30's scripted answer, the gate reports
python/klbr-runtime/tests/test_processes.py inside the staged tree removed from the staged copy (tests/, dist/, *.egg-info excluded) test_editable_defaults_match_attention_contract asserts ("discord.mention", {"action": "wake", "priority": "directed"})

The six /nix/store trees above were found by scanning the whole readable filesystem for the defect string, after the repo-only sweep had already missed two leak sources. That is the lesson worth carrying: a clean-room sweep has to cover nix store paths, Downloads scratch, .prime transcripts and home-directory caches, not just the repository under test.

A.5 Cost ledger, all attempts #

attempt requests prompt tokens completion tokens prompt cache hits cost @ $0.15/$0.60 per M
run 1 (contaminated, gate-report.md) 47 1,688,844 28,277 1,554,816 $0.2703
attempt 2 (invalidated: Downloads/nix leaks) 10 365,716 2,843 321,152 $0.0566
run 3a (clean profile, invalidated: staged python/.../tests) 10 200,817 4,247 152,576 $0.0327
run 3b (clean room, complete) 40 584,450 12,163 447,872 $0.0950
run 3 total (3a+3b) 50 785,267 16,410 600,448 $0.1277
TOTAL, all attempts 107 2,839,827 47,530 2,476,416 $0.4546

Run 1's bill was not driven by any single answer. It was driven by keeping one session alive across four turns: every model step re-sends the whole conversation, so prompt tokens per request climbed from 511 to 78,000, and turns 3 plus the later task were 87% of the $0.2703. Two of those four turns existed only because the model flailed first. The clean-room run, with the same model and a comparable number of steps, cost $0.1277 - fewer turns, not a cheaper model, is what changed the bill.

A.6 The three located causes, and the two extra findings #

Causes of the U31 outcome (each independently checkable in the appendix data):

  1. Step budget. max_steps = 10 per turn, not configurable in klbr.kdl (the key does not exist): the literal is the 4th argument of run_turn_loop_with_purpose at klbr-daemon/src/daemon.rs:1208 (argument on line 1212, cell budget Duration::from_secs(30) on 1213); the maintenance path carries its own copy at klbr-daemon/src/maintenance.rs:248/265/373. Both clean-room turns spent 9-10 of 10 steps on reconnaissance and ended by exhaustion with no candidate.
  2. Recurrence identity. Production min_recurrence = 2 (observation.rs:30, via session_registry.rs:604, never overridden by main.rs), evaluated per error signature and reset by the 60s grouping window. Two identical operator stimuli minutes apart produced two different signatures ('/Users/dawn', 'ps') and no work item; the U30 test's min_recurrence = 1 override is test-only, so the loop U30 certifies is not the loop production runs.
  3. Session-scoped activation. Activation writes hooks.activated plus the session's hook_revision/hook_epoch; the boot release comes from project_root/behavior. A new session therefore reads the source directory (appendix A.1: u31fresh pinned to eb3e9d0..., epoch 1), not any activated revision. "Transfers it" is false for new sessions unless the live source is updated, which activation does not do.

Extra findings, separate from the gate:

  1. A pending operator input is stranded across a restart. work-input-45 (u31cr, input event 45) stayed pending with readiness='ready' and no blocked_reason across two daemon boots and a client attach, while the eligibility predicate was satisfied and the session was ready. Neither the 50 ms periodic driver (daemon.rs:1830-1889, sessions_with_pending_work()) nor the startup recovery scan (daemon.rs:1805) took it; nothing in the daemon log records an attempt. It is left pending as evidence rather than worked around.
  2. Clean-room noise. Hiding /Users/dawn cost the model roughly half of turn 1 hunting for a workspace ("Hmm, /Users/dawn appears empty, or permission", "The task environment must be somewhere else"), every denied read became an observer case, and /bin/ps is unexecutable inside the sandbox because it is setuid. The clean room therefore removes discovery tools as well as the answer, which limits how far the observed flail can be read as a model-capability measurement.

A.7 Process state at hand-over #

All helper processes were stopped and the ports confirmed free:

$ lsof -nP -iTCP:8765 -sTCP:LISTEN   # exit 1, no output
$ lsof -nP -iTCP:8791 -sTCP:LISTEN   # exit 1, no output
$ lsof -nP -iTCP:8792 -sTCP:LISTEN   # exit 1, no output
$ pgrep -fl klbr-daemon              # exit 1, no output
$ pgrep -fl shim.py                  # exit 1, no output
$ pgrep -fl llm_proxy.py             # exit 1, no output

Stopped: the clean-room daemon (pid 98081, sandbox-exec wrapper + klbr-daemon), the Qdrant BM25 / gemini embedding shim (pid 20195, port 8791), the provider logging proxy (pid 20198, port 8792), the run-1 gate daemon (pid 59639) and every driver script. No provider calls were made during this hand-over work.