<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">PROP-031 — Algorithmic refactoring: the codemod engine and the write-side of the model</title>
  <status stage="spec" state="done" action="continue" comment="B0 2026-07-24: design proposal v0.1, drafted for review; open to challenge until ratified; fact grain 2026-07-24"/>
  <p p="1"><fact id="status-line" status="spec/done">**Status.** Design proposal v0.1 — not implementation-locked. Drafted for review; every decision below is open to challenge until ratified. This PROP establishes a *direction and a model*; it schedules no implementation of its own — its first consumer is the SPECMAP Unit-Mobility Plan (archived: `legacy-spec/terraforms/SPECMAP-UNIT-MOBILITY-PLAN-v0.1.md`), which builds the first operation.</fact></p>
  <p p="2"><fact id="companions" status="spec/done">**Companions.** [PROP-032 — the project model &amp; agent-first IDE substrate](spec://org.vibevm.core/vibevm/common/PROP-032#root) (the universal typed graph these operations mutate; this PROP is its *mutation* half) · [PROP-014 — specmap bidirectional traceability](spec://org.vibevm.ai-native/core-ai-native/mechanisms/PROP-014#index) (the read-side model this PROP makes writable; its `#llm-boundary` and `#open` §7.3 are extended here) · [PROP-003 — dependency evolution](spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003) §2.5.3 (the LLM-boundary philosophy) · [PROP-000 §3 License](spec://org.vibevm.core/vibevm/common/PROP-000#license) (permissive-only dependency posture) · [PROP-029 — fully-qualified addresses](spec://org.vibevm.core/vibevm/common/PROP-029) and [PROP-012 — managed redirect block](spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-012#markers) (the address + redirect substrate) · the AI-Native discipline card `scaffold-i-codemods` (the existing beachhead) · the delegation-first directive in `CLAUDE.md` (the economic thesis this PROP serves).</fact></p>
  <section id="problem" title="1. Problem statement">
    <p p="3"><fact id="problem-lead" status="spec/done">Refactoring in this repository is done one of two ways today, and both are wrong for the volume ahead:</fact></p>
    <list ordered="true" p="4">
      <item><fact id="PROBLEM-BY-HAND" status="spec/done">**By hand.** The naming campaigns in the git log (`refactor(spec): spec:// authority joins group and name with /`; `repoint every reference to the new package groups`) were large, mechanical, cross-file renames performed by a human or an LLM walking files. Correct, but slow and not repeatable.</fact></item>
      <item><fact id="PROBLEM-LLM-REWRITE" status="spec/done">**By LLM file-rewriting.** An agent opens each file and rewrites it. For an elementary change — rename a `spec://` address, move a spec unit into a package — this can take **hours**, cost a fortune in tokens, and is **unreliable**: a single missed call-site silently severs a spec↔code edge, and nothing catches it unless a gate happens to run.</fact></item>
    </list>
    <list ordered="false" p="5">
      <item><fact id="DELEGATION-THESIS" status="spec/done">Both violate the repository's own delegation-first thesis (`CLAUDE.md`): *mechanical transforms should cost `O(decision)`, not `O(files)`.*</fact></item>
      <item><fact id="RENAME-IS-TOOL-CALL" status="spec/done">A rename has **zero** generative content — it is a deterministic function of the tree — so it should not consume any model at all, cheap or expensive; it should be a **tool call**.</fact></item>
    </list>
    <list ordered="false" p="6">
      <item><fact id="BEACHHEAD-SCAFFOLD-I" status="spec/done">The beachhead exists. The AI-Native discipline already ships **Scaffold I — codemods** (`scaffold-i-codemods`): "a recurring multi-file change offered as ONE parameterized, checked, atomic operation," explicitly naming `codemod rename-seam --from X --to Y`.</fact></item>
      <item><fact id="BEACHHEAD-LIMITS" status="spec/done">But today it is (a) **one operation** (`add-cell` scaffolding only), (b) marked **`[E-hyp]`** (unvalidated hypothesis), and (c) **a single language stack's card**, not a cross-layer capability with a ratified model.</fact></item>
      <item><fact id="EXTRACTION-DEMAND" status="spec/done">The upcoming cultural-pattern extraction refactoring will perform thousands of unit moves and address renames; without an algorithmic engine it is economically and operationally impossible to do well.</fact></item>
    </list>
    <p p="7"><fact id="PROP-PURPOSE" status="spec/done">This PROP names the capability, fixes the model, and — critically — states what every artifact must do **now** so the engine, when it lands, has a clean model to operate on.</fact></p>
  </section>
  <section id="decisions" title="2. Decisions">
    <section id="write-side" title="2.1 A refactoring is the write-side of the traceability model">
      <list ordered="false" p="8">
        <item><fact id="READ-SIDE" status="spec/done">`prop r1` — specmap (PROP-014) is a **read-only, deterministic, queryable graph** of spec↔code: `index` builds it, `check` gates it, `explain` renders it.</fact></item>
        <item><fact id="WRITE-SIDE-DEF" status="spec/done">An algorithmic refactoring is the **write-side of that same model**: it mutates a node or an edge (rename a `spec://` address, move a unit, retarget an edge), the engine **emits the corresponding file edits**, and then **re-checks the graph**.</fact></item>
        <item><fact id="COMPLETION-NOT-SUBSYSTEM" status="spec/done">Algorithmic refactoring is therefore not a new subsystem — it is the natural completion of specmap: *read → write*.</fact></item>
        <item><fact id="SUBSTRATE-FREE" status="spec/done">Everything already built (cross-package resolution, revisions, suspects, dangling detection, determinism) becomes the refactorer's substrate at no additional cost.</fact></item>
        <item><fact id="GRAPH-GENERALISED" status="spec/done">The graph itself is generalised by [PROP-032 §2.1](spec://org.vibevm.core/vibevm/common/PROP-032#graph) into a **symmetric model over spec *and* code nodes**; these operations mutate that graph, so as it grows (`code://` nodes, spec→spec / spec→code edges) the same operations extend to the new directions for free.</fact></item>
      </list>
      <p p="9"><fact id="ADDRESSABILITY-COROLLARY" status="spec/done">**Corollary (load-bearing):** *nothing is refactorable that is not first addressable in a machine-readable model.* What lives only in prose cannot be mechanically transformed. This is the root of the build-in-anticipation discipline (§3).</fact></p>
    </section>
    <section id="llm-boundary" title="2.2 The LLM boundary: the model emits typed commands, not free-form edits">
      <list ordered="false" p="10">
        <item><fact id="LLM-DIVISION" status="spec/done">`req r1` — The division of labour is fixed: **the LLM SELECTS and PARAMETERIZES a typed refactoring operation; a deterministic engine EXECUTES and GATES it.**</fact></item>
        <item><fact id="LLM-JUDGEMENT" status="spec/done">The LLM decides *what* to refactor and *why* (extract this pattern? into which package? is the text clean or mixed?) — irreducibly a judgement.</fact></item>
        <item><fact id="LLM-MUST-NOT-REWRITE" status="spec/done">The LLM MUST NOT rewrite files to perform a *mechanical* refactoring; it emits an operation from the algebra (§2.6) with its parameters, and the engine does the rest.</fact></item>
      </list>
      <list ordered="false" p="11">
        <item><fact id="BOUNDARY-COMPLETION" status="spec/done">This is the completion of [PROP-014 §2.7](spec://org.vibevm.ai-native/core-ai-native/mechanisms/PROP-014#llm-boundary) and PROP-003 §2.5.3 — *the LLM emits facts and renderings; deterministic machinery decides.*</fact></item>
        <item><fact id="TYPED-COMMAND" status="spec/done">A refactoring is a **typed command the LLM proposes**, reviewed like any diff, not free-form editing.</fact></item>
        <item><fact id="ECONOMIC-CONSEQUENCE" status="spec/done">The consequence is the economic one: LLM cost drops from `O(files touched)` to `O(one decision)`.</fact></item>
      </list>
    </section>
    <section id="gated-invariant" title="2.3 The gated invariant: a refactoring is *done* only when the model re-checks clean">
      <p p="12"><fact id="GATED-INVARIANT-LEAD" status="spec/done">`req r1` — Every operation is:</fact></p>
      <list ordered="false" p="13">
        <item><fact id="OP-ATOMIC" status="spec/done">**Atomic** — all-or-nothing; a failed post-check rolls **every** write back (the pattern `codemod add-cell` already implements, `rust-ai-native-cli/src/codemod.rs`).</fact></item>
        <item><fact id="OP-DETERMINISTIC" status="spec/done">**Deterministic** — same tree + same parameters → same edits; twice-run is byte-identical (the specmap determinism contract, PROP-014 §2.5).</fact></item>
        <item><fact id="OP-DRY-RUNNABLE" status="spec/done">**Dry-runnable** — `--dry-run` prints the exact plan and touches nothing; the human reviews before the write.</fact></item>
        <item><fact id="OP-GATED" status="spec/done">**Gated** — the operation is **not complete until the model re-checks clean**: `specmap --check` (0 dangling, 0 new suspects) plus the tier's own gate (`self-check.sh`, `cargo check`).</fact></item>
      </list>
      <p p="14"><fact id="TRUST-PROPERTY" status="spec/done">This gated invariant is the **trust property that LLM file-rewriting structurally lacks**: an LLM rename is "done" when the model says it is done; an engine rename is done when the *invariant* says so. That difference is the whole value.</fact></p>
    </section>
    <section id="three-tier" title="2.4 The three-tier stack">
      <p p="15"><fact id="THREE-TIER" status="spec/done">`prop r1` — Refactoring operations live at three tiers, mirroring the discipline's existing product / stack / core structure. Each tier owns the model it can address:</fact></p>
      <table p="16">
        <tr>
          <td>Tier</td>
          <td>Owns / knows</td>
          <td>Representative operations</td>
        </tr>
        <tr>
          <td><fact id="TIER-PRODUCT" status="spec/done">**product — vibevm**</fact></td>
          <td><fact id="TIER-PRODUCT-OWNS-KNOWS" status="spec/done">the project object-model: lockfile, `vibe.toml` graph, boot manifest (`vibevm/vibespecs/boot/INDEX.md`), the embedded registry (PROP-030), package FQIDs (PROP-029)</fact></td>
          <td><fact id="TIER-PRODUCT-REPRESENTATIVE-OPERATION" status="spec/done">`rename-package`, `move-package-between-groups`, `repoint-dependency`, `relocate-boot-snippet`, `split-package` / `merge-package`</fact></td>
        </tr>
        <tr>
          <td><fact id="TIER-DISCIPLINE" status="spec/done">**discipline — specmark / specmap** (language-neutral)</fact></td>
          <td><fact id="TIER-DISCIPLINE-OWNS-KNOWS" status="spec/done">the `spec://` address space and the spec↔code edge graph</fact></td>
          <td><fact id="TIER-DISCIPLINE-REPRESENTATIVE-OPERATION" status="spec/done">`rename-address`, `move-unit` (the capsule), `retarget-edge`, `bump-revision` + re-affirm pins</fact></td>
        </tr>
        <tr>
          <td><fact id="TIER-LANGUAGE" status="spec/done">**language — rust-ai-native / typescript-ai-native**</fact></td>
          <td><fact id="TIER-LANGUAGE-OWNS-KNOWS" status="spec/done">code symbols + their spec tags, per language</fact></td>
          <td><fact id="TIER-LANGUAGE-REPRESENTATIVE-OPERATION" status="spec/done">`rename-symbol` (+ its `#[spec]`/`scope!` tags), `move-item` (+ its edges), `change-signature` — **wrapping** an existing engine (§2.5)</fact></td>
        </tr>
      </table>
      <list ordered="false" p="17">
        <item><fact id="TIER-COMPOSE" status="spec/done">Operations **compose across tiers**: `move-unit` (discipline) = `rename-address` ∘ `relocate-text` ∘ `external-specs-upkeep`; a package rename (product) may drive N `rename-address` (discipline) + N `rename-symbol` (language).</fact></item>
        <item><fact id="GROWTH-BY-COMPOSITION" status="spec/done">The engine grows by composition, not by bespoke commands.</fact></item>
      </list>
    </section>
    <section id="wrap-engines" title="2.5 Wrap permissive engines; never reimplement AST surgery">
      <list ordered="false" p="18">
        <item><fact id="WRAP-LAW" status="spec/done">`req r1` — The language tier does **not** reimplement rename/move on raw ASTs. It **orchestrates an existing, permissively-licensed refactoring backend** and adds the one thing those backends do not know: spec-awareness (updating `#[spec]`/`scope!` tags and keeping the specmap graph consistent).</fact></item>
        <item><fact id="WRAP-CANDIDATES" status="spec/done">Candidate backends — `rust-analyzer` (Apache-2.0/MIT), `ast-grep` (MIT), `ts-morph` (MIT), `comby` (Apache-2.0) — all satisfy [PROP-000 §3](spec://org.vibevm.core/vibevm/common/PROP-000#license) (permissive-only; GPL/AGPL/LGPL forbidden as dependencies).</fact></item>
        <item><fact id="CLEAN-ROOM" status="spec/done">Study of any research refactoring codebase follows the repository's clean-room rule (`vibevm/vibespecs/boot/90-user.xml`): understand the approach, write structurally different code; never port.</fact></item>
        <item><fact id="LICENSE-REVERIFY" status="spec/done">License fields re-verified before any code-level reuse (§5).</fact></item>
      </list>
    </section>
    <section id="algebra" title="2.6 The operation algebra">
      <p p="19"><fact id="ALGEBRA" status="spec/done">`prop r1` — The engine exposes a small, growing **algebra** of typed operations, each with named parameters, a dry-run, and a post-check. v0.1 catalogue (not exhaustive; grows by owner amendment):</fact></p>
      <fence p="20">rename-address   &lt;from-uri&gt; &lt;to-uri&gt;              # retarget every citing edge to a new spec:// address
move-unit        &lt;from-uri&gt; &lt;to-doc&gt;[#anchor]     # relocate a spec unit across a boundary (the capsule)
retarget-edge    &lt;symbol&gt; &lt;from-uri&gt; &lt;to-uri&gt;     # repoint one code→spec edge
bump-revision    &lt;uri&gt; --to r&lt;N&gt;                  # bump a unit's revision; list the pins it makes suspect
rename-symbol    &lt;from&gt; &lt;to&gt;                       # rename a code symbol + its spec tags (wraps §2.5)
rename-package   &lt;from-fqid&gt; &lt;to-fqid&gt;            # rename a package + repoint every consumer (product tier)
repoint-dependency &lt;consumer&gt; &lt;from&gt; &lt;to&gt;          # move a dependency edge in the manifest graph
relocate-boot-snippet &lt;slot&gt; &lt;to&gt;                  # move a boot entry + regenerate INDEX.md</fence>
      <list ordered="false" p="21">
        <item><fact id="OP-PURE-FUNCTION" status="spec/done">Each is a pure function `(tree, params) → edits`, applied atomically and gated (§2.3).</fact></item>
        <item><fact id="FIRST-OPERATION" status="spec/done">`move-unit` is the first to be built (SPECMAP Unit-Mobility Plan Phase 3), and it is built **as a composition** on top of `rename-address` — which is the purest instance and therefore the one that validates the whole loop first.</fact></item>
      </list>
    </section>
  </section>
  <section id="anticipation" title="3. Build-in-anticipation discipline (what to do NOW)">
    <p p="22"><fact id="ANTICIPATION-LAW" status="spec/done">`req r1` — The engine does not exist yet, but its arrival is a **standing assumption** from this PROP forward. Everything authored between now and then MUST keep the model refactor-ready, so the engine inherits a clean substrate rather than a swamp:</fact></p>
    <list ordered="true" p="23">
      <item><fact id="ANT-ADDRESS-EVERYTHING" status="spec/done">**Address everything; prose-reference nothing.** Every cross-reference is a resolvable URI (`spec://…#anchor`, a package FQID, a symbol path), never "see above" / "the section on X". Generalises [PROP-014 §3.1.9](spec://org.vibevm.ai-native/core-ai-native/mechanisms/PROP-014#index) from a style rule to a **precondition**: the engine can only rename what it can address. An un-addressable reference is invisible to the refactorer and will silently rot.</fact></item>
      <item><fact id="ANT-STABLE-IDENTITY" status="spec/done">**Stable identity for anything that can move.** Spec units keep immutable `{#anchor}`s; code carries `#[spec]`/`scope!`; packages carry FQIDs; boot entries carry INDEX ids. Renaming preserves the anchor; retiring tombstones it (PROP-014 §2.1). Identity is what an operation targets.</fact></item>
      <item><fact id="ANT-GRAPH-OVER-PROSE" status="spec/done">**Prefer the graph over prose for anything you may later refactor.** If a link must survive a rename, it belongs in the machine-readable graph, not in a paragraph. **This resolves the SPECMAP plan's D3 in favour of graph-edges:** prose `spec://` references should become first-class specmap edges (extend `mdspec`), because that makes them not merely *gated* but *refactorable*. A standalone prose-link checker gates; a graph edge gates **and** moves.</fact></item>
      <item><fact id="ANT-ALGEBRA-INSTANCES" status="spec/done">**Build bespoke tools as instances of the algebra, not one-offs.** The SPECMAP `move-unit` command is written as the first operation of *this* engine (§2.6), sharing the dry-run / atomic / gated contract, so the second operation is composition, not a rewrite.</fact></item>
      <item><fact id="ANT-GATE-NOW" status="spec/done">**Gate the models now.** A write-side is only trustworthy over a read-side that is enforced. Wiring `specmap --check` into `self-check.sh` (SPECMAP Plan M1) is a precondition for *any* refactoring operation: the invariant the engine checks against must already be green and gated.</fact></item>
    </list>
  </section>
  <section id="rejected" title="4. Rejected alternatives">
    <list ordered="true" p="24">
      <item><fact id="REJ-LLM-REWRITE" status="spec/done">**LLM free-form file-rewriting (the status quo).** The problem, not a solution: `O(files)` cost, no atomicity, no gate, silent edge-severing. Retained only for the *judgement* half (deciding what to refactor), never the *mechanical* half.</fact></item>
      <item><fact id="REJ-SIDECAR-DB" status="spec/done">**A sidecar refactoring database** (operations recorded outside the tree). Violates "project facts live in the repo" (`CLAUDE.md` memory discipline) and PROP-014's rejection of sidecar maps — the model is the tree (specmap graph + manifests), and the engine reads/writes it directly.</fact></item>
      <item><fact id="REJ-REIMPLEMENT-AST" status="spec/done">**Reimplementing AST surgery per language.** Wasteful and fragile against language evolution; §2.5 wraps mature permissive engines instead, adding only spec-awareness.</fact></item>
      <item><fact id="REJ-IDE-ONLY" status="spec/done">**IDE-only refactoring (LSP rename in the editor).** Necessary but insufficient: not scriptable, not headless, not gated by the discipline, not composable into swarm/`fractality` runs, and blind to `spec://` addresses and package graphs. The engine is CLI-first and gate-first; IDE integration is a later surface over the same operations.</fact></item>
      <item><fact id="REJ-DEFER-MODEL" status="spec/done">**Deferring the model until the engine is built.** Rejected as the whole point of this PROP: the *anticipation discipline* (§3) is what makes the eventual engine cheap. Building the model late means retrofitting addressability across a corpus that grew without it.</fact></item>
    </list>
  </section>
  <section id="prior-art" title="5. Prior art &amp; license posture">
    <p p="25"><fact id="prior-art-lead" status="spec/done">Conventions and ideas are free; code is not (PROP-000 §3). Roles explicit; license fields re-verified before any code-level reuse.</fact></p>
    <table p="26">
      <tr>
        <td>System</td>
        <td>License (verify)</td>
        <td>Role here</td>
      </tr>
      <tr>
        <td><fact id="PA-OPENREWRITE" status="spec/done">OpenRewrite</fact></td>
        <td><fact id="PA-OPENREWRITE-LICENSE-VERIFY" status="spec/done">Apache-2.0</fact></td>
        <td><fact id="PA-OPENREWRITE-ROLE-HERE" status="spec/done">**Study — the closest prior art.** Typed, composable, *gated* refactoring "recipes" over a Lossless Semantic Tree. The recipe = a typed operation; the LST = the model. Borrow the *shape* (recipes + a checked model), not code.</fact></td>
      </tr>
      <tr>
        <td><fact id="PA-RUST-ANALYZER" status="spec/done">rust-analyzer</fact></td>
        <td><fact id="PA-RUST-ANALYZER-LICENSE-VERIFY" status="spec/done">Apache-2.0 / MIT</fact></td>
        <td><fact id="PA-RUST-ANALYZER-ROLE-HERE" status="spec/done">Wrap candidate for the Rust language tier (rename, SSR) via its library crates or LSP.</fact></td>
      </tr>
      <tr>
        <td><fact id="PA-AST-GREP" status="spec/done">ast-grep</fact></td>
        <td><fact id="PA-AST-GREP-LICENSE-VERIFY" status="spec/done">MIT</fact></td>
        <td><fact id="PA-AST-GREP-ROLE-HERE" status="spec/done">Wrap candidate — structural search/replace, multi-language, CLI + rules.</fact></td>
      </tr>
      <tr>
        <td><fact id="PA-TS-MORPH" status="spec/done">ts-morph</fact></td>
        <td><fact id="PA-TS-MORPH-LICENSE-VERIFY" status="spec/done">MIT</fact></td>
        <td><fact id="PA-TS-MORPH-ROLE-HERE" status="spec/done">Wrap candidate for the TypeScript language tier (AST refactoring library).</fact></td>
      </tr>
      <tr>
        <td><fact id="PA-COMBY" status="spec/done">comby</fact></td>
        <td><fact id="PA-COMBY-LICENSE-VERIFY" status="spec/done">Apache-2.0</fact></td>
        <td><fact id="PA-COMBY-ROLE-HERE" status="spec/done">Study/wrap — structural rewriting across languages.</fact></td>
      </tr>
      <tr>
        <td><fact id="PA-LSP" status="spec/done">LSP rename / SSR</fact></td>
        <td><fact id="PA-LSP-LICENSE-VERIFY" status="spec/done">n/a (protocol)</fact></td>
        <td><fact id="PA-LSP-ROLE-HERE" status="spec/done">The interaction model the CLI operations mirror headlessly.</fact></td>
      </tr>
      <tr>
        <td><fact id="PA-JSCODESHIFT" status="spec/done">jscodeshift / codemod.com</fact></td>
        <td><fact id="PA-JSCODESHIFT-LICENSE-VERIFY" status="spec/done">MIT</fact></td>
        <td><fact id="PA-JSCODESHIFT-ROLE-HERE" status="spec/done">Study — the codemod-as-script lineage (the discipline's Scaffold I already draws on it).</fact></td>
      </tr>
    </table>
    <p p="27"><fact id="DIFFERENTIATORS" status="spec/done">**Differentiators.**</fact></p>
    <list ordered="true" p="28">
      <item><fact id="DIFF-SPEC-AWARE" status="spec/done">operations are **spec-aware** — they update the `spec://` edge graph, which no general refactoring tool knows about;</fact></item>
      <item><fact id="DIFF-GATED" status="spec/done">they are **gated by the discipline's own invariant** (`specmap --check` / `self-check`), not merely "compiles";</fact></item>
      <item><fact id="DIFF-LLM-PARTICIPANT" status="spec/done">an **LLM is a first-class participant** — strictly as the proposer/parameterizer behind a deterministic core (§2.2);</fact></item>
      <item><fact id="DIFF-COMPOSE-TIERS" status="spec/done">operations **compose across three tiers** (spec / code / package) because the models are addressable end-to-end.</fact></item>
    </list>
  </section>
  <section id="open" title="6. Open questions">
    <status stage="spec" state="work" comment="B1 2026-07-24: six questions open; ratification pending"/>
    <list ordered="true" p="29">
      <item><fact id="open-mechanism-home" status="spec/work">**Where the discipline mechanism lives.** This host PROP is the vibevm-facing anchor. Elevating Scaffold I from an `[E-hyp]` card to a ratified language-neutral **mechanism** in `flow:org.vibevm.ai-native/core-ai-native` (a sibling of PROP-014) is a separate, later, owner-decided step. Decide when the second operation lands.</fact></item>
      <item><fact id="open-weak-tier" status="spec/work">**Weak-tier parameterization (the `[E-hyp]` question, inherited from Scaffold I).** Can the weakest swarm tier correctly *parameterize* an operation, or must the weakest tier be restricted to fixed-parameter invocations? The prime pilot question; answered empirically once `rename-address` / `move-unit` ship.</fact></item>
      <item><fact id="open-transactional" status="spec/work">**Transactional multi-tier operations.** A `rename-package` fans out into discipline + language operations across many files; is the whole fan-out one transaction (all-or-nothing across tiers), or a checkpointed sequence? Lean: one transaction with a single post-gate, checkpointing only if wall-time forces it.</fact></item>
      <item><fact id="open-concurrency" status="spec/work">**Concurrency with in-flight human edits.** An operation assumes a quiescent tree; define the posture when the working tree is dirty (refuse? operate only on committed state?).</fact></item>
      <item><fact id="open-undo" status="spec/work">**Undo / history.** Beyond git revert — does the engine keep an operation journal for structured inverse operations, or is git the only undo? Lean: git is the undo; operations are designed to invert cleanly (a rename's inverse is a rename).</fact></item>
      <item><fact id="open-redirect-default" status="spec/work">**Redirect vs eager-retarget as the default** (PROP-014 §7.3). `rename-address` eager-retargets; redirect stubs are the deferred/parallel path. Which is the default for a swarm run is a policy the operation exposes, not a fixed choice (SPECMAP Plan D1).</fact></item>
    </list>
    <list ordered="false" p="30">
      <item><fact id="ratification-note" status="spec/done">*This PROP is a design proposal. Ratification — and the first operation's implementation — happens through PR review against this document and the SPECMAP Unit-Mobility Plan.*</fact></item>
      <item><fact id="unexercised-removed" status="spec/done">*Any mechanism specified here that is not exercised by the second shipped operation is removed from the spec rather than carried as aspirational documentation (the PROP-014 §335 discipline, inherited).*</fact></item>
    </list>
  </section>
</spec>
