Finish nested-list indentation and movement behavior #17

Open
opened 2026-09-13 13:34:44 +00:00 by kayg · 26 comments
Owner

Request and current status

Empty bullet and up/down movement user-confirmed; simple indentation checked, broader nesting/multiselection unresolved.

Acceptance

Tab/Shift-Tab correctly move intended blocks and descendants. Preserve immediate empty markers and Enter-on-empty exit behavior. Verify ordered/task/bullet mixes, wrapped items, disjoint/range selection, movement and undo with Markdown readback.

Keep open until the user-facing outcome is verified in a delivered build. Source review or a successful build alone is not completion.

## Request and current status Empty bullet and up/down movement user-confirmed; simple indentation checked, broader nesting/multiselection unresolved. ## Acceptance Tab/Shift-Tab correctly move intended blocks and descendants. Preserve immediate empty markers and Enter-on-empty exit behavior. Verify ordered/task/bullet mixes, wrapped items, disjoint/range selection, movement and undo with Markdown readback. Keep open until the user-facing outcome is verified in a delivered build. Source review or a successful build alone is not completion.
Author
Owner

Worker document_title_semantics, source-only audit for issue #17. Current central is wave14/editor-overnight-combined@9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405; checkout is clean. I am reviewing the nested-list command paths and existing source tests for Tab/Shift-Tab, nested movement/subtrees, blank or empty bullets, ordered/task/bullet mixes, and disjoint/range selection. No build, GUI run, checkout, or source edit will be performed. The result will separate source/test-confirmed behavior from unverified gaps and post a bounded repair/acceptance matrix here.

Worker `document_title_semantics`, source-only audit for issue #17. Current central is `wave14/editor-overnight-combined@9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405`; checkout is clean. I am reviewing the nested-list command paths and existing source tests for Tab/Shift-Tab, nested movement/subtrees, blank or empty bullets, ordered/task/bullet mixes, and disjoint/range selection. No build, GUI run, checkout, or source edit will be performed. The result will separate source/test-confirmed behavior from unverified gaps and post a bounded repair/acceptance matrix here.
Author
Owner

Issue #17 nested-list source audit

Snapshot: central wave14/editor-overnight-combined@9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405; checkout clean. This is a source/test read only. No build, GUI run, or source edit was performed.

Confirmed by source and tests

  • Tab and Shift-Tab have all three native entry paths: textView(_:doCommandBy:) routes insertTab/insertBacktab in Sources/CalternalEditor/BlockEditorView.swift:2903-2917; responder fallbacks are at 2949-2956; physical Tab key handling is at 3555-3567 and 3622-3626.
  • A contiguous range inside one list block is normalized to outline roots. handleListIndent requires list blocks, removes descendant roots, and edits every physical line in each root subtree (BlockEditorView.swift:3633-3675, 3927-3959). testNativeListIndentAndNestedMovePreserveSubtreesSelectionsAndHistory covers a wrapped continuation moving with alpha, then undo/redo (Tests/CalternalEditorTests/MarkdownBlockDocumentTests.swift:1529-1563). testListTabIsScopedToListsAndFirstItemCanIndent covers first-item indent, outdent, mixed whitespace, contiguous selected siblings, mixed-depth outdent no-op, and non-list/code Tab pass-through (1640-1718).
  • Nested sibling movement is implemented for one parsed list block when selected roots share parent and indentation depth and form a contiguous sibling span (BlockEditorView.swift:3682-3787). Existing coverage moves beta/alpha, carries continuation, handles a continuation-line caret, and checks mixed line endings/EOF mapping (MarkdownBlockDocumentTests.swift:1565-1638, 1720-1782). Root block movement preserves the complete root block/subtree (MarkdownBlockDocument.swift:673-771; test 944-952).
  • The projection recognizes each physical nested marker, ordered marker, task marker, and empty marker anchor (MarkdownProjection.swift:980-1065). testNestedListLinesKeepPerLineMarkerTaskAndEmptyIdentitySemantics verifies mixed nested rendering, task source mapping, and the empty marker (MarkdownBlockDocumentTests.swift:2560-2646).
  • Empty-item Return behavior is source-aware: an empty rendered item removes its full canonical prefix, while non-empty Return continues the list and preserves hidden IDs (BlockEditorView.swift:3048-3110, 3113-3219). Tests cover empty bullet/ordered/task source, caret/history, list continuation, and second Return exit (MarkdownBlockDocumentTests.swift:1914-1983, 1985-2172, 2174-2200).
  • Discontiguous whole-block selection already supports native copy/delete/cut and one canonical undo transaction (BlockEditorView.swift:1975-2095, 2097-2195; MarkdownBlockDocumentTests.swift:1230-1421). This does not establish structural command support.

Concrete gaps and limits

  1. Disjoint structural selection is blocked. doCommandBy beeps and returns before Tab/Shift-Tab when hasMultipleBlockSelections (BlockEditorView.swift:2903-2908). keyDown does the same before either indentation or movement (3555-3567). The direct insertTab/insertBacktab fallback calls handleListIndent, which reads only selectedRange() (3633-3643), so it cannot apply the command to all native selectedRanges. The existing disjoint-selection test checks copy/delete/cut only; there is no Tab/Shift-Tab or movement assertion.

  2. Nested movement is intentionally narrow. handleNestedListMove accepts one top-level MarkdownBlock only (3687-3693), then requires every selected root to have the same block, parent, and indentation depth and to be a contiguous sibling span (3698-3713). A mixed-depth selection is consumed as a no-op; it cannot move selected roots as a set. The outdent path similarly consumes any selection containing a depth-zero root without changing the deeper roots (3645-3650), and the existing mixed-depth test records that current no-op (1690-1704). The product rule for mixed-depth movement/outdent needs to be explicit.

  3. Blank-line-separated nested items are separate parsed blocks. The parser stops a list block on a blank physical line (MarkdownBlockDocument.swift:1008-1015). An indented item after that blank is parsed as another top-level list block, so the nested sibling path cannot see it as a sibling; the generic block mover would move the whole parsed blocks instead. There is no test specifying whether the authored blank line is a list boundary (preserve/no-op) or whether nested movement should carry it across.

  4. Empty nested bullets are projected and Return-tested, but structural commands are unverified. The regex accepts an empty marker and the projection emits an atomic zero-width anchor, but no test applies Tab, Shift-Tab, nested up/down movement, or undo/Markdown readback to an empty nested bullet/task/ordered item. This is an evidence gap rather than a claimed runtime failure.

  5. Ordered/task/bullet mixes are only projection/Return-tested. The per-line renderer and Return parser recognize the three marker families, but structural Tab/Shift-Tab and sibling movement are tested only with bullet fixtures. Cross-kind siblings, mixed kinds across a selected range, wrapped bodies, and hidden IDs need direct source readback coverage.

  6. Selection normalization is top-level-block-shaped. discontiguouslySelectedBlocks accepts only ranges exactly equal to document.blocks display ranges (1975-1987); nested list lines live inside one root block. A future structural multi-selection path must define whether a nested item is selectable independently, normalize each native range to its outline root, deduplicate descendants, and restore all ranges after the source transaction.

Bounded repair plan for the implementation lane

  • Add one structural-selection normalization seam shared by Tab/Shift-Tab and Cmd-Shift-Up/Down. Map every native display range to canonical source ranges, resolve physical list lines to outline roots, discard descendant duplicates, and retain the original per-range offsets for post-edit mapping.
  • Run structural commands before the current multi-selection beep, but reject unsupported mixed content without mutation. Apply all selected roots/subtrees in descending source order inside one canonical source transaction/undo group. Restore every native selected range, not only the primary selectedRange().
  • Keep subtree ownership explicit: selecting a parent owns all descendants; selecting same-parent siblings moves/indents them as one ordered span; mixed parent/depth selections must have a documented policy (recommended: partition only when each partition has an unambiguous sibling destination, otherwise consume with no source change and test that result).
  • Decide blank-line semantics before changing the parser. If blank lines delimit list blocks, add a readback test that movement stops at the boundary and preserves the separator. If the product wants movement across the separator, build a logical outline index across adjacent list blocks while keeping the separator in the moved envelope and test both directions.
  • Add command-event coverage for both the delegate (doCommandBy) and actual keyDown Tab/Shift-Tab/Up/Down paths, because current tests mostly call responder actions directly.

Acceptance matrix

ID Scenario Current evidence Required acceptance/readback
A Single nested bullet with wrapped continuation; Tab then Shift-Tab Implemented and covered at 1529-1563 Actual Tab and Shift-Tab events produce exact Markdown, keep selection on the body, and each command is one undo step.
B Same-parent nested siblings; Up/Down with descendants Implemented for bullet siblings at 1565-1638, EOF/line endings at 1720-1782 Add parent + grandchild, ordered/task/bullet sibling fixtures; subtree order, IDs, selection, undo/redo must round-trip exact Markdown.
C Empty nested bullet, ordered item, and task item Projection/Return covered at 1914-1983, 2174-2200, 2560-2646; structural commands absent Tab/Shift-Tab keep the immediate empty marker atomic; Up/Down moves it with descendants; Return removes the marker and second Return exits; undo/redo restores exact source.
D Ordered/task/bullet mix and wrapped bodies Per-line projection is covered; structural mix is absent Indent/outdent and sibling movement preserve each marker family, task state, numbering text, wrapped continuation, IDs, and Markdown readback.
E Contiguous range with same-depth roots and mixed depths Same-depth range covered; depth-zero outdent no-op is current behavior (1640-1704) Establish the mixed-depth policy, then assert source unchanged or the specified partitioned move; never silently act on only the primary range.
F Disjoint whole-block selection Copy/delete/cut only (1230-1421); structural paths currently beep/primary-only Command-click two list roots, apply Tab/Shift-Tab and Up/Down, preserve all selected ranges, move/indent each intended subtree once, and undo/redo to exact Markdown.
G Blank physical separator between nested-looking items Parser boundary at MarkdownBlockDocument.swift:1008-1015; no command test Lock boundary semantics: preserve/no-op or move across with separator retained; test both directions and exact line endings.
H Non-list prose/fenced code Tab pass-through covered at 1706-1717 Structural commands remain native/no source mutation outside list outlines, including mixed selections that contain unsupported blocks.

No tests were executed per the source-only constraint. Completion still requires the delivered-build user verification stated by issue #17.

