When source records collide on every coordinate, the import wizard now asks:
sum them, keep them separate with a generated occurrence category, or go
back. Collisions are found before the build by the same placement pass the
build uses, and are carried to the TUI as structured data (WizardCache) and
listed in full, scrollable. At the 12-category cap, "keep separate" is shown
disabled with its reason and remedy.
Every wizard warning and message now wraps to the panel instead of being
truncated, and long lists scroll.
Headless paths no longer sum silently: `import --no-wizard` takes
`--on-duplicate refuse|sum|separate` (default refuse), and `:import-json`
refuses and points at `:import`.
Reasoning: context/code/formula-and-io.md, "Colliding records are a
question, not a default"; context/code/tui.md; context/code/cli.md §11.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Grid: App::cmd_context counted visible_cols from term_width while
draw_content gave the grid term_width minus the 32-column side panel, so
with any panel open the cursor was scrolled past the last drawn column.
viewport::grid_width, reached through App::grid_width, is now the one
answer: draw_content splits on it and the keypress path counts on it.
Tile bar: the scroll measured from the end of the prefix while the draw
began one column later, two once scrolled (the left arrow), so the
selected tile could be dropped. tiles_left(start) is now where both the
scroll (first_tile) and the draw begin.
The grid defect dates from b5418f2e; it became the launch state when
50e4a372 opened the category panel by default, which is why it read as
a regression. Mixed-width columns still lose the cursor with no panel
open: improvise-gtn7.2. Reasoning: context/code/tui.md.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Add ADR 007 (stable identities, accepted 2026-09-25 on PR #210) and the
missing ADR 004 to the repo map's context-docs list, noting that no ADR
005/006 file exists. Add decision(improvise-sboz, ...) for clause 12:
a formula edit's display names are mapped to ids when the editor opens.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
The adversarial review of 4830fa30 found clause 6 and the km71 section
contradicted each other on a concurrent rename (B1, also Codex's P1 on
29ad14f4). Clause 12, the ADR's own reading, fixes the display-name
mapping when the formula editor opens, as OpenedCell does for cells, and
requires a regression test. fdk1 (#221) and wpxr (#281) have landed, and
CellId::Coordinate exists. Status stays proposed pending the user's
confirmation of revision 8.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
On #210 the review and comment JSON outgrew ARG_MAX, and
`jq -n --argjson ...` failed to exec with exit 126 before printing
anything. A `combine` helper now pipes the three documents to `jq -s`
through the printf builtin, on both the fixture path and the live path.
The new suite cases put about 2 MB on each surface, so a fix that moves
only one document off argv still fails. Both rivals fail 5 of 30: the
pre-fix script, and a partial fix that keeps the issue comments on argv.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Answer 29: the gensym suffix only ever goes on a generated id; an id
read from a file is never renamed, and two identical hand-written ids
refuse the load (answers 11, 22, 29). No question open; still proposed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Answers 26-28: casefold is full Unicode case folding; the suffix is a
plain number; any colliding id, on import, in a session or across kinds,
gets a suffix from a gensym-style increment-only document counter.
Status stays proposed until the user's Approved.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
AGENTS.md and the wave skill: Copilot reviews again and is answered like
Codex; check baseRefName before merging a stacked PR; land a batch as one
integration PR; never resolve with --ours/--theirs, diff against both
parents; a clean merge of one test file can still fail together; CI takes
its tools from the .#ci dev shell; watch open ADR PRs; fmt-workspaces must
not be piped; Playwright serves the assembled harness/serve/.
repo-map: gotchas 1, 3, 18, 19, 38, 42, 44 and 47 brought up to gh/main
(view-named record resolution and Grids, nested group runs and remark,
the fold's spanned narrowing, uneditable/NonItem, the browser editor's
opened cell, NEEDS_THE_HOST, notify/settle_status); recounted the wire
vocabulary (28 model effects, 26 ModelCommand variants); File Inventory
line counts refreshed at c1772ca9; the median-binary ratio is degenerate.
kb.pl, through scripts/kb: 19 new facts; five stale ones replaced (the
checker's bash pin, the nix-shebang premise, the Copilot lapse, the
dev-shell environment, the fmt pipe).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Every write the merged PRs added now names a view, chosen deliberately:
- The keyboard commit names OpenedCell::view, captured when the editor
opened, as EditTarget does for the mouse (context/code/clients.md).
- RenameRecordCoordinate names no view. Its record must hold cells, so it
resolves in the store alone: NamedRecord::Stored, as does the rename
destination records_at_stake adds. named_records replaces cells_named as
the exhaustive list records_named is read off.
- #252/#265's non_item_refusal moves into Grids::unwritable. The strict view
lookup (a missing view is RecordGone) and the Grids memo are kept.
- Test fixtures name a view their document has: Default for host() and
host_on_a_fold(), the records view for the rename pair, and the viewing
client's own view in browser_round_trip.
Evidence files: both sides kept, every heading of both parents verified
present. Test names: the merge holds every test of both parents.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Answers 21-25: spaces collapse to one _, a duplicate slug gets a numeric
suffix, a file has ids on everything or nothing; ids are globally unique;
virtual ids are _index/_dim/_measure and no other id starts with _; an
old file's undeclared item is declared at load; the version stays an
explicit first-line literal and a second literal marks the new format.
Q18(b) and a new Q22 remain open. Status stays proposed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Resolutions:
- resolve.rs: dropped #295's record_at_cursor in favour of 8xq0's
captured-cell path (commit_value / opened_at_cursor); nothing references
it any more. declined_at keeps #292's NonItem arm. #274's two new
exhaustive matches (opened_at_cursor, uncaptured) gain a NonItem arm that
answers None; refused_here already declines a commit over a NonItem cell
when nothing is captured, so uncaptured never reaches it.
- client.rs: kept main's status_seen/status_owner beside #274's
Opened/OpenedCell/OpenedTarget.
- lockstep.rs: #274 made the same sent -> sent_to_host rename #295 did;
kept this branch's sent_or_upstream (main already owns sent_to_host).
- context/test-evidence/clients.md: kept both sides. Because #274 and #295
both carry the 7mro commits, the three 7mro entries
(keys_sent_before_a_scroll_is_answered_agree_with_the_tui,
a_held_cell_is_read_at_its_position_and_not_its_cache_index,
resolve::tests::a_cursor_on_an_empty_grid_waits_for_nothing) arrived
twice. The first two copies were byte-identical; #274's copy of the third
also carries its "Amending the entry ... for #274's capture" paragraph,
so #274's copies are kept and #295's are removed. Heading union against
both parents: nothing missing.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Resolutions:
- client.rs imports: EditorSession (main) and ModelCommand (#251).
- client.rs refused(): #251 keeps the popped frame to learn which record it
renamed; main (#279/3kfc) calls settle_sent() after the pop. Both kept, in
the order pop, settle_sent, replay, then #251's Opened::Retry.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Resolutions:
- CellId: #221 gives Coordinate fields { record, category }; main (#292)
adds NonItem { category, item }. Every exhaustive match now names both
(render.rs, core.rs x2, project.rs, resolve.rs x3, wasm-client lib.rs and
render.rs); project.rs's basis arm keeps #221's Coordinate-carries-a-record.
- resolve.rs edit_or_drill: #221 drops the "renaming a coordinate" decline
(Coordinate opens an editor); main's NonItem decline arm is kept.
coordinate_at_cursor's None arm gains NonItem. reopened_at keeps #295's
declined_at shape; declined_at's editable arm names Coordinate { .. }.
- client.rs: kept main's status_seen/status_owner and #221's opened +
OpenedCoordinate; every settle site calls both settle_opened and
settle_status. Main's new rebase() also gets settle_opened, since it
rebuilds the view exactly as apply() does.
- view/mod.rs: re-export both GridEval (main) and record_row (#221).
- context/code/command.md and context/test-evidence/clients.md: both sides
appended independent sections; kept both.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Resolutions against gh/main 8d870c15:
- client.rs: kept main's settle_status (1x9h) and #295's
settle_declined_editor (5m9z) side by side.
- resolve.rs reopened_at: took #295's declined_at shape and moved #292's
CellId::NonItem arm into declined_at, which reopened_at consults before
any seed choice, so a NonItem landing still re-opens nothing.
- lockstep.rs: both sides appended at EOF; kept main's tail then #295's.
Both defined sent_to_host with different semantics (main's panics on a
non-local key, #295's lets an upstream key reach a silent host), so
#295's copy is renamed sent_or_upstream with its three callers.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Conflicts with #294 in render.rs and project.rs resolved as tested:
#250's side of every hunk (levelled GroupEnd { level }, groups()/group_of,
axis_frame's carried headers, the try_from level check), then #294's shape
(Item { tuple, .. }, FrameEntry::item(..), the DataItem { tuple, collapsed }
arm, and GroupEnd { .. } in folds). Evidence EOF appends keep both sides.