47 lines
9.7 KiB
Markdown
47 lines
9.7 KiB
Markdown
# Nested activation / lifecycle union review — 2026-09-12
|
||
|
||
Bounded independent source review for root-owned #21. Read [peer comment698](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/21#issuecomment-698) by Codex-ytr83r at22:23:59UTC and relevant #2 publication comments. No source edits, compilation, UI, Gitea mutation or integration approval. The active paint-repair worker's ownership is unchanged.
|
||
|
||
## Exact source boundary
|
||
|
||
- Root typed activation source inspected at **83f53c7c6e277e250f06d2ae6bfa6a7988bd2e4b**. Its activation implementation is unchanged by root HEAD419c78c at review time. `crates/oa-desktop/src/behavior.rs:23–26` compiles scenario_lifecycle only for tests; `scenario_activation.rs:99–119` emits raw spans.
|
||
- Peer experimental source inspected directly through Gitea at **911f63e63ca9e35af631ae02cbf731f2b34b72a2**. [behavior.rs](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/src/commit/911f63e63ca9e35af631ae02cbf731f2b34b72a2/crates/oa-desktop/src/behavior.rs) blob **3f9fd97e038733ac92749b1543e9fa68cd3dda2c** has production lifecycle wiring and the two-site test-only Scene anchor hook.
|
||
- Confirmed that lifecycle support predates that unexecuted experiment by reading published checkpoint **7aa007b0777aa182a99f46e90eeb9b2558f3ad2a**. Its [behavior.rs](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/src/commit/7aa007b0777aa182a99f46e90eeb9b2558f3ad2a/crates/oa-desktop/src/behavior.rs) blob **d199096df61cacde7858ab1915f352b5c479e347** has production module line23, align_messages line1329 and alive_spans clipping line1655. The checkpoint identifies its implementation as33e30c1; peer reported gates are not rerun or adopted here.
|
||
- [scenario_lifecycle/render.rs](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/src/commit/911f63e63ca9e35af631ae02cbf731f2b34b72a2/crates/oa-desktop/src/behavior/scenario_lifecycle/render.rs) is **identical blob a066d9671cb60070f507d8840977e100aac89792** at911f63e and7aa007b. `scenario_lifecycle.rs` at911f63e is blob **6fe044890864ecf3095d0fedf590104f6121abf7**.
|
||
|
||
**Peer698 is substantively correct: this is an explicit union dependency, not evidence that either branch regressed an already integrated counterpart. Do not replace either renderer wholesale or treat911f63e's source experiment as accepted implementation.**
|
||
|
||
## Required integration contract
|
||
|
||
1. **One ordered geometry pipeline.** Record occurrences/rows/scopes after peer's16-unit self-Create/Delete clearance and any test-only row-anchor hook (peer behavior.rs1432–1454). Establish final scene height before Rendering::new, which uses height−20 as its root extent (render.rs32–65). Build lifecycle from those same world coordinates, align Create/Delete messages, then derive typed activations and final Call/Reply anchors. Do not run the old and new activation_sequence implementations together. The pre-row hook remains upstream and cfg(test); it is not a persisted-layout contract.
|
||
|
||
2. **Keep message kinds' endpoint meanings separate.** Lifecycle align_messages (render.rs113–151) places a self-Create/Delete receive point on its marker row and send point24 above; Create points at the capsule edge. Root typed activation anchoring (scenario_activation.rs216) intentionally handles Call/Reply/Asynchronous only. Keep that exclusion: a self-Call starts at its lower receive endpoint, while self-Create/Delete's marker row must not be shifted or rewritten as a Call loop. Both aligners must preserve occurrence IDs and use the same recorded rows.
|
||
|
||
3. **Clip visible activation pieces by receiver AND exact scope.** alive_spans (render.rs154–175) intersects only Life::Alive intervals with the requested extent and rejects absent/unresolved regions. It may return zero, one or multiple pieces. Peer lifecycle projection gives siblings the same entry rather than the previous screen operand's exit, and marks conditional/repeated/parallel continuation unresolved when appropriate (scenario_lifecycle.rs197–205,246–273). Preserve that conservative meaning unless root separately decides otherwise. A parent activation must not bridge a death, pre-birth region or another operand merely because screen y is continuous. Retain typed call/receiver/scope/column identity for each surviving piece.
|
||
|
||
4. **Keep logical correlation timing distinct from clipped rectangle edges.** Root currently reconstructs Correlation.start and reply times from Segment.rect/Finish at scenario_activation.rs216–232; reply anchoring finds a segment by Finish::Reply without checking that its visible end is the reply's send y (around258–265). Blindly clipping rects while retaining the original finish on every piece is unsafe.
|
||
|
||
Concrete union falsifier: raw Call at148, receiver Delete at240, correlated Reply at332. Clipping the Call→Reply segment to148…240 and leaving Finish::Reply(reply332) makes the geometric end look like a reply at240. It also lets the actual reply at332 attach to that displaced execution's x despite no visible execution there. If several alive pieces survive, copying Reply to all pieces creates ambiguous first-match anchoring. Conversely, simply deleting Reply metadata can erase the real correlation used to distinguish crossed calls.
|
||
|
||
Required observable rule: only a visible piece that actually reaches the terminal reply-send coordinate can supply that reply anchor/cap. A lifetime-clipped end is not a reply. Preserve original call/compatible-reply timing for correlation decisions even when its visible representation is clipped or absent. This can be a small separation of logical metadata from visible fragments; it is not a request for another traversal engine or new model schema.
|
||
|
||
5. **Deletion terminates the local execution without pretending to answer the call.** Peer behavior.rs1723–1734 explicitly handles receiver Delete, clips at death, preserves an unanswered-call cue, and stops that local traversal. Root Finish currently has Reply/Boundary/Continuation/Open but no explicit death terminal. Decide a typed representation that distinguishes “execution terminated, call unanswered” from both reply and ordinary continuation. Preserve the sibling-open path and unresolved post-fragment state. Do not derive all unresolved cues only from surviving clipped fragments: an entirely invisible fragment can otherwise erase the semantic uncertainty cue. Nor may a later Create automatically resurrect an execution already terminated by Delete.
|
||
|
||
6. **Columns, hit geometry and paint use the same visible pieces.** One call's related pieces must retain a consistent chosen track; clipping cannot silently change call identity or make different siblings chronological. No active_segment result may come from an absent interval or from fabricated nesting caused by clipped start/end times (root scenario_activation.rs313–380). Preserve source/receiver anchors at real events, marker hit identity, and the paint worker's existing selection/layering correction. Integration must explicitly reconcile lifecycle lanes/markers with that painter; this report does not allocate or edit its files.
|
||
|
||
## Minimal combined acceptance cases before adoption
|
||
|
||
Retain the existing root nested/crossed/reentrant/self/UUID tests and peer lifecycle tests, adapting representations rather than dropping assertions. Add these discriminating combined cases in OA and SA where the core admits them:
|
||
|
||
- Delayed Create → C1 → C2 → R2 → R1 → Delete: typed starts are actual call receives, each reply reaches its correlated visible end, and bars remain inside alive spans.
|
||
- C1 → ALT(left: Delete; right: empty): preserve left death termination plus unanswered cue, right26-unit open span, and no definite post-frame bar. Peer `render_tests.rs:478–545` already provides the independent lifecycle oracle. Replace its width8 anonymous-box lookup with typed call/receiver/scope lookup; preserve the actual assertions.
|
||
- Call before delayed birth, Call spanning Delete, and a later correlated Reply after Delete: preserve admitted semantic data and lifecycle uncertainty; no invented reply finish at a clipping boundary or detached bar anchor. If a constructed sequence is rejected by core semantics, record that and use an admitted incomplete case.
|
||
- Delete then later Create: no automatic resurrection of the prior terminated activation. Multiple alive pieces must not duplicate reply finishes or unresolved cues.
|
||
- Self-Create/Delete after an Action retains16-unit clearance, marker receive row and hit identity; self-Call/Reply still uses the typed lower receive start. Peer `render_tests.rs:666–737` covers the marker half.
|
||
- Crossed replies spanning a clipped/uncertain operand: compare original compatible correlation endpoints so clipping cannot manufacture an innermost caller execution.
|
||
- Passive source roundtrip and moved test-only anchors compare **both** lifecycle geometry and complete typed segment tuples, plus final polylines, IDs, labels, frames and whole Project. Peer Scene experiment `mod.rs:88–104` already compares lifecycle but predates typed segments. Keep that assertion and add segment metadata. Its baseline self-call x oracle at175–178 must change from lane+75 to the actual typed lane/lane+66/lane+66/lane+6 for its isolated self-call; its send/receive y oracle remains636/660.
|
||
- Native pan/zoom and selection at birth/death markers and each exposed nested shoulder, including unselected bars, must verify the final combined painter. Root's native83f53c7 and peer historical renderer results each remain scoped to their own source.
|
||
|
||
The bounded Scene experiment at911f63e is explicitly uncompiled/unexecuted and does not cover delayed creation/deletion or nested activations. Passing its seven tests alone could not establish this union. Required interface decisions are the endpoint/clip/finish distinction and one geometry pipeline; no peer schema or general free-editing policy is accepted by this review.
|
||
|