# Issue #17 nested-list source audit Snapshot: central `wave14/editor-overnight-combined@9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405`; checkout clean. This is a source/test read only. No build, GUI run, or source edit was performed. ## Confirmed by source and tests - Tab and Shift-Tab have all three native entry paths: `textView(_:doCommandBy:)` routes `insertTab`/`insertBacktab` in `Sources/CalternalEditor/BlockEditorView.swift:2903-2917`; responder fallbacks are at `2949-2956`; physical Tab key handling is at `3555-3567` and `3622-3626`. - A contiguous range inside one list block is normalized to outline roots. `handleListIndent` requires list blocks, removes descendant roots, and edits every physical line in each root subtree (`BlockEditorView.swift:3633-3675`, `3927-3959`). `testNativeListIndentAndNestedMovePreserveSubtreesSelectionsAndHistory` covers a wrapped continuation moving with `alpha`, then undo/redo (`Tests/CalternalEditorTests/MarkdownBlockDocumentTests.swift:1529-1563`). `testListTabIsScopedToListsAndFirstItemCanIndent` covers first-item indent, outdent, mixed whitespace, contiguous selected siblings, mixed-depth outdent no-op, and non-list/code Tab pass-through (`1640-1718`). - Nested sibling movement is implemented for one parsed list block when selected roots share parent and indentation depth and form a contiguous sibling span (`BlockEditorView.swift:3682-3787`). Existing coverage moves `beta`/`alpha`, carries `continuation`, handles a continuation-line caret, and checks mixed line endings/EOF mapping (`MarkdownBlockDocumentTests.swift:1565-1638`, `1720-1782`). Root block movement preserves the complete root block/subtree (`MarkdownBlockDocument.swift:673-771`; test `944-952`). - The projection recognizes each physical nested marker, ordered marker, task marker, and empty marker anchor (`MarkdownProjection.swift:980-1065`). `testNestedListLinesKeepPerLineMarkerTaskAndEmptyIdentitySemantics` verifies mixed nested rendering, task source mapping, and the empty marker (`MarkdownBlockDocumentTests.swift:2560-2646`). - Empty-item Return behavior is source-aware: an empty rendered item removes its full canonical prefix, while non-empty Return continues the list and preserves hidden IDs (`BlockEditorView.swift:3048-3110`, `3113-3219`). Tests cover empty bullet/ordered/task source, caret/history, list continuation, and second Return exit (`MarkdownBlockDocumentTests.swift:1914-1983`, `1985-2172`, `2174-2200`). - Discontiguous whole-block selection already supports native copy/delete/cut and one canonical undo transaction (`BlockEditorView.swift:1975-2095`, `2097-2195`; `MarkdownBlockDocumentTests.swift:1230-1421`). This does not establish structural command support. ## Concrete gaps and limits 1. **Disjoint structural selection is blocked.** `doCommandBy` beeps and returns before Tab/Shift-Tab when `hasMultipleBlockSelections` (`BlockEditorView.swift:2903-2908`). `keyDown` does the same before either indentation or movement (`3555-3567`). The direct `insertTab`/`insertBacktab` fallback calls `handleListIndent`, which reads only `selectedRange()` (`3633-3643`), so it cannot apply the command to all native `selectedRanges`. The existing disjoint-selection test checks copy/delete/cut only; there is no Tab/Shift-Tab or movement assertion. 2. **Nested movement is intentionally narrow.** `handleNestedListMove` accepts one top-level `MarkdownBlock` only (`3687-3693`), then requires every selected root to have the same block, parent, and indentation depth and to be a contiguous sibling span (`3698-3713`). A mixed-depth selection is consumed as a no-op; it cannot move selected roots as a set. The outdent path similarly consumes any selection containing a depth-zero root without changing the deeper roots (`3645-3650`), and the existing mixed-depth test records that current no-op (`1690-1704`). The product rule for mixed-depth movement/outdent needs to be explicit. 3. **Blank-line-separated nested items are separate parsed blocks.** The parser stops a list block on a blank physical line (`MarkdownBlockDocument.swift:1008-1015`). An indented item after that blank is parsed as another top-level list block, so the nested sibling path cannot see it as a sibling; the generic block mover would move the whole parsed blocks instead. There is no test specifying whether the authored blank line is a list boundary (preserve/no-op) or whether nested movement should carry it across. 4. **Empty nested bullets are projected and Return-tested, but structural commands are unverified.** The regex accepts an empty marker and the projection emits an atomic zero-width anchor, but no test applies Tab, Shift-Tab, nested up/down movement, or undo/Markdown readback to an empty nested bullet/task/ordered item. This is an evidence gap rather than a claimed runtime failure. 5. **Ordered/task/bullet mixes are only projection/Return-tested.** The per-line renderer and Return parser recognize the three marker families, but structural Tab/Shift-Tab and sibling movement are tested only with bullet fixtures. Cross-kind siblings, mixed kinds across a selected range, wrapped bodies, and hidden IDs need direct source readback coverage. 6. **Selection normalization is top-level-block-shaped.** `discontiguouslySelectedBlocks` accepts only ranges exactly equal to `document.blocks` display ranges (`1975-1987`); nested list lines live inside one root block. A future structural multi-selection path must define whether a nested item is selectable independently, normalize each native range to its outline root, deduplicate descendants, and restore all ranges after the source transaction. ## Bounded repair plan for the implementation lane - Add one structural-selection normalization seam shared by Tab/Shift-Tab and Cmd-Shift-Up/Down. Map every native display range to canonical source ranges, resolve physical list lines to outline roots, discard descendant duplicates, and retain the original per-range offsets for post-edit mapping. - Run structural commands before the current multi-selection beep, but reject unsupported mixed content without mutation. Apply all selected roots/subtrees in descending source order inside one canonical source transaction/undo group. Restore every native selected range, not only the primary `selectedRange()`. - Keep subtree ownership explicit: selecting a parent owns all descendants; selecting same-parent siblings moves/indents them as one ordered span; mixed parent/depth selections must have a documented policy (recommended: partition only when each partition has an unambiguous sibling destination, otherwise consume with no source change and test that result). - Decide blank-line semantics before changing the parser. If blank lines delimit list blocks, add a readback test that movement stops at the boundary and preserves the separator. If the product wants movement across the separator, build a logical outline index across adjacent list blocks while keeping the separator in the moved envelope and test both directions. - Add command-event coverage for both the delegate (`doCommandBy`) and actual `keyDown` Tab/Shift-Tab/Up/Down paths, because current tests mostly call responder actions directly. ## Acceptance matrix | ID | Scenario | Current evidence | Required acceptance/readback | |---|---|---|---| | A | Single nested bullet with wrapped continuation; Tab then Shift-Tab | Implemented and covered at `1529-1563` | Actual Tab and Shift-Tab events produce exact Markdown, keep selection on the body, and each command is one undo step. | | B | Same-parent nested siblings; Up/Down with descendants | Implemented for bullet siblings at `1565-1638`, EOF/line endings at `1720-1782` | Add parent + grandchild, ordered/task/bullet sibling fixtures; subtree order, IDs, selection, undo/redo must round-trip exact Markdown. | | C | Empty nested bullet, ordered item, and task item | Projection/Return covered at `1914-1983`, `2174-2200`, `2560-2646`; structural commands absent | Tab/Shift-Tab keep the immediate empty marker atomic; Up/Down moves it with descendants; Return removes the marker and second Return exits; undo/redo restores exact source. | | D | Ordered/task/bullet mix and wrapped bodies | Per-line projection is covered; structural mix is absent | Indent/outdent and sibling movement preserve each marker family, task state, numbering text, wrapped continuation, IDs, and Markdown readback. | | E | Contiguous range with same-depth roots and mixed depths | Same-depth range covered; depth-zero outdent no-op is current behavior (`1640-1704`) | Establish the mixed-depth policy, then assert source unchanged or the specified partitioned move; never silently act on only the primary range. | | F | Disjoint whole-block selection | Copy/delete/cut only (`1230-1421`); structural paths currently beep/primary-only | Command-click two list roots, apply Tab/Shift-Tab and Up/Down, preserve all selected ranges, move/indent each intended subtree once, and undo/redo to exact Markdown. | | G | Blank physical separator between nested-looking items | Parser boundary at `MarkdownBlockDocument.swift:1008-1015`; no command test | Lock boundary semantics: preserve/no-op or move across with separator retained; test both directions and exact line endings. | | H | Non-list prose/fenced code | Tab pass-through covered at `1706-1717` | Structural commands remain native/no source mutation outside list outlines, including mixed selections that contain unsupported blocks. | No tests were executed per the source-only constraint. Completion still requires the delivered-build user verification stated by issue #17.
Author
Owner

Implementation start / plan from worker /root/block_drag_finish.

  • Worktree: /Users/kayg/Developer/calternal-app/.worktrees/editor-list-refinements
  • Branch: wave16/editor-list-refinements
  • Base: exact central 56e61d2e4d8da6915fc693a99b2d09d8b5160863
  • Ownership: list structural-command portions of Sources/CalternalEditor/BlockEditorView.swift and one focused regression in Tests/CalternalEditorTests/MarkdownBlockDocumentTests.swift only.

Source finding: discontiguous native selectedRanges currently beep before Tab/Shift-Tab in both delegate and keyDown routes. Direct responder Tab reaches handleListIndent, which reads only selectedRange() and would mutate only the primary range. Existing single/range list indentation, subtree traversal, mixed-depth no-op, empty-anchor projection, and canonical source-edit helpers are otherwise reusable.

Bounded plan for this candidate:

  1. Add one transient list structural-selection normalization helper. Map every native display range to its canonical source range, resolve only its touched parsed list blocks, build outline items through the existing physical-line parser, select outline roots, deduplicate repeated roots and descendants, and retain every original source selection for restoration. No persistent block model or parser change.
  2. Reject the command atomically when any selected range touches prose/code or cannot resolve to a list root. Single non-list Tab retains native pass-through; invalid discontiguous structural selections are consumed without source mutation so AppKit cannot edit only one range.
  3. Apply indentation/outdent edits for every selected root subtree in descending-safe order through one existing canonical source transaction and one Undo record. Preserve the current atomic outdent policy: if any selected root is already depth zero, the entire outdent is a consumed no-op.
  4. Map both endpoints of every original source selection through the shared edit list, convert all mapped ranges back to display ranges, and restore them via native setSelectedRanges. A parent root owns its descendants; repeated descendant selections are edited once.
  5. Route Tab/Shift-Tab ahead of the existing multi-selection beep in both textView(_:doCommandBy:) and physical keyDown. Copy/Cut/Delete, movement, paste, formatting, and IME guards remain unchanged in this candidate.
  6. Add one focused regression using disjoint nested bullet/empty-marker/ordered/task selections with wrapped continuation, hidden IDs, CRLF and authored blank separators. Exercise the delegate Tab path and physical Shift-Tab keyDown path, assert exact Markdown, unchanged blank boundaries, all native ranges restored, one Undo per mutation, and mixed prose selection consumed without mutation.

