Skip to content

gui: Navigate card read-back groups - #109

Draft
BenWestgate wants to merge 1 commit into
codex/gui-shared-transcriptionfrom
claude/bails-pin-reentry
Draft

BenWestgate wants to merge 1 commit into
codex/gui-shared-transcriptionfrom
claude/bails-pin-reentry

Conversation

@BenWestgate

@BenWestgate BenWestgate commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Keep matching groups locked and edit mismatches using arrows, Ctrl+arrows, Tab, Home, and End. Preserve entered text and keep the original card hidden.

Based on #171, which follows #118. This diff contains only GUI changes and their tests.

1,068 tests pass; one is skipped. The size gate fails at 2,276 lines against 2,250; awaiting the maintainer's budget decision. Ruff and library/GUI mypy pass. Supported-Tails testing remains pending.

@BenWestgate BenWestgate self-assigned this Oct 2, 2026
@BenWestgate

Copy link
Copy Markdown
Owner Author

nit: It should also lock from editing the groups that are already correct.
Like the video in this link (please watch it)
BlockstreamResearch/codex32#54 (comment)

@BenWestgate
BenWestgate marked this pull request as ready for review October 3, 2026 05:01

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1027e599cd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32_gui/entry.py Outdated
Comment on lines +111 to +112
start = next((i for i in range(same) if old[i] != new[i]), same)
tail = next((i for i in range(same - start) if old[-1 - i] != new[-1 - i]), same - start)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the deletion position for repeated symbols

When an editable group contains adjacent identical symbols, this first-difference calculation cannot determine which copy the operator deleted and ignores the GTK cursor position already captured by _reformat. For example, deleting the first B from ABBC produces ABC? with the cursor after the remaining B, so typing X yields ABXC rather than the intended AXBC. This breaks the promised in-place correction for valid cards containing repeated characters; use the actual edit/cursor location when padding the deletion.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d17822a550

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32_gui/entry.py Outdated
Comment on lines 57 to 58
self._dropped, self._locked = "", frozenset()
self.set_text(PREFIX)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear the cached card synchronously

When a read-back page is left or confirmation succeeds, clear() replaces only the GTK text and unlocks the entry, but _shown still references the complete recovery card last assigned by _reformat. set_text(PREFIX) merely schedules another idle reformat, so the card remains reachable after the page cleanup—and indefinitely if that idle callback does not run—contrary to the recovery-text clearing guarantee in docs/security/model.md. Reset _shown to PREFIX directly in clear() as part of the synchronous cleanup.

AGENTS.md reference: AGENTS.md:L78-L82

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e4f96aea5c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32_gui/entry.py Outdated
Comment on lines +114 to +115
while start and len(new) - tail > cursor and new[-1 - tail] == old[-1 - tail]:
start, tail = start - 1, tail + 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the cursor after repeated-suffix replacements

When a selection is replaced with text sharing a suffix with the old group, this adjustment only handles inferred edit boundaries to the right of GTK's cursor. For example, replacing a selected editable QQQQ group with WQQQ leaves the text correct but infers only W as typed and moves the cursor after W instead of after the replacement; subsequent typing then edits the wrong position. Fresh evidence beyond the earlier deletion case is that the current fix still fails for multi-character replacements whose trailing symbols match the old text.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think once the user has submitted their text, correct groups should be locked and only individual boxes with mistakes remain editable.
characters should no longer shift between boxes at that point, and tab can navigate between the remaining wrong boxes. We preserve the left most groups as correct when an extra or missing character falls between two groups. We also prefer the interpretation that leaves fewer red groups and more correct and locked groups.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Current head still uses one shifting Gtk.Entry plus cursor/suffix inference, so it does not implement this requested post-submit model. Rework the mismatch state into fixed editable boxes/groups with matched boxes locked and Tab navigation; that removes the repeated-symbol cursor ambiguity instead of extending the heuristic.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 728db2b835

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32_gui/entry.py Outdated
Comment on lines +119 to +120
if first // GROUP in self._locked or len(old) - tail > end:
return old, start

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow edits across adjacent open groups

When two or more consecutive groups are highlighted, selecting those groups and pasting their corrected text changes only editable groups, but this condition compares the edit against the end of the first group and restores the entire old card whenever the edit continues into the next group. For example, an eight-character replacement spanning mismatched groups 2 and 3 is rejected even though neither group is locked, forcing the operator to edit each group separately despite the UI saying all highlighted groups can be changed.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should prevent pasting as a security measure. It makes it easier to not backup the cards.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Current a458f9e still accepts pasted replacement text—indeed the latest commit explicitly lets one edit span adjacent open groups—so this requested behavior is not implemented. Disable paste in the post-submit correction state and keep edits confined to the remaining open boxes.

@chatgpt-codex-connector

This comment has been minimized.

@BenWestgate BenWestgate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex current-head re-review: NACK a458f9e. The synchronous secret-cache cleanup is fixed, but the remaining single-entry cursor heuristics still conflict with the maintainer's requested mismatch UX: matched boxes should become fixed/locked, only wrong boxes editable with Tab navigation, and paste disabled in that state. The existing repeated-symbol/cursor findings should be resolved by that rework rather than more inference. No additional finding.

@BenWestgate BenWestgate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex current-head review at a458f9e: existing P2s remain in the post-submit correction UI. Repeated-symbol edits still depend on cursor/suffix inference, paste remains accepted across open groups, and the requested fixed/locked mismatch boxes with Tab navigation are not implemented.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-24T04:37:02.054538Z fcb1a01 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 04aeb87633

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32_gui/entry.py Outdated
Comment on lines +108 to +111
self.add_css_class("card-entry")
self.set_input_hints(Gtk.InputHints.NO_SPELLCHECK | Gtk.InputHints.NO_EMOJI)
refuse_paste(self)
self.connect("changed", lambda _entry: GLib.idle_add(self._capitals))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear primary selections from correction boxes

When the operator selects text in a highlighted mismatch box—for example, before replacing the group—GroupEntry lacks the notify::selection-bound and notify::cursor-position hooks used by Codex32Entry to clear GTK's primary selection. The selected recovery fragment therefore remains published long enough for a clipboard manager to persist it, rather than being reclaimed on the next main-loop turn as promised by the GUI security model; reuse the same unpublishing behavior for these new entries.

AGENTS.md reference: AGENTS.md:L78-L82

Useful? React with 👍 / 👎.

Comment thread src/codex32_gui/pages.py Outdated
Comment on lines +525 to +527
if not result.accepted:
groups = result.mismatched_groups
where = f"Group {min(groups)}" if groups else "What you typed"
_say(status, f"{where} does not match. Check it against your card.", "error")
correct(reading.aligned(card.text.upper(), entered))
update()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve locked boundaries when retrying corrections

On every failed retry, this globally realigns the concatenated box contents and rebuilds all boxes, so an edit can move into—and unlock—a previously matched group. For example, after groups 1 and 3 are open while group 2 (NAME) is locked, correcting group 1 to MS12N causes the next retry to redraw group 1 as locked MS12 and group 2 as editable NNAME; the extra character moved across the supposedly fixed boundary. Fresh evidence beyond the earlier single-entry cursor reports is that the new fixed-box implementation discards its boundaries here; retries should realign only existing editable boxes while retaining locked labels.

AGENTS.md reference: AGENTS.md:L78-L82

Useful? React with 👍 / 👎.

BenWestgate pushed a commit that referenced this pull request Oct 7, 2026
Correction boxes did not take their selection back from the primary
clipboard (Codex review on #109). The field that did watched only the
selection bounds, but GTK also republishes the selection on focus and
when the same range is selected again, so a copy could stay published.

Both entries now share PrivateEntry, which watches the primary
clipboard while the entry is realized and takes back any local copy
made while it holds a selection. GTK only publishes from realized text,
so nothing is missed, and the handler is dropped on unrealize.

Security: narrows the window in which a clipboard manager can persist
selected card text, for the read-back field, its boxes and the restore
fields.

Validation: new primary-clipboard test passed 20 of 20 runs (the old
selection watch failed it about a third of the time); full suite
normal and -O (998 passed); ruff, mypy.

Claude-Session: https://claude.ai/code/session_018HrKoywz6PT9c91jvKou7Q
BenWestgate pushed a commit that referenced this pull request Oct 7, 2026
A failed retry realigned the joined text of every box and rebuilt them,
so an extra character typed into an open box could move across into a
locked group and unlock it (Codex review on #109).

A retry now keeps every box where it is and only rechecks the open
ones against their own groups; the cross-group alignment runs once, on
the first submission from the single field.

Its regression test, test_a_retry_keeps_every_box_where_it_is, landed
in the previous commit by mistake and passes from this one.

Validation: the retry test fails before and passes after; full suite
normal and -O (998 passed).

Claude-Session: https://claude.ai/code/session_018HrKoywz6PT9c91jvKou7Q

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6505f47b02

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32_gui/pages.py Outdated
Comment on lines +527 to +529
retried = tuple(
(box.get_text().upper(), box.get_text().upper() == want) for box, want in zip(boxes, groups)
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize spaces before locking corrected groups

When multiple boxes remain open and the operator fixes one using spaces (which the page explicitly says do not matter), confirm() evaluates the whitespace-stripped value, but this raw comparison still marks that box as wrong. For example, entering AB CD for an expected ABCD group while another group remains incorrect causes the repaired group to stay highlighted and editable on the retry. Compare each box using the same whitespace/case normalization used for confirmation while preserving the fixed group boundaries.

Useful? React with 👍 / 👎.

Comment thread tests/test_gui_boundaries.py Outdated
)
CORE_ADAPTER = "codex32._bitcoin_core"
BUDGET = 2000
BUDGET = 2050

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Synchronize the documented GUI size budget

Raising the enforced budget to 2,050 leaves the repository's review contracts stale: docs/developer/gui.md still states that this test enforces 2,000 lines, while docs/developer/api.md still records a separate 1,800-line GUI budget. Future reviewers therefore cannot tell which limit was authorized, and changes between 2,000 and 2,049 lines silently pass despite the current GUI documentation. Update the matching durable documentation together with this enforcement change.

Useful? React with 👍 / 👎.

BenWestgate pushed a commit that referenced this pull request Oct 7, 2026
The page says spaces and capitals do not matter, and confirm() strips
them, but a retry compared each box's raw text with its group, so a
group typed as "AB CD" stayed highlighted while another was still wrong
(Codex review on #109). Boxes are now compared as confirm() reads them.

Validation: new retry test fails before, passes after; GUI tests,
ruff, mypy.

Claude-Session: https://claude.ai/code/session_018HrKoywz6PT9c91jvKou7Q
BenWestgate pushed a commit that referenced this pull request Oct 7, 2026
gui.md still said 2,000 and api.md still said 1,800 after the enforced
budget rose to 2,050 for the card read-back rework (Codex review on
#109). Both now state the enforced figure, and gui.md notes why it
rose.

Claude-Session: https://claude.ai/code/session_018HrKoywz6PT9c91jvKou7Q
@chatgpt-codex-connector

This comment has been minimized.

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

This comment has been minimized.

@BenWestgate BenWestgate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI current-head review: ACK c57dd55. The fixed-box mismatch model removes the earlier cursor/repeated-symbol ambiguity, retry comparison stays within the existing group boundaries, whitespace is normalized before a repaired group locks, and PrivateEntry reclaims primary-selection contents for both the original entry and correction boxes. Paste/drop paths are disabled and the GUI budget documentation matches 2,050. The older unresolved threads are against superseded implementations; I found no current-head correctness issue.

@BenWestgate

Copy link
Copy Markdown
Owner Author

Could you squash your commits according to CONTRIBUTING.md before human code review?

@BenWestgate
BenWestgate force-pushed the claude/bails-pin-reentry branch from c57dd55 to 243c627 Compare October 7, 2026 21:00
@BenWestgate BenWestgate changed the title gui: Show every mismatch when a card is read back gui: Correct a read-back mismatch in fixed boxes Oct 7, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 243c627380

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32_gui/pages.py Outdated
field.set_visible(True)
state = reading.read(reading.normalize(typed()), length=len(card.text)) if boxes else field.reading()
# A missing or extra character may be submitted: its group is then the one highlighted.
accept.set_sensitive(abs(len(state.text) - state.expected) <= reading.SLACK)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep lookalike errors out of correction mode

When B, I, O, or 1 is typed instead of a card symbol, _reformat removes it while retaining the specific lookalike warning; this new length-only condition nevertheless enables submission because the normalized value is only one character short. check() then aligns that normalized value, permanently discarding the offending glyph and replacing its useful “probably 8/J/L/0” diagnostic with the generic mismatch message. Require the lookalike fault to be clear before enabling confirmation, while still allowing genuine missing or extra symbols.

Useful? React with 👍 / 👎.

Comment thread docs/developer/gui.md Outdated
Comment on lines +37 to +38
2,000 until the card read-back rework of 2026-10-07, which added fixed
correction boxes, group alignment and paste refusal.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the review map for the expanded modules

This note records the read-back rework, but the review map immediately above still lists reading.py and entry.py at 131 and 73 logical lines; using the test's counting rule they are now 154 and 111. It also still says only the first three modules make decisions even though entry.py now owns the primary-selection and paste-refusal security behavior, so reviewers following the documented order can under-review the newly added boundary logic. Update the table, totals, and review guidance alongside the budget rationale.

Useful? React with 👍 / 👎.

@BenWestgate BenWestgate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI-assisted current-head review: code ACK 62e1a08. Retry boxes retain matched-group boundaries, normalize spaces, reject look-alike faults, and share the primary-selection guard. The review map now covers the new security-sensitive entry code. Before human review: satisfy the requested atomic commit cleanup and exercise GTK read-back on Tails.

@BenWestgate

Copy link
Copy Markdown
Owner Author

I'm not crACKing the size of this PR +300 lines to fix something that already works properly in the CLI. That's a sign we probably aren't putting the Library API in charge of enough that they can share their good UX.

What

On the card read-back page (Bails's pinned GUI, 1938b60):

* **After a mismatch, each group gets its own fixed box.** Groups that match the card are locked; only the wrong ones can be typed in, so characters never move between groups. **Tab** moves from one wrong group to the next.

cACK, nit: arrow (by character) and Ctrl + arrow should also jump to next/last non-matching groups.. Tab having the same function as Ctrl+right arrow (except looping), might be nice if Home and End worked also.

* **A slipped character marks only its own group.** What was typed is split into the card's groups: the fewest wrong groups win, and at a group boundary the left group stays right.

nit: leftmost group stays right. elsewhere in the mixed correct incorrect data you may minimize incorrect groups.

A card within eight characters of its length can be submitted, so a single missing character is located instead of blocking the button. A typed B, I, O or 1 is still named and must be fixed first.

Why 8 characters? Why force them to fix invalid characters? Just show the groups as wrong, right? Or do you want to educate the users about the charset here rather than just get them setup as quickly and easily as possible?

* **Paste is refused** in the read-back field and its boxes: Ctrl+V, the context menu, middle-click and dropped text. The card is read back from paper.

cACK

* **Enter confirms.** The original card stays hidden, and leaving or clearing the page drops the boxes.

Thanks

Why

The current GUI line (gui-reviewability-v1) already does the highlighting and Enter. Repinning Bails to it would drop restore's recorded-fingerprint check, so this ports those behaviours onto the pin. Ben then asked for matched groups to be locked, for fixed boxes with Tab navigation, and for paste to be refused.

This is causing maintenance and review difficulty. Lets just get everything Bails needs (and I asked for) into gui-reviewability-v1 and pin Bails to that. I can't stand this having two different staging branches for the GUI.

BenWestgate added a commit that referenced this pull request Oct 22, 2026
Consolidate the existing Bails restore safeguards on gui-reviewability-v1. Verify the recorded fingerprint before listing, creating or unlocking a destination. Restoring without a record remains an explicit informed choice; fresh creation records its new fingerprint.

Replays the established Core, CLI and GUI safeguards together so Bails can use one GUI staging branch. refs #109
BenWestgate added a commit that referenced this pull request Oct 22, 2026
Move the existing CLI alignment into a toolkit-free library module so the graphical interface can reuse the same grouping and tie-breaking rules. Return only entered characters; comparison ignores whitespace and ASCII case without treating Unicode lookalikes as printed card symbols.

Exercise alignment with external strings, invalid characters, leading matches, and a property that alignment never completes the transcription. Existing CLI confirmation tests use the shared helper. refs #109
BenWestgate added a commit that referenced this pull request Oct 22, 2026
Use the library alignment shared with the CLI instead of maintaining a second alignment algorithm. Keep matching groups locked and let arrows, Ctrl+arrows, Tab, Home and End navigate the remaining boxes. Reuse read-back entry normalization and its clipboard and paste controls for each box.

Compare invalid glyphs and missing groups directly, without the former eight-character tolerance. Preserve oversized input and report the comparison limit explicitly. Clear retained correction widgets synchronously, and leave boundary-arrow behavior to GTK when no adjacent editable group exists.

Validation: GTK regression tests and the graphical walkthrough; library/CLI confirmation tests, Ruff and mypy. An independent code review found two issues, both fixed with regressions. refs #109
@BenWestgate
BenWestgate force-pushed the claude/bails-pin-reentry branch from 62e1a08 to 6f9e3ef Compare October 22, 2026 15:36
@BenWestgate BenWestgate changed the title gui: Correct a read-back mismatch in fixed boxes gui: Unify Bails staging and card read-back Oct 22, 2026
@BenWestgate
BenWestgate changed the base branch from bails-v1-pin to gui-reviewability-v1 October 22, 2026 15:37
@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

pieces, changed = _entered_groups(text, card.text)

P2 Badge Move read-back alignment off the GTK main loop

When a mismatched transcription approaches the advertised 1,024-character comparison limit, this synchronous alignment blocks the GTK event handler for a substantial time. Calling the same helper with 1,024 observed characters and a 127-character expected card took approximately 58 seconds locally; even 512 characters took 13 seconds. During that interval the window cannot repaint, navigate, or respond to requests to hide the card. Run alignment through the background-work mechanism or bound its computation sufficiently to keep the interface responsive.


if self._dropped and state.artifact is None and state.level != "error":
return replace(state, message=self._dropped, level="error")

P2 Badge Report dropped lookalikes even when the remaining card validates

In Check a card and the ordinary import flows, entering an otherwise valid card followed by B, I, O, or 1 silently removes that glyph and enables acceptance of the remaining card. For example, a valid share followed by B becomes a valid artifact and reports “Every character checks out,” because this condition suppresses the retained lookalike diagnostic whenever parsing succeeds. This can incorrectly report a damaged transcription as intact, contrary to the documented behavior of naming these glyphs rather than silently deleting them. Preserve the warning and refuse acceptance until the operator resolves the lookalike.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@BenWestgate
BenWestgate added this pull request to stack #167 October 22, 2026 23:40
Use the library alignment shared with the CLI instead of maintaining a second alignment algorithm. Keep matching groups locked and let arrows, Ctrl+arrows, Tab, Home and End navigate the remaining boxes. Reuse read-back entry normalization and its clipboard and paste controls for each box.

Compare invalid glyphs and missing groups directly, without the former eight-character tolerance. Preserve oversized input and report the comparison limit explicitly. Clear retained correction widgets synchronously, and leave boundary-arrow behavior to GTK when no adjacent editable group exists.

Validation: GTK regression tests and the graphical walkthrough; library/CLI confirmation tests, Ruff and mypy. An independent code review found two issues, both fixed with regressions. refs #109
@BenWestgate
BenWestgate marked this pull request as draft October 24, 2026 04:30
@BenWestgate
BenWestgate force-pushed the claude/bails-pin-reentry branch from 6f9e3ef to fcb1a01 Compare October 24, 2026 04:30
@BenWestgate BenWestgate changed the title gui: Unify Bails staging and card read-back gui: Navigate card read-back groups Oct 24, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@BenWestgate
BenWestgate removed this pull request from stack #167 October 24, 2026 04:33
@BenWestgate
BenWestgate changed the base branch from gui-reviewability-v1 to codex/gui-shared-transcription October 24, 2026 04:33
@BenWestgate
BenWestgate added this pull request to stack #172 October 24, 2026 04:33
@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

capture_layers=capture_layers,
observed_text=damaged_text,
seed_candidates=candidates,
optional_only=interpretation is not None,

P2 Badge Share admission limits across both case interpretations

For mixed-case damage, passing the same capture_layers list only combines accounting after admission: each _search_many() call independently invokes _frontier() with a fresh mass allowance. Consequently, the combined search can exceed the mandatory shared bound of 1. For example, replacing positions 9–21 of ms10testsxxxxxxxxxxxxxxxxxxxxxxxxxx4nzvca9cmczlw with thirteen uppercase P characters and calling correct(CorrectionContext('ms', 48), damaged) returns a candidate whose cumulative capture volume divided by its checksum space is approximately 1.318. Admit both interpretations against one ledger before searching, rather than independently admitting their frontiers and summing them afterward; the CLI's _scheduled_candidates() needs the same treatment.

AGENTS.md reference: AGENTS.md:L79-L81



P2 Badge Fit the expanded GUI within its enforced size budget

The updated GUI contains 2,276 logical review lines, so the new 2,250-line limit still makes test_the_gui_keeps_its_own_size_budget fail (assert 2276 < 2250). The parent commit contained 1,986 lines and passed its 2,000-line limit, so this is a newly introduced failure, independent of the earlier documentation mismatch. Because the test runs without GTK and is included in both workflow test matrices, it blocks those checks even on headless runners. Reduce the expanded implementation to fit the documented budget before merging.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

This branch has not been deployed

No deployments
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