- The review's file evidence rebuilds the whole diff without context lines (
-U0) when any file's section would be clipped or left out, then applies the same 16 KiB / 6 KiB budget; the item says so in context, and dropped context alone does not make it partial. On seeded requirement drops the dropped code reached the packet in 18/18 cases instead of 15/18, and in 41/41 instead of 39/41 on drops not used to choose the change; the opus reviewer caught the three earlier misses, with 0/6 corrections on the references ($0.61 for 11 calls). Mechanism evidence on constructed drops, not a benefit claim. - On Claude Code the SessionStart report goes to the user as the hook's
systemMessage instead of plain stdout, which Claude Code put in the model's context: the supervised agent was handed the blind-spot list, every shape that destroys .rabadon/guard.json unrefused, and ~2 KB written for a person. The agent now gets the handoff plus a short brief as additionalContext (263 bytes instead of 1975 on a project with a suite). Cursor and rabadon run are unchanged. - Retain full ordered user messages in a session journal, read a bounded first/ recent window for optional model judgments, and preserve rapid corrections.
- Add an explicitly opt-in Claude semantic completion review. Grounded feedback continues the same actor; two constructed repairs completed in the live pilot, while two legitimate controls received no correction. This is not a claim of general reliability or net token savings; default behavior stays unchanged.
- Record reviewer token classes, actual model and list cost; unknown costs stay unknown. Usage reports these reviews without claiming estimated savings.
- The review's evidence is a bounded selection of the current turn instead of the transcript's last 24 KiB: the first 8 KiB and last 12 KiB of items, up to 8 KiB of distinct middle actions (tool calls, failed results, feedback already given this turn), repeated identical actions and dropped observations counted in place, items clipped at 2 KiB with both ends kept, tool inputs keeping their object shape, thinking excluded, meta and compaction records labelled as such, and only the transcript's last items when the turn's start was not recorded. On 92 real turns over 200 KB the first edit reaches the packet in 43 instead of 3, all edits in 136 of 432 instead of 11; the packet grows from a median 6.8 KB to 25.9 KB, so each reviewer call costs more input. Whether the reviewer judges better with it is measured only on constructed turns: reviewer-only on three long constructed turns, tail window 1/6, turn selection 5/6 expected verdicts.
- A reviewer answer wrapped in one
` code fence is unwrapped before validation and the prompt asks for the bare object; 7 of 12 answers in the reviewer-only run were fenced and would have been skipped silently. - The verdict carries
goal_ids and evidence_ids as separate lists; a correct verdict needs one of each, and an id in the wrong list is rejected. With one list the model named the user's message in its reason but not in the list, so 6 of 9 correct verdicts on real turns were dropped; with two lists 11 of 11 answers validated. SEMANTIC_VERDICT records both lists. - After a second adversarial review: the middle keeps the turn's first distinct actions instead of the last (first edit reaches the packet in 61 of 92 real turns instead of 43); feedback already given rides in the envelope as
prior_feedback and can no longer be evicted by the actor's own repair; markers are not counted as items; a tool input with many keys becomes one bounded item; unknown may cite nothing; a Stop with nothing observed since the prompt skips the reviewer instead of spending a call; --rescore takes the run's schema. A shadowed variable had written a 36 MB survey table into the packet evidence; regenerated (38 KB). - Read repair policy fields only inside the top-level repair object; unrelated mode/check fields can no longer authorize an automatic proposal or replace its check.
- Stream transcript accounting for budget decisions, incremental Stop tokens and the close counter, retaining token classes, call counts and model selection without loading the complete session into RAM. Explicit budget behavior is preserved.
- Stream mode-history/counter/handoff ledger reads rather than loading day files wholesale; retain only the counter events and the last six handoff refusals.
- Do not count absent follow-up evidence as an instant repair: require a later green suite observation with no conflicting failure.
- Evaluate and reject the assist candidate after a live paired Claude run: both arms pass 6/6 tasks, but assist uses more tokens in the pilot. Retain the candidate only as an archived reproducible patch and evidence, not a runtime mode.
- Breaking: the JavaScript API is removed.
import { pipeline, session } from 'rabadon' (index.mjs, core/) was the first product direction and outlived it; nothing in the guard used it. rabadon watch and rabadon ui went with it (they read only that API's bus). The node gate (hooks/gate.mjs) is retired: rabadon init has installed the native gate since 0.2.0, and settings that still name the old path are recognized and replaced. - repair locks a test file whose name JSON has to escape. rabadon-truth hands repair the test list as JSON and repair read each name as raw bytes, so a test file named with
" or \ was hash-locked under paths that do not exist, and a proposal that neutered it came back VERIFIED. Names are decoded now, and that proposal is rejected. - Control bytes are escaped in every JSON line rabadon writes. A check that failed in color wrote a raw ESC into a chained ledger line (pipeline), a test file named with a tab made
rabadon-truth --json invalid, and a project directory named with a control byte did the same to drift's ledger line. - The ledger's lock is
flock alone. The <day>.jsonl.lock file is gone: two writers could each steal the same stale one, and a writer queued without bound behind a held lock. A .lock file left by an older version is ignored. - The gate reads a hook event up to 16 MiB. Past it the event is not judged on a prefix: a tool call is refused by the sealed rule
event-unread (recorded as WOULD_BLOCK in watch), and any other hook is recorded as CHECK_SKIPPED and let be. A 64 MiB event used to hold about 700 MiB and be allowed. - drift's goal-drift event is chained. It was appended outside the chain, which left its whole day UNVERIFIABLE to
rabadon audit.