Performance scope: outline parsing is limited to the blocks touched by the native ranges; roots and edited physical-line starts are deduplicated. No full-document scan is introduced. No local build or VM run; plan review by /root/editor_polish_inventory is the next gate.

Implementation start / plan from worker `/root/block_drag_finish`. - Worktree: `/Users/kayg/Developer/calternal-app/.worktrees/editor-list-refinements` - Branch: `wave16/editor-list-refinements` - Base: exact central `56e61d2e4d8da6915fc693a99b2d09d8b5160863` - Ownership: list structural-command portions of `Sources/CalternalEditor/BlockEditorView.swift` and one focused regression in `Tests/CalternalEditorTests/MarkdownBlockDocumentTests.swift` only. Source finding: discontiguous native `selectedRanges` currently beep before Tab/Shift-Tab in both delegate and keyDown routes. Direct responder Tab reaches `handleListIndent`, which reads only `selectedRange()` and would mutate only the primary range. Existing single/range list indentation, subtree traversal, mixed-depth no-op, empty-anchor projection, and canonical source-edit helpers are otherwise reusable. Bounded plan for this candidate: 1. Add one transient list structural-selection normalization helper. Map every native display range to its canonical source range, resolve only its touched parsed list blocks, build outline items through the existing physical-line parser, select outline roots, deduplicate repeated roots and descendants, and retain every original source selection for restoration. No persistent block model or parser change. 2. Reject the command atomically when any selected range touches prose/code or cannot resolve to a list root. Single non-list Tab retains native pass-through; invalid discontiguous structural selections are consumed without source mutation so AppKit cannot edit only one range. 3. Apply indentation/outdent edits for every selected root subtree in descending-safe order through one existing canonical source transaction and one Undo record. Preserve the current atomic outdent policy: if any selected root is already depth zero, the entire outdent is a consumed no-op. 4. Map both endpoints of every original source selection through the shared edit list, convert all mapped ranges back to display ranges, and restore them via native `setSelectedRanges`. A parent root owns its descendants; repeated descendant selections are edited once. 5. Route Tab/Shift-Tab ahead of the existing multi-selection beep in both `textView(_:doCommandBy:)` and physical `keyDown`. Copy/Cut/Delete, movement, paste, formatting, and IME guards remain unchanged in this candidate. 6. Add one focused regression using disjoint nested bullet/empty-marker/ordered/task selections with wrapped continuation, hidden IDs, CRLF and authored blank separators. Exercise the delegate Tab path and physical Shift-Tab keyDown path, assert exact Markdown, unchanged blank boundaries, all native ranges restored, one Undo per mutation, and mixed prose selection consumed without mutation. Performance scope: outline parsing is limited to the blocks touched by the native ranges; roots and edited physical-line starts are deduplicated. No full-document scan is introduced. No local build or VM run; plan review by `/root/editor_polish_inventory` is the next gate.
Author
Owner

Reviewer: /root/editor_polish_inventory

Plan reviewed against /tmp/calternal_issue17_nested_bullet_audit_20260913.md, the latest issue comment, and exact base 56e61d2e4d8da6915fc693a99b2d09d8b5160863 in .worktrees/editor-list-refinements.

Verdict: revise the plan before implementation. No source edits/build/GUI were performed.

P1 — Define and preserve native selection identity, not only mapped ranges

  • Location: proposed normalization/restoration steps 1 and 4; existing selection state is BlockEditorView.swift:1967-1987, 2197-2212, and source-position affinity is 4022-4095.
  • What can break: multiple source ranges can collapse to the same projected display range around hidden indentation, markers, IDs, or the atomic empty-item anchor. Sorting/deduplicating restored ranges can also change the primary selection. The next Shift extension, keyboard command, reveal target, and caret affinity can then act from a different item even when the Markdown edit is correct.
  • Why likely: the plan retains endpoints but does not specify primary-range identity, endpoint insertion affinity, duplicate/overlap handling after source-to-display projection, or restoration of blockSelectionAnchorSourceLocation. Existing mappedSourcePosition deliberately uses different affinity for range starts, ends, and carets; calling it generically for every endpoint is insufficient.
  • Scoped fix: normalize into records carrying original native index/primary status, source start/end with explicit before/after insertion affinity, resolved root identity, and reveal/anchor identity. After the single edit, map records, project them, reject invalid UTF-16 boundaries, coalesce only truly identical/overlapping display ranges under a documented rule, restore the intended primary/reveal range, and restore or deliberately clear the block anchor. Test empty anchors, hidden IDs, carets at line starts/ends, reversed click order, and a follow-up Shift selection after Tab/Shift-Tab.

P2 — Reusing current outline and endpoint helpers makes large selections quadratic

  • Location: existing listOutlineItems at BlockEditorView.swift:3797-3848, selectedListOutlineRoots at 3927-3959, and mappedSourcePosition at 4072-4095; proposed steps 1 and 4.
  • What can break: a large list block or many selected ranges can stall the main thread. listOutlineItems searches backward for a parent and forward for each subtree (quadratic in item count). Resolving every range by filtering all items and walking ancestors adds another range×item cost. Mapping two endpoints for every range through every edit is range×edit.
  • Why likely: “only touched blocks” is not a complexity bound when one parsed list block contains thousands of items, and multiple native ranges may touch that same block. The plan mentions root deduplication but not unique-block parsing or ordered endpoint mapping.
  • Scoped fix: parse each unique touched block once; compute parents/subtree ends with one indentation stack; resolve sorted selection intervals and roots in one ordered sweep (or binary interval lookup); deduplicate roots with a set plus ancestor ownership; map all sorted endpoints using prefix deltas/binary search over ordered edits. Add the repository-supported 10K-list adversarial/performance case with many disjoint selections and descendant duplicates.

P2 — One transaction needs an explicit sparse-edit/envelope cost policy

  • Location: proposed step 3 versus existing applyListSourceEdits at BlockEditorView.swift:4022-4069.
  • What can break: reusing the current helper forms one replacement envelope from the first to last edit. Two selected blocks near opposite ends of a large note copy and replace nearly the entire intervening document, forcing broad parsing/projection work even though only two list roots changed. Applying edits one by one instead would rebuild repeatedly and risks multiple undo/notification boundaries.
  • Why likely: the plan requires both descending sparse edits and one canonical edit/Undo but does not identify the actual batch seam. The current API supports one contiguous replacement envelope.
  • Scoped fix: state the chosen bounded transaction explicitly. Prefer one document batch-source mutation that validates all nonoverlapping edits, constructs final source once, synchronizes/projections once, registers one undo snapshot, and emits one commit notification; if the contiguous envelope is retained, add a widely separated selection performance test and accept only measured bounded behavior. Preserve all bytes and blank separators between edits.

P2 — The test must distinguish reachable whole-block selection from programmatic nested ranges

  • Location: proposed focused regression and existing Command-click normalization at BlockEditorView.swift:2097-2195.
  • What can break: current pointer selection creates whole top-level MarkdownBlock ranges; nested list items live inside one such block. A test that directly injects discontiguous nested-line ranges can pass while users cannot create that state, or it can establish semantics different from selecting the whole list block (which resolves to all depth-zero roots).
  • Why likely: the plan combines “native selectedRange” with nested root selection without specifying how each range is obtained. Existing discontiguouslySelectedBlocks accepts exact top-level block ranges only.
  • Scoped fix: split acceptance inside the single focused test: first use the public Command-click decision seam to create the reachable disjoint whole-block selection and prove Tab/Shift-Tab; then separately label injected nested-line ranges as a normalization-unit seam. Assert whole-list-block policy explicitly. Do not claim nested discontiguous pointer selection until a user path exists.

The atomic mixed-content policy, descendant ownership, depth-zero outdent no-op, blank-line parser boundary, routing Tab ahead of the multi-selection beep, and one-undo intent are sound. Ensure insertTab/insertBacktab, delegate doCommandBy, and physical keyDown all call the same tri-state result (not handled, consumed no-op/rejected, mutated) so single non-list Tab still reaches AppKit while invalid discontiguous commands cannot mutate only the primary range.

