Skip to content

fix(mention-open): a guessed repo you cannot override is a prompt with one wrong answer - #1380

Merged
ZacxDev merged 3 commits into
mainfrom
fix/guessed-repo-offers-universe
Sep 8, 2026
Merged

fix(mention-open): a guessed repo you cannot override is a prompt with one wrong answer#1380
ZacxDev merged 3 commits into
mainfrom
fix/guessed-repo-offers-universe

Conversation

@ZacxDev

@ZacxDev ZacxDev commented Sep 8, 2026

Copy link
Copy Markdown
Member

Reported from the real click path 2026-09-07. Clicking audit-pr 1291 in Alacritty
gave a one-row picker holding the tmux pane's repo, above the note "audit-pr 1291
names no repository". The operator's words:

in this case the guess is right, but in practice it's not

The defect

#1336 was right to suppress the auto-open — a default-sourced repo is evidence about
the window, not about the reference, so it must never open unconfirmed. But having
declined to act on the guess, the handler offered nothing else: confirm the wrong repo,
or dismiss and type the URL by hand. Both are worse than the refusal the picker
replaced, and it defeats the 392-row fuzzy universe from #1369 — which was already
built and sitting right there, unreached by this one arm.

The guess now leads a picker instead of being all of it: still first (most likely
answer, one Enter), with the universe appended and deduped beneath it.

Scoped to the guess that is ALONE — this is the substance, not a detail

A bare #N the pane attributes already offers two rows (clawgate task + the pane's
repo), and test_a_bare_hash_N_that_the_PANE_already_attributes_does_NOT_get_the_universe
pins that deliberately: it's the most common interaction in this handler, and burying
two good rows under several hundred is a regression dressed as a feature. My first
version wasn't scoped and broke exactly that test — the suite caught it.

The same complaint partly applies there: if the pane guess is wrong on a bare
#N, the right repo is still unreachable. Fixing it costs every ordinary click a
full-height picker — the operator's trade to make, not one to smuggle in beside a bug
fix. Left alone and written down; open question on the PR.

The note needed two wordings

"Confirm, or dismiss" is now false on the common path — neither is what to do. With
alternatives on offer it says the first row is a guess and the rest are searchable. The
one-row wording is kept, not deleted: with no mapping file the universe is empty and
a lone guessed row is still reachable.

🔴 The note is chosen by branch order, and both conditions are now true at once.
universe_note opens "nothing here knows X", which is false when the first row is a
recommendation the handler is asking about. Swapping the branches leaves the rows
correct and only the words wrong, so no behavioural test sees it —
test_a_guessed_picker_is_NOT_described_as_nothing_here_knows is the guard.

Superseded, not deleted

test_the_one_row_picker_for_a_guessed_repo_SAYS_WHY asserted n == 1 — which is
the reported defect. Renamed and now asserts n > 1; its real claims (the note explains
itself, and never names a repository) are unchanged.

Caught by the gates, not by review

The new branch adds a second offered_universe = True, which made mutation-battery rows
K38 and K19 match 2 sites instead of 1. A 2× anchor mutates a place the row doesn't
describe. Re-anchored onto unique context — and, per the guard's own instruction,
re-ran the battery rather than stopping at "the anchors parse now":

P1  control     KILLED                (the battery can observe)
K38 disclosure  KILLED(attributed)    f=1
K19 deletion    KILLED(attributed)    f=6
3/3 killed for the stated reason, restore OK

Verification

Real click path, rofi stubbed so no window is raised:

clicked before after
audit-pr 1291 1 row, no way out 392 rows, guess first, "type to search"
#1291 2 rows, no note unchanged
civitai/talos-infra#1065 opens directly unchanged

Both tiers green on the merged tree fb57872f (origin/main confirmed an ancestor):
dev-host gate.sh --tier both PASS (20,904 pytest + 1,449 node, 0 failed);
sandbox built one derivation at a time from a git archive extract — pytests PASS,
nodetests PASS.

⚠ One of my own new tests was wrong in a way worth recording: universe=[] does not
empty the universe, because repo_universe() unions the generated file with
discover_repos(). It asserted 1 row and got 4. The helper now takes the mapping as a
parameter so the empty case is actually reachable.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FENxxrZztNTsrKgChnGT1X

ZacxDev and others added 3 commits September 7, 2026 20:57
…h one wrong answer

Reported from the real click path 2026-09-07. Clicking `audit-pr 1291` in
Alacritty gave a ONE-ROW picker holding the tmux pane's repo, above the note
"audit-pr 1291 names no repository". The operator's words:

    "in this case the guess is right, but in practice it's not"

That is the defect. #1336 was right to suppress the auto-open — a
`default`-sourced repo is evidence about the WINDOW, not about the reference,
so it must never open unconfirmed. But having declined to act on the guess, the
handler offered nothing else: confirm the wrong repo, or dismiss and type the
URL by hand. Both are worse than the refusal the picker replaced, and it
defeats the 392-row fuzzy universe added in #1369 — which was already built and
sitting right there, unreached by this one arm.

So the guess now leads a picker instead of being the whole of it. It stays
FIRST — it is the most likely answer and remains one Enter away — with the
universe appended and deduped beneath it.

🔴 SCOPED TO THE GUESS THAT IS *ALONE*, and that narrowing is the substance of
the change rather than a detail. A bare `#N` the pane attributes already offers
two rows (the clawgate task and the pane's repo), and
`test_a_bare_hash_N_that_the_PANE_already_attributes_does_NOT_get_the_universe`
pins that deliberately: it is the most common interaction in this handler, and
burying two good rows under several hundred is a regression dressed as a
feature. My first version was not scoped and broke exactly that test — the
suite caught it.

⚠ The same complaint does PARTLY apply to that two-row case: if the pane guess
is wrong there, the right repo is still unreachable. Fixing it costs every
ordinary click a full-height picker, which is the operator's trade to make, not
one to smuggle in beside a bug fix. Written down, not silently taken.

The note needed two wordings, because "Confirm, or dismiss" is now FALSE on the
common path — neither is what to do. With alternatives on offer it says the
first row is a guess and the rest are searchable. The one-row wording is KEPT,
not deleted: with no mapping file the universe is empty and a lone guessed row
is still reachable.

🔴 The note is chosen by BRANCH ORDER, and both conditions are now true at once.
`universe_note` opens "nothing here knows X", which is false when the first row
is a recommendation the handler is asking about. Swapping the branches leaves
the rows correct and only the words wrong, so no behavioural test sees it —
`test_a_guessed_picker_is_NOT_described_as_nothing_here_knows` is the guard.

Superseded rather than deleted: `test_the_one_row_picker_for_a_guessed_repo_
SAYS_WHY` asserted `n == 1`, which IS the reported defect. Renamed, and it now
asserts `n > 1`; its real claims — the note explains itself, and never names a
repository — are unchanged.

⚠ One of my own new tests was wrong in a way worth recording: `universe=[]` does
NOT empty the universe, because `repo_universe()` unions the generated file with
`discover_repos()`. It asserted 1 row and got 4. The helper now takes the
mapping as a parameter so the empty case is actually reachable.

Verified through the REAL click path with `rofi` stubbed (no window raised):
  audit-pr 1291            -> 392 rows, guess FIRST, new note
  #1291                    -> 2 rows, no note (unchanged)
  civitai/talos-infra#1065 -> opens directly, no picker (unchanged)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FENxxrZztNTsrKgChnGT1X
Claude-Session-Id: 3495c5a1-5b5f-491d-b47c-606eafc05a61
…tch twice

Caught by `test_every_mutation_anchor_occurs_exactly_once_in_its_target`, in
BOTH tiers, and the guard is exactly right.

Both rows anchor on `offered_universe = True`. The guessed-repo fix adds a
second assignment of it, so each anchor went from 1x to 2x — and a 2x anchor
mutates a site the row's description does not name, which is a mutation result
about something nobody asked about. Re-anchored onto the dead-end-1 comment
line directly above the original assignment, which is unique.

🔴 Re-anchoring is HALF the fix; the guard's own message says to re-run the
battery and confirm the row still kills. Done, and both do:

  P1  control     KILLED               (the battery can observe)
  K38 disclosure  KILLED(attributed)   f=1  killer: ..._never_reaches_STDOUT_STDERR_...
  K19 deletion    KILLED(attributed)   f=6  killer: ..._ONE_ENTRY_universe_is_still_a_CHOICE_...

3/3 killed for the stated reason, restore OK. Without that re-run the anchors
would parse and the rows could still have been pinning nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FENxxrZztNTsrKgChnGT1X
Claude-Session-Id: 3495c5a1-5b5f-491d-b47c-606eafc05a61
@ZacxDev
ZacxDev merged commit bc9b900 into main Sep 8, 2026
0 of 2 checks passed
@ZacxDev
ZacxDev deleted the fix/guessed-repo-offers-universe branch September 8, 2026 03:50
ZacxDev added a commit that referenced this pull request Sep 8, 2026
#1387)

#1380 closed the shape where the pane's guess was ALONE (`audit-pr N`) and
deliberately left the bare `#N` two-row picker alone, writing the trade down in
both the handler and
`test_a_bare_hash_N_that_the_PANE_already_attributes_does_NOT_get_the_universe`:
burying two good rows under several hundred looked like "a regression dressed as
a feature". The operator overruled it on 2026-09-08 — "fix the bare-#N and any
other cases left unfixed" — because when the pane guess is wrong the right
repository is unreachable, which is the same defect one rung along.

So the offer is now scoped to `repo_source == default` alone, not to that rung
PLUS being the only row. The MEASURED rows keep their positions — clawgate,
then the pane's GitHub repo — so the common case is still one Enter, and the
fuzzy universe is appended beneath them.

Two things the widening required:

  * `guessed_note` grew a `rank`. Its multi-row wording said "The FIRST row is a
    guess", true of `audit-pr N` and FALSE of a bare `#N`, where row 1 is the
    clawgate task. Naming the wrong row is worse than saying nothing.
  * the append is guarded on what it actually ADDS, not on the universe being
    non-empty. A host whose whole universe is the pane's own repo dedupes to
    nothing, and `offered_universe` would then have claimed rows that were not
    in the list — to the auto-open guard as well as to the note.

DELIBERATELY UNCHANGED, each verified rather than assumed: `owner/repo#N` and
`repo#N` still open with zero keystrokes (they are evidence about the
REFERENCE); `#282828` is still a named toast; `--print` still refuses and never
lists a repository; a bare `#N` nothing attributed keeps PASS 3's own arm and
its silent picker.

Superseded on purpose, not deleted: the two tests that pinned the old behaviour
are rewritten to assert the new intent and to record who asked and when, keeping
the half of their claim that survives (the measured rows come FIRST, in that
order).

Test matrix — 9 red at 18bc150, 185 green at HEAD; invariant guards labelled as
such in their own docstrings. Mutation rows K45/K46/K47 added and watched to
kill for their stated reason, with P1 as the positive control.


Claude-Session: https://claude.ai/code/session_01E1h5KrSQj42u746XYVWiGh
Claude-Session-Id: 3495c5a1-5b5f-491d-b47c-606eafc05a61

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant