Skip to content

fix(evals): run-validity passes a run whose plugin under test never loaded #12190

Closed

Description

@kyle-sexton

Observed

run-validity.py judges a run VALID when the plugin under test never loaded. On 2026-11-01, lane 4 smoke-ran two converted playgrounds cases (use-absent-emits-install-commands, use-cloud-session-feature-detects-delivery; #8635 group 1). Each trace's startup record showed plugin_errors: dependency-unsatisfied for playground@claude-plugins-official, and playgrounds was missing from the loaded plugins, so both arms ran without the plugin. run-validity.py passed "session started" on those runs.

plugins/evals/skills/plugin-eval/scripts/run-validity.py reads suite.plugins[].path (line 125) but has no check on the trace's plugin_errors or on whether each suite plugin appears in the session's loaded plugins (grep for plugin_errors finds nothing).

Fix wanted

A run whose with-arm trace reports a plugin_errors entry for a suite plugin, or does not list a suite plugin as loaded, is INVALID with a reason naming the plugin and the error. A test with a trace fixture that fails before the fix.

Related

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Nov 2, 2026
  2. github-actions commented on Nov 2, 2026

    @github-actions
    Contributor

    Proposed work class: work-class: scoped
    Basis: automated intake triage; the lanes App applied this class.

    Size: Small
    Complexity: Low
    Uncertainty: Known
    Flags: none
    Blocked by: none

    Understood: run-validity.py passes a run even when the plugin under test never loaded. The trace init line showed plugin_errors (dependency-unsatisfied) and the plugin was missing from the loaded list. The fix is a new check that marks such a with-arm run INVALID, with a reason naming the plugin and the error. It comes with fixture tests that fail before the fix.

    The issue text and the existing refinement comment give a clear done-when, so nothing is missing. Related, but not duplicates: #8635, #12043, #12191 (the playgrounds suite issue).

    Automated triage, applied by the lanes App.

  3. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Nov 2, 2026
  4. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    on Nov 2, 2026
  5. melodic-automation-lanes commented on Nov 2, 2026

    @melodic-automation-lanes
    Contributor

    Not admitted to the issue lane: no trusted-human acceptance criteria: a listed human must put the confirmed - [ ] criteria in the body or post them as their own comment, or, on an issue a listed human filed, intake's newest refinement comment must hold them unedited. Admission takes the issue once each of those is met, when intake triages it again (.github/actions/resolve-config/admission-rules.json).

  6. melodic-automation-lanes commented on Nov 2, 2026

    @melodic-automation-lanes
    Contributor

    The latest triage verdict holds nothing: the issue is at status: ready.

  7. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    and removed
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    on Nov 2, 2026
  8. melodic-automation-lanes commented on Nov 2, 2026

    @melodic-automation-lanes
    Contributor

    Refinement. A read-only run explored this repository, searched its issues and pull requests, and read the allowed docs to draft what follows. On an issue a listed human filed, it counts as the issue's spec once posted, while unedited; it is still model text, so check it.

    Intended outcome: run-validity.py fails a run whose with-arm trace init line reports a plugin_errors entry for a suite plugin or omits a suite plugin from its loaded plugins, with a reason naming the plugin and error.

    Acceptance criteria

    • run-validity.py has a new check (for example 'plugins loaded') that reads each with-arm run's trace init line, the (system, init) line already matched by TRACE_INIT at plugins/evals/skills/plugin-eval/scripts/run-validity.py:155.
    • The check identifies each suite plugin from suite.plugins[].path (read at run-validity.py:125), taking its name from the plugin's .claude-plugin/plugin.json.
    • A with-arm run whose init line plugin_errors has an entry for a suite plugin makes the check FAIL, with a detail line naming the run, the plugin and the error text (for example dependency-unsatisfied).
    • A with-arm run whose init line loaded plugins list lacks a suite plugin makes the check FAIL, with a detail line naming the run and the missing plugin.
    • A FAIL from the check adds a reason to the final INVALID output, so main() prints INVALID and exits with the invalid status.
    • A run with no trace, or no init line or plugins field, is reported as UNCHECKED or warned like check_probe_tools, not passed silently.
    • A suite with no plugins, and a run where every suite plugin is loaded with no plugin_errors, still pass the check.
    • A fixture trace in test_run_validity.py with plugin_errors dependency-unsatisfied and the plugin missing from loaded plugins makes the new test assert INVALID and the reason naming the plugin and error; this test fails on the pre-fix script.
    • A second test covers a plugin missing from the loaded list with no plugin_errors entry, and a third covers the passing case.
    • The script's header docstring lists the new check next to 'session started', and run-validity.test.sh and test_run_validity.py pass.

    External state: none

    Related work

    Sources read

    • plugins/evals/skills/plugin-eval/scripts/run-validity.py:125: SUITE_PLUGINS/PLUGIN_PATH read suite.plugins[].path, with no name or plugin_errors handling
    • plugins/evals/skills/plugin-eval/scripts/run-validity.py:155: TRACE_INIT is the (system, init) trace line
    • plugins/evals/skills/plugin-eval/scripts/run-validity.py:683: check_started judges only 0-turn runs and sandbox failures, nothing about plugin loading
    • plugins/evals/skills/plugin-eval/scripts/run-validity.py:1222: check_probe_tools shows how to read the init line and report UNCHECKED or WARN
    • plugins/evals/skills/plugin-eval/scripts/run-validity.py:1486: main() assembles the checks, and a new check is added in the later list
    • plugins/evals/skills/plugin-eval/scripts/test_run_validity.py:760: existing tests set data["suite"]["plugins"] = [{"path": ...}] for fixtures
    • repository grep for plugin_errors: no matches, so no check exists yet

    Automated refinement by the lanes App. Intake triages the issue again with it.

  9. removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Nov 2, 2026
  10. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    admission-deferredAdmitted but waiting for WIP room; the hourly work-unblock sweep labels it agent-ready.
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    and removed
    admission-deferredAdmitted but waiting for WIP room; the hourly work-unblock sweep labels it agent-ready.
    on Nov 2, 2026
  11. github-actions commented on Nov 2, 2026

    @github-actions
    Contributor
    No description provided.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions