Status: Complete with measured memory blocker - Milestone: M43 (native memory and short-key owner reduction) - Created: 2026-06-26 - 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 (
- [x]) syntax for tracking.
Reduce the largest remaining native-engine performance gap after M42 without
regressing the closed M40/M42 behavior: first prove whole-process memory and
hao/ni fixed-overhead owners, then implement exactly the measured owner
branch that is safe to change.
M43 is not an abbreviation-latency milestone. The two M42 abbreviation rows
(cszysmsrsd and zybfshmsru) remain behavior guards and final benchmark
rows, but their 3.469x and 5.069x same-run librime latency blockers are not
the implementation target for this milestone. A future M44-style plan can
attack abbreviation graph/search latency after M43 either reduces memory or
records a measured memory/short-key blocker.
M43 is a native-engine-only, owner-first milestone with a hard Phase 0 branch:
- Measure retained memory owners and short-key fixed overhead on the M42 baseline.
- Choose exactly one primary implementation branch:
- memory-owner reduction if retained heap-owned reducible duplication is the largest bounded owner;
- short-key fixed-overhead reduction if
hao/niremain dominated by a named translator/materialization/export owner and memory has no safe bounded owner; - reporting/no-go if Phase 0 disproves the suspected owners or every plausible fix would violate storage, behavior, or bounded-output guards.
- Preserve all M42 behavior, M40 long-row wins, selected storage contracts, and Track B guard evidence before closeout.
This plan intentionally prefers structural accounting before allocator rewrites. A Windows allocator-level heap profile may be attached if available, but the minimum required evidence is a deterministic Yune-owned owner profile that accounts for the major retained structures by module and purpose.
- Rust native engine:
crates/yune-coreandcrates/yune-rime-api. - Benchmark harness:
crates/yune-rime-api/benches/native_inprocess_benchmark.rs. - Existing metric export surface:
crates/yune-core/src/m37_metrics.rsand the native benchmarkm37_metrics.csvwriter. - Likely memory-owner modules:
crates/yune-core/src/dictionary/compiled_table.rs,crates/yune-core/src/poet/mod.rs,crates/yune-core/src/poet/index.rs,crates/yune-core/src/translator/mod.rs, andcrates/yune-rime-api/src/schema_install.rs. - Likely short-key modules:
crates/yune-core/src/translator/mod.rs,crates/yune-rime-api/src/context_api.rs, andcrates/yune-rime-api/src/session.rs. - Evidence root:
docs/reports/evidence/m43-native-memory-short-key-owner-reduction/. - Oracle target: upstream
rime/librime 1.17.0at33e78140250125871856cdc5b42ddc6a5fcd3cd4.
M43 starts from the published M42 closeout at commit 3c53c69b.
| Row | M42 Yune median | Same-run librime median | Ratio / status |
|---|---|---|---|
| startup/runtime-ready | 23,856.300us |
31,421.900us |
0.759x |
| session create/select/destroy | 23,776.500us |
27,766.600us |
0.856x |
hao |
38.800us |
11.333us |
3.424x |
ni |
57.150us |
14.000us |
4.082x |
zhongguo |
60.188us |
166.025us |
0.363x |
ceshiyixiachangjushuruxingnengzenyang |
278.438us |
290.873us |
0.957x |
zhegeyinqingqishiyinggaizhichichaochangjuzishurucainengyong |
474.683us |
658.592us |
0.721x |
cszysmsrsd |
4,127.580us |
1,189.890us |
behavior pass; 3.469x latency blocker |
zybfshmsru |
4,257.100us |
839.860us |
behavior pass; 5.069x latency blocker |
M42 storage and memory baseline:
- Track A max peak working set:
119,775,232 B. - Track A 37-character working set:
113,610,752 B. - Track A 59-character working set:
114,339,840 B. - Track B guard median:
186.513us/op; p95:204.680us/op. - Track B guard max peak working set:
504,901,632 B. selected_storage=rsmarisa_byte_backed.- table/prism mapping mode:
mmap. - selected table/prism heap mirror bytes:
0. source_fallback=false.- positive runtime
rsmarisaexact/prefix counters on target rows.
M42 owner evidence:
ni:56.25us/opprocess-key owner,53.0us/optranslator owner,20owned candidates/op.hao:38.2us/opprocess-key owner,34.7us/optranslator owner,20owned candidates/op.cszysmsrsdandzybfshmsru: translator and upstream sentence-model owners remain abbreviation-latency blockers, not M43 targets.
In scope:
- Track A native
luna_pinyinwhole-process memory owner attribution. - Track A native
haoandnifixed-overhead owner attribution. - One owner-backed implementation branch: memory reduction or short-key fixed overhead reduction.
- Preservation of startup/session,
zhongguo, both Track A long rows, both M42 abbreviation behavior rows, Track B guard row, storage status, bounded output/context, and upstream-observable behavior. - Performance/root-cause report updates after final evidence exists.
Out of scope:
- Abbreviation graph/search latency optimization for
cszysmsrsdandzybfshmsru. - Web harness, frontend, browser startup, public demo, product delivery, packaging, deployment, or browser memory claims.
- TypeDuck-profile performance work beyond the existing Track B guard row.
- Source-YAML fallback or selected table/prism heap mirrors as a shortcut.
- Broad librime feature parity,
.gram/octagram, plugin ABI, or AI behavior. - Moving this plan to completed before all closeout gates have evidence.
- Capture a fresh same-run native benchmark under
docs/reports/evidence/m43-native-memory-short-key-owner-reduction/phase-0-baseline/with the M42 row set: startup, session,hao,ni,zhongguo, both Track A long rows,cszysmsrsd,zybfshmsru, and the Track B 50+ guard row. - Capture a run-to-run noise baseline before choosing a branch. At minimum,
record repeated Track A peak samples and repeated
hao/nimedians from the same benchmark configuration, then publish the observed variance band used by M43 success and no-regression decisions. - Add a deterministic structural owner profile export, for example
memory-owner-profile.csv, that records retained owner estimates by module and structure. Each row must classify bytes asheap_owned_reducible,heap_owned_guarded,mmap_file_backed,shared, oroverlap_estimate. Branch-selection thresholds use only non-overlappingheap_owned_reduciblebytes. The minimum owner set is:compact_table.syllabary_codes,compact_table.syllable_ids_by_code,compact_table.storage,translator.entries_by_code,poet.entries_by_code,poet.lookup_index,poet.abbreviation_vocabulary,schema.config,schema.processors,session.userdb, andruntime.session_state. - Add a reconciliation section to the Phase 0 verdict that compares owner
estimates against measured Track A working set/peak movement. The verdict
must name excluded
mmap_file_backed,shared, andoverlap_estimatebytes so duplicated logical strings or mapped storage cannot double-count into a branch trigger. - Add
m37_metrics.csvfields before trusting new metrics. The benchmark must not silently omit any new M43 metric from the CSV bundle. - Produce a short-key owner profile for
haoandnithat splits at least these buckets: raw prism lookup, raw table lookup, translator production, candidate clone/materialization, ranking/sorting/filtering, context export, ABI string allocation, and free-context work. - Prove M42 abbreviation candidate output still matches upstream for
cszysmsrsdandzybfshmsrubefore any implementation branch starts. - Write a Phase 0 verdict file that chooses one branch:
memory-owner-reduction,short-key-fixed-overhead, orreporting-no-go.
Branch selection rules:
- Choose
memory-owner-reductionif a bounded retained owner or duplicate owner family accounts for at least10 MBof non-overlappingheap_owned_reduciblebytes, or if the top two related owners together account for at least15 MBof non-overlappingheap_owned_reduciblebytes, and the proposed fix can preserve mmap/rsmarisa, zero selected heap mirrors, no source fallback, and candidate output. Mapped storage such ascompact_table.storagemay be reported, but it cannot satisfy the trigger while classified asmmap_file_backed. - Choose
short-key-fixed-overheadonly if memory profiling does not name a safe bounded owner andhao/niremain at least75%dominated by a named translator/materialization/export bucket that can be reduced without touching the M40 full-pinyin sentence path or M42 abbreviation path. - Choose
reporting-no-goif owner evidence disproves the suspected duplicated strings/model-entry hypothesis, if allocator/structural evidence is too weak to justify a rewrite, or if all plausible fixes require source fallback, selected heap mirrors, unbounded candidate materialization, or behavior drift.
Run only if Phase 0 selects memory-owner-reduction.
- Write failing or guard tests for the exact owner being changed before
implementation. Examples:
- compact table tests proving canonical code lookup still returns identical candidates when syllabary storage changes;
- poet tests proving
ModelEntrystorage changes preserve sentence candidate order and M42 abbreviation output; - session/API tests proving storage status and source-fallback counters remain unchanged.
- Reduce exactly the selected owner family first. Acceptable shapes include interned/string-id storage, borrowed ranges over already-retained compiled bytes, compact numeric ids, or lazily built owner state. Do not add a new always-on mirror whose retained bytes erase the win.
- If the selected owner is
compact_table.syllabary_codesplussyllable_ids_by_code, store each code once and make lookup reuse the same representation. Preservelookup_canonical_codes,rsmarisapath segmentation, and all existing compact table tests. - If the selected owner is
poet.entries_by_code, changeModelEntrystorage without changingSentenceLookupIndexordering semantics,compare_model_entry_by_code, abbreviation vocabulary filtering, or candidate text/comment output. - If the selected owner is schema/session/userdb state, keep runtime resource identifiers logical, keep userdb learning behavior unchanged, and do not delay a structure unless first use is measured and bounded.
- Re-run the Phase 0 owner profile after the change and prove the selected owner moved materially.
Memory branch closeout requires one of these outcomes:
- Whole-process memory win: Track A peak working set is at least
10%lower than the M42 peak (<=107,797,708 B), with no candidate-output regression; or - Partial structural reduction, not a whole-process memory win: a named
non-overlapping
heap_owned_reducibleowner family drops by at least15 MB, the drop is corroborated by the post-change owner profile, Track A peak stays within the Phase 0 observed noise band rather than merely under the+5%ceiling, and the final reports explicitly say the whole-process memory target did not move enough and needs another owner pass.
If neither threshold is met, M43 may close only as a measured blocker with explicit documentation that no memory win was achieved.
Run only if Phase 0 selects short-key-fixed-overhead.
- Add focused tests for the exact
hao/niowner before implementation. The tests must assert candidate text/order/comments where behavior could change and metric counters where the optimization changes materialization or context/export shape. - Keep
upstream_sentence_model_calls=0forhaoandni; do not route short keys through the M40 sentence model or the M42 abbreviation path. - If candidate materialization is the owner, bound owned candidate cloning to first-page/context needs while preserving paging behavior when later pages are requested.
- If lookup enumeration is the owner, reduce repeated exact/prefix table walks without losing dictionary candidates or changing ranking.
- If ABI/context export is the owner, reduce string allocation/free work
without changing
RimeCandidate,RimeContext, ownership, or free rules. - Report any new always-on cache or retained data structure with retained
bytes in
memory-owner-profile.csv. Branch B must keep Track A peak within the Phase 0 observed noise band of the M42 baseline, not merely below the+5%memory ceiling. - Re-run the short-key owner profile and final native benchmark after the change.
Short-key branch success requires both short rows to improve by at least 15%
from M42 medians, clear the Phase 0 observed run-to-run noise band, and show a
commensurate drop in the named owner counter:
hao <=32.980us.ni <=48.577us.
This is a self-relative Yune improvement target, not librime parity. Even at
the threshold, hao remains about 2.91x same-run librime and ni remains
about 3.47x same-run librime. Final reports must publish the residual
same-run librime ratios and must not describe Branch B as closing the short-key
librime gap unless the final same-run ratios actually prove that.
If only one row improves or either row regresses, M43 may close only as a measured blocker unless the user explicitly accepts a narrower result.
Run only if Phase 0 selects reporting-no-go.
- Not selected. Phase 0 chose Branch A (
memory-owner-reduction), so the reporting/no-go branch did not run.
| Gate | Required closeout evidence |
|---|---|
| Startup/session | Final startup and session rows stay within same-run librime and within 5% of M42 medians unless the final report records a measured accepted blocker. |
| Short rows | hao, ni, and zhongguo stay within 5% of M42 medians when they are not the selected optimization branch. If Branch B is selected, hao and ni must meet the Branch B success thresholds, clear the observed noise band, show a named-owner counter drop, report residual same-run librime ratios, and avoid claiming short-key parity unless ratios prove it. |
| Long rows | Both Track A long rows stay within 1.25x same-run librime and within 5% of M42 medians. The M40 full-pinyin sentence lookup path must not invoke M42 abbreviation span expansion. |
| Abbreviation behavior | cszysmsrsd and zybfshmsru final native candidate count, text, comments, order, preedit, commit preview, and first-page metadata still match the M42 upstream oracle artifact. Latency may remain a blocker; do not claim an abbreviation speed win. |
| Storage | Track A storage remains rsmarisa_byte_backed; table/prism stay mmap or byte-backed; selected table/prism heap mirror bytes stay 0; source_fallback=false; positive rsmarisa counters remain present. |
| Memory | Track A peak must not exceed M42 peak 119,775,232 B by more than 5% (125,763,994 B) in any branch. Branch A may claim a whole-process memory win only at <=107,797,708 B; estimate-backed owner movement without peak movement is a partial structural reduction, not a whole-process win. Branch B must stay within the Phase 0 observed memory noise band and report retained bytes for any new cache. |
| Bounded output/context | First-page candidate export and RimeGetContext stay page-bounded; any full-list fallback remains explicit and counted. |
| Track B guard | The 50+ jyut6ping3_mobile row remains guard-only and within 10% of M42 median/p95 unless a measured blocker is accepted. No TypeDuck-profile speed claim is allowed. |
| Native-only claim | No web, frontend, product, packaging, delivery, public-demo, or browser speed claim appears in M43 docs or reports. |
M43 is complete with final selected-branch evidence.
Required final artifacts:
docs/reports/evidence/m43-native-memory-short-key-owner-reduction/final-gates.md- final same-run native benchmark bundle containing:
summary-comparison.csv;summary.csv;samples.csv;m37_metrics.csv;startup_session_trace.csv;product_path_status.csv;raw_lookup_microbench.csv;memory-owner-profile.csv;- a Phase 0 and final noise-band summary for Track A peak and
hao/nimedians; - short-key owner profile if Branch B ran;
- candidate-output comparison for
cszysmsrsdandzybfshmsru.
- Updated reports:
docs/reports/yune-vs-librime-performance.mddocs/reports/yune-vs-librime-root-cause-analysis.md
- Updated milestone docs:
docs/roadmap.mddocs/requirements.mddocs/decisions.mddocs/ledgers/milestone-history.mdafter closeout only.
Required final commands:
cargo fmt --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
git diff --checkFiles:
-
Modify:
crates/yune-rime-api/benches/native_inprocess_benchmark.rs -
Modify if new counters are needed:
crates/yune-core/src/m37_metrics.rs -
Modify if structural owner APIs are needed:
crates/yune-core/src/dictionary/compiled_table.rs,crates/yune-core/src/poet/mod.rs,crates/yune-core/src/translator/mod.rs,crates/yune-rime-api/src/schema_install.rs -
Create evidence under:
docs/reports/evidence/m43-native-memory-short-key-owner-reduction/phase-0-baseline/ -
Add structural memory-owner accounting for the required owner set.
-
Add CSV export for
memory-owner-profile.csv. -
Add or update tests proving the new counters export through the benchmark surface.
-
Run the fresh Phase 0 benchmark and write the branch verdict.
Files depend on Phase 0 verdict.
-
Branch A likely tests:
crates/yune-core/src/tests/dictionary.rs,crates/yune-core/src/tests/poet.rs,crates/yune-core/src/tests/translator.rs,crates/yune-rime-api/src/tests/session_api.rs. -
Branch B likely tests:
crates/yune-core/src/tests/translator.rs,crates/yune-rime-api/src/tests/session_api.rs,crates/yune-rime-api/src/tests/frontend_client.rs. -
Add failing or guard tests for the selected owner.
-
Prove the tests fail or prove the guard captures the current counter shape before implementation.
Files depend on Phase 0 verdict.
-
Branch A likely implementation:
crates/yune-core/src/dictionary/compiled_table.rs,crates/yune-core/src/poet/mod.rs,crates/yune-core/src/poet/index.rs,crates/yune-core/src/translator/mod.rs. -
Branch B likely implementation:
crates/yune-core/src/translator/mod.rs,crates/yune-rime-api/src/context_api.rs,crates/yune-rime-api/src/session.rs. -
Implement only the selected owner change.
-
Keep storage status, source-fallback, bounded output, and candidate-output behavior observable in tests.
-
Run the focused tests for the touched module.
Files:
-
Modify:
docs/reports/yune-vs-librime-performance.md -
Modify:
docs/reports/yune-vs-librime-root-cause-analysis.md -
Create final evidence under:
docs/reports/evidence/m43-native-memory-short-key-owner-reduction/ -
Run the final native benchmark with all required rows.
-
Compare against M42 baselines and same-run librime.
-
Update report visualizations only after final data exists.
-
Record whether M43 is a whole-process memory win, partial structural memory reduction, self-relative short-key improvement, or measured blocker. Short-key reporting must include residual same-run librime ratios.
Files:
-
Modify:
docs/roadmap.md -
Modify:
docs/requirements.md -
Modify:
docs/decisions.md -
Modify after completion only:
docs/ledgers/milestone-history.md -
Move after completion only:
docs/plans/completed/m43-plan-native-memory-short-key-owner-reduction.md -
Update roadmap, requirements, and decisions to match final evidence.
-
Run all required final commands.
-
Move the plan to completed only after every closeout gate passes.