# Qualified scenario Action allocation — bounded design, 2026-09-11 Codex-ytr83r / server_audit. Design only; root ratification is required after published staged-source integration. Only this report is owned. No production, core, compiler, native-input or Git mutations were performed. Source citations describe the current local working source, with HEAD observed as `023e3a8f097158ac84ca47a58cfa917c503804b0`; they are not claims about another host's unpublished implementation. ## Coordination and scope Read Gitea issue #1 through #225, the empty open-PR inventory, and Wiki pages ContextualSourceDrafts20260911, LocalBehaviorCreation20260911 and BehaviorAuthoring20260911. Ownership announced in #225. The staged-source plan and independent review, textual-authoring design, local behavior-creation report and behavior-gap audit were consulted. Codex-9e8r6t owns the existing staged prerequisite implementation. Its current Wiki/#214 reports Lifeline, process Work and machine-owner staging, with no inferred allocation; qualified Action allocation is explicitly deferred in both plan and independent review. Their test/native evidence must not be attributed to this proposal. This proposal adds a small explicit responsibility decision to that future integrated draft infrastructure. It does not recreate source staging, alter the external chooser, add a metamodel relation, or expand exchange/operation/reuse authoring. "Qualified" here means an Action on the exact clicked local lifeline and sequence slot, not traversal into a reused scenario definition. ## Confirmed behavior and the actual gap Existing unallocated work is **not universally blocked** on participant lanes. The current Action source picker includes all same-layer work (`behavior/scenario.rs:942`, especially line 953). The planner requires an existing source and a local lifeline, then creates only an Action occurrence (`scenario.rs:1370`), with ordered insertion at line 1441. It creates no allocation. Canvas entry captures the exact slot and represented local lane (`scenario.rs:508`); an unresolved lane refuses this entry at line 527. The core only reports `scenario_endpoint` when compatibility is `Some(false)`; unresolved `None` is not that error (`oa-core/src/validation.rs:3006`, Action dispatch at line 3045). Consequently a same-layer, previously unallocated leaf can be selected and committed on a concrete participant lane, subject to all other admission rules. The ordinary `unallocated_leaf` warning remains (`validation.rs:342`). This is source-derived behavior, not a new native pass. The form does not thereby make or prove a responsibility assignment. The missing workflow is **explicitly allocate existing work and add its Action**, or **create work, explicitly allocate it, and add its Action**, without abandoning the clicked slot/name/draft. The local form offers an existing named-source picker (`scenario/workspace.rs:331`) and observed-lifeline picker (line 476), with no allocation operation. Basic missing-source staging elsewhere is already owned and must survive unchanged. Earlier wording that all participant Actions require an already resolved performer is too strong for current admission. ## Exact eligibility rules | Lifeline/viewpoint | Existing Action compatibility | Explicit new responsibility | | --- | --- | --- | | OA OperationalActivity / Activity | The represented Activity itself matches by identity, regardless of allocation. A different Activity is incompatible. | No allocation is needed to observe represented work; never replace the lane's represented identity to make another work fit. | | SA Functional / Function | Same identity rule for Function. | Same restriction. | | OA ParticipantInteraction / Entity or Actor | Effective performer equals represented participant: compatible. A different known performer: incompatible. Missing or ambiguous effective performer: unresolved, admitted unless another rule fails. | A direct Allocation from this exact participant to an admissible leaf Activity can make the responsibility explicit. | | OA ParticipantInteraction / Role | An explicit RoleAssignment from this exact Role to the Activity is required; absence is incompatible, even when some participant realizes the Role. | A Role is not a performer. RoleAssignment is a distinct engineering choice; never label it Allocation or silently pick a role realizer. Defer creating role assignments in the first direct-allocation slice. Existing assigned-role Actions remain supported. | | SA BoundaryInterface / System or SystemActor | Same effective-performer rule, for Function. These are the actual component families admitted in this viewpoint. | Direct Allocation from the exact System/SystemActor to leaf Function. No new component, port, interface or exchange is implied. | | Unrepresented local lane / MixedLegacy | Incomplete models remain admitted through existing paths; direct canvas entry requires representation. MixedLegacy retains its current compatibility semantics. | Do not invent a representation or expose new allocation staging for these cases in the first slice. Preserve existing editing. | Authority: `validation.rs:1262` (viewpoint families), `:1284` (same-layer identity, RoleAssignment and performer compatibility), `:1329` (lifeline adapter). `effective_performer` at `:2850` uses one direct Allocation first; otherwise it collects distinct RoleRealization sources for all assigned roles and resolves only a singleton. It does not inherit allocations from work parents. `allocation_summary` at `:2811` is display aggregation, not an inherited relation. Allocation permits performer-to-work (`model.rs:931`); performers are Entity, Actor, System, SystemActor (`model.rs:153`). Its target must be a leaf and have at most one direct Allocation, even if duplicates would name the same performer (`validation.rs:2528`). Work containment remains Activity-under-Activity or Function-under-Function (`validation.rs:92`), not participant containment. RoleAssignment likewise targets leaf Activity; a direct performer outside a nonempty assigned-role realizer set raises the existing `role_allocation_conflict` **warning**, not an error (`validation.rs:2553`). The UI must disclose such a warning without claiming the core prohibits it. ## Two minimal explicit workflows | Design | Interaction and transaction | Tradeoff | | --- | --- | --- | | A — responsibility section in the Action form | Choose existing work or stage new work; show exact work and participant with a choice between leaving responsibility unchanged and adding the displayed Allocation. Final Create commits the opted-in allocation plus Action and any new source. | Fewer navigation steps; however it places an architectural change beside routine occurrence fields and needs careful inactive-option pruning when work/lane changes. It must never precheck allocation because the work is unallocated. | | B — explicit nested “Allocate work to this participant…” action | Beside the source field, open one contextual child with the exact participant fixed and visible. Choose existing unallocated leaf or Create new activity/function using the integrated staging machinery. Show “Allocate [work] to [participant]”; Use returns a staged work+allocation to the Action form. Final Create shows the whole effect and commits once. | One extra navigation step, but the engineering decision is named at entry and confirmed in context. It matches the staged-source ownership/Back/Use pattern and keeps ordinary Actions small. | Recommend **B**, as a later adapter over the integrated staged-source planner. Use one child editing level, with existing/new work modes inside it, rather than opening a second nested source modal. Keep the existing source selection route available, including incomplete responsibility admitted by core. For that route, plain wording such as “Responsibility is not yet resolved; no allocation will be added” prevents a successful Action from implying an assignment. For already compatible work, use its existing direct or role-derived responsibility unchanged. Do not add a redundant direct Allocation merely to turn a derived singleton performer into a direct one. Offer the new direct route initially for work with no direct Allocation and no assigned roles, plus new work. This is a deliberately bounded UI scope, not a stronger language rule. Shared or conflicting role responsibility deserves a separately explicit role-resolution workflow. Work already allocated elsewhere is not silently reassigned; no delete/replace-allocation action belongs in this slice. The child shows source name, kind, alias/identity and semantic parent separately from the Action's name and local lifeline. A new source parent is root or an explicit valid work parent. Adding a child can make an already allocated parent non-leaf, so validate the complete candidate rather than merely the new child. Never create from a failed search automatically or bind duplicate names by first match. Changing the observed lane/work must visibly invalidate the old staged allocation, without silently retargeting or retaining an unused source. ## Atomic effects, recovery and invalidation Capture the original document/model identity and revision, draft invocation, scenario/viewpoint, local lane and represented participant, exact operand and before-anchor, selected work and semantic parent. Preserve raw names, search, scroll, slot and reserved work/allocation/occurrence IDs in recovery. Reuse the staged-source implementation's exact-owner guards and command-correlated post-commit selection; do not weaken navigation guards or auto-apply unrelated raw source/property editors. For existing work, the final flat batch adds one Allocation `P -> W`, one Action `{ action: W, lifeline: L }` under the captured scenario/operand, and updates only that owner's steps at the captured slot. For new work it additionally creates one Activity/Function at its explicitly chosen semantic parent. No lifeline, participant, capability involvement, RoleAssignment/RoleRealization, exchange, placement or caller binding is invented. Source and occurrence names are independent; aliases and IDs are reserved once, including retry/recovery. Use a private preview to validate staged commands and final occurrence together; the accepted Project/catalog/source remain unchanged until final Create. `session.rs:170`/`:286` provide prepared command/batch admission. `document.rs:301` prepares the candidate, updates source with its identity map, and only then commits; `:352`/`:365` restore whole accepted snapshots for Undo/Redo. One Undo must restore the pre-operation Project and accepted SourceBundle, and Redo the same IDs and bytes. File persistence remains the existing later Save contract, not a new multi-file filesystem-atomicity promise. Back/Escape from the child discards only that child; parent Cancel creates nothing. Selecting existing work afterward prunes inactive staged source and allocation commands. Refused core/source preparation retains the complete raw draft and accepted history. Changed document, owner, viewpoint, lane representation, participant/work ownership, reserved ID, branch/anchor or allocation state requires refusal with retained intent and explicit restart or review, not a fresh interpretation against current selection. Missing/foreign lanes, wrong-layer work, invalid semantic parents and lifecycle use outside the allowed scope are still checked by the common admission path. ## Concrete acceptance predictions and falsifiers These are predictions for a later implementation gate, not executed tests. Extend the existing scenario/staged-source/native oracles rather than duplicate their fixtures and reports. Prepare full expected models/source before GUI input. 1. **Preserved baseline admission:** on OA Entity and SA System lanes, select existing unallocated leaf work through the ordinary source picker. Exactly Action plus steps changes; no Allocation appears and the unallocated warning remains. If this instead universally refuses, the source-derived baseline above is falsified and must be revisited before UX implementation. 2. **Existing-work explicit allocation:** on OA Actor and SA SystemActor lanes, stage previously unallocated leaf W. Use/Back/preview create nothing. Final Create adds exactly one relation and one occurrence at the clicked ALT operand before-anchor; other operand/source/work bytes are unchanged. One Undo/Redo restores complete snapshots and exact IDs, including after Save/reopen. 3. **New-work explicit allocation:** repeat OA Entity and SA System with distinct source/Action names and an explicit valid work parent. Exactly one work, Allocation, Action and local steps edit; no new lane or capability relation. Retain unrelated Unicode/CRLF include and detached-file bytes under the existing save contract. A source-update limit refusal must commit none of it. 4. **Role and work lanes:** represented work accepts itself without allocation; different work refuses. Assigned OA Role accepts its exact RoleAssignment; absent assignment refuses `scenario_endpoint`. No direct-Allocation button appears for Role and no realizer is guessed. Singleton role-derived concrete performer uses the existing route without creating a redundant relation; shared-role ambiguity remains explicit and does not choose a participant. 5. **Ownership and allocation failures:** work already allocated elsewhere, non-leaf work, duplicate direct allocation, foreign/wrong-layer lane or work, and a new child making an allocated parent non-leaf refuse the new operation with exact accepted model/source/history retained. Role conflict warnings remain warnings; the first UI slice can decline complex role editing without misreporting it as a core error. 6. **Recovery/staleness:** recover names, slot and all reserved IDs; change lane representation, source parent, viewpoint, branch membership or allocation in the accepted model. Late Use/Submit must not allocate a different participant or move the Action. Pending unrelated property/source edits remain untouched. 7. **Native context:** at 1100×700, keep the clicked lane/operand understandable; source identity, allocation direction and pinned Back/Use/Create controls are visible with long duplicate names. Keyboard child Back returns to the correct parent field; overlay Escape precedes child Back and parent Cancel. Final selection is the exact new Action, with stable camera/caller context. No implementation lease follows from this report. Root should first integrate the published staged-source work, recheck these source seams and baseline admission, then ratify the small direct-allocation adapter and its first UI scope.