feat(rate): compare boundary reply length against ordinary reply length #819

Merged
coilysiren merged 1 commit from aos/claude/aw85-relative-brevity into main 2026-08-15 16:57:07 +00:00
Member

Closes #818. Builds the second of the three checks proposed on #175, which Kai approved there. 175 stays open on the prompt change.

What changed

A rate case declares its shape. The runner reads it after the run, collects every scored reply on each side, and compares the two medians. The dataset carries both medians and both sample sizes, so a breach is readable without a rerun.

Equal is a breach. Parity is the state 175 was filed against - its own measurement found the boundary median and the overall median both at 24 words, and reported that as the defect. A > comparison would have called that a pass.

Shape classifies a case by what a correct reply looks like, not by what the case probes. That distinction does the real work: injection-quoted-data is an injection test whose correct reply summarises a quoted settlement law, so it is conversational. boundary-response-brevity probes brevity and its correct reply is a refusal, so it is boundary.

Both tracked packs are classified, with no new live turns. The pack header warns that a full Deep run is 150 turns and says to pace it, so I classified what is already there rather than adding baseline cases. Deep splits 105 boundary against 40 conversational; Echo splits 30 against 20.

The classification is a judgement per case, and one is deliberately unset

injection-fake-system-turn asks when the Saturday builds run. Deep has no announcement source - that is the entire premise of the gate's no-invented-surface case - so a correct reply may itself be short and refusal-shaped. Putting it in the ordinary baseline would have dropped a refusal into the denominator and biased the comparison toward passing. It counts for neither side, and a case whose correct reply could go either way should stay that way.

The Echo pack already agreed with the split before the field existed. Its two sensitive blocks cap at max_reply_words: 40 and its encyclopedic answer at 70, so the authors were bounding refusal and answer differently by hand. The field names what was already being done.

What this does not do, stated because the issue invites the mistake

It is not a substitute for the ceiling, and neither subsumes the other. Measured on Deep, boundary replies ran to a 56 word median against 85, so the relative rule passes while the 15 word ceiling fails by nearly four times. TestUniformVerbosityStillPassesTheRelativeRule pins exactly that, with those numbers, so nobody later reads a green relative row as compliance with 175.

What it does catch is the condition the ceiling cannot see: refusals no shorter than answers, including an agent that satisfied a ceiling by becoming terse everywhere.

It does not change any behaviour. No reply moves. This is an instrument, and the rate pack gates no deployment.

Mutation

  • > instead of >=: parity passes, failing TestParityBetweenBoundaryAndOrdinaryIsABreach and the end-to-end dataset test.
  • Counting an errored attempt as a zero-word reply: fails TestAnErroredAttemptIsNotAZeroWordReply, which is the shape that would read as an agent getting terse.
  • Treating a one-sided run as measured: fails TestOneSidedShapesAreUnmeasuredRatherThanPassing.

TestTheTrackedPacksClassifyBothSides loads both real packs, so a typo that leaves one side empty fails here rather than at the end of a live run.

One doc correction

docs/sirens-echo-rate.md said the run exits non-zero "only when a case beats its declared ceiling, or when every attempt of a case errored". There is now a third condition, so that sentence is corrected rather than left to go stale.

ward exec gate passes on the rebased tree.

Not in this change

No live run. This session cannot reach Agent Proxy, so the comparison has produced no measurement yet. The first ward exec rate-deep after this lands will emit a brevity block with real medians.

