Skip to content

repo-hygiene:clean: emit each branch tip and require tip capture before any deletion batch #3853

Description

@kyle-sexton

This was generated by AI during triage.

Parent

Refs #3346, gap G1, first half. Listed in that issue's operating-model contract under "additional acceptance criteria beyond the ladder", so it is a named deliverable rather than an optional nicety.

What to build

Make recovery from a wrong deletion mechanical instead of lucky.

The parent records a real near-miss: an investigating pass returned eighty-one branches marked for deletion, five of which carried work that had landed nowhere. The deletion pass removed all five from both local and origin. They were recovered only because their tip identifiers happened to have been captured beforehand, for unrelated reasons. Nothing in the skill required that capture, and without it the work would have been unrecoverable, because a deleted remote branch leaves no reflog.

Two changes:

  1. The branch audit emits each branch's tip commit identifier alongside its verdict, as a first-class field in the output rather than as prose. A tip identifier is what makes a deleted branch restorable; it must be present for every branch the audit reports, not only for those it recommends deleting, since verdicts can be wrong in either direction and that is the whole point.

  2. Tip capture is a precondition for any deletion batch. The deletion path must refuse to proceed unless the tips of the branches it is about to delete have been captured to a durable artifact. Not a warning, a refusal: a warning at the moment of deletion is exactly the thing an operator working through eighty branches will skim past.

Design points the implementer should settle and state:

  • Where the captured tips live. They must outlive the session and be findable afterwards by someone who does not know how the run was invoked. A file beside the run's other artifacts is the obvious answer; state the path convention in the skill's documentation so recovery does not require reading the source.
  • What "captured" means for a stale plan. The parent records that this skill already has a working staleness guard, which correctly skipped a worktree that had changed between survey and apply. Tip capture should compose with it: a tip captured at survey time and a branch that moved before apply is precisely the case where deletion should stop rather than proceed against a stale identifier.
  • The output must state how to restore. A captured identifier that the operator does not know how to use is not recovery. Emit the restoration command, or point to it in the skill's documentation.

Acceptance criteria

  • Every branch in the audit's output carries its tip commit identifier as a structured field, not as prose.
  • A deletion batch attempted without captured tips is refused, with a message naming what is missing and how to produce it.
  • Captured tips are written to a durable artifact whose location is documented in the skill, and which survives the session.
  • A branch whose tip moved between capture and deletion stops the deletion rather than proceeding against the stale identifier.
  • The output tells the operator how to restore a branch from a captured tip.
  • A test demonstrates the end-to-end property: a branch deleted through the skill's own path can be restored from the artifact the skill produced, with no other information.
  • scripts/affected-tests.sh --run selects and passes the suites mapped to the changed files.

Out of scope

  • The additional verdict state for lossy-but-deletable branches, which is the sibling child and the other half of this gap.
  • Extending the destructive guard, which is a separate human-gated decision.
  • Remote-branch analysis as a capability, which is a later ladder rung. This item makes the existing deletion path recoverable; it does not add new deletion capability.

Blocked by

None. Can start immediately, and the parent's contract recommends landing it before any remote-deletion capability, since that rung's mistakes are irreversible.

Activity

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: highSignificant impact, or blocks an imminent release; staff this cycle.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.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions