Commit Graph

908 Commits

Author SHA1 Message Date
Edward Langley 044e8d2d8d Merge fix/xd3q-reset-clobbers-pipelined-placement (d0e36142) into fix/1x9h-browser-refusal-stands 2026-09-24 02:07:46 -07:00
Edward Langley d0e36142ff Merge fix/hv0r-jpba-relays (37dbf02e) into fix/xd3q-reset-clobbers-pipelined-placement
# Conflicts:
#	context/test-evidence/clients.md
2026-09-24 02:04:55 -07:00
Edward Langley 37dbf02e4e Merge gh/main (220abc61) into fix/hv0r-jpba-relays
# Conflicts:
#	context/test-evidence/clients.md
#	crates/improvise-protocol/src/client.rs
2026-09-24 02:00:09 -07:00
Edward Langley 0b645a8f0e Merge fix/xd3q-reset-clobbers-pipelined-placement (75ce4230) into fix/1x9h-browser-refusal-stands 2026-09-23 23:15:08 -07:00
Edward Langley 75ce42309a Merge fix/hv0r-jpba-relays (361ba50e) into fix/xd3q-reset-clobbers-pipelined-placement
# Conflicts:
#	context/test-evidence/clients.md
#	context/test-evidence/command.md
2026-09-23 23:11:00 -07:00
Edward Langley 271f34978b Merge gh/main (666de199) into fix/fy9o-reopened-editor-reseeded
This head already carries #272 (p6v6), merged at d9c65181.

Conflicts:
- resolve.rs advanced: main's `reopened_at` (decline an aggregate or a
  formula's result) now takes this branch's `writes` and answers the
  decline arm first, then `awaiting_seed` or `opened_on(state, ..)`, as
  the #282 review prescribed for this combination.
