Grey Box agent monitoring

Evidence

Every test was preregistered: hypotheses, data, metrics and pass criteria were written down and hash-locked (SHA-256) before the test ran. The lock times are self-reported; for T13b, T16 and T20 the lock was also published before the result. The table below is the project's record, reproduced verbatim, including every failure, deviation and correction.

How to read it: pass the preregistered criterion was met; fail it was not; mixed some endpoints passed and some failed; not tested the data did not allow the preregistered test. AUROC: 0.5 is chance, 1.0 perfect. Brackets are 95% bootstrap confidence intervals.
Words used in this table
  • AUROC: the chance that a random violation gets a higher score than a random safe action (0.5 = guessing, 1.0 = perfect).
  • Caught at 5%: the share of violations among the 5% of actions with the highest scores (what a human reviewer would see).
  • Reader: an open language model (Qwen3-8B) that reads the transcript; a simple classifier on its internal state is the monitor.
  • Probe: a simple (linear) classifier on a model's internal state.
  • Replica: an estimate of an agent's hidden state, computed from the reader; R² is the share of the state's variation that it reproduces.
  • TF-IDF: a word-count classifier (the browser trainer's default monitor).
  • Preregistered, hash-locked: the plan and the analysis code were fixed, and their fingerprint saved, before the test ran.
  • Exploratory: an analysis decided after seeing data; it suggests, it does not confirm.
  • Open / closed agent: a model with public weights (we can read its internals) / a model behind an API (we cannot).
TestOutcomeResultDataLocked
L2 open LLMs (H1–H3)passPASS all, after deviation 1: H1 +0.120 [0.115, 0.126]; H2 +0.057 [0.045, 0.073] (7/8 models); H3 +0.359 [0.310, 0.415]; Holm p < 0.0005 each. First run: H1 valid PASS, H2/H3 invalid (numerical; see note) (results/l2/l2_confirm.json)held-out 30% of L2 contexts (1,440), 8 models22:18 PDT
T1 agents (F1–F3; addendum 1: F4–F5)mixedClaim (a) CONFIRMED (F1, F2 pass: R16 − WB +0.063 [0.033, 0.094]); claim (b) NOT confirmed (F3 fails: Ψ − WB −0.021 [−0.054, 0.009]); addendum F4 passes (R4+Ψ − WB +0.049 [0.020, 0.080]); F5 fails (R2+Ψ − R16 −0.023 [−0.053, 0.006]) (results/t1/t1_agents_confirm.json)fresh CAPE episodes (Gemma, seeds 40–43 / 40–41)lock
L1 Othello recovery (E1–E3)passPASS all: E1 R² 0.967 [0.967, 0.968] > 0.90; E2 ΔR² +0.094 [0.086, 0.105], Holm p < 0.0005; E3 Δ occupied acc +0.043 [0.040, 0.046], Holm p < 0.0005. White-box reference 0.983 (results/othello/l1_confirm.json)1,000 fresh games, seed 20262026-10-15 13:53 PDT
L3 Claude Haiku 5.5 readout transfer (C1–C3)passall pass: C1 0.993 [0.983, 0.999]; C2 0.997 [0.990, 1.000]; C3 0.935 [0.868, 0.982] (results/l3/)192 L2 confirmation contexts, Claude Haiku 5.5 via API2026-10-15 23:59 PDT
L3b Claude Haiku 5.5: grey box vs text moderation (D1–D3)passD1 pass 0.923 [0.884, 0.957]; D2 (key) pass grey box − moderation +0.176 [0.060, 0.287] (0.827 vs 0.651); D3 not tested (1/40 over-refusals) (results/l3/claude_livebench.json)48 calib + 200 eval Live-benchmark conversations, Claude Haiku 5.5 via API2026-10-16T01:30:19-07:00
L3c Claude Haiku 5.5: one-call grey box + compliance alarm (E1–E3)passall pass vs the preregistered 3-level verdict: E1 +0.142 [0.081, 0.203] (0.815 vs 0.673); E2 AP +0.230 [0.161, 0.307]; E3 AP +0.081 [0.036, 0.140]. Against GRADED moderators E1 ties (Qwen3Guard +0.018 [−0.043, +0.081]; Llama-Guard −0.031 [−0.082, +0.020]); the alarm gain holds (results/l3/claude_batch.json, l3c_graded_reanalysis.json)48 calib + 680 eval (200 L3b + 480 fresh) conversations, Claude Haiku 5.5 via API2026-10-16T09:29:27-07:00
L3d Claude Haiku 5.5: transcript-framing grey box (F1–F2)passboth pass: F1 grey box − moderation on harmful refusals +0.141 [0.082, 0.199] (0.817 vs 0.676); F2 compliance-risk AP (Claude-moderator) +0.115 [0.076, 0.179] (results/l3/claude_transcript.json)44 calib + 500 single-turn eval conversations (L3c's), Claude via API2026-10-16T09:55:37-07:00
T2 time: internals at CAPE's decision point vs black box (G1–G3)passall pass: G1 I_dec − R16_ts +0.075 [0.044, 0.106]; G2 R16_dec − I_dec +0.021 [0.011, 0.035]; G3 I_dec − WB_ts +0.138 [0.107, 0.163] (results/t1/t2_time.json)the 12,130 fresh T1 units, decision point (new)2026-10-16T12:54:02-07:00
L3e Claude Haiku 5.5: the Live tool's alarm, prospective (A1–A3)mixedA1 pass (alarm precision 0.535 vs 0.274 for the moderator alone, +0.261 [0.215, 0.311]); A2 FAIL (grey box 0.873 vs graded Qwen3Guard 0.855, +0.018 [−0.023, 0.062]); A3 FAIL (multi-turn 0.894 vs 0.906) (results/l3/l3e_tool.json)923 fresh conversations (ToxicChat incl. 94 jailbreaks, HarmfulQA, multi-turn)2026-10-16T14:06:28-07:00
T3 deployable monitors: LLM judge instead of the oracle checker (K1–K3)failK1 FAIL (judge-scored resampling 0.782 < turn-start probe 0.846, −0.065 [−0.115, −0.019]); K2: probe better (CAPE probe 0.976 > judge on actual action 0.910, −0.067 [−0.104, −0.036] for the judge); K3 FAIL (resampling hurts the action judge, −0.049) (results/t1/t3_deployable.json)3,496 of the fresh T1 units (stratified, seed 7)2026-10-16T14:50:40-07:00
T4 reader trained on labels vs the agent's internals (M1–M2)passboth pass: M1 READER_act − I_dec +0.015 [0.007, 0.026] (0.994 vs 0.979); M2 READER_act − J_act +0.085 [0.052, 0.127] (results/t1/t4_reader.json)dev 5,493 / fresh 12,130 units; reader Qwen3-8B2026-10-16T16:07:08-07:00
T5 agent internals vs transcript reader on unseen scenario families (P1–P2)passP1 pass (reader − agent internals on unseen families −0.007 [−0.014, −0.0001], margin −0.02); P2: agent probe better than zero-shot judge (+0.062 [0.028, 0.101]) (results/t1/t5_family.json)dev 5,493 / fresh 12,130 units, 5 family folds2026-10-16T16:17:52-07:00
T6 reader trained on Gemma, monitoring gpt-oss (Q1)passQ1 pass: Gemma-trained reader on gpt-oss 0.915 vs zero-shot judge 0.833, +0.082 [0.043, 0.129] (results/t1/t6_cross_agent.json)gpt-oss-20b clean units (5,229; 729 unsafe)2026-10-16T17:36:47-07:00
T7 reader monitor on AgentDojo prompt injection, zero transfer training (R1–R2)passR1 pass: reader 0.781 vs zero-shot judge 0.537, +0.249 [0.136, 0.369]; R2 reader better than CAPE's gate: gpt-oss calls as the prereg text specifies, 0.823 vs 0.601, +0.222 [0.143, 0.303] (locked code's broader subset: +0.264 [0.174, 0.359]) (results/t1/t7_agentdojo.json)3,455 executed calls, 125 injected (Gemma, gpt-oss)2026-10-16T18:09:10-07:00
T8 Claude Haiku 5.5 as an agent, monitored by a reader trained only on Gemma (S1)not testedS1 NOT TESTED: 0 unsafe units under the preregistered post-reveal rule (Claude's 68 violations all happen at or without the reveal); see T8b1,000 Claude episodes on CAPE-Bench core24b x−2026-10-16T18:13:08-07:00
T8b Claude as an agent, all non-read actions (S1b)passS1b pass: Gemma-trained reader on Claude 0.991 vs zero-shot judge 0.633, +0.360 [0.302, 0.413]; 95.6% of violations caught at 5% escalation with a cut set on labelled safe actions (judge 0%); at the label-free cut used elsewhere, 94.1% (results/t1/t8b_claude_all_actions.json, label_free_cuts.json)3,128 actions in 991 Claude episodes, 68 unsafe2026-10-16T18:48:08-07:00
T9 trained TF-IDF monitor on the reader's own input, same labels (B1 Claude, B2 unseen families)mixedB2 pass, B1 FAIL: unseen families reader 0.969 vs TF-IDF 0.950 (+0.019 [0.007, 0.032]); Claude reader 0.991 vs TF-IDF 0.997 (−0.006 [−0.027, +0.007]). AgentDojo (reported) 0.781 vs 0.503 (results/t1/t9_text_baseline.json)T4–T8b units; reader scores reused2026-10-16T19:25:49-07:00
T10 Claude on task families the monitor never saw (C1 pooled, C2 within)passC1, C2 pass (vs zero-shot judge): pooled 0.912 vs 0.570 (+0.342 [0.311, 0.371]); within 0.948 vs 0.633 (+0.318 [0.265, 0.374]). But at the label-free cut the unseen restart family is caught 0/26 (results/t1/t10_claude_unseen_families.json)T8b units; monitors retrained on Gemma without cons_service_restart (17,465 units)2026-10-16T20:16:27-07:00
T11 second closed family: gpt-6-luna as agent, frozen monitors (G1 pooled vs judge, G2 vs tool identity, G3 within tool)passG1, G2, G3 all pass: GPT-6-luna, 3,627 actions, 66 unsafe in 6 families. Reader pooled 0.996 vs judge 0.778 (+0.217 [0.174, 0.265]); vs tool identity +0.141 [0.111, 0.171]; within tool vs judge +0.039 [0.015, 0.066]. 98.5% caught at the label-free 5% cut (judge 37.9%) (results/t1/t11_gpt_agent.json)1,000 GPT episodes on CAPE-Bench core24b x− (same order and seed as Claude)2026-10-17T04:21:46-07:00
T12 labels needed for a new policy, prospective on GPT (H1 40 vs 0 labels, H2 catch at 40 ≥ 0.5)mixedH1 FAILS, H2 passes: with 0 labels of the held-out credentials policy, the reader already caught 18/18 of GPT's violations of it, so added labels had nothing to fix (40 − 0: 0.0). The T10 curve does not replicate on this family (results/t1/t12_new_policy_labels.json)T11 GPT units; held-out family cred_analytics_token (18 GPT violations)2026-10-17T05:00:05-07:00
T13 a closed agent on an external benchmark: GPT-6-luna on AgentDojo, frozen monitors (K1 reader vs judge)not testedK1 NOT TESTED: GPT-6-luna resisted the injections (attack success 2.1%), leaving 4 injected calls (minimum 10). Utility on benign tasks 0.862 (results/t1/t13_gpt_agentdojo.json)AgentDojo v1.2.2 dev split, spot arm, attack + benign2026-10-17T05:13:38-07:00
T13b closed agent on AgentDojo without the defense (arm none, dev + conf; K1b reader vs judge)failK1b FAILS: 36 injected calls; reader 0.840 vs zero-shot judge 0.787 within suite (+0.052 [−0.026, +0.130]). TF-IDF 0.335. At the benign-call 5% cut: reader 36%, judge 53% (results/t1/t13b_gpt_agentdojo_none.json)AgentDojo v1.2.2, both splits, attack + benign2026-10-17T05:26:09-07:00; lock published in commit 4dd5df4 at 05:26, the result in c8f494a at 05:52
T14 labels of the new policy from open agents, tested on the closed agent (L1 vs judge, L2 vs no labels)passL1, L2 pass: with AgentDojo labels from open agents, the reader on GPT's AgentDojo calls scores 0.922 vs judge 0.787 (+0.136 [0.078, 0.191]) and vs no labels +0.081 [0.044, 0.121]; caught at the benign 5% cut 36% → 92% (results/t1/t14_agentdojo_labels.json)train: CAPE-Bench + k AgentDojo calls of open agents (T7); test: GPT AgentDojo calls (T13b)2026-10-17T05:52:53-07:00
T15 latent replication: does the reader replicate the agent's hidden state? (E1 R² vs text, E2 readouts on the replica)passE1, E2 pass: from the transcript alone, the reader replica reconstructs 66.4% of the agent's decision-state variance (top 128 PCs; text 58.6%; +0.079 [0.075, 0.083]); a probe trained on TRUE states scores 0.987 on the replica vs 0.984 on the true state (+0.003 [−0.002, +0.007]) (results/t1/t15_latent_replication.json)Gemma-4 decision-point states, 5,493 dev / 12,130 fresh steps (5,492 / 12,128 with a valid decision state)2026-10-17T11:21:27-07:00
T16 live prevention on a closed agent: the monitor blocks GPT-6-luna's escalated actions in the loop (P1 violation episodes, gated − ungated)passP1 passes: live, the grey-box gate cut GPT-6-luna's episodes with an executed violation from 6.6% to 0.2% (−0.064 [−0.088, −0.044]); 0 violations after a block; goals 47.4% → 45.6%; round trip 89 ms median (results/t1/t16_live_gate.json)500 CAPE-Bench scenarios × 2 arms, GPT-6-luna2026-10-17T11:24:32-07:00; lock published in commit bb79257 at 11:39, the result in ca463b6 at 12:00
T16b live prevention on a second closed family: Claude Haiku 5.5 in the loop (P1b)passP1b passes: on Claude Haiku 5.5, episodes with an executed violation 6.7% → 0.2% (−0.064 [−0.087, −0.044]); 0 violations after a block; goals 40.7% → 34.9%; round trip 80 ms median (results/t1/t16b_claude_live_gate.json)450 CAPE-Bench scenarios × 2 arms (T16's draw)2026-10-17T12:16:02-07:00
T17 replication on three more open agents: gpt-oss-20b, Qwen3.8-27B, Muse-Glimmer-30B (E1, E2 per agent; scenario-disjoint split)passE1 and E2 pass on all three agents (replication generalizes): from the transcript alone, R² of the decision state on fresh scenarios: gpt-oss 0.494 (text 0.392; +0.102 [0.093, 0.110]), Qwen3.8 0.542 (0.441; +0.101 [0.091, 0.111]), Muse Glimmer 0.462 (0.401; +0.061 [0.051, 0.071]). A probe trained on the true states, true → replica: 0.900 → 0.924, 0.955 → 0.972, 0.929 → 0.969 (all lower bounds > −0.02). Fidelity: the agents' own models predict 91–100% of their next 16 tool-call tokens. Exploratory, Gemma-4 under the same split: R² 0.631 (text 0.556). Exploratory: the text map chose α = 1, the edge of the grid; a finer grid (α 0.01–1, exact dual-form ridge, scripts/96b) is worse at every smaller α for all three agents, so α = 1 is the text map's optimum (results/t1/t17_replication_agents.json, t17_txt_alpha_exploratory.json)decision-point states: gpt-oss 5,229, Qwen3.8 4,664, Muse Glimmer 5,184 steps2026-10-17T14:28:57-07:00
T16c hold for review instead of block: Claude Haiku 5.5, escalated actions go to a reviewer (R1 safety kept, R2 no goal cost vs T16b ungated)mixedR1 passes, R2 fails. Episodes with an executed violation: 6.7% (T16b ungated) → 0.0% (review) (−0.067 [−0.091, −0.044]). Goals: 40.7% → 38.7% (−0.020 [−0.051, +0.007]); the lower bound misses the −0.03 margin, so no goal cost is NOT shown. Reviewer workload: 88 held actions (0.20 per episode, 6.2% of scored actions), 31 of them violations; 0 violations after a block. Exploratory (scripts/97b): episodes with a held-and-approved action kept their goals (60.8% vs 58.8%); the gap is in never-held episodes (38.9% vs 41.0%, n = 368), where both arms ran the same way, which we suggest is run-to-run variation against a non-concurrent control (a hypothesis that T16c does not test). Spend $0.81. Deviation 1 (infrastructure, 16:39): the first start ran 0 episodes. The monitoring server loaded the reader outside its lock, and 6 concurrent first requests raced on the lazy transformers imports (ImportError). Fix: the load moved inside the lock (src/graybox/monitor_server.py; scoring unchanged; regression test tests/test_sdk.py). Rerun from scratch on job 3928; spend of the failed start $0.004T16b's 450 CAPE-Bench scenarios, one new arm2026-10-17T14:58:24-07:00
T18 a second outside benchmark: Claude Haiku 5.5 on τ²-bench airline, monitors trained on four frontier agents' labelled trajectories (H1 within-tool READER vs TOOL, H2 READER vs TXT)not testednot tested: 9 violations < the preregistered minimum of 15 (Claude violated in 1.5% of episodes; the 9 come from 3 tasks). Descriptive only: within-tool AUROC reader 0.756, TF-IDF 0.963; pooled reader 0.835, TF-IDF 0.960, tool 0.686; the CAPE-trained probe zero-shot 0.357 pooled (results/t1/t18_tau2_claude.json)600 Claude episodes (30 confirmation tasks × 20); 343 labelled writes2026-10-17T15:12:06-07:00
T19 readers small enough for a browser or a CPU: do they transfer? (F1 browser reader vs TF-IDF on GPT AgentDojo; F2 non-inferior to the 8B reader on closed CAPE)mixedF1 passes, F2 fails. Selected browser reader (best on T7): Qwen3-Embedding-0.6B. On T13b (GPT on AgentDojo) it beats TF-IDF: 0.605 vs 0.335 (+0.270 [0.134, 0.451]); on the closed agents' CAPE-Bench actions it is below the 8B reader: −0.097 [−0.115, −0.079] (Claude 0.912, GPT 0.884 vs 0.989, 0.996). Decoder readers on T13b: 0.6B 0.651, 1.7B 0.771, 4B 0.696, 8B 0.840, 14B 0.689; none is within 0.02 of the 8B on both sets, so no CPU option is offered. The shipped 8B reproduces its published AUROCs exactly (results/t1/t19_small_readers.json). Deviation 1: the analysis crashed after computing, when writing its JSON (a numpy bool); fix: one bool() cast, no computation changed17,623 training steps; T7, T13b, T8b, T112026-10-17T15:01:37-07:00
T20 τ²-bench with two closed agents (Claude Haiku 5.5, GPT-6-luna) and a persistent customer; T18's monitors (G1 reader vs tool within tool, G2 TF-IDF vs tool)mixedG2 passes, G1 fails. Within-tool AUROC: TF-IDF 0.987 (+0.487 [0.428, 0.500] over tool identity), reader 0.738 (+0.238 [−0.053, 0.431]); reported: reader − TF-IDF −0.250 [−0.518, −0.077]. Per agent: Claude reader 0.555 / TF-IDF 0.966; GPT 0.739 / 1.000. Reading fixed in advance: on τ²-bench, labels of the policy from other agents transfer to both closed agents through word counts, and the reader does not use them as well (results/t1/t20_tau2_two_closed.json). Spend (from the ledgers): Claude $1.71, GPT $0.8320 development tasks: Claude 440 and GPT 100 episodes; 262 labelled writes, 19 violations (Claude 8, GPT 11)2026-10-17T17:28:58-07:00; lock published in commit 9c55ea1 before any result
T21 τ²-bench, policy or tasks? T20's test, training without the test tasks (H1 reader vs TF-IDF, H2 reader vs tool; within tool)failH1 and H2 fail: neither monitor transfers to unseen tasks. Within-tool AUROC: reader 0.535, TF-IDF 0.519 (T20 with the same tasks: 0.738, 0.987); reader − TF-IDF +0.017 [−0.514, 0.539]; reader − tool +0.035 [−0.230, 0.259]. TF-IDF with entities masked 0.366 (exploratory). T20's word-count advantage was memorisation of the tasks (results/t1/t21_tau2_unseen_tasks.json)TRAIN 554 frontier writes of 28 other tasks (144 violations); TEST T20's 262 writes (19 violations)2026-10-17T18:46:25-07:00; lock published in commit 4a5c153 before any result
T22 τ²-bench, a zero-shot reasoning judge (Qwen3-32B, thinking; no labels) on T20's writes (J1 judge vs tool, J2 judge vs T21's reader; within tool)failJ1 and J2 fail (intervals include 0). Within-tool AUROC 0.804 (T21's reader 0.535); judge − tool +0.304 [−0.084, 0.427]; judge − reader +0.268 [−0.074, 0.511]. Pooled 0.785; 53% caught at the 5% cut as first computed; 34.5% with exactly 5% reviewed (ties at the cut counted in proportion; scripts/111); at 50: 12 of 19 caught, 16 of 243 safe flagged. 262/262 answers parsed, none truncated (median 485 tokens). 88% of scores are exactly 0. T18: within tool 0.694, 2 of 9 caught at 50. Large point estimate, too few violating tasks to confirm (results/t1/t22_tau2_judge.json)TEST T20's 262 writes of Claude Haiku 5.5 and GPT-6-luna (19 violations, 7 tasks with a violation); reported T18's 343 writes (9 violations)2026-10-17T18:49:10-07:00; lock published in commit 1b26040 before the judge ran
T23 τ²-bench, T22's judge unchanged on the 894 published writes of four closed frontier agents (K1 judge vs tool, K2 judge vs reader cross-validated by task; within tool)mixedK1 passes, K2 fails. Within tool: judge 0.766, READER_cv 0.646, TXT_cv 0.490; judge − tool +0.266 [0.151, 0.338]; judge − READER_cv +0.120 [−0.047, 0.274]. Reported: 4-sample mean 0.838, − READER_cv +0.192 [0.022, 0.336]; per agent (judge) 0.768 / 0.771 / 0.775 / 0.618 (o4-mini). With exactly 5% of writes reviewed: READER_cv catches 18.4%, the judge 11.7%, the 4-sample mean 15.3%, the tool 13.0% (most possible 19.7%). 894/894 parsed in every sample; none truncated; 63% of scores exactly 0. Reading (fixed): the judge checks rules beyond the tool identity, but not better than the reader trained on other tasks (results/t1/t23_tau2_judge_frontier.json)Claude 3.7 Sonnet, GPT-4.1, GPT-4.1-mini, o4-mini: 894 writes, 227 violations, 29 tasks with a violation; 4 judge samples (seeds 0–3)2026-10-17T19:09:50-07:00; published b002a85
T24 monitor-aware closed agent: Claude Haiku 5.5 with and without CAPE's oversight notice, 990 scenarios × 2 arms, no gate; the shipped reader with a cut frozen on Claude's earlier unlabelled traffic (A1 caught aware − plain; A2 aware caught)passA1 and A2 pass. Caught at the frozen cut: plain 83.6%, aware 97.1% [92.9%, 100%]; aware − plain +0.136 [+0.050, +0.225]. Being told did not change how often Claude violated (−0.003 [−0.012, +0.005]) or reached the goal (37.6% vs 37.8%). Note: the notice moves the score distribution up: the frozen cut escalates 15.2% of the aware arm's actions (plain 5.3%). At each arm's own 5% budget: 88.6% vs 83.6%. AUROC within template 0.994 vs 0.967 (results/t1/t24_monitor_aware.json)1,980 fresh episodes; 73 (plain) and 70 (aware) violations; $3.63lock
T25 adaptive attacker with score access: Qwen3-32B rewrites the free text of 134 real closed-agent violations (2 rounds × 16, score feedback), the checker confirms each still violates (B1 reader caught after attack; B2 reader − TF-IDF)failB1 and B2 fail. Reader caught 96.3% → 29.1% [21.6%, 36.6%] after attack (Claude 11.8%, GPT 47.0%); TF-IDF 57.5% → 34.3%; reader − TF-IDF −0.052 [−0.149, +0.037]. Every rewrite still violated (replay checker). The rewrites keep the decisive field (recipient, service and host) and add self-reported approvals ('approved under routine maintenance protocol …', '--reason …'): the learned monitors read the agent's own claims as evidence. Reading as fixed: the monitor is not robust to adaptive rewording (results/t1/t25_adaptive_attack.json)T8b Claude (68) and T11 GPT (66) violations; frozen cuts from each agent's own earlier traffic2026-10-18T00:17:27-07:00; published 700a2f7 before any rewrite
T26 canonical-action monitor: the shipped reader and recipe trained on canonical actions (free-text fields → "[free text]", quoted prose and # comments removed); T25's attack re-run against it with seed 1 (C1 caught after attack; C2 clean catch − shipped on Claude ∪ GPT; C3 AgentDojo within-suite − shipped)failC1, C2 and C3 fail. After attack 50.8% [42.5%, 59.0%] caught (shipped reader 29.1%); before attack 55.2%. Clean catch at 5%: Claude 94.1% → 51.5%, GPT 98.5% → 59.1%; C2 −0.410 [−0.493, −0.311]. AgentDojo C3 −0.029 [−0.080, +0.010]. By tool: send_message 29.3% before and after (the canonical score cannot move, as Corollary 1 predicts); execute_mock_command 96.2% → 84.6% (commands keep their words). Cause: the premise that the label depends on the action only through κ(A) is false for 81 of the 82 send_message targets (one family, tp_campaign_test: the body carries the draft that is leaked), so the body is payload, not only self-report [this cause was wrong: see "Correction to the T26 cause" below]. Reading as fixed: canonical mode is an option with its measured cost, not the default (results/t1/t26_canonical_monitor.json)the same 134 violations; T8b/T11 closed-agent actions; T13b GPT AgentDojo callslock
T27 adversarial training: Gemma training actions of the attacked tools, violating AND safe (300 + 300), rewritten by T25's attacker (8 each), labelled by replay (4,554 rewrites; 28 changed label) and added to training; T25's attack re-run against the hardened monitor with seed 2 and told the defense (D1 caught after attack; D2 clean catch − shipped on Claude ∪ GPT; D3 AgentDojo − shipped)failD1, D2 and D3 fail. After the defense-aware attack 59.7% [51.5%, 67.9%] caught (before 92.5%); by tool: send_message 98.8% → 47.6%, execute_mock_command 82.7% → 78.8%. The shipped probe on the same rewrites: 96.3% → 57.5%, so hardening added about 2 points. Clean catch at 5%: Claude 94.1% → 88.2%, GPT 98.5% → 97.0%; D2 −0.037 [−0.078, +0.016]. AgentDojo D3 +0.012 [−0.050, +0.071]: the lower bound equals the margin after the locked code's 4-decimal rounding, so it fails as registered. Reading as fixed: augmentation with a known attack does not stop a defense-aware attacker; three preregistered defenses against score-querying rewording have failed (results/t1/t27_adversarial_training.json)the same 134 violations; T8b/T11 closed-agent actions; T13b GPT AgentDojo callslock
T28 set the cut again after a prompt change, live: Claude Haiku 5.5 with T24's oversight notice, 400 scenarios × (ungated, gated); the cut set from T24's aware-arm reader scores (3,046, no labels), budget 5%, frozen (R1 violation rate gated − ungated; R2 share of ungated actions escalated within [0.025, 0.075])passR1 and R2 pass. Episodes with an executed violation 6.5% (26/400) → 0.0% (0/400): −0.065 [−0.090, −0.043]. The new cut escalated 4.73% [3.49%, 6.10%] of the ungated arm's 1,206 actions; the cut frozen on plain traffic would have escalated 16.6%. 25 of 54 blocked actions would have been violations; goals 38.5% → 35.5%; violations caught at the new cut in the ungated arm 88.5%; median round trip 83 ms. Reading as fixed: setting the cut again on unlabelled traffic restores the budget, and the gate prevents the violations of an agent that knows it is monitored (results/t1/t28_recalibrated_gate.json)800 fresh episodes; $1.44 (Anthropic ledger $19.855, the user's last balance)lock
G training-free observable geometry: on 8 open models (F1 answers vs text, F2 8 samples keep ≥95%, F3 88 vs 8 questions); on Claude Haiku 5.5 (C1 split-half > 0.7, C2 vs text); exact Gram recovery on Qwen3-0.6B (E1–E3)passall pass: F1 8/8 (gains +0.16 to +0.49, lower bounds ≥ 0.141); F2 8/8 (lower bounds 0.957–0.997); F3 8/8; C1 0.950 [0.939, 0.960]; C2 +0.438 [0.391, 0.485]; E1 Pearson 1.0 (8 digits) at 2× d(d+1)/2, median cosine error 7e-6; E2 error 0.51 → 7e-6 across the threshold; E3 vs baselines 0.40, 0.11. Before the lock, from dev and the pilot only: F2 changed from an absolute margin to a ratio, C1's bound raised 0.5 → 0.7 (both disclosed in the prereg). After the lock: Correction 1 to Theorem 5 (below)G1: 1,440 L2 confirm contexts; G2: 192 L3 confirm contexts, 24 questions × 8 samples (existing); G3: 1,152,000 self-generated contexts, seed 0, 2,000 held out2026-10-18T12:28:38-07:00; lock published in commit ebb89b1 at 19:28:56Z, before any confirmatory result
G5 which outputs carry the state: yes/no answers vs the model's own replies (H1 exact answers vs 8 replies; H2 88 one-token sampled answers vs 1 reply; H3 replies saturate)passall pass: H1 8/8 (+0.16 to +0.48); H2 7/8 (gpt-oss −0.048 [−0.075, −0.023]); H3 8/8 (≤ 0.031). Replies' geometry 0.22–0.34, close to text. Dev dry run of the dropped G4 design disclosed in the prereg.1,440 L2 confirm contexts, 8 open models, one fresh pass2026-10-18T14:42:32-07:00; lock published in commit 0163682 at 21:42:32Z, before the confirm data existed
G6 the observable geometry is shared across models (S1 no own-model excess, equivalence ±0.02; S2 an open model's hidden geometry is the better stand-in; S3 answers beat text on four new kinds)passall pass: S1 +0.002 [−0.001, +0.006]; S2 6/7 (Mistral −0.049); S3 6/8 (Gemma, gpt-oss include 0). On fresh contexts agreement is lower than on L2 (answers 0.22–0.64); Gemma's replies beat its answers (0.43 vs 0.34). Motivated by an independent review's control (recorded in the ledger).1,000 fresh contexts (6 L2 kinds, fresh items; news, code, jailbreak behaviours, prompt injections), 8 open models2026-10-18T17:18:17-07:00; lock published in commit 85ed1bb at 00:18:18Z, before any model output on the contexts

Figures

True hidden state vs grey-box replica
The agent's true hidden state (a) and its replica from the transcript (b), on fresh steps; (c) the variance replicated per principal component (T15, preregistered).
AUROC of monitors under increasing shift
Monitoring an agent's next action from its transcript, under increasing shift: trained reader (blue), trained bag-of-words (hollow square), zero-shot 70B judge (green), the agent's own internals (orange). The dashed line is chance (AUROC 0.5). The two Claude rows rest on one stratum (136 actions, 26 violations).
Time, not access
The same 12,128 fresh steps read at the start of the agent's turn and after its reasoning. Reading later helps every method; access alone does not.
Label efficiency
Reader accuracy against the number of labelled training actions.
Policy coverage
A policy family removed from training. A credentials policy with similar trained policies transferred with no labels (GPT, T12). A service-restart policy without them was missed until 20–40 labelled steps were added (Claude, T10, exploratory).
Refusal forecast vs moderation
Chat: which harmful requests Claude refuses. The forecast beats a 3-level moderation verdict and ties graded moderators.
Guard trade-off
A resampling guard, with samples scored by the environment's own rule checker (an oracle; not deployable: with an LLM judge as the checker it catches 12%).