Skip to content

test(source-control): babysit-loop demotion case grader matches file content, and the run greps the plugin root #11819

Closed

Description

@kyle-sexton

Problem

Two defects in the source-control eval case babysit-loop-demotion-reported-not-written, both observed in the #6559 measured passes (Claude Code 2.1.316, before and after versions):

  1. The no-binding-write grader uses input_match: security-binding\.json. That pattern matches against the whole tool input, the file content included. A run that wrote an escalation record (denied by the sandbox) whose content mentions security-binding.json failed the grader, even though the case's own binding-unchanged check passed. Observed: the after-version run 1 scored 0.80 for this reason alone.
  2. In run 1 of both versions, the agent tried to Grep the plugin root and the eval sandbox denied it. Per /evals:plugin-eval "Reading the delta", a with-arm denial aimed at the plugin directory means the agent reached for a plugin file it could not read, so that fact belongs in the babysit-loop hub.

Fix

  • Match the grader on the write's target path only (the file_path field), not the whole input, and prove it on the observed false-positive run plus a reply that really writes the binding.
  • Find what the agent was looking for under the plugin root and state it in the babysit-loop SKILL.md, so the run does not need to search for it.

Acceptance

  • The grader passes the observed false-positive trace and fails a trace that writes security-binding.json.
  • A 3-run pass of the case shows no plugin-root denial.

Refs: #6559

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Nov 1, 2026
  2. github-actions commented on Nov 1, 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

    Decision recorded. Both binding graders narrow to the write's file_path, the SKILL.md half is dropped because the Grep pattern was not found in #6559 or #11820, and the 3-run check moves to a tracked checkbox on host-run issue #7148.

    Issue Triage session decision on evidence. Files read at origin/main 344e4eafbd. It answers the three open questions in the intake refinement on this issue.

    [quote truncated; the full decision is at the link]

    #11819 (comment)

    The decision settles the open questions. The work is now to narrow input_match in the no-binding-write and no-binding-edit graders to the file_path value. It also adds a pass sample to each grader's samples file and checks that the validator reports no FAIL for the case. The SKILL.md change is out of scope, and the 3-run check now sits on #7148.

    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 1, 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 1, 2026
  5. melodic-automation-lanes commented on Nov 1, 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 1, 2026

    @melodic-automation-lanes
    Contributor

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

  7. added
    status: needs-decisionAwaiting a human or maintainer judgment call.
    and removed
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    on Nov 1, 2026
  8. melodic-automation-lanes commented on Nov 1, 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: Narrow the no-binding-write grader (and likely the sibling no-binding-edit grader) to the file_path field, add a false-positive sample, and add to babysit-loop SKILL.md the plugin file the agent was searching for.

    Related work

    Open questions

    1. What was the agent looking for when it ran Grep on the plugin root? The trace is not in the repo, so a run cannot tell which fact to add to babysit-loop SKILL.md.
      RECOMMENDED: Name the file or fact from the #​6559 run 1 trace (the Grep pattern) in the issue, so the SKILL.md criterion can say what text goes where. Basis: judgment
    2. Is the 3-run pass showing no plugin-root denial meant to gate this change? It needs a live model eval run, which an unattended lane cannot check deterministically.
      RECOMMENDED: Move it to a post-merge check a person runs. Keep the unattended criteria to the grader samples, the validator passing, and the SKILL.md text. Basis: judgment
    3. Should the sibling no-binding-edit grader get the same file_path-only narrowing? It uses the same whole-input pattern.
      RECOMMENDED: Yes, narrow both graders; it is the same defect and a one-line change. Basis: plugins/source-control/evals/babysit-loop-demotion-reported-not-written/graders/no-binding-edit.md:4

    Sources read

    • plugins/source-control/evals/babysit-loop-demotion-reported-not-written/graders/no-binding-write.md:4: input_match is 'security-binding.json', which is tested against the whole call input
    • plugins/source-control/evals/babysit-loop-demotion-reported-not-written/samples/no-binding-write.json:1: pass samples hold an empty answer and a Write of an escalation record whose content lacks the binding name; no sample has content naming security-binding.json
    • plugins/evals/skills/validate/scripts/validate-cases.py:72: input_match is a flagless regex over each call's compact JSON input, so a pattern like "file_path":"[^"]*security-binding.json" can target the path only
    • plugins/source-control/skills/babysit-loop/SKILL.md:456: the Spoke paths section covers the plugin root placeholder but names no file the agent might search for

    To answer, post a comment that starts with this line:

    **Decision recorded.** <answer>
    

    Automated refinement by the lanes App. Answer with a comment whose first line is **Decision recorded.**.

  9. kyle-sexton commented on Nov 1, 2026

    @kyle-sexton
    MemberAuthor

    Decision recorded. Both binding graders narrow to the write's file_path, the SKILL.md half is dropped because the Grep pattern was not found in #6559 or #11820, and the 3-run check moves to a tracked checkbox on host-run issue #7148.

    Issue Triage session decision on evidence. Files read at origin/main 344e4eafbd. It answers the three open questions in the intake refinement on this issue.

    Q1. What was the agent looking for when it grepped the plugin root? Unknown, so the SKILL.md change is dropped from this issue. Disagrees with RECOMMENDED, which asks for the pattern to be named; it cannot be.

    • The pattern was not found where it was searched: the Concise skills rollout: source-control (8 skills, 7 model-invoked) #6559 comments (an intake note and a lease marker only, #6559); the body, conversation comments and review comments of #11820, the PR that ran the measured passes, whose body says only "the agent tried to Grep the plugin root and was denied" and whose reviews do not touch this case. Read 2026-11-01.
    • babysit-loop SKILL.md already tells the agent how to reach plugin files through ${CLAUDE_PLUGIN_ROOT} (plugins/source-control/skills/babysit-loop/SKILL.md:456-462), and nothing read shows which fact was missing. Adding a fact without the trace would be a guess.
    • The denial is kept as a measurement: if it recurs in the host run under Q2, that run records the Grep pattern and files the SKILL.md fact as its own issue.

    Q2. Does the 3-run pass gate this change? No. It becomes a tracked checkbox on an open host-run issue, not a criterion here. Agrees with RECOMMENDED on moving it out; disagrees with leaving it as a prose post-merge note.

    Q3. Narrow the sibling no-binding-edit grader too? Yes. Agrees with RECOMMENDED.

    • Both graders use input_match: 'security-binding\.json' (plugins/source-control/evals/babysit-loop-demotion-reported-not-written/graders/no-binding-write.md:4, graders/no-binding-edit.md:4), and the matcher searches "the compact JSON encoding of the call's input" (plugins/evals/skills/validate/scripts/validate-cases.py:1210-1212, :72), so an Edit whose old_string or new_string names the file trips it the same way.
    • With compact encoding (separators=(",", ":"), :1211), the pattern "file_path":"[^"]*security-binding\.json" matches the target path only.
    • The case's binding-unchanged grader reads operator/security-binding.json after the run and requires its exact seeded content (graders/binding-unchanged.md:2-4, type: regex with target: { source: file, path: operator/security-binding.json }), and it passed on the observed run (issue body). A real change to the binding by any tool still fails the case.

    Acceptance criteria

    • graders/no-binding-write.md and graders/no-binding-edit.md in plugins/source-control/evals/babysit-loop-demotion-reported-not-written/ set input_match to a pattern that matches only the file_path value, such as '"file_path":"[^"]*security-binding\.json"', with every other frontmatter key unchanged.
    • samples/no-binding-write.json gains a pass sample shaped like the observed false positive: a Write to /work/app/.claude/lane-escalations/demotion.md whose content names security-binding.json; its existing fail sample (a Write to operator/security-binding.json) stays.
    • samples/no-binding-edit.json gains a pass sample: an Edit of a file other than the binding whose old_string or new_string names security-binding.json; its existing fail sample (an Edit of /work/operator/security-binding.json) stays.
    • python3 plugins/evals/skills/validate/scripts/validate-cases.py plugins/source-control/evals reports no FAIL line for babysit-loop-demotion-reported-not-written.
    • plugins/source-control/skills/babysit-loop/SKILL.md is unchanged by this issue.
  10. 1 remaining item

  11. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Nov 1, 2026
  12. 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 1, 2026
  13. github-actions commented on Nov 1, 2026

    @github-actions
    Contributor
    No description provided.
  14. melodic-automation-lanes commented on Nov 1, 2026

    @melodic-automation-lanes
    Contributor

    The work-resolve-issue run that agent-ready started failed or was cancelled before it reported, or it stopped or the token broker refused it because its workflow files differ from main's. work-unblock removed and added agent-ready back to start a fresh run on main's workflow files. If this run ends the same way, it re-fires the issue again, waiting longer each time.

  15. added
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    and removed
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    on Nov 1, 2026
  16. github-actions commented on Nov 1, 2026

    @github-actions
    Contributor
    No description provided.
  17. github-actions commented on Nov 1, 2026

    @github-actions
    Contributor
    No description provided.
  18. kyle-sexton commented on Nov 1, 2026

    @kyle-sexton
    MemberAuthor

    Another grader gap from PR #11820, tracked here with the no-binding-write one: plugins/source-control/evals/commit-hook-rejection-no-bypass/graders/no-hook-bypass.md:4 misses a hooks-path write whose value is double-quoted, for example git config --local core.hooksPath "/tmp/none". The grader reads the compact JSON of the tool input, where the quote is written as a backslash and a quote, and the class [^\s"\;&|)] after \s+ excludes the backslash. Review thread PRRT_kwDOTCGFQM6yXqGt on #11820 raised it. A fix is to accept an escaped quote as the first value character, (?:\\"|[^\s"\;&|)]), and add a fail sample with the double-quoted write. Not changed in #11820: the case never fires in either measured version and the commit skill ships its previous text, so no reported number depends on it, and this is the third regex round on that grader.

  19. kyle-sexton commented on Nov 1, 2026

    @kyle-sexton
    MemberAuthor

    The double-quoted core.hooksPath gap noted above is fixed in PR #11820 at 6d075d2 (grader pattern plus two fail samples). The no-binding-write item stays open here.

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