Skip to content

fix(app-control): close the open threads pid-binding and eval follow-ups #9546

Open

Description

@kyle-sexton

Refs: #9532

Problem

PR #9542 added the threads capture kind to /app-control:drive and a thread-dump reading page to /debugging:analyze-profile. Its review rounds found the items below. They are outside the two pid-binding safety fixes that PR completed, so they were left open there.

Fix

Drive pid binding

  • Race after the recheck. A target can exec a setuid binary with the same argv between the script's recheck and the recorder: pid, start time and cmdline hash survive exec. Recheck again after the recorder exits, and drop the capture on a difference.
  • Platform. The integer-only uid and start-time rule leaves only Linux defined. On macOS and Windows a threads capture is blocked with no named reason. Either state that the binding is Linux-only with a named block, or give each platform's integer form.
  • Under runas. "The script's own uid, which is root" does not hold there.
  • Start-time parsing. Read starttime from the fields after the last ) of /proc/<pid>/stat, since comm can hold spaces or ).
  • Order of checks. State which blocked line an invalid pid gets when unattended.
  • Elevated attach. It has no binding: capture the attached pid's uid, start time and hash when the script is shown, and recheck them in the script.
  • Other pid-targeting kinds. Pid binding covers only threads. Extend it to the cpu and heap recorders that take a pid, and say whether cleanup's stop rechecks first.
  • Secrets mark in report.json. The table has no field for it (for example secrets_mark).
  • Body size. The drive body is 175 lines, above the measured max of 160 (/skill-quality:check). Consider moving Pid binding to a reference spoke.

Evals

  • Anchor the drive graders. In threads-capture-blocked-unattended, anchor no-recorder-or-elevation and no-process-lookup to the "command":" value. Today they scan description and heredoc text, and \bps misses a lookup after an escaped \n.
  • no-shown-script. It catches only a Write to a .sh path.
  • names-a-second-dump in analyze-profile-reads-thread-dump over-matches ("another thread holds…") and under-matches ("take two dumps", "run it again"). Replace it or fold it into the judge criteria.
  • Grader samples. Add samples/<grader>.json for every new grader.
  • No-edit grader. Add a grader for "no file edited" in the analyze-profile case, and align the names-the-cycle sample's "proposes a fix" reason.
  • Interactive coverage. No case covers exit 3, a root-owned wrapper child, or the hash recheck. Add an interactive case.

Other

  • control-skill.md keeps manual pointers (dotnet-stack, GDB thread apply all, GOTRACEBACK) that the hang row no longer names. Keep them for the JVM, .NET, Go and native rows, or remove them.
  • analyze-profile's description does not name thread dumps (slice plan Q16, option a). Decide it with invocation probes.

Acceptance criteria

  • Each item above is fixed, or closed with its reason in this issue.
  • Each changed eval grader is tested against JSON-serialized tool input and has samples.
  • grep -nE '#[0-9]{3,}' over the changed skill files returns nothing.

Activity

  1. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    on Oct 24, 2026
  2. added theissue type on Oct 24, 2026
  3. kyle-sexton commented on Oct 24, 2026

    @kyle-sexton
    MemberAuthor

    Added from the #9542 review: Bundle the recheck. Codex P1 on drive/SKILL.md suggests shipping the deterministic pid recheck as a bundled script instead of having the model generate it for each capture, so the recheck is tested code rather than prose followed per run. Weigh it against the shown-script route, where the person reads the exact commands before the yes.

  4. github-actions commented on Oct 26, 2026

    @github-actions
    Contributor

    The triage sweep dispatched intake triage for this issue (attempt 1 of 2).

  5. github-actions commented on Oct 26, 2026

    @github-actions
    Contributor

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

    Size: Large
    Complexity: Medium
    Uncertainty: Knowable
    Flags: intent
    Blocked by: none

    Understood: a bundle of follow-ups from #9542 to the app-control drive pid binding, its evals, and two doc items. It's too big for one change and should be split. Three choices are left open in the text:

    1. Platform: state that pid binding is Linux-only with a named block, or give each platform's integer form? RECOMMENDED: Linux-only with a named block. The issue says only Linux is defined today, and this is the smaller change.
    2. Recheck delivery: ship the recheck as a bundled, tested script, or keep the shown script that the person reads before approving? RECOMMENDED: the bundled script, with the shown script displaying its exact invocation. This keeps the recheck as tested code without hiding the commands.
    3. analyze-profile description: name thread dumps or not? RECOMMENDED: decide after invocation probes, as the issue says.
    4. Manual pointers in control-skill.md: keep them for the JVM, .NET, Go and native rows, or remove them? RECOMMENDED: keep them, since the hang row no longer names them.

    No duplicates found.

    Automated triage, applied by the lanes App.

  6. added
    status: needs-decisionAwaiting a human or maintainer judgment call.
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 26, 2026
  7. melodic-automation-lanes commented on Oct 26, 2026

    @melodic-automation-lanes
    Contributor

    The triage verdict left this issue at status: needs-decision:

    • flagged: intent
    • held by status: needs-decision
    • no lanes App verdict comment shows whether an earlier verdict was flagged
  8. added
    work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.
    and removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 26, 2026
  9. melodic-automation-lanes commented on Oct 26, 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: Split the bundle into separate changes: pid-binding fixes in drive, eval grader fixes, and the two small doc decisions, each with its own checkable criteria.

    Dependencies

    • #​9542 merged (done); #​9490 is the open parent feature for the threads capture kind

    Related work

    Open questions

    1. Should pid binding be Linux-only with a named block on macOS and Windows, or define an integer form per platform?
      RECOMMENDED: Linux-only with a named blocked reason Basis: .base/plugins/app-control/skills/drive/SKILL.md:150
    2. Should the recheck be a bundled, tested script, or stay a shown script the person reads before approving?
      RECOMMENDED: Bundled script, with the shown script displaying its exact invocation so the commands stay visible Basis: comment by kyle-sexton on Codex P1, and intake triage item 2
    3. Should this one issue be split, since it bundles about 20 items across drive pid binding, evals and docs?
      RECOMMENDED: Yes: (1) drive pid-binding safety fixes, (2) extend binding to cpu/heap and elevated attach plus the secrets_mark field, (3) eval graders and samples, (4) body-size spoke move and control-skill.md pointers Basis: judgment: size Large per intake triage, and the acceptance criterion 'each item fixed or closed' is not checkable as one unit
    4. Should analyze-profile's description name thread dumps?
      RECOMMENDED: Decide only after invocation probes; leave out of this change until the owner runs them Basis: judgment: the issue itself defers it to probes, which an unattended run cannot judge
    5. Should the control-skill.md manual pointers (dotnet-stack, GDB thread apply all, GOTRACEBACK) be kept for the JVM, .NET, Go and native rows or removed?
      RECOMMENDED: Keep them on those rows Basis: intake triage item 4

    Sources read

    • /home/runner/work/_temp/refine-data/context.json: issue 9546, intake triage, one maintainer comment, candidates
    • plugins/app-control/skills/drive/SKILL.md:35: the capture row says threads binds to the launched pid via Pid binding
    • plugins/app-control/skills/drive/SKILL.md:134: unattended threads with no launch record gives a blocked line
    • plugins/app-control/skills/drive/SKILL.md:150: the Pid binding section starts here

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

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

    priority: mediumReal value, no hard deadline; normal backlog flow.status: needs-decisionAwaiting a human or maintainer judgment call.work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.

    Type

    Fields

    No fields configured for Task.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions