# Process removal source-oracle investigation — 2026-09-25 Local-only, bounded investigation at source `fe637dcd277b17653139ffa234e601b29775c565`. Parent owns Process removal and oracle integration. No production code, tests, or versioned fixtures edited; no Cargo, build, UI or Gitea operation. Another worker's `model_menu.rs` edit was observed and left untouched. ## Conclusion The full semantic Project comparison passed before the lexical assertion failed. The three selected/dependent declarations (Action `a`, Control `c`, SequenceLink `approved`) are removed, Process steps retain `e1,e2`, reused definitions and unrelated OA/SA records agree with the independently authored model oracle. The failed assertion is an incorrect **lossless-source oracle**, not evidence of a semantic deletion defect or a newly introduced writer regression. The source contract explicitly says removed declarations erase syntax tokens while retaining their comments **and whitespace** as enclosing annotations (`docs/language.rst:1987-1989`). It also requires deletion annotations be separated from adjacent declarations with blank lines (`:1963-1964`) and preserves surviving reference-list chunks and their separator-adjacent trivia (`:1993-2000`). Canonical export is a different operation (`:1926-1929`); the mutation path must not silently reformat source (`:1969-1973`). `harness/release-source-project.md:43-45` and `harness/DECISIONS.md:87,93` corroborate this accepted policy. This does not establish that blank space-only annotations are the ideal future editor UX. They follow an explicit existing contract and pre-existing implementation; changing them would require a separately scoped source-policy decision and source/core validation. Silently removing them solely to satisfy a newly authored Process oracle would change the common writer contract. No production formatting fix is justified within this aggregate-removal acceptance task. ## Independent derivation Input `harness/fixtures/process-removal-baseline-20260925.arcadia`: - Source commit: `fe637dcd277b17653139ffa234e601b29775c565`. - Git blob: `9570e150d160bea87dc70b5dacedc692eb3708b4`. - SHA-256: `9965f4024584d64ac81442724aeb77b018b0cfae94e50bd412c5dcbbac49f6bf`. - Original UTF-8/LF bytes are required; derivation refuses changed input or CR characters. 1. Original steps are `[@a,@e1,@c,@e2]`. Surviving entries have no leading/trailing trivia and the removed entries have no trivia. Retain `@e1` and `@e2`, emit their one comma, and invent no whitespace: **`[@e1,@e2]`**. `source_project.rs:1516-1651` implements unique-reference identity matching and chunk preservation; this is not canonical `, ` formatting. 2. For each removed single-line declaration, quoted strings are indivisible syntax tokens. Their interior spaces disappear with those strings. Every whitespace byte outside strings survives, including the four-space indentation. Independent token-boundary counting yields **22 spaces for Action `a`, 20 for Control `c`, 16 for link `approved`**. 3. `source_structure.rs:236-271` creates deleted-declaration pieces through `trivia`; `source_project.rs:1127-1139` retains only Whitespace/Comment tokens. `attached_span` at `source_structure.rs:435` includes the line indentation and leaves the ordinary following newline in the enclosing gap when there is no trailing comment. 4. Existing concrete structural policy (`source_structure.rs:397-404`) surrounds each orphaned annotation with **two LF characters on each side**. The untouched original gap has one LF on either side. Consequently the exact post-predecessor sequence is `"\n\n\n" + " " * N + "\n\n\n"`, followed by the next declaration's unchanged four-space indentation. These are three LF characters per side, not three full empty lines per side. 5. All other baseline bytes remain unchanged. The specification requires whitespace retention and blank-line separation; the exact two-LF inserted boundary is the established writer policy, not a claim that every conforming future writer must always choose that count. The common structural file's latest historical change is `4e8575bd1127d132b8170b408163ef234b4d307e` (`feat: preserve nested source projects across desktop and REST`), predating this Process change. Existing tests `crates/oa-core/tests/source_project.rs:1065` (`removed_list_items_and_declarations_keep_comments_as_enclosing_annotations`) and `crates/oa-core/tests/source_nested_updates.rs:187` (`deleting_owner_retains_annotations_and_extracts_independently_moved_descendant`) verify comment retention, semantic equality and annotation ownership. Those tests support the policy but do not themselves prescribe the exact 22/20/16 whitespace-only output; the above input-specific derivation does. ## Created artifacts and separate observation check - `.local/process-removal-native/derive-source-oracle-v2.ps1`: create-only fixture-specific derivation script. It reads only the checksum-pinned baseline, applies the independently stated lexical rules, and refuses to overwrite an existing output. It does **not** read production writer code, expected-v1, failure logs or actual output. Script SHA-256: `38979a4b233b7d28a6392070c72298fb6c17660b2a2c8dc2a3bff74c3c816fae`. - `.local/process-removal-native/expected-removed-v2.arcadia`: independently derived candidate, **2258 bytes**, SHA-256 `b4a2b07ad4c796f555c61945ca42b1c221b454b35488c60fefc86f96f7aa71ba`. - Reproduce into a new destination: `& .local/process-removal-native/derive-source-oracle-v2.ps1 -OutputPath `. The script refuses changed baseline and an existing destination. Only **after creating** the candidate, I separately extracted the sole `left: SourceBundle` project's JSON-compatible ASCII debug string from the failed log using an anchored shape check and `ConvertFrom-Json`, then encoded UTF-8 and compared byte-for-byte. **MATCH**, 2258 derived bytes and 2258 observed bytes. This observation corroborates the rule derivation; actual output was not an input to the derivation script. Failure log `.local/scenario-group-gates/process-removal-tests-1/stdout.log` SHA-256: `aeb571241a21c246ac94ae64f698b478ded69988b9f811c806bb689bb8af6dc9`. The original versioned expected-v1 remains untouched (SHA-256 `117b550f0c10753f53febb3ca6beb2c8088688ffa707f21eac654573e4a3d29c`). The original failed run remains a failure. No new test execution or native acceptance is claimed. ## Concrete next action Parent should preserve v1/failure evidence, introduce a new versioned v2 literal fixture from the pinned independent candidate, and point the full-source comparison and separately versioned native oracle/manifest to v2. Keep the full Project comparison, exact-source assertion and Undo/Redo checks. Explain the lexical correction and explicitly preserve significant space-only lines against editor trimming; a narrowly scoped Git whitespace attribute may be needed for the fixture, consistent with other exact source oracles. Re-run the relevant failed gate on the identified new source and separately review the menu correction. Do not canonicalize the baseline or weaken exact-source equality to semantic-only equality.