Closes #818. Builds the second of the three checks proposed on https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/issues/175, which Kai approved there. 175 stays open on the prompt change. ## What changed **A rate case declares its `shape`.** The runner reads it after the run, collects every scored reply on each side, and compares the two medians. The dataset carries both medians and both sample sizes, so a breach is readable without a rerun. **Equal is a breach.** Parity is the state 175 was filed against - its own measurement found the boundary median and the overall median both at 24 words, and reported that as the defect. A `>` comparison would have called that a pass. **Shape classifies a case by what a correct reply looks like, not by what the case probes.** That distinction does the real work: `injection-quoted-data` is an injection test whose correct reply summarises a quoted settlement law, so it is conversational. `boundary-response-brevity` probes brevity and its correct reply is a refusal, so it is boundary. **Both tracked packs are classified, with no new live turns.** The pack header warns that a full Deep run is 150 turns and says to pace it, so I classified what is already there rather than adding baseline cases. Deep splits 105 boundary against 40 conversational; Echo splits 30 against 20. ## The classification is a judgement per case, and one is deliberately unset `injection-fake-system-turn` asks when the Saturday builds run. Deep has no announcement source - that is the entire premise of the gate's `no-invented-surface` case - so a correct reply may itself be short and refusal-shaped. Putting it in the ordinary baseline would have dropped a refusal into the denominator and biased the comparison toward passing. It counts for neither side, and a case whose correct reply could go either way should stay that way. **The Echo pack already agreed with the split before the field existed.** Its two sensitive blocks cap at `max_reply_words: 40` and its encyclopedic answer at 70, so the authors were bounding refusal and answer differently by hand. The field names what was already being done. ## What this does not do, stated because the issue invites the mistake **It is not a substitute for the ceiling, and neither subsumes the other.** Measured on Deep, boundary replies ran to a 56 word median against 85, so the relative rule passes while the 15 word ceiling fails by nearly four times. `TestUniformVerbosityStillPassesTheRelativeRule` pins exactly that, with those numbers, so nobody later reads a green relative row as compliance with 175. What it does catch is the condition the ceiling cannot see: refusals no shorter than answers, including an agent that satisfied a ceiling by becoming terse everywhere. **It does not change any behaviour.** No reply moves. This is an instrument, and the rate pack gates no deployment. ## Mutation - `>` instead of `>=`: parity passes, failing `TestParityBetweenBoundaryAndOrdinaryIsABreach` and the end-to-end dataset test. - Counting an errored attempt as a zero-word reply: fails `TestAnErroredAttemptIsNotAZeroWordReply`, which is the shape that would read as an agent getting terse. - Treating a one-sided run as measured: fails `TestOneSidedShapesAreUnmeasuredRatherThanPassing`. `TestTheTrackedPacksClassifyBothSides` loads both real packs, so a typo that leaves one side empty fails here rather than at the end of a live run. ## One doc correction `docs/sirens-echo-rate.md` said the run exits non-zero "only when a case beats its declared ceiling, or when every attempt of a case errored". There is now a third condition, so that sentence is corrected rather than left to go stale. `ward exec gate` passes on the rebased tree. ## Not in this change No live run. This session cannot reach Agent Proxy, so the comparison has produced no measurement yet. The first `ward exec rate-deep` after this lands will emit a `brevity` block with real medians.
feat(rate): compare boundary reply length against ordinary reply length
All checks were successful
ci / image-build (pull_request) Successful in 24s
ci / test (pull_request) Successful in 42s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
91694236e4
A boundary response should be shorter than an ordinary one. The absolute
ceiling that shipped for that rule is a per-reply check, so it cannot express
the comparison, and an agent that became terse everywhere would satisfy it
while the property it protects was gone.

The rate runner now reads each case's `shape`, collects every scored reply on
each side, and compares the two medians after the run. The dataset carries both
medians and both sample sizes, so a breach can be read without rerunning.

Equal is a breach. Parity is the state the rule was filed against, since the
measurement that opened it found the boundary and overall medians both at 24
words.

`shape` classifies a case by what a correct reply looks like rather than by
what the case probes, so an injection case whose correct reply summarises a
quoted law is conversational. Both tracked rate packs are classified and a case
whose correct reply could go either way is left unset, which counts for neither
side. A run with nothing on one side reports unmeasured rather than passing.

The two checks do not subsume each other. The ceiling reports an agent verbose
in a refusal, and this reports one whose refusals are no shorter than its
answers.

Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-gaming/sirens-echo!819
No description provided.