Files
ARCADIA-Studio/harness/release-source-alias-rename-design-20260911.md
T

18 KiB
Raw Blame History

Text-caret alias rename — proposal for critique, 2026-09-11

Codex-9e8r6t /root/behavior_audit; issue 9. Inspected production commit 36db9356cce3c7614ae37eec9fe17678ca210afe, issue 9 and .local/next-slice-audit-20260911.md. This is a source-derived design, not implementation, executed tests or native acceptance. The frozen #6 GUI DF7126B8… remains separate; finish its acceptance before adding this slice. No source8, calculation, library, core or CLI change is proposed here.

Recommendation: an editor-local Rename alias · F2 action opens a compact modal, prepares a complete source preview against the current accepted document, then explicitly adopts that exact candidate as one model/source change. Refuse pending drafts and uncertain target/source membership. Keep Save separate.

Existing authority and concrete traps

  • Command::SetAlias edits the header by UUID; prepare_command validates the complete candidate and returns identity provenance (session.rs, lines 170–198, 607–609, 816–870). It supports the project, elements, relations, diagrams, node placements, artifacts and traces. Project::identities covers those same families; alias rules are ASCII letter/underscore followed by ASCII alphanumeric/underscore, case-sensitive global uniqueness and the existing reserved set (model.rs, lines 1667–1744). Do not substitute engineering-name matching, lowercase/trim the input, or reject every lexer keyword: some highlighted words remain legal aliases.
  • The updater rechecks the current compiled index/model/bytes, changes typed syntax and recompiles to exact candidate-model equality. Reference edits preserve the separate @, intervening comments and unrelated trivia (source_project.rs, lines 780–800, 852–1027, 1133–1225). Existing exact tests include comment-separated references and CRLF/escaped text (source_project tests, lines 843–897). These support the implementation choice; they do not prove a future desktop flow.
  • Document::execute already prepares and commits model/source together. Public CompiledSourceProject fields are not a validated capability: apply_compiled recompiles and compares bundle, model and index before private commit (document.rs, lines 301–397). Keep that check; do not expose commit or install a worker's public DTO unchecked.
  • Message::Command calls App::apply(), which can accept a dirty property form; sync() refreshes the property draft and accepted source (app.rs, lines 709–739, 785–855, 2601–2625). A clean Text buffer is insufficient: a property/behavior draft may still exist. Rename must use its own guarded adoption route, with no implicit Apply.
  • History is bounded by 100 entries and 32 MiB of estimated source plus serialized model, not the 64 MiB source admission. commit may evict even the immediately preceding snapshot; the existing large-current test explicitly expects no Undo (document.rs, lines 24–32, 388–394, 796–820). An unconditional one-Undo promise is false without capacity admission.
  • Workspace::accept resets accepted files' text-history stacks; ordinary Text Ctrl+Z routes to Undo text, not model history (source_workspace.rs, lines 334–361; app.rs, lines 2640–2674). Preview/failure/no-op must not call sync. Successful rename uses model Undo/Redo, and the UI must say so.

Alternatives and selected boundaries

Alternative Decision and reason
Edit the selected alias inline and replace #6 reference rows in draft buffers Reject. Its lexical list can be partial/truncated; it is not a typed replacement plan. Per-file text history cannot establish one accepted multi-file transaction.
Reuse Properties, immediately apply SetAlias Existing semantic capability, but it leaves Text context and lacks complete change review. Generic command dispatch can also accept an unrelated property draft.
Compact modal with explicit Preview, exact candidate, guarded Document adoption Select. It separates identity/name, keeps a visible change boundary and prevents background actions from retargeting an open form. A persistent side inspector would further narrow the editor; repeated inline expandable diffs would displace it.

For transaction implementation, select recompute-on-confirm through Document::execute(SetAlias). Preview uses the same prepare_command plus update_bundle_with_identity_map on the pinned accepted snapshot, without live commit. A private form-owned value holds immutable target UUID, old/exact new alias, base and complete preview output; rendering receives read-only data and Confirm carries only its token. After exact freshness/no-op/draft checks, execute that stored typed intent directly, bypassing generic App command dispatch. Already accepted IDs plus alias-only intent make this deterministic; tests must compare the complete actual result with the reviewed output. Never execute then Undo to obtain a preview: that destroys an existing Redo branch and can evict history.

Add a narrow read-only Document history-capacity check, using its existing estimate/budget, before Preview becomes confirmable and again before execution. Refuse if estimated(before) + estimated(candidate) > HISTORY_BYTES; a no-op requires no reservation. Older history may still be trimmed normally. Do not duplicate the private byte estimator in App or introduce a general compiled-accept method for this command.

