Skip to content

Correctness sweep: dead processes, wildcards, an inert field, and --resume - #55

Merged
leggetter merged 2 commits into
mainfrom
correctness-sweep
Aug 25, 2026
Merged

Correctness sweep: dead processes, wildcards, an inert field, and --resume#55
leggetter merged 2 commits into
mainfrom
correctness-sweep

Conversation

@leggetter

Copy link
Copy Markdown
Collaborator

Four faults from the scorer audit, none of which needed a run to find. Plus the twelve cells they invalidated, re-measured.

A dead process is no longer scored — #45

The guard only rejected a run that errored and left nothing behind, so a container killed mid-flight came through with a populated transcript and a plausible partial score. One did on 21 August — error_exit_255, fifteen tool calls, written as a 2/6 agent failure — and was spotted only because a baseline failing after three passes looked odd.

Budget exhaustion stays scoreable: timeout, max_steps and error_max_turns all mean the agent had its run and used it up.

A deny-list rather than an allow-list, because runners derive stop reasons from three different sources and an uncatalogued one is likelier to be a new legitimate outcome than a new kind of crash.

Caveat recorded in the code: exit 137 maps to timeout, and 137 is also what a stopping Docker daemon sends. Telling those apart needs the harness's elapsed time, which that layer doesn't have.

Wildcard topics, decided per site — #48

site * accepted? why
004 queue no "they only want orders on the queue" — a wildcard puts the customer's retry traffic there too, the acted-too-broadly failure the scenario is built around
003 secondary alert no accepting it let an agent pass without ever finding either topic name
003 primary alert yes asks whether the alert would reach them; a wildcard means yes
005 platform guard yes asks whether anything should have arrived at all

tenants[].topics removed — #49

Verified live that the API ignores it: a PUT carrying topics returns []. It had already produced a scorer justifying its design on an agent "editing the tenant's topics", a route that does not exist. Gone from the schema and four seed files.

--resume added, re-run default kept — #50

A stale row surviving a code change is a live hazard — this PR is itself an instance, since 003 and 004 needed re-running. What was missing was a way to resume after an interruption, which three runs needed this week.

with --resume:  6 SKIP
without:        6 PLAN

The re-measurement

11 of 12 pass. The tightening cost nothing: every agent that would have passed still passes, because they were naming topics explicitly. The holes were routes nobody had taken yet.

The one failure is 003's familiar variance — found /operator-events, hit the rejected PATCH /config, stopped to ask for input.

compare-snapshots: 104 → 103, flagged as not attributable to the agent because that scorer changed. Correct default, even though the real cause was variance.

The published page is unaffected — it reads from the v0.3.0 tag, so this snapshot is the basis for the next release.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Nt2Zgjw7STjrnFXYKRRVAA

leggetter and others added 2 commits August 25, 2026 10:38
…esume

Four separate faults, none of which needed a run to find.

**A dead process is no longer scored.** The guard only rejected a run that
errored *and* left nothing, so a container killed mid-flight came through
with a populated transcript and a plausible partial score. One did on 21
August — error_exit_255, fifteen tool calls, written as a 2/6 agent failure
— and was spotted only because a baseline failing after three passes looked
odd. Budget exhaustion stays scoreable: timeout, max_steps and
error_max_turns all mean the agent had its run and used it.

A deny-list rather than an allow-list, because runners derive stop reasons
from three different sources and an uncatalogued one is likelier to be a new
legitimate outcome than a new crash. Caveat recorded in the code: exit 137
maps to `timeout`, and 137 is also what a stopping Docker daemon sends.

**Wildcard topics, decided per site rather than blanket.** Rejected for
outpost-004's queue, where "they only want orders on the queue" means a
wildcard puts the customer's retry traffic there too — the acted-too-broadly
failure that scenario is built around, and applyOutpostSeed's own default.
Rejected for outpost-003's secondary alert, where accepting it let an agent
pass without ever finding either topic name. Accepted, and now documented as
intentional, for outpost-003's primary check and outpost-005's platform-fault
guard: both ask whether anything would arrive, and a wildcard means yes.

**tenants[].topics removed** from the schema and four seed files. Verified
live that the API ignores it; it had already produced a scorer justifying its
design on an agent "editing the tenant's topics", a route that does not exist.

**--resume added; the re-run default kept.** A stale row surviving a code
change is a live hazard — outpost-001's scorer, prompt and seed were all
corrected on 24 August, and keeping its old rows would have published results
scored by code that no longer exists. What was missing was a way to resume
after an interruption, which three runs needed this week.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nt2Zgjw7STjrnFXYKRRVAA
Those twelve rows were scored by code that no longer exists: both scenarios
stopped accepting a wildcard where a specific topic is the point. Keeping
them would have published results produced by a scorer that had since
changed, which is the reason outpost-001 was re-run for v0.3.0.

11 of 12 pass. The tightening cost nothing — every agent that would have
passed still passes, because they were naming topics explicitly rather than
subscribing to everything. The wildcard holes were routes nobody had taken
yet, which is the good version of that finding.

The single failure is outpost-003's familiar variance: the agent found
/operator-events, hit the rejected PATCH /config, and stopped to ask for
input rather than continuing to enumerate — the same mode as one of the
three majority passes yesterday.

104 -> 103. compare-snapshots flags it as not attributable to the agent
because that scenario's scorer changed between refs, which is the correct
default even though the actual cause was variance.

The published page is unaffected: it reads from the v0.3.0 tag, so this
snapshot is the basis for the next release rather than a change to that one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nt2Zgjw7STjrnFXYKRRVAA
@leggetter
leggetter merged commit 80c1404 into main Aug 25, 2026
2 checks passed
@leggetter
leggetter deleted the correctness-sweep branch August 25, 2026 10:43
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