Add image size/fit controls and a nearby contextual toolbar #12

Open
opened 2026-09-13 13:34:42 +00:00 by kayg · 88 comments
Owner

Request and current status

Design exists; controls and nearby toolbar remain unfinished. Portable presentation persistence is not settled.

Acceptance

Separate size from fit/crop; preserve source bytes and clarify persistence. Provide labeled reachable native toolbar without jumps/timer leaks. Verify duplicates, reflow, scroll, rapid hover, keyboard and reduced motion; do not invent unsupported Markdown syntax.

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 Design exists; controls and nearby toolbar remain unfinished. Portable presentation persistence is not settled. ## Acceptance Separate size from fit/crop; preserve source bytes and clarify persistence. Provide labeled reachable native toolbar without jumps/timer leaks. Verify duplicates, reflow, scroll, rapid hover, keyboard and reduced motion; do not invent unsupported Markdown syntax. 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

Delivery audit and minimum implementation plan (2026-09-13)

Worker / scope: /root/image_preview_native_repair; read-only audit of the shared editor. No production source or GUI changes were made in this pass.

What already exists

Calternal already has a portable width representation in the web/domain implementation: image alt pipes accept ![alt|640](path) and ![alt|640x480](path). The existing parser preserves the raw pipe and unknown trailing parameters, while pipeWithWidth replaces or removes only the leading numeric width segment. This is covered by byte-stable round-trip tests in calternal.js/packages/web/src/lib/editor/markdown.ts and its tests. The web image resize flow stores an explicit pixel width and commits once at drag end so the edit is one undo step.

The Apple editor does not yet interpret that contract. Its image token/projection carries only destination and alternate text, and EditorImageAttachment.Geometry derives a contain-fit frame capped at 220 pt. There is no Apple size/fit state or persistence model yet.

There is no existing portable syntax for Fit versus Fill. We must not invent a private |fill-style parameter or claim that a presentation-only choice is saved.

Issue #11 candidate 39915dabc31ffbc2298be53890181e66650090bd provides the useful foundation: exact realized-fragment image targeting and a native attachment frame. That targeting should become one shared image-interaction target rather than duplicating TextKit hit scans.

Minimum correct implementation

  1. Land a lossless Apple pipe model first. Parse the image label into visible alt text plus an opaque pipe payload compatible with the existing W, WxH, and unknown-tail behavior. Carry the authored width through Markdown projection and attachment geometry without discarding unknown parameters. Rewriting an explicit width must touch only the leading numeric segment and form one native undo transaction.
  2. Keep authored width distinct from view controls. Authored |W/|WxH is portable document state. The Craft-derived Size choices (Auto, Large) are semantic view presets whose stable source mapping has not been specified. They must remain explicitly presentation-only until product semantics define a durable integer width. They must not silently replace an authored width.
  3. Treat Fit/Fill as presentation-only. Fit contains the full image. Fill aspect-fills and clips the rendered view only; it never edits/crops the source image or rewrites Markdown. The toolbar must expose this as a view setting (for example, a persistent static “This view” label/accessibility help), rather than implying that it survives reload.
  4. Use public native AppKit controls. Add a focused EditorImageToolbarController using a native nonactivating panel or popover, static NSTextField labels, and NSSegmentedControl or NSPopUpButton choices for Image Size: Auto / Large and Image Fit: Fit / Fill. Preserve keyboard order, checked/selected state, Escape dismissal and focus restoration. Do not add timers.
  5. Anchor to one exact occurrence. Generalize #11's target to carry the exact display range/token identity, preview URL and native attachment rect. Re-anchor from that occurrence on layout/reflow/scroll, and dismiss when it becomes unrealized, its identity changes, the editor detaches, or the owner window closes. Identical destination paths in different occurrences must keep independent presentation state.
  6. Keep geometry bounded. Auto/Fit retains current aspect-preserving behavior. Large/Fit uses the available-width presentation slot with the current 220 pt height bound. Fill clips inside that slot. Targeting and updates stay within the selected realized fragment; no full-document layout scan or synchronous image decode is added.

Verification required

  • Parser/rewriter tests: no pipe, W, WxH, unknown-only and W|unknown, escaped labels/destinations, CRLF, and duplicate occurrences, with exact source-byte preservation outside the edited numeric segment.
  • Mounted AppKit tests: exact occurrence selection; Auto/Fit, Large/Fit and Fill geometry; no distortion or source-file mutation; duplicate-path independence; inline/list images; very tall, wide, small and missing images.
  • Toolbar lifecycle tests: native labels/states, keyboard reachability, Escape/focus restoration, reflow/scroll/window-close teardown, rapid selection changes, and no retained monitor/observer/timer.
  • VM user flow: reduced motion/transparency, VoiceOver names, appearance changes, scrolling/reflow, and interaction with the final #3 multi-block selection semantics.
  • Release profiling remains required for launch and scroll-spam claims; focused/mounted tests are not performance evidence.

Integration order and dependencies

Issue #3 is actively changing BlockEditorView.swift, native selectedRanges, click suppression, Copy/Cut/Delete/Undo, drag behavior and context-action guards. Issue #11 also changes the same editor and supplies the exact image target. Freeze/integrate #3 first, then rebase and land #11, then implement #12 against the resulting image-selection contract. Root coordination is required before any shared editor edit.

This issue stays open. The portable width model exists, but Apple support, native controls, runtime verification and any durable semantics for Auto/Large or Fit/Fill are not delivered yet.

## Delivery audit and minimum implementation plan (2026-09-13) **Worker / scope:** `/root/image_preview_native_repair`; read-only audit of the shared editor. No production source or GUI changes were made in this pass. ### What already exists Calternal already has a portable width representation in the web/domain implementation: image alt pipes accept `![alt|640](path)` and `![alt|640x480](path)`. The existing parser preserves the raw pipe and unknown trailing parameters, while `pipeWithWidth` replaces or removes only the leading numeric width segment. This is covered by byte-stable round-trip tests in `calternal.js/packages/web/src/lib/editor/markdown.ts` and its tests. The web image resize flow stores an explicit pixel width and commits once at drag end so the edit is one undo step. The Apple editor does not yet interpret that contract. Its image token/projection carries only destination and alternate text, and `EditorImageAttachment.Geometry` derives a contain-fit frame capped at 220 pt. There is no Apple size/fit state or persistence model yet. There is no existing portable syntax for Fit versus Fill. We must not invent a private `|fill`-style parameter or claim that a presentation-only choice is saved. Issue #11 candidate `39915dabc31ffbc2298be53890181e66650090bd` provides the useful foundation: exact realized-fragment image targeting and a native attachment frame. That targeting should become one shared image-interaction target rather than duplicating TextKit hit scans. ### Minimum correct implementation 1. **Land a lossless Apple pipe model first.** Parse the image label into visible alt text plus an opaque pipe payload compatible with the existing `W`, `WxH`, and unknown-tail behavior. Carry the authored width through Markdown projection and attachment geometry without discarding unknown parameters. Rewriting an explicit width must touch only the leading numeric segment and form one native undo transaction. 2. **Keep authored width distinct from view controls.** Authored `|W`/`|WxH` is portable document state. The Craft-derived Size choices (`Auto`, `Large`) are semantic view presets whose stable source mapping has not been specified. They must remain explicitly presentation-only until product semantics define a durable integer width. They must not silently replace an authored width. 3. **Treat Fit/Fill as presentation-only.** `Fit` contains the full image. `Fill` aspect-fills and clips the rendered view only; it never edits/crops the source image or rewrites Markdown. The toolbar must expose this as a view setting (for example, a persistent static “This view” label/accessibility help), rather than implying that it survives reload. 4. **Use public native AppKit controls.** Add a focused `EditorImageToolbarController` using a native nonactivating panel or popover, static `NSTextField` labels, and `NSSegmentedControl` or `NSPopUpButton` choices for **Image Size: Auto / Large** and **Image Fit: Fit / Fill**. Preserve keyboard order, checked/selected state, Escape dismissal and focus restoration. Do not add timers. 5. **Anchor to one exact occurrence.** Generalize #11's target to carry the exact display range/token identity, preview URL and native attachment rect. Re-anchor from that occurrence on layout/reflow/scroll, and dismiss when it becomes unrealized, its identity changes, the editor detaches, or the owner window closes. Identical destination paths in different occurrences must keep independent presentation state. 6. **Keep geometry bounded.** Auto/Fit retains current aspect-preserving behavior. Large/Fit uses the available-width presentation slot with the current 220 pt height bound. Fill clips inside that slot. Targeting and updates stay within the selected realized fragment; no full-document layout scan or synchronous image decode is added. ### Verification required - Parser/rewriter tests: no pipe, `W`, `WxH`, unknown-only and `W|unknown`, escaped labels/destinations, CRLF, and duplicate occurrences, with exact source-byte preservation outside the edited numeric segment. - Mounted AppKit tests: exact occurrence selection; Auto/Fit, Large/Fit and Fill geometry; no distortion or source-file mutation; duplicate-path independence; inline/list images; very tall, wide, small and missing images. - Toolbar lifecycle tests: native labels/states, keyboard reachability, Escape/focus restoration, reflow/scroll/window-close teardown, rapid selection changes, and no retained monitor/observer/timer. - VM user flow: reduced motion/transparency, VoiceOver names, appearance changes, scrolling/reflow, and interaction with the final #3 multi-block selection semantics. - Release profiling remains required for launch and scroll-spam claims; focused/mounted tests are not performance evidence. ### Integration order and dependencies Issue #3 is actively changing `BlockEditorView.swift`, native `selectedRanges`, click suppression, Copy/Cut/Delete/Undo, drag behavior and context-action guards. Issue #11 also changes the same editor and supplies the exact image target. Freeze/integrate #3 first, then rebase and land #11, then implement #12 against the resulting image-selection contract. Root coordination is required before any shared editor edit. This issue stays open. The portable width model exists, but Apple support, native controls, runtime verification and any durable semantics for Auto/Large or Fit/Fill are not delivered yet.
Author
Owner

Source contract and bounded native implementation plan (2026-09-13)

Worker: /root/image_preview_native_repair
Worktree: /Users/kayg/Developer/calternal-app/.worktrees/image-controls
Branch: wave16/image-controls
Base: 9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405

No implementation has started yet. This plan is awaiting source/UX review.

Verified portable source semantics

The existing product implementation in calternal.js/packages/web/src/lib/editor/markdown.ts defines the supported image pipe contract:

  • ![alt|640](path) and ![alt|640x480](path) are accepted.
  • The first | separates alt text from the raw pipe payload.
  • Only a leading bare W or WxH segment is interpreted.
  • Everything after that first pipe segment is opaque and must round-trip verbatim.
  • Updating width replaces the leading numeric segment, or prepends one when the first segment is unknown: 640x480|circle -> 320|circle, circle -> 320|circle.
  • The current web renderer applies the authored width and uses height: auto; the parsed height remains compatibility metadata and does not authorize distortion or cropping.

The matching web tests cover 640, 640x480, 640x480|circle, unknown-only pipes, and width rewrites. Apple currently treats the full alt|pipe label as alternate text and does not apply the authored width.

No existing portable source representation for Fit versus Fill was found. This implementation will not invent one.

Proposed minimum behavior

  1. Add a small lossless image-source helper in a new image-controls file. It will inspect the exact canonical image token selected through the integrated #11 attachment target, split at the first raw |, parse only the leading numeric size segment, and rewrite only that segment. It will preserve the destination, alt spelling/escapes, unknown pipe tail, line endings, surrounding prose, and source-image bytes.
  2. Add native Image Size choices Auto and Large (640 px). Auto removes only an existing leading numeric segment (including WxH) while preserving an unknown tail. Large writes the stable portable width 640, replacing or prepending only the leading segment. A document-authored non-640 width is displayed as Custom (N px) and remains untouched until the user explicitly chooses Auto or Large. Each source change is one canonical transaction and one undo step.
  3. Honor any authored leading width in attachment geometry, bounded by the realized line width and the existing 220 pt display-height cap. The source image is never re-encoded or overwritten. WxH remains losslessly preserved; consistent with the existing renderer, width controls layout while height remains compatibility metadata.
  4. Add native Image Fit choices Fit and Fill as mounted-view presentation state only. Fit contains the full image. Fill clips an aspect-filled drawing inside the presentation slot; it never crops source bytes. The control is visibly labeled IMAGE FIT — THIS VIEW and carries equivalent accessibility help so reload persistence is not implied.
  5. Use one focused EditorImageToolbarController backed by public AppKit controls: a native nonactivating NSPanel, static NSTextField labels, and NSSegmentedControl/NSPopUpButton choices. An unmodified single-click on an exact image attachment selects only that occurrence and shows the panel adjacent to its native TextKit frame. Double-click continues to Quick Look. Command/Shift/Control/Option gestures retain the integrated block-selection behavior.
  6. Reuse/generalize the #11 exact realized-fragment target for selection, preview, controls, and anchor frame. The panel re-anchors from the exact selected attachment during layout and scroll, dismisses if that occurrence becomes unrealized or selection changes, and tears down on editor/window removal. There are no dwell timers, document-wide layout scans, new block models, title/inspector changes, or synchronous image decoding.
  7. Keep per-occurrence Fit/Fill state inside the mounted image presenter. Duplicate paths do not share state. A projection refresh may remap state only when the same canonical image token can be identified exactly; otherwise it falls back to Fit instead of applying state to a different occurrence.

Focused verification

  • Lossless source tests for absent size, W, WxH, unknown-only, W|unknown, escaped labels/destinations, inline/list/standalone images, duplicate destinations, CRLF, and Auto/Large undo/redo.
  • Geometry/drawing tests for authored width, viewport/220 pt caps, very small/wide/tall images, Fit containment, Fill clipping, missing loads, and no distortion or source-byte mutation.
  • Mounted panel tests for exact occurrence selection, Custom state, labels/accessibility, keyboard traversal, Escape/focus restoration, reflow/scroll anchoring, duplicate independence, rapid selection changes, close/detach cleanup, reduced motion/transparency, and no retained monitor/observer/timer.
  • Exact-tip remote Swift 6.3 build and focused tests after source review. VM/native interaction and Release launch/scroll-spam evidence remain separate gates; no local build or VM lease will be used by this worker.

The issue remains open through exact-tip source review, remote tests, VM interaction, delivered build, and user acceptance.

## Source contract and bounded native implementation plan (2026-09-13) **Worker:** `/root/image_preview_native_repair` **Worktree:** `/Users/kayg/Developer/calternal-app/.worktrees/image-controls` **Branch:** `wave16/image-controls` **Base:** `9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405` No implementation has started yet. This plan is awaiting source/UX review. ### Verified portable source semantics The existing product implementation in `calternal.js/packages/web/src/lib/editor/markdown.ts` defines the supported image pipe contract: - `![alt|640](path)` and `![alt|640x480](path)` are accepted. - The **first** `|` separates alt text from the raw pipe payload. - Only a leading bare `W` or `WxH` segment is interpreted. - Everything after that first pipe segment is opaque and must round-trip verbatim. - Updating width replaces the leading numeric segment, or prepends one when the first segment is unknown: `640x480|circle -> 320|circle`, `circle -> 320|circle`. - The current web renderer applies the authored width and uses `height: auto`; the parsed height remains compatibility metadata and does not authorize distortion or cropping. The matching web tests cover `640`, `640x480`, `640x480|circle`, unknown-only pipes, and width rewrites. Apple currently treats the full `alt|pipe` label as alternate text and does not apply the authored width. No existing portable source representation for **Fit** versus **Fill** was found. This implementation will not invent one. ### Proposed minimum behavior 1. Add a small lossless image-source helper in a new image-controls file. It will inspect the exact canonical image token selected through the integrated #11 attachment target, split at the first raw `|`, parse only the leading numeric size segment, and rewrite only that segment. It will preserve the destination, alt spelling/escapes, unknown pipe tail, line endings, surrounding prose, and source-image bytes. 2. Add native **Image Size** choices `Auto` and `Large (640 px)`. `Auto` removes only an existing leading numeric segment (including `WxH`) while preserving an unknown tail. `Large` writes the stable portable width `640`, replacing or prepending only the leading segment. A document-authored non-640 width is displayed as `Custom (N px)` and remains untouched until the user explicitly chooses Auto or Large. Each source change is one canonical transaction and one undo step. 3. Honor any authored leading width in attachment geometry, bounded by the realized line width and the existing 220 pt display-height cap. The source image is never re-encoded or overwritten. `WxH` remains losslessly preserved; consistent with the existing renderer, width controls layout while height remains compatibility metadata. 4. Add native **Image Fit** choices `Fit` and `Fill` as mounted-view presentation state only. `Fit` contains the full image. `Fill` clips an aspect-filled drawing inside the presentation slot; it never crops source bytes. The control is visibly labeled `IMAGE FIT — THIS VIEW` and carries equivalent accessibility help so reload persistence is not implied. 5. Use one focused `EditorImageToolbarController` backed by public AppKit controls: a native nonactivating `NSPanel`, static `NSTextField` labels, and `NSSegmentedControl`/`NSPopUpButton` choices. An unmodified single-click on an exact image attachment selects only that occurrence and shows the panel adjacent to its native TextKit frame. Double-click continues to Quick Look. Command/Shift/Control/Option gestures retain the integrated block-selection behavior. 6. Reuse/generalize the #11 exact realized-fragment target for selection, preview, controls, and anchor frame. The panel re-anchors from the exact selected attachment during layout and scroll, dismisses if that occurrence becomes unrealized or selection changes, and tears down on editor/window removal. There are no dwell timers, document-wide layout scans, new block models, title/inspector changes, or synchronous image decoding. 7. Keep per-occurrence Fit/Fill state inside the mounted image presenter. Duplicate paths do not share state. A projection refresh may remap state only when the same canonical image token can be identified exactly; otherwise it falls back to Fit instead of applying state to a different occurrence. ### Focused verification - Lossless source tests for absent size, `W`, `WxH`, unknown-only, `W|unknown`, escaped labels/destinations, inline/list/standalone images, duplicate destinations, CRLF, and Auto/Large undo/redo. - Geometry/drawing tests for authored width, viewport/220 pt caps, very small/wide/tall images, Fit containment, Fill clipping, missing loads, and no distortion or source-byte mutation. - Mounted panel tests for exact occurrence selection, Custom state, labels/accessibility, keyboard traversal, Escape/focus restoration, reflow/scroll anchoring, duplicate independence, rapid selection changes, close/detach cleanup, reduced motion/transparency, and no retained monitor/observer/timer. - Exact-tip remote Swift 6.3 build and focused tests after source review. VM/native interaction and Release launch/scroll-spam evidence remain separate gates; no local build or VM lease will be used by this worker. The issue remains open through exact-tip source review, remote tests, VM interaction, delivered build, and user acceptance.
Author
Owner

Reviewer: ui_fixes_review_medium
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Base reviewed: 9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405
State: pre-implementation plan REJECTED pending bounded clarifications; no source edits, build, or UI verification.

P1 — source actions need stale-target validation. Each Auto/Large action must re-resolve the current document's exact image token at the captured occurrence and require the raw token/range to match before applying the smallest numeric-label edit through MarkdownBlockDocument's canonical replacement/Undo path. A stored range can become stale after an edit, projection rebuild, or note/session change and otherwise rewrite unrelated source. The toolbar controller must not capture or mutate a note session directly.

P2 — Fit/Fill lacks a defined presentation slot. Existing attachment bounds preserve the image aspect ratio, and authored W still yields that aspect ratio because H is intentionally ignored. Fit and Fill therefore render identically unless the plan defines a bounded slot with an independent aspect ratio/height. Specify the exact Auto/Large slot, document-height effect, and small/wide/tall behavior before coding. Do not invent an unsupported fixed ratio merely to make Fill visible; leave Fill unavailable where there is no meaningful crop distinction if necessary.

P2 — duplicate occurrence remapping is underspecified. Byte-identical tokens cannot be identified by canonical token text or destination. Keep Fit/Fill only on the same attachment instance, or key it to document identity plus exact occurrence/source revision and carry it only through a proven edit-range transform. Otherwise reset to Fit. The duplicate test must include two identical tokens, not only two tokens with the same destination.

P3 — the prior issue comment says Auto/Large must remain presentation-only until durable semantics are defined, while the newer plan makes Auto remove numeric width and Large persist 640. Root's latest task treats these mutations as intended, so the issue should explicitly record that the new decision supersedes the earlier constraint. It should also state that Auto removal is a new Apple inverse operation: calternal.js defines width insertion/replacement but no width-removal helper. Define whitespace behavior for a trimmed numeric first segment so byte-preservation assertions have one contract.

Confirmed: first literal pipe splitting and leading trimmed W/WxH parsing match calternal.js; unknown trailing pipe data must remain opaque. Preserve the raw label/destination through canonical source-range edits rather than reconstructing from Swift Markdown's decoded alternate text. Authored width should upscale toward W when needed, bounded by realized line width and 220 pt; Auto should retain intrinsic no-upscale behavior. Avoid content-based remapping, timers, document scans, and direct session ownership.

Reviewer: ui_fixes_review_medium Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Base reviewed: `9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405` State: pre-implementation plan REJECTED pending bounded clarifications; no source edits, build, or UI verification. P1 — source actions need stale-target validation. Each Auto/Large action must re-resolve the current document's exact image token at the captured occurrence and require the raw token/range to match before applying the smallest numeric-label edit through `MarkdownBlockDocument`'s canonical replacement/Undo path. A stored range can become stale after an edit, projection rebuild, or note/session change and otherwise rewrite unrelated source. The toolbar controller must not capture or mutate a note session directly. P2 — Fit/Fill lacks a defined presentation slot. Existing attachment bounds preserve the image aspect ratio, and authored W still yields that aspect ratio because H is intentionally ignored. Fit and Fill therefore render identically unless the plan defines a bounded slot with an independent aspect ratio/height. Specify the exact Auto/Large slot, document-height effect, and small/wide/tall behavior before coding. Do not invent an unsupported fixed ratio merely to make Fill visible; leave Fill unavailable where there is no meaningful crop distinction if necessary. P2 — duplicate occurrence remapping is underspecified. Byte-identical tokens cannot be identified by canonical token text or destination. Keep Fit/Fill only on the same attachment instance, or key it to document identity plus exact occurrence/source revision and carry it only through a proven edit-range transform. Otherwise reset to Fit. The duplicate test must include two identical tokens, not only two tokens with the same destination. P3 — the prior issue comment says Auto/Large must remain presentation-only until durable semantics are defined, while the newer plan makes Auto remove numeric width and Large persist 640. Root's latest task treats these mutations as intended, so the issue should explicitly record that the new decision supersedes the earlier constraint. It should also state that Auto removal is a new Apple inverse operation: calternal.js defines width insertion/replacement but no width-removal helper. Define whitespace behavior for a trimmed numeric first segment so byte-preservation assertions have one contract. Confirmed: first literal pipe splitting and leading trimmed W/WxH parsing match calternal.js; unknown trailing pipe data must remain opaque. Preserve the raw label/destination through canonical source-range edits rather than reconstructing from Swift Markdown's decoded alternate text. Authored width should upscale toward W when needed, bounded by realized line width and 220 pt; Auto should retain intrinsic no-upscale behavior. Avoid content-based remapping, timers, document scans, and direct session ownership.
Author
Owner

Plan correction after pre-code review

The newer #12 direction supersedes the earlier audit statement that both Auto and Large would remain presentation-only. The reviewed direction is now:

  • Image Size is portable document state. Auto is Apple’s new inverse operation for the existing width pipe; Large (640 px) uses the existing portable |W representation. calternal.js defines width insertion/replacement but does not currently define removal, so Auto removal is specified below rather than attributed to the web helper.
  • Image Fit remains mounted-view state. There is still no portable Fit/Fill syntax, and none will be invented.

No code has started; the plan remains under review.

Exact source-mutation fence

The toolbar controller will never hold or mutate NoteEditorSession, and it will never apply a stored range directly. Its captured target contains only the editor document identity, source revision, exact display range, exact canonical source range, and raw image-token bytes.

On every Auto/Large action, BlockEditorView must re-resolve the currently selected attachment against the current document and require all captured identity, revision, display range, source range, and raw-token values to match. It must also parse that current raw token again. Any mismatch dismisses the panel and performs no edit. The minimal label subrange then travels through the existing canonical document replace/Undo seam as one transaction. Projection rebuild, unrelated edit, note swap, or stale selection therefore fails closed instead of rewriting whatever now occupies an old NSRange.

Width syntax follows the verified JavaScript behavior exactly for whitespace:

  • A leading segment is a size when its trimmed text is bare W or WxH.
  • Large replaces the entire raw first segment, including surrounding whitespace, with 640.
  • If the first segment is unknown, Large inserts 640| before it without changing that unknown segment or its whitespace.
  • With no pipe, Large inserts |640 immediately before the label’s closing ].
  • Auto is the new inverse: for a recognized size plus another segment, it removes the entire first raw segment and the following separator (alt| 640 |circle -> alt|circle); for size-only it removes the first | plus the entire raw segment (alt| 640 -> alt). Unknown-only pipes are unchanged.
  • The destination, raw alt spelling/escapes, unknown tail, surrounding inline text, line endings, and image file are never reconstructed or rewritten.

The first literal | rule intentionally matches the existing calternal.js limitation, including its escaped-pipe behavior.

Exact presentation slots and Fit availability

  • Auto with no authored width preserves today’s intrinsic, no-upscale, aspect-fit bounds under the line-width and 220 pt height caps. It has no independent crop slot, so Fill is unavailable and the effective mode is Fit.
  • Custom authored width (W other than bare 640, or any WxH) uses the natural aspect ratio at the requested width, allowed to upscale toward W but still bounded by line width and 220 pt height. The height component is preserved compatibility metadata, consistent with the web renderer’s height:auto. This also has no independent crop slot, so Fill is unavailable.
  • Large is exactly bare |640. Its presentation slot is min(640, positive realized line width) × 220 pt. The slot contributes the full 220 pt to document height while loading, missing, Fit, or Fill, preventing a mode-driven height jump. Fit centers an aspect-contained image in that slot and may upscale. Fill centers an aspect-filled drawing and clips only the displayed view to that slot. Very wide, tall, and small images use the same rule. Fill is disabled until an image is loaded and when its aspect ratio is effectively equal to the slot, because there is then no visible crop distinction.

This 640-by-220 Large slot is the existing Craft-derived design target already recorded in the editor polish inventory; it is not new Markdown syntax. Only |640 persists. Fit/Fill and cropping remain explicitly THIS VIEW state.

Exact occurrence lifetime

Fit/Fill state lives only on the current EditorImageAttachment instance. It is never searched or remapped by destination, token bytes, or occurrence ordinal. The toolbar target also requires that same attachment identity. Any projection replacement or ambiguous lifecycle resets to Fit and dismisses the stale panel. Two byte-identical image tokens therefore remain independent.

The new panel will follow the established nonactivating-panel focus, Escape/outside-click monitor, child-window, observer, and teardown pattern. The first click may show it; an exact second click dismisses it before invoking Quick Look.

Tests will include stale revision/token/range rejection, whitespace-normalized size replacement/removal, two byte-identical tokens, disabled Fill for Auto/custom/equal-aspect/unloaded states, fixed Large document height, very small/wide/tall Fit and Fill, projection-reset behavior, and panel/monitor teardown.

### Plan correction after pre-code review The newer #12 direction **supersedes** the earlier audit statement that both Auto and Large would remain presentation-only. The reviewed direction is now: - **Image Size is portable document state.** `Auto` is Apple’s new inverse operation for the existing width pipe; `Large (640 px)` uses the existing portable `|W` representation. `calternal.js` defines width insertion/replacement but does not currently define removal, so Auto removal is specified below rather than attributed to the web helper. - **Image Fit remains mounted-view state.** There is still no portable Fit/Fill syntax, and none will be invented. No code has started; the plan remains under review. #### Exact source-mutation fence The toolbar controller will never hold or mutate `NoteEditorSession`, and it will never apply a stored range directly. Its captured target contains only the editor document identity, source revision, exact display range, exact canonical source range, and raw image-token bytes. On every Auto/Large action, `BlockEditorView` must re-resolve the currently selected attachment against the **current** document and require all captured identity, revision, display range, source range, and raw-token values to match. It must also parse that current raw token again. Any mismatch dismisses the panel and performs no edit. The minimal label subrange then travels through the existing canonical document replace/Undo seam as one transaction. Projection rebuild, unrelated edit, note swap, or stale selection therefore fails closed instead of rewriting whatever now occupies an old `NSRange`. Width syntax follows the verified JavaScript behavior exactly for whitespace: - A leading segment is a size when its **trimmed** text is bare `W` or `WxH`. - Large replaces the entire raw first segment, including surrounding whitespace, with `640`. - If the first segment is unknown, Large inserts `640|` before it without changing that unknown segment or its whitespace. - With no pipe, Large inserts `|640` immediately before the label’s closing `]`. - Auto is the new inverse: for a recognized size plus another segment, it removes the entire first raw segment and the following separator (`alt| 640 |circle -> alt|circle`); for size-only it removes the first `|` plus the entire raw segment (`alt| 640 -> alt`). Unknown-only pipes are unchanged. - The destination, raw alt spelling/escapes, unknown tail, surrounding inline text, line endings, and image file are never reconstructed or rewritten. The first **literal** `|` rule intentionally matches the existing calternal.js limitation, including its escaped-pipe behavior. #### Exact presentation slots and Fit availability - **Auto** with no authored width preserves today’s intrinsic, no-upscale, aspect-fit bounds under the line-width and 220 pt height caps. It has no independent crop slot, so Fill is unavailable and the effective mode is Fit. - **Custom authored width** (`W` other than bare `640`, or any `WxH`) uses the natural aspect ratio at the requested width, allowed to upscale toward W but still bounded by line width and 220 pt height. The height component is preserved compatibility metadata, consistent with the web renderer’s `height:auto`. This also has no independent crop slot, so Fill is unavailable. - **Large** is exactly bare `|640`. Its presentation slot is `min(640, positive realized line width) × 220 pt`. The slot contributes the full 220 pt to document height while loading, missing, Fit, or Fill, preventing a mode-driven height jump. `Fit` centers an aspect-contained image in that slot and may upscale. `Fill` centers an aspect-filled drawing and clips only the displayed view to that slot. Very wide, tall, and small images use the same rule. Fill is disabled until an image is loaded and when its aspect ratio is effectively equal to the slot, because there is then no visible crop distinction. This 640-by-220 Large slot is the existing Craft-derived design target already recorded in the editor polish inventory; it is not new Markdown syntax. Only `|640` persists. Fit/Fill and cropping remain explicitly `THIS VIEW` state. #### Exact occurrence lifetime Fit/Fill state lives only on the current `EditorImageAttachment` instance. It is never searched or remapped by destination, token bytes, or occurrence ordinal. The toolbar target also requires that same attachment identity. Any projection replacement or ambiguous lifecycle resets to Fit and dismisses the stale panel. Two byte-identical image tokens therefore remain independent. The new panel will follow the established nonactivating-panel focus, Escape/outside-click monitor, child-window, observer, and teardown pattern. The first click may show it; an exact second click dismisses it before invoking Quick Look. Tests will include stale revision/token/range rejection, whitespace-normalized size replacement/removal, two byte-identical tokens, disabled Fill for Auto/custom/equal-aspect/unloaded states, fixed Large document height, very small/wide/tall Fit and Fill, projection-reset behavior, and panel/monitor teardown.
Author
Owner

Review ownership handoff

Plan and subsequent implementation review for #12 are now owned by /root/image_controls_review, relieving the shared UI-fixes review queue. The corrected plan is the current contract; implementation remains paused until that dedicated reviewer returns PASS.

Worker and source ownership remain /root/image_preview_native_repair in .worktrees/image-controls on base 9e3a64b6. No central, title, inspector, local-build, or VM changes have been made.