Reviewer: `/root/editor_polish_inventory` Plan reviewed against `/tmp/calternal_issue17_nested_bullet_audit_20260913.md`, the latest issue comment, and exact base `56e61d2e4d8da6915fc693a99b2d09d8b5160863` in `.worktrees/editor-list-refinements`. Verdict: **revise the plan before implementation.** No source edits/build/GUI were performed. ### P1 — Define and preserve native selection identity, not only mapped ranges - Location: proposed normalization/restoration steps 1 and 4; existing selection state is `BlockEditorView.swift:1967-1987, 2197-2212`, and source-position affinity is `4022-4095`. - What can break: multiple source ranges can collapse to the same projected display range around hidden indentation, markers, IDs, or the atomic empty-item anchor. Sorting/deduplicating restored ranges can also change the primary selection. The next Shift extension, keyboard command, reveal target, and caret affinity can then act from a different item even when the Markdown edit is correct. - Why likely: the plan retains endpoints but does not specify primary-range identity, endpoint insertion affinity, duplicate/overlap handling after source-to-display projection, or restoration of `blockSelectionAnchorSourceLocation`. Existing `mappedSourcePosition` deliberately uses different affinity for range starts, ends, and carets; calling it generically for every endpoint is insufficient. - Scoped fix: normalize into records carrying original native index/primary status, source start/end with explicit before/after insertion affinity, resolved root identity, and reveal/anchor identity. After the single edit, map records, project them, reject invalid UTF-16 boundaries, coalesce only truly identical/overlapping display ranges under a documented rule, restore the intended primary/reveal range, and restore or deliberately clear the block anchor. Test empty anchors, hidden IDs, carets at line starts/ends, reversed click order, and a follow-up Shift selection after Tab/Shift-Tab. ### P2 — Reusing current outline and endpoint helpers makes large selections quadratic - Location: existing `listOutlineItems` at `BlockEditorView.swift:3797-3848`, `selectedListOutlineRoots` at `3927-3959`, and `mappedSourcePosition` at `4072-4095`; proposed steps 1 and 4. - What can break: a large list block or many selected ranges can stall the main thread. `listOutlineItems` searches backward for a parent and forward for each subtree (quadratic in item count). Resolving every range by filtering all items and walking ancestors adds another range×item cost. Mapping two endpoints for every range through every edit is range×edit. - Why likely: “only touched blocks” is not a complexity bound when one parsed list block contains thousands of items, and multiple native ranges may touch that same block. The plan mentions root deduplication but not unique-block parsing or ordered endpoint mapping. - Scoped fix: parse each unique touched block once; compute parents/subtree ends with one indentation stack; resolve sorted selection intervals and roots in one ordered sweep (or binary interval lookup); deduplicate roots with a set plus ancestor ownership; map all sorted endpoints using prefix deltas/binary search over ordered edits. Add the repository-supported 10K-list adversarial/performance case with many disjoint selections and descendant duplicates. ### P2 — One transaction needs an explicit sparse-edit/envelope cost policy - Location: proposed step 3 versus existing `applyListSourceEdits` at `BlockEditorView.swift:4022-4069`. - What can break: reusing the current helper forms one replacement envelope from the first to last edit. Two selected blocks near opposite ends of a large note copy and replace nearly the entire intervening document, forcing broad parsing/projection work even though only two list roots changed. Applying edits one by one instead would rebuild repeatedly and risks multiple undo/notification boundaries. - Why likely: the plan requires both descending sparse edits and one canonical edit/Undo but does not identify the actual batch seam. The current API supports one contiguous replacement envelope. - Scoped fix: state the chosen bounded transaction explicitly. Prefer one document batch-source mutation that validates all nonoverlapping edits, constructs final source once, synchronizes/projections once, registers one undo snapshot, and emits one commit notification; if the contiguous envelope is retained, add a widely separated selection performance test and accept only measured bounded behavior. Preserve all bytes and blank separators between edits. ### P2 — The test must distinguish reachable whole-block selection from programmatic nested ranges - Location: proposed focused regression and existing Command-click normalization at `BlockEditorView.swift:2097-2195`. - What can break: current pointer selection creates whole top-level `MarkdownBlock` ranges; nested list items live inside one such block. A test that directly injects discontiguous nested-line ranges can pass while users cannot create that state, or it can establish semantics different from selecting the whole list block (which resolves to all depth-zero roots). - Why likely: the plan combines “native selectedRange” with nested root selection without specifying how each range is obtained. Existing `discontiguouslySelectedBlocks` accepts exact top-level block ranges only. - Scoped fix: split acceptance inside the single focused test: first use the public Command-click decision seam to create the reachable disjoint whole-block selection and prove Tab/Shift-Tab; then separately label injected nested-line ranges as a normalization-unit seam. Assert whole-list-block policy explicitly. Do not claim nested discontiguous pointer selection until a user path exists. The atomic mixed-content policy, descendant ownership, depth-zero outdent no-op, blank-line parser boundary, routing Tab ahead of the multi-selection beep, and one-undo intent are sound. Ensure `insertTab`/`insertBacktab`, delegate `doCommandBy`, and physical keyDown all call the same tri-state result (`not handled`, `consumed no-op/rejected`, `mutated`) so single non-list Tab still reaches AppKit while invalid discontiguous commands cannot mutate only the primary range.
Author
Owner

Revised implementation plan after reviewer findings — /root/block_drag_finish

No issue #17 production code has been written yet. The earlier plan is superseded as follows:

  • All Tab entry points will share a tri-state result: not handled, consumed without mutation, or mutated. This preserves native single non-list Tab while preventing an invalid multi-selection from editing only its primary range.
  • Each structural selection record will retain native index, primary selection identity, source endpoints with explicit insertion affinity, reveal identity, and blockSelectionAnchorSourceLocation. Restoration will map every endpoint through a prefix-delta edit index, coalesce only identical/overlapping projected ranges under a defined primary-owner rule, and restore/map the anchor when its block survives.
  • Each unique touched list block will be parsed once. Parent and subtree ranges will be computed in one indentation-stack pass. Sorted nonoverlapping selection intervals will resolve roots through ordered/binary lookup, and preorder subtree containment will deduplicate descendants without ancestor walks.
  • All edits will be validated/sorted once; endpoint mapping will be O(range count × log edit count), not range count × edit count.
  • The one-command transaction will use a bounded hybrid in BlockEditorView: dense/many edits retain one canonical envelope replacement; a small number of widely separated edits apply in descending order under one editor-owned mutation boundary, register one old-source Undo snapshot, and emit one commit/timing callback after the complete batch. The expected final source is built first for validation/rollback, and untouched separator bytes remain byte-identical.
  • The focused regression will distinguish reachable whole-top-level-block Command-click selection from explicitly labeled injected nested-line normalization coverage. It will cover delegate/responder/physical Tab routes, empty anchors, hidden IDs, CRLF, reversed range order, selection primary/anchor restoration, follow-up Shift behavior, exact blank separators, mixed prose rejection, and one Undo. A 10K-list many-selection functional adversary will exercise the linear path without claiming a measured performance pass.

Reviewer re-check of the hybrid transaction and native primary ordering is active. No local build or GUI run.

Revised implementation plan after reviewer findings — `/root/block_drag_finish` No issue #17 production code has been written yet. The earlier plan is superseded as follows: - All Tab entry points will share a tri-state result: not handled, consumed without mutation, or mutated. This preserves native single non-list Tab while preventing an invalid multi-selection from editing only its primary range. - Each structural selection record will retain native index, primary selection identity, source endpoints with explicit insertion affinity, reveal identity, and `blockSelectionAnchorSourceLocation`. Restoration will map every endpoint through a prefix-delta edit index, coalesce only identical/overlapping projected ranges under a defined primary-owner rule, and restore/map the anchor when its block survives. - Each unique touched list block will be parsed once. Parent and subtree ranges will be computed in one indentation-stack pass. Sorted nonoverlapping selection intervals will resolve roots through ordered/binary lookup, and preorder subtree containment will deduplicate descendants without ancestor walks. - All edits will be validated/sorted once; endpoint mapping will be O(range count × log edit count), not range count × edit count. - The one-command transaction will use a bounded hybrid in `BlockEditorView`: dense/many edits retain one canonical envelope replacement; a small number of widely separated edits apply in descending order under one editor-owned mutation boundary, register one old-source Undo snapshot, and emit one commit/timing callback after the complete batch. The expected final source is built first for validation/rollback, and untouched separator bytes remain byte-identical. - The focused regression will distinguish reachable whole-top-level-block Command-click selection from explicitly labeled injected nested-line normalization coverage. It will cover delegate/responder/physical Tab routes, empty anchors, hidden IDs, CRLF, reversed range order, selection primary/anchor restoration, follow-up Shift behavior, exact blank separators, mixed prose rejection, and one Undo. A 10K-list many-selection functional adversary will exercise the linear path without claiming a measured performance pass. Reviewer re-check of the hybrid transaction and native primary ordering is active. No local build or GUI run.
Author
Owner

Revised plan review at base 56e61d2e: one P2 blocker remains; do not start the hybrid sparse mutation path as written. The tri-state routing, selection records/affinities, ordered lookup and prefix-delta mapping, reachable-vs-injected test phases, atomic mixed rejection, and 10K functional adversarial case address the prior review.

  • P2 plan blocker — proposed hybrid sparse transaction conflicts with the current canonical mutation cost/lifecycle. MarkdownBlockDocument.replacing(range:with:) constructs a new full source string (MarkdownBlockDocument.swift:590-597) and setSource synchronizes/rebuilds after each call (:867-944). Applying even “a small number” of distant edits one-by-one therefore publishes intermediate projections and pays repeated full-source copy/synchronization costs. BlockEditorView.applyingDisplayEdit suppresses editor delegate handling; it does not turn multiple document replacements into one atomic document/projection notification. A precomputed final source and best-effort rollback cannot make observers unsee intermediate states, and rollback adds another mutation if a later step fails.

Keep this feature on one existing canonical transaction: validate all edits first, build the final replacement for the smallest enclosing envelope, and call applyCanonicalSourceReplacement once. For two remote roots that envelope may approach the document, but it is still one copy/synchronization/Undo/commit boundary and is asymptotically safer than N calls to the current replacing. If profiling later proves the envelope path unacceptable, a separate document-owned batch API would need to coalesce storage edits, synchronization, projection notification, and Undo atomically; that is outside this bounded fix. Add an assertion/callback count proving exactly one source revision/commit and one Undo for remote ranges.

Primary-first restoration is acceptable only if the implementation explicitly reorders records so the range containing the original primary is index 0 before setSelectedRanges(_:affinity:stillSelecting:); preserve original order for the remainder and map the block anchor separately as proposed. Do not assume AppKit retains a primary designation attached to a non-first range.

Revised plan review at base `56e61d2e`: **one P2 blocker remains; do not start the hybrid sparse mutation path as written.** The tri-state routing, selection records/affinities, ordered lookup and prefix-delta mapping, reachable-vs-injected test phases, atomic mixed rejection, and 10K functional adversarial case address the prior review. - **P2 plan blocker — proposed hybrid sparse transaction conflicts with the current canonical mutation cost/lifecycle.** `MarkdownBlockDocument.replacing(range:with:)` constructs a new full source string (`MarkdownBlockDocument.swift:590-597`) and `setSource` synchronizes/rebuilds after each call (`:867-944`). Applying even “a small number” of distant edits one-by-one therefore publishes intermediate projections and pays repeated full-source copy/synchronization costs. `BlockEditorView.applyingDisplayEdit` suppresses editor delegate handling; it does not turn multiple document replacements into one atomic document/projection notification. A precomputed final source and best-effort rollback cannot make observers unsee intermediate states, and rollback adds another mutation if a later step fails. Keep this feature on one existing canonical transaction: validate all edits first, build the final replacement for the smallest enclosing envelope, and call `applyCanonicalSourceReplacement` once. For two remote roots that envelope may approach the document, but it is still one copy/synchronization/Undo/commit boundary and is asymptotically safer than N calls to the current `replacing`. If profiling later proves the envelope path unacceptable, a separate document-owned batch API would need to coalesce storage edits, synchronization, projection notification, and Undo atomically; that is outside this bounded fix. Add an assertion/callback count proving exactly one source revision/commit and one Undo for remote ranges. Primary-first restoration is acceptable only if the implementation explicitly reorders records so the range containing the original primary is index 0 before `setSelectedRanges(_:affinity:stillSelecting:)`; preserve original order for the remainder and map the block anchor separately as proposed. Do not assume AppKit retains a primary designation attached to a non-first range.
Author
Owner

Plan gate resolved — /root/block_drag_finish

Reviewer accepted the revised selection identity, linear outline construction, indexed endpoint mapping, tri-state routing, and reachable-versus-injected coverage. The proposed sparse multi-call mutation was rejected because MarkdownBlockDocument.replacing publishes and rebuilds on each call; applyingDisplayEdit is not a document batch boundary.

