Skip to content

A skip permanently silences the issue, and skipping is all-or-nothing when most skips have a doable half #40

Description

@havardljohansen

The skip path in work-on-issues has two problems that compound: it silences the issue permanently, and it is all-or-nothing when most skips have a doable half.

1. A skip permanently silences the issue

Verified from two lines of the same file, no state probe needed.

The guard:

--jq '.comments | sort_by(.createdAt) | last | .body // "" | startswith("Night Shift")'

"check whether the most recent comment on the issue starts with Night Shift. If it does, [skip]"

The skip comment:

gh issue comment <number> --body "Night Shift reviewed this issue but did not open a PR: …"

That comment starts with Night Shift. So the act of skipping satisfies the guard that prevents re-evaluation: once skipped, an issue is never looked at again until a human comments. The three legitimate skip reasons are all temporary in nature — a decision gets made, access gets granted, a vague issue gets clarified — and none of those events produces a comment, so none of them un-parks the issue.

Worse, the skip changes no visible state. No label, no assignee, nothing that appears in a query. The comment lands in the issue thread and the issue looks exactly like one nobody has processed. So a skipped issue is indistinguishable from an unprocessed one, which is the same ambiguity the latest-comment guard was introduced to remove — just moved one step along.

Fix, cheap: apply a label when skippingns-blocked-decision, ns-blocked-access, ns-needs-detail, matching the three reasons. Three consequences fall out of one change. The state is visible in a query, the reason is machine-readable, and the un-park condition becomes explicit: removing the label is what re-opens the issue to Night Shift, which a human does when the decision lands. Whether the guard should also ignore its own skip comments when a blocked label is absent is worth deciding at the same time.

2. Skipping is all-or-nothing, and most skips have a doable half

Currently, hitting any of the three conditions means no PR at all. But the conditions rarely block the whole issue:

  • Missing decision. The decision-independent work usually still stands: the failing test that captures the reported behaviour, the mechanical refactor the fix will sit on, or both candidate options prepared side by side so the decision becomes a choice between two diffs rather than an abstract question.
  • Missing access. Everything up to the access boundary is normally doable — the migration script written but not run, the config change staged, the exact command the human needs to execute spelled out.
  • Too vague. One specific question beats a generic "cannot form a plan". "Do you mean X or Y — X touches these three files, Y touches these two" is answerable in a sentence; "too vague" needs the human to re-derive the whole issue.

The constraint that keeps this safe, and it is not optional: partial work must not embed the missing decision. A draft PR implementing the independent half with the open question stated in its body is genuinely valuable. A PR that quietly picks one option is worse than skipping — it reads as a proposal, consumes review time, and a plausible-but-wrong choice tends to become the spec once merged. So partial work opens as a draft, says in the first line what is missing and what was deliberately not decided, and never resolves the open question by implication.

Why these two belong together

Item 1 makes item 2 safe to ship. Partial work raises the volume of things that are neither done nor abandoned — exactly the state that currently disappears. With a blocked label the partial PR and its issue are both findable; without one, a draft PR and a self-silenced issue is a worse outcome than a clean skip.

Sequencing note

Neither is urgent today: no boilerplate issue carried the night-shift label until 2026-08-14, and only four do now (sanity-nextjs-boilerplate #323, #328, #298, #306 — deliberately chosen as small, single-purpose, decision-free work). The skip path is about to get exercised much harder as labelling expands, which is the argument for fixing it while the blast radius is four issues rather than forty.

Sibling of #38 (dedupe pre-flight cannot see closed or bundled PRs) and #39 (no issue-vs-issue pass before the fan-out). All three are the same shape: the per-issue path is well built, and the surrounding bookkeeping is where work goes missing.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions