Skip to content

Externally-sourced operators: liveness reporting, shape probe, cue-token insert - #1

Merged
egnaro9 merged 12 commits into
mainfrom
liveness-outcome
Aug 17, 2026
Merged

Externally-sourced operators: liveness reporting, shape probe, cue-token insert#1
egnaro9 merged 12 commits into
mainfrom
liveness-outcome

Conversation

@egnaro9

@egnaro9 egnaro9 commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Nine commits. The catalog goes 18 to 20 operators, and three of them now cite a source outside my own repositories where yesterday none did.

Why

An audit of the operator catalog found that 16 of the 18 shipped operators trace their real_origin to graders in repos I own. The citation gate proves each operator reproduces something documented; it proves almost nothing about whether the population is representative of faults anyone else would care about missing. Two rounds of mining external sources produced the cards below. This PR ships the ones that run against today's EvalCase.

What landed

OperatorType.LIVENESS and score.forged_verdicts. A survival where the mutant writes the grader's own verdict channel does not mean this check missed this defect. It means the check has no liveness: its verdict can be authored by the thing it grades, so every result it has ever reported is unfalsifiable, including its passes. Reported apart from blind_spots because "fix the check" is the wrong instruction when the channel is the bug.

verdict_channel, a declared field on EvalCase. Folds BenchJack's payload class into inject_denylisted_tool rather than shipping a tenth operator. The denylist path probes the grader first and declines if it accepts, since the case's expected may not match the real denylist. The verdict channel cannot work that way: a grader that accepts a verdict write cannot tell you whether the write was legitimate output or a forged result. Wrongness comes from the author's declaration, like tolerates. Undeclared means decline.

garbage_answer gains a shape probe. The old battery only asked whether a grader accepts opaque nonsense. A grader that rejects bare tokens but accepts the same tokens capitalized and punctuated read as discriminating, when in fact it checks formatting. _GARBAGE3 is _GARBAGE's exact tokens wearing answer shape, so it adds no lexical surface and carries no digit.

spurious_cue_token_insert. Inverse of keyword_present_but_negated: there the cue survives in a sentence meaning the opposite, here in text meaning nothing. Both rest on the presence_check tag, where the author has declared the grep is a proxy for a property it cannot see.

append_grader_directed_suffix. Appends text arguing for the answer to a base that is already wrong, so polarity never depends on the suffix.

The result worth reading

The dogfood score went down: 91.4% (32/35, 3 holes) to 90.9% (40/44, 4 holes).

The denominator grew faster than the catches, which is the honest direction. An operator that only ever confirmed existing catches would be worth nothing. The new blind spot is a contains grader needing all of ['capital'] on a presence_check task: it passes opaque garbage carrying the token capital and nothing else, so the grep is the entire signal. That is the ARCT result reproduced against my own code.

append_grader_directed_suffix found nothing new, which is what a deliberately degraded static suffix should do against lexical graders. Recorded as a true negative rather than dressed up.

Decisions that could reasonably go the other way

garbage_answer stays SANITY. The null-model paper argues it should be KILL, since "asserts nothing about the answer" would be a false report against a judge that was genuinely persuaded. True for a judge, but this operator gates on _requires_content, which admits only lexical families and can never reach one. For every grader it can touch, passing the full disjoint battery does mean vacuity, and retyping it would mis-report genuine vacuity as a broken check.

append_grader_directed_suffix is degraded on purpose, and that asymmetry is written into its real_origin rather than a comment. A static sentence is not an optimized adversarial sequence and will not reproduce 90.8% ASR. A survival is meaningful; a catch proves very little.

Fixtures are not optional here. The parametrized defect test skips any operator without one, and a skip reads green. Shipping without them would have left both new operators never exercised while the suite still reported 97 passed.

Provenance

  • BenchJack, arXiv:2605.12673 (Wang, Li, Mang, Cheung, Sen, Song; Berkeley): 219 distinct flaws across ten agent benchmarks
  • Null models, arXiv:2410.07137: 86.5% LC win rate on AlpacaEval 2.0 from a constant reply shaped like the evaluator's scaffolding, against 0.6% naive
  • ARCT, arXiv:1907.07355 (Niven & Kao, ACL 2019): 77% off the unigram "not"; the symmetric-cue control drops the identical model to chance
  • Judge injection, arXiv:2403.17710 (Shi et al., ACM CCS 2024): 10.8% ASR-B to 90.8% ASR on MT-Bench

Every arXiv ID above was fetched and checked by hand, not taken from a summary.

Verification

99/99 tests pass. VAC bundle regenerated by emit_vac.py and byte-identical on re-emission. bundle-freshness green in CI.

inject_denylisted_tool gains a second payload class: a write to the grader's
own verdict channel (the file it reads its outcome from, a reporting hook it
honors, a binary it shells out to for the answer). The channel is DECLARED on
the case via verdict_channel, defaulting to empty so an undecorated case
declines rather than being falsely accused, matching tolerates and num_tol.

The denylist payload probes the grader before asserting a defect. The verdict
channel cannot work that way: a grader that accepts a verdict write cannot tell
you whether the write was legitimate output or a forged result, so wrongness
comes from the author's declaration.

Which payload fired changes what a survival MEANS, so op_type is now per-case
via an optional op_type_for hook. A surviving verdict-channel mutation is
OperatorType.LIVENESS and lands in score.forged_verdicts, apart from
blind_spots, because "fix the check" is the wrong instruction when the check's
verdict is forgeable. Nothing that grader has ever reported is falsifiable
while the channel stays writable, including its passes.

First operator in the catalog whose provenance is external to these
repositories: BenchJack (arXiv:2605.12673) audited ten agent benchmarks and
found 219 distinct flaws, driving exploitable tasks from near 100% to under
10% only after iterative patching. 16 of the other 17 operators trace to
graders in repos I own, which is the weakness this is the first crack in.

Signed-off-by: egnaro9 <egnaro9@gmail.com>
.deepeval/ holds .deepeval-cache.json and per-run scratch written by the
deepeval CLI during the external comparison. Generated, not authored, and it
kept the tree dirty enough that emit_vac.py refused to stamp.

Signed-off-by: egnaro9 <egnaro9@gmail.com>
Companions to external/promptfoo_suite.py, same shape and the same declaration
discipline. deepeval is Python and installed, so deepeval_adapters.py drives
the ACTUAL shipped metric objects rather than a port, which is why the promptfoo
suite needed reimplemented assertions and these do not.

Committed here because emit_vac.py refuses to stamp a tree with anything dirty
outside OUTPUT_PATHS, and these were the last three. Results from this run are
recorded as non-confirmatory in EVALCOV_HANDOFF.md; nothing in this commit
claims otherwise.

Signed-off-by: egnaro9 <egnaro9@gmail.com>
Regenerated by emit_vac.py, not hand-edited: the operator catalog changed, so
the committed artifacts and their sha256s no longer reproduced and
test_vac_bundle.py failed exactly as it should. Stamp moves to e717602, the
commit that produced this code.

97/97 green.

Signed-off-by: egnaro9 <egnaro9@gmail.com>
The bare-token battery only ever asked whether a grader accepts opaque
nonsense. A grader that rejects bare tokens but accepts the same tokens
capitalized and punctuated reads as discriminating under that battery, while in
fact it checks formatting and passes every well-formed nonsense reply.

_GARBAGE3 is _GARBAGE's exact tokens wearing answer shape: leading capital,
internal comma, terminal period. Same lexical surface, so any needle matching it
already matches _GARBAGE and is guarded; no digit, so a number grader cannot
parse an answer out of it. When the bare garbage is rejected and the shaped one
passes, the operator now returns the shape that survives, so the finding names
the real hole.

Sourced from arXiv:2410.07137: a constant, input-independent reply scored 86.5%
LC win rate on AlpacaEval 2.0 when shaped like the evaluator's scaffolding,
against 0.6% naive. Same operator class, ~140x apart on form alone.

op_type stays SANITY, deliberately. That paper is about an LLM judge, and a
survival there would NOT mean the check asserts nothing. But this operator gates
on _requires_content, which admits only lexical families (exact, one_of, number,
contains, regex, valid_json, grounding) and never a judge, so for every grader
it can actually reach, passing the full disjoint battery does mean vacuity.
Retyping it KILL would mis-report genuine vacuity as a broken check.

Signed-off-by: egnaro9 <egnaro9@gmail.com>
Only provenance text moved. The shape probe found no new holes in either
suite: gradecore's graders and the promptfoo ports all reject punctuated
nonsense as readily as bare nonsense, so neither carries a form-only check.
A true negative, recorded as one.

