Skip to content

fix(source-control): require per-thread pins for autonomous bulk babysit thread resolves #326

Description

@kyle-sexton

Problem

babysit_resolve_thread.py's bulk resolve path (--resolve with no --thread-id) does not
require the per-thread TOCTOU pins that the single-thread path does, so an unattended
worker (--autonomous) can resolve review threads it never vetted.

The pin guard (--expected-comment-count + --expected-last-updated) only fires when
--thread-id is supplied (babysit_resolve_thread.py:319). The documented worker/autopilot flow
resolves in bulksource-control-babysit-resolve-thread owner/repo#N --allowed-owners <watched-owners> --resolve --include-human (SKILL.md §Autopilot step 2), no --thread-id. In
autonomous mode the tool resolves every isOutdated bot thread; because a worker's own push is
what marks a thread isOutdated, a finding can flip to outdated between the vet snapshot and the
resolve, and the bulk call clears it with no proof it was addressed.

The address-then-resolve discipline is enforced by prose ("address the finding first, then
resolve"), not by the tool: the bulk path trusts the orchestrator instead of pinning each thread.
Reported by Codex on #322 (P2, inline on babysit_resolve_thread.py).

The decision to make

Two shapes, both defensible — needs a call:

  • Reject bulk autonomous resolves: in --autonomous mode, require a pinned --thread-id per
    thread (with --expected-comment-count + --expected-last-updated), forcing the orchestrator
    to resolve one vetted thread at a time. Safest; changes the worker flow from one bulk call to a
    per-thread loop.
  • Pin the bulk set: allow bulk autonomous resolve but require a snapshot pin (e.g. the head
    SHA the vet was taken against) so a thread that changed since the vet is skipped, not cleared.

Acceptance

  • Autonomous bulk resolve can no longer clear a thread that changed since it was vetted.
  • The worker/autopilot flow in SKILL.md and reference/* is updated to the chosen shape.
  • Regression test in test_guards.py (autonomous bulk resolve without pins is refused / skips
    changed threads).

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: highSignificant impact, or blocks an imminent release; staff this cycle.status: readyTriaged, unblocked, and fully specified; eligible to pick up.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions