fix(insights): round 2 says the derived outcome is 52%, not 63% — Step 1 reopens (v0.329.1) - #600
Merged
Merged
Conversation
…p 1 reopens (v0.329.1)
The Step 1 PR shipped with a debt: its 63% agreement was measured on the same 28
rows whose errors had just bought two of the rules, so it measured the fitting.
This is the re-validation that debt called for.
32 conversations round 1 never touched (`--exclude`), stratified across all nine
bases, labelled blind from transcripts, scored against the rules exactly as
shipped in v0.323.0. Nothing was changed after seeing the result.
round 1, v1 rules 50% exact / 43% baseline
round 1, after tuning 63% exact / 32% baseline
round 2, out of sample 52% exact / 43% baseline, 78% sign
So the 63% was fitting, and the real signal is nine points above "call everything
a success". That is not enough to build Step 2 on, so Step 1 goes back to open.
The 11 disagreements cluster into three causes:
· 5 are `no-evidence` → unknown on conversations a human reads in seconds —
runs that did substantial work and left no observable trace. This is exactly
the residual the Stop-hook half was deferred over in Step 1. It is 6% of the
corpus but 45% of the mistakes, because those runs are concentrated in the
cases the OS is blind to rather than spread evenly. Judging a residual by its
share instead of its share of the errors is the mistake. The hook is back in
scope and Step 1 is not finished without it.
· 3 are quota deaths with zero tool calls, which fall through `died-early`'s
`tool_calls > 0` guard and read as `noop`. That guard was itself bought by
round 1 (an agent replying "looks like a test message" is a noop, not a
failure) and the DB cannot currently tell the two shapes apart.
· 1 is `task-retried` beating a later success inside a 4-run conversation — a
fold-order bug, and the cheapest of the three to fix.
Two further disagreements were probably my labels rather than the rules: I called
two automation runs that produced no assistant output at all `noop`, where
`died-early` called them failures. An unattended run that produces nothing is
closer to a failure; corrected, the number is ~57%.
No rule changed here. Fixing rules against the round that judged them is how the
63% happened, and round 3 is what the fixes get measured on.
Tooling: `outcome-label-score.cjs` takes a labels-file argument, and
`outcome-label-sample.cjs` takes `--exclude` so a re-validation can only draw rows
an earlier round never saw.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AiTKjtdcF4ESbuYVWj2CfU
vikasprogrammer
added a commit
that referenced
this pull request
Aug 11, 2026
…p 1 reopens (v0.329.1) (#600) The Step 1 PR shipped with a debt: its 63% agreement was measured on the same 28 rows whose errors had just bought two of the rules, so it measured the fitting. This is the re-validation that debt called for. 32 conversations round 1 never touched (`--exclude`), stratified across all nine bases, labelled blind from transcripts, scored against the rules exactly as shipped in v0.323.0. Nothing was changed after seeing the result. round 1, v1 rules 50% exact / 43% baseline round 1, after tuning 63% exact / 32% baseline round 2, out of sample 52% exact / 43% baseline, 78% sign So the 63% was fitting, and the real signal is nine points above "call everything a success". That is not enough to build Step 2 on, so Step 1 goes back to open. The 11 disagreements cluster into three causes: · 5 are `no-evidence` → unknown on conversations a human reads in seconds — runs that did substantial work and left no observable trace. This is exactly the residual the Stop-hook half was deferred over in Step 1. It is 6% of the corpus but 45% of the mistakes, because those runs are concentrated in the cases the OS is blind to rather than spread evenly. Judging a residual by its share instead of its share of the errors is the mistake. The hook is back in scope and Step 1 is not finished without it. · 3 are quota deaths with zero tool calls, which fall through `died-early`'s `tool_calls > 0` guard and read as `noop`. That guard was itself bought by round 1 (an agent replying "looks like a test message" is a noop, not a failure) and the DB cannot currently tell the two shapes apart. · 1 is `task-retried` beating a later success inside a 4-run conversation — a fold-order bug, and the cheapest of the three to fix. Two further disagreements were probably my labels rather than the rules: I called two automation runs that produced no assistant output at all `noop`, where `died-early` called them failures. An unattended run that produces nothing is closer to a failure; corrected, the number is ~57%. No rule changed here. Fixing rules against the round that judged them is how the 63% happened, and round 3 is what the fixes get measured on. Tooling: `outcome-label-score.cjs` takes a labels-file argument, and `outcome-label-sample.cjs` takes `--exclude` so a re-validation can only draw rows an earlier round never saw. Claude-Session: https://claude.ai/code/session_01AiTKjtdcF4ESbuYVWj2CfU Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
The Step 1 PR (#592) shipped with a debt: its 63% agreement was measured on the same 28 rows whose errors had just bought two of the rules. This is the re-validation that debt called for.
32 conversations round 1 never touched (
--exclude), stratified across all nine bases, labelled blind from transcripts, scored against the rules exactly as shipped in v0.323.0. Nothing was changed after seeing the result.The 63% was fitting. The real signal is nine points above "call everything a success" — not enough to build Step 2 on. Step 1 goes back to open.
The 11 disagreements, and what they cost
no-evidence→unknownon conversations a human reads in seconds (4 successes, 1 partial) — runs that did substantial work and left no observable trace. This is exactly the residual the Stop-hook half was deferred over in Step 1. It is 6% of the corpus but 45% of the mistakes, because those runs are concentrated in the cases the OS is blind to rather than spread evenly. Judging a residual by its share instead of its share of the errors is the mistake. The hook is back in scope, and Step 1 is not finished without it.noop— they fall throughdied-early'stool_calls > 0guard, which round 1 itself bought (an agent replying "looks like a test message" is a noop, not a failure). The DB cannot currently tell the two shapes apart; this needs a fact neither has today.task-retriedbeat a later success in a 4-run conversation — a fold-order bug, and the cheapest of the three to fix.Two further disagreements were probably my labels, not the rules: I called two automation runs that produced no assistant output at all
noop, wheredied-earlycalled them failures. An unattended run that produces nothing is closer to a failure. Corrected, the number is ~57%.No rules changed here
Fixing rules against the round that judged them is how the 63% happened. The three fixes get measured on round 3, against rows neither round has seen.
Tooling:
outcome-label-score.cjstakes a labels-file argument;outcome-label-sample.cjstakes--excludeso a re-validation can only draw rows an earlier round never saw. Docs and scripts only — nosrc/change.🤖 Generated with Claude Code
https://claude.ai/code/session_01AiTKjtdcF4ESbuYVWj2CfU