The candidate therefore uses exactly one validated smallest-envelope applyCanonicalSourceReplacement call for every Tab/Shift-Tab command. Tests will assert one source revision, one edit callback, and one Undo transaction, including remotely separated selected list blocks. Restored ranges put the original-primary owner at index 0 and preserve remaining native order.

Implementation is now active in .worktrees/editor-list-refinements at base 56e61d2e; no local build or GUI run.

Plan gate resolved — `/root/block_drag_finish` Reviewer accepted the revised selection identity, linear outline construction, indexed endpoint mapping, tri-state routing, and reachable-versus-injected coverage. The proposed sparse multi-call mutation was rejected because `MarkdownBlockDocument.replacing` publishes and rebuilds on each call; `applyingDisplayEdit` is not a document batch boundary. The candidate therefore uses exactly one validated smallest-envelope `applyCanonicalSourceReplacement` call for every Tab/Shift-Tab command. Tests will assert one source revision, one edit callback, and one Undo transaction, including remotely separated selected list blocks. Restored ranges put the original-primary owner at index 0 and preserve remaining native order. Implementation is now active in `.worktrees/editor-list-refinements` at base `56e61d2e`; no local build or GUI run.
Author
Owner

Pre-freeze dirty source review in .worktrees/editor-list-refinements at base 56e61d2e: one P2 fix required before commit. No build/tests/GUI were run.

  • P2 — Sources/CalternalEditor/BlockEditorView.swift:3658-3665: a single contiguous selection spanning list content and prose falls through to AppKit instead of being rejected atomically. listStructuralSelection() returns nil for both “no list content” and “mixed/invalid list selection.” handleListIndent then returns .notHandled solely because hasMultipleBlockSelections is false. insertTab/insertBacktab consequently call super, which can insert/traverse using that mixed selection. The intended pass-through applies only to a single wholly non-list selection; any selection touching list content plus unsupported blocks must be consumed without mutation. Fix by returning/classifying noList, validList, and invalidMixed (or inspecting touched blocks before normalization), and add single contiguous list + blank/prose Tab and Shift-Tab unchanged-source cases. The existing mixed test uses two native ranges, so it cannot catch this route.

The remaining inspected implementation is suitable to freeze after that fix: tri-state delegate/responder/keyDown routing is shared; the indentation stack computes parents/subtrees linearly; touched blocks are parsed once; roots/descendants are deduplicated; endpoint mapping uses ordered prefix deltas; restoration maps the block anchor and places the AppKit selectedRange() owner first; edits use one validated canonical envelope transaction; focused tests cover delegate/responder/physical routes, CRLF, IDs, empty/task/ordered lines, reachable whole blocks, injected nested selections, one revision/commit/Undo, and a 10K functional path.

AppKit guarantees selectedRanges readback is sorted, so the anchor-follow-up assertion is the meaningful proof of user click origin; do not describe a non-leading range as an AppKit primary selection. git diff --check is clean.

Pre-freeze dirty source review in `.worktrees/editor-list-refinements` at base `56e61d2e`: **one P2 fix required before commit.** No build/tests/GUI were run. - **P2 — `Sources/CalternalEditor/BlockEditorView.swift:3658-3665`: a single contiguous selection spanning list content and prose falls through to AppKit instead of being rejected atomically.** `listStructuralSelection()` returns nil for both “no list content” and “mixed/invalid list selection.” `handleListIndent` then returns `.notHandled` solely because `hasMultipleBlockSelections` is false. `insertTab`/`insertBacktab` consequently call `super`, which can insert/traverse using that mixed selection. The intended pass-through applies only to a single wholly non-list selection; any selection touching list content plus unsupported blocks must be consumed without mutation. Fix by returning/classifying `noList`, `validList`, and `invalidMixed` (or inspecting touched blocks before normalization), and add single contiguous list + blank/prose Tab and Shift-Tab unchanged-source cases. The existing mixed test uses two native ranges, so it cannot catch this route. The remaining inspected implementation is suitable to freeze after that fix: tri-state delegate/responder/keyDown routing is shared; the indentation stack computes parents/subtrees linearly; touched blocks are parsed once; roots/descendants are deduplicated; endpoint mapping uses ordered prefix deltas; restoration maps the block anchor and places the AppKit `selectedRange()` owner first; edits use one validated canonical envelope transaction; focused tests cover delegate/responder/physical routes, CRLF, IDs, empty/task/ordered lines, reachable whole blocks, injected nested selections, one revision/commit/Undo, and a 10K functional path. AppKit guarantees `selectedRanges` readback is sorted, so the anchor-follow-up assertion is the meaningful proof of user click origin; do not describe a non-leading range as an AppKit primary selection. `git diff --check` is clean.
Author
Owner

Candidate frozen for exact source review — /root/block_drag_finish

  • Worktree: .worktrees/editor-list-refinements
  • Branch: wave16/editor-list-refinements
  • Base: 56e61d2e4d8da6915fc693a99b2d09d8b5160863
  • Commit: 57a2fe0457cfdf2554751a3053d818daa5ae8608
  • Scope: list structural-command portions of BlockEditorView.swift plus focused MarkdownBlockDocumentTests.swift coverage only

Implemented:

  • Delegate, responder, and physical Tab/Shift-Tab share tri-state handling before the discontiguous-selection guard.
  • Native selections are normalized to list roots/subtrees, with descendant deduplication and atomic mixed-content rejection.
  • Outline parent/subtree construction is a single indentation-stack pass per unique touched block; selection roots use ordered/binary lookup.
  • All source endpoints map through an indexed prefix-delta table. Restored ranges preserve the original primary first, preserve the remaining native order, coalesce projected overlap, and remap the block anchor.
  • Every command uses one validated smallest-envelope canonical replacement, one source revision, one callback, and one Undo boundary. Authored blank separators remain within the unchanged envelope bytes.

Coverage adds reachable reversed-order Command-click whole-block selection, delegate Tab, physical Shift-Tab, follow-up Shift anchor, injected nested child/continuation and empty marker, ordered/task markers, hidden IDs, CRLF, exact blank separators, single contiguous and disjoint mixed-prose rejection, and a 10K-list many-selection functional adversary.

The final dirty-review finding is fixed: a single contiguous selection spanning list plus prose is consumed for both Tab and Shift-Tab without source/revision change. Worktree and git diff --check are clean. No local build or GUI run. Exact reviewer gate is active.

Candidate frozen for exact source review — `/root/block_drag_finish` - Worktree: `.worktrees/editor-list-refinements` - Branch: `wave16/editor-list-refinements` - Base: `56e61d2e4d8da6915fc693a99b2d09d8b5160863` - Commit: `57a2fe0457cfdf2554751a3053d818daa5ae8608` - Scope: list structural-command portions of `BlockEditorView.swift` plus focused `MarkdownBlockDocumentTests.swift` coverage only Implemented: - Delegate, responder, and physical Tab/Shift-Tab share tri-state handling before the discontiguous-selection guard. - Native selections are normalized to list roots/subtrees, with descendant deduplication and atomic mixed-content rejection. - Outline parent/subtree construction is a single indentation-stack pass per unique touched block; selection roots use ordered/binary lookup. - All source endpoints map through an indexed prefix-delta table. Restored ranges preserve the original primary first, preserve the remaining native order, coalesce projected overlap, and remap the block anchor. - Every command uses one validated smallest-envelope canonical replacement, one source revision, one callback, and one Undo boundary. Authored blank separators remain within the unchanged envelope bytes. Coverage adds reachable reversed-order Command-click whole-block selection, delegate Tab, physical Shift-Tab, follow-up Shift anchor, injected nested child/continuation and empty marker, ordered/task markers, hidden IDs, CRLF, exact blank separators, single contiguous and disjoint mixed-prose rejection, and a 10K-list many-selection functional adversary. The final dirty-review finding is fixed: a single contiguous selection spanning list plus prose is consumed for both Tab and Shift-Tab without source/revision change. Worktree and `git diff --check` are clean. No local build or GUI run. Exact reviewer gate is active.
Author
Owner

Exact source gate — 57a2fe0457cfdf2554751a3053d818daa5ae8608 (parent 56e61d2e4d8da6915fc693a99b2d09d8b5160863): PASS, no P1-P3 findings. Worktree clean; no local build/tests/GUI were run.

Verified:

  • Tab routing uses one tri-state result across delegate, responder actions, and physical keyDown. Multiple/invalid structural selections are consumed; a wholly non-list single selection retains AppKit pass-through.
  • The dirty-review gap is fixed at BlockEditorView.swift:3658-3669, 3922-3932: when normalization fails, selectionTouchesListOutlineBlock() distinguishes a contiguous list+unsupported selection from ordinary prose. Both Tab and Backtab are consumed without source/revision change, and the focused test now covers that exact single-range route before the discontiguous mixed case.
  • Each touched list block is parsed once. The indentation stack closes parents/subtrees in linear time; ordered candidate lookup and subtree containment avoid the prior quadratic ancestor/subtree scans.
  • Edits are validated/sorted and applied through exactly one smallest-envelope applyCanonicalSourceReplacement. Prefix deltas map selection endpoints in logarithmic lookup time, then source ranges are projected, overlap-coalesced, restored through native setSelectedRanges, and the block-selection anchor is mapped separately.
  • The reachable Command-click phase proves whole-block Tab/physical Shift-Tab, exact CRLF/source, one revision/callback/Undo, and follow-up Shift-anchor behavior. The explicitly injected nested phase covers empty/list/task/ordered/hidden-ID selection normalization and atomic mixed rejection. The 10K functional case exercises many disjoint selections and still asserts one revision/callback/Undo without claiming a timing pass.
  • AppKit API use is plausible against the SDK header: setSelectedRanges(_:affinity:stillSelecting:) accepts [NSValue]; readback is sorted/nonoverlapping, which matches the assertions. git diff 57a2fe04^..57a2fe04 --check passes.

Required next gate: compile and run the two focused tests on agents@mbp; the 10K case is functional evidence only, so Release-app scroll/edit profiling remains required before any performance claim or issue closure.

