|
| 1 | +--- |
| 2 | +name: reasoning |
| 3 | +description: > |
| 4 | + Self-questioning checklist to run before implementing any feature. |
| 5 | + Use to surface edge cases, lifecycle gaps, persistence requirements, |
| 6 | + dedup needs, and UI completeness issues before writing code. |
| 7 | + Invoke mentally (or literally write answers) before starting implementation. |
| 8 | +--- |
| 9 | + |
| 10 | +# Feature Reasoning Checklist |
| 11 | + |
| 12 | +Before writing code, work through these question groups out loud. |
| 13 | +Answer each one briefly — a one-liner is enough. Unanswered questions = gaps in the plan. |
| 14 | + |
| 15 | +--- |
| 16 | + |
| 17 | +## 1. Data Model Questions |
| 18 | + |
| 19 | +*Trigger: adding or changing any struct field, enum variant, or type.* |
| 20 | + |
| 21 | +- Does this new field need to be **persisted** (saved to disk / TOML)? |
| 22 | + → If yes: add `#[serde(default)]` so old files still load. |
| 23 | +- Are there **struct literal initializations** (`Struct { field: val, ... }`) elsewhere |
| 24 | + that will now fail to compile? |
| 25 | + → Search for every place the struct is constructed by name. |
| 26 | +- Does the `Default` impl need updating? |
| 27 | +- Do any `Clone`, `PartialEq`, or `Display` impls need to handle the new field? |
| 28 | +- If I added an enum variant: are there `match` statements on this enum elsewhere? |
| 29 | + → Every exhaustive match must get a new arm. |
| 30 | + |
| 31 | +--- |
| 32 | + |
| 33 | +## 2. Lifecycle / Sync Questions |
| 34 | + |
| 35 | +*Trigger: any feature that creates, modifies, or destroys stateful data.* |
| 36 | + |
| 37 | +- **When is this data created?** (startup, user action, event?) |
| 38 | +- **When is it modified?** (every keystroke, on submit, on navigate-away?) |
| 39 | +- **When should it be flushed/saved?** Never assume "it's saved automatically." |
| 40 | + → List every code path that changes it; each path needs a save call or a sync point. |
| 41 | +- **When is it destroyed?** (tab close, workspace switch, app exit?) |
| 42 | + → Every destruction path must flush state first. |
| 43 | +- What happens on **app restart**? Is the state loaded back correctly? |
| 44 | + → Test: create → close app → reopen → is state intact? |
| 45 | + |
| 46 | +--- |
| 47 | + |
| 48 | +## 3. Idempotency / Dedup Questions |
| 49 | + |
| 50 | +*Trigger: any feature that opens, creates, or adds something.* |
| 51 | + |
| 52 | +- What happens if the user **triggers this action twice** in a row? |
| 53 | + → Should it be a no-op, an error, or create a second item? |
| 54 | +- Is there an **existing open instance** that should be re-focused instead? |
| 55 | + → Search open_tabs / active list before pushing a new item. |
| 56 | +- What if the **item already exists** with the same identity? |
| 57 | + → Define identity: is it by ID, by name, by position? |
| 58 | + |
| 59 | +--- |
| 60 | + |
| 61 | +## 4. Inverse / Symmetric Operations |
| 62 | + |
| 63 | +*Trigger: any "open", "create", "start", or "enable" action.* |
| 64 | + |
| 65 | +For every action X, list its inverses and verify each handles the new state: |
| 66 | + |
| 67 | +| Action added | Inverses to check | |
| 68 | +|---|---| |
| 69 | +| open tab | close tab, switch tab, switch workspace, app exit | |
| 70 | +| create item | delete item, rename item, duplicate item | |
| 71 | +| add field | all constructors, all serialization round-trips | |
| 72 | +| enable feature | disable feature, reset to default | |
| 73 | + |
| 74 | +**Every entry point needs a matching exit point that cleans up / persists.** |
| 75 | + |
| 76 | +--- |
| 77 | + |
| 78 | +## 5. UI Completeness Questions |
| 79 | + |
| 80 | +*Trigger: any new visible element (widget, panel, row, popup, indicator).* |
| 81 | + |
| 82 | +- Should this element be **keyboard-navigable**? |
| 83 | + → If yes: add a `Focus` variant, update `next()`/`prev()`, add visual indicator. |
| 84 | +- Does it need a **direct shortcut key** (number, letter)? |
| 85 | +- Does it need **keybinding hints** in a status bar or hint footer? |
| 86 | +- What happens when the element is **empty** (zero items, blank state)? |
| 87 | + → Render a placeholder; don't panic on `list[0]`. |
| 88 | +- What happens when the element is **out of screen bounds** (many items, small terminal)? |
| 89 | + → Clamp scroll_offset; ensure cursor stays visible. |
| 90 | + |
| 91 | +--- |
| 92 | + |
| 93 | +## 6. Related State Coherence |
| 94 | + |
| 95 | +*Trigger: any action that adds or removes items from a list, or changes active indices.* |
| 96 | + |
| 97 | +- After this action, are all **indices still valid**? |
| 98 | + → active_tab_idx, cursor, scroll_offset — clamp them after mutations. |
| 99 | +- Are there **other state fields** that reference the mutated data by index or ID? |
| 100 | + → Update or invalidate caches (e.g. highlighted_body, selected row). |
| 101 | +- Does any **other component render** based on the data I changed? |
| 102 | + → Read render functions that touch the same state; ensure they handle new shape. |
| 103 | + |
| 104 | +--- |
| 105 | + |
| 106 | +## 7. The "Who Else Touches This?" Audit |
| 107 | + |
| 108 | +*Run this for every struct, field, or function you modify.* |
| 109 | + |
| 110 | +1. Search the codebase for all uses of the symbol. |
| 111 | +2. Categorize: create / read / update / delete / display / persist / test. |
| 112 | +3. For each category: does my change break or require updating that site? |
| 113 | + |
| 114 | +``` |
| 115 | +Symbol: CollectionRequest |
| 116 | + create: CollectionRequest::new(), struct literal in sidebar_duplicate → needs url/body_raw |
| 117 | + read: flatten_tree(), find_col_request_by_id() → fine, reads by field |
| 118 | + update: update_col_request_state() → needs url/body_raw |
| 119 | + persist: save_collection_meta() → handled by serde |
| 120 | + open: handle_sidebar_enter() → needs to load url/body_raw back |
| 121 | + close: close_active_tab() → needs to sync url/body_raw first |
| 122 | +``` |
| 123 | + |
| 124 | +--- |
| 125 | + |
| 126 | +## Checklist (run before every implementation) |
| 127 | + |
| 128 | +- [ ] Listed all struct literals for modified structs → all compile? |
| 129 | +- [ ] Named every lifecycle stage (create / modify / destroy) and wired save/load |
| 130 | +- [ ] Checked for dedup: what if this is triggered twice? |
| 131 | +- [ ] Verified all inverses (close, delete, switch) handle the new state |
| 132 | +- [ ] If new UI element: added to Focus cycle, visual indicator, hint bar |
| 133 | +- [ ] Indices/cursors clamped after any list mutation |
| 134 | +- [ ] "Who else touches this?" audit complete — no missed call sites |
0 commit comments