4.4 KiB
Milestone 3 baseline
Scope and method
This baseline records the independent-projection behavior completed in Milestone 3. It was
captured on 2026-07-29 from clean candidate commit
f5dccb5e1c312121f1af63780162f593d9363b98.
The maintained command was:
.venv/bin/python tools/milestone3_benchmark.py \
--mode full \
--nodes 1000 \
--samples 10 \
--output benchmarks/milestone3-2026-07-29.json
The synthetic generic fixture contains 1,000 manual pages, 1,000 portable-graph nodes, and 999
edges. Durations use time.perf_counter_ns() and nearest-rank p95. In-process peak memory uses
tracemalloc; detached worker peak memory comes from the worker receipt and RUSAGE_SELF.
Every measured result is checked for deterministic semantic identity and bounded response size.
Environment:
- Linux 7.1.3-200.nobara.fc44.x86_64.
- CPython 3.14.6.
- x86_64.
- Ten samples except the one-time production cold render and fragment-cache population.
- In-process and detached-worker memory ceiling: 268,435,456 bytes.
- Detached artifact-transfer ceiling: 20,000,000 bytes.
The complete machine-readable result is
benchmarks/milestone3-2026-07-29.json.
Results
| Operation | Median | p95 | Limit | Maximum response |
|---|---|---|---|---|
| Manual full plan/package/render | 801.948 ms | 810.490 ms | 15,000 ms | 664 B |
| Manual detached worker | 591.317 ms | 599.394 ms | 20,000 ms | 667 B |
| Fragment-assisted equivalence | 638.999 ms | 666.119 ms | 15,000 ms | 664 B |
| Production incremental cold | 2,827.152 ms | 2,827.152 ms | 20,000 ms | 668 B |
| Production incremental warm | 2,143.388 ms | 2,206.540 ms | 20,000 ms | 669 B |
| Production forced full | 944.135 ms | 978.870 ms | 20,000 ms | 668 B |
| Fragment cache miss sweep | 106.203 ms | 106.888 ms | 5,000 ms | 145 B |
| Fragment cache hit sweep | 498.911 ms | 514.324 ms | 5,000 ms | 145 B |
| Portable graph full plan/package/render | 303.736 ms | 323.690 ms | 10,000 ms | 657 B |
| Portable graph detached worker | 265.448 ms | 268.428 ms | 20,000 ms | 660 B |
| Manual receipt-only status | 62.881 ms | 111.381 ms | 500 ms | 1,542 B |
| Portable graph receipt-only status | 58.467 ms | 59.331 ms | 500 ms | 879 B |
The largest traced in-process peak was 35,160,716 bytes. The direct manual worker track peaked at 88,580,096 bytes and the portable graph worker at 89,583,616 bytes. The production manual paths, including cold, warm, forced-full, and mutation variants, peaked at 104,771,584 bytes. Every child peak was validated from its projection receipt against the 268,435,456-byte gate.
The manual artifact was 583,149 bytes. The portable graph artifact was 718,383 bytes. The manual plan was 1,006,393 bytes and its ordinary package was 1,007,297 bytes. The graph plan was 398,158 bytes and its package was 398,715 bytes.
Equivalence and no-work gates
The benchmark proved exact output equivalence for:
- Manual in-process and detached rendering.
- Manual full and fragment-assisted rendering.
- Production cold, warm, and forced-full rendering.
- Production add, change, delete, and reorder variants.
- Portable graph in-process and detached rendering.
Manual and portable-graph status each performed zero project loads, source parses, adapter projection loads, adapter extraction, index checks, synchronization, index builds, render preparation, output construction, output hashing, and viewer-manager requests. Each status path performed only two cheap source-generation checks and verified committed receipt or manifest evidence.
Measured limits and future notes
- Fragment reuse is a correctness, isolation, and recovery boundary in this milestone. At 1,000 pages, production warm fragment validation is slower than the forced-full path. Later optimization must start from this measurement and preserve byte equivalence.
- Full rendering remains the oracle and recovery path. Invalid, corrupt, oversized, stale, or mismatched fragment records fall back without changing canonical facts.
- The benchmark main-process
ru_maxrssvalue was 102,692 KiB. It is cumulative across all main-process operations and is recorded only as diagnostic context. Detached child peaks are measured separately. Per-operation traced peaks and every detached receipt peak own the memory gates. - The results do not justify a storage rewrite, render farm, remote renderer, or separate render MCP.