Commit de4c8aa
fix(tui): replace permission_request double-unwrap with pattern match
Closes the concrete Phase 4 'permissions hardening' defect flagged by
the audit at app.rs:5806-5812.
`handle_permission_key` bound `pr = self.permission_request.as_mut()`
once at the top of the function, then re-borrowed `.as_mut().unwrap()`
twice more inside the Up and Down arms. The audit called this out as
high-severity because:
* the dialog can be cleared between key events (e.g. a tool result
resolves the request from the model side), and
* the inner unwrap would panic the TUI on what should be a no-op
Up/Down keystroke against a dialog that just went away.
Both arms now pattern-match via `if let Some(pr) = self.permission_request.as_mut()`
per AGENTS.md's rule "No `.unwrap()` / `.expect()` on fallible operations
in production paths — propagate via Result or pattern-match." The Up
and Down handlers silently no-op when no dialog is active, which is
the correct behaviour: there is nothing to navigate.
Two regression tests added in claurst-tui:
* arrow_keys_do_not_panic_without_permission_dialog — handles the
audit scenario directly: a stray Up/Down with no active dialog.
Before this fix that would have panicked the second unwrap.
* arrow_keys_navigate_permission_dialog_selection — pins the
bound-saturation behaviour with a real PermissionRequest, walking
past index 0 and the last index in both directions.
All four verification gates clean at v0.0.14:
cargo fmt --all -- --check ✅
cargo check --workspace ✅
cargo clippy -- -D warnings ✅
cargo test --workspace ✅ 1549 passing, 0 failing
(+2 net new tests)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 9b39623 commit de4c8aa
2 files changed
Lines changed: 62 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5880 | 5880 | | |
5881 | 5881 | | |
5882 | 5882 | | |
5883 | | - | |
5884 | | - | |
5885 | | - | |
| 5883 | + | |
| 5884 | + | |
| 5885 | + | |
| 5886 | + | |
| 5887 | + | |
| 5888 | + | |
| 5889 | + | |
| 5890 | + | |
5886 | 5891 | | |
5887 | 5892 | | |
5888 | 5893 | | |
5889 | | - | |
5890 | | - | |
5891 | | - | |
| 5894 | + | |
| 5895 | + | |
| 5896 | + | |
| 5897 | + | |
5892 | 5898 | | |
5893 | 5899 | | |
5894 | 5900 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1575 | 1575 | | |
1576 | 1576 | | |
1577 | 1577 | | |
| 1578 | + | |
| 1579 | + | |
| 1580 | + | |
| 1581 | + | |
| 1582 | + | |
| 1583 | + | |
| 1584 | + | |
| 1585 | + | |
| 1586 | + | |
| 1587 | + | |
| 1588 | + | |
| 1589 | + | |
| 1590 | + | |
| 1591 | + | |
| 1592 | + | |
| 1593 | + | |
| 1594 | + | |
| 1595 | + | |
| 1596 | + | |
| 1597 | + | |
| 1598 | + | |
| 1599 | + | |
| 1600 | + | |
| 1601 | + | |
| 1602 | + | |
| 1603 | + | |
| 1604 | + | |
| 1605 | + | |
| 1606 | + | |
| 1607 | + | |
| 1608 | + | |
| 1609 | + | |
| 1610 | + | |
| 1611 | + | |
| 1612 | + | |
| 1613 | + | |
| 1614 | + | |
| 1615 | + | |
| 1616 | + | |
| 1617 | + | |
| 1618 | + | |
| 1619 | + | |
| 1620 | + | |
| 1621 | + | |
| 1622 | + | |
| 1623 | + | |
| 1624 | + | |
| 1625 | + | |
| 1626 | + | |
| 1627 | + | |
1578 | 1628 | | |
0 commit comments