From 775f02b4e4387dcf8808d2d155d7d15aaa151708 Mon Sep 17 00:00:00 2001 From: Edward Langley Date: Tue, 22 Sep 2026 23:08:27 -0700 Subject: [PATCH] improvise-q9eg: correct the false sentence in command.md; evidence Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze --- context/code/command.md | 12 +++++++-- context/test-evidence/clients.md | 11 ++++++++ context/test-evidence/command.md | 26 +++++++++++++++++-- .../improvise-command/src/command/cmd/cell.rs | 3 ++- .../improvise-command/src/command/keymap.rs | 6 ++++- 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/context/code/command.md b/context/code/command.md index bdb1e0cc..a2e8b709 100644 --- a/context/code/command.md +++ b/context/code/command.md @@ -3197,8 +3197,16 @@ key the two questions agree, because a cursor key never carries a None-axis category. The **collapsed-group fold** half of improvise-l4mp cannot be seen by any question about the key alone, because the key carries the group's name as an ordinary coordinate. It is answered at the cursor instead, by the next section. -Since then the checks in `paste_into` are reached only by a key a script spells -out: the cursor path hands `PasteCell` a key the door has already resolved. +**The first version of that section wrote a false sentence here**: that the +checks in `paste_into` were reached "only by a key a script spells out". The +cursor path handed `PasteCell` the resolved record key, and `paste_into` ran +`aggregates` over it **again**. That is a second derivation beside `cell_id`, and +it reads a record lacking a later category (every record, once `+cat` adds one) +as an aggregate, so `p` refused where gh/main had pasted and the browser still +wrote (improvise-q9eg). The distinction is now a type: `PasteAt::Resolved` +carries a key the door answered and is written as it stands, and +`PasteAt::Spelled` carries a key a script typed, which only its shape can vet. +Nothing is asked twice. ## The cursor's cell has three doors (improvise-gw18, lx7w, 54g1, yk2s) diff --git a/context/test-evidence/clients.md b/context/test-evidence/clients.md index 2c847d86..3bff3a6a 100644 --- a/context/test-evidence/clients.md +++ b/context/test-evidence/clients.md @@ -4561,3 +4561,14 @@ normal edges only, because a dev edge would unify the feature back in which fails naming that crate while the two tests above pass. Then removed from `improvise-ws-server` alone, which fails naming it. The native path runs without `--target`, so the two arms are different invocations. + +### p_onto_a_sparse_record_writes_what_the_browser_writes + +improvise-q9eg, both ends, on a **sparse** record: `Season` is added after +entering records mode, so no record carries it. `yy` on North/Revenue, then `p` +on South/Revenue (row 1), through `both_ends`, which compares the host's +document with the one the client's composed commands build. The host refused +while the browser composed `SetCell`, so the documents differed. The final +assertion that South holds 1200 is the half that keeps the test from passing +when both ends decline. Rival: `PasteAt::Resolved` back through `paste_into`. +This test fails. diff --git a/context/test-evidence/command.md b/context/test-evidence/command.md index c5a32696..4660c50c 100644 --- a/context/test-evidence/command.md +++ b/context/test-evidence/command.md @@ -5244,8 +5244,16 @@ and a value yanked, and no stored coordinate may name a non-item. The sweep is of improvise-l4mp) without being told. The first run failed on `[(Char('p'), NONE)] on a fold stored [("Month", "Q2")]`. It asserts that the enumeration reaches `p`, so an empty sweep cannot pass. What it cannot see is a -write two keys deep (`>` then `o`). That is why the drill test above exists and -why a two-key sweep was measured and rejected as too slow. +write two keys deep (`>` then `o`). That is why the drill test above exists. A +two-key sweep was **estimated**, not measured, at several seconds and not built. + +Widened after PR #197's review, which showed that `H` without its fold check +passed the sweep: a ghost `hidden:` entry is not a stored coordinate. Every +stroke must now also leave the `## Data` section and the view's hidden set +exactly as they were. With the `H` guard disabled, this test fails as well as +the yk2s one. What no sweep can see is `clear-cell` back on the reading +accessor, because clearing a key nothing is stored at changes nothing. The +lx7w tests and the fold lockstep case catch that. ### hiding_a_folds_row_is_refused_and_persists_no_hidden_group @@ -5345,3 +5353,17 @@ refusal is recorded and the mode is not `Quit`. `import-json` failed first, before `refuse_and_stop` was applied to its arms. For `load`, the injected fault is removing its abort (`refuse_and_stop` back to `app.refuse`), and the test then fails with "`load absent.improv . q` quit having loaded nothing". + +### p_onto_a_sparse_record_writes_it + +improvise-q9eg, a regression introduced by PR #197 and found in its review. In +records mode a category is added (as `+cat` does), so every existing record +lacks it and it sits on `Axis::None`. `yy` on East/Cost, then `p` on West/Cost +(row 1): gh/main pasted 700, and #197 refused with the aggregate message. +`value_cell_key` handed `PasteCell` the real record key, and `paste_into` then +re-ran `aggregates(ctx, key)`. That key-shape check is a second derivation +beside `cell_id`, and it reads a record missing a None-axis category as an +aggregate. Every records fixture before this one was fully populated, which is +why nothing saw it. The fix is `PasteAt::{Resolved, Spelled}`: a resolved key is +written as it stands. Rival: routing `Resolved` back through `paste_into`. This +test and `p_onto_a_sparse_record_writes_what_the_browser_writes` fail. diff --git a/crates/improvise-command/src/command/cmd/cell.rs b/crates/improvise-command/src/command/cmd/cell.rs index d5f41a4b..4642aa97 100644 --- a/crates/improvise-command/src/command/cmd/cell.rs +++ b/crates/improvise-command/src/command/cmd/cell.rs @@ -359,7 +359,8 @@ mod tests { let key = record("West", "Revenue").with("Product", "Gadget"); let effects = PasteCell { at: PasteAt::Spelled(key.clone()), - }.execute(&ctx); + } + .execute(&ctx); let mut app = aggregated_app(crate::view::Axis::None); app.apply_effects(effects); assert_eq!( diff --git a/crates/improvise-command/src/command/keymap.rs b/crates/improvise-command/src/command/keymap.rs index 5bdf9f8c..50768f91 100644 --- a/crates/improvise-command/src/command/keymap.rs +++ b/crates/improvise-command/src/command/keymap.rs @@ -532,7 +532,11 @@ mod tests { } let stray = test_helpers::non_item_coordinates(&app.model_state.workbook); assert!(stray.is_empty(), "{stroke:?} on a fold stored {stray:?}"); - assert_eq!(touched(&app), before, "{stroke:?} on a fold changed the document"); + assert_eq!( + touched(&app), + before, + "{stroke:?} on a fold changed the document" + ); } }