This choice incorporates the independent critique, read after the initial independent draft (SHA256 A1B68F330EEB4ED62B31788B8EEFE2D205E5A1593686633D9C9E38BDB1775512). The first draft preferred guarded apply_compiled; the critique correctly distinguishes internal consistency from exact SetAlias correspondence. A self-consistent but unrelated source replacement is not rename authority. Recompute the immutable typed intent instead. An opaque alias-specific Document-owned prepared result remains the alternative if measured representative valid-project preparation/confirmation latency warrants it; keep construction private and consuming adoption guarded. No public mutable CompiledSourceProject or PreparedCommand is that capability. Root will measure before choosing a more complex API; #6 lexical timings do not settle this question.

Exact contract

Admission and target. Begin requires Text context with no busy file operation, model workflow, architecture draft, pending property/behavior draft or competing modal. Require Workspace.applied, no buffer edits, exact entry plus loaded path/text equality with Document.bundle, and the bounded #6 snapshot's complete/validated included scope. For the first slice, any extra loaded detached buffer refuses; explicitly close a clean detached buffer, or reattach/revert a dirty one through existing actions. Physical orphan files not loaded are outside the rename and remain unchanged. This conservative policy prevents silent omission; it does not delete or auto-close a file.

Resolve only an alias token or live @ use under the exact caret/selection, using the existing bounded hit/query seam. Require exactly one complete definition, included/validated evidence, unique authored UUID, and agreement with the accepted project's alias and declaration path. Check the alias role lies within the accepted declaration location; do not require the outline's whole declaration extent to equal the compiler's project-header extent. Names, comments, strings, historical UUIDs, blank space, ambiguous definitions, missing IDs, partial includes or an exhausted query budget cannot authorize rename. A truncated reference list is neither needed nor consulted; all changes come from the typed updater. Never compile a raw unapplied workspace just to enable the action: compilation can allocate missing UUIDs or migrate source (source_project.rs, lines 286–300).

Accepted-but-unsaved documents are eligible. Preview compares against the accepted source, not the last disk baseline. Stabilization/migration already accepted by ordinary Open/Apply retains its fixed IDs; this rename must add no new ID, migration, default, file or include change. Save may later include earlier unsaved accepted edits as well as this rename; the modal says that it only previews this operation.

Form and preview. Capture invocation ID, document snapshot Arc, document revision, workspace session/revision, active path and exact origin cursor/alias span/UUID. Keep the replacement string raw. Invalid syntax, reserved/colliding aliases and same-alias input produce useful inline feedback; same alias is “No change” with Confirm unavailable and no history/reset. Duplicate engineering names are valid and never disambiguate identity.

Explicit Preview starts at most one worker. It prepares SetAlias(target_uuid, replacement) against the pinned accepted snapshot with the desktop limits. Require full candidate Project equality to an independently formed alias-only expectation, identity-map identity for every surviving record, identical file membership/entry and ownership, and unchanged non-alias fields. Preserve old/new source via the two snapshots, not duplicated whole-file strings in every row. Updater errors leave accepted data and all drafts intact.

Preview rows are derived from every changed file in the complete candidate. Because alias replacement cannot add/remove newlines, pair source lines by ordinal, collect every changed line and group nearby context into hunks; unexpected line-ending/line-count changes refuse rather than falling back to a lossy preview. The changed-line count is not presented as a count of semantic references. Proposed display admission is 256 changed files, 50,000 changed lines and 8 MiB of retained diff display data; exceeding a bound explains that no rename was applied. Page complete admitted hunks; never approve a truncated candidate. These are proposed editor limits, not new grammar limits. Do not use unbounded quadratic line diff or copy the CLI's single potentially huge middle hunk into one widget.

Stale and confirmation. Every dialog event carries its invocation ID; Preview/Confirm also identify the exact replacement generation and preview ID. Reject old widget events before canceling or changing the current form. Worker completion must match the wanted job, invocation, replacement generation, original document snapshot/revision and exact workspace readback. Close hides the form immediately but retains the occupied worker slot until its completion; late results do not reopen it. A source edit, file/membership switch, reset, recovery, model transaction, Undo/Redo or replacement edit invalidates approval, even if later bytes happen to match again. The input field survives same-form invalidation for correction. Reopen/new-session IDs cannot reuse an old approval.

After the target is pinned, typing in the rename field, scrolling the preview and focusing its buttons must remain usable: do not compare all dialog input to #6's original raw-input clock, which those legitimate interactions advance. Keep source/workspace/document freshness separate from form input generation. Passive lint/viewport receipts do not approve or cancel a current preview.

Confirm rechecks all admission predicates, exact old/new alias, target UUID and the exact approved candidate, then recomputes and executes only the stored SetAlias through Document once. Consume the approval before dispatch to make repeated Confirm harmless. It neither reruns name resolution from the current caret nor calls generic Message::Command, App::apply, apply_source, Save or migration. If command/source validation or history admission fails, show the error and retain the replacement; no accepted bytes, save baseline, revisions, selection or histories change. Successful adoption follows normal accepted-source synchronization, stays in Text, and selects the new alias at the same origin occurrence, using an exact before/after line/token position map. No whole-buffer search for the first new alias. Apply the existing guarded reveal mechanism so a stale focus task cannot steal focus.