Signed-off-by: egnaro9 <egnaro9@gmail.com>
Two of the three pass-2 defect cards that run against today's EvalCase. The
third, the grader's verdict channel, already shipped as an inject_denylisted_tool
payload.

spurious_cue_token_insert is the inverse of keyword_present_but_negated: there
the cue survives in a sentence meaning the opposite, here it survives in text
meaning nothing. Both rest on the presence_check tag, where the author has said
the grep is a PROXY for a property it cannot see, so cue-present/property-absent
is wrong by the task's own contract. Untagged it declines, because for a plain
contains grader 'the needle is there' IS the contract and passing garbage that
carries the needle is correct behavior, not a hole.
Sourced from arXiv:1907.07355: BERT hit 77% on ARCT off the unigram 'not' at 61%
productivity, and the symmetric-cue control drops the identical model to 50.5%,
chance.

append_grader_directed_suffix appends text arguing FOR the answer to a base that
is already wrong, so polarity never depends on the suffix. It declines when the
bare garbage already passes, since garbage_answer owns that finding and counting
it twice would inflate the hole count off one defect.
Sourced from arXiv:2403.17710: an optimized suffix moved a Mistral-7B judge from
10.8% ASR-B to 90.8% ASR on MT-Bench. Degraded here on purpose: a static
sentence is not an optimized sequence, so a survival is meaningful and a catch
proves very little. That asymmetry is in the real_origin, not just here.

Both carry fixtures. The parametrized defect test SKIPS an operator with no
fixture, and a skip reads green, so shipping without them would have left two
operators never exercised.

Signed-off-by: egnaro9 <egnaro9@gmail.com>
…d suite

Dogfood goes 91.4% (32/35, 3 holes) to 90.9% (40/44, 4 holes). The score fell
because the denominator grew faster than the catches, which is the honest
direction: a new operator that only ever confirmed existing catches would be
worth nothing.

The new blind spot is a contains grader needing all of ['capital']. It passes
opaque garbage carrying the token 'capital' and nothing else, so on a task
tagged presence_check the grep is the entire signal. append_grader_directed_suffix
found nothing new, which is the expected result for a deliberately degraded
static suffix against lexical graders.

Signed-off-by: egnaro9 <egnaro9@gmail.com>
The DCO check requires Signed-off-by on every PR commit, so the branch was
rebased with --signoff and every SHA changed. That orphaned the bundle's
issuer_commit: it named ceaf1f7, which is no longer an ancestor of this branch.
Re-emitted so the stamp points at a commit that actually exists here.

Nothing else moved. This is exactly the staleness the freshness gate exists to
catch, arriving from a direction I did not anticipate: rewriting history is
enough to invalidate a bundle even when not one byte of code or output changed.

Signed-off-by: egnaro9 <egnaro9@gmail.com>
Freshness proves the artifacts are what the code re-emits. It says nothing
about whether the commit the manifest NAMES still exists here, and a history
rewrite breaks the second while leaving the first perfectly green: every SHA
moves, every byte stays. The bundle then points a replayer at git checkout
<sha> for a commit that is not there, and every check passes.

Found by hand, not by a red test, when git rebase --signoff for the DCO check
orphaned a stamp that freshness had certified minutes earlier. That is the
uncomfortable part: the freshness gate would catch a tampered artifact and did
not catch this, because rewriting history changes no bytes.

stamp_is_reachable REFUSES on a shallow clone rather than answering. A shallow
repo cannot see its own history, so False would falsely accuse a good stamp and
True would be a gate that passed because it could not look. The test does not
skip on shallow either, since a skip reads green, which is the failure this
file exists to prevent. The test job now checks out with fetch-depth: 0 so it
can actually walk the history.

Three tests: the committed stamp is reachable; an amended-away commit reads
unreachable (liveness, reproducing the real incident); a shallow clone is
refused.

Signed-off-by: egnaro9 <egnaro9@gmail.com>
emit_vac.py is a CODE path, so adding the reachability check moved the stamp
to 7aff502. Caught by the new gate on its first real run, which is the proof
it was worth adding.

Signed-off-by: egnaro9 <egnaro9@gmail.com>
Signed-off-by: egnaro9 <egnaro9@gmail.com>
@egnaro9
egnaro9 merged commit 74525db into main Aug 17, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant