Latency measured while another job hogs the cores is not comparable: the scale curve
moved from 1.315s to 0.809s at 50,000 sources between two runs of the same code.
- bench/systems.py: machine_facts() reports cpus plus the 1/5/15 minute load average.
- bench/run.py, bench/run_external.py: both reports carry it, and BASELINE.md labels
the latency table a ceiling when the machine was busy.
Verification: pytest bench/tests -q -> 60 passed; ruff check bench/ -> all checks
passed; mypy (fresh cache) -> no issues in 25 source files.
The frozen baseline showed the unmodified RetrievalService agreeing with an equivalent
BM25 index on 0% of its top ten results. Reproduced by hand: its top ten atoms came
from one document's pages, so a source-level ranking cannot overlap it.
- bench/systems.py: live_product_rankings also counts distinct sources behind the
product's top-k atoms.
- bench/run.py: scale probes no longer filtered by gold (a source prefix keeps almost
no gold, so the 500/2,000/10,000 rows were silently skipped); scale_arm_names reads
only latency dicts, which is what crashed write_markdown on the note field; the
unanswerable share is computed instead of hard-coded.
- bench/tests/test_joint.py: 60 tests total, including the writer regression.
Verification: pytest bench/tests -q -> 60 passed; ruff check bench/ -> all checks
passed; mypy (fresh cache) -> no issues in 25 source files.
The per-arm runner recomputed BM25 and the dense matmul for every arm, which put the
full ablation at roughly 16 hours and left no way to survive a kill. JointRunner
computes each signal once per query, attributes latency to the components each arm
uses, and checkpoints every query to runs/baseline/rankings.jsonl.
- bench/systems.py: JointRunner + ARM_COMPONENTS signal attribution.
- bench/run.py: joint pass, rankings cache with a run fingerprint, per-query resume,
latency summary, resident-memory progress lines.
- bench/tests/test_joint.py: joint rankings equal the per-arm rankings for all five
arms; the sparse corpus is scored once even with three arms that need it; cache
fingerprint mismatch and malformed rows fail fast.
- bench/reports/EXTERNAL_APPENDIX.md: what a real Mem0/Zep run would cost, and which
published numbers are comparable at all.
Verification: pytest bench/tests -q -> 57 passed; ruff check bench/ -> all checks
passed; mypy (fresh cache) -> no issues in 25 source files.
The merged database names a source by content hash (`11089_4f2a...`) while the
frozen sets name the same file by its corpus id, so every arm scored 0.000 until
load_atoms joined atoms through sources.path. It now returns corpus ids and
refuses an atom it cannot trace to a corpus file.
Also fixes found by running the harness:
- merge rebuilt atom_fts from the deduped atoms table; two attempts on one file
left 288,266 fts rows for 165,973 atoms.
- merge accepts the two honest reasons a corpus file has no product source
(500 byte-identical LongMemEval sessions collapse under content hashing, and
12 photos that ONNX Runtime cannot decode) and reports them.
- --arms used action=extend against a non-empty default, so naming two arms ran
seven.
- the dense cache is keyed by the atom set, so a scale-curve subset cannot be
scored with full-corpus vectors.
- write_markdown crashed on a run that covered only some modalities.
- bench/ingest_baseline.py drives the unmodified product IngestionService over
all 50,789 corpus files in sharded SQLite DBs, then merges them. Thread and
memory ceilings are set explicitly: ONNX Runtime defaulted to every core
(95 threads/worker, load 490) and its CPU arena kept freed pages mapped,
which OOM-killed workers.
- bench/metrics.py: recall@k, MRR, nDCG@10, Wilson lower bound, chance
baseline. No model, no product import, so the scorer cannot grade itself.
- bench/systems.py + bench/run.py: the five ablation arms over the merged DB,
latency percentiles, scale curve, and a top-10 equivalence check against the
live RetrievalService.
- bench/counterpart.py + bench/run_external.py: in-repo Mem0-style flat store
and Zep-style temporal store as the external reference point.
- bench/audit.py: enforces single-attempt scoring, frozen n, a chance row
beside every score, and producer != verifier. It already flags the product's
retry-until-target loop at backend/src/ely_eye/evals.py:2351.
- backend/pyproject.toml: rapidocr-onnxruntime>=1.4.4 was unsatisfiable
(PyPI maxes at 1.2.3); the successor is the renamed rapidocr package.