Exact source gate — `57a2fe0457cfdf2554751a3053d818daa5ae8608` (parent `56e61d2e4d8da6915fc693a99b2d09d8b5160863`): **PASS, no P1-P3 findings.** Worktree clean; no local build/tests/GUI were run. Verified: - Tab routing uses one tri-state result across delegate, responder actions, and physical keyDown. Multiple/invalid structural selections are consumed; a wholly non-list single selection retains AppKit pass-through. - The dirty-review gap is fixed at `BlockEditorView.swift:3658-3669, 3922-3932`: when normalization fails, `selectionTouchesListOutlineBlock()` distinguishes a contiguous list+unsupported selection from ordinary prose. Both Tab and Backtab are consumed without source/revision change, and the focused test now covers that exact single-range route before the discontiguous mixed case. - Each touched list block is parsed once. The indentation stack closes parents/subtrees in linear time; ordered candidate lookup and subtree containment avoid the prior quadratic ancestor/subtree scans. - Edits are validated/sorted and applied through exactly one smallest-envelope `applyCanonicalSourceReplacement`. Prefix deltas map selection endpoints in logarithmic lookup time, then source ranges are projected, overlap-coalesced, restored through native `setSelectedRanges`, and the block-selection anchor is mapped separately. - The reachable Command-click phase proves whole-block Tab/physical Shift-Tab, exact CRLF/source, one revision/callback/Undo, and follow-up Shift-anchor behavior. The explicitly injected nested phase covers empty/list/task/ordered/hidden-ID selection normalization and atomic mixed rejection. The 10K functional case exercises many disjoint selections and still asserts one revision/callback/Undo without claiming a timing pass. - AppKit API use is plausible against the SDK header: `setSelectedRanges(_:affinity:stillSelecting:)` accepts `[NSValue]`; readback is sorted/nonoverlapping, which matches the assertions. `git diff 57a2fe04^..57a2fe04 --check` passes. Required next gate: compile and run the two focused tests on `agents@mbp`; the 10K case is functional evidence only, so Release-app scroll/edit profiling remains required before any performance claim or issue closure.
Author
Owner

Combined integration candidate — worker /root/block_drag_finish

Reviewed discontiguous Tab/Shift-Tab commit 57a2fe0457cfdf2554751a3053d818daa5ae8608 was integrated conflict-free as f99ed4f28ae3b21beb87e4a99c4bf4a05acaaae8 onto base 26eb1552; stable patch ID is identical (d7c8afe3…). The combined worktree also contains reviewed fenced-code projection and caret-reveal deltas, so exact interaction review is active before handoff.

Worktree .worktrees/editor-structural-combined is clean and git diff --check passes. No local build or GUI run. Focused selectors: testListTabIsScopedToListsAndFirstItemCanIndent, testNativeListIndentAndNestedMovePreserveSubtreesSelectionsAndHistory, testDiscontiguousListIndentRestoresNativeSelectionsAndUsesOneTransaction, and testManyDiscontiguousNestedListSelectionsUseOneCanonicalIndentTransaction.

Combined integration candidate — worker `/root/block_drag_finish` Reviewed discontiguous Tab/Shift-Tab commit `57a2fe0457cfdf2554751a3053d818daa5ae8608` was integrated conflict-free as `f99ed4f28ae3b21beb87e4a99c4bf4a05acaaae8` onto base `26eb1552`; stable patch ID is identical (`d7c8afe3…`). The combined worktree also contains reviewed fenced-code projection and caret-reveal deltas, so exact interaction review is active before handoff. Worktree `.worktrees/editor-structural-combined` is clean and `git diff --check` passes. No local build or GUI run. Focused selectors: `testListTabIsScopedToListsAndFirstItemCanIndent`, `testNativeListIndentAndNestedMovePreserveSubtreesSelectionsAndHistory`, `testDiscontiguousListIndentRestoresNativeSelectionsAndUsesOneTransaction`, and `testManyDiscontiguousNestedListSelectionsUseOneCanonicalIndentTransaction`.
Author
Owner

Source integration review — exact combined tip 5f8dd69e029e63d5c87e68d4b5e663b63684ef52 against base 26eb155253241603ec8f1a89e263a7a8cd496341: PASS (no P1–P3 findings).

The #17 commit has an identical stable patch to the reviewed source. Multi-range list edits still form one validated canonical envelope transaction, map source endpoints through sorted edits, restore the primary native range first, preserve/map the block anchor, and consume invalid mixed selections without mutating. Its explicit post-restore reveal supersedes the transaction's stale single-selection callback through the existing selection fence. Added code-fragment and hover layout work does not alter list normalization or source mapping.

This is a source-only integration verdict. Compile, 10K functional execution, Undo, and mounted gesture verification remain with the build/QA lanes.

Source integration review — exact combined tip `5f8dd69e029e63d5c87e68d4b5e663b63684ef52` against base `26eb155253241603ec8f1a89e263a7a8cd496341`: **PASS (no P1–P3 findings)**. The #17 commit has an identical stable patch to the reviewed source. Multi-range list edits still form one validated canonical envelope transaction, map source endpoints through sorted edits, restore the primary native range first, preserve/map the block anchor, and consume invalid mixed selections without mutating. Its explicit post-restore reveal supersedes the transaction's stale single-selection callback through the existing selection fence. Added code-fragment and hover layout work does not alter list normalization or source mapping. This is a source-only integration verdict. Compile, 10K functional execution, Undo, and mounted gesture verification remain with the build/QA lanes.
Author
Owner

Root fast-forwarded the clean preview integration branch from26eb1552 to exact5f8dd69e after independent combined source review PASS and diff-check. Includes code-block presentation, atomic disjoint list indentation, native-paste reveal coalescing, and hover lifecycle/footer-width correction. The known roughly7pt visible text/mentions alignment gap remains for native measurement. This is a NEXT build candidate; it does not supersede the current26eb event/title build and is not installed. No runtime/performance acceptance is claimed.

Root fast-forwarded the clean preview integration branch from26eb1552 to exact5f8dd69e after independent combined source review PASS and diff-check. Includes code-block presentation, atomic disjoint list indentation, native-paste reveal coalescing, and hover lifecycle/footer-width correction. The known roughly7pt visible text/mentions alignment gap remains for native measurement. This is a NEXT build candidate; it does not supersede the current26eb event/title build and is not installed. No runtime/performance acceptance is claimed.
Author
Owner

Exact central 5f8dd69e029e63d5c87e68d4b5e663b63684ef52 build-host status:

SwiftPM Release test compilation stopped before any list selector could execute because Sources/CalternalEditor/BlockEditorView.swift:7444:58 calls unavailable NSColor.resolvedColor(with:); lines 7445-7446 have the same API shape. Compile log SHA-256: eff73d6e1cdd24b73777ba946f70e7ddd0af6aa15f0ac7f729b15441cf9028e2 at /Users/agents/Developer/BuildOnly/package-tests-d40/Evidence/package-tests/20260913T154953Z-central-5f8dd69e-code-list-hover-1d82888f/swift-build.log.

No list test executed, no runtime was staged, and no Release build was attempted. List source remains reviewer-passed but build/runtime-unverified at this exact tip.

Exact central `5f8dd69e029e63d5c87e68d4b5e663b63684ef52` build-host status: SwiftPM Release test compilation stopped before any list selector could execute because `Sources/CalternalEditor/BlockEditorView.swift:7444:58` calls unavailable `NSColor.resolvedColor(with:)`; lines 7445-7446 have the same API shape. Compile log SHA-256: `eff73d6e1cdd24b73777ba946f70e7ddd0af6aa15f0ac7f729b15441cf9028e2` at `/Users/agents/Developer/BuildOnly/package-tests-d40/Evidence/package-tests/20260913T154953Z-central-5f8dd69e-code-list-hover-1d82888f/swift-build.log`. No list test executed, no runtime was staged, and no Release build was attempted. List source remains reviewer-passed but build/runtime-unverified at this exact tip.
Author
Owner

Root took over the existing sole compiler controller after /root/build_pipeline_recover hit usage limits. Exact704b347e26c7c48f3652a4cf7cd235f7815b7364 SwiftPM Release compile PASSED and VM test runtime staged. Tests executed:0 so far. Build log SHA6d41a977d4e100e63c9f20ecfb6c500b5545d25cf17d83bb48ae25b13d6d67a9; runtime manifest8ad650319b90b9e89070f07fabace4d39b9bc276127c2f47615d5c73f70b2fb7. /root/image_preview_qa assigned exact runtime tests. Separately source-reviewed combined chrome/image-controls/cross-event candidate68885 merged cleanly with painter repair as9a69a955; that newer revision is not built. Each thread owns updates in its relevant issues. Desktop remains26eb1552.

Root took over the existing sole compiler controller after /root/build_pipeline_recover hit usage limits. Exact704b347e26c7c48f3652a4cf7cd235f7815b7364 SwiftPM Release compile PASSED and VM test runtime staged. Tests executed:0 so far. Build log SHA6d41a977d4e100e63c9f20ecfb6c500b5545d25cf17d83bb48ae25b13d6d67a9; runtime manifest8ad650319b90b9e89070f07fabace4d39b9bc276127c2f47615d5c73f70b2fb7. /root/image_preview_qa assigned exact runtime tests. Separately source-reviewed combined chrome/image-controls/cross-event candidate68885 merged cleanly with painter repair as9a69a955; that newer revision is not built. Each thread owns updates in its relevant issues. Desktop remains26eb1552.
Author
Owner

704b VM package runtime result for discontiguous list behavior: 1/2 passed, 1 failed. testManyDiscontiguousNestedListSelectionsUseOneCanonicalIndentTransaction passed. testDiscontiguousListIndentRestoresNativeSelectionsAndUsesOneTransaction failed: restored ranges were [{10,5}, {46,1}, {50,7}, {62,4}], expected [{10,5}, {44,1}, {48,7}, {60,4}] — a +2 offset in each later selection. Executed product assertion; no runner issue. Full logs VM /private/tmp/qa-704b-package-run-20260913-093737/list/; local 14-package-console.txt, 15-failure-extracts.txt.

704b VM package runtime result for discontiguous list behavior: **1/2 passed, 1 failed**. `testManyDiscontiguousNestedListSelectionsUseOneCanonicalIndentTransaction` passed. `testDiscontiguousListIndentRestoresNativeSelectionsAndUsesOneTransaction` failed: restored ranges were `[{10,5}, {46,1}, {50,7}, {62,4}]`, expected `[{10,5}, {44,1}, {48,7}, {60,4}]` — a +2 offset in each later selection. Executed product assertion; no runner issue. Full logs VM `/private/tmp/qa-704b-package-run-20260913-093737/list/`; local `14-package-console.txt`, `15-failure-extracts.txt`.
Author
Owner

Current orchestration checkpoint: /root/image_preview_qa executed704b runtime9selectors:7passed,2failed. #9 mounted code gutter/resize assertions and #17 discontiguous selection restoration are assigned to /root/code_block_polish and /root/block_drag_finish respectively; no weakened assertions accepted. #4 hover and #13 native paste/Undo passed that bounded runtime. Root integrated reviewed #4 outward editor frame + explicit unmeasured-geometry docs as4ebc6804/6b7d8f83; centered760pt cap/footer width preserved, actualalignmentpending. #12 compiler repair73964bc6 is under /root/image_controls_review exact review. Central6b7d8f83 is not built; desktop26eb1552 unchanged. Each individual issue contains owning task and evidence.

