Skip to content

test(ci): run the changed agents' smoke and the changed benchmarks' oracle - #333

Merged
elronbandel merged 5 commits into
mainfrom
elron/affected-agents-oracle
Aug 10, 2026
Merged

test(ci): run the changed agents' smoke and the changed benchmarks' oracle#333
elronbandel merged 5 commits into
mainfrom
elron/affected-agents-oracle

Conversation

@elronbandel

Copy link
Copy Markdown
Contributor

Follow-up to #327 (which landed the affected-fixture selection). Answers "are agent tests running when agents change?" — they weren't, and neither were benchmark oracle checks.

What now runs on a PR

From the same offline hash diff #327 introduced:

Changed Runs
an agent its replay fixture (#327) + its own agent_smoke test (new)
a benchmark its replay fixture (#327) + its oracle gold-solution check (new)
a shared base the same, for the leaves the cascade reaches
  • Agent smoke: --exact idents so agent_claude_code never matches agent_claude_code_rtk; AGENTS_SMOKE_BUILD=1 so the suite builds the PR's agent image from source rather than pulling one that doesn't exist yet. Agents with no agent_smoke! entry warn by name — bob is deliberately absent (IBM-backend-tied, documented in the suite).
  • Oracle: the gold solution must still score 1.0, so a broken grader or a moved dataset fails the PR that broke it — precisely the mmmu-class rot the convergence run surfaced after months invisible. Per-task benchmarks warn and stay nightly (GB-scale upstream bases).

Harness fixes this required (both from the rung-6 audit)

  • ORACLE_ONLY becomes a comma/space-separated list — it was a single substring and literally could not express a set.
  • An ORACLE_ONLY that matches nothing now asserts instead of running zero checks and reporting success. A machine-generated filter must never pass vacuously.
  • Every new step fails loudly on running 0 tests.

Cost control

Both suites cap at 2 components per PR, with a ::warning naming what the cap dropped (no silent truncation — the audit's rule). A core-base change affects dozens of leaves and each of these is a minutes-long build.

Validation

Selection run through real bash at three history points: agent+benchmark change → 2 smoke idents + 1 oracle benchmark; per-task-only change → two warnings, nothing selected; new-agent commit → smoke for both changed agents. Oracle list semantics verified separately, including the fail-loud empty case ("nope" → assert, not green).

Rules checked against

…racle

#327 selected replay fixtures for affected components; a changed agent
still waited for the nightly to run its own smoke suite, and a changed
benchmark's gold-solution (oracle) check never ran on a PR at all. Both
now run in the affected job, from the same offline hash diff:

- agent smoke: --exact idents (agent_claude_code never matches _rtk);
  AGENTS_SMOKE_BUILD=1 so the suite builds the PR's agent image from
  source instead of pulling one that does not exist yet; agents with no
  agent_smoke! entry warn by name (bob is deliberately absent — it is
  IBM-backend-tied, see tests/run/agents/test.rs)
- oracle: ORACLE_ONLY per changed benchmark, so a broken grader or a
  moved dataset fails the PR that broke it — the mmmu-class rot the
  convergence run surfaced. Per-task benchmarks warn and stay nightly
  (their upstream bases are GB-scale)

Harness fixes this needed (both audit findings):
- ORACLE_ONLY becomes a comma/space-separated LIST (it was a single
  substring, unable to express a set)
- an ORACLE_ONLY that matches nothing now ASSERTS instead of running
  zero checks and passing green — a machine-generated filter must
  never pass vacuously
- every new step fails loudly on 'running 0 tests'

Both suites are capped at 2 components per PR with a ::warning naming
what the cap dropped (no silent truncation): a core-base change affects
dozens of leaves and these builds are minutes each.

Selection validated through real bash on three history points: agent+
benchmark change -> 2 smoke idents + 1 oracle; per-task-only change ->
two warnings, nothing selected; new agent -> smoke for both agents.
Oracle list semantics verified including the fail-loud empty case.

Signed-off-by: Elron Bandel <elron.bandel@ibm.com>
…for coverage

Per-task benchmarks were excluded from the PR oracle on the assumption
they cost a ~600-task build. Wrong: the suite already covers each with
ONE pinned task (swe-bench sympy__sympy-24066, skills-bench two tasks,
swe-lancer 12155_1, swe-bench-pro one instance), so a changed per-task
benchmark can and should be oracled on the PR that changes it.

Removing the exclusion naively would have failed those PRs, though:
terminal-bench has NO oracle check by design (its upstream gold drifted
past deterministic scoring) and the strict ORACLE_ONLY now asserts on a
no-match. So coverage is no longer guessed in YAML — the harness
declares it:

  ORACLE_LIST=1 cargo test --test oracle -- --ignored --nocapture
    -> "oracle-label: <benchmark>[ (task <id>)]"

The oracle step intersects the changed benchmarks with that list, runs
what is covered, and warns by name for what is not. Asking the harness
immediately paid: gsm8k and aider-polyglot turn out to have no oracle
check either (only 11 benchmarks meet the auto-cover conditions, plus
16 SPECIAL), which a per-task heuristic would have silently mistaken
for coverage.

Also: the replay cap now announces what it drops like the other two
(it was the only silent truncation left), cap() sits beside pick(), the
three setup steps share one "any" output instead of repeating a
three-clause OR, and the job id is "affected" — it stopped being
replay-only when smoke and oracle joined it.

Signed-off-by: Elron Bandel <elron.bandel@ibm.com>
@elronbandel
elronbandel force-pushed the elron/affected-agents-oracle branch from 1ada9cf to a72c733 Compare August 10, 2026 15:15
66 lines of shell inline in a workflow, when this repo's pattern is a
script the workflow calls in one line (six precedents in tests/static/).
The tell was that validating it meant reconstructing the logic in a
scratch copy — testing a lookalike, not the artifact. The affected job
drops 161 -> 91 lines and the script is runnable locally:

  tests/select-affected.sh <base-ref>            # what a change selects
  tests/select-affected.sh oracle-filter <b>...  # what the oracle covers

Extraction immediately exposed two real bugs the inline version hid:

1. cap()'s ::warning:: went to stdout INSIDE command substitution, so
   the warning text was captured into the value: tests=::warning::replay:
   5 affected... — a garbage --exact argument would have shipped.
   Warnings cannot go to stderr either (GitHub parses workflow commands
   from stdout), so they now accumulate in a file that survives the
   subshell and flush once at the end.
2. head on empty input emits a newline, so an empty list became ' ' and
   the any flag read true: a PR that selected nothing would still have
   installed the Rust toolchain and logged into GHCR. Values are
   normalized before the flag is computed.

Both are now covered by running the real script: no-change -> any=false
with empty values; agent+benchmark change -> 3 replay idents, 2 smoke
idents, 5 oracle candidates, warnings listing what the caps dropped and
which components have no fixture.

Signed-off-by: Elron Bandel <elron.bandel@ibm.com>
Touches ai2d (replay fixture + oracle check) and openclaw (replay
fixture + agent_smoke) so CI runs the smoke and oracle steps for real —
they have only ever run the empty path.

Also fixes a selection flaw the proof exposed: the diff used GitHub's
pull_request.base.sha, which is main's TIP, so anything main merged
after the branch point counted as affected by this PR (the preview
selected open-interpreter/appworld/mmmu — the chip session's fixes on
main, nothing to do with this branch). Now diffs the merge base, so a
PR is judged on what it changed.

Signed-off-by: Elron Bandel <elron.bandel@ibm.com>
The ai2d/openclaw comments existed only to make CI exercise the smoke
and oracle steps for real. Proof run: job 'Test affected' ran Select ->
Replay (replay_ai2d_1852_openclaw) -> Smoke (agent_openclaw, built from
source) -> Oracle (ai2d gold = 1.0), every step success. That was the
first end-to-end execution of the smoke and oracle paths.

The merge-base selection fix from that commit stays — it is a real fix,
not scaffolding.

Signed-off-by: Elron Bandel <elron.bandel@ibm.com>
@elronbandel
elronbandel merged commit 9216e1e into main Aug 10, 2026
6 checks passed
@elronbandel
elronbandel deleted the elron/affected-agents-oracle branch August 10, 2026 17:57
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