Skip to content

emrg: a rant's issue handle is a statement, not a number a sentence mentions #2658

Closed

Description

@pm25coder

What the reading does today

scripts/review-queue.py renders one row per open rant (pending / in_progress) so a cycle can tell whether a rant has already become work. The pairing is read from the rant entry's own progress field — the place the evolution prompt's R5 writes it at take-up (issue #N), and the only per-installation record that holds the whole history.

The predicate is a substring search:

_PROGRESS_ISSUE = re.compile(r"(?i)\bissues?\s*#(\d+)((?:\s*(?:,|/|&|\band\b)\s*#\d+)*)")

\b is a word boundary, not a line anchor: the words issue/issues followed by a number, anywhere in the field, are read as this rant's issue.

The defect

progress is free text, and a cycle writes sentences into it, not only handles. A sentence that mentions some other issue — most often as the reason this rant is not being taken up yet — is read as this rant's handle.

Reproduced on 98468f4 with the tool's own function, no reimplementation:

>>> _progress_issues("R5 is closed this cycle because issue #2633 is open, "
...                  "and a rant becomes work only by opening its issue first.")
[2633]
>>> _progress_issues("issue #2637")
[2637]

The first field states no pairing. It says a different issue is open, which is precisely why this rant has none, and it is the note a cycle writes when the gate is closed. The reading answers #2633 and the row renders as though the rant had been filed against it.

Why it is not noise

This row is the only reading a cycle consults to decide whether a rant has already become work — R5's fail-closed rule, where "no issue" is the condition for opening one. A false pair therefore tells the next cycle that the rant was already filed, so that cycle neither opens its issue nor takes the rant, and the rant stops moving without anyone deciding to stop it.

It also silently disables the second reading. open_rant_rows consults the issue side (Origin: rant <ts>) only when the entry names no number (scripts/review-queue.py:672), so a narrated number does not merely add a wrong pairing — it prevents the fallback from running on a row the fallback would have answered.

And the sibling instrument cannot catch it: check-issue-links.py asks the opposite question (does an open issue have a PR that claims it) and reports nothing about a rant with no issue at all. Two readings over one wrong pair, both clean.

What the fix must satisfy

  1. A handle is a statement, not a mention. The form R5 defines — issue #N — counts when it begins a line (after optional leading whitespace and markdown emphasis), and not when it appears inside a sentence.
  2. The continuation forms stay readable: issue #1/#2, issue #1, #2, issue #1 and #2 — these are how entries spell several numbers, and they are unchanged.
  3. A progress that names no number is unchanged: no pairing, and the issue-side fallback still runs, as it does today.
  4. The comment above the predicate tells the truth. It currently calls the pattern "Anchored" while the pattern is not anchored at all.

Acceptance, measured in both directions:

  • a progress whose sentence narrates another issue ⇒ no pair, and the issues-side reading is consulted;
  • a progress that states the handle ⇒ pair, exactly as today;
  • a progress with no number ⇒ unchanged.

What the change re-reads

The rule changes which existing entries pair, so the ledger is re-measured under it rather than assumed. On this host, over 13 rants in the ledger:

rows
paired by the substring rule 12
paired by the anchored rule 2
lose their pairing 10
never paired 1

Every one of the 10 is completed, so no row the queue renders changes on the day this lands: the queue renders only pending / in_progress, and the ledger has none. The two that keep their pairing are the two most recent, and both spell the handle exactly the way R5 says to write it (issue #2459 closed; PR #2460 merged …, issue #2637 → PR #2640 …).

The 10 that lose it are entries written before the pairing moved into progress, in the shape of a report on work already finished (Merged. Issue #2565 closed by PR #2566 …, … Issue #1114 CLOSED COMPLETED …). Two consequences, both stated rather than discovered later:

  • those rows are history, so the pairing they lose is not read by anything;
  • if such an entry is ever returned to in_progress (R6's correction path), its pairing now falls to the issue-side Origin: fallback. For an issue filed after the convention moved that line does not exist, so the row would print no issue yet. That is the failure this row exists to prevent, and it is the price of no longer reading mentions as handles. A cycle writing the handle in the form R5 defines keeps it.

Activity

  1. pm25coder commented on Oct 30, 2026

    @pm25coder
    CollaboratorAuthor

    Handled by #2659

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions