You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Recent optimization evidence shows that low-level SQLite/write-path work can
produce real wins, but the largest remaining end-to-end cost sits in the
TypeScript-owned finalization/reference-resolution tail. Continuing to optimize
that tail as isolated local patches risks hiding the real architecture problem:
the hybrid boundary may be forcing repeated candidate hydration, repeated
database lookup, and fragmented diagnostics across the Rust core and TypeScript
shell.
Before executing the architecture/performance PRD, create an independent
resolver migration decision plan. This plan is a prerequisite to #295's
architecture phase. It should decide how to approach full migration, not
directly implement the full migration.
Goal
Define the migration route from the current TypeScript-owned
finalization/reference-resolution tail toward:
Rust-owned finalization/reference-resolution
with a narrow protocol boundary to the TypeScript product shell
The long-term target is to migrate the entire finalization/reference-resolution
chain out of the TypeScript tail, in multiple independently validated plans.
The first decision-plan outcome is a full migration blueprint plus the first
implementation-plan slice.
The first implementation slice is:
candidate lookup/cache protocol
This first slice should move candidate collection/cache and lookup hydration
toward a protocol-owned or Rust-owned boundary. It must not migrate the
every-reference disambiguation decision.
Non-Goals
Do not implement the full resolver migration in this plan.
Do not migrate broad disambiguation semantics in the first slice.
Do not change every-reference disambiguation semantics.
Do not migrate framework or dynamic-dispatch synthesis as the first slice.
Do not rewrite the TypeScript product shell.
Do not change the SQLite schema by default.
Do not change user-facing CLI, SDK, MCP, status, or doctor behavior.
Do not run a new large-corpus profile during this plan unless existing
evidence is insufficient to make the first-slice decision.
Do not update README metrics.
Do not run a full scoreboard or agent A/B campaign for the plan document.
Target Architecture
The desired end state is not "everything becomes Rust." It is a narrower split:
Rust owns or protocolizes reusable candidate lookup and edge-emission
mechanics.
Rust emits profile sub-buckets that explain finalization work as one
continuous indexing pipeline.
TypeScript remains the product shell for CLI/SDK lifecycle, fallback planning,
status/doctor packaging, MCP surfaces, and compatibility glue.
The protocol boundary passes stable graph facts, fallback taxonomy,
diagnostic profile data, and health information.
The TypeScript shell should not keep doing high-volume resolver database work
after the relevant responsibility has migrated.
Migration Domains
The full migration should be split into multiple future plans or phases.
1. Candidate Lookup / Cache Protocol
First slice.
Responsibilities:
collect candidate sets in batch;
avoid repeated database hydration for the same names, files, scopes, and
languages;
expose lookup counts, cache hit/miss counts, hydration time, and candidate set
size diagnostics;
feed the existing TypeScript disambiguation decision without changing its
semantics.
Expected first-slice output:
a narrow protocol shape or cache contract;
deterministic tests that prove candidate availability is equivalent;
before/after profile evidence;
VS Code sparse targeted profile during implementation;
graphStats, fallback taxonomy, and RSS or unavailable reason.
No-go condition:
If candidate lookup/cache does not reduce repeated database hydration or make
finalization cost more explainable, do not keep extending this slice as a
performance strategy. Escalate to the next likely bottleneck.
The success criterion is not "resolver migration has started." The success
criterion is that resolver migration has a route that can be judged, split, and
validated without blurring architecture decisions into local performance
patches.
Rust-Hybrid Resolver Migration Decision Plan
Parent
docs/prds/2026-06-19-rust-hybrid-architecture-and-performance-optimization.mddocs/benchmarks/2026-06-19-rust-hybrid-optimization-big-picture-decision.mdContext
The
rust-hybriddefault path now has a clear split:Recent optimization evidence shows that low-level SQLite/write-path work can
produce real wins, but the largest remaining end-to-end cost sits in the
TypeScript-owned finalization/reference-resolution tail. Continuing to optimize
that tail as isolated local patches risks hiding the real architecture problem:
the hybrid boundary may be forcing repeated candidate hydration, repeated
database lookup, and fragmented diagnostics across the Rust core and TypeScript
shell.
Before executing the architecture/performance PRD, create an independent
resolver migration decision plan. This plan is a prerequisite to #295's
architecture phase. It should decide how to approach full migration, not
directly implement the full migration.
Goal
Define the migration route from the current TypeScript-owned
finalization/reference-resolution tail toward:
The long-term target is to migrate the entire finalization/reference-resolution
chain out of the TypeScript tail, in multiple independently validated plans.
The first decision-plan outcome is a full migration blueprint plus the first
implementation-plan slice.
The first implementation slice is:
This first slice should move candidate collection/cache and lookup hydration
toward a protocol-owned or Rust-owned boundary. It must not migrate the
every-reference disambiguation decision.
Non-Goals
evidence is insufficient to make the first-slice decision.
Target Architecture
The desired end state is not "everything becomes Rust." It is a narrower split:
mechanics.
continuous indexing pipeline.
status/doctor packaging, MCP surfaces, and compatibility glue.
diagnostic profile data, and health information.
after the relevant responsibility has migrated.
Migration Domains
The full migration should be split into multiple future plans or phases.
1. Candidate Lookup / Cache Protocol
First slice.
Responsibilities:
languages;
size diagnostics;
semantics.
Expected first-slice output:
No-go condition:
finalization cost more explainable, do not keep extending this slice as a
performance strategy. Escalate to the next likely bottleneck.
2. Disambiguation Execution
Later slice.
Responsibilities:
Risks:
3. Import / Export Resolution
Later slice.
Responsibilities:
Risks:
4. Local Exact References
Later slice.
Responsibilities:
Risks:
5. Cleanup / Edge-Write / DB Maintenance
Later slice, or a fallback first implementation if candidate cache is no-go.
Responsibilities:
Risks:
6. Framework Post-Extract
Later slice.
Responsibilities:
Risks:
7. Dynamic-Dispatch Synthesis
Later slice.
Responsibilities:
Risks:
8. Diagnostics / Profile / Status Contract
Cross-cutting slice.
Responsibilities:
Risks:
Required Architecture Questions
The decision plan must answer:
TypeScript-owned today?
disambiguation semantics?
and fallback interactions?
Rust core indexing?
cost, rather than merely moving time between buckets?
first slice?
right first migration path?
Testing And Evidence Strategy
Plan-stage evidence:
insufficient to choose the first slice.
First implementation slice evidence:
Agent A/B becomes required only if a later slice changes graph semantics,
language coverage, or sufficiency claims.
Execution Order
resolution.
evidence.
slice.
Success Criteria
This plan is complete when it produces:
the first slice;
consume this plan.
The success criterion is not "resolver migration has started." The success
criterion is that resolver migration has a route that can be judged, split, and
validated without blurring architecture decisions into local performance
patches.