1
0
Fork 0
Code Issues Pull requests Projects Releases 2 Packages Wiki Activity Actions Pages
DocForge2/docs/MILESTONE_3_BASELINE.md

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_maxrss value 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.