- context/test-evidence/{clients,command}.md: both sides' entries kept.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 23:07:51 -07:00
Edward Langley 361ba50e6c Merge gh/main (666de199) into fix/hv0r-jpba-relays
# Conflicts:
#	context/test-evidence/clients.md
#	context/test-evidence/command.md
2026-09-23 23:07:10 -07:00
Ed Langley 666de19963 Merge pull request #247 from fiddlerwoaroof/collapse-fu/h6z1
improvise-h6z1: one fold memo per grid build (stacked on #239)
2026-09-23 22:42:07 -07:00
Ed Langley eb9ec7e98b Merge pull request #277 from fiddlerwoaroof/fix/enz6-advance-onto-fold
No editor re-opens on a cell i declines: a fold or a formula's result (improvise-enz6)
2026-09-23 22:41:16 -07:00
Ed Langley 6e013511b9 Merge pull request #284 from fiddlerwoaroof/perf/i5z6-formula-tests
Parse formula.pest once per test process (improvise-i5z6)
2026-09-23 22:41:01 -07:00
Ed Langley eade33c94e Merge pull request #264 from fiddlerwoaroof/fix/uln5-help-black-holes
Mark the help rows a browser cannot run, and guard it from one list (improvise-uln5)
2026-09-23 22:40:34 -07:00
Ed Langley 881c5807c3 Merge pull request #256 from fiddlerwoaroof/fix/rq3f-resolver-gaps
Pin the browser's Tab-commit advance and the tile cursor's upper clamp (improvise-rq3f)
2026-09-23 22:39:26 -07:00
Ed Langley 4e8c5d4c9e Merge pull request #252 from fiddlerwoaroof/fix/pr8t-nacd-item-coordinates
Refuse a wire write unless every coordinate names an item (improvise-nacd, improvise-pr8t)
2026-09-23 22:39:11 -07:00
Ed Langley 2700afc027 Merge pull request #239 from fiddlerwoaroof/collapse-fu/wm20
improvise-wm20: a column total is its cell as if every drawn row were one fold
2026-09-23 22:38:33 -07:00
Ed Langley 90ea08beaf Merge pull request #249 from fiddlerwoaroof/fix/m6op-measure-agg-fixture
improvise-m6op: the cross-instance fixture carries measure_agg entries
2026-09-23 22:37:13 -07:00
Ed Langley 5074d66d10 Merge pull request #229 from fiddlerwoaroof/fix/we1a-abort-refuses
Pin that every aborting model effect also refuses (improvise-we1a)
2026-09-23 22:36:27 -07:00
Edward Langley 7025ec2471 Merge #266 (fix/xd3q) into #279: one notify, and a rebase settles the status (improvise-0dbk)
Both PRs added ClientState::notify, so the merge failed with E0592. #266's
is kept: it queues the sentence through fold_outgoing, which runs
settle_status, so the owner is still recorded. #279's direct-write notify
is deleted.

#266's rebase() rebuilt the view without settle_status, so a relay that
moved the view off the editor left the message owned, and an equal
editor reopened afterwards took it back. rebase() now settles it, pinned
by a_rebase_off_the_editor_ends_the_message_standing (red before).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 18:57:06 -07:00
Edward Langley 12f206fb0a Merge collapse-fu/wm20 (500d4609) into collapse-fu/h6z1
# Conflicts:
#	benches/grid_projection.rs
2026-09-23 18:33:53 -07:00
Edward Langley 500d46092b improvise-jq0m: pin both narrowings against the per-member definition; record the bench and the evidence
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 18:32:33 -07:00
Edward Langley b1715f49b4 improvise-i5z6: parse formula.pest once per test process
The two generator strategies re-parsed the grammar inside their
prop_map, once per generated case: the same defect improvise-8shu fixed
in improvise-io. A OnceLock takes the lib test binary from ~0.9s to
~0.06s on the same machine and load.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 18:23:45 -07:00
Edward Langley 3f9f74a7da improvise-i5z6: red test, formula.pest is re-parsed per generated case
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 18:21:52 -07:00
Edward Langley 57b713cf15 A refusal's sentence queues at the tail, so a rebase cannot erase it (improvise-n0pb)
`fold_frame` wrote the rejection sentence straight into `view.status_msg`,
so it was in neither `settled` nor `in_flight`, and the xd3q rebase erased
it whenever a relay queued behind a frame still in flight: an in-flight
frame's own `SetStatus` was replayed over it.

`ClientState::notify` queues the sentence as a view-only entry at the tail
of `in_flight`, where `fold_outgoing` puts a frame the host never answers.
Frames sent before it replay first, relays queue ahead of it, frames sent
after it may replace it, and it settles when everything ahead is answered.
Writing it into `settled` too was tried as a rival and fails the same way.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 18:20:12 -07:00
Edward Langley 08f84c25e2 improvise-jq0m: a small span narrows per covered item, not by the whole category; grouped bench cases
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 18:16:29 -07:00
Edward Langley 9eb83538fe A message beside its open editor stands in the browser too (improvise-1x9h)
The toast hid every status after six seconds, so a refusal the user was
still fixing vanished with its prompt open: su4u's bug on a timer. The
browser now asks the TUI's question. EditorSession moves into
improvise-protocol, ClientState records which editor a status was
written in, and RenderModel::status_stands tells the toast to hold it
until that editor closes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 18:08:26 -07:00
Edward Langley aab62a362a improvise-enz6: pin the commit door directly, and write up the evidence
The advance no longer reaches the commit door on a fold or a formula's
cell, so the two older advance tests stopped seeing it (measured: the
cell_key rival passes them). Two tests seat the editor there directly.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 17:56:41 -07:00
Edward Langley f4c0feec2c Close the entry half of improvise-enz6: no editor re-opens on a cell i declines
EnterEditAtCursor asks core::uneditable, the commit door's own question,
now shared with committable_cell_key. The browser's advance asks the
projected id at the landing cell; lockstep pins both ends on a fold and
on a formula's cell.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 17:49:44 -07:00
Edward Langley 69764bd52b improvise-enz6: red tests, the re-opened editor lands on a fold or a formula's cell
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 17:41:36 -07:00
Edward Langley be99391818 Merge collapse-fu/wm20 (f668ddc9) into collapse-fu/h6z1
# Conflicts:
#	context/code/command.md
#	context/test-evidence/core.md
#	crates/improvise-core/src/model/types.rs
2026-09-23 17:34:11 -07:00
Edward Langley 9872cc936f Every cell-editor opener awaits its seed while a write is unanswered (improvise-p6v6)
mdfc put the "any unanswered write" check inside `advanced` alone, so an
editor opened with i/a (`edit_or_drill`) still seeded from the cache the
write had made stale: `i 9 Tab Esc i 5 Enter`, typed faster than the
answer, stored 15 in the browser where the TUI stores 195.

The in-flight half now lives in `opened_on`, so no opener can forget it.
`advanced` keeps the "this frame writes" half, since the commit being
resolved is not in flight yet; dropping it fails the 3tt4/3uzg tests.

Stacked on #227 (fix/fy9o-reopened-editor-reseeded, de4a7d78).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 17:33:33 -07:00
Edward Langley f668ddc94e rustfmt the yb4b/b5dp changes
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 17:24:40 -07:00
Edward Langley cf5c6fc711 Mark the help rows a browser cannot run, and guard it from one list
improvise-uln5. The browser painted every help-overlay row plainly,
including six whose keys go upstream to a host that answers nothing:
/, n, H, z, Enter, and search mode's Enter/Esc. Every ex-command row was
painted plainly too, although `:` opens a command line the browser
cannot run. A dead key is worse than a gap: the keys typed after it land
on live bindings (improvise-koh6).

- resolve::NEEDS_THE_HOST is now the one list of names this client has
  no arm for. KeyRow keeps the command it was built for.
- The browser's RenderHelpRow draws a listed row, and every ex row while
  the command line is stranded, as `dim` with "(not in the browser yet)".
  It marks rather than omits: both front ends keep drawing the same rows,
  the feature stays findable, and web/ needs no change.
- the_command_names_that_still_need_the_host_are_these now drives that
  list rather than a table of its own.
- every_help_row_the_browser_cannot_run_is_one_it_marks holds it from
  the other side: silent help rows == listed rows, and no hint line
  names one.
- every_advertised_command_answers_in_its_own_mode no longer restates
  the black holes.

Red: a_help_row_the_browser_cannot_run_is_drawn_marked at 202e7eac.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 17:22:48 -07:00
Edward Langley 1a9d73259c Merge gh/main (202e7eac) into collapse-fu/wm20
# Conflicts:
#	context/test-evidence/command.md
2026-09-23 17:19:55 -07:00
Edward Langley e4b5ce9046 A relay heard while frames are in flight rebases the view on them (improvise-xd3q)
A pruning commit is answered with ResetCursor and an echo of its own
placement. A frame sent before that answer had already been folded
optimistically, and fold applied the relays straight onto view on top of
it. The echo is per frame, so the later placement was never re-sent: the
client sat at (1,0) while its mirror sat at (2,0), and the next write
landed on West where the TUI writes East.

#246 already queues each relay behind the head frame, so the queue holds
the right order. fold now rebuilds view as settled plus everything still
in flight whenever a relay queues, the same replay a refusal uses.
Replaying from settled, rather than re-applying what queued behind the
relay, is pinned by a ViewBack test: re-applying stepped back twice.

Stacked on #246 (fix/hv0r-jpba-relays, 790a33ba).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 17:19:22 -07:00
Edward Langley 076ead7c7c improvise-yb4b/b5dp: pin the scan against the per-member fold; record the ruling, the bench and the evidence
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 17:18:55 -07:00
Edward Langley ec85401a44 improvise-yb4b: a stored fold scans the store once instead of looking up each member
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 17:03:05 -07:00
Edward Langley 74920ade5d improvise-b5dp: pin the pooled-ratio ruling for a formula column's total; bench mid-size cases
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 16:59:40 -07:00
Edward Langley 3fcd407b08 A reopened editor awaits any unanswered write, settles only while editing, and states its awaiting flag (improvise-mdfc, improvise-4cb5, improvise-mgis)
improvise-mdfc: an untouched commit seeded the reopened editor from the
cache even while an earlier write from this client was unanswered, so
Tab Tab at the rightmost column stored 505 where the TUI stores 5095.
`advanced` now awaits when this frame writes or any in-flight frame is
awaited. The lockstep test sends three Tabs before answering any.

improvise-4cb5: `settle_awaited_seed` also requires an editing mode, so
an Esc before the answer no longer leaves the seed in Normal's buffer.

improvise-mgis: `OpenedEditor::awaiting` loses `serde(default)`; a frame
missing it fails to parse as the missing field (protocol.md §3, 1wl0).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 16:59:23 -07:00
Edward Langley c349d14dd6 lockstep: deliver folds host frames through fold, not fold_outgoing
improvise-xoxh, found in the delta review of #246. deliver hands a client
what the HOST sent, so a relay must go through fold, which queues it
directly behind the awaited head. fold_outgoing queues it at the back as
the client's own frame. That is the pre-jpba ordering, so a test built on
deliver could not see a jpba regression. The bug was latent, because
deliver's one caller sent only view-only frames.

deliver_queues_a_host_relay_behind_the_awaited_head was red at 790a33ba.
With deliver fixed, putting the pre-jpba ordering back in settle_relay
fails this test and nothing else in the lockstep binary.

The renaming test that came in through the gh/main merge now folds its
own commands through fold_outgoing. It also asserts that the commit is
the one awaited frame, so the two doors are told apart.

Stacked on #246 (fix/hv0r-jpba-relays).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 16:57:50 -07:00
Edward Langley eb146bccab Pin the browser's Tab-commit advance and the tile cursor's upper clamp
improvise-rq3f: two resolver faults passed the whole workspace. Two unit
tests in resolve.rs now fail under each, and only under its own fault.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 11:29:13 -07:00
Edward Langley 47b166eed9 Refuse a wire write unless every coordinate names an item
improvise-nacd and improvise-pr8t.

The b114 rule refused a coordinate that is a group. The invariant it
protects (improvise-gw18) is positive: every coordinate names an item.
Two writes onto a stored record fell in the gap and were accepted: a
measure that is no item at all (Bogus), and a parent group that holds no
item directly (Totals), where items_in_group is empty.

App::group_refusal becomes App::non_item_refusal. It refuses any
coordinate that is not in Model::effective_item_names for its category.
Formula targets count as _Measure items, so a write under a formula is
still refused by the Derived rule, with the true reason.

Tests:
- pr8t pins the same-name case: an item named like a group of its
  category is writable. Removing the old exemption fails it.
- nacd is red at 202e7eac for both Bogus and Totals.
- A third test pins that a formula cell is refused for the formula.

Two reduce.rs fixtures wrote _Measure=Revenue without the item. They now
add it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 11:20:51 -07:00
Edward Langley c0442e68da improvise-m6op: the cross-instance fixture carries measure_agg entries, so its sort is pinned
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 11:12:40 -07:00
Edward Langley 790a33ba8e Merge gh/main 202e7eac into fix/hv0r-jpba-relays
Evidence: append/append in clients.md, gh/main's entries first.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 11:04:51 -07:00
Edward Langley e0dec9660e improvise-3kfc: a refusal settles what queued behind it; lockstep folds its own commands outgoing
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 11:03:53 -07:00
Edward Langley baabe1a9b1 Evidence and the argument for seeding a reopened editor from the host's answer (improvise-3uzg, improvise-xbgm)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 10:59:41 -07:00
Edward Langley 1d2032ef82 Merge remote-tracking branch 'gh/main' into fix/fy9o-reopened-editor-reseeded
# Conflicts:
#	context/test-evidence/clients.md
#	context/test-evidence/command.md
#	crates/improvise-wasm-client/tests/lockstep.rs
2026-09-23 10:54:59 -07:00
Edward Langley 96ecfd6018 After a write, the reopened editor takes its seed from the host's answer (improvise-3uzg)
landed_seed assumed the client's cache was stale only at the cell the frame
wrote. Under prune_empty a write can take its row away and renumber the rest,
so the advance landed on a position the cache still filled with another
record. The advance after a write now opens the editor awaiting its seed, and
the client settles it from the grid it holds once nothing it sent is
unanswered. A seed never overwrites typing that arrived first.

This also removes CellValue::edit_text from the client bundle, so the
nontrapping-float-to-int wasm-opt flag a093d126 added is no longer needed and
is reverted (improvise-xbgm).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 10:53:59 -07:00
Ed Langley 202e7eac63 Merge pull request #219 from fiddlerwoaroof/fix/vndi-edit-generation
improvise-vndi: an inline edit opened before a document swap is refused
2026-09-23 10:50:14 -07:00
Ed Langley 0ff17c0f0e Merge pull request #240 from fiddlerwoaroof/fix/ugj4-jibp-mouse-editor
Mouse editor: seed from the target, report the first edit (improvise-ugj4, improvise-jibp)
2026-09-23 10:49:45 -07:00
Ed Langley 799a81aed6 Merge pull request #235 from fiddlerwoaroof/collapse-fu/b114
improvise-b114/xur5: no coordinate of a wire write may name a group
2026-09-23 10:49:18 -07:00
Ed Langley d3f03f8c01 Merge pull request #241 from fiddlerwoaroof/fix/djcn-canonical-debug
Make Model's Debug exhaustive and the Debug fingerprint canonical across instances (improvise-djcn)
2026-09-23 10:48:23 -07:00