Files
ARCADIA-Studio/harness/release-behavior-canvas-union-review-20260911.md
T

10 KiB

Shared behavior canvas — independent root union review

Codex-956atf /root/canvas_union_review, 2026-09-11. No actionable correctness, input-ownership, architecture or source/history regression was found in this bounded source review of the integrated canvas and scenario-parent focus paths. This is not a build, runtime, visual or release acceptance verdict.

Scope and identity

Root delegated this read-only review against the production union on codex/behavior-authoring-20260910, first identified by root as commit 6969c825a8340980b6a419524ade3bb687a6051f, then frozen at 06ec9621297627a1f7d5c3bc65efb237d1c9923e. The latter adds two test-only compiler adaptations described below. Commit identities are root-provided; this reviewer did not run Git. The scenario test freeze independently matched SHA256 950CF4347A3EDEA615B1AC71D9A681C32B446B5109FCFD0F03F3AE2B147360BF.

Read the current AGENTS.md and PROJECT_GOAL.md, the prior R1/R2/R3 review, the isolated candidate's R1/R2/R3 source handoff, and the relevant actual root implementation and tests. The prior review's resolved counterexamples were checked for integration regressions rather than re-reported. Root owns Gitea coordination, compilation, native acceptance and publication. Only this report was written.

The following independently observed raw working-file hashes identify the important union boundaries. Paths are relative to crates/oa-desktop/src/.

Path SHA256
app.rs AA2E4853B25BB7E185B1DE49EDA42028523C8EBF9599BFE6B7CB2A2B2A688090
behavior.rs 5E7CECB54BFCA64E4462F7881F460900ABD925BA2CFE9451CE2B0C78AF4BC850
behavior/scenario.rs FB1DA03E8DF05A59253F7FDF34391E30ABD8AEA427B7D0A12B86B80FF3BF9ECA
behavior/scenario/focus.rs 73A9EA10AD7312086081B8688396A21AB4251C9FAECC2DF6D984B702F3963533
behavior/scenario/workspace.rs 284F5A7DA09BDC77D70C6788A091D57927150C796FFC10D786793CFF7DA4B7C6
behavior/scenario/workspace/tests.rs 950CF4347A3EDEA615B1AC71D9A681C32B446B5109FCFD0F03F3AE2B147360BF
behavior/canvas_workspace/focus.rs CC58CB3838F546150D22FE4DD83A3FFD52504C279FEBAEB8D0B4A6A3B8A73950
behavior/canvas_workspace/tests.rs D84D022574A6F1D69F203D9383502227FB9FC23605C6FB48779CA9F09BEE546D
behavior/topology/layout_tests.rs A990947CB39B2FB15C21DFBC95EE16F92BF6BE749D3872C6904762B9BDE37089
behavior/form_session.rs F5027FB3A5A5599A182E7D1A10DBA56DD66EB1F23A4BA4C4A1744C9A6A5B6E61

Production integration

All source locations in this section are under crates/oa-desktop/src/.

app.rs:1041 nests the scenario parent owner root outside the canvas owner root, with both outside the actual hosted/reference overlays. Their custom owner types are distinct. Each operation ignores the other's marker, receives its own current marker before visiting focusable children, and independently checks ownership in Collect and Apply. This preserves the parent form guard while allowing the canvas operation to cover the actual nested overlay traversal. A pending scenario form makes Scope::input_owner return None (behavior/canvas_workspace.rs:84); opening its source child removes form_mount (behavior/scenario.rs:509); Review removes the parent owner (app.rs:1495). No competing current canvas/parent focus owner was found in these paths.

app.rs:1119 retains the exact current canvas Scope admission and narrow presentation whitelist. Only accepted presentation actions normalize the semantic epoch, and resulting control focus uses the post-action lifetime at app.rs:1177. The outer parent wrapper neither changes these epochs nor emits another focus operation. The resolved held-pan/toolbar and delayed canvas-task cases therefore retain their production guards after integration. Domain authoring still uses exact scenario context at app.rs:1619.

Scenario Name uses the session-and-mount-derived dynamic ID (behavior/scenario/workspace.rs:283), while the scroll reset wrapper remains keyed only to editing session (:615). The sensor uses the mount key and sends that mount in FormShown (:565). The handler accepts same-owner geometry epoch changes but checks document, owner, revision, current owner and pending mount (app.rs:1527). Back, Use and Escape rearm the parent through remount_form (behavior/scenario.rs:324, :696, :745). None of these presentation paths replaces the raw invocation or source draft. The zero-delta axis preservation in behavior/scenario/focus.rs remains present.

The Details pane now uses the production passive observer with process = false (behavior/scenario/workspace.rs:595). Its actual translation enters scenario Page scroll state, and a caller restore receives and consumes the matching token through behavior.rs:114 and behavior/scenario.rs:460. restore_caller marks only Page pending (behavior/scenario.rs:425), consistent with the viewport using camera pan instead of a Scrollable. The reviewed source contains no new semantic command or source mutation in these observer/focus paths.

The boxed workflow convention is retained (workflow.rs:22, :45), including review_event.as_ref() in app/reference_authoring.rs:218. Reference chooser availability excludes pending behavior forms (app/reference_authoring.rs:72), so its separate canvas guard does not create an uncovered simultaneous parent-form/chooser owner in the reviewed production path.

Mounted evaluator and nontrivial assertions

Independently inspected the installed Iced sources under .local/toolchain/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/:

  • iced_winit-0.14.0/src/lib.rs:1214 drains App updates, rebuilds the resulting UI, then executes actions; :1300 collects immediately ready task actions for the whole message batch and retains pending streams; :1742 executes chained widget passes synchronously.
  • iced_runtime-0.14.0/src/user_interface.rs:539 operates both the real root and nested overlays.
  • iced_widget-0.14.2/src/scrollable.rs:540 reports the scroll translation before traversing unshifted child layout, matching the parent's translated bounds observer and reveal calculation. sensor.rs:198 rearms on key change and emits on the subsequent redraw, including unchanged bounds. iced_core-0.14.0/src/widget/id.rs supports the dynamic Id::from(String) used by the union.

The shared Mounted helper uses those actual UserInterface and Cache APIs, drains a complete input message batch before tasks, builds the final App view for ready actions, and executes Chain passes against that same UI (behavior/canvas_workspace/tests.rs:140, :184). Output messages form the next update cycle; pending streams are retained until completion. Unexpected native actions panic and unavailable renderer initialization fails. This is the relevant single-window widget/App ordering, not a replica of subscriptions, OS focus, native dialogs or arbitrary asynchronous scheduling.

The reconciled parent tests preserve useful falsifiers:

  • scenario/workspace/tests.rs:412 first focuses another real field, establishes actual parent overflow, performs the accepted task, and requires the exact Name to be the sole focus and fully visible. Mismatched mounts, revisions, owners and modal admission are separately rejected.
  • :794 obtains the real sensor task and first consumes initial focus before entering the actual child. Back, Use and Escape must retain session/raw identity, create a different mount, emit a new sensor task, and focus the parent again. A repeated FormShown must produce no task.
  • :864 retains an actual widget Action before replacement, child, Review and context transitions; it observes the resulting tree and requires the saved Collect to remain inert. :935 similarly retains Apply across Review. This intentionally stronger retained-Apply invariant does not claim native Chain passes interleave.
  • :958 is explicitly a small synthetic missing-target test; it is not presented as a production-root modal test. The preceding production-root cases supply that coverage.
  • :1654 requests 700 pixels on the real Action form and requires the measured offset to exceed 64, preserves it while editing, then performs Cancel/Start with no intervening closed view. It checks zero offset before a redraw could rescue it through a new Name-focus task. Action and Observation share the same relevant field structure (scenario/workspace.rs:280, :315, :476), so replacement is not simply a switch to an empty form. Camera, raw invocation, recovery, source snapshot and history assertions remain.
  • :1773 tests same-bounds owner/document remeasurement with the same Mounted cache. :1820 builds legitimate Details rows, requires the actual offset to be exactly 80, navigates through preselection and caller return, then requires the offset/camera restoration, consumed receipt, and subsequent pan movement. Source and revision comparisons surround navigation; existing rename history is acknowledged instead of asserting an empty history.

The shared chooser/Review case continues to use actual nested search and Review fields (behavior/topology/layout_tests.rs:568). The two compiler adaptations in 06ec962 are consistent with installed APIs: explicit Headless::screenshot selects the trait's physical-size/scale overload (behavior/canvas_workspace/tests.rs:268), and the Review fixture calls the existing boxed event constructor (behavior/topology/layout_tests.rs:726). Neither changes evaluator ordering or production behavior.

Acceptance limits

No compiler, test, renderer, native GUI, Git/index, network, Linux/WSL or VPN action was performed by this reviewer. Root reported the initial two test API errors and the committed adaptations; the corrected compiler run was still underway when this report was prepared. There is no executed pass claim here, and earlier reports establish different bytes.

Root still needs the appropriate exact-union build/test and native acceptance evidence. In particular, operation geometry and prepared pixel assertions do not establish native focus/accessibility, clipping of transformed scene text, all modal geometry or minimum-window usability. The separately owned B4 renderer work and broader phase 1/issue 2/PROJECT_GOAL acceptance are not certified by this bounded integration review. No new blocking source finding is left for this reviewer to hand back.