Undo, Save and reopening. Success supplies a context-bound “Undo rename” action and identifies “Undo model” as the persistent control; Text Ctrl+Z remains Undo text. The immediate Undo action must refuse pending source/property/behavior drafts and a newer accepted revision rather than applying them or undoing some later operation. Undo restores the entire preceding Project and exact accepted SourceBundle; Redo restores the exact candidate, each as one model-history transition. A successful new rename clears the previous redo branch normally; cancel, invalid, stale and no-op paths preserve it. Successful sync has the existing accepted-buffer history behavior; do not promise older per-file draft Undo stacks survive it.

Ordinary Save uses existing observed-dependency/journal checks and retains the accepted rename on a save failure. No cross-process CAS or atomic multi-file disk visibility is claimed. Pure rename creates/deletes no file, so Save/Undo/Save must preserve the same physical file set and pre-existing orphan bytes. Reopen verifies exact saved model/IDs/source; Undo history and an unconfirmed preview are not persisted. Recovery must never serialize an executable approved rename plan; a recovered accepted document requires a fresh invocation/preview.

Interaction at minimum width

Add F2 only while the source editor is focused, plus a visible “Rename alias” Text action. It opens on the selected declaration/use without navigating away. The modal is at most 760 px wide and bounded by available window height/width, with a compact target caption (kind, engineering name, full source path available), Source alias input first, then summary and one unified diff pane. Explain “Engineering name stays unchanged.” Node placements use “Placement of …” context because they have no independent engineering name. Long names/paths/aliases must not push the input or footer out of view; offer full selectable details without an unbounded header.

Keep Cancel, Preview and Rename alias outside the independently scrolling diff. Use file search/selection plus Previous/Next changed file and hunk paging, rather than mounting a long homogeneous list. All admitted files/hunks are reachable; there are no per-file checkboxes because the operation is atomic. Show +/−, line numbers and before/after labels, not color alone. Enter in the alias field requests Preview, never commits implicitly; Tab/Shift+Tab reaches controls and an explicitly focused Confirm button activates normally. Captured Escape closes the rename form once, preserving source selection/drafts; it must not fall through to a different editor. Tests/native review must verify this composition at 1100×700 and a narrow dialog host, including long Unicode engineering names and paths.

Bounded evaluator and real workflows

Prepare expected Project and exact source bytes before exercising the implementation; change only the chosen family's alias field and the literal role-proven declaration/typed-reference tokens. Pin all authored UUIDs. Compare complete Project, SourceBundle, declaration file ownership, saved baseline and history transitions, not only changed-file snippets or a successful reparse.

  1. OA activity across modules: from a comment-separated @assess in a process, rename to assess_damage; keep the Unicode engineering name, CRLF, repeated uses, prose @assess, escaped strings, diagram geometry and trace history unchanged. Preview, Cancel, repeat Confirm, Model Undo/Redo, Save/reopen.
  2. Non-element source identity: rename a relation alias used by view routes/traces, then a placement alias; ensure the relation/placement UUIDs, endpoints, engineering names and routed geometry do not change. Include project, diagram, artifact and trace targets in the parameterized headless family matrix rather than assuming element coverage transfers.
  3. Repair without loss: invoke from an invalid or unapplied include draft with another dirty property form; no preview mutation or hidden Apply. After explicit repair/Apply or cancellation outside this flow, invoke afresh and complete the rename. Include a detached duplicate and a missing include; closing/reattaching remains a separate user action.

Required falsifiers: two same-name objects; legal keyword-classified alias; invalid/reserved/colliding/identical alias; target deleted/reidentified or source moved; old Confirm after same-ID reset; source edit then Undo to identical bytes; changed replacement then back to identical text; dirty property form while Text remains in sync; corrupted public candidate/index and a self-consistent unrelated compiled replacement delivered as counterfeit preview data; admitted model exceeding immediate-Undo capacity; more than 200 real uses; diff-bound overflow; long names/paths; same-line repeated uses and a caret on the final occurrence. Assert unchanged raw drafts, model/source, save baseline, revision, both undo/redo branches and cursor on every rejected/canceled/no-op path. Use real App messages for modal/captured Escape and stale queues, not only disabled-button tests. Mounted layout tests must use real paragraph metrics and actual bounded scroll/footer geometry.

Native acceptance belongs to a new identified build after #6: inspect complete preview at minimum/wide windows, keyboard focus and Escape, change the alias from a reference, Undo/Redo, Save/reopen and compare the pre-authored whole-project/source oracle. Test preparation/confirmation timing separately on a representative accepted model; the draft-only 100-module #6 query trial is not evidence for this transaction or its UI.