diff --git a/AGENTS.md b/AGENTS.md index 2b6a540c..17aa67da 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,4 +1,4 @@ - + ## Settled decisions (RAC) @@ -87,4 +87,5 @@ These decisions are already accepted. Do not re-open or contradict them; ask the - **RAC-KXE0M2QBF2MP** — ADR-114: Native Index Workspace Dependencies — memmap2 In, inotify Deferred _(Technical)_ - **RAC-KXFK11FQDN1Y** — ADR-115: The Shared Artifact-Spec Registry Both Engines Read (ADR-063 Guard 1) _(Architecture)_ - **RAC-KXGVR299XY5E** — ADR-116: The Native Rust Engine Is a Sanctioned Second Implementation Under Lockstep Guards _(Architecture)_ +- **RAC-KXWVENM15TF1** — ADR-118: Rust Is the RAC Engine Authority and the Python Engine Is Retired _(Architecture)_ diff --git a/rac/decisions/adr-118-rust-authority-and-python-retirement.md b/rac/decisions/adr-118-rust-authority-and-python-retirement.md new file mode 100644 index 00000000..c2f970bb --- /dev/null +++ b/rac/decisions/adr-118-rust-authority-and-python-retirement.md @@ -0,0 +1,232 @@ +--- +schema_version: 1 +id: RAC-KXWVENM15TF1 +type: decision +tags: [architecture, engine, rust, python, distribution, ci] +--- +# ADR-118: Rust Is the RAC Engine Authority and the Python Engine Is Retired + +## Context + +ADR-116 sanctioned the Rust engine as a second implementation under a Python +arbiter. That was the right entry gate: the native engine first had to prove +byte-identical CLI and MCP behavior, shared-spec conformance, cache parity, and +mutation correctness before it could carry product authority. The evidence is +now sufficient, and the operational cost ADR-116 accepted has become the next +constraint: every retained behavior has to be implemented, reviewed, tested, +and released twice for no user benefit. + +The remaining Python-only surfaces do not justify two engines: + +- document and note-tool ingestion is preprocessing that produces reviewable + Markdown drafts; it does not validate or serve RAC artifacts; +- Explorer is not required and will be removed rather than ported; +- the supported Python API can be a thin client over native `rac --json`, as + ADR-063 already requires for other languages; +- Rust already implements the stdio and HTTP MCP transports and the six-tool + server surface. + +Repository and delivery topology also need one recorded answer. ADR-092 places +inbound ingest in `rac-connectors` and keeps the Python SDK inside `rac-core`. +That no longer fits the end state: ingest is tightly coupled to the draft and +artifact contracts but should remain separately installable, while a Python SDK +that reimplements no engine belongs with the other thin clients in `rac-sdk`. +Creating a new repository solely for ingest would increase the constellation's +maintenance burden without establishing an independently owned product. + +Finally, installation must not expose the source-repository topology to users. +A lean native install and a single batteries-included Homebrew command are both +required, while `rac-ci` remains a remotely consumed GitHub Actions surface +rather than a local package. + +## Decision + +RAC adopts Rust as its sole engine authority and retires the Python engine on a +bounded schedule. + +1. **One engine, one authority.** The Rust workspace is the only implementation + of RAC parsing, classification, validation, policy, graph, retrieval, cache, + CLI, MCP, and output behavior. No third engine is authorized. + +2. **The contract outlives the oracle.** `rac-spec`, the shared artifact-spec + registry, committed conformance vectors, golden output fixtures, mutation + referees, and Rust regression tests define behavior. Python-vs-Rust parity is + retained only long enough to prove that every old oracle basket has an + independent owner. After that audit, Python comparison is scheduled evidence, + not a merge-blocking authority. + +3. **The Python engine freezes.** At the Rust-authority cutover, the Python + implementation is tagged and frozen. It receives only critical security or + transition correctness fixes. New product behavior lands in Rust with its + contract fixtures; routine dual implementation stops immediately. + +4. **Remaining Python surfaces are resolved explicitly.** + + - Explorer is removed without replacement. + - `rac-ingest` is a separately installable Python distribution and executable + sourced from `packages/rac-ingest/` in the `rac-core` repository. It owns + MarkItDown-backed document conversion and deterministic Obsidian, Logseq, + Notion, and Roam normalisation. Its output is an untrusted draft until human + review and native validation. It cannot implement or import an engine. + - A native `rac ingest` command may remain only as a discover-and-exec shim + for `rac-ingest`; it cannot interpret conversion results or fall back to + the retired Python engine. + - The Python SDK moves to the `py/` member of `rac-sdk`. It shells out to the + installed native binary, consumes stable JSON and exit-code contracts, and + reimplements no engine behavior. + - The hidden native `retrieve` implementation is adopted only through the + contract-led surface process; it no longer waits for a permanent Python + implementation once authority has changed. + +5. **Ingest gets a package boundary, not a repository boundary.** Co-location + keeps the converter fixtures beside the draft/artifact contracts they must + track. `rac-ingest` keeps independent package metadata, dependencies, tests, + versioning, and releases. A separate repository is reconsidered only if it + develops independent ownership, cadence, or a substantial source ecosystem. + +6. **Native CI becomes blocking.** Required checks build and test the Rust + workspace, certify the pinned `rac-spec` revision, replay language-neutral + conformance and mutation fixtures, dogfood the released command surfaces, and + smoke-test supported artifacts. The live Python oracle becomes advisory and + is then removed from normal CI. + +7. **`rac-ci` installs native RAC.** Every shipped wrapper in + `itsthelore/rac-ci` uses one shared setup implementation to download a pinned + native release, verify its checksum, and place `rac` on `PATH`. Actions remain + thin wrappers over public CLI contracts. CI onboarding is surfaced by + `rac ci init github`, which writes a deterministic, non-overwriting workflow + with pinned `rac-ci` and RAC versions. + +8. **Homebrew has lean and complete installations.** + + - `brew install itsthelore/tap/rac` installs the native runtime and requires + no Python. + - `brew install itsthelore/tap/rac-full` installs the supported local + toolchain by depending on `rac`, `rac-ingest`, and `rac-connectors`. + - `rac-sdk` is a developer library and is not part of `rac-full`. + - `rac-ci` is remotely consumed and is not represented by an empty Homebrew + formula; `rac-full` points users to `rac ci init github` instead. + +9. **The retirement window is finite.** The next normal minor release is the + Rust-authoritative release: native behavior is default and the Python engine, + fallback dispatcher, and in-process SDK are deprecated. The following normal + minor release removes them. The target is `v0.23.0` for authority and + `v0.24.0` for removal; if release numbering changes before execution, the + invariant is still N then N+1, with no indefinite fallback. A delay beyond + 2026-09-17 requires a new recorded decision naming the concrete blocker. + +10. **Defects are adjudicated, not copied forever.** A documented Python defect + may be fixed by updating the language-neutral contract and Rust tests. The + final Python tag remains recoverable as historical evidence, not normative + runtime code. + +## Consequences + +RAC has one implementation to evolve, one performance model, and one runtime +authority. Native installs, MCP servers, containers, and CI no longer require +Python. Users can still import existing material through MarkItDown and use a +typed Python client without keeping a second engine alive. `rac-full` hides the +optional-package topology behind one supported installation command. + +The transition is intentionally more work than deleting `src/rac`: behavior +must first be captured in independent fixtures, shared assets must move out of +the Python package, native release channels must exist, `rac-ci` must stop +installing the PyPI engine, and SDK and ingest migration guidance must ship. + +Co-locating `rac-ingest` means `rac-core` remains a mixed-language source +repository even though its core runtime is Rust-only. This is accepted because +the Python code has one narrow preprocessing concern and no parity relationship +with the engine. Path-filtered CI and separate packaging keep that boundary +visible. + +Removing the fallback can strand unsupported platforms. The supported native +matrix and installation routes therefore become release gates, and unsupported +targets must be documented rather than silently routed to Python. + +## Status + +Accepted + +## Category + +Architecture + +## Alternatives Considered + +### Keep the ADR-116 two-engine arrangement permanently + +Rejected. It preserves the exact duplication this decision removes: two engine +implementations, an arbiter relationship, and merge-blocking pairwise tests after +independent contract evidence already exists. + +### Bind Rust into the Python package with PyO3 + +Rejected. It keeps Python mandatory for the primary product, creates an FFI and +wheel matrix as new runtime surface, and does not help native CLI, MCP, Homebrew, +or container delivery. + +### Rewrite MarkItDown and every note-tool converter in Rust + +Rejected. Conversion is initial corpus preparation rather than engine work. A +rewrite adds parser and fidelity risk without improving the hot path or reducing +engine duplication. + +### Move ingest into `rac-connectors` + +Rejected for this phase, amending ADR-092's inbound-integration clause. +`rac-connectors` consumes stable RAC exports to publish or verify against +external systems; ingest begins with foreign material and creates reviewable +drafts whose contract changes with RAC artifacts. Co-location with the contract +is the tighter maintenance boundary. + +### Create a dedicated `rac-ingest` repository + +Rejected now. A separately installable package supplies dependency and release +isolation without adding repository administration and another required project +surface. The ADR-092 independent-ownership/cadence escape hatch remains. + +### Put every optional component in the lean `rac` formula + +Rejected. It would make Python and provider SDKs mandatory for users who already +have a Markdown corpus. `rac-full` supplies one-command convenience while +preserving a small native base. + +## Supersedes + +- ADR-116 +- ADR-062 + +## Amends + +- ADR-063: its thin-client rule remains; Rust replaces Python as the engine. +- ADR-072: MarkItDown remains; packaging moves from a core extra to `rac-ingest`. +- ADR-092: ingest stays in `rac-core` as a separate package, and Python joins + the language members in `rac-sdk`. + +## Related Decisions + +- adr-002 +- adr-007 +- adr-010 +- adr-027 +- adr-063 +- adr-072 +- adr-073 +- adr-075 +- adr-079 +- adr-092 +- adr-095 +- adr-098 +- adr-111 +- adr-115 +- adr-116 + +## Related Designs + +- rust-authority-cutover-surface-inventory + +## Related Roadmaps + +- rust-authority-and-python-retirement +- native-engine-cutover +- native-binary-channels diff --git a/rac/designs/rust-authority-cutover-surface-inventory.md b/rac/designs/rust-authority-cutover-surface-inventory.md new file mode 100644 index 00000000..b73147a1 --- /dev/null +++ b/rac/designs/rust-authority-cutover-surface-inventory.md @@ -0,0 +1,180 @@ +--- +schema_version: 1 +id: RAC-KXWVF13DS53R +type: design +tags: [architecture, rust, migration, distribution, ci] +--- +# Rust Authority Cutover Surface Inventory + +## Context + +ADR-118 retires the Python engine rather than maintaining the ADR-116 +two-engine arrangement indefinitely. Deletion is safe only when every current +runtime, library, install, CI, and compatibility surface has an explicit owner +and disposition. + +This inventory was taken from `itsthelore/rac-core` `main` at commit +`ffb8ffcd6e4efbd9619340fab039989a7aab9e5a` on 2026-07-19. The external +`itsthelore/rac-ci` capability list was inspected from its `main` README on the +same date. Both repositories are moving quickly; an implementation PR must +refresh the affected rows rather than treating this document as live discovery. + +## User Need + +Users need one RAC product, not a visible assembly of engine implementations and +repositories. An existing Markdown corpus must work with the native `rac` +installation alone. A user who wants initial corpus conversion and external +connectors must be able to install the supported local toolchain with one +command. A maintainer must be able to remove the Python engine without silently +dropping a command, SDK contract, Action, platform, or migration route. + +## Design + +### Runtime and API Surfaces + +| Surface | Baseline owner/state | End state | Disposition and gate | +| --- | --- | --- | --- | +| Root help, no command, unknown command, `--version` | Python console script decides whether to dispatch | Native `rac` | **Port/retain.** Golden stdout/stderr/exit-code fixtures must cover parse-level behavior before dispatcher removal. | +| Covered CLI commands | Rust implements the ADR-116 parity set; Python dispatcher execs bundled binaries | Native `rac` | **Retain Rust, remove Python duplicate.** Conformance, dogfood, and mutation gates become blocking. | +| `retrieve` CLI | Implemented in Rust but intentionally hidden from the mainline choice list | Native `rac` when its contract is adopted | **Adopt contract-first.** Add language-neutral vectors and update help in the same change; no permanent Python implementation is required after authority cutover. | +| `mcp` stdio | Rust `rac-mcp`; Python dispatcher can select it | Native `rac-mcp` | **Retain Rust.** Six tools and protocol/error frames remain golden-tested. | +| `mcp` HTTP | Rust transport and audit path exist | Native `rac-mcp` | **Retain Rust.** Concurrency, audit, authentication/profile, and HTTP parity fixtures are release gates. | +| `ingest` | Python services inside `src/rac`; MarkItDown extras and note-tool normalisers | `packages/rac-ingest/`, PyPI `rac-ingest`, executable `rac-ingest` | **Split package, same repository.** Preserve golden conversion fixtures, deterministic drafts, warnings, and no-overwrite behavior. Native `rac ingest` is at most an exec shim. | +| Explorer | Python/Textual optional extra | No product surface | **Remove.** Delete command, dependencies, tests, assets, and docs; a bounded deprecation message may precede removal. | +| Python import API (`rac.__all__`) | In-process Python engine API in `rac-core` | `rac-sdk/py`, subprocess client over native JSON contracts | **Replace.** Publish old-to-new method mapping; no FFI, engine imports, or behavior reimplementation. | +| Dispatcher and `RAC_ENGINE` | Python routes covered commands and supplies universal fallback | No dispatcher or engine selector | **Remove.** `RAC_ENGINE=python`, automatic fallback, and platform-wheel routing disappear after the deprecation release. | +| Shared artifact registry | Vendored under `src/rac/spec`, embedded by Rust | Language-neutral `spec/` or equivalent | **Relocate.** Byte-preserving move plus pinned `rac-spec` sync gate before `src/rac` deletion. | +| Templates, skills, hooks, Portal assets | Several canonical copies live beneath `src/rac` | Language-neutral `assets/` embedded by Rust | **Relocate.** Replace Python-copy equality tests with neutral-source integrity tests. | +| Final Python oracle | Live merge-blocking comparison | Recoverable historical tag and scheduled evidence only | **Freeze then retire.** Every parity basket needs an independent fixture owner before deletion. | + +The covered CLI row must be regenerated from `src/rac/dispatch.py`, +`rust/rac-engine/src/cli.rs`, and current conformance case lists. At the baseline, +the native set includes validation, inspection, relationships, review, policy, +index/search, export, portfolio, agent integration, telemetry, scaffolding, +migration, and lifecycle commands; `ingest` and Explorer are deliberate gaps, +not accidental missing ports. + +### Local Installation and Distribution + +| Surface | End state | Required evidence | +| --- | --- | --- | +| GitHub Releases | Signed or provenance-backed native archives for the supported platform matrix, plus checksums | Extracted-artifact CLI/MCP/version smoke tests | +| Homebrew `rac` | Native runtime only; no Python dependency | Clean-machine install, `rac --version`, corpus validation, MCP smoke | +| Homebrew `rac-ingest` | Isolated Homebrew Python environment with pinned resources | Document and vault fixture conversion; system Python remains untouched | +| Homebrew `rac-connectors` | Isolated Python environment containing shipped connector CLIs and supported provider dependencies | Command/version tests and deterministic missing-credential behavior | +| Homebrew `rac-full` | Meta-formula depending on `rac`, `rac-ingest`, and `rac-connectors` | One transaction exposes `rac`, `rac-mcp`, `rac-ingest`, and `rac-connect` | +| PyPI `rac-core` | Bounded transition only; no permanent Python engine distribution | Deprecation release followed by retirement/redirect decision | +| PyPI `rac-ingest` | Independent package sourced from `packages/rac-ingest/` | Native `rac validate` integration against generated drafts | +| `rac-sdk` Python member | Developer-installed thin client | Injected-runner tests plus supported native-binary integration matrix | +| Container | Native multi-stage image with no Python runtime | Final-image smoke, SBOM/provenance, no Python executable present | + +`rac-sdk` is not installed by `rac-full`: it is a developer library, not a local +product command. `rac-ci` is also not a formula dependency because its Actions +are consumed remotely. + +### CI Delivery + +At the baseline, `rac-ci` exposes these capability/platform members: + +| Capability | Current command | End state | +| --- | --- | --- | +| Watchkeeper/GitHub | `rac watchkeeper` | Shared native setup, then thin command/annotation wrapper | +| Gatekeeper/GitHub | `rac gate --sarif` | Shared native setup, then thin SARIF/exit-code wrapper | +| Registrar/GitHub | `rac validate --sarif` | Shared native setup, then thin SARIF/exit-code wrapper | +| Herald/GitHub | `rac decisions-for --json` | Shared native setup, then thin PR-comment wrapper | +| Recordkeeper | Placeholder | Not shipped until its own contract and acceptance evidence land | + +One setup implementation must resolve a pinned RAC release, select the platform +archive, verify its checksum, cache safely, and place `rac` on `PATH`. No Action +may install the retired PyPI engine or independently implement policy. + +The user-facing bootstrap is: + +```bash +rac ci init github +``` + +It previews or writes a deterministic workflow with pinned `rac-ci` and +`rac-version` references, refuses to overwrite by default, and requires no +network merely to render the template. Historical in-core `action.yml`, +`validate-action/`, and `pr-gate-action/` paths remain available only through +frozen compatibility tags or explicit migration documentation; they are not a +second actively maintained Action suite. + +### Transition Milestones + +| Milestone | State | +| --- | --- | +| R0 | ADR-118 accepted; this inventory and repository roadmap land | +| R1 | Independent contract ledger covers every live Python/Rust parity basket | +| R2 | Ingest package and thin Python SDK are published; Explorer is removed | +| R3 | Rust/conformance/dogfood gates are authoritative; Python oracle advisory | +| R4 | Native archives, `rac`, `rac-full`, container, and `rac-ci` native setup ship | +| R5 / Release N | Rust authoritative/default; Python engine and API deprecated | +| R6 / Release N+1 | Python engine, fallback, in-core API, and Python core packaging removed | + +## Constraints + +- Rust output, ordering, errors, and mutation behavior remain governed by + language-neutral contracts; performance does not authorize behavior drift. +- `rac` alone must remain sufficient for an existing Markdown corpus. +- Python in `packages/rac-ingest/` cannot import, bind, or recreate engine logic. +- Connector SDKs and network behavior remain outside the offline engine. +- Generated ingest output is untrusted until human review and native validation. +- Homebrew Python formulae use isolated, pinned environments and never modify + system Python at install or first run. +- No destructive corpus write, workflow overwrite, or inferred relationship is + introduced by migration convenience commands. +- Supported platform gaps block fallback removal or are documented through a new + decision; they never silently reactivate Python authority. + +## Rationale + +The design separates *runtime authority* from *optional tooling language*. +Python is not inherently the maintenance problem; maintaining a second engine +is. Keeping a narrow converter package preserves the mature MarkItDown ecosystem +without putting Python on the query, validation, CI, or serving path. + +The installation topology likewise separates implementation from experience. +Independent formulae keep dependencies testable and upgradeable, while +`rac-full` gives users one command. Remote CI remains a repository concern but +is made discoverable from the installed product rather than represented by a +meaningless local formula. + +## Alternatives + +- Keep both engines: rejected by ADR-118 because contract evidence can replace + permanent pairwise maintenance. +- Put ingest in `rac-connectors`: rejected because it produces draft artifacts + rather than consuming stable exports, and it tracks the core artifact contract. +- Create another repository for ingest: rejected until independent ownership or + cadence justifies the operational cost. +- Install every component from `rac`: rejected because a native-only user should + not inherit Python and provider SDKs. +- Add a `rac-ci` formula: rejected because the current product is remotely + consumed Actions, not a local executable. + +## Accessibility + +This change adds no graphical interface. CLI help, errors, dry-run previews, and +generated workflow messages must remain understandable without color, preserve +machine-readable alternatives, and write diagnostics to the documented stream. +Removing Explorer must not be presented as replacing an accessible terminal +surface with an inaccessible web-only requirement. + +## Style Guidance + +Use one product vocabulary across channels: `rac` is the native runtime, +`rac-full` is the complete local toolchain, `rac-ingest` creates reviewable +drafts, `rac-connect` integrates external systems, and `rac-ci` supplies remote +automation. Avoid describing optional packages as additional engines. + +## Open Questions + +- Which Linux and Windows targets are release-blocking for fallback removal? +- Which connector providers are sufficiently shipped and dependency-compatible + to enter the first `rac-connectors` Homebrew formula? +- Do historical in-core Action paths receive redirect documentation only, or a + final compatibility tag with a deprecation notice? +- Does `rac ingest` remain as a permanent executable shim after one migration + release, or is `rac-ingest` the sole long-term command? diff --git a/rac/roadmaps/future/native-engine-cutover.md b/rac/roadmaps/future/native-engine-cutover.md index 1e95d1a0..d9e818b7 100644 --- a/rac/roadmaps/future/native-engine-cutover.md +++ b/rac/roadmaps/future/native-engine-cutover.md @@ -9,6 +9,11 @@ type: roadmap Planned +This historical covered-surface plan remains resolvable for its implementation +evidence, but its permanent Python-arbiter end state is replaced by +`rust-authority-and-python-retirement` under ADR-118. ADR-118 is normative where +the two roadmaps differ. + The native-engine phase after native-derived-index. ADR-116 is ratified: the Rust engine is a sanctioned second implementation, and the Python reference stays the arbiter. This item makes the sanctioned arrangement real for users — diff --git a/rac/roadmaps/future/rust-authority-and-python-retirement.md b/rac/roadmaps/future/rust-authority-and-python-retirement.md new file mode 100644 index 00000000..2218d12f --- /dev/null +++ b/rac/roadmaps/future/rust-authority-and-python-retirement.md @@ -0,0 +1,149 @@ +--- +schema_version: 1 +id: RAC-KXWW4NGN7JYA +type: roadmap +tags: [rust, engine, migration, distribution, ci] +--- +# Rust Authority and Python Engine Retirement + +## Status + +Planned + +ADR-118 replaces the permanent two-engine end state with a bounded migration to +one Rust engine. This roadmap owns the authority, surface, distribution, and +deletion lane. Performance work can proceed in parallel and does not keep the +Python engine alive once the correctness and delivery gates below are met. + +## Outcomes + +- Rust is RAC's sole behavioral authority and implementation. +- An existing corpus runs through `rac` and `rac-mcp` with no Python runtime. +- `rac-ingest` preserves initial document/vault conversion as a separately + installable Python package under `packages/rac-ingest/`, not a second engine. +- Python developers use the thin `rac-sdk/py` client over native JSON contracts. +- Explorer and the fallback dispatcher are removed. +- `brew install itsthelore/tap/rac-full` installs the complete supported local + toolchain, while the lean `rac` formula remains Python-free. +- Every shipped `rac-ci` Action installs and invokes a verified native release, + and `rac ci init github` makes that remote capability discoverable. + +## Initiatives + +### R0 — Authority and inventory + +Land ADR-118 and `rust-authority-cutover-surface-inventory`. Freeze the removal +milestones and supersede the prior permanent-hybrid roadmap. + +### R1 — Independent contract evidence + +Move canonical specs/assets out of `src/rac`, pin `rac-spec`, map every old +parity basket to language-neutral fixtures or an explicit non-contract, preserve +the final Python environment/tag, and make Rust certifiable without installing +the Python engine. + +### R2 — Resolve Python-only surfaces + +Extract `packages/rac-ingest/` with byte-identical golden fixtures, publish the +thin Python SDK member in `rac-sdk`, adopt retained native retrieval contracts, +and remove Explorer without replacement. Core keeps at most a process-forwarding +`rac ingest` shim. + +### R3 — Rust-authoritative CI + +Promote workspace fmt/clippy/test, pinned-spec conformance, mutation, dogfood, +and supported-platform checks to required. Demote the frozen Python oracle to a +scheduled compatibility witness. + +### R4 — Native distribution, Homebrew, and `rac-ci` + +Ship versioned native archives and container images, publish `rac`, +`rac-ingest`, `rac-connectors`, and `rac-full` formulae, migrate all shipped +`rac-ci` wrappers to one checksum-verifying native setup implementation, and +ship `rac ci init github`. + +### R5 — Deprecation release + +Release N (`v0.23.0` target) makes Rust authoritative/default and warns only on +the Python engine, fallback selector, and in-process Python SDK entry points. +Publish migration guidance to `rac-ingest`, `rac-sdk/py`, native channels, and +`rac-ci`. + +### R6 — Engine deletion + +Release N+1 (`v0.24.0` target) removes `src/rac` engine behavior, Python parity +tests, dispatcher/fallback, engine extras, Python core packaging, and obsolete +CI. Preserve neutral assets, ingest package, SDK compatibility map, final oracle +tag, and historical evidence. A delay beyond 2026-09-17 requires a new decision. + +## Success Measures + +- No supported core command, MCP transport, container, release archive, or + `rac-ci` Action imports or installs the Python engine. +- Rust passes language-neutral CLI/MCP/output/mutation conformance from a clean + checkout with no Python RAC package. +- `brew install .../rac` works with Python absent. +- `brew install .../rac-full` exposes `rac`, `rac-mcp`, `rac-ingest`, and + `rac-connect` in one transaction. +- `rac ci init github` generates a pinned workflow that passes an end-to-end + fixture repository run without overwriting an existing file. +- Ingest golden fixtures remain deterministic and their reviewed outputs pass + released native `rac validate`. +- The Python SDK integration suite passes against every supported native release + platform and contains no engine implementation. +- The Python engine, `RAC_ENGINE=python`, Explorer, and automatic fallback are + absent by Release N+1. + +## Assumptions + +- Current parity and fuzz evidence is sufficient to start authority transfer; + R1 audits coverage rather than restarting the port. +- Native archives can cover the supported user matrix before fallback removal. +- MarkItDown remains appropriate for born-digital document conversion and does + not need to enter the engine. +- `rac-connectors` can publish a tested Homebrew environment for the subset of + providers declared shipped at the time. +- The existing `rac-ci` wrappers remain thin enough to share one native setup + implementation without moving policy into the Actions. + +## Risks + +- A parity basket may still encode undocumented behavior. Mitigation: R1's + coverage ledger blocks deletion until every basket has an independent owner. +- Native platform coverage may lag the retirement date. Mitigation: publish the + matrix early and require a new decision for any schedule exception. +- Co-located Python ingest may be mistaken for a retained engine. Mitigation: + separate package tree, path-filtered CI, executable boundary, and no imports + from engine modules. +- `rac-full` may accumulate incompatible or very large provider dependencies. + Mitigation: include shipped providers only and keep independently testable + component formulae. +- Historical in-core and current `rac-ci` Action paths may create two active + suites. Mitigation: freeze old tags and document one supported current path. +- Removing Explorer may surprise existing users. Mitigation: one bounded + deprecation message and explicit release notes; no replacement promise. + +## Related Decisions + +- adr-118 +- adr-063 +- adr-072 +- adr-079 +- adr-092 +- adr-111 +- adr-115 +- adr-116 + +## Related Designs + +- rust-authority-cutover-surface-inventory + +## Related Roadmaps + +- native-engine-cutover + +## Migration Relationship + +The migration replaces the end state described by `native-engine-cutover`. +That roadmap remains resolvable as the historical covered-surface plan; ADR-118 +is the normative authority for the new end state.