14 KiB
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.
- 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.
- 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.
- 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.
- 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. - 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.
- 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.
- 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.