### Review ownership handoff Plan and subsequent implementation review for #12 are now owned by `/root/image_controls_review`, relieving the shared UI-fixes review queue. The corrected plan is the current contract; implementation remains paused until that dedicated reviewer returns PASS. Worker and source ownership remain `/root/image_preview_native_repair` in `.worktrees/image-controls` on base `9e3a64b6`. No central, title, inspector, local-build, or VM changes have been made.
Author
Owner

Reviewer: ui_fixes_review_medium
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Base: 9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405
State: corrected pre-code plan remains REJECTED for one bounded classification gap; no implementation/build/UI work reviewed.

P2 — the corrected presentation section defines Large as exactly bare |640. The portable grammar and the proposed rewrite both produce valid leading-size forms such as |640|circle and | 640 |circle; selecting Large for unknown |circle itself produces |640|circle. If only a bare pipe activates the Large slot, the action immediately lands in an undefined/custom state and disables Fill. Classify Large from the parsed leading segment as width == 640 && height == nil, regardless of raw first-segment whitespace or an opaque tail, while preserving the tail byte-for-byte. Keep 640xH custom because height metadata is present. Add control-state and geometry cases for 640|circle and whitespace plus a tail.

P3 — every successful Auto/Large source edit replaces the attachment and the current lifecycle says any replacement resets Fit and dismisses the panel. Consider deliberately reacquiring the exact newly projected occurrence after this known transaction, with Fit reset, so Size then Fit does not require reopening the toolbar. The reacquisition must use the proven edit result/range and new attachment identity, never content search.

All earlier blockers are otherwise resolved: current-document/revision/range/raw-token validation, minimal canonical Undo edit, exact whitespace rules, explicit Auto/Large supersession, defined bounded slots and Fill availability, attachment-instance-only state, identical-token coverage, and double-click panel dismissal are suitable.

Reviewer: ui_fixes_review_medium Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Base: `9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405` State: corrected pre-code plan remains REJECTED for one bounded classification gap; no implementation/build/UI work reviewed. P2 — the corrected presentation section defines Large as exactly bare `|640`. The portable grammar and the proposed rewrite both produce valid leading-size forms such as `|640|circle` and `| 640 |circle`; selecting Large for unknown `|circle` itself produces `|640|circle`. If only a bare pipe activates the Large slot, the action immediately lands in an undefined/custom state and disables Fill. Classify Large from the parsed leading segment as `width == 640 && height == nil`, regardless of raw first-segment whitespace or an opaque tail, while preserving the tail byte-for-byte. Keep `640xH` custom because height metadata is present. Add control-state and geometry cases for `640|circle` and whitespace plus a tail. P3 — every successful Auto/Large source edit replaces the attachment and the current lifecycle says any replacement resets Fit and dismisses the panel. Consider deliberately reacquiring the exact newly projected occurrence after this known transaction, with Fit reset, so Size then Fit does not require reopening the toolbar. The reacquisition must use the proven edit result/range and new attachment identity, never content search. All earlier blockers are otherwise resolved: current-document/revision/range/raw-token validation, minimal canonical Undo edit, exact whitespace rules, explicit Auto/Large supersession, defined bounded slots and Fill availability, attachment-instance-only state, identical-token coverage, and double-click panel dismissal are suitable.
Author
Owner

Plan correction 2: Large classification and post-edit reacquisition

The Large presentation state is classified by the parsed leading segment: width == 640 && height == nil, regardless of surrounding whitespace or any opaque tail. Therefore |640, | 640 , |640|circle, and | 640 |circle all use the same 640-by-220 Large slot and expose Fit/Fill when loaded and aspect-distinct. |640xH remains Custom because height metadata is present. Large rewriting still normalizes only the leading segment to 640 and preserves the opaque tail byte-for-byte.

Tests will cover classification, geometry, and control state for bare 640, 640|circle, whitespace plus tail, and 640xH.

After a successful Auto/Large source transaction replaces the attachment, BlockEditorView may immediately reacquire the new occurrence only through the proven edit result: it computes the new enclosing token range from the exact old token plus the applied UTF-16 length delta, keeps that new token selected through the canonical transaction, and validates the returned display range against that exact new source range and expected newly edited raw token. It never searches by contents or destination. If every fence passes, the panel reopens on the replacement attachment with Fit reset; otherwise it dismisses. This lets the user choose Size and then Fit without reopening while preserving fail-closed occurrence identity.

This correction and the prior correction together are the implementation contract. Code remains paused for dedicated reviewer /root/image_controls_review.

### Plan correction 2: Large classification and post-edit reacquisition The Large presentation state is classified by the **parsed** leading segment: `width == 640 && height == nil`, regardless of surrounding whitespace or any opaque tail. Therefore `|640`, `| 640 `, `|640|circle`, and `| 640 |circle` all use the same 640-by-220 Large slot and expose Fit/Fill when loaded and aspect-distinct. `|640xH` remains Custom because height metadata is present. Large rewriting still normalizes only the leading segment to `640` and preserves the opaque tail byte-for-byte. Tests will cover classification, geometry, and control state for bare 640, `640|circle`, whitespace plus tail, and `640xH`. After a successful Auto/Large source transaction replaces the attachment, `BlockEditorView` may immediately reacquire the new occurrence only through the proven edit result: it computes the new enclosing token range from the exact old token plus the applied UTF-16 length delta, keeps that new token selected through the canonical transaction, and validates the returned display range against that exact new source range and expected newly edited raw token. It never searches by contents or destination. If every fence passes, the panel reopens on the replacement attachment with Fit reset; otherwise it dismisses. This lets the user choose Size and then Fit without reopening while preserving fail-closed occurrence identity. This correction and the prior correction together are the implementation contract. Code remains paused for dedicated reviewer `/root/image_controls_review`.
Author
Owner

Plan correction 3: lossless numeric bounds and synchronous CAS

The source grammar recognizes a leading size segment lexically as trimmed ASCII digits W or WxH, including 0 and digit strings too large for a machine integer. Recognition and preservation are separate from safe presentation conversion:

  • The raw leading segment and opaque tail always remain lossless.
  • Numeric conversion uses an overflow-checking digit scan with no force conversion, floating parser, or trapping arithmetic.
  • A positive finite width representable within the bounded presentation policy may drive Custom geometry.
  • Zero, non-positive results, or unrepresentable/oversized digit strings remain visibly Custom, preserve their exact source, and fall back to Auto geometry. Their display label is bounded (Custom) rather than echoing an arbitrarily large source string into the panel.
  • Large classification still means a parsed leading width of exactly 640 with no height component, regardless of raw whitespace or opaque trailing segments. Any 640xH remains Custom.
  • Auto and Large actions can safely normalize an existing lexically recognized zero/huge segment because they replace/remove that exact raw segment after the full stale-target fence; unknown tail bytes remain untouched.

Tests add |0, |0x0, extremely long W/H digit strings, huge values with an opaque tail, and Auto/Large rewrites from those sources. They assert no trap, bounded geometry, bounded control labels, and byte preservation outside the exact leading segment.

The source edit is a synchronous @MainActor compare-and-swap inside BlockEditorView: current document identity, revision, selected display range, mapped source range, current raw token, and reparsed mutation range are checked consecutively, then the existing canonical transaction is invoked immediately with no suspension, callback, task, notification wait, or controller/session mutation between validation and replacement.

This correction completes the proposed pre-code contract and awaits dedicated reviewer PASS.

### Plan correction 3: lossless numeric bounds and synchronous CAS The source grammar recognizes a leading size segment lexically as trimmed ASCII digits `W` or `WxH`, including `0` and digit strings too large for a machine integer. Recognition and preservation are separate from safe presentation conversion: - The raw leading segment and opaque tail always remain lossless. - Numeric conversion uses an overflow-checking digit scan with no force conversion, floating parser, or trapping arithmetic. - A positive finite width representable within the bounded presentation policy may drive Custom geometry. - Zero, non-positive results, or unrepresentable/oversized digit strings remain visibly `Custom`, preserve their exact source, and fall back to Auto geometry. Their display label is bounded (`Custom`) rather than echoing an arbitrarily large source string into the panel. - Large classification still means a parsed leading width of exactly `640` with no height component, regardless of raw whitespace or opaque trailing segments. Any `640xH` remains Custom. - Auto and Large actions can safely normalize an existing lexically recognized zero/huge segment because they replace/remove that exact raw segment after the full stale-target fence; unknown tail bytes remain untouched. Tests add `|0`, `|0x0`, extremely long W/H digit strings, huge values with an opaque tail, and Auto/Large rewrites from those sources. They assert no trap, bounded geometry, bounded control labels, and byte preservation outside the exact leading segment. The source edit is a synchronous `@MainActor` compare-and-swap inside `BlockEditorView`: current document identity, revision, selected display range, mapped source range, current raw token, and reparsed mutation range are checked consecutively, then the existing canonical transaction is invoked immediately with no suspension, callback, task, notification wait, or controller/session mutation between validation and replacement. This correction completes the proposed pre-code contract and awaits dedicated reviewer PASS.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch reviewed: .worktrees/image-controls / wave16/image-controls
Base reviewed: 9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405
State: corrected pre-implementation plan is accepted with one bounded P2 contract correction; no source diff, build, or GUI verification exists yet.

The correction comment resolves the prior review findings: every size mutation is fenced by document/attachment identity, source revision, exact display/source ranges, and raw token before a synchronous canonical transaction; Large now has a distinct fixed-height min(640, realized line width) × 220 slot; Fit/Fill stays on the same attachment instance and never remaps duplicate content; and the issue explicitly supersedes the earlier Auto/Large persistence assumption while defining Auto whitespace removal.

P2 — define safe presentation for zero and unrepresentable numeric pipe sizes before coding. Location: proposed lossless image-source helper and EditorImageAttachment geometry in Sources/CalternalEditor/. The inherited JavaScript grammar is \d+, so |0, |0x0, and arbitrarily long decimal W/H segments are syntactically recognized source, even when they cannot become a positive finite CGFloat/Int. A direct integer conversion or requested-width geometry can overflow, fail inconsistently, yield zero/invalid bounds, or make an authored image disappear. Fix: parse without trapping; preserve the raw recognized W/WxH segment and unknown tail byte-for-byte; classify only exact bare 640 as Large; display every other recognized value as Custom; and for any non-positive or non-representable width, keep the source untouched but fall back to bounded Auto/Fit geometry. Add focused 0, 0x0, and decimal strings longer than Int.max tests for parse, rewrite, projection, and geometry. Height remains opaque compatibility metadata and must never be numerically required for layout.

Required mutation invariant (confirmed): run the complete identity/revision/range/raw-token validation and the minimal replacement synchronously on MainActor, then route it through BlockEditorView's existing canonical source replacement/Undo path. The toolbar controller must not receive document/session mutation authority. A failed check performs no edit and dismisses the panel.

No other P1/P2/P3 plan findings are open at this revision. Candidate review must inspect the exact diff, especially identical-token occurrence independence, projection-reset behavior, fixed Large document height, Fill clipping without distortion, and one-step undo/redo. Issue remains open for implementation, exact-tip review, remote build/tests, VM checks, delivered preview, and user acceptance.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch reviewed: `.worktrees/image-controls` / `wave16/image-controls` Base reviewed: `9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405` State: corrected pre-implementation plan is **accepted with one bounded P2 contract correction**; no source diff, build, or GUI verification exists yet. The correction comment resolves the prior review findings: every size mutation is fenced by document/attachment identity, source revision, exact display/source ranges, and raw token before a synchronous canonical transaction; Large now has a distinct fixed-height `min(640, realized line width) × 220` slot; Fit/Fill stays on the same attachment instance and never remaps duplicate content; and the issue explicitly supersedes the earlier Auto/Large persistence assumption while defining Auto whitespace removal. **P2 — define safe presentation for zero and unrepresentable numeric pipe sizes before coding.** Location: proposed lossless image-source helper and `EditorImageAttachment` geometry in `Sources/CalternalEditor/`. The inherited JavaScript grammar is `\d+`, so `|0`, `|0x0`, and arbitrarily long decimal W/H segments are syntactically recognized source, even when they cannot become a positive finite `CGFloat`/`Int`. A direct integer conversion or requested-width geometry can overflow, fail inconsistently, yield zero/invalid bounds, or make an authored image disappear. Fix: parse without trapping; preserve the raw recognized W/WxH segment and unknown tail byte-for-byte; classify only exact bare `640` as Large; display every other recognized value as Custom; and for any non-positive or non-representable width, keep the source untouched but fall back to bounded Auto/Fit geometry. Add focused `0`, `0x0`, and decimal strings longer than `Int.max` tests for parse, rewrite, projection, and geometry. Height remains opaque compatibility metadata and must never be numerically required for layout. **Required mutation invariant (confirmed):** run the complete identity/revision/range/raw-token validation and the minimal replacement synchronously on `MainActor`, then route it through `BlockEditorView`'s existing canonical source replacement/Undo path. The toolbar controller must not receive document/session mutation authority. A failed check performs no edit and dismisses the panel. No other P1/P2/P3 plan findings are open at this revision. Candidate review must inspect the exact diff, especially identical-token occurrence independence, projection-reset behavior, fixed Large document height, Fill clipping without distortion, and one-step undo/redo. Issue remains open for implementation, exact-tip review, remote build/tests, VM checks, delivered preview, and user acceptance.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Plan reviewed: issue #12 corrections 1–3 on base 9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405
State: PRE-CODE PLAN PASS; author may implement. No source diff, build, or GUI result has been reviewed.

Correction to my immediately preceding comment: its phrase “classify only exact bare 640 as Large” was based on the earlier issue snapshot and is superseded by plan correction 2. The correct contract is: Large is a lexically recognized leading width numerically equal to 640 with no height component, regardless of whitespace or opaque tail (640, 640, 640|circle, and 640 |circle). 640xH remains Custom. This makes the Large action stable when it preserves an unknown tail.

Plan correction 3 fully resolves my numeric-bound P2: recognition is lexical and lossless; conversion is checked and nontrapping; zero/oversized values remain bounded Custom controls and fall back to Auto/Fit geometry; normalization/removal still works through the exact stale-target fence. Its 0, 0x0, huge W/H, and opaque-tail cases are sufficient for the pre-code contract.

The approved implementation remains bounded to:

  • lossless leading W/WxH parse and Auto/Large rewrite without reconstructing destination, escapes, tail, surrounding text, or line endings;
  • synchronous @MainActor attachment/document/revision/display-range/source-range/raw-token CAS immediately followed by BlockEditorView's canonical Undo transaction;
  • intrinsic Auto geometry, bounded Custom width geometry, and a fixed min(640, positive realized line width) × 220 Large slot;
  • Fit/Fill only for loaded, aspect-distinct Large slots, stored on one attachment instance and never remapped by bytes/path/ordinal;
  • optional post-size-edit panel reacquisition only from the proven edit result and exact new source/display range, with Fit reset and fail-closed dismissal;
  • native labeled AppKit controls and existing panel/monitor/observer teardown conventions.

No open P1/P2/P3 plan findings remain. The implementation still requires exact-diff review before remote build, tests, VM interaction, delivery, or acceptance claims.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Plan reviewed: issue #12 corrections 1–3 on base `9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405` State: **PRE-CODE PLAN PASS**; author may implement. No source diff, build, or GUI result has been reviewed. Correction to my immediately preceding comment: its phrase “classify only exact bare 640 as Large” was based on the earlier issue snapshot and is superseded by plan correction 2. The correct contract is: Large is a lexically recognized leading width numerically equal to 640 with **no height component**, regardless of whitespace or opaque tail (`640`, ` 640 `, `640|circle`, and ` 640 |circle`). `640xH` remains Custom. This makes the Large action stable when it preserves an unknown tail. Plan correction 3 fully resolves my numeric-bound P2: recognition is lexical and lossless; conversion is checked and nontrapping; zero/oversized values remain bounded Custom controls and fall back to Auto/Fit geometry; normalization/removal still works through the exact stale-target fence. Its `0`, `0x0`, huge W/H, and opaque-tail cases are sufficient for the pre-code contract. The approved implementation remains bounded to: - lossless leading W/WxH parse and Auto/Large rewrite without reconstructing destination, escapes, tail, surrounding text, or line endings; - synchronous `@MainActor` attachment/document/revision/display-range/source-range/raw-token CAS immediately followed by `BlockEditorView`'s canonical Undo transaction; - intrinsic Auto geometry, bounded Custom width geometry, and a fixed `min(640, positive realized line width) × 220` Large slot; - Fit/Fill only for loaded, aspect-distinct Large slots, stored on one attachment instance and never remapped by bytes/path/ordinal; - optional post-size-edit panel reacquisition only from the proven edit result and exact new source/display range, with Fit reset and fail-closed dismissal; - native labeled AppKit controls and existing panel/monitor/observer teardown conventions. No open P1/P2/P3 plan findings remain. The implementation still requires exact-diff review before remote build, tests, VM interaction, delivery, or acceptance claims.
Author
Owner

Implementation candidate is ready at exact bcc9d6af1d517a394376c41115df78209015d84f in the isolated image-controls worktree (base 9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405).

The candidate implements the reviewed contract:

  • Lossless first-pipe parsing of leading W / WxH, including safe zero and arbitrarily large numeric handling.
  • Auto removes only the leading numeric segment; Large writes width 640 while preserving opaque tails.
  • Large classification includes 640, 640|tail, and whitespace around the leading segment; 640xH stays Custom.
  • Auto and Custom retain aspect geometry; Large uses a bounded 640-by-220 slot. Fit/Fill is mounted-view state only and Fill is unavailable when no crop distinction exists.
  • A synchronous MainActor compare-and-swap revalidates document identity, source revision, selected display occurrence, source range, raw token, parsed token, and attachment identity before the canonical minimal source transaction.
  • Successful size edits reacquire only the exact resulting source/display range and a new attachment identity, with Fit reset. No byte/destination/ordinal search is used.
  • The UI is an AppKit nonactivating child panel with native NSPopUpButton and NSSegmentedControl, keyboard entry/escape handling, lifecycle cleanup, and double-click dismissal before Quick Look.
  • Tests cover classification and exact mutations, zero/huge values, geometry, Fit/Fill, mounted native controls, exact duplicate-token mutation, Undo, and stale-revision rejection.

Source review and remote build/runtime checks are pending. No local build or GUI validation was run from this worktree.

Implementation candidate is ready at exact `bcc9d6af1d517a394376c41115df78209015d84f` in the isolated `image-controls` worktree (base `9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405`). The candidate implements the reviewed contract: - Lossless first-pipe parsing of leading `W` / `WxH`, including safe zero and arbitrarily large numeric handling. - Auto removes only the leading numeric segment; Large writes width 640 while preserving opaque tails. - Large classification includes `640`, `640|tail`, and whitespace around the leading segment; `640xH` stays Custom. - Auto and Custom retain aspect geometry; Large uses a bounded 640-by-220 slot. Fit/Fill is mounted-view state only and Fill is unavailable when no crop distinction exists. - A synchronous MainActor compare-and-swap revalidates document identity, source revision, selected display occurrence, source range, raw token, parsed token, and attachment identity before the canonical minimal source transaction. - Successful size edits reacquire only the exact resulting source/display range and a new attachment identity, with Fit reset. No byte/destination/ordinal search is used. - The UI is an AppKit nonactivating child panel with native `NSPopUpButton` and `NSSegmentedControl`, keyboard entry/escape handling, lifecycle cleanup, and double-click dismissal before Quick Look. - Tests cover classification and exact mutations, zero/huge values, geometry, Fit/Fill, mounted native controls, exact duplicate-token mutation, Undo, and stale-revision rejection. Source review and remote build/runtime checks are pending. No local build or GUI validation was run from this worktree.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Candidate: bcc9d6af1d517a394376c41115df78209015d84f
Worktree/branch: .worktrees/image-controls / wave16/image-controls
State: SOURCE REVIEW REJECTED — 3 P2 findings. git diff --check passed. Per lane rules, no local build, test execution, or GUI run was performed.

No P1 finding. The lossless lexical W/WxH parser, bounded numeric conversion, Auto/Large normalization, synchronous stale-target CAS, identical-token occurrence targeting, canonical Undo transaction, and fixed Large geometry match the approved plan on source inspection.

P2 — Fit and measured-slot state leak between mounted views

Location: Sources/CalternalEditor/EditorImagePresentation.swift:126-183, :284-296, :379-418, and :431-462.

What breaks: Opening the same MarkdownBlockDocument in two mounted editors can make changing Fit/Fill in one editor change the other. Fill availability can also be computed from the wrong width after another layout manager—or estimatedDocumentHeight through the legacy attachment-bounds callback—last overwrites Geometry.slotSize.

Why likely: The projected NSTextStorage is shared by the document. currentTokens explicitly reuses an existing EditorImageAttachment from that shared storage, while the candidate stores one mutable fit and one mutable slotSize on that attachment. Both attachment-bounds callbacks overwrite the same slot with no mounted-layout identity. This reintroduces the cross-layout state race the module header says it avoids.

Scoped fix: Scope Fit and slot geometry to the current EditorImagePresentation/NSTextLayoutManager identity, while retaining exact attachment occurrence validation. Pass that mount identity through controlState and setFit, clear it from cancel, and calculate canFill from the exact mounted target frame/slot rather than a shared “last bounds callback” scalar. Add a two-editors/one-document test proving Fit independence, plus a test that height estimation or the other editor’s narrower layout cannot change the first editor’s control state.

P2 — entering the native toolbar dismisses it through responder teardown

Location: Sources/CalternalEditor/EditorImageControls.swift:433-450 and Sources/CalternalEditor/BlockEditorView.swift:704-709.

What breaks: Pressing Tab to reach Image Size/Image Fit can immediately close the toolbar. Mouse interaction with controls that makes the nonactivating panel key can follow the same path.

Why likely: The event monitor calls panel.makeKey() and moves first responder into a panel control. That makes BlockEditorView.resignFirstResponder() run, and it unconditionally calls dismissImageToolbar(), removing the child panel and its event monitor during the focus transfer. The tests inspect controls and invoke editor methods directly; none sends the actual Tab/click path.

Scoped fix: Keep the toolbar alive while first responder is moving into its owned child panel (for example, a controller-owned focus-transfer predicate checked by resignFirstResponder), or leave the editor first responder and proxy keyboard traversal without keying the panel. Continue dismissing for unrelated responder loss. Add mounted native event tests for Tab, Shift-Tab, operating both controls, Escape restoration, and click outside.

P2 — scroll anchoring does not reject an offscreen cached fragment

Location: Sources/CalternalEditor/BlockEditorView.swift:1107-1129 and :1221-1237.

What breaks: After the selected image scrolls out of view, its panel can remain visible and be clamped to a screen edge, detached from the image, instead of dismissing as the approved lifecycle requires.

Why likely: imageInteraction(forDisplayRange:) accepts any textLayoutFragment(for:) with a positive attachment frame. It never checks the viewport’s realized range or whether the attachment frame intersects visibleRect. TextKit may retain an already-created fragment after scrolling. The bounds-change observer then repositions the panel from that stale/offscreen frame, and screen clamping makes the jump visible.

Scoped fix: Before updating the target/anchor, require the exact attachment location to be in the mounted viewport and require its native frame to intersect the editor’s visible rect; otherwise dismiss. Add a mounted scroll test that shows the panel, scrolls the occurrence fully out, and proves teardown rather than edge clamping, plus a reflow case that stays visible and reanchors.

The candidate remains unapproved until these findings are fixed and the amended exact diff is reviewed. Build-host and VM validation remain later gates.

Reviewer: `/root/image_controls_review` (reviewer) Candidate: `bcc9d6af1d517a394376c41115df78209015d84f` Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` State: **SOURCE REVIEW REJECTED — 3 P2 findings.** `git diff --check` passed. Per lane rules, no local build, test execution, or GUI run was performed. No P1 finding. The lossless lexical W/WxH parser, bounded numeric conversion, Auto/Large normalization, synchronous stale-target CAS, identical-token occurrence targeting, canonical Undo transaction, and fixed Large geometry match the approved plan on source inspection. ### P2 — Fit and measured-slot state leak between mounted views **Location:** `Sources/CalternalEditor/EditorImagePresentation.swift:126-183`, `:284-296`, `:379-418`, and `:431-462`. **What breaks:** Opening the same `MarkdownBlockDocument` in two mounted editors can make changing Fit/Fill in one editor change the other. Fill availability can also be computed from the wrong width after another layout manager—or `estimatedDocumentHeight` through the legacy attachment-bounds callback—last overwrites `Geometry.slotSize`. **Why likely:** The projected `NSTextStorage` is shared by the document. `currentTokens` explicitly reuses an existing `EditorImageAttachment` from that shared storage, while the candidate stores one mutable `fit` and one mutable `slotSize` on that attachment. Both attachment-bounds callbacks overwrite the same slot with no mounted-layout identity. This reintroduces the cross-layout state race the module header says it avoids. **Scoped fix:** Scope Fit and slot geometry to the current `EditorImagePresentation`/`NSTextLayoutManager` identity, while retaining exact attachment occurrence validation. Pass that mount identity through `controlState` and `setFit`, clear it from `cancel`, and calculate `canFill` from the exact mounted target frame/slot rather than a shared “last bounds callback” scalar. Add a two-editors/one-document test proving Fit independence, plus a test that height estimation or the other editor’s narrower layout cannot change the first editor’s control state. ### P2 — entering the native toolbar dismisses it through responder teardown **Location:** `Sources/CalternalEditor/EditorImageControls.swift:433-450` and `Sources/CalternalEditor/BlockEditorView.swift:704-709`. **What breaks:** Pressing Tab to reach Image Size/Image Fit can immediately close the toolbar. Mouse interaction with controls that makes the nonactivating panel key can follow the same path. **Why likely:** The event monitor calls `panel.makeKey()` and moves first responder into a panel control. That makes `BlockEditorView.resignFirstResponder()` run, and it unconditionally calls `dismissImageToolbar()`, removing the child panel and its event monitor during the focus transfer. The tests inspect controls and invoke editor methods directly; none sends the actual Tab/click path. **Scoped fix:** Keep the toolbar alive while first responder is moving into its owned child panel (for example, a controller-owned focus-transfer predicate checked by `resignFirstResponder`), or leave the editor first responder and proxy keyboard traversal without keying the panel. Continue dismissing for unrelated responder loss. Add mounted native event tests for Tab, Shift-Tab, operating both controls, Escape restoration, and click outside. ### P2 — scroll anchoring does not reject an offscreen cached fragment **Location:** `Sources/CalternalEditor/BlockEditorView.swift:1107-1129` and `:1221-1237`. **What breaks:** After the selected image scrolls out of view, its panel can remain visible and be clamped to a screen edge, detached from the image, instead of dismissing as the approved lifecycle requires. **Why likely:** `imageInteraction(forDisplayRange:)` accepts any `textLayoutFragment(for:)` with a positive attachment frame. It never checks the viewport’s realized range or whether the attachment frame intersects `visibleRect`. TextKit may retain an already-created fragment after scrolling. The bounds-change observer then repositions the panel from that stale/offscreen frame, and screen clamping makes the jump visible. **Scoped fix:** Before updating the target/anchor, require the exact attachment location to be in the mounted viewport and require its native frame to intersect the editor’s visible rect; otherwise dismiss. Add a mounted scroll test that shows the panel, scrolls the occurrence fully out, and proves teardown rather than edge clamping, plus a reflow case that stays visible and reanchors. The candidate remains unapproved until these findings are fixed and the amended exact diff is reviewed. Build-host and VM validation remain later gates.
Author
Owner

Candidate follow-up is exact 360841daeca74b99dfb1dddc71b24743dd0e2b4a (cumulative from base 9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405). It addresses the first exact-diff review findings:

  • Fit is now keyed by the mounted NSTextLayoutManager, so two editors sharing one document attachment do not share view-only Fit state. Presenter cancel/switch clears only its own key.
  • Fill eligibility is computed from the exact current frameForTextAttachment size supplied by the active BlockEditorView; no attachment-bounds callback or height-estimation result is retained as the slot.
  • Each Large attachment drawing provider reads Fit through its own layout-manager key.
  • Tab and panel mouse events establish an owned focus transition before the child panel can take key/first-responder status. The editor suppresses its normal resign teardown and focus callback during that transition. Escape, panel resign, owner close/resign, and app resign still tear down cleanly.
  • Native frame lookup must return a nonzero exact attachment frame (AppKit's layout-available contract), and initial presentation/reanchoring also require intersection with the editor's current visibleRect; scrolling the image out dismisses the panel.
  • New mounted tests cover two simultaneous editors with independent Fit state, Tab entry, native segmented-control mouse dispatch, Escape focus restoration, and scroll-out dismissal.

The dedicated source re-review and remote build/runtime checks are pending. No local build or GUI validation was run.

Candidate follow-up is exact `360841daeca74b99dfb1dddc71b24743dd0e2b4a` (cumulative from base `9e3a64b6b2a23b1ac9e6c10ba13219bda3d32405`). It addresses the first exact-diff review findings: - Fit is now keyed by the mounted `NSTextLayoutManager`, so two editors sharing one document attachment do not share view-only Fit state. Presenter cancel/switch clears only its own key. - Fill eligibility is computed from the exact current `frameForTextAttachment` size supplied by the active `BlockEditorView`; no attachment-bounds callback or height-estimation result is retained as the slot. - Each Large attachment drawing provider reads Fit through its own layout-manager key. - Tab and panel mouse events establish an owned focus transition before the child panel can take key/first-responder status. The editor suppresses its normal resign teardown and focus callback during that transition. Escape, panel resign, owner close/resign, and app resign still tear down cleanly. - Native frame lookup must return a nonzero exact attachment frame (AppKit's layout-available contract), and initial presentation/reanchoring also require intersection with the editor's current `visibleRect`; scrolling the image out dismisses the panel. - New mounted tests cover two simultaneous editors with independent Fit state, Tab entry, native segmented-control mouse dispatch, Escape focus restoration, and scroll-out dismissal. The dedicated source re-review and remote build/runtime checks are pending. No local build or GUI validation was run.
Author
Owner

Exact review target correction: the frozen cumulative candidate is abb397be8b4ea118504ec10677b3a98a2b6b3903, superseding 360841da.

The final small delta restores the reviewer-requested viewport-membership check for reanchoring while keeping visibleRect intersection and AppKit's nonzero frameForTextAttachment layout-available fence. The mounted event test now also exercises the size popup through its native target/action, Shift-Tab entry at the final control, and outside-click teardown in addition to Tab, segmented-control mouse dispatch, and Escape restoration.

The worktree is clean and frozen for exact-tip source review. No local build or GUI verification was run.

Exact review target correction: the frozen cumulative candidate is `abb397be8b4ea118504ec10677b3a98a2b6b3903`, superseding `360841da`. The final small delta restores the reviewer-requested viewport-membership check for reanchoring while keeping `visibleRect` intersection and AppKit's nonzero `frameForTextAttachment` layout-available fence. The mounted event test now also exercises the size popup through its native target/action, Shift-Tab entry at the final control, and outside-click teardown in addition to Tab, segmented-control mouse dispatch, and Escape restoration. The worktree is clean and frozen for exact-tip source review. No local build or GUI verification was run.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Candidate: abb397be8b4ea118504ec10677b3a98a2b6b3903
Worktree/branch: .worktrees/image-controls / wave16/image-controls
State: SOURCE REVIEW PASS — no P1/P2/P3 findings. git diff --check passes. No local build, test execution, or GUI run was performed by this reviewer.

The cumulative diff from base 9e3a64b6 was reviewed against issue #12 corrections 1–3 and the three findings on bcc9d6af:

  • Mounted Fit isolation fixed. Fit is keyed by the mounted NSTextLayoutManager, drawing providers read only their manager's state, and presenter detach/switch clears only its own key. Fill eligibility is computed from the exact current frameForTextAttachment slot supplied by the active editor; attachment-bounds and height-estimation calls no longer overwrite shared slot state. The two-editor/one-document mounted regression covers independence across different widths.
  • Owned panel focus fixed. Tab or a panel mouse-down establishes the owned focus transition before the panel becomes key. BlockEditorView.resignFirstResponder retains the image panel only for that owned transition/key child, while unrelated responder loss still dismisses. Tests now exercise native popup target/action, Tab, Shift-Tab, panel mouse dispatch, Escape focus restoration, and outside-click teardown.
  • Offscreen anchoring fixed. Exact attachment lookup requires a nonzero native attachment frame. Re-anchoring additionally requires the attachment location in the mounted viewport and intersection with the current visibleRect; failure dismisses instead of clamping the panel to a screen edge. The mounted scroll-out regression covers teardown.

The source parser and mutation path remain correct: lexical ASCII W/WxH recognition is lossless and overflow-safe; zero/huge values stay bounded Custom/Auto geometry; Large is parsed width 640 without H regardless of whitespace/tail; Auto/Large preserve opaque bytes; the synchronous MainActor CAS checks document/revision/selection/ranges/raw token/parsed token/attachment identity before the minimal canonical Undo transaction; duplicate occurrences never remap by contents or destination.

The TextKit override boundary was also inspected. attachmentBounds and viewProvider are nonisolated as required by the imported AppKit signatures and access only lock-backed presentation values there. NSTextAttachmentViewProvider.loadView contains AppKit view construction inside MainActor.assumeIsolated; per-manager drawing state is then read by the main-actor drawing view. The required agents@mbp Swift 6.3 build remains necessary to establish SDK/compiler acceptance, followed by focused tests and VM/user UI checks.

This source pass does not close issue #12. Build, focused test execution, native runtime interaction, Release performance evidence where claimed, delivered preview, and user acceptance remain distinct gates.

Reviewer: `/root/image_controls_review` (reviewer) Candidate: `abb397be8b4ea118504ec10677b3a98a2b6b3903` Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` State: **SOURCE REVIEW PASS — no P1/P2/P3 findings.** `git diff --check` passes. No local build, test execution, or GUI run was performed by this reviewer. The cumulative diff from base `9e3a64b6` was reviewed against issue #12 corrections 1–3 and the three findings on `bcc9d6af`: - **Mounted Fit isolation fixed.** Fit is keyed by the mounted `NSTextLayoutManager`, drawing providers read only their manager's state, and presenter detach/switch clears only its own key. Fill eligibility is computed from the exact current `frameForTextAttachment` slot supplied by the active editor; attachment-bounds and height-estimation calls no longer overwrite shared slot state. The two-editor/one-document mounted regression covers independence across different widths. - **Owned panel focus fixed.** Tab or a panel mouse-down establishes the owned focus transition before the panel becomes key. `BlockEditorView.resignFirstResponder` retains the image panel only for that owned transition/key child, while unrelated responder loss still dismisses. Tests now exercise native popup target/action, Tab, Shift-Tab, panel mouse dispatch, Escape focus restoration, and outside-click teardown. - **Offscreen anchoring fixed.** Exact attachment lookup requires a nonzero native attachment frame. Re-anchoring additionally requires the attachment location in the mounted viewport and intersection with the current `visibleRect`; failure dismisses instead of clamping the panel to a screen edge. The mounted scroll-out regression covers teardown. The source parser and mutation path remain correct: lexical ASCII W/WxH recognition is lossless and overflow-safe; zero/huge values stay bounded Custom/Auto geometry; Large is parsed width 640 without H regardless of whitespace/tail; Auto/Large preserve opaque bytes; the synchronous MainActor CAS checks document/revision/selection/ranges/raw token/parsed token/attachment identity before the minimal canonical Undo transaction; duplicate occurrences never remap by contents or destination. The TextKit override boundary was also inspected. `attachmentBounds` and `viewProvider` are nonisolated as required by the imported AppKit signatures and access only lock-backed presentation values there. `NSTextAttachmentViewProvider.loadView` contains AppKit view construction inside `MainActor.assumeIsolated`; per-manager drawing state is then read by the main-actor drawing view. The required agents@mbp Swift 6.3 build remains necessary to establish SDK/compiler acceptance, followed by focused tests and VM/user UI checks. This source pass does not close issue #12. Build, focused test execution, native runtime interaction, Release performance evidence where claimed, delivered preview, and user acceptance remain distinct gates.
Author
Owner

