Skip to content

repo-hygiene:clean: decide whether the destructive guard should cover branch and remote-branch deletion #3852

Description

@kyle-sexton

This was generated by AI during triage.

Parent

Refs #3346, finding D1, second half. The first half (correcting the frontmatter's overstated claim) is a sibling child and does not wait on this.

The decision

The cleaning skill's destructive guard matches six command shapes. It does not match branch deletion, and it does not match remote branch deletion. Remote branch deletion is the only genuinely irreversible step in the skill's own documented branch-cleanup path: a deleted local branch is recoverable from the reflog, a deleted remote branch is recoverable only if someone captured its tip first.

So the question is not academic. Should the guard cover the skill's own most dangerous operation?

Why this is human-gated rather than a defect fix

Because the guard's current scope is a deliberate posture, not an oversight. Its own header declares it a best-effort net rather than a security boundary, with known coverage gaps explicitly accepted. An agent that simply adds patterns would be silently converting a best-effort net into something operators may then rely on as a boundary, which is worse than the current honest gap: a guard trusted beyond its design is more dangerous than one known to be partial.

The decision therefore requires answering what the guard is for, and that is a threat-model call:

  1. Is the guard a net or a boundary? The header says net. If that stands, the right coverage rule is "catch the common accidental spellings on the skill's own documented paths", and remote branch deletion clearly qualifies. If it is meant to become a boundary, that is a much larger commitment and the header, the frontmatter, and the coverage all have to change together.
  2. What does the guard block versus prompt for? Branch deletion is a routine, intentional operation in this skill's happy path. A guard that blocks it outright makes the skill unusable; one that surfaces a confirmation may duplicate the confirmation the skill already performs. The interaction with the skill's existing gating needs deciding before any pattern is written.
  3. How does this interact with the host permission layer? The parent records that on the audited machine the host's own classifier independently denied several operations, so the documented recovery path did not complete. Adding guard coverage on top of a layer that already denies unpredictably could produce a skill that cannot run at all.
  4. Does coverage extend to the six mutating scripts? They are currently unmatched. Gating them by name is brittle (a rename defeats it) and gating them by behavior is what the guard already fails to do.

None of these has a defaulted answer that triage could pick without making policy.

What a resolution looks like

A comment on this issue stating: the guard's intended role, whether branch deletion and remote branch deletion are in scope, whether the response is a block or a confirmation, and how that composes with the skill's existing gating and the host permission layer. Once those are settled the implementation is ordinary and can be delegated.

Strongly recommended regardless of the outcome

The parent's contract records two mitigations that make this decision far less load-bearing, and both are already tracked as sibling children: emitting each branch's tip identifier and requiring tip capture before any deletion batch, and surfacing lossy-but-deletable branches as their own block before the deletion confirmation. Those make the irreversible step recoverable by construction rather than by luck. If the guard decision stalls, those two should still land — they address the actual near-miss the audit recorded, in which five branches carrying unlanded work were deleted from local and origin and were recovered only because their tips happened to have been captured beforehand.

Acceptance criteria

  • The four questions above are answered in a comment on this issue.
  • If coverage is extended, the guard's header and the skill's frontmatter are updated together so the stated posture, the claimed coverage, and the actual coverage all agree.
  • If coverage is not extended, that decision and its rationale are recorded here and in the guard's header, so it is not rediscovered as a defect by the next audit.
  • Either outcome leaves no document claiming coverage the guard does not provide.

Out of scope

  • The frontmatter correction, which is a sibling child and is not blocked by this.
  • Turning the guard into a general-purpose security boundary, unless question 1 is deliberately answered that way.

Blocked by

None, but it cannot proceed without a maintainer's answer.

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

    area: securitySecurity-relevant: vulnerability, hardening, or disclosure follow-up.needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.priority: highSignificant impact, or blocks an imminent release; staff this cycle.work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions