393 lines
31 KiB
Markdown
393 lines
31 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.
|
||
|
||
## Independent implementation review, 2026-09-11
|
||
|
||
Codex-9e8r6t `/root/behavior_audit`. Resumed after the author froze the first
|
||
production candidate. Read issue #1 through #151 and traced the actual App,
|
||
behavior dispatch, nested draft, recovery, view, and command-selection paths.
|
||
The author made explicitly identified corrections between the first and second
|
||
compile windows. This reviewer edited only this report and ran no Cargo, rustc,
|
||
native input, or implementation tests. The author's first compilation exposed
|
||
missing Clone derives; no passing runtime result is inferred from that compile.
|
||
|
||
Five independently derived counterexamples were sent directly to the author
|
||
and root. All five have corresponding corrections in the second frozen source
|
||
inspected here. The following is source verification, pending the author's
|
||
19-case focused gate and root's native acceptance.
|
||
|
||
| Priority / finding in first candidate | Concrete counterexample and consequence | Correction inspected in second frozen source |
|
||
| --- | --- | --- |
|
||
| P1: missing pending owner can panic while rendering another owner | Recover source draft for scenario A after A is absent, with another same-layer scenario B present. `behavior::selected_owner` returns pending A, while `behavior::view` falls back to B. B's workspace calls `scenario_context().expect(...)`, but the context still resolves absent A and is None. Process fallback has the same mismatch. With no other owner, the pending form is hidden behind New instead. Safe `sources()` and `prepare_pending()` do not protect this render path. | `behavior::view` now checks the pending owner's presence/kind/layer before choosing a fallback. It shows the retained consumer name plus current child form or explicit parent Cancel. The child Back remains reachable; it never silently opens B as the pending consumer. New orphan-view tests construct both no-choice and remaining-B cases. |
|
||
| P1: staged recovery completeness was assumed by presentation | Recover selected staged source with `source.staged.kind = null`, a valid value for its serialized `Option<Kind>`. Deserialization accepts it; `State::label` then calls `unwrap()` and panics in parent view/selection before command validation can return its existing missing-kind error. | `source_draft::State::label` is now total and displays a missing-kind label. Planning still refuses; raw recovery remains intact. A malformed-kind regression exercises both planning and the label. |
|
||
| P2: owner-first machine creation cannot leave its valid child | New → Machine, leave machine name blank, Create new owner, choose valid kind/name, Use. The source is valid, but the parent handler calls `next.command(p)` and refuses the blank machine name. Parent edits are locked while the child is open; Back drops the entered owner before the machine can be named. | Machine Use stages the valid prerequisite and checks the actual eligible-owner predicate on its private preview. It does not require an already complete machine. Final Submit still validates the complete batch. The owner-first regression keeps the same source/name while the machine is subsequently named. |
|
||
| P2: footer Back disagrees with Escape on retained stale/dirty recovery | After recovering unrelated dirty source/property text, App rejects every source event, including Back. After deleting/changing the owner, scenario/topology validate the origin before dispatching Back; the helper also compares scope first. The visible Back button refuses although global Escape succeeds through `source_back()`. | Token-only `source.dismiss` runs before semantic context checks. App exempts only `Source(Edit::Back)` from other-editor admission. Wrong/old tokens still refuse; Open and Use keep their guards. Added dirty-editor and deleted-owner Back regressions preserve parent/property state. |
|
||
| P2: new empty actions accept a previous owner's event | Capture A's new first-action message, navigate to clean B or another layer, then deliver A's bare `Start(owner, tool)`. That route checks dirtiness and owner existence but carries no context. It can open A; `selected_owner` prioritizes the resulting pending owner. | Scenario CTAs now use `CanvasEvent::First(Context, Tool)` through the existing context and dirty guards, with a fresh semantic emptiness check. Process first Work uses its existing context-bound Begin with the explicit default insertion. A new owner/layer-stale CTA regression rejects old context and admits the current one. |
|
||
|
||
The source changes address the reported mechanisms. Their tests are authored
|
||
regressions, not independently executed evidence in this review. In particular,
|
||
constructing an orphan view prevents the identified `expect` panic but does not
|
||
by itself prove its footer can be clicked at the minimum native window size.
|
||
|
||
The unchanged core contracts are used correctly in the inspected paths:
|
||
|
||
- App form start/source admission checks raw source and property dirtiness
|
||
without calling generic Apply. Source/parent submission retains the existing
|
||
dirty guard. Model-menu and modal Escape precedence is resolved before child
|
||
Back, then parent cancellation. Raw edits and form rendering create no
|
||
accepted model/history operation.
|
||
- Source commands keep source name, semantic parent, kind, layer, document, and
|
||
exact captured consumer/parent identity distinct from the consumer. Existing
|
||
validation admits Role only where appropriate, enforces System uniqueness,
|
||
and preserves allowed completeness warnings. No allocation, role realization,
|
||
reuse binding, or shared exchange retargeting is inferred.
|
||
- For an actively selected staged source, the helper previews the source,
|
||
prepares the original consumer, remaps every new element/relation identity
|
||
and typed reference plus SetSteps to the reserved set, then forms one flat
|
||
validated batch. Recomputed aliases use the reserved IDs rather than an
|
||
abandoned temporary UUID. Machine/view/placement identities remain reserved
|
||
by the existing creation planner. This review does not claim that the older
|
||
non-staged planners reserve their IDs across separate preparations.
|
||
- App compares the complete prepared staged command before assigning its
|
||
consumer selection, and assigns it only after `Document::execute` succeeds.
|
||
Parent acknowledgement follows success. Choosing an existing reference makes
|
||
the staged source inactive: preview/combine omit it, so it is not published.
|
||
Parent Cancel drops the entire pending state.
|
||
- Captured process link identity/endpoints and presentation-before slot remain
|
||
validated. Work insertion preserves the existing guarded link and adds the
|
||
new successor link; a fresh source next to an existing Exchange still cannot
|
||
impersonate the required endpoint and refuses with raw input retained.
|
||
- New empty guidance counts semantic Lifeline/Occurrence/contribution records,
|
||
rather than rendered positions. An unresolved lifeline is still a lifeline;
|
||
ScenarioUse, fragment, and offscreen content do not become empty merely
|
||
because of presentation. Existing scenario canvas/scroll slots remain in the
|
||
surrounding workspace tree while the explicit child form occupies its form
|
||
pane.
|
||
|
||
The author deliberately made explicit staged-consumer names exact, including
|
||
leading/trailing whitespace; source names are also exact, and a blank consumer
|
||
continues to default to its chosen source name. This supersedes the earlier
|
||
matrix's inherited trimming expectation **for active staged-source consumers**.
|
||
The older existing-reference consumer path still has its pre-existing trim
|
||
policy. Native/oracle expectations must distinguish those paths and must not
|
||
borrow an observed output name to define the expected model.
|
||
|
||
Second frozen source fingerprints captured at approximately 11:39 UTC:
|
||
|
||
| File | SHA-256 |
|
||
| --- | --- |
|
||
| `crates/oa-desktop/src/app.rs` | `81E0AA21A93126D716E628B3EBD440201AB19D6B578E2585F5E500072244D58B` |
|
||
| `crates/oa-desktop/src/behavior.rs` | `A0E595F17F254002F1FBD7984EEB679320DAB042CA310C38D8916F0055713780` |
|
||
| `crates/oa-desktop/src/behavior/source_draft.rs` | `32057E30C0526FA674D463F47C4EAC7C0F391B1F4C5060757981A3CBED16C6AE` |
|
||
| `crates/oa-desktop/src/behavior/scenario.rs` | `759805631BE9E8526DACFB959D91C76CA1A2A40F47F8645BCEB0E0C15B77E326` |
|
||
| `crates/oa-desktop/src/behavior/topology.rs` | `8E1C65AFE4C7C097F683B33A6DF237219F48AFD1E81F81329B07612F4D6994CC` |
|
||
| `crates/oa-desktop/src/behavior/creation.rs` | `BE75840293E84FCAE90DC6D17CCD6630A586B389FB189ADF73D1E9B046CE3DE2` |
|
||
| `crates/oa-desktop/src/behavior/contextual_source_tests.rs` | `242B68E0DFF14E57E1F510EA3DEA95ED1B2ADCDABFD24C9F493FC871CB50F049` |
|
||
|
||
No additional implementation blocker was found in this bounded review. Required
|
||
evidence still includes terminal focused checks and native minimum/wide form
|
||
authoring, plus independent complete model/source comparison for actual
|
||
source/consumer creation and Undo/Redo/reopen. The earlier explicit detached-file
|
||
retention rule remains unchanged. No native result, full-suite result, or release
|
||
completion is claimed here.
|
||
|
||
## Final staged-source delta review, 2026-09-11
|
||
|
||
Codex-9e8r6t `/root/behavior_audit`. Reviewed only the changes after the recorded
|
||
second freeze: compact consumer captions, explicit creation summaries, recovered
|
||
typed-scope validation, nested semantic-parent and callee/caller regressions,
|
||
guide correction, and App Undo/Redo result handling. Read the final author gate
|
||
and current Gitea decisions through #178. No production edits, Cargo, rustc or
|
||
native input; root retains the immutable full-suite run and native acceptance.
|
||
|
||
The source inspected in this pass matched all ten corresponding entries in
|
||
`.local/contextual-source-20260911/focused4-inputs.json`: App, behavior, source
|
||
draft, scenario, scenario workspace, topology, topology view, creation,
|
||
contextual-source tests and guide. This identifies the precise compiled source
|
||
without presenting the earlier second-freeze fingerprints as current.
|
||
|
||
### Concrete corrections identified at the final boundary
|
||
|
||
1. **P2 — The State machine guide still directs the user out of the new flow.**
|
||
At `guide.rs:547`, the first step says to cancel and create a missing owner in
|
||
Architecture; the immediately following new step describes Create new owner
|
||
with the retained machine draft. The old sentence would unnecessarily lose
|
||
the user's pending setup and hides the new supported route. Sent directly to
|
||
the author/root; the author removed it after the Clippy source freeze and
|
||
this reviewer confirmed the source readback. The guide's previously rejected
|
||
`explain` argument count is already corrected in the passing focused4 source.
|
||
|
||
2. **P2 — The source origin must survive inactive dependency planning.**
|
||
The author identified this additional case before review closure, and this
|
||
reviewer independently confirmed its actual code path. Start a Lifeline or
|
||
Work form with a valid existing target, open Create new source, then Back.
|
||
`source.engaged` remains true, but there is no editing/active staged source.
|
||
`check_scope` and `preview` therefore pass without a source-side document
|
||
check. Parent `Draft::command` at scenario.rs:1350/topology.rs:582 then reaches
|
||
its ordinary consumer planner against a different `Project.id` with the same
|
||
owner and target UUIDs. The captured `source_origin` is checked only while
|
||
handling Source events. Use followed by reselecting an existing source has
|
||
the same inactive-dependency mechanism. This is a concrete preparation-boundary
|
||
failure; no claim is made that ordinary file navigation preserves the form
|
||
through its existing App reset.
|
||
|
||
The narrow proposed correction checks captured document plus exact owner at
|
||
final command preparation whenever source creation has been engaged, keeping
|
||
token-only Back and cancellation available. Regression must begin with a
|
||
valid existing target, prove baseline preparation succeeds, then refuse the
|
||
other document while retaining all raw fields. A compatibility edge was sent
|
||
separately: old recovered forms legitimately have `source_origin=None` and
|
||
unengaged default source state. Their first successful source Open should bind
|
||
the current origin; an already engaged missing/mismatched origin must never
|
||
be silently rebound. The author implemented these document/legacy controls
|
||
after the source freeze, with a valid-target Scenario/Work × Back/inactive ×
|
||
ordinary/legacy regression matrix. That later source is not covered by
|
||
focused4 and no new execution is claimed here.
|
||
|
||
**One final owner-binding detail remains at this handoff.** The initial new
|
||
guard compares the captured owner with `p.elements.get(&owner.id)`. A recovered
|
||
origin can contain another valid, unchanged same-layer owner B while the
|
||
parent draft still targets A. That lookup validates B against itself; the
|
||
otherwise valid consumer planner still operates on A. Compare the captured
|
||
owner record with `p.elements.get(&self.owner)` in final planning and
|
||
`p.elements.get(&d.owner)` in Source-event admission, or explicitly require
|
||
the two IDs to agree. The simplest negative control replaces only the
|
||
serialized origin's owner record with B, leaving the valid target/slot and
|
||
actual draft owner A unchanged. This avoids a false rejection caused by an
|
||
unrelated invalid Scenario parent slot. This reviewer sent that independently
|
||
derived detail to author/root; final strengthened source readback is pending.
|
||
|
||
### Confirmed scope of the other deltas
|
||
|
||
- New outer consumer captions call `views::short` with 60 characters, or 80 in
|
||
the orphan card. That helper collapses whitespace and truncates presentation;
|
||
it does not rewrite raw draft names. The source fields still have their own
|
||
remaining-height scroller and a separate Back/Use footer. Active-source
|
||
summaries describe the actual source+lifeline/work/machine transaction, with
|
||
the first machine view explicitly conditional. No view call adopts a model
|
||
command. Native minimum-window readability is not inferred from this trace.
|
||
- `source.check_scope` is called before preview in all three parent planners.
|
||
A selected staged source or current child with the wrong typed consumer scope
|
||
is rejected; an inactive staged source remains excluded. The malformed-kind
|
||
regression now also falsifies a Machine scope inside a Lifeline draft.
|
||
- The nested-parent test uses a real OA Activity parent, refuses an Entity as
|
||
work ownership, stages exactly one child Activity, then changes the captured
|
||
parent's kind and proves private preview refuses without changing the raw
|
||
source state. The implementation validates both the exact parent snapshot
|
||
and current `can_parent` predicate. This is not a test of every parent family.
|
||
- The callee regression has one existing ScenarioUse with an empty binding list.
|
||
Adding a new Activity-backed callee lifeline preserves every original
|
||
element, relation and diagram and produces the expected
|
||
`missing_lifeline_binding` warning on that use. Its shared history helper
|
||
checks model/source Undo, Redo and fresh source reconstruction. This is useful
|
||
evidence for allowing an incomplete caller; it is not a claim of independently
|
||
testing multiple callers with nonempty Role mappings.
|
||
- App Undo/Redo now uses the actual boolean returned by `Document`, calls sync
|
||
only for a history step, and reports Nothing to undo/redo when appropriate.
|
||
Its test exercises both an empty history and a real rename through the public
|
||
`Message::Command` path. Existing `apply()` guards for pending behavior/source
|
||
remain in front; the existing property-Apply behavior is unchanged. No claim
|
||
that all Undo/Redo requests are inherently free of property application is
|
||
introduced.
|
||
|
||
### CLI documentation cross-check
|
||
|
||
`docs/source-cli.md` and README's explicit `cargo run --locked -p oa-cli --bin
|
||
arcadia -- check examples/text-first/project.arcadia` example match the final
|
||
CLI adapter. The example's execution was already verified by root and was not
|
||
repeated here. The page correctly separates aliases from display names, previews
|
||
from explicit per-invocation writes, changed-file reports from unchanged captured
|
||
dependencies, pending recovery from automatic recovery, and source3–7 migration
|
||
from canonical formatting or detached-file deletion. Root accepted and applied
|
||
two precision additions during this review: Unicode scalar columns, and
|
||
`written:false` not implying guaranteed rollback. Readback confirmed both. No
|
||
new CLI implementation issue or saved-plan/digest requirement was raised.
|
||
|
||
### Evidence status
|
||
|
||
Read the author's terminal `focused4.log`/status: **22 passed, 0 failed, 653
|
||
filtered**, 2.04 seconds test execution, exit 0 at 11:59:25 UTC. The matched
|
||
immutable test executable is SHA-256
|
||
`6E677F58458B6122EA1886AAC98882640CD9CF260651FE3ECE62BDDA4BE38CC0`, inventory 675.
|
||
The full suite was running under root at review time; it is not reported passed
|
||
here. Guide/source-origin corrections above are later deltas and require their
|
||
own coherent source/test evidence, including the final owner-binding detail.
|
||
Current source-input manifest, focused logs,
|
||
and author's revised implementation report remain the build evidence authority;
|
||
this reviewer executed no desktop tests or native workflow.
|
||
|
||
### Final source readback closure
|
||
|
||
The author froze the strengthened source and root requested a short final
|
||
readback. **No remaining material source finding in this bounded delta review.**
|
||
This closes the pending owner-binding detail above; it does not assert that the
|
||
new source has completed its later compiled/native gates.
|
||
|
||
All four guards now compare the captured owner record against the actual parent
|
||
draft's `d.owner`/`self.owner`, in addition to the document identity. The 23rd
|
||
regression includes ordinary/legacy × Back/inactive-existing variants for both
|
||
Scenario and Work. Each has a valid existing-target control, wrong-document and
|
||
null-origin refusal, and a borrowed full record from another valid same-layer
|
||
owner. The latter must fail both final preparation and Source Open while the
|
||
entire raw recovery snapshot remains unchanged. This is the exact falsifier
|
||
requested in the preceding handoff, not an unrelated invalid-parent failure.
|
||
|
||
For an old unengaged draft, first Source Open creates its missing origin only in
|
||
a private clone; the clone replaces the parent only after source admission
|
||
succeeds. It cannot rebind an already engaged missing/mismatched origin. Back is
|
||
still dismissed by its token before those semantic guards, and parent Cancel
|
||
remains available. The old guide sentence is absent and the retained-owner
|
||
creation instruction is present.
|
||
|
||
Readback hashes match the author's final freeze:
|
||
|
||
| File | SHA-256 |
|
||
| --- | --- |
|
||
| `behavior/scenario.rs` | `D12A4B1CAA61C08F69C4D2A64BD15568C4B7158DEA91AAC5A52A58A35ADB863C` |
|
||
| `behavior/topology.rs` | `D06B2F0FC39B4814E94200297E148F1D4D97E04CB167766030AC9DF18689E3B0` |
|
||
| `behavior/contextual_source_tests.rs` | `5F05318A6533503B9D6FEBF1EC4DD7256F192394BC1B952A7904C8175BD8DDAE` |
|
||
| `guide.rs` | `47EEB3CC0A48D5712720096015A08387CD354FB91559B0BD6FA106B5CAC6292C` |
|
||
|
||
Paths in this last table are under `crates/oa-desktop/src/`. Root subsequently
|
||
reported the earlier immutable 675-test artifact passed 675/675 in 448.33 seconds
|
||
(Gitea #185). That artifact predates these final corrections. The author's
|
||
focused5, matching GUI/lint and root's native/source oracle remain the appropriate
|
||
next evidence; no Cargo, rustc, native input or production change was performed
|
||
by this reviewer during closure.
|