Execution blocker: multiple implementation/reviewer agents stopped with Codex usage-limit errors. No further source or runtime acceptance is claimed. Desktop26eb1552 is installed and native launch/prior note verified. Central3e881860 contains next editor changes but is compile-blocked on nonisolated code painter helpers; isolated096a2725 repair is awaiting mandatory reviewer. Source-approved candidates pending combined integration: cross-event1fb74e92 (three-commit chain), imagecontrolsabb397be, chrome net27bd..a969f8ef. Event test cleanupd745 is integrated but shared XCTest async-teardown abort remains under investigation; title owner needs exact pre-feature-control PID52796 crash stack before choosing test-only fix. Layout centered760pt cap remains settled, exact alignment still pending. Preserve all active worktrees and uncommitted work; resume from these issues, do not restart or claim completion.

Execution blocker: multiple implementation/reviewer agents stopped with Codex usage-limit errors. No further source or runtime acceptance is claimed. Desktop26eb1552 is installed and native launch/prior note verified. Central3e881860 contains next editor changes but is compile-blocked on nonisolated code painter helpers; isolated096a2725 repair is awaiting mandatory reviewer. Source-approved candidates pending combined integration: cross-event1fb74e92 (three-commit chain), imagecontrolsabb397be, chrome net27bd..a969f8ef. Event test cleanupd745 is integrated but shared XCTest async-teardown abort remains under investigation; title owner needs exact pre-feature-control PID52796 crash stack before choosing test-only fix. Layout centered760pt cap remains settled, exact alignment still pending. Preserve all active worktrees and uncommitted work; resume from these issues, do not restart or claim completion.
Author
Owner

Work resumed at user request. Individual agent tasks must record their task name, worktree/branch, exact candidate revision, current status, next check and blockers in each relevant issue, with readback. Active dispatch: /root/block_drag_finish integrates source-approved #6 a969f8ef net, #12 abb397be, #15 1fb74e92 chain in an isolated checkout; /root/code_block_polish repairs #9 remaining actor-isolated scalar access, /root/ui_fixes_review_medium reviews; /root/title_completion and /root/event_date_completion investigate/correct awaited test fixture teardown in #5/#1. Central remains3e881860; desktop26eb1552 remains installed. No new build or acceptance yet. Prior usage blocker is historical: resumed agents are responding.

Work resumed at user request. Individual agent tasks must record their task name, worktree/branch, exact candidate revision, current status, next check and blockers in each relevant issue, with readback. Active dispatch: /root/block_drag_finish integrates source-approved #6 a969f8ef net, #12 abb397be, #15 1fb74e92 chain in an isolated checkout; /root/code_block_polish repairs #9 remaining actor-isolated scalar access, /root/ui_fixes_review_medium reviews; /root/title_completion and /root/event_date_completion investigate/correct awaited test fixture teardown in #5/#1. Central remains3e881860; desktop26eb1552 remains installed. No new build or acceptance yet. Prior usage blocker is historical: resumed agents are responding.
Author
Owner

Task identity: /root/block_drag_finish

Isolated integration candidate:

  • Worktree: /Users/kayg/Developer/calternal-app/.worktrees/editor-final-combined
  • Branch: wave16/editor-final-combined
  • Base: 3e8818608b7981a0670d229f322985f3474dbe58
  • Tip: 68885f1c4b8dceb4a59b35cc07b8516ffd0d4362

Integrated the complete reviewed change chain for this issue without editing central. Shared BlockEditorView conflicts were resolved by preserving both the image-toolbar anchor update and the existing coalesced block-handle hover reconciliation during scroll/layout. Stable patch parity is exact for all commits except the first image-controls commit, whose deliberate two-call conflict resolution accounts for the patch-ID difference.

Source checks completed: clean worktree, no conflict markers, git diff --check clean. No local build or GUI run. Exact merged interaction review is now requested. Current central/base still has the separately owned known Swift 6 code-painter isolation compiler blocker; this candidate does not claim to repair or compile past it.

Task identity: `/root/block_drag_finish` Isolated integration candidate: - Worktree: `/Users/kayg/Developer/calternal-app/.worktrees/editor-final-combined` - Branch: `wave16/editor-final-combined` - Base: `3e8818608b7981a0670d229f322985f3474dbe58` - Tip: `68885f1c4b8dceb4a59b35cc07b8516ffd0d4362` Integrated the complete reviewed change chain for this issue without editing central. Shared `BlockEditorView` conflicts were resolved by preserving both the image-toolbar anchor update and the existing coalesced block-handle hover reconciliation during scroll/layout. Stable patch parity is exact for all commits except the first image-controls commit, whose deliberate two-call conflict resolution accounts for the patch-ID difference. Source checks completed: clean worktree, no conflict markers, `git diff --check` clean. No local build or GUI run. Exact merged interaction review is now requested. Current central/base still has the separately owned known Swift 6 code-painter isolation compiler blocker; this candidate does not claim to repair or compile past it.
Author
Owner

Merged interaction source review — exact isolated tip 68885f1c4b8dceb4a59b35cc07b8516ffd0d4362 against base 3e8818608b7981a0670d229f322985f3474dbe58: PASS (no P1–P3 findings).

The #12 image-control chain is preserved, with its foundation already ancestral. Exact attachment targeting uses realized TextKit attachment frames; the toolbar stores document/revision/range/source/attachment identity and fails closed after external edits or projection replacement. Size changes use one canonical Markdown edit and rebind to the replacement attachment; Fit/Fill remains per mounted layout manager and does not alter source bytes. Detach, selection changes, scrolling out of view, app/window resign, Escape, outside click, and Quick Look transition dismiss ownership appropriately, while focus transfer into native panel controls is retained.

At the only shared layout/scroll conflict, both updateImageToolbarAnchor() and scheduleHoverReconciliation() are retained. Their state is independent and both are guarded by current window/viewport/target ownership. Existing formatting, hover, block drag, clipboard, and multi-selection behavior is preserved in the merged source.

This is source-only; native control rendering and interaction remain runtime QA.

Merged interaction source review — exact isolated tip `68885f1c4b8dceb4a59b35cc07b8516ffd0d4362` against base `3e8818608b7981a0670d229f322985f3474dbe58`: **PASS (no P1–P3 findings)**. The #12 image-control chain is preserved, with its foundation already ancestral. Exact attachment targeting uses realized TextKit attachment frames; the toolbar stores document/revision/range/source/attachment identity and fails closed after external edits or projection replacement. Size changes use one canonical Markdown edit and rebind to the replacement attachment; Fit/Fill remains per mounted layout manager and does not alter source bytes. Detach, selection changes, scrolling out of view, app/window resign, Escape, outside click, and Quick Look transition dismiss ownership appropriately, while focus transfer into native panel controls is retained. At the only shared layout/scroll conflict, both `updateImageToolbarAnchor()` and `scheduleHoverReconciliation()` are retained. Their state is independent and both are guarded by current window/viewport/target ownership. Existing formatting, hover, block drag, clipboard, and multi-selection behavior is preserved in the merged source. This is source-only; native control rendering and interaction remain runtime QA.
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

Root integrated exact source-reviewed test lifecycle fixes: title3817c269c524898647b8265ac8755a2c22d4b359 as82ff556e and eventabcd17f50f7cb7c0d4f5ac72bb215a0bd36b8c1f as3171535b. Root independently matched event binary diff SHA0c241a51. Exact3171535be7f04e038f80799074104de68c4f5015 archive and265-input manifest are now building through the existing agents@mbp sole controller. Includes source-reviewed #6/#12/#15 combined changes. /root/image_preview_qa handles preceding704b focused runtime; root handles compiler while build subagent is usage-blocked. No new desktop delivery; no new test result yet.

Root integrated exact source-reviewed test lifecycle fixes: title3817c269c524898647b8265ac8755a2c22d4b359 as82ff556e and eventabcd17f50f7cb7c0d4f5ac72bb215a0bd36b8c1f as3171535b. Root independently matched event binary diff SHA0c241a51. Exact3171535be7f04e038f80799074104de68c4f5015 archive and265-input manifest are now building through the existing agents@mbp sole controller. Includes source-reviewed #6/#12/#15 combined changes. /root/image_preview_qa handles preceding704b focused runtime; root handles compiler while build subagent is usage-blocked. No new desktop delivery; no new test result yet.
Author
Owner

Root exact3171535b compile failed before tests (0 executed): image toolbar optional controller access; untyped Fit/Fill ternary; NSTexLayoutManager captured by Sendable lock closure. Exact local evidence .agents/wave16/central-3171535b-root/swift-build.log, SHA d915d3d98311237d786f10fe1fa305cf24c10fcf4a3167078931686a5c4fa0be. /root/image_preview_native_repair owns bounded #12 compiler repair and must obtain reviewer before integration. Earlier704b painter-only compile passed; do not conflate revisions. Title/event test-cleanup fixes are integrated but not yet rerun.

Root exact3171535b compile failed before tests (0 executed): image toolbar optional controller access; untyped Fit/Fill ternary; NSTexLayoutManager captured by Sendable lock closure. Exact local evidence .agents/wave16/central-3171535b-root/swift-build.log, SHA d915d3d98311237d786f10fe1fa305cf24c10fcf4a3167078931686a5c4fa0be. /root/image_preview_native_repair owns bounded #12 compiler repair and must obtain reviewer before integration. Earlier704b painter-only compile passed; do not conflate revisions. Title/event test-cleanup fixes are integrated but not yet rerun.
Author
Owner

/root/image_preview_native_repair is handling the exact 3171535b compile failure in the isolated wave16/image-controls worktree at abb397be.

Evidence: /Users/kayg/Developer/calternal-app/.agents/wave16/central-3171535b-root/swift-build.log, SHA-256 d915d3d98311237d786f10fe1fa305cf24c10fcf4a3167078931686a5c4fa0be. The three errors are confined to the new controls implementation: an optional toolbar controller used after a guard that did not bind it, an enum ternary without sufficient contextual type inside withLock, and a @Sendable lock closure capturing non-Sendable NSTextLayoutManager instead of its precomputed ObjectIdentifier.

The bounded candidate will add a valid optional binding, give the fit value its explicit type, and compute the layout-manager key before entering the lock. It will also clear the new same-file warnings by returning the view provider explicitly, consuming the lock removal result, and avoiding creation of the MainActor attachment cell in the nonisolated decoding initializer; normal construction and later MainActor reference updates install the cell. Existing Quick Look and layout-fragment isolation warnings predate #12 and are not broadened here. No behavior, syntax persistence, or source mutation contract changes.

`/root/image_preview_native_repair` is handling the exact `3171535b` compile failure in the isolated `wave16/image-controls` worktree at `abb397be`. Evidence: `/Users/kayg/Developer/calternal-app/.agents/wave16/central-3171535b-root/swift-build.log`, SHA-256 `d915d3d98311237d786f10fe1fa305cf24c10fcf4a3167078931686a5c4fa0be`. The three errors are confined to the new controls implementation: an optional toolbar controller used after a guard that did not bind it, an enum ternary without sufficient contextual type inside `withLock`, and a `@Sendable` lock closure capturing non-Sendable `NSTextLayoutManager` instead of its precomputed `ObjectIdentifier`. The bounded candidate will add a valid optional binding, give the fit value its explicit type, and compute the layout-manager key before entering the lock. It will also clear the new same-file warnings by returning the view provider explicitly, consuming the lock removal result, and avoiding creation of the MainActor attachment cell in the nonisolated decoding initializer; normal construction and later MainActor reference updates install the cell. Existing Quick Look and layout-fragment isolation warnings predate #12 and are not broadened here. No behavior, syntax persistence, or source mutation contract changes.
Author
Owner

Compile-repair candidate: exact 73964bc67ba3b8eb52f37ba6434cd1116aa38387 on top of reviewed abb397be8b4ea118504ec10677b3a98a2b6b3903.

Changes are limited to BlockEditorView.swift and EditorImagePresentation.swift: bind the optional toolbar controller before update; explicitly type EditorImageFitMode in the locked mutation; precompute ObjectIdentifier(NSTextLayoutManager) outside the @Sendable closure; explicitly return the attachment view provider; consume the lock removal result; and defer custom attachment-cell installation from nonisolated decoding until the first MainActor updateReference (normal construction still installs it immediately).

Evidence: clean worktree after commit and git diff --check PASS. No local build or GUI was run. Exact-tip source review and the sole remote Swift 6 build remain required before integration; the VM behavior is unverified.

Compile-repair candidate: exact `73964bc67ba3b8eb52f37ba6434cd1116aa38387` on top of reviewed `abb397be8b4ea118504ec10677b3a98a2b6b3903`. Changes are limited to `BlockEditorView.swift` and `EditorImagePresentation.swift`: bind the optional toolbar controller before update; explicitly type `EditorImageFitMode` in the locked mutation; precompute `ObjectIdentifier(NSTextLayoutManager)` outside the `@Sendable` closure; explicitly return the attachment view provider; consume the lock removal result; and defer custom attachment-cell installation from nonisolated decoding until the first MainActor `updateReference` (normal construction still installs it immediately). Evidence: clean worktree after commit and `git diff --check` PASS. No local build or GUI was run. Exact-tip source review and the sole remote Swift 6 build remain required before integration; the VM behavior is unverified.
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

Reviewer: /root/image_controls_review (reviewer)
Candidate: 73964bc67ba3b8eb52f37ba6434cd1116aa38387 atop source-approved abb397be8b4ea118504ec10677b3a98a2b6b3903
Worktree/branch: .worktrees/image-controls / wave16/image-controls
State: COMPILER-REPAIR SOURCE REVIEW PASS — no P1/P2/P3 findings. git diff --check abb397be..73964bc passes. Exact-tip Swift 6.3 compiler rerun is still required; this review does not claim a successful build.

Evidence inspected: .agents/wave16/central-3171535b-root/swift-build.log. The recorded 3171535b Release test-build failed on four candidate errors: optional imageToolbarController.update, ambiguous .fill inference, unused view-provider initializer result, and capture of non-Sendable NSTextLayoutManager in the lock closure. It also reported the actor-isolated attachment-cell initialization and unused lock-result warnings addressed in the same delta. The Quick Look/list/code warnings shown in that log predate and are outside this issue's repair.

The exact delta is behavior-preserving:

  • Strong local toolbar bindings replace invalid optional member access in reanchor and Fit update paths; failure still uses the existing fail-closed dismissal guard.
  • let next: EditorImageFitMode resolves ternary inference without changing Fit/Fill eligibility.
  • return EditorImageAttachmentViewProvider(...) supplies the intended override result.
  • clearPresentation computes ObjectIdentifier(layoutManager) before entering the lock closure, so the closure captures a Sendable value rather than retaining/capturing the non-Sendable layout manager. Key identity and per-mount cleanup semantics are unchanged.
  • Attachment-cell installation moved out of nonisolated init(coder:). Normal construction installs the cell immediately. A decoded private attachment receives it on the first main-actor updateReference, and every attachment enumerated by EditorImagePresentation.currentTokens goes through that call before presenter installation or image loading. The helper is idempotent, assigns the attachment back-reference before publication, and does not reset image, geometry, mounted Fit state, or lifecycle ownership.
  • Explicitly discarding the lock removal result only silences the unused-result diagnostic; it does not change cleanup.

No tests changed in this compiler-only commit, and the previously approved mounted/source coverage remains intact. Root should now run the same Release swift build --build-tests command against exact 73964bc; only fresh exit-zero output can establish compiler acceptance. Issue #12 remains open through focused test execution, VM interaction, delivery, and user acceptance.

