Status: Complete with measured blockers - Milestone: M45 (native short-key latency and memory attribution) - Created: 2026-06-27 - Closed: 2026-06-27 - Type: native-engine plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Close the Track A luna_pinyin short-key latency gap for n, ni, and
hao against same-run upstream librime, and resolve the Track A memory target
question by attribution before any storage rewrite.
M45 has two independent workstreams:
- Implement a bounded, behavior-guarded short-prefix path only if Phase 0
proves the current owner and captures upstream candidate-output oracle
evidence for
n,ni, andhao. - Attribute native Track A memory by splitting steady-state after-ready resident size from observed high-water peak, private heap from file-backed mapped pages, and transient deploy/startup high-water from steady runtime.
The memory workstream is attribution and verdict first. M45 must not start
another compact_table or poet storage rewrite just because peak memory is
above the old target. M43 already reduced a large retained owner without moving
peak; M45 only authorizes code if new evidence names a safe, bounded,
peak-moving owner.
M45 closes as a partial native-engine result with measured blockers, not as a full short-key or memory success.
Final short-key evidence:
- Phase 0 selected
short-key-measured-no-go, so M45 did not retain a short-key engine implementation branch. The final medians are fresh same-run evidence for blocker status and candidate-output parity, not optimization progress from M45. n:68.900us,3.313xsame-run upstream librime; target missed and recorded as a measured benchmark-parity blocker.ni:49.450us,3.458x; target missed and recorded as a measured benchmark-parity blocker.hao:24.267us,2.110x; M44 target pass preserved.- Final
n/ni/haocandidate output matches upstream librime1.17.0for candidate text, comments, order, preedit, commit preview, and page metadata. upstream_sentence_model_calls=0remains true for the short-key rows, so the blocker is not the M40 full-pinyin sentence lookup or M42 abbreviation routing path.
Final memory evidence:
- Steady Track A resident rows are below
107,797,708 B, ranging from87,498,752 Bto98,684,928 B. - The first startup sample still records a real
127,475,712 Bhigh-water peak, so the final memory verdict issteady-state-meets-target-standing-peak-cost. - No memory-code or storage rewrite is retained. The retained owner profile
names
poet.entries_by_code(18,694,662 B) and file-backedcompact_table.storage(13,013,460 B), but does not name a new safe peak-moving owner.
M45 preserves startup/session, zhongguo, both M40 full-pinyin long rows,
both M42/M44 abbreviation rows, bounded output/context, Track A storage
(rsmarisa_byte_backed, mmap table/prism, zero selected heap mirrors,
source_fallback=false, positive rsmarisa counters), and the Track B guard.
It makes no browser, frontend, WASM, public-demo, packaging, deployment, broad
product, AI, learned .gram/octagram, or plugin ABI claim.
Primary evidence:
docs/reports/evidence/m45-native-short-key-memory-attribution/
M45 is native-engine only. It follows the post-M44 diagnostic split:
short-prefix latency is a Track A hot-path problem centered on the n prefix
family, while the memory blocker is a measurement and attribution problem
until private heap, mapped residency, allocator high-water, and steady-state
resident size are separated.
The likely short-key implementation is a borrowed first-page prefix path: keep exact and prefix candidates as borrowed table references, prove first-page ordering before early stop, and materialize only the requested output page. The existing M44 under-fill fallback remains mandatory: if filters or uniquifier behavior can drop the bounded page below the requested size, the path must escalate to a complete refresh rather than returning an under-filled first page.
The memory implementation path is deliberately gated. Phase 0 must distinguish a benchmark-cumulative high-water artifact from a real per-cold-start deploy or startup peak. Those outcomes are not interchangeable: a benchmark artifact can be reframed away from the resident-memory target, while a real cold-start peak remains a standing peak cost and possible constrained-machine/OOM risk even if steady after-ready resident memory meets target. A storage rewrite is not in scope unless profiling names a bounded owner whose reduction is expected to move the measured target.
- Rust native engine:
crates/yune-core. - Rime ABI and native benchmark harness:
crates/yune-rime-api. - Likely hot-path files:
crates/yune-core/src/translator/mod.rscrates/yune-core/src/engine.rscrates/yune-core/src/m37_metrics.rscrates/yune-rime-api/benches/native_inprocess_benchmark.rs
- Tests likely touched:
crates/yune-core/src/tests/translator.rscrates/yune-rime-api/src/tests/session_api.rs
- Reports and evidence:
docs/reports/evidence/m45-native-short-key-memory-attribution/docs/reports/yune-vs-librime-performance.mddocs/reports/yune-vs-librime-root-cause-analysis.md
- Oracle target: upstream
rime/librime 1.17.0at33e78140250125871856cdc5b42ddc6a5fcd3cd4.
M45 starts from the post-M44 native diagnostic evidence under
docs/reports/evidence/post-m44-bottleneck-profiling/phase-0-native-diagnostic/.
That run is diagnostic evidence, not an M45 closeout.
Short-prefix rows:
| Row | Yune median | librime median | Ratio | Current read |
|---|---|---|---|---|
n |
79.400 us |
21.900 us |
3.626x |
Sharpest remaining Track A short-prefix owner. |
ni |
53.750 us |
15.050 us |
3.571x |
Misses parity; includes the earlier n prefix step. |
hao |
25.667 us |
12.100 us |
2.121x |
M44 target remains met, but constant-factor gap remains. |
Raw lookup evidence:
| Input | Prism completions | Table lookup codes | Raw candidates | Raw table median | Translator median |
|---|---|---|---|---|---|
n |
26 |
27 |
1,260 |
166.000 us |
74.100 us |
ni |
1 |
1 |
182 |
19.600 us |
50.200 us |
hao |
1 |
1 |
139 |
15.500 us |
22.533 us |
Memory diagnostic:
| Measurement | Value | Current read |
|---|---|---|
| Repeated Track A high-water peak | 127,430,656 B |
Same peak repeats across startup, session, short, long, and abbreviation rows. |
| Session after-ready median | 87,240,704 B |
Steady session sample is below the 107,797,708 B target. |
n after-ready median |
90,714,112 B |
Short-prefix steady footprint is below the target. |
| Longest diagnostic row after-ready median | 97,677,312 B |
Longest sampled row remains below the target. |
| Reducible retained owner still named | 18,694,662 B |
poet.entries_by_code; not enough to explain process peak. |
| Mapped table bytes | 13,013,460 B |
File-backed table storage; not a selected heap mirror. |
Phase 0 must classify the repeated 127,430,656 B high-water value. It may be
a benchmark-cumulative artifact from one process carrying maximum working-set
history across rows, or it may be a real per-cold-start deploy/startup spike.
M45 closeout must keep both the peak value and the steady after-ready resident
value visible either way.
In scope:
- Native Track A
luna_pinyinshort-key rowsn,ni, andhao. - Upstream candidate-output oracle capture for
n,ni, andhao: candidate count, text, comments, order, page metadata, context preedit, and commit preview. - Short-key owner counters for prefix enumeration, raw table lookup, borrowed candidate iteration, candidate materialization, ranking/sort, comment/quality formatting, filters, context export, and ABI string export.
- Native Track A memory attribution for steady after-ready resident size, high-water peak, private heap, file-backed mapped pages, allocator behavior, deployment/startup transient memory, and retained owner estimates.
- No-regression evidence for M40, M42, M43, and M44 closed behavior and storage gates.
Out of scope:
- Browser harness, WASM linear memory, public-demo packaging, frontend startup, payload transfer, and yune-web/My RIME browser comparison. WEB-01 owns those.
- Future WASM engine-memory reduction for the
893 MiBbrowser Jyutping row. - New abbreviation optimization; M44 already closed the selected abbreviation latency target.
- Track B short-row re-optimization; M44 already closed the selected native Track B short-row targets.
- AI behavior, learned
.gram/octagram, plugin ABI, broader schema breadth, product delivery, packaging, deployment, or public-demo speed claims.
-
Capture a fresh same-run native benchmark under
docs/reports/evidence/m45-native-short-key-memory-attribution/phase-0-native-baseline/. Required rows:- startup/runtime-ready;
- session create/select/destroy;
n,ni,hao, andzhongguo;ceshiyixiachangjushuruxingnengzenyang;zhegeyinqingqishiyinggaizhichichaochangjuzishurucainengyong;cszysmsrsdandzybfshmsru;- Track B 50+ guard row
neigojangingkeisatjinggoiziwunciucoenggeoizisyujapsinhojijung.
-
Capture upstream librime
1.17.0native candidate-output oracle evidence forn,ni, andhaobefore implementation. Store the artifact under the M45 evidence root asphase-0-short-key-oracle/and include:- schema id and oracle version;
- input string;
- candidate count;
- first-page candidate text, comments, and order;
- page number, page size, highlighted candidate index, and has-next state;
- context preedit;
- commit preview where available;
- capture command and environment.
-
Add a Yune-vs-librime candidate comparison artifact for current Yune
n,ni, andhao. If Yune already matches output, record that as the behavior guard. If it differs, stop short-key implementation until the behavior target is clarified. -
Confirm short-key owner split for
n,ni, andhaoinraw_lookup_microbench.csvandm37_metrics.csv. Required fields must distinguish:- prism/prefix code enumeration count and time;
- raw table lookup codes and candidates considered;
- borrowed or owned candidate rows scanned;
- candidates materialized and cloned;
- sort/rank time;
- comment/quality formatting time;
- filter pipeline time;
- first-page materialization time;
- context export and ABI string allocation time.
-
If any required counter is missing from the CSV bundle, add it to
crates/yune-core/src/m37_metrics.rsand export it throughM37_METRIC_FIELDSincrates/yune-rime-api/benches/native_inprocess_benchmark.rsbefore trusting the baseline. -
Add or extend a metric-export regression test proving any new M45 metric appears in the snapshot JSON and benchmark CSV export list.
-
Produce a Phase 0 short-key verdict:
short-key-borrowed-prefix: proceed only if output is guardable and the owner is prefix enumeration/materialization/ranking/export work;short-key-measured-no-go: record the owner if no bounded safe branch is available;short-key-reporting-only: stop if current output does not match upstream and cannot be corrected inside M45 scope.
-
Extend the native benchmark evidence, or add a focused helper, so M45 can separate these memory classes for Track A:
- after-ready resident working set;
- observed high-water peak;
- benchmark-cumulative high-water carried across rows;
- real per-cold-start deploy/startup peak;
- after-finalize working set;
- private bytes or closest Windows-supported proxy;
- file-backed mapped bytes and resident mapped pages where available;
- allocator high-water or retained heap proxy;
- deployment/startup transient memory;
- retained structural owner estimates from
memory-owner-profile.csv.
-
Capture repeated Track A memory bands for startup, session,
n,ni,hao,zhongguo, both M40 long rows, and both M42 abbreviation rows. Include min/median/max after-ready working set and max high-water peak. -
Reconcile the memory-owner profile against measured process memory. The report must explicitly name which bytes are:
- heap-owned reducible;
- heap-owned guarded;
- file-backed mmap;
- shared or overlap estimates;
- unclassified process memory.
-
Produce a Phase 0 memory verdict before memory code changes:
steady-state-meets-target-benchmark-artifact: after-ready resident Track A rows are within<=107,797,708 B, the repeated high-water peak is proven to be a benchmark-cumulative artifact rather than a real cold-start cost, both peak and steady-state numbers remain visible in reports, and the remaining librime gap is reported honestly;steady-state-meets-target-standing-peak-cost: after-ready resident Track A rows are within<=107,797,708 B, but the127 MB-class high-water is a real per-cold-start deploy/startup spike. M45 may report resident target success, but it must keep the peak as a standing cost/blocker and cannot declare full memory success;transient-peak-bound: peak is caused by a bounded transient owner that can be safely reduced without changing storage representation;measured-no-go: the remaining gap is mapped-page, allocator, benchmark, or unknown behavior that is not safe to change in M45;memory-owner-reduction: only allowed if a bounded owner is named and the expected movement is tied to the measured target.
This workstream starts only after Phase 0 records
short-key-borrowed-prefix.
-
Add failing or guard tests for
n,ni, andhaofirst-page output against the captured Phase 0 oracle. The tests must cover candidate text, comments, order, context preedit, page metadata, and commit preview where available. -
Implement the smallest target-scoped borrowed prefix path. Expected shape:
- keep exact and prefix table rows borrowed while ranking first-page output;
- avoid cloning or allocating full candidate lists for the broad
nprefix; - early-stop only when first-page order is proven stable under the active filters, uniquifier, simplifier, and page-size settings;
- materialize owned candidates only for the exported page.
-
Preserve the M44 under-fill fallback. If a bounded path produces fewer than the requested first-page candidates after filters, rerun the complete refresh path for that target rather than returning an under-filled page.
-
Keep
upstream_sentence_model_calls=0onn,ni, andhao. The M45 short-key path must not invoke M40 full-pinyin sentence lookup or M42 abbreviation sentence routing. -
Keep the fast path target-scoped to upstream
luna_pinyinshort-key rows or to a provably equivalent generic short-key condition. Do not silently widen TypeDuck/profile behavior. -
Rerun focused short-key tests and candidate-output comparison for
n,ni, andhao. -
Rerun the native short-key profile. Workstream A success requires:
n,ni, andhaofinal ratios are each<=3.0xsame-run upstream librime;haodoes not regress beyond its M442.5xratio guard unless the final candidate-output oracle requires more work;- first-page candidate output matches the captured Phase 0 oracle;
- no closed M40/M42/M44 guard regresses.
If only one or two rows pass, M45 may not close as full short-key success. It
must record the missed row as a measured blocker with owner evidence. Bare
single-letter n is a degenerate row (27 lookup codes and 1,260 raw
candidates in the post-M44 diagnostic), so a partial closeout where n remains
above <=3.0x is acceptable only if the final report names it as a measured
benchmark-parity blocker rather than a user-visible UX problem. These rows are
already tens of microseconds; M45 must not claim a perceptible typing UX win
from improving them.
This workstream starts after Phase 0 records a memory verdict.
-
If Phase 0 selects
steady-state-meets-target-benchmark-artifact, update the reports to distinguish steady after-ready resident memory from observed high-water peak. Record the old peak target as not comparable to the new steady-state metric only because the high-water value is proven to be a benchmark artifact. Keep both values visible. Do not claim parity with librime; Yune may still use multiple times the steady resident memory of librime. -
If Phase 0 selects
steady-state-meets-target-standing-peak-cost, update the reports to say the resident target is met but the peak target is not. Keep the cold-start peak as a standing cost, including any constrained-memory or OOM risk, and do not close memory as a full success. -
If Phase 0 selects
transient-peak-bound, implement only the bounded transient reduction named by evidence. Do not rewrite compact storage, sentence storage, or table/prism representation unless that owner is directly named by the attribution. -
If Phase 0 selects
measured-no-go, do not change memory code. Record the blocker, the measured classes, and the next evidence needed. -
If Phase 0 selects
memory-owner-reduction, add a focused test or metric guard before changing representation. The change must preserve:- selected storage
rsmarisa_byte_backed; - selected table/prism heap mirrors at
0; - table/prism mmap or selected byte-backed mapping;
source_fallback=false;- positive runtime
rsmarisacounters; - upstream-observable candidate output.
- selected storage
-
Rerun memory bands after any memory-code change. A memory success claim requires either:
- steady after-ready Track A rows
<=107,797,708 Bwith high-water peak classified as a benchmark artifact and reported separately; or - the retained/peak target explicitly chosen in Phase 0 and met by final evidence.
- steady after-ready Track A rows
If steady resident memory meets target but a real per-cold-start peak remains above target, M45 may close only as resident-memory success with a standing peak-cost blocker.
M45 inherits closed gates from M40, M42, M43, and M44:
- Startup/runtime-ready and session remain within
1.25xsame-run upstream librime and within the M44 no-regression band unless a measured environment shift is documented. -
zhongguoremains faster than same-run upstream librime and within5%of the M44 final Yune median. - Both M40 full-pinyin long rows remain within
1.25xsame-run upstream librime. They must not invoke abbreviation expansion or the M45 short-key fast path. -
cszysmsrsdandzybfshmsrupreserve M42/M44 candidate-output parity and do not regress beyond a10%latency band from M44 final medians unless the final same-run ratio remains faster than librime and the difference is explained. - Track A storage remains
rsmarisa_byte_backed, table/prism mapping stays mmap or selected byte-backed, selected table/prism heap mirrors remain0,source_fallback=false, and runtimersmarisacounters remain positive. - First-page output and
RimeGetContextremain bounded and page-sized. - Track B 50+ guard remains stable and source-fallback-free. No Track B speed claim is made from M45.
- WEB-01/browser/WASM/product claims remain out of the M45 reports unless referenced only as explicitly separate work.
M45 closeout must include:
- Phase 0 native benchmark and owner evidence under
docs/reports/evidence/m45-native-short-key-memory-attribution/. - Upstream oracle candidate-output artifact for
n,ni, andhao. - Final Yune-vs-librime candidate-output comparison for
n,ni, andhao. - Final native benchmark with startup, session,
n,ni,hao,zhongguo, both M40 long rows,cszysmsrsd,zybfshmsru, and the Track B 50+ guard. - Final memory attribution artifact naming the selected memory verdict.
- Updated performance report and root-cause report, including any visual refresh needed to keep the reports clear.
- Updated roadmap, requirements, decisions, and milestone history if M45 closes.
- Required final quality gates:
cargo fmt --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
git diff --checkM45 moves to docs/plans/completed/ only after the final evidence supports
both the short-key verdict and the memory verdict. If either workstream misses
its target, the plan closes only as a partial result with a measured blocker,
not as a full performance success.