Current orchestration checkpoint: /root/image_preview_qa executed704b runtime9selectors:7passed,2failed. #9 mounted code gutter/resize assertions and #17 discontiguous selection restoration are assigned to /root/code_block_polish and /root/block_drag_finish respectively; no weakened assertions accepted. #4 hover and #13 native paste/Undo passed that bounded runtime. Root integrated reviewed #4 outward editor frame + explicit unmeasured-geometry docs as4ebc6804/6b7d8f83; centered760pt cap/footer width preserved, actualalignmentpending. #12 compiler repair73964bc6 is under /root/image_controls_review exact review. Central6b7d8f83 is not built; desktop26eb1552 unchanged. Each individual issue contains owning task and evidence.
Author
Owner

Task identity: /root/block_drag_finish

Runtime failure follow-up:

  • Worktree: /Users/kayg/Developer/calternal-app/.worktrees/editor-list-refinements
  • Branch: wave16/editor-list-refinements
  • Starting SHA: 57a2fe0457cfdf2554751a3053d818daa5ae8608
  • Failing hosted selector: CalternalEditorTests.MarkdownBlockDocumentTests/testDiscontiguousListIndentRestoresNativeSelectionsAndUsesOneTransaction
  • Evidence: .agents/native-break/704b-code-list-hover-qa/15-failure-extracts.txt

Root cause: the source edit adds two spaces to the selected wrapped continuation line. Marker indentation is hidden by projection, but continuation indentation is authored visible text, so later display selections correctly move by +2 UTF-16 units. The test compared post-edit absolute display offsets with the pre-edit offsets and therefore rejected correct content-following restoration.

Planned bounded repair: test-only, derive exact expected post-edit ranges from the new projection's same selected contents/empty anchor; continue asserting all four selections, primary owner, exact Markdown, one revision/commit/Undo transaction, and round-trip source. No assertion tolerance or product behavior change. No local build/GUI.

Task identity: `/root/block_drag_finish` Runtime failure follow-up: - Worktree: `/Users/kayg/Developer/calternal-app/.worktrees/editor-list-refinements` - Branch: `wave16/editor-list-refinements` - Starting SHA: `57a2fe0457cfdf2554751a3053d818daa5ae8608` - Failing hosted selector: `CalternalEditorTests.MarkdownBlockDocumentTests/testDiscontiguousListIndentRestoresNativeSelectionsAndUsesOneTransaction` - Evidence: `.agents/native-break/704b-code-list-hover-qa/15-failure-extracts.txt` Root cause: the source edit adds two spaces to the selected wrapped continuation line. Marker indentation is hidden by projection, but continuation indentation is authored visible text, so later display selections correctly move by +2 UTF-16 units. The test compared post-edit absolute display offsets with the pre-edit offsets and therefore rejected correct content-following restoration. Planned bounded repair: test-only, derive exact expected post-edit ranges from the new projection's same selected contents/empty anchor; continue asserting all four selections, primary owner, exact Markdown, one revision/commit/Undo transaction, and round-trip source. No assertion tolerance or product behavior change. No local build/GUI.
Author
Owner

Task identity: /root/block_drag_finish

Test-only candidate: eeed031a28cbae672de108d70738c6c89f19584e
Parent: 57a2fe0457cfdf2554751a3053d818daa5ae8608
Worktree/branch: .worktrees/editor-list-refinements / wave16/editor-list-refinements

The failing assertion now checks the actual contract: every restored selection must equal the exact current projected range of its original selected contents, including the empty-list anchor, and selected substrings must remain byte-for-byte equal. It also asserts the original primary owner. Exact Markdown, one revision, one commit, one Undo transaction, and full Undo source restoration remain unchanged.

This accounts for the required +2 display shift caused only by newly visible indentation on the wrapped continuation; it does not loosen ranges or introduce tolerance. git diff --check passes and the worktree is clean. No local build/GUI. Exact source review is pending, followed by the same hosted selector rerun.

Task identity: `/root/block_drag_finish` Test-only candidate: `eeed031a28cbae672de108d70738c6c89f19584e` Parent: `57a2fe0457cfdf2554751a3053d818daa5ae8608` Worktree/branch: `.worktrees/editor-list-refinements` / `wave16/editor-list-refinements` The failing assertion now checks the actual contract: every restored selection must equal the exact current projected range of its original selected contents, including the empty-list anchor, and selected substrings must remain byte-for-byte equal. It also asserts the original primary owner. Exact Markdown, one revision, one commit, one Undo transaction, and full Undo source restoration remain unchanged. This accounts for the required +2 display shift caused only by newly visible indentation on the wrapped continuation; it does not loosen ranges or introduce tolerance. `git diff --check` passes and the worktree is clean. No local build/GUI. Exact source review is pending, followed by the same hosted selector rerun.
Author
Owner

Exact test-only source review — eeed031a28cbae672de108d70738c6c89f19584e (parent 57a2fe0457cfdf2554751a3053d818daa5ae8608): PASS (no P1–P3 findings).

The revised expectation remains exact. It captures the four distinct displayed selections before indentation (child, the sole empty-list zero-width anchor, ordered, and task), resolves each unique content in the post-edit projection, asserts every resolution exists, compares the complete ordered selectedRanges array to those exact ranges, compares each selected substring to its original content, and verifies the first restored range remains primary. This catches lost, reordered, broadened, collapsed, or wrongly targeted selections while allowing the legitimate +2 display displacement caused by newly visible continuation indentation.

The canonical source expectation, one source-revision increment, one commit callback, Undo availability, exact source restoration, mixed-content rejection, and commit-count checks are unchanged. Only Tests/CalternalEditorTests/MarkdownBlockDocumentTests.swift changed; the API usage is compile-plausible and git diff --check passes.

No product behavior or assertion contract was weakened. Hosted rerun remains the execution gate.

Exact test-only source review — `eeed031a28cbae672de108d70738c6c89f19584e` (parent `57a2fe0457cfdf2554751a3053d818daa5ae8608`): **PASS (no P1–P3 findings)**. The revised expectation remains exact. It captures the four distinct displayed selections before indentation (`child`, the sole empty-list zero-width anchor, `ordered`, and `task`), resolves each unique content in the post-edit projection, asserts every resolution exists, compares the complete ordered `selectedRanges` array to those exact ranges, compares each selected substring to its original content, and verifies the first restored range remains primary. This catches lost, reordered, broadened, collapsed, or wrongly targeted selections while allowing the legitimate +2 display displacement caused by newly visible continuation indentation. The canonical source expectation, one source-revision increment, one commit callback, Undo availability, exact source restoration, mixed-content rejection, and commit-count checks are unchanged. Only `Tests/CalternalEditorTests/MarkdownBlockDocumentTests.swift` changed; the API usage is compile-plausible and `git diff --check` passes. No product behavior or assertion contract was weakened. Hosted rerun remains the execution gate.
Author
Owner

Root exact80efddbc compile passed the prior three image-controls errors, then failed at EditorImagePresentation.swift:653: task-isolated provider self captured by MainActor.assumeIsolated loadView. Tests executed0. Log .agents/wave16/central-80efddbc-root/swift-build.log SHA07a8c920bc0deeb45d4c71c6f8318b057ee97e09c8597f6ff44dd06ad37f260d. /root/image_preview_native_repair owns SDK isolation diagnosis and review-gated repair. Root integrated reviewed #17 test correctioneeed031a asada08756: exact selection contents move with visible continuation indentation, source/Undo/revision assertions preserved. No newer desktop installed.

Root exact80efddbc compile passed the prior three image-controls errors, then failed at EditorImagePresentation.swift:653: task-isolated provider self captured by MainActor.assumeIsolated loadView. Tests executed0. Log .agents/wave16/central-80efddbc-root/swift-build.log SHA07a8c920bc0deeb45d4c71c6f8318b057ee97e09c8597f6ff44dd06ad37f260d. /root/image_preview_native_repair owns SDK isolation diagnosis and review-gated repair. Root integrated reviewed #17 test correctioneeed031a asada08756: exact selection contents move with visible continuation indentation, source/Undo/revision assertions preserved. No newer desktop installed.
Author
Owner

Exact 3bbb package compile and VM staging

Worker/role: /root/title_completion, transfer-only infrastructure handoff
Workspace/branch: /Users/kayg/Developer/calternal-app, dev (read-only; no source mutation)
Exact central revision: 3bbb28a6fcf7bac1dae310bd07ea8e7a0ace6b68
State: package test compilation and staging passed; runtime assertions pending QA

The sole agents@mbp controller completed swift build -c release --build-tests --enable-xctest --disable-swift-testing -Xswiftc -enable-testing with return code 0 in 13.916 seconds. Staging returned 0. The result records compileOnly=true, swiftTestInvoked=false, xctestInvoked=false, and testsExecuted=false, so this is compile/staging evidence only.

Builder evidence: build log SHA-256 54c3fe1d5cf2a36e5b3b2ead2fe915657a6c446754b5c6ac0983e48d2a81b8f1; runtime manifest 167cd835ece65a3e13fec0ed235f930c0e052406ab7a05235fbc4dee8324c976; package test binary 307239fd7f2fb84c172e86c4c60f529d037f9578664e3ea153f295e9c9d3a426; result ebe531e1521f3a6113fc8f6d6afec4f474587d69ebbd2dcc6d64c08e70e31ba5; source archive cca8fffc2c461a0b26703efcbea07561816ca85e10c0f770071c2d87012ee343; source manifest 6f49233d1fc8510db16078a172568a4c2cb858d2041918110ba59eb4a1ce1ddf.

The staged closure was archived on the builder and transferred by authenticated rsync delta into a unique VM .partial. After its full SHA matched, it was atomically published read-only at /Users/lume/CalternalQA/3bbb28a6-package-runtime/vm-xctest-runtime-3bbb28a6-4d217fcf.tar. Builder and VM SHA-256 are both 5fd5149b201d1064aa0fe9b0c3be1c96dfd83c930c380a0d712b5d2963f02e6d; mode is 0444 and the same-name partial is absent. The successful retry matched 85,579,024 of 85,634,560 bytes and sent 92,696 bytes.

QA /root/image_preview_qa has the exact path and hashes and owns unpack verification and the focused runtime selectors after the current f907 title/event lane. This task invoked no compiler, test runner, app, or GUI. Linked issues remain open pending their actual selector and user-facing acceptance evidence.