Reviewer: `/root/image_controls_review` (reviewer) Candidate: `73964bc67ba3b8eb52f37ba6434cd1116aa38387` atop source-approved `abb397be8b4ea118504ec10677b3a98a2b6b3903` Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` State: **COMPILER-REPAIR SOURCE REVIEW PASS — no P1/P2/P3 findings.** `git diff --check abb397be..73964bc` passes. Exact-tip Swift 6.3 compiler rerun is still required; this review does not claim a successful build. Evidence inspected: `.agents/wave16/central-3171535b-root/swift-build.log`. The recorded `3171535b` Release test-build failed on four candidate errors: optional `imageToolbarController.update`, ambiguous `.fill` inference, unused view-provider initializer result, and capture of non-Sendable `NSTextLayoutManager` in the lock closure. It also reported the actor-isolated attachment-cell initialization and unused lock-result warnings addressed in the same delta. The Quick Look/list/code warnings shown in that log predate and are outside this issue's repair. The exact delta is behavior-preserving: - Strong local `toolbar` bindings replace invalid optional member access in reanchor and Fit update paths; failure still uses the existing fail-closed dismissal guard. - `let next: EditorImageFitMode` resolves ternary inference without changing Fit/Fill eligibility. - `return EditorImageAttachmentViewProvider(...)` supplies the intended override result. - `clearPresentation` computes `ObjectIdentifier(layoutManager)` before entering the lock closure, so the closure captures a Sendable value rather than retaining/capturing the non-Sendable layout manager. Key identity and per-mount cleanup semantics are unchanged. - Attachment-cell installation moved out of nonisolated `init(coder:)`. Normal construction installs the cell immediately. A decoded private attachment receives it on the first main-actor `updateReference`, and every attachment enumerated by `EditorImagePresentation.currentTokens` goes through that call before presenter installation or image loading. The helper is idempotent, assigns the attachment back-reference before publication, and does not reset image, geometry, mounted Fit state, or lifecycle ownership. - Explicitly discarding the lock removal result only silences the unused-result diagnostic; it does not change cleanup. No tests changed in this compiler-only commit, and the previously approved mounted/source coverage remains intact. Root should now run the same Release `swift build --build-tests` command against exact `73964bc`; only fresh exit-zero output can establish compiler acceptance. Issue #12 remains open through focused test execution, VM interaction, delivery, and user acceptance.
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

/root/image_preview_native_repair is diagnosing the next exact combined compile failure after the three prior errors were fixed. Evidence: exact 80efddbc, log /Users/kayg/Developer/calternal-app/.agents/wave16/central-80efddbc-root/swift-build.log, SHA-256 07a8c920bc0deeb45d4c71c6f8318b057ee97e09c8597f6ff44dd06ad37f260d.

The sole new error is EditorImagePresentation.swift:653: NSTextAttachmentViewProvider.loadView() is an SDK-nonisolated override, and MainActor.assumeIsolated cannot safely capture and retain the task-isolated provider self. No unchecked conformance, unsafe wrapper, or diagnostic suppression will be added.

Plan awaiting focused source review before code: use the already installed native NSTextAttachmentCell drawing path (the #11 TextKit 2 baseline renders through attachment cells with attachment views disabled), keep allowsTextAttachmentView = false, and select per-mounted Fit/Fill state from (controlView as? NSTextView)?.textLayoutManager during cell drawing. Attachment bounds, the fixed Large slot, aspect-preserving content rectangle, clipping, source image, exact attachment identity, and Quick Look URL targeting remain unchanged. Root is coordinating image_controls_review on this architecture correction before the worktree moves.

`/root/image_preview_native_repair` is diagnosing the next exact combined compile failure after the three prior errors were fixed. Evidence: exact `80efddbc`, log `/Users/kayg/Developer/calternal-app/.agents/wave16/central-80efddbc-root/swift-build.log`, SHA-256 `07a8c920bc0deeb45d4c71c6f8318b057ee97e09c8597f6ff44dd06ad37f260d`. The sole new error is `EditorImagePresentation.swift:653`: `NSTextAttachmentViewProvider.loadView()` is an SDK-nonisolated override, and `MainActor.assumeIsolated` cannot safely capture and retain the task-isolated provider `self`. No unchecked conformance, unsafe wrapper, or diagnostic suppression will be added. Plan awaiting focused source review before code: use the already installed native `NSTextAttachmentCell` drawing path (the #11 TextKit 2 baseline renders through attachment cells with attachment views disabled), keep `allowsTextAttachmentView = false`, and select per-mounted Fit/Fill state from `(controlView as? NSTextView)?.textLayoutManager` during cell drawing. Attachment bounds, the fixed Large slot, aspect-preserving content rectangle, clipping, source image, exact attachment identity, and Quick Look URL targeting remain unchanged. Root is coordinating `image_controls_review` on this architecture correction before the worktree moves.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Reviewed source tip: 73964bc67ba3b8eb52f37ba6434cd1116aa38387; failed combined build revision: 80efddbc
State: NATIVE ATTACHMENT-CELL REPAIR PLAN PASS, WITH BOUNDED CANDIDATE PROOF REQUIRED. No source implementation, local build, or GUI run was performed in this review lane.

Root-cause evidence is exact: .agents/wave16/central-80efddbc-root/swift-build.log (recorded SHA-256 07a8c920bc0deeb45d4c71c6f8318b057ee97e09c8597f6ff44dd06ad37f260d) fails at EditorImagePresentation.swift:653 because SDK-nonisolated NSTextAttachmentViewProvider.loadView() captures task-isolated provider self in MainActor.assumeIsolated. The proposed repair removes that unsafe boundary instead of suppressing it.

The native cell route is supported by the installed SDK contract:

  • AppKit.framework/Headers/NSTextAttachmentCell.h:20 marks drawWithFrame:inView: NS_SWIFT_UI_ACTOR, so the custom cell can access AppKit image/drawing state without MainActor.assumeIsolated or an unchecked Sendable wrapper.
  • AppKit.framework/Headers/NSTextAttachment.h:77-93 defines the macOS attachment cell as the attachment drawing/interaction object and states that allowsTextAttachmentView controls whether AppKit attempts the view-provider path. Keeping it false disables the failing provider architecture.
  • The cell receives AppKit's exact cellFrame; the existing attachmentBounds overrides continue to negotiate the bounded min(640, positive realized line width) × 220 Large slot. The existing contentRect plus clip-to-frame drawing preserves source aspect ratio and makes Fill crop within that same slot.

The accepted bounded implementation is: remove EditorImageAttachmentViewProvider, EditorImageDrawingView, the viewProvider override, weak drawing-view registry, and related invalidation; set allowsTextAttachmentView = false in normal construction, decoding, and every updateReference; keep the custom NSTextAttachmentCell; in its main-actor draw override select the per-presenter state using (controlView as? NSTextView)?.textLayoutManager, with a nil/non-text-view fallback to .fit; draw and clip into the exact supplied cellFrame; and let the initiating BlockEditorView set needsDisplay after a Fit change. Do not introduce MainActor.assumeIsolated, unchecked isolation, or a provider wrapper.

Selection and Quick Look remain source/frame/identity based in BlockEditorView and EditorImageQuickLookController; removing the decorative attachment subview does not change their exact occurrence, native attachment-frame, URL, or teardown paths.

Candidate acceptance must add or extend one mounted regression to establish the only SDK behavior not proven by headers alone: under the app's TextKit 2 editor, the attachment-cell callback receives the owning NSTextView, resolves that editor's NSTextLayoutManager, and changing one mounted editor to Fill produces pixel-distinct cropped output in the same fixed slot while the second editor remains Fit. A direct cell.draw(...) unit call is insufficient; the test must exercise mounted TextKit drawing. The existing tests prove geometry math and per-manager control state but do not prove this rendering dispatch.

No P1/P2/P3 plan blocker remains under that proof requirement. Next action: author implements the bounded cell-only delta and freezes an exact candidate for source review; root then runs the same agents@mbp Swift 6.3 Release compile before focused runtime/VM checks.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Reviewed source tip: `73964bc67ba3b8eb52f37ba6434cd1116aa38387`; failed combined build revision: `80efddbc` State: **NATIVE ATTACHMENT-CELL REPAIR PLAN PASS, WITH BOUNDED CANDIDATE PROOF REQUIRED.** No source implementation, local build, or GUI run was performed in this review lane. Root-cause evidence is exact: `.agents/wave16/central-80efddbc-root/swift-build.log` (recorded SHA-256 `07a8c920bc0deeb45d4c71c6f8318b057ee97e09c8597f6ff44dd06ad37f260d`) fails at `EditorImagePresentation.swift:653` because SDK-nonisolated `NSTextAttachmentViewProvider.loadView()` captures task-isolated provider `self` in `MainActor.assumeIsolated`. The proposed repair removes that unsafe boundary instead of suppressing it. The native cell route is supported by the installed SDK contract: - `AppKit.framework/Headers/NSTextAttachmentCell.h:20` marks `drawWithFrame:inView:` `NS_SWIFT_UI_ACTOR`, so the custom cell can access AppKit image/drawing state without `MainActor.assumeIsolated` or an unchecked Sendable wrapper. - `AppKit.framework/Headers/NSTextAttachment.h:77-93` defines the macOS attachment cell as the attachment drawing/interaction object and states that `allowsTextAttachmentView` controls whether AppKit attempts the view-provider path. Keeping it `false` disables the failing provider architecture. - The cell receives AppKit's exact `cellFrame`; the existing `attachmentBounds` overrides continue to negotiate the bounded `min(640, positive realized line width) × 220` Large slot. The existing `contentRect` plus clip-to-frame drawing preserves source aspect ratio and makes Fill crop within that same slot. The accepted bounded implementation is: remove `EditorImageAttachmentViewProvider`, `EditorImageDrawingView`, the `viewProvider` override, weak drawing-view registry, and related invalidation; set `allowsTextAttachmentView = false` in normal construction, decoding, and every `updateReference`; keep the custom `NSTextAttachmentCell`; in its main-actor draw override select the per-presenter state using `(controlView as? NSTextView)?.textLayoutManager`, with a nil/non-text-view fallback to `.fit`; draw and clip into the exact supplied `cellFrame`; and let the initiating `BlockEditorView` set `needsDisplay` after a Fit change. Do not introduce `MainActor.assumeIsolated`, unchecked isolation, or a provider wrapper. Selection and Quick Look remain source/frame/identity based in `BlockEditorView` and `EditorImageQuickLookController`; removing the decorative attachment subview does not change their exact occurrence, native attachment-frame, URL, or teardown paths. Candidate acceptance must add or extend one mounted regression to establish the only SDK behavior not proven by headers alone: under the app's TextKit 2 editor, the attachment-cell callback receives the owning `NSTextView`, resolves that editor's `NSTextLayoutManager`, and changing one mounted editor to Fill produces pixel-distinct cropped output in the same fixed slot while the second editor remains Fit. A direct `cell.draw(...)` unit call is insufficient; the test must exercise mounted TextKit drawing. The existing tests prove geometry math and per-manager control state but do not prove this rendering dispatch. No P1/P2/P3 plan blocker remains under that proof requirement. Next action: author implements the bounded cell-only delta and freezes an exact candidate for source review; root then runs the same agents@mbp Swift 6.3 Release compile before focused runtime/VM checks.
Author
Owner

Provider-isolation repair candidate: exact 455b06b2765b004ca3d56eb3307794592172eedb on top of 73964bc67ba3b8eb52f37ba6434cd1116aa38387.

Following the focused plan PASS, this removes the custom NSTextAttachmentViewProvider.loadView() override and its unsafe MainActor.assumeIsolated capture. EditorImageAttachment now always disables attachment-view lookup and draws through its native NSTextAttachmentCell. The cell uses (controlView as? NSTextView)?.textLayoutManager to resolve Fit/Fill for that exact mounted presenter; nil/non-text controls fall back to Fit. The existing fixed attachment bounds, aspect-preserving content rectangle, and exact cellFrame clip are unchanged. BlockEditorView.setSelectedImageFit continues to invalidate the owning editor display.

The existing two-editor mounted regression now records real cell callbacks and requires each callback to carry the expected editor and TextKit 2 layout-manager identity. It also caches the rendered attachment pixels before and after Fit→Fill, verifies edge pixels differ, and asserts the native attachment frame is byte-for-byte equal across modes; the second editor remains Fit.

Evidence: worktree clean and git diff --check PASS. No local build or GUI. Exact-tip source review and remote Swift 6 compile/runtime remain required; VM behavior remains unverified.

Provider-isolation repair candidate: exact `455b06b2765b004ca3d56eb3307794592172eedb` on top of `73964bc67ba3b8eb52f37ba6434cd1116aa38387`. Following the focused plan PASS, this removes the custom `NSTextAttachmentViewProvider.loadView()` override and its unsafe `MainActor.assumeIsolated` capture. `EditorImageAttachment` now always disables attachment-view lookup and draws through its native `NSTextAttachmentCell`. The cell uses `(controlView as? NSTextView)?.textLayoutManager` to resolve Fit/Fill for that exact mounted presenter; nil/non-text controls fall back to Fit. The existing fixed attachment bounds, aspect-preserving content rectangle, and exact `cellFrame` clip are unchanged. `BlockEditorView.setSelectedImageFit` continues to invalidate the owning editor display. The existing two-editor mounted regression now records real cell callbacks and requires each callback to carry the expected editor and TextKit 2 layout-manager identity. It also caches the rendered attachment pixels before and after Fit→Fill, verifies edge pixels differ, and asserts the native attachment frame is byte-for-byte equal across modes; the second editor remains Fit. Evidence: worktree clean and `git diff --check` PASS. No local build or GUI. Exact-tip source review and remote Swift 6 compile/runtime remain required; VM behavior remains unverified.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Candidate: exact 455b06b2765b004ca3d56eb3307794592172eedb atop 73964bc67ba3b8eb52f37ba6434cd1116aa38387
State: NATIVE-CELL SOURCE REVIEW PASS — no P1/P2/P3 findings. git diff --check 73964bc..455b06b2 passes and the worktree is clean. Per lane ownership, this reviewer ran no build, tests, or GUI.

The exact two-file delta matches the approved architecture correction:

  • EditorImagePresentation.swift removes the NSTextAttachmentViewProvider, its drawing view, registrations, and every MainActor.assumeIsolated use from this image path. Normal construction, decoding, and updateReference keep allowsTextAttachmentView = false, so Large cannot re-enter the failed provider path.
  • The existing @MainActor native NSTextAttachmentCell.draw(withFrame:in:) obtains the mounted presenter key from (controlView as? NSTextView)?.textLayoutManager, reads only that manager's Fit state, and falls back to Fit when AppKit supplies no text view/layout manager. It computes the aspect-preserving target from the exact supplied cellFrame, clips to that same frame, and draws the loaded attachment image. The existing attachmentBounds callbacks still determine the bounded Auto/Custom/Large layout slot.
  • Fit invalidation remains owned by BlockEditorView.setSelectedImageFit, which sets that initiating editor's needsDisplay; image-load and geometry invalidation remain covered by the presenter's onGeometryChange -> invalidateTextLayout callback. Per-manager cleanup and source-independent Fit state are unchanged.
  • Exact occurrence selection, toolbar CAS, Quick Look URL targeting, and panel lifecycle live outside the removed decorative view and retain the same attachment identity/native frame contracts.

The mounted regression is materially stronger than the previous state-only check. It draws the shared attachment through two real BlockEditorView/TextKit 2 mounts, observes that AppKit passed each exact NSTextView and its own NSTextLayoutManager to the cell, requires both Fit and Fill callbacks for editor A and Fit for editor B, asserts the native attachment frame is unchanged across Fit/Fill, and compares cached rendered edge pixels so a no-op/same-render Fit implementation fails. The wide solid fixture makes Fit expose the editor background at a vertical edge while Fill occupies and horizontally crops the fixed slot; a missing attachment render also fails the pixel-difference assertion. The second mount still proves that A's Fill state does not leak into B.

No implementation finding remains at this exact revision. Root should run the same agents@mbp Swift 6.3 Release compiler command that exposed the 80efddbc provider failure, then execute the focused mounted test and VM interaction gates. Issue #12 remains open through those results, desktop delivery, and user acceptance.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Candidate: exact `455b06b2765b004ca3d56eb3307794592172eedb` atop `73964bc67ba3b8eb52f37ba6434cd1116aa38387` State: **NATIVE-CELL SOURCE REVIEW PASS — no P1/P2/P3 findings.** `git diff --check 73964bc..455b06b2` passes and the worktree is clean. Per lane ownership, this reviewer ran no build, tests, or GUI. The exact two-file delta matches the approved architecture correction: - `EditorImagePresentation.swift` removes the `NSTextAttachmentViewProvider`, its drawing view, registrations, and every `MainActor.assumeIsolated` use from this image path. Normal construction, decoding, and `updateReference` keep `allowsTextAttachmentView = false`, so Large cannot re-enter the failed provider path. - The existing `@MainActor` native `NSTextAttachmentCell.draw(withFrame:in:)` obtains the mounted presenter key from `(controlView as? NSTextView)?.textLayoutManager`, reads only that manager's Fit state, and falls back to Fit when AppKit supplies no text view/layout manager. It computes the aspect-preserving target from the exact supplied `cellFrame`, clips to that same frame, and draws the loaded attachment image. The existing `attachmentBounds` callbacks still determine the bounded Auto/Custom/Large layout slot. - Fit invalidation remains owned by `BlockEditorView.setSelectedImageFit`, which sets that initiating editor's `needsDisplay`; image-load and geometry invalidation remain covered by the presenter's `onGeometryChange -> invalidateTextLayout` callback. Per-manager cleanup and source-independent Fit state are unchanged. - Exact occurrence selection, toolbar CAS, Quick Look URL targeting, and panel lifecycle live outside the removed decorative view and retain the same attachment identity/native frame contracts. The mounted regression is materially stronger than the previous state-only check. It draws the shared attachment through two real `BlockEditorView`/TextKit 2 mounts, observes that AppKit passed each exact `NSTextView` and its own `NSTextLayoutManager` to the cell, requires both Fit and Fill callbacks for editor A and Fit for editor B, asserts the native attachment frame is unchanged across Fit/Fill, and compares cached rendered edge pixels so a no-op/same-render Fit implementation fails. The wide solid fixture makes Fit expose the editor background at a vertical edge while Fill occupies and horizontally crops the fixed slot; a missing attachment render also fails the pixel-difference assertion. The second mount still proves that A's Fill state does not leak into B. No implementation finding remains at this exact revision. Root should run the same agents@mbp Swift 6.3 Release compiler command that exposed the `80efddbc` provider failure, then execute the focused mounted test and VM interaction gates. Issue #12 remains open through those results, desktop delivery, and user acceptance.
Author
Owner

Task identity: /root/block_drag_finish

Active integration repair:

  • Worktree: /Users/kayg/Developer/calternal-app/.worktrees/editor-overnight-combined
  • Branch: wave14/editor-overnight-combined
  • Current parent: c5c2e1904209ba9d575b4000d8b56ae9cf3716d9 (reviewed #12 image controls)
  • Cherry-pick: b0770f0ee7eabb35ccb95b96c39d06be735d96a4 (reviewed #11 complete double-click dispatch)
  • Status: one active conflict, only Sources/CalternalEditor/BlockEditorView.swift, at the shared image mouse-down route.

Resolution contract: preserve #11's pending-click identity/revision/range/URL/time/distance validation and dispatcher observations for both AppKit clickCount>=2 and paired clickCount==1 delivery; retain #12's exact imageInteraction target used by first-click native controls; dismiss the #12 toolbar before Quick Look dispatch; preserve both detach/projection lifecycle cleanup paths. The other two #11 files applied without conflict and will not be modified.

No build/GUI. I will stage and continue only after source/type/callsite and conflict-marker checks, then request exact integration review against c5c2e190.

Task identity: `/root/block_drag_finish` Active integration repair: - Worktree: `/Users/kayg/Developer/calternal-app/.worktrees/editor-overnight-combined` - Branch: `wave14/editor-overnight-combined` - Current parent: `c5c2e1904209ba9d575b4000d8b56ae9cf3716d9` (reviewed #12 image controls) - Cherry-pick: `b0770f0ee7eabb35ccb95b96c39d06be735d96a4` (reviewed #11 complete double-click dispatch) - Status: one active conflict, only `Sources/CalternalEditor/BlockEditorView.swift`, at the shared image mouse-down route. Resolution contract: preserve #11's pending-click identity/revision/range/URL/time/distance validation and dispatcher observations for both AppKit clickCount>=2 and paired clickCount==1 delivery; retain #12's exact `imageInteraction` target used by first-click native controls; dismiss the #12 toolbar before Quick Look dispatch; preserve both detach/projection lifecycle cleanup paths. The other two #11 files applied without conflict and will not be modified. No build/GUI. I will stage and continue only after source/type/callsite and conflict-marker checks, then request exact integration review against c5c2e190.
Author
Owner

Task identity: /root/block_drag_finish

Resolved integration candidate:

  • Worktree/branch: .worktrees/editor-overnight-combined / wave14/editor-overnight-combined
  • Parent: c5c2e1904209ba9d575b4000d8b56ae9cf3716d9
  • Exact tip: 35e20ac2740033016ec44eae19c979e50aab69bc
  • Integrated original: reviewed b0770f0ee7eabb35ccb95b96c39d06be735d96a4

The shared mouse-down conflict retains #11's complete gesture dispatcher and #12's richer image interaction/control target. Single unmodified clicks arm validated paired-click recognition and activate native image controls. AppKit clickCount>=2 or a valid paired click dispatches Quick Look. Dispatch dismisses the image toolbar before selection and again after selection notifications can reopen it, then prepares/presents Quick Look and records the native result. Modified clicks reject preview dispatch. Detach and projection changes clear pending recognition and image toolbar ownership.

Only the conflicted BlockEditorView.swift was manually resolved; the Quick Look controller and #11 regression applied unchanged. Worktree is clean, git diff --check passes, and no conflict markers remain. No build/GUI. Exact merged interaction review by /root/ui_fixes_review_medium is pending.

Task identity: `/root/block_drag_finish` Resolved integration candidate: - Worktree/branch: `.worktrees/editor-overnight-combined` / `wave14/editor-overnight-combined` - Parent: `c5c2e1904209ba9d575b4000d8b56ae9cf3716d9` - Exact tip: `35e20ac2740033016ec44eae19c979e50aab69bc` - Integrated original: reviewed `b0770f0ee7eabb35ccb95b96c39d06be735d96a4` The shared mouse-down conflict retains #11's complete gesture dispatcher and #12's richer image interaction/control target. Single unmodified clicks arm validated paired-click recognition and activate native image controls. AppKit clickCount>=2 or a valid paired click dispatches Quick Look. Dispatch dismisses the image toolbar before selection and again after selection notifications can reopen it, then prepares/presents Quick Look and records the native result. Modified clicks reject preview dispatch. Detach and projection changes clear pending recognition and image toolbar ownership. Only the conflicted `BlockEditorView.swift` was manually resolved; the Quick Look controller and #11 regression applied unchanged. Worktree is clean, `git diff --check` passes, and no conflict markers remain. No build/GUI. Exact merged interaction review by `/root/ui_fixes_review_medium` is pending.
Author
Owner

Reviewer: /root/ui_fixes_review_medium
Integration worktree: .worktrees/editor-overnight-combined
Exact candidate: 35e20ac2740033016ec44eae19c979e50aab69bc
Parent: c5c2e1904209ba9d575b4000d8b56ae9cf3716d9
Status/verdict: INTEGRATION SOURCE PASS — no P1–P3 findings in the #11/#12 interaction.

#12 retains first-click image-control ownership through the richer ImageInteractionTarget; #11's compatibility preview wrapper derives from that same exact occurrence and only adds URL resolution for preview. A first single click still selects the image and presents controls. The matching fallback second click or native double-click dismisses the image toolbar before Quick Look, including a second dismissal after selection notification can reopen it. Modified clicks do not activate controls or preview and continue to native block selection/editing.

Pending preview state is invalidated on projection changes and detachment alongside #12 toolbar teardown. There is no change to size/fit mutation, raw token fencing, source mapping, or attachment-local control state. Source/integration review only; merged native first-click controls, double-click transition, focus/panel ownership, and toolbar teardown require runtime verification.

Reviewer: `/root/ui_fixes_review_medium` Integration worktree: `.worktrees/editor-overnight-combined` Exact candidate: `35e20ac2740033016ec44eae19c979e50aab69bc` Parent: `c5c2e1904209ba9d575b4000d8b56ae9cf3716d9` Status/verdict: **INTEGRATION SOURCE PASS** — no P1–P3 findings in the #11/#12 interaction. #12 retains first-click image-control ownership through the richer `ImageInteractionTarget`; #11's compatibility preview wrapper derives from that same exact occurrence and only adds URL resolution for preview. A first single click still selects the image and presents controls. The matching fallback second click or native double-click dismisses the image toolbar before Quick Look, including a second dismissal after selection notification can reopen it. Modified clicks do not activate controls or preview and continue to native block selection/editing. Pending preview state is invalidated on projection changes and detachment alongside #12 toolbar teardown. There is no change to size/fit mutation, raw token fencing, source mapping, or attachment-local control state. Source/integration review only; merged native first-click controls, double-click transition, focus/panel ownership, and toolbar teardown require runtime verification.
Author
Owner

Root build handoff: exact integrated 35e20ac274 has passed independent interaction review (ui_fixes_review_medium) after block_drag_finish resolved #11/#12 overlap. Root independently checked the merged dispatch wrappers and diff; central is clean. The sole agents@mbp package export/upload/build pipeline is dispatched using the existing reviewed controller/helper. Local evidence destination .agents/wave16/central-35e20ac2-root. Build/runtime outcome pending; desktop still26eb1552. In parallel, f90751c4 event/title hosted runtime is transferring to the VM; slow relay transfer is being replaced with a direct staged handoff. No tests are claimed from a build or partial archive.

Root build handoff: exact integrated 35e20ac2740033016ec44eae19c979e50aab69bc has passed independent interaction review (ui_fixes_review_medium) after block_drag_finish resolved #11/#12 overlap. Root independently checked the merged dispatch wrappers and diff; central is clean. The sole agents@mbp package export/upload/build pipeline is dispatched using the existing reviewed controller/helper. Local evidence destination .agents/wave16/central-35e20ac2-root. Build/runtime outcome pending; desktop still26eb1552. In parallel, f90751c4 event/title hosted runtime is transferring to the VM; slow relay transfer is being replaced with a direct staged handoff. No tests are claimed from a build or partial archive.
Author
Owner

Task /root/editor_polish_inventory — next-combined-preview acceptance handoff (planning only; no GUI/build).

Already established: native-cell repair 455b06b2 and merged #11/#12 interaction passed source review. Earlier tests cover source classification/geometry/control-state design; the repaired native cell and final merged toolbar have not yet compiled/run on the target build.

Remaining VM checks, owned by /root on the next exact combined build: single-click the exact wide image and require a nearby native toolbar labelled IMAGE SIZE Auto/Large and IMAGE FIT Fill/Fit. Verify Auto↔Large changes only the intended Markdown size segment and one Undo/Redo round-trips exact bytes. Verify Fit↔Fill keeps the same slot/frame and source bytes while visibly changing crop, with no distortion; the duplicate image occurrence and a second editor must retain independent state. Traverse controls by Tab/Shift-Tab; Escape/outside click/scroll fully out/document switch/window resign/double-click Quick Look must dismiss correctly, while visible reflow/resize reanchors without jitter. Check unloaded/equal-aspect/custom sizes expose honest disabled/custom state. Keep #12 open.

Task `/root/editor_polish_inventory` — next-combined-preview acceptance handoff (planning only; no GUI/build). Already established: native-cell repair `455b06b2` and merged #11/#12 interaction passed source review. Earlier tests cover source classification/geometry/control-state design; the repaired native cell and final merged toolbar have not yet compiled/run on the target build. Remaining VM checks, owned by `/root` on the next exact combined build: single-click the exact wide image and require a nearby native toolbar labelled IMAGE SIZE Auto/Large and IMAGE FIT Fill/Fit. Verify Auto↔Large changes only the intended Markdown size segment and one Undo/Redo round-trips exact bytes. Verify Fit↔Fill keeps the same slot/frame and source bytes while visibly changing crop, with no distortion; the duplicate image occurrence and a second editor must retain independent state. Traverse controls by Tab/Shift-Tab; Escape/outside click/scroll fully out/document switch/window resign/double-click Quick Look must dismiss correctly, while visible reflow/resize reanchors without jitter. Check unloaded/equal-aspect/custom sizes expose honest disabled/custom state. Keep #12 open.
Author
Owner

Exact35e20ac2 package compile reached test compilation after production modules compiled. Tests executed:0. Two test-source compiler errors: CodeBlockPresentationTests247 mixes Int rowBodyX and CGFloat gutterWidth; EditorImageControlsTests580 requires explicit self in lazy compactMap closure. Root downloaded and SHA-verified swift-build.log:51ec35262da9d28ac93ce5207e3d0af9b742de3aaa87a4faef1a5ff0525d9319 at .agents/wave16/central-35e20ac2-root. code_block_polish owns #9 correction; image_preview_native_repair owns #12 correction, each with independent reviewer before integration. This does not establish runtime behavior or a test pass. Native image-cell production compiler blocker is cleared. Root keeps sole compiler and prepares Release candidate handoff separately.

Exact35e20ac2 package compile reached test compilation after production modules compiled. Tests executed:0. Two test-source compiler errors: CodeBlockPresentationTests247 mixes Int rowBodyX and CGFloat gutterWidth; EditorImageControlsTests580 requires explicit self in lazy compactMap closure. Root downloaded and SHA-verified swift-build.log:51ec35262da9d28ac93ce5207e3d0af9b742de3aaa87a4faef1a5ff0525d9319 at .agents/wave16/central-35e20ac2-root. code_block_polish owns #9 correction; image_preview_native_repair owns #12 correction, each with independent reviewer before integration. This does not establish runtime behavior or a test pass. Native image-cell production compiler blocker is cleared. Root keeps sole compiler and prepares Release candidate handoff separately.
Author
Owner

Test-only Swift 6 candidate: exact 057d09fb7e505ac1f76c09d48c0653d5604337a9 on top of reviewed 455b06b2765b004ca3d56eb3307794592172eedb.

The exact combined 35e20ac build confirmed production compilation passed and found one #12 test compile error at EditorImageControlsTests.swift:580: Swift 6 requires explicit instance capture in the recursive lazy compactMap closure. This commit changes only descendant(...) to call self.descendant(...); test behavior and assertions are unchanged.

Compiler evidence: /Users/kayg/Developer/calternal-app/.agents/wave16/central-35e20ac2-root/swift-build.log, SHA-256 51ec35262da9d28ac93ce5207e3d0af9b742de3aaa87a4faef1a5ff0525d9319. Worktree is clean and git diff --check passes. Exact-tip review and remote rerun remain required; no local build or GUI was run.

Test-only Swift 6 candidate: exact `057d09fb7e505ac1f76c09d48c0653d5604337a9` on top of reviewed `455b06b2765b004ca3d56eb3307794592172eedb`. The exact combined `35e20ac` build confirmed production compilation passed and found one #12 test compile error at `EditorImageControlsTests.swift:580`: Swift 6 requires explicit instance capture in the recursive lazy `compactMap` closure. This commit changes only `descendant(...)` to call `self.descendant(...)`; test behavior and assertions are unchanged. Compiler evidence: `/Users/kayg/Developer/calternal-app/.agents/wave16/central-35e20ac2-root/swift-build.log`, SHA-256 `51ec35262da9d28ac93ce5207e3d0af9b742de3aaa87a4faef1a5ff0525d9319`. Worktree is clean and `git diff --check` passes. Exact-tip review and remote rerun remain required; no local build or GUI was run.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Candidate: exact 057d09fb7e505ac1f76c09d48c0653d5604337a9 atop source-approved 455b06b2765b004ca3d56eb3307794592172eedb
State: TEST-COMPILE REPAIR SOURCE PASS — no P1/P2/P3 findings. The worktree is clean and git diff --check 455b06b2..057d09fb passes. No build, test execution, or GUI run was performed in this review lane.

The recorded exact combined-build evidence, .agents/wave16/central-35e20ac2-root/swift-build.log (SHA-256 51ec35262da9d28ac93ce5207e3d0af9b742de3aaa87a4faef1a5ff0525d9319), reports at EditorImageControlsTests.swift:580 that the recursive call inside the escaping lazy compactMap closure requires explicit self capture under Swift 6.

The exact one-line delta changes descendant(of:as:) to call self.descendant(of:as:). It resolves precisely that diagnostic without changing recursion order, generic type inference, view traversal, assertions, production source, native-cell drawing, or test behavior. No new test is warranted for an explicit-capture compile repair.

Root may integrate this one-line commit and rerun the same agents@mbp Release test build. The separate #9 test-source error in the same log is outside this candidate. Issue #12 remains open pending a fresh successful compile, focused test/runtime evidence, delivery, and user acceptance.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Candidate: exact `057d09fb7e505ac1f76c09d48c0653d5604337a9` atop source-approved `455b06b2765b004ca3d56eb3307794592172eedb` State: **TEST-COMPILE REPAIR SOURCE PASS — no P1/P2/P3 findings.** The worktree is clean and `git diff --check 455b06b2..057d09fb` passes. No build, test execution, or GUI run was performed in this review lane. The recorded exact combined-build evidence, `.agents/wave16/central-35e20ac2-root/swift-build.log` (SHA-256 `51ec35262da9d28ac93ce5207e3d0af9b742de3aaa87a4faef1a5ff0525d9319`), reports at `EditorImageControlsTests.swift:580` that the recursive call inside the escaping lazy `compactMap` closure requires explicit `self` capture under Swift 6. The exact one-line delta changes `descendant(of:as:)` to call `self.descendant(of:as:)`. It resolves precisely that diagnostic without changing recursion order, generic type inference, view traversal, assertions, production source, native-cell drawing, or test behavior. No new test is warranted for an explicit-capture compile repair. Root may integrate this one-line commit and rerun the same agents@mbp Release test build. The separate #9 test-source error in the same log is outside this candidate. Issue #12 remains open pending a fresh successful compile, focused test/runtime evidence, delivery, and user acceptance.
Author
Owner

Root integrated independently reviewed test-only fixes057d09fb (#12 explicitself) and d99d751f (#9 CGFloatgeometry) as4edde45e/3bbb28a6. Exact central3bbb28a6fcf7bac1dae310bd07ea8e7a0ace6b68 is clean; only test sources changed since35e production compilation. Sole package rerun dispatched using proven rsync delta transport and existing hash-verifying controller. Local evidence .agents/wave16/central-3bbb28a6-root. Runtime results pending.

In parallel f907 hosted runtime is verified/published onVM with archiveSHA176b4b4aaab3efb55cd4cb36c6c7beceaa6ec2dcc99cbffdef9b3ed338bff2bf. image_preview_qa owns actual7event+6title executions. title_completion resolved host-key verification using independently matching public fingerprints and delta transport; no partial used. block_drag_finish prepares same-revision Release wrapper only; root retains sole compiler ownership. Desktop remains26eb.

Root integrated independently reviewed test-only fixes057d09fb (#12 explicitself) and d99d751f (#9 CGFloatgeometry) as4edde45e/3bbb28a6. Exact central3bbb28a6fcf7bac1dae310bd07ea8e7a0ace6b68 is clean; only test sources changed since35e production compilation. Sole package rerun dispatched using proven rsync delta transport and existing hash-verifying controller. Local evidence .agents/wave16/central-3bbb28a6-root. Runtime results pending. In parallel f907 hosted runtime is verified/published onVM with archiveSHA176b4b4aaab3efb55cd4cb36c6c7beceaa6ec2dcc99cbffdef9b3ed338bff2bf. image_preview_qa owns actual7event+6title executions. title_completion resolved host-key verification using independently matching public fingerprints and delta transport; no partial used. block_drag_finish prepares same-revision Release wrapper only; root retains sole compiler ownership. Desktop remains26eb.
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

Exact combined 3bbb28a6 VM package run executed all 10 EditorImageControlsTests; 9 test cases passed and testFitStateAndSlotStayIndependentAcrossMountedEditors failed four assertions. Exact log: /Users/kayg/Developer/calternal-app/.agents/native-break/3bbb-combined-package-qa/exact-logs/imagecontrols/CalternalEditorTests_EditorImageControlsTests/xctest.log.

The failures are diagnostic: both actual-pixel comparison and all three native-cell callback observations failed. Therefore TextKit 2 did not invoke NSTextAttachmentCell.draw for either mounted editor, and the equal cached pixels cannot validate Fit/Fill. Size parsing/mutation, geometry math, stale occurrence, scroll teardown, native toolbar/keyboard/click lifecycle, and Undo all passed.

Proposed source plan is held for focused review before editing: restore the per-occurrence NSTextAttachmentViewProvider only for Large images, mark the provider class @MainActor, implement its SDK designated initializer as nonisolated so the nonisolated attachment factory can instantiate it, and keep loadView() nonisolated while synchronously entering MainActor.assumeIsolated. Because the instance is then MainActor-isolated, capturing self in that bridge is actor-safe rather than sending a task-isolated non-Sendable provider. Restore the weak drawing-view invalidation registry and per-layout-manager Fit lookup. Replace cell diagnostics with drawing-view diagnostics keyed to the exact editor layout managers, and retain the strict same-frame pixel comparison. No unchecked Sendable, unsafe wrapper, suppression, or weakened pixel assertion.

Exact combined `3bbb28a6` VM package run executed all 10 `EditorImageControlsTests`; 9 test cases passed and `testFitStateAndSlotStayIndependentAcrossMountedEditors` failed four assertions. Exact log: `/Users/kayg/Developer/calternal-app/.agents/native-break/3bbb-combined-package-qa/exact-logs/imagecontrols/CalternalEditorTests_EditorImageControlsTests/xctest.log`. The failures are diagnostic: both actual-pixel comparison and all three native-cell callback observations failed. Therefore TextKit 2 did not invoke `NSTextAttachmentCell.draw` for either mounted editor, and the equal cached pixels cannot validate Fit/Fill. Size parsing/mutation, geometry math, stale occurrence, scroll teardown, native toolbar/keyboard/click lifecycle, and Undo all passed. Proposed source plan is held for focused review before editing: restore the per-occurrence `NSTextAttachmentViewProvider` only for Large images, mark the provider class `@MainActor`, implement its SDK designated initializer as nonisolated so the nonisolated attachment factory can instantiate it, and keep `loadView()` nonisolated while synchronously entering `MainActor.assumeIsolated`. Because the instance is then MainActor-isolated, capturing `self` in that bridge is actor-safe rather than sending a task-isolated non-Sendable provider. Restore the weak drawing-view invalidation registry and per-layout-manager Fit lookup. Replace cell diagnostics with drawing-view diagnostics keyed to the exact editor layout managers, and retain the strict same-frame pixel comparison. No unchecked Sendable, unsafe wrapper, suppression, or weakened pixel assertion.
Author
Owner

3bbb VM package runtime exact hashes verified. CalternalEditorTests.EditorImageControlsTests executed 10 tests with 4 failures, all in testFitStateAndSlotStayIndependentAcrossMountedEditors. The mounted pixel assertion says Fill did not visibly crop into its fixed slot (same Fit pixels), followed by three isolation assertions. The other 9 image-control tests passed. Evidence: .agents/native-break/3bbb-combined-package-qa/04-vm-summary.txt; full log: exact-logs/imagecontrols/CalternalEditorTests_EditorImageControlsTests/xctest.log.

3bbb VM package runtime exact hashes verified. `CalternalEditorTests.EditorImageControlsTests` executed 10 tests with 4 failures, all in `testFitStateAndSlotStayIndependentAcrossMountedEditors`. The mounted pixel assertion says Fill did not visibly crop into its fixed slot (same Fit pixels), followed by three isolation assertions. The other 9 image-control tests passed. Evidence: `.agents/native-break/3bbb-combined-package-qa/04-vm-summary.txt`; full log: `exact-logs/imagecontrols/CalternalEditorTests_EditorImageControlsTests/xctest.log`.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Evidence revision: exact combined 3bbb28a6fcf7bac1dae310bd07ea8e7a0ace6b68; proposed source parent 057d09fb7e505ac1f76c09d48c0653d5604337a9
State: REVISED LARGE-ONLY VIEW-PROVIDER PLAN PASS. Code remains paused for an exact candidate review. No source edit, build, test execution, or GUI run was performed in this reviewer lane.

The prior native-cell plan is superseded by actual mounted evidence. Exact 3bbb28a6 compiled, and all 10 EditorImageControlsTests ran on the VM: nine passed, while testFitStateAndSlotStayIndependentAcrossMountedEditors failed its pixel comparison and all three attachment-cell draw observations. The exact log is .agents/native-break/3bbb-combined-package-qa/exact-logs/imagecontrols/CalternalEditorTests_EditorImageControlsTests/xctest.log. Empty callbacks for both real TextKit 2 mounts establish that NSTextAttachmentCell.draw is not this editor's rendering path; equal pixels establish that the cell-only Fit state never reaches rendering. Keeping or weakening that route would ship a nonfunctional Fill control.

The revised provider construction is viable under the installed Swift 6/AppKit contract and directly addresses the earlier 80efddbc diagnostic:

  • NSTextAttachment.viewProvider(for:location:textContainer:), NSTextAttachmentViewProvider.init(textAttachment:parentView:textLayoutManager:location:), and loadView() import as nonisolated SDK entry points. The attachment factory therefore needs a synchronously callable nonisolated provider initializer.
  • Annotate the provider class itself @MainActor. Its instance self is then global-actor-isolated rather than the prior task-isolated non-Sendable value that Swift rejected.
  • Explicitly override the SDK designated initializer as nonisolated and only forward its four arguments to super.init. It must not read or initialize separate MainActor state there.
  • Keep the required loadView() override nonisolated, and synchronously enter MainActor.assumeIsolated to construct/set the NSView and capture the now MainActor-isolated provider self. This is the narrow legacy SDK bridge; do not use nonisolated(unsafe), unchecked Sendable, a suppression, asynchronous dispatch, or a second wrapper object. The exact agents@mbp Swift 6.3 build remains the authoritative compiler proof.

Native behavior remains bounded to the already reviewed implementation: enable attachment views only for parsed Large state; return one provider carrying AppKit's exact NSTextLayoutManager; retain the existing attachment-bounds callbacks for the fixed min(640, positive realized line width) × 220 slot; have the drawing view read Fit from only that layout-manager identity, compute the aspect-preserving Fit/Fill content rectangle, and clip to its exact bounds. Restore the weak drawing-view registry so Fit changes and image/reference changes invalidate mounted provider views. Auto and Custom continue through the existing non-view image path. Source parsing, exact occurrence CAS, Undo, selection, panel lifecycle, and Quick Look targeting remain untouched.

The candidate must replace the now disproven cell diagnostics with drawing-view/provider diagnostics and retain the strong mounted assertions: exact editor A/B layout-manager identities, A Fit then Fill, B still Fit, identical native attachment frame across modes, and pixel-distinct cached output in that same frame. Do not weaken the pixel assertion or satisfy it by directly invoking a draw helper.

No P1/P2/P3 plan blocker remains. Next action: author implements only this provider correction and freezes an exact candidate for source review; root then runs the same Swift 6.3 Release compile and the focused mounted test before VM/user acceptance. Issue #12 remains open.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Evidence revision: exact combined `3bbb28a6fcf7bac1dae310bd07ea8e7a0ace6b68`; proposed source parent `057d09fb7e505ac1f76c09d48c0653d5604337a9` State: **REVISED LARGE-ONLY VIEW-PROVIDER PLAN PASS.** Code remains paused for an exact candidate review. No source edit, build, test execution, or GUI run was performed in this reviewer lane. The prior native-cell plan is superseded by actual mounted evidence. Exact `3bbb28a6` compiled, and all 10 `EditorImageControlsTests` ran on the VM: nine passed, while `testFitStateAndSlotStayIndependentAcrossMountedEditors` failed its pixel comparison and all three attachment-cell draw observations. The exact log is `.agents/native-break/3bbb-combined-package-qa/exact-logs/imagecontrols/CalternalEditorTests_EditorImageControlsTests/xctest.log`. Empty callbacks for both real TextKit 2 mounts establish that `NSTextAttachmentCell.draw` is not this editor's rendering path; equal pixels establish that the cell-only Fit state never reaches rendering. Keeping or weakening that route would ship a nonfunctional Fill control. The revised provider construction is viable under the installed Swift 6/AppKit contract and directly addresses the earlier `80efddbc` diagnostic: - `NSTextAttachment.viewProvider(for:location:textContainer:)`, `NSTextAttachmentViewProvider.init(textAttachment:parentView:textLayoutManager:location:)`, and `loadView()` import as nonisolated SDK entry points. The attachment factory therefore needs a synchronously callable nonisolated provider initializer. - Annotate the provider class itself `@MainActor`. Its instance `self` is then global-actor-isolated rather than the prior task-isolated non-Sendable value that Swift rejected. - Explicitly override the SDK designated initializer as `nonisolated` and only forward its four arguments to `super.init`. It must not read or initialize separate MainActor state there. - Keep the required `loadView()` override `nonisolated`, and synchronously enter `MainActor.assumeIsolated` to construct/set the `NSView` and capture the now MainActor-isolated provider `self`. This is the narrow legacy SDK bridge; do not use `nonisolated(unsafe)`, unchecked Sendable, a suppression, asynchronous dispatch, or a second wrapper object. The exact agents@mbp Swift 6.3 build remains the authoritative compiler proof. Native behavior remains bounded to the already reviewed implementation: enable attachment views only for parsed Large state; return one provider carrying AppKit's exact `NSTextLayoutManager`; retain the existing attachment-bounds callbacks for the fixed `min(640, positive realized line width) × 220` slot; have the drawing view read Fit from only that layout-manager identity, compute the aspect-preserving Fit/Fill content rectangle, and clip to its exact bounds. Restore the weak drawing-view registry so Fit changes and image/reference changes invalidate mounted provider views. Auto and Custom continue through the existing non-view image path. Source parsing, exact occurrence CAS, Undo, selection, panel lifecycle, and Quick Look targeting remain untouched. The candidate must replace the now disproven cell diagnostics with drawing-view/provider diagnostics and retain the strong mounted assertions: exact editor A/B layout-manager identities, A Fit then Fill, B still Fit, identical native attachment frame across modes, and pixel-distinct cached output in that same frame. Do not weaken the pixel assertion or satisfy it by directly invoking a draw helper. No P1/P2/P3 plan blocker remains. Next action: author implements only this provider correction and freezes an exact candidate for source review; root then runs the same Swift 6.3 Release compile and the focused mounted test before VM/user acceptance. Issue #12 remains open.
Author
Owner

Runtime-repair candidate: exact cc6a8d35c52311223c3d778b74ea1d130aa41812 on top of reviewed 057d09fb7e505ac1f76c09d48c0653d5604337a9.

Following the revised plan PASS, Large images again use a per-occurrence NSTextAttachmentViewProvider; Auto and custom widths retain the native cell fallback. The provider class is now @MainActor, its SDK designated initializer is explicitly nonisolated for the nonisolated attachment factory, and its nonisolated loadView() synchronously enters MainActor.assumeIsolated while capturing globally actor-isolated self. The original task-isolated Sendable error therefore has no unchecked/unsafe workaround or suppression.

The weak drawing-view registry and per-layout-manager Fit invalidation are restored. The mounted test observes the actual drawing-view callback with exact layout-manager identity for both editors, requires distinct view instances per presenter, preserves the exact native frame across Fit/Fill, and retains the real cached-pixel difference assertion.

Evidence: worktree clean and git diff --check PASS. No local build or GUI. Exact-tip source review, Swift 6.3 compile, focused runtime rerun, and combined VM UI remain required.

Runtime-repair candidate: exact `cc6a8d35c52311223c3d778b74ea1d130aa41812` on top of reviewed `057d09fb7e505ac1f76c09d48c0653d5604337a9`. Following the revised plan PASS, Large images again use a per-occurrence `NSTextAttachmentViewProvider`; Auto and custom widths retain the native cell fallback. The provider class is now `@MainActor`, its SDK designated initializer is explicitly nonisolated for the nonisolated attachment factory, and its nonisolated `loadView()` synchronously enters `MainActor.assumeIsolated` while capturing globally actor-isolated `self`. The original task-isolated Sendable error therefore has no unchecked/unsafe workaround or suppression. The weak drawing-view registry and per-layout-manager Fit invalidation are restored. The mounted test observes the actual drawing-view callback with exact layout-manager identity for both editors, requires distinct view instances per presenter, preserves the exact native frame across Fit/Fill, and retains the real cached-pixel difference assertion. Evidence: worktree clean and `git diff --check` PASS. No local build or GUI. Exact-tip source review, Swift 6.3 compile, focused runtime rerun, and combined VM UI remain required.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Candidate: exact cc6a8d35c52311223c3d778b74ea1d130aa41812 atop 057d09fb7e505ac1f76c09d48c0653d5604337a9
State: LARGE VIEW-PROVIDER SOURCE REVIEW PASS — no P1/P2/P3 findings. The worktree is clean and git diff --check 057d09fb..cc6a8d35 passes. Per lane ownership, no build, tests, or GUI were run by this reviewer.

The exact two-file delta implements the approved correction without broadening source or control behavior:

  • EditorImageAttachmentViewProvider is now a @MainActor type. Its explicit nonisolated SDK designated initializer only forwards textAttachment, parentView, textLayoutManager, and location to super.init, so the attachment's nonisolated factory can construct it without reading separate actor state. Its required loadView() remains nonisolated to match AppKit and synchronously enters MainActor.assumeIsolated; the captured self is now MainActor-isolated rather than the task-isolated provider rejected at 80efddbc. No unchecked Sendable, nonisolated(unsafe), suppression, asynchronous hop, or wrapper was added.
  • View-provider lookup is enabled only when the losslessly parsed size state is Large and the nonisolated factory repeats that locked Large guard. Decoded attachments start with views disabled and the first MainActor updateReference installs the cell and applies the parsed state as before. Auto and Custom retain the existing baseline image route.
  • The provider passes AppKit's exact NSTextLayoutManager weakly into its drawing view. Drawing reads only that manager's attachment-local Fit state, computes the existing aspect-preserving content rectangle inside the provider bounds, clips exactly to those bounds, and keeps the fixed Large layout slot under the unchanged attachmentBounds overrides.
  • Weak drawing-view registration and invalidation are restored for reference, image, Fit, and mounted-state changes. This can ask another mounted provider to redraw, but each provider rereads only its own layout-manager key, so no Fit state leaks between editors.
  • The fallback attachment cell remains Fit-only for non-view and compatibility paths; the exact 3bbb28a6 VM evidence established it is not the Large TextKit 2 rendering path, so it cannot override the provider's per-manager state.

The mounted regression remains strict. It replaces the disproven cell callback with observations from actual provider drawing, requires editor A's exact layout-manager identity in both Fit and Fill draws, requires editor B's exact identity in Fit, proves the two managers receive disjoint drawing-view instances, keeps the native attachment frame identical across modes, and retains the rendered edge-pixel difference. It does not directly invoke the draw helper or weaken the pixel comparison.

No source finding remains at this exact revision. Root should run the same agents@mbp Swift 6.3 Release test build to prove the revised actor boundary compiles, then run the focused mounted test on the VM. Issue #12 remains open through runtime interaction, delivery, and user acceptance.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Candidate: exact `cc6a8d35c52311223c3d778b74ea1d130aa41812` atop `057d09fb7e505ac1f76c09d48c0653d5604337a9` State: **LARGE VIEW-PROVIDER SOURCE REVIEW PASS — no P1/P2/P3 findings.** The worktree is clean and `git diff --check 057d09fb..cc6a8d35` passes. Per lane ownership, no build, tests, or GUI were run by this reviewer. The exact two-file delta implements the approved correction without broadening source or control behavior: - `EditorImageAttachmentViewProvider` is now a `@MainActor` type. Its explicit `nonisolated` SDK designated initializer only forwards `textAttachment`, `parentView`, `textLayoutManager`, and `location` to `super.init`, so the attachment's nonisolated factory can construct it without reading separate actor state. Its required `loadView()` remains nonisolated to match AppKit and synchronously enters `MainActor.assumeIsolated`; the captured `self` is now MainActor-isolated rather than the task-isolated provider rejected at `80efddbc`. No unchecked Sendable, `nonisolated(unsafe)`, suppression, asynchronous hop, or wrapper was added. - View-provider lookup is enabled only when the losslessly parsed size state is Large and the nonisolated factory repeats that locked Large guard. Decoded attachments start with views disabled and the first MainActor `updateReference` installs the cell and applies the parsed state as before. Auto and Custom retain the existing baseline image route. - The provider passes AppKit's exact `NSTextLayoutManager` weakly into its drawing view. Drawing reads only that manager's attachment-local Fit state, computes the existing aspect-preserving content rectangle inside the provider bounds, clips exactly to those bounds, and keeps the fixed Large layout slot under the unchanged `attachmentBounds` overrides. - Weak drawing-view registration and invalidation are restored for reference, image, Fit, and mounted-state changes. This can ask another mounted provider to redraw, but each provider rereads only its own layout-manager key, so no Fit state leaks between editors. - The fallback attachment cell remains Fit-only for non-view and compatibility paths; the exact `3bbb28a6` VM evidence established it is not the Large TextKit 2 rendering path, so it cannot override the provider's per-manager state. The mounted regression remains strict. It replaces the disproven cell callback with observations from actual provider drawing, requires editor A's exact layout-manager identity in both Fit and Fill draws, requires editor B's exact identity in Fit, proves the two managers receive disjoint drawing-view instances, keeps the native attachment frame identical across modes, and retains the rendered edge-pixel difference. It does not directly invoke the draw helper or weaken the pixel comparison. No source finding remains at this exact revision. Root should run the same agents@mbp Swift 6.3 Release test build to prove the revised actor boundary compiles, then run the focused mounted test on the VM. Issue #12 remains open through runtime interaction, delivery, and user acceptance.
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

Root next exact centrald5ce608f includes reviewed#12 providercc6a (bb186), #11 geometrydiagnosticsabf3 (5041), #9 guardeddiagnosticsNETd99d..a07c (932e; rejectedgeometrycf7 excluded), #5 structuredcontrol+samepathcontrol through8920 (f463/043e/d5ce). Each candidate source-reviewed; diagnostics preserve strict assertions and avoid user source/URL output. Sole packagecompile pipeline dispatched; subsequent hostedtitlecontrol build remains queued. These newchanges are NOT in desktop3bbb. Runtime rendering and gestures are unproven; earlierfailures explicitly open. Root owns integration/build; authors await exactdiagnosticlogs for decisions.

Root next exact centrald5ce608f includes reviewed#12 providercc6a (bb186), #11 geometrydiagnosticsabf3 (5041), #9 guardeddiagnosticsNETd99d..a07c (932e; rejectedgeometrycf7 excluded), #5 structuredcontrol+samepathcontrol through8920 (f463/043e/d5ce). Each candidate source-reviewed; diagnostics preserve strict assertions and avoid user source/URL output. Sole packagecompile pipeline dispatched; subsequent hostedtitlecontrol build remains queued. These newchanges are NOT in desktop3bbb. Runtime rendering and gestures are unproven; earlierfailures explicitly open. Root owns integration/build; authors await exactdiagnosticlogs for decisions.
Author
Owner

Exactd5ce608f package compile failed at EditorImagePresentation.swift668: task-isolated provider self captured by MainActor.assumeIsolated, despite the reviewed class annotation. Root downloaded/hash-verified log45975635ffadceff5ed437a55c80484fd1963fc60db51e29968dc1b36b76a7da (.agents/wave16/central-d5ce608f-root/swift-build.log). Tests0. /root/image_preview_native_repair now owns bounded SDK compiler probes before another full source change; reviewed plan is not compiler evidence. #9/#11 diagnostic runtime and #5 same-path control remain queued. Desktop3bbb remains installed and unchanged; userQAcontinues. Rootroutefinding forVM: actualSettings Spacebookmark configuration needed, QA assignednativefolderpicker instead of guessedFilemenu.

Exactd5ce608f package compile failed at EditorImagePresentation.swift668: task-isolated provider self captured by MainActor.assumeIsolated, despite the reviewed class annotation. Root downloaded/hash-verified log45975635ffadceff5ed437a55c80484fd1963fc60db51e29968dc1b36b76a7da (.agents/wave16/central-d5ce608f-root/swift-build.log). Tests0. /root/image_preview_native_repair now owns bounded SDK compiler probes before another full source change; reviewed plan is not compiler evidence. #9/#11 diagnostic runtime and #5 same-path control remain queued. Desktop3bbb remains installed and unchanged; userQAcontinues. Rootroutefinding forVM: actualSettings Spacebookmark configuration needed, QA assignednativefolderpicker instead of guessedFilemenu.
Author
Owner

Thread: /root/image_preview_native_repair (wave16/image-controls)

Exact combined candidate d5ce608f failed the Swift 6.3 package build before runtime tests. The sole new error is EditorImagePresentation.swift:668:17: sending 'self' risks causing data races: the NSTextAttachmentViewProvider.loadView() override is imported nonisolated, so capturing provider self inside MainActor.assumeIsolated remains a task-isolated-to-main-actor send even when the subclass is @MainActor. Build log: .agents/wave16/central-d5ce608f-root/swift-build.log, SHA-256 45975635ffadceff5ed437a55c80484fd1963fc60db51e29968dc1b36b76a7da.

The reviewed assumeIsolated { self ... } architecture is therefore disproved by the exact compiler and will not be repeated. Production remains frozen at isolated source candidate cc6a8d35c52311223c3d778b74ea1d130aa41812 while a five-case, standalone AppKit type-check matrix tests direct actor-isolated and narrowly scoped @preconcurrency override forms against Xcode 26.6 / Swift 6.3. No replacement will enter the source candidate until a tiny exact-toolchain probe passes and the independent reviewer approves the resulting architecture.

Thread: `/root/image_preview_native_repair` (`wave16/image-controls`) Exact combined candidate `d5ce608f` failed the Swift 6.3 package build before runtime tests. The sole new error is `EditorImagePresentation.swift:668:17: sending 'self' risks causing data races`: the `NSTextAttachmentViewProvider.loadView()` override is imported nonisolated, so capturing provider `self` inside `MainActor.assumeIsolated` remains a task-isolated-to-main-actor send even when the subclass is `@MainActor`. Build log: `.agents/wave16/central-d5ce608f-root/swift-build.log`, SHA-256 `45975635ffadceff5ed437a55c80484fd1963fc60db51e29968dc1b36b76a7da`. The reviewed `assumeIsolated { self ... }` architecture is therefore disproved by the exact compiler and will not be repeated. Production remains frozen at isolated source candidate `cc6a8d35c52311223c3d778b74ea1d130aa41812` while a five-case, standalone AppKit type-check matrix tests direct actor-isolated and narrowly scoped `@preconcurrency` override forms against Xcode 26.6 / Swift 6.3. No replacement will enter the source candidate until a tiny exact-toolchain probe passes and the independent reviewer approves the resulting architecture.
Author
Owner

Root compiled five bounded SDK probes on agents@mbp with AppleSwift6.3.3. Typecheck-only was insufficient: currentassumeIsolated case passed typecheck but all five actual -c -O -parse-as-library -swift-version6 object compilations failed. Evidence .agents/wave16/provider-isolation-object-probes.json. Variants01selfrace;02–04attachment/layoutManager sendrace;05overrideactor mismatch. No probe execution or appGUI. Dedicated image_controls_review reassesses minimal runtime-confined SDKboundary; no further speculative annotation patch accepted.

To avoid blocking independent issues, block_drag_finish is creating an isolated3bbb-based diagnostics-only worktree for#9/#11, excluding the uncompiled#12 provider. Root will run its reviewed tests while#12investigation and#5isolatedhostedcontrol continue. Desktop3bbb stays unchanged.

Root compiled five bounded SDK probes on agents@mbp with AppleSwift6.3.3. Typecheck-only was insufficient: currentassumeIsolated case passed typecheck but all five actual -c -O -parse-as-library -swift-version6 object compilations failed. Evidence .agents/wave16/provider-isolation-object-probes.json. Variants01selfrace;02–04attachment/layoutManager sendrace;05overrideactor mismatch. No probe execution or appGUI. Dedicated image_controls_review reassesses minimal runtime-confined SDKboundary; no further speculative annotation patch accepted. To avoid blocking independent issues, block_drag_finish is creating an isolated3bbb-based diagnostics-only worktree for#9/#11, excluding the uncompiled#12 provider. Root will run its reviewed tests while#12investigation and#5isolatedhostedcontrol continue. Desktop3bbb stays unchanged.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Rejected source candidate: cc6a8d35c52311223c3d778b74ea1d130aa41812; compiler evidence revision: combined d5ce608f
State: ARCHITECTURE REASSESSMENT — PRIOR PROVIDER ISOLATION PLAN REJECTED; ONE BOUNDED RUNTIME-CHECKED PROBE APPROVED. No source edit, product build, test run, or GUI was performed by this reviewer.

P1 — @MainActor on the provider does not make the inherited nonisolated override capture safe

Location: Sources/CalternalEditor/EditorImagePresentation.swift:649-678 at cc6a8d35, specifically EditorImageAttachmentViewProvider.loadView().

What breaks: the product cannot compile under the required Swift 6.3 optimized build, so the Large Fit/Fill rendering repair cannot ship.

Why it breaks: exact d5ce608f compilation reports sending 'self' risks causing data races at the MainActor.assumeIsolated closure despite the provider class annotation. The follow-up .agents/wave16/provider-isolation-object-probes.json compiles all five variants with swiftc -c -O; all fail. The current bridge still diagnoses task-isolated provider self; direct and @preconcurrency forms send task-isolated attachment/layout-manager objects to MainActor; explicitly marking the override MainActor conflicts with AppKit's nonisolated declaration. Earlier -typecheck exit zero was a false positive because the diagnostic appears during optimized object emission.

Scoped fix/probe: replace the disproven annotation assumption with one file-private, final provider boundary that has no custom stored mutable state and declares @unchecked Sendable solely to permit capture of its own reference by this synchronous SDK callback. Keep loadView() nonisolated, call MainActor.preconditionIsolated() as the first operation, and only then enter MainActor.assumeIsolated { [self] in ... } to read the inherited provider properties, create/register EditorImageDrawingView, and set view. Remove @MainActor from the provider type. Do not add @preconcurrency, nonisolated(unsafe), a wrapper/registry, asynchronous dispatch, Objective-C escape hatch, or diagnostic suppression.

This is an unchecked declaration, but it is not accepted on faith. Its safety argument is narrow and testable: AppKit's installed NSTextAttachment.h says the view getter invokes loadView() to create the custom view hierarchy and that callers must never invoke loadView() directly; however, the SDK omits NS_SWIFT_UI_ACTOR. The runtime precondition closes that annotation gap before any application or NSView state is touched. The class must remain final/file-private, expose no API, own no additional mutable state, and perform all application-defined work only inside the checked MainActor closure. The provider remains owned and called by TextKit.

Before product code changes, root should run an exact tiny probe with the same Xcode 26.6 / Swift 6.3 toolchain and concurrency flags in two stages:

  1. Compile the exact proposed provider declaration with swiftc -c -O, not -typecheck; require exit zero and no concurrency warnings/errors.
  2. In a separate tiny main-thread executable or XCTest probe, instantiate the provider through its SDK designated initializer, invoke the SDK view getter (not loadView() directly), and assert that the expected drawing view is synchronously installed without a precondition failure. This establishes the documented lazy path and runtime confinement. The product candidate must then receive exact-diff review and the real mounted TextKit 2 test must still prove provider callbacks for both exact layout managers, disjoint views, unchanged slot frame, A Fit/Fill pixel difference, and B remaining Fit.

@unchecked Sendable is rejected if the optimized probe still fails, if the implementation adds provider-owned mutable state, or if any runtime evidence shows the SDK calling this boundary away from MainActor. In that case stop rather than stacking another isolation workaround.

The native cell fallback remains disproven for TextKit 2 by exact 3bbb28a6 runtime evidence and is not an alternative. Source syntax/CAS/Undo/selection/Quick Look contracts remain unchanged. Issue #12 stays open.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Rejected source candidate: `cc6a8d35c52311223c3d778b74ea1d130aa41812`; compiler evidence revision: combined `d5ce608f` State: **ARCHITECTURE REASSESSMENT — PRIOR PROVIDER ISOLATION PLAN REJECTED; ONE BOUNDED RUNTIME-CHECKED PROBE APPROVED.** No source edit, product build, test run, or GUI was performed by this reviewer. ### P1 — `@MainActor` on the provider does not make the inherited nonisolated override capture safe **Location:** `Sources/CalternalEditor/EditorImagePresentation.swift:649-678` at `cc6a8d35`, specifically `EditorImageAttachmentViewProvider.loadView()`. **What breaks:** the product cannot compile under the required Swift 6.3 optimized build, so the Large Fit/Fill rendering repair cannot ship. **Why it breaks:** exact `d5ce608f` compilation reports `sending 'self' risks causing data races` at the `MainActor.assumeIsolated` closure despite the provider class annotation. The follow-up `.agents/wave16/provider-isolation-object-probes.json` compiles all five variants with `swiftc -c -O`; all fail. The current bridge still diagnoses task-isolated provider `self`; direct and `@preconcurrency` forms send task-isolated attachment/layout-manager objects to MainActor; explicitly marking the override MainActor conflicts with AppKit's nonisolated declaration. Earlier `-typecheck` exit zero was a false positive because the diagnostic appears during optimized object emission. **Scoped fix/probe:** replace the disproven annotation assumption with one file-private, final provider boundary that has no custom stored mutable state and declares `@unchecked Sendable` solely to permit capture of its own reference by this synchronous SDK callback. Keep `loadView()` nonisolated, call `MainActor.preconditionIsolated()` as the first operation, and only then enter `MainActor.assumeIsolated { [self] in ... }` to read the inherited provider properties, create/register `EditorImageDrawingView`, and set `view`. Remove `@MainActor` from the provider type. Do not add `@preconcurrency`, `nonisolated(unsafe)`, a wrapper/registry, asynchronous dispatch, Objective-C escape hatch, or diagnostic suppression. This is an unchecked declaration, but it is not accepted on faith. Its safety argument is narrow and testable: AppKit's installed `NSTextAttachment.h` says the `view` getter invokes `loadView()` to create the custom view hierarchy and that callers must never invoke `loadView()` directly; however, the SDK omits `NS_SWIFT_UI_ACTOR`. The runtime precondition closes that annotation gap before any application or NSView state is touched. The class must remain final/file-private, expose no API, own no additional mutable state, and perform all application-defined work only inside the checked MainActor closure. The provider remains owned and called by TextKit. Before product code changes, root should run an exact tiny probe with the same Xcode 26.6 / Swift 6.3 toolchain and concurrency flags in two stages: 1. Compile the exact proposed provider declaration with `swiftc -c -O`, not `-typecheck`; require exit zero and no concurrency warnings/errors. 2. In a separate tiny main-thread executable or XCTest probe, instantiate the provider through its SDK designated initializer, invoke the SDK `view` getter (not `loadView()` directly), and assert that the expected drawing view is synchronously installed without a precondition failure. This establishes the documented lazy path and runtime confinement. The product candidate must then receive exact-diff review and the real mounted TextKit 2 test must still prove provider callbacks for both exact layout managers, disjoint views, unchanged slot frame, A Fit/Fill pixel difference, and B remaining Fit. `@unchecked Sendable` is rejected if the optimized probe still fails, if the implementation adds provider-owned mutable state, or if any runtime evidence shows the SDK calling this boundary away from MainActor. In that case stop rather than stacking another isolation workaround. The native cell fallback remains disproven for TextKit 2 by exact `3bbb28a6` runtime evidence and is not an alternative. Source syntax/CAS/Undo/selection/Quick Look contracts remain unchanged. Issue #12 stays open.
Author
Owner

Thread: /root/image_preview_native_repair (wave16/image-controls)

The sixth bounded SDK bridge probe also failed exact optimized Swift 6.3 compilation. Probe 06 used the reviewed narrow form: a file-private final NSTextAttachmentViewProvider subclass with no custom stored state, scoped @unchecked Sendable, an immediate MainActor.preconditionIsolated(), then MainActor.assumeIsolated { [self] ... }. swiftc -O -parse-as-library rejected the closure at line 37 with task or actor isolated value cannot be sent; no runnable binary was produced, so VM runtime proof could not begin.

This result closes the tested synchronous Swift loadView() bridge variants: all six optimized object/executable probes fail under Apple Swift 6.3.3. The earlier -typecheck successes were false positives because the region-based sending diagnostic appears during object generation. Production remains frozen at cc6a8d35c52311223c3d778b74ea1d130aa41812; there will be no seventh annotation guess or production edit. The next step is independent architecture review of another SDK rendering boundary, followed by optimized compiler proof before integration.

Thread: `/root/image_preview_native_repair` (`wave16/image-controls`) The sixth bounded SDK bridge probe also failed exact optimized Swift 6.3 compilation. Probe 06 used the reviewed narrow form: a file-private final `NSTextAttachmentViewProvider` subclass with no custom stored state, scoped `@unchecked Sendable`, an immediate `MainActor.preconditionIsolated()`, then `MainActor.assumeIsolated { [self] ... }`. `swiftc -O -parse-as-library` rejected the closure at line 37 with `task or actor isolated value cannot be sent`; no runnable binary was produced, so VM runtime proof could not begin. This result closes the tested synchronous Swift `loadView()` bridge variants: all six optimized object/executable probes fail under Apple Swift 6.3.3. The earlier `-typecheck` successes were false positives because the region-based sending diagnostic appears during object generation. Production remains frozen at `cc6a8d35c52311223c3d778b74ea1d130aa41812`; there will be no seventh annotation guess or production edit. The next step is independent architecture review of another SDK rendering boundary, followed by optimized compiler proof before integration.
Author
Owner

Root integration status: desktop preview remains exact 3bbb28a6. Reviewer approved isolated diagnostics 2c3d934ecd for issues #9/#11; optimized package compile now running on agents@mbp, with rejected image provider absent. #5 exact 8920c961 hosted build-for-testing passed and runtime staged to VM; tests not yet executed. #12 sixth SDK provider probe failed optimized compilation at assumeIsolated capture despite narrow Sendable bridge; no product fix accepted. Source author and reviewer are investigating next bounded alternative. VM QA owns native Space routing and styled #4/#6 checks. All runtime and performance gates remain explicit; no issue closed based on source review alone.

Root integration status: desktop preview remains exact 3bbb28a6. Reviewer approved isolated diagnostics 2c3d934ecd3eb8f4fa0b1a7848a7b7894ae7b38c for issues #9/#11; optimized package compile now running on agents@mbp, with rejected image provider absent. #5 exact 8920c961 hosted build-for-testing passed and runtime staged to VM; tests not yet executed. #12 sixth SDK provider probe failed optimized compilation at assumeIsolated capture despite narrow Sendable bridge; no product fix accepted. Source author and reviewer are investigating next bounded alternative. VM QA owns native Space routing and styled #4/#6 checks. All runtime and performance gates remain explicit; no issue closed based on source review alone.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Inputs reviewed: /tmp/calternal-provider-isolation-repro/08a-return-view-control.swift and 08b-prepared-sendable-provider.swift; product remains frozen at rejected cc6a8d35c52311223c3d778b74ea1d130aa41812
State: PROBE 08B CONDITIONALLY APPROVED AFTER ONE REQUIRED SOURCE CORRECTION; 08A IS DIAGNOSTIC CONTROL ONLY. No product edit, compiler invocation, test run, or GUI was performed by this reviewer.

Probe 06 is rejected by exact Swift 6.3 optimized compilation: the final stateless provider's @unchecked Sendable conformance plus MainActor.preconditionIsolated() still did not make inherited loadView() provider self sendable into MainActor.assumeIsolated. No executable existed, so it supplied no runtime evidence. All provider loadView override forms are now closed.

P1 — both draft Probe 08 closures still implicitly capture attachment self

Location: /tmp/calternal-provider-isolation-repro/08a-return-view-control.swift:32-34 and 08b-prepared-sendable-provider.swift:48-50.

What breaks: the next optimized compiler submission can repeat the same task-isolated attachment send failure instead of testing the intended Sendable-only bridge.

Why likely: geometry is an instance property. Referring to it unqualified inside either closure implicitly captures attachment self, even though the property's lock handle is declared nonisolated and Sendable. The exact premise is that the actor closure captures the lock value, never the attachment object.

Scoped correction before submission: before MainActor.preconditionIsolated(), assign let drawingGeometry = geometry. Give 08A the explicit closure capture list [drawingGeometry, key]; give 08B [provider, drawingGeometry, key]; and pass drawingGeometry to the view initializer. No closure may reference attachment self, textContainer, layoutManager, parentView, location, or an unqualified instance member.

After that correction, 08A may compile as a useful falsification control, but it is not an approved product architecture: it returns a MainActor-created NSView to nonisolated scope and assigns provider.view outside the statically isolated closure. A compiler pass would establish acceptance by the importer, not the stronger containment desired here.

Corrected 08B is approved for exact compiler and runtime probing. Its source principle is bounded:

  • use a file-private final PreparedProvider: NSTextAttachmentViewProvider, @unchecked Sendable with no stored properties, method overrides, or exposed API;
  • construct that provider through the SDK initializer in the nonisolated attachment factory, where the factory arguments already live;
  • precompute only the compiler-proven Sendable geometry lock handle and optional ObjectIdentifier layout key;
  • call MainActor.preconditionIsolated() immediately before one MainActor.assumeIsolated closure;
  • capture only [provider, drawingGeometry, key]; construct the @MainActor drawing view and assign provider.view entirely inside that closure;
  • after the closure, only return the already prepared provider. Because view is nonnil, AppKit's documented getter does not invoke loadView; there is no custom callback boundary.

The 08B runner is appropriately narrow: it creates a real TextKit 2 content-storage/layout-manager/container chain on MainActor, calls the attachment factory, reads the SDK provider's view getter, and requires the retained drawing view to observe the expected locked state and exact layout-manager identity. Root should first compile the corrected exact file with Swift 6.3 using optimized executable/object emission, then run it. Typecheck-only evidence remains invalid.

If corrected 08B fails optimized compilation or runtime, stop this bridge family. If it passes, the author must propose the product mapping for review before editing, including how the existing image/reference state reaches the drawing view through compiler-proven Sendable state without adding an unbounded shared registry or losing redraw invalidation. The real mounted provider/pixel test remains unchanged. Issue #12 stays open.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Inputs reviewed: `/tmp/calternal-provider-isolation-repro/08a-return-view-control.swift` and `08b-prepared-sendable-provider.swift`; product remains frozen at rejected `cc6a8d35c52311223c3d778b74ea1d130aa41812` State: **PROBE 08B CONDITIONALLY APPROVED AFTER ONE REQUIRED SOURCE CORRECTION; 08A IS DIAGNOSTIC CONTROL ONLY.** No product edit, compiler invocation, test run, or GUI was performed by this reviewer. Probe 06 is rejected by exact Swift 6.3 optimized compilation: the final stateless provider's `@unchecked Sendable` conformance plus `MainActor.preconditionIsolated()` still did not make inherited `loadView()` provider `self` sendable into `MainActor.assumeIsolated`. No executable existed, so it supplied no runtime evidence. All provider `loadView` override forms are now closed. ### P1 — both draft Probe 08 closures still implicitly capture attachment `self` **Location:** `/tmp/calternal-provider-isolation-repro/08a-return-view-control.swift:32-34` and `08b-prepared-sendable-provider.swift:48-50`. **What breaks:** the next optimized compiler submission can repeat the same task-isolated attachment send failure instead of testing the intended Sendable-only bridge. **Why likely:** `geometry` is an instance property. Referring to it unqualified inside either closure implicitly captures attachment `self`, even though the property's lock handle is declared nonisolated and Sendable. The exact premise is that the actor closure captures the lock value, never the attachment object. **Scoped correction before submission:** before `MainActor.preconditionIsolated()`, assign `let drawingGeometry = geometry`. Give 08A the explicit closure capture list `[drawingGeometry, key]`; give 08B `[provider, drawingGeometry, key]`; and pass `drawingGeometry` to the view initializer. No closure may reference attachment `self`, `textContainer`, `layoutManager`, `parentView`, `location`, or an unqualified instance member. After that correction, 08A may compile as a useful falsification control, but it is not an approved product architecture: it returns a MainActor-created `NSView` to nonisolated scope and assigns `provider.view` outside the statically isolated closure. A compiler pass would establish acceptance by the importer, not the stronger containment desired here. Corrected 08B is approved for exact compiler and runtime probing. Its source principle is bounded: - use a file-private final `PreparedProvider: NSTextAttachmentViewProvider, @unchecked Sendable` with no stored properties, method overrides, or exposed API; - construct that provider through the SDK initializer in the nonisolated attachment factory, where the factory arguments already live; - precompute only the compiler-proven Sendable geometry lock handle and optional `ObjectIdentifier` layout key; - call `MainActor.preconditionIsolated()` immediately before one `MainActor.assumeIsolated` closure; - capture only `[provider, drawingGeometry, key]`; construct the `@MainActor` drawing view and assign `provider.view` entirely inside that closure; - after the closure, only return the already prepared provider. Because `view` is nonnil, AppKit's documented getter does not invoke `loadView`; there is no custom callback boundary. The 08B runner is appropriately narrow: it creates a real TextKit 2 content-storage/layout-manager/container chain on MainActor, calls the attachment factory, reads the SDK provider's `view` getter, and requires the retained drawing view to observe the expected locked state and exact layout-manager identity. Root should first compile the corrected exact file with Swift 6.3 using optimized executable/object emission, then run it. Typecheck-only evidence remains invalid. If corrected 08B fails optimized compilation or runtime, stop this bridge family. If it passes, the author must propose the product mapping for review before editing, including how the existing image/reference state reaches the drawing view through compiler-proven Sendable state without adding an unbounded shared registry or losing redraw invalidation. The real mounted provider/pixel test remains unchanged. Issue #12 stays open.
Author
Owner

Root compiler evidence: corrected probe08a SHA42ec1c42495f3ed624d66018fa5f259f77ef1ae2fdc16294340ffdb820f8bf5e passes optimized object emission (-c -O -parse-as-library -swift-version 6) exit0 on agents@mbp. Corrected08b SHA520efa2e7741099b77dc86ed4fe478540893a6e4f5b4e2ba124c3624517ed914 fails optimized executable compilation at actor closure provider capture (task or actor-isolated value cannot be sent). Reviewer now prefers A: plain SDK provider, Sendable geometry/key only captured, returns MainActor view, synchronously assigns provider.view after explicit MainActor precondition; no unchecked conformance. Author preparing executable A with retained view/lock/key assertions, then VM-only runtime. No product changes accepted from these probes yet.

Root compiler evidence: corrected probe08a SHA42ec1c42495f3ed624d66018fa5f259f77ef1ae2fdc16294340ffdb820f8bf5e passes optimized object emission (-c -O -parse-as-library -swift-version 6) exit0 on agents@mbp. Corrected08b SHA520efa2e7741099b77dc86ed4fe478540893a6e4f5b4e2ba124c3624517ed914 fails optimized executable compilation at actor closure provider capture (task or actor-isolated value cannot be sent). Reviewer now prefers A: plain SDK provider, Sendable geometry/key only captured, returns MainActor view, synchronously assigns provider.view after explicit MainActor precondition; no unchecked conformance. Author preparing executable A with retained view/lock/key assertions, then VM-only runtime. No product changes accepted from these probes yet.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Evidence: corrected Probe 08A optimized object compile PASS; Probe 08B optimized executable compile FAIL; product remains frozen at rejected cc6a8d35c52311223c3d778b74ea1d130aa41812
State: PREPARED PLAIN-PROVIDER SHAPE 08A IS THE PREFERRED BOUNDED RUNTIME PROBE. No product source edit, build, test run, or GUI was performed by this reviewer.

The corrected 08A explicitly copies the nonisolated Sendable lock handle to a local and captures only that value plus the optional ObjectIdentifier key in MainActor.assumeIsolated. Exact Apple Swift 6.3 optimized object emission (-c -O -parse-as-library -swift-version 6) exits zero with no diagnostics. This is materially stronger than the earlier false-positive typecheck: SIL/object generation accepts the MainActor-created NSView result leaving the closure.

08B is rejected and no longer needed. Its optimized executable compilation fails at the actor closure even with the final stateless prepared provider marked @unchecked Sendable; capturing the provider remains a task/actor-isolated send. It provides no runtime evidence and should not enter product source.

08A is the narrower architecture because it uses AppKit's plain NSTextAttachmentViewProvider and never subclasses or overrides loadView, never sends/captures the provider, and declares no unchecked conformance. The exact invariant is:

  1. In the SDK-nonisolated attachment factory, compute the layout-manager ObjectIdentifier, copy the compiler-proven Sendable drawing-state handle to a local, and construct the plain provider with the factory's existing attachment/parent/layout/location arguments.
  2. Call MainActor.preconditionIsolated() immediately before view preparation.
  3. Enter MainActor.assumeIsolated with an explicit capture list containing only the Sendable drawing-state handle and identity key; create the @MainActor drawing view there and return it.
  4. With no suspension or intervening callback, assign that returned view to the plain provider's SDK-nonisolated view property and return the prepared provider. The optimized compiler has proven the returned global-actor view can cross this static boundary; the explicit runtime precondition establishes that construction and the immediately following setter execute on the actual MainActor.

The next approved step is an 08A executable probe mirroring 08B's runner: build it with optimized executable emission, create a real TextKit 2 content-storage/layout-manager/container chain in @MainActor main, invoke the attachment factory, read the provider's view getter, and assert the exact prepared view, locked value, and layout-manager identity. Because view is already nonnil, the getter must return it without entering base loadView. A successful run establishes the prepared-provider seam; any precondition failure or missing/replaced view rejects it.

Even after that runtime pass, product editing remains gated on a separate source plan for drawing state. The value captured by the actor closure must remain compiler-proven Sendable and cannot contain NSImage, NSView, NSTextLayoutManager, the attachment, or a mutable global registry. Probe the intended immutable raster representation (for example CGImage) and bounded lock state with optimized emission before use. Redraw invalidation must stay per mounted editor/view and cannot rely on broad shared mutable view state. The real mounted test must retain exact manager identities, disjoint views, unchanged slot frame, A Fit/Fill pixel difference, and B remaining Fit.

No P1/P2/P3 blocker remains for submitting the corrected 08A runtime probe. Issue #12 remains open.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Evidence: corrected Probe 08A optimized object compile PASS; Probe 08B optimized executable compile FAIL; product remains frozen at rejected `cc6a8d35c52311223c3d778b74ea1d130aa41812` State: **PREPARED PLAIN-PROVIDER SHAPE 08A IS THE PREFERRED BOUNDED RUNTIME PROBE.** No product source edit, build, test run, or GUI was performed by this reviewer. The corrected 08A explicitly copies the nonisolated Sendable lock handle to a local and captures only that value plus the optional `ObjectIdentifier` key in `MainActor.assumeIsolated`. Exact Apple Swift 6.3 optimized object emission (`-c -O -parse-as-library -swift-version 6`) exits zero with no diagnostics. This is materially stronger than the earlier false-positive typecheck: SIL/object generation accepts the MainActor-created `NSView` result leaving the closure. 08B is rejected and no longer needed. Its optimized executable compilation fails at the actor closure even with the final stateless prepared provider marked `@unchecked Sendable`; capturing the provider remains a task/actor-isolated send. It provides no runtime evidence and should not enter product source. 08A is the narrower architecture because it uses AppKit's plain `NSTextAttachmentViewProvider` and never subclasses or overrides `loadView`, never sends/captures the provider, and declares no unchecked conformance. The exact invariant is: 1. In the SDK-nonisolated attachment factory, compute the layout-manager `ObjectIdentifier`, copy the compiler-proven Sendable drawing-state handle to a local, and construct the plain provider with the factory's existing attachment/parent/layout/location arguments. 2. Call `MainActor.preconditionIsolated()` immediately before view preparation. 3. Enter `MainActor.assumeIsolated` with an explicit capture list containing only the Sendable drawing-state handle and identity key; create the `@MainActor` drawing view there and return it. 4. With no suspension or intervening callback, assign that returned view to the plain provider's SDK-nonisolated `view` property and return the prepared provider. The optimized compiler has proven the returned global-actor view can cross this static boundary; the explicit runtime precondition establishes that construction and the immediately following setter execute on the actual MainActor. The next approved step is an 08A executable probe mirroring 08B's runner: build it with optimized executable emission, create a real TextKit 2 content-storage/layout-manager/container chain in `@MainActor main`, invoke the attachment factory, read the provider's `view` getter, and assert the exact prepared view, locked value, and layout-manager identity. Because `view` is already nonnil, the getter must return it without entering base `loadView`. A successful run establishes the prepared-provider seam; any precondition failure or missing/replaced view rejects it. Even after that runtime pass, product editing remains gated on a separate source plan for drawing state. The value captured by the actor closure must remain compiler-proven Sendable and cannot contain `NSImage`, `NSView`, `NSTextLayoutManager`, the attachment, or a mutable global registry. Probe the intended immutable raster representation (for example `CGImage`) and bounded lock state with optimized emission before use. Redraw invalidation must stay per mounted editor/view and cannot rely on broad shared mutable view state. The real mounted test must retain exact manager identities, disjoint views, unchanged slot frame, A Fit/Fill pixel difference, and B remaining Fit. No P1/P2/P3 blocker remains for submitting the corrected 08A runtime probe. Issue #12 remains open.
Author
Owner

Thread: /root/image_preview_native_repair (wave16/image-controls)

Compiler probe update: corrected control 08A passed exact Apple Swift 6.3.3 optimized object compilation (-c -O -parse-as-library). It creates a plain NSTextAttachmentViewProvider; the checked MainActor.assumeIsolated closure captures only an OSAllocatedUnfairLock<Sendable Geometry> and an optional ObjectIdentifier, returns the newly created NSView, and the nonisolated factory installs that returned view on the provider. Corrected 08B still failed when its closure captured the provider, even though that provider was stateless and declared Sendable. This leaves one compiler-proven source shape with no unchecked conformance. The 08A optimized executable also compiled; VM runtime identity checks are pending.

Conditional production mapping, frozen until the VM probe and reviewer gate:

  • Delete the custom provider subclass and every loadView() override. The attachment factory creates a plain AppKit provider and immediately calls MainActor.preconditionIsolated().
  • Before the closure, copy only the attachment's existing OSAllocatedUnfairLock and the target layout manager's ObjectIdentifier. The closure captures those values explicitly and constructs the drawing view; it does not capture the attachment, text layout manager, text container, provider, or factory self.
  • Extend the lock's Sendable geometry with an immutable CGImage snapshot extracted on MainActor when an image is installed. The drawing view stores a @Sendable snapshot reader over the lock and key, so every native draw reads the current image dimensions and that mounted editor's Fit/Fill state. It never retains or calls the attachment/layout manager.
  • Keep Auto/custom on the existing attachment-cell fallback. Only Large asks for a view provider. Keep the exact 640-by-220-bounded attachment geometry unchanged.
  • Replace drawing diagnostics' layout-manager object with the already computed optional identity. The strict mounted test continues to require distinct native views, exact manager identities, equal Fit/Fill frames, and visibly different clipped pixels.
  • Remove the weak drawing-view registry. Source-image completion already invalidates editor layout through onGeometryChange; Fit mutation already invalidates the exact attachment range and marks the owning BlockEditorView for display. Those existing native invalidations must drive redraw in the unchanged mounted regression. If they do not, the test remains a blocker rather than adding a cross-actor registry.
  • clearPresentation continues to remove only the detached layout manager's keyed Fit state. No raster cache or new global registry is introduced.

No production source has changed for this plan. Candidate review and exact package/runtime tests remain required.

Thread: `/root/image_preview_native_repair` (`wave16/image-controls`) Compiler probe update: corrected control 08A passed exact Apple Swift 6.3.3 optimized object compilation (`-c -O -parse-as-library`). It creates a plain `NSTextAttachmentViewProvider`; the checked `MainActor.assumeIsolated` closure captures only an `OSAllocatedUnfairLock<Sendable Geometry>` and an optional `ObjectIdentifier`, returns the newly created `NSView`, and the nonisolated factory installs that returned view on the provider. Corrected 08B still failed when its closure captured the provider, even though that provider was stateless and declared Sendable. This leaves one compiler-proven source shape with no unchecked conformance. The 08A optimized executable also compiled; VM runtime identity checks are pending. Conditional production mapping, frozen until the VM probe and reviewer gate: - Delete the custom provider subclass and every `loadView()` override. The attachment factory creates a plain AppKit provider and immediately calls `MainActor.preconditionIsolated()`. - Before the closure, copy only the attachment's existing `OSAllocatedUnfairLock` and the target layout manager's `ObjectIdentifier`. The closure captures those values explicitly and constructs the drawing view; it does not capture the attachment, text layout manager, text container, provider, or factory `self`. - Extend the lock's Sendable geometry with an immutable `CGImage` snapshot extracted on MainActor when an image is installed. The drawing view stores a `@Sendable` snapshot reader over the lock and key, so every native draw reads the current image dimensions and that mounted editor's Fit/Fill state. It never retains or calls the attachment/layout manager. - Keep Auto/custom on the existing attachment-cell fallback. Only Large asks for a view provider. Keep the exact 640-by-220-bounded attachment geometry unchanged. - Replace drawing diagnostics' layout-manager object with the already computed optional identity. The strict mounted test continues to require distinct native views, exact manager identities, equal Fit/Fill frames, and visibly different clipped pixels. - Remove the weak drawing-view registry. Source-image completion already invalidates editor layout through `onGeometryChange`; Fit mutation already invalidates the exact attachment range and marks the owning `BlockEditorView` for display. Those existing native invalidations must drive redraw in the unchanged mounted regression. If they do not, the test remains a blocker rather than adding a cross-actor registry. - `clearPresentation` continues to remove only the detached layout manager's keyed Fit state. No raster cache or new global registry is introduced. No production source has changed for this plan. Candidate review and exact package/runtime tests remain required.
Author
Owner

Worker /root/title_completion — exact probe 08a bounded VM runtime result: PASS.

Root explicitly granted this one direct-SSH runtime check after the optimized Swift 6.3 compile passed. No compiler, test bundle, Calternal app, window, or GUI process was invoked by this task.

  • Source: /Users/agents/Developer/BuildOnly/provider-isolation-probe-20260913-root/08a-runtime.swift
  • Source SHA-256: 570be0008fc2e70c6f70a8c7da7ed78810d6c5d11a42eb0f6eaac97a9ef8d5b9
  • Builder executable: /Users/agents/Developer/BuildOnly/provider-isolation-probe-20260913-root/probe08a-runtime
  • VM executable: /Users/lume/CalternalQA/provider-isolation-probe-08a/probe08a-runtime
  • Executable SHA-256 before transfer, as VM partial, after atomic publication, and after execution: 527e388d896e4839e515fb56e7813626ddf904ecec5f53efe702e42b96797089
  • VM executable: 64,640 bytes, mode 0555
  • Direct execution exit code: 0
  • Stdout: PASS returned main-actor view and plain provider identities
  • Stderr: empty

VM evidence directory: /Users/lume/CalternalQA/provider-isolation-probe-08a/run-20260913-110414/.

  • stdout.txt SHA-256: 5d489666d959b8e8e07a85c164eb5c1318a1d63ac08c45a500d96100f2228097
  • stderr.txt SHA-256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
  • exit-code.txt SHA-256: 9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa
  • binary-sha256.txt SHA-256: 31604b985a883f9bc2194b678a895d4890b1ad2a5b45db361583d75ecc3bc642

The runtime constructs the attachment, layout manager, provider, and preinstalled drawing view on the main actor; it asserts attachment identity, layout-manager identity, shared geometry state, and the 64×32 frame. This result supports mapping probe 08a into a reviewed product candidate. It does not prove mounted TextKit rendering, Fit/Fill behavior, toolbar behavior, performance, delivery, or user acceptance; those #12 gates remain open.

Worker `/root/title_completion` — exact probe 08a bounded VM runtime result: **PASS**. Root explicitly granted this one direct-SSH runtime check after the optimized Swift 6.3 compile passed. No compiler, test bundle, Calternal app, window, or GUI process was invoked by this task. - Source: `/Users/agents/Developer/BuildOnly/provider-isolation-probe-20260913-root/08a-runtime.swift` - Source SHA-256: `570be0008fc2e70c6f70a8c7da7ed78810d6c5d11a42eb0f6eaac97a9ef8d5b9` - Builder executable: `/Users/agents/Developer/BuildOnly/provider-isolation-probe-20260913-root/probe08a-runtime` - VM executable: `/Users/lume/CalternalQA/provider-isolation-probe-08a/probe08a-runtime` - Executable SHA-256 before transfer, as VM partial, after atomic publication, and after execution: `527e388d896e4839e515fb56e7813626ddf904ecec5f53efe702e42b96797089` - VM executable: 64,640 bytes, mode `0555` - Direct execution exit code: `0` - Stdout: `PASS returned main-actor view and plain provider identities` - Stderr: empty VM evidence directory: `/Users/lume/CalternalQA/provider-isolation-probe-08a/run-20260913-110414/`. - `stdout.txt` SHA-256: `5d489666d959b8e8e07a85c164eb5c1318a1d63ac08c45a500d96100f2228097` - `stderr.txt` SHA-256: `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855` - `exit-code.txt` SHA-256: `9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa` - `binary-sha256.txt` SHA-256: `31604b985a883f9bc2194b678a895d4890b1ad2a5b45db361583d75ecc3bc642` The runtime constructs the attachment, layout manager, provider, and preinstalled drawing view on the main actor; it asserts attachment identity, layout-manager identity, shared geometry state, and the 64×32 frame. This result supports mapping probe 08a into a reviewed product candidate. It does not prove mounted TextKit rendering, Fit/Fill behavior, toolbar behavior, performance, delivery, or user acceptance; those #12 gates remain open.
Author
Owner

Worker /root/title_completion — probe 08a evidence follow-up: the VM-generated structured receipt was copied byte-for-byte to /Users/kayg/Developer/calternal-app/.agents/wave16/provider-08a-runtime-receipt.json, made read-only (0444), and parsed as JSON. VM and local receipt SHA-256 are both b68744bd3ca84e293e8d08790571c27d6ab1f2160118f10834b014e7d797cf25. It records exit 0, exact PASS stdout, empty stderr, source/binary hashes, and appLaunchInvoked: false / guiInvoked: false, allowing root to verify the runtime result independently.

Worker `/root/title_completion` — probe 08a evidence follow-up: the VM-generated structured receipt was copied byte-for-byte to `/Users/kayg/Developer/calternal-app/.agents/wave16/provider-08a-runtime-receipt.json`, made read-only (`0444`), and parsed as JSON. VM and local receipt SHA-256 are both `b68744bd3ca84e293e8d08790571c27d6ab1f2160118f10834b014e7d797cf25`. It records exit 0, exact PASS stdout, empty stderr, source/binary hashes, and `appLaunchInvoked: false` / `guiInvoked: false`, allowing root to verify the runtime result independently.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Probe evidence: corrected 08A optimized executable VM PASS; source SHA-256 570be0008fc2e70c6f70a8c7da7ed78810d6c5d11a42eb0f6eaac97a9ef8d5b9; binary SHA-256 527e388d896e4839e515fb56e7813626ddf904ecec5f53efe702e42b96797089
State: PLAIN-PROVIDER PRODUCT MAPPING PLAN PASS — implementation may proceed within the bounds below. No product source edit, build, test run, or GUI was performed in this reviewer lane.

The exact optimized executable and VM run now establish the prepared-provider seam: a real MainActor TextKit 2 chain returned the expected MainActor-created view from a plain NSTextAttachmentViewProvider, retained the exact provider/view identities, and observed the expected locked value and layout-manager identity. There is no provider subclass, loadView() override, unchecked conformance, or delayed hop.

The proposed product mapping is the smallest safe correction to Sources/CalternalEditor/EditorImagePresentation.swift:

  • In EditorImageAttachment.viewProvider(for:location:textContainer:) (currently lines 424-435), retain the Large-only locked guard. Copy the existing OSAllocatedUnfairLock and textContainer?.textLayoutManager.map(ObjectIdentifier.init) into locals, construct a plain SDK provider from the factory arguments, call MainActor.preconditionIsolated() immediately, then construct the drawing view in one MainActor.assumeIsolated closure with an explicit capture list containing only the lock and optional identity. Assign the returned view synchronously to provider.view and return the prepared provider. The closure must not capture attachment self, provider, parent view, text container, layout manager, or location.
  • Extend locked Geometry (currently lines 312-321) with a compiler-proven Sendable immutable raster and return a small Sendable drawing snapshot containing that raster, the existing point-space imageSize, and only mounted[key]?.fit ?? .fit. Keep imageSize derived from NSImage.size; do not substitute CGImage.width/height, because layout is currently defined in AppKit points and changing to pixels can alter high-resolution image geometry.
  • Update the raster at the existing MainActor updateGeometry() seam (currently lines 534-540), atomically with imageSize and fallback bounds. Clearing or replacing image must clear or replace the raster in the same lock update so an existing Large view cannot draw the prior URL after updateReference. The current loader creates each cached NSImage from a CGImage, so this extraction stays bounded to the existing decoded representation. The intended Geometry/snapshot declarations must independently pass optimized Swift 6.3 emission with no unchecked wrapper.
  • EditorImageDrawingView (currently lines 687-733) may retain the Sendable snapshot reader and layout identity, but no attachment or layout-manager reference. To preserve the current NSImage.draw(... respectFlipped: true) orientation, color handling, and interpolation without allocating on every draw, cache a MainActor-local NSImage(cgImage:size:) per raster identity/point size in the view and reuse the existing clipped draw helper. Reset that cache when the snapshot raster changes or becomes nil. Do not derive layout dimensions from this cached wrapper.
  • Replace diagnostics' NSTextLayoutManager? payload with the already captured ObjectIdentifier?; remove EditorImageAttachmentViewProvider, the weak drawingViews table, registration, and invalidateDrawingViews() calls. The diagnostic remains observational and MainActor-only.

The registry-free invalidation premise matches the current source paths. Image completion calls onGeometryChange at EditorImagePresentation.swift:139-144; BlockEditorView.swift:544-547 routes that to invalidateTextLayout(), which invalidates the full TextKit range and sets layout/display dirty at lines 501-507. Fit mutation invalidates the exact attachment text range at EditorImagePresentation.swift:251-256, and BlockEditorView.setSelectedImageFit marks the owning editor for display at line 1276. Canonical size edits refresh projection and mark layout/display dirty through refreshProjectionLayout() at lines 2518-2527. clearPresentation may simply remove the detached manager key; it does not need to redraw a detached mount.

Those calls are a source-level justification, not proof that AppKit propagates dirtiness to an existing attachment subview. Keep the mounted regression unchanged as the acceptance gate: actual provider draws for exact manager A in Fit and Fill, manager B still Fit, disjoint view identities, identical slot frame, and different cached pixels. Its asynchronous image-load loop also verifies that a provider created before image completion displays the new raster. If any draw/pixel assertion fails, stop and review the exact invalidation evidence; do not restore a cross-actor weak registry or weaken/directly invoke the draw assertion.

No P1/P2/P3 plan finding remains. Next action: author implements only this mapping, freezes an exact commit, and submits its diff for review before root runs the Swift 6.3 Release package build and focused mounted runtime test. Issue #12 remains open through build, VM interaction, delivery, and user acceptance.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Probe evidence: corrected 08A optimized executable VM PASS; source SHA-256 `570be0008fc2e70c6f70a8c7da7ed78810d6c5d11a42eb0f6eaac97a9ef8d5b9`; binary SHA-256 `527e388d896e4839e515fb56e7813626ddf904ecec5f53efe702e42b96797089` State: **PLAIN-PROVIDER PRODUCT MAPPING PLAN PASS — implementation may proceed within the bounds below.** No product source edit, build, test run, or GUI was performed in this reviewer lane. The exact optimized executable and VM run now establish the prepared-provider seam: a real MainActor TextKit 2 chain returned the expected MainActor-created view from a plain `NSTextAttachmentViewProvider`, retained the exact provider/view identities, and observed the expected locked value and layout-manager identity. There is no provider subclass, `loadView()` override, unchecked conformance, or delayed hop. The proposed product mapping is the smallest safe correction to `Sources/CalternalEditor/EditorImagePresentation.swift`: - In `EditorImageAttachment.viewProvider(for:location:textContainer:)` (currently lines 424-435), retain the Large-only locked guard. Copy the existing `OSAllocatedUnfairLock` and `textContainer?.textLayoutManager.map(ObjectIdentifier.init)` into locals, construct a plain SDK provider from the factory arguments, call `MainActor.preconditionIsolated()` immediately, then construct the drawing view in one `MainActor.assumeIsolated` closure with an explicit capture list containing only the lock and optional identity. Assign the returned view synchronously to `provider.view` and return the prepared provider. The closure must not capture attachment `self`, provider, parent view, text container, layout manager, or location. - Extend locked `Geometry` (currently lines 312-321) with a compiler-proven Sendable immutable raster and return a small Sendable drawing snapshot containing that raster, the existing point-space `imageSize`, and only `mounted[key]?.fit ?? .fit`. Keep `imageSize` derived from `NSImage.size`; do not substitute `CGImage.width/height`, because layout is currently defined in AppKit points and changing to pixels can alter high-resolution image geometry. - Update the raster at the existing MainActor `updateGeometry()` seam (currently lines 534-540), atomically with `imageSize` and fallback bounds. Clearing or replacing `image` must clear or replace the raster in the same lock update so an existing Large view cannot draw the prior URL after `updateReference`. The current loader creates each cached `NSImage` from a `CGImage`, so this extraction stays bounded to the existing decoded representation. The intended `Geometry`/snapshot declarations must independently pass optimized Swift 6.3 emission with no unchecked wrapper. - `EditorImageDrawingView` (currently lines 687-733) may retain the Sendable snapshot reader and layout identity, but no attachment or layout-manager reference. To preserve the current `NSImage.draw(... respectFlipped: true)` orientation, color handling, and interpolation without allocating on every draw, cache a MainActor-local `NSImage(cgImage:size:)` per raster identity/point size in the view and reuse the existing clipped draw helper. Reset that cache when the snapshot raster changes or becomes nil. Do not derive layout dimensions from this cached wrapper. - Replace diagnostics' `NSTextLayoutManager?` payload with the already captured `ObjectIdentifier?`; remove `EditorImageAttachmentViewProvider`, the weak `drawingViews` table, registration, and `invalidateDrawingViews()` calls. The diagnostic remains observational and MainActor-only. The registry-free invalidation premise matches the current source paths. Image completion calls `onGeometryChange` at `EditorImagePresentation.swift:139-144`; `BlockEditorView.swift:544-547` routes that to `invalidateTextLayout()`, which invalidates the full TextKit range and sets layout/display dirty at lines 501-507. Fit mutation invalidates the exact attachment text range at `EditorImagePresentation.swift:251-256`, and `BlockEditorView.setSelectedImageFit` marks the owning editor for display at line 1276. Canonical size edits refresh projection and mark layout/display dirty through `refreshProjectionLayout()` at lines 2518-2527. `clearPresentation` may simply remove the detached manager key; it does not need to redraw a detached mount. Those calls are a source-level justification, not proof that AppKit propagates dirtiness to an existing attachment subview. Keep the mounted regression unchanged as the acceptance gate: actual provider draws for exact manager A in Fit and Fill, manager B still Fit, disjoint view identities, identical slot frame, and different cached pixels. Its asynchronous image-load loop also verifies that a provider created before image completion displays the new raster. If any draw/pixel assertion fails, stop and review the exact invalidation evidence; do not restore a cross-actor weak registry or weaken/directly invoke the draw assertion. No P1/P2/P3 plan finding remains. Next action: author implements only this mapping, freezes an exact commit, and submits its diff for review before root runs the Swift 6.3 Release package build and focused mounted runtime test. Issue #12 remains open through build, VM interaction, delivery, and user acceptance.
Author
Owner

Thread: /root/image_preview_native_repair (wave16/image-controls)

Source candidate: exact 57364fa4fcac23cc9fc12c58094fc5442de0bf74, clean isolated worktree. This replaces the Swift 6.3-invalid custom loadView() bridge with the compiler- and VM-proven 08A shape: a plain NSTextAttachmentViewProvider, immediate main-actor precondition, and an actor closure that captures only the existing Sendable geometry lock and layout-manager identity and returns the native drawing view. The provider, attachment, layout manager, text container, and factory self do not enter that closure.

The geometry lock now atomically holds the immutable source CGImage, point-space image size, size mode, and per-mounted-manager Fit state. Each drawing view reads a current snapshot through a Sendable closure and caches its MainActor NSImage wrapper by raster identity and point size, avoiding per-draw allocation. The custom provider subclass and weak drawing-view registry are gone. Existing source completion, exact-range layout invalidation, and editor redraw requests remain the only invalidation path.

The mounted regression remains strict: distinct native views per editor, exact manager identity, equal Fit/Fill frames, visible pixel differences, and independent Fit state. Its diagnostic payload now receives the precomputed manager identity rather than retaining an NSTextLayoutManager. git diff --check passes. No local build or GUI run. Exact candidate review, package compilation, and the mounted VM pixel test remain pending; only standalone probe 08A has compiled and run successfully so far.

Thread: `/root/image_preview_native_repair` (`wave16/image-controls`) Source candidate: exact `57364fa4fcac23cc9fc12c58094fc5442de0bf74`, clean isolated worktree. This replaces the Swift 6.3-invalid custom `loadView()` bridge with the compiler- and VM-proven 08A shape: a plain `NSTextAttachmentViewProvider`, immediate main-actor precondition, and an actor closure that captures only the existing Sendable geometry lock and layout-manager identity and returns the native drawing view. The provider, attachment, layout manager, text container, and factory `self` do not enter that closure. The geometry lock now atomically holds the immutable source `CGImage`, point-space image size, size mode, and per-mounted-manager Fit state. Each drawing view reads a current snapshot through a Sendable closure and caches its MainActor `NSImage` wrapper by raster identity and point size, avoiding per-draw allocation. The custom provider subclass and weak drawing-view registry are gone. Existing source completion, exact-range layout invalidation, and editor redraw requests remain the only invalidation path. The mounted regression remains strict: distinct native views per editor, exact manager identity, equal Fit/Fill frames, visible pixel differences, and independent Fit state. Its diagnostic payload now receives the precomputed manager identity rather than retaining an `NSTextLayoutManager`. `git diff --check` passes. No local build or GUI run. Exact candidate review, package compilation, and the mounted VM pixel test remain pending; only standalone probe 08A has compiled and run successfully so far.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Candidate: exact 57364fa4fcac23cc9fc12c58094fc5442de0bf74 atop rejected provider source cc6a8d35c52311223c3d778b74ea1d130aa41812
State: PLAIN-PROVIDER PRODUCT SOURCE REVIEW PASS — no P1/P2/P3 findings. Worktree is clean and git diff --check cc6a8d35..57364fa4 passes. Per lane ownership, no compiler, test runner, app, or GUI was invoked.

The exact two-file, +65/-55 delta implements the approved and VM-proven 08A mapping without retaining the rejected provider bridge:

  • Sources/CalternalEditor/EditorImagePresentation.swift:422-457 keeps the locked Large-only gate, precomputes the exact layout-manager ObjectIdentifier, copies the existing Sendable geometry lock, and gives the drawing view a @Sendable snapshot reader over only those values. The MainActor.assumeIsolated capture list contains only that reader and identity. It does not capture attachment self, the plain provider, parent view, text container, layout manager, or location. A plain SDK provider receives the returned view synchronously after MainActor.preconditionIsolated; there is no provider subclass, loadView() override, unchecked conformance, asynchronous hop, or mutable global registry.
  • Locked Geometry at lines 316-322 adds only immutable CGImage?. updateGeometry() at lines 545-558 extracts it on the attachment's MainActor and writes raster, the existing NSImage.size point dimensions, and fallback bounds in one lock transaction. Reference replacement clears image before this update, so the raster clears with it; image installation replaces both together. Large layout continues to use point dimensions rather than CGImage pixels. Extraction is change-driven through the existing reference/image geometry update seams, not hover or draw.
  • EditorImageDrawingSnapshot and EditorImageDrawingView at lines 667-744 contain no attachment or layout-manager objects. Each draw takes one locked immutable snapshot for its exact manager identity. The view resets cached state when raster becomes nil and rebuilds its MainActor-local NSImage only when raster identity or point size changes, then reuses the existing clipped NSImage.draw(... respectFlipped: true) helper. This preserves orientation, color/interpolation behavior, and avoids per-draw image construction during scrolling.
  • The weak drawing-view registry and all direct cross-mount redraw calls are removed. Existing image-load, size-edit, and Fit invalidation paths remain unchanged. Whether AppKit propagates those invalidations to an already mounted attachment view is intentionally a runtime gate, not assumed source proof.
  • Tests/CalternalEditorTests/EditorImageControlsTests.swift:372-565 changes only the diagnostic payload from a layout-manager object to the already computed identity. The test still requires actual drawing callbacks for editor A in Fit and Fill, editor B in Fit, disjoint view identities, identical native slot frames, visibly different cached pixels, and retained per-manager state. No helper is directly drawn and no assertion is weakened.

No source-level behavior, isolation, lifetime, cache-clearing, or test-strength finding remains at this exact SHA. Root should now run the exact Swift 6.3 optimized Release package build, then the focused mounted test on the VM. A compile diagnostic around CGImage Sendable conformance or any missing Fit/Fill draw/pixel observation blocks this candidate and returns to the author; it is not grounds to add an unchecked wrapper, restore the registry, or weaken the test. Issue #12 remains open through runtime interaction, performance evidence, delivery, and user acceptance.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Candidate: exact `57364fa4fcac23cc9fc12c58094fc5442de0bf74` atop rejected provider source `cc6a8d35c52311223c3d778b74ea1d130aa41812` State: **PLAIN-PROVIDER PRODUCT SOURCE REVIEW PASS — no P1/P2/P3 findings.** Worktree is clean and `git diff --check cc6a8d35..57364fa4` passes. Per lane ownership, no compiler, test runner, app, or GUI was invoked. The exact two-file, `+65/-55` delta implements the approved and VM-proven 08A mapping without retaining the rejected provider bridge: - `Sources/CalternalEditor/EditorImagePresentation.swift:422-457` keeps the locked Large-only gate, precomputes the exact layout-manager `ObjectIdentifier`, copies the existing Sendable geometry lock, and gives the drawing view a `@Sendable` snapshot reader over only those values. The `MainActor.assumeIsolated` capture list contains only that reader and identity. It does not capture attachment `self`, the plain provider, parent view, text container, layout manager, or location. A plain SDK provider receives the returned view synchronously after `MainActor.preconditionIsolated`; there is no provider subclass, `loadView()` override, unchecked conformance, asynchronous hop, or mutable global registry. - Locked `Geometry` at lines 316-322 adds only immutable `CGImage?`. `updateGeometry()` at lines 545-558 extracts it on the attachment's MainActor and writes raster, the existing `NSImage.size` point dimensions, and fallback bounds in one lock transaction. Reference replacement clears `image` before this update, so the raster clears with it; image installation replaces both together. Large layout continues to use point dimensions rather than CGImage pixels. Extraction is change-driven through the existing reference/image geometry update seams, not hover or draw. - `EditorImageDrawingSnapshot` and `EditorImageDrawingView` at lines 667-744 contain no attachment or layout-manager objects. Each draw takes one locked immutable snapshot for its exact manager identity. The view resets cached state when raster becomes nil and rebuilds its MainActor-local `NSImage` only when raster identity or point size changes, then reuses the existing clipped `NSImage.draw(... respectFlipped: true)` helper. This preserves orientation, color/interpolation behavior, and avoids per-draw image construction during scrolling. - The weak drawing-view registry and all direct cross-mount redraw calls are removed. Existing image-load, size-edit, and Fit invalidation paths remain unchanged. Whether AppKit propagates those invalidations to an already mounted attachment view is intentionally a runtime gate, not assumed source proof. - `Tests/CalternalEditorTests/EditorImageControlsTests.swift:372-565` changes only the diagnostic payload from a layout-manager object to the already computed identity. The test still requires actual drawing callbacks for editor A in Fit and Fill, editor B in Fit, disjoint view identities, identical native slot frames, visibly different cached pixels, and retained per-manager state. No helper is directly drawn and no assertion is weakened. No source-level behavior, isolation, lifetime, cache-clearing, or test-strength finding remains at this exact SHA. Root should now run the exact Swift 6.3 optimized Release package build, then the focused mounted test on the VM. A compile diagnostic around `CGImage` Sendable conformance or any missing Fit/Fill draw/pixel observation blocks this candidate and returns to the author; it is not grounds to add an unchecked wrapper, restore the registry, or weaken the test. Issue #12 remains open through runtime interaction, performance evidence, delivery, and user acceptance.
Author
Owner

Root integrated reviewed #12 product candidate57364fa4fcac23cc9fc12c58094fc5442de0bf74 as f8319e26 on editor-overnight-combined. This replaces failing provider subclass with VM-proven plain provider seam, Sendable raster snapshot and drawing-view cache. Root read/hash-verified 08a VM receipt b68744bd3ca84e293e8d08790571c27d6ab1f2160118f10834b014e7d797cf25, exit0. Exact combined optimized package compile now running on agents@mbp. Mounted Fit/Fill pixel test still required; no app fix/runtime acceptance claimed. Desktop remains3bbb.

Root integrated reviewed #12 product candidate57364fa4fcac23cc9fc12c58094fc5442de0bf74 as f8319e26 on editor-overnight-combined. This replaces failing provider subclass with VM-proven plain provider seam, Sendable raster snapshot and drawing-view cache. Root read/hash-verified 08a VM receipt b68744bd3ca84e293e8d08790571c27d6ab1f2160118f10834b014e7d797cf25, exit0. Exact combined optimized package compile now running on agents@mbp. Mounted Fit/Fill pixel test still required; no app fix/runtime acceptance claimed. Desktop remains3bbb.
Author
Owner

QA / /root/title_controls_runtime_qa is awaiting the exact staged VM package-test archive for compiled revision f8319e26f4f58ea71bdf8d01647da480bccd7f86.

Planned runtime scope: strict ten-test CalternalEditorTests.EditorImageControlsTests suite plus mounted image geometry identity selector. Gates require nonempty actual draw observation and passing per-layout-manager Fit/slot/pixel assertions; no assertion threshold changes. QA owns VM execution only, preserves source/fixture state, and will publish archive provenance, commands, test counts, traces, and outcome here and #20.

QA / `/root/title_controls_runtime_qa` is awaiting the exact staged VM package-test archive for compiled revision `f8319e26f4f58ea71bdf8d01647da480bccd7f86`. Planned runtime scope: strict ten-test `CalternalEditorTests.EditorImageControlsTests` suite plus mounted image geometry identity selector. Gates require nonempty actual draw observation and passing per-layout-manager Fit/slot/pixel assertions; no assertion threshold changes. QA owns VM execution only, preserves source/fixture state, and will publish archive provenance, commands, test counts, traces, and outcome here and #20.
Author
Owner

Worker /root/title_completion — exact reviewed #12 product candidate f8319e26f4f58ea71bdf8d01647da480bccd7f86 is compiled, packaged, and atomically staged for VM tests. No test or app process was launched by this task.

  • Build evidence: /Users/agents/Developer/BuildOnly/package-tests-d40/Evidence/package-tests/20260913T181107Z-central-f8319e26-combined-f2a6d9e1
  • Optimized package compiler returned 0 in 32.654 seconds; stage helper returned 0.
  • Result records compileOnly: true, swiftTestInvoked: false, xctestInvoked: false, testsExecuted: false.
  • result.json SHA-256: 8bc7d501b2ce962bab233c4b7dc66f38eb337fda7b564aa4bd5418079cfb6859
  • Swift build log SHA-256: 337d54ea99d07c52e8f22420a87ebdbaf89d619c055003ef48e32e9e4b3f85c9
  • Stage log SHA-256: d9f851d8406c867d48b67cfb6758a7c63cd73f330ed8a02b56c4f02c7752ddc2
  • Bundle inspection SHA-256: 952adbb24080f308cd23b21adc05815e1b67da99e8f969dd18c6380222ee8bf8
  • Embedded manifest SHA-256: 776837c06d2b9b9226adde4f5a3286e63dc36f1ea808172d90588da15849716a
  • Package test executable SHA-256: 99dff017ef8198220f2b6f1a62e03b38136b4b8e0d6456f7caa45a7315aa565c

Builder archive: /Users/agents/Developer/BuildOnly/package-tests-d40/Evidence/package-tests/20260913T181107Z-central-f8319e26-combined-f2a6d9e1/vm-xctest-runtime-f8319e26-f2a6d9e1.tar.

VM archive: /Users/lume/CalternalQA/f8319e26-image-runtime/vm-xctest-runtime-f8319e26-f2a6d9e1.tar, SHA-256 8c0114e0a307c2dd39b6639a34c3d7c2493efbc484f7e874b021711438126984, 85,731,840 bytes, mode 0444; same-name partial is absent. The first delta stream ended early and left an unpublished partial whose hash did not match. A checksum-forced delta corrected it; only the exact full-hash match was atomically renamed to the final path.

QA /root/title_controls_runtime_qa received a triggered follow-up with the exact archive, hashes, proven direct package-XCTest environment, and selectors: full CalternalEditorTests.EditorImageControlsTests plus CalternalEditorTests.EditorImageGeometryTests/testMountedEditorHitsExactInlineImageFramesAcrossFragments. Runtime Fit/Fill pixels, provider/view identities, image targeting, GUI behavior, performance, delivery, and user acceptance remain unverified.

Worker `/root/title_completion` — exact reviewed #12 product candidate `f8319e26f4f58ea71bdf8d01647da480bccd7f86` is compiled, packaged, and atomically staged for VM tests. **No test or app process was launched by this task.** - Build evidence: `/Users/agents/Developer/BuildOnly/package-tests-d40/Evidence/package-tests/20260913T181107Z-central-f8319e26-combined-f2a6d9e1` - Optimized package compiler returned 0 in 32.654 seconds; stage helper returned 0. - Result records `compileOnly: true`, `swiftTestInvoked: false`, `xctestInvoked: false`, `testsExecuted: false`. - `result.json` SHA-256: `8bc7d501b2ce962bab233c4b7dc66f38eb337fda7b564aa4bd5418079cfb6859` - Swift build log SHA-256: `337d54ea99d07c52e8f22420a87ebdbaf89d619c055003ef48e32e9e4b3f85c9` - Stage log SHA-256: `d9f851d8406c867d48b67cfb6758a7c63cd73f330ed8a02b56c4f02c7752ddc2` - Bundle inspection SHA-256: `952adbb24080f308cd23b21adc05815e1b67da99e8f969dd18c6380222ee8bf8` - Embedded manifest SHA-256: `776837c06d2b9b9226adde4f5a3286e63dc36f1ea808172d90588da15849716a` - Package test executable SHA-256: `99dff017ef8198220f2b6f1a62e03b38136b4b8e0d6456f7caa45a7315aa565c` Builder archive: `/Users/agents/Developer/BuildOnly/package-tests-d40/Evidence/package-tests/20260913T181107Z-central-f8319e26-combined-f2a6d9e1/vm-xctest-runtime-f8319e26-f2a6d9e1.tar`. VM archive: `/Users/lume/CalternalQA/f8319e26-image-runtime/vm-xctest-runtime-f8319e26-f2a6d9e1.tar`, SHA-256 `8c0114e0a307c2dd39b6639a34c3d7c2493efbc484f7e874b021711438126984`, 85,731,840 bytes, mode `0444`; same-name partial is absent. The first delta stream ended early and left an unpublished partial whose hash did not match. A checksum-forced delta corrected it; only the exact full-hash match was atomically renamed to the final path. QA `/root/title_controls_runtime_qa` received a triggered follow-up with the exact archive, hashes, proven direct package-XCTest environment, and selectors: full `CalternalEditorTests.EditorImageControlsTests` plus `CalternalEditorTests.EditorImageGeometryTests/testMountedEditorHitsExactInlineImageFramesAcrossFragments`. Runtime Fit/Fill pixels, provider/view identities, image targeting, GUI behavior, performance, delivery, and user acceptance remain unverified.
Author
Owner

QA VM package runtime, exact f8319e26f4f58ea71bdf8d01647da480bccd7f86.

Provenance matched: archive SHA-256 8c0114e0a307c2dd39b6639a34c3d7c2493efbc484f7e874b021711438126984, mode 0444, size 85731840; manifest 776837c06d2b9b9226adde4f5a3286e63dc36f1ea808172d90588da15849716a; test binary 99dff017ef8198220f2b6f1a62e03b38136b4b8e0d6456f7caa45a7315aa565c. Fresh VM extraction /private/tmp/qa-f831-1789323429; isolated TMPDIRs and direct package XCTest runtime paths were used.

CalternalEditorTests.EditorImageControlsTests: 10 tests executed, 1 failure, 0 unexpected, 2.911s. Nine cases pass, including stale/exact duplicate occurrence, viewport dismissal, mutations, authored geometry and Fit/Fill same-slot/aspect checks. Remaining failure is testFitStateAndSlotStayIndependentAcrossMountedEditors line 509: “Fill must visibly crop into the fixed slot instead of rendering the same Fit pixels.” This is a real mounted native pixel assertion, so the draw registry is active enough for the strict suite to execute; it is not a Fit/Fill acceptance pass.

CalternalEditorTests.EditorImageGeometryTests/testMountedEditorHitsExactInlineImageFramesAcrossFragments: 1 test executed, 8 failures, 0 unexpected, 0.905s. Expected candidate {47,1} was not armed, selection remained {138,0}, dispatch was nil, and expected {130,1} dispatch was absent. Native event trace has double-click event point (95.79541015625,560.0) / view point (95.79541015625,140.0) with targetRange:nil; a later single click at (217.79541015625,560.0) / (217.79541015625,140.0) resolves hover {47,1}.

Full exact output with commands, provenance, XCTest counts, Fill assertion, and gesture trace: /tmp/qa-runs/20260913-232653-title-controls-8920/32-f831-run.txt. No source edits, threshold changes, desktop UI launch, performance claim, or user acceptance. Recommendation: FAIL; #12 runtime blocked pending actual Fill-vs-Fit pixel differentiation and image coordinate/identity repair, followed by exact rerun to 10/0 and 1/0.

QA VM package runtime, exact `f8319e26f4f58ea71bdf8d01647da480bccd7f86`. Provenance matched: archive SHA-256 `8c0114e0a307c2dd39b6639a34c3d7c2493efbc484f7e874b021711438126984`, mode `0444`, size `85731840`; manifest `776837c06d2b9b9226adde4f5a3286e63dc36f1ea808172d90588da15849716a`; test binary `99dff017ef8198220f2b6f1a62e03b38136b4b8e0d6456f7caa45a7315aa565c`. Fresh VM extraction `/private/tmp/qa-f831-1789323429`; isolated TMPDIRs and direct package XCTest runtime paths were used. `CalternalEditorTests.EditorImageControlsTests`: **10 tests executed, 1 failure, 0 unexpected, 2.911s**. Nine cases pass, including stale/exact duplicate occurrence, viewport dismissal, mutations, authored geometry and Fit/Fill same-slot/aspect checks. Remaining failure is `testFitStateAndSlotStayIndependentAcrossMountedEditors` line 509: **“Fill must visibly crop into the fixed slot instead of rendering the same Fit pixels.”** This is a real mounted native pixel assertion, so the draw registry is active enough for the strict suite to execute; it is not a Fit/Fill acceptance pass. `CalternalEditorTests.EditorImageGeometryTests/testMountedEditorHitsExactInlineImageFramesAcrossFragments`: **1 test executed, 8 failures, 0 unexpected, 0.905s**. Expected candidate `{47,1}` was not armed, selection remained `{138,0}`, dispatch was nil, and expected `{130,1}` dispatch was absent. Native event trace has double-click event point `(95.79541015625,560.0)` / view point `(95.79541015625,140.0)` with `targetRange:nil`; a later single click at `(217.79541015625,560.0)` / `(217.79541015625,140.0)` resolves hover `{47,1}`. Full exact output with commands, provenance, XCTest counts, Fill assertion, and gesture trace: `/tmp/qa-runs/20260913-232653-title-controls-8920/32-f831-run.txt`. No source edits, threshold changes, desktop UI launch, performance claim, or user acceptance. Recommendation: **FAIL; #12 runtime blocked** pending actual Fill-vs-Fit pixel differentiation and image coordinate/identity repair, followed by exact rerun to 10/0 and 1/0.
Author
Owner

Thread: /root/image_preview_native_repair (wave16/image-controls)

Exact integrated candidate f8319e26 ran all 10 EditorImageControlsTests on the VM with one remaining assertion failure, down from four. The per-editor native drawing-view identity assertions now pass for both Fit and Fill, including distinct view identities and exact layout-manager identities. The sole failure is line 509's rendered edge-pixel comparison. VM log: /tmp/qa-runs/20260913-232653-title-controls-8920/32-f831-run.txt; runtime tar SHA-256 8c0114e0a307c2dd39b6639a34c3d7c2493efbc484f7e874b021711438126984.

The passing Fit and Fill draw observations prove the state reached the correct native drawing callback with the same slot size. The remaining test captures the parent NSTextView rectangle with cacheDisplay; the attachment view is layer-backed, so this parent cache path can omit the child layer's newly rendered pixels even though the child's draw callback ran. The bounded correction under review is to retain the actual NSView supplied by the opt-in draw diagnostic and cache/sample that native attachment view's bounds directly before and after the state change. This preserves the same strict requirement—visible Fit and Fill pixels must differ in the identical slot—and measures the component that actually drew them. No assertion will be removed or replaced with state-only evidence. Production source remains frozen pending plan review.

Thread: `/root/image_preview_native_repair` (`wave16/image-controls`) Exact integrated candidate `f8319e26` ran all 10 `EditorImageControlsTests` on the VM with one remaining assertion failure, down from four. The per-editor native drawing-view identity assertions now pass for both Fit and Fill, including distinct view identities and exact layout-manager identities. The sole failure is line 509's rendered edge-pixel comparison. VM log: `/tmp/qa-runs/20260913-232653-title-controls-8920/32-f831-run.txt`; runtime tar SHA-256 `8c0114e0a307c2dd39b6639a34c3d7c2493efbc484f7e874b021711438126984`. The passing Fit and Fill draw observations prove the state reached the correct native drawing callback with the same slot size. The remaining test captures the parent `NSTextView` rectangle with `cacheDisplay`; the attachment view is layer-backed, so this parent cache path can omit the child layer's newly rendered pixels even though the child's draw callback ran. The bounded correction under review is to retain the actual `NSView` supplied by the opt-in draw diagnostic and cache/sample that native attachment view's bounds directly before and after the state change. This preserves the same strict requirement—visible Fit and Fill pixels must differ in the identical slot—and measures the component that actually drew them. No assertion will be removed or replaced with state-only evidence. Production source remains frozen pending plan review.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Runtime evidence: exact integrated f8319e26f4f58ea71bdf8d01647da480bccd7f86
State: NATIVE ATTACHMENT-VIEW PIXEL DIAGNOSTIC PLAN PASS WITH ONE REQUIRED BINDING RULE. No source edit, compiler, test runner, app, or GUI was invoked in this reviewer lane.

The actual VM result narrows #12 correctly. EditorImageControlsTests executed 10 tests with one failure at line 509. The existing native draw observations for editor A Fit, editor A Fill, editor B Fit, exact manager identities, disjoint native views, and equal attachment slot frames all passed. The only failed oracle cached the attachment rectangle from the parent NSTextView. The provider view is layer-backed (EditorImagePresentation.swift:692-694), so NSTextView.cacheDisplay(in:to:) is not reliable evidence that the child layer's pixels were composited into that parent bitmap.

Passing the actual installed NSView through the opt-in MainActor draw diagnostic and caching that view's own bounds is a valid bounded discriminator. It exercises the native provider-created view and its real draw(_:); it does not invoke EditorImageDrawingView.draw directly or infer pixels from Fit state. Keep the parent-text-view captures as a control in the same run. If native-view pixels differ while parent captures remain equal, that directly establishes parent-cache omission. If both differ, the end-to-end parent oracle has recovered and the test still has stronger native-view evidence. Record both booleans/colors in the assertion activity or failure text so the rerun is auditable rather than silently discarding the old result.

Required binding rule before implementation

Location: Tests/CalternalEditorTests/EditorImageControlsTests.swift:372-557, especially the observation type/callback and captures around current lines 488-524.

What can break: caching one retained drawing view both before and after the Fit toggle can pass against a detached provider view even if TextKit replaced that view during exact-range layout invalidation. That would weaken the mounted-product oracle.

Why likely: setSelectedImageFit invalidates the attachment's TextKit range before redisplay. AppKit is allowed to recreate the attachment provider/view for the invalidated fragment; the existing test deliberately permits multiple view identities for one manager and only requires the A/B identity sets to be disjoint.

Scoped fix: change the diagnostic payload from drawing-view identity to the actual NSView, but select two observations independently:

  1. After the real Fit windowA.displayIfNeeded(), require an observation whose manager identity is exactly ObjectIdentifier(layoutA), mode is .fit, and bounds size equals frameAFit.size; retain that observation's installed view and cache its own bounds.
  2. Toggle through editorA.setSelectedImageFit(.fill) and perform the real window display. Then require a newly appended observation whose manager identity is exactly ObjectIdentifier(layoutA), mode is .fill, and bounds size equals frameAFill.size; retain that observation's installed view and cache that view's own bounds. Do not reuse the Fit view merely because its snapshot reader would now return Fill.
  3. Require the two view bounds to match the unchanged native attachment slot, and require the same edge-color threshold (> 0.15) between the two native-view captures. Preserve the existing parent-view Fit/Fill captures as the omission control and preserve the A/B disjoint identity and B-still-Fit assertions by deriving ObjectIdentifier(observation.view).
  4. renderedVerticalEdgeColors may be generalized from NSTextView to NSView; it must call the public native view caching APIs only. Do not call draw(_:), display(_:) on a fabricated view, the static draw helper, the snapshot reader, or mutate wantsLayer for the test.

The production diagnostic remains @MainActor, opt-in, and observational; tests may retain the view for the test lifetime, while normal production leaves the callback nil. This change does not validate on-screen compositing by itself. After the component-level package test passes, retain the existing VM app/visual and user acceptance gates for actual window composition.

No P1/P2/P3 plan blocker remains after applying the binding rule. Submit the exact test/diagnostic-only candidate for review, then rerun the full 10-test image-control suite. A direct native-view pixel failure indicates a real crop/drawing defect and must return to product code; it must not be treated as another capture artifact or resolved by weakening the threshold. The separate mounted gesture failure belongs to its existing geometry/Quick Look repair lane and is not evidence about this pixel oracle. Issue #12 remains open.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Runtime evidence: exact integrated `f8319e26f4f58ea71bdf8d01647da480bccd7f86` State: **NATIVE ATTACHMENT-VIEW PIXEL DIAGNOSTIC PLAN PASS WITH ONE REQUIRED BINDING RULE.** No source edit, compiler, test runner, app, or GUI was invoked in this reviewer lane. The actual VM result narrows #12 correctly. `EditorImageControlsTests` executed 10 tests with one failure at line 509. The existing native draw observations for editor A Fit, editor A Fill, editor B Fit, exact manager identities, disjoint native views, and equal attachment slot frames all passed. The only failed oracle cached the attachment rectangle from the parent `NSTextView`. The provider view is layer-backed (`EditorImagePresentation.swift:692-694`), so `NSTextView.cacheDisplay(in:to:)` is not reliable evidence that the child layer's pixels were composited into that parent bitmap. Passing the actual installed `NSView` through the opt-in MainActor draw diagnostic and caching that view's own `bounds` is a valid bounded discriminator. It exercises the native provider-created view and its real `draw(_:)`; it does not invoke `EditorImageDrawingView.draw` directly or infer pixels from Fit state. Keep the parent-text-view captures as a control in the same run. If native-view pixels differ while parent captures remain equal, that directly establishes parent-cache omission. If both differ, the end-to-end parent oracle has recovered and the test still has stronger native-view evidence. Record both booleans/colors in the assertion activity or failure text so the rerun is auditable rather than silently discarding the old result. ### Required binding rule before implementation **Location:** `Tests/CalternalEditorTests/EditorImageControlsTests.swift:372-557`, especially the observation type/callback and captures around current lines 488-524. **What can break:** caching one retained drawing view both before and after the Fit toggle can pass against a detached provider view even if TextKit replaced that view during exact-range layout invalidation. That would weaken the mounted-product oracle. **Why likely:** `setSelectedImageFit` invalidates the attachment's TextKit range before redisplay. AppKit is allowed to recreate the attachment provider/view for the invalidated fragment; the existing test deliberately permits multiple view identities for one manager and only requires the A/B identity sets to be disjoint. **Scoped fix:** change the diagnostic payload from drawing-view identity to the actual `NSView`, but select two observations independently: 1. After the real Fit `windowA.displayIfNeeded()`, require an observation whose manager identity is exactly `ObjectIdentifier(layoutA)`, mode is `.fit`, and bounds size equals `frameAFit.size`; retain that observation's installed view and cache its own bounds. 2. Toggle through `editorA.setSelectedImageFit(.fill)` and perform the real window display. Then require a newly appended observation whose manager identity is exactly `ObjectIdentifier(layoutA)`, mode is `.fill`, and bounds size equals `frameAFill.size`; retain that observation's installed view and cache that view's own bounds. Do not reuse the Fit view merely because its snapshot reader would now return Fill. 3. Require the two view bounds to match the unchanged native attachment slot, and require the same edge-color threshold (`> 0.15`) between the two native-view captures. Preserve the existing parent-view Fit/Fill captures as the omission control and preserve the A/B disjoint identity and B-still-Fit assertions by deriving `ObjectIdentifier(observation.view)`. 4. `renderedVerticalEdgeColors` may be generalized from `NSTextView` to `NSView`; it must call the public native view caching APIs only. Do not call `draw(_:)`, `display(_:)` on a fabricated view, the static draw helper, the snapshot reader, or mutate `wantsLayer` for the test. The production diagnostic remains `@MainActor`, opt-in, and observational; tests may retain the view for the test lifetime, while normal production leaves the callback nil. This change does not validate on-screen compositing by itself. After the component-level package test passes, retain the existing VM app/visual and user acceptance gates for actual window composition. No P1/P2/P3 plan blocker remains after applying the binding rule. Submit the exact test/diagnostic-only candidate for review, then rerun the full 10-test image-control suite. A direct native-view pixel failure indicates a real crop/drawing defect and must return to product code; it must not be treated as another capture artifact or resolved by weakening the threshold. The separate mounted gesture failure belongs to its existing geometry/Quick Look repair lane and is not evidence about this pixel oracle. Issue #12 remains open.
Author
Owner

Thread: /root/image_preview_native_repair (wave16/image-controls)

Bounded diagnostic candidate: exact b5af68672acbd7f5523d47b244c3553d15cde968, clean isolated worktree. The opt-in drawing callback now supplies the actual provider-installed NSView rather than only its identity. The mounted test retains the view observed after the real Fit window draw, caches that view's own bounds, records the observation count, performs the real Fill action and window draw, then selects the Fill view only from the newly appended callback suffix and caches that view's own bounds. It does not reuse the Fit view after range invalidation or construct/call the renderer directly.

The exact attachment frames must still be equal; callback mode, manager identity, and frame checks remain; A/B views must remain disjoint; B must remain Fit; and the provider pixel delta must still exceed 0.15. Parent NSTextView captures are retained as a control and both parent/provider deltas are printed in the VM log. This distinguishes child-layer capture limitations from actual provider rendering without weakening the visible-pixel requirement.

git diff --check passes. No local build or GUI run. Exact-tip source review, optimized compilation, and VM execution remain pending.

Thread: `/root/image_preview_native_repair` (`wave16/image-controls`) Bounded diagnostic candidate: exact `b5af68672acbd7f5523d47b244c3553d15cde968`, clean isolated worktree. The opt-in drawing callback now supplies the actual provider-installed `NSView` rather than only its identity. The mounted test retains the view observed after the real Fit window draw, caches that view's own bounds, records the observation count, performs the real Fill action and window draw, then selects the Fill view only from the newly appended callback suffix and caches that view's own bounds. It does not reuse the Fit view after range invalidation or construct/call the renderer directly. The exact attachment frames must still be equal; callback mode, manager identity, and frame checks remain; A/B views must remain disjoint; B must remain Fit; and the provider pixel delta must still exceed 0.15. Parent `NSTextView` captures are retained as a control and both parent/provider deltas are printed in the VM log. This distinguishes child-layer capture limitations from actual provider rendering without weakening the visible-pixel requirement. `git diff --check` passes. No local build or GUI run. Exact-tip source review, optimized compilation, and VM execution remain pending.
Author
Owner

Reviewer: /root/image_controls_review (reviewer)
Worktree/branch: .worktrees/image-controls / wave16/image-controls
Candidate: exact b5af68672acbd7f5523d47b244c3553d15cde968 atop reviewed product candidate 57364fa4fcac23cc9fc12c58094fc5442de0bf74
State: NATIVE-VIEW PIXEL CAPTURE SOURCE REVIEW PASS — no P1/P2/P3 findings. Worktree is clean and git diff --check 57364fa4..b5af6867 passes. No compiler, test runner, app, or GUI was invoked in this reviewer lane.

The exact two-file diagnostic/test delta preserves and strengthens the mounted oracle:

  • Sources/CalternalEditor/EditorImagePresentation.swift:673-722 changes the opt-in MainActor diagnostic payload from ObjectIdentifier(self) to the actual provider-installed NSView. Normal production ownership is unchanged because the callback remains nil outside the test; the draw view does not gain a registry, backreference, or new stored state.
  • Tests/CalternalEditorTests/EditorImageControlsTests.swift:374-389 retains those views only in the test-local observations array. This keeps detached test objects alive until the test ends but does not retain a provider, attachment, layout manager, window, or editor through product code. The callback is reset with defer, and no lifecycle assertion in another test shares this state.
  • The Fit capture is selected after a real windowA.displayIfNeeded() from an observation with exact manager A, .fit, and the exact native slot size. The test caches that observed view's own bounds.
  • observationsBeforeFill is recorded only after the Fit provider capture. The Fill observation is selected exclusively from the appended suffix after the real toolbar mutation and window display, with exact manager A, .fill, and the unchanged slot size. The test therefore cannot reuse a pre-invalidation Fit view merely because its snapshot reader later reports Fill.
  • Both provider views must have bounds equal to the corresponding native attachment frames. The pixel oracle still uses the same vertical-edge samples and strict > 0.15 maximum color-distance threshold. It invokes only native NSView bitmap caching on the installed views; it does not call the draw override, static draw helper, snapshot reader, or a fabricated view.
  • Parent NSTextView Fit/Fill captures remain in the same run and their delta is printed beside the provider delta. Thus a provider change with an unchanged parent bitmap records the hypothesized layer-composition omission, while a provider failure remains a hard assertion failure. Existing exact-manager Fit/Fill observations, A/B disjoint view identities, equal slot frames, and B-still-Fit assertions remain intact.

No source finding remains at this SHA. Root may integrate the exact commit into the next batch and run the optimized Swift 6.3 package build followed by all 10 EditorImageControlsTests on the VM. A provider delta at or below 0.15 is a product drawing failure, not a reason to adjust the threshold. A component-level pass still requires the planned VM app/visual and user acceptance checks for actual window composition. Issue #12 remains open.

Reviewer: `/root/image_controls_review` (reviewer) Worktree/branch: `.worktrees/image-controls` / `wave16/image-controls` Candidate: exact `b5af68672acbd7f5523d47b244c3553d15cde968` atop reviewed product candidate `57364fa4fcac23cc9fc12c58094fc5442de0bf74` State: **NATIVE-VIEW PIXEL CAPTURE SOURCE REVIEW PASS — no P1/P2/P3 findings.** Worktree is clean and `git diff --check 57364fa4..b5af6867` passes. No compiler, test runner, app, or GUI was invoked in this reviewer lane. The exact two-file diagnostic/test delta preserves and strengthens the mounted oracle: - `Sources/CalternalEditor/EditorImagePresentation.swift:673-722` changes the opt-in MainActor diagnostic payload from `ObjectIdentifier(self)` to the actual provider-installed `NSView`. Normal production ownership is unchanged because the callback remains nil outside the test; the draw view does not gain a registry, backreference, or new stored state. - `Tests/CalternalEditorTests/EditorImageControlsTests.swift:374-389` retains those views only in the test-local observations array. This keeps detached test objects alive until the test ends but does not retain a provider, attachment, layout manager, window, or editor through product code. The callback is reset with `defer`, and no lifecycle assertion in another test shares this state. - The Fit capture is selected after a real `windowA.displayIfNeeded()` from an observation with exact manager A, `.fit`, and the exact native slot size. The test caches that observed view's own bounds. - `observationsBeforeFill` is recorded only after the Fit provider capture. The Fill observation is selected exclusively from the appended suffix after the real toolbar mutation and window display, with exact manager A, `.fill`, and the unchanged slot size. The test therefore cannot reuse a pre-invalidation Fit view merely because its snapshot reader later reports Fill. - Both provider views must have bounds equal to the corresponding native attachment frames. The pixel oracle still uses the same vertical-edge samples and strict `> 0.15` maximum color-distance threshold. It invokes only native `NSView` bitmap caching on the installed views; it does not call the draw override, static draw helper, snapshot reader, or a fabricated view. - Parent `NSTextView` Fit/Fill captures remain in the same run and their delta is printed beside the provider delta. Thus a provider change with an unchanged parent bitmap records the hypothesized layer-composition omission, while a provider failure remains a hard assertion failure. Existing exact-manager Fit/Fill observations, A/B disjoint view identities, equal slot frames, and B-still-Fit assertions remain intact. No source finding remains at this SHA. Root may integrate the exact commit into the next batch and run the optimized Swift 6.3 package build followed by all 10 `EditorImageControlsTests` on the VM. A provider delta at or below `0.15` is a product drawing failure, not a reason to adjust the threshold. A component-level pass still requires the planned VM app/visual and user acceptance checks for actual window composition. Issue #12 remains open.
Author
Owner

Root integrated reviewed native provider-view capture candidate b5af68672a as 5a18daf3 on combined branch. Optimized package compile now running independently of unresolved #9 test-oracle review, so #12 VM validation does not wait. Actual provider-installed Fit/Fill views are measured after separate observation fences; parent capture remains control and strict thresholds retained. Desktop3bbb unchanged. #5 19b compiled, transfer final hash pending before VM run.

Root integrated reviewed native provider-view capture candidate b5af68672acbd7f5523d47b244c3553d15cde968 as 5a18daf3 on combined branch. Optimized package compile now running independently of unresolved #9 test-oracle review, so #12 VM validation does not wait. Actual provider-installed Fit/Fill views are measured after separate observation fences; parent capture remains control and strict thresholds retained. Desktop3bbb unchanged. #5 19b compiled, transfer final hash pending before VM run.
Author
Owner

Thread handoff: /root/image_preview_native_repair

The reviewed provider-view pixel diagnostic b5af68672acbd7f5523d47b244c3553d15cde968 is integrated centrally as 5a18. The exact optimized package build passed in 28.767 seconds. VM staging for the strict mounted Fit/Fill test is still pending its final runtime hash/result.

Current acceptance state: source review PASS and optimized compilation PASS. The strict provider-view pixel result, real native composition, and user UI acceptance remain open, so issue #12 is not complete. Per the user's bedtime direction, this implementation thread is stopping now; root will record the VM result when it arrives and any failed result will be diagnosed in a later work session rather than starting another repair round tonight.

Thread handoff: `/root/image_preview_native_repair` The reviewed provider-view pixel diagnostic `b5af68672acbd7f5523d47b244c3553d15cde968` is integrated centrally as `5a18`. The exact optimized package build passed in 28.767 seconds. VM staging for the strict mounted Fit/Fill test is still pending its final runtime hash/result. Current acceptance state: source review PASS and optimized compilation PASS. The strict provider-view pixel result, real native composition, and user UI acceptance remain open, so issue #12 is not complete. Per the user's bedtime direction, this implementation thread is stopping now; root will record the VM result when it arrives and any failed result will be diagnosed in a later work session rather than starting another repair round tonight.
Author
Owner

/root/title_completion — exact reviewed #12 capture-diagnostic package candidate is packaged and atomically staged for VM controls.

  • Revision: 5a18daf3e447120b2ace3caefce67bb3fd99322e.
  • Build provenance supplied and read by root: optimized package compile PASS in 28.767 seconds at /Users/agents/Developer/BuildOnly/package-tests-d40/Evidence/package-tests/20260913T182540Z-central-5a18daf3-combined-dde33649.
  • VM artifact: /Users/lume/CalternalQA/5a18daf3-image-controls/vm-xctest-runtime-5a18daf3-dde33649.tar, 85,772,800 bytes, mode 0444, SHA-256 63ce31ec7bd00a4de7657ac34907023889adc69908419a271edc9f136bc31a1c; same-name .partial is absent.
  • Embedded identities: manifest SHA-256 0519018e82fdd81860dcaadb14da19171b4e85b386d33f75af4780a46cd7bc57; CalternalPackageTests executable SHA-256 3f123868f5322449a708076b0a64add54754518855b8a9eaf11c40d87d45d15b.
  • Transfer procedure: persisted builder-side script /Users/agents/Developer/BuildOnly/stage-package-runtime-to-vm.sh (SHA-256 42f697dbc0553c0f1d6f946225a00e62aa9be4110f76817923812780a6bb3de4) verified the source manifest and executable, created an immutable archive, used the prior f8319e26 VM archive as a seed, completed rsync in one attempt, checked the full remote SHA, and only then atomically published the final file. The script does not compile, invoke XCTest, or launch the app.
  • Next action: /root/title_controls_runtime_qa owns exact CalternalEditorTests.EditorImageControlsTests execution through the staged package XCTest route with a fresh extraction/TMPDIR and bounded watchdog. The prior f8319e26 run was 10 executed / 1 Fill pixel failure; this candidate adds capture diagnostics and has no runtime result yet. Release remains blocked pending the actual result.
`/root/title_completion` — exact reviewed #12 capture-diagnostic package candidate is packaged and atomically staged for VM controls. - Revision: `5a18daf3e447120b2ace3caefce67bb3fd99322e`. - Build provenance supplied and read by root: optimized package compile PASS in 28.767 seconds at `/Users/agents/Developer/BuildOnly/package-tests-d40/Evidence/package-tests/20260913T182540Z-central-5a18daf3-combined-dde33649`. - VM artifact: `/Users/lume/CalternalQA/5a18daf3-image-controls/vm-xctest-runtime-5a18daf3-dde33649.tar`, 85,772,800 bytes, mode `0444`, SHA-256 `63ce31ec7bd00a4de7657ac34907023889adc69908419a271edc9f136bc31a1c`; same-name `.partial` is absent. - Embedded identities: manifest SHA-256 `0519018e82fdd81860dcaadb14da19171b4e85b386d33f75af4780a46cd7bc57`; `CalternalPackageTests` executable SHA-256 `3f123868f5322449a708076b0a64add54754518855b8a9eaf11c40d87d45d15b`. - Transfer procedure: persisted builder-side script `/Users/agents/Developer/BuildOnly/stage-package-runtime-to-vm.sh` (SHA-256 `42f697dbc0553c0f1d6f946225a00e62aa9be4110f76817923812780a6bb3de4`) verified the source manifest and executable, created an immutable archive, used the prior `f8319e26` VM archive as a seed, completed rsync in one attempt, checked the full remote SHA, and only then atomically published the final file. The script does not compile, invoke XCTest, or launch the app. - Next action: `/root/title_controls_runtime_qa` owns exact `CalternalEditorTests.EditorImageControlsTests` execution through the staged package XCTest route with a fresh extraction/TMPDIR and bounded watchdog. The prior `f8319e26` run was 10 executed / 1 Fill pixel failure; this candidate adds capture diagnostics and has no runtime result yet. Release remains blocked pending the actual result.
Author
Owner

QA VM package runtime for exact 5a18daf3e447120b2ace3caefce67bb3fd99322e: PASS for the requested controls suite only.

Fresh extraction provenance matched: archive SHA-256 63ce31ec7bd00a4de7657ac34907023889adc69908419a271edc9f136bc31a1c, mode 0444, size 85772800; manifest 0519018e82fdd81860dcaadb14da19171b4e85b386d33f75af4780a46cd7bc57; CalternalPackageTests executable 3f123868f5322449a708076b0a64add54754518855b8a9eaf11c40d87d45d15b.

Direct package XCTest command used fresh TMPDIR, isolated VM extraction /private/tmp/qa-5a18-1789324558, and normal runtime framework/library paths. CalternalEditorTests.EditorImageControlsTests completed 10 executed / 0 failures / rc 0 in 1.782 seconds. The formerly failing testFitStateAndSlotStayIndependentAcrossMountedEditors passes and emits capture diagnostic image-fit-fill-pixels parent=0.0 provider=1.8229637444019318, confirming non-identical provider Fill pixels in this fixture.

Full command, provenance and test output: /tmp/qa-runs/20260913-232653-title-controls-8920/39-5a18-run.txt. No source edits, threshold changes, geometry rerun, GUI verification, release, performance claim, or user acceptance. This suite pass does not resolve the separately recorded mounted image geometry/Quick Look failures.

QA VM package runtime for exact `5a18daf3e447120b2ace3caefce67bb3fd99322e`: **PASS for the requested controls suite only**. Fresh extraction provenance matched: archive SHA-256 `63ce31ec7bd00a4de7657ac34907023889adc69908419a271edc9f136bc31a1c`, mode `0444`, size `85772800`; manifest `0519018e82fdd81860dcaadb14da19171b4e85b386d33f75af4780a46cd7bc57`; `CalternalPackageTests` executable `3f123868f5322449a708076b0a64add54754518855b8a9eaf11c40d87d45d15b`. Direct package XCTest command used fresh `TMPDIR`, isolated VM extraction `/private/tmp/qa-5a18-1789324558`, and normal runtime framework/library paths. `CalternalEditorTests.EditorImageControlsTests` completed **10 executed / 0 failures / rc 0** in 1.782 seconds. The formerly failing `testFitStateAndSlotStayIndependentAcrossMountedEditors` passes and emits capture diagnostic `image-fit-fill-pixels parent=0.0 provider=1.8229637444019318`, confirming non-identical provider Fill pixels in this fixture. Full command, provenance and test output: `/tmp/qa-runs/20260913-232653-title-controls-8920/39-5a18-run.txt`. No source edits, threshold changes, geometry rerun, GUI verification, release, performance claim, or user acceptance. This suite pass does not resolve the separately recorded mounted image geometry/Quick Look failures.
Author
Owner

Bedtime checkpoint requested by user: finish already active tasks, record results, then stop. No new repair round tonight. No launch or application interaction on kayg@mbp after locking. Build-only work remains agents@mbp; runtime/computer use remains Lume VM.

Frozen combined revision: da644b0467. Exact source/integration review PASS; optimized package compile PASS (31.782 seconds), log hash independently verified. Final Release build/package in progress; desktop stays 3bbb until morning, no desktop launch/install overnight.

#12 exact 5a18 controls: 10 tests executed, 0 failures, rc0. Parent capture delta0 vs provider delta1.8229637444019318 demonstrates native provider Fit/Fill pixels change. #12 product/test blobs unchanged in da644. Native composition/user acceptance remain open.
#9/#11 final diagnostics/test corrections source-reviewed and compiled in da644; final runtime rerun remains a morning follow-up. No code-block or Quick Look fix claim.
#5 exact 19b isolated hosted rename control exited139 after sandbox related-item warning. No matching new IPS. Config audit identifies missing production-equivalent fixture authorization and relocated XCTest runtime as competing hypotheses. Production rename task ownership unchanged; no speculative repair.
#2 remains user-accepted fixed. Other individual issue acceptance gaps remain in master tracker. All implementation/review/QA agents finished; only final Release packaging is active. Root will append artifact receipt and stop.

Bedtime checkpoint requested by user: finish already active tasks, record results, then stop. No new repair round tonight. No launch or application interaction on kayg@mbp after locking. Build-only work remains agents@mbp; runtime/computer use remains Lume VM. Frozen combined revision: da644b0467a96a9d74e199592b6a56f7e7f9c318. Exact source/integration review PASS; optimized package compile PASS (31.782 seconds), log hash independently verified. Final Release build/package in progress; desktop stays 3bbb until morning, no desktop launch/install overnight. #12 exact 5a18 controls: 10 tests executed, 0 failures, rc0. Parent capture delta0 vs provider delta1.8229637444019318 demonstrates native provider Fit/Fill pixels change. #12 product/test blobs unchanged in da644. Native composition/user acceptance remain open. #9/#11 final diagnostics/test corrections source-reviewed and compiled in da644; final runtime rerun remains a morning follow-up. No code-block or Quick Look fix claim. #5 exact 19b isolated hosted rename control exited139 after sandbox related-item warning. No matching new IPS. Config audit identifies missing production-equivalent fixture authorization and relocated XCTest runtime as competing hypotheses. Production rename task ownership unchanged; no speculative repair. #2 remains user-accepted fixed. Other individual issue acceptance gaps remain in master tracker. All implementation/review/QA agents finished; only final Release packaging is active. Root will append artifact receipt and stop.
Author
Owner

/root/title_completion final bedtime build handoff for exact central revision da644b0467a96a9d74e199592b6a56f7e7f9c318 (tree 6b389118016bab48a226205956de13b15df21592). The #12 provider/view source and strict controls are unchanged from ancestor 5a18daf3; that ancestor's exact VM suite passed 10/10 with rc 0. This does not substitute for the remaining central diagnostic runs or user visual acceptance.

Release compilation on agents@mbp passed in 62.508 seconds. Raw build evidence: /Users/agents/Developer/BuildOnly/calternal-preview-evidence/artifacts/20260913T183809Z-da644b0467a9-00031a65; executable SHA-256 1edd96e29065fc70483b122e24552bc2bc5ef87d10c9efd916a55f9d2a81f4a2.

Immutable morning package: /Users/Shared/CalternalBuilds/da644b0467a9-00031a65/Calternal-da644b0467a9-Release-arm64.zip, SHA-256 c781f08c7c20ce8f97eab389252f28df50f15b583730291ed3d256ebeacbbb2b. Fresh unpack strict codesign and byte-for-byte bundle comparison passed; archive receipt SHA-256 08b029ef97af3c0898fe4270de73ac2b0b08c92acbf90b5f7ccdb1fc5e45a6f8.

No desktop install, app launch, or GUI action was performed for this artifact. #12 remains open for actual window composition, user acceptance, and the stable performance gates.

`/root/title_completion` final bedtime build handoff for exact central revision `da644b0467a96a9d74e199592b6a56f7e7f9c318` (tree `6b389118016bab48a226205956de13b15df21592`). The #12 provider/view source and strict controls are unchanged from ancestor `5a18daf3`; that ancestor's exact VM suite passed 10/10 with rc 0. This does not substitute for the remaining central diagnostic runs or user visual acceptance. Release compilation on `agents@mbp` passed in 62.508 seconds. Raw build evidence: `/Users/agents/Developer/BuildOnly/calternal-preview-evidence/artifacts/20260913T183809Z-da644b0467a9-00031a65`; executable SHA-256 `1edd96e29065fc70483b122e24552bc2bc5ef87d10c9efd916a55f9d2a81f4a2`. Immutable morning package: `/Users/Shared/CalternalBuilds/da644b0467a9-00031a65/Calternal-da644b0467a9-Release-arm64.zip`, SHA-256 `c781f08c7c20ce8f97eab389252f28df50f15b583730291ed3d256ebeacbbb2b`. Fresh unpack strict codesign and byte-for-byte bundle comparison passed; archive receipt SHA-256 `08b029ef97af3c0898fe4270de73ac2b0b08c92acbf90b5f7ccdb1fc5e45a6f8`. No desktop install, app launch, or GUI action was performed for this artifact. #12 remains open for actual window composition, user acceptance, and the stable performance gates.
Author
Owner

User requested latest build launch this morning. Root installed and launched exact da644b0467 at /Users/kayg/Applications/Calternal.app. Verified archive and executable hashes, strict codesign, normal Quit of old preview, rollback retained, vault text inventory unchanged during replacement. Fresh native AX confirms visible window and previous note with Style inspector restored. Install receipt .agents/desktop-install/da644b04/install-receipt.json. Image controls10/10 prior5a18 with unchanged relevant files; exact-final #9/#11 runtime, user UI/performance and title hosted environment remain open. Preview delivery only; no stable acceptance claim.

User requested latest build launch this morning. Root installed and launched exact da644b0467a96a9d74e199592b6a56f7e7f9c318 at /Users/kayg/Applications/Calternal.app. Verified archive and executable hashes, strict codesign, normal Quit of old preview, rollback retained, vault text inventory unchanged during replacement. Fresh native AX confirms visible window and previous note with Style inspector restored. Install receipt .agents/desktop-install/da644b04/install-receipt.json. Image controls10/10 prior5a18 with unchanged relevant files; exact-final #9/#11 runtime, user UI/performance and title hosted environment remain open. Preview delivery only; no stable acceptance claim.
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.

  • wave16/image-controls — b5af68672acbd7f5523d47b244c3553d15cde968

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. - `wave16/image-controls` — `b5af68672acbd7f5523d47b244c3553d15cde968` Master #20 contains the resume instructions. No force push; dev remains 1d8f4adf.
Author
Owner

User report 2026-09-15 (bc3ace0): hovering an image block deforms it — the paragraph-indent hover slide shifts the text layer while the native image view stays, and the hover buttons overlap the image. Image aspect-ratio handling needs more refinement. Fix: standalone image blocks must move as a unit with the hover slide (or be excluded consistently with no overlap), controls never overlap the image.

User report 2026-09-15 (bc3ace0): hovering an image block deforms it — the paragraph-indent hover slide shifts the text layer while the native image view stays, and the hover buttons overlap the image. Image aspect-ratio handling needs more refinement. Fix: standalone image blocks must move as a unit with the hover slide (or be excluded consistently with no overlap), controls never overlap the image.
Author
Owner

Implemented on branch wave19/block-editor-craft, commit 1de08bd.

#18: BlockEditorView now exposes explicit text/block modes with modeDidChangeNotification and a host callback; whole-block selection paths enter block mode, text editing/double-click/typing return to text mode, Esc promotes a text caret to its current block, and formatting UI is gated to non-empty text selections. NoteEditorSession mirrors the mode for Inspector consumers.

#12: Standalone image blocks no longer receive the paragraph hover slide used for text blocks. Native attachment geometry remains stable; block handle and actions are placed in the leading/trailing gutter outside the image when possible.

Proof: Scripts/build-mbp.sh block-editor-craft package succeeded (existing Swift actor-isolation warnings only). Craft visual references captured locally: craft-editor-reference.png and craft-image-hover-reference-3.png (the latter shows gutter controls without image deformation).

Implemented on branch wave19/block-editor-craft, commit 1de08bd. #18: BlockEditorView now exposes explicit text/block modes with modeDidChangeNotification and a host callback; whole-block selection paths enter block mode, text editing/double-click/typing return to text mode, Esc promotes a text caret to its current block, and formatting UI is gated to non-empty text selections. NoteEditorSession mirrors the mode for Inspector consumers. #12: Standalone image blocks no longer receive the paragraph hover slide used for text blocks. Native attachment geometry remains stable; block handle and actions are placed in the leading/trailing gutter outside the image when possible. Proof: Scripts/build-mbp.sh block-editor-craft package succeeded (existing Swift actor-isolation warnings only). Craft visual references captured locally: craft-editor-reference.png and craft-image-hover-reference-3.png (the latter shows gutter controls without image deformation).
Author
Owner

User feedback 2026-09-15 on desktop build 5b72a45:

  1. Images still break on hover: either horizontally squeezed (aspect ratio changes) or drawn twice over themselves (duplicate). Screenshots attached to the conversation; reproduce with a wide chat screenshot image inside a note.
  2. Tapping a block goes straight into text editing; it must select the block first (block mode), and only a second click / double-click / typing enters text mode. Compare Craft on the VM for the exact feel.
User feedback 2026-09-15 on desktop build 5b72a45: 1. Images still break on hover: either horizontally squeezed (aspect ratio changes) or drawn twice over themselves (duplicate). Screenshots attached to the conversation; reproduce with a wide chat screenshot image inside a note. 2. Tapping a block goes straight into text editing; it must select the block first (block mode), and only a second click / double-click / typing enters text mode. Compare Craft on the VM for the exact feel.
Author
Owner

User (2026-09-15): remove the 'IMAGE SIZE / IMAGE FIT — THIS VIEW' popover on images entirely. Replace with Craft's image affordance: on hover/selection a compact floating toolbar centered over the image (icons: layout/card, frame, expand (fit), collapse (fill), reaction, comment, ⋯), no labels, no section headers, one row, material background, selection ring around the image. Only the actions we actually support (fit/fill, ⋯) ship; unsupported ones are omitted, not disabled.

User (2026-09-15): remove the 'IMAGE SIZE / IMAGE FIT — THIS VIEW' popover on images entirely. Replace with Craft's image affordance: on hover/selection a compact floating toolbar centered over the image (icons: layout/card, frame, expand (fit), collapse (fill), reaction, comment, ⋯), no labels, no section headers, one row, material background, selection ring around the image. Only the actions we actually support (fit/fill, ⋯) ship; unsupported ones are omitted, not disabled.
Author
Owner

Settled (user): click model = unfocused single click selects the block, double-click enters text, focused clicks place the caret (build d9dfcf1 does not honour it — reproduce on VM). Image: selection ring hugs the image bounds exactly; the image toolbar REUSES the formatting toolbar's capsule view; Fit/Fill/⋯ must work and Fit/Fill persist as a markdown attribute; invariant: hover never changes any block's geometry (pixel-diff across all block kinds). Block-onto-block drop (Settings → Editor, per-Space): make-note (default: destination becomes a note link, source moved into its body) / swap / nest-as-child.

Settled (user): click model = unfocused single click selects the block, double-click enters text, focused clicks place the caret (build d9dfcf1 does not honour it — reproduce on VM). Image: selection ring hugs the image bounds exactly; the image toolbar REUSES the formatting toolbar's capsule view; Fit/Fill/⋯ must work and Fit/Fill persist as a markdown attribute; invariant: hover never changes any block's geometry (pixel-diff across all block kinds). Block-onto-block drop (Settings → Editor, per-Space): make-note (default: destination becomes a note link, source moved into its body) / swap / nest-as-child.
Author
Owner

Worker EditorGate — worktree /home/kayg/Developer/calternal-apple/.worktrees/editor-click-image, branch wave19/editor-click-image.

Implemented Fill/Fit invalidation as commit 2263d82: setFit now invalidates the exact attachment layout and rendering-attribute range, and registered TextKit drawing views are explicitly dirtied so their draw pass re-reads the current mounted snapshot. Restored the mounted test's unconditional Fill drawing observation/pixel-delta assertion.

Initial focused gate reached compile successfully but the build-host SSH session ended with exit 255 before tests ran; a retry is pending build-host connectivity restoration. No VM QA claimed.

Worker EditorGate — worktree /home/kayg/Developer/calternal-apple/.worktrees/editor-click-image, branch wave19/editor-click-image. Implemented Fill/Fit invalidation as commit 2263d82: setFit now invalidates the exact attachment layout and rendering-attribute range, and registered TextKit drawing views are explicitly dirtied so their draw pass re-reads the current mounted snapshot. Restored the mounted test's unconditional Fill drawing observation/pixel-delta assertion. Initial focused gate reached compile successfully but the build-host SSH session ended with exit 255 before tests ran; a retry is pending build-host connectivity restoration. No VM QA claimed.
Author
Owner

Worker: EditorFinish
Worktree/branch: editor-click-image / wave19/editor-click-image
Commit: cba84825

Implemented and verified the TextKit 2 fit redraw fix. The mounted attachment is updated before canonical projection replacement so its already-mounted provider redraws; the presentation also marks the exact NSTextStorage attribute range edited and invalidates/ensures the matching NSTextRange. Mounted fit state remains per presenter and the native toolbar is updated immediately from the requested action.

Executed:

  • Scripts/build-mbp.sh editor-click-image test CalternalEditorTests.EditorImageControlsTests — PASS, 11/11. The unconditional Fill pixel assertion reported image-fit-fill-pixels provider=1.6667693257331848.
  • Scripts/build-mbp.sh editor-click-image app — PASS. BUILT_APP=/Users/agents/Developer/Worktrees/editor-click-image/App/build/Build/Products/Debug/Calternal.app.
  • Scripts/build-mbp.sh editor-click-image test CalternalEditorTests.MarkdownBlockDocumentTests exposed the existing hover-handle assertion at line 1249 (expected >=30, got 10).
  • Baseline comparison executed: ssh -o ControlPath=none agents@mbp 'cd ~/Developer/Worktrees/desktop-test && swift test --filter CalternalEditorTests.MarkdownBlockDocumentTests/testBlockHandleAppearsOnlyForHoverAndStaysReachableDuringInteraction'; it fails with the identical line-1249 assertion, confirming it predates this work.

VM verification remains queued behind the active sidebar-narrow lease.

Worker: EditorFinish Worktree/branch: editor-click-image / wave19/editor-click-image Commit: cba84825 Implemented and verified the TextKit 2 fit redraw fix. The mounted attachment is updated before canonical projection replacement so its already-mounted provider redraws; the presentation also marks the exact `NSTextStorage` attribute range edited and invalidates/ensures the matching `NSTextRange`. Mounted fit state remains per presenter and the native toolbar is updated immediately from the requested action. Executed: - `Scripts/build-mbp.sh editor-click-image test CalternalEditorTests.EditorImageControlsTests` — PASS, 11/11. The unconditional Fill pixel assertion reported `image-fit-fill-pixels provider=1.6667693257331848`. - `Scripts/build-mbp.sh editor-click-image app` — PASS. `BUILT_APP=/Users/agents/Developer/Worktrees/editor-click-image/App/build/Build/Products/Debug/Calternal.app`. - `Scripts/build-mbp.sh editor-click-image test CalternalEditorTests.MarkdownBlockDocumentTests` exposed the existing hover-handle assertion at line 1249 (expected >=30, got 10). - Baseline comparison executed: `ssh -o ControlPath=none agents@mbp 'cd ~/Developer/Worktrees/desktop-test && swift test --filter CalternalEditorTests.MarkdownBlockDocumentTests/testBlockHandleAppearsOnlyForHoverAndStaysReachableDuringInteraction'`; it fails with the identical line-1249 assertion, confirming it predates this work. VM verification remains queued behind the active sidebar-narrow lease.
Author
Owner

Overnight (Main) editor-click-image @ c92ac88a merged into desktop-test: EditorImageControlsTests 11/11 incl. unconditional Fill redraw pixel delta; VM (dark, A0 fixture): hover → handle + ⋯ + slide visible (/tmp/vm/block-editor/hover-1-bullet.png), wide/tall image pixels unchanged on hover PASS. Checker heuristics for handle/⋯ detection and text-block geometry (which must ignore the 18 pt slide) still FAIL on the current fixture layout — script debt, not product evidence; click-mode verified by the focused unit test only. Morning: verify click model, image ring/toolbar, Fit/Fill on the desktop.

Overnight (Main) editor-click-image @ c92ac88a merged into desktop-test: EditorImageControlsTests 11/11 incl. unconditional Fill redraw pixel delta; VM (dark, A0 fixture): hover → handle + ⋯ + slide visible (/tmp/vm/block-editor/hover-1-bullet.png), wide/tall image pixels unchanged on hover PASS. Checker heuristics for handle/⋯ detection and text-block geometry (which must ignore the 18 pt slide) still FAIL on the current fixture layout — script debt, not product evidence; click-mode verified by the focused unit test only. Morning: verify click model, image ring/toolbar, Fit/Fill on the desktop.
Author
Owner

Parallels VM (calternalvm, macOS 27) findings, build 771b73ad:

  • Fixed: ![alt|640](…) images used a fixed 640×220 card → ring 45 pt taller than a wide screenshot and the next block pushed down. Slot now equals the drawn pixels (Fit = image aspect ≤ 220; Fill = 220 card, cropped). Cached mounted slot is keyed on the proposed line width (inspector/window resize re-lays out instead of clipping a stale wider slot). VM: whole image visible at the column width, aspect preserved; idle/hover/click row edges identical (no jump).
  • Fixed: click model verified on the VM — single click selects the block, clicking the selected block places the caret.
  • Open (pre-existing, reproduced on the VM): clicking Fill in the image capsule highlights the segment but setSelectedImageFit never applies the |fit=fill mutation (file unchanged after 10 s and ⌘S; layout unchanged). Unit path (editorA.setSelectedImageFit(.fill)) works, so the guard in setSelectedImageFit fails for the live panel click — likely selectedRange() == captured.displayRange after the panel takes key. Needs a runtime trace.
Parallels VM (`calternalvm`, macOS 27) findings, build 771b73ad: - Fixed: `![alt|640](…)` images used a fixed 640×220 card → ring 45 pt taller than a wide screenshot and the next block pushed down. Slot now equals the drawn pixels (Fit = image aspect ≤ 220; Fill = 220 card, cropped). Cached mounted slot is keyed on the proposed line width (inspector/window resize re-lays out instead of clipping a stale wider slot). VM: whole image visible at the column width, aspect preserved; idle/hover/click row edges identical (no jump). - Fixed: click model verified on the VM — single click selects the block, clicking the selected block places the caret. - Open (pre-existing, reproduced on the VM): clicking **Fill** in the image capsule highlights the segment but `setSelectedImageFit` never applies the `|fit=fill` mutation (file unchanged after 10 s and ⌘S; layout unchanged). Unit path (`editorA.setSelectedImageFit(.fill)`) works, so the guard in `setSelectedImageFit` fails for the live panel click — likely `selectedRange() == captured.displayRange` after the panel takes key. Needs a runtime trace.
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#12
No description provided.