Files
ARCADIA-Studio/harness/analysis-mixed-rename-plan-contract-20260924.md
T

193 lines
12 KiB
Markdown

# Complete-target mixed rename planning contract
2026-09-24. Accepted successor to verified private source
`ee500908e3d77182ddd54e12524f9b6c6eb43b60`, after
[source mapping](analysis-mixed-rename-plan-20260924/RENAME-PLAN-SOURCE-MAP.md) and
[independent critique](analysis-mixed-rename-plan-20260924/RENAME-PLAN-CRITIQUE.md).
This document does not change user-owned requirements. Implementation and
runtime acceptance remain separate gates.
The user requires complete graphical/text/API editing parity. This dependency
verifies whole-model rename intent and complete original-coordinate token edits.
Output emission/admission, other scalar and structural edits, public source8,
history and checked persistence remain required subsequent capabilities.
## Inputs, ownership and result
Consume one opaque `AuthoredMixedProject` and immutably borrow one independently
supplied desired `Project` for the returned plan's lifetime. The original owner
retains its exact SourceBundle, canonical files, complete admitted model,
warnings, both occurrence families, qualified names and inherited limits/ledger.
Never accept replacement source, profile, occurrence maps or caller edit batches.
Failure returns diagnostics and drops the consumed attempt; no partial plan
escapes. The desired Project is neither changed nor normalized.
The returned private plan owns the original witness and exactly two maps:
- changed qualified `Target` to a borrowed desired-name `str`;
- original physical `(canonical_file, alias_start, alias_end)` to qualified Target.
The desired Project is an external immutable borrow, not a field that another
field borrows. No whole-Project/name clone, typed Path copy, separate per-family
batch, duplicate source table or legacy Index conversion is needed. Read-only
inspection derives replacement text from the retained name map and original
token text from the original witness. Inspection records cannot install a subset
or transfer authority to another source owner.
Borrowing the desired model avoids copying names and model state. Consuming a
desired model and copying changed names remains a justified alternative only if
a real integration owner needs independent target lifetime. A generic model diff,
serde conversion, alias-erased Project clone and two legacy producer adapters
introduce unnecessary storage or authority boundaries for this scope.
## Whole-target gate
Compare fixed collections by length, ordered key and each record's own identity.
Walk borrowed collections; do not allocate `Project::identities()` or clone
payloads. Use exhaustive struct destructuring without `..` for the records whose
alias/name fields are exempted, so added fields require an explicit decision.
Only global aliases and calculation-parameter names may differ. Require:
1. Project schema, ID, display name, description and complete collection sets.
2. Definitions' IDs, display names, descriptions and body variants. QuantityKind
and Unit payloads compare in full. Calculations retain parameter count and
each parameter's ID **at the same ordered position**, value type, result and
body. Only definition alias and scoped parameter name are exempted.
3. Elements' IDs, display names, descriptions, parents and full bodies; relations'
IDs, display names, descriptions and full bodies.
4. Diagrams' IDs, display names, descriptions, layer, projection, view options,
routes and node-key sets. Each node retains ID, element, position, size,
collapsed state and port anchors. Only diagram/node aliases are exempted.
5. Artifacts' and traces' full non-alias fields, including endpoints, historical
baselines, URI, revision, fragment and prose.
Equality follows existing whole-model PartialEq semantics. In particular,
positive/negative floating zero are equivalent in all existing carriers,
including scalar data and historical facets, not just geometry. This does not
authorize rewriting any non-name source bytes. The emitter must preserve those
bytes exactly. Nonfinite originals are excluded by existing admission.
Opaque unchanged payloads may use existing equality after checking variants and
container sizes. Their expression comparator is iterative **and allocates** a
work Vec. Reserve E scratch entry slots before this gate, where E is the total
retained original raw expression-node/site count. Sequential comparisons have
at most a frontier of E distinct old nodes. List/call sizes are checked before
pairing, and variant mismatches refuse before traversing a target-only tree.
When E=0, no Expr comparison may be invoked. Release this reservation only after
the equality calls and internal vectors finish. This conservative bound can
require headroom even for no-op intent; do not promise every accepted owner can
plan under an exactly exhausted profile.
Current reachability must be proved from all four roots: calculation body,
engineering-property base, analysis-case overrides and analysis-check predicate.
Historical semantic payloads use their distinct lifeline binding and string
expression fields. An added Expr carrier requires revisiting the bound. If that
proof fails, add a narrow budgeted equality seam rather than duplicating a full
expression matcher or treating its allocations as free.
## Final namespaces and exact edits
After releasing comparison scratch, collect only changed qualified names. Check
their cumulative UTF-8 byte lengths against the inherited source-byte limit
before validating their characters; borrowed external strings do not justify
unbounded scanning. Use the existing ASCII/reserved-word alias predicate.
Validate final names across the entire original catalog simultaneously. Global
aliases share one namespace. Parameters share a namespace only within their
owning calculation. Identity is qualified even if UUIDs or spellings coincide.
Every changed target must exist in that catalog. Use a borrowed temporary set of
`(scope, final_name)` with explicit entry reservations. Drop it before collecting
edits. A no-change result may reuse the already accepted original namespaces.
Walk both complete authenticated occurrence families. For each changed target,
insert its whole alias-token range and qualified identity into the single edit
map, reserving before insertion and refusing a duplicate physical key. Ordinary
records resolve to Global; typed records retain their existing qualified target.
Markers, trivia, prose, historical UUIDs, includes and unrelated bytes are never
replacement ranges.
Validate membership, original spelling, nonempty whole UTF-8 token spans and
monotone/nonoverlapping physical order. Rescan both original occurrence families
to require every changed occurrence exactly once with the right target and no
unchanged occurrence; compare total required count with edit-map length to rule
out extras without an extra seen set. A changed alias with only its header still
requires that header edit. Complete-set authority cannot be reduced to a caller's
selected edit list.
Expose a private complete-current-bundle validation seam for the eventual
emitter: entry, canonical path keys, exact file set and every file's bytes must
equal the original witness, including untouched files. A supplied snapshot check
alone does not promise an atomic filesystem/history installation.
## Storage and combined sizing
Let B be the inherited live ledger, Q the complete qualified-name count, R changed
targets, M changed physical occurrences and E the bound above. The selected phase
order has added peak `max(E, R + Q, R + M)` when namespace checking is required.
Successful retention is exactly R+M entry slots, zero occurrence slots and zero
copied text bytes. Count any implementation-added temporary container explicitly.
Reserve before growth; release after the logical entries/containers cease to be
live. Parsing/frame/reference/numeric Usage is unchanged by planning.
Compute each final file length while merging canonical files and sorted edits.
Sum that file's removed and replacement byte totals separately using checked
arithmetic, then subtract removed bytes before adding replacements. Sum all
final files, including untouched files, and
check the inherited complete output-byte limit. Do not enforce a separate typed
intermediate size: one family's shrink may offset the other's growth. A lengths
map is unnecessary; a later emitter may repeat the bounded sizing walk. Shrink
does not reduce the still-live B/R/M reservations.
## Required behavior and acceptance
Support complete project/ordinary/typed alias changes, simultaneous global swaps,
scoped parameter swaps, repeated/reordered call labels, cross-family references,
same spelling in distinct scopes and no-op intent. Reject collision with an
unchanged member in the same scope, invalid aliases, unknown/changed IDs,
parameter reorder/add/remove/type change and every non-name semantic mutation.
Reject the entire target before output; no partial success or repaired identity.
Use independently authored complete physical edit maps and final-name sets.
Include OA/SA, canonical cross-file order/coincident offsets, Unicode/CRLF,
line-comment-separated references, all ordinary categories and historical UUID
exclusion. Verify unchanged original/desired Projects, exact desired borrow,
original bundle authority, inherited Usage and R+M retention.
Attempt one unsupported mutation in every exempted-record field group; include
target-only deep/wide expression damage, mismatched list/call sizes and zero-E
variant changes. Verify the conservative equality bound with wide and deep old
trees and signed-zero equivalence in geometry/scalar/historical carriers.
Corrupt missing/extra/wrong-target edits, overlap, stale touched/untouched files,
entry/path/file-set and UTF-8 spans, requiring safe original diagnostics.
Hand-count realistic B+scratch peaks and cap/cap-minus-one cases that actually
pass predecessor phases. Exercise small-stack gate comparison, success/drop and
late refusal. Preserve existing legacy Plan/Composition tests, all private
baseline outcomes and explicit known full-suite/formatting failures.
## Mandatory successor: accepted rewritten output
An opaque plan is not accepted edited source. The next execution contract must
emit every file once from original coordinates, own complete output strings/path
keys/entry with F map slots and all copied bytes accounted, parse/resolve/admit
those actual bytes, and compare the entire resulting Project with desired intent.
It must reject admissible-but-wrong output as well as malformed output.
Preserve the exact inherited policy for each deliberate snapshot parse; do not
use a default profile or silently reset a live witness. Specify new-snapshot work
counters and one aggregate live-storage boundary. Output coexists with B during
emission. Before verification, either drop the consumed old auxiliary owner at a
documented transition while retaining output/intent/policy, or explicitly charge
both owners together. A fresh independent Ledger cannot hide live output storage.
Parser metadata and resolver storage need the carried surviving baseline. The
final whole-Project equality also needs its E scratch reservation even if the
old witness has already dropped; retain E as scalar verified metadata.
Returning an owning bundle alongside syntax that borrows it would be self-
referential. Prefer a narrow owning accepted result after temporary verification
syntax drops, or explicitly justify another lifetime design. No-op execution
should preserve the original owner through an explicit unchanged outcome. No
usable partial result or history/save adoption may escape failed verification.
These are constraints for the successor, not an already implemented execution API.