## Exact 3bbb package compile and VM staging **Worker/role:** `/root/title_completion`, transfer-only infrastructure handoff **Workspace/branch:** `/Users/kayg/Developer/calternal-app`, `dev` (read-only; no source mutation) **Exact central revision:** `3bbb28a6fcf7bac1dae310bd07ea8e7a0ace6b68` **State:** package test compilation and staging passed; runtime assertions pending QA The sole `agents@mbp` controller completed `swift build -c release --build-tests --enable-xctest --disable-swift-testing -Xswiftc -enable-testing` with return code 0 in 13.916 seconds. Staging returned 0. The result records `compileOnly=true`, `swiftTestInvoked=false`, `xctestInvoked=false`, and `testsExecuted=false`, so this is compile/staging evidence only. Builder evidence: build log SHA-256 `54c3fe1d5cf2a36e5b3b2ead2fe915657a6c446754b5c6ac0983e48d2a81b8f1`; runtime manifest `167cd835ece65a3e13fec0ed235f930c0e052406ab7a05235fbc4dee8324c976`; package test binary `307239fd7f2fb84c172e86c4c60f529d037f9578664e3ea153f295e9c9d3a426`; result `ebe531e1521f3a6113fc8f6d6afec4f474587d69ebbd2dcc6d64c08e70e31ba5`; source archive `cca8fffc2c461a0b26703efcbea07561816ca85e10c0f770071c2d87012ee343`; source manifest `6f49233d1fc8510db16078a172568a4c2cb858d2041918110ba59eb4a1ce1ddf`. The staged closure was archived on the builder and transferred by authenticated rsync delta into a unique VM `.partial`. After its full SHA matched, it was atomically published read-only at `/Users/lume/CalternalQA/3bbb28a6-package-runtime/vm-xctest-runtime-3bbb28a6-4d217fcf.tar`. Builder and VM SHA-256 are both `5fd5149b201d1064aa0fe9b0c3be1c96dfd83c930c380a0d712b5d2963f02e6d`; mode is 0444 and the same-name partial is absent. The successful retry matched 85,579,024 of 85,634,560 bytes and sent 92,696 bytes. QA `/root/image_preview_qa` has the exact path and hashes and owns unpack verification and the focused runtime selectors after the current f907 title/event lane. This task invoked no compiler, test runner, app, or GUI. Linked issues remain open pending their actual selector and user-facing acceptance evidence.
Author
Owner

3bbb VM package runtime exact hashes verified. Both discontiguous list cases passed with one executed test each: testDiscontiguousListIndentRestoresNativeSelectionsAndUsesOneTransaction and testManyDiscontiguousNestedListSelectionsUseOneCanonicalIndentTransaction. No timeouts. Evidence: .agents/native-break/3bbb-combined-package-qa/04-vm-summary.txt and exact-logs/list/.

3bbb VM package runtime exact hashes verified. Both discontiguous list cases passed with one executed test each: `testDiscontiguousListIndentRestoresNativeSelectionsAndUsesOneTransaction` and `testManyDiscontiguousNestedListSelectionsUseOneCanonicalIndentTransaction`. No timeouts. Evidence: `.agents/native-break/3bbb-combined-package-qa/04-vm-summary.txt` and `exact-logs/list/`.
Author
Owner

Root installed and launched exact3bbb28a6fcf7bac1dae310bd07ea8e7a0ace6b68 as the only ~/Applications/Calternal.app. ExecutableSHA56e57a8fc553ce7ce82f6b72dbf04f2e2d442aefb53402b943adca14c208f408; zipSHAa8b1175bc354b455426351b0b7bfc9efb826071ddf0b4b69779cac0add9adb95; strict signature/arm64/Release/revision verified. Prior26eb quit via native menu; rollback retained. Space content inventory matched before/after replacement. Native current app restored the previously open note and Style inspector without editing its content. Receipt .agents/desktop-install/3bbb28a6/install-receipt.json.

User QA preview only. Pass: basic native launch/selection; package lists2/hover1/cross-event3; separate f907event7/7. Fail/open: actual mounted code gutter7assertions, imageFit/Fill4, imageQuickLookgesture8, hostedtitle4allocatoraborts. StyledVMdeeplink did not reach note; nativeUIfallback assigned. Each failure has independent author+reviewer, not closed. No stable or performance acceptance; latest imageprovider repair and diagnostics are NOT in this desktoppreview.

User test focus: centered width and mentions alignment, hover-only six dots, block selection/dragging, cross-event Copy/Move/Cancel/Remember dialog. These UI outcomes remain user acceptance gates.

Root installed and launched exact3bbb28a6fcf7bac1dae310bd07ea8e7a0ace6b68 as the only ~/Applications/Calternal.app. ExecutableSHA56e57a8fc553ce7ce82f6b72dbf04f2e2d442aefb53402b943adca14c208f408; zipSHAa8b1175bc354b455426351b0b7bfc9efb826071ddf0b4b69779cac0add9adb95; strict signature/arm64/Release/revision verified. Prior26eb quit via native menu; rollback retained. Space content inventory matched before/after replacement. Native current app restored the previously open note and Style inspector without editing its content. Receipt .agents/desktop-install/3bbb28a6/install-receipt.json. User QA preview only. Pass: basic native launch/selection; package lists2/hover1/cross-event3; separate f907event7/7. Fail/open: actual mounted code gutter7assertions, imageFit/Fill4, imageQuickLookgesture8, hostedtitle4allocatoraborts. StyledVMdeeplink did not reach note; nativeUIfallback assigned. Each failure has independent author+reviewer, not closed. No stable or performance acceptance; latest imageprovider repair and diagnostics are NOT in this desktoppreview. User test focus: centered width and mentions alignment, hover-only six dots, block selection/dragging, cross-event Copy/Move/Cancel/Remember dialog. These UI outcomes remain user acceptance gates.
Author
Owner

Remote preservation checkpoint — 2026-09-14

The following original-worktree candidates are now pushed and exact hashes verified on both Forgejo and GitHub. These are preserved candidates/diagnostics, not a claim of new acceptance; some may already be integrated by cherry-pick or superseded. Use the issue’s existing evidence before choosing changes to resume.

  • codex/wip/editor-hr-leaf-fix-20260914 — 6450f21ea42f84a71f0917f2edc2d58aac0b3899
  • wave14/editor-block-drag — 05fefc98890003a4d14ff297d4ead459deca0538
  • wave14/editor-empty-marker-host-repro — 79dc861166b57a70a29e6591c1dc1effbd4f7a82
  • wave14/editor-empty-marker-map-publication — c2dcd6d05e22d0ef39b9da8d9e37fa95ec03e2be
  • wave14/editor-empty-marker-paint — e32565510ac13063a5c72994ce0db16dae7ac355
  • wave14/editor-empty-marker-preview — 10d6af95f1fe4d786c6c7423d4154bc9e39a2bce
  • wave14/editor-empty-marker-probe — bded2b644854c65f4e1c4dfbaeedf30302b19f34
  • wave14/editor-empty-marker-runtime-diag — bf946ddd7a0c9b0e89e73dc6cc85f1461228b9e4
  • wave14/editor-list-enter-next — 66c4af4aaddb3b09f7366211d48d4533d8b08cf6
  • wave14/editor-list-handle-integrated — 3441a34263f24aab2c4a8142db103ca1cd8ee3e6
  • wave14/editor-list-keyboard-audit — 846a9c768425e2bec809063aae09c3dd6f16ba78
  • wave16/editor-list-refinements — eeed031a28cbae672de108d70738c6c89f19584e

Master #20 contains the resume instructions. No force push; dev remains 1d8f4adf.

Remote preservation checkpoint — 2026-09-14 The following original-worktree candidates are now pushed and exact hashes verified on both Forgejo and GitHub. These are preserved candidates/diagnostics, not a claim of new acceptance; some may already be integrated by cherry-pick or superseded. Use the issue’s existing evidence before choosing changes to resume. - `codex/wip/editor-hr-leaf-fix-20260914` — `6450f21ea42f84a71f0917f2edc2d58aac0b3899` - `wave14/editor-block-drag` — `05fefc98890003a4d14ff297d4ead459deca0538` - `wave14/editor-empty-marker-host-repro` — `79dc861166b57a70a29e6591c1dc1effbd4f7a82` - `wave14/editor-empty-marker-map-publication` — `c2dcd6d05e22d0ef39b9da8d9e37fa95ec03e2be` - `wave14/editor-empty-marker-paint` — `e32565510ac13063a5c72994ce0db16dae7ac355` - `wave14/editor-empty-marker-preview` — `10d6af95f1fe4d786c6c7423d4154bc9e39a2bce` - `wave14/editor-empty-marker-probe` — `bded2b644854c65f4e1c4dfbaeedf30302b19f34` - `wave14/editor-empty-marker-runtime-diag` — `bf946ddd7a0c9b0e89e73dc6cc85f1461228b9e4` - `wave14/editor-list-enter-next` — `66c4af4aaddb3b09f7366211d48d4533d8b08cf6` - `wave14/editor-list-handle-integrated` — `3441a34263f24aab2c4a8142db103ca1cd8ee3e6` - `wave14/editor-list-keyboard-audit` — `846a9c768425e2bec809063aae09c3dd6f16ba78` - `wave16/editor-list-refinements` — `eeed031a28cbae672de108d70738c6c89f19584e` Master #20 contains the resume instructions. No force push; dev remains 1d8f4adf.
Author
Owner

Rendering defects observed on the VM while verifying hover (build from wave19/block-editor-craft after 45a700b, but the same rendering is visible on dev 1d8f4adf in the earlier baseline capture): in the fixture note A0 Block Editor and Style QA (Overnight Perf QA / Native Break spaces) the ordered-list markers 1. are painted one line BELOW their item text ("populated ordered item" text at y≈557, its 1. at y≈578; the empty second item's 1. at y≈626 with no text beside it), and consecutive ordered items both show 1. instead of 1./2. Evidence: .agents/evidence/block-editor/walk-grid.png, hov-1.png.

Rendering defects observed on the VM while verifying hover (build from `wave19/block-editor-craft` after 45a700b, but the same rendering is visible on dev 1d8f4adf in the earlier baseline capture): in the fixture note `A0 Block Editor and Style QA` (Overnight Perf QA / Native Break spaces) the ordered-list markers `1.` are painted one line BELOW their item text ("populated ordered item" text at y≈557, its `1.` at y≈578; the empty second item's `1.` at y≈626 with no text beside it), and consecutive ordered items both show `1.` instead of 1./2. Evidence: `.agents/evidence/block-editor/walk-grid.png`, `hov-1.png`.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal-macos#17
No description provided.