feat(adjudicate): delta-aware re-judging — judge on additive change, hold on pure subtraction (JEF-391)#207
Merged
thejefflarson merged 1 commit intoJul 8, 2026
Conversation
…hold on pure subtraction (JEF-391)
Implements ADR-0023 ("the state is the context, the delta is the question").
The adjudication prompt keeps the full-state snapshot unchanged and gains a
"Changes since the last decisive verdict" section listing the ADDITIONS since
this entry's baseline (newly-reachable objectives, newly-running CVEs, newly-
exposed secrets, new posture, newly-corroborated behaviors), fenced like all
other evidence. The re-judge gate now re-judges on a non-empty ADDITIVE delta
(or no baseline / an LRU miss), and HOLDS the prior decisive verdict on a purely
SUBTRACTIVE change — a peer aging out or a pod vanishing no longer re-judges,
which stops the ephemeral-churn ping-pong at its root.
- surface.rs: JudgedSurface projects the entry's judged evidence from the SAME
rendered lines the prompt carries (no second source of truth); additions are a
per-category set-difference, so a modified element reads as removed+added and
re-judges (fail toward re-judging).
- verdict_store.rs: a bounded per-entry baseline (surface + decisive verdict),
set only on a decisive verdict (Uncertain never baselines), pruned with the
entry. In-memory only: after a restart the entry re-judges once before its
baseline is re-established.
- adj_gate.rs (extracted to hold mod.rs under the 1,000-line cap): the layered
gate — exact-fingerprint LRU hit / subtractive hold / breaker+backoff / judge.
- prompt.rs: the verdict-cache key is the FULL-STATE hash and EXCLUDES the delta
section, so an identical full state always keys identically (the LRU stays a
true exact-state guard, restart-safe with JEF-301) and the surface-delta gate
is the sole additive re-judge driver — resolving ADR-0023's open question.
Correctness guards (security-relevant): the full current state is ALWAYS in the
prompt (the delta only directs attention); a new element that makes an already-
reachable objective exploitable re-judges with both the full state and the new
element present; the delta section is sanitized/fenced.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VtjoJttCvBY4dzCoE4f9vP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes JEF-391. Implements the ACCEPTED ADR-0023 — "the state is the context, the delta is the question."
What changed
Today
build_judgment_promptis a static full-state snapshot with no "what changed" markers, and the re-judge gate is purely "the whole-prompt fingerprint changed" — so every new reachable object (ephemeral pods cycling) makes the model re-derive the world, and a known peer flickering out re-judges even though nothing was ADDED.Now:
prompt.rs): the full-state snapshot is UNCHANGED and gains one section —Changes since the last decisive verdict: <<<additions>>>— the ADDITIONS since this entry's baseline (newly-reachable objectives, newly-running CVEs, newly-exposed secrets, new posture, newly-corroborated behaviors),(none)when nothing was added, fenced/sanitized like all other evidence. The instruction directs the model to judge the current state as a whole with particular attention to whether the NEW elements introduce exploitation evidence or complete an exploitable path.state/verdict_store.rs): on a DECISIVE verdict the entry's judged surface (aJudgedSurface— reachable-objective lines, running-CVE lines, secrets, posture, behaviors) is snapshotted with that verdict as the entry's bounded baseline. The delta iscurrent_surface \ baseline.adj_gate.rs, extracted from the orchestrator to holdmod.rsunder the 1,000-line cap): re-judge on a non-empty ADDITIVE delta, or no baseline (first judgment), or an LRU miss; a purely SUBTRACTIVE change (a peer aged out, a pod vanished) HOLDS the prior decisive verdict — no fresh model call — since its surface only shrank and removal is de-escalated by the existing recency/reversion path (JEF-141), not a re-judge.Correctness guards (security-relevant)
!additive-without-baseline both re-judge.fence_list-sanitized (a>>>injection in an objective key is stripped — tested).Resolving ADR-0023's open questions
VerdictEntryalongside the LRU (Option<VerdictBaseline>), projected from the SAME rendered prompt lines (no second source of truth), bounded by the entry's proven surface and pruned with the entry. In-memory only — after a restart the entry re-judges once (fail-safe) before its baseline is re-established; the LRU is still journal-re-seeded (JEF-301).(none)or additive, while the model prompt still differs.Tests (all in this PR)
adj_gate_tests.rs(the layered gate),adjudicate/tests/delta.rs(the delta prompt + surface math + correctness guards + the cache-key resolution), and averdict_storebaseline round-trip.engine/tests.rs::an_uncertain_re_judge_keeps_showing_the_prior_decisive_verdictwas updated to drive its re-judge with an ADDITIVE change (adding a CVE) rather than a subtractive one, since ADR-0023 deliberately no longer re-judges on pure subtraction.Checks
cargo fmt,cargo clippy --all-targets(warnings clean),cargo nextest run— 794 passed, 2 skipped, including thefile_size_guardcap check (all files < 1,000 lines).Scope notes / risks
adr-0023-delta-aware-adjudication); this PR is the implementation off latestorigin/main.🤖 Generated with Claude Code
https://claude.ai/code/session_01VtjoJttCvBY4dzCoE4f9vP