139 lines
12 KiB
Markdown
139 lines
12 KiB
Markdown
# Contextual source creation: independent preimplementation review
|
||
|
||
Codex-9e8r6t /root/behavior_audit, 2026-09-11. Reviewed the proposed
|
||
`release-contextual-source-creation-plan-20260911.md` against committed
|
||
`4bb4aaf3dc47b9738625b4d3f23ef8c74f286395` desktop contracts and current unchanged
|
||
core. Read AGENTS, revised PROJECT_GOAL, Gitea issue1 through #138, empty open PR
|
||
inventory and LocalBehaviorCreation20260911 Wiki. No evolving implementation was
|
||
read; no production edits, Cargo, direct rustc or native input. These are
|
||
source-derived integration traps and exact acceptance expectations, not findings
|
||
against the new implementation. Urgent items were sent directly to its author.
|
||
|
||
The proposed staged-source transaction is coherent for Lifeline, process Work
|
||
and new machine owner. Keep qualified Action allocation, new ScenarioUse targets
|
||
and the external chooser implementation outside this slice. The following
|
||
existing contracts require explicit handling; a generic wrapper is insufficient.
|
||
|
||
## Ranked material traps
|
||
|
||
1. **P1 — New first-action routes can implicitly commit another editor.**
|
||
In committed `app.rs:2326`, non-creation `starts_form()` invokes `self.apply()`.
|
||
A new first-lifeline/contribution button routed to the existing Start event,
|
||
arriving while a valid raw property draft exists, commits that property
|
||
before opening its form. The explicit Canvas Choose guard does not protect
|
||
this route. Reject source/property/pending conflicts in the actual new App
|
||
event path before generic Apply; a disabled button alone cannot guard stale
|
||
dispatch. Assert accepted snapshot/history and all raw strings unchanged.
|
||
|
||
2. **P1 — Stale scenario owners can panic before transaction validation.**
|
||
`scenario.rs`'s `parents()` always includes the supplied owner ID, even if that
|
||
element is absent. A recovered Lifeline draft therefore passes the first
|
||
destination check in `Draft::command`, then `sources()` at line 941 indexes
|
||
`p.elements[&d.owner]`. A removed owner can panic before `execute_batch` gets
|
||
a chance to reject it. Validate owner existence/kind/layer/viewpoint before
|
||
candidate rendering and parent planning. Show repair/cancel with both raw
|
||
drafts retained. Do not interpret a same UUID with changed kind or viewpoint
|
||
as the unchanged invocation merely because a new source still exists.
|
||
|
||
3. **P2 — Nesting the old process batch loses consumer selection.**
|
||
`topology/direct.rs:209` scans only immediate Batch children for a newly
|
||
created contribution. `Batch[CreateSource, Batch(parent_commands)]` therefore
|
||
returns no contribution selection. Core `session.rs:386` uses the last
|
||
selected operation and `SetSteps` at line 703 selects the process owner.
|
||
Flatten with preserved command order, or carry the exact prepared command's
|
||
consumer target through success. Test the actual App selection, including
|
||
rejection of changed/trailing commands borrowing that target.
|
||
|
||
4. **P2 — Stable source identity does not make the combined plan stable.**
|
||
`scenario.rs:1274` still creates a fresh Lifeline via `make_element` each
|
||
prepare; `topology.rs:476–508` creates fresh occurrence and link UUIDs.
|
||
Reserve/cache the complete created identity set, including repaired links.
|
||
With a blank consumer label, source and consumer share a display name: the
|
||
source already owns its alias in the private preview, so the consumer alias
|
||
includes its UUID suffix. Replacing only the temporary consumer ID leaves an
|
||
alias derived from a discarded UUID. All aliases, endpoints, SetSteps,
|
||
parent references and optional machine/view IDs must use the reserved set.
|
||
Require full prepared-Command equality across preview/retry/recovery, not
|
||
merely equality of the source UUID or final object count.
|
||
|
||
5. **P2 — A fresh Work source cannot satisfy every captured insertion.**
|
||
`topology.rs:438–449` requires a Work target next to an Exchange contribution
|
||
to equal that exchange's exact source/target UUID. A newly created Function
|
||
cannot equal an existing endpoint. The plan's successful “between two
|
||
contributions” case should use Action→Action. An Exchange-adjacent case must
|
||
refuse and retain both names and the exact slot; it must not retarget the
|
||
shared exchange, change a reusable definition, choose a different source or
|
||
silently append. Keep the existing full compatibility check on the preview.
|
||
|
||
## Semantic constraints that the new source form must expose accurately
|
||
|
||
`validation.rs:92` separates source containment from its use. Activity may be
|
||
root-owned or owned by Activity; Function by Function; OA Entity/Actor/Role may
|
||
be roots or children of Entity. Current SA System and SystemActor admit no
|
||
semantic parent, so a new SA owner is a root even when its machine is nested
|
||
under it. Neither process, scenario nor lifeline owns new work. A new Lifeline
|
||
belongs directly to its scenario, never an operand, and does not enter its
|
||
ordered steps (`session.rs:336` attaches Occurrences only).
|
||
|
||
`viewpoint_represents` at validation.rs:1262 admits Activity, Function,
|
||
Entity/Actor/Role, and System/SystemActor for the four explicit viewpoints
|
||
respectively. Role is valid for an OA participant lifeline but **not** a machine
|
||
owner: `Kind::is_performer` at model.rs:153 excludes Role. SA System uniqueness
|
||
is a hard project-wide error at validation.rs:238. A second System must refuse,
|
||
even if named differently; an Actor requires a separate explicit choice.
|
||
|
||
Do not turn completeness warnings into new blockers. Unallocated leaf work and
|
||
a missing SA System are warnings. Adding a lifeline to an already reused callee
|
||
can also be accepted while existing uses gain `missing_lifeline_binding`
|
||
warnings (`validation.rs:2112`); keep all caller bindings unchanged. By contrast,
|
||
an explicitly incompatible binding is an error. Compatibility uses represented
|
||
identities or explicit RoleRealization/RoleAssignment, never equal names
|
||
(`validation.rs:1283`, `:2073`). A new same-named Role does not impersonate an
|
||
existing referenced role, and staging it creates no realization or allocation.
|
||
|
||
Persist authored state and reserve identities, but separate it from runtime
|
||
canvas generations. Existing behavior recovery deliberately drops viewport and
|
||
revision tokens (`behavior.rs:789`); App reset gives a fresh `canvas_document`.
|
||
A recovered valid draft must be rebound to that runtime document without
|
||
reusing stale event invocations. A child invocation token must still reject
|
||
late Use/Name/Back events after that child was cancelled/reopened. Passive
|
||
scroll/viewport epoch changes must neither discard input nor count as a semantic
|
||
context change. New optional recovery fields must preserve older pending forms.
|
||
|
||
## Compact exact acceptance matrix
|
||
|
||
Use separate fixed symbols for source `S`, consumer `C`, child invocation `I`,
|
||
new link `L`, and optional machine/view/placement `M/V/N`. Only a new cancelled-
|
||
then-reopened invocation may reserve a new set. Every accepted row compares the
|
||
complete Project and SourceBundle against the explicit delta; every refused or
|
||
cancelled row requires exact accepted baseline and raw-draft preservation.
|
||
|
||
| Case | Exact expected result |
|
||
| --- | --- |
|
||
| OA activity lifeline | OperationalActivity scenario; source **Assess distress**, consumer **Assessment role**. Exactly Activity `S` at selected valid work parent/root and Lifeline `C` under the original scenario with `represented=S`. Names remain separate, description/body defaults empty, scenario steps unchanged. No allocation, capability involvement, actor, view or placement. Blank consumer label uses the source name; explicit label follows the existing consumer trimming policy, while raw text remains exact during staging. |
|
||
| SA function lifeline | Functional scenario, no existing Function/System. Exactly Function `S` at root or selected Function parent plus Lifeline `C`, with fixed represented identity. Missing allocation/System warnings do not cause fallback or automatic participant creation. Wrong-viewpoint source kind refuses. |
|
||
| OA Role and reuse mapping | ParticipantInteraction scenario can create Role `S` plus Lifeline `C`; no relationship is inferred. An existing local Actor maps to an existing referenced Role only through its explicit realization. A new same-named Role without that relationship cannot satisfy the old binding. While editing a reused callee, adding `C` leaves both existing caller-use records byte-for-byte unchanged; missing-binding warnings are expected, not auto-binding or rejection. |
|
||
| SA boundary and new owner kinds | BoundaryInterface permits explicit System/SystemActor, not Function/Role. Empty SA permits one new System; existing System makes another System refuse unchanged. Explicit SystemActor remains valid. Role cannot own a machine. Illegal source-parent choices refuse; source-parent change must not become machine-parent change. |
|
||
| Work at exact Action→Action link | For captured `A —(R, guard g)→ B`, source `S`, contribution `C`: add root/valid-parent work `S`; `C` is `Action { action:S, lifeline:None }` owned by that process. Preserve `R`'s ID/name/alias/guard and change only its target to `C`; add `L: C→B` with empty guard; insert `C` in the captured order. All sibling paths and referenced definitions unchanged. Select `C`. Repeat preparation/recovery with exactly the same new IDs/aliases. |
|
||
| Work next to Exchange / stale slot | A new UUID cannot equal the captured existing exchange endpoint; refuse without changing it. Also remove/change the captured link or presentation-before ID between staging and Apply: retain both drafts and require an explicit position repair. Never fall back to current selection or append. |
|
||
| Machine before participant | Name machine **Rescue modes**, opt into first view, stage explicit valid participant **Rescue team**. Commit exactly participant `S` + machine `M` with `parent=S`; optional view `V` named **Rescue modes · states**, StateMachine projection, one placement `N`, no regions/states/routes. Select/open `M/V`. Child Back restores prior owner; parent Cancel creates nothing. Re-selecting an existing owner commits no abandoned staged source. |
|
||
| Invocation, recovery and Escape | Parent label, source raw name, search, original reference, viewpoint, slot and IDs survive child opening/Back/recovery. Old invocation `I` cannot affect a reopened child `I2`, even with identical names and owner IDs. Restored valid drafts survive the fresh runtime canvas ID; missing owner refuses without panic. Overlay Escape closes the overlay first, then child Back, then parent Cancel. The focused captured-Escape path must follow the same ordering. |
|
||
| Semantic first action and history | With no semantic contributions, first-work action is directly visible; with no lifelines/occurrences, first-lifeline action is visible. An unresolved lifeline (`represented=None`), offscreen content, ScenarioUse or fragment prevents a false “empty” claim. A lifeline-only scenario gets applicable guidance without inventing an exchange/action allocation. CTA appearance/resize and rejected stale Start leave model/source/history/raw properties unchanged. |
|
||
|
||
For committed names with leading/trailing whitespace, pin source and consumer
|
||
policies explicitly: current scenario/topology planners trim an explicit
|
||
consumer label; they do not overwrite it with the selected source's label. Do
|
||
not claim all committed names remain byte-exact by inspecting only raw recovery.
|
||
|
||
One Undo must restore the prior Project and reachable SourceBundle, while disk
|
||
Save may retain newly detached source files. Use the corrected oracle's explicit
|
||
history origin: disk equals the first committed checkpoint's file map overlaid
|
||
with expected reachable files; unknown/changed retained bytes fail. Redo/reopen
|
||
uses original committed role IDs, not newly borrowed replacement UUIDs.
|
||
|
||
This matrix deliberately excludes qualified Action allocation and new reuse
|
||
definitions. Those require further explicit semantic intent; they are not
|
||
required to validate this staged-source slice. The external chooser remains
|
||
owned separately. Implementation review and native evidence follow only after
|
||
the author freezes the new source.
|