diff --git a/.clangd b/.clangd
new file mode 100644
index 000000000..769242d25
--- /dev/null
+++ b/.clangd
@@ -0,0 +1,36 @@
+# clangd configuration for codebase-memory-mcp
+#
+# Mirrors the include paths and defines from Makefile.cbm CFLAGS_COMMON so
+# clangd can resolve all headers without needing compile_commands.json.
+# Paths are relative to the project root (where this file lives).
+#
+# Works with both clang (macOS/Linux) and gcc — clangd uses these flags
+# directly regardless of which compiler is selected for the build.
+
+CompileFlags:
+ Add:
+ - -std=c11
+ - -D_DEFAULT_SOURCE
+ # Project source headers
+ - -Isrc
+ # Vendored libraries: yyjson, xxhash, sqlite3 wrappers
+ - -Ivendored
+ - -Ivendored/sqlite3
+ - -Ivendored/mimalloc/include
+ # Internal cbm extraction layer and tree-sitter runtime
+ - -Iinternal/cbm
+ - -Iinternal/cbm/vendored/ts_runtime/include
+ # Remove flags clangd cannot handle (sanitizer, link flags)
+ Remove:
+ - -fsanitize=*
+ - -fno-omit-frame-pointer
+ - -lstdc++
+ - -lpthread
+ - -lm
+ - -lz
+
+Diagnostics:
+ # Suppress false-positive "implicit declaration" warnings caused by
+ # clangd analysing files in isolation without the full TU context.
+ Suppress:
+ - pp_file_not_found
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 387b7069e..fd13111a8 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -98,7 +98,7 @@ body:
attributes:
label: Logs
description: |
- Relevant log output (stderr of the binary; for the UI variant also
+ Relevant log output (stderr of the binary; for UI issues also
`GET /api/logs`). Will be auto-formatted as code — no backticks needed.
Please check for private paths/strings before pasting.
render: text
diff --git a/.github/workflows/_lint.yml b/.github/workflows/_lint.yml
index aa7eb7062..98721b675 100644
--- a/.github/workflows/_lint.yml
+++ b/.github/workflows/_lint.yml
@@ -23,6 +23,18 @@ jobs:
- name: No-skips policy (tests pass or fail)
run: bash scripts/check-no-test-skips.sh
+ # Runs before the C toolchain setup so a harness regression fails in seconds
+ # rather than after the cppcheck build. Pure stdlib: no binary, no network,
+ # synthetic SQLite fixtures and the checked-in manifests only.
+ - name: Benchmark harness tests
+ run: python3 benchmarks/test_rank_quality.py
+
+ # The allowlist is generated from CBM_CONFIG_REGISTRY and the cbm_config_get_*
+ # call sites, so a config change that does not regenerate it is caught here
+ # instead of silently letting a stale key through benchmark validation.
+ - name: Benchmark config-key allowlist is current
+ run: python3 benchmarks/generate_config_keys.py --check
+
- name: Install build deps
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev cmake
diff --git a/.github/workflows/_test.yml b/.github/workflows/_test.yml
index 3b9562975..b612a5332 100644
--- a/.github/workflows/_test.yml
+++ b/.github/workflows/_test.yml
@@ -534,7 +534,7 @@ jobs:
run: repo/scripts/ci/verify-shard-union.sh manifests
# Windows product-surface regression guards. Distinct from test-windows above
- # (the sanitizer C suite): these drive a real product binary + external UI pack
+ # (the sanitizer C suite): these drive a real product binary with embedded UI
# over stdio / CLI / HTTP and fail if a Windows bug already fixed on main comes
# back -- non-ASCII repo paths dropping definitions (#636/#357, fixed by #700),
# the PreToolUse hook augmenter no-op on drive-letter cwd (#618, fixed by #619),
@@ -571,9 +571,9 @@ jobs:
ccache-guards-${{ github.ref }}-
ccache-guards-
- - name: Build product binary with external UI assets and guard seams
+ - name: Build product binary with embedded UI assets and guard seams
shell: msys2 {0}
- # --with-ui builds the frontend and its content-addressed asset pack, so
+ # --with-ui builds and embeds the frontend, so
# the drive-picker guard's HTTP UI is available. Functional gate only
# (no sanitizers).
run: scripts/build.sh --with-ui CC=clang CXX=clang++ TEST_SEAMS=1
diff --git a/.github/workflows/dry-run.yml b/.github/workflows/dry-run.yml
index 43a6b6bd9..e71d130bd 100644
--- a/.github/workflows/dry-run.yml
+++ b/.github/workflows/dry-run.yml
@@ -109,3 +109,102 @@ jobs:
duration_minutes: 10
run_asan: ${{ inputs.soak_level == 'full' }}
use_release_artifacts: true
+
+ # ── VirusTotal full-surface pass (final step) ─────────────────
+ # _build.yml already scans the 24 executable CANDIDATES and selects one per
+ # target. This job covers everything else we ship — install.sh, install.ps1,
+ # LICENSE, THIRD_PARTY_NOTICES.md, the MCPB manifest.json and the unpacked UI
+ # assets — so a dry run answers the same question the release will ask, before
+ # we tag anything. The only difference is where the containers come from: the
+ # release pulls them off a published release, a dry run has none, so they come
+ # from the build job's artifacts — the SAME bytes, produced by the same
+ # canonical package-release.sh.
+ #
+ # Runs after smoke and soak deliberately. It is the slowest job (polling can
+ # take up to two hours) and the one most likely to be waiting on someone
+ # else's queue, so it must not delay the feedback that is actually about our
+ # code.
+ #
+ # It needs smoke and soak only so it runs LAST, not because it depends on
+ # them: a skipped smoke or soak leaves the scan reachable (result 'skipped',
+ # which is not 'failure'), while a FAILED one withholds it — if the artifacts
+ # are broken, a verdict on them is not worth two hours of polling.
+ virustotal:
+ if: ${{ inputs.skip_builds != true && inputs.skip_virustotal != true && !cancelled() && needs.build.result == 'success' && needs.smoke.result != 'failure' && needs.soak.result != 'failure' }}
+ needs: [build, smoke, soak]
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ steps:
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ persist-credentials: false
+
+ - name: Download build artifacts
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ pattern: binaries-*
+ merge-multiple: true
+ path: ${{ runner.temp }}/release-archives
+
+ - name: Download the candidate-selection evidence
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: release-selection-evidence
+ path: ${{ runner.temp }}/selection-evidence
+
+ # Same extraction the release verify job performs, over the same container
+ # set: 14 = 8 archives + 6 MCPB bundles; runtime 42 = 8x3 archive sidecars
+ # + 6x3 bundle members. VirusTotal receives only extracted release objects,
+ # never .tar.gz/.zip/.mcpb containers.
+ - name: Extract archive artifacts
+ run: |
+ scripts/ci/extract-release-archives.sh "$RUNNER_TEMP/release-archives" binaries \
+ --expect-archives=14 \
+ --expect-binaries=14 \
+ --expect-runtime-files=42
+
+ # The selected executables were already scanned as candidates in
+ # _build.yml, and identity is settled by SHA-256, so re-submitting them
+ # adds no assurance and costs a second, independently-timed verdict.
+ # Reached only when skip_virustotal is false, i.e. when the candidate scan
+ # this withholding relies on actually ran.
+ - name: Withhold already-scanned selected executables
+ run: |
+ bash scripts/ci/exclude-rescanned-selected-objects.sh \
+ binaries/objects "$RUNNER_TEMP/selection-evidence/release-selection.tsv" \
+ binaries/virustotal-withheld.tsv
+
+ - name: VirusTotal scan
+ uses: crazy-max/ghaction-virustotal@936d8c5c00afe97d3d9a1af26d017cfdf26800a2 # v5.0.0
+ id: virustotal
+ with:
+ vt_api_key: ${{ secrets.VIRUS_TOTAL_SCANNER_API_KEY }}
+ files: binaries/objects/*
+ request_rate: 4
+
+ # Same policy as the release and candidate gates: a single Microsoft `!ml`
+ # is tolerated and disclosed, anything else blocks. Engine count is
+ # evidence, not a gate.
+ - name: Wait for VirusTotal results
+ env:
+ VT_API_KEY: ${{ secrets.VIRUS_TOTAL_SCANNER_API_KEY }}
+ VT_ANALYSIS: ${{ steps.virustotal.outputs.analysis }}
+ VT_EXPECTED_SCAN_SET: binaries/scan-set.tsv
+ VT_ASSOCIATIONS: binaries/associations.tsv
+ VT_RESULTS_PATH: binaries/vt-results.tsv
+ VT_WITHHELD: binaries/virustotal-withheld.tsv
+ MIN_ENGINES: 50
+ run: scripts/ci/check-virustotal.sh
+
+ - name: Preserve VirusTotal scope and result evidence
+ if: ${{ always() }}
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: virustotal-evidence-dry-run-${{ github.run_id }}
+ path: |
+ binaries/associations.tsv
+ binaries/scan-set.tsv
+ binaries/vt-results.tsv
+ binaries/virustotal-withheld.tsv
+ if-no-files-found: warn
diff --git a/.gitignore b/.gitignore
index 83658c626..794c3975c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,7 +10,10 @@ bin/
# Test artifacts
*.test
*.out
+*.log
coverage.txt
+# Clang static analyzer (make -f Makefile.cbm test-analyze) per-file reports
+*.plist
# Test fixture temp dirs (created by C test suite in CWD instead of /tmp/)
cbm_*/
@@ -26,6 +29,16 @@ cli-*/
.DS_Store
Thumbs.db
+# Git worktrees (created by Claude Code subagents)
+.worktrees/
+
+# Runtime/session artifacts
+session_project
+project
+project|params.project
+conductor/
+with
+
# Database files (local cache)
*.db
*.db-wal
@@ -40,9 +53,11 @@ Thumbs.db
# Local project memory (Claude Code auto-memory)
memory/
reference/
+.claude/
# Local-only scratch / session notes (never pushed)
private/
+notes/
# Build artifacts
build/
@@ -54,11 +69,23 @@ src/ui/embedded_assets.c
# Generated reports
BENCHMARK_REPORT.md
+benchmark-results/
+*.facts/
TEST_PLAN.md
+scripts/autotune_results.json
CHANGELOG.md
-# Soak test output
+# Local memory/soak outputs (uploaded as CI artifacts, never committed)
+memlab-*.jsonl
soak-results/
+soak-results-query-leak/
+# ...and ANY ad-hoc run directory at the repo root. The two exact names above did
+# not match hand-named runs, so 13 soak directories and 4 memlab files (78 files
+# of logs and CSVs) were committed to main by accident in 7808eee. Root-anchored
+# so nothing under scripts/ or tests/ is affected — scripts/soak-legs.sh and
+# scripts/soak-test.sh stay tracked.
+/soak*/
+/memlab-*
# LSP originality-check reference cache (scripts/check-lsp-originality.sh)
.lsp-refs/
@@ -70,16 +97,18 @@ graph-ui/.npm-cache-local/
__pycache__/
*.pyc
-# Local soak-leg outputs (uploaded as CI artifacts, never committed)
-soak-results/
-soak-results-query-leak/
-# ...and ANY ad-hoc run directory at the repo root. The two exact names above did
-# not match hand-named runs, so 13 soak directories and 4 memlab files (78 files
-# of logs and CSVs) were committed to main by accident in 7808eee. Root-anchored
-# so nothing under scripts/ or tests/ is affected — scripts/soak-legs.sh and
-# scripts/soak-test.sh stay tracked.
-/soak*/
-/memlab-*
+# Benchmark data derived from a corpus, never authored. Test labels are generated by
+# benchmarks/generate_test_labels.py from whichever checkout was measured, so a copy in
+# the repository is both large and able to drift from the tree actually indexed; the
+# harness derives them at run time instead. Campaign specs and rollups are likewise
+# regenerated from benchmarks/campaign_specs.py and benchmarks/rank_report.py.
+# NOT ignored, deliberately: benchmarks/config-keys-v1.json and
+# benchmarks/config-spellings-v1.json, which are generated but checked in as allowlists
+# and guarded by `generate_config_keys.py --check` in CI.
+benchmarks/labels/
+benchmarks/campaign-specs/
+benchmarks/rollup*.json
+benchmarks/rollup*.md
# Compiled Go wrapper binary. `go build` in pkg/go drops the executable beside
# its sources; one was committed by accident (8.8 MB ELF, flagged by OSSF
diff --git a/.mcp.json b/.mcp.json
new file mode 100644
index 000000000..82532a474
--- /dev/null
+++ b/.mcp.json
@@ -0,0 +1,8 @@
+{
+ "mcpServers": {
+ "codebase-memory-mcp": {
+ "command": "sh",
+ "args": ["-c", "exec $HOME/.local/bin/codebase-memory-mcp"]
+ }
+ }
+}
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 000000000..b4031a8f5
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,61 @@
+# codebase-memory-mcp — Developer Notes for Claude
+
+Every commit needs a DCO sign-off: commit with `git commit -s`; CI enforces it via `scripts/check-dco.sh` (see CONTRIBUTING.md).
+
+Before changing capabilities or architecture, map the existing design first: look for
+equivalent tools, config, helpers, metadata, algorithms, and conventions. Prefer extending
+the established path over adding a parallel one. New abstractions should close a named gap
+and fit the repo's ownership, allocation, threading, logging, portability, protocol I/O,
+and naming patterns.
+
+Adding a new node/edge JSON property key in `src/pipeline/*.c` or `src/git/*.c`? Add it to
+the declared registry in `src/store/store.c`/`store.h` (`schema_declared_node_property_keys`/
+`schema_declared_edge_property_keys`) or `tests/test_schema_declared_property_keys.c` will fail.
+
+## Build & Test (C server)
+
+All C targets use `Makefile.cbm`:
+
+```bash
+make -f Makefile.cbm test # build + run full test suite (ASan/UBSan)
+make -f Makefile.cbm test-leak # heap leak check (see below)
+make -f Makefile.cbm test-analyze # Clang static analyzer (requires clang, not gcc)
+```
+
+## Memory Leak Testing
+
+**macOS** — uses Apple's `leaks --atExit` on a separate ASan-free binary:
+```bash
+make -f Makefile.cbm test-leak
+# Report saved to build/c/leak-report.txt
+# Target line: "Process NNNNN: 0 leaks for 0 total leaked bytes."
+```
+
+**Linux** — uses LSan via ASan env var on the regular test runner:
+```bash
+make -f Makefile.cbm test-leak
+# Report saved to build/c/leak-report.txt
+# Exit 0 = no leaks.
+```
+
+Why a separate binary on macOS: `leaks` cannot inspect processes that use a custom malloc (ASan replaces it). The `test-runner-nosan` target rebuilds without `-fsanitize` flags specifically for this purpose.
+
+## Memory-Corruption Debugging (macOS)
+
+For non-deterministic corruption (uninit reads, use-after-free, overruns) that ASan/TSan miss — used to investigate the custom-writer B1 bug. Both run the nosan binary (ASan replaces malloc, which defeats these libmalloc knobs); set `CBM_ONLY_SUITE=` to target a slow suite.
+
+```bash
+make -f Makefile.cbm test-memory # MallocScribble=1 + MallocPreScribble=1
+ # uninit reads -> 0xAA, use-after-free -> 0x55 (deterministic)
+make -f Makefile.cbm test-gmalloc # Guard Malloc (libgmalloc): guard page per allocation
+ # allocation-owning suites; exact overrun/UAF stack
+# Report saved to build/c/mem-report.txt
+```
+
+`test-memory` is the macOS MSan-equivalent for uninit reads (scribble makes them deterministic). `test-gmalloc` is the strictest — it crashes at the exact bad write, pinpointing the line. Its default suite list stays on allocation-owning in-process surfaces because macOS propagates `DYLD_INSERT_LIBRARIES` into external helpers such as `git`; use `CBM_ONLY_SUITE`/`CBM_ONLY_TEST` for a narrower probe. (No valgrind/MSan on macOS; on Linux use `-fsanitize=memory`.)
+
+## Project Structure (C server)
+
+Sources live under `src/`; tests under `tests/`; vendored C libs under `vendored/`.
+Tree-sitter extraction and its vendored language grammars live under `internal/cbm/`.
+See `CONTRIBUTING.md` for the complete source layout and contribution workflow.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 96ce8f861..e34f4e8f3 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -26,19 +26,101 @@ The binary is output to `build/c/codebase-memory-mcp`.
scripts/test.sh
```
-This builds with ASan + UBSan and runs the full C test suite. Key test files:
+This is the local maintainer gate used by the project scripts. It cleans the C build, runs the
+full ASan + UBSan C test suite, builds the production binary, and then runs the parent-watchdog
+and security-string regression scripts. The exact test count changes as suites are added; use the
+runner summary as the source of truth. Key test files:
- `tests/test_pipeline.c` — pipeline integration tests
- `tests/test_httplink.c` — HTTP route extraction and linking
- `tests/test_mcp.c` — MCP protocol and tool handler tests
- `tests/test_store_*.c` — SQLite graph store tests
+Useful script options and environment:
+
+```bash
+scripts/test.sh --arch arm64 # macOS: force target architecture
+scripts/test.sh CC=clang CXX=clang++ # override compiler
+CBM_RUN_HANG_TEST=1 scripts/test.sh # include the slower C++ index-hang guard
+```
+
+## Run C Server Tests
+
+The MCP server core is written in C and has its own test suite under `tests/`:
+
+```bash
+make -f Makefile.cbm test # full suite with ASan + UBSan
+make -f Makefile.cbm test-tsan # thread-sensitive suites with ThreadSanitizer
+make -f Makefile.cbm test-leak # heap leak check (see below)
+make -f Makefile.cbm test-memory # macOS MallocScribble/PreScribble nosan run
+make -f Makefile.cbm test-gmalloc # macOS Guard Malloc nosan run
+make -f Makefile.cbm test-analyze # Clang static analyzer (requires clang, not gcc)
+```
+
+Focused runs are opt-in. Leave these unset for the complete suite:
+
+```bash
+CBM_ONLY_SUITE=pipeline make -f Makefile.cbm test
+CBM_ONLY_SUITE=pipeline CBM_ONLY_TEST=exact build/c/test-runner
+```
+
+By default, tests isolate `CBM_CACHE_DIR` in a temporary directory so local indexes are not
+polluted. Set `CBM_TEST_NO_ISOLATE=1` only when intentionally testing the user's configured cache.
+
+### Build profiles
+
+Use `scripts/build.sh` for a clean local release build. It is the same entry point used by the
+release workflow and produces the default installable binary with `-O2`. For a faster incremental
+release rebuild, use `make -f Makefile.cbm cbm`; `make -f Makefile.cbm install` installs that same
+optimized artifact.
+
+Use `scripts/test.sh` for normal development validation. Its C test binary uses `-g -O1` with
+ASan and UBSan, then it builds the production binary for the parent/worker watchdog checks. Use
+the dedicated `test-tsan`, `test-leak`, `test-memory`, and `test-gmalloc` targets above when
+diagnosing concurrency or allocator lifetime behavior. These diagnostic binaries are not valid
+performance-benchmark inputs.
+
+For performance changes, use the canonical fact tables and comparison rules in
+[`docs/BENCHMARK_EXPERIMENTS.md`](docs/BENCHMARK_EXPERIMENTS.md). Field, step,
+concurrency, and lifecycle meanings come from the generated
+[`docs/BENCHMARK_TERMINOLOGY.md`](docs/BENCHMARK_TERMINOLOGY.md), whose source of
+truth is `benchmarks/terminology.json`.
+
+Additional build flags follow the Makefile conventions:
+
+```bash
+make -f Makefile.cbm test SANITIZE= # disable ASan/UBSan, mainly for unsupported toolchains
+make -f Makefile.cbm cbm CFLAGS_EXTRA=-DCBM_VERSION=dev
+make -f Makefile.cbm cbm STATIC=1 # static link where supported
+```
+
+**Memory leak detection:**
+
+On **macOS**, `test-leak` builds a sanitizer-free binary (`test-runner-nosan`) and runs Apple's
+`leaks --atExit` on allocation-owning store, pipeline, ranker, and parallel-worker
+suites. ASan replaces malloc, so the standard `test-runner` cannot be inspected by `leaks` — the
+separate nosan build is required. Deliberate crash tests are excluded because Apple's debugger
+stops their child processes before the parent can reap them; this includes the subprocess,
+stack-overflow, MCP crash-quarantine, and HTTP socket-inheritance suites.
+
+On **Linux**, `test-leak` runs the regular `test-runner` with `ASAN_OPTIONS=detect_leaks=1` to
+activate LSan.
+
+In both cases the full report is written to `build/c/leak-report.txt`. A clean run ends with:
+```
+Process NNNNN: 0 leaks for 0 total leaked bytes.
+```
+
## Run Linter
```bash
scripts/lint.sh
+make -f Makefile.cbm lint-source-safety
```
-Runs clang-tidy, cppcheck, and clang-format. All must pass before committing (also enforced by pre-commit hook).
+Runs clang-tidy, cppcheck, and clang-format. `lint-source-safety` runs the source guard and its
+self-tests; it blocks new MCP stdout writes, insecure string APIs, raw env/filesystem calls in
+reviewed paths, and other regressions that should use existing CBM helpers instead. All must pass
+before committing (also enforced by pre-commit hook).
## Run Security Audit
@@ -55,7 +137,7 @@ src/
foundation/ Arena allocator, hash table, string utils, platform compat
store/ SQLite graph storage (WAL mode, FTS5)
cypher/ Cypher query → SQL translation
- mcp/ MCP server (JSON-RPC 2.0 over stdio, 14 tools)
+ mcp/ MCP server and tools (JSON-RPC 2.0 over stdio)
pipeline/ Multi-pass indexing pipeline
pass_*.c Individual pipeline passes (definitions, calls, usages, etc.)
httplink.c HTTP route extraction (Go/Express/Laravel/Ktor/Python)
diff --git a/Makefile.cbm b/Makefile.cbm
index 28eb21e27..bfc3d1e13 100644
--- a/Makefile.cbm
+++ b/Makefile.cbm
@@ -2,10 +2,25 @@
#
# Usage:
# make -f Makefile.cbm test # Build + run all tests (ASan + UBSan)
+# CBM_ONLY_SUITE=pipeline make -f Makefile.cbm test
+# # Run one suite after building
+# CBM_ONLY_SUITE=pipeline CBM_ONLY_TEST=exact build/c/test-runner
+# # Run matching tests inside one suite
# make -f Makefile.cbm test-foundation # Foundation tests only (fast)
# make -f Makefile.cbm test-tsan # Thread sanitizer build
-# make -f Makefile.cbm cbm # Production binary
+# make -f Makefile.cbm test-syntax TEST_SYNTAX_SRCS="tests/test_mcp.c"
+# # syntax-check selected C units with real test flags
+# make -f Makefile.cbm cbm # Production binary (auto-signed on macOS)
+# make -f Makefile.cbm native-extraction-benchmark
+# # O2 production extraction benchmark runner
+# make -f Makefile.cbm install # Build + install to INSTALL_DIR (default ~/.local/bin)
# make -f Makefile.cbm clean-c # Remove build artifacts
+#
+# macOS signing note:
+# macOS 25+ enforces ad-hoc code signatures on binaries. Copying a binary
+# without re-signing causes immediate SIGKILL at runtime. This Makefile
+# runs `codesign --force --sign -` automatically after every build and
+# install step on macOS. On Linux and other platforms the step is a no-op.
# Compiler selection — override via: make CC=gcc CXX=g++
# macOS: cc (Apple Clang) — universal binary with ASan support
@@ -34,6 +49,44 @@ TS_INCLUDE = $(CBM_DIR)/vendored/ts_runtime/include
# This ensures we use our vendored copies instead of requiring system libicu-dev.
TS_SRC = $(CBM_DIR)/vendored/ts_runtime/src
+# ── Optional libgit2 (faster git history parsing) ────────────────
+# Auto-detected via pkg-config. Falls back to popen("git log ...") if absent.
+LIBGIT2_CFLAGS := $(shell pkg-config --cflags libgit2 2>/dev/null)
+LIBGIT2_LIBS := $(shell pkg-config --libs libgit2 2>/dev/null)
+ifneq ($(LIBGIT2_LIBS),)
+LIBGIT2_FLAGS = -DHAVE_LIBGIT2 $(LIBGIT2_CFLAGS)
+else
+LIBGIT2_FLAGS =
+LIBGIT2_LIBS =
+endif
+
+# ── Platform detection & code signing ───────────────────────────
+# macOS 25+ kills unsigned or invalidly-signed binaries with SIGKILL.
+# codesign --force --sign - applies an ad-hoc signature (no Apple Developer
+# account required). On Linux/other platforms this entire block is a no-op.
+UNAME_S := $(shell uname -s)
+ifeq ($(UNAME_S),Darwin)
+CODESIGN_BIN := $(shell command -v codesign 2>/dev/null)
+ifneq ($(CODESIGN_BIN),)
+# codesign is available — sign and report
+define codesign_binary
+ @$(CODESIGN_BIN) --force --sign - $(1) 2>&1 && \
+ echo " ✓ signed $(1) (ad-hoc, macOS 25+ compatible)" || \
+ { echo " ✗ WARNING: codesign failed for $(1) — binary may crash on macOS 25+"; true; }
+endef
+else
+# codesign not found — warn but don't fail the build
+define codesign_binary
+ @echo " ✗ WARNING: codesign not found — $(1) may crash on macOS 25+ (install Xcode CLT)"
+endef
+endif
+else
+# Non-macOS: signing is a documented no-op
+define codesign_binary
+ @echo " (signing skipped — not macOS)"
+endef
+endif
+
# GCC-only warning suppressions (Clang rejects unknown -Wno-* with -Werror).
# Detect GCC by checking for __GNUC__ without __clang__ — handles all versions.
IS_GCC := $(shell echo | $(CC) -dM -E - 2>/dev/null | grep -q '__GNUC__' && ! echo | $(CC) -dM -E - 2>/dev/null | grep -q '__clang__' && echo yes || echo no)
@@ -50,6 +103,7 @@ endif
CFLAGS_COMMON = -std=c11 -D_DEFAULT_SOURCE -D_GNU_SOURCE -Wall -Wextra -Werror \
-Wno-unused-parameter -Wno-sign-compare -Wdate-time \
$(GCC_ONLY_FLAGS) \
+ $(LIBGIT2_FLAGS) \
-Isrc -Ivendored -Ivendored/sqlite3 \
-Ivendored/mimalloc/include \
-I$(CBM_DIR) -I$(TS_INCLUDE) -I$(BUILD_DIR)/generated
@@ -58,33 +112,32 @@ CXXFLAGS_COMMON = -std=c++14 -Wall -Wextra -Werror \
-Wno-unused-parameter \
-I$(CBM_DIR) -I$(TS_INCLUDE)
-# Test seams are OPT-IN, never opt-out. Some suites drive behaviour that only a
-# test should be able to ask for (fork an orphan the watchdog must reap, publish
-# a lease-ownership marker). That code has no production caller and reads exactly
-# like malware to a generic classifier, so it must not be in a shipped binary.
-# Opt-IN means the failure mode of forgetting the flag is a CLEAN binary rather
-# than a leaky one — the opposite choice would make every future release depend
-# on someone remembering. scripts/test.sh passes TEST_SEAMS=1 for the suites that
-# need it; the test-runner always has them.
+# Test seams are opt-in for production binaries. The test runner always enables
+# them through EDITOR_TEST_DEFINES, while selected production watchdog tests set
+# TEST_SEAMS=1 explicitly. A forgotten flag therefore produces a clean release
+# binary instead of silently shipping test-only process and lease controls.
TEST_SEAM_DEFINE :=
ifeq ($(TEST_SEAMS),1)
TEST_SEAM_DEFINE := -DCBM_ENABLE_TEST_SEAMS=1
endif
-# Production flags (CFLAGS_EXTRA allows CI to inject -DCBM_VERSION)
+# Production flags. CFLAGS_EXTRA carries the generated version define;
+# EXTRA_{C,CXX,LD}FLAGS are explicit developer/CI overrides appended last.
# CBM_BIND_TS_ALLOCATOR=1: bind the tree-sitter runtime to mimalloc (#424). Only
# the prod build uses mimalloc (MI_OVERRIDE=1); the test build is CRT+ASan, where
# binding would create an alloc/free mismatch, so the guard is prod-only.
CFLAGS_PROD = $(CFLAGS_COMMON) -O2 -DCBM_BIND_TS_ALLOCATOR=1 $(TEST_SEAM_DEFINE) \
- $(GLOBAL_OVERRIDE_DEFINE) $(CFLAGS_EXTRA)
-CXXFLAGS_PROD = $(CXXFLAGS_COMMON) -O2
+ $(GLOBAL_OVERRIDE_DEFINE) $(CFLAGS_EXTRA) $(EXTRA_CFLAGS)
+CXXFLAGS_PROD = $(CXXFLAGS_COMMON) -O2 $(EXTRA_CXXFLAGS)
# Test flags: debug + sanitizers (override SANITIZE= to disable on Windows)
SANITIZE = -fsanitize=address,undefined -fno-omit-frame-pointer
EDITOR_TEST_DEFINES = -DCBM_JSON_LIKE_ENABLE_TEST_API=1 \
-DCBM_TOML_EDIT_ENABLE_TEST_API=1 -DCBM_YAML_ENABLE_TEST_API=1 \
-DCBM_TEXT_EDIT_ENABLE_TEST_API=1 -DCBM_CLI_ENABLE_TEST_API=1 \
- -DCBM_DIAGNOSTICS_ENABLE_TEST_API=1 -DCBM_ENABLE_TEST_SEAMS=1
+ -DCBM_DIAGNOSTICS_ENABLE_TEST_API=1 -DCBM_PIPELINE_ENABLE_TEST_API=1 \
+ -DCBM_WATCHER_ENABLE_TEST_API=1 -DCBM_ENABLE_TEST_SEAMS=1
+TEST_INCLUDE_FLAGS = -Itests -Itests/repro
# The build system is the single source of truth for "is this binary
# instrumented": compiler-specific probes (__SANITIZE_ADDRESS__) miss
# clang's feature-check spelling and every non-ASan sanitizer, so the
@@ -183,6 +236,8 @@ endif
# surface for data that is never executed, and it is invisible to section flags.
ELF_HARDENING_FLAGS :=
ifeq ($(IS_LINUX),yes)
+# A Linux container may cross-compile a PE binary. IS_LINUX identifies the
+# build host, so the compiler-derived target guard is also required.
ifneq ($(IS_MINGW),yes)
ELF_HARDENING_FLAGS := -Wl,-z,noexecstack -Wl,-z,separate-code
endif
@@ -197,9 +252,20 @@ endif
# instead of the system libstdc++ (scripts/msan.sh overrides both vars).
CXX_STDLIB ?= -lstdc++
CXX_STDLIB_FLAGS ?=
-LDFLAGS = -lm $(CXX_STDLIB) -lpthread -lz $(WIN32_LIBS) $(STATIC_FLAGS) $(MIMALLOC_WRAP_FLAGS) $(ELF_HARDENING_FLAGS)
-LDFLAGS_TEST = -lm $(CXX_STDLIB) -lpthread -lz $(SANITIZE) $(WIN32_LIBS) $(MIMALLOC_WRAP_FLAGS) $(ELF_HARDENING_FLAGS)
-LDFLAGS_TSAN = -lm $(CXX_STDLIB) -lpthread -lz $(TSAN_SANITIZE) $(WIN32_LIBS) $(MIMALLOC_WRAP_FLAGS) $(ELF_HARDENING_FLAGS)
+LDFLAGS = -lm $(CXX_STDLIB) -lpthread -lz $(LIBGIT2_LIBS) $(WIN32_LIBS) \
+ $(STATIC_FLAGS) $(MIMALLOC_WRAP_FLAGS) $(ELF_HARDENING_FLAGS) $(EXTRA_LDFLAGS)
+LDFLAGS_TEST = -lm $(CXX_STDLIB) -lpthread -lz $(SANITIZE) $(LIBGIT2_LIBS) \
+ $(WIN32_LIBS) $(MIMALLOC_WRAP_FLAGS) $(ELF_HARDENING_FLAGS)
+LDFLAGS_TSAN = -lm $(CXX_STDLIB) -lpthread -lz $(TSAN_SANITIZE) $(LIBGIT2_LIBS) \
+ $(WIN32_LIBS) $(MIMALLOC_WRAP_FLAGS) $(ELF_HARDENING_FLAGS)
+# nosan: no ASan/UBSan — required for macOS 'leaks' tool (incompatible with ASan malloc replacement).
+# Keep every test API identical to the sanitizer/TSan runners; changing the
+# allocator instrumentation must not silently compile a different test suite.
+CFLAGS_NOSAN = $(CFLAGS_COMMON) $(EDITOR_TEST_DEFINES) \
+ $(KOTLIN_DEDUP_TEST_DEFINE) $(CALL_REFERENCE_LOOKUP_TEST_DEFINE) \
+ $(INCREMENTAL_TEST_DEFINE) -g -O1
+LDFLAGS_NOSAN = -lm $(CXX_STDLIB) -lpthread -lz $(LIBGIT2_LIBS) $(WIN32_LIBS) \
+ $(MIMALLOC_WRAP_FLAGS) $(ELF_HARDENING_FLAGS)
# ── Source files ─────────────────────────────────────────────────
@@ -254,7 +320,6 @@ EXTRACTION_SRCS = \
# LSP resolvers (compiled as one unit via lsp_all.c)
LSP_SRCS = $(CBM_DIR)/lsp_all.c
-
# Header/source dependencies of the lsp_all unity object. lsp_all.c #includes
# every lsp/*.c resolver, which in turn include cbm.h — and CBMCall is copied
# BY VALUE across the lsp -> pipeline boundary (cbm_calls_push). This object is
@@ -345,6 +410,9 @@ PIPELINE_SRCS = \
src/pipeline/pass_gitdiff.c \
src/pipeline/pass_configures.c \
src/pipeline/pass_configlink.c \
+ src/pipeline/pass_normalize.c \
+ src/pipeline/httplink.c \
+ src/pipeline/pass_httplinks.c \
src/pipeline/pass_route_nodes.c \
src/pipeline/pass_enrichment.c \
src/pipeline/pass_envscan.c \
@@ -367,6 +435,12 @@ SEMANTIC_SRCS = src/semantic/semantic.c src/semantic/ast_profile.c src/semantic/
# nomic-embed-code pretrained vectors (assembler blob)
UNIXCODER_BLOB_SRC = vendored/nomic/code_vectors_blob.S
+# Depindex module (dependency/reference API indexing)
+DEPINDEX_SRCS = src/depindex/depindex.c
+
+# PageRank module (node + edge ranking)
+PAGERANK_SRCS = src/pagerank/pagerank.c
+
# Traces module (new)
TRACES_SRCS = src/traces/traces.c
@@ -374,7 +448,9 @@ TRACES_SRCS = src/traces/traces.c
WATCHER_SRCS = src/watcher/watcher.c
# Git context module (new)
-GIT_SRCS = src/git/git_context.c
+GIT_SRCS = src/git/git_command.c \
+ src/git/git_context.c \
+ src/git/git_snapshot.c
# CLI module (new)
CLI_SRCS = src/cli/cli.c src/cli/progress_sink.c src/cli/hook_augment.c src/cli/client_adapter.c \
@@ -475,7 +551,7 @@ TRE_CFLAGS = -std=c11 -g -O1 -w -Ivendored/tre
YYJSON_SRC = vendored/yyjson/yyjson.c
# All production sources
-PROD_SRCS = $(FOUNDATION_SRCS) $(STORE_SRCS) $(CYPHER_SRCS) $(MCP_SRCS) $(DAEMON_SRCS) $(DISCOVER_SRCS) $(GRAPH_BUFFER_SRCS) $(PIPELINE_SRCS) $(SIMHASH_SRCS) $(SEMANTIC_SRCS) $(TRACES_SRCS) $(WATCHER_SRCS) $(GIT_SRCS) $(CLI_SRCS) $(UI_SRCS) $(YYJSON_SRC)
+PROD_SRCS = $(FOUNDATION_SRCS) $(STORE_SRCS) $(CYPHER_SRCS) $(MCP_SRCS) $(DAEMON_SRCS) $(DISCOVER_SRCS) $(GRAPH_BUFFER_SRCS) $(PIPELINE_SRCS) $(DEPINDEX_SRCS) $(PAGERANK_SRCS) $(SIMHASH_SRCS) $(SEMANTIC_SRCS) $(TRACES_SRCS) $(WATCHER_SRCS) $(GIT_SRCS) $(CLI_SRCS) $(UI_SRCS) $(YYJSON_SRC)
EXISTING_C_SRCS = $(EXTRACTION_SRCS) $(LSP_SRCS) $(TS_RUNTIME_SRC) \
$(GRAMMAR_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC)
@@ -496,7 +572,10 @@ PROJECT_HDRS = $(wildcard src/*.h src/*/*.h $(CBM_DIR)/*.h $(CBM_DIR)/lsp/*.h te
# ── Test sources ─────────────────────────────────────────────────
TEST_FOUNDATION_SRCS = \
- tests/test_main.c \
+ tests/test_foundation_main.c \
+ $(TEST_FOUNDATION_CASE_SRCS)
+
+TEST_FOUNDATION_CASE_SRCS = \
tests/test_arena.c \
tests/test_hash_table.c \
tests/test_dyn_array.c \
@@ -506,12 +585,13 @@ TEST_FOUNDATION_SRCS = \
tests/test_workspace.c \
tests/test_platform.c \
tests/test_diagnostics.c \
- tests/test_complexity.c \
tests/test_dump_verify.c \
tests/test_subprocess.c \
tests/test_private_file_lock.c \
tests/test_lock_registry.c
+TEST_MAIN_SRC = tests/test_main.c
+
TEST_EXTRACTION_SRCS = \
tests/test_extraction.c \
tests/test_extraction_inheritance.c \
@@ -530,7 +610,8 @@ TEST_STORE_SRCS = \
tests/test_store_bulk.c \
tests/test_store_pragmas.c \
tests/test_store_checkpoint.c \
- tests/test_dump_verify_io.c
+ tests/test_dump_verify_io.c \
+ tests/test_schema_declared_property_keys.c
TEST_CYPHER_SRCS = \
tests/test_cypher.c
@@ -559,7 +640,34 @@ TEST_DISCOVER_SRCS = \
TEST_GRAPH_BUFFER_SRCS = tests/test_graph_buffer.c
-TEST_PIPELINE_SRCS = tests/test_registry.c tests/test_pipeline.c tests/test_cross_repo.c tests/test_fqn.c tests/test_route_canon.c tests/test_path_alias.c tests/test_configlink.c tests/test_infrascan.c tests/test_worker_pool.c tests/test_parallel.c tests/test_index_resilience.c tests/test_call_reference_contract.c tests/repro/repro_call_scope_usages.c tests/repro/repro_call_argument_usages.c tests/repro/repro_reference_precision.c tests/repro/repro_lexical_binding_precision.c tests/repro/repro_call_argument_matrix_a.c tests/repro/repro_call_argument_matrix_b.c tests/repro/repro_call_node_behaviors.c tests/repro/repro_language_registry.c tests/repro/repro_call_node_manifest.c tests/repro/repro_lsp_ordered_signatures.c tests/repro/repro_lsp_ordered_local.c tests/repro/repro_ts_overload_return_chains.c tests/repro/repro_harness_cleanup.c tests/repro/repro_runner_filter.c
+TEST_PIPELINE_SRCS = \
+ tests/test_complexity.c \
+ tests/test_registry.c \
+ tests/test_pipeline.c \
+ tests/test_cross_repo.c \
+ tests/test_fqn.c \
+ tests/test_route_canon.c \
+ tests/test_path_alias.c \
+ tests/test_configlink.c \
+ tests/test_infrascan.c \
+ tests/test_worker_pool.c \
+ tests/test_parallel.c \
+ tests/test_index_resilience.c \
+ tests/test_call_reference_contract.c \
+ tests/repro/repro_call_scope_usages.c \
+ tests/repro/repro_call_argument_usages.c \
+ tests/repro/repro_reference_precision.c \
+ tests/repro/repro_lexical_binding_precision.c \
+ tests/repro/repro_call_argument_matrix_a.c \
+ tests/repro/repro_call_argument_matrix_b.c \
+ tests/repro/repro_call_node_behaviors.c \
+ tests/repro/repro_language_registry.c \
+ tests/repro/repro_call_node_manifest.c \
+ tests/repro/repro_lsp_ordered_signatures.c \
+ tests/repro/repro_lsp_ordered_local.c \
+ tests/repro/repro_ts_overload_return_chains.c \
+ tests/repro/repro_harness_cleanup.c \
+ tests/repro/repro_runner_filter.c
TEST_WATCHER_SRCS = tests/test_watcher.c
@@ -613,9 +721,18 @@ TEST_MEM_SRCS = tests/test_mem.c
TEST_UI_SRCS = tests/test_ui.c
TEST_HTTPD_SRCS = tests/test_httpd.c
-TEST_SECURITY_SRCS = tests/test_security.c
+TEST_DEPINDEX_SRCS = tests/test_depindex.c
+
+TEST_PAGERANK_SRCS = tests/test_pagerank.c
+TEST_TOKEN_REDUCTION_SRCS = tests/test_token_reduction.c
+
+TEST_TOOL_CONSOLIDATION_SRCS = tests/test_tool_consolidation.c
+TEST_INPUT_VALIDATION_SRCS = tests/test_input_validation.c
+
+TEST_SECURITY_SRCS = tests/test_security.c
TEST_YAML_SRCS = tests/test_yaml.c
+TEST_HTTPLINK_SRCS = tests/test_httplink.c
TEST_SEMANTIC_SRCS = tests/test_semantic.c
TEST_AST_PROFILE_SRCS = tests/test_ast_profile.c
@@ -702,8 +819,57 @@ TEST_REPRO_SRCS = \
tests/repro/repro_lsp_java_cs.c \
tests/repro/repro_lsp_kt_php_rust.c
-ALL_TEST_SRCS =$(TEST_FOUNDATION_SRCS) $(TEST_EXTRACTION_SRCS) $(TEST_STORE_SRCS) $(TEST_CYPHER_SRCS) $(TEST_MCP_SRCS) $(TEST_DAEMON_SRCS) $(TEST_DISCOVER_SRCS) $(TEST_GRAPH_BUFFER_SRCS) $(TEST_PIPELINE_SRCS) $(TEST_WATCHER_SRCS) $(TEST_LZ4_SRCS) $(TEST_ZSTD_SRCS) $(TEST_ARTIFACT_SRCS) $(TEST_SQLITE_WRITER_SRCS) $(TEST_GO_LSP_SRCS) $(TEST_C_LSP_SRCS) $(TEST_PHP_LSP_SRCS) $(TEST_CS_LSP_SRCS) $(TEST_CS_LSP_BENCH_SRCS) $(TEST_PERL_LSP_SRCS) $(TEST_SCOPE_SRCS) $(TEST_TYPE_REP_SRCS) $(TEST_PY_LSP_SRCS) $(TEST_PY_LSP_BENCH_SRCS) $(TEST_PY_LSP_STRESS_SRCS) $(TEST_PY_LSP_SCALE_SRCS) $(TEST_TS_LSP_SRCS) $(TEST_JAVA_LSP_SRCS) $(TEST_KOTLIN_LSP_SRCS) $(TEST_RUST_LSP_SRCS) $(TEST_TRACES_SRCS) $(TEST_CLI_SRCS) $(TEST_MEM_SRCS) $(TEST_UI_SRCS) $(TEST_HTTPD_SRCS) $(TEST_SECURITY_SRCS) $(TEST_YAML_SRCS) $(TEST_SEMANTIC_SRCS) $(TEST_AST_PROFILE_SRCS) $(TEST_SLAB_ALLOC_SRCS) $(TEST_SIMHASH_SRCS) $(TEST_STACK_OVERFLOW_SRCS) $(TEST_INTEGRATION_SRCS)
-
+ALL_TEST_SRCS = \
+ $(TEST_MAIN_SRC) \
+ $(TEST_FOUNDATION_CASE_SRCS) \
+ $(TEST_EXTRACTION_SRCS) \
+ $(TEST_STORE_SRCS) \
+ $(TEST_CYPHER_SRCS) \
+ $(TEST_MCP_SRCS) \
+ $(TEST_DAEMON_SRCS) \
+ $(TEST_DISCOVER_SRCS) \
+ $(TEST_GRAPH_BUFFER_SRCS) \
+ $(TEST_PIPELINE_SRCS) \
+ $(TEST_WATCHER_SRCS) \
+ $(TEST_LZ4_SRCS) \
+ $(TEST_ZSTD_SRCS) \
+ $(TEST_ARTIFACT_SRCS) \
+ $(TEST_SQLITE_WRITER_SRCS) \
+ $(TEST_GO_LSP_SRCS) \
+ $(TEST_C_LSP_SRCS) \
+ $(TEST_PHP_LSP_SRCS) \
+ $(TEST_CS_LSP_SRCS) \
+ $(TEST_CS_LSP_BENCH_SRCS) \
+ $(TEST_PERL_LSP_SRCS) \
+ $(TEST_SCOPE_SRCS) \
+ $(TEST_TYPE_REP_SRCS) \
+ $(TEST_PY_LSP_SRCS) \
+ $(TEST_PY_LSP_BENCH_SRCS) \
+ $(TEST_PY_LSP_STRESS_SRCS) \
+ $(TEST_PY_LSP_SCALE_SRCS) \
+ $(TEST_TS_LSP_SRCS) \
+ $(TEST_JAVA_LSP_SRCS) \
+ $(TEST_KOTLIN_LSP_SRCS) \
+ $(TEST_RUST_LSP_SRCS) \
+ $(TEST_TRACES_SRCS) \
+ $(TEST_HTTPLINK_SRCS) \
+ $(TEST_CLI_SRCS) \
+ $(TEST_MEM_SRCS) \
+ $(TEST_UI_SRCS) \
+ $(TEST_HTTPD_SRCS) \
+ $(TEST_DEPINDEX_SRCS) \
+ $(TEST_PAGERANK_SRCS) \
+ $(TEST_TOKEN_REDUCTION_SRCS) \
+ $(TEST_TOOL_CONSOLIDATION_SRCS) \
+ $(TEST_INPUT_VALIDATION_SRCS) \
+ $(TEST_SECURITY_SRCS) \
+ $(TEST_YAML_SRCS) \
+ $(TEST_SEMANTIC_SRCS) \
+ $(TEST_AST_PROFILE_SRCS) \
+ $(TEST_SLAB_ALLOC_SRCS) \
+ $(TEST_SIMHASH_SRCS) \
+ $(TEST_STACK_OVERFLOW_SRCS) \
+ $(TEST_INTEGRATION_SRCS)
# ── Build directories ────────────────────────────────────────────
@@ -712,10 +878,10 @@ BUILD_DIR = build/c
# ── Object file compilation (grammars need relaxed warnings) ─────
# Grammar + tree-sitter runtime: compiled without -Werror (upstream code has warnings)
-GRAMMAR_CFLAGS = -std=c11 -D_DEFAULT_SOURCE -O2 -w -I$(CBM_DIR) -I$(TS_INCLUDE) -I$(TS_SRC)
-GRAMMAR_CFLAGS_TEST = -std=c11 -D_DEFAULT_SOURCE -g -O1 -w -I$(CBM_DIR) -I$(TS_INCLUDE) -I$(TS_SRC) \
+GRAMMAR_CFLAGS = -std=c11 -D_DEFAULT_SOURCE -O2 -w -Isrc -I$(CBM_DIR) -I$(TS_INCLUDE) -I$(TS_SRC)
+GRAMMAR_CFLAGS_TEST = -std=c11 -D_DEFAULT_SOURCE -g -O1 -w -Isrc -I$(CBM_DIR) -I$(TS_INCLUDE) -I$(TS_SRC) \
-DCBM_ENABLE_TEST_SEAMS=1 $(SANITIZED_DEFINE) $(SANITIZE)
-GRAMMAR_CFLAGS_TSAN = -std=c11 -D_DEFAULT_SOURCE -g -O1 -w -I$(CBM_DIR) -I$(TS_INCLUDE) -I$(TS_SRC) \
+GRAMMAR_CFLAGS_TSAN = -std=c11 -D_DEFAULT_SOURCE -g -O1 -w -Isrc -I$(CBM_DIR) -I$(TS_INCLUDE) -I$(TS_SRC) \
-DCBM_ENABLE_TEST_SEAMS=1 -DCBM_SANITIZED_BUILD=1 $(TSAN_SANITIZE)
# Object files for grammars + ts_runtime + lsp_all + preprocessor
@@ -728,25 +894,52 @@ TS_RUNTIME_OBJ_TSAN = $(BUILD_DIR)/tsan_ts_runtime.o
LSP_OBJ_TSAN = $(BUILD_DIR)/tsan_lsp_all.o
PP_OBJ_TSAN = $(BUILD_DIR)/tsan_preprocessor.o
+# Grammar wrappers include generated parser/scanner C files. Compiler-generated
+# dependency files keep incremental builds correct after grammar refreshes and
+# branch/worktree switches. The v1 stamp forces pre-depfile objects to rebuild
+# once; subsequent builds invalidate only the grammar whose included files moved.
+GRAMMAR_DEP_STAMP = $(BUILD_DIR)/.grammar-deps-v1
+GRAMMAR_DEPFILES = $(addsuffix .d,$(GRAMMAR_OBJS_TEST) $(GRAMMAR_OBJS_TSAN))
+
# ── Targets ──────────────────────────────────────────────────────
-.PHONY: test test-par test-repro test-foundation test-tsan test-daemon-smoke cbm cbm-with-ui frontend embed clean-c lint lint-tidy lint-tidy-diff lint-cppcheck lint-format security
+.PHONY: test test-par test-focused test-compositional test-repro test-foundation test-tsan \
+ test-syntax test-daemon-smoke \
+ test-leak test-analyze test-memory test-gmalloc cbm \
+ cbm-with-ui frontend embed clean-c lint lint-tidy lint-tidy-diff lint-cppcheck \
+ lint-format lint-source-safety install test-runner-nosan security \
+ native-extraction-benchmark
$(BUILD_DIR):
mkdir -p $(BUILD_DIR)
# ── Foundation-only test (fast, no extraction) ───────────────────
-$(BUILD_DIR)/test-foundation: $(TEST_FOUNDATION_SRCS) $(FOUNDATION_SRCS) $(PROJECT_HDRS) | $(BUILD_DIR)
- $(CC) $(CFLAGS_TEST) -o $@ $(TEST_FOUNDATION_SRCS) $(FOUNDATION_SRCS) $(LDFLAGS_TEST)
+$(BUILD_DIR)/test-foundation: $(TEST_FOUNDATION_SRCS) $(FOUNDATION_SRCS) \
+ $(MIMALLOC_OBJ_TEST) $(TS_RUNTIME_OBJ_TEST) $(PROJECT_HDRS) | $(BUILD_DIR)
+ $(CC) $(CFLAGS_TEST) -o $@ $(TEST_FOUNDATION_SRCS) $(FOUNDATION_SRCS) \
+ $(MIMALLOC_OBJ_TEST) $(TS_RUNTIME_OBJ_TEST) $(LDFLAGS_TEST)
test-foundation: $(BUILD_DIR)/test-foundation
cd $(CURDIR) && $(BUILD_DIR)/test-foundation
+# Fast C syntax check for selected test or production translation units. Reuse
+# the nosan test flags so gated *_for_testing declarations and both test include
+# roots cannot drift from the real test builds. Example:
+# make -f Makefile.cbm test-syntax TEST_SYNTAX_SRCS="tests/test_mcp.c src/mcp/mcp.c"
+TEST_SYNTAX_SRCS ?=
+test-syntax:
+ @test -n "$(strip $(TEST_SYNTAX_SRCS))" || \
+ (echo "TEST_SYNTAX_SRCS is required for test-syntax"; exit 2)
+ $(CC) $(CFLAGS_NOSAN) $(TEST_INCLUDE_FLAGS) -fsyntax-only $(TEST_SYNTAX_SRCS)
+
# ── Grammar/TS/LSP object files (compiled with relaxed warnings) ─
-$(BUILD_DIR)/%.o: $(CBM_DIR)/%.c | $(BUILD_DIR)
- $(CC) $(GRAMMAR_CFLAGS_TEST) -c -o $@ $<
+$(GRAMMAR_DEP_STAMP): | $(BUILD_DIR)
+ @touch $@
+
+$(GRAMMAR_OBJS_TEST): $(BUILD_DIR)/%.o: $(CBM_DIR)/%.c $(GRAMMAR_DEP_STAMP) | $(BUILD_DIR)
+ $(CC) $(GRAMMAR_CFLAGS_TEST) -MMD -MP -MF $@.d -c -o $@ $<
$(BUILD_DIR)/ts_runtime.o: $(TS_RUNTIME_DEPS) | $(BUILD_DIR)
$(CC) $(GRAMMAR_CFLAGS_TEST) -c -o $@ $<
@@ -757,8 +950,8 @@ $(BUILD_DIR)/lsp_all.o: $(LSP_UNITY_DEPS) | $(BUILD_DIR)
$(BUILD_DIR)/preprocessor.o: $(CBM_DIR)/preprocessor.cpp | $(BUILD_DIR)
$(CXX) $(CXXFLAGS_TEST) -w -I$(CBM_DIR)/vendored -c -o $@ $<
-$(BUILD_DIR)/tsan_%.o: $(CBM_DIR)/%.c | $(BUILD_DIR)
- $(CC) $(GRAMMAR_CFLAGS_TSAN) -c -o $@ $<
+$(GRAMMAR_OBJS_TSAN): $(BUILD_DIR)/tsan_%.o: $(CBM_DIR)/%.c $(GRAMMAR_DEP_STAMP) | $(BUILD_DIR)
+ $(CC) $(GRAMMAR_CFLAGS_TSAN) -MMD -MP -MF $@.d -c -o $@ $<
$(BUILD_DIR)/tsan_ts_runtime.o: $(TS_RUNTIME_DEPS) | $(BUILD_DIR)
$(CC) $(GRAMMAR_CFLAGS_TSAN) -c -o $@ $<
@@ -837,6 +1030,67 @@ $(BUILD_DIR)/prod_tre.o: $(TRE_SRC) | $(BUILD_DIR)
$(CC) $(TRE_CFLAGS) -O2 -c -o $@ $<
endif
+# ── Nosan build: ASan-free test runner for macOS heap leak detection ─────────
+#
+# WHY THIS EXISTS:
+# 'make test-leak' uses Apple's 'leaks --atExit' tool to find heap leaks.
+# But leaks cannot inspect a process that uses a custom malloc (such as ASan).
+# The regular test-runner is built with -fsanitize=address,undefined, which
+# replaces malloc → leaks aborts with "unable to inspect heap ranges".
+#
+# HOW IT WORKS:
+# We rebuild all ASan-instrumented vendored objects without -fsanitize flags
+# into $(NOSAN_DIR), then link test-runner-nosan against them.
+# The resulting binary runs the full test suite under Apple's heap profiler.
+# Full leak report is written to $(LEAK_LOG) = build/c/leak-report.txt.
+#
+# HOW TO USE:
+# make test-leak # runs full suite + heap check, saves report to LEAK_LOG
+# cat build/c/leak-report.txt # review complete leak report after run
+#
+# WHICH OBJECTS NEED NOSAN VARIANTS (use SANITIZE in their *_TEST flags):
+# sqlite3, lsp_all, preprocessor, grammar/*.c, ts_runtime
+# WHICH ARE REUSED AS-IS (never use SANITIZE):
+# mimalloc (MIMALLOC_CFLAGS_TEST has no -fsanitize)
+# tre (only on Windows; TRE_CFLAGS has no -fsanitize)
+#
+NOSAN_DIR = $(BUILD_DIR)/nosan
+# Keeps -DCBM_ENABLE_TEST_SEAMS=1 for the same reason GRAMMAR_CFLAGS_TEST and
+# GRAMMAR_CFLAGS_TSAN do: the nosan objects are the TEST build minus sanitizers,
+# and test-runner-nosan is linked with the seam define. Dropping it here compiles
+# the seam bodies out of nosan/lsp_all.o while tests still reference them, which
+# fails the leaks/scribble/gmalloc link with undefined
+# _cbm_ts_lsp_test_budget_remaining / _cbm_ts_lsp_test_budget_warned.
+# CBM_SANITIZED_BUILD is deliberately absent — this variant has no sanitizer.
+GRAMMAR_CFLAGS_NOSAN = -std=c11 -D_DEFAULT_SOURCE -g -O1 -w -Isrc -I$(CBM_DIR) -I$(TS_INCLUDE) -I$(TS_SRC) \
+ -DCBM_ENABLE_TEST_SEAMS=1
+GRAMMAR_OBJS_NOSAN = $(patsubst $(CBM_DIR)/%.c,$(NOSAN_DIR)/%.o,$(GRAMMAR_SRCS))
+GRAMMAR_DEPFILES += $(addsuffix .d,$(GRAMMAR_OBJS_NOSAN))
+
+$(NOSAN_DIR):
+ mkdir -p $(NOSAN_DIR)
+
+# Grammar C files (tree-sitter parsers) — recompiled without ASan/UBSan
+$(GRAMMAR_OBJS_NOSAN): $(NOSAN_DIR)/%.o: $(CBM_DIR)/%.c $(GRAMMAR_DEP_STAMP) | $(NOSAN_DIR)
+ $(CC) $(GRAMMAR_CFLAGS_NOSAN) -MMD -MP -MF $@.d -c -o $@ $<
+
+$(NOSAN_DIR)/ts_runtime.o: $(CBM_DIR)/ts_runtime.c | $(NOSAN_DIR)
+ $(CC) $(GRAMMAR_CFLAGS_NOSAN) -c -o $@ $<
+
+$(NOSAN_DIR)/lsp_all.o: $(LSP_UNITY_DEPS) | $(NOSAN_DIR)
+ $(CC) $(GRAMMAR_CFLAGS_NOSAN) -c -o $@ $<
+
+$(NOSAN_DIR)/preprocessor.o: $(CBM_DIR)/preprocessor.cpp | $(NOSAN_DIR)
+ $(CXX) $(CXXFLAGS_COMMON) -g -O1 -w -I$(CBM_DIR)/vendored -c -o $@ $<
+
+$(NOSAN_DIR)/sqlite3.o: $(SQLITE3_SRC) | $(NOSAN_DIR)
+ $(CC) $(SQLITE3_CFLAGS_TEST) -c -o $@ $<
+
+OBJS_VENDORED_NOSAN = $(MIMALLOC_OBJ_TEST) $(NOSAN_DIR)/sqlite3.o $(TRE_OBJ_TEST) \
+ $(GRAMMAR_OBJS_NOSAN) $(NOSAN_DIR)/ts_runtime.o \
+ $(NOSAN_DIR)/lsp_all.o $(NOSAN_DIR)/preprocessor.o \
+ $(NOSAN_LZ4_OBJ) $(NOSAN_ZSTD_OBJ) $(UNIXCODER_OBJ)
+
# Vendored LZ4 (test build)
LZ4_OBJ_TEST = $(BUILD_DIR)/test_lz4.o $(BUILD_DIR)/test_lz4hc.o
LZ4_OBJ_TSAN = $(BUILD_DIR)/tsan_lz4.o $(BUILD_DIR)/tsan_lz4hc.o
@@ -865,6 +1119,17 @@ $(BUILD_DIR)/test_zstd.o: $(CBM_DIR)/vendored/zstd/zstd.c | $(BUILD_DIR)
$(BUILD_DIR)/tsan_zstd.o: $(CBM_DIR)/vendored/zstd/zstd.c | $(BUILD_DIR)
$(CC) -std=c11 -D_DEFAULT_SOURCE -g -O1 $(TSAN_SANITIZE) -w -I$(CBM_DIR)/vendored/zstd -c -o $@ $<
+# Vendored LZ4/zstd (NOSAN build — sanitizer-free so `leaks --atExit` can walk the
+# heap on macOS; ASan replaces malloc and is incompatible with the leaks tool).
+NOSAN_LZ4_OBJ = $(NOSAN_DIR)/lz4.o $(NOSAN_DIR)/lz4hc.o
+NOSAN_ZSTD_OBJ = $(NOSAN_DIR)/zstd.o
+$(NOSAN_DIR)/lz4.o: $(CBM_DIR)/vendored/lz4/lz4.c | $(NOSAN_DIR)
+ $(CC) -std=c11 -D_DEFAULT_SOURCE -g -O1 -w -I$(CBM_DIR) -c -o $@ $<
+$(NOSAN_DIR)/lz4hc.o: $(CBM_DIR)/vendored/lz4/lz4hc.c | $(NOSAN_DIR)
+ $(CC) -std=c11 -D_DEFAULT_SOURCE -g -O1 -w -I$(CBM_DIR)/vendored/lz4 -c -o $@ $<
+$(NOSAN_DIR)/zstd.o: $(CBM_DIR)/vendored/zstd/zstd.c | $(NOSAN_DIR)
+ $(CC) -std=c11 -D_DEFAULT_SOURCE -g -O1 -w -I$(CBM_DIR)/vendored/zstd -c -o $@ $<
+
# nomic-embed-code pretrained vector blob
UNIXCODER_OBJ = $(BUILD_DIR)/unixcoder_blob.o
$(UNIXCODER_OBJ): $(UNIXCODER_BLOB_SRC) vendored/nomic/code_vectors.bin | $(BUILD_DIR)
@@ -874,12 +1139,19 @@ OBJS_VENDORED_TEST = $(MIMALLOC_OBJ_TEST) $(SQLITE3_OBJ_TEST) $(TRE_OBJ_TEST) $(
OBJS_VENDORED_TSAN = $(MIMALLOC_OBJ_TSAN) $(SQLITE3_OBJ_TSAN) $(TRE_OBJ_TSAN) $(GRAMMAR_OBJS_TSAN) $(TS_RUNTIME_OBJ_TSAN) $(LSP_OBJ_TSAN) $(PP_OBJ_TSAN) $(LZ4_OBJ_TSAN) $(ZSTD_OBJ_TSAN) $(UNIXCODER_OBJ)
$(BUILD_DIR)/test-runner: $(ALL_TEST_SRCS) $(PROD_SRCS) $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) $(OBJS_VENDORED_TEST) $(PROJECT_HDRS) | $(BUILD_DIR)
- $(CC) $(CFLAGS_TEST) -Itests -Itests/repro -o $@ \
+ $(CC) $(CFLAGS_TEST) $(TEST_INCLUDE_FLAGS) -o $@ \
$(ALL_TEST_SRCS) $(PROD_SRCS) \
$(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) \
$(OBJS_VENDORED_TEST) \
$(LDFLAGS_TEST)
+$(BUILD_DIR)/test-runner-nosan: $(ALL_TEST_SRCS) $(PROD_SRCS) $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) $(OBJS_VENDORED_NOSAN) | $(BUILD_DIR) $(NOSAN_DIR)
+ $(CC) $(CFLAGS_NOSAN) $(TEST_INCLUDE_FLAGS) -o $@ \
+ $(ALL_TEST_SRCS) $(PROD_SRCS) \
+ $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) \
+ $(OBJS_VENDORED_NOSAN) \
+ $(LDFLAGS_NOSAN)
+
test: $(BUILD_DIR)/test-runner
cd $(CURDIR) && $(BUILD_DIR)/test-runner
@@ -897,6 +1169,47 @@ test-focused: $(BUILD_DIR)/test-runner
(echo "TEST_SUITES is required for test-focused"; exit 2)
cd $(CURDIR) && $(BUILD_DIR)/test-runner $(TEST_SUITES)
+# Cross-parent interaction canaries. Keep this target small: each row pairs a
+# classifier or policy from one side of the merge with the publication action
+# that consumes it, while the full suite remains the exhaustive gate.
+test-compositional: $(BUILD_DIR)/test-runner
+ cd $(CURDIR) && CBM_ONLY_SUITE=pipeline \
+ CBM_ONLY_TEST=incremental_frontier_full_fallback_failure_preserves_dirty_ledger \
+ $(BUILD_DIR)/test-runner
+ cd $(CURDIR) && CBM_ONLY_SUITE=input_validation \
+ CBM_ONLY_TEST=path_project_autoindex_honors_dep_limit_and_refreshes_rank \
+ $(BUILD_DIR)/test-runner
+ cd $(CURDIR) && CBM_ONLY_SUITE=daemon_application \
+ CBM_ONLY_TEST=daemon_application_auto_index_honors_tracked_file_limit \
+ $(BUILD_DIR)/test-runner
+ cd $(CURDIR) && CBM_ONLY_SUITE=pagerank \
+ CBM_ONLY_TEST=pagerank_refresh_defer_exact_delta_reindexes_does_not_defer_containment \
+ $(BUILD_DIR)/test-runner
+ cd $(CURDIR) && CBM_ONLY_SUITE=pagerank \
+ CBM_ONLY_TEST=pagerank_refresh_defer_all_incremental_reindexes_defers_full_fallback \
+ $(BUILD_DIR)/test-runner
+ cd $(CURDIR) && CBM_ONLY_SUITE=mcp \
+ CBM_ONLY_TEST=tool_query_graph_uses_active_relationship_query_with_ready_overlay \
+ $(BUILD_DIR)/test-runner
+ cd $(CURDIR) && CBM_ONLY_SUITE=mcp \
+ CBM_ONLY_TEST=watcher_publication_reopens_cached_store_generation \
+ $(BUILD_DIR)/test-runner
+# These two established stdio-notification oracles use POSIX pipe/alarm
+# fixtures and are not registered by tests/test_mcp.c on native Windows.
+ifneq ($(OS),Windows_NT)
+ cd $(CURDIR) && CBM_ONLY_SUITE=mcp \
+ CBM_ONLY_TEST=mcp_index_repository_inprocess_sends_list_changed \
+ $(BUILD_DIR)/test-runner
+ cd $(CURDIR) && CBM_ONLY_SUITE=mcp \
+ CBM_ONLY_TEST=mcp_autoindex_thread_sends_list_changed \
+ $(BUILD_DIR)/test-runner
+endif
+ cd $(CURDIR) && CBM_ONLY_SUITE=daemon_runtime \
+ CBM_ONLY_TEST=daemon_runtime_request_cancel_is_exact_and_session_remains_usable \
+ $(BUILD_DIR)/test-runner
+ cd $(CURDIR) && CBM_ONLY_SUITE=mcp \
+ CBM_ONLY_TEST=tool_index_repository_lock_wait_honors_request_cancel \
+ $(BUILD_DIR)/test-runner
# ── Cumulative bug-reproduction runner (RED board by design, non-gating) ──
# Mirrors test-runner's link line but uses repro_main.c (own main + counters)
# and TEST_REPRO_SRCS instead of ALL_TEST_SRCS. Exits non-zero while any bug is
@@ -921,6 +1234,14 @@ test-repro: $(BUILD_DIR)/test-repro-runner
cd $(CURDIR) && $(BUILD_DIR)/test-repro-runner
# ── TSan full test ───────────────────────────────────────────────
+#
+# ThreadSanitizer build for data-race detection in the parallel pipeline.
+# Mirrors test-runner but links vendored objects compiled with
+# -fsanitize=thread and links the test mimalloc object (MI_OVERRIDE=0 —
+# does NOT override malloc, so TSan intercepts the real malloc/free) to
+# satisfy the unconditional mi_* calls in src/foundation/mem.c.
+#
+# Cannot be combined with ASan/UBSan. Uses the system allocator.
# Every threaded production surface that runs clean AND stable under TSan:
# allocator concurrency (mem, slab_alloc), the parallel extraction worker pool
@@ -944,6 +1265,11 @@ test-repro: $(BUILD_DIR)/test-repro-runner
TEST_TSAN_SUITES ?= mem slab_alloc parallel worker_pool watcher httpd pipeline \
diagnostics mcp mcp_mutation_guard subprocess daemon daemon_application \
daemon_runtime daemon_ipc daemon_frontend
+# Keep the project suppression separate from the caller's ordinary TSan knobs.
+# Advanced runs can point this at a combined suppression file without replacing
+# halt/report/history settings supplied through TSAN_OPTIONS.
+TSAN_PROJECT_OPTIONS ?= suppressions=$(CURDIR)/tests/tsan.supp
+TSAN_WORKERS ?= 4
# halt_on_error: a race is a bug, stop at the first one.
#
# report_thread_leaks=0: this disables TSan's thread-HYGIENE check only —
@@ -962,17 +1288,128 @@ TSAN_OPTIONS ?= halt_on_error=1:report_thread_leaks=0
# invoke test-runner-tsan directly so release gates cannot drift accidentally.
$(BUILD_DIR)/test-runner-tsan: $(ALL_TEST_SRCS) $(PROD_SRCS) $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) $(OBJS_VENDORED_TSAN) $(PROJECT_HDRS) | $(BUILD_DIR)
- $(CC) $(CFLAGS_TSAN) -Itests -Itests/repro -o $@ \
+ $(CC) $(CFLAGS_TSAN) $(TEST_INCLUDE_FLAGS) -o $@ \
$(ALL_TEST_SRCS) $(PROD_SRCS) \
$(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) \
$(OBJS_VENDORED_TSAN) \
$(LDFLAGS_TSAN)
test-tsan: $(BUILD_DIR)/test-runner-tsan
- @echo "ThreadSanitizer workers: 4"
- cd $(CURDIR) && CBM_WORKERS=4 TSAN_OPTIONS="$(TSAN_OPTIONS)" \
+ @echo "Running ThreadSanitizer with $(TSAN_WORKERS) workers. Reports go to stderr."
+ cd $(CURDIR) && CBM_WORKERS=$(TSAN_WORKERS) \
+ TSAN_OPTIONS="$(TSAN_OPTIONS):$(TSAN_PROJECT_OPTIONS)" \
$(BUILD_DIR)/test-runner-tsan $(TEST_TSAN_SUITES)
+# ── Leak detection ───────────────────────────────────────────────
+# macOS: uses `leaks --atExit` (Apple Clang LSan not available on all versions)
+# Linux: ASAN_OPTIONS=detect_leaks=1 (GCC/Clang ASan always includes LSan)
+# Note: if false positives appear from system libraries on Linux, create lsan.supp
+# and set LSAN_OPTIONS=suppressions=lsan.supp
+LEAK_LOG = $(BUILD_DIR)/leak-report.txt
+
+# Stream a long-running gate through tee while preserving both failure sources.
+# Make recipes use /bin/sh by default, so Bash-only PIPESTATUS is not portable
+# (notably, Debian/Ubuntu /bin/sh is dash). The pipeline's left-hand subshell
+# records its status in a per-process sidecar; the parent shell then returns the
+# command failure first, or tee's failure when the command itself succeeded.
+define run_logged_command
+ @status_file="$(1).status.$$$$"; \
+ trap 'rm -f "$$status_file"' 0 1 2 3 15; \
+ { $(2); printf '%s\n' "$$?" > "$$status_file"; } 2>&1 | tee "$(1)"; \
+ tee_status=$$?; \
+ if test ! -s "$$status_file"; then \
+ echo "ERROR: logged command ended without recording its status" >&2; \
+ exit 1; \
+ fi; \
+ command_status=$$(sed -n '1p' "$$status_file"); \
+ if test "$$command_status" -ne 0; then exit "$$command_status"; fi; \
+ exit "$$tee_status"
+endef
+
+# Apple's leaks debugger stops descendant test binaries, so crash, socket-
+# inheritance, and UI child-process probes cannot run under `leaks --atExit`
+# without deadlocking or failing their parent. Cover the allocation-owning
+# stores, pipelines, rankers, and parallel workers explicitly instead. The test runner
+# also always includes httplink, token_reduction, depindex, pagerank,
+# tool_consolidation, and input_validation when suite arguments are present.
+TEST_LEAK_SUITES ?= arena hash_table dyn_array str_intern store_nodes store_edges \
+ store_search store_bulk store_pragmas store_checkpoint dump_verify_io \
+ graph_buffer registry pipeline worker_pool parallel slab_alloc mem \
+ integration incremental
+# Guard Malloc is inherited across exec on macOS. Keep its default gate on
+# allocation-owning, in-process surfaces: otherwise external helpers such as
+# git are instrumented too, and watcher tests observe libgmalloc/tool behavior
+# instead of the server's memory safety. CBM_ONLY_SUITE/CBM_ONLY_TEST still
+# allow an explicit narrower probe.
+TEST_GMALLOC_SUITES ?= $(TEST_LEAK_SUITES) lz4 zstd artifact sqlite_writer
+ifeq ($(UNAME_S),Darwin)
+# macOS: 'leaks' cannot inspect ASan-instrumented processes (ASan replaces malloc).
+# Use test-runner-nosan (no ASan/UBSan) so leaks can walk the heap.
+test-leak: $(BUILD_DIR)/test-runner-nosan
+ @echo "Running heap leak detection via 'leaks --atExit' on nosan build (macOS). May take 2-5 minutes."
+ @echo "Full report saved to $(LEAK_LOG). Exit 0 = no leaks."
+ $(call run_logged_command,$(LEAK_LOG),leaks --atExit -- $(BUILD_DIR)/test-runner-nosan $(TEST_LEAK_SUITES))
+else
+test-leak: $(BUILD_DIR)/test-runner
+ @echo "Running heap leak detection via ASan/LSan (Linux). Full report saved to $(LEAK_LOG). Exit 0 = no leaks."
+ $(call run_logged_command,$(LEAK_LOG),ASAN_OPTIONS=detect_leaks=1 $(BUILD_DIR)/test-runner)
+endif
+
+# ── Memory-corruption debug (macOS) ───────────────────────────────
+# Catches uninit reads, use-after-free, and overruns that ASan/TSan can miss
+# (used to investigate the B1 custom-writer non-deterministic corruption).
+# All run the NOSAN binary: ASan replaces malloc, which would defeat these
+# libmalloc knobs. Set CBM_ONLY_SUITE= to target a slow suite, and
+# optionally CBM_ONLY_TEST= to run matching tests after suite setup.
+MEM_LOG = $(BUILD_DIR)/mem-report.txt
+ifeq ($(UNAME_S),Darwin)
+# MallocScribble=1 → freed memory filled with 0x55 (catches use-after-free).
+# MallocPreScribble=1 → freshly-allocated memory filled with 0xAA (catches
+# uninitialized reads — the macOS MSan equivalent; makes uninit deterministic).
+test-memory: $(BUILD_DIR)/test-runner-nosan
+ @echo "Running under MallocScribble+MallocPreScribble (macOS nosan): uninit reads -> 0xAA, use-after-free -> 0x55."
+ @echo "Full report saved to $(MEM_LOG)."
+ $(call run_logged_command,$(MEM_LOG),MallocScribble=1 MallocPreScribble=1 $(BUILD_DIR)/test-runner-nosan)
+
+# Guard Malloc (libgmalloc): a guard page around EVERY allocation → crashes at
+# the exact overrun / use-after-free, with a stack trace. Stricter than scribble
+# (which only paints bytes); slower and noisier. The decisive memory tool.
+test-gmalloc: $(BUILD_DIR)/test-runner-nosan
+ @echo "Running allocation-owning suites under Guard Malloc (libgmalloc). Crashes at the exact overrun/UAF. Slow."
+ @echo "Full report saved to $(MEM_LOG)."
+ $(call run_logged_command,$(MEM_LOG),DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib $(BUILD_DIR)/test-runner-nosan $(TEST_GMALLOC_SUITES))
+else
+test-memory test-gmalloc: $(BUILD_DIR)/test-runner
+ @echo "These targets are macOS-only (MallocScribble/libgmalloc). On Linux use 'make test-leak' (ASan/LSan), or build with -fsanitize=memory (MSan) for uninit detection."
+endif
+
+# ── Static analysis (Clang analyzer only — GCC has no --analyze flag) ──────
+ifeq ($(IS_GCC),no)
+# Every test seam define is required, not optional: the test sources call the
+# *_for_testing APIs that those defines gate. Analyzing without one makes those
+# calls implicit declarations returning int, which reports false compile errors
+# and poisons the analyzer's type reasoning for the whole translation unit.
+ANALYZE_LOG = $(BUILD_DIR)/analyze-report.txt
+test-analyze: $(ALL_TEST_SRCS) $(PROD_SRCS) | $(BUILD_DIR)
+ @echo "Running Clang static analyzer..."
+ @$(CC) --analyze $(CFLAGS_COMMON) $(EDITOR_TEST_DEFINES) \
+ $(KOTLIN_DEDUP_TEST_DEFINE) $(CALL_REFERENCE_LOOKUP_TEST_DEFINE) \
+ $(INCREMENTAL_TEST_DEFINE) $(TEST_INCLUDE_FLAGS) \
+ $(ALL_TEST_SRCS) $(PROD_SRCS) $(EXTRACTION_SRCS) >"$(ANALYZE_LOG)" 2>&1; \
+ analyze_status=$$?; \
+ if grep -E "warning:|error:|note:" "$(ANALYZE_LOG)"; then \
+ :; \
+ elif [ $$analyze_status -eq 0 ]; then \
+ echo "No issues found."; \
+ else \
+ cat "$(ANALYZE_LOG)"; \
+ fi; \
+ exit $$analyze_status
+else
+test-analyze:
+ @echo "Static analysis skipped: requires Clang (not GCC). Install clang and re-run."
+endif
+
# Real-binary POSIX lifecycle smoke. The endpoint is deliberately account-wide;
# an explicit Make invocation requires a clean rendezvous and fails rather than
# silently skipping an occupied one. Deterministic C tests cover Windows IPC.
@@ -986,9 +1423,12 @@ GRAMMAR_OBJS_PROD = $(patsubst $(CBM_DIR)/%.c,$(BUILD_DIR)/prod_%.o,$(GRAMMAR_SR
TS_RUNTIME_OBJ_PROD = $(BUILD_DIR)/prod_ts_runtime.o
LSP_OBJ_PROD = $(BUILD_DIR)/prod_lsp_all.o
PP_OBJ_PROD = $(BUILD_DIR)/prod_preprocessor.o
+GRAMMAR_DEPFILES += $(addsuffix .d,$(GRAMMAR_OBJS_PROD))
-$(BUILD_DIR)/prod_%.o: $(CBM_DIR)/%.c | $(BUILD_DIR)
- $(CC) $(GRAMMAR_CFLAGS) -c -o $@ $<
+-include $(GRAMMAR_DEPFILES)
+
+$(GRAMMAR_OBJS_PROD): $(BUILD_DIR)/prod_%.o: $(CBM_DIR)/%.c $(GRAMMAR_DEP_STAMP) | $(BUILD_DIR)
+ $(CC) $(GRAMMAR_CFLAGS) -MMD -MP -MF $@.d -c -o $@ $<
$(BUILD_DIR)/prod_ts_runtime.o: $(TS_RUNTIME_DEPS) | $(BUILD_DIR)
$(CC) $(GRAMMAR_CFLAGS) -c -o $@ $<
@@ -1047,8 +1487,41 @@ $(BUILD_DIR)/codebase-memory-mcp: $(MAIN_SRC) $(PROD_SRCS) $(EXTRACTION_SRCS) $(
$(OBJS_VENDORED_PROD) \
$(LDFLAGS)
+# Extraction latency/scale probe linked under the release configuration. It
+# deliberately excludes test API defines and sanitizer flags, unlike
+# test-runner-nosan, so measurements represent the shipped hot path while
+# remaining independent of the account-wide daemon cohort.
+NATIVE_EXTRACTION_BENCH_SRCS = \
+ benchmarks/native_extraction_benchmark_main.c \
+ $(TEST_CS_LSP_BENCH_SRCS) \
+ $(TEST_PY_LSP_BENCH_SRCS) \
+ $(TEST_PY_LSP_SCALE_SRCS)
+
+$(BUILD_DIR)/native-extraction-benchmark: $(NATIVE_EXTRACTION_BENCH_SRCS) $(PROD_SRCS) $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) $(OBJS_VENDORED_PROD) $(BUILD_DIR)/.build-config $(PROJECT_HDRS) | $(BUILD_DIR)
+ $(CC) $(CFLAGS_PROD) $(TEST_INCLUDE_FLAGS) -o $@ \
+ $(NATIVE_EXTRACTION_BENCH_SRCS) $(PROD_SRCS) \
+ $(EXTRACTION_SRCS) $(AC_LZ4_SRCS) $(ZSTD_SRCS) $(SQLITE_WRITER_SRC) \
+ $(OBJS_VENDORED_PROD) \
+ $(LDFLAGS)
+ $(call codesign_binary,$@)
+
+native-extraction-benchmark: $(BUILD_DIR)/native-extraction-benchmark
+ @echo "Built: $(BUILD_DIR)/native-extraction-benchmark"
+
cbm: $(BUILD_DIR)/codebase-memory-mcp
@echo "Built: $(BUILD_DIR)/codebase-memory-mcp"
+ $(call codesign_binary,$(BUILD_DIR)/codebase-memory-mcp)
+
+# ── Install to INSTALL_DIR (default ~/.local/bin) ────────────────
+# Re-signs after copy — required on macOS 25+ where cp invalidates the
+# existing ad-hoc signature and an unsigned binary gets SIGKILL at startup.
+INSTALL_DIR ?= $(HOME)/.local/bin
+install: cbm
+ @echo "Installing to $(INSTALL_DIR)/codebase-memory-mcp ..."
+ install -d "$(INSTALL_DIR)"
+ install -m 755 "$(BUILD_DIR)/codebase-memory-mcp" "$(INSTALL_DIR)/codebase-memory-mcp"
+ $(call codesign_binary,$(INSTALL_DIR)/codebase-memory-mcp)
+ @echo "Done. Run: $(INSTALL_DIR)/codebase-memory-mcp"
# ── Build with embedded UI (requires Node.js) ───────────────────
@@ -1110,11 +1583,14 @@ lint-tidy:
lint-tidy-diff:
@scripts/lint-tidy-diff.sh "$(CLANG_TIDY)" $(LINT_SRCS) -- $(CFLAGS_COMMON) $(SYSROOT_FLAG)
-# cppcheck: complementary analysis (config in .cppcheck)
+# cppcheck: complementary analysis (config in .cppcheck). Analyze the
+# failpoint-enabled superset so test-only allocation and cleanup paths remain
+# checked instead of collapsing to production constant-false stubs.
lint-cppcheck:
@echo "=== cppcheck ==="
@$(CPPCHECK) --enable=warning,style,performance,portability \
--std=c11 --language=c \
+ -DCBM_ENABLE_TEST_SEAMS \
--suppressions-list=.cppcheck \
--error-exitcode=1 \
--inline-suppr \
@@ -1152,6 +1628,11 @@ lint-no-suppress:
fi
@echo " Checking NOLINT(misc-no-recursion) against whitelist..."
@scripts/check-nolint-whitelist.sh
+ @bash scripts/check-source-safety.sh
+
+lint-source-safety:
+ @bash scripts/check-source-safety.sh
+ @bash scripts/test-source-safety.sh
# All linters (run with make -j3 lint for parallel execution)
lint: lint-tidy lint-cppcheck lint-format lint-no-suppress
diff --git a/README.md b/README.md
index ca39ef418..b70f30c34 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[](https://github.com/DeusData/codebase-memory-mcp/releases/latest)
[](LICENSE)
[](https://github.com/DeusData/codebase-memory-mcp/actions/workflows/dry-run.yml)
-[](https://github.com/DeusData/codebase-memory-mcp)
+[](https://github.com/DeusData/codebase-memory-mcp)
[](https://github.com/DeusData/codebase-memory-mcp)
[](#hybrid-lsp)
[](https://github.com/DeusData/codebase-memory-mcp)
@@ -14,9 +14,9 @@
[](https://github.com/DeusData/codebase-memory-mcp/releases/latest)
[](https://arxiv.org/abs/2603.27277)
-**The fastest and most efficient code intelligence engine for AI coding agents.** Full-indexes an average repository in milliseconds, the Linux kernel (28M LOC, 75K files) in 3 minutes. Answers structural queries in under 1ms. Ships as a native executable with a small verified runtime-asset set for macOS, Linux, and Windows — download, run `install`, done.
+**The fastest and most efficient code intelligence engine for AI coding agents.** Full-indexes an average repository in milliseconds, the Linux kernel (28M LOC, 75K files) in 3 minutes. Answers structural queries in under 1ms. Ships as one self-contained native executable per platform — download, run `install`, done.
-High-quality parsing through [tree-sitter](https://tree-sitter.github.io/tree-sitter/) AST analysis across all 158 languages, enhanced with [**Hybrid LSP** semantic type resolution](#hybrid-lsp) for Python, TypeScript / JavaScript / JSX / TSX, PHP, C#, Go, C, C++, Java, Kotlin, Rust, and Perl — producing a persistent knowledge graph of functions, classes, call chains, HTTP routes, and cross-service links. 15 MCP tools. No language runtime, hosted service, or API key. Plug and play across 43 supported automatic/conditional client surfaces.
+High-quality parsing through [tree-sitter](https://tree-sitter.github.io/tree-sitter/) AST analysis across all 158 languages, enhanced with [**Hybrid LSP** semantic type resolution](#hybrid-lsp) for Python, TypeScript / JavaScript / JSX / TSX, PHP, C#, Go, C, C++, Java, Kotlin, Rust, and Perl — producing a persistent knowledge graph of functions, classes, call chains, HTTP routes, and cross-service links. MCP exposes a streamlined default tool set with all 16 tools available in classic mode. No hosted service or API key. Plug and play across 43 supported automatic/conditional client surfaces.
> **Research** — The design and benchmarks behind this project are described in the preprint [*Codebase-Memory: Tree-Sitter-Based Knowledge Graphs for LLM Code Exploration via MCP*](https://arxiv.org/abs/2603.27277) (arXiv:2603.27277). Evaluated across 31 real-world repositories: 83% answer quality, 10× fewer tokens, 2.1× fewer tool calls vs. file-by-file exploration.
@@ -31,13 +31,13 @@ High-quality parsing through [tree-sitter](https://tree-sitter.github.io/tree-si
## Why codebase-memory-mcp
- **Extreme indexing speed** — Linux kernel (28M LOC, 75K files) in 3 minutes. RAM-first pipeline: LZ4 compression, in-memory SQLite, fused Aho-Corasick pattern matching. Memory released after indexing.
-- **Plug and play** — native executable plus authenticated release-owned assets for macOS (arm64/amd64), Linux (arm64/amd64), and Windows (amd64). The native install needs no Docker, language runtime, or API keys. Download → `install` → restart agent → done.
+- **Plug and play** — one self-contained native executable for macOS (arm64/amd64), Linux (arm64/amd64), and Windows (amd64). The native install needs no Docker, language runtime, or API keys. Download → `install` → restart agent → done.
- **158 languages** — vendored tree-sitter grammars compiled into the binary. Nothing to install, nothing that breaks.
- **120x fewer tokens** — 5 structural queries: ~3,400 tokens vs ~412,000 via file-by-file search. One graph query replaces dozens of grep/read cycles.
- **43 supported automatic/conditional client surfaces** — `install` configures detected clients and safely activates conditional clients only when their documented platform, marker, or explicit existing config path is present. See [Multi-Agent Support](#multi-agent-support) for the complete matrix and manual/UI-only boundaries.
- **Built-in graph visualization** — 3D interactive UI at `localhost:9749`, served from the binary itself.
- **Infrastructure-as-code indexing** — Dockerfiles, Kubernetes manifests, and Kustomize overlays indexed as graph nodes with cross-references. `Resource` nodes for K8s kinds, `Module` nodes for Kustomize overlays with `IMPORTS` edges to referenced resources.
-- **15 MCP tools** — search, trace, architecture, impact analysis, targeted index-coverage checks, Cypher queries, dead code detection, cross-service HTTP linking, ADR management, and more.
+- **16 MCP tools** (classic mode; a streamlined subset is the default) — search, trace, architecture, impact analysis, Cypher queries, dead code detection, cross-service HTTP linking, ADR management, and more.
## Quick Start
@@ -46,11 +46,6 @@ High-quality parsing through [tree-sitter](https://tree-sitter.github.io/tree-si
curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash
```
-With graph visualization UI:
-```bash
-curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash
-```
-
**Windows** (PowerShell):
```powershell
# 1. Download the installer
@@ -69,7 +64,10 @@ Unblock-File .\install.ps1
> **Note:** If you see a script execution policy error, run `Set-ExecutionPolicy -Scope Process Bypass` first, or invoke with `PowerShell -ExecutionPolicy Bypass -File .\install.ps1`.
-Options: `--skip-config` (binary only, no agent setup), `--dir=` (custom location).
+Options: `--skip-config` (binary only), `--skip-binary` (agent setup only),
+`--force-binary` (copy even when a package manager owns the running binary), and
+`--dir=` (custom location). Use `--clients` to list client tokens or
+`--clients=claude,codex` to restrict agent setup. `--skip-binary` leaves PATH unchanged.
> **Antivirus note:** Microsoft Defender may flag a release binary as
> `Trojan:Script/Wacatac.B!ml`. This is a known false positive — typically 61 of
@@ -127,7 +125,7 @@ All active CBM processes must run the exact same version, executable build, coor
The native `install`, `update`, and `uninstall` commands are the deliberate exception to that conflict rule. Download, verification, and private same-filesystem staging happen first so a bad candidate never disrupts active work. Activation then publishes account-wide maintenance intent, asks the daemon and every temporary local operation to cancel, and waits to a finite deadline for all coordinated CBM processes to exit. It holds the admission and lifetime barriers exclusively while changing the active binary, configuration, PATH, or indexes. New CBM work cannot enter during this window. Activation progress and results are recorded in `${CBM_CACHE_DIR}/logs/activation-events.ndjson`, and a successful command tells you to restart open coding-agent sessions so they launch the activated build.
-Package-manager setup (npm, PyPI, or Go) verifies and publishes a coherent private cached runtime set. Sidecars are replaced before the executable with per-file atomic renames; an interrupted multi-file publication is detected and repaired on the next launch rather than being described as one crash-atomic filesystem transaction. It does not replace the active native installation and therefore does not stop running CBM sessions. When that cached binary is executed, it still enters the same exact-build admission barrier. The shell and PowerShell installers invoke the verified candidate's native `install` command, so they do receive the full account-wide activation guarantee.
+Package-manager setup (npm, PyPI, or Go) verifies and atomically publishes one self-contained executable into its private cache under an exclusive lease lock. It does not replace the active native installation and therefore does not stop running CBM sessions. When that cached binary is executed, it still enters the same exact-build admission barrier. The shell and PowerShell installers invoke the verified candidate's native `install` command, so they do receive the full account-wide activation guarantee.
The ordinary `cli` mode is intentionally separate: it runs one command locally and never starts or connects to the coordination daemon, registers a daemon session, or starts watchers/UI. Its only shared state is the OS admission barrier plus per-project locks for graph mutations. While the command is running, a temporary monitor lets activation cancel that operation and its supervised worker safely; the monitor exits with the command and never becomes a standing daemon. See [CLI Mode](#cli-mode) for details.
@@ -143,13 +141,13 @@ Open `http://localhost:9749` in your browser. The UI is owned by the shared coor
### Auto-Index
-Enable automatic indexing on MCP session start:
+Enable automatic indexing at MCP session startup or first graph-backed use:
```bash
codebase-memory-mcp config set auto_index true
```
-When enabled, new projects are indexed automatically on first connection. Previously-indexed projects are registered with the background watcher for ongoing git-based change detection. Configurable file limit: `config set auto_index_limit 50000`.
+When enabled, new projects are indexed automatically at startup or first graph-backed use. With `auto_watch=true`, indexed projects are registered with the background watcher for Git-based change detection; refreshes use the configured reindex policy. Configurable file limit: `config set auto_index_limit 50000`.
Watcher registration is controlled separately by `auto_watch` (default `true`). Set `config set auto_watch false` to keep a session from registering its project with the background watcher — useful when working across many projects and you want each session contained to explicit indexing.
@@ -231,23 +229,23 @@ The install script placed beside the binary is **reported, not deleted** — uni
- **RAM-first pipeline**: LZ4 compression, in-memory SQLite, single dump at end. Memory released after.
### Distribution & operation
-- **Native runtime set, zero infrastructure services**: SQLite-backed, persists to `~/.cache/codebase-memory-mcp/`
-- **Auto-sync**: Background watcher detects file changes and re-indexes automatically
+- **One self-contained native executable, zero infrastructure services**: SQLite-backed, persists to `~/.cache/codebase-memory-mcp/`
+- **Auto-sync**: Background watcher detects file changes and re-indexes automatically when configured
- **Route nodes**: REST endpoints are first-class graph entities
-- **CLI mode**: `codebase-memory-mcp cli search_graph '{"project": "my-project", "name_pattern": ".*Handler.*"}'`
+- **CLI mode**: `codebase-memory-mcp cli search_graph --project my-project --name-pattern '.*Handler.*'`
- **Available on**: npm, PyPI, Homebrew, Scoop, Winget, Chocolatey, AUR, `go install`
## Team-Shared Graph Artifact
Commit a single compressed file to your repo and your teammates skip the reindex.
-`.codebase-memory/graph.db.zst` is a zstd-compressed snapshot of the knowledge graph that lives next to your source. When you index, the artifact is written or refreshed; when a teammate clones the repo and runs `codebase-memory-mcp` for the first time, the artifact is decompressed and incremental indexing fills in their local diff.
+`.codebase-memory/graph.db.zst` is a zstd-compressed snapshot of the knowledge graph that lives next to your source. When you index with persistence enabled, the artifact is written or refreshed; when a teammate clones the repo and runs `codebase-memory-mcp` for the first time, the artifact can bootstrap their local graph before any configured refresh.
- **Format**: SQLite database, indexes stripped, `VACUUM INTO` compacted, then zstd 1.5.7 compressed (8–13:1 ratio typical)
- **Two tiers**:
- **Best** (`zstd -9` + index strip + `VACUUM INTO`) — written on explicit `index_repository`
- - **Fast** (`zstd -3`) — written by the watcher for low-latency incremental updates
-- **Bootstrap**: when no local DB exists but the artifact is present, `index_repository` imports the artifact first, then runs incremental indexing — avoiding the full reindex cost
+ - **Fast** (`zstd -3`) — written by the watcher when it refreshes an existing artifact
+- **Bootstrap**: when no local DB exists but the artifact is present, `index_repository` imports the artifact first, then applies the configured refresh policy
- **No merge pain**: a `.gitattributes` line with `merge=ours` is auto-created on first export, so concurrent edits don't produce conflicts on the binary artifact
- **Optional**: never committed unless you want it. Add `.codebase-memory/` to `.gitignore` if you prefer everyone to reindex from scratch.
@@ -273,6 +271,11 @@ Agent: presents the call chain in plain English
Benchmarked on Apple M3 Pro:
+Reproducible experiment runs use the fact-table contract in
+[Benchmark Experiments](docs/BENCHMARK_EXPERIMENTS.md) and the normative terms in
+[Benchmark Terminology](docs/BENCHMARK_TERMINOLOGY.md). The latter distinguishes
+lifecycle wall time from overlapping component work before any ratio is reported.
+
| Operation | Time | Notes |
|-----------|------|-------|
| **Linux kernel full index** | **3 min** | 28M LOC, 75K files → 4.81M nodes, 7.72M edges |
@@ -401,6 +404,19 @@ scripts/ci/smoke-artifact.sh
it accepts only an already-final `--selected-binary` plus its
`--expected-sha256`; it never builds, strips, signs, or relinks the executable.
+The standard and release pathways use the Makefile's optimized production defaults
+(`-O2`). For an inspectable local development binary, append debug flags through the
+same build entry point; the final override wins over the production optimization:
+
+```bash
+scripts/build.sh EXTRA_CFLAGS="-g -O0 -fno-omit-frame-pointer" \
+ EXTRA_CXXFLAGS="-g -O0 -fno-omit-frame-pointer"
+```
+
+Use `make -f Makefile.cbm test`, `test-tsan`, or `test-leak` for sanitizer and
+lifecycle validation; those targets already select their purpose-built compiler and
+allocator configurations.
+
### Manual MCP Configuration
@@ -419,33 +435,23 @@ Add to `~/.claude.json` (user scope) or project `.mcp.json`:
}
```
-Restart your agent. Verify with `/mcp` — you should see `codebase-memory-mcp` with 15 tools.
+Restart your agent. Verify with `/mcp` — you should see `codebase-memory-mcp` with
+its tools listed. The streamlined subset is the default; run
+`codebase-memory-mcp config set tool_mode classic` for all 16. Persisted
+configuration changes the live shared daemon, while a process environment
+override applies only when it is present in the daemon process that serves the
+session.
## Multi-Agent Support
-`install` configures 43 client surfaces: 37 detected automatically and 6
-conditional or explicit. “Conditional” means the installer writes only when the
+`install` configures 43 supported automatic/conditional client surfaces: 37 detected
+automatically and 6 conditional or explicit. “Conditional” means the installer writes only when the
documented platform or an explicit, already-existing config path proves the
target is active. It never flips experimental feature flags, enables plugins,
YOLO modes, global permission bypasses, or third-party instruction trust.
-Where a client has a documented custom-agent format, the installer creates three
-exact-owned definitions from one canonical contract:
-
-- **Scout (Tier 1)** — about 3–4 narrow calls for fast positive, provisional discovery; no absence, exhaustive-impact, or dead-code claims.
-- **Verify (Tier 2, default)** — task-directed graph evidence, exact source checks, path coverage for every cited file, and scope coverage before negative claims.
-- **Auditor (Tier 3)** — bounded scope, current index generation, complete relevant pagination, broader relationship checks, and explicit unresolved limitations.
-
-Every direct tier batches `check_index_coverage` for its evidence paths and reads
-flagged ranges or skipped/excluded files directly. A clean coverage result means
-only “no recorded gap,” never proof of completeness. Clients without safe child
-MCP access receive the same three tiers as parent-handoff agents; the parent must
-supply project, generation, pagination state, graph evidence, and coverage
-results. Updates migrate only byte-identical prior Verify definitions and never
-overwrite user-modified agents.
-
| Agent | Activation | MCP config | Durable context / augmentation |
|-------|------------|------------|--------------------------------|
| Claude Code | Detected | `~/.claude.json` | Skill + three exact-tool graph agents; `SessionStart`, `SubagentStart`, non-blocking `PreToolUse` for `Grep`/`Glob`, and post-`Read` coverage |
@@ -469,7 +475,7 @@ overwrite user-modified agents.
| Warp | Detected, skill only | UI, Warp Drive, or per invocation (manual) | Shared `~/.agents/skills/codebase-memory/SKILL.md` |
| Qwen Code | Detected | `.qwen/settings.json` | `QWEN.md`, skill, three explicit read/graph-tool agents; `SessionStart`, `SubagentStart`, and post-`ReadFile` coverage |
| GitHub Copilot CLI | Detected | `$COPILOT_HOME/mcp-config.json` | Instructions, skill, three read-only agents; `sessionStart` + `subagentStart` |
-| Factory Droid | Detected | `.factory/mcp.json` | `AGENTS.md`, skill, three droids with exact per-tier graph-tool lists (without additive whole-server exposure); `SessionStart` + post-`Read` coverage on macOS/Linux, withheld on Windows |
+| Factory Droid | Detected | `.factory/mcp.json` | `AGENTS.md`, skill, three droids with exact per-tier graph-tool lists; `SessionStart` + post-`Read` coverage on macOS/Linux, withheld on Windows |
| Crush | Detected | `.config/crush/crush.json` | Managed context path with explicit parent-to-child handoff |
| Goose | Detected | `.config/goose/config.yaml` | `.goosehints` |
| Mistral Vibe | Detected | `$VIBE_HOME/config.toml` | `AGENTS.md`, skill, and three matched agent/prompt pairs with explicit read-only graph-tool allowlists |
@@ -492,87 +498,20 @@ overwrite user-modified agents.
| IBM Bob IDE | Conditional | Existing `~/.bob/mcp.json` | Shared rule + IDE skill; no invented hook or agent |
| Sourcegraph Cody | Explicit opt-in | Existing `$CBM_CODY_CONFIG_PATH` | MCP only |
-### Sessions, compaction, and subagents
-
-Hooks installed by this project are fail-open and context-only. Claude Code's
-`PreToolUse` observes `Grep`/`Glob` and injects matching graph symbols as
-`additionalContext`; `PostToolUse` on `Read` adds targeted coverage context when
-the graph could not fully parse or index that file. It never denies or replaces
-the requested tool call.
-
-Claude Code, Codex CLI, Qwen Code, GitHub Copilot CLI, and VS Code's Copilot
-runtime receive paired session/subagent context where the vendor exposes a
-documented context-output contract. Codex users must review and trust installed
-hooks through `/hooks`; changing a hook definition changes its trust hash, so an
-update can require re-trust. Qoder uses `SessionStart`, `SubagentStart`, and
-post-`Read` coverage, including its documented PowerShell executor on Windows.
-Kimi uses `UserPromptSubmit`, while Hermes uses `pre_llm_call`; both retain their
-documented Windows execution paths. Devin installs
-`UserPromptSubmit` and `PostCompaction` on macOS/Linux and adds `SessionStart`
-only when Claude's equivalent managed hook is not present. GitLab Duo gets a
-narrowly scoped macOS/Linux user `SessionStart` entry on its experimental hook
-surface. GitLab Duo, Devin, and Factory hooks are withheld on Windows
-because those vendors do not document a deterministic shell/executor contract
-there. Gemini CLI, Factory Droid, and Augment also add documented post-read/view
-coverage context but expose no equivalent documented child-start context.
-
-For runtimes without a stable context-producing lifecycle event, durable files
-carry the contract across fresh sessions and compaction: verify the graph project
-and index freshness, query structural facts in the parent, then pass the project,
-qualified symbols, paths, and call-chain evidence in every delegated task.
-Claude, Codex, Gemini, Kiro, Qwen, Copilot, CodeBuddy, OpenCode, Kilo, Vibe,
-Qoder, Junie, and Factory receive Scout, Verify, and Auditor graph profiles.
-Kiro embeds this MCP server with `--tool-profile scout` for Scout and
-`--tool-profile analysis` for Verify/Auditor. Junie registers equivalent named
-server aliases because its subagent schema filters by server rather than by
-individual tool. Both process profiles use positive allowlists: Scout exposes
-seven fast inspection tools, Analysis exposes eleven, and future or mutating
-tools remain unavailable until explicitly reviewed. If either Junie alias
-collides with user configuration, the installer preserves it and installs
-parent-handoff profiles instead. Qoder combines its documented named-server
-selection with exact tier-specific MCP tool IDs. Factory uses exact registered
-MCP tool IDs without its additive `mcpServers` field, which would expose the
-whole server. Codex, Kilo, Vibe, and other capable formats likewise enumerate
-the narrowest supported tool set. Rovo, Cursor, Augment, Pochi, and Cline use parent handoff where direct
-child MCP is unavailable or unsafe; Pochi is limited to `readFile`, and Cline
-child agents cannot use MCP.
-
-Cline's file hooks auto-activate when present, and current Cline does not
-reliably consume their context output, so automatic adapters are withheld and
-older owned adapters are cleaned up. CodeBuddy's beta, version-gated hooks are
-not auto-installed. Junie's EAP
-`SessionStart` output is documented as ignored, so no context hook is installed.
-Junie custom agents remain EAP-dependent. Qoder can resolve higher-priority
-project or plugin agents before user agents with the same name; reload the
-client after installation or profile changes.
-Cursor context
-hooks are withheld: session context injection has a known race, `subagentStart`
-is control-only, and read-only subagents cannot safely receive MCP access. Rovo
-has no documented session context-output hook, and Bob
-documents neither a suitable hook nor a custom-agent surface. Those surfaces are
-not approximated with invented augmentation. Kimi plugins, Amp plugins, and
-GitLab experimental global skills remain opt-in.
-
-OpenClaw reinjects the `Codebase Knowledge Graph (codebase-memory-mcp)` AGENTS
-section after compaction and places the same guidance in `TOOLS.md`, the bootstrap
-files inherited by its subagents. Automatic augmentation covers the active/default
-workspace. Separate `agents.list[].workspace` directories require making that
-workspace active for installation or copying the managed block there.
-
-The installed Claude shim is named `cbm-code-discovery-gate` for backward
-compatibility; despite the legacy name, it never gates or blocks.
-
-### Manual or UI-managed integrations
-
-These are intentionally not counted as automatic installs: Qodo MCP is added
-through its UI and may be governed by enterprise allowlists; Warp MCP is managed
-through Warp Drive/UI or per invocation (only the shared skill is automatic);
-JetBrains AI Assistant / ACP is IDE-managed; GitHub Copilot coding agent, Jules,
-and CodeRabbit are cloud/repository-managed; Replit exposes a remote/service
-integration rather than a stable local user-global client; BLACKBOX AI does not
-document a stable arbitrary user-global MCP/instruction/agent schema; Plandex has
-no stable global registry safe to mutate; and SWE-agent uses explicit YAML and is
-no longer a suitable automatic global target.
+Claude Desktop is additionally supported as a detected MCP-only desktop
+surface through its platform `claude_desktop_config.json`; it is outside the
+43 coding-agent registry matrix above.
+
+**Hooks are structurally non-blocking** (exit code 0, every failure path).
+For Claude Code, the non-blocking `PreToolUse` augmenter observes `Grep`, `Glob`,
+and `Read`. It injects graph matches for searches and indexing-coverage notes for
+reads as `additionalContext`; it never denies the underlying tool call. For Codex,
+Gemini CLI, and Antigravity, a `SessionStart` hook
+injects a one-line code-discovery reminder as session context (Gemini CLI also
+keeps its `BeforeTool` reminder).
+The installed Claude shim file is named `cbm-code-discovery-gate` for
+backward compatibility with existing installs; despite the legacy name it
+never gates and never blocks.
## CLI Mode
@@ -606,7 +545,7 @@ JSON arguments can also be piped on stdin, for tools that take arguments. A tool
| Tool | Description |
|------|-------------|
-| `index_repository` | Index a repository into the graph. Auto-sync keeps it fresh after that. |
+| `index_repository` | Index a repository into the graph. Auto-sync can refresh it after that when configured. |
| `list_projects` | List all indexed projects with node/edge counts. |
| `delete_project` | Remove a project and all its graph data. |
| `index_status` | Check indexing status of a project. |
@@ -616,7 +555,7 @@ JSON arguments can also be piped on stdin, for tools that take arguments. A tool
| Tool | Description |
|------|-------------|
| `search_graph` | Structured search by label, name pattern, file pattern, degree filters. Pagination via limit/offset. |
-| `trace_path` | BFS traversal — who calls a function and what it calls (alias: `trace_call_path`). Depth 1-5. |
+| `trace_path` | BFS traversal — who calls a function and what it calls. Depth 1-5. |
| `detect_changes` | Map git diff to affected symbols + blast radius with risk classification. |
| `query_graph` | Execute Cypher-like graph queries (read-only). |
| `get_graph_schema` | Node/edge counts, relationship patterns, property definitions per label. Run this first. |
@@ -646,13 +585,13 @@ JSON arguments can also be piped on stdin, for tools that take arguments. A tool
`query_graph` is a read-only openCypher subset:
-- **Clauses**: `MATCH`, `OPTIONAL MATCH`, multiple `MATCH`, `WHERE`, `WITH` (+ `WITH … WHERE`), `RETURN`, `ORDER BY`, `SKIP`, `LIMIT`, `DISTINCT`, `UNWIND`, `UNION` / `UNION ALL`, `CASE`.
+- **Clauses**: `MATCH`, `OPTIONAL MATCH`, multiple `MATCH`, `WHERE`, `WITH` (+ `WITH … WHERE` and later match stages), `RETURN`, multi-key `ORDER BY` on projected fields or aliases, `SKIP`, `LIMIT`, `DISTINCT`, `UNWIND`, `UNION` / `UNION ALL`, `CASE`.
- **Patterns**: labelled nodes, label alternation `(n:A|B)`, relationship types/direction, variable-length paths `[*1..3]`, inline property maps.
- **WHERE**: `= <> < <= > >=`, `AND/OR/XOR/NOT`, `IN`, `CONTAINS`, `STARTS WITH`, `ENDS WITH`, `IS [NOT] NULL`, regex `=~`, label test `n:Label`, and `EXISTS { (n)-[:TYPE]->() }` (single-hop existence — great for dead-code, e.g. `WHERE NOT EXISTS { (f)<-[:CALLS]-() }`).
-- **Aggregates**: `count` (+`DISTINCT`), `sum`, `avg`, `min`, `max`, `collect`.
+- **Aggregates**: `count`, `sum`, `avg`, `min`, `max`, `collect` (all accept `DISTINCT` arguments).
- **Functions**: `labels`, `type`, `id`, `keys`, `properties`; `toLower/toUpper/toString/toInteger/toFloat/toBoolean`; `size`, `length`, `trim/ltrim/rtrim`, `reverse`; `coalesce`, `substring`, `replace`, `left`, `right`.
-Anything outside this subset (write/`MERGE`/`CALL` clauses, unsupported functions, list/map literals, comprehensions, path functions, parameters) **fails with a clear `unsupported …` error** rather than returning empty results.
+Anything outside this subset (write/`MERGE`/`CALL` clauses, unsupported functions, list/map literals, comprehensions, path functions, parameters) **fails with a clear `unsupported …` error** rather than returning empty results. Valid queries that match zero rows return a hint naming any label or relationship type not present in that project's graph, plus a short summary of the vocabulary that is.
## Ignoring Files
@@ -663,13 +602,34 @@ See [docs/cbmignore.md](docs/cbmignore.md) for the full `.cbmignore` how-to: syn
## Configuration
```bash
-codebase-memory-mcp config list # show all settings
-codebase-memory-mcp config set auto_index true # auto-index on session start
+codebase-memory-mcp config list # show common effective settings
+codebase-memory-mcp config describe pagerank_damping # show default, accepted extent, and tuning guidance
+codebase-memory-mcp config set auto_index true # auto-index on startup/first use
codebase-memory-mcp config set auto_index_limit 50000 # max files for auto-index
+codebase-memory-mcp config set tool_mode streamlined # concise surface; reveal advanced tools on demand
+codebase-memory-mcp config set auto_index_deps true # index installed dependency APIs
+codebase-memory-mcp config set auto_dep_limit 20 # import-ranked dependency package cap; 0=unlimited
+codebase-memory-mcp config set dep_max_files 1000 # per-package source-file cap; 0=unlimited
+codebase-memory-mcp config preset list # list named capability/API configurations
+codebase-memory-mcp config preset apply streamlined-automatic-dependency-source-indexing-disabled
+codebase-memory-mcp config preset apply streamlined-automatic-dependency-source-indexing-enabled
codebase-memory-mcp config set auto_watch false # don't register background git watcher (default: true)
+codebase-memory-mcp config set default_response_format json # full JSON objects instead of compact TOON tables
codebase-memory-mcp config reset auto_index # reset to default
```
+Normal streamlined exploration uses the core tools without a reveal; first-use
+indexing and first-response codebase context are automatic when configured. Use
+`_hidden_tools` only for explicit advanced operations such as `check_index_coverage`,
+`index_repository`, or `index_dependencies`. Classic mode advertises those tools
+directly and uses `search_graph`, then `trace_path`, then `get_code_snippet` for
+structural discovery. Automatic repository indexing obeys
+`auto_index`/`auto_index_limit`; automatic dependency indexing obeys
+`auto_index_deps`/`auto_dep_limit`/`dep_max_files` and is disabled by default.
+Packages above `dep_max_files` are skipped rather than partially indexed. Explicit
+`index_dependencies` calls remain available; disabling automation does not delete
+dependency projects that are already indexed.
+
### Environment Variables
| Variable | Default | Description |
@@ -677,7 +637,7 @@ codebase-memory-mcp config reset auto_index # reset to default
| `CBM_ALLOWED_ROOT` | *(unset)* | Confine `index_repository` to paths within this directory. When set, a `repo_path` that resolves (after symlink / `..` resolution) outside this root is refused, and the same check now applies to the graph UI's `POST /api/index` route rather than only to the MCP tool. Unset imposes no *containment* restriction — but see the always-on limits below, which apply whether or not this is set. Useful when the server may be driven by an untrusted caller, e.g. agentic or multi-tenant deployments. |
| `CBM_CACHE_DIR` | `~/.cache/codebase-memory-mcp` | Override the database storage directory. All project indexes and config are stored here. One account can use only one canonical cache root at a time; close active CBM sessions/commands before switching it. |
| `CBM_DIAGNOSTICS` | `false` | Set to `1` or `true` to enable the shared daemon's periodic `snapshot.json` and retained `trajectory.ndjson` below a fresh owner-private directory in the system temp directory. Exact paths are logged by `diagnostics.start`. |
-| `CBM_DOWNLOAD_URL` | *(GitHub releases)* | Override the download URL for updates. Used for testing or self-hosted deployments. |
+| `CBM_DOWNLOAD_URL` | *(GitHub releases)* | Override the install script's release-download base URL. Used for local fixtures or self-hosted deployments. |
| `CBM_LOG_LEVEL` | `info` | Set the minimum log level. Accepted values (case-insensitive): `debug`, `info`, `warn`, `error`, `none` — or their numeric equivalents `0`–`4` matching the internal enum. Thin-frontend messages go to that session's stderr; detached daemon events go to `${CBM_CACHE_DIR}/logs/cbm-daemon.log`. Stdout is reserved for MCP JSON-RPC. |
| `CBM_WORKERS` | *(detected)* | Override the parallel-indexing worker count returned by `cbm_default_worker_count`. Useful inside containers where `sysconf(_SC_NPROCESSORS_ONLN)` reports host CPUs rather than the cgroup's effective quota. Range 1–256; invalid values are ignored with a warning. |
| `CBM_MEM_BUDGET_MB` | *(detected)* | Override the in-memory graph budget with an explicit cap in MiB, taking precedence over the `ram_fraction × total_RAM` default. Useful on bare-metal hosts without a cgroup limit, or to pin a budget *below* the cgroup limit so headroom is left for sibling processes. Must be a positive integer; it is clamped to detected total RAM (logged as `mem.budget.clamped`), and non-numeric or non-positive values are ignored with a warning (`mem.budget.env.invalid`). |
@@ -777,7 +737,7 @@ Also supported (not yet benchmarked): Ada, Agda, Apex, Assembly (NASM), Astro, A
src/
main.c Entry point (MCP stdio server + CLI + install/update/config)
daemon/ Per-account session coordination, IPC, lifecycle, shared jobs/watchers
- mcp/ MCP server (15 tools, JSON-RPC 2.0, session detection, auto-index)
+ mcp/ MCP server (16 classic tools, JSON-RPC 2.0, session detection, auto-index)
cli/ Install/uninstall/update/config (43 client surfaces, hooks, instructions)
store/ SQLite graph storage (nodes, edges, traversal, search, Louvain)
pipeline/ Multi-pass indexing (structure → definitions → calls → HTTP links → config → tests)
@@ -785,7 +745,7 @@ src/
discover/ File discovery (.gitignore, .cbmignore, symlink handling)
watcher/ Background auto-sync (git polling, adaptive intervals)
traces/ Runtime trace ingestion
- ui/ Local HTTP server + verified external 3D-UI asset pack
+ ui/ Local HTTP server + embedded 3D-UI assets
foundation/ Platform abstractions (threads, filesystem, logging, memory)
internal/cbm/ Vendored tree-sitter grammars (158 languages) + AST extraction engine
```
@@ -799,7 +759,7 @@ Every release is verified through a multi-layer pipeline before publication:
- **Sigstore cosign** — keyless signatures on all artifacts; bundles included in every release
- **SHA-256 checksums** — `checksums.txt` published with every release; verified by both install scripts before extraction
- **CodeQL SAST** — blocks release pipeline if any open alerts remain
-- **No language-runtime dependency chain** — libraries are vendored at compile time; the small release-owned runtime assets are checksum-verified and content-addressed
+- **No language-runtime dependency chain** — libraries, integration templates, and UI assets are compiled into the executable
### v0.7.0 VirusTotal scans
diff --git a/SECURITY.md b/SECURITY.md
index 48da1d1a1..995642d04 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -4,7 +4,7 @@
codebase-memory-mcp interacts deeply with your filesystem. It reads source files across your entire codebase, writes to agent configuration files, and spawns background processes. This is inherent to what it does — not a bug.
-**If you are uncomfortable with these access patterns**, please audit the source code before running. The full source is available in this repository. Release archives produced by the current release pipeline are verifiably built from this source and can be independently verified via SLSA Build Level 3 provenance, Sigstore signatures, and SHA-256 checksums (see [Verification](#verification) below). Each archive contains a native executable and its authenticated release-owned runtime assets.
+**If you are uncomfortable with these access patterns**, please audit the source code before running. The full source is available in this repository. Release archives produced by the current release pipeline are verifiably built from this source and can be independently verified via SLSA Build Level 3 provenance, Sigstore signatures, and SHA-256 checksums (see [Verification](#verification) below). Each platform runtime is one self-contained native executable; the graph UI and integration templates are embedded.
We are humans and can make mistakes. We take security seriously — it is Priority #1 for this project — but we cannot guarantee perfection. By using this software you accept responsibility for evaluating whether it meets your own security requirements.
@@ -29,9 +29,11 @@ check is ignored. The request is also bounded with `curl --max-time 5`; a
process shutting down immediately while the check is still running may wait for
that bounded background thread to finish.
-Explicit install, package-manager, and `codebase-memory-mcp update` flows are
-separate user-initiated network operations that download release assets and
-checksums from GitHub.
+Explicit install and package-manager flows are separate user-initiated network
+operations that download release archives and checksums from GitHub.
+`codebase-memory-mcp update` performs no network or replacement work itself; it
+prints the platform installer command, and downloading begins only if the user
+runs that command.
## Help Us Stay Secure
@@ -154,7 +156,7 @@ tolerance and selection table are specified in [Our release policy](#our-release
### Verification
-Users can independently verify any release archive and the runtime set it contains:
+Users can independently verify any release archive and the executable it contains:
```bash
# SLSA Build Level 3 provenance for release archives
diff --git a/THIRD_PARTY.md b/THIRD_PARTY.md
index bbb3559fa..6647440e1 100644
--- a/THIRD_PARTY.md
+++ b/THIRD_PARTY.md
@@ -150,5 +150,5 @@ radix-ui, lucide-react, tailwindcss, and friends) are all under permissive
licenses (MIT / ISC / Apache-2.0 / Zlib); the exact set is recorded in
`graph-ui/package.json` and `graph-ui/package-lock.json`, and the per-package
license texts of the production bundle are appended to the
-`THIRD_PARTY_NOTICES.md` shipped inside the `-ui` release archives
+`THIRD_PARTY_NOTICES.md` shipped inside each release archive
(generated by `scripts/gen-ui-licenses.py`).
diff --git a/benchmarks/README.md b/benchmarks/README.md
new file mode 100644
index 000000000..32138c2c2
--- /dev/null
+++ b/benchmarks/README.md
@@ -0,0 +1,358 @@
+# Benchmark tooling
+
+This directory owns the benchmark implementations, active schemas, machine-readable
+terminology, configuration-spelling compatibility data, and source fixtures.
+
+Primary entry points:
+
+- `run_benchmark.py`: run one isolated benchmark and emit canonical fact tables.
+- `run_experiments.py`: build and execute immutable, resumable benchmark matrices.
+- `summarize_results.py`: render quality-gated Markdown from retained result JSON.
+- `fact_comparisons.py`: derive parity, capability-delta, and lifecycle tables from
+ canonical facts.
+- `run_evidence_suite.py`: emit one auditable receipt whose performance and rank commands
+ both use `run_experiments.py`; add `--container` plus one resource budget to switch both.
+- `autotune.py`: compatibility frontend for the fixed native PageRank profile sweep. It
+ evaluates profiles but does not select or publish a tuned configuration.
+
+Rank-quality campaign files (see "Rank-quality campaign" below):
+
+- `corpora-v1.json`: pinned real corpora and what each one is for.
+- `rank-queries-v1/manifest.json`: the query battery and its relevance judgments.
+- `config-keys-v1.json`: config keys the product actually reads (generated).
+- `generate_test_labels.py`: derives test/not-test labels from a corpus's own declaration.
+ The harness calls it at run time against the measured checkout; the output is data
+ derived from a corpus and is gitignored rather than stored.
+- `generate_config_keys.py`: regenerates the config-key allowlist, checked by CI.
+- `test_rank_quality.py`: tests for the campaign code. Runs in CI.
+
+Start with the built-in help:
+
+```sh
+uv run python benchmarks/run_benchmark.py --help
+uv run python benchmarks/run_experiments.py --help
+```
+
+`run_benchmark.py` is the single-run entry point. `run_experiments.py` is the
+multi-candidate, repeated-run entry point; automatic modes store durable ignored
+state under `.worktrees/benchmark-campaign/`. Explicit runs should use an ignored
+`benchmark-results/` root or another durable path outside the checkout.
+
+For a merge or hot-path change that needs an in-process extraction comparison,
+build each candidate's production-native runner and measure the executables in a
+rotated order:
+
+```sh
+make -f Makefile.cbm native-extraction-benchmark
+
+uv run python benchmarks/run_native_extraction_comparison.py \
+ --candidate merged=/absolute/path/to/merged/build/c/native-extraction-benchmark \
+ --candidate first-parent=/absolute/path/to/first-parent-runner \
+ --candidate second-parent=/absolute/path/to/second-parent-runner \
+ --warmups 2 --repetitions 21 \
+ --output-dir /durable/ignored/path/native-extraction-comparison
+```
+
+The runner profiles a repeated shared JSON parse fixture, fixed C# and Python
+fixtures, and a Python scale fixture. The shared fixture establishes an
+output-parity cohort for parser and extraction-orchestration work; the language
+fixtures retain capability differences instead of hiding them. A no-work startup
+cohort runs in the same rotated schedule. Its resource counters are subtracted from
+each candidate's matching workload repetition to report
+`incremental_max_rss_bytes`, `incremental_peak_footprint_bytes`,
+`incremental_instructions`, and `incremental_cycles` without charging the workload
+for different executable mappings and startup paths.
+
+The runner records output counts, extraction-phase latency, and host resource
+counters in `native-extraction-results.json`, with command output retained in
+`native-extraction-raw.txt`. The JSON includes every ordered candidate comparison,
+output-parity differences, and paired median percentage changes. Candidate order
+rotates for every repetition. Compare absolute latency only when output counts
+establish a parity cohort; otherwise report the result as a capability delta under
+`docs/BENCHMARK_TERMINOLOGY.md`. On macOS, peak memory footprint is the physical
+working-set signal, while maximum RSS also includes executable mappings. Linux
+records maximum RSS through `/usr/bin/time -v`.
+
+The automatic `--quick` and `--full` matrices default to MCP transport. Cross-build
+CLI matrices require a dedicated OS account/runtime or a quiescent account-wide CBM
+daemon: current one-shot CLI commands enforce the same exact-build cohort as MCP and
+correctly reject a candidate that differs from an active daemon. MCP matrices require
+an isolated account/runtime or one active daemon compatible with every candidate.
+The runner does not silently change transports. Neither entry point requires Docker.
+
+For example, this runs the full repeated matrix against the exact local `main` ref:
+
+```sh
+uv run python benchmarks/run_experiments.py --full --transport cli \
+ --candidate-ref upstream-main=main \
+ --experiment-root /durable/path/full-head-vs-main
+```
+
+Run that command only after verifying that its OS account has no active CBM daemon,
+or from a dedicated benchmark account. Merely changing `CBM_CACHE_DIR`, the Git
+worktree, or the experiment root does not create a separate daemon cohort.
+
+`upstream-main` is the stable candidate role used by the report schema. Overriding
+its ref does not rename the role, so cite the resolved ref and commit recorded in the
+expanded plan when describing results.
+
+For ongoing development, a compact `--matrix-spec` may use arbitrary candidate
+`{"label": "...", "ref": "branch-or-commit"}` entries. The runner resolves,
+production-builds, hashes, and archives those candidates before expanding the
+existing immutable plan schema. Profiles remain the reusable configuration axis:
+use `config_overrides` for product config keys, `product_environment` for explicit
+`CBM_*` process knobs such as `CBM_WORKERS`, and `benchmark_args` for additive
+workload flags. Candidate, profile, and scenario scopes can add new branches,
+capabilities, and controlled sweeps without editing the built-in dated presets.
+Top-level `build_environment` is shared across candidates and accepts only `CC`,
+`CXX`, `EXTRA_CFLAGS`, and `EXTRA_CXXFLAGS`; probes and builds retain those values
+in candidate identity, and arbitrary environment keys are rejected.
+New candidate worktrees default to `/.worktrees/benchmark-candidates`.
+Use one `--candidate-root` to select a different writable primary and repeat
+`--candidate-search-root` to reuse exact, clean, registered worktrees from moved
+locations. Search roots are checked in argument order and never receive new
+worktrees or harness metadata; a selected existing worktree may have its ordinary
+`build/` output refreshed to verify the requested toolchain identity.
+See [the complete matrix example](../docs/BENCHMARK_EXPERIMENTS.md#reusable-ref-based-matrices).
+
+For cross-build measurements while the host daemon remains active, select container
+execution on the same experiment CLI. It creates an exact Git bundle, runs the same
+experiment runner with no host bind mounts, and exports immutable results back to the
+named history:
+
+```sh
+uv run python benchmarks/run_experiments.py \
+ --matrix-spec /absolute/path/development-comparison.json \
+ --experiment-root /durable/ignored/path/development-comparison \
+ --container --cpus 4 --memory 8g --workers 4
+```
+
+CPU, memory, and worker budgets are required rather than guessed. Candidate builds
+use the complete declared CPU budget by default (`--cpus 16` runs `make -j16`);
+fractional CPU budgets round up to avoid leaving an available execution slot idle.
+Use `--build-jobs N` only when build-memory pressure requires a smaller positive
+override. The resolved value is part of the run identity and environment manifest.
+The repository-relative `.worktrees/benchmark-candidates` default, build outputs, caches,
+daemon state, and result generation remain on two labeled Docker volumes during measurement.
+The coordinator first archives the exact Git bundle under
+`EXPERIMENT_ROOT/source-bundles/`. After a successful verified export it removes the owned work
+scratch by default, while failures retain it for inspection and resume; pass
+`--work-volume-retention always` to retain successful work too. The results volume remains
+available until its host export is audited and the exact printed volume is removed. The measured
+container is always native `arm64` or `amd64`, resource bounded, and removed on success or failure.
+Each invocation writes a content-addressed container-environment manifest, so changed
+arguments create a new audit record instead of replacing history. Failed candidate
+build logs are exported under `container-failures//build-logs/`; if
+that export itself fails, the error identifies the retained work volume and path.
+Each measured source/spec/resource cohort is isolated under
+`runsets//`; `--audit-only` resolves to the same cohort and cannot create
+a second attempt. Canonical Git ref/commit content identifies the repository
+snapshot even when equivalent bundle pack bytes differ; the exact bundle SHA-256
+remains in the manifest. The run key also hashes the selected image's runtime
+configuration and root-filesystem layers while ignoring BuildKit's nondeterministic
+attestation index. A different snapshot, runtime image, spec, or resource budget cannot
+be misreported as an unplanned cell in the current runset.
+Container numbers are controlled Linux relative comparisons, not absolute macOS
+latency. See [Container isolation](../docs/BENCHMARK_EXPERIMENTS.md#container-isolation).
+Docker benchmarks default to Clang 18.1.3. The pinned image also provides GCC for
+explicit portability or compiler-ablation cohorts; override both `CC` and `CXX`
+together in `build_environment`. Run Clang and GCC as distinct named histories
+with otherwise identical specs, and never infer cross-cohort comparability from a
+shared OS image alone. Native execution retains its existing configurable compiler
+selection.
+
+To run the fixed nine-cell synthetic rank diagnostic through that same isolated
+container path, generate its matrix from the canonical hypothesis registry and pass the
+result to the coordinator:
+
+```sh
+uv run python benchmarks/campaign_specs.py \
+ --quick-hypotheses \
+ --out-dir /durable/ignored/path/rank-hypotheses-spec
+
+uv run python benchmarks/run_experiments.py \
+ --matrix-spec /durable/ignored/path/rank-hypotheses-spec/rank-hypotheses-quick-v2.json \
+ --experiment-root /durable/ignored/path/rank-hypotheses \
+ --container --cpus 4 --memory 6g --workers 4
+```
+
+The generated matrix contains exactly nine profiles, one MCP repetition, no real-corpus
+dependency, and no suite-duration target. Its per-cell timeout is a subprocess safety
+boundary recorded in the matrix, not an expected duration or suite cutoff.
+
+The generated Markdown report leads with data-derived recommendations, recorded configuration
+and overrides, measurement counts, end-to-end attempt time, scorer/mechanism coverage, workflow,
+evidence scope, and parameter provenance before the complete detailed tables. The Markdown is a
+decision view; the hashed derived inputs, raw `result.json`/`attempt.json` receipts, and
+fact-comparison JSON are the audit authority. A mechanism absent from the coverage table was not
+measured by that run and must not be interpreted as a zero or a losing result.
+
+`schema/` contains schemas for records emitted by current tooling.
+`terminology.json` defines every normative fact, step, join, and formula identifier.
+The generated human view remains in `docs/BENCHMARK_TERMINOLOGY.md`, and the full
+workflow is documented in `docs/BENCHMARK_EXPERIMENTS.md`.
+
+The upstream-owned `scripts/benchmark-index.sh`, `scripts/benchmark-search-graph.sh`,
+and `scripts/clone-bench-repos.sh` retain their established locations. Branch-created
+Python benchmark implementations live here without executable compatibility copies.
+`docs/schema/benchmark-facts-v1.schema.json` retains its frozen URI because v1 bundles
+embed that identifier.
+
+---
+
+# Rank-quality campaign
+
+Measures **which persisted score should order search results**, on real corpora, against
+the baseline the upstream maintainer proposed instead of PageRank.
+
+## What question this answers
+
+PageRank has been rejected upstream twice (PR #147, PR #151) with a specific, testable
+objection: *"PageRank on a call graph would rank `log.Error()` and `fmt.Sprintf()` as the
+most important functions in any codebase… just utility popularity. We already have
+`min_degree`/`max_degree`… the same ranking signal without the conceptual mismatch or the
+computation cost."*
+
+So `ORDER BY degree DESC` is the **required baseline arm**, not "ranking off", and the
+campaign is built to be able to conclude that the maintainer was right.
+
+## Run it
+
+Nothing below clones or writes outside the cache unless you ask it to.
+
+```sh
+# 1. One corpus, one cell. Resolves the pin, materializes it, runs the battery.
+uv run python benchmarks/run_benchmark.py \
+ --capability-quality rank \
+ --corpus cosign \
+ --rank-query-manifest benchmarks/rank-queries-v1/manifest.json \
+ --clone-missing-real-repos \
+ --out results/cosign.json
+
+# 2. Already have a checkout? Point at it and skip the network entirely.
+uv run python benchmarks/run_benchmark.py \
+ --capability-quality rank --corpus cosign \
+ --corpus-repo cosign=/path/to/cosign \
+ --rank-query-manifest benchmarks/rank-queries-v1/manifest.json \
+ --out results/cosign.json
+
+# 3. Render the report, including the ranking score comparison table.
+uv run python benchmarks/summarize_results.py \
+ --input cosign=results/cosign.json --out results/report.md
+```
+
+A corpus is resolved in this order, and **nothing is ever cloned implicitly**:
+
+1. `--corpus-repo =`
+2. `CBM_BENCH_CORPUS_` environment variable
+3. `~/.cache/codebase-memory-mcp/bench-repos/`
+4. clone the pinned commit — only with `--clone-missing-real-repos`
+
+If none apply, the error names every path searched, so a typo cannot look like a network
+problem.
+
+**Defaults are inert.** Without `--corpus` and `--rank-query-manifest`, a rank run issues
+the single built-in query exactly as before, so previously cached cells stay valid.
+
+**A real corpus is indexed alone.** The synthetic `zz_order_core` fixture is *not* written
+into a materialized corpus tree, because no real corpus battery queries those symbols — it
+would dilute every corpus-scoped score without acting as a control. `--rank-fixture-overlay`
+plants it deliberately as a positive control and appends its canary query so the control
+actually runs. Either way `cases[0].fixture.corpus_overlay` records which happened.
+
+## Run the whole campaign in Docker
+
+The host daemon enforces an exact-build cohort, so a candidate that differs from an active
+daemon is correctly rejected. The `--container` execution path sidesteps that without
+weakening it: no host bind mounts, an exact Git bundle, and pinned corpora carried in.
+
+```sh
+# 1. Generate the four arms. --corpora runs a pilot first; drop it for the sweep.
+uv run python benchmarks/campaign_specs.py \
+ --out-dir /durable/ignored/path/campaign-specs --corpora flask
+
+# 2. One arm per invocation. Corpora named in the spec are staged automatically.
+uv run python benchmarks/run_experiments.py \
+ --matrix-spec /durable/ignored/path/campaign-specs/rank-quality-v1.json \
+ --experiment-root /durable/ignored/path/campaign \
+ --container --cpus 6 --memory 6g --workers 4 \
+ --clone-missing-real-repos
+
+# 3. Roll every arm up into one verdict document.
+uv run python benchmarks/rank_report.py \
+ --experiment-root /durable/ignored/path/campaign \
+ --out /durable/ignored/path/campaign/rollup.md \
+ --json /durable/ignored/path/campaign/rollup.json
+```
+
+Each corpus is resolved and **pin-verified on the host** — where the failure is cheap and
+visible — then copied into the retained work volume at a revision-keyed path and exposed
+to the container as `CBM_BENCH_CORPUS_`. That is rung 2 of the ladder above, so the
+container needs no new flag, no network, and no second resolver. The staged pins are part
+of the container run key: re-pinning a corpus starts a new runset instead of resuming into
+cells measured against a different tree.
+
+`campaign_specs.py` emits four arms from one definition:
+
+| Arm | `index_mode` | What it answers |
+|---|---|---|
+| `rank-quality-v1` | `full` | H1/H2/H4/H5 node-ranking evidence and H6 instrumentation. It explicitly does not evaluate H3 cost or H7 held-out adaptation. Full indexing keeps `FAST_SKIP_DIRS` out of the ordering comparison. Includes the cosign reply-detail frontier |
+| `coverage-full-v1` | `full` | the reference arm for the silent-drop diff |
+| `coverage-moderate-v1` | `moderate` | coverage lost outside full mode |
+| `coverage-fast-v1` | `fast` | the mode 151 of upstream's 159 evaluation corpora use |
+
+The three coverage arms are byte-identical apart from `index_mode` — a test asserts it,
+because any other difference would be measured as coverage loss.
+
+## Read the results
+
+| Column / field | Means | Watch for |
+|---|---|---|
+| `Utility contamination` | fraction of the top-K that is a logging/allocation utility, matched on identifier tokens | **High for `degree` and low for `pagerank` contradicts the PR #151 objection.** The reverse confirms it |
+| `Scaffolding` | fraction of the top-K that is test scaffolding, derived from the corpus's own test declaration | `null` means no independent labels were supplied — it is never inferred from this server's own predicates |
+| `ρ vs degree`, `Jaccard` | agreement between a score and the degree baseline | **High values support the maintainer's "same ranking signal" claim.** Report them either way |
+| `Rank views fresh` | whether `pagerank`/`linkrank`/`node_degree` were current | **`False` invalidates the ranking numbers in that row** — `search_graph` silently falls back to a degree sort when these are stale |
+| `Status` = `N/A` | that score is absent from this database | Expected for `importance` on any binary without PR #879's pass |
+| `zero_result_behavior` | zero-result rate across the battery | `search_code` was 8% of recovered real calls but ~70% of zero-result failures |
+| `repetition_stability` | result counts across repeats of one query | `stable: false` means the same call against a fixed index returned different counts |
+
+**Polarity warning.** On `jest` the product *is* test infrastructure, so a **low**
+scaffolding score is a defect, not a win. The sign is reported per corpus.
+
+## Adjust or extend it
+
+**Add a corpus** — append to `corpora-v1.json` with a 40-char `revision` **and** `tree`
+(both are verified), `stars >= 1000`, and which hypothesis it discriminates. Then add a
+matching entry to `rank-queries-v1/manifest.json`: the two must agree, and
+`manifest_corpus_disagreements()` fails the campaign if they drift.
+
+**Add a query** — add it under a corpus in `rank-queries-v1/manifest.json`. Include
+`judgments` to have it scored (`expected_substring`, optional `required_substrings`,
+`relevance`), or omit them for a behavioral-only probe that measures result counts and
+latency without claiming relevance. Set `repetitions` above 1 to measure count stability.
+Author graded targets **grep-first** — find them by reading source, never through the
+graph — per `docs/EVALUATION_PLAN.md` [CR-1]; record the evidence in `grep_first_evidence`.
+
+**Add a scorer** — add SQL to `RANK_PROBE_SQL` in `run_benchmark.py` returning
+`(qualified_name, file_path, score)`.
+
+**Inspect labels** for a corpus — the harness derives these automatically, so this is
+only for checking what a corpus declares:
+
+```sh
+uv run python benchmarks/generate_test_labels.py --corpus cosign
+uv run python benchmarks/generate_config_keys.py # after any config change
+```
+
+**Tune weights** — pass `--config edge_weight_tests=0.01`. Unknown keys are rejected at
+parse time against `config-keys-v1.json`, because the product itself accepts any key and
+would otherwise report a difference of exactly zero for a typo.
+
+## Test it
+
+```sh
+uv run python benchmarks/test_rank_quality.py
+```
+
+25 tests, stdlib only, no binary or network. Runs in CI. Every test names the defect it
+guards; most exist because that defect shipped and was found by audit rather than by a test.
diff --git a/benchmarks/autotune.py b/benchmarks/autotune.py
new file mode 100755
index 000000000..5f7331785
--- /dev/null
+++ b/benchmarks/autotune.py
@@ -0,0 +1,301 @@
+#!/usr/bin/env python3
+"""Create or run an auditable PageRank tuning experiment.
+
+This compatibility frontend uses the repository's versioned rank-quality fixture
+and content-addressed experiment runner. It never changes the user's normal CBM
+configuration or cache, and it retains every result under an ignored durable
+experiment root rather than an operating-system temporary directory.
+"""
+
+from __future__ import annotations
+
+import argparse
+import copy
+import importlib.util
+import json
+import subprocess
+import sys
+from pathlib import Path
+from types import ModuleType
+from typing import Any
+
+ROOT = Path(__file__).resolve().parents[1]
+BENCHMARK = ROOT / "benchmarks" / "run_benchmark.py"
+EXPERIMENT_RUNNER = ROOT / "benchmarks" / "run_experiments.py"
+DEFAULT_EXPERIMENT_ROOT = ROOT / ".worktrees" / "benchmark-experiments" / "autotune"
+
+try: # Package import under tests; script-local import for direct execution.
+ from benchmarks import rank_hypotheses as rank_evidence
+except ModuleNotFoundError: # pragma: no cover - direct script execution
+ import rank_hypotheses as rank_evidence
+
+
+def tuning_profiles() -> tuple[dict[str, Any], ...]:
+ """Return the DRY hypothesis profiles while retaining the v1 baseline label."""
+ profiles = rank_evidence.quick_hypothesis_profiles()
+ profiles[0]["label"] = "candidate-default"
+ profiles[0]["cell_name"] = "RANK-CELL-01 — candidate default"
+ return tuple(profiles)
+
+
+# Compatibility export used by existing callers/tests. Values come from the canonical
+# product declarations read by rank_hypotheses.py, not duplicated literals here.
+TUNING_PROFILES = tuning_profiles()
+
+
+def load_experiment_runner(path: Path = EXPERIMENT_RUNNER) -> ModuleType:
+ spec = importlib.util.spec_from_file_location("cbm_benchmark_experiment", path)
+ if not spec or not spec.loader:
+ raise RuntimeError(f"cannot load experiment runner: {path}")
+ module = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(module)
+ return module
+
+
+def git_revision(repo: Path) -> str:
+ proc = subprocess.run(
+ ["git", "rev-parse", "HEAD"],
+ cwd=repo,
+ text=True,
+ capture_output=True,
+ check=False,
+ )
+ revision = proc.stdout.strip()
+ if proc.returncode != 0 or len(revision) != 40:
+ raise ValueError(
+ f"cannot resolve a full Git revision for {repo}: {proc.stderr.strip()}"
+ )
+ return revision
+
+
+def build_matrix_spec(
+ *,
+ binary: Path,
+ revision: str,
+ repetitions: int,
+ timeout_seconds: int,
+ transports: list[str],
+ build: dict[str, str],
+ profiles: tuple[dict[str, Any], ...] | list[dict[str, Any]] | None = None,
+) -> dict[str, Any]:
+ if not binary.is_file():
+ raise ValueError(f"binary does not exist: {binary}")
+ if len(revision) != 40:
+ raise ValueError("revision must be a full 40-character commit hash")
+ if repetitions <= 0 or timeout_seconds <= 0:
+ raise ValueError("repetitions and timeout_seconds must be positive")
+ if not transports or not set(transports).issubset({"cli", "mcp"}):
+ raise ValueError("transports must contain cli, mcp, or both")
+ for key in ("target", "compiler", "cflags"):
+ if not build.get(key):
+ raise ValueError(f"build metadata requires non-empty {key}")
+
+ runner = load_experiment_runner()
+ selected_profiles = list(profiles or TUNING_PROFILES)
+ if not selected_profiles:
+ raise ValueError("profiles must be non-empty")
+ return {
+ "schema_version": 1,
+ "harness_version": f"run_benchmark.py:{runner.file_sha256(BENCHMARK)}",
+ "benchmark_script": str(BENCHMARK),
+ "capability_quality": "rank",
+ "index_mode": "full",
+ "cwd": str(ROOT),
+ "timeout_seconds": timeout_seconds,
+ "cell_timeout_seconds": timeout_seconds * 4,
+ "accepted_exit_codes": [0, 1],
+ "execution_order": "paired_interleaved",
+ "repetitions": repetitions,
+ "transports": transports,
+ "candidates": [
+ {
+ "label": "candidate",
+ "revision": revision,
+ "binary": str(binary.resolve()),
+ "build": dict(sorted(build.items())),
+ "capability_support": {"rank": True},
+ }
+ ],
+ "profiles": [dict(profile) for profile in selected_profiles],
+ "suite_name": rank_evidence.RANK_SUITE_NAME,
+ "evidence_contract": rank_evidence.public_hypothesis_registry(),
+ }
+
+
+def write_spec_and_plan(
+ runner: ModuleType,
+ experiment_root: Path,
+ spec: dict[str, Any],
+ *,
+ stem: str,
+) -> tuple[Path, Path, dict[str, Any]]:
+ plan = runner.expand_matrix_spec(spec)
+ spec_path = experiment_root / f"{stem}-matrix-spec.json"
+ plan_path = experiment_root / f"{stem}-plan.json"
+ runner.atomic_write_json(spec_path, spec)
+ runner.atomic_write_json(plan_path, plan)
+ return spec_path, plan_path, plan
+
+
+def build_preflight_spec(spec: dict[str, Any]) -> dict[str, Any]:
+ """Reuse the first real cell as a fail-fast candidate/protocol preflight.
+
+ This does not add an experiment or alter cell identity. A successful cell is
+ content-addressed and reused when the complete plan runs; a failed cell prevents the
+ remaining profiles from repeating the same environment or protocol failure.
+ """
+ profiles = spec.get("profiles")
+ if not isinstance(profiles, list) or not profiles:
+ raise ValueError("autotune preflight requires at least one profile")
+ preflight = copy.deepcopy(spec)
+ preflight["profiles"] = preflight["profiles"][:1]
+ return preflight
+
+
+def run_plan(plan_path: Path, experiment_root: Path) -> int:
+ process = subprocess.run(
+ [
+ sys.executable,
+ str(EXPERIMENT_RUNNER),
+ "--plan",
+ str(plan_path),
+ "--experiment-root",
+ str(experiment_root),
+ ],
+ cwd=ROOT,
+ check=False,
+ )
+ return process.returncode
+
+
+def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "--binary", type=Path, default=ROOT / "build" / "c" / "codebase-memory-mcp"
+ )
+ parser.add_argument(
+ "--revision",
+ default="",
+ help="Full candidate commit; defaults to repository HEAD.",
+ )
+ parser.add_argument(
+ "--experiment-root",
+ "--campaign-root",
+ dest="experiment_root",
+ type=Path,
+ default=DEFAULT_EXPERIMENT_ROOT,
+ help="Durable result root (--campaign-root is a legacy alias).",
+ )
+ parser.add_argument("--repetitions", type=int)
+ parser.add_argument("--timeout", type=int, default=1200)
+ parser.add_argument("--transport", choices=("cli", "mcp", "both"))
+ parser.add_argument(
+ "--build-target",
+ required=True,
+ help="Exact build command/target used for the measured binary.",
+ )
+ parser.add_argument(
+ "--compiler", required=True, help="Exact compiler identity/version."
+ )
+ parser.add_argument(
+ "--cflags", required=True, help="Exact optimization/profiling flags."
+ )
+ parser.add_argument(
+ "--plan-only",
+ action="store_true",
+ help="Write and validate the plan without running cells.",
+ )
+ parser.add_argument(
+ "--profile",
+ action="append",
+ default=[],
+ help="Run only this named profile; repeat in desired priority order.",
+ )
+ parser.add_argument(
+ "--quick",
+ action="store_true",
+ help=(
+ "Run each fixed rank-evidence profile once over MCP. Actual duration is "
+ "recorded; the suite has no wall-clock target or cutoff."
+ ),
+ )
+ return parser.parse_args(argv)
+
+
+def main(argv: list[str] | None = None) -> int:
+ args = parse_args(argv)
+ binary = args.binary.expanduser().resolve()
+ revision = args.revision or git_revision(ROOT)
+ transport = args.transport or ("mcp" if args.quick else "both")
+ repetitions = args.repetitions or (1 if args.quick else 3)
+ transports = ["cli", "mcp"] if transport == "both" else [transport]
+ build = {
+ "target": args.build_target,
+ "compiler": args.compiler,
+ "cflags": args.cflags,
+ }
+ profiles_by_label = {profile["label"]: profile for profile in TUNING_PROFILES}
+ unknown = [label for label in args.profile if label not in profiles_by_label]
+ if unknown:
+ raise ValueError(
+ f"unknown profile(s) {unknown}; available: {', '.join(profiles_by_label)}"
+ )
+ requested_profiles = (
+ tuple(profiles_by_label[label] for label in args.profile) or TUNING_PROFILES
+ )
+ runner = load_experiment_runner()
+ experiment_root = args.experiment_root.expanduser().resolve()
+ runner.validate_experiment_root(experiment_root)
+ experiment_root.mkdir(parents=True, exist_ok=True)
+
+ spec = build_matrix_spec(
+ binary=binary,
+ revision=revision,
+ repetitions=repetitions,
+ timeout_seconds=args.timeout,
+ transports=transports,
+ build=build,
+ profiles=requested_profiles,
+ )
+ spec_path, plan_path, _plan = write_spec_and_plan(
+ runner, experiment_root, spec, stem="autotune"
+ )
+ if args.plan_only:
+ print(
+ json.dumps(
+ {"matrix_spec": str(spec_path), "plan": str(plan_path)}, indent=2
+ )
+ )
+ return 0
+
+ if args.quick:
+ preflight_spec = build_preflight_spec(spec)
+ _, preflight_plan_path, _ = write_spec_and_plan(
+ runner, experiment_root, preflight_spec, stem="autotune-preflight"
+ )
+ preflight_status = run_plan(preflight_plan_path, experiment_root)
+ if preflight_status != 0:
+ print(
+ json.dumps(
+ {
+ "status": "preflight_failed",
+ "remaining_cells_started": False,
+ "plan": str(preflight_plan_path),
+ "guidance": (
+ "Inspect the preserved attempt error. If it reports an "
+ "exact-build or cache-cohort conflict, close active CBM "
+ "sessions and rerun from a standalone terminal, or execute "
+ "the campaign in its isolated container environment."
+ ),
+ },
+ indent=2,
+ ),
+ file=sys.stderr,
+ )
+ return preflight_status
+
+ return run_plan(plan_path, experiment_root)
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/benchmarks/campaign_specs.py b/benchmarks/campaign_specs.py
new file mode 100644
index 000000000..8d946f1b1
--- /dev/null
+++ b/benchmarks/campaign_specs.py
@@ -0,0 +1,534 @@
+#!/usr/bin/env python3
+"""Generate the rank-quality campaign's matrix specs from one definition.
+
+Why generated rather than checked in
+------------------------------------
+`index_mode` is a spec-level field (`run_experiments.py:1301`), so one spec observes one
+index mode and the silent-drop comparison needs three otherwise-identical specs. Three
+hand-maintained near-copies drift, and a drifted arm confounds coverage loss with
+whatever else changed. One definition emitting three specs cannot drift, and
+`test_coverage_specs_differ_only_in_index_mode` proves it each run.
+
+The generated bytes are measured input: `run_container_experiment.py` hashes the spec
+into the container run key, so generation has to be deterministic. It is a pure function
+of `corpora-v1.json` and this file's constants.
+
+Usage:
+ python3 benchmarks/campaign_specs.py --out-dir /durable/path/campaign-specs
+ python3 benchmarks/campaign_specs.py --print rank-quality
+ python3 benchmarks/campaign_specs.py --quick-hypotheses \
+ --out-dir /durable/path/rank-hypotheses-spec
+"""
+
+from __future__ import annotations
+
+import argparse
+import json
+import sys
+from pathlib import Path
+from typing import Any
+
+try: # Package import under tests; script-local import for direct execution.
+ from benchmarks import rank_hypotheses as rank_evidence
+except ModuleNotFoundError: # pragma: no cover - direct script execution
+ import rank_hypotheses as rank_evidence
+
+BENCHMARKS = Path(__file__).resolve().parent
+QUERY_MANIFEST = "benchmarks/rank-queries-v1/manifest.json"
+CORPUS_MANIFEST = "benchmarks/corpora-v1.json"
+
+# The popularity cohort: real OSS, pinned by commit and tree, each chosen for a stated
+# discriminating condition (corpora-v1.json "discriminates"). The four mined-workload
+# repositories are deliberately absent: they resolve their revision at run time from a
+# local checkout, so they cannot be pin-verified before staging and would weaken the
+# reproducibility the container coordinator exists to provide. Run them natively.
+# scikit-learn is here for domain rather than language: it is Python like flask, but
+# flask's "test" occurrences are scaffolding while sklearn's are public API
+# (train_test_split, test_size, hypothesis testing). Without it every corpus comes from a
+# domain where the hardcoded criteria happen to hold, which under-samples the failure
+# the campaign exists to find.
+POPULARITY_CORPORA = (
+ "cosign",
+ "jest",
+ "runc",
+ "flask",
+ "redis",
+ "ripgrep",
+ "scikit-learn",
+)
+
+# H1-H5 compare orderings over one graph, so they must not also vary coverage. Full
+# indexing removes FAST_SKIP_DIRS from the comparison entirely.
+RANK_INDEX_MODE = "full"
+COVERAGE_INDEX_MODES = ("full", "moderate", "fast")
+
+# Reply detail is a measured determinant of answer quality, not presentation: upstream
+# #1382 recorded recall 0.723 -> 0.525 on jackrabbit-oak purely from the graph arm
+# returning less. Sweeping it alongside a ranking change is what separates "ordered
+# better" from "returned more". Keys verified against config-keys-v1.json.
+DETAIL_PROFILES: tuple[tuple[str, dict[str, str]], ...] = (
+ (
+ "detail-lean",
+ {"search_limit": "10", "trace_max_results": "10", "snippet_max_lines": "40"},
+ ),
+ ("detail-default", {}),
+ (
+ "detail-rich",
+ {"search_limit": "200", "trace_max_results": "100", "snippet_max_lines": "400"},
+ ),
+)
+# One corpus carries the detail frontier. Crossing every corpus with every detail level
+# would triple the campaign for a question that is about the detail axis, not the corpus.
+DETAIL_FRONTIER_CORPUS = "cosign"
+
+CAPABILITY_SUPPORT = {"rank": True}
+
+# Every runtime knob that can change a published ranking score, from
+# src/pagerank/pagerank.h:89-101,113-222 and validated against config-keys-v1.json.
+# A knob absent from this set is one the campaign never proved does anything, and a
+# sweep over it would report a difference of exactly zero whether it is live or inert.
+RANKING_KNOBS = rank_evidence.RANK_OPTION_GROUPS["ranking_semantics"]
+# epsilon and max_iter are numerics rather than semantics: changing them changes how
+# precisely the same fixed point is reached, not which one. Sweeping them here would
+# report convergence noise as knob efficacy.
+NUMERIC_KNOBS = rank_evidence.RANK_OPTION_GROUPS["numerical_convergence_controls"]
+PARAMETER_CONTRACTS = rank_evidence.parameter_macro_contracts()
+
+
+def declared_intervention(option: str) -> tuple[str, dict[str, str]]:
+ """Pick a non-default endpoint from the product's declared/recommended range."""
+ contract = PARAMETER_CONTRACTS[option]
+ if option == "pagerank_max_iter":
+ field = "declared_min"
+ elif contract.get("recommended_max") != contract["default"]:
+ field = "recommended_max"
+ else:
+ field = "recommended_min"
+ return contract[field], {
+ "option": option,
+ "selected_field": field,
+ "value": contract[field],
+ "source": contract["source"],
+ "macros": contract["macros"],
+ }
+
+
+def corpus_arguments(corpus_id: str) -> list[str]:
+ """Workload flags that point one cell at one corpus.
+
+ --capability-quality and --index-mode are experiment-owned
+ (BENCHMARK_ARGS_RESERVED_FLAGS, run_experiments.py:115-140) and are set by the spec
+ fields instead; passing them here is rejected at validation time.
+ """
+ return [
+ "--corpus",
+ corpus_id,
+ "--rank-query-manifest",
+ QUERY_MANIFEST,
+ "--corpus-manifest",
+ CORPUS_MANIFEST,
+ ]
+
+
+def base_spec(
+ *,
+ harness_version: str,
+ campaign_arm: str,
+ index_mode: str,
+ profiles: list[dict[str, Any]],
+ ref: str,
+ repetitions: int,
+ timeout_seconds: int,
+) -> dict[str, Any]:
+ return {
+ "schema_version": 1,
+ "identity_version": 2,
+ "harness_version": harness_version,
+ "campaign_arm": campaign_arm,
+ "benchmark_script": "benchmarks/run_benchmark.py",
+ "cwd": ".",
+ "repetitions": repetitions,
+ "timeout_seconds": timeout_seconds,
+ "execution_order": "paired_interleaved",
+ "transports": ["mcp"],
+ "index_mode": index_mode,
+ "capability_quality": "rank",
+ "candidates": [
+ {
+ "label": "head",
+ "ref": ref,
+ "capability_support": dict(CAPABILITY_SUPPORT),
+ }
+ ],
+ "profiles": profiles,
+ # capability_quality runs force frontier_files and exact_caps to [None]
+ # (run_experiments.py:1565-1567), so the scenario is a single named cell.
+ "scenarios": [{"name": "rank_quality"}],
+ }
+
+
+def corpus_profile(
+ corpus_id: str, *, label: str | None = None, overrides: dict[str, str] | None = None
+) -> dict[str, Any]:
+ """One cell: one corpus, optionally under one reply-detail configuration."""
+ hypothesis_ids = ("H1", "H2", "H4", "H5", "H6")
+ cell_label = label or f"corpus-{corpus_id}"
+ return {
+ "label": cell_label,
+ "cell_name": f"RANK-CORPUS — {cell_label}",
+ "informs_hypotheses": list(hypothesis_ids),
+ "questions": [
+ {
+ "id": hypothesis_id,
+ "name": rank_evidence.HYPOTHESES[hypothesis_id]["name"],
+ "question": rank_evidence.HYPOTHESES[hypothesis_id]["question"],
+ }
+ for hypothesis_id in hypothesis_ids
+ ],
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "config_overrides": dict(overrides or {}),
+ "benchmark_args": corpus_arguments(corpus_id),
+ }
+
+
+def selected_corpora(corpora: tuple[str, ...] | None) -> tuple[str, ...]:
+ """Resolve the corpus set, rejecting an unknown id at generation time.
+
+ docs/EVALUATION_PLAN.md asks for a pilot before a sweep, so a one-corpus run is a
+ first-class mode rather than something to hand-edit a generated spec for. An
+ unrecognised id would otherwise fail after the image build and the candidate build.
+ """
+ if corpora is None:
+ return POPULARITY_CORPORA
+ unknown = [name for name in corpora if name not in POPULARITY_CORPORA]
+ if unknown:
+ raise ValueError(
+ f"unknown corpus id(s) {unknown}; this campaign covers "
+ + ", ".join(POPULARITY_CORPORA)
+ )
+ return tuple(name for name in POPULARITY_CORPORA if name in set(corpora))
+
+
+def build_rank_spec(
+ ref: str,
+ repetitions: int,
+ timeout_seconds: int,
+ corpora: tuple[str, ...] | None = None,
+) -> dict[str, Any]:
+ """Real-corpus node/edge ranking arm plus the reply-detail sweep.
+
+ Every scorer is read from the same graph by run_rank_score_probes, so the six-way
+ comparison needs one candidate rather than six. Adding PR #879's `importance` arm is
+ one more candidates[] entry pointing at its ref; it reports applicable: false here.
+
+ This arm instruments H1/H2/H4/H5/H6. It does not pair rank-on with rank-off cost or
+ tune across held-out language strata, so it must not claim H3 or H7.
+ """
+ chosen = selected_corpora(corpora)
+ profiles = [corpus_profile(corpus_id) for corpus_id in chosen]
+ profiles.extend(
+ corpus_profile(
+ DETAIL_FRONTIER_CORPUS,
+ label=f"{DETAIL_FRONTIER_CORPUS}-{name}",
+ overrides=overrides,
+ )
+ for name, overrides in DETAIL_PROFILES
+ # detail-default is already covered by the plain corpus profile
+ if overrides and DETAIL_FRONTIER_CORPUS in chosen
+ )
+ spec = base_spec(
+ harness_version="rank-quality-v1",
+ campaign_arm="rank",
+ index_mode=RANK_INDEX_MODE,
+ profiles=profiles,
+ ref=ref,
+ repetitions=repetitions,
+ timeout_seconds=timeout_seconds,
+ )
+ spec["evidence_contract"] = {
+ "role": "real_corpus_rank_quality",
+ "hypotheses": ["H1", "H2", "H4", "H5", "H6"],
+ "not_evaluated": ["H3", "H7"],
+ "independent_unit": "corpus; repetitions and detail profiles are repeated observations",
+ "registry": rank_evidence.public_hypothesis_registry(),
+ }
+ return spec
+
+
+def build_canary_spec(
+ ref: str, repetitions: int, timeout_seconds: int
+) -> dict[str, Any]:
+ """The validity precondition: prove every ranking knob actually moves the scores.
+
+ Runs on the synthetic rank fixture rather than a corpus. The question is whether a
+ config value reaches the scorer at all, which 17 files answer as well as 3,000 do,
+ and a per-corpus canary would cost minutes per knob.
+
+ Nothing downstream is trustworthy until this passes: a knob that silently does
+ nothing produces a clean run reporting a difference of exactly zero, which reads
+ identically to "this knob does not help".
+ """
+ profiles = [
+ {
+ "label": "baseline",
+ "cell_name": "RANK-CANARY — baseline published ranking",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "config_overrides": {},
+ "benchmark_args": [],
+ "informs_hypotheses": ["H2", "H3", "H4", "H7"],
+ "questions": [
+ {
+ "id": hypothesis_id,
+ "name": rank_evidence.HYPOTHESES[hypothesis_id]["name"],
+ "question": rank_evidence.HYPOTHESES[hypothesis_id]["question"],
+ }
+ for hypothesis_id in ("H2", "H3", "H4", "H7")
+ ],
+ }
+ ]
+ for knob in sorted(RANKING_KNOBS):
+ value, parameter_source = declared_intervention(knob)
+ hypothesis_ids = ("H2", "H4", "H7")
+ profiles.append(
+ {
+ "label": f"knob-{knob}",
+ "cell_name": f"RANK-CANARY — {knob} declared-range intervention",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "config_overrides": {knob: value},
+ "benchmark_args": [],
+ "parameter_sources": [parameter_source],
+ "informs_hypotheses": list(hypothesis_ids),
+ "questions": [
+ {
+ "id": hypothesis_id,
+ "name": rank_evidence.HYPOTHESES[hypothesis_id]["name"],
+ "question": rank_evidence.HYPOTHESES[hypothesis_id]["question"],
+ }
+ for hypothesis_id in hypothesis_ids
+ ],
+ }
+ )
+ for knob in sorted(NUMERIC_KNOBS):
+ value, parameter_source = declared_intervention(knob)
+ profiles.append(
+ {
+ "label": f"numeric-{knob}",
+ "cell_name": f"RANK-CANARY — {knob} convergence control",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "config_overrides": {knob: value},
+ "benchmark_args": [],
+ "parameter_sources": [parameter_source],
+ "informs_hypotheses": ["H3"],
+ "questions": [
+ {
+ "id": "H3",
+ "name": rank_evidence.HYPOTHESES["H3"]["name"],
+ "question": rank_evidence.HYPOTHESES["H3"]["question"],
+ }
+ ],
+ }
+ )
+ spec = base_spec(
+ harness_version="knob-canary-v1",
+ campaign_arm="canary",
+ index_mode=RANK_INDEX_MODE,
+ profiles=profiles,
+ ref=ref,
+ repetitions=repetitions,
+ timeout_seconds=timeout_seconds,
+ )
+ spec["evidence_contract"] = {
+ "role": "instrument_validity",
+ "hypotheses": [],
+ "option_groups": ["ranking_semantics", "numerical_convergence_controls"],
+ "semantic_expectation": "fingerprint changes when the fixture contains the affected edge type",
+ "numerical_expectation": "publication, rank drift, and latency are measured; byte change is not required",
+ }
+ return spec
+
+
+def build_quick_hypothesis_spec(
+ ref: str = "HEAD", *, timeout_seconds: int
+) -> dict[str, Any]:
+ """Prioritized synthetic cells covering scorers, semantics, numerics, and lifecycle.
+
+ This is the bounded development diagnostic used by ``run_evidence_suite.py``. It is
+ intentionally not a cross-language quality verdict: a synthetic Python fixture can
+ establish wiring, metric domains, publication behavior, and relative cost, while the
+ real-corpus arm supplies language/task generalization evidence.
+ """
+ profiles = rank_evidence.quick_hypothesis_profiles()
+ for profile in profiles:
+ profile["benchmark_args"] = []
+ spec = base_spec(
+ harness_version="rank-hypotheses-quick-v2",
+ campaign_arm="hypothesis_quick",
+ index_mode=RANK_INDEX_MODE,
+ profiles=profiles,
+ ref=ref,
+ repetitions=1,
+ timeout_seconds=timeout_seconds,
+ )
+ spec["suite_name"] = rank_evidence.RANK_SUITE_NAME
+ spec["runtime_policy"] = {
+ "design": "one repetition per fixed evidence arm over MCP",
+ "measurement": "record actual elapsed time for every cell",
+ }
+ spec["evidence_contract"] = {
+ "role": "bounded_development_diagnostic",
+ "hypotheses": ["H2", "H3", "H4", "H6"],
+ "not_evaluated": ["H1", "H5", "H7"],
+ "limitations": [
+ "synthetic Python fixture only",
+ "H6 edge ranking is instrumented but has no judged edge/path task",
+ "H3 cost is a smoke estimate, not a production-scale overhead claim",
+ ],
+ "registry": rank_evidence.public_hypothesis_registry(),
+ }
+ return spec
+
+
+def build_coverage_specs(
+ ref: str,
+ repetitions: int,
+ timeout_seconds: int,
+ corpora: tuple[str, ...] | None = None,
+) -> list[dict[str, Any]]:
+ """The silent-drop arm: identical corpora and profiles, one spec per index mode.
+
+ The comparison is the diff between these runsets, so anything differing besides
+ index_mode would be measured as coverage loss. That invariant is a test, not a
+ comment: test_coverage_specs_differ_only_in_index_mode.
+ """
+ profiles = [corpus_profile(corpus_id) for corpus_id in selected_corpora(corpora)]
+ return [
+ base_spec(
+ harness_version=f"coverage-{index_mode}-v1",
+ campaign_arm="coverage",
+ index_mode=index_mode,
+ profiles=profiles,
+ ref=ref,
+ repetitions=repetitions,
+ timeout_seconds=timeout_seconds,
+ )
+ for index_mode in COVERAGE_INDEX_MODES
+ ]
+
+
+def build_all_specs(
+ ref: str = "HEAD",
+ repetitions: int = 1,
+ timeout_seconds: int = 2400,
+ corpora: tuple[str, ...] | None = None,
+) -> list[dict[str, Any]]:
+ return [
+ build_canary_spec(ref, repetitions, timeout_seconds),
+ build_rank_spec(ref, repetitions, timeout_seconds, corpora),
+ *build_coverage_specs(ref, repetitions, timeout_seconds, corpora),
+ ]
+
+
+def spec_filename(spec: dict[str, Any]) -> str:
+ return f"{spec['harness_version']}.json"
+
+
+def main(argv: list[str] | None = None) -> int:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "--out-dir",
+ type=Path,
+ help="Directory to write the generated specs into; created if absent.",
+ )
+ parser.add_argument(
+ "--print",
+ dest="print_arm",
+ help="Print one spec by harness_version instead of writing files.",
+ )
+ parser.add_argument(
+ "--ref",
+ default="HEAD",
+ help="Candidate Git ref measured by every arm; defaults to HEAD.",
+ )
+ parser.add_argument(
+ "--corpora",
+ default="",
+ help=(
+ "Comma-separated subset of the corpus set, for a pilot before the sweep. "
+ "Defaults to all of: " + ", ".join(POPULARITY_CORPORA)
+ ),
+ )
+ parser.add_argument(
+ "--quick-hypotheses",
+ action="store_true",
+ help=(
+ "Write only the fixed nine-cell synthetic rank diagnostic used by the "
+ "unified evidence suite. It always uses one MCP repetition; --corpora and "
+ "non-default --repetitions are rejected."
+ ),
+ )
+ parser.add_argument("--repetitions", type=int, default=1)
+ parser.add_argument("--timeout-seconds", type=int, default=2400)
+ args = parser.parse_args(argv)
+
+ chosen = tuple(name.strip() for name in args.corpora.split(",") if name.strip())
+ try:
+ if args.quick_hypotheses:
+ if chosen:
+ raise ValueError(
+ "--quick-hypotheses uses the synthetic fixture and cannot be "
+ "combined with --corpora"
+ )
+ if args.repetitions != 1:
+ raise ValueError(
+ "--quick-hypotheses has one fixed MCP repetition; omit "
+ "--repetitions or pass 1"
+ )
+ specs = [
+ build_quick_hypothesis_spec(
+ args.ref, timeout_seconds=args.timeout_seconds
+ )
+ ]
+ else:
+ specs = build_all_specs(
+ args.ref, args.repetitions, args.timeout_seconds, chosen or None
+ )
+ except ValueError as error:
+ parser.error(str(error))
+ if args.print_arm:
+ for spec in specs:
+ if spec["harness_version"] == args.print_arm:
+ print(json.dumps(spec, indent=2, sort_keys=True))
+ return 0
+ available = ", ".join(spec["harness_version"] for spec in specs)
+ parser.error(f"unknown arm {args.print_arm!r}; available: {available}")
+ if args.out_dir is None:
+ parser.error("pass --out-dir to write specs, or --print to inspect one")
+ args.out_dir.mkdir(parents=True, exist_ok=True)
+ for spec in specs:
+ path = args.out_dir / spec_filename(spec)
+ path.write_text(
+ json.dumps(spec, indent=2, sort_keys=True) + "\n", encoding="utf-8"
+ )
+ # Read the flag rather than a fixed position: the canary's profiles carry no
+ # workload flags at all, and indexing into them crashed generation after the
+ # first arm was written.
+ corpora = sorted(
+ {
+ arguments[index + 1]
+ for profile in spec["profiles"]
+ for arguments in [profile["benchmark_args"]]
+ for index, argument in enumerate(arguments)
+ if argument == "--corpus" and index + 1 < len(arguments)
+ }
+ )
+ scope = f"{len(corpora)} corpora" if corpora else "the synthetic fixture"
+ print(f"wrote {path}: {len(spec['profiles'])} cells over {scope}")
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/benchmarks/config-keys-v1.json b/benchmarks/config-keys-v1.json
new file mode 100644
index 000000000..0d4bf308e
--- /dev/null
+++ b/benchmarks/config-keys-v1.json
@@ -0,0 +1,140 @@
+{
+ "schema_version": 1,
+ "generated_by": "benchmarks/generate_config_keys.py",
+ "source_revision": "8112a5daa86a297eb835faf7b21d9f89ac598994",
+ "note": "Allowlist for benchmark --config overrides. cbm_config_value_is_valid in src/cli/cli.c returns true for keys absent from CBM_CONFIG_REGISTRY, so the product cannot reject a typo; the harness rejects it instead.",
+ "registry_note": "Listed in CBM_CONFIG_REGISTRY; `config set` range-validates these.",
+ "consumed_note": "Read via cbm_config_get_*() but absent from CBM_CONFIG_REGISTRY, so `config set` accepts any value unvalidated. Real keys; still allowed.",
+ "registry_count": 56,
+ "consumed_count": 6,
+ "registry": [
+ "arch_cluster_node_budget",
+ "arch_hotspot_limit",
+ "architecture_resolution",
+ "auto_dep_limit",
+ "auto_index_deps",
+ "auto_watch",
+ "build_fingerprint_mode",
+ "context_injection",
+ "context_key_functions_limit",
+ "default_response_format",
+ "dep_max_files",
+ "edge_weight_async_calls",
+ "edge_weight_calls",
+ "edge_weight_configures",
+ "edge_weight_decorates",
+ "edge_weight_default",
+ "edge_weight_defines",
+ "edge_weight_defines_method",
+ "edge_weight_http_calls",
+ "edge_weight_imports",
+ "edge_weight_member_of",
+ "edge_weight_tests",
+ "edge_weight_usage",
+ "edge_weight_writes",
+ "extract_timeout_ms",
+ "githistory_enabled",
+ "githistory_max_couplings",
+ "githistory_min_coupling",
+ "httplinks_enabled",
+ "incremental_derived_results_refresh",
+ "incremental_exact_max_affected_paths",
+ "incremental_exact_max_changed_paths",
+ "incremental_reindex",
+ "key_functions_count",
+ "key_functions_exclude",
+ "overlay_compaction_max_generations",
+ "overlay_compaction_policy",
+ "overlay_publish",
+ "pagerank_damping",
+ "pagerank_epsilon",
+ "pagerank_max_iter",
+ "query_max_output_bytes",
+ "query_max_rows",
+ "query_max_working_rows",
+ "rank_enabled",
+ "rank_refresh",
+ "rank_scope",
+ "search_limit",
+ "semantic_edges_enabled",
+ "similarity_enabled",
+ "snippet_max_lines",
+ "tool_mode",
+ "trace_max_results",
+ "ui-lang",
+ "ui_enabled",
+ "ui_port"
+ ],
+ "consumed_unregistered": [
+ "auto_index",
+ "auto_index_limit",
+ "httplink_min_confidence",
+ "lsp_confidence_floor",
+ "semantic_threshold",
+ "similarity_threshold"
+ ],
+ "keys": [
+ "arch_cluster_node_budget",
+ "arch_hotspot_limit",
+ "architecture_resolution",
+ "auto_dep_limit",
+ "auto_index",
+ "auto_index_deps",
+ "auto_index_limit",
+ "auto_watch",
+ "build_fingerprint_mode",
+ "context_injection",
+ "context_key_functions_limit",
+ "default_response_format",
+ "dep_max_files",
+ "edge_weight_async_calls",
+ "edge_weight_calls",
+ "edge_weight_configures",
+ "edge_weight_decorates",
+ "edge_weight_default",
+ "edge_weight_defines",
+ "edge_weight_defines_method",
+ "edge_weight_http_calls",
+ "edge_weight_imports",
+ "edge_weight_member_of",
+ "edge_weight_tests",
+ "edge_weight_usage",
+ "edge_weight_writes",
+ "extract_timeout_ms",
+ "githistory_enabled",
+ "githistory_max_couplings",
+ "githistory_min_coupling",
+ "httplink_min_confidence",
+ "httplinks_enabled",
+ "incremental_derived_results_refresh",
+ "incremental_exact_max_affected_paths",
+ "incremental_exact_max_changed_paths",
+ "incremental_reindex",
+ "key_functions_count",
+ "key_functions_exclude",
+ "lsp_confidence_floor",
+ "overlay_compaction_max_generations",
+ "overlay_compaction_policy",
+ "overlay_publish",
+ "pagerank_damping",
+ "pagerank_epsilon",
+ "pagerank_max_iter",
+ "query_max_output_bytes",
+ "query_max_rows",
+ "query_max_working_rows",
+ "rank_enabled",
+ "rank_refresh",
+ "rank_scope",
+ "search_limit",
+ "semantic_edges_enabled",
+ "semantic_threshold",
+ "similarity_enabled",
+ "similarity_threshold",
+ "snippet_max_lines",
+ "tool_mode",
+ "trace_max_results",
+ "ui-lang",
+ "ui_enabled",
+ "ui_port"
+ ]
+}
diff --git a/benchmarks/config-spellings-v1.json b/benchmarks/config-spellings-v1.json
new file mode 100644
index 000000000..a74d13929
--- /dev/null
+++ b/benchmarks/config-spellings-v1.json
@@ -0,0 +1,109 @@
+{
+ "schema_version": 1,
+ "profiles": {
+ "derived_results_refresh_at_publish": {
+ "canonical": "incremental_derived_results_refresh_at_publish",
+ "historical": [
+ "incremental_semantic_freshness_eager"
+ ]
+ }
+ },
+ "experiment_labels": {
+ "derived_results_refresh_at_publish": {
+ "canonical": "derived-results-refresh-at-publish",
+ "historical": [
+ "eager-derived-freshness"
+ ]
+ }
+ },
+ "config_overrides": [
+ {
+ "id": "incremental_reindex_full_rebuild",
+ "canonical": {
+ "key": "incremental_reindex",
+ "value": "full_rebuild"
+ },
+ "historical": {
+ "key": "incremental_reindex",
+ "value": "off"
+ }
+ },
+ {
+ "id": "incremental_reindex_fast_mode_indexes_only",
+ "canonical": {
+ "key": "incremental_reindex",
+ "value": "fast_mode_indexes_only"
+ },
+ "historical": {
+ "key": "incremental_reindex",
+ "value": "fast"
+ }
+ },
+ {
+ "id": "incremental_derived_results_refresh_at_publish",
+ "canonical": {
+ "key": "incremental_derived_results_refresh",
+ "value": "at_publish"
+ },
+ "historical": {
+ "key": "incremental_derived_refresh",
+ "value": "eager"
+ }
+ },
+ {
+ "id": "incremental_derived_results_refresh_defer_exact_delta_reindexes",
+ "canonical": {
+ "key": "incremental_derived_results_refresh",
+ "value": "defer_exact_delta_reindexes"
+ },
+ "historical": {
+ "key": "incremental_derived_refresh",
+ "value": "stale_on_exact"
+ }
+ },
+ {
+ "id": "incremental_derived_results_refresh_defer_all_incremental_reindexes",
+ "canonical": {
+ "key": "incremental_derived_results_refresh",
+ "value": "defer_all_incremental_reindexes"
+ },
+ "historical": {
+ "key": "incremental_derived_refresh",
+ "value": "stale_on_incremental"
+ }
+ },
+ {
+ "id": "rank_refresh_at_publish",
+ "canonical": {
+ "key": "rank_refresh",
+ "value": "at_publish"
+ },
+ "historical": {
+ "key": "rank_refresh",
+ "value": "eager"
+ }
+ },
+ {
+ "id": "rank_refresh_defer_exact_delta_reindexes",
+ "canonical": {
+ "key": "rank_refresh",
+ "value": "defer_exact_delta_reindexes"
+ },
+ "historical": {
+ "key": "rank_refresh",
+ "value": "stale_on_exact"
+ }
+ },
+ {
+ "id": "rank_refresh_defer_all_incremental_reindexes",
+ "canonical": {
+ "key": "rank_refresh",
+ "value": "defer_all_incremental_reindexes"
+ },
+ "historical": {
+ "key": "rank_refresh",
+ "value": "stale_on_incremental"
+ }
+ }
+ ]
+}
diff --git a/benchmarks/corpora-v1.json b/benchmarks/corpora-v1.json
new file mode 100644
index 000000000..976d55f29
--- /dev/null
+++ b/benchmarks/corpora-v1.json
@@ -0,0 +1,301 @@
+{
+ "schema_version": 1,
+ "corpus_set_version": "corpora-v1",
+ "purpose": "Pinned real open-source corpora for the rank-quality campaign. Each entry records why it was chosen, which hardcoded criterion it exercises, and the file loss predicted from the skip lists in src/discover/discover.c before any indexing happens.",
+ "selection_rules": [
+ "Real, popular OSS only for the popularity cohort (>=1k stars), per docs/EVALUATION_PLAN.md:256 upstream.",
+ "Pinned by BOTH commit sha and tree sha; copy_git_revision_to_dir (run_benchmark.py:5055-5121) records and verifies both.",
+ "Every corpus states the hypothesis it discriminates (H4-H7) or the issue it reproduces.",
+ "Predicted losses below are computed from ALWAYS_SKIP_DIRS and FAST_SKIP_DIRS parsed out of src/discover/discover.c, matched against each pinned tree. They are pre-registered predictions, not post-hoc observations."
+ ],
+ "skip_list_source": {
+ "file": "src/discover/discover.c",
+ "always_skip_dirs_entries": 77,
+ "fast_skip_dirs_entries": 36,
+ "mode_gate": "src/discover/discover.c:448-452 applies FAST_SKIP_DIRS when mode != CBM_MODE_FULL",
+ "note": "ALWAYS_SKIP_DIRS applies in every mode including full."
+ },
+ "hypotheses": {
+ "H4": "edge-type insensitivity: degree counts TESTS and vendored edges at full weight; weighted PageRank can damp them.",
+ "H5": "utility inversion: raw in-degree ranks max-fan-in utilities first by construction.",
+ "H6": "edge ranking: LinkRank orders edges; no node-degree statistic can.",
+ "H7": "adaptation: runtime weights recover quality where compile-time constants cannot."
+ },
+ "corpora": [
+ {
+ "id": "cosign",
+ "repo": "sigstore/cosign",
+ "url": "https://github.com/sigstore/cosign",
+ "revision": "83d9ec8f4bdb25d680c2331528503cd85888868f",
+ "tree": "018c2e89e2c1b964d30fd98701eff57a513d9591",
+ "committed": "2026-07-31T15:14:31Z",
+ "language": "Go",
+ "stars": 6175,
+ "files_in_tree": 479,
+ "cohort": "adversarial",
+ "discriminates": [
+ "H4",
+ "H5",
+ "H7"
+ ],
+ "why": "The string 'attest' contains the substring 'test'. 30 paths under the pinned tree match 'attest', including production command code, so the bare strstr(file,\"test\") penalty at src/mcp/mcp.c:15367 (SCORE_TEST=-5) and the bare strstr(fp,\"test\") classifier at src/store/store.c:14905-14910 both fire on core production code. 163 paths contain 'test' overall, of which 104 are genuine _test.go files, giving a real signal/noise contrast rather than a synthetic one.",
+ "predicted_loss": {
+ "always_skipped_top_dirs": [],
+ "files_lost_every_mode": 0,
+ "fast_skipped_top_dirs": [
+ "doc",
+ "hack",
+ "scripts"
+ ],
+ "files_lost_outside_full_mode": 49
+ },
+ "issues": [
+ "#1406"
+ ],
+ "notes": "Uses plural scripts/, which IS in FAST_SKIP_DIRS. Pairs with runc, which uses singular script/, which is NOT."
+ },
+ {
+ "id": "jest",
+ "repo": "jestjs/jest",
+ "url": "https://github.com/jestjs/jest",
+ "revision": "f49721c78e195558b40913977c9230f5b7f559d8",
+ "tree": "9ab69bfdd7af987de9304dda0adb76513b3ea32f",
+ "committed": "2026-06-24T09:42:12Z",
+ "language": "TypeScript",
+ "stars": 45457,
+ "files_in_tree": 3317,
+ "cohort": "adversarial",
+ "discriminates": [
+ "H4",
+ "H7"
+ ],
+ "why": "The polarity-inversion corpus: the product IS test infrastructure, so 1630 of 3317 paths contain 'test' and a global test penalty demotes precisely the code a user is searching for. #879's TEST_MUL=0.1 and our edge_weight_tests=0.05 both misfire here in the same direction. Lower scaffolding@K is a DEFECT on this corpus, not a win; the metric is reported with an explicit sign.",
+ "predicted_loss": {
+ "always_skipped_top_dirs": [
+ ".claude",
+ ".vscode",
+ ".yarn"
+ ],
+ "files_lost_every_mode": 8,
+ "fast_skipped_top_dirs": [
+ "docs",
+ "e2e",
+ "examples",
+ "scripts"
+ ],
+ "files_lost_outside_full_mode": 1711
+ },
+ "issues": [
+ "#1406",
+ "#1294"
+ ],
+ "notes": "1711 of 3317 files (51.6%) disappear outside full mode. This is the strongest single demonstration of the #1406 class."
+ },
+ {
+ "id": "runc",
+ "repo": "opencontainers/runc",
+ "url": "https://github.com/opencontainers/runc",
+ "revision": "0c87c02ff02123f1bc2cd1b3f850f94e5b8de983",
+ "tree": "431b845435e4eb19593fd27ec12080c3a6fec29a",
+ "committed": "2026-07-29T18:18:53Z",
+ "language": "Go",
+ "stars": 13384,
+ "files_in_tree": 1305,
+ "cohort": "adversarial",
+ "discriminates": [
+ "H4",
+ "H5",
+ "H6"
+ ],
+ "why": "Natural experiment on skip-list asymmetry: runc keeps its shell helpers in script/ (singular), which is absent from FAST_SKIP_DIRS, while cosign uses scripts/ (plural), which is present. Same intent, opposite treatment, exactly parallel to the deploy/deployment asymmetry in ALWAYS_SKIP_DIRS reported as #1184. Also carries a committed vendor/ tree, so it measures ranking when 75% of the repository is absent from the graph in every mode.",
+ "predicted_loss": {
+ "always_skipped_top_dirs": [
+ "vendor"
+ ],
+ "files_lost_every_mode": 978,
+ "fast_skipped_top_dirs": [
+ "docs"
+ ],
+ "files_lost_outside_full_mode": 8
+ },
+ "issues": [
+ "#1184",
+ "#1406"
+ ],
+ "notes": "978 of 1305 files (74.9%) are dropped in EVERY mode including full, via the single ALWAYS_SKIP_DIRS entry 'vendor'. SCORE_VENDORED=-50 (mcp.c:15362) also targets vendored paths, so two mechanisms serve one intent."
+ },
+ {
+ "id": "flask",
+ "repo": "pallets/flask",
+ "url": "https://github.com/pallets/flask",
+ "revision": "6a2f545bfd8ed31e19066a299296917e034aca58",
+ "tree": "70a41ed9ca5461fc58ae35e39978af9b2ae93542",
+ "committed": "2026-07-30T17:29:33Z",
+ "language": "Python",
+ "stars": 72069,
+ "files_in_tree": 236,
+ "cohort": "adversarial",
+ "discriminates": [
+ "H4"
+ ],
+ "why": "Pure pytest project, so every test function carries is_test=false: def.is_test is assigned only for Rust #[test] and C++ GoogleTest at internal/cbm/extract_defs.c:3718,3723. Measures how much test signal survives on the TESTS-edge and path-heuristic channel alone when the node property is uniformly wrong. Small and well known, so relevance targets (Flask, Blueprint, url_for) are unambiguous.",
+ "predicted_loss": {
+ "always_skipped_top_dirs": [],
+ "files_lost_every_mode": 0,
+ "fast_skipped_top_dirs": [
+ "docs",
+ "examples"
+ ],
+ "files_lost_outside_full_mode": 129
+ },
+ "issues": [
+ "#1294",
+ "#1406"
+ ],
+ "notes": "129 of 236 files (54.7%) lost outside full mode."
+ },
+ {
+ "id": "redis",
+ "repo": "redis/redis",
+ "url": "https://github.com/redis/redis",
+ "revision": "0708bdbc0086bea03c5a40d9b606b5fe73d7159d",
+ "tree": "5d2b153566a03b37d14538863cbcb31bacf50649",
+ "committed": "2026-08-03T02:24:18Z",
+ "language": "C",
+ "stars": 75845,
+ "files_in_tree": 1858,
+ "cohort": "adversarial",
+ "discriminates": [
+ "H5",
+ "H6"
+ ],
+ "why": "Hub-utility corpus for H5: C allocators and logging helpers (zmalloc, serverLog, sds*) have the highest raw fan-in in the repository, which is precisely the shape the maintainer predicted PageRank would surface (#151: 'PageRank would rank log.Error() and fmt.Sprintf() as the most important functions'). Testing that claim needs a corpus where such hubs genuinely dominate. Deep call chains also make it the primary corpus for H6 edge ordering.",
+ "predicted_loss": {
+ "always_skipped_top_dirs": [],
+ "files_lost_every_mode": 0,
+ "fast_skipped_top_dirs": [
+ "scripts",
+ "tools"
+ ],
+ "files_lost_outside_full_mode": 13
+ },
+ "issues": [],
+ "notes": "594 paths contain 'test' (Tcl suite); 1 contains 'latest', a direct false-positive probe for strstr(fp,\"test\")."
+ },
+ {
+ "id": "ripgrep",
+ "repo": "BurntSushi/ripgrep",
+ "url": "https://github.com/BurntSushi/ripgrep",
+ "revision": "435f59fc4b43af3ab32f34d53fa34978f393fe52",
+ "tree": "45a1e81a7682d20dd41096482516a506d0adbdd1",
+ "committed": "2026-07-29T15:00:03Z",
+ "language": "Rust",
+ "stars": 66894,
+ "files_in_tree": 237,
+ "cohort": "control",
+ "discriminates": [],
+ "why": "Positive control: Rust is the one ecosystem where def.is_test is actually populated (#[test] handling at internal/cbm/extract_defs.c:3718), and the repository has almost nothing in the skip lists. If a metric moves here, the cause is the score rather than missing coverage.",
+ "predicted_loss": {
+ "always_skipped_top_dirs": [
+ ".cargo"
+ ],
+ "files_lost_every_mode": 1,
+ "fast_skipped_top_dirs": [
+ "scripts"
+ ],
+ "files_lost_outside_full_mode": 1
+ },
+ "issues": [],
+ "notes": "Near-zero predicted loss is the point: it isolates score effects from coverage effects."
+ },
+ {
+ "id": "codebase-memory-mcp",
+ "repo": "ahundt/codebase-memory-mcp",
+ "cohort": "workload",
+ "language": "C",
+ "revision": "resolve-at-run-time",
+ "discriminates": [],
+ "why": "Mined-workload corpus: 3422 real graph-tool calls were recovered against this repository, so its query battery is empirical rather than authored. Self-measurement also exposes our own scores to the same audit we apply to #879.",
+ "issues": [],
+ "notes": "Excluded from the >=1k-star popularity rule by design; it is a workload-validity corpus, not a popularity-cohort corpus.",
+ "url": "https://github.com/ahundt/codebase-memory-mcp"
+ },
+ {
+ "id": "ai-session-search",
+ "repo": "ahundt/ai-session-search",
+ "cohort": "workload",
+ "language": "Rust",
+ "revision": "resolve-at-run-time",
+ "discriminates": [],
+ "why": "Largest mined-workload source: 8558 real graph-tool calls, 66% of the recovered corpus. Supplies the highest-confidence realistic query distribution.",
+ "issues": [],
+ "notes": "Rust-heavy, so it over-represents one language; weighted accordingly in reporting.",
+ "url": "https://github.com/ahundt/ai-session-search"
+ },
+ {
+ "id": "autorun",
+ "repo": "ahundt/autorun",
+ "cohort": "workload",
+ "language": "Python",
+ "revision": "resolve-at-run-time",
+ "discriminates": [],
+ "why": "Mined-workload corpus with 648 real calls and a 33.3% query_graph zero-result rate, the highest observed. Supplies realistic structural-query failure cases.",
+ "issues": [],
+ "notes": "Also pytest-based, so it corroborates the flask is_test finding on a second Python codebase.",
+ "url": "https://github.com/ahundt/autorun"
+ },
+ {
+ "id": "codex",
+ "repo": "openai/codex",
+ "cohort": "workload",
+ "language": "Rust",
+ "revision": "resolve-at-run-time",
+ "discriminates": [],
+ "why": "Fourth permitted mined-workload repository (54 calls). Smallest contribution; included for coverage of a fourth independent codebase.",
+ "issues": [],
+ "notes": "Low call volume, so it contributes queries but carries little weight in the workload distribution.",
+ "url": "https://github.com/openai/codex"
+ },
+ {
+ "id": "scikit-learn",
+ "repo": "scikit-learn/scikit-learn",
+ "url": "https://github.com/scikit-learn/scikit-learn",
+ "revision": "5799d3eac08bda44fbce3309e641cbf98c5d312a",
+ "tree": "becf3d78e1e67254c8a1de53a3178d420e5ee7b8",
+ "committed": "2026-07-31T15:16:02Z",
+ "language": "Python",
+ "stars": 66855,
+ "cohort": "adversarial",
+ "discriminates": [
+ "H4",
+ "H7"
+ ],
+ "why": "The only corpus here where 'test' is production vocabulary at the SYMBOL level rather than a path convention: train_test_split is public API exported from sklearn/model_selection/__init__.py, and test_size, TimeSeriesSplit and hypothesis-testing helpers are core interface. A search_graph query for 'test' must therefore return production API here and scaffolding on flask, from the same language and the same labeller. Every other corpus comes from a domain where the substring means scaffolding, so without this one the corpus set under-samples the failure the campaign exists to find.",
+ "issues": [],
+ "notes": "Measured against the pinned tree, not assumed: 1812 files, 1016 Python, 330 paths containing 'test' of which 319 are genuine test modules. So the PATH-level misclassification surface is small (11 files, mostly conftest.py and sklearn/utils/_test_common/), and this corpus is NOT strong evidence for the path-based predicates at src/mcp/mcp.c:15367 or src/store/store.c:14905-14910. Its value is the symbol-name axis and the flask pairing: same language, same labeller, opposite polarity for the token 'test'.",
+ "files_in_tree": 1812,
+ "predicted_loss": {
+ "always_skipped_top_dirs": [],
+ "files_lost_every_mode": 0,
+ "fast_skipped_top_dirs": [
+ "doc",
+ "examples"
+ ],
+ "files_lost_outside_full_mode": 705
+ }
+ }
+ ],
+ "holdout": {
+ "id": "TBD-typescript-monorepo",
+ "cohort": "holdout",
+ "status": "unselected",
+ "requirement": "A TypeScript monorepo with substantial generated-code directories. Pinned and opened exactly once, after finalists are selected, per the cross-validation protocol.",
+ "rule": "Must not be inspected, indexed, or queried before selection is frozen."
+ },
+ "measurements_deferred_to_run_time": [
+ "TESTS-edge fraction per corpus (needs an index; required to rank corpora by H4 discriminating power).",
+ "Hub-utility identity and fan-in per corpus (needs an index; required for H5).",
+ "Actual vs predicted file loss per index mode (the silent-drop matrix, P4.6)."
+ ],
+ "workload_corpus_resolution": "Workload corpora record revision \"resolve-at-run-time\": their value is the query distribution mined against whatever the operator actually had indexed, so pinning one commit would misdescribe them. They resolve through the same ladder as every other benchmark repository (--corpus-repo =PATH, CBM_BENCH_CORPUS_, the shared cache) and, with --clone-missing-real-repos, clone the current tip of the url below. The commit actually measured is read from the checkout and recorded in the run manifest, so a result always names a real commit even though the registry does not pin one."
+}
diff --git a/benchmarks/environment-policy-v1.json b/benchmarks/environment-policy-v1.json
new file mode 100644
index 000000000..b205f3ab2
--- /dev/null
+++ b/benchmarks/environment-policy-v1.json
@@ -0,0 +1,18 @@
+{
+ "schema_version": 1,
+ "product_environment_prefix": "CBM_",
+ "build_environment_keys": [
+ "CC",
+ "CXX",
+ "EXTRA_CFLAGS",
+ "EXTRA_CXXFLAGS"
+ ],
+ "harness_owned_keys": [
+ "CBM_AUTO_INDEX",
+ "CBM_BENCHMARK_ARTIFACT_DIR",
+ "CBM_BENCHMARK_RUN_CONTEXT",
+ "CBM_CACHE_DIR",
+ "CBM_CONTEXT_INJECTION",
+ "CBM_PROFILE"
+ ]
+}
diff --git a/benchmarks/fact_comparisons.py b/benchmarks/fact_comparisons.py
new file mode 100755
index 000000000..987bb1109
--- /dev/null
+++ b/benchmarks/fact_comparisons.py
@@ -0,0 +1,699 @@
+#!/usr/bin/env python3
+"""Derive auditable comparison and lifecycle views from benchmark fact bundles."""
+
+from __future__ import annotations
+
+import argparse
+from datetime import datetime, timezone
+import hashlib
+import json
+import os
+from pathlib import Path, PureWindowsPath
+import statistics
+import sys
+import tempfile
+from typing import Any, Iterable
+
+
+SCHEMA_VERSION = 1
+SCHEMA_URI = "benchmarks/schema/comparisons-v1.schema.json"
+FACT_SCHEMA_URIS = {
+ 1: {"docs/schema/benchmark-facts-v1.schema.json"},
+ 2: {
+ "benchmarks/schema/facts-v2.schema.json",
+ "docs/schema/benchmark-facts-v2.schema.json",
+ },
+}
+PARITY_JOIN_ID = "parity_manifest_and_contract_v1"
+CAPABILITY_DELTA_JOIN_ID = "capability_delta_manifest_v1"
+MEDIAN_FORMULA_ID = "median_elapsed_ms_v1"
+RATIO_FORMULA_ID = "left_elapsed_divided_by_right_elapsed_v1"
+LIFECYCLE_STEP_IDS = (
+ "initial_index",
+ "incremental_index",
+ "clean_rebuild_index",
+)
+REPO_ROOT = Path(__file__).resolve().parents[1]
+TERMINOLOGY_PATH = Path(__file__).with_name("terminology.json")
+
+
+def canonical_json_bytes(value: Any) -> bytes:
+ return json.dumps(value, separators=(",", ":"), sort_keys=True).encode("utf-8")
+
+
+def content_id(value: Any, length: int = 24) -> str:
+ return hashlib.sha256(canonical_json_bytes(value)).hexdigest()[:length]
+
+
+def portable_source_path(path: Path) -> str:
+ resolved = path.resolve()
+ try:
+ return str(resolved.relative_to(REPO_ROOT))
+ except ValueError:
+ parent_id = content_id(str(resolved.parent), length=12)
+ return f"external/{parent_id}/{resolved.name}"
+
+
+def portable_value(value: Any) -> Any:
+ if isinstance(value, dict):
+ return {key: portable_value(child) for key, child in value.items()}
+ if isinstance(value, list):
+ return [portable_value(child) for child in value]
+ if isinstance(value, str):
+ if Path(value).is_absolute():
+ return portable_source_path(Path(value))
+ windows_path = PureWindowsPath(value)
+ if windows_path.is_absolute():
+ parent_id = content_id(str(windows_path.parent), length=12)
+ return f"external/{parent_id}/{windows_path.name}"
+ return value
+
+
+def is_unknown(value: Any) -> bool:
+ if isinstance(value, dict):
+ if value.get("status") == "unknown":
+ return True
+ return any(is_unknown(child) for child in value.values())
+ if isinstance(value, list):
+ return any(is_unknown(child) for child in value)
+ return False
+
+
+def load_fact_bundle(path: Path) -> dict[str, Any]:
+ document = json.loads(path.read_text(encoding="utf-8"))
+ if not isinstance(document, dict):
+ raise ValueError(f"fact bundle must be an object: {path}")
+ version = document.get("schema_version")
+ expected_uris = FACT_SCHEMA_URIS.get(version)
+ if expected_uris is None or document.get("$schema") not in expected_uris:
+ raise ValueError(f"unsupported or mismatched fact schema in {path}")
+ for table in ("runs", "steps", "results", "artifacts"):
+ if not isinstance(document.get(table), list):
+ raise ValueError(f"fact bundle {table} must be an array: {path}")
+ if len(document["runs"]) != 1 or not isinstance(document["runs"][0], dict):
+ raise ValueError(f"fact bundle must contain one run row: {path}")
+ run_id = document["runs"][0].get("run_id")
+ if not isinstance(run_id, str):
+ raise ValueError(f"fact bundle run_id is invalid: {path}")
+ for field, expected_type in (
+ ("cell_label", str),
+ ("mode", str),
+ ("implementation", dict),
+ ("capabilities", dict),
+ ("scope", dict),
+ ("cache", dict),
+ ("host", dict),
+ ("harness", dict),
+ ):
+ if not isinstance(document["runs"][0].get(field), expected_type):
+ raise ValueError(f"fact bundle run {field} is invalid: {path}")
+ if version == 2:
+ for field in (
+ "terminology_version",
+ "terminology_sha256",
+ "generator_revision",
+ ):
+ if not isinstance(document.get(field), str):
+ raise ValueError(f"fact bundle {field} is invalid: {path}")
+ for table in ("steps", "results", "artifacts"):
+ if any(
+ not isinstance(row, dict) or row.get("run_id") != run_id
+ for row in document[table]
+ ):
+ raise ValueError(f"fact bundle {table} has a foreign run_id: {path}")
+ return document
+
+
+def result_contract_projection(
+ results: Iterable[dict[str, Any]],
+) -> list[dict[str, Any]]:
+ projection = []
+ for row in results:
+ value = row.get("value")
+ contract: Any = None
+ if isinstance(value, dict):
+ contract = {
+ key: value[key]
+ for key in (
+ "scenario",
+ "criterion",
+ "expected_substring",
+ "applicable",
+ "policy",
+ "declared_stale_views",
+ "excluded_edge_types",
+ )
+ if key in value
+ }
+ projection.append(
+ {
+ "result_id": row.get("result_id"),
+ "kind": row.get("kind"),
+ "contract": contract,
+ }
+ )
+ return sorted(projection, key=lambda row: (str(row["result_id"]), str(row["kind"])))
+
+
+def implementation_projection(implementation: Any) -> dict[str, Any]:
+ if not isinstance(implementation, dict):
+ return {}
+ binary = implementation.get("binary")
+ return {
+ "revision": implementation.get("revision"),
+ "binary": (
+ {key: binary.get(key) for key in ("sha256", "size_bytes") if key in binary}
+ if isinstance(binary, dict)
+ else {}
+ ),
+ "build": implementation.get("build"),
+ }
+
+
+def capability_projection(capabilities: Any) -> dict[str, Any]:
+ if not isinstance(capabilities, dict):
+ return {}
+ return {
+ key: capabilities.get(key)
+ for key in ("values", "completeness")
+ if key in capabilities
+ }
+
+
+def harness_projection(harness: Any) -> dict[str, Any]:
+ if not isinstance(harness, dict):
+ return {}
+ return {
+ key: harness.get(key)
+ for key in ("fact_schema_version", "sha256")
+ if key in harness
+ }
+
+
+def benchmark_contract_projection(
+ bundle: dict[str, Any], run: dict[str, Any]
+) -> dict[str, Any]:
+ return {
+ "fact_schema_version": bundle.get("schema_version"),
+ "terminology_version": bundle.get(
+ "terminology_version",
+ {"status": "unknown", "reason": "fact_schema_v1_did_not_record_it"},
+ ),
+ "terminology_sha256": bundle.get(
+ "terminology_sha256",
+ {"status": "unknown", "reason": "fact_schema_v1_did_not_record_it"},
+ ),
+ "generator_revision": bundle.get(
+ "generator_revision",
+ {"status": "unknown", "reason": "fact_schema_v1_did_not_record_it"},
+ ),
+ "harness": harness_projection(run.get("harness")),
+ }
+
+
+def cell_group_identity(
+ bundle: dict[str, Any], run: dict[str, Any], results: list[dict[str, Any]]
+) -> dict[str, Any]:
+ return {
+ "label": run.get("cell_label"),
+ "mode": run.get("mode"),
+ "implementation": implementation_projection(run.get("implementation")),
+ "capabilities": capability_projection(run.get("capabilities")),
+ "scope": run.get("scope"),
+ "cache": run.get("cache"),
+ "host": run.get("host"),
+ "benchmark_contract": benchmark_contract_projection(bundle, run),
+ "result_contract": result_contract_projection(results),
+ }
+
+
+def aggregate_steps(step_rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ grouped: dict[str, list[dict[str, Any]]] = {}
+ for row in step_rows:
+ step_id = row.get("step_id")
+ elapsed = row.get("elapsed_ms")
+ if (
+ isinstance(step_id, str)
+ and isinstance(elapsed, (int, float))
+ and not isinstance(elapsed, bool)
+ ):
+ grouped.setdefault(step_id, []).append(row)
+ aggregates = []
+ for step_id, rows in sorted(grouped.items()):
+ values = [float(row["elapsed_ms"]) for row in rows]
+ aggregates.append(
+ {
+ "step_id": step_id,
+ "formula_id": MEDIAN_FORMULA_ID,
+ "count": len(values),
+ "median_elapsed_ms": statistics.median(values),
+ "min_elapsed_ms": min(values),
+ "max_elapsed_ms": max(values),
+ "source_occurrence_ids": sorted(
+ str(row["occurrence_id"]) for row in rows
+ ),
+ }
+ )
+ return aggregates
+
+
+def aggregate_results(result_rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ grouped: dict[tuple[str, str], list[dict[str, Any]]] = {}
+ for row in result_rows:
+ result_id = row.get("result_id")
+ kind = row.get("kind")
+ if isinstance(result_id, str) and isinstance(kind, str):
+ grouped.setdefault((result_id, kind), []).append(row)
+ aggregates = []
+ for (result_id, kind), rows in sorted(grouped.items()):
+ statuses = [str(row.get("status")) for row in rows]
+ aggregates.append(
+ {
+ "result_id": result_id,
+ "kind": kind,
+ "statuses": statuses,
+ "all_passed": bool(statuses)
+ and all(status == "passed" for status in statuses),
+ "source_run_ids": sorted(str(row["run_id"]) for row in rows),
+ }
+ )
+ return aggregates
+
+
+def aggregate_cells(
+ sources: list[tuple[Path, dict[str, Any]]],
+) -> list[dict[str, Any]]:
+ groups: dict[str, dict[str, Any]] = {}
+ seen_run_ids: dict[str, Path] = {}
+ for path, bundle in sources:
+ run = bundle["runs"][0]
+ run_id = run["run_id"]
+ previous_path = seen_run_ids.get(run_id)
+ if previous_path is not None:
+ raise ValueError(
+ f"duplicate fact run_id {run_id}: {previous_path} and {path}"
+ )
+ seen_run_ids[run_id] = path
+ identity = cell_group_identity(bundle, run, bundle["results"])
+ group_id = content_id(identity)
+ group = groups.setdefault(
+ group_id,
+ {
+ "cell_group_id": group_id,
+ "label": run.get("cell_label"),
+ "mode": run.get("mode"),
+ "implementation": identity["implementation"],
+ "capabilities": identity["capabilities"],
+ "scope": run.get("scope"),
+ "cache": run.get("cache"),
+ "host": run.get("host"),
+ "benchmark_contract": identity["benchmark_contract"],
+ "result_contract": identity["result_contract"],
+ "source_run_ids": [],
+ "source_fact_paths": [],
+ "_steps": [],
+ "_results": [],
+ },
+ )
+ group["source_run_ids"].append(run["run_id"])
+ group["source_fact_paths"].append(portable_source_path(path))
+ group["_steps"].extend(bundle["steps"])
+ group["_results"].extend(bundle["results"])
+ cells = []
+ for group in groups.values():
+ group["source_run_ids"].sort()
+ group["source_fact_paths"].sort()
+ group["step_aggregates"] = aggregate_steps(group.pop("_steps"))
+ group["result_aggregates"] = aggregate_results(group.pop("_results"))
+ cells.append(group)
+ return sorted(
+ cells,
+ key=lambda cell: (
+ str(cell.get("label")),
+ str(cell.get("implementation", {}).get("revision")),
+ cell["cell_group_id"],
+ ),
+ )
+
+
+def capability_differences(left: Any, right: Any) -> list[dict[str, Any]]:
+ left_values = left.get("values", {}) if isinstance(left, dict) else {}
+ right_values = right.get("values", {}) if isinstance(right, dict) else {}
+ if not isinstance(left_values, dict) or not isinstance(right_values, dict):
+ return []
+ return [
+ {
+ "capability_id": key,
+ "left": left_values.get(key),
+ "right": right_values.get(key),
+ }
+ for key in sorted(set(left_values) | set(right_values))
+ if left_values.get(key) != right_values.get(key)
+ ]
+
+
+def manifest_equal(left: dict[str, Any], right: dict[str, Any], key: str) -> bool:
+ return canonical_json_bytes(left.get(key)) == canonical_json_bytes(right.get(key))
+
+
+def capabilities_complete(cell: dict[str, Any]) -> bool:
+ capabilities = cell.get("capabilities")
+ return (
+ isinstance(capabilities, dict)
+ and capabilities.get("completeness") == "complete_declared_cell"
+ and not is_unknown(capabilities)
+ )
+
+
+def common_step_ratios(
+ left: dict[str, Any], right: dict[str, Any]
+) -> list[dict[str, Any]]:
+ left_steps = {row["step_id"]: row for row in left["step_aggregates"]}
+ right_steps = {row["step_id"]: row for row in right["step_aggregates"]}
+ rows = []
+ for step_id in sorted(set(left_steps) & set(right_steps)):
+ numerator = left_steps[step_id]["median_elapsed_ms"]
+ denominator = right_steps[step_id]["median_elapsed_ms"]
+ rows.append(
+ {
+ "step_id": step_id,
+ "formula_id": RATIO_FORMULA_ID,
+ "left_median_elapsed_ms": numerator,
+ "right_median_elapsed_ms": denominator,
+ "left_elapsed_divided_by_right_elapsed": (
+ numerator / denominator if denominator > 0 else None
+ ),
+ "left_source_occurrence_ids": left_steps[step_id][
+ "source_occurrence_ids"
+ ],
+ "right_source_occurrence_ids": right_steps[step_id][
+ "source_occurrence_ids"
+ ],
+ }
+ )
+ return rows
+
+
+def classify_pair(left: dict[str, Any], right: dict[str, Any]) -> dict[str, Any]:
+ same_mode = left.get("mode") == right.get("mode")
+ same_scope = manifest_equal(left, right, "scope")
+ same_cache = manifest_equal(left, right, "cache")
+ same_host = manifest_equal(left, right, "host")
+ same_benchmark_contract = manifest_equal(left, right, "benchmark_contract")
+ same_contract = manifest_equal(left, right, "result_contract")
+ same_capabilities = manifest_equal(left, right, "capabilities")
+ complete = capabilities_complete(left) and capabilities_complete(right)
+ manifest_unknown = any(
+ is_unknown(cell.get(key))
+ for cell in (left, right)
+ for key in (
+ "scope",
+ "cache",
+ "host",
+ "benchmark_contract",
+ "result_contract",
+ )
+ )
+ common = {
+ "comparison_id": content_id(
+ {
+ "left": left["cell_group_id"],
+ "right": right["cell_group_id"],
+ }
+ ),
+ "left_cell_group_id": left["cell_group_id"],
+ "right_cell_group_id": right["cell_group_id"],
+ "left_source_run_ids": left["source_run_ids"],
+ "right_source_run_ids": right["source_run_ids"],
+ }
+ if (
+ same_mode
+ and same_scope
+ and same_cache
+ and same_host
+ and same_benchmark_contract
+ and same_contract
+ and same_capabilities
+ and complete
+ and not manifest_unknown
+ ):
+ return {
+ **common,
+ "comparison_kind": "parity_comparison",
+ "join_id": PARITY_JOIN_ID,
+ "ratio_allowed": True,
+ "capability_differences": [],
+ "step_comparisons": common_step_ratios(left, right),
+ "limitations": [],
+ }
+ differences = capability_differences(
+ left.get("capabilities"), right.get("capabilities")
+ )
+ if (
+ same_mode
+ and same_scope
+ and same_cache
+ and same_host
+ and same_benchmark_contract
+ and same_contract
+ and complete
+ and differences
+ ):
+ limitations = []
+ if manifest_unknown:
+ limitations.append(
+ "scope, cache, host, benchmark-contract, or correctness metadata "
+ "contains unknown values"
+ )
+ return {
+ **common,
+ "comparison_kind": "capability_delta_comparison",
+ "join_id": CAPABILITY_DELTA_JOIN_ID,
+ "ratio_allowed": False,
+ "capability_differences": differences,
+ "step_comparisons": [],
+ "limitations": limitations,
+ }
+ reasons = []
+ for matched, reason in (
+ (same_mode, "workload mode differs"),
+ (same_scope, "scope manifest differs"),
+ (same_cache, "cache manifest differs"),
+ (same_host, "host manifest differs"),
+ (same_benchmark_contract, "benchmark contract differs"),
+ (same_contract, "correctness contract differs"),
+ (complete, "capability manifest is incomplete or unknown"),
+ ):
+ if not matched:
+ reasons.append(reason)
+ if manifest_unknown:
+ reasons.append(
+ "required manifest or benchmark contract contains unknown values"
+ )
+ return {
+ **common,
+ "comparison_kind": "not_eligible",
+ "join_id": None,
+ "ratio_allowed": False,
+ "capability_differences": differences,
+ "step_comparisons": [],
+ "limitations": sorted(set(reasons)),
+ }
+
+
+def generate_comparison_document(
+ sources: list[tuple[Path, dict[str, Any]]],
+ *,
+ generated_at_utc: str,
+ terminology_version: str,
+ terminology_sha256: str,
+) -> dict[str, Any]:
+ cells = aggregate_cells(sources)
+ comparisons = [
+ classify_pair(cells[left], cells[right])
+ for left in range(len(cells))
+ for right in range(left + 1, len(cells))
+ ]
+ source_bundles = [
+ {
+ "path": portable_source_path(path),
+ "sha256": hashlib.sha256(path.read_bytes()).hexdigest(),
+ "schema_version": bundle["schema_version"],
+ "run_id": bundle["runs"][0]["run_id"],
+ }
+ for path, bundle in sorted(sources, key=lambda item: str(item[0]))
+ ]
+ return {
+ "$schema": SCHEMA_URI,
+ "schema_version": SCHEMA_VERSION,
+ "generated_at_utc": generated_at_utc,
+ "terminology_version": terminology_version,
+ "terminology_sha256": terminology_sha256,
+ "joins": [
+ {
+ "join_id": PARITY_JOIN_ID,
+ "fields": [
+ "mode",
+ "capabilities",
+ "scope",
+ "cache",
+ "host",
+ "benchmark_contract",
+ "result_contract",
+ ],
+ "unknown_values_allowed": False,
+ "ratio_allowed": True,
+ },
+ {
+ "join_id": CAPABILITY_DELTA_JOIN_ID,
+ "fields": [
+ "mode",
+ "scope",
+ "cache",
+ "host",
+ "benchmark_contract",
+ "result_contract",
+ ],
+ "unknown_values_allowed": True,
+ "ratio_allowed": False,
+ },
+ ],
+ "formulas": [
+ {
+ "formula_id": MEDIAN_FORMULA_ID,
+ "expression": "versioned median of elapsed_ms for one cell group and step_id",
+ },
+ {
+ "formula_id": RATIO_FORMULA_ID,
+ "expression": "left median elapsed_ms / right median elapsed_ms",
+ },
+ ],
+ "source_bundles": source_bundles,
+ "cell_groups": portable_value(cells),
+ "comparisons": comparisons,
+ "lifecycle_rows": [
+ {
+ "cell_group_id": cell["cell_group_id"],
+ "label": cell["label"],
+ "source_run_ids": cell["source_run_ids"],
+ "steps": [
+ step
+ for step in cell["step_aggregates"]
+ if step["step_id"] in LIFECYCLE_STEP_IDS
+ ],
+ "wall_time_rule": (
+ "each listed lifecycle step uses its recorded outer elapsed_ms; "
+ "component spans are not summed"
+ ),
+ }
+ for cell in cells
+ ],
+ }
+
+
+def render_markdown(document: dict[str, Any]) -> str:
+ comparisons = document["comparisons"]
+ parity = [
+ row for row in comparisons if row["comparison_kind"] == "parity_comparison"
+ ]
+ deltas = [
+ row
+ for row in comparisons
+ if row["comparison_kind"] == "capability_delta_comparison"
+ ]
+ rejected = [row for row in comparisons if row["comparison_kind"] == "not_eligible"]
+ lines = [
+ "## Fact-derived comparison audit",
+ "",
+ f"- Source fact bundles: {len(document['source_bundles'])}",
+ f"- Cell groups: {len(document['cell_groups'])}",
+ f"- Apples-to-apples parity pairs: {len(parity)}",
+ f"- Apples-to-oranges capability-delta pairs: {len(deltas)}",
+ f"- Ineligible pairs: {len(rejected)}",
+ "",
+ "Ratios appear only for parity pairs. Capability-delta rows deliberately carry no "
+ "cross-implementation speed ratio. Component spans remain separate when their "
+ "recorded boundaries cannot prove serial execution.",
+ "",
+ "### Lifecycle fact table",
+ "",
+ "| Configuration | Step | Median ms | Repetitions | Source occurrence IDs |",
+ "|---|---|---:|---:|---|",
+ ]
+ for lifecycle in document["lifecycle_rows"]:
+ lines.extend(
+ (
+ f"| {lifecycle['label']} | `{step['step_id']}` | "
+ f"{step['median_elapsed_ms']:.3f} | {step['count']} | "
+ f"`{', '.join(step['source_occurrence_ids'])}` |"
+ )
+ for step in lifecycle["steps"]
+ )
+ lines.extend(
+ (
+ "",
+ "The adjacent comparison JSON retains every join ID, formula ID, source run ID, "
+ "result contract, step occurrence ID, capability manifest, scope manifest, and "
+ "cache manifest used to classify these rows.",
+ "",
+ )
+ )
+ return "\n".join(lines)
+
+
+def atomic_write_text(path: Path, text: str) -> None:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ descriptor, temporary_name = tempfile.mkstemp(
+ prefix=f".{path.name}.", suffix=".tmp", dir=path.parent
+ )
+ temporary = Path(temporary_name)
+ try:
+ with os.fdopen(descriptor, "w", encoding="utf-8") as stream:
+ stream.write(text)
+ stream.flush()
+ os.fsync(stream.fileno())
+ os.replace(temporary, path)
+ finally:
+ if temporary.exists():
+ temporary.unlink()
+
+
+def parse_args() -> argparse.Namespace:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "--fact",
+ action="append",
+ type=Path,
+ required=True,
+ help="Fact bundle to include; repeat for every completed run.",
+ )
+ parser.add_argument("--out", type=Path, required=True)
+ parser.add_argument("--markdown-out", type=Path, required=True)
+ return parser.parse_args()
+
+
+def main() -> int:
+ args = parse_args()
+ try:
+ sources = [(path, load_fact_bundle(path)) for path in args.fact]
+ terminology = json.loads(TERMINOLOGY_PATH.read_text(encoding="utf-8"))
+ document = generate_comparison_document(
+ sources,
+ generated_at_utc=datetime.now(timezone.utc).isoformat(),
+ terminology_version=terminology["terminology_version"],
+ terminology_sha256=hashlib.sha256(
+ canonical_json_bytes(terminology)
+ ).hexdigest(),
+ )
+ atomic_write_text(
+ args.out, json.dumps(document, indent=2, sort_keys=True) + "\n"
+ )
+ atomic_write_text(args.markdown_out, render_markdown(document))
+ except (OSError, ValueError, json.JSONDecodeError) as exc:
+ print(f"error: cannot generate fact comparisons: {exc}", file=sys.stderr)
+ return 1
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/benchmarks/generate_config_keys.py b/benchmarks/generate_config_keys.py
new file mode 100644
index 000000000..86bf3c09d
--- /dev/null
+++ b/benchmarks/generate_config_keys.py
@@ -0,0 +1,205 @@
+#!/usr/bin/env python3
+"""Generate the benchmark config-key allowlist from the C sources.
+
+Why this exists
+---------------
+`cbm_config_value_is_valid` (src/cli/cli.c) accepts any key absent from
+CBM_CONFIG_REGISTRY so that extension/private keys survive:
+
+ return true; /* preserve extension/private keys not owned by this registry */
+
+A mistyped or removed key is therefore written to the config DB, exits 0, and is
+recorded in a benchmark cell's `parameters.config_overrides` as if it had taken
+effect. The run then reports a difference of exactly zero with no warning, which
+is indistinguishable from "this knob does not matter". Every tuning campaign
+built on that is invalid.
+
+The benchmark harness cannot rely on the product to reject typos, so it validates
+against this generated allowlist instead (see apply_config_overrides in
+run_benchmark.py). Generating rather than hand-maintaining keeps the list honest:
+regenerate after any config change and the diff shows exactly what moved.
+
+Two key populations are emitted, because they differ in how the product treats
+them:
+
+ registry -- listed in CBM_CONFIG_REGISTRY; `config set` range-validates these.
+ consumed -- read through cbm_config_get_*() but absent from the registry, so
+ `config set` accepts any value without range validation. These are
+ real keys; rejecting them would break valid experiments.
+
+Usage:
+ python3 benchmarks/generate_config_keys.py # write config-keys-v1.json
+ python3 benchmarks/generate_config_keys.py --check # verify it is up to date
+"""
+
+from __future__ import annotations
+
+import argparse
+import json
+import re
+import subprocess
+import sys
+from pathlib import Path
+from typing import Any
+
+ROOT = Path(__file__).resolve().parents[1]
+OUT_PATH = Path(__file__).resolve().with_name("config-keys-v1.json")
+SCHEMA_VERSION = 1
+
+# Literals that are macro *values* (enum members, sentinels) rather than key
+# names. They match the key-shaped pattern but are never valid `config set` keys.
+NON_KEY_LITERALS = frozenset(
+ {
+ "after_publish",
+ "always",
+ "always_rehash",
+ "at_publish",
+ "cached_exact",
+ "classic",
+ "fast_mode_indexes_only",
+ "full_rebuild",
+ "manual",
+ "never",
+ "off",
+ "small_deltas",
+ "streamlined",
+ "true",
+ "false",
+ }
+)
+
+KEY_SHAPE = re.compile(r"[a-z][a-z0-9_\-]*\Z")
+DEFINE_RE = re.compile(r'^#define\s+(CBM_CONFIG_[A-Z0-9_]+)\s+"([^"]*)"', re.M)
+REGISTRY_ENTRY_RE = re.compile(r"\{\s*(CBM_CONFIG_[A-Z0-9_]+)\s*,")
+REGISTRY_DECL = "const cbm_config_entry_t CBM_CONFIG_REGISTRY[] = {"
+
+
+def read(path: Path) -> str:
+ return path.read_text(encoding="utf-8", errors="replace")
+
+
+def macro_table(root: Path) -> dict[str, str]:
+ """Map every CBM_CONFIG_* macro to its string literal, across all headers."""
+ table: dict[str, str] = {}
+ for header in sorted(root.glob("src/**/*.h")):
+ for match in DEFINE_RE.finditer(read(header)):
+ table.setdefault(match.group(1), match.group(2))
+ if not table:
+ raise SystemExit("no CBM_CONFIG_* macros found; wrong repository root?")
+ return table
+
+
+def registry_macros(root: Path) -> list[str]:
+ """First field of every CBM_CONFIG_REGISTRY entry, in declaration order."""
+ source = read(root / "src" / "cli" / "cli.c")
+ try:
+ start = source.index(REGISTRY_DECL)
+ except ValueError as exc: # pragma: no cover - structural change in cli.c
+ raise SystemExit(f"cannot locate {REGISTRY_DECL!r} in cli.c") from exc
+ end = source.index("\n};", start)
+ return REGISTRY_ENTRY_RE.findall(source[start:end])
+
+
+def consumed_macros(root: Path) -> set[str]:
+ """Macros passed to a cbm_config_get_*() call anywhere in the C sources."""
+ call = re.compile(r"cbm_config_get(?:_[a-z]+)?\s*\(\s*[^,]+,\s*(CBM_CONFIG_[A-Z0-9_]+)")
+ found: set[str] = set()
+ for source in sorted(root.glob("src/**/*.c")):
+ found.update(call.findall(read(source)))
+ return found
+
+
+def git_revision(root: Path) -> str:
+ proc = subprocess.run(
+ ["git", "rev-parse", "HEAD"],
+ cwd=root,
+ text=True,
+ capture_output=True,
+ check=False,
+ )
+ revision = proc.stdout.strip()
+ return revision if len(revision) == 40 else "unknown"
+
+
+def build_document(root: Path) -> dict[str, Any]:
+ macros = macro_table(root)
+ registry_order = registry_macros(root)
+
+ unresolved = sorted({m for m in registry_order if m not in macros})
+ if unresolved:
+ raise SystemExit(f"registry macros with no string literal: {unresolved}")
+
+ registry = sorted({macros[m] for m in registry_order})
+ registry_set = set(registry)
+
+ consumed = sorted(
+ {
+ macros[m]
+ for m in consumed_macros(root)
+ if m in macros
+ and macros[m] not in registry_set
+ and macros[m] not in NON_KEY_LITERALS
+ and KEY_SHAPE.match(macros[m])
+ }
+ )
+
+ return {
+ "schema_version": SCHEMA_VERSION,
+ "generated_by": "benchmarks/generate_config_keys.py",
+ "source_revision": git_revision(root),
+ "note": (
+ "Allowlist for benchmark --config overrides. cbm_config_value_is_valid "
+ "in src/cli/cli.c returns true for keys absent from CBM_CONFIG_REGISTRY, "
+ "so the product cannot reject a typo; the harness rejects it instead."
+ ),
+ "registry_note": "Listed in CBM_CONFIG_REGISTRY; `config set` range-validates these.",
+ "consumed_note": (
+ "Read via cbm_config_get_*() but absent from CBM_CONFIG_REGISTRY, so "
+ "`config set` accepts any value unvalidated. Real keys; still allowed."
+ ),
+ "registry_count": len(registry),
+ "consumed_count": len(consumed),
+ "registry": registry,
+ "consumed_unregistered": consumed,
+ "keys": sorted(registry_set | set(consumed)),
+ }
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "--check",
+ action="store_true",
+ help="Exit non-zero if the checked-in file differs from freshly generated output.",
+ )
+ args = parser.parse_args()
+
+ document = build_document(ROOT)
+ rendered = json.dumps(document, indent=2, sort_keys=False) + "\n"
+
+ if args.check:
+ if not OUT_PATH.is_file():
+ print(f"missing {OUT_PATH}", file=sys.stderr)
+ return 1
+ current = OUT_PATH.read_text(encoding="utf-8")
+ # source_revision moves with every commit; compare the key sets only.
+ old = json.loads(current)
+ if old.get("keys") != document["keys"]:
+ added = sorted(set(document["keys"]) - set(old.get("keys", [])))
+ removed = sorted(set(old.get("keys", [])) - set(document["keys"]))
+ print(f"config keys changed: added={added} removed={removed}", file=sys.stderr)
+ return 1
+ print(f"up to date: {len(document['keys'])} keys")
+ return 0
+
+ OUT_PATH.write_text(rendered, encoding="utf-8")
+ print(
+ f"wrote {OUT_PATH.name}: {document['registry_count']} registry "
+ f"+ {document['consumed_count']} consumed-unregistered "
+ f"= {len(document['keys'])} keys"
+ )
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/benchmarks/generate_terminology.py b/benchmarks/generate_terminology.py
new file mode 100755
index 000000000..813a7e75e
--- /dev/null
+++ b/benchmarks/generate_terminology.py
@@ -0,0 +1,268 @@
+#!/usr/bin/env python3
+"""Validate benchmark terminology and render its checked-in derived views."""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import json
+from pathlib import Path
+import re
+import sys
+from typing import Any
+
+
+REPO_ROOT = Path(__file__).resolve().parents[1]
+REGISTRY_PATH = Path(__file__).with_name("terminology.json")
+MARKDOWN_PATH = REPO_ROOT / "docs" / "BENCHMARK_TERMINOLOGY.md"
+HEADER_PATH = REPO_ROOT / "src" / "foundation" / "profile_terms_generated.h"
+REQUIRED_ENTRY_FIELDS = (
+ "term_id",
+ "display_name",
+ "definition",
+ "status",
+ "kind",
+ "data_type",
+ "allowed_values_or_range",
+ "unit",
+ "clock_or_cpu_scope",
+ "boundary_semantics",
+ "aggregation_rule",
+ "concurrency_rule",
+ "missing_or_unsupported_behavior",
+ "configuration_precedence",
+ "capability_or_freshness_implications",
+ "source_anchors",
+ "introduced_version",
+ "deprecated_replacement",
+ "examples",
+)
+TERM_ID_PATTERN = re.compile(r"^[a-z][a-z0-9_]*$")
+
+
+def canonical_json_bytes(value: Any) -> bytes:
+ return json.dumps(value, separators=(",", ":"), sort_keys=True).encode("utf-8")
+
+
+def load_registry(path: Path = REGISTRY_PATH) -> dict[str, Any]:
+ with path.open(encoding="utf-8") as stream:
+ registry = json.load(stream)
+ validate_registry(registry)
+ return registry
+
+
+def validate_registry(registry: dict[str, Any]) -> None:
+ if registry.get("schema_version") != 1:
+ raise ValueError("benchmark terminology schema_version must equal 1")
+ version = registry.get("terminology_version")
+ if not isinstance(version, str) or not re.fullmatch(r"[1-9]\d*\.\d+\.\d+", version):
+ raise ValueError("terminology_version must be a semantic version")
+ entries = registry.get("entries")
+ if not isinstance(entries, list) or not entries:
+ raise ValueError("benchmark terminology entries must be a non-empty array")
+ seen: set[str] = set()
+ for index, entry in enumerate(entries):
+ if not isinstance(entry, dict):
+ raise ValueError(f"terminology entry {index} must be an object")
+ missing = [field for field in REQUIRED_ENTRY_FIELDS if field not in entry]
+ if missing:
+ raise ValueError(
+ f"terminology entry {index} is missing fields: {', '.join(missing)}"
+ )
+ term_id = entry["term_id"]
+ if not isinstance(term_id, str) or not TERM_ID_PATTERN.fullmatch(term_id):
+ raise ValueError(f"invalid term_id at entry {index}: {term_id!r}")
+ if term_id in seen:
+ raise ValueError(f"duplicate benchmark term_id: {term_id}")
+ seen.add(term_id)
+ if entry["status"] not in {"existing", "proposed", "deprecated"}:
+ raise ValueError(f"{term_id}: invalid status {entry['status']!r}")
+ for field in (
+ "display_name",
+ "definition",
+ "kind",
+ "data_type",
+ "allowed_values_or_range",
+ "unit",
+ "clock_or_cpu_scope",
+ "boundary_semantics",
+ "aggregation_rule",
+ "concurrency_rule",
+ "missing_or_unsupported_behavior",
+ "configuration_precedence",
+ "capability_or_freshness_implications",
+ "introduced_version",
+ ):
+ if not isinstance(entry[field], str) or not entry[field].strip():
+ raise ValueError(f"{term_id}: {field} must be a non-empty string")
+ if not isinstance(entry["source_anchors"], list) or not entry["source_anchors"]:
+ raise ValueError(f"{term_id}: source_anchors must be a non-empty array")
+ if not all(
+ isinstance(anchor, str) and anchor.strip()
+ for anchor in entry["source_anchors"]
+ ):
+ raise ValueError(f"{term_id}: source_anchors contains an invalid anchor")
+ if not isinstance(entry["examples"], list):
+ raise ValueError(f"{term_id}: examples must be an array")
+ replacement = entry["deprecated_replacement"]
+ if replacement is not None and (
+ not isinstance(replacement, str)
+ or not TERM_ID_PATTERN.fullmatch(replacement)
+ ):
+ raise ValueError(f"{term_id}: deprecated_replacement is invalid")
+ if entry["status"] == "deprecated" and replacement is None:
+ raise ValueError(f"{term_id}: deprecated term requires a replacement")
+ for entry in entries:
+ replacement = entry["deprecated_replacement"]
+ if replacement is not None and replacement not in seen:
+ raise ValueError(
+ f"{entry['term_id']}: replacement {replacement!r} is not registered"
+ )
+ step_id_order = registry.get("step_id_order")
+ if not isinstance(step_id_order, list) or not step_id_order:
+ raise ValueError("step_id_order must be a non-empty array")
+ if len(step_id_order) != len(set(step_id_order)):
+ raise ValueError("step_id_order contains a duplicate")
+ registered_step_ids = {
+ entry["term_id"] for entry in entries if entry["kind"] == "step_id"
+ }
+ if set(step_id_order) != registered_step_ids:
+ raise ValueError(
+ "step_id_order must contain every registered step_id exactly once"
+ )
+
+
+def registry_sha256(registry: dict[str, Any]) -> str:
+ return hashlib.sha256(canonical_json_bytes(registry)).hexdigest()
+
+
+def markdown_cell(value: str) -> str:
+ return value.replace("|", "\\|").replace("\n", " ")
+
+
+def render_markdown(registry: dict[str, Any]) -> str:
+ digest = registry_sha256(registry)
+ lines = [
+ "# Benchmark terminology",
+ "",
+ "",
+ "",
+ f"- Terminology version: `{registry['terminology_version']}`",
+ "- Canonical registry: `benchmarks/terminology.json`",
+ f"- Canonical-content SHA-256: `{digest}`",
+ "",
+ "Every definition below is normative. Parent relations describe containment, "
+ "not execution order; overlapping elapsed spans are work-time evidence and must "
+ "not be summed into lifecycle wall time.",
+ "",
+ ]
+ by_kind: dict[str, list[dict[str, Any]]] = {}
+ for entry in registry["entries"]:
+ by_kind.setdefault(entry["kind"], []).append(entry)
+ for kind in sorted(by_kind):
+ lines.extend((f"## {kind.replace('_', ' ').title()}", ""))
+ lines.extend(
+ (
+ "| ID | Normative definition | Status; type; unit | "
+ "Boundaries; aggregation; concurrency | Missing/configuration/effect | Sources |",
+ "|---|---|---|---|---|---|",
+ )
+ )
+ for entry in sorted(by_kind[kind], key=lambda item: item["term_id"]):
+ identity = f"`{entry['term_id']}` {entry['display_name']}"
+ type_cell = (
+ f"{entry['status']}; {entry['data_type']}; "
+ f"{entry['allowed_values_or_range']}; {entry['unit']}; "
+ f"scope: {entry['clock_or_cpu_scope']}"
+ )
+ timing_cell = (
+ f"boundaries: {entry['boundary_semantics']}; "
+ f"aggregation: {entry['aggregation_rule']}; "
+ f"concurrency: {entry['concurrency_rule']}"
+ )
+ behavior_cell = (
+ f"missing/unsupported: {entry['missing_or_unsupported_behavior']}; "
+ f"configuration: {entry['configuration_precedence']}; "
+ f"effect: {entry['capability_or_freshness_implications']}"
+ )
+ sources = ", ".join(f"`{anchor}`" for anchor in entry["source_anchors"])
+ lines.append(
+ "| "
+ + " | ".join(
+ markdown_cell(value)
+ for value in (
+ identity,
+ entry["definition"],
+ type_cell,
+ timing_cell,
+ behavior_cell,
+ sources,
+ )
+ )
+ + " |"
+ )
+ lines.append("")
+ return "\n".join(lines).rstrip() + "\n"
+
+
+def render_header(registry: dict[str, Any]) -> str:
+ step_ids = registry["step_id_order"]
+ macro_lines = ["#define CBM_BENCHMARK_STEP_IDS(X)"]
+ macro_lines.extend(
+ f' X({term_id.upper()}, "{term_id}")' for term_id in step_ids
+ )
+ # Emit the repository's clang-format-stable escaped-newline layout so the
+ # generator check and format gate remain composable on every platform.
+ continuation_width = max(len(line) for line in macro_lines[:-1])
+ rows = " \\\n".join(
+ line.ljust(continuation_width) for line in macro_lines[:-1]
+ )
+ rows += f" \\\n{macro_lines[-1]}"
+ return (
+ "/* Generated by benchmarks/generate_terminology.py; do not edit. */\n"
+ "#ifndef CBM_PROFILE_TERMS_GENERATED_H\n"
+ "#define CBM_PROFILE_TERMS_GENERATED_H\n\n"
+ f'#define CBM_BENCHMARK_TERMINOLOGY_VERSION "{registry["terminology_version"]}"\n'
+ "#define CBM_BENCHMARK_TERMINOLOGY_SHA256 \\\n"
+ f' "{registry_sha256(registry)}"\n\n'
+ f"{rows}\n\n"
+ "#endif /* CBM_PROFILE_TERMS_GENERATED_H */\n"
+ )
+
+
+def check_or_write(path: Path, expected: str, check: bool) -> bool:
+ actual = path.read_text(encoding="utf-8") if path.exists() else None
+ if actual == expected:
+ return True
+ if check:
+ print(f"stale generated benchmark terminology file: {path}", file=sys.stderr)
+ return False
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_text(expected, encoding="utf-8")
+ return True
+
+
+def parse_args() -> argparse.Namespace:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "--check",
+ action="store_true",
+ help="Fail if generated Markdown or C step-ID definitions are stale.",
+ )
+ return parser.parse_args()
+
+
+def main() -> int:
+ args = parse_args()
+ try:
+ registry = load_registry()
+ except (OSError, ValueError, json.JSONDecodeError) as exc:
+ print(f"invalid benchmark terminology registry: {exc}", file=sys.stderr)
+ return 1
+ ok = check_or_write(MARKDOWN_PATH, render_markdown(registry), args.check)
+ ok = check_or_write(HEADER_PATH, render_header(registry), args.check) and ok
+ return 0 if ok else 1
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/benchmarks/generate_test_labels.py b/benchmarks/generate_test_labels.py
new file mode 100644
index 000000000..593d6ad8a
--- /dev/null
+++ b/benchmarks/generate_test_labels.py
@@ -0,0 +1,272 @@
+#!/usr/bin/env python3
+"""Label a corpus's test files from the project's own declaration, not from cbm.
+
+Why this exists
+---------------
+`scaffolding@K` asks what fraction of a scorer's top-K is test scaffolding. Answering it
+with any of the server's own test predicates would be circular: those predicates are the
+thing under measurement. PR #879's audit hit the same problem from the other side — its
+test penalty under-fired precisely because the classifier disagreed with reality.
+
+So the label comes from a source that knows nothing about codebase-memory-mcp:
+
+ declared the project's own test configuration (pytest testpaths/python_files from
+ pyproject.toml, setup.cfg, pytest.ini or tox.ini; jest testMatch from
+ package.json)
+ spec the language toolchain's own rule, which is not a heuristic but a
+ definition: Go compiles `*_test.go` as tests (cmd/go), Cargo treats
+ `tests/*.rs` as integration tests (Cargo book)
+ runner the test runner enumerating its own suite, when it can run without
+ installing the project's dependencies
+
+Every label records which of those produced it. Files no independent source can classify
+are emitted as `unknown` rather than guessed, because a guess here would quietly
+reintroduce the circularity this file exists to remove.
+
+Usage:
+ python3 benchmarks/generate_test_labels.py --corpus flask --repo PATH
+ python3 benchmarks/generate_test_labels.py --corpus flask # resolve from the cache
+"""
+
+from __future__ import annotations
+
+import argparse
+import configparser
+import fnmatch
+import json
+import re
+import subprocess
+import sys
+import tomllib
+from pathlib import Path
+from typing import Any
+
+ROOT = Path(__file__).resolve().parents[1]
+LABELS_DIR = Path(__file__).resolve().with_name("labels")
+SCHEMA_VERSION = 1
+
+# pytest's own defaults when a project declares none (pytest docs: python_files).
+PYTEST_DEFAULT_PATTERNS = ("test_*.py", "*_test.py")
+
+SOURCE_EXTENSIONS = {
+ ".py", ".go", ".rs", ".js", ".jsx", ".ts", ".tsx", ".c", ".h", ".cc", ".cpp",
+ ".hpp", ".java", ".kt", ".rb", ".php", ".cs", ".scala", ".swift", ".m",
+}
+
+VENDOR_DIR_NAMES = {".git", "node_modules", "vendor", "target", "dist", "build"}
+
+
+def tracked_files(repo: Path) -> list[str]:
+ """Repo-relative paths of tracked source files, via git so ignores are honored."""
+ proc = subprocess.run(
+ ["git", "ls-files"], cwd=repo, text=True, capture_output=True, check=False
+ )
+ if proc.returncode != 0:
+ raise SystemExit(f"git ls-files failed in {repo}: {proc.stderr.strip()}")
+ paths = []
+ for line in proc.stdout.splitlines():
+ path = Path(line)
+ if path.suffix.lower() not in SOURCE_EXTENSIONS:
+ continue
+ if VENDOR_DIR_NAMES & set(path.parts):
+ continue
+ paths.append(line)
+ return sorted(paths)
+
+
+def pytest_declaration(repo: Path) -> dict[str, Any] | None:
+ """Read the project's declared pytest configuration, in pytest's own lookup order."""
+ pyproject = repo / "pyproject.toml"
+ if pyproject.is_file():
+ data = tomllib.loads(pyproject.read_text(encoding="utf-8", errors="replace"))
+ ini = data.get("tool", {}).get("pytest", {}).get("ini_options")
+ if isinstance(ini, dict):
+ return {
+ "testpaths": list(ini.get("testpaths") or []),
+ "python_files": tuple(
+ ini.get("python_files") or PYTEST_DEFAULT_PATTERNS
+ ),
+ "declared_in": "pyproject.toml [tool.pytest.ini_options]",
+ }
+ for name, section in (("pytest.ini", "pytest"), ("tox.ini", "pytest"), ("setup.cfg", "tool:pytest")):
+ path = repo / name
+ if not path.is_file():
+ continue
+ parser = configparser.ConfigParser()
+ parser.read_string(path.read_text(encoding="utf-8", errors="replace"))
+ if not parser.has_section(section):
+ continue
+ return {
+ "testpaths": parser.get(section, "testpaths", fallback="").split(),
+ "python_files": tuple(
+ parser.get(section, "python_files", fallback="").split()
+ or PYTEST_DEFAULT_PATTERNS
+ ),
+ "declared_in": f"{name} [{section}]",
+ }
+ return None
+
+
+def jest_declaration(repo: Path) -> dict[str, Any] | None:
+ package = repo / "package.json"
+ if not package.is_file():
+ return None
+ data = json.loads(package.read_text(encoding="utf-8", errors="replace"))
+ config = data.get("jest")
+ if not isinstance(config, dict):
+ return None
+ patterns = config.get("testMatch") or config.get("testRegex")
+ if not patterns:
+ return None
+ return {
+ "patterns": patterns if isinstance(patterns, list) else [patterns],
+ "declared_in": "package.json [jest]",
+ }
+
+
+def label_path(
+ path: str, pytest_config: dict[str, Any] | None, jest_config: dict[str, Any] | None
+) -> tuple[bool | None, str, str]:
+ """Return (is_test, source, evidence) for one repo-relative path."""
+ suffix = Path(path).suffix.lower()
+
+ # Language-spec rules. These are definitions, not conventions: the toolchain will
+ # not compile the file as anything else.
+ if suffix == ".go":
+ is_test = path.endswith("_test.go")
+ return is_test, "spec", "go: cmd/go compiles *_test.go as the test binary"
+ if suffix == ".rs":
+ if path.startswith("tests/") or "/tests/" in path:
+ return True, "spec", "cargo: tests/ holds integration tests"
+ return None, "unknown", "cargo: unit tests live in #[cfg(test)] modules inline"
+
+ if suffix == ".py" and pytest_config is not None:
+ name = Path(path).name
+ # python_files is what makes a module a test module. testpaths only sets the
+ # default collection root, so gating on it would mislabel a real test suite that
+ # simply is not collected by a bare `pytest` invocation — flask's
+ # examples/tutorial/tests/ is exactly that case, and it is scaffolding either way.
+ if any(
+ fnmatch.fnmatch(name, pattern) for pattern in pytest_config["python_files"]
+ ):
+ return (
+ True,
+ "declared",
+ f"pytest: matches python_files ({pytest_config['declared_in']})",
+ )
+ # conftest.py is test-support infrastructure wherever pytest would load it,
+ # which is any directory on the path to a collected test module.
+ if name == "conftest.py":
+ return (
+ True,
+ "declared",
+ "pytest: conftest.py is test-support infrastructure",
+ )
+ return (
+ False,
+ "declared",
+ f"pytest: does not match python_files ({pytest_config['declared_in']})",
+ )
+
+ if suffix in {".js", ".jsx", ".ts", ".tsx"} and jest_config is not None:
+ for pattern in jest_config["patterns"]:
+ if pattern.startswith(("**", "!")) or "*" in pattern:
+ if fnmatch.fnmatch(path, pattern.lstrip("!")) or fnmatch.fnmatch(
+ "/" + path, pattern.lstrip("!")
+ ):
+ return True, "declared", f"jest: testMatch ({jest_config['declared_in']})"
+ elif re.search(pattern, path):
+ return True, "declared", f"jest: testRegex ({jest_config['declared_in']})"
+ return False, "declared", f"jest: not matched ({jest_config['declared_in']})"
+
+ return None, "unknown", "no independent declaration or language rule applies"
+
+
+def repo_revision(repo: Path) -> str:
+ """The checkout's commit, or empty when it is not a git checkout."""
+ return subprocess.run(
+ ["git", "rev-parse", "HEAD"], cwd=repo, text=True, capture_output=True, check=False
+ ).stdout.strip()
+
+
+def build_labels(
+ corpus_id: str, repo: Path, paths: list[str] | None = None
+) -> dict[str, Any]:
+ """Label a corpus's files, reading its own declared test configuration.
+
+ `paths` exists so the labelling rules can be exercised against a plain list of
+ file names. Without it every caller — including every test — has to construct a
+ git repository just to reach the rules, which drags repository-mutating commands
+ into code that only classifies strings. Production passes None and gets the
+ tracked-file list, so `.gitignore` is still honored where it matters.
+ """
+ pytest_config = pytest_declaration(repo)
+ jest_config = jest_declaration(repo)
+ revision = repo_revision(repo)
+
+ rows: list[dict[str, Any]] = []
+ counts = {"test": 0, "not_test": 0, "unknown": 0}
+ for path in (tracked_files(repo) if paths is None else sorted(paths)):
+ is_test, source, evidence = label_path(path, pytest_config, jest_config)
+ counts["unknown" if is_test is None else "test" if is_test else "not_test"] += 1
+ rows.append(
+ {
+ "file_path": path,
+ "is_test": is_test,
+ "source": source,
+ "evidence": evidence,
+ }
+ )
+ return {
+ "schema_version": SCHEMA_VERSION,
+ "corpus": corpus_id,
+ "revision": revision,
+ "generated_by": "benchmarks/generate_test_labels.py",
+ "independence": (
+ "Labels derive from the project's own declaration or the language "
+ "toolchain's rule. No codebase-memory-mcp test predicate was consulted, so "
+ "scaffolding@K does not measure the classifier against itself."
+ ),
+ "declarations": {
+ "pytest": pytest_config,
+ "jest": jest_config,
+ },
+ "counts": counts,
+ "labels": rows,
+ }
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("--corpus", required=True, help="Corpus id from corpora-v1.json.")
+ parser.add_argument(
+ "--repo",
+ default="",
+ help="Checkout to label; defaults to the shared bench-repos cache entry.",
+ )
+ parser.add_argument("--out", default="", help="Output path; defaults to labels/.json.")
+ args = parser.parse_args()
+
+ repo = (
+ Path(args.repo).expanduser()
+ if args.repo
+ else Path.home() / ".cache" / "codebase-memory-mcp" / "bench-repos" / args.corpus
+ )
+ if not (repo / ".git").exists():
+ raise SystemExit(f"not a git checkout: {repo}")
+
+ document = build_labels(args.corpus, repo)
+ out = Path(args.out) if args.out else LABELS_DIR / f"{args.corpus}.json"
+ out.parent.mkdir(parents=True, exist_ok=True)
+ out.write_text(json.dumps(document, indent=2) + "\n", encoding="utf-8")
+ counts = document["counts"]
+ print(
+ f"wrote {out.relative_to(ROOT) if out.is_relative_to(ROOT) else out}: "
+ f"{counts['test']} test, {counts['not_test']} not-test, "
+ f"{counts['unknown']} unknown"
+ )
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/benchmarks/native_extraction_benchmark_main.c b/benchmarks/native_extraction_benchmark_main.c
new file mode 100644
index 000000000..821ad96af
--- /dev/null
+++ b/benchmarks/native_extraction_benchmark_main.c
@@ -0,0 +1,153 @@
+/*
+ * Production-configuration entry point for the native extraction benchmarks.
+ *
+ * The ordinary test runner intentionally enables test seams and uses -O1 so
+ * sanitizers and fault injection stay useful. Performance comparisons need
+ * the release compiler flags, allocator binding, and production source set;
+ * Makefile.cbm therefore links this small selector with those exact inputs.
+ */
+#include "test_framework.h"
+#include "cbm.h"
+#include
+
+int tf_pass_count = 0;
+int tf_fail_count = 0;
+int tf_skip_count = 0;
+int tf_filter_count = 0;
+
+const char *tf_repository_root(void) {
+ return NULL;
+}
+
+extern void suite_cs_lsp_bench(void);
+extern void suite_py_lsp_bench(void);
+extern void suite_py_lsp_scale(void);
+
+static const char *shared_bench_source =
+ "{\n"
+ " \"projects\": [\n"
+ " {\"name\": \"alpha\", \"enabled\": true, \"weights\": [1, 2, 3, 5, 8]},\n"
+ " {\"name\": \"beta\", \"enabled\": false, \"weights\": [13, 21, 34]},\n"
+ " {\"name\": \"gamma\", \"enabled\": true, \"weights\": [55, 89]}\n"
+ " ],\n"
+ " \"limits\": {\"workers\": 8, \"timeout_ms\": 3000},\n"
+ " \"features\": {\"calls\": true, \"usages\": true, \"types\": true}\n"
+ "}\n";
+
+static double elapsed_ms(struct timespec start, struct timespec end) {
+ double seconds = (double)(end.tv_sec - start.tv_sec);
+ double nanoseconds = (double)(end.tv_nsec - start.tv_nsec);
+ return seconds * 1000.0 + nanoseconds / 1000000.0;
+}
+
+TEST(shared_parse_baseline) {
+ enum { ITERATIONS = 1024 };
+ int definitions = -1;
+ int calls = -1;
+ int resolved = -1;
+ int usages = -1;
+ int type_refs = -1;
+ int read_write = -1;
+ struct timespec start;
+ struct timespec end;
+
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ for (int iteration = 0; iteration < ITERATIONS; ++iteration) {
+ CBMFileResult *result =
+ cbm_extract_file(shared_bench_source, (int)strlen(shared_bench_source), CBM_LANG_JSON,
+ "bench", "shared.json", 0, NULL, NULL);
+ ASSERT_NOT_NULL(result);
+
+ if (iteration == 0) {
+ definitions = result->defs.count;
+ calls = result->calls.count;
+ resolved = result->resolved_calls.count;
+ usages = result->usages.count;
+ type_refs = result->type_refs.count;
+ read_write = result->rw.count;
+ }
+ bool output_matches =
+ definitions == result->defs.count && calls == result->calls.count &&
+ resolved == result->resolved_calls.count && usages == result->usages.count &&
+ type_refs == result->type_refs.count && read_write == result->rw.count;
+ cbm_free_result(result);
+ ASSERT_TRUE(output_matches);
+ }
+ clock_gettime(CLOCK_MONOTONIC, &end);
+ ASSERT_EQ(cbm_get_lsp_ns(), 0);
+
+ int lines = 0;
+ for (const char *cursor = shared_bench_source; *cursor != '\0'; ++cursor) {
+ if (*cursor == '\n')
+ lines++;
+ }
+ double milliseconds = elapsed_ms(start, end);
+ int resolution_percent = calls > 0 ? resolved * 100 / calls : 0;
+ printf(" bench: %d lines, %d defs, %d calls, %d resolved (%d%%), "
+ "%d usages, %d type_refs, %d rw, %.2f ms\n",
+ lines, definitions, calls, resolved, resolution_percent, usages, type_refs, read_write,
+ milliseconds);
+ PASS();
+}
+
+SUITE(shared_parse_baseline) {
+ RUN_TEST(shared_parse_baseline);
+}
+
+static void print_usage(const char *program) {
+ fprintf(stderr,
+ "usage: %s {shared_parse_baseline|cs_lsp_bench|py_lsp_bench|py_lsp_scale|all}\n",
+ program);
+}
+
+static void print_profile(void) {
+ uint64_t parse_ns = 0;
+ uint64_t extract_ns = 0;
+ uint64_t files = 0;
+ uint64_t lsp_ns = cbm_get_lsp_ns();
+ cbm_get_profile((cbm_profile_out_t){
+ .parse_ns = &parse_ns,
+ .extract_ns = &extract_ns,
+ .files = &files,
+ });
+ uint64_t non_lsp_ns = extract_ns >= lsp_ns ? extract_ns - lsp_ns : 0;
+ printf(" profile: files=%llu parse=%.3fms non_lsp=%.3fms lsp=%.3fms total_extract=%.3fms\n",
+ (unsigned long long)files, (double)parse_ns / 1000000.0, (double)non_lsp_ns / 1000000.0,
+ (double)lsp_ns / 1000000.0, (double)extract_ns / 1000000.0);
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ print_usage(argv[0]);
+ return 2;
+ }
+
+ if (strcmp(argv[1], "shared_parse_baseline") == 0 || strcmp(argv[1], "all") == 0) {
+ cbm_reset_profile();
+ RUN_SUITE(shared_parse_baseline);
+ print_profile();
+ }
+ if (strcmp(argv[1], "cs_lsp_bench") == 0 || strcmp(argv[1], "all") == 0) {
+ cbm_reset_profile();
+ RUN_SUITE(cs_lsp_bench);
+ print_profile();
+ }
+ if (strcmp(argv[1], "py_lsp_bench") == 0 || strcmp(argv[1], "all") == 0) {
+ cbm_reset_profile();
+ RUN_SUITE(py_lsp_bench);
+ print_profile();
+ }
+ if (strcmp(argv[1], "py_lsp_scale") == 0 || strcmp(argv[1], "all") == 0) {
+ cbm_reset_profile();
+ RUN_SUITE(py_lsp_scale);
+ print_profile();
+ }
+ if (strcmp(argv[1], "shared_parse_baseline") != 0 && strcmp(argv[1], "cs_lsp_bench") != 0 &&
+ strcmp(argv[1], "py_lsp_bench") != 0 && strcmp(argv[1], "py_lsp_scale") != 0 &&
+ strcmp(argv[1], "all") != 0) {
+ print_usage(argv[0]);
+ return 2;
+ }
+
+ TEST_SUMMARY();
+}
diff --git a/benchmarks/rank-queries-v1/manifest.json b/benchmarks/rank-queries-v1/manifest.json
new file mode 100644
index 000000000..b92294ed5
--- /dev/null
+++ b/benchmarks/rank-queries-v1/manifest.json
@@ -0,0 +1,626 @@
+{
+ "schema_version": 1,
+ "task_set_version": "rank-queries-v1",
+ "default_cutoff": 5,
+ "ground_truth_scope": "Graded judgments cover grep-first authored targets and planted canaries only. Workload-verbatim and adversarial probes are behavioral-only and are never rank-scored.",
+ "judgment_schema": {
+ "consumed_by": "score_ranked_relevance in benchmarks/run_benchmark.py",
+ "fields": {
+ "expected_substring": "required string; matched against the canonical JSON of each ranked item",
+ "required_substrings": "optional list; all must also appear in the same item",
+ "relevance": "required number > 0; graded gain (3 = primary target, 2 = acceptable, 1 = marginal)"
+ }
+ },
+ "authoring_policy": {
+ "rule": "CR-1 symmetric authoring, from upstream docs/EVALUATION_PLAN.md:834-846",
+ "applied": "Every graded target below was located by reading source at the pinned commit (GitHub contents API + text grep), never via the codebase-memory graph. A target the graph then fails to return is a finding, not a defective question.",
+ "verified_at_pin": true
+ },
+ "families": {
+ "A": "workload-realistic - verbatim patterns recovered from 12894 real graph-tool calls",
+ "B": "centrality - grep-first authored targets on real corpora",
+ "C": "adversarial/diagnostic - probes that attack a named hardcoded criterion; behavioral-only",
+ "D": "anti-regression - the existing synthetic fixture oracle, unchanged"
+ },
+ "detail_profiles": {
+ "note": "Crossed with the scorer arms to produce the recall-vs-token frontier. All keys validated against config-keys-v1.json.",
+ "detail-lean": {
+ "search_limit": "10",
+ "trace_max_results": "10",
+ "snippet_max_lines": "40"
+ },
+ "detail-default": {},
+ "detail-rich": {
+ "search_limit": "200",
+ "trace_max_results": "100",
+ "snippet_max_lines": "400"
+ },
+ "paging-compliant": {
+ "follow_has_more": true,
+ "note": "Control arm isolating issue #1382's measured recall collapse 0.723 -> 0.525 from genuine ranking effects."
+ }
+ },
+ "corpora": {
+ "synthetic-rank-v1": {
+ "note": "Family D. Byte-identical to the current hardcoded oracle so historical cells stay comparable.",
+ "queries": [
+ {
+ "id": "central_order_search",
+ "family": "D",
+ "tool": "search_graph",
+ "arguments": {
+ "label": "Function",
+ "name_pattern": "order",
+ "limit": 10
+ },
+ "criterion": "rank the structurally central order workflow ahead of lexical-only decoys",
+ "cutoff": 5,
+ "judgments": [
+ {
+ "expected_substring": "zz_order_core",
+ "relevance": 3
+ }
+ ]
+ }
+ ]
+ },
+ "cosign": {
+ "revision": "83d9ec8f4bdb25d680c2331528503cd85888868f",
+ "queries": [
+ {
+ "id": "attest_production_symbols",
+ "family": "B",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*Attest*",
+ "limit": 10
+ },
+ "criterion": "surface production attestation code despite its path containing the substring 'test'",
+ "cutoff": 5,
+ "judgments": [
+ {
+ "expected_substring": "AttestCommand",
+ "required_substrings": [
+ "cmd/cosign/cli/attest"
+ ],
+ "relevance": 3
+ },
+ {
+ "expected_substring": "attest.go",
+ "relevance": 2
+ }
+ ],
+ "grep_first_evidence": "cmd/cosign/cli/attest/attest.go:44 'type AttestCommand struct', :61 'func (c *AttestCommand) Exec' - read from source at the pinned tree",
+ "attacks": "strstr(file,\"test\") -> SCORE_TEST=-5 at src/mcp/mcp.c:15367; bare strstr(fp,\"test\") at src/store/store.c:14905-14910"
+ },
+ {
+ "id": "bare_test_probe",
+ "family": "C",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "test",
+ "limit": 20
+ },
+ "behavioral_only": true,
+ "criterion": "diagnostic: measure how much of the top-20 for the bare token 'test' is production attestation code versus genuine tests",
+ "note": "The literal token 'test' appears ZERO times as a query in 12894 real calls. This is a diagnostic probe, not representative workload, and is reported as such.",
+ "judgments": []
+ },
+ {
+ "id": "script_coverage_probe",
+ "family": "C",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*script*",
+ "limit": 20
+ },
+ "behavioral_only": true,
+ "criterion": "diagnostic: cosign keeps 49 files under doc/, hack/ and scripts/, all in FAST_SKIP_DIRS; compare recall across index modes",
+ "attacks": "FAST_SKIP_DIRS at src/discover/discover.c:61-68, gated at :448-452",
+ "issues": [
+ "#1406"
+ ],
+ "judgments": []
+ }
+ ]
+ },
+ "jest": {
+ "revision": "f49721c78e195558b40913977c9230f5b7f559d8",
+ "queries": [
+ {
+ "id": "test_is_the_product",
+ "family": "C",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*test*",
+ "limit": 20
+ },
+ "behavioral_only": true,
+ "criterion": "polarity inversion: on a test framework, demoting paths containing 'test' demotes the product itself. A LOW scaffolding@K here is a DEFECT, reported with explicit sign.",
+ "attacks": "every global test penalty: #879 TEST_MUL=0.1, our edge_weight_tests=0.05, SCORE_TEST=-5",
+ "judgments": []
+ },
+ {
+ "id": "jest_coverage_probe",
+ "family": "C",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*",
+ "limit": 50
+ },
+ "behavioral_only": true,
+ "criterion": "coverage: 1711 of 3317 files (51.6%) are predicted lost outside full mode via docs/, e2e/, examples/, scripts/",
+ "issues": [
+ "#1406"
+ ],
+ "judgments": []
+ }
+ ]
+ },
+ "runc": {
+ "revision": "0c87c02ff02123f1bc2cd1b3f850f94e5b8de983",
+ "queries": [
+ {
+ "id": "singular_script_probe",
+ "family": "C",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*script*",
+ "limit": 20
+ },
+ "behavioral_only": true,
+ "criterion": "asymmetry control: runc uses script/ (singular), absent from FAST_SKIP_DIRS, while cosign uses scripts/ (plural), present. Same intent, opposite treatment.",
+ "attacks": "FAST_SKIP_DIRS plural-only entry at src/discover/discover.c:67",
+ "issues": [
+ "#1184",
+ "#1406"
+ ],
+ "judgments": []
+ },
+ {
+ "id": "vendor_absence_probe",
+ "family": "C",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*",
+ "limit": 50
+ },
+ "behavioral_only": true,
+ "criterion": "coverage: 978 of 1305 files (74.9%) are dropped in EVERY mode via the single ALWAYS_SKIP_DIRS entry 'vendor'",
+ "attacks": "ALWAYS_SKIP_DIRS at src/discover/discover.c:31-54; SCORE_VENDORED=-50 at mcp.c:15362 targets the same intent twice",
+ "judgments": []
+ }
+ ]
+ },
+ "flask": {
+ "revision": "6a2f545bfd8ed31e19066a299296917e034aca58",
+ "queries": [
+ {
+ "id": "flask_public_api",
+ "family": "B",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "url_for",
+ "limit": 10
+ },
+ "criterion": "rank the documented public API entry point ahead of incidental matches",
+ "cutoff": 5,
+ "judgments": [
+ {
+ "expected_substring": "url_for",
+ "required_substrings": [
+ "src/flask/app.py"
+ ],
+ "relevance": 3
+ }
+ ],
+ "grep_first_evidence": "src/flask/app.py:1102 'def url_for(' and :109 'class Flask(App)' - read from source at the pinned tree"
+ },
+ {
+ "id": "flask_is_test_probe",
+ "family": "C",
+ "tool": "query_graph",
+ "arguments": {
+ "query": "MATCH (f:Function) WHERE f.is_test = true RETURN count(f) AS n"
+ },
+ "behavioral_only": true,
+ "criterion": "expected to return 0 on a pure pytest project: def.is_test is assigned only for Rust #[test] and C++ GoogleTest",
+ "attacks": "internal/cbm/extract_defs.c:3718,3723",
+ "issues": [
+ "#1294"
+ ],
+ "judgments": []
+ }
+ ]
+ },
+ "redis": {
+ "revision": "0708bdbc0086bea03c5a40d9b606b5fe73d7159d",
+ "queries": [
+ {
+ "id": "hub_utility_contamination",
+ "family": "C",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*",
+ "limit": 20,
+ "sort_by": "relevance"
+ },
+ "behavioral_only": true,
+ "criterion": "H5, the maintainer's own claim: measure what fraction of each scorer's top-20 is a logging/allocation hub (zmalloc, zfree, serverLog, sds*). ORDER BY degree DESC ranks max-fan-in first by construction; PageRank damping redistributes.",
+ "utility_symbols": [
+ "zmalloc",
+ "zfree",
+ "zrealloc",
+ "serverLog",
+ "sdsnew",
+ "sdscatlen",
+ "addReply"
+ ],
+ "grep_first_evidence": "src/zmalloc.h declares 'void zfree(' - read from source at the pinned tree",
+ "attacks": "PR #151 maintainer claim: 'PageRank would rank log.Error() and fmt.Sprintf() as the most important functions'",
+ "judgments": []
+ },
+ {
+ "id": "latest_false_positive",
+ "family": "C",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*latest*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "criterion": "false-positive probe: 1 path under the pinned tree contains 'latest', which bare strstr(fp,\"test\") classifies as a test file",
+ "attacks": "src/store/store.c:14905-14910",
+ "judgments": []
+ }
+ ]
+ },
+ "ripgrep": {
+ "revision": "435f59fc4b43af3ab32f34d53fa34978f393fe52",
+ "note": "Positive control. Rust is the one ecosystem where def.is_test is actually populated, and almost nothing here is in the skip lists, so a metric that moves is attributable to the score rather than to missing coverage.",
+ "queries": [
+ {
+ "id": "rust_is_test_populated",
+ "family": "C",
+ "tool": "query_graph",
+ "arguments": {
+ "query": "MATCH (f:Function) WHERE f.is_test = true RETURN count(f) AS n"
+ },
+ "behavioral_only": true,
+ "criterion": "expected to be NON-zero here, unlike flask: internal/cbm/extract_defs.c:3718 populates is_test for Rust #[test]. This is the control that proves the flask result is a language gap rather than a broken query.",
+ "judgments": []
+ },
+ {
+ "id": "ripgrep_clean_coverage",
+ "family": "C",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*",
+ "limit": 50
+ },
+ "behavioral_only": true,
+ "criterion": "coverage control: only 2 of 237 files are predicted lost across all index modes, so mode-to-mode deltas here isolate score effects",
+ "judgments": []
+ }
+ ]
+ },
+ "codex": {
+ "note": "Family A. Smallest mined-workload source (54 recovered calls); contributes queries but little weight.",
+ "queries": [
+ {
+ "id": "wl_hook",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*on_hook_*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_session",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "Session",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_alternation_hooks",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "PreToolUse|Hook|run_hooks|hooks",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ }
+ ]
+ },
+ "codebase-memory-mcp": {
+ "note": "Family A. Patterns are verbatim from real recovered calls against this repository.",
+ "queries": [
+ {
+ "id": "wl_pagerank",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*pagerank*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_config_set",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*config*set*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_vector_search",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*vector_search*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_envscan",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*envscan*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_incremental",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*incremental*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_handle_prefix",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "handle_*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_alternation_quarantine",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "quarantine_corrupt_store|resolve_store_internal|cbm_store_check_integrity_full",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "note": "Alternation of 2-6 symbol names is the second most common real query shape.",
+ "judgments": []
+ },
+ {
+ "id": "wl_negative_control",
+ "family": "A",
+ "tool": "query_graph",
+ "arguments": {
+ "query": "MATCH (n:DefinitelyMissingLabel) RETURN n.name LIMIT 5"
+ },
+ "behavioral_only": true,
+ "note": "A deliberate zero-row probe already present in the recovered corpus; reused as the negative control.",
+ "judgments": []
+ }
+ ]
+ },
+ "ai-session-search": {
+ "note": "Family A plus the flaky-repeat set. 8558 real calls, the largest mined source.",
+ "queries": [
+ {
+ "id": "wl_message_search",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*MessageSearch*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_session_search",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*SessionSearch*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_run_search",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "run_search",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "flaky_max_hits_per_page",
+ "family": "A",
+ "tool": "search_code",
+ "arguments": {
+ "pattern": "max_hits_per_page",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "repetitions": 10,
+ "criterion": "stability: this exact call returned zero results 18 of 54 times against a fixed index in recovered history. Measures result-count stability, not relevance.",
+ "judgments": []
+ },
+ {
+ "id": "flaky_todo",
+ "family": "A",
+ "tool": "search_code",
+ "arguments": {
+ "pattern": "TODO",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "repetitions": 10,
+ "criterion": "stability: returned zero 10 of 20 times in recovered history",
+ "judgments": []
+ },
+ {
+ "id": "nl_query_timeout",
+ "family": "C",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "timeout deadline busy wait interruption request timeout",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "criterion": "natural-language probe: all 3 natural-language queries in the entire recovered corpus returned zero results",
+ "judgments": []
+ }
+ ]
+ },
+ "autorun": {
+ "note": "Family A. 648 real calls; highest observed query_graph zero-result rate at 33.3%.",
+ "queries": [
+ {
+ "id": "wl_task",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*task*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_daemon",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*daemon*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_dedup",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*dedup*",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "wl_alternation_stop",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "continue_running|enforce_stop|deliver_pending|pending_stop|deliver",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "judgments": []
+ },
+ {
+ "id": "nl_query_staleness",
+ "family": "C",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "task staleness reminder injection tool_calls_since_task_update",
+ "limit": 10
+ },
+ "behavioral_only": true,
+ "criterion": "verbatim natural-language query from recovered history; returned zero results",
+ "judgments": []
+ }
+ ]
+ },
+ "scikit-learn": {
+ "queries": [
+ {
+ "id": "train_test_split_is_production_api",
+ "family": "B",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "*train_test_split*",
+ "limit": 10
+ },
+ "criterion": "surface the public train_test_split API despite its name containing the substring 'test'",
+ "cutoff": 5,
+ "judgments": [
+ {
+ "expected_substring": "train_test_split",
+ "required_substrings": [
+ "model_selection"
+ ],
+ "relevance": 3
+ }
+ ],
+ "grep_first_evidence": "sklearn/model_selection/_split.py defines train_test_split as public API and sklearn/model_selection/__init__.py exports it - read from source at the pinned tree, never through the graph",
+ "attacks": "strstr(file,\"test\") -> SCORE_TEST=-5 at src/mcp/mcp.c:15367; bare strstr(fp,\"test\") at src/store/store.c:14905-14910. Both fire on a public API symbol here."
+ },
+ {
+ "id": "bare_test_probe",
+ "family": "C",
+ "tool": "search_graph",
+ "arguments": {
+ "pattern": "test",
+ "limit": 20
+ },
+ "behavioral_only": true,
+ "criterion": "diagnostic: measure how much of the top-20 for the bare token 'test' is production estimator and model-selection API versus scaffolding",
+ "note": "Pairs with the identical probe on cosign and flask. Same query, three domains: cosign where 'test' is a substring of production names, flask where it is scaffolding, sklearn where it is API vocabulary.",
+ "judgments": []
+ }
+ ]
+ }
+ },
+ "authoring_backlog": {
+ "note": "Graded Family B judgments currently seed 2 corpora (cosign, flask). Before the campaign reports MRR/nDCG per corpus, each remaining popularity-cohort corpus needs grep-first authored targets.",
+ "pending": [
+ "jest",
+ "runc",
+ "redis",
+ "ripgrep"
+ ],
+ "procedure": "Read source at the pinned commit via text search only, never via the graph (CR-1). Record the file:line evidence in grep_first_evidence. Behavioral-only probes need no judgments and are unaffected."
+ }
+}
diff --git a/benchmarks/rank_hypotheses.py b/benchmarks/rank_hypotheses.py
new file mode 100644
index 000000000..bd2c0b33a
--- /dev/null
+++ b/benchmarks/rank_hypotheses.py
@@ -0,0 +1,552 @@
+"""Single source of truth for rank hypotheses, options, scorers, and quick arms.
+
+The benchmark previously spread bare H identifiers, scorer SQL, and parameter lists
+across the spec generator, probe, report, and prose. That made it possible for a report
+to claim H1--H7 while only computing H2/H4/H5. This module owns those definitions as
+data so every surface can emit the same auditable contract.
+
+The registry contains experiment definitions, not product defaults. Intervention values
+are deliberately far enough from the defaults in ``src/pagerank/pagerank.h`` to expose
+wiring or convergence behavior, and each profile states the observable it is allowed to
+support. A changed fingerprint is expected from semantic interventions; numerical and
+lifecycle controls have different outcomes and must not be called inert merely because
+their converged ranking is unchanged.
+"""
+
+from __future__ import annotations
+
+import re
+from copy import deepcopy
+from pathlib import Path
+from typing import Any
+
+PERFORMANCE_SUITE_NAME = "performance-v1 — Incremental indexing cost, correctness, and capability attribution"
+RANK_SUITE_NAME = (
+ "rank-evidence-v2 — Node/edge ranking quality and runtime-configuration evidence"
+)
+UNIFIED_SUITE_NAME = (
+ "codebase-memory-evidence-v1 — Unified performance and ranking assessment"
+)
+ROOT = Path(__file__).resolve().parents[1]
+PAGERANK_HEADER = ROOT / "src" / "pagerank" / "pagerank.h"
+
+
+HYPOTHESIS_FAMILIES: dict[str, dict[str, Any]] = {
+ "utility_relevance": {
+ "name": "Utility popularity versus architectural relevance",
+ "hypotheses": ("H1", "H5"),
+ "independent_unit": "corpus",
+ "reason_consolidated": (
+ "H1 and H5 are opposite causal readings of the same ranked utility labels; "
+ "reporting them as independent evidence would double-count each corpus."
+ ),
+ },
+ "node_order_equivalence": {
+ "name": "Node ordering equivalence",
+ "hypotheses": ("H2",),
+ "independent_unit": "corpus",
+ "reason_consolidated": "One family contains one independently testable claim.",
+ },
+ "cost_and_adaptation": {
+ "name": "Ranking cost and runtime adaptation",
+ "hypotheses": ("H3", "H7"),
+ "independent_unit": "corpus by language and task stratum",
+ "reason_consolidated": (
+ "H3 asks whether rank cost buys task quality; H7 asks whether runtime tuning "
+ "moves that same quality/latency frontier under distribution shift."
+ ),
+ },
+ "edge_semantics": {
+ "name": "Typed-edge weighting and edge-level capability",
+ "hypotheses": ("H4", "H6"),
+ "independent_unit": "corpus and edge-task stratum",
+ "reason_consolidated": (
+ "H4 compares typed and untyped aggregation; H6 checks the information lost "
+ "when an edge ranking is collapsed to a node statistic."
+ ),
+ },
+}
+
+
+HYPOTHESES: dict[str, dict[str, Any]] = {
+ "H1": {
+ "name": "PageRank utility-hub domination",
+ "family": "utility_relevance",
+ "question": (
+ "Does weighted PageRank surface high-fan-in utility symbols instead of "
+ "task-relevant architectural entry points?"
+ ),
+ "required_evidence": (
+ "fan-in-independent utility or architectural labels",
+ "graded task relevance",
+ "paired scorer windows on independently sampled corpora",
+ ),
+ },
+ "H2": {
+ "name": "Degree and PageRank ordering equivalence",
+ "family": "node_order_equivalence",
+ "question": (
+ "Do unweighted total degree and weighted PageRank return interchangeable "
+ "top-ranked node pages for real code-search tasks?"
+ ),
+ "required_evidence": (
+ "paired complete top-K rankings",
+ "top-K overlap or rank-biased overlap",
+ "per-corpus task relevance",
+ ),
+ },
+ "H3": {
+ "name": "PageRank cost without task benefit",
+ "family": "cost_and_adaptation",
+ "question": (
+ "Does computing and refreshing PageRank add indexing latency or memory "
+ "without improving judged retrieval quality over the rank-disabled arm?"
+ ),
+ "required_evidence": (
+ "paired rank-enabled and rank-disabled cells",
+ "wall time and peak RSS",
+ "domain-correct graded retrieval metrics",
+ ),
+ },
+ "H4": {
+ "name": "Unweighted degree ignores edge semantics",
+ "family": "edge_semantics",
+ "question": (
+ "Does counting every incoming and outgoing edge equally mis-rank corpora "
+ "whose TESTS, USAGE, IMPORTS, and control-flow edges have different meaning?"
+ ),
+ "required_evidence": (
+ "edge-type inventory",
+ "weighted and unweighted in/out/total node scorers",
+ "opposite-polarity corpus controls",
+ ),
+ },
+ "H5": {
+ "name": "Raw degree promotes utility hubs",
+ "family": "utility_relevance",
+ "question": (
+ "Does raw degree promote high-fan-in utilities ahead of independently "
+ "labelled public or architectural symbols?"
+ ),
+ "required_evidence": (
+ "fan-in-independent utility or public-surface labels",
+ "paired degree and PageRank windows",
+ "pre-registered independently sampled signal corpora",
+ ),
+ },
+ "H6": {
+ "name": "LinkRank preserves edge and path evidence",
+ "family": "edge_semantics",
+ "question": (
+ "Do edge-level LinkRank results solve judged relationship or path tasks "
+ "that no node-degree ordering can represent?"
+ ),
+ "required_evidence": (
+ "ranked source-edge-target tuples",
+ "edge or path task judgments",
+ "node-only baseline with the same candidate budget",
+ ),
+ },
+ "H7": {
+ "name": "Runtime weights adapt across language distributions",
+ "family": "cost_and_adaptation",
+ "question": (
+ "Can runtime edge weights improve held-out task quality across languages "
+ "without unacceptable latency, memory, or regression elsewhere?"
+ ),
+ "required_evidence": (
+ "pre-registered language and task strata",
+ "paired default and tuned profiles",
+ "held-out quality, latency, memory, and stability",
+ ),
+ },
+}
+
+
+EDGE_WEIGHT_OPTIONS = frozenset(
+ {
+ "edge_weight_async_calls",
+ "edge_weight_calls",
+ "edge_weight_configures",
+ "edge_weight_decorates",
+ "edge_weight_default",
+ "edge_weight_defines",
+ "edge_weight_defines_method",
+ "edge_weight_http_calls",
+ "edge_weight_imports",
+ "edge_weight_member_of",
+ "edge_weight_tests",
+ "edge_weight_usage",
+ "edge_weight_writes",
+ }
+)
+
+# These are disjoint by construction. A test enforces that an option cannot silently be
+# interpreted as both a semantic intervention and a numerical/lifecycle control.
+RANK_OPTION_GROUPS: dict[str, frozenset[str]] = {
+ "ranking_semantics": EDGE_WEIGHT_OPTIONS | {"pagerank_damping"},
+ "numerical_convergence_controls": frozenset(
+ {"pagerank_epsilon", "pagerank_max_iter"}
+ ),
+ "rank_lifecycle_policies": frozenset(
+ {"rank_enabled", "rank_refresh", "rank_scope"}
+ ),
+ "retrieval_budget_controls": frozenset(
+ {"search_limit", "trace_max_results", "snippet_max_lines"}
+ ),
+}
+
+
+# Expressions are fixed source constants, never user input. Building the repetitive SQL
+# from this registry keeps scorer names, directions, labels, and formulas in lockstep.
+SCORER_SPECS: dict[str, dict[str, str]] = {
+ "pagerank": {
+ "label": "Weighted global PageRank",
+ "source": "pagerank",
+ "direction": "global",
+ "expression": "p.rank",
+ },
+ "degree_weighted_in": {
+ "label": "Weighted incoming edge sum",
+ "source": "node_degree",
+ "direction": "in",
+ "expression": "d.weighted_in",
+ },
+ "degree_weighted_out": {
+ "label": "Weighted outgoing edge sum",
+ "source": "node_degree",
+ "direction": "out",
+ "expression": "d.weighted_out",
+ },
+ "degree_weighted_total": {
+ "label": "Weighted total edge sum",
+ "source": "node_degree",
+ "direction": "total",
+ "expression": "(d.weighted_in + d.weighted_out)",
+ },
+ "degree_unweighted_in": {
+ "label": "Unweighted incoming edge count",
+ "source": "node_degree",
+ "direction": "in",
+ "expression": "d.total_in",
+ },
+ "degree_unweighted_out": {
+ "label": "Unweighted outgoing edge count",
+ "source": "node_degree",
+ "direction": "out",
+ "expression": "d.total_out",
+ },
+ "degree_unweighted_total": {
+ "label": "Unweighted total edge count",
+ "source": "node_degree",
+ "direction": "total",
+ "expression": "(d.total_in + d.total_out)",
+ },
+ "calls_in": {
+ "label": "Incoming direct call count",
+ "source": "node_degree",
+ "direction": "in",
+ "expression": "d.calls_in",
+ },
+ "calls_out": {
+ "label": "Outgoing direct call count",
+ "source": "node_degree",
+ "direction": "out",
+ "expression": "d.calls_out",
+ },
+ "calls_total": {
+ "label": "Total direct call count",
+ "source": "node_degree",
+ "direction": "total",
+ "expression": "(d.calls_in + d.calls_out)",
+ },
+ "linkrank_in": {
+ "label": "Incoming LinkRank flow sum",
+ "source": "node_degree",
+ "direction": "in",
+ "expression": "d.linkrank_in",
+ },
+ "importance_pr879": {
+ "label": "PR 879 node importance score",
+ "source": "node_property",
+ "direction": "global",
+ "expression": "CAST(json_extract(n.properties,'$.importance') AS REAL)",
+ },
+}
+
+# Existing result documents and consumers use these names. Emit aliases indefinitely;
+# new analysis uses the explicit formula-bearing names above.
+SCORER_ALIASES: dict[str, str] = {
+ "weighted_in": "degree_weighted_in",
+ "degree": "degree_unweighted_total",
+ "in_degree": "degree_unweighted_in",
+ "importance": "importance_pr879",
+}
+DEGREE_BASELINE = "degree_unweighted_total"
+
+
+def build_rank_probe_sql(scope: str) -> dict[str, str]:
+ """Return one SQL query per canonical scorer.
+
+ Each query reads at most ``LIMIT K`` rows into Python. SQLite may scan and maintain a
+ bounded top-K sort over N ranked nodes, so the database work is O(N log K) time and
+ O(K) temporary state without a score index; Python retains O(K) rows per scorer.
+ """
+ queries: dict[str, str] = {}
+ for name, scorer in SCORER_SPECS.items():
+ expression = scorer["expression"]
+ if scorer["source"] == "pagerank":
+ source = "FROM nodes n JOIN pagerank p ON p.node_id = n.id"
+ present = ""
+ elif scorer["source"] == "node_degree":
+ source = "FROM nodes n JOIN node_degree d ON d.node_id = n.id"
+ present = ""
+ else:
+ source = "FROM nodes n"
+ present = " AND json_extract(n.properties,'$.importance') IS NOT NULL"
+ queries[name] = (
+ f"SELECT n.qualified_name, n.file_path, {expression} AS s {source} "
+ f"WHERE n.project = ? AND {scope}{present} "
+ "ORDER BY s DESC, n.qualified_name LIMIT ?"
+ )
+ return queries
+
+
+_NUMERIC_DEFINE = re.compile(
+ r"^#define\s+([A-Z][A-Z0-9_]+)\s+([-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?)\s*$",
+ re.MULTILINE,
+)
+
+EDGE_WEIGHT_MACRO_STEMS: dict[str, str] = {
+ "edge_weight_async_calls": "ASYNC_CALLS",
+ "edge_weight_calls": "CALLS",
+ "edge_weight_configures": "CONFIGURES",
+ "edge_weight_decorates": "DECORATES",
+ "edge_weight_default": "FALLBACK",
+ "edge_weight_defines": "DEFINES",
+ "edge_weight_defines_method": "DEFINES_METHOD",
+ "edge_weight_http_calls": "HTTP_CALLS",
+ "edge_weight_imports": "IMPORTS",
+ "edge_weight_member_of": "MEMBER_OF",
+ "edge_weight_tests": "TESTS",
+ "edge_weight_usage": "USAGE",
+ "edge_weight_writes": "WRITES",
+}
+
+
+def parameter_macro_contracts(
+ header: Path = PAGERANK_HEADER,
+) -> dict[str, dict[str, str]]:
+ """Read experiment values from the product's canonical macro declarations."""
+ values = dict(_NUMERIC_DEFINE.findall(header.read_text(encoding="utf-8")))
+
+ def contract(**macros: str) -> dict[str, str]:
+ missing = [macro for macro in macros.values() if macro not in values]
+ if missing:
+ raise RuntimeError(
+ f"missing PageRank parameter macros in {header}: {missing}"
+ )
+ result = {field: values[macro] for field, macro in macros.items()}
+ result["source"] = str(header.relative_to(ROOT))
+ result["macros"] = ",".join(macros.values())
+ return result
+
+ contracts = {
+ "pagerank_damping": contract(
+ default="CBM_PAGERANK_DAMPING",
+ recommended_min="CBM_PAGERANK_DAMPING_RECOMMENDED_MIN",
+ recommended_max="CBM_PAGERANK_DAMPING_RECOMMENDED_MAX",
+ ),
+ "pagerank_epsilon": contract(
+ default="CBM_PAGERANK_EPSILON",
+ recommended_min="CBM_PAGERANK_EPSILON_RECOMMENDED_MIN",
+ recommended_max="CBM_PAGERANK_EPSILON_RECOMMENDED_MAX",
+ ),
+ "pagerank_max_iter": contract(
+ default="CBM_PAGERANK_MAX_ITER",
+ declared_min="CBM_PAGERANK_MAX_ITER_MIN",
+ ),
+ }
+ for option, stem in EDGE_WEIGHT_MACRO_STEMS.items():
+ contracts[option] = contract(
+ default=f"CBM_PAGERANK_WEIGHT_{stem}_DEFAULT",
+ recommended_min=f"CBM_PAGERANK_WEIGHT_{stem}_RECOMMENDED_MIN",
+ recommended_max=f"CBM_PAGERANK_WEIGHT_{stem}_RECOMMENDED_MAX",
+ )
+ return contracts
+
+
+def quick_hypothesis_profiles() -> list[dict[str, Any]]:
+ """Build prioritized arms from declared product values, not Python magic numbers.
+
+ The list is ordered by evidentiary value. The quick suite runs each arm once over MCP;
+ it records actual elapsed time but has no total-duration target or cutoff.
+ """
+ parameters = parameter_macro_contracts()
+
+ def sources(*options: str) -> list[dict[str, str]]:
+ return [
+ {
+ "option": option,
+ "source": parameters[option]["source"],
+ "macros": parameters[option]["macros"],
+ }
+ for option in options
+ ]
+
+ equal_weight = parameters["edge_weight_calls"]["default"]
+ profiles = [
+ {
+ "label": "baseline",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "config_overrides": {},
+ "expected_observable": "reference ranking, quality, latency, and memory",
+ "parameter_sources": [],
+ },
+ {
+ "label": "rank-disabled",
+ "config_profile": "rank_disabled",
+ "capabilities": {"rank_enabled": "false"},
+ "config_overrides": {},
+ "expected_observable": "rank rows absent and indexing cost reduced or unchanged",
+ "parameter_sources": [
+ {
+ "option": "rank_enabled",
+ "source": "src/cli/cli.c:CBM_CONFIG_REGISTRY",
+ "macros": "CBM_CONFIG_RANK_ENABLED",
+ }
+ ],
+ },
+ {
+ "label": "equal-edge-weights",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "config_overrides": {
+ key: equal_weight for key in sorted(EDGE_WEIGHT_OPTIONS)
+ },
+ "expected_observable": "typed weighting ablation changes rankings when edge types differ",
+ "parameter_sources": sources(*sorted(EDGE_WEIGHT_OPTIONS)),
+ },
+ {
+ "label": "control-flow-prior",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "config_overrides": {
+ "edge_weight_calls": parameters["edge_weight_calls"]["recommended_max"],
+ "edge_weight_usage": parameters["edge_weight_usage"]["recommended_min"],
+ "edge_weight_tests": parameters["edge_weight_tests"]["recommended_min"],
+ },
+ "expected_observable": "CALLS dominate dense USAGE and TESTS edges",
+ "parameter_sources": sources(
+ "edge_weight_calls", "edge_weight_usage", "edge_weight_tests"
+ ),
+ },
+ {
+ "label": "shorter-propagation",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "config_overrides": {
+ "pagerank_damping": parameters["pagerank_damping"]["recommended_min"]
+ },
+ "expected_observable": "semantic ranking fingerprint changes toward local structure",
+ "parameter_sources": sources("pagerank_damping"),
+ },
+ {
+ "label": "loose-convergence",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "config_overrides": {
+ "pagerank_epsilon": parameters["pagerank_epsilon"]["recommended_max"]
+ },
+ "expected_observable": "publication succeeds with measured latency and bounded rank drift",
+ "parameter_sources": sources("pagerank_epsilon"),
+ },
+ {
+ "label": "declared-minimum-iterations",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "config_overrides": {
+ "pagerank_max_iter": parameters["pagerank_max_iter"]["declared_min"]
+ },
+ "expected_observable": "non-convergence is explicit and preserves the prior published generation",
+ "parameter_sources": sources("pagerank_max_iter"),
+ },
+ {
+ "label": "project-only-scope",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "config_overrides": {"rank_scope": "project"},
+ "expected_observable": "dependency symbols are excluded while project ranks remain fresh",
+ "parameter_sources": [
+ {
+ "option": "rank_scope",
+ "source": "src/cli/cli.c:CBM_CONFIG_REGISTRY",
+ "macros": "CBM_CONFIG_RANK_SCOPE",
+ }
+ ],
+ },
+ {
+ "label": "refresh-at-publish",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "config_overrides": {"rank_refresh": "at_publish"},
+ "expected_observable": "rank views are fresh at publication and refresh cost is recorded",
+ "parameter_sources": [
+ {
+ "option": "rank_refresh",
+ "source": "src/pagerank/pagerank.h",
+ "macros": "CBM_RANK_REFRESH_AT_PUBLISH",
+ }
+ ],
+ },
+ ]
+ profile_hypotheses = {
+ "baseline": ("H1", "H2", "H4", "H5", "H6"),
+ "rank-disabled": ("H3",),
+ "equal-edge-weights": ("H4",),
+ "control-flow-prior": ("H4", "H7"),
+ "shorter-propagation": ("H2", "H7"),
+ "loose-convergence": ("H3",),
+ "declared-minimum-iterations": ("H3",),
+ "project-only-scope": ("H3", "H6"),
+ "refresh-at-publish": ("H3",),
+ }
+ for priority, profile in enumerate(profiles, start=1):
+ hypothesis_ids = profile_hypotheses[profile["label"]]
+ profile["cell_name"] = (
+ f"RANK-CELL-{priority:02d} — {profile['label'].replace('-', ' ')}"
+ )
+ profile["priority"] = priority
+ profile["informs_hypotheses"] = list(hypothesis_ids)
+ profile["questions"] = [
+ {
+ "id": hypothesis_id,
+ "name": HYPOTHESES[hypothesis_id]["name"],
+ "question": HYPOTHESES[hypothesis_id]["question"],
+ }
+ for hypothesis_id in hypothesis_ids
+ ]
+ profile["evidence_scope"] = (
+ "synthetic rank fixture: establishes wiring, publication, and measured cost; "
+ "real multilingual corpora are required for task-quality generalization"
+ )
+ return deepcopy(profiles)
+
+
+def public_hypothesis_registry() -> dict[str, Any]:
+ """Return a JSON-safe registry for specs, receipts, and reports."""
+ return {
+ "families": deepcopy(HYPOTHESIS_FAMILIES),
+ "hypotheses": deepcopy(HYPOTHESES),
+ "option_groups": {
+ name: sorted(values) for name, values in RANK_OPTION_GROUPS.items()
+ },
+ "scorers": deepcopy(SCORER_SPECS),
+ "scorer_aliases": dict(SCORER_ALIASES),
+ "degree_baseline": DEGREE_BASELINE,
+ "suite": {
+ "name": RANK_SUITE_NAME,
+ "runtime_policy": "measure actual duration; do not impose a suite cutoff",
+ },
+ }
diff --git a/benchmarks/rank_report.py b/benchmarks/rank_report.py
new file mode 100644
index 000000000..f5b051ce0
--- /dev/null
+++ b/benchmarks/rank_report.py
@@ -0,0 +1,1245 @@
+#!/usr/bin/env python3
+"""Roll the rank-quality campaign's runsets up into one verdict document.
+
+Why this is separate from summarize_results.py
+----------------------------------------------
+`summarize_results.py` is deliberately descriptive: no confidence intervals, no
+inference, nearest-rank percentiles (`:29-34`, `:2206-2210`). Those choices are correct
+for a per-runset report and this file does not change them. The campaign question is
+cross-runset by construction — `capability_quality` and `index_mode` are both spec-level
+fields, so one corpus set at one index mode is one runset, and the comparison lives
+above them.
+
+What it answers
+---------------
+H1/H5 utility contamination per scorer. PR #151: "PageRank on a call graph would rank
+ log.Error() and fmt.Sprintf() as the most important functions in any codebase
+ ... that's not architectural importance, it's just utility popularity."
+H2 whether `ORDER BY degree DESC` "gives you the same ranking signal", by rank
+ correlation and top-K overlap against each score.
+H4 scaffolding@K per scorer, from Tier-A labels only.
+Silent drop which directories are present under one index mode and absent under
+ another, cited to the issue that reported the exclusion.
+
+The verdicts are written so they can come out against the ranking claim. A rollup that
+can only report a win is not evidence, and the counter-metrics discipline is the reason
+the rest of the numbers are worth reading.
+
+Usage:
+ python3 benchmarks/rank_report.py --experiment-root /path/to/campaign --out report.md
+ python3 benchmarks/rank_report.py --input a.json --input b.json --json rollup.json
+"""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import json
+import sys
+from pathlib import Path
+from typing import Any
+
+try: # Package import under tests; script-local import for direct execution.
+ from benchmarks import rank_hypotheses as rank_evidence
+except ModuleNotFoundError: # pragma: no cover - direct script execution
+ import rank_hypotheses as rank_evidence
+
+# Every silent-exclusion row cites the issue that reported that directory, so the table
+# is sourced evidence rather than an observation the reader has to take on trust.
+# Verified against the issue text and against src/discover/discover.c.
+DIRECTORY_ISSUES: dict[str, tuple[str, ...]] = {
+ "scripts": ("#1406",),
+ "script": ("#1406",),
+ "assets": ("#1219",),
+ "deploy": ("#1184",),
+ "deployed": ("#1184",),
+ "deployment": ("#1184",),
+ "deployments": ("#1184",),
+ "vendor": ("#411",),
+ "docs": ("#411",),
+ "doc": ("#411",),
+ "examples": ("#411",),
+ "e2e": ("#411",),
+ "migrations": ("#411",),
+ "testdata": ("#411",),
+ "bin": ("#411",),
+ "hack": ("#411",),
+}
+# The mode gate at src/discover/discover.c:448-452 applies FAST_SKIP_DIRS whenever the
+# mode is not full, so full is the only reference arm a loss can be measured against.
+REFERENCE_INDEX_MODE = "full"
+UTILITY_CUTOFF = "10"
+METRIC_ALIASES = {"leaf_hub_rate": ("utility_contamination",)}
+SCAFFOLDING_CUTOFF = "10"
+DEGREE_BASELINE = rank_evidence.DEGREE_BASELINE
+LEGACY_DEGREE_BASELINE = "degree"
+SYNTHETIC_CORPUS = "synthetic-rank-v1"
+
+
+def directory_issues(name: str) -> str:
+ return ", ".join(DIRECTORY_ISSUES.get(name, ())) or "unreported"
+
+
+def rank_cases(documents: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ """Flatten result documents into rank-quality cases, keeping the index mode.
+
+ index_mode lives in the document's parameters rather than the case, because it is a
+ property of the whole run; carrying it down is what makes the coverage diff possible.
+ """
+ cases: list[dict[str, Any]] = []
+ for document in documents:
+ parameters = document.get("parameters") or {}
+ for case in document.get("cases") or []:
+ if not isinstance(case, dict) or case.get("scenario") != "rank_quality":
+ continue
+ corpus = case.get("corpus") or {}
+ cases.append(
+ {
+ **case,
+ # A canary cell has no corpus: it runs on the synthetic fixture.
+ # Naming it here keeps every table keyed the same way, and the
+ # verdicts still exclude it because it registers no hypothesis.
+ "corpus_id": corpus.get("id") or SYNTHETIC_CORPUS,
+ "language": corpus.get("language") or "unknown",
+ "index_mode": parameters.get("index_mode"),
+ "repetition": (
+ parameters.get("repetition")
+ or document.get("repetition")
+ or case.get("repetition")
+ ),
+ "config_profile": parameters.get("config_profile"),
+ "cell_name": parameters.get("cell_name"),
+ "informs_hypotheses": parameters.get("informs_hypotheses") or [],
+ "questions": parameters.get("questions") or [],
+ # The knob canary reads these; they are run parameters rather than
+ # case fields, so they are carried down once here.
+ "config_overrides": parameters.get("config_overrides") or {},
+ }
+ )
+ return cases
+
+
+def partition_usable(cases: list[dict[str, Any]]) -> tuple[list, list]:
+ """Split cases into evidence and excluded, with the reason recorded.
+
+ A cell whose ranking views were stale measured the silent degree fallback at
+ src/store/store.c:11695-11711, not the score it asked for. Dropping it silently
+ would overstate agreement between the scores; dropping it loudly is the point.
+ """
+ usable: list[dict[str, Any]] = []
+ excluded: list[dict[str, Any]] = []
+ for case in cases:
+ staleness = case.get("rank_score_staleness") or {}
+ if staleness.get("available") and staleness.get("rank_views_fresh") is False:
+ excluded.append(
+ {
+ "corpus": case["corpus_id"],
+ "index_mode": case.get("index_mode"),
+ "reason": "rank_views_stale",
+ "detail": (
+ "search_graph falls back to a degree sort when pagerank, "
+ "linkrank or node_degree are stale, so this cell does not "
+ "measure the requested score"
+ ),
+ }
+ )
+ continue
+ usable.append(case)
+ return usable, excluded
+
+
+def cutoff_metric(case: dict[str, Any], cutoff: str, metric: str) -> dict[str, Any]:
+ """One metric for every applicable scorer in one case, at one cutoff."""
+ scorers = ((case.get("rank_score_probes") or {}).get("scorers")) or {}
+ values: dict[str, Any] = {}
+ for name, entry in scorers.items():
+ if not isinstance(entry, dict) or not entry.get("applicable"):
+ continue
+ window = (entry.get("by_cutoff") or {}).get(cutoff)
+ if not isinstance(window, dict):
+ continue
+ # utility_contamination is the pre-rename spelling of leaf_hub_rate; accepted so
+ # runsets recorded before the rename still parse rather than reading as empty.
+ for key in (metric, *METRIC_ALIASES.get(metric, ())):
+ if key in window:
+ values[name] = window[key]
+ break
+ return values
+
+
+def scorer_table(
+ cases: list[dict[str, Any]], cutoff: str, metric: str
+) -> list[dict[str, Any]]:
+ rows = []
+ for case in cases:
+ values = cutoff_metric(case, cutoff, metric)
+ if not values:
+ continue
+ rows.append(
+ {
+ "corpus": case["corpus_id"],
+ "language": case.get("language") or "unknown",
+ "index_mode": case.get("index_mode"),
+ "discriminates": (case.get("corpus") or {}).get("discriminates") or [],
+ "repetition": case.get("repetition"),
+ "config_profile": case.get("config_profile"),
+ "config_overrides": case.get("config_overrides") or {},
+ "cutoff": int(cutoff),
+ "scores": values,
+ }
+ )
+ return sorted(rows, key=lambda row: (row["corpus"], str(row["index_mode"])))
+
+
+def scorer_value(scores: dict[str, Any], scorer: str) -> Any:
+ """Read a canonical scorer while accepting retained pre-registry documents."""
+ if scorer in scores:
+ return scores[scorer]
+ for alias, canonical in rank_evidence.SCORER_ALIASES.items():
+ if canonical == scorer and alias in scores:
+ return scores[alias]
+ return None
+
+
+def collapse_scorer_rows(rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ """Collapse repetitions/detail cells to the independent corpus unit.
+
+ Means summarize repeated observations; they do not create extra sample units. For R
+ rows and S scorer names this is O(R*S) time and O(C*S) memory for C corpora.
+ """
+ grouped: dict[str, list[dict[str, Any]]] = {}
+ for row in rows:
+ grouped.setdefault(row["corpus"], []).append(row)
+ collapsed: list[dict[str, Any]] = []
+ for corpus, observations in sorted(grouped.items()):
+ names = sorted(
+ {name for observation in observations for name in observation["scores"]}
+ )
+ scores = {
+ name: mean(
+ [
+ observation["scores"].get(name)
+ for observation in observations
+ if isinstance(observation["scores"].get(name), (int, float))
+ ]
+ )
+ for name in names
+ }
+ collapsed.append(
+ {
+ "corpus": corpus,
+ "language": next(
+ (
+ row.get("language")
+ for row in observations
+ if row.get("language") and row.get("language") != "unknown"
+ ),
+ "unknown",
+ ),
+ "discriminates": sorted(
+ {
+ value
+ for row in observations
+ for value in row.get("discriminates") or []
+ }
+ ),
+ "observation_count": len(observations),
+ "scores": scores,
+ }
+ )
+ return collapsed
+
+
+def degree_agreement(cases: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ """H2: does degree give "the same ranking signal"? Reported either way.
+
+ Real corpora only. The canary arm measures a 17-file fixture built to have one
+ structurally central symbol, where the two scores agree at Spearman 0.979 by
+ construction; including it reported PR #151's claim as confirmed over 15 "corpora".
+ """
+ rows = []
+ for case in cases:
+ if case["corpus_id"] == SYNTHETIC_CORPUS:
+ continue
+ comparisons = (case.get("rank_score_probes") or {}).get("comparisons") or {}
+ if not comparisons:
+ continue
+ rows.append(
+ {
+ "corpus": case["corpus_id"],
+ "language": case.get("language") or "unknown",
+ "index_mode": case.get("index_mode"),
+ "repetition": case.get("repetition"),
+ "comparisons": comparisons,
+ }
+ )
+ return sorted(rows, key=lambda row: (row["corpus"], str(row["index_mode"])))
+
+
+def retrieval_quality_by_scorer(cases: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ """Collapse paired graded-query sort variants to corpus/scorer evidence units."""
+ grouped: dict[tuple[str, str], list[dict[str, Any]]] = {}
+ languages: dict[str, str] = {}
+ for case in cases:
+ if case["corpus_id"] == SYNTHETIC_CORPUS:
+ continue
+ summary = ((case.get("oracles") or {}).get("scorer_variant_quality")) or {}
+ languages[case["corpus_id"]] = case.get("language") or "unknown"
+ for scorer, values in summary.items():
+ if isinstance(values, dict):
+ grouped.setdefault((case["corpus_id"], scorer), []).append(values)
+ rows = []
+ for (corpus, scorer), observations in sorted(grouped.items()):
+ rows.append(
+ {
+ "corpus": corpus,
+ "language": languages.get(corpus, "unknown"),
+ "scorer": scorer,
+ "observation_count": len(observations),
+ "graded_query_count": sum(
+ int(item.get("query_count") or 0) for item in observations
+ ),
+ "mean_ndcg": mean([item.get("mean_ndcg") for item in observations]),
+ "mean_reciprocal_rank": mean(
+ [item.get("mean_reciprocal_rank") for item in observations]
+ ),
+ "hit_at_1_rate": mean(
+ [item.get("hit_at_1_rate") for item in observations]
+ ),
+ }
+ )
+ return rows
+
+
+def silent_drop(cases: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ """Directories present under full indexing and absent under another mode.
+
+ Compared per corpus so a difference between corpora cannot be read as a mode
+ effect. Only losses are emitted: a directory that gained files across modes is not
+ a silent exclusion, and reporting it as a zero row would pad the table.
+ """
+ reference: dict[str, dict[str, int]] = {}
+ for case in cases:
+ coverage = case.get("corpus_coverage") or {}
+ if case.get("index_mode") == REFERENCE_INDEX_MODE and coverage.get("available"):
+ reference[case["corpus_id"]] = coverage.get("top_level_directories") or {}
+ rows: list[dict[str, Any]] = []
+ for case in cases:
+ mode = case.get("index_mode")
+ coverage = case.get("corpus_coverage") or {}
+ corpus_id = case["corpus_id"]
+ if mode == REFERENCE_INDEX_MODE or not coverage.get("available"):
+ continue
+ baseline = reference.get(corpus_id)
+ if baseline is None:
+ continue
+ observed = coverage.get("top_level_directories") or {}
+ for name, full_count in sorted(baseline.items()):
+ lost = full_count - observed.get(name, 0)
+ if lost <= 0:
+ continue
+ rows.append(
+ {
+ "corpus": corpus_id,
+ "index_mode": mode,
+ "directory": name or "(repository root)",
+ "files_in_full": full_count,
+ "files_in_mode": observed.get(name, 0),
+ "files_lost": lost,
+ "issues": directory_issues(name),
+ }
+ )
+ return rows
+
+
+# The reply-detail knobs campaign_specs.py sweeps. A cell carrying none of them is the
+# as-shipped default arm.
+DETAIL_KEYS = ("search_limit", "trace_max_results", "snippet_max_lines")
+
+
+def detail_label(overrides: dict[str, str]) -> str:
+ declared = [f"{key}={overrides[key]}" for key in DETAIL_KEYS if key in overrides]
+ return ", ".join(declared) or "default"
+
+
+def detail_frontier(cases: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ """Retrieval quality per 1k response tokens, per corpus, per reply-detail setting.
+
+ Reply detail is a measured determinant of answer quality rather than presentation:
+ upstream #1382 recorded recall falling 0.723 -> 0.525 on jackrabbit-oak purely
+ because the graph arm returned less, an effect larger than any plausible re-ranking
+ gain. Scoring per query alone cannot separate "ordered better" from "returned more",
+ so the battery's own recorded response_token_estimate is the denominator.
+
+ Cells with no recorded tokens are omitted rather than divided by zero, which would
+ print an unbounded efficiency for a cell that measured nothing.
+ """
+ rows: list[dict[str, Any]] = []
+ for case in cases:
+ oracles = case.get("oracles") or {}
+ tokens = sum(
+ int(oracle["response_token_estimate"])
+ for oracle in oracles.values()
+ if isinstance(oracle, dict)
+ and isinstance(oracle.get("response_token_estimate"), int)
+ )
+ quality = oracles.get("quality")
+ if tokens <= 0 or not isinstance(quality, dict):
+ continue
+ ndcg = quality.get("mean_ndcg_at_5")
+ mrr = quality.get("mean_reciprocal_rank")
+ per_1k = 1000.0 / tokens
+ rows.append(
+ {
+ "corpus": case["corpus_id"],
+ "detail": detail_label(case.get("config_overrides") or {}),
+ "response_tokens": tokens,
+ "ndcg_at_5": ndcg,
+ "mean_reciprocal_rank": mrr,
+ "ndcg_per_1k_tokens": (
+ ndcg * per_1k if isinstance(ndcg, (int, float)) else None
+ ),
+ "mrr_per_1k_tokens": (
+ mrr * per_1k if isinstance(mrr, (int, float)) else None
+ ),
+ }
+ )
+ return sorted(rows, key=lambda row: (row["corpus"], row["detail"]))
+
+
+def knob_canary(cases: list[dict[str, Any]]) -> dict[str, Any]:
+ """Which ranking knobs actually moved the published scores.
+
+ A knob whose cell produced the baseline's pagerank fingerprint changed nothing.
+ That is the failure src/cli/cli.c:7160-7173 makes silent — an unowned key is
+ accepted, persisted and exits 0 — so a sweep over an inert knob reports a difference
+ of exactly zero and reads exactly like "this knob does not help". Any inert knob
+ fails the canary, because nothing measured downstream of it is interpretable.
+ """
+ baseline: str | None = None
+ observed: dict[str, str] = {}
+ for case in cases:
+ # Within the canary arm only. The rank arm's reply-detail cells also carry
+ # config_overrides (search_limit, snippet_max_lines), and counting them here
+ # compared a cosign fingerprint against a synthetic-fixture baseline and
+ # reported search_limit as a ranking knob proved live.
+ if case["corpus_id"] != SYNTHETIC_CORPUS:
+ continue
+ fingerprint = case.get("rank_table_fingerprint")
+ overrides = case.get("config_overrides") or {}
+ if not fingerprint:
+ continue
+ if not overrides:
+ baseline = fingerprint
+ continue
+ for knob in overrides:
+ observed[knob] = fingerprint
+ if baseline is None or not observed:
+ return {
+ "passed": None,
+ "live": [],
+ "inert": [],
+ "statement": "no baseline and knob cell pair was measured",
+ }
+ live = sorted(knob for knob, value in observed.items() if value != baseline)
+ inert = sorted(knob for knob, value in observed.items() if value == baseline)
+ return {
+ "passed": not inert,
+ "live": live,
+ "inert": inert,
+ "statement": (
+ f"all {len(live)} ranking knobs changed the published scores"
+ if not inert
+ else f"{len(inert)} ranking knob(s) left the published scores byte-identical "
+ f"at an extreme value: {', '.join(inert)}. Any tuning result for these is "
+ "a difference of exactly zero regardless of what the knob means."
+ ),
+ }
+
+
+def mean(values: list[float]) -> float | None:
+ numeric = [float(value) for value in values if isinstance(value, (int, float))]
+ return sum(numeric) / len(numeric) if numeric else None
+
+
+def discriminating(rows: list[dict[str, Any]], hypothesis: str) -> tuple[list, list]:
+ """Split rows by whether corpora-v1.json registered them for this hypothesis.
+
+ The registry states which condition each corpus was chosen to expose, before any
+ run. flask carries H4 and has no hub utilities at all, so folding its zero utility
+ contamination into H5 would pull the mean toward zero using a corpus that cannot
+ speak to the question. Honouring the pre-registration is what keeps the corpus set
+ from being chosen after the fact.
+ """
+ included, excluded = [], []
+ for row in rows:
+ (
+ included if hypothesis in (row.get("discriminates") or []) else excluded
+ ).append(row)
+ return included, excluded
+
+
+def paired_means(
+ rows: list[dict[str, Any]], challenger: str
+) -> tuple[float | None, float | None, list[dict[str, Any]]]:
+ paired = [
+ row
+ for row in rows
+ if isinstance(scorer_value(row["scores"], DEGREE_BASELINE), (int, float))
+ and isinstance(scorer_value(row["scores"], challenger), (int, float))
+ ]
+ return (
+ mean([scorer_value(row["scores"], DEGREE_BASELINE) for row in paired]),
+ mean([scorer_value(row["scores"], challenger) for row in paired]),
+ paired,
+ )
+
+
+def corpora_with_signal(rows: list[dict[str, Any]]) -> list[str]:
+ """Corpora where the metric actually moved off zero for at least one scorer.
+
+ A corpus on which every scorer scored 0.000 did not measure anything; it only
+ contributed a zero to a mean. Every defect found on the first real campaign run —
+ probes ranking File nodes, the rollup reading a key the probe does not emit, the
+ canary counting another arm's cells — printed a confident verdict whose backing rows
+ were entirely zero. Counting signal separately from corpora is what makes that
+ visible without rerunning anything.
+ """
+ return sorted(
+ {
+ row["corpus"]
+ for row in rows
+ if any(
+ isinstance(value, (int, float)) and value != 0
+ for value in row["scores"].values()
+ )
+ }
+ )
+
+
+def contamination_verdict(
+ rows: list[dict[str, Any]],
+ *,
+ hypothesis: str,
+ metric_name: str,
+ cutoff: str,
+ when_degree_worse: str,
+ when_degree_better: str,
+ when_absent: str,
+) -> dict[str, Any]:
+ """Compare degree against weighted PageRank on one top-K contamination metric.
+
+ Shared by H4 (scaffolding) and H5 (utility) because the shape is identical: both ask
+ whether the arm PR #151 proposed puts more of an unwanted category in the top K than
+ the weighted score does. Stated as a direction rather than a pass, and both the
+ corpus count and the number of corpora that produced any signal travel with it, so
+ neither a one-corpus pilot nor a set of all-zero rows can read as a campaign result.
+ """
+ scoped_observations, other = discriminating(rows, hypothesis)
+ scoped = collapse_scorer_rows(scoped_observations)
+ degree_mean, pagerank_mean, paired = paired_means(scoped, "pagerank")
+ with_signal = corpora_with_signal(paired)
+ verdict: dict[str, Any] = {
+ "hypothesis": hypothesis,
+ "metric": metric_name,
+ "cutoff": int(cutoff),
+ "corpora_compared": len(paired),
+ "observation_count": sum(row.get("observation_count", 1) for row in paired),
+ "corpora_with_signal": len(with_signal),
+ "signal_corpora": with_signal,
+ "not_discriminating": sorted({row["corpus"] for row in other}),
+ "status": "measured_descriptive" if paired else "not_run",
+ }
+ if degree_mean is None or pagerank_mean is None:
+ return {**verdict, "supported": None, "statement": when_absent}
+ verdict.update({"degree_mean": degree_mean, "pagerank_mean": pagerank_mean})
+ corpora = ", ".join(sorted({row["corpus"] for row in paired}))
+ margin = f"{degree_mean:.3f} vs {pagerank_mean:.3f} at K={cutoff} over {corpora}"
+ if not with_signal:
+ return {
+ **verdict,
+ "supported": None,
+ "statement": (
+ f"every scorer measured zero on all {len(paired)} corpora, so this "
+ f"metric did not discriminate anything ({margin})"
+ ),
+ }
+ if degree_mean == pagerank_mean:
+ return {
+ **verdict,
+ "supported": None,
+ "statement": (
+ f"no measurable difference between degree and weighted PageRank "
+ f"({margin})"
+ ),
+ }
+ degree_higher = degree_mean > pagerank_mean
+ return {
+ **verdict,
+ # Retained for old JSON readers; the report does not use it as a decision rule.
+ "supported": None,
+ "effect_direction": "degree_higher" if degree_higher else "pagerank_higher",
+ "effect_size": degree_mean - pagerank_mean,
+ "status": "measured_descriptive",
+ "statement": (
+ f"{when_degree_worse} ({margin}); descriptive effect, not a thresholded verdict"
+ if degree_higher
+ else f"{when_degree_better} ({margin}); descriptive effect, not a thresholded verdict"
+ ),
+ }
+
+
+def utility_verdict(
+ rows: list[dict[str, Any]], non_public_rows: list[dict[str, Any]]
+) -> dict[str, Any]:
+ """H5: measured against the public-API label, which does not use fan-in.
+
+ PR #151's claim is that the highest-fan-in symbols are utilities, so a metric derived
+ from fan-in cannot test it — that is why leaf_hub_rate was demoted to descriptive.
+ The public-API label is independent of degree: Go's export rule and Python's
+ underscore privacy are name-level language rules. Where neither applies the label is
+ null and the corpus contributes nothing rather than a zero, so H5 reports
+ not_measurable rather than a direction derived from an empty set.
+
+ Superseded reasoning, kept because it is why this metric exists:
+
+ PR #151's claim is that the highest-fan-in symbols are utilities. Testing it needs a
+ definition of "utility" that does not itself use fan-in, and neither candidate
+ qualifies: the lexical marker list is independent of fan-in but fired on one corpus
+ only, and the structural leaf-hub shape is general but selects by the very quantity
+ the degree scorers rank by, so it approaches 1.0 by construction and labelled
+ sklearn.base.BaseEstimator and hiredis redisCommand as utilities.
+
+ Reported as not measurable rather than computed, because a verdict from a circular
+ metric is worse than none: it reads as evidence. The leaf-hub and lexical rates are
+ still emitted as descriptive statistics for whoever builds the real instrument.
+ """
+ if not non_public_rows:
+ scoped, other = discriminating(rows, "H5")
+ _, _, paired = paired_means(scoped, "pagerank")
+ return {
+ "hypothesis": "H5",
+ "metric": "non_public_rate",
+ "cutoff": int(UTILITY_CUTOFF),
+ "supported": None,
+ "status": "not_measurable",
+ "corpora_compared": len(paired),
+ "corpora_with_signal": 0,
+ "signal_corpora": [],
+ "not_discriminating": sorted({row["corpus"] for row in other}),
+ "statement": (
+ "not measurable: no corpus produced a public-API verdict. The label is a "
+ "name-level language rule (Go export capitalisation, Python underscore "
+ "privacy) and returns null elsewhere, so C and Rust corpora cannot "
+ "contribute. leaf_hub_rate is descriptive only — it selects on the same "
+ "fan-in the degree scorers rank by, so it cannot adjudicate this."
+ ),
+ }
+ return contamination_verdict(
+ non_public_rows,
+ hypothesis="H5",
+ metric_name="non_public_rate",
+ cutoff=UTILITY_CUTOFF,
+ when_degree_worse=(
+ "degree DESC surfaces more non-public symbols than weighted PageRank, which "
+ "is the shape PR #151 described, measured without using fan-in"
+ ),
+ when_degree_better=(
+ "degree DESC surfaces fewer non-public symbols than weighted PageRank; the "
+ "PR #151 objection does not hold on this evidence"
+ ),
+ when_absent="no corpus registered for H5 produced both rankings with the label",
+ )
+
+
+def scaffolding_verdict(rows: list[dict[str, Any]]) -> dict[str, Any]:
+ """H4: degree counts every edge equally, including TESTS edges."""
+ return contamination_verdict(
+ rows,
+ hypothesis="H4",
+ metric_name="scaffolding",
+ cutoff=SCAFFOLDING_CUTOFF,
+ when_degree_worse="degree surfaces more test scaffolding than weighted PageRank",
+ when_degree_better="weighted PageRank surfaces more test scaffolding than degree",
+ when_absent=(
+ "no corpus registered for H4 carried Tier-A labels, so scaffolding@K is "
+ "null rather than inferred from this server's own test predicates"
+ ),
+ )
+
+
+def agreement_verdict(rows: list[dict[str, Any]]) -> dict[str, Any]:
+ """H2 observations without an arbitrary equivalence cutoff.
+
+ Repetitions and detail profiles are averaged inside each corpus first. RBO/Jaccard
+ describe the returned top page; the legacy shared-row Spearman remains visible but
+ cannot establish equivalence because it ignores symbols absent from one page.
+ """
+
+ def comparison(row: dict[str, Any]) -> dict[str, Any]:
+ values = row.get("comparisons") or {}
+ for key in (
+ f"pagerank_vs_{DEGREE_BASELINE}",
+ "pagerank_vs_degree",
+ ):
+ if isinstance(values.get(key), dict):
+ return values[key]
+ return {}
+
+ observations: dict[str, list[dict[str, Any]]] = {}
+ for row in rows:
+ value = comparison(row)
+ if value:
+ observations.setdefault(row["corpus"], []).append(value)
+ per_corpus = []
+ for corpus, values in sorted(observations.items()):
+ per_corpus.append(
+ {
+ "corpus": corpus,
+ "observation_count": len(values),
+ "rank_biased_overlap": mean(
+ [value.get("rank_biased_overlap") for value in values]
+ ),
+ "top_k_jaccard": mean([value.get("top_k_jaccard") for value in values]),
+ "shared_spearman_rho": mean(
+ [
+ value.get("shared_spearman_rho", value.get("spearman_rho"))
+ for value in values
+ ]
+ ),
+ }
+ )
+ if not per_corpus:
+ return {
+ "hypothesis": "H2",
+ "supported": None,
+ "corpora_compared": 0,
+ "observation_count": 0,
+ "corpora_with_signal": 0,
+ "signal_corpora": [],
+ "status": "not_run",
+ "statement": "no corpus produced a degree-to-pagerank correlation",
+ }
+ rbo = mean([row["rank_biased_overlap"] for row in per_corpus])
+ jaccard = mean([row["top_k_jaccard"] for row in per_corpus])
+ spearman = mean([row["shared_spearman_rho"] for row in per_corpus])
+ metric_summary = ", ".join(
+ f"{name}={value:.3f}"
+ for name, value in (
+ ("RBO", rbo),
+ ("Jaccard", jaccard),
+ ("shared-row Spearman", spearman),
+ )
+ if value is not None
+ )
+ corpora = [row["corpus"] for row in per_corpus]
+ return {
+ "hypothesis": "H2",
+ "supported": None,
+ "corpora_compared": len(corpora),
+ "observation_count": sum(row["observation_count"] for row in per_corpus),
+ "corpora_with_signal": len(corpora),
+ "signal_corpora": corpora,
+ "status": "measured_descriptive",
+ "rank_biased_overlap_mean": rbo,
+ "top_k_jaccard_mean": jaccard,
+ "spearman_mean": spearman,
+ "per_corpus": per_corpus,
+ "statement": (
+ f"measured {metric_summary or 'no numeric agreement metric'} over "
+ f"{len(corpora)} independent corpora and "
+ f"{sum(row['observation_count'] for row in per_corpus)} observations. "
+ "No equivalence/non-inferiority margin was pre-registered, so these effect "
+ "sizes are descriptive rather than a supported/refuted verdict."
+ ),
+ }
+
+
+def hypothesis_metadata(hypothesis_id: str, verdict: dict[str, Any]) -> dict[str, Any]:
+ definition = rank_evidence.HYPOTHESES[hypothesis_id]
+ return {
+ "hypothesis": hypothesis_id,
+ "name": definition["name"],
+ "question": definition["question"],
+ "family": definition["family"],
+ **verdict,
+ }
+
+
+def not_run_verdict(hypothesis_id: str, statement: str) -> dict[str, Any]:
+ return hypothesis_metadata(
+ hypothesis_id,
+ {
+ "supported": None,
+ "status": "not_run",
+ "corpora_compared": 0,
+ "observation_count": 0,
+ "corpora_with_signal": 0,
+ "signal_corpora": [],
+ "statement": statement,
+ },
+ )
+
+
+def utility_family_h1(h5: dict[str, Any]) -> dict[str, Any]:
+ """Represent H1 without pretending H5's shared observations are new evidence."""
+ return hypothesis_metadata(
+ "H1",
+ {
+ "supported": None,
+ "status": h5.get("status", "not_run"),
+ "corpora_compared": h5.get("corpora_compared", 0),
+ "observation_count": h5.get("observation_count", 0),
+ "corpora_with_signal": h5.get("corpora_with_signal", 0),
+ "signal_corpora": h5.get("signal_corpora", []),
+ "shared_evidence_with": "H5",
+ "independent_evidence": False,
+ "statement": (
+ "H1 and H5 share the same utility/public-surface observations; this row "
+ "does not count them twice. "
+ + str(h5.get("statement", "No shared evidence was measured."))
+ ),
+ },
+ )
+
+
+def linkrank_capability_verdict(cases: list[dict[str, Any]]) -> dict[str, Any]:
+ observed = [
+ case
+ for case in cases
+ if ((case.get("rank_score_probes") or {}).get("edge_linkrank") or {}).get(
+ "applicable"
+ )
+ ]
+ if not observed:
+ return not_run_verdict(
+ "H6", "no cell emitted an applicable edge-level LinkRank ranking"
+ )
+ corpora = sorted({case["corpus_id"] for case in observed})
+ return hypothesis_metadata(
+ "H6",
+ {
+ "supported": None,
+ "status": "instrumented_not_evaluated",
+ "corpora_compared": len(corpora),
+ "observation_count": len(observed),
+ "corpora_with_signal": len(corpora),
+ "signal_corpora": corpora,
+ "statement": (
+ f"{len(observed)} cells over {len(corpora)} corpora emitted ranked "
+ "source-edge-target tuples. No judged edge/path task and node-only "
+ "candidate-budget control were run, so H6 has instrumentation but no verdict."
+ ),
+ },
+ )
+
+
+def language_strata(cases: list[dict[str, Any]]) -> dict[str, dict[str, Any]]:
+ grouped: dict[str, set[str]] = {}
+ observations: dict[str, int] = {}
+ for case in cases:
+ language = str(case.get("language") or "unknown")
+ grouped.setdefault(language, set()).add(case["corpus_id"])
+ observations[language] = observations.get(language, 0) + 1
+ return {
+ language: {
+ "corpora": sorted(corpora),
+ "corpus_count": len(corpora),
+ "observation_count": observations[language],
+ }
+ for language, corpora in sorted(grouped.items())
+ }
+
+
+def cell_question_map(cases: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ """Deduplicate the audit mapping carried from matrix profile to result document."""
+ records: dict[str, dict[str, Any]] = {}
+ for case in cases:
+ name = case.get("cell_name")
+ if not isinstance(name, str) or not name:
+ continue
+ records[name] = {
+ "cell_name": name,
+ "informs_hypotheses": list(case.get("informs_hypotheses") or []),
+ "questions": list(case.get("questions") or []),
+ }
+ return [records[name] for name in sorted(records)]
+
+
+def validation_gate(rollup: dict[str, Any]) -> dict[str, Any]:
+ """Whether this rollup's verdicts may be quoted, and if not, exactly why.
+
+ Not a formality. On the first complete campaign run every one of three separate
+ defects in this pipeline printed a confident verdict, and each would have been
+ caught here: two produced all-zero backing rows, and the third contaminated the
+ canary with another arm's cells so it reported more live knobs than exist.
+
+ A reader must be able to see the reason without rerunning anything, so each
+ precondition is reported individually rather than collapsed into one boolean.
+ """
+ canary = rollup["knob_canary"]["passed"]
+ provisional = sorted(
+ name
+ for name, verdict in rollup["verdicts"].items()
+ if verdict.get("status") != "decision_ready"
+ )
+ checks = {
+ "knob_canary_passed": canary,
+ "no_cells_excluded": not rollup["excluded"],
+ "fixture_overlay_declared": rollup["fixture_overlay"] != [],
+ "provisional_verdicts": provisional,
+ "decision_rule_pre_registered": False,
+ "independent_unit": "corpus; repetitions and detail profiles are observations",
+ }
+ checks["passed"] = False
+ checks["statement"] = (
+ "NOT DECISION-READY — no equivalence/non-inferiority margin or inferential "
+ "decision rule was pre-registered. Report the continuous effect sizes, corpus "
+ "coverage, and missing arms; do not quote supported/refuted labels."
+ )
+ return checks
+
+
+def build_rollup(documents: list[dict[str, Any]]) -> dict[str, Any]:
+ """Reduce campaign result documents to tables, verdicts and a content address."""
+ cases = rank_cases(documents)
+ usable, excluded = partition_usable(cases)
+ utility_rows = scorer_table(usable, UTILITY_CUTOFF, "leaf_hub_rate")
+ non_public_rows = [
+ row
+ for row in scorer_table(usable, UTILITY_CUTOFF, "non_public_rate")
+ if any(value is not None for value in row["scores"].values())
+ ]
+ scaffolding_rows = [
+ row
+ for row in scorer_table(usable, SCAFFOLDING_CUTOFF, "scaffolding")
+ if any(value is not None for value in row["scores"].values())
+ ]
+ agreement_rows = degree_agreement(usable)
+ retrieval_rows = retrieval_quality_by_scorer(usable)
+ h2 = hypothesis_metadata("H2", agreement_verdict(agreement_rows))
+ task_quality_corpora = len({row["corpus"] for row in retrieval_rows})
+ h2["task_quality_corpora"] = task_quality_corpora
+ h2["retrieval_quality_by_scorer"] = retrieval_rows
+ if retrieval_rows:
+ h2["statement"] += (
+ f" Paired graded-query quality was also measured for "
+ f"{len({row['scorer'] for row in retrieval_rows})} search rank modes over "
+ f"{task_quality_corpora} corpora; see retrieval_quality_by_scorer."
+ )
+ h4 = hypothesis_metadata("H4", scaffolding_verdict(scaffolding_rows))
+ h5 = hypothesis_metadata("H5", utility_verdict(utility_rows, non_public_rows))
+ h6 = linkrank_capability_verdict(usable)
+ rollup: dict[str, Any] = {
+ "schema_version": 1,
+ "corpora": sorted({case["corpus_id"] for case in usable}),
+ "index_modes": sorted({str(case.get("index_mode")) for case in usable}),
+ "language_strata": language_strata(usable),
+ "cell_question_map": cell_question_map(usable),
+ "evidence_units": {
+ "independent_unit": "corpus",
+ "corpus_count": len({case["corpus_id"] for case in usable}),
+ "observation_count": len(usable),
+ "warning": (
+ "repetitions, detail profiles, and config arms are repeated observations; "
+ "they are never counted as independent corpora"
+ ),
+ },
+ "hypothesis_registry": rank_evidence.public_hypothesis_registry(),
+ "leaf_hub_rate": utility_rows,
+ "non_public_rate": non_public_rows,
+ "scaffolding": scaffolding_rows,
+ "degree_agreement": agreement_rows,
+ "retrieval_quality_by_scorer": retrieval_rows,
+ "silent_drop": silent_drop(usable),
+ "predicted_loss_checks": [
+ {
+ "corpus": case["corpus_id"],
+ "index_mode": case.get("index_mode"),
+ **(
+ (case.get("corpus_coverage") or {}).get("predicted_loss_check")
+ or {}
+ ),
+ }
+ for case in usable
+ if (case.get("corpus_coverage") or {}).get("predicted_loss_check")
+ ],
+ # Validity, not decoration: an overlaid fixture changes what every corpus-scoped
+ # number means, so the state travels with the numbers.
+ "fixture_overlay": sorted(
+ {str((case.get("fixture") or {}).get("corpus_overlay")) for case in usable}
+ ),
+ "detail_frontier": detail_frontier(usable),
+ "excluded": excluded,
+ # A validity precondition rather than a result: an inert knob makes every
+ # tuning number downstream of it a difference of exactly zero.
+ "knob_canary": knob_canary(usable),
+ "verdicts": {
+ "H1": utility_family_h1(h5),
+ "H2": h2,
+ "H3": not_run_verdict(
+ "H3",
+ "no paired rank-enabled/rank-disabled production-scale cost and task-quality arm was analyzed",
+ ),
+ "H4": h4,
+ "H5": h5,
+ "H6": h6,
+ "H7": not_run_verdict(
+ "H7",
+ "no pre-registered default-versus-tuned held-out language/task comparison was analyzed",
+ ),
+ },
+ }
+ rollup["validation"] = validation_gate(rollup)
+ payload = json.dumps(rollup, sort_keys=True, separators=(",", ":")).encode("utf-8")
+ rollup["manifest"] = {
+ "rollup_sha256": hashlib.sha256(payload).hexdigest(),
+ "document_count": len(documents),
+ "case_count": len(cases),
+ "usable_case_count": len(usable),
+ }
+ return rollup
+
+
+def format_number(value: Any) -> str:
+ if isinstance(value, (int, float)) and not isinstance(value, bool):
+ return f"{value:.3f}"
+ return "n/a"
+
+
+def scorer_section(title: str, rows: list[dict[str, Any]], note: str) -> list[str]:
+ if not rows:
+ return [f"### {title}", "", f"No rows. {note}", ""]
+ names = sorted({name for row in rows for name in row["scores"]})
+ lines = [
+ f"### {title}",
+ "",
+ "| Corpus | Mode | " + " | ".join(names) + " |",
+ "|---|---|" + "---|" * len(names),
+ ]
+ for row in rows:
+ cells = " | ".join(format_number(row["scores"].get(name)) for name in names)
+ lines.append(f"| {row['corpus']} | {row['index_mode']} | {cells} |")
+ lines.extend(["", note, ""])
+ return lines
+
+
+def render_markdown(rollup: dict[str, Any]) -> str:
+ lines = [
+ "# Rank-quality campaign rollup",
+ "",
+ (
+ f"Corpora: {', '.join(rollup['corpora']) or 'none'}. "
+ f"Index modes: {', '.join(rollup['index_modes']) or 'none'}. "
+ f"Fixture overlay: {', '.join(rollup['fixture_overlay']) or 'n/a'}."
+ ),
+ "",
+ f"## Validation: {'DECISION-READY' if rollup['validation']['passed'] else 'NOT DECISION-READY'}",
+ "",
+ rollup["validation"]["statement"],
+ "",
+ (
+ "Continuous effects are observations. Without a pre-registered decision rule, "
+ "they are not supported/refuted findings."
+ ),
+ "",
+ "## Verdicts",
+ "",
+ "| Hypothesis and plain-English name | Status | Corpora | Observations | Statement |",
+ "|---|---|---|---|---|",
+ ]
+ for key in rank_evidence.HYPOTHESES:
+ verdict = rollup["verdicts"][key]
+ lines.append(
+ f"| {key} — {verdict['name']} | {verdict.get('status', 'unknown')} | "
+ f"{verdict.get('corpora_compared', 0)} | "
+ f"{verdict.get('observation_count', 0)} | {verdict['statement']} |"
+ )
+ canary = rollup["knob_canary"]
+ state = {True: "passed", False: "FAILED", None: "not run"}[canary["passed"]]
+ lines.extend(
+ [
+ "",
+ "## Knob-efficacy canary",
+ "",
+ f"**{state}** — {canary['statement']}",
+ "",
+ f"Live: {', '.join(canary['live']) or 'none'}.",
+ "",
+ ]
+ )
+ lines.extend(["## Ranking", ""])
+ if rollup["retrieval_quality_by_scorer"]:
+ lines.extend(
+ [
+ "### Paired graded-query quality by search rank mode",
+ "",
+ "| Corpus | Language | Scorer | Graded queries | nDCG | MRR | Hit@1 |",
+ "|---|---|---|---|---|---|---|",
+ ]
+ )
+ for row in rollup["retrieval_quality_by_scorer"]:
+ lines.append(
+ f"| {row['corpus']} | {row['language']} | {row['scorer']} | "
+ f"{row['graded_query_count']} | {format_number(row['mean_ndcg'])} | "
+ f"{format_number(row['mean_reciprocal_rank'])} | "
+ f"{format_number(row['hit_at_1_rate'])} |"
+ )
+ lines.extend(
+ [
+ "",
+ (
+ "Each corpus is one evidence unit; repeated cells are averaged. These "
+ "are effect measurements, not a supported/refuted label without a "
+ "declared decision rule."
+ ),
+ "",
+ ]
+ )
+ lines.extend(
+ scorer_section(
+ f"Leaf-hub rate @{UTILITY_CUTOFF} (descriptive, not a verdict)",
+ rollup["leaf_hub_rate"],
+ "Fraction of the top-K whose fan-in is above the corpus's 99th percentile "
+ "with near-zero fan-out. NOT a utility count and NOT evidence about PR #151: "
+ "the degree scorers rank by the same quantity this selects on.",
+ )
+ )
+ lines.extend(
+ scorer_section(
+ f"Scaffolding @{SCAFFOLDING_CUTOFF}",
+ rollup["scaffolding"],
+ "From Tier-A labels only; a corpus with no label file is absent rather than "
+ "scored zero. On jest the product is test infrastructure, so a low value "
+ "there is a defect rather than a win.",
+ )
+ )
+ if rollup["silent_drop"]:
+ lines.extend(
+ [
+ "## Silent drop",
+ "",
+ "| Corpus | Mode | Directory | Files in full | Files in mode | Lost | Issues |",
+ "|---|---|---|---|---|---|---|",
+ ]
+ )
+ for row in rollup["silent_drop"]:
+ lines.append(
+ f"| {row['corpus']} | {row['index_mode']} | `{row['directory']}` | "
+ f"{row['files_in_full']} | {row['files_in_mode']} | {row['files_lost']} | "
+ f"{row['issues']} |"
+ )
+ lines.append("")
+ if rollup["detail_frontier"]:
+ lines.extend(
+ [
+ "## Reply-detail frontier",
+ "",
+ "| Corpus | Detail | Response tokens | nDCG@5 | nDCG@5 per 1k tokens |",
+ "|---|---|---|---|---|",
+ ]
+ )
+ for row in rollup["detail_frontier"]:
+ lines.append(
+ f"| {row['corpus']} | {row['detail']} | {row['response_tokens']} | "
+ f"{format_number(row['ndcg_at_5'])} | "
+ f"{format_number(row['ndcg_per_1k_tokens'])} |"
+ )
+ lines.extend(
+ [
+ "",
+ (
+ "Quality per token, not per query: upstream #1382 measured recall "
+ "0.723 -> 0.525 purely from the graph arm returning less, an effect "
+ "larger than any plausible re-ranking gain."
+ ),
+ "",
+ ]
+ )
+ if rollup["excluded"]:
+ lines.extend(
+ [
+ "## Excluded from the verdicts",
+ "",
+ "| Corpus | Mode | Reason |",
+ "|---|---|---|",
+ ]
+ )
+ for row in rollup["excluded"]:
+ lines.append(f"| {row['corpus']} | {row['index_mode']} | {row['reason']} |")
+ lines.append("")
+ lines.extend(
+ [
+ "## Manifest",
+ "",
+ f"- Rollup SHA-256: `{rollup['manifest']['rollup_sha256']}`",
+ f"- Result documents: {rollup['manifest']['document_count']}",
+ (
+ f"- Rank-quality cases: {rollup['manifest']['case_count']} "
+ f"({rollup['manifest']['usable_case_count']} used)"
+ ),
+ "",
+ ]
+ )
+ return "\n".join(lines)
+
+
+def load_documents(roots: list[Path], inputs: list[Path]) -> list[dict[str, Any]]:
+ """Read the derived report inputs run_experiments.py already materializes.
+
+ reports/inputs/-.json is written by materialize_report_input
+ (run_experiments.py:2414-2441) and carries the full result document plus its
+ provenance, so the rollup reads one stable location instead of walking attempts.
+ """
+ paths: list[Path] = list(inputs)
+ for root in roots:
+ paths.extend(sorted((root / "reports" / "inputs").glob("*.json")))
+ # A container run nests each measured cohort under runsets//.
+ paths.extend(sorted(root.glob("runsets/*/reports/inputs/*.json")))
+ documents = []
+ for path in sorted(set(paths)):
+ documents.append(json.loads(path.read_text(encoding="utf-8")))
+ return documents
+
+
+def main(argv: list[str] | None = None) -> int:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "--experiment-root",
+ action="append",
+ default=[],
+ type=Path,
+ help="Campaign experiment root, repeatable; reads reports/inputs/*.json.",
+ )
+ parser.add_argument(
+ "--input", action="append", default=[], type=Path, help="One result document."
+ )
+ parser.add_argument("--out", type=Path, help="Markdown output path.")
+ parser.add_argument("--json", dest="json_out", type=Path, help="Rollup JSON path.")
+ args = parser.parse_args(argv)
+
+ documents = load_documents(args.experiment_root, args.input)
+ if not documents:
+ parser.error(
+ "no result documents found; pass --experiment-root pointing at a campaign "
+ "root containing reports/inputs/, or --input for a single result file"
+ )
+ rollup = build_rollup(documents)
+ text = render_markdown(rollup)
+ if args.out:
+ args.out.parent.mkdir(parents=True, exist_ok=True)
+ args.out.write_text(text + "\n", encoding="utf-8")
+ print(f"wrote {args.out}")
+ if args.json_out:
+ args.json_out.parent.mkdir(parents=True, exist_ok=True)
+ args.json_out.write_text(
+ json.dumps(rollup, indent=2, sort_keys=True) + "\n", encoding="utf-8"
+ )
+ print(f"wrote {args.json_out}")
+ if not args.out and not args.json_out:
+ print(text)
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/benchmarks/run_benchmark.py b/benchmarks/run_benchmark.py
new file mode 100755
index 000000000..716dc718e
--- /dev/null
+++ b/benchmarks/run_benchmark.py
@@ -0,0 +1,9432 @@
+#!/usr/bin/env python3
+"""Run one isolated indexing benchmark and emit auditable fact tables.
+
+The default workload gates fast-mode exact incremental indexing against a fresh
+full rebuild. Additional flags select self-dogfood, quality, scaling, and surface
+measurements. Every workload uses an isolated cache and removes only paths it created.
+"""
+
+from __future__ import annotations
+
+import argparse
+import ast
+import gzip
+import hashlib
+import importlib.util
+import json
+import math
+import os
+import platform
+import queue
+import re
+import shutil
+import sqlite3
+import statistics
+import subprocess
+import sys
+import tarfile
+import tempfile
+import threading
+import time
+from contextlib import closing, suppress
+from datetime import datetime, timezone
+from itertools import pairwise
+from pathlib import Path
+from typing import Any
+
+try: # Package import under tests; script-local import for direct execution.
+ from benchmarks import rank_hypotheses as rank_evidence
+except ModuleNotFoundError: # pragma: no cover - selected by ``python benchmarks/...``
+ import rank_hypotheses as rank_evidence
+
+
+CONFIG_SPELLING_SPEC_PATH = Path(__file__).with_name("config-spellings-v1.json")
+with CONFIG_SPELLING_SPEC_PATH.open(encoding="utf-8") as stream:
+ CONFIG_SPELLING_SPEC = json.load(stream)
+if CONFIG_SPELLING_SPEC.get("schema_version") != 1:
+ raise RuntimeError(
+ f"unsupported benchmark config spelling schema: {CONFIG_SPELLING_SPEC_PATH}"
+ )
+
+DEFAULT_CORPORA_MANIFEST = Path(__file__).with_name("corpora-v1.json")
+
+# Every benchmark repository - corpora and the fastapi probe alike - is cached here.
+BENCH_REPO_CACHE_ROOT = Path.home() / ".cache" / "codebase-memory-mcp" / "bench-repos"
+# Declared by the workload corpora in corpora-v1.json: their value is the query
+# distribution mined against whatever the operator had indexed, so no single commit
+# describes them. The commit actually measured is read from the checkout and recorded.
+UNPINNED_REVISION = "resolve-at-run-time"
+
+CONFIG_KEYS_PATH = Path(__file__).with_name("config-keys-v1.json")
+with CONFIG_KEYS_PATH.open(encoding="utf-8") as stream:
+ CONFIG_KEYS_SPEC = json.load(stream)
+if CONFIG_KEYS_SPEC.get("schema_version") != 1:
+ raise RuntimeError(f"unsupported benchmark config key schema: {CONFIG_KEYS_PATH}")
+KNOWN_CONFIG_KEYS = frozenset(CONFIG_KEYS_SPEC["keys"])
+
+BENCHMARK_TERMINOLOGY_PATH = Path(__file__).with_name("terminology.json")
+with BENCHMARK_TERMINOLOGY_PATH.open(encoding="utf-8") as stream:
+ BENCHMARK_TERMINOLOGY = json.load(stream)
+if BENCHMARK_TERMINOLOGY.get("schema_version") != 1:
+ raise RuntimeError(
+ f"unsupported benchmark terminology schema: {BENCHMARK_TERMINOLOGY_PATH}"
+ )
+BENCHMARK_TERMINOLOGY_VERSION = BENCHMARK_TERMINOLOGY["terminology_version"]
+BENCHMARK_TERMINOLOGY_SHA256 = hashlib.sha256(
+ json.dumps(BENCHMARK_TERMINOLOGY, separators=(",", ":"), sort_keys=True).encode(
+ "utf-8"
+ )
+).hexdigest()
+BENCHMARK_TERMINOLOGY_MARKDOWN_PATH = (
+ Path(__file__).resolve().parents[1] / "docs" / "BENCHMARK_TERMINOLOGY.md"
+)
+
+
+BENCHMARK_ARTIFACT_DIR_ENV = "CBM_BENCHMARK_ARTIFACT_DIR"
+BENCHMARK_RUN_CONTEXT_ENV = "CBM_BENCHMARK_RUN_CONTEXT"
+BENCHMARK_ENVIRONMENT_POLICY_PATH = Path(__file__).with_name(
+ "environment-policy-v1.json"
+)
+with BENCHMARK_ENVIRONMENT_POLICY_PATH.open(encoding="utf-8") as stream:
+ BENCHMARK_ENVIRONMENT_POLICY = json.load(stream)
+if BENCHMARK_ENVIRONMENT_POLICY.get("schema_version") != 1:
+ raise RuntimeError(
+ f"unsupported benchmark environment policy: {BENCHMARK_ENVIRONMENT_POLICY_PATH}"
+ )
+PRODUCT_ENVIRONMENT_PREFIX = BENCHMARK_ENVIRONMENT_POLICY["product_environment_prefix"]
+HARNESS_OWNED_PRODUCT_ENV = frozenset(
+ BENCHMARK_ENVIRONMENT_POLICY["harness_owned_keys"]
+)
+DAEMON_LOG_RELATIVE_PATH = Path("logs") / "cbm-daemon.log"
+BENCHMARK_FACT_SCHEMA_VERSION = 2
+BENCHMARK_FACT_SCHEMA = "benchmarks/schema/facts-v2.schema.json"
+BENCHMARK_FACT_COMPATIBLE_SCHEMA_URIS = {
+ BENCHMARK_FACT_SCHEMA,
+ "docs/schema/benchmark-facts-v2.schema.json",
+}
+BENCHMARK_FACT_LEGACY_SCHEMAS = {
+ 1: "docs/schema/benchmark-facts-v1.schema.json",
+}
+REPEATED_JSON_TRIALS = 3
+
+
+DEFAULT_FILE_COUNT = 240
+DEFAULT_FUNCTIONS_PER_FILE = 12
+DEFAULT_CHANGED_FILES = 2
+DEFAULT_MIN_SPEEDUP = 10.0
+DEFAULT_TIMEOUT_SECONDS = 240
+RANK_REFRESH_CANDIDATE_DEFAULT = "candidate_default"
+DEFAULT_RANK_REFRESH = RANK_REFRESH_CANDIDATE_DEFAULT
+DEFAULT_OVERHEAD_PROBES = 0
+DEFAULT_OVERHEAD_TOOL = "index_status"
+DEFAULT_INDEXED_QUERY_PROBES = 0
+DEFAULT_INDEXED_QUERY_TOOL = "index_status"
+DEFAULT_FRONTIER_FILES = 16
+DEFAULT_LIST_PROJECT_COUNTS = "1,16,64"
+DEFAULT_LIST_PROJECT_FIXTURE_MAX_MB = 512
+LIST_PROJECT_DISK_RESERVE_BYTES = 2 * 1024 * 1024 * 1024
+LIST_PROJECT_DISK_RESERVE_FRACTION = 0.05
+SEARCH_PROJECTION_INTERNAL_FIELDS = frozenset({"fp", "sp", "bt"})
+SEARCH_PROJECTION_CORE_FIELDS = frozenset(
+ {
+ "name",
+ "qualified_name",
+ "label",
+ "file_path",
+ "pagerank",
+ "in_degree",
+ "out_degree",
+ "source",
+ "package",
+ "read_only",
+ "connected",
+ }
+)
+DEFAULT_FASTAPI_URL = "https://github.com/fastapi/fastapi.git"
+CONFIG_PROFILE_CANDIDATE_NATIVE = "candidate_native_configuration"
+CONFIG_PROFILE_AUTOMATIC_DEPENDENCY_SOURCE_INDEXING_DISABLED = (
+ "automatic_dependency_source_indexing_disabled"
+)
+CONFIG_PROFILE_AUTOMATIC_DEPENDENCY_SOURCE_INDEXING_ENABLED = (
+ "automatic_dependency_source_indexing_enabled"
+)
+CONFIG_PROFILE_DEFAULT = CONFIG_PROFILE_AUTOMATIC_DEPENDENCY_SOURCE_INDEXING_DISABLED
+CONFIG_PROFILE_RANK_DISABLED = "rank_disabled"
+CONFIG_PROFILE_SIMILARITY_DISABLED = "similarity_disabled"
+CONFIG_PROFILE_SEMANTIC_EDGES_DISABLED = "semantic_edges_disabled"
+CONFIG_PROFILE_GIT_HISTORY_DISABLED = "git_history_disabled"
+CONFIG_PROFILE_HTTP_LINKS_DISABLED = "http_links_disabled"
+# Retained plans may still name this removed duplicate profile.
+CONFIG_PROFILE_OPTIONAL_GRAPH_DISABLED = "optional_graph_disabled"
+CONFIG_PROFILE_INCREMENTAL_DERIVED_RESULTS_REFRESH_AT_PUBLISH = CONFIG_SPELLING_SPEC[
+ "profiles"
+]["derived_results_refresh_at_publish"]["canonical"]
+CONFIG_PROFILE_MINIMAL_INDEXING = "minimal_indexing"
+DERIVED_REFRESH_CANDIDATE_DEFAULT = "candidate_default"
+CONFIG_SPELLING_CANONICAL = "canonical"
+CONFIG_SPELLING_PRE_RENAME = "pre_rename"
+CONFIG_SPELLING_MODES: dict[tuple[str, int, int], str] = {}
+CONFIG_SPELLING_MODES_LOCK = threading.Lock()
+CONFIG_OVERRIDE_SPELLINGS = {
+ entry["id"]: entry for entry in CONFIG_SPELLING_SPEC["config_overrides"]
+}
+PRE_RENAME_CONFIG_SPELLINGS = {
+ (entry["canonical"]["key"], entry["canonical"]["value"]): (
+ entry["historical"]["key"],
+ entry["historical"]["value"],
+ )
+ for entry in CONFIG_SPELLING_SPEC["config_overrides"]
+}
+DERIVED_RESULTS_AT_PUBLISH_OVERRIDE = CONFIG_OVERRIDE_SPELLINGS[
+ "incremental_derived_results_refresh_at_publish"
+]["canonical"]
+RANK_REFRESH_DEFAULT_SPELLINGS = CONFIG_OVERRIDE_SPELLINGS[
+ "rank_refresh_defer_all_incremental_reindexes"
+]
+RANK_REFRESH_POLICIES = tuple(
+ entry["canonical"]["value"]
+ for entry in CONFIG_SPELLING_SPEC["config_overrides"]
+ if entry["canonical"]["key"] == "rank_refresh"
+)
+PRODUCT_DEFAULT_GRAPH_CAPABILITIES = {
+ "auto_index_deps": "false",
+ "rank_enabled": "true",
+ "similarity_enabled": "true",
+ "semantic_edges_enabled": "true",
+ "githistory_enabled": "true",
+ "httplinks_enabled": "true",
+}
+
+
+def product_default_graph_capabilities(**changes: str) -> dict[str, str]:
+ values = dict(PRODUCT_DEFAULT_GRAPH_CAPABILITIES)
+ values.update(changes)
+ return values
+
+
+MINIMAL_INDEXING_CAPABILITIES = product_default_graph_capabilities(
+ rank_enabled="false",
+ similarity_enabled="false",
+ semantic_edges_enabled="false",
+ githistory_enabled="false",
+ httplinks_enabled="false",
+)
+
+
+CONFIG_PROFILES: dict[str, dict[str, str]] = {
+ CONFIG_PROFILE_CANDIDATE_NATIVE: {},
+ CONFIG_PROFILE_AUTOMATIC_DEPENDENCY_SOURCE_INDEXING_DISABLED: product_default_graph_capabilities(),
+ CONFIG_PROFILE_AUTOMATIC_DEPENDENCY_SOURCE_INDEXING_ENABLED: product_default_graph_capabilities(
+ auto_index_deps="true"
+ ),
+ CONFIG_PROFILE_RANK_DISABLED: product_default_graph_capabilities(
+ rank_enabled="false"
+ ),
+ CONFIG_PROFILE_SIMILARITY_DISABLED: product_default_graph_capabilities(
+ similarity_enabled="false"
+ ),
+ CONFIG_PROFILE_SEMANTIC_EDGES_DISABLED: product_default_graph_capabilities(
+ semantic_edges_enabled="false"
+ ),
+ CONFIG_PROFILE_GIT_HISTORY_DISABLED: product_default_graph_capabilities(
+ githistory_enabled="false"
+ ),
+ CONFIG_PROFILE_HTTP_LINKS_DISABLED: product_default_graph_capabilities(
+ httplinks_enabled="false"
+ ),
+ CONFIG_PROFILE_INCREMENTAL_DERIVED_RESULTS_REFRESH_AT_PUBLISH: {
+ **product_default_graph_capabilities(),
+ DERIVED_RESULTS_AT_PUBLISH_OVERRIDE["key"]: DERIVED_RESULTS_AT_PUBLISH_OVERRIDE[
+ "value"
+ ],
+ },
+ CONFIG_PROFILE_OPTIONAL_GRAPH_DISABLED: MINIMAL_INDEXING_CAPABILITIES,
+ CONFIG_PROFILE_MINIMAL_INDEXING: MINIMAL_INDEXING_CAPABILITIES,
+}
+INDEX_MODES = ("fast", "moderate", "full")
+PROJECT_DB_SUFFIX = ".db"
+CONFIG_DB_NAME = "_config.db"
+# Keep benchmark cache discovery aligned with CBM_DEP_SEPARATOR in
+# src/depindex/depindex.h. Dependency indexes are separate project databases,
+# not ambiguous candidates for the benchmark workload's primary database.
+DEPENDENCY_PROJECT_SEPARATOR = ".dep."
+LOG_TAIL_LINES = 24
+FAILURE_TAIL_LINES = 80
+FAILURE_ARTIFACT_DIRNAME = "failures"
+FAILURE_FALLBACK_DIRNAME = "cbm-benchmark-failures"
+FAILURE_TIMESTAMP_FORMAT = "%Y-%m-%d-%H%M%SZ"
+MCP_INIT_PROTOCOL_VERSION = "2024-11-05"
+MCP_CAPABILITY_SURFACES = (
+ (
+ "structural_search",
+ "structural and semantic symbol lookup",
+ ("search_graph",),
+ ("search_graph",),
+ ),
+ (
+ "programmable_graph_analysis",
+ "problem-specific read-only Cypher",
+ ("query_graph",),
+ ("query_graph",),
+ ),
+ (
+ "source_text_search",
+ "literal and regular-expression source lookup",
+ ("search_code",),
+ ("search_code",),
+ ),
+ (
+ "call_path_analysis",
+ "inbound, outbound, and bidirectional call tracing",
+ ("trace_path",),
+ ("trace_path",),
+ ),
+ (
+ "source_retrieval",
+ "qualified-symbol source retrieval",
+ ("get_code_snippet",),
+ ("get_code",),
+ ),
+ (
+ "explicit_index_control",
+ "explicit repository indexing",
+ ("index_repository",),
+ (),
+ ),
+ (
+ "schema_and_architecture",
+ "graph schema and architecture diagnostics",
+ ("get_graph_schema", "get_architecture"),
+ (),
+ ),
+ (
+ "index_diagnostics",
+ "freshness, inventory, and coverage diagnostics",
+ ("index_status", "list_projects", "check_index_coverage"),
+ (),
+ ),
+ ("change_impact", "git-change blast-radius analysis", ("detect_changes",), ()),
+ (
+ "dependency_sources",
+ "local dependency source indexing",
+ ("index_dependencies",),
+ (),
+ ),
+ ("project_lifecycle", "indexed-project deletion", ("delete_project",), ()),
+ (
+ "architecture_evidence",
+ "ADR storage and runtime-trace ingest request surfaces",
+ ("manage_adr", "ingest_traces"),
+ (),
+ ),
+)
+MATRIX_SCENARIOS_DEFAULT = "go_modify_1,go_modify_2,go_create,go_delete,go_rename,go_new_folder,route_decorator,python_reexport"
+MATRIX_REAL_REPO_SCENARIOS = frozenset({"fastapi_insert_probe"})
+# Capabilities whose fixture may be overlaid on a real checked-out repository via
+# --quality-background-repo. "rank" is included so ranking quality can be measured on
+# real corpora rather than only on the synthetic create_rank_quality_repo fixture,
+# which contains eight lexical decoys and no test files at all.
+QUALITY_BACKGROUND_CAPABILITIES = frozenset({"similarity", "semantic_edges", "rank"})
+
+CAPABILITY_QUALITY_CASES = (
+ "rank",
+ "dependencies",
+ "similarity",
+ "semantic_edges",
+ "git_history",
+ "http_links",
+)
+CROSS_FILE_RESOLVER_LANGUAGES = (
+ "go",
+ "c",
+ "cpp",
+ "cuda",
+ "python",
+ "javascript",
+ "typescript",
+ "tsx",
+ "php",
+ "csharp",
+ "java",
+ "kotlin",
+ "rust",
+)
+SCOPED_EXACT_FRONTIER_LANGUAGES = frozenset({"go", "c", "cpp", "cuda", "python"})
+INCREMENTAL_PARALLEL_MIN_FILES = 50
+PARALLEL_SCOPED_LSP_FALLBACK_LANGUAGES = frozenset({"python"})
+MATRIX_FRONTIER_SCENARIOS = {
+ "go_inbound_frontier": "go",
+ "python_inbound_frontier": "python",
+ "c_header_inbound_frontier": "c_header",
+ "cpp_inbound_frontier": "cpp",
+ "cuda_inbound_frontier": "cuda",
+ "javascript_inbound_frontier": "javascript",
+ "typescript_inbound_frontier": "typescript",
+ "tsx_inbound_frontier": "tsx",
+ "php_inbound_frontier": "php",
+ "csharp_inbound_frontier": "csharp",
+ "java_inbound_frontier": "java",
+ "kotlin_inbound_frontier": "kotlin",
+ "rust_inbound_frontier": "rust",
+}
+SELF_DOGFOOD_SCENARIOS_DEFAULT = (
+ "noop,one_source_file,route_handler,store_pipeline_batch,multi_file_small"
+)
+SELF_DOGFOOD_MARKER_PREFIX = "cbm_pan4_oracle"
+SELF_DOGFOOD_REPO_SUBDIR = "repo"
+SELF_DOGFOOD_CACHE_SUBDIR = "cache"
+SELF_DOGFOOD_SCENARIO_PATHS = {
+ "noop": (),
+ "one_source_file": ("src/pipeline/pipeline_internal.h",),
+ "route_handler": ("src/ui/http_server.c",),
+ "c_new_leaf": ("src/cbm_benchmark_leaf.c",),
+ "store_pipeline_batch": (
+ "src/store/store.h",
+ "src/pipeline/pipeline_internal.h",
+ ),
+ "multi_file_small": ("src/mcp/mcp.c", "tests/test_mcp.c"),
+}
+FASTAPI_PROBE_REL_PATH = "fastapi/routing.py"
+FASTAPI_PROBE_INSERT_BEFORE = "\n def add_api_route(\n"
+FASTAPI_PROBE_RETURN_VALUE = 64
+PUBLISH_FULL = "full"
+PUBLISH_INCREMENTAL_NOOP = "incremental_noop"
+PUBLISH_INCREMENTAL_EXACT = "incremental_exact"
+PUBLISH_INCREMENTAL_OVERLAY = "incremental_overlay"
+PUBLISH_INCREMENTAL_CONTAINMENT = "incremental_containment"
+OVERLAY_STATUS_READY = "overlay_ready" # CBM_STORE_OVERLAY_STATUS_READY
+OVERLAY_TOMBSTONE_FILE = "file" # CBM_STORE_OVERLAY_TOMBSTONE_FILE
+OVERLAY_TOMBSTONE_ACTIVE = 1 # STORE_OVERLAY_TOMBSTONE_ACTIVE
+OVERLAY_ROW_OWNED = 1 # STORE_OVERLAY_ROW_OWNED
+SOURCE_SPAN_LABELS = frozenset(
+ {
+ "Function",
+ "Method",
+ "Class",
+ "Struct",
+ "Interface",
+ "Enum",
+ "Type",
+ "Trait",
+ "Module",
+ }
+)
+LOG_MARKER_PIPELINE_DONE = "pipeline.done"
+LOG_MARKER_INCREMENTAL_DONE = "incremental.done"
+LOG_MARKER_EXACT_DONE = "incremental.exact.done"
+LOG_MARKER_EXACT_FRONTIER = "incremental.exact.frontier"
+LOG_MARKER_EXACT_FALLBACK = "incremental.exact.fallback"
+LOG_MARKER_EXACT_DELETE_FALLBACK = "incremental.exact.delete.fallback"
+LOG_MARKER_EXACT_SKIP = "incremental.exact.skip"
+LOG_MARKER_DEP_AUTO_INDEX = "sub=dep_auto_index"
+LOG_MARKER_RANK_REFRESH = "phase=index_repository sub=rank_refresh"
+LOG_MARKER_INDEX_WORKER_TOTAL = "phase=index_repository sub=TOTAL"
+INDEXED_QUERY_PROFILE_COMPONENTS = (
+ ("resolve_store", "open_validate"),
+ ("resolve_store", "integrity"),
+ ("resolve_store", "project_lookup"),
+ ("resolve_store", "session_sync"),
+ ("request_release_store", "store_close"),
+ ("request_release_store", "mem_collect"),
+ ("index_status", "resolve_project"),
+ ("index_status", "graph_counts"),
+ ("index_status", "dependency_inventory"),
+ ("index_status", "project_coverage"),
+ ("index_status", "pagerank"),
+ ("index_status", "freshness_overlay"),
+ ("index_status", "serialize"),
+)
+
+
+class BenchmarkCommandError(RuntimeError):
+ def __init__(self, message: str, detail: dict[str, Any]) -> None:
+ super().__init__(message)
+ self.detail = detail
+
+
+def now_ms() -> float:
+ return time.perf_counter() * 1000.0
+
+
+def write_text(path: Path, text: str) -> None:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_text(text, encoding="utf-8")
+
+
+def atomic_write_text(path: Path, text: str) -> None:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ temporary = path.with_name(f".{path.name}.{os.getpid()}.{time.time_ns()}.tmp")
+ try:
+ with temporary.open("w", encoding="utf-8") as stream:
+ stream.write(text)
+ stream.flush()
+ os.fsync(stream.fileno())
+ os.replace(temporary, path)
+ finally:
+ if temporary.exists():
+ temporary.unlink()
+
+
+def file_sha256(path: Path) -> str:
+ digest = hashlib.sha256()
+ with path.open("rb") as stream:
+ for chunk in iter(lambda: stream.read(1024 * 1024), b""):
+ digest.update(chunk)
+ return digest.hexdigest()
+
+
+def canonical_json_bytes(value: Any) -> bytes:
+ return json.dumps(value, separators=(",", ":"), sort_keys=True).encode("utf-8")
+
+
+def unknown_fact(reason: str) -> dict[str, str]:
+ return {"status": "unknown", "reason": reason}
+
+
+def benchmark_run_context() -> dict[str, Any]:
+ raw = os.environ.get(BENCHMARK_RUN_CONTEXT_ENV)
+ if not raw:
+ return {}
+ try:
+ value = json.loads(raw)
+ except json.JSONDecodeError as exc:
+ raise ValueError(
+ f"{BENCHMARK_RUN_CONTEXT_ENV} must contain valid JSON"
+ ) from exc
+ if not isinstance(value, dict):
+ raise ValueError(f"{BENCHMARK_RUN_CONTEXT_ENV} must contain a JSON object")
+ return value
+
+
+def benchmark_harness_metadata() -> dict[str, Any]:
+ script = Path(__file__).resolve()
+ return {
+ "path": str(script),
+ "sha256": file_sha256(script),
+ "fact_schema_version": BENCHMARK_FACT_SCHEMA_VERSION,
+ "terminology_path": str(BENCHMARK_TERMINOLOGY_PATH),
+ "terminology_version": BENCHMARK_TERMINOLOGY_VERSION,
+ "terminology_sha256": BENCHMARK_TERMINOLOGY_SHA256,
+ }
+
+
+def report_mode(report: dict[str, Any]) -> str:
+ mode = report.get("mode")
+ if isinstance(mode, str) and mode:
+ return mode
+ if isinstance(report.get("cases"), list):
+ return "legacy_cases"
+ return "incremental_speed"
+
+
+def report_implementation_identity(
+ report: dict[str, Any], context: dict[str, Any]
+) -> dict[str, Any]:
+ binary = report.get("binary_metadata")
+ binary = (
+ binary if isinstance(binary, dict) else unknown_fact("binary_metadata_missing")
+ )
+ revision = context.get("revision")
+ revision_source = str(context.get("revision_source") or "experiment_cell")
+ allow_report_revision_fallback = context.get("label") != "standalone"
+ if (
+ not isinstance(revision, str) or not revision
+ ) and allow_report_revision_fallback:
+ source_git = report.get("source_git")
+ revision = source_git.get("head") if isinstance(source_git, dict) else None
+ revision_source = "source_git.head"
+ if (
+ not isinstance(revision, str) or not revision
+ ) and allow_report_revision_fallback:
+ background = report.get("repository_background")
+ revision = background.get("revision") if isinstance(background, dict) else None
+ revision_source = "repository_background.revision"
+ revision_value: Any = revision
+ if not isinstance(revision_value, str) or not revision_value:
+ revision_value = unknown_fact("legacy_report_did_not_record_candidate_revision")
+ revision_source = "unavailable"
+ build = context.get("build")
+ if not isinstance(build, dict):
+ build = unknown_fact("legacy_report_did_not_record_build_metadata")
+ return {
+ "revision": revision_value,
+ "revision_source": revision_source,
+ "binary": binary,
+ "build": build,
+ }
+
+
+def report_capability_manifest(
+ report: dict[str, Any], context: dict[str, Any]
+) -> dict[str, Any]:
+ parameters = report.get("parameters")
+ parameters = parameters if isinstance(parameters, dict) else {}
+ declared = context.get("capabilities")
+ declared = dict(declared) if isinstance(declared, dict) else {}
+ overrides = parameters.get("config_overrides")
+ requested_overrides = dict(overrides) if isinstance(overrides, dict) else {}
+ if isinstance(overrides, dict):
+ declared.update(overrides)
+ for key in ("index_mode", "rank_refresh", "config_profile", "transport"):
+ value = parameters.get(key)
+ if value is not None:
+ declared[key] = value
+ candidate_native = (
+ parameters.get("config_profile") == CONFIG_PROFILE_CANDIDATE_NATIVE
+ )
+ context_declared = context.get("capabilities") is not None
+ complete = context_declared and not candidate_native and not report.get("error")
+ if complete:
+ provenance = "experiment_cell_plus_isolated_successful_config_set_arguments"
+ elif context_declared:
+ provenance = "candidate_native_configuration"
+ else:
+ provenance = "legacy_report_parameters_only"
+ return {
+ "values": dict(sorted(declared.items())),
+ "requested_config_overrides": dict(sorted(requested_overrides.items())),
+ "effective_config_overrides": (
+ unknown_fact("candidate_native_configuration_was_not_overridden")
+ if candidate_native
+ else dict(sorted(requested_overrides.items()))
+ ),
+ "completeness": "complete_declared_cell" if complete else "partial",
+ "provenance": provenance,
+ "missing_behavior": (
+ "none for declared capability keys"
+ if complete
+ else "unknown values prohibit parity joins"
+ ),
+ }
+
+
+def report_scope_manifest(report: dict[str, Any]) -> dict[str, Any]:
+ recorded = report.get("scope")
+ if isinstance(recorded, dict):
+ return recorded
+ parameters = report.get("parameters")
+ parameters = parameters if isinstance(parameters, dict) else {}
+ background = report.get("repository_background")
+ generated_source_policy: Any = unknown_fact(
+ "report_did_not_record_generated_source_policy"
+ )
+ if report_mode(report) == "incremental_speed" and isinstance(
+ parameters.get("files"), int
+ ):
+ generated_source_policy = {
+ "kind": "deterministic_generated_go_fixture",
+ "generator": "create_repo/go_file_content",
+ "mutation": "modify_existing_files revision_offset_1000",
+ "provenance": "benchmark_harness_contract",
+ }
+ scope: dict[str, Any] = {
+ "workload": report_mode(report),
+ "files": parameters.get("files", unknown_fact("file_count_not_recorded")),
+ "functions_per_file": parameters.get(
+ "functions_per_file", unknown_fact("function_count_not_recorded")
+ ),
+ "changed_files": parameters.get(
+ "changed_files", unknown_fact("changed_file_count_not_recorded")
+ ),
+ "generated_source_policy": generated_source_policy,
+ }
+ if isinstance(background, dict):
+ scope["repository_background"] = background
+ elif isinstance(report.get("source_repo"), str):
+ scope["repository"] = report["source_repo"]
+ return scope
+
+
+def report_cache_manifest(
+ report: dict[str, Any], imported_report: bool
+) -> dict[str, Any]:
+ recorded = report.get("cache")
+ if isinstance(recorded, dict):
+ return recorded
+ if imported_report:
+ return {
+ "process": unknown_fact(
+ "imported_report_did_not_record_process_cache_state"
+ ),
+ "repository_graph": unknown_fact(
+ "imported_report_did_not_record_repository_graph_cache_state"
+ ),
+ "dependency_artifacts": unknown_fact(
+ "imported_report_did_not_record_dependency_cache_identity"
+ ),
+ "os_page_cache": unknown_fact(
+ "imported_report_did_not_record_os_page_cache_state"
+ ),
+ "sqlite_page_cache": unknown_fact(
+ "imported_report_did_not_record_sqlite_page_cache_state"
+ ),
+ "parser_compiler_cache": unknown_fact(
+ "imported_report_did_not_record_parser_compiler_cache_state"
+ ),
+ "fixture_cache": unknown_fact(
+ "imported_report_did_not_record_fixture_cache_state"
+ ),
+ }
+ parameters = report.get("parameters")
+ parameters = parameters if isinstance(parameters, dict) else {}
+ transport = parameters.get("transport")
+ return {
+ "process": {
+ "state": "persistent_within_lifecycle"
+ if transport == "mcp"
+ else "new_per_tool_call",
+ "source": "transport_contract"
+ if transport in {"cli", "mcp"}
+ else "unknown",
+ },
+ "repository_graph": {
+ "initial_state": "empty_harness_owned_cache",
+ "reset_procedure": "remove_project_dbs_before_clean_rebuild",
+ },
+ "dependency_artifacts": unknown_fact(
+ "legacy_harness_did_not_record_dependency_cache_identity"
+ ),
+ "os_page_cache": unknown_fact("os_page_cache_state_not_controlled"),
+ "sqlite_page_cache": unknown_fact("sqlite_page_cache_state_not_recorded"),
+ "parser_compiler_cache": unknown_fact(
+ "parser_compiler_cache_state_not_recorded"
+ ),
+ "fixture_cache": unknown_fact("fixture_cache_state_not_recorded"),
+ }
+
+
+STEP_ID_BY_FIELD = {
+ "initial_fast_full": "initial_index",
+ "incremental": "incremental_index",
+ "incremental_exact": "incremental_index",
+ "fresh_fast_full_after_change": "clean_rebuild_index",
+ "fresh_full_after_change": "clean_rebuild_index",
+}
+
+
+def fact_step_rows(report: dict[str, Any], run_id: str) -> list[dict[str, Any]]:
+ rows: list[dict[str, Any]] = []
+ seen_objects: set[int] = set()
+
+ def visit(
+ value: Any, path: tuple[str, ...], parent_occurrence_id: str | None
+ ) -> None:
+ if isinstance(value, dict):
+ object_id = id(value)
+ if object_id in seen_objects:
+ return
+ seen_objects.add(object_id)
+ elapsed = value.get("elapsed_ms")
+ current_parent = parent_occurrence_id
+ if isinstance(elapsed, (int, float)) and not isinstance(elapsed, bool):
+ field = path[-1] if path else "operation"
+ step_id = STEP_ID_BY_FIELD.get(field, field)
+ occurrence_id = hashlib.sha256(
+ canonical_json_bytes({"run_id": run_id, "path": path})
+ ).hexdigest()[:24]
+ row = {
+ "run_id": run_id,
+ "step_id": step_id,
+ "occurrence_id": occurrence_id,
+ "source_path": ".".join(path),
+ "parent_occurrence_id": parent_occurrence_id,
+ "dependency_occurrence_ids": [],
+ "elapsed_ms": float(elapsed),
+ "monotonic_start_ns": unknown_fact(
+ "profile_marker_did_not_record_start_timestamp"
+ ),
+ "monotonic_end_ns": unknown_fact(
+ "profile_marker_did_not_record_end_timestamp"
+ ),
+ "cpu_ms": unknown_fact("cpu_time_not_recorded"),
+ "cpu_scope": "unknown",
+ "queue_wait_ms": unknown_fact("queue_wait_not_recorded"),
+ "thread_or_worker_id": unknown_fact("worker_identity_not_recorded"),
+ "critical_path": unknown_fact("dependency_event_dag_not_recorded"),
+ "peak_rss_mb": value.get(
+ "peak_rss_mb", unknown_fact("peak_rss_not_recorded")
+ ),
+ "work_counters": {},
+ "provenance": "normalized_report_measurement",
+ }
+ rows.append(row)
+ current_parent = occurrence_id
+ components = value.get("timing_components_ms")
+ if isinstance(components, dict):
+ for name, duration in sorted(components.items()):
+ if not isinstance(duration, (int, float)) or isinstance(
+ duration, bool
+ ):
+ continue
+ component_occurrence = hashlib.sha256(
+ canonical_json_bytes(
+ {"run_id": run_id, "path": path, "component": name}
+ )
+ ).hexdigest()[:24]
+ rows.append(
+ {
+ "run_id": run_id,
+ "step_id": str(name),
+ "occurrence_id": component_occurrence,
+ "source_path": ".".join(
+ (*path, "timing_components_ms", name)
+ ),
+ "parent_occurrence_id": occurrence_id,
+ "dependency_occurrence_ids": [],
+ "elapsed_ms": float(duration),
+ "monotonic_start_ns": unknown_fact(
+ "component_marker_did_not_record_start_timestamp"
+ ),
+ "monotonic_end_ns": unknown_fact(
+ "component_marker_did_not_record_end_timestamp"
+ ),
+ "cpu_ms": unknown_fact("cpu_time_not_recorded"),
+ "cpu_scope": "unknown",
+ "queue_wait_ms": unknown_fact(
+ "queue_wait_not_recorded"
+ ),
+ "thread_or_worker_id": unknown_fact(
+ "worker_identity_not_recorded"
+ ),
+ "critical_path": unknown_fact(
+ "dependency_event_dag_not_recorded"
+ ),
+ "peak_rss_mb": unknown_fact(
+ "component_peak_rss_not_recorded"
+ ),
+ "work_counters": {},
+ "provenance": "parsed_existing_profile_marker",
+ }
+ )
+ for key, child in value.items():
+ if (
+ key == "incremental"
+ and "incremental_exact" in value
+ and value["incremental_exact"] == child
+ ):
+ continue
+ visit(child, (*path, str(key)), current_parent)
+ elif isinstance(value, list):
+ for index, child in enumerate(value):
+ visit(child, (*path, str(index)), parent_occurrence_id)
+
+ measurements = report.get("measurements")
+ if isinstance(measurements, dict):
+ visit(measurements, ("measurements",), None)
+ cases = report.get("cases")
+ if isinstance(cases, list):
+ visit(cases, ("cases",), None)
+ return rows
+
+
+def fact_result_rows(report: dict[str, Any], run_id: str) -> list[dict[str, Any]]:
+ rows: list[dict[str, Any]] = []
+ derived = report.get("derived")
+ passed = derived.get("passed") if isinstance(derived, dict) else None
+ rows.append(
+ {
+ "run_id": run_id,
+ "result_id": "benchmark_gate",
+ "kind": "product_contract",
+ "status": "passed"
+ if passed is True
+ else "failed"
+ if passed is False
+ else "unknown",
+ "value": passed
+ if isinstance(passed, bool)
+ else unknown_fact("derived_passed_missing"),
+ "provenance": "report.derived.passed",
+ }
+ )
+ error = report.get("error")
+ if error is not None:
+ rows.append(
+ {
+ "run_id": run_id,
+ "result_id": "harness_error",
+ "kind": "instrumentation",
+ "status": "failed",
+ "value": error,
+ "provenance": "report.error",
+ }
+ )
+ cases = report.get("cases")
+ if isinstance(cases, list):
+ for index, case in enumerate(cases):
+ if not isinstance(case, dict):
+ continue
+ scenario = case.get("scenario")
+ scenario_id = (
+ re.sub(r"[^a-zA-Z0-9_.-]+", "_", scenario)
+ if isinstance(scenario, str) and scenario
+ else str(index)
+ )
+ case_passed = case.get("passed")
+ rows.append(
+ {
+ "run_id": run_id,
+ "result_id": f"case.{scenario_id}.contract",
+ "kind": "correctness_contract",
+ "status": (
+ "passed"
+ if case_passed is True
+ else "failed"
+ if case_passed is False
+ else "unknown"
+ ),
+ "value": {
+ "scenario": scenario,
+ "publish_kind": (
+ case.get("incremental", {}).get("publish_kind")
+ if isinstance(case.get("incremental"), dict)
+ else None
+ ),
+ "exact_reason": case.get("exact_reason"),
+ },
+ "provenance": f"report.cases[{index}]",
+ }
+ )
+ for field, kind in (
+ ("graph_gate", "graph_oracle"),
+ ("canonical_graph", "graph_equality"),
+ ("freshness_scoped_graph", "freshness_oracle"),
+ ):
+ value = case.get(field)
+ if not isinstance(value, dict):
+ continue
+ passed_value = value.get("passed", value.get("equal"))
+ rows.append(
+ {
+ "run_id": run_id,
+ "result_id": f"case.{scenario_id}.{field}",
+ "kind": kind,
+ "status": (
+ "passed"
+ if passed_value is True
+ else "failed"
+ if passed_value is False
+ else "unknown"
+ ),
+ "value": {
+ key: value[key]
+ for key in (
+ "policy",
+ "reason",
+ "equal",
+ "canonical_equal",
+ "freshness_scoped_equal",
+ "declared_stale_views",
+ "excluded_edge_types",
+ "left_count",
+ "right_count",
+ "left_sha256",
+ "right_sha256",
+ )
+ if key in value
+ },
+ "provenance": f"report.cases[{index}].{field}",
+ }
+ )
+ oracles = case.get("oracles")
+ if not isinstance(oracles, dict):
+ continue
+ quality = oracles.get("quality")
+ if isinstance(quality, dict):
+ quality_passed = quality.get("passed")
+ rows.append(
+ {
+ "run_id": run_id,
+ "result_id": f"case.{scenario_id}.quality",
+ "kind": "retrieval_quality",
+ "status": (
+ "passed"
+ if quality_passed is True
+ else "failed"
+ if quality_passed is False
+ else "unknown"
+ ),
+ "value": dict(quality),
+ "provenance": f"report.cases[{index}].oracles.quality",
+ }
+ )
+ for oracle_name, oracle in sorted(oracles.items()):
+ if oracle_name in {"passed", "quality"} or not isinstance(oracle, dict):
+ continue
+ oracle_quality = oracle.get("quality")
+ if not isinstance(oracle_quality, dict):
+ continue
+ applicable = oracle_quality.get("applicable")
+ oracle_passed = oracle_quality.get("passed")
+ rows.append(
+ {
+ "run_id": run_id,
+ "result_id": (
+ f"case.{scenario_id}.oracle."
+ + re.sub(r"[^a-zA-Z0-9_.-]+", "_", oracle_name)
+ ),
+ "kind": "retrieval_task",
+ "status": (
+ "skipped"
+ if applicable is False
+ else "passed"
+ if oracle_passed is True
+ else "failed"
+ if oracle_passed is False
+ else "unknown"
+ ),
+ "value": {
+ "scenario": scenario,
+ "criterion": oracle_quality.get("criterion"),
+ "expected_substring": oracle_quality.get(
+ "expected_substring"
+ ),
+ "applicable": applicable,
+ "rank": oracle_quality.get("rank"),
+ "reciprocal_rank": oracle_quality.get("reciprocal_rank"),
+ "hit_at_1": oracle_quality.get("hit_at_1"),
+ "hit_at_5": oracle_quality.get("hit_at_5"),
+ "ndcg_at_5": oracle_quality.get("ndcg_at_5"),
+ "freshness": oracle.get("freshness"),
+ "freshness_state": oracle.get("freshness_state"),
+ },
+ "provenance": (
+ f"report.cases[{index}].oracles.{oracle_name}.quality"
+ ),
+ }
+ )
+ return rows
+
+
+def fact_artifact_rows(report: dict[str, Any], run_id: str) -> list[dict[str, Any]]:
+ """Normalize path-based and content-addressed log metadata from any report branch.
+
+ Visiting N report values and A distinct artifacts costs O(N + A) time and
+ O(A) memory for the emitted rows and deduplication set.
+ """
+ rows: list[dict[str, Any]] = []
+ seen: set[tuple[str, str]] = set()
+
+ def visit(value: Any) -> None:
+ if isinstance(value, dict):
+ artifacts = value.get("measurement_log_artifacts")
+ if isinstance(artifacts, list):
+ for artifact in artifacts:
+ if not isinstance(artifact, dict):
+ continue
+ path = (
+ artifact.get("path")
+ or artifact.get("artifact_path")
+ or artifact.get("artifact_name")
+ )
+ digest = artifact.get("sha256") or artifact.get("artifact_sha256")
+ if not isinstance(path, str) or not isinstance(digest, str):
+ continue
+ key = (path, digest)
+ if key in seen:
+ continue
+ seen.add(key)
+ rows.append(
+ {
+ "run_id": run_id,
+ "artifact_id": hashlib.sha256(
+ canonical_json_bytes(key)
+ ).hexdigest()[:24],
+ "artifact_type": "measurement_log",
+ "path": path,
+ "sha256": digest,
+ "size_bytes": artifact.get(
+ "size_bytes",
+ artifact.get(
+ "artifact_bytes",
+ unknown_fact("artifact_size_not_recorded"),
+ ),
+ ),
+ "schema_version": unknown_fact(
+ "unstructured_measurement_log"
+ ),
+ "cleanup_status": "retained",
+ }
+ )
+ for child in value.values():
+ visit(child)
+ elif isinstance(value, list):
+ for child in value:
+ visit(child)
+
+ visit(report)
+ return rows
+
+
+def normalize_benchmark_report(
+ report: dict[str, Any],
+ context: dict[str, Any] | None = None,
+ *,
+ imported_report: bool | None = None,
+) -> dict[str, Any]:
+ if not isinstance(report, dict):
+ raise ValueError("benchmark report must be a JSON object")
+ resolved_context = dict(context or {})
+ is_imported_report = (
+ not bool(resolved_context) if imported_report is None else imported_report
+ )
+ implementation = report_implementation_identity(report, resolved_context)
+ run_identity = {
+ "generated_at_utc": report.get("generated_at_utc"),
+ "mode": report_mode(report),
+ "implementation": implementation,
+ "measurement_checkout": resolved_context.get(
+ "source_git", unknown_fact("measurement_checkout_not_recorded")
+ ),
+ "cell_identity": resolved_context.get("cell_identity"),
+ "repetition": resolved_context.get("repetition"),
+ "parameters": report.get("parameters"),
+ }
+ run_id = hashlib.sha256(canonical_json_bytes(run_identity)).hexdigest()[:24]
+ recorded_host = report.get("host")
+ if not isinstance(recorded_host, dict):
+ recorded_host = report.get("host_metadata")
+ if not isinstance(recorded_host, dict):
+ recorded_host = (
+ {
+ "platform": platform.platform(),
+ "machine": platform.machine(),
+ "python": platform.python_version(),
+ "provenance": "measurement_process",
+ }
+ if resolved_context
+ else unknown_fact("legacy_report_did_not_record_host_metadata")
+ )
+ run_row = {
+ "run_id": run_id,
+ "lifecycle_id": run_id,
+ "generated_at_utc": report.get(
+ "generated_at_utc", unknown_fact("legacy_report_timestamp_missing")
+ ),
+ "mode": report_mode(report),
+ "cell_identity": resolved_context.get(
+ "cell_identity", unknown_fact("not_executed_by_experiment_runner")
+ ),
+ "cell_label": resolved_context.get(
+ "label", unknown_fact("cell_label_not_recorded")
+ ),
+ "repetition": resolved_context.get(
+ "repetition", unknown_fact("repetition_not_recorded")
+ ),
+ "implementation": implementation,
+ "harness": benchmark_harness_metadata(),
+ "host": recorded_host,
+ "measurement_checkout": resolved_context.get(
+ "source_git", unknown_fact("measurement_checkout_not_recorded")
+ ),
+ "capabilities": report_capability_manifest(report, resolved_context),
+ "scope": report_scope_manifest(report),
+ "cache": report_cache_manifest(report, is_imported_report),
+ "legacy_import": is_imported_report,
+ }
+ return {
+ "$schema": BENCHMARK_FACT_SCHEMA,
+ "schema_version": BENCHMARK_FACT_SCHEMA_VERSION,
+ "terminology_version": BENCHMARK_TERMINOLOGY_VERSION,
+ "terminology_sha256": BENCHMARK_TERMINOLOGY_SHA256,
+ "generator_revision": benchmark_harness_metadata()["sha256"],
+ "runs": [run_row],
+ "steps": fact_step_rows(report, run_id),
+ "results": fact_result_rows(report, run_id),
+ "artifacts": fact_artifact_rows(report, run_id),
+ }
+
+
+def validate_benchmark_facts(
+ facts: dict[str, Any], *, require_current_contract: bool = True
+) -> None:
+ if facts.get("schema_version") != BENCHMARK_FACT_SCHEMA_VERSION:
+ raise ValueError("benchmark facts schema_version is unsupported")
+ terminology_version = facts.get("terminology_version")
+ if not isinstance(terminology_version, str) or not re.fullmatch(
+ r"[1-9]\d*\.\d+\.\d+", terminology_version
+ ):
+ raise ValueError("benchmark facts terminology_version must be semantic")
+ terminology_sha256 = facts.get("terminology_sha256")
+ if not isinstance(terminology_sha256, str) or not re.fullmatch(
+ r"[0-9a-f]{64}", terminology_sha256
+ ):
+ raise ValueError("benchmark facts terminology_sha256 must be a SHA-256")
+ if require_current_contract and (
+ terminology_version != BENCHMARK_TERMINOLOGY_VERSION
+ or terminology_sha256 != BENCHMARK_TERMINOLOGY_SHA256
+ ):
+ raise ValueError(
+ "benchmark facts terminology contract does not match the current registry"
+ )
+ generator_revision = facts.get("generator_revision")
+ if not isinstance(generator_revision, str) or not re.fullmatch(
+ r"[0-9a-f]{64}", generator_revision
+ ):
+ raise ValueError("benchmark facts generator_revision must be a SHA-256")
+ for table in ("runs", "steps", "results", "artifacts"):
+ rows = facts.get(table)
+ if not isinstance(rows, list):
+ raise ValueError(f"benchmark facts {table} must be an array")
+ if len(facts["runs"]) != 1 or not isinstance(facts["runs"][0], dict):
+ raise ValueError("benchmark facts must contain exactly one run row")
+ run = facts["runs"][0]
+ required_run_fields = {
+ "run_id",
+ "lifecycle_id",
+ "generated_at_utc",
+ "mode",
+ "implementation",
+ "harness",
+ "host",
+ "measurement_checkout",
+ "capabilities",
+ "scope",
+ "cache",
+ "legacy_import",
+ }
+ missing_run_fields = sorted(required_run_fields - run.keys())
+ if missing_run_fields:
+ raise ValueError(
+ "benchmark facts run row is missing required fields: "
+ + ", ".join(missing_run_fields)
+ )
+ run_id = run.get("run_id")
+ if not isinstance(run_id, str) or not re.fullmatch(r"[0-9a-f]{24}", run_id):
+ raise ValueError("benchmark fact run_id must be 24 lowercase hex characters")
+ for table in ("steps", "results", "artifacts"):
+ for row in facts[table]:
+ if not isinstance(row, dict) or row.get("run_id") != run_id:
+ raise ValueError(f"benchmark facts {table} row has a foreign run_id")
+ occurrence_ids = [row.get("occurrence_id") for row in facts["steps"]]
+ if len(occurrence_ids) != len(set(occurrence_ids)):
+ raise ValueError("benchmark fact step occurrence IDs must be unique")
+
+
+def load_benchmark_fact_bundle(path: Path) -> dict[str, Any]:
+ """Load current or retained v1 facts without inventing missing v1 metadata."""
+ document = json.loads(path.read_text(encoding="utf-8"))
+ if not isinstance(document, dict):
+ raise ValueError("benchmark fact bundle must be a JSON object")
+ version = document.get("schema_version")
+ if version == BENCHMARK_FACT_SCHEMA_VERSION:
+ if document.get("$schema") not in BENCHMARK_FACT_COMPATIBLE_SCHEMA_URIS:
+ raise ValueError(
+ "benchmark fact bundle schema URI does not match its version"
+ )
+ validate_benchmark_facts(document, require_current_contract=False)
+ return document
+ legacy_schema = BENCHMARK_FACT_LEGACY_SCHEMAS.get(version)
+ if legacy_schema is None:
+ raise ValueError(f"unsupported benchmark fact schema_version: {version!r}")
+ if document.get("$schema") != legacy_schema:
+ raise ValueError("legacy benchmark fact bundle schema URI is invalid")
+ for table in ("runs", "steps", "results", "artifacts"):
+ if not isinstance(document.get(table), list):
+ raise ValueError(f"legacy benchmark facts {table} must be an array")
+ if len(document["runs"]) != 1 or not isinstance(document["runs"][0], dict):
+ raise ValueError("legacy benchmark facts must contain exactly one run row")
+ run_id = document["runs"][0].get("run_id")
+ if not isinstance(run_id, str) or not re.fullmatch(r"[0-9a-f]{24}", run_id):
+ raise ValueError("legacy benchmark fact run_id is invalid")
+ for table in ("steps", "results", "artifacts"):
+ if any(
+ not isinstance(row, dict) or row.get("run_id") != run_id
+ for row in document[table]
+ ):
+ raise ValueError(f"legacy benchmark facts {table} row has a foreign run_id")
+ return document
+
+
+def write_benchmark_fact_tables(facts: dict[str, Any], root: Path) -> dict[str, Any]:
+ validate_benchmark_facts(facts)
+ root.mkdir(parents=True, exist_ok=True)
+ files: dict[str, dict[str, Any]] = {}
+ bundle_path = root / "facts.json"
+ atomic_write_text(bundle_path, json.dumps(facts, indent=2, sort_keys=True) + "\n")
+ files["bundle"] = {
+ "path": str(bundle_path),
+ "sha256": file_sha256(bundle_path),
+ "rows": sum(
+ len(facts[table]) for table in ("runs", "steps", "results", "artifacts")
+ ),
+ }
+ for table in ("runs", "steps", "results", "artifacts"):
+ path = root / ("steps.jsonl" if table == "steps" else f"{table}.json")
+ if table == "steps":
+ payload = "".join(
+ json.dumps(row, separators=(",", ":"), sort_keys=True) + "\n"
+ for row in facts[table]
+ )
+ else:
+ payload = json.dumps(facts[table], indent=2, sort_keys=True) + "\n"
+ atomic_write_text(path, payload)
+ files[table] = {
+ "path": str(path),
+ "sha256": file_sha256(path),
+ "rows": len(facts[table]),
+ }
+ manifest = {
+ "schema_version": BENCHMARK_FACT_SCHEMA_VERSION,
+ "terminology_version": BENCHMARK_TERMINOLOGY_VERSION,
+ "terminology_sha256": BENCHMARK_TERMINOLOGY_SHA256,
+ "generator_revision": facts["generator_revision"],
+ "run_id": facts["runs"][0]["run_id"],
+ "files": files,
+ }
+ manifest_path = root / "manifest.json"
+ atomic_write_text(
+ manifest_path, json.dumps(manifest, indent=2, sort_keys=True) + "\n"
+ )
+ manifest["manifest_path"] = str(manifest_path)
+ manifest["manifest_sha256"] = file_sha256(manifest_path)
+ return manifest
+
+
+def resolve_facts_dir(args: argparse.Namespace) -> Path | None:
+ if getattr(args, "facts_dir", ""):
+ return Path(args.facts_dir).expanduser()
+ artifact_dir = os.environ.get(BENCHMARK_ARTIFACT_DIR_ENV)
+ if artifact_dir:
+ return Path(artifact_dir).expanduser() / "facts"
+ if getattr(args, "out", ""):
+ output = Path(args.out).expanduser()
+ return output.parent / f"{output.stem}.facts"
+ return None
+
+
+def standalone_run_context(args: argparse.Namespace) -> dict[str, Any]:
+ context: dict[str, Any] = {
+ "label": "standalone",
+ "repetition": 1,
+ "harness_version": benchmark_harness_metadata()["sha256"],
+ }
+ build = getattr(args, "build_metadata", None)
+ if isinstance(build, dict) and build:
+ context["build"] = build
+ candidates = [Path(args.binary).expanduser().resolve().parent]
+ repo_root = getattr(args, "repo_root", "")
+ if repo_root:
+ candidates.append(Path(repo_root).expanduser().resolve())
+ for candidate in candidates:
+ try:
+ root = resolve_git_repo_root(candidate, args.timeout)
+ revision_arg = getattr(args, "candidate_revision", "") or "HEAD"
+ revision = command_stdout(
+ ["git", "rev-parse", f"{revision_arg}^{{commit}}"], args.timeout, root
+ )
+ context["source_git"] = git_metadata(root, args.timeout)
+ if getattr(args, "candidate_revision", ""):
+ context["revision"] = revision
+ context["revision_source"] = "standalone_declared_revision"
+ else:
+ context["checkout_revision"] = revision
+ break
+ except (OSError, RuntimeError, subprocess.SubprocessError):
+ continue
+ return context
+
+
+def emit_report(report: dict[str, Any], args: argparse.Namespace) -> None:
+ context = benchmark_run_context()
+ if not context:
+ context = standalone_run_context(args)
+ if context:
+ report["benchmark_run_context"] = context
+ facts = normalize_benchmark_report(report, context)
+ facts_dir = resolve_facts_dir(args)
+ if facts_dir is not None:
+ report["fact_manifest"] = write_benchmark_fact_tables(facts, facts_dir)
+ if args.out:
+ atomic_write_text(
+ Path(args.out).expanduser(),
+ json.dumps(report, indent=2, sort_keys=True) + "\n",
+ )
+ print(json.dumps(report, indent=2, sort_keys=True))
+
+
+def archive_measurement_log(source: Path, artifact_dir: Path) -> dict[str, Any]:
+ """Stream one worker log into a content-addressed reproducible gzip artifact."""
+ artifact_dir.mkdir(parents=True, exist_ok=True)
+ temporary = artifact_dir / f".worker-log-{os.getpid()}-{time.time_ns()}.tmp"
+ source_digest = hashlib.sha256()
+ source_bytes = 0
+ try:
+ with source.open("rb") as input_stream, temporary.open("wb") as output_stream:
+ with gzip.GzipFile(
+ filename="", mode="wb", fileobj=output_stream, mtime=0
+ ) as compressed:
+ for chunk in iter(lambda: input_stream.read(1024 * 1024), b""):
+ source_digest.update(chunk)
+ source_bytes += len(chunk)
+ compressed.write(chunk)
+ output_stream.flush()
+ os.fsync(output_stream.fileno())
+ source_sha256 = source_digest.hexdigest()
+ artifact_name = f"{source_sha256}.log.gz"
+ destination = artifact_dir / artifact_name
+ if destination.exists():
+ temporary.unlink()
+ else:
+ os.replace(temporary, destination)
+ return {
+ "artifact_name": artifact_name,
+ "source_name": source.name,
+ "source_bytes": source_bytes,
+ "source_sha256": source_sha256,
+ "artifact_bytes": destination.stat().st_size,
+ "artifact_sha256": file_sha256(destination),
+ "compression": "gzip-mtime-0",
+ }
+ finally:
+ if temporary.exists():
+ temporary.unlink()
+
+
+def go_file_content(index: int, revision: int, funcs_per_file: int) -> str:
+ lines = ["package main", ""]
+ for func_index in range(funcs_per_file):
+ value = index * funcs_per_file + func_index + revision
+ lines.extend(
+ [
+ f"func Func{index:04d}_{func_index:02d}() int {{",
+ f"\treturn {value}",
+ "}",
+ "",
+ ]
+ )
+ return "\n".join(lines)
+
+
+def create_repo(repo_dir: Path, file_count: int, funcs_per_file: int) -> None:
+ write_text(repo_dir / "go.mod", "module example.com/cbmbench\n\ngo 1.22\n")
+ write_text(repo_dir / "main.go", "package main\n\nfunc main() {}\n")
+ for index in range(file_count):
+ write_text(
+ repo_dir / f"pkg/file_{index:04d}.go",
+ go_file_content(index, 0, funcs_per_file),
+ )
+
+
+def modify_existing_files(
+ repo_dir: Path, changed_files: int, funcs_per_file: int
+) -> list[str]:
+ changed: list[str] = []
+ for index in range(changed_files):
+ rel = Path("pkg") / f"file_{index:04d}.go"
+ write_text(repo_dir / rel, go_file_content(index, 1000, funcs_per_file))
+ changed.append(rel.as_posix())
+ return changed
+
+
+def create_python_reexport_repo(repo_dir: Path) -> None:
+ write_text(
+ repo_dir / "fastapi" / "__init__.py", "from .param_functions import Header\n"
+ )
+ write_text(
+ repo_dir / "fastapi" / "param_functions.py",
+ "def Header(default=None):\n return default\n",
+ )
+ write_text(
+ repo_dir / "fastapi" / "openapi" / "models.py", "class Header:\n pass\n"
+ )
+ write_text(
+ repo_dir / "docs_src" / "app" / "main.py",
+ "from fastapi import Header\n\ndef create_item():\n return Header(None)\n",
+ )
+
+
+def create_route_repo(repo_dir: Path, route_path: str) -> None:
+ write_text(
+ repo_dir / "routes.py",
+ "from fastapi import FastAPI\n\n"
+ "app = FastAPI()\n\n"
+ f"@app.get('{route_path}')\n"
+ "def orders():\n"
+ " return {'ok': True}\n",
+ )
+
+
+def create_rank_quality_repo(repo_dir: Path) -> dict[str, Any]:
+ """Create a lexical-decoy graph where structural rank identifies the useful result."""
+ write_text(
+ repo_dir / "order_core.py",
+ "def zz_order_core(order):\n"
+ ' """Validate and persist the canonical order workflow."""\n'
+ " return {'accepted': bool(order)}\n",
+ )
+ decoy_names = [f"a{letter}_order_stub" for letter in "abcdefgh"]
+ write_text(
+ repo_dir / "order_stubs.py",
+ "\n\n".join(f"def {name}(order):\n return order" for name in decoy_names)
+ + "\n",
+ )
+ for index in range(8):
+ write_text(
+ repo_dir / f"caller_{index}.py",
+ "from order_core import zz_order_core\n\n"
+ f"def workflow_{index}(order):\n"
+ " return zz_order_core(order)\n",
+ )
+ return {
+ "fixture_version": 1,
+ "capability": "rank",
+ "language": "python",
+ "relevant_symbol": "zz_order_core",
+ "lexical_decoys": decoy_names,
+ "ranking_signal": "eight distinct callers target the relevant symbol",
+ }
+
+
+def create_dependency_quality_repo(repo_dir: Path) -> dict[str, Any]:
+ """Create a local npm dependency whose source can be auto-indexed without I/O."""
+ package_name = "cbmbenchdep"
+ symbol = "canonicalDependencyAPI"
+ write_text(
+ repo_dir / "package.json",
+ json.dumps(
+ {
+ "name": "cbm-dependency-quality-fixture",
+ "version": "1.0.0",
+ "dependencies": {package_name: "1.0.0"},
+ },
+ indent=2,
+ sort_keys=True,
+ )
+ + "\n",
+ )
+ write_text(
+ repo_dir / "src" / "app.js",
+ f"import {{ {symbol} }} from '{package_name}';\n\n"
+ f"export function useDependency(value) {{ return {symbol}(value); }}\n",
+ )
+ write_text(
+ repo_dir / "node_modules" / package_name / "package.json",
+ json.dumps(
+ {"name": package_name, "version": "1.0.0", "main": "index.js"},
+ indent=2,
+ sort_keys=True,
+ )
+ + "\n",
+ )
+ write_text(
+ repo_dir / "node_modules" / package_name / "index.js",
+ f"export function {symbol}(value) {{ return {{ accepted: Boolean(value) }}; }}\n",
+ )
+ return {
+ "fixture_version": 1,
+ "capability": "dependencies",
+ "language": "javascript",
+ "package_manager": "npm",
+ "package": package_name,
+ "relevant_symbol": symbol,
+ "source_resolution": f"node_modules/{package_name}",
+ "network_required": False,
+ }
+
+
+def create_git_history_quality_repo(repo_dir: Path) -> dict[str, Any]:
+ """Create a deterministic four-commit co-change history for two source files."""
+ alpha = repo_dir / "alpha.py"
+ beta = repo_dir / "beta.py"
+ git_env = os.environ.copy()
+ git_env.update(
+ {
+ "GIT_AUTHOR_NAME": "CBM Benchmark",
+ "GIT_AUTHOR_EMAIL": "benchmark@example.invalid",
+ "GIT_COMMITTER_NAME": "CBM Benchmark",
+ "GIT_COMMITTER_EMAIL": "benchmark@example.invalid",
+ }
+ )
+
+ def git(*arguments: str, commit_index: int | None = None) -> None:
+ env = git_env
+ if commit_index is not None:
+ env = git_env.copy()
+ timestamp = f"2026-01-{commit_index:02d}T00:00:00+00:00"
+ env["GIT_AUTHOR_DATE"] = timestamp
+ env["GIT_COMMITTER_DATE"] = timestamp
+ subprocess.run(
+ ["git", *arguments],
+ cwd=repo_dir,
+ env=env,
+ check=True,
+ capture_output=True,
+ text=True,
+ )
+
+ git("init", "-q")
+ for commit_index in range(1, 5):
+ write_text(
+ alpha,
+ alpha.read_text(encoding="utf-8")
+ + f"def alpha_{commit_index}():\n return {commit_index}\n\n"
+ if alpha.exists()
+ else f"def alpha_{commit_index}():\n return {commit_index}\n\n",
+ )
+ write_text(
+ beta,
+ beta.read_text(encoding="utf-8")
+ + f"def beta_{commit_index}():\n return {commit_index}\n\n"
+ if beta.exists()
+ else f"def beta_{commit_index}():\n return {commit_index}\n\n",
+ )
+ git("add", "--", "alpha.py", "beta.py")
+ git(
+ "commit",
+ "-q",
+ "-m",
+ f"coupled change {commit_index}",
+ commit_index=commit_index,
+ )
+ return {
+ "fixture_version": 1,
+ "capability": "git_history",
+ "language": "python",
+ "coupled_paths": ["alpha.py", "beta.py"],
+ "expected_co_changes": 4,
+ "relationship": "FILE_CHANGES_WITH",
+ "network_required": False,
+ }
+
+
+def create_http_links_quality_repo(repo_dir: Path) -> dict[str, Any]:
+ """Create a source-discovered Ktor route plus a cross-service HTTP client call."""
+ concrete_path = "/api/cbmbench-orders/42"
+ route_template = "/api/cbmbench-orders/{order_id}"
+ write_text(
+ repo_dir / "server" / "Routes.kt",
+ "import io.ktor.server.application.*\n"
+ "import io.ktor.server.response.*\n"
+ "import io.ktor.server.routing.*\n\n"
+ "fun Application.configureRouting() {\n"
+ " routing {\n"
+ f' get("{route_template}") {{\n'
+ ' call.respondText("order")\n'
+ " }\n"
+ " }\n"
+ "}\n",
+ )
+ write_text(
+ repo_dir / "client" / "service.py",
+ "import requests\n\n"
+ "def fetch_order():\n"
+ f" return requests.get('http://orders.invalid{concrete_path}')\n",
+ )
+ return {
+ "fixture_version": 1,
+ "capability": "http_links",
+ "language": "python+kotlin",
+ "caller": "fetch_order",
+ "handler": "configureRouting",
+ "route_path": concrete_path,
+ "route_template": route_template,
+ "relationship": "HTTP_CALLS",
+ "network_required": False,
+ }
+
+
+def canonical_json_sha256(value: Any) -> str:
+ payload = json.dumps(value, separators=(",", ":"), sort_keys=True).encode("utf-8")
+ return hashlib.sha256(payload).hexdigest()
+
+
+def create_pair_quality_repo(repo_dir: Path, capability: str) -> dict[str, Any]:
+ task_root = Path(__file__).resolve().parents[1] / "benchmarks" / "semantic-pairs-v1"
+ manifest_path = task_root / "manifest.json"
+ manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
+ if manifest.get("schema_version") != 1:
+ raise ValueError("semantic pair manifest schema_version must be 1")
+ cases = manifest.get("cases")
+ case = cases.get(capability) if isinstance(cases, dict) else None
+ if not isinstance(case, dict):
+ raise ValueError(f"semantic pair manifest has no case for {capability}")
+ source_paths = case.get("source_paths")
+ if not isinstance(source_paths, list) or not source_paths:
+ raise ValueError(f"semantic pair case {capability} requires source_paths")
+ source_sha256: dict[str, str] = {}
+ for relative in source_paths:
+ if (
+ not isinstance(relative, str)
+ or not relative
+ or Path(relative).is_absolute()
+ or ".." in Path(relative).parts
+ ):
+ raise ValueError("semantic pair source path must be relative")
+ source = task_root / relative
+ payload = source.read_bytes()
+ target = repo_dir / relative
+ target.parent.mkdir(parents=True, exist_ok=True)
+ target.write_bytes(payload)
+ source_sha256[relative] = hashlib.sha256(payload).hexdigest()
+ mutation = case.get("mutation")
+ if not isinstance(mutation, dict):
+ raise ValueError(f"semantic pair case {capability} requires mutation")
+ replacement_relative = mutation.get("replacement_source_path")
+ target_relative = mutation.get("target_path")
+ if (
+ not isinstance(replacement_relative, str)
+ or not replacement_relative
+ or Path(replacement_relative).is_absolute()
+ or ".." in Path(replacement_relative).parts
+ or target_relative not in source_paths
+ ):
+ raise ValueError(f"semantic pair case {capability} has invalid mutation paths")
+ replacement_payload = (task_root / replacement_relative).read_bytes()
+ mutation = {
+ **mutation,
+ "replacement_source_sha256": hashlib.sha256(replacement_payload).hexdigest(),
+ }
+ task_set = {
+ "schema_version": manifest["schema_version"],
+ "task_set_version": manifest["task_set_version"],
+ "ground_truth_scope": manifest["ground_truth_scope"],
+ "query_name_marker": manifest["query_name_marker"],
+ **case,
+ "mutation": mutation,
+ "source_sha256": source_sha256,
+ "manifest_sha256": hashlib.sha256(manifest_path.read_bytes()).hexdigest(),
+ }
+ return {**task_set, "task_set_sha256": canonical_json_sha256(task_set)}
+
+
+def create_similarity_quality_repo(repo_dir: Path) -> dict[str, Any]:
+ return create_pair_quality_repo(repo_dir, "similarity")
+
+
+def create_semantic_edges_quality_repo(repo_dir: Path) -> dict[str, Any]:
+ return create_pair_quality_repo(repo_dir, "semantic_edges")
+
+
+def apply_pair_quality_mutation(
+ repo_dir: Path, fixture: dict[str, Any]
+) -> dict[str, Any]:
+ mutation = fixture.get("mutation")
+ if not isinstance(mutation, dict):
+ raise ValueError("pair quality fixture has no mutation")
+ target_relative = str(mutation["target_path"])
+ replacement_relative = str(mutation["replacement_source_path"])
+ target = repo_dir / target_relative
+ before_payload = target.read_bytes()
+ before_sha256 = hashlib.sha256(before_payload).hexdigest()
+ expected_before = fixture.get("source_sha256", {}).get(target_relative)
+ if before_sha256 != expected_before:
+ raise ValueError(
+ f"pair quality mutation source hash mismatch for {target_relative}"
+ )
+ task_root = Path(__file__).resolve().parents[1] / "benchmarks" / "semantic-pairs-v1"
+ replacement_payload = (task_root / replacement_relative).read_bytes()
+ after_sha256 = hashlib.sha256(replacement_payload).hexdigest()
+ if after_sha256 != mutation.get("replacement_source_sha256"):
+ raise ValueError("pair quality replacement source hash mismatch")
+ atomic_write_text(target, replacement_payload.decode("utf-8"))
+ return {
+ "description": mutation["description"],
+ "changed_paths": [target_relative],
+ "before_sha256": before_sha256,
+ "after_sha256": after_sha256,
+ "post_judgments": list(mutation["post_judgments"]),
+ }
+
+
+def create_inbound_frontier_repo(
+ repo_dir: Path, language: str, dependent_files: int
+) -> dict[str, Any]:
+ """Create one definition file with a requested number of inbound dependents."""
+ if dependent_files <= 0:
+ raise ValueError("frontier files must be positive")
+ dependent_paths: list[str] = []
+ if language == "go":
+ write_text(repo_dir / "go.mod", "module example.com/cbmfrontier\n\ngo 1.22\n")
+ write_text(
+ repo_dir / "leaf.go", "package frontier\n\nfunc Leaf() int { return 1 }\n"
+ )
+ for index in range(dependent_files):
+ relative = f"caller_{index:04d}.go"
+ write_text(
+ repo_dir / relative,
+ "package frontier\n\n"
+ f"func Caller{index:04d}() int {{ return Leaf() + {index} }}\n",
+ )
+ dependent_paths.append(relative)
+ changed_path = "leaf.go"
+ elif language == "python":
+ write_text(repo_dir / "leaf.py", "def leaf():\n return 1\n")
+ for index in range(dependent_files):
+ relative = f"caller_{index:04d}.py"
+ write_text(
+ repo_dir / relative,
+ "from leaf import leaf\n\n"
+ f"def caller_{index:04d}():\n return leaf() + {index}\n",
+ )
+ dependent_paths.append(relative)
+ changed_path = "leaf.py"
+ elif language == "c_header":
+ write_text(
+ repo_dir / "shared.h",
+ "#ifndef SHARED_H\n"
+ "#define SHARED_H\n"
+ "static int shared_value(void) { return 1; }\n"
+ "#endif\n",
+ )
+ for index in range(dependent_files):
+ relative = f"consumer_{index:04d}.c"
+ write_text(
+ repo_dir / relative,
+ '#include "shared.h"\n\n'
+ f"int consumer_{index:04d}(void) {{ return shared_value() + {index}; }}\n",
+ )
+ dependent_paths.append(relative)
+ changed_path = "shared.h"
+ elif language in {"cpp", "cuda"}:
+ header_ext, source_ext = ("hpp", "cpp") if language == "cpp" else ("cuh", "cu")
+ changed_path = f"shared.{header_ext}"
+ write_text(repo_dir / changed_path, "inline int shared_value() { return 1; }\n")
+ for index in range(dependent_files):
+ relative = f"consumer_{index:04d}.{source_ext}"
+ write_text(
+ repo_dir / relative,
+ f'#include "{changed_path}"\n\n'
+ f"int consumer_{index:04d}() {{ return shared_value() + {index}; }}\n",
+ )
+ dependent_paths.append(relative)
+ elif language in {"javascript", "typescript", "tsx"}:
+ extension = {"javascript": "js", "typescript": "ts", "tsx": "tsx"}[language]
+ changed_path = f"leaf.{extension}"
+ return_type = "" if language == "javascript" else ": number"
+ write_text(
+ repo_dir / changed_path,
+ f"export function leaf(){return_type} {{ return 1; }}\n",
+ )
+ for index in range(dependent_files):
+ relative = f"caller_{index:04d}.{extension}"
+ import_suffix = ".js" if language == "javascript" else ""
+ write_text(
+ repo_dir / relative,
+ f"import {{ leaf }} from './leaf{import_suffix}';\n\n"
+ f"export function caller{index:04d}(){return_type} "
+ f"{{ return leaf() + {index}; }}\n",
+ )
+ dependent_paths.append(relative)
+ elif language == "php":
+ changed_path = "Leaf.php"
+ write_text(
+ repo_dir / changed_path,
+ " i32 { 1 }\n")
+ modules = ["mod leaf;"]
+ for index in range(dependent_files):
+ module = f"caller_{index:04d}"
+ relative = f"{module}.rs"
+ modules.append(f"mod {module};")
+ write_text(
+ repo_dir / relative,
+ "use crate::leaf::leaf_value;\n"
+ f"pub fn caller_{index:04d}() -> i32 {{ leaf_value() + {index} }}\n",
+ )
+ dependent_paths.append(relative)
+ write_text(repo_dir / "lib.rs", "\n".join(modules) + "\n")
+ else:
+ raise ValueError(f"unsupported frontier language: {language}")
+ resolver_language = "c" if language == "c_header" else language
+ metadata = {
+ "source": "synthetic_inbound_frontier",
+ "language": language,
+ "cross_file_resolver_language": resolver_language,
+ "changed_path": changed_path,
+ "requested_inbound_dependents": dependent_files,
+ "dependent_paths": dependent_paths,
+ }
+ parallel_scoped_lsp_fallback = (
+ resolver_language in PARALLEL_SCOPED_LSP_FALLBACK_LANGUAGES
+ and dependent_files + 1 > INCREMENTAL_PARALLEL_MIN_FILES
+ )
+ if (
+ resolver_language in SCOPED_EXACT_FRONTIER_LANGUAGES
+ and not parallel_scoped_lsp_fallback
+ ):
+ metadata.update(
+ {
+ "incremental_contract": "exact_frontier",
+ "expected_minimum_affected_files": dependent_files + 1,
+ }
+ )
+ else:
+ metadata.update(
+ {
+ "incremental_contract": "safe_full_rebuild",
+ "expected_publish_kind": PUBLISH_FULL,
+ "expected_reason": "scoped_lsp_gap",
+ }
+ )
+ return metadata
+
+
+def mutate_inbound_frontier_repo(repo_dir: Path, language: str) -> list[str]:
+ if language == "go":
+ changed_path = "leaf.go"
+ content = (
+ "package frontier\n\n"
+ "func Leaf() int { return 2 }\n\n"
+ "func LeafExtra() int { return Leaf() + 1 }\n"
+ )
+ elif language == "python":
+ changed_path = "leaf.py"
+ content = (
+ "def leaf():\n return 2\n\ndef leaf_extra():\n return leaf() + 1\n"
+ )
+ elif language == "c_header":
+ changed_path = "shared.h"
+ content = (
+ "#ifndef SHARED_H\n"
+ "#define SHARED_H\n"
+ "static int shared_value(void) { return 2; }\n"
+ "static int shared_extra(void) { return shared_value() + 1; }\n"
+ "#endif\n"
+ )
+ elif language in {"cpp", "cuda"}:
+ header_ext = "hpp" if language == "cpp" else "cuh"
+ changed_path = f"shared.{header_ext}"
+ content = (
+ "inline int shared_value() { return 2; }\n"
+ "inline int shared_extra() { return shared_value() + 1; }\n"
+ )
+ elif language in {"javascript", "typescript", "tsx"}:
+ extension = {"javascript": "js", "typescript": "ts", "tsx": "tsx"}[language]
+ changed_path = f"leaf.{extension}"
+ return_type = "" if language == "javascript" else ": number"
+ content = (
+ f"export function leaf(){return_type} {{ return 2; }}\n"
+ f"export function leafExtra(){return_type} {{ return leaf() + 1; }}\n"
+ )
+ elif language == "php":
+ changed_path = "Leaf.php"
+ content = (
+ " i32 { 2 }\n"
+ "pub fn leaf_extra() -> i32 { leaf_value() + 1 }\n"
+ )
+ else:
+ raise ValueError(f"unsupported frontier language: {language}")
+ write_text(repo_dir / changed_path, content)
+ return [changed_path]
+
+
+def command_result(
+ cmd: list[str],
+ env: dict[str, str],
+ timeout: int,
+ cwd: Path | None = None,
+) -> tuple[subprocess.CompletedProcess[str], float]:
+ start = now_ms()
+ proc = subprocess.run(
+ cmd,
+ cwd=str(cwd) if cwd else None,
+ env=env,
+ capture_output=True,
+ text=True,
+ timeout=timeout,
+ check=False,
+ )
+ return proc, now_ms() - start
+
+
+def parse_list_project_counts(raw: str) -> list[int]:
+ """Parse a strictly increasing positive scaling series."""
+ items = raw.split(",") if raw else []
+ try:
+ counts = [int(item.strip()) for item in items if item.strip()]
+ except ValueError as exc:
+ raise ValueError(
+ "list project counts must be comma-separated integers"
+ ) from exc
+ if not counts or any(count <= 0 for count in counts):
+ raise ValueError("list project counts must contain positive integers")
+ if any(left >= right for left, right in pairwise(counts)):
+ raise ValueError("list project counts must be strictly increasing")
+ return counts
+
+
+def list_project_fixture_budget(
+ *,
+ seed_bytes: int,
+ maximum_projects: int,
+ maximum_fixture_mb: int,
+ disk_free_bytes: int,
+) -> dict[str, Any]:
+ """Return a deterministic disk gate before cloning list-project fixtures."""
+ if min(seed_bytes, maximum_projects, maximum_fixture_mb, disk_free_bytes) <= 0:
+ raise ValueError("list-project fixture budget inputs must be positive")
+ mib = 1024 * 1024
+ projected_bytes = seed_bytes * maximum_projects
+ cap_bytes = maximum_fixture_mb * mib
+ reserved_bytes = max(
+ LIST_PROJECT_DISK_RESERVE_BYTES,
+ math.ceil(disk_free_bytes * LIST_PROJECT_DISK_RESERVE_FRACTION),
+ )
+ available_after_reserve = max(0, disk_free_bytes - reserved_bytes)
+ reason = ""
+ if projected_bytes > cap_bytes:
+ reason = "projected fixture exceeds configured cap"
+ elif projected_bytes > available_after_reserve:
+ reason = "projected fixture violates free-space reserve"
+ return {
+ "passed": not reason,
+ "reason": reason or None,
+ "seed_bytes": seed_bytes,
+ "maximum_projects": maximum_projects,
+ "projected_fixture_bytes": projected_bytes,
+ "configured_cap_bytes": cap_bytes,
+ "disk_free_bytes": disk_free_bytes,
+ "reserved_free_bytes": reserved_bytes,
+ "available_after_reserve_bytes": available_after_reserve,
+ }
+
+
+def text_tail(text: str, max_lines: int = FAILURE_TAIL_LINES) -> list[str]:
+ lines = text.splitlines()
+ return lines[-max_lines:]
+
+
+def failure_artifact_dir(env: dict[str, str]) -> Path:
+ cache_dir = env.get("CBM_CACHE_DIR")
+ if cache_dir:
+ return Path(cache_dir).expanduser().parent / FAILURE_ARTIFACT_DIRNAME
+ return Path(tempfile.gettempdir()) / FAILURE_FALLBACK_DIRNAME
+
+
+def command_failure(
+ label: str,
+ cmd: list[str],
+ env: dict[str, str],
+ proc: subprocess.CompletedProcess[str],
+ elapsed_ms: float,
+) -> BenchmarkCommandError:
+ safe_label = re.sub(r"[^A-Za-z0-9_.-]+", "_", label).strip("_") or "command"
+ stamp = datetime.now(timezone.utc).strftime(FAILURE_TIMESTAMP_FORMAT)
+ prefix = failure_artifact_dir(env) / f"{stamp}-{safe_label}"
+ stdout_path = Path(f"{prefix}.stdout.txt")
+ stderr_path = Path(f"{prefix}.stderr.txt")
+ meta_path = Path(f"{prefix}.meta.json")
+
+ write_text(stdout_path, proc.stdout)
+ write_text(stderr_path, proc.stderr)
+ detail: dict[str, Any] = {
+ "label": label,
+ "returncode": proc.returncode,
+ "elapsed_ms": round(elapsed_ms, 3),
+ "stdout_bytes": len(proc.stdout.encode("utf-8")),
+ "stderr_bytes": len(proc.stderr.encode("utf-8")),
+ "stdout_tail": text_tail(proc.stdout),
+ "stderr_tail": text_tail(proc.stderr),
+ "artifacts": {
+ "stdout": str(stdout_path),
+ "stderr": str(stderr_path),
+ "meta": str(meta_path),
+ },
+ }
+ write_text(
+ meta_path,
+ json.dumps({"cmd": cmd, **detail}, indent=2, sort_keys=True) + "\n",
+ )
+ return BenchmarkCommandError(
+ f"{label} failed with rc={proc.returncode}; artifacts={detail['artifacts']}",
+ detail,
+ )
+
+
+def record_report_error(report: dict[str, Any], exc: Exception) -> None:
+ report["error"] = f"{type(exc).__name__}: {exc}"
+ if isinstance(exc, BenchmarkCommandError):
+ report["error_detail"] = exc.detail
+
+
+def command_stdout(cmd: list[str], timeout: int, cwd: Path | None = None) -> str:
+ proc, _ = command_result(cmd, dict(os.environ), timeout, cwd)
+ if proc.returncode != 0:
+ rendered = " ".join(cmd)
+ raise RuntimeError(f"{rendered} failed: {proc.stderr.strip()}")
+ return proc.stdout.strip()
+
+
+def command_stdout_bytes(
+ cmd: list[str], timeout: int, cwd: Path | None = None
+) -> bytes:
+ proc = subprocess.run(
+ cmd,
+ cwd=str(cwd) if cwd else None,
+ env=dict(os.environ),
+ capture_output=True,
+ timeout=timeout,
+ check=False,
+ )
+ if proc.returncode != 0:
+ rendered = " ".join(cmd)
+ stderr = proc.stderr.decode("utf-8", "replace").strip()
+ raise RuntimeError(f"{rendered} failed: {stderr}")
+ return proc.stdout
+
+
+def append_text(path: Path, text: str) -> None:
+ current = path.read_text(encoding="utf-8")
+ path.write_text(current + text, encoding="utf-8")
+
+
+def unwrap_cli_json(stdout: str) -> dict[str, Any]:
+ outer = json.loads(stdout)
+ if "content" in outer:
+ return json.loads(outer["content"][0]["text"])
+ return outer
+
+
+def unwrap_mcp_result(response: dict[str, Any]) -> dict[str, Any]:
+ result = response.get("result", {})
+ if "content" in result:
+ return json.loads(result["content"][0]["text"])
+ return result
+
+
+def cli_result_text(stdout: str) -> str:
+ outer = json.loads(stdout)
+ if "content" in outer:
+ return str(outer["content"][0]["text"])
+ return json.dumps(outer, separators=(",", ":"), sort_keys=True)
+
+
+def mcp_result_text(response: dict[str, Any]) -> str:
+ result = response.get("result", {})
+ content = result.get("content")
+ if isinstance(content, list):
+ # The server may prepend a one-shot update notice as a separate text block.
+ # The tool payload remains the final text block; selecting it preserves both
+ # JSON and default TOON responses without matching notice wording.
+ for item in reversed(content):
+ if (
+ isinstance(item, dict)
+ and item.get("type") == "text"
+ and isinstance(item.get("text"), str)
+ ):
+ return item["text"]
+ return json.dumps(result, separators=(",", ":"), sort_keys=True)
+
+
+TOKEN_ESTIMATOR = "utf8_bytes_div_4_ceil"
+
+
+def canonical_response_bytes(data: dict[str, Any]) -> bytes:
+ """Serialize the tool payload independently of CLI/MCP envelopes."""
+ return json.dumps(data, separators=(",", ":"), sort_keys=True).encode("utf-8")
+
+
+def estimate_response_tokens(payload: bytes) -> int:
+ """Return a deterministic, dependency-free byte/4 token estimate."""
+ return (len(payload) + 3) // 4
+
+
+def build_search_projection_observation(
+ variant: str,
+ data: dict[str, Any],
+ mcp_envelope_bytes: int,
+ elapsed_ms: float,
+ transport_survived: bool,
+) -> dict[str, Any]:
+ results = data.get("results")
+ typed_results = (
+ [item for item in results if isinstance(item, dict)]
+ if isinstance(results, list)
+ else []
+ )
+ result_keys = {str(key) for item in typed_results for key in item}
+ property_fields = sorted(result_keys - SEARCH_PROJECTION_CORE_FIELDS)
+ internal_fields = sorted(result_keys & SEARCH_PROJECTION_INTERNAL_FIELDS)
+ qualified_names = [
+ str(item["qualified_name"])
+ for item in typed_results
+ if isinstance(item.get("qualified_name"), str)
+ ]
+ payload = canonical_response_bytes(data)
+ return {
+ "variant": variant,
+ "returned_count": len(typed_results),
+ "qualified_names": qualified_names,
+ "property_fields": property_fields,
+ "internal_fields": internal_fields,
+ "response_bytes": len(payload),
+ "response_token_estimate": estimate_response_tokens(payload),
+ "mcp_envelope_bytes": mcp_envelope_bytes,
+ "elapsed_ms": round(elapsed_ms, 3),
+ "transport_survived": transport_survived,
+ "passed": isinstance(results, list)
+ and not internal_fields
+ and transport_survived,
+ }
+
+
+def process_rss_kb(pid: int) -> int | None:
+ """Read resident memory after a call; this is not a peak-RSS measurement."""
+ try:
+ proc = subprocess.run(
+ ["ps", "-o", "rss=", "-p", str(pid)],
+ capture_output=True,
+ text=True,
+ timeout=5,
+ check=False,
+ )
+ if proc.returncode != 0:
+ return None
+ return int(proc.stdout.strip())
+ except (OSError, ValueError, subprocess.TimeoutExpired):
+ return None
+
+
+def tool_schema_sha256(tool: dict[str, Any]) -> str:
+ schema = tool.get("inputSchema")
+ payload = json.dumps(schema, separators=(",", ":"), sort_keys=True).encode("utf-8")
+ return hashlib.sha256(payload).hexdigest()
+
+
+def tool_contract_sha256(tool: dict[str, Any]) -> str:
+ """Hash every MCP tools/list field that affects client discovery and invocation."""
+ contract = {
+ key: tool.get(key)
+ for key in (
+ "name",
+ "title",
+ "description",
+ "inputSchema",
+ "outputSchema",
+ "annotations",
+ )
+ }
+ payload = json.dumps(contract, separators=(",", ":"), sort_keys=True).encode(
+ "utf-8"
+ )
+ return hashlib.sha256(payload).hexdigest()
+
+
+def tool_schema_properties(tool: dict[str, Any] | None) -> set[str]:
+ if not isinstance(tool, dict):
+ return set()
+ schema = tool.get("inputSchema")
+ properties = schema.get("properties") if isinstance(schema, dict) else None
+ return set(map(str, properties)) if isinstance(properties, dict) else set()
+
+
+def tool_schema_required(tool: dict[str, Any] | None) -> set[str]:
+ if not isinstance(tool, dict):
+ return set()
+ schema = tool.get("inputSchema")
+ required = schema.get("required") if isinstance(schema, dict) else None
+ return set(map(str, required)) if isinstance(required, list) else set()
+
+
+def schema_validation_shape(value: Any) -> Any:
+ """Remove documentation-only JSON Schema fields while retaining validation semantics."""
+ if isinstance(value, dict):
+ return {
+ str(key): schema_validation_shape(item)
+ for key, item in sorted(value.items())
+ if key not in {"description", "title", "$comment", "examples"}
+ }
+ if isinstance(value, list):
+ return [schema_validation_shape(item) for item in value]
+ return value
+
+
+def compare_mcp_tool_surfaces(
+ pre_reveal: list[dict[str, Any]],
+ post_reveal: list[dict[str, Any]],
+ classic: list[dict[str, Any]],
+ *,
+ pre_dispatch: dict[str, bool],
+ list_changed_observed: bool,
+) -> dict[str, Any]:
+ """Compare discovery and callable coverage without conflating hidden with absent."""
+ pre_by_name = {
+ str(tool.get("name")): tool for tool in pre_reveal if tool.get("name")
+ }
+ post_by_name = {
+ str(tool.get("name")): tool for tool in post_reveal if tool.get("name")
+ }
+ classic_by_name = {
+ str(tool.get("name")): tool for tool in classic if tool.get("name")
+ }
+ classic_names = set(classic_by_name)
+ advertised_pre = sorted(classic_names & set(pre_by_name))
+ hidden_pre = sorted(classic_names - set(pre_by_name))
+ dispatch_recognized_pre = sorted(
+ name for name in classic_names if pre_dispatch.get(name) is True
+ )
+ missing_post = sorted(classic_names - set(post_by_name))
+ schema_mismatches = sorted(
+ name
+ for name in classic_names & set(post_by_name)
+ if tool_schema_sha256(classic_by_name[name])
+ != tool_schema_sha256(post_by_name[name])
+ )
+ name_parity = not missing_post
+ schema_parity = name_parity and not schema_mismatches
+ contract_mismatches = sorted(
+ name
+ for name in classic_names & set(post_by_name)
+ if tool_contract_sha256(classic_by_name[name])
+ != tool_contract_sha256(post_by_name[name])
+ )
+ contract_parity = name_parity and not contract_mismatches
+ dispatch_parity = len(dispatch_recognized_pre) == len(classic_names) and bool(
+ classic_names
+ )
+ alias_streamlined = pre_by_name.get("get_code")
+ alias_classic = classic_by_name.get("get_code_snippet")
+ streamlined_properties = tool_schema_properties(alias_streamlined)
+ classic_properties = tool_schema_properties(alias_classic)
+ streamlined_required = tool_schema_required(alias_streamlined)
+ classic_required = tool_schema_required(alias_classic)
+ alias = {
+ "streamlined_name": "get_code",
+ "classic_name": "get_code_snippet",
+ "both_advertised_in_compared_surfaces": bool(
+ alias_streamlined and alias_classic
+ ),
+ "schema_equal": bool(alias_streamlined and alias_classic)
+ and tool_schema_sha256(alias_streamlined) == tool_schema_sha256(alias_classic),
+ "validation_shape_equal": bool(alias_streamlined and alias_classic)
+ and schema_validation_shape(alias_streamlined.get("inputSchema"))
+ == schema_validation_shape(alias_classic.get("inputSchema")),
+ "property_names_equal": streamlined_properties == classic_properties,
+ "shared_properties": sorted(streamlined_properties & classic_properties),
+ "streamlined_only_properties": sorted(
+ streamlined_properties - classic_properties
+ ),
+ "classic_only_properties": sorted(classic_properties - streamlined_properties),
+ "streamlined_required": sorted(streamlined_required),
+ "classic_required": sorted(classic_required),
+ "required_names_equal": streamlined_required == classic_required,
+ }
+ capability_parity: list[dict[str, Any]] = []
+ for (
+ capability,
+ outcome,
+ classic_required_names,
+ streamlined_names,
+ ) in MCP_CAPABILITY_SURFACES:
+ classic_required = set(classic_required_names)
+ if not classic_required.issubset(classic_names):
+ continue
+ streamlined_required = set(streamlined_names)
+ pre_advertised = bool(streamlined_required) and streamlined_required.issubset(
+ pre_by_name
+ )
+ pre_callable = pre_advertised or all(
+ pre_dispatch.get(name) is True for name in classic_required
+ )
+ capability_parity.append(
+ {
+ "capability": capability,
+ "outcome": outcome,
+ "classic_tools": sorted(classic_required),
+ "streamlined_pre_reveal_tools": sorted(streamlined_required),
+ "classic_advertised": True,
+ "streamlined_pre_reveal_advertised": pre_advertised,
+ "streamlined_pre_reveal_callable": pre_callable,
+ "streamlined_post_reveal_advertised": classic_required.issubset(
+ post_by_name
+ ),
+ "evidence": "tools/list contracts and bounded handler-recognition probes",
+ }
+ )
+ capability_parity_passed = bool(capability_parity) and all(
+ item["streamlined_pre_reveal_callable"]
+ and item["streamlined_post_reveal_advertised"]
+ for item in capability_parity
+ )
+ return {
+ "comparison_scope": {
+ "advertised_parity": (
+ "tool names and full tools/list contract hashes: title, description, "
+ "input/output schemas, and annotations"
+ ),
+ "dispatch_parity": (
+ "handler recognition from bounded empty-argument calls; this does not claim "
+ "end-to-end behavioral equality"
+ ),
+ "capability_parity": (
+ "user-outcome mapping from advertised contracts and bounded handler recognition; "
+ "functional quality is measured by separate capability fixtures"
+ ),
+ },
+ "pre_reveal": {
+ "advertised_classic_tools": f"{len(advertised_pre)}/{len(classic_names)}",
+ "advertised_classic_tool_names": advertised_pre,
+ "intentionally_hidden_classic_tools": hidden_pre,
+ "dispatch_recognized_classic_tools": (
+ f"{len(dispatch_recognized_pre)}/{len(classic_names)}"
+ ),
+ "dispatch_recognized_classic_tool_names": dispatch_recognized_pre,
+ "classic_dispatch_parity": dispatch_parity,
+ "get_code_alias": alias,
+ },
+ "post_reveal": {
+ "classic_name_parity": name_parity,
+ "missing_classic_tools": missing_post,
+ "classic_schema_parity": schema_parity,
+ "schema_mismatches": schema_mismatches,
+ "classic_contract_parity": contract_parity,
+ "contract_mismatches": contract_mismatches,
+ "tools_list_changed_observed": list_changed_observed,
+ },
+ "capability_parity": capability_parity,
+ "passed": (
+ dispatch_parity
+ and name_parity
+ and schema_parity
+ and contract_parity
+ and capability_parity_passed
+ and list_changed_observed
+ ),
+ }
+
+
+def capture_tool_surface(
+ client: "McpClient",
+) -> tuple[dict[str, Any], list[dict[str, Any]]]:
+ start = now_ms()
+ response = client._request("tools/list", {})
+ elapsed_ms = now_ms() - start
+ result = response.get("result")
+ tools = result.get("tools") if isinstance(result, dict) else None
+ if not isinstance(tools, list) or not all(isinstance(tool, dict) for tool in tools):
+ raise RuntimeError("MCP tools/list did not return an object array")
+ typed_tools = list(tools)
+ payload = json.dumps(response, separators=(",", ":"), sort_keys=True).encode(
+ "utf-8"
+ )
+ return (
+ {
+ "tool_count": len(typed_tools),
+ "tool_names": [str(tool.get("name")) for tool in typed_tools],
+ "input_schema_sha256": {
+ str(tool.get("name")): tool_schema_sha256(tool)
+ for tool in typed_tools
+ if tool.get("name")
+ },
+ "list_elapsed_ms": round(elapsed_ms, 3),
+ "response_bytes": len(payload),
+ "response_token_estimate": estimate_response_tokens(payload),
+ "token_estimator": TOKEN_ESTIMATOR,
+ },
+ typed_tools,
+ )
+
+
+class McpClient:
+ def __init__(self, binary: Path, env: dict[str, str], timeout: int) -> None:
+ self.binary = binary
+ self.env = env
+ self.timeout = timeout
+ self.next_id = 1
+ self.notifications: list[dict[str, Any]] = []
+ self.stderr_lines: list[str] = []
+ self.stderr_lock = threading.Lock()
+ self.stdout_queue: queue.Queue[str | None] = queue.Queue()
+ self.proc: subprocess.Popen[str] | None = None
+ self.stdout_thread: threading.Thread | None = None
+ self.stderr_thread: threading.Thread | None = None
+ self.cleanup: dict[str, Any] = {
+ "process_reaped": False,
+ "reader_threads_reaped": False,
+ "returncode": None,
+ }
+
+ def __enter__(self) -> "McpClient":
+ self.proc = subprocess.Popen(
+ [str(self.binary)],
+ env=self.env,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ text=True,
+ bufsize=1,
+ )
+ self.stdout_thread = threading.Thread(target=self._read_stdout, daemon=True)
+ self.stderr_thread = threading.Thread(target=self._read_stderr, daemon=True)
+ self.stdout_thread.start()
+ self.stderr_thread.start()
+ self._initialize()
+ return self
+
+ def __exit__(self, exc_type: object, exc: object, tb: object) -> None:
+ if not self.proc:
+ return
+ proc = self.proc
+ process_reaped = False
+ try:
+ try:
+ if proc.stdin:
+ proc.stdin.close()
+ proc.wait(timeout=5)
+ process_reaped = True
+ except subprocess.TimeoutExpired:
+ proc.terminate()
+ try:
+ proc.wait(timeout=5)
+ process_reaped = True
+ except subprocess.TimeoutExpired:
+ proc.kill()
+ proc.wait(timeout=5)
+ process_reaped = True
+ finally:
+ reader_threads = tuple(
+ thread for thread in (self.stdout_thread, self.stderr_thread) if thread
+ )
+ for thread in reader_threads:
+ thread.join(timeout=5)
+ alive_threads = [thread for thread in reader_threads if thread.is_alive()]
+ for stream in (proc.stdout, proc.stderr):
+ if stream:
+ stream.close()
+ for thread in alive_threads:
+ thread.join(timeout=1)
+ readers_still_alive = any(thread.is_alive() for thread in alive_threads)
+ self.cleanup = {
+ "process_reaped": process_reaped,
+ "reader_threads_reaped": not readers_still_alive,
+ "returncode": getattr(proc, "returncode", None),
+ }
+ self.proc = None
+ self.stdout_thread = None
+ self.stderr_thread = None
+ if readers_still_alive and exc_type is None:
+ raise RuntimeError("MCP reader thread did not stop after process exit")
+
+ def _read_stdout(self) -> None:
+ assert self.proc and self.proc.stdout
+ for line in self.proc.stdout:
+ self.stdout_queue.put(line)
+ self.stdout_queue.put(None)
+
+ def _read_stderr(self) -> None:
+ assert self.proc and self.proc.stderr
+ for line in self.proc.stderr:
+ with self.stderr_lock:
+ self.stderr_lines.append(line.rstrip("\n"))
+
+ def _stderr_mark(self) -> int:
+ with self.stderr_lock:
+ return len(self.stderr_lines)
+
+ def _stderr_since(self, mark: int) -> str:
+ with self.stderr_lock:
+ return "\n".join(self.stderr_lines[mark:])
+
+ def server_exit_error(self, method: str) -> RuntimeError:
+ """Retain bounded candidate stderr when MCP exits before a response."""
+ with self.stderr_lock:
+ stderr_tail = self.stderr_lines[-FAILURE_TAIL_LINES:]
+ returncode = self.proc.poll() if self.proc else None
+ detail = (
+ f"; returncode={returncode}; stderr_tail={stderr_tail!r}"
+ if stderr_tail or returncode is not None
+ else ""
+ )
+ return RuntimeError(f"MCP server exited before response: {method}{detail}")
+
+ def _send(self, message: dict[str, Any]) -> None:
+ if not self.proc or not self.proc.stdin:
+ raise RuntimeError("MCP server is not running")
+ self.proc.stdin.write(json.dumps(message, separators=(",", ":")) + "\n")
+ self.proc.stdin.flush()
+
+ def _request(
+ self, method: str, params: dict[str, Any] | None = None
+ ) -> dict[str, Any]:
+ req_id = self.next_id
+ self.next_id += 1
+ message: dict[str, Any] = {"jsonrpc": "2.0", "id": req_id, "method": method}
+ if params is not None:
+ message["params"] = params
+ self._send(message)
+
+ deadline = time.monotonic() + self.timeout
+ while True:
+ remaining = deadline - time.monotonic()
+ if remaining <= 0:
+ raise TimeoutError(f"MCP request timed out: {method}")
+ line = self.stdout_queue.get(timeout=remaining)
+ if line is None:
+ raise self.server_exit_error(method)
+ try:
+ response = json.loads(line)
+ except json.JSONDecodeError as exc:
+ raise RuntimeError(f"non-JSON MCP stdout line: {line[:200]!r}") from exc
+ if "id" not in response and isinstance(response.get("method"), str):
+ self.notifications.append(response)
+ continue
+ if response.get("id") == req_id:
+ if "error" in response:
+ raise RuntimeError(f"MCP request failed: {response['error']}")
+ return response
+
+ def _notification(self, method: str, params: dict[str, Any] | None = None) -> None:
+ message: dict[str, Any] = {"jsonrpc": "2.0", "method": method}
+ if params is not None:
+ message["params"] = params
+ self._send(message)
+
+ def _initialize(self) -> None:
+ self._request(
+ "initialize",
+ {
+ "protocolVersion": MCP_INIT_PROTOCOL_VERSION,
+ "capabilities": {},
+ "clientInfo": {"name": "cbm-incr-speed", "version": "1.0"},
+ },
+ )
+ self._notification("notifications/initialized")
+
+ def call_tool(
+ self, name: str, arguments: dict[str, Any]
+ ) -> tuple[dict[str, Any], str, int, float]:
+ text, stderr, stdout_bytes, elapsed_ms = self.call_tool_text(name, arguments)
+ try:
+ data = json.loads(text)
+ except json.JSONDecodeError as exc:
+ raise RuntimeError(
+ f"MCP tool {name} returned non-JSON text: {text[:200]!r}"
+ ) from exc
+ return data, stderr, stdout_bytes, elapsed_ms
+
+ def call_tool_text(
+ self, name: str, arguments: dict[str, Any]
+ ) -> tuple[str, str, int, float]:
+ mark = self._stderr_mark()
+ start = now_ms()
+ response = self._request("tools/call", {"name": name, "arguments": arguments})
+ elapsed_ms = now_ms() - start
+ stderr = self._stderr_since(mark)
+ stdout_bytes = len(json.dumps(response, separators=(",", ":")).encode("utf-8"))
+ return mcp_result_text(response), stderr, stdout_bytes, elapsed_ms
+
+
+def run_mcp_surface_parity(
+ args: argparse.Namespace, binary: Path
+) -> tuple[dict[str, Any], int]:
+ auto_root = not bool(args.work_root)
+ work_root = (
+ Path(args.work_root).expanduser()
+ if args.work_root
+ else Path(tempfile.mkdtemp(prefix="cbm-mcp-surface-"))
+ )
+ work_root.mkdir(parents=True, exist_ok=True)
+ report: dict[str, Any] = {
+ "generated_at_utc": datetime.now(timezone.utc).isoformat(),
+ "binary": str(binary),
+ "binary_metadata": binary_metadata(binary),
+ "mode": "mcp_surface_parity",
+ "protocol_version": MCP_INIT_PROTOCOL_VERSION,
+ "work_root": str(work_root),
+ "cleanup": {
+ "requested": auto_root and not args.keep_work_root,
+ "removed": False,
+ },
+ }
+ exit_code = 1
+ try:
+ base_env = build_env(work_root / "cache", args.product_environment)
+ base_env["CBM_AUTO_INDEX"] = "false"
+
+ classic_env = dict(base_env)
+ classic_env["CBM_TOOL_MODE"] = "classic"
+ with McpClient(binary, classic_env, args.timeout) as classic_client:
+ classic_summary, classic_tools = capture_tool_surface(classic_client)
+ classic_summary["lifecycle"] = dict(classic_client.cleanup)
+
+ streamlined_env = dict(base_env)
+ streamlined_env["CBM_TOOL_MODE"] = "streamlined"
+ with McpClient(binary, streamlined_env, args.timeout) as streamlined_client:
+ pre_summary, pre_tools = capture_tool_surface(streamlined_client)
+ pre_dispatch: dict[str, bool] = {}
+ dispatch_bytes: dict[str, int] = {}
+ for tool in classic_tools:
+ name = str(tool.get("name") or "")
+ if not name:
+ continue
+ text, _, response_bytes, _ = streamlined_client.call_tool_text(name, {})
+ pre_dispatch[name] = "unknown tool" not in text.lower()
+ dispatch_bytes[name] = response_bytes
+ streamlined_client.call_tool_text("_hidden_tools", {})
+ post_summary, post_tools = capture_tool_surface(streamlined_client)
+ list_changed_observed = any(
+ item.get("method") == "notifications/tools/list_changed"
+ for item in streamlined_client.notifications
+ )
+ pre_summary["lifecycle"] = dict(streamlined_client.cleanup)
+ post_summary["lifecycle"] = dict(streamlined_client.cleanup)
+
+ comparison = compare_mcp_tool_surfaces(
+ pre_tools,
+ post_tools,
+ classic_tools,
+ pre_dispatch=pre_dispatch,
+ list_changed_observed=list_changed_observed,
+ )
+ pre_summary["classic_dispatch_recognized"] = pre_dispatch
+ pre_summary["dispatch_response_bytes"] = dispatch_bytes
+ lifecycle_passed = all(
+ bool(summary.get("lifecycle", {}).get("process_reaped"))
+ and bool(summary.get("lifecycle", {}).get("reader_threads_reaped"))
+ for summary in (classic_summary, pre_summary, post_summary)
+ )
+ comparison["lifecycle_passed"] = lifecycle_passed
+ comparison["passed"] = bool(comparison["passed"]) and lifecycle_passed
+ report.update(
+ {
+ "surfaces": {
+ "streamlined_pre_reveal": pre_summary,
+ "streamlined_post_reveal": post_summary,
+ "classic": classic_summary,
+ },
+ "comparison": comparison,
+ "derived": {"passed": comparison["passed"]},
+ }
+ )
+ exit_code = 0 if comparison["passed"] else 1
+ except Exception as exc:
+ record_report_error(report, exc)
+ finally:
+ if auto_root and not args.keep_work_root:
+ shutil.rmtree(work_root, ignore_errors=True)
+ report["cleanup"]["removed"] = not work_root.exists()
+ emit_report(report, args)
+ return report, exit_code
+
+
+def run_list_projects_scaling(
+ args: argparse.Namespace, binary: Path
+) -> tuple[dict[str, Any], int]:
+ counts = parse_list_project_counts(args.list_project_counts)
+ auto_root = not bool(args.work_root)
+ work_root = (
+ Path(args.work_root).expanduser()
+ if args.work_root
+ else Path(tempfile.mkdtemp(prefix="cbm-list-projects-scaling-"))
+ )
+ cache_dir = work_root / "cache"
+ seed_repo = work_root / "seed-repo"
+ cache_dir.mkdir(parents=True, exist_ok=True)
+ seed_repo.mkdir(parents=True, exist_ok=True)
+ generated_at = datetime.now(timezone.utc)
+ metadata = binary_metadata(binary)
+ run_id = (
+ f"list-projects-{generated_at.strftime(FAILURE_TIMESTAMP_FORMAT)}-"
+ f"{metadata['sha256'][:12]}-{os.getpid()}"
+ )
+ report: dict[str, Any] = {
+ "schema_version": 1,
+ "run_id": run_id,
+ "generated_at_utc": generated_at.isoformat(),
+ "binary": str(binary),
+ "binary_metadata": metadata,
+ "source_revision": git_metadata(
+ Path(__file__).resolve().parents[1], args.timeout
+ ),
+ "mode": "list_projects_scaling",
+ "parameters": {
+ "project_counts": counts,
+ "maximum_fixture_mb": args.list_project_fixture_max_mb,
+ "timeout_seconds": args.timeout,
+ "process_isolation": "fresh_mcp_server_per_count",
+ "seed_index_mode": "fast",
+ "seed_config_profile": CONFIG_PROFILE_MINIMAL_INDEXING,
+ "list_projects_arguments": {"all": True},
+ "inventory_mode": "explicit_full_compatibility",
+ "token_estimator": TOKEN_ESTIMATOR,
+ "rss_measurement": "post_call_resident_kb_not_peak",
+ },
+ "work_root": str(work_root),
+ "cleanup": {
+ "requested": auto_root and not args.keep_work_root,
+ "removed": False,
+ },
+ "observations": [],
+ "completion": {"status": "running"},
+ }
+ exit_code = 1
+ try:
+ create_repo(seed_repo, 1, 1)
+ env = build_env(cache_dir, args.product_environment)
+ env.pop("CBM_PROFILE", None)
+ apply_config_overrides(
+ binary, env, CONFIG_PROFILES[CONFIG_PROFILE_MINIMAL_INDEXING], args.timeout
+ )
+ with McpClient(binary, env, args.timeout) as client:
+ seed_result, _, _, _ = client.call_tool(
+ "index_repository",
+ {**index_tool_arguments(seed_repo, "fast"), "auto_index_deps": False},
+ )
+ seed_db = find_project_db(cache_dir)
+ seed_project = str(seed_result.get("project") or seed_db.stem)
+ disk = shutil.disk_usage(work_root)
+ budget = list_project_fixture_budget(
+ seed_bytes=seed_db.stat().st_size,
+ maximum_projects=counts[-1],
+ maximum_fixture_mb=args.list_project_fixture_max_mb,
+ disk_free_bytes=disk.free,
+ )
+ report["fixture"] = {
+ "seed_project": seed_project,
+ "seed_db": str(seed_db),
+ "budget": budget,
+ }
+ if not budget["passed"]:
+ raise RuntimeError(str(budget["reason"]))
+
+ created_projects = 1
+ for requested_count in counts:
+ for fixture_index in range(created_projects, requested_count):
+ project = f"list-project-{fixture_index:06d}"
+ destination = cache_dir / f"{project}{PROJECT_DB_SUFFIX}"
+ root_path = work_root / "roots" / project
+ clone_list_project_db(seed_db, destination, project, str(root_path))
+ created_projects = requested_count
+
+ client = McpClient(binary, env, args.timeout)
+ with client:
+ data, stderr, stdout_bytes, elapsed_ms = client.call_tool(
+ "list_projects", {"all": True}
+ )
+ projects = data.get("projects")
+ returned_count = len(projects) if isinstance(projects, list) else None
+ transport_start = now_ms()
+ tools_response = client._request("tools/list", {})
+ transport_probe_ms = now_ms() - transport_start
+ transport_survived = isinstance(tools_response.get("result"), dict)
+ rss_kb = process_rss_kb(client.proc.pid) if client.proc else None
+ server_reaped = (
+ client.proc is None
+ and client.stdout_thread is None
+ and client.stderr_thread is None
+ )
+ payload = canonical_response_bytes(data)
+ db_bytes = sum(
+ path.stat().st_size
+ for path in cache_dir.glob(f"*{PROJECT_DB_SUFFIX}")
+ if path.name != CONFIG_DB_NAME
+ )
+ report["observations"].append(
+ {
+ "requested_projects": requested_count,
+ "returned_projects": returned_count,
+ "response_bytes": len(payload),
+ "response_token_estimate": estimate_response_tokens(payload),
+ "mcp_envelope_bytes": stdout_bytes,
+ "elapsed_ms": round(elapsed_ms, 3),
+ "post_call_rss_kb": rss_kb,
+ "transport_probe_ms": round(transport_probe_ms, 3),
+ "transport_survived": transport_survived,
+ "server_reaped": server_reaped,
+ "fixture_db_bytes": db_bytes,
+ "stderr_bytes": len(stderr.encode("utf-8")),
+ "passed": (
+ returned_count == requested_count
+ and transport_survived
+ and server_reaped
+ ),
+ }
+ )
+
+ observations = report["observations"]
+ first = observations[0]
+ last = observations[-1]
+ count_delta = last["requested_projects"] - first["requested_projects"]
+ byte_delta = last["response_bytes"] - first["response_bytes"]
+ report["derived"] = {
+ "passed": all(item["passed"] for item in observations),
+ "largest_response_bytes": last["response_bytes"],
+ "largest_response_token_estimate": last["response_token_estimate"],
+ "incremental_response_bytes_per_project": (
+ round(byte_delta / count_delta, 3) if count_delta > 0 else None
+ ),
+ "claim_boundary": (
+ "Measures list_projects alone in isolated caches; does not attribute combined "
+ "multi-tool response size or claim peak RSS."
+ ),
+ }
+ exit_code = 0 if report["derived"]["passed"] else 1
+ report["completion"] = {"status": "complete", "exit_code": exit_code}
+ except Exception as exc:
+ record_report_error(report, exc)
+ report["completion"] = {"status": "failed", "exit_code": 1}
+ exit_code = 1
+ finally:
+ if auto_root and not args.keep_work_root:
+ shutil.rmtree(work_root, ignore_errors=True)
+ report["cleanup"]["removed"] = not work_root.exists()
+ emit_report(report, args)
+ return report, exit_code
+
+
+def run_search_projection(
+ args: argparse.Namespace, binary: Path
+) -> tuple[dict[str, Any], int]:
+ if args.search_projection_results <= 0:
+ raise ValueError("search projection results must be positive")
+ auto_root = not bool(args.work_root)
+ work_root = (
+ Path(args.work_root).expanduser()
+ if args.work_root
+ else Path(tempfile.mkdtemp(prefix="cbm-search-projection-"))
+ )
+ cache_dir = work_root / "cache"
+ repo_dir = work_root / "repo"
+ cache_dir.mkdir(parents=True, exist_ok=True)
+ repo_dir.mkdir(parents=True, exist_ok=True)
+ generated_at = datetime.now(timezone.utc)
+ metadata = binary_metadata(binary)
+ report: dict[str, Any] = {
+ "schema_version": 1,
+ "run_id": (
+ f"search-projection-{generated_at.strftime(FAILURE_TIMESTAMP_FORMAT)}-"
+ f"{metadata['sha256'][:12]}-{os.getpid()}"
+ ),
+ "generated_at_utc": generated_at.isoformat(),
+ "binary_metadata": metadata,
+ "source_revision": git_metadata(
+ Path(__file__).resolve().parents[1], args.timeout
+ ),
+ "mode": "search_projection",
+ "parameters": {
+ "requested_results": args.search_projection_results,
+ "format": "json",
+ "index_mode": "fast",
+ "config_profile": CONFIG_PROFILE_MINIMAL_INDEXING,
+ "process_isolation": "fresh_mcp_server_per_variant",
+ "token_estimator": TOKEN_ESTIMATOR,
+ "rss_measurement": "post_call_resident_kb_not_peak",
+ },
+ "work_root": str(work_root),
+ "cleanup": {
+ "requested": auto_root and not args.keep_work_root,
+ "removed": False,
+ },
+ "observations": [],
+ "completion": {"status": "running"},
+ }
+ variants: tuple[tuple[str, dict[str, Any]], ...] = (
+ ("compact_default", {}),
+ ("compact_true", {"compact": True}),
+ (
+ "compact_selected_fields",
+ {"compact": True, "fields": ["complexity", "signature"]},
+ ),
+ ("compact_false", {"compact": False}),
+ )
+ exit_code = 1
+ try:
+ file_count = min(4, args.search_projection_results)
+ funcs_per_file = math.ceil(args.search_projection_results / file_count)
+ create_repo(repo_dir, file_count, funcs_per_file)
+ env = build_env(cache_dir, args.product_environment)
+ env.pop("CBM_PROFILE", None)
+ apply_config_overrides(
+ binary, env, CONFIG_PROFILES[CONFIG_PROFILE_MINIMAL_INDEXING], args.timeout
+ )
+ with McpClient(binary, env, args.timeout) as client:
+ index_result, _, _, _ = client.call_tool(
+ "index_repository",
+ {**index_tool_arguments(repo_dir, "fast"), "auto_index_deps": False},
+ )
+ project = str(index_result.get("project") or "")
+ if not project:
+ raise RuntimeError("projection fixture index response omitted project")
+
+ for variant, overrides in variants:
+ arguments: dict[str, Any] = {
+ "project": project,
+ "name_pattern": "Func",
+ "limit": args.search_projection_results,
+ "sort_by": "name",
+ "include_dependencies": False,
+ "format": "json",
+ **overrides,
+ }
+ client = McpClient(binary, env, args.timeout)
+ with client:
+ data, _, envelope_bytes, elapsed_ms = client.call_tool(
+ "search_graph", arguments
+ )
+ tools_response = client._request("tools/list", {})
+ transport_survived = isinstance(tools_response.get("result"), dict)
+ rss_kb = process_rss_kb(client.proc.pid) if client.proc else None
+ server_reaped = (
+ client.proc is None
+ and client.stdout_thread is None
+ and client.stderr_thread is None
+ )
+ observation = build_search_projection_observation(
+ variant, data, envelope_bytes, elapsed_ms, transport_survived
+ )
+ observation["post_call_rss_kb"] = rss_kb
+ observation["server_reaped"] = server_reaped
+ observation["passed"] = bool(observation["passed"] and server_reaped)
+ report["observations"].append(observation)
+
+ observations = report["observations"]
+ baseline_names = observations[0]["qualified_names"]
+ by_variant = {item["variant"]: item for item in observations}
+ for observation in observations:
+ observation["identity_equal_to_default"] = (
+ observation["qualified_names"] == baseline_names
+ )
+ fields = set(observation["property_fields"])
+ variant = observation["variant"]
+ if variant in {"compact_default", "compact_true"}:
+ projection_met = not fields
+ elif variant == "compact_selected_fields":
+ projection_met = bool(fields) and fields <= {"complexity", "signature"}
+ else:
+ projection_met = bool(fields)
+ observation["projection_contract_met"] = projection_met
+ observation["passed"] = bool(
+ observation["passed"]
+ and observation["identity_equal_to_default"]
+ and projection_met
+ )
+ compact_bytes = int(by_variant["compact_true"]["response_bytes"])
+ selected_bytes = int(by_variant["compact_selected_fields"]["response_bytes"])
+ verbose_bytes = int(by_variant["compact_false"]["response_bytes"])
+ report["derived"] = {
+ "passed": all(bool(item["passed"]) for item in observations),
+ "identity_parity": all(
+ bool(item["identity_equal_to_default"]) for item in observations
+ ),
+ "internal_fields_absent": all(
+ not item["internal_fields"] for item in observations
+ ),
+ "compact_bytes": compact_bytes,
+ "selected_fields_bytes": selected_bytes,
+ "non_compact_bytes": verbose_bytes,
+ "non_compact_over_compact_ratio": (
+ round(verbose_bytes / compact_bytes, 3) if compact_bytes else None
+ ),
+ "projection_order_expected": compact_bytes
+ <= selected_bytes
+ <= verbose_bytes,
+ "claim_boundary": (
+ "Measures response projection for identical ranked results after one small FAST "
+ "index; one latency observation per variant is descriptive only."
+ ),
+ }
+ report["derived"]["passed"] = bool(
+ report["derived"]["passed"]
+ and report["derived"]["projection_order_expected"]
+ )
+ exit_code = 0 if report["derived"]["passed"] else 1
+ report["completion"] = {"status": "complete", "exit_code": exit_code}
+ except Exception as exc:
+ record_report_error(report, exc)
+ report["completion"] = {"status": "failed", "exit_code": 1}
+ exit_code = 1
+ finally:
+ if auto_root and not args.keep_work_root:
+ shutil.rmtree(work_root, ignore_errors=True)
+ report["cleanup"]["removed"] = not work_root.exists()
+ emit_report(report, args)
+ return report, exit_code
+
+
+def log_tail(stderr: str) -> list[str]:
+ lines = stderr.splitlines()
+ return lines[-LOG_TAIL_LINES:]
+
+
+def log_has(stderr: str, marker: str) -> bool:
+ return marker in stderr
+
+
+def response_publish_kind(data: dict[str, Any]) -> str:
+ publish_kind = data.get("publish_kind")
+ return publish_kind if isinstance(publish_kind, str) else ""
+
+
+def response_publish_reason(data: dict[str, Any]) -> str:
+ publish_reason = data.get("publish_reason")
+ return publish_reason if isinstance(publish_reason, str) else ""
+
+
+def response_freshness(data: dict[str, Any]) -> dict[str, Any] | None:
+ freshness = data.get("freshness")
+ return freshness if isinstance(freshness, dict) else None
+
+
+def response_freshness_state(data: dict[str, Any]) -> str:
+ freshness = response_freshness(data)
+ if not freshness:
+ return ""
+ state = freshness.get("state")
+ return state if isinstance(state, str) else ""
+
+
+def declared_stale_views(oracles: dict[str, Any]) -> list[str]:
+ """Return the sorted union of derived views explicitly reported stale."""
+ views: set[str] = set()
+ for oracle in oracles.values():
+ if not isinstance(oracle, dict):
+ continue
+ freshness = oracle.get("freshness")
+ if (
+ not isinstance(freshness, dict)
+ or freshness.get("state") != "stale_with_warning"
+ ):
+ continue
+ stale = freshness.get("stale_views")
+ if isinstance(stale, list):
+ views.update(item for item in stale if isinstance(item, str) and item)
+ return sorted(views)
+
+
+# One ranked list per scorer, read straight from a retained project database. Our three
+# scores live in dedicated tables (src/store/store.c:591-615); PR #879's importance is a
+# JSON key inside nodes.properties instead, so it needs json_extract and yields zero rows
+# on a binary without that pass. "degree" is the maintainer's own one-line alternative
+# from PR #151 ("ORDER BY degree DESC ... gives you the same ranking signal") and is the
+# REQUIRED baseline arm, not an afterthought.
+# The dispute is about callable symbols. PR #151 names log.Error() and fmt.Sprintf();
+# PR #879's pass scores Function, Method and Class (pass_importance.c:172-215). Without
+# this scope the top ranks are File and Module nodes — the first full campaign ranked
+# go.mod, .github/workflows/build.yaml, Makefile and src/server.h above every function,
+# so the top-K rates read 0.000 on the two corpora chosen for having hub
+# utilities. A node with no file_path is outside the repository (builtins.str reached
+# redis's PageRank top 10) and cannot be scaffolding, a utility, or architecture.
+# A node outside the repository cannot be scaffolding, a utility, or architecture, so it
+# must not occupy a rank. Two spellings mean "not a file": an empty path, and an
+# angle-bracket sentinel such as "" (internal/cbm/lsp/py_builtins.c:84)
+# or "" (src/mcp/mcp.c:13880). Excluding only the empty spelling let
+# builtins.str, builtins.list and builtins.list.append take ranks 1, 3 and 5 of redis's
+# PageRank top 10 — in a C repository.
+RANK_PROBE_SCOPE = (
+ "n.label IN ('Function','Method','Class') "
+ "AND n.file_path <> '' AND n.file_path NOT LIKE '<%'"
+)
+
+# Every callable symbol's in/out degree, for structural_leaf_hubs. Same scope as the
+# score probes so "is this a utility" and "is this ranked" describe the same population.
+LEAF_HUB_DEGREE_SQL = (
+ "SELECT n.qualified_name, d.total_in, d.total_out "
+ "FROM nodes n JOIN node_degree d ON d.node_id = n.id "
+ "WHERE n.project = ? AND " + RANK_PROBE_SCOPE
+)
+# A utility is defined by the shape PR #151 named — "they have the highest fan-in" —
+# not by its name. Both cuts are relative to the corpus so the definition transfers
+# across languages and repository sizes without a vocabulary.
+LEAF_HUB_FAN_IN_QUANTILE = 0.99
+LEAF_HUB_MAX_FAN_OUT_RATIO = 0.1
+LEAF_HUB_MIN_POPULATION = 20
+
+
+def python_public_exports(repo: Path) -> frozenset[str]:
+ """Names a Python project re-exports from its package __init__.py files.
+
+ Large Python libraries define in a private module and re-export publicly:
+ scikit-learn, pandas and numpy all do it. Without this, the underscore rule calls
+ sklearn.linear_model._logistic.LogisticRegression private when it is the library's
+ public API, and the corpus reports a non-public rate near 1.
+
+ Reads `__all__` entries and `from .module import Name` aliases, which are the two
+ forms that make a name part of the package surface. Parsed with ast rather than
+ regex so a string containing "__all__" cannot be mistaken for a declaration.
+
+ Never raises: an unparseable source file is skipped, and a missing tree yields the
+ empty set, because a label source is not worth failing a run over.
+ """
+ root = Path(repo)
+ if not root.is_dir():
+ return frozenset()
+ exported: set[str] = set()
+ for init in root.rglob("__init__.py"):
+ if any(
+ part in {".git", "node_modules", "vendor", "build"} for part in init.parts
+ ):
+ continue
+ try:
+ tree = ast.parse(init.read_text(encoding="utf-8", errors="replace"))
+ except (SyntaxError, ValueError, OSError):
+ continue
+ package = init.parent.name
+ for node in ast.walk(tree):
+ if isinstance(node, ast.ImportFrom):
+ # Relative (`from ._m import X`) and absolute self-imports
+ # (`from sklearn._config import X` inside sklearn/__init__.py) are both
+ # re-exports. scikit-learn uses the absolute form, so requiring a
+ # relative import missed its entire public surface.
+ own = node.level > 0 or (node.module or "").split(".")[0] == package
+ if own:
+ exported.update(
+ alias.asname or alias.name
+ for alias in node.names
+ if alias.name != "*" and not alias.name.startswith("_")
+ )
+ elif isinstance(node, (ast.Assign, ast.AugAssign)):
+ targets = (
+ node.targets if isinstance(node, ast.Assign) else [node.target]
+ )
+ if not any(
+ isinstance(target, ast.Name) and target.id == "__all__"
+ for target in targets
+ ):
+ continue
+ # __all__ is often built by concatenation — scikit-learn writes
+ # `__all__ = [...] + [...]` — so every string constant in the assigned
+ # expression counts, not just a bare list literal.
+ exported.update(
+ element.value
+ for element in ast.walk(node.value)
+ if isinstance(element, ast.Constant)
+ and isinstance(element.value, str)
+ )
+ return frozenset(exported)
+
+
+def is_public_api(
+ qualified_name: str,
+ file_path: str,
+ python_exports: frozenset[str] = frozenset(),
+) -> bool | None:
+ """Whether a symbol is part of its project's declared public surface.
+
+ This is the label H1/H5 need. PR #151's claim is that the highest-fan-in symbols are
+ utilities rather than architecture, so testing it requires a notion of "utility" that
+ does not itself use fan-in — otherwise the metric assumes its own conclusion, which is
+ what made leaf_hub_rate unusable for the purpose.
+
+ Publicity is decided by the language's own rule, not by a heuristic:
+
+ Go exported iff the identifier begins with an upper-case letter. This is the
+ language specification, not a convention: the compiler enforces it.
+ Python a leading underscore on any component of the dotted path marks that
+ component private (PEP 8, and what `from x import *` honours). Dunders are
+ language protocol rather than private surface.
+
+ Everything else returns None. C publicity needs header parsing, Rust needs `pub`,
+ and TypeScript needs `export`; none is a name-level rule, and guessing would put the
+ metric back where the marker list was. None means "not measurable here", and the
+ caller reports null rather than folding it in as a zero.
+ """
+ if not file_path or not qualified_name:
+ return None
+ suffix = file_path.rsplit(".", 1)[-1].lower() if "." in file_path else ""
+ identifier = qualified_name.rsplit(".", 1)[-1]
+ if not identifier:
+ return None
+ if suffix == "go":
+ return identifier[:1].isupper()
+ if suffix == "py":
+ parts = qualified_name.split(".")
+ # A re-exported name is public wherever it is defined, which is the convention
+ # large Python libraries use; the underscore rule alone misreads it. Any
+ # component may carry the export — for a method it is the class that is exported
+ # — but an underscore-prefixed terminal identifier is private regardless.
+ if not identifier.startswith("_") and any(
+ part in python_exports for part in parts
+ ):
+ return True
+ for part in parts:
+ if part.startswith("_") and not (
+ part.startswith("__") and part.endswith("__")
+ ):
+ return False
+ return True
+ return None
+
+
+def non_public_rate(
+ rows: list[tuple[Any, ...]], python_exports: frozenset[str] = frozenset()
+) -> float | None:
+ """Fraction of a ranked window outside the project's declared public surface.
+
+ None when the window's language has no name-level publicity rule, so a corpus the
+ label cannot speak to reports null instead of contributing a zero.
+ """
+ verdicts = [is_public_api(str(row[0]), str(row[1]), python_exports) for row in rows]
+ known = [verdict for verdict in verdicts if verdict is not None]
+ if not known:
+ return None
+ return sum(1 for verdict in known if not verdict) / len(known)
+
+
+def structural_leaf_hubs(nodes: list[dict[str, Any]]) -> frozenset[str]:
+ """Symbols with very high fan-in and near-zero fan-out. A shape, not a category.
+
+ NAMED CAREFULLY. This was called `structural_utilities` and its output was reported
+ as `utility_contamination`, which read as adjudicating PR #151's claim that the
+ highest-fan-in symbols are utilities. It cannot do that, for two reasons found by
+ running it on real corpora:
+
+ 1. Circular. It selects fan-in above the corpus's own quantile, while the `degree`
+ and `in_degree` scorers rank BY fan-in, so the top K of a fan-in ranking sits
+ above the quantile almost by construction and the rate approaches 1.0 regardless
+ of what those symbols are.
+ 2. It does not identify utilities. On scikit-learn it selected
+ `sklearn.base.BaseEstimator`, the library's central abstraction; on redis it
+ selected hiredis's `redisCommand` and `redisReply`. Those are architecture, which
+ is the opposite of the intended meaning.
+
+ The underlying problem admits no calibration: PR #151's claim IS "high fan-in means
+ utilities", so no fan-in-derived definition can test it without assuming it. What
+ would work is a category label independent of degree — the project's own declared
+ public surface — which is not built yet.
+
+ So this stays as an honest descriptive statistic about graph shape, and the campaign
+ reports H1/H5 as not measurable rather than deciding them from it.
+
+ Replaces a hand-written marker list (`log`, `fmt`, `printf`, `malloc`, ...). That
+ list was the weakest instrument in the campaign for a specific reason: the campaign's
+ own thesis is that hardcoded, non-general string criteria fail at scale, so deciding
+ its headline metric with one was self-refuting. It also only ever fired on a single
+ corpus, because the vocabulary happened to match C.
+
+ This is what PR #151 actually claimed, stated structurally: *"PageRank on a call
+ graph would rank log.Error() and fmt.Sprintf() as the most important functions in
+ any codebase, because they have the highest fan-in."* A symbol that many things call
+ and that calls almost nothing itself is a leaf utility whatever it is named, in
+ whatever language.
+
+ Both thresholds are relative to the corpus's own distribution, so the definition does
+ not need retuning per repository: fan-in above the 99th percentile, and fan-out no
+ more than a tenth of that symbol's fan-in. A graph with no hub yields the empty set
+ rather than an arbitrary top slice.
+
+ Time and memory are O(n) plus one O(n log n) sort of the fan-in values.
+ """
+ degrees = [
+ (str(node["qualified_name"]), int(node["total_in"]), int(node["total_out"]))
+ for node in nodes
+ if isinstance(node.get("total_in"), int)
+ and isinstance(node.get("total_out"), int)
+ ]
+ if len(degrees) < LEAF_HUB_MIN_POPULATION:
+ # Too few symbols for a quantile to mean anything. Reporting nothing is honest;
+ # picking a fixed threshold here would reintroduce the arbitrariness this
+ # function exists to remove.
+ return frozenset()
+ fan_in = sorted(value for _, value, _ in degrees)
+ # Clamped to leave at least the top element above the cut. Without the clamp the
+ # quantile index lands on the maximum in any population under ~100, so the one
+ # symbol the metric exists to find is the one excluded by the strict comparison.
+ index = max(0, min(len(fan_in) - 2, int(LEAF_HUB_FAN_IN_QUANTILE * len(fan_in))))
+ cut = fan_in[index]
+ if cut <= 0:
+ return frozenset()
+ return frozenset(
+ name
+ for name, incoming, outgoing in degrees
+ # Strictly above the cut: a flat graph where every symbol sits at the quantile
+ # has no hubs, and calling them all utilities would invert the metric.
+ if incoming > cut and outgoing <= LEAF_HUB_MAX_FAN_OUT_RATIO * incoming
+ )
+
+
+RANK_PROBE_CANONICAL_SQL = rank_evidence.build_rank_probe_sql(RANK_PROBE_SCOPE)
+# Public compatibility mapping: historical callers can still inspect ``degree``,
+# ``in_degree``, ``weighted_in``, and ``importance``. The probe executes only the
+# canonical SQL and materializes aliases afterward, avoiding duplicate database scans.
+RANK_PROBE_SQL: dict[str, str] = {
+ **RANK_PROBE_CANONICAL_SQL,
+ **{
+ alias: RANK_PROBE_CANONICAL_SQL[target]
+ for alias, target in rank_evidence.SCORER_ALIASES.items()
+ },
+}
+
+RANK_EDGE_TYPE_COUNTS_SQL = (
+ "SELECT type, COUNT(*) FROM edges WHERE project = ? GROUP BY type ORDER BY type"
+)
+RANK_EDGE_LINKRANK_SQL = (
+ "SELECT source.qualified_name, target.qualified_name, e.type, lr.rank, "
+ "source.file_path, target.file_path "
+ "FROM linkrank lr JOIN edges e ON e.id = lr.edge_id "
+ "JOIN nodes source ON source.id = e.source_id "
+ "JOIN nodes target ON target.id = e.target_id "
+ "WHERE e.project = ? ORDER BY lr.rank DESC, e.id LIMIT ?"
+)
+
+# Logging, formatting and allocation helpers carry the highest raw fan-in in most
+# codebases. PR #151: "PageRank on a call graph would rank log.Error() and fmt.Sprintf()
+# as the most important functions in any codebase ... that's not architectural
+# importance - it's just utility popularity." Measuring that claim needs a fixed,
+# declared list rather than a judgement call at reporting time.
+# How many ranked rows each scorer keeps in the report as a readable head sample. This
+# is presentation only; the metrics are computed over the cutoffs, not this depth.
+TOP_RANKED_SAMPLE = 10
+
+# RBO is a descriptive sensitivity metric, not a pass/fail rule. Publishing its depth
+# persistence beside every comparison keeps the top-weighting assumption auditable:
+# 0.9 assigns about 86% of finite weight to the first 20 ranks while retaining tail
+# disagreement. Callers can override it when performing a declared sensitivity analysis.
+RANK_BIASED_OVERLAP_PERSISTENCE = 0.9
+
+# Matched as whole identifier tokens (see is_utility_symbol), never as substrings.
+# Deliberately excludes "trace", "debug", "warn" and "free": they collide with ordinary
+# production identifiers such as this project's own trace_path, and a marker that fires
+# on the corpus under test would inflate exactly the number the campaign reports.
+UTILITY_SYMBOL_TOKENS: frozenset[str] = frozenset(
+ {
+ "log",
+ "logf",
+ "logger",
+ "printf",
+ "sprintf",
+ "fprintf",
+ "println",
+ "puts",
+ "malloc",
+ "calloc",
+ "realloc",
+ "zmalloc",
+ "zfree",
+ "zrealloc",
+ "xmalloc",
+ "memcpy",
+ "memmove",
+ "memset",
+ "strlen",
+ "strcmp",
+ "strcpy",
+ "strdup",
+ "assert",
+ "errorf",
+ "wrapf",
+ "panic",
+ "fatal",
+ "abort",
+ }
+)
+
+
+def spearman_rho(left: list[float], right: list[float]) -> float | None:
+ """Spearman rank correlation, or None when it is undefined for these inputs.
+
+ statistics.correlation(method="ranked") is Spearman and handles tied ranks; it
+ raises StatisticsError for the two undefined cases (fewer than two points, or a
+ constant input), which callers here want as None rather than an exception.
+ """
+ if len(left) != len(right):
+ return None
+ try:
+ return statistics.correlation(left, right, method="ranked")
+ except statistics.StatisticsError:
+ return None
+
+
+def rank_biased_overlap(
+ left: list[str],
+ right: list[str],
+ *,
+ persistence: float = RANK_BIASED_OVERLAP_PERSISTENCE,
+) -> float | None:
+ """Finite extrapolated RBO for two top-weighted rankings.
+
+ Unlike Spearman over the intersection, RBO penalizes a symbol missing from either
+ top-K page. ``persistence`` is the probability of continuing to the next rank; 0.9
+ gives 86% of the finite weight to the first 20 positions. Runtime and memory are
+ O(K), where K is the longer bounded result page.
+ """
+ if not left or not right or not 0.0 < persistence < 1.0:
+ return None
+ depth = max(len(left), len(right))
+ left_seen: set[str] = set()
+ right_seen: set[str] = set()
+ weighted_agreement = 0.0
+ agreement = 0.0
+ for index in range(depth):
+ if index < len(left):
+ left_seen.add(left[index])
+ if index < len(right):
+ right_seen.add(right[index])
+ agreement = len(left_seen & right_seen) / (index + 1)
+ weighted_agreement += agreement * persistence**index
+ # The residual term extrapolates the agreement at the observed depth instead of
+ # silently treating every unobserved tail item as a disagreement.
+ return (1.0 - persistence) * weighted_agreement + agreement * persistence**depth
+
+
+# Derived views published by cbm_pagerank_compute (src/pagerank/pagerank.c). When any of
+# these is stale, search_graph silently degrades: sort_by "linkrank"/"calls" fall back to
+# (in_deg + out_deg) at src/store/store.c:11695-11711 with nothing in the response saying
+# so. A ranking measurement taken through that fallback is not a measurement of the score
+# it claims to test, so every rank oracle records this alongside its result.
+RANK_DERIVED_VIEWS = ("pagerank", "linkrank", "node_degree")
+
+
+def rank_score_staleness(
+ cache_dir: Path, project: str, oracles: dict[str, Any] | None = None
+) -> dict[str, Any]:
+ """Record whether the persisted ranking views were stale when oracles ran.
+
+ Takes the union of what the tool responses declared and what the freshness ledger
+ persisted, the same combination the incremental path already uses, because the two
+ can disagree: a response can report stale_with_warning after derived_view_state has
+ been re-marked fresh, and a view can be marked stale in the ledger without any
+ response having said so.
+ """
+ try:
+ db_path = find_project_db(cache_dir)
+ except (RuntimeError, OSError) as exc:
+ return {"available": False, "reason": str(exc)}
+ try:
+ persisted = persisted_stale_views(db_path, project)
+ except sqlite3.Error as exc:
+ return {"available": False, "reason": f"{type(exc).__name__}: {exc}"}
+ declared = declared_stale_views(oracles) if oracles else []
+ stale = sorted(set(declared) | set(persisted))
+ stale_rank_views = [view for view in RANK_DERIVED_VIEWS if view in stale]
+ return {
+ "available": True,
+ "stale_views": stale,
+ "declared_stale_views": sorted(declared),
+ "persisted_stale_views": sorted(persisted),
+ "stale_rank_views": stale_rank_views,
+ # True means the ranking numbers in this case are trustworthy as a measurement
+ # of the requested score rather than of the degree fallback.
+ "rank_views_fresh": not stale_rank_views,
+ }
+
+
+def is_utility_symbol(qualified_name: str | None) -> bool:
+ """Match utility markers on identifier-token boundaries, not bare substrings.
+
+ Bare `in` matching inflates the metric on the very corpora under test: "trace"
+ matches this project's own `trace_path`, "free" matches `freeze`, "debug" matches
+ ordinary identifiers. Splitting the qualified name into tokens on non-alphanumeric
+ boundaries and on camelCase humps keeps `zmalloc`, `serverLog` and `fmt.Sprintf`
+ matching while leaving `trace_path` alone.
+ """
+ if not qualified_name:
+ return False
+ tokens = {
+ token.lower()
+ for token in re.findall(
+ r"[A-Z]+(?![a-z])|[A-Z][a-z]+|[a-z]+|[0-9]+", qualified_name
+ )
+ if token
+ }
+ return bool(tokens & UTILITY_SYMBOL_TOKENS)
+
+
+DEFAULT_LABELS_DIR = Path(__file__).resolve().with_name("labels")
+# One row per indexed file. Grouping in SQL keeps the transfer proportional to the file
+# count rather than the node count, which is one to two orders of magnitude larger.
+COVERAGE_PROBE_SQL = (
+ "SELECT file_path, COUNT(*) FROM nodes "
+ "WHERE project = ? AND file_path IS NOT NULL AND file_path <> '' "
+ "GROUP BY file_path"
+)
+
+
+def load_module_beside(name: str) -> Any:
+ """Import a sibling benchmarks/ module by path, reusing an already-loaded copy.
+
+ Same importlib pattern autotune.py uses for run_experiments.py helpers. Registering
+ in sys.modules keeps one instance, so a caller that also loads the module directly
+ sees the same objects rather than a second copy with equal-but-not-identical state.
+ """
+ cached = sys.modules.get(name)
+ if cached is not None:
+ return cached
+ path = Path(__file__).resolve().with_name(f"{name}.py")
+ spec = importlib.util.spec_from_file_location(name, path)
+ if spec is None or spec.loader is None:
+ raise RuntimeError(f"cannot load {name} from {path}")
+ module = importlib.util.module_from_spec(spec)
+ sys.modules[name] = module
+ spec.loader.exec_module(module)
+ return module
+
+
+def scaffolding_paths_from_document(document: dict[str, Any]) -> frozenset[str] | None:
+ """Test-file paths from a label document, or None when it classified nothing.
+
+ None rather than an empty set when no source could classify anything, because the
+ two mean different things: "no independent source could speak" must report null,
+ while an empty set would claim the corpus contains no test files. A project the
+ runner did classify and found no tests in is a real zero, so the cases are separated
+ by whether anything was classified rather than by the test count.
+ """
+ counts = document.get("counts") or {}
+ if not counts.get("test") and not counts.get("not_test"):
+ return None
+ return frozenset(
+ row["file_path"]
+ for row in document.get("labels", [])
+ if row.get("is_test") is True
+ )
+
+
+def derive_scaffolding_paths(
+ corpus_id: str, source_repo: Path | None, timeout: int
+) -> frozenset[str] | None:
+ """Label a corpus's test files by reading the corpus, not a checked-in file.
+
+ Labels are data derived from a corpus, so storing them in this repository would add
+ generated JSON that can drift from the tree actually indexed. Deriving them from the
+ staged checkout at run time keeps one implementation and makes that drift impossible.
+
+ Runs against the source checkout rather than the materialized copy: the copy is
+ produced by `git archive` and has no `.git`, and the derivation reads the project's
+ tracked file list. Never raises — a run that already produced oracles must not abort
+ because a label source was unreadable; it reports null instead.
+ """
+ if source_repo is None or not Path(source_repo).is_dir():
+ return None
+ try:
+ labeller = load_module_beside("generate_test_labels")
+ document = labeller.build_labels(corpus_id, Path(source_repo))
+ except Exception: # noqa: BLE001 - a label source is never worth failing a run over
+ return None
+ return scaffolding_paths_from_document(document)
+
+
+def load_scaffolding_paths(corpus_id: str, labels_dir: str) -> frozenset[str] | None:
+ """Tier-A test-file labels for a corpus, or None when none were generated.
+
+ The labels come from the project's own test declaration or its language toolchain's
+ rule (benchmarks/generate_test_labels.py), never from one of this server's seven
+ test predicates — those are the thing under measurement, so deriving the label from
+ them would make scaffolding@K a test of the classifier against itself.
+
+ None rather than an empty set when no label file exists, because the two mean
+ different things: "no independent labels were supplied" must report null, while an
+ empty set would claim the corpus has no tests.
+ """
+ if not corpus_id:
+ return None
+ root = Path(labels_dir).expanduser() if labels_dir else DEFAULT_LABELS_DIR
+ path = root / f"{corpus_id}.json"
+ if not path.is_file():
+ return None
+ document = json.loads(path.read_text(encoding="utf-8"))
+ counts = document.get("counts") or {}
+ # A file whose sources classified nothing is not a measurement. redis is C and jest
+ # declares its test configuration in JavaScript, so both label files are entirely
+ # "unknown"; returning an empty set would claim those corpora contain no test files
+ # and print scaffolding@K as a clean 0.000. A corpus the runner did classify and
+ # found no tests in is a real zero, so the two cases are distinguished by whether
+ # anything was classified at all rather than by the test count alone.
+ if not counts.get("test") and not counts.get("not_test"):
+ return None
+ return frozenset(
+ row["file_path"]
+ for row in document.get("labels", [])
+ if row.get("is_test") is True
+ )
+
+
+RANK_FINGERPRINT_SQL = (
+ "SELECT n.qualified_name, p.rank FROM nodes n JOIN pagerank p ON p.node_id = n.id "
+ "WHERE n.project = ? ORDER BY n.qualified_name"
+)
+
+
+def rank_table_fingerprint(cache_dir: Path, project: str) -> str | None:
+ """Content hash of the published pagerank table, or None when there is no database.
+
+ The knob-efficacy canary compares this between two cells that differ only by one
+ edge-weight config value. Equal fingerprints mean the knob changed nothing, which is
+ the failure cbm_config_value_is_valid (src/cli/cli.c:7160-7173) makes silent: it
+ returns true for keys absent from CBM_CONFIG_REGISTRY, so a typo'd or removed knob
+ is persisted, exits 0, and yields a clean run reporting a difference of exactly
+ zero — indistinguishable from "tuning does not help".
+
+ Ordered by qualified_name rather than by rank so the hash tracks the scores rather
+ than a tie-ordering that SQLite is free to vary between runs.
+ """
+ try:
+ db_path = find_project_db(cache_dir)
+ except (RuntimeError, OSError):
+ return None
+ try:
+ rows = query_tuples(db_path, RANK_FINGERPRINT_SQL, (project,))
+ except sqlite3.Error:
+ return None
+ digest = hashlib.sha256()
+ for qualified_name, rank in rows:
+ # repr() of the float, so a difference below display precision still registers.
+ digest.update(f"{qualified_name}\t{rank!r}\n".encode("utf-8"))
+ return digest.hexdigest()
+
+
+def run_corpus_coverage_probe(
+ cache_dir: Path,
+ project: str,
+ *,
+ predicted_loss: dict[str, Any] | None = None,
+ index_mode: str = "",
+) -> dict[str, Any]:
+ """Which files reached the graph, attributed to their top-level directory.
+
+ The silent-exclusion issues (#1406 scripts/, #1219 assets/, #1184 deploy/, #411
+ whole subtrees) all make the same claim: a directory is absent from the index and
+ nothing says so. A file count alone cannot support or refute that; a per-directory
+ count states exactly which name disappeared.
+
+ Read from the graph rather than from an index log line, so the number is what a
+ query can actually reach rather than what the indexer reported attempting.
+
+ index_mode is a matrix-spec field (run_experiments.py:1301), so one run observes one
+ mode. The across-mode diff is therefore a cross-runset operation and lives in the
+ campaign rollup, not here.
+
+ Time and memory are O(indexed files) after SQLite's grouped scan; the node table is
+ read once through the same read-only path as the score probes.
+ """
+ try:
+ db_path = find_project_db(cache_dir)
+ except (RuntimeError, OSError) as exc:
+ return {"available": False, "reason": str(exc)}
+ started = time.monotonic()
+ try:
+ rows = query_tuples(db_path, COVERAGE_PROBE_SQL, (project,))
+ except sqlite3.Error as exc:
+ return {"available": False, "reason": f"{type(exc).__name__}: {exc}"}
+ directories: dict[str, int] = {}
+ extensions: dict[str, int] = {}
+ node_total = 0
+ for file_path, node_count in rows:
+ text = str(file_path)
+ # "" is the root, kept as its own bucket: attributing a root-level file to some
+ # directory would invent coverage that the graph does not have.
+ head = text.split("/", 1)[0] if "/" in text else ""
+ directories[head] = directories.get(head, 0) + 1
+ # A directory count cannot distinguish "this directory was skipped" from "these
+ # file types were skipped inside it". The first campaign lost files from
+ # directories on no published skip list, so the second mechanism has to be
+ # separable from the first.
+ name = text.rsplit("/", 1)[-1]
+ suffix = f".{name.rsplit('.', 1)[-1]}" if "." in name.lstrip(".") else ""
+ extensions[suffix] = extensions.get(suffix, 0) + 1
+ node_total += int(node_count)
+ result: dict[str, Any] = {
+ "available": True,
+ "elapsed_ms": (time.monotonic() - started) * 1000.0,
+ "indexed_file_count": len(rows),
+ "indexed_node_count": node_total,
+ "top_level_directories": dict(sorted(directories.items())),
+ "extensions": dict(sorted(extensions.items())),
+ }
+ if predicted_loss is not None:
+ # corpora-v1.json registers these before any indexing happens. Scoring the
+ # prediction here is what keeps it a prediction rather than a decoration.
+ #
+ # Which prediction applies depends on the mode: ALWAYS_SKIP_DIRS fires in every
+ # mode, while FAST_SKIP_DIRS is gated on mode != CBM_MODE_FULL
+ # (src/discover/discover.c:448-452). Scoring the fast list against a full run
+ # would report every correctly-indexed docs/ directory as a failed prediction.
+ present = set(directories)
+ checks = {
+ field: [str(name) for name in predicted_loss.get(field) or []]
+ for field in ("always_skipped_top_dirs", "fast_skipped_top_dirs")
+ }
+ applicable = set(checks["always_skipped_top_dirs"])
+ if index_mode and index_mode != "full":
+ applicable |= set(checks["fast_skipped_top_dirs"])
+ predicted_all = sorted(applicable)
+ result["predicted_loss_check"] = {
+ **checks,
+ "index_mode": index_mode,
+ "applicable_predictions": predicted_all,
+ "absent_as_predicted": [n for n in predicted_all if n not in present],
+ "present_despite_prediction": [n for n in predicted_all if n in present],
+ }
+ return result
+
+
+def run_rank_score_probes(
+ cache_dir: Path,
+ project: str,
+ *,
+ top_n: int = 40,
+ cutoffs: tuple[int, ...] = (10, 40),
+ scaffolding_paths: frozenset[str] | None = None,
+ python_exports: frozenset[str] = frozenset(),
+) -> dict[str, Any]:
+ """Rank every persisted score over the same graph and compare them directly.
+
+ This is the head-to-head that the tool-level oracles cannot provide: search_graph
+ routes through BM25 and the hardcoded label boosts at src/mcp/mcp.c:7402-7419, so a
+ tool result mixes candidate generation with ordering. Reading the score columns
+ isolates the ordering, which is the thing under dispute.
+
+ scaffolding_paths carries Tier-A labels (a language test runner's own verdict). When
+ absent, scaffolding@K is reported as null rather than being filled in from one of the
+ seven string predicates under test, which would make the metric circular.
+ """
+ if top_n <= 0 or not cutoffs or any(cutoff <= 0 for cutoff in cutoffs):
+ raise ValueError("rank probe top_n and every cutoff must be positive")
+ try:
+ db_path = find_project_db(cache_dir)
+ except (RuntimeError, OSError) as exc:
+ return {"available": False, "reason": str(exc)}
+
+ # Derived once per corpus from the graph itself, then applied to every scorer's
+ # window. Computing it per scorer would let a scorer's own ranking influence what
+ # counts as a utility, which is the circularity scaffolding@K already avoids.
+ try:
+ leaf_hub_names = structural_leaf_hubs(
+ [
+ {"qualified_name": row[0], "total_in": row[1], "total_out": row[2]}
+ for row in query_tuples(db_path, LEAF_HUB_DEGREE_SQL, (project,))
+ ]
+ )
+ except sqlite3.Error:
+ leaf_hub_names = frozenset()
+
+ scorers: dict[str, Any] = {}
+ ranked_by_scorer: dict[str, list[tuple[Any, ...]]] = {}
+ for name, sql in RANK_PROBE_CANONICAL_SQL.items():
+ started = time.monotonic()
+ try:
+ rows = query_tuples(db_path, sql, (project, top_n))
+ except sqlite3.Error as exc:
+ scorers[name] = {
+ "applicable": False,
+ "reason": f"{type(exc).__name__}: {exc}",
+ }
+ continue
+ # Named elapsed_ms exactly so fact_step_rows publishes each probe as a timing
+ # fact keyed by the scorer name; a bespoke key would make them invisible there.
+ elapsed_ms = (time.monotonic() - started) * 1000.0
+ if not rows:
+ # Expected for "importance" on a binary without PR #879's pass.
+ scorers[name] = {
+ "applicable": False,
+ "reason": "no rows; score not present in this database",
+ "elapsed_ms": elapsed_ms,
+ }
+ continue
+ ranked_by_scorer[name] = rows
+ entry: dict[str, Any] = {
+ "applicable": True,
+ "ranked_count": len(rows),
+ "elapsed_ms": elapsed_ms,
+ # Named for what it is (a head sample) rather than a fixed depth, so the
+ # key does not become a lie when cutoffs change.
+ "top_ranked_depth": TOP_RANKED_SAMPLE,
+ "top_ranked": [
+ {"qualified_name": row[0], "file_path": row[1], "score": row[2]}
+ for row in rows[:TOP_RANKED_SAMPLE]
+ ],
+ }
+ # Keyed by cutoff rather than baked into the key name, so a consumer can
+ # iterate cutoffs without reconstructing field names it has to guess.
+ by_cutoff: dict[str, Any] = {}
+ for cutoff in cutoffs:
+ window = rows[:cutoff]
+ if not window:
+ continue
+ # Structural is the reportable definition: it is what PR #151 actually
+ # claimed ("highest fan-in") and it needs no vocabulary. The lexical count
+ # is retained beside it, not replaced, so the two can be compared and a
+ # disagreement is visible rather than silently resolved in one's favour.
+ leaf_hubs = sum(1 for row in window if row[0] in leaf_hub_names)
+ lexical = sum(1 for row in window if is_utility_symbol(row[0]))
+ scaffolding = (
+ None
+ if scaffolding_paths is None
+ else sum(1 for row in window if row[1] in scaffolding_paths)
+ / len(window)
+ )
+ by_cutoff[str(cutoff)] = {
+ "window_size": len(window),
+ "leaf_hub_rate": leaf_hubs / len(window),
+ "lexical_marker_rate": lexical / len(window),
+ # The fan-in-independent replacement in the H1/H5 role. Null where the
+ # language has no name-level publicity rule.
+ "non_public_rate": non_public_rate(window, python_exports),
+ "scaffolding": scaffolding,
+ }
+ entry["by_cutoff"] = by_cutoff
+ scorers[name] = entry
+
+ # Aliases are output compatibility, not extra experiments. Reusing the canonical
+ # rows keeps this expansion O(A) dictionaries and avoids A additional O(N log K)
+ # SQLite rankings for A historical names.
+ for alias, canonical in rank_evidence.SCORER_ALIASES.items():
+ canonical_entry = scorers.get(canonical)
+ if canonical_entry is None:
+ continue
+ scorers[alias] = {**canonical_entry, "alias_of": canonical}
+ if canonical in ranked_by_scorer:
+ ranked_by_scorer[alias] = ranked_by_scorer[canonical]
+
+ try:
+ edge_type_counts = {
+ str(row[0]): int(row[1])
+ for row in query_tuples(db_path, RANK_EDGE_TYPE_COUNTS_SQL, (project,))
+ }
+ except sqlite3.Error:
+ edge_type_counts = {}
+
+ edge_started = time.monotonic()
+ try:
+ edge_rows = query_tuples(db_path, RANK_EDGE_LINKRANK_SQL, (project, top_n))
+ except sqlite3.Error as exc:
+ edge_linkrank: dict[str, Any] = {
+ "applicable": False,
+ "reason": f"{type(exc).__name__}: {exc}",
+ }
+ else:
+ edge_elapsed_ms = (time.monotonic() - edge_started) * 1000.0
+ edge_linkrank = {
+ "applicable": bool(edge_rows),
+ "reason": None if edge_rows else "no persisted LinkRank edge rows",
+ "ranked_count": len(edge_rows),
+ "elapsed_ms": edge_elapsed_ms,
+ "top_ranked": [
+ {
+ "source": row[0],
+ "target": row[1],
+ "edge_type": row[2],
+ "score": row[3],
+ "source_file": row[4],
+ "target_file": row[5],
+ }
+ for row in edge_rows[:TOP_RANKED_SAMPLE]
+ ],
+ "interpretation": (
+ "This instruments H6 with ranked source-edge-target tuples; it is not an "
+ "H6 verdict until a judged edge/path task compares them with a node-only arm."
+ ),
+ }
+
+ # H2/H4: is degree "the same ranking signal" as PageRank, as PR #151 asserts?
+ comparisons: dict[str, Any] = {}
+ baseline = rank_evidence.DEGREE_BASELINE
+ comparison_k = min(cutoffs)
+ if baseline in ranked_by_scorer:
+ base_rows = ranked_by_scorer[baseline]
+ base_scores = {row[0]: row[2] for row in base_rows}
+ base_order = [str(row[0]) for row in base_rows[:comparison_k]]
+ base_top = set(base_order)
+ for name in RANK_PROBE_CANONICAL_SQL:
+ if name == baseline or name not in ranked_by_scorer:
+ continue
+ rows = ranked_by_scorer[name]
+ shared = [row for row in rows if row[0] in base_scores]
+ rho = spearman_rho(
+ [float(row[2]) for row in shared],
+ [float(base_scores[row[0]]) for row in shared],
+ )
+ other_order = [str(row[0]) for row in rows[:comparison_k]]
+ other_top = set(other_order)
+ union = base_top | other_top
+ comparison = {
+ # Kept for old reports. It is explicitly over the shared bounded rows;
+ # RBO and Jaccard below account for missing symbols.
+ "spearman_rho": rho,
+ "shared_spearman_rho": rho,
+ "shared_symbols": len(shared),
+ "top_k": comparison_k,
+ "top_k_jaccard": (
+ len(base_top & other_top) / len(union) if union else None
+ ),
+ "rank_biased_overlap": rank_biased_overlap(base_order, other_order),
+ "rank_biased_overlap_persistence": RANK_BIASED_OVERLAP_PERSISTENCE,
+ "interpretation": (
+ "high rank_biased_overlap and top_k_jaccard support interchangeable "
+ "top pages; shared_spearman_rho alone does not penalize missing rows"
+ ),
+ }
+ comparisons[f"{name}_vs_{baseline}"] = comparison
+ # Historical result readers key comparisons by ``*_vs_degree``.
+ comparisons[f"{name}_vs_degree"] = comparison
+
+ return {
+ "available": True,
+ "top_n": top_n,
+ "cutoffs": list(cutoffs),
+ "scaffolding_labels_present": scaffolding_paths is not None,
+ "structural_leaf_hub_count": len(leaf_hub_names),
+ "structural_leaf_hub_sample": sorted(leaf_hub_names)[:10],
+ "utility_token_count": len(UTILITY_SYMBOL_TOKENS),
+ "scorer_registry": rank_evidence.public_hypothesis_registry()["scorers"],
+ "scorer_aliases": dict(rank_evidence.SCORER_ALIASES),
+ "scorers": scorers,
+ "comparisons": comparisons,
+ "edge_type_counts": edge_type_counts,
+ "edge_linkrank": edge_linkrank,
+ "complexity": {
+ "node_score_queries": "O(S * N log K) time, O(S * K) retained rows",
+ "edge_linkrank_query": "O(E log K) time, O(K) retained rows",
+ "symbols": {
+ "S": "canonical scorers",
+ "N": "ranked nodes",
+ "E": "edges",
+ "K": "top_n",
+ },
+ },
+ }
+
+
+def persisted_stale_views(db_path: Path, project: str) -> list[str]:
+ """Read global derived-view state from the canonical SQLite freshness ledger."""
+ uri = f"{db_path.resolve().as_uri()}?mode=ro"
+ try:
+ with closing(sqlite3.connect(uri, uri=True)) as con:
+ rows = con.execute(
+ "SELECT view_name FROM derived_view_state "
+ "WHERE project = ? AND status = 'stale' ORDER BY view_name",
+ (project,),
+ )
+ return [str(row[0]) for row in rows if row[0]]
+ except sqlite3.OperationalError as exc:
+ if "no such table" in str(exc):
+ return []
+ raise
+
+
+def is_incremental_publish_kind(publish_kind: str) -> bool:
+ return publish_kind in {
+ PUBLISH_INCREMENTAL_NOOP,
+ PUBLISH_INCREMENTAL_EXACT,
+ PUBLISH_INCREMENTAL_OVERLAY,
+ PUBLISH_INCREMENTAL_CONTAINMENT,
+ }
+
+
+def is_explicit_incremental_route(
+ publish_kind: str | None, reason: str | None = None
+) -> bool:
+ return is_incremental_publish_kind(publish_kind or "") or bool(reason)
+
+
+def parse_logged_elapsed_ms(stderr: str, marker: str) -> int | None:
+ return parse_log_int_field(stderr, marker, "elapsed_ms")
+
+
+def parse_log_int_field(stderr: str, marker: str, field: str) -> int | None:
+ prefix = f"{field}="
+ for line in stderr.splitlines():
+ if marker not in line:
+ continue
+ for item in line.split():
+ if item.startswith(prefix):
+ try:
+ return int(item.split("=", 1)[1])
+ except ValueError:
+ return None
+ return None
+
+
+def parse_log_max_int_field(stderr: str, marker: str, field: str) -> int | None:
+ prefix = f"{field}="
+ maximum: int | None = None
+ for line in stderr.splitlines():
+ if marker not in line:
+ continue
+ for item in line.split():
+ if not item.startswith(prefix):
+ continue
+ try:
+ value = int(item.split("=", 1)[1])
+ except ValueError:
+ continue
+ maximum = value if maximum is None else max(maximum, value)
+ return maximum
+
+
+def parse_log_text_field(stderr: str, marker: str, field: str) -> str | None:
+ prefix = f"{field}="
+ for line in reversed(stderr.splitlines()):
+ if marker not in line:
+ continue
+ for item in line.split():
+ if item.startswith(prefix):
+ return item[len(prefix) :]
+ return None
+
+
+def daemon_log_window(env: dict[str, str]) -> tuple[Path | None, int]:
+ cache_dir = env.get("CBM_CACHE_DIR")
+ path = Path(cache_dir) / DAEMON_LOG_RELATIVE_PATH if cache_dir else None
+ offset = path.stat().st_size if path and path.is_file() else 0
+ return path, offset
+
+
+def read_log_window(path: Path | None, offset: int) -> str:
+ if not path or not path.is_file():
+ return ""
+ try:
+ current_size = path.stat().st_size
+ with path.open("rb") as stream:
+ stream.seek(offset if current_size >= offset else 0)
+ return stream.read().decode("utf-8", errors="replace")
+ except OSError:
+ return ""
+
+
+def update_int_summary(summary: dict[str, int], value: int) -> None:
+ if not summary:
+ summary.update(first=value, last=value, min=value, max=value)
+ return
+ summary["last"] = value
+ summary["min"] = min(summary["min"], value)
+ summary["max"] = max(summary["max"], value)
+
+
+def summarize_daemon_mem_census_since(
+ path: Path | None, offset: int
+) -> dict[str, Any] | None:
+ """Summarize B new log bytes in O(B) time and O(L + F) memory.
+
+ L is the longest log line and F is the fixed field count. Retained memory is
+ independent of the number of request samples, unlike storing every census.
+ """
+ if not path or not path.is_file():
+ return None
+ fields = ("rss_kb", "mi_area_kb", "mi_live_kb")
+ summaries: dict[str, dict[str, int]] = {field: {} for field in fields}
+ count = 0
+ try:
+ current_size = path.stat().st_size
+ with path.open("rb") as stream:
+ stream.seek(offset if current_size >= offset else 0)
+ for raw_line in stream:
+ line = raw_line.decode("utf-8", errors="replace")
+ if "msg=mem.census" not in line or "at=mcp.request" not in line:
+ continue
+ parsed = {
+ field: parse_log_int_field(line, "msg=mem.census", field)
+ for field in fields
+ }
+ if any(value is None for value in parsed.values()):
+ continue
+ for field, value in parsed.items():
+ update_int_summary(summaries[field], int(value))
+ count += 1
+ except OSError:
+ return None
+ if count == 0:
+ return None
+ for summary in summaries.values():
+ summary["delta"] = summary["last"] - summary["first"]
+ return {
+ "count": count,
+ **summaries,
+ }
+
+
+def summarize_daemon_profiles_since(
+ path: Path | None,
+ offset: int,
+ selected_profiles: tuple[tuple[str, str], ...],
+) -> dict[str, dict[str, int | float]] | None:
+ """Summarize selected profile spans in O(B + R) time and O(L + P) memory.
+
+ B is the number of new log bytes, R the matching records, L the longest log
+ line, and P the caller-bounded profile key count. Aggregating count/sum/range
+ avoids retaining every request duration while preserving exact arithmetic
+ means and extrema for server-versus-transport attribution.
+ """
+ if not path or not path.is_file() or not selected_profiles:
+ return None
+ selected = set(selected_profiles)
+ summaries: dict[tuple[str, str], dict[str, int]] = {}
+ try:
+ current_size = path.stat().st_size
+ with path.open("rb") as stream:
+ stream.seek(offset if current_size >= offset else 0)
+ for raw_line in stream:
+ line = raw_line.decode("utf-8", errors="replace")
+ if "msg=prof" not in line:
+ continue
+ phase = parse_log_text_field(line, "msg=prof", "phase")
+ subphase = parse_log_text_field(line, "msg=prof", "sub")
+ profile = (phase, subphase)
+ if profile not in selected:
+ continue
+ elapsed_us = parse_log_int_field(line, "msg=prof", "us")
+ if elapsed_us is None or elapsed_us < 0:
+ continue
+ summary = summaries.setdefault(profile, {})
+ if not summary:
+ summary.update(
+ count=1,
+ total_us=elapsed_us,
+ min_us=elapsed_us,
+ max_us=elapsed_us,
+ )
+ else:
+ summary["count"] += 1
+ summary["total_us"] += elapsed_us
+ summary["min_us"] = min(summary["min_us"], elapsed_us)
+ summary["max_us"] = max(summary["max_us"], elapsed_us)
+ except OSError:
+ return None
+ if not summaries:
+ return None
+ return {
+ f"{phase}/{subphase}": {
+ **profile_summary,
+ "mean_us": profile_summary["total_us"] / profile_summary["count"],
+ }
+ for phase, subphase in selected_profiles
+ if (profile_summary := summaries.get((phase, subphase))) is not None
+ }
+
+
+def parse_exact_reason(stderr: str) -> str | None:
+ detail = parse_exact_route_detail(stderr)
+ reason = detail.get("reason")
+ return reason if isinstance(reason, str) and reason else None
+
+
+def parse_exact_route_detail(stderr: str) -> dict[str, Any]:
+ detail: dict[str, Any] = {
+ "frontier_changed_files": parse_log_int_field(
+ stderr, LOG_MARKER_EXACT_FRONTIER, "changed"
+ ),
+ "frontier_expanded_files": parse_log_int_field(
+ stderr, LOG_MARKER_EXACT_FRONTIER, "expanded"
+ ),
+ "exact_done_files": parse_log_int_field(stderr, LOG_MARKER_EXACT_DONE, "files"),
+ "event": None,
+ "reason": None,
+ }
+ reason_markers = (
+ (LOG_MARKER_EXACT_FALLBACK, "fallback"),
+ (LOG_MARKER_EXACT_DELETE_FALLBACK, "delete_fallback"),
+ (LOG_MARKER_EXACT_SKIP, "skip"),
+ )
+ for line in stderr.splitlines():
+ for marker, event in reason_markers:
+ prefix = f"msg={marker} reason="
+ if prefix not in line:
+ continue
+ reason = line.split(prefix, 1)[1].split()[0]
+ detail["event"] = event
+ detail["reason"] = reason or None
+ return detail
+ if detail["exact_done_files"] is not None:
+ detail["event"] = "exact"
+ elif detail["frontier_expanded_files"] is not None:
+ detail["event"] = "frontier_observed"
+ return detail
+
+
+def response_exact_delta(data: dict[str, Any]) -> dict[str, Any]:
+ exact_delta = data.get("exact_delta")
+ return exact_delta if isinstance(exact_delta, dict) else {}
+
+
+def merge_exact_route_detail(
+ detail: dict[str, Any],
+ data: dict[str, Any],
+ publish_kind: str,
+ publish_reason: str,
+) -> dict[str, Any]:
+ exact_delta = response_exact_delta(data)
+ field_map = {
+ "changed_paths": "frontier_changed_files",
+ "affected_paths": "frontier_expanded_files",
+ "published_paths": "exact_done_files",
+ }
+ for response_key, detail_key in field_map.items():
+ value = exact_delta.get(response_key)
+ if detail.get(detail_key) is None and isinstance(value, int):
+ detail[detail_key] = value
+ if not detail.get("reason") and publish_reason:
+ detail["reason"] = publish_reason
+ if not detail.get("event"):
+ published = detail.get("exact_done_files")
+ if isinstance(published, int) and published > 0:
+ detail["event"] = "exact"
+ elif isinstance(published, int) and published == 0:
+ detail["event"] = "noop"
+ elif publish_reason:
+ detail["event"] = "fallback"
+ elif publish_kind == PUBLISH_INCREMENTAL_EXACT:
+ detail["event"] = "exact"
+ elif publish_kind == PUBLISH_INCREMENTAL_OVERLAY:
+ detail["event"] = "overlay"
+ elif publish_kind == PUBLISH_INCREMENTAL_NOOP:
+ detail["event"] = "noop"
+ return detail
+
+
+def indexed_work_elapsed_ms(logged_elapsed_ms: dict[str, int | None]) -> int | None:
+ incremental_ms = logged_elapsed_ms.get("incremental_done")
+ if incremental_ms is not None:
+ return incremental_ms
+ return logged_elapsed_ms.get("pipeline_done")
+
+
+def candidate_binary_identity(binary: Path) -> tuple[str, int, int]:
+ resolved = binary.resolve()
+ metadata = resolved.stat()
+ return str(resolved), metadata.st_mtime_ns, metadata.st_size
+
+
+def config_spelling_mode(binary: Path, env: dict[str, str], timeout: int) -> str:
+ identity = candidate_binary_identity(binary)
+ with CONFIG_SPELLING_MODES_LOCK:
+ cached = CONFIG_SPELLING_MODES.get(identity)
+ if cached is not None:
+ return cached
+
+ with tempfile.TemporaryDirectory(
+ prefix="cbm-config-spelling-probe-"
+ ) as cache_dir:
+ probe_env = dict(env)
+ probe_env["CBM_CACHE_DIR"] = cache_dir
+ canonical_cmd = [
+ str(binary),
+ "config",
+ "set",
+ RANK_REFRESH_DEFAULT_SPELLINGS["canonical"]["key"],
+ RANK_REFRESH_DEFAULT_SPELLINGS["canonical"]["value"],
+ ]
+ canonical, canonical_elapsed_ms = command_result(
+ canonical_cmd, probe_env, timeout
+ )
+ if canonical.returncode == 0:
+ CONFIG_SPELLING_MODES[identity] = CONFIG_SPELLING_CANONICAL
+ return CONFIG_SPELLING_CANONICAL
+
+ pre_rename_cmd = [
+ str(binary),
+ "config",
+ "set",
+ RANK_REFRESH_DEFAULT_SPELLINGS["historical"]["key"],
+ RANK_REFRESH_DEFAULT_SPELLINGS["historical"]["value"],
+ ]
+ pre_rename, pre_rename_elapsed_ms = command_result(
+ pre_rename_cmd, probe_env, timeout
+ )
+ if pre_rename.returncode == 0:
+ CONFIG_SPELLING_MODES[identity] = CONFIG_SPELLING_PRE_RENAME
+ return CONFIG_SPELLING_PRE_RENAME
+ raise command_failure(
+ "config_spelling_probe",
+ pre_rename_cmd,
+ probe_env,
+ pre_rename,
+ pre_rename_elapsed_ms,
+ ) from command_failure(
+ "config_spelling_probe_canonical",
+ canonical_cmd,
+ probe_env,
+ canonical,
+ canonical_elapsed_ms,
+ )
+
+
+def run_config_set(
+ binary: Path, env: dict[str, str], key: str, value: str, timeout: int
+) -> None:
+ canonical = (key, value)
+ if (
+ canonical in PRE_RENAME_CONFIG_SPELLINGS
+ and config_spelling_mode(binary, env, timeout) == CONFIG_SPELLING_PRE_RENAME
+ ):
+ key, value = PRE_RENAME_CONFIG_SPELLINGS[canonical]
+ cmd = [str(binary), "config", "set", key, value]
+ proc, elapsed_ms = command_result(cmd, env, timeout)
+ if proc.returncode != 0:
+ raise command_failure(f"config_set_{key}", cmd, env, proc, elapsed_ms)
+
+
+def parse_key_value_arguments(items: list[str], option: str) -> dict[str, str]:
+ values: dict[str, str] = {}
+ for item in items:
+ key, sep, value = item.partition("=")
+ if not sep or not key or not value:
+ raise SystemExit(f"error: {option} must be key=value, got {item!r}")
+ values[key] = value
+ return values
+
+
+def parse_config_overrides(items: list[str]) -> dict[str, str]:
+ return parse_key_value_arguments(items, "--config")
+
+
+def validate_product_environment(
+ values: dict[str, str],
+) -> dict[str, str]:
+ for key in values:
+ if not key.startswith(PRODUCT_ENVIRONMENT_PREFIX):
+ raise SystemExit(
+ "error: --product-env key must start with "
+ f"{PRODUCT_ENVIRONMENT_PREFIX}, got {key!r}"
+ )
+ if key in HARNESS_OWNED_PRODUCT_ENV:
+ raise SystemExit(
+ f"error: --product-env {key} is owned by the benchmark harness"
+ )
+ return dict(values)
+
+
+def parse_product_environment(items: list[str]) -> dict[str, str]:
+ return validate_product_environment(
+ parse_key_value_arguments(items, "--product-env")
+ )
+
+
+def resolve_config_overrides(profile: str, items: list[str]) -> dict[str, str]:
+ """Return one explicit benchmark profile plus higher-priority per-key overrides."""
+ if profile not in CONFIG_PROFILES:
+ raise ValueError(f"unknown config profile: {profile}")
+ overrides = dict(CONFIG_PROFILES[profile])
+ overrides.update(parse_config_overrides(items))
+ validate_config_overrides(overrides)
+ return overrides
+
+
+def index_tool_arguments(repo_dir: Path, index_mode: str) -> dict[str, str]:
+ if index_mode not in INDEX_MODES:
+ raise ValueError(f"unsupported index mode: {index_mode}")
+ return {"repo_path": str(repo_dir), "mode": index_mode}
+
+
+def index_mode_capability_applicability(index_mode: str) -> dict[str, dict[str, Any]]:
+ if index_mode not in INDEX_MODES:
+ raise ValueError(f"unsupported index mode: {index_mode}")
+ available = {"applicable": True, "reason": f"available in {index_mode} mode"}
+ result = {
+ name: dict(available)
+ for name in (
+ "rank",
+ "similarity",
+ "semantic_edges",
+ "git_history",
+ "http_links",
+ "dependencies",
+ )
+ }
+ if index_mode == "fast":
+ result["similarity"] = {
+ "applicable": False,
+ "reason": "SIMILAR_TO generation requires full or moderate mode",
+ }
+ result["semantic_edges"] = {
+ "applicable": False,
+ "reason": "SEMANTICALLY_RELATED generation requires full or moderate mode",
+ }
+ return result
+
+
+def validate_config_overrides(overrides: dict[str, str]) -> None:
+ """Reject config keys the product would silently swallow.
+
+ cbm_config_value_is_valid (src/cli/cli.c) ends with
+
+ return true; /* preserve extension/private keys not owned by this registry */
+
+ so `config set ` is persisted, exits 0, and is recorded in the
+ cell's parameters.config_overrides as though it took effect. The experiment
+ then reports a difference of exactly zero, which reads identically to "this
+ knob does not matter". Failing here keeps an inert override from ever being
+ published as a measured condition.
+ """
+ unknown = sorted(set(overrides) - KNOWN_CONFIG_KEYS)
+ if unknown:
+ raise ValueError(
+ "unknown config key(s) "
+ + ", ".join(repr(key) for key in unknown)
+ + f"; not listed in {CONFIG_KEYS_PATH.name}. Fix the spelling, or regenerate "
+ "the allowlist with benchmarks/generate_config_keys.py if the product's "
+ "config surface changed."
+ )
+
+
+def apply_config_overrides(
+ binary: Path, env: dict[str, str], overrides: dict[str, str], timeout: int
+) -> None:
+ # Keys are validated once at parse time in resolve_config_overrides, before any
+ # measurement starts. Validating here instead would raise deep inside the measured
+ # run, where the enclosing except-Exception handlers would have to cope with it.
+ for key, value in overrides.items():
+ run_config_set(binary, env, key, value, timeout)
+
+
+def apply_rank_refresh_override(
+ binary: Path, env: dict[str, str], policy: str, timeout: int
+) -> bool:
+ """Apply an explicit rank policy while preserving each candidate's default."""
+ if policy == RANK_REFRESH_CANDIDATE_DEFAULT:
+ return False
+ run_config_set(binary, env, "rank_refresh", policy, timeout)
+ return True
+
+
+def build_index_result(
+ data: dict[str, Any],
+ stderr: str,
+ stdout_bytes: int,
+ elapsed_ms: float,
+ include_logs: bool,
+ measurement_diagnostics: str = "",
+) -> dict[str, Any]:
+ measurement_log_markers: list[str] = []
+ measurement_log_artifacts: list[dict[str, Any]] = []
+ logfiles: list[str] = []
+ supervisor_diagnostics = f"{stderr}\n{measurement_diagnostics}"
+ supervisor_log = parse_log_text_field(
+ supervisor_diagnostics, "index.supervisor.profile_log", "log"
+ )
+ if supervisor_log:
+ logfiles.append(supervisor_log)
+ response_log = data.get("logfile")
+ if isinstance(response_log, str) and response_log and response_log not in logfiles:
+ logfiles.append(response_log)
+ for logfile in logfiles:
+ log_path = Path(logfile)
+ artifact_dir_value = os.environ.get(BENCHMARK_ARTIFACT_DIR_ENV)
+ if artifact_dir_value and log_path.is_file():
+ measurement_log_artifacts.append(
+ archive_measurement_log(log_path, Path(artifact_dir_value))
+ )
+ try:
+ with log_path.open(encoding="utf-8", errors="replace") as stream:
+ for line in stream:
+ if any(
+ marker in line
+ for marker in (
+ "msg=mem.phase",
+ "msg=pipeline.done",
+ "msg=incremental.done",
+ LOG_MARKER_DEP_AUTO_INDEX,
+ LOG_MARKER_RANK_REFRESH,
+ LOG_MARKER_INDEX_WORKER_TOTAL,
+ )
+ ):
+ measurement_log_markers.append(line.rstrip("\n"))
+ if len(measurement_log_markers) >= 512:
+ break
+ except OSError:
+ continue
+ if measurement_log_markers:
+ break
+ measurement_text = "\n".join(
+ (stderr, measurement_diagnostics, *measurement_log_markers)
+ )
+ elapsed_ms_int = int(elapsed_ms)
+ publish_kind = response_publish_kind(data)
+ logged_elapsed_ms = {
+ "pipeline_done": parse_logged_elapsed_ms(
+ measurement_text, LOG_MARKER_PIPELINE_DONE
+ ),
+ "incremental_done": parse_logged_elapsed_ms(
+ measurement_text, LOG_MARKER_INCREMENTAL_DONE
+ ),
+ }
+ indexed_ms = indexed_work_elapsed_ms(logged_elapsed_ms)
+ publish_reason = response_publish_reason(data)
+ exact_route_detail = merge_exact_route_detail(
+ parse_exact_route_detail(stderr), data, publish_kind, publish_reason
+ )
+ freshness = response_freshness(data)
+ freshness_state = response_freshness_state(data)
+ peak_candidates = [
+ parse_log_max_int_field(measurement_text, marker, "peak_mb")
+ for marker in (
+ "mem.phase",
+ LOG_MARKER_PIPELINE_DONE,
+ LOG_MARKER_INCREMENTAL_DONE,
+ )
+ ]
+ peak_rss_mb = max(
+ (value for value in peak_candidates if value is not None), default=None
+ )
+ dependency_phase_ms = parse_log_int_field(
+ measurement_text, LOG_MARKER_DEP_AUTO_INDEX, "ms"
+ )
+ rank_refresh_ms = parse_log_int_field(
+ measurement_text, LOG_MARKER_RANK_REFRESH, "ms"
+ )
+ worker_elapsed_ms = parse_log_int_field(
+ measurement_text, LOG_MARKER_INDEX_WORKER_TOTAL, "ms"
+ )
+ known_elapsed_ms = worker_elapsed_ms
+ if known_elapsed_ms is None:
+ known_components = [
+ value
+ for value in (indexed_ms, dependency_phase_ms, rank_refresh_ms)
+ if value is not None
+ ]
+ known_elapsed_ms = sum(known_components) if known_components else None
+ process_overhead_ms = (
+ max(0, elapsed_ms_int - known_elapsed_ms)
+ if known_elapsed_ms is not None
+ else None
+ )
+ dependencies_indexed = data.get("dependencies_indexed")
+ dependency_packages = (
+ dependencies_indexed
+ if isinstance(dependencies_indexed, int) and dependencies_indexed >= 0
+ else None
+ )
+ result: dict[str, Any] = {
+ "elapsed_ms": elapsed_ms_int,
+ "peak_rss_mb": peak_rss_mb,
+ "measurement_log_markers": measurement_log_markers,
+ "measurement_log_artifacts": measurement_log_artifacts,
+ "indexed_work_elapsed_ms": indexed_ms,
+ "worker_elapsed_ms": worker_elapsed_ms,
+ "process_overhead_ms": process_overhead_ms,
+ # Backwards-compatible field: now excludes every measured worker phase,
+ # not just the main pipeline. Prefer process_overhead_ms in new reports.
+ "unlogged_overhead_ms": process_overhead_ms,
+ "timing_components_ms": {
+ "main_index": indexed_ms,
+ "dependency_index": dependency_phase_ms,
+ "rank_refresh": rank_refresh_ms,
+ "worker_total": worker_elapsed_ms,
+ "cold_process_and_supervisor": process_overhead_ms,
+ },
+ "response": data,
+ "publish_kind": publish_kind or None,
+ "freshness_state": freshness_state or None,
+ "freshness": freshness,
+ "stdout_bytes": stdout_bytes,
+ "dependency_indexing": {
+ "measurement_status": (
+ "measured"
+ if dependency_phase_ms is not None or dependency_packages is not None
+ else "unknown"
+ ),
+ "phase_elapsed_ms": dependency_phase_ms,
+ "packages_indexed": dependency_packages,
+ },
+ "markers": {
+ "incremental_exact_done": log_has(stderr, LOG_MARKER_EXACT_DONE)
+ or publish_kind == PUBLISH_INCREMENTAL_EXACT,
+ "incremental_done": log_has(stderr, LOG_MARKER_INCREMENTAL_DONE)
+ or is_incremental_publish_kind(publish_kind),
+ "pagerank_done": log_has(stderr, "pagerank.done"),
+ "pagerank_defer": log_has(stderr, "pagerank.defer"),
+ "full_route": log_has(stderr, "pipeline.route path=full")
+ or publish_kind == PUBLISH_FULL,
+ "incremental_route": log_has(stderr, "pipeline.route path=incremental")
+ or is_incremental_publish_kind(publish_kind),
+ },
+ "logged_elapsed_ms": logged_elapsed_ms,
+ "exact_reason": publish_reason or exact_route_detail.get("reason"),
+ "exact_route_detail": exact_route_detail,
+ "stderr_tail": log_tail(stderr),
+ }
+ if include_logs:
+ result["stderr"] = stderr
+ return result
+
+
+def run_index(
+ binary: Path,
+ env: dict[str, str],
+ repo_dir: Path,
+ timeout: int,
+ include_logs: bool,
+ index_mode: str = "fast",
+) -> dict[str, Any]:
+ args = json.dumps(index_tool_arguments(repo_dir, index_mode))
+ cmd = [str(binary), "cli", "--json", "index_repository", args]
+ proc, elapsed_ms = command_result(
+ cmd,
+ env,
+ timeout,
+ )
+ if proc.returncode != 0:
+ raise command_failure("index_repository", cmd, env, proc, elapsed_ms)
+ data = unwrap_cli_json(proc.stdout)
+ return build_index_result(
+ data, proc.stderr, len(proc.stdout.encode("utf-8")), elapsed_ms, include_logs
+ )
+
+
+def run_index_mcp(
+ client: McpClient,
+ repo_dir: Path,
+ include_logs: bool,
+ index_mode: str = "fast",
+) -> dict[str, Any]:
+ daemon_log, daemon_log_offset = daemon_log_window(client.env)
+ text, stderr, stdout_bytes, elapsed_ms = client.call_tool_text(
+ "index_repository", index_tool_arguments(repo_dir, index_mode)
+ )
+ daemon_diagnostics = read_log_window(daemon_log, daemon_log_offset)
+ try:
+ data = json.loads(text)
+ except json.JSONDecodeError as exc:
+ diagnostics = f"{stderr}\n{daemon_diagnostics}\n{text}"
+ worker_log = failure_worker_log_path(diagnostics)
+ measurement_log_artifacts: list[dict[str, Any]] = []
+ archive_error = ""
+ artifact_dir_value = os.environ.get(BENCHMARK_ARTIFACT_DIR_ENV)
+ if worker_log and artifact_dir_value and worker_log.is_file():
+ try:
+ # Streaming archive is O(L) time and O(1) working memory for an
+ # L-byte worker log. It runs only on the already-failing path,
+ # before the case finally-block removes its isolated cache.
+ measurement_log_artifacts.append(
+ archive_measurement_log(worker_log, Path(artifact_dir_value))
+ )
+ except OSError as archive_exc:
+ archive_error = f"{type(archive_exc).__name__}: {archive_exc}"
+ detail: dict[str, Any] = {
+ "label": "index_repository",
+ "elapsed_ms": round(elapsed_ms, 3),
+ "stdout_bytes": stdout_bytes,
+ "response_text_bytes": len(text.encode("utf-8")),
+ "response_text_tail": text_tail(text),
+ "stderr_tail": text_tail(stderr),
+ "daemon_log_tail": text_tail(daemon_diagnostics),
+ "worker_log_path": str(worker_log) if worker_log else "",
+ "measurement_log_artifacts": measurement_log_artifacts,
+ }
+ if archive_error:
+ detail["measurement_log_archive_error"] = archive_error
+ raise BenchmarkCommandError(
+ f"MCP tool index_repository returned non-JSON text; "
+ f"worker_log_archived={bool(measurement_log_artifacts)}",
+ detail,
+ ) from exc
+ return build_index_result(
+ data,
+ stderr,
+ stdout_bytes,
+ elapsed_ms,
+ include_logs,
+ measurement_diagnostics=daemon_diagnostics,
+ )
+
+
+def failure_worker_log_path(diagnostics: str) -> Path | None:
+ """Return the last worker-log path named by a failed supervisor response.
+
+ Diagnostic scanning is O(D) time and O(1) auxiliary state for D bytes. The
+ human-readable inspect-log form is line-delimited, so paths containing
+ spaces remain intact; structured log output retains its established
+ whitespace-delimited representation.
+ """
+ for line in reversed(diagnostics.splitlines()):
+ marker = "inspect log:"
+ if marker in line:
+ value = line.partition(marker)[2].strip().strip("'\"")
+ if value:
+ return Path(value)
+ if "index.supervisor." in line:
+ value = parse_log_text_field(line, "index.supervisor.", "log")
+ if value:
+ return Path(value)
+ return None
+
+
+def build_tool_probe_result(
+ data: dict[str, Any],
+ stderr: str,
+ stdout_bytes: int,
+ elapsed_ms: float,
+ include_logs: bool,
+) -> dict[str, Any]:
+ elapsed_ms_value = round(elapsed_ms, 3)
+ result: dict[str, Any] = {
+ "elapsed_ms": elapsed_ms_value,
+ "stdout_bytes": stdout_bytes,
+ "response_keys": sorted(str(key) for key in data),
+ "stderr_tail": log_tail(stderr),
+ }
+ if include_logs:
+ result["stderr"] = stderr
+ return result
+
+
+def run_cli_tool_probe(
+ binary: Path,
+ env: dict[str, str],
+ tool_name: str,
+ timeout: int,
+ include_logs: bool,
+ arguments: dict[str, Any] | None = None,
+) -> dict[str, Any]:
+ encoded = json.dumps(arguments or {}, separators=(",", ":"))
+ cmd = [str(binary), "cli", "--json", tool_name, encoded]
+ proc, elapsed_ms = command_result(cmd, env, timeout)
+ if proc.returncode != 0:
+ raise command_failure(f"{tool_name}_probe", cmd, env, proc, elapsed_ms)
+ data = unwrap_cli_json(proc.stdout)
+ return build_tool_probe_result(
+ data, proc.stderr, len(proc.stdout.encode("utf-8")), elapsed_ms, include_logs
+ )
+
+
+def run_mcp_tool_probe(
+ client: McpClient,
+ tool_name: str,
+ include_logs: bool,
+ arguments: dict[str, Any] | None = None,
+) -> dict[str, Any]:
+ data, stderr, stdout_bytes, elapsed_ms = client.call_tool(
+ tool_name, arguments or {}
+ )
+ return build_tool_probe_result(data, stderr, stdout_bytes, elapsed_ms, include_logs)
+
+
+def build_tool_call_result(
+ data: dict[str, Any],
+ stderr: str,
+ stdout_bytes: int,
+ elapsed_ms: float,
+ include_logs: bool,
+ response_payload: bytes | None = None,
+) -> dict[str, Any]:
+ quality_payload = canonical_response_bytes(data)
+ payload = response_payload if response_payload is not None else quality_payload
+ result: dict[str, Any] = {
+ "elapsed_ms": round(elapsed_ms, 3),
+ # Preserve the historical field while separating transport framing from
+ # the canonical payload used for cross-transport comparisons.
+ "stdout_bytes": stdout_bytes,
+ "transport_response_bytes": stdout_bytes,
+ "response_bytes": len(payload),
+ "response_token_estimate": estimate_response_tokens(payload),
+ "token_estimator": TOKEN_ESTIMATOR,
+ "response_encoding": "tool_default"
+ if response_payload is not None
+ else "canonical_json",
+ "quality_response_bytes": len(quality_payload),
+ "response": data,
+ "freshness_state": response_freshness_state(data) or None,
+ "freshness": response_freshness(data),
+ "stderr_tail": log_tail(stderr),
+ }
+ if include_logs:
+ result["stderr"] = stderr
+ return result
+
+
+def run_cli_tool_call(
+ binary: Path,
+ env: dict[str, str],
+ tool_name: str,
+ arguments: dict[str, Any],
+ timeout: int,
+ include_logs: bool,
+) -> dict[str, Any]:
+ encoded = json.dumps(arguments, separators=(",", ":"))
+ cmd = [str(binary), "cli", "--json", tool_name, encoded]
+ proc, elapsed_ms = command_result(cmd, env, timeout)
+ if proc.returncode != 0:
+ raise command_failure(f"{tool_name}_call", cmd, env, proc, elapsed_ms)
+ raw_payload = cli_result_text(proc.stdout).encode("utf-8")
+ quality_arguments = dict(arguments)
+ quality_arguments["format"] = "json"
+ quality_cmd = [
+ str(binary),
+ "cli",
+ "--json",
+ tool_name,
+ json.dumps(quality_arguments, separators=(",", ":")),
+ ]
+ quality_elapsed: list[float] = []
+ quality_hashes: list[str] = []
+ data: dict[str, Any] = {}
+ for _ in range(REPEATED_JSON_TRIALS):
+ quality_proc, quality_elapsed_ms = command_result(quality_cmd, env, timeout)
+ if quality_proc.returncode != 0:
+ raise command_failure(
+ f"{tool_name}_quality_call",
+ quality_cmd,
+ env,
+ quality_proc,
+ quality_elapsed_ms,
+ )
+ data = unwrap_cli_json(quality_proc.stdout)
+ quality_elapsed.append(round(quality_elapsed_ms, 3))
+ quality_hashes.append(
+ hashlib.sha256(canonical_response_bytes(data)).hexdigest()
+ )
+ result = build_tool_call_result(
+ data,
+ proc.stderr,
+ len(proc.stdout.encode("utf-8")),
+ elapsed_ms,
+ include_logs,
+ raw_payload,
+ )
+ add_repeated_json_measurements(result, quality_elapsed, quality_hashes)
+ return result
+
+
+def run_mcp_tool_call(
+ client: McpClient,
+ tool_name: str,
+ arguments: dict[str, Any],
+ include_logs: bool,
+) -> dict[str, Any]:
+ raw_text, stderr, stdout_bytes, elapsed_ms = client.call_tool_text(
+ tool_name, arguments
+ )
+ quality_arguments = dict(arguments)
+ quality_arguments["format"] = "json"
+ quality_elapsed: list[float] = []
+ quality_hashes: list[str] = []
+ data: dict[str, Any] = {}
+ for _ in range(REPEATED_JSON_TRIALS):
+ data, _, _, quality_elapsed_ms = client.call_tool(tool_name, quality_arguments)
+ quality_elapsed.append(round(quality_elapsed_ms, 3))
+ quality_hashes.append(
+ hashlib.sha256(canonical_response_bytes(data)).hexdigest()
+ )
+ result = build_tool_call_result(
+ data, stderr, stdout_bytes, elapsed_ms, include_logs, raw_text.encode("utf-8")
+ )
+ add_repeated_json_measurements(result, quality_elapsed, quality_hashes)
+ return result
+
+
+def add_repeated_json_measurements(
+ result: dict[str, Any], elapsed_ms: list[float], response_hashes: list[str]
+) -> None:
+ ordered = sorted(elapsed_ms)
+ result["quality_probe_elapsed_ms"] = elapsed_ms[0] if elapsed_ms else None
+ result["repeated_json_trials_ms"] = elapsed_ms
+ result["repeated_json_latency_ms"] = {
+ "count": len(ordered),
+ "min": ordered[0] if ordered else None,
+ "median": ordered[len(ordered) // 2] if ordered else None,
+ "max": ordered[-1] if ordered else None,
+ }
+ result["repeated_json_response_sha256"] = response_hashes
+ result["repeated_json_payloads_byte_equal"] = len(set(response_hashes)) <= 1
+
+
+def run_tool_call_for_transport(
+ transport: str,
+ binary: Path,
+ env: dict[str, str],
+ tool_name: str,
+ arguments: dict[str, Any],
+ timeout: int,
+ include_logs: bool,
+ client: McpClient | None = None,
+) -> dict[str, Any]:
+ if transport == "mcp":
+ if client is None:
+ raise RuntimeError("MCP transport requires an active client")
+ return run_mcp_tool_call(client, tool_name, arguments, include_logs)
+ return run_cli_tool_call(binary, env, tool_name, arguments, timeout, include_logs)
+
+
+def summarize_elapsed_ms(probes: list[dict[str, Any]]) -> dict[str, Any]:
+ elapsed = sorted(float(probe["elapsed_ms"]) for probe in probes)
+ if not elapsed:
+ return {"count": 0}
+ return {
+ "count": len(elapsed),
+ "min_ms": elapsed[0],
+ "median_ms": elapsed[len(elapsed) // 2],
+ "max_ms": elapsed[-1],
+ }
+
+
+def measure_cli_overhead_probes(
+ binary: Path,
+ env: dict[str, str],
+ tool_name: str,
+ count: int,
+ timeout: int,
+ include_logs: bool,
+ arguments: dict[str, Any] | None = None,
+) -> dict[str, Any] | None:
+ if count <= 0:
+ return None
+ probes = [
+ run_cli_tool_probe(binary, env, tool_name, timeout, include_logs, arguments)
+ for _ in range(count)
+ ]
+ return {
+ "tool": tool_name,
+ "trials": probes,
+ "summary": summarize_elapsed_ms(probes),
+ }
+
+
+def measure_mcp_overhead_probes(
+ client: McpClient,
+ tool_name: str,
+ count: int,
+ include_logs: bool,
+ arguments: dict[str, Any] | None = None,
+) -> dict[str, Any] | None:
+ if count <= 0:
+ return None
+ probes = [
+ run_mcp_tool_probe(client, tool_name, include_logs, arguments)
+ for _ in range(count)
+ ]
+ return {
+ "tool": tool_name,
+ "trials": probes,
+ "summary": summarize_elapsed_ms(probes),
+ }
+
+
+def measure_indexed_query_probes_for_transport(
+ transport: str,
+ binary: Path,
+ env: dict[str, str],
+ tool_name: str,
+ count: int,
+ project: str,
+ timeout: int,
+ include_logs: bool,
+ client: McpClient | None = None,
+) -> dict[str, Any] | None:
+ """Measure a named file-backed project after its initial index exists."""
+ arguments = {"project": project}
+ if transport == "mcp":
+ if client is None:
+ raise RuntimeError("MCP indexed-query probes require an active client")
+ daemon_log, daemon_log_offset = daemon_log_window(env)
+ result = measure_mcp_overhead_probes(
+ client, tool_name, count, include_logs, arguments
+ )
+ census = summarize_daemon_mem_census_since(daemon_log, daemon_log_offset)
+ if result is not None and census is not None:
+ result["daemon_mem_census"] = census
+ profiles = summarize_daemon_profiles_since(
+ daemon_log,
+ daemon_log_offset,
+ (
+ ("mcp_tool_execute", tool_name),
+ ("mcp_request_total", "tools/call"),
+ *INDEXED_QUERY_PROFILE_COMPONENTS,
+ ),
+ )
+ if result is not None and profiles is not None:
+ result["daemon_profile"] = profiles
+ return result
+ return measure_cli_overhead_probes(
+ binary, env, tool_name, count, timeout, include_logs, arguments
+ )
+
+
+def remove_project_dbs(cache_dir: Path) -> list[str]:
+ removed: list[str] = []
+ for path in cache_dir.iterdir():
+ if not path.is_file():
+ continue
+ if path.name == CONFIG_DB_NAME or not path.name.endswith(PROJECT_DB_SUFFIX):
+ continue
+ path.unlink()
+ removed.append(path.name)
+ for suffix in ("-wal", "-shm"):
+ sidecar = cache_dir / f"{path.name}{suffix}"
+ if sidecar.exists():
+ sidecar.unlink()
+ removed.append(sidecar.name)
+ return removed
+
+
+def find_project_db(cache_dir: Path) -> Path:
+ dbs = sorted(
+ path
+ for path in cache_dir.iterdir()
+ if path.is_file()
+ and path.name != CONFIG_DB_NAME
+ and path.name.endswith(PROJECT_DB_SUFFIX)
+ )
+ primary_dbs = [
+ path for path in dbs if DEPENDENCY_PROJECT_SEPARATOR not in path.stem
+ ]
+ if len(primary_dbs) != 1:
+ primary_names = ", ".join(path.name for path in primary_dbs) or "(none)"
+ all_names = ", ".join(path.name for path in dbs) or "(none)"
+ raise RuntimeError(
+ f"expected one primary project DB in {cache_dir}, "
+ f"found {len(primary_dbs)}: {primary_names}; "
+ f"all project DBs: {all_names}"
+ )
+ return primary_dbs[0]
+
+
+def remove_sqlite_sidecars(path: Path) -> None:
+ for suffix in ("-wal", "-shm"):
+ sidecar = Path(f"{path}{suffix}")
+ if sidecar.exists():
+ sidecar.unlink()
+
+
+def copy_sqlite_snapshot(source: Path, destination: Path) -> None:
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ if destination.exists():
+ destination.unlink()
+ remove_sqlite_sidecars(destination)
+ uri = f"{source.resolve().as_uri()}?mode=ro"
+ with (
+ closing(sqlite3.connect(uri, uri=True)) as src,
+ closing(sqlite3.connect(str(destination))) as dst,
+ ):
+ src.backup(dst)
+
+
+def clone_list_project_db(
+ source: Path, destination: Path, project: str, root_path: str
+) -> None:
+ """Clone one valid project DB and rekey rows used by list_projects."""
+ copy_sqlite_snapshot(source, destination)
+ with closing(sqlite3.connect(str(destination))) as con, con:
+ project_rows = con.execute("SELECT name FROM projects").fetchall()
+ if len(project_rows) != 1:
+ raise RuntimeError(
+ f"list-project fixture seed must contain one project, found {len(project_rows)}"
+ )
+ old_project = str(project_rows[0][0])
+ con.execute(
+ "UPDATE projects SET name = ?, root_path = ? WHERE name = ?",
+ (project, root_path, old_project),
+ )
+ con.execute(
+ "UPDATE nodes SET project = ? WHERE project = ?", (project, old_project)
+ )
+ con.execute(
+ "UPDATE edges SET project = ? WHERE project = ?", (project, old_project)
+ )
+
+
+def decode_sqlite_text(data: bytes) -> str:
+ return data.decode("utf-8", "surrogateescape")
+
+
+def sqlite_cbm_source_span_label(label: str | None) -> int:
+ return int(label in SOURCE_SPAN_LABELS)
+
+
+def query_rows(db_path: Path, sql: str, params: tuple[Any, ...]) -> list[str]:
+ """First column of each row, as text. Fingerprinting and comparison callers use this."""
+ return [str(row[0]) for row in query_tuples(db_path, sql, params)]
+
+
+def query_tuples(
+ db_path: Path, sql: str, params: tuple[Any, ...]
+) -> list[tuple[Any, ...]]:
+ """Read every column of a read-only query. The single SQLite read primitive here.
+
+ query_rows projects this to its first column; the rank probes need the full
+ (qualified_name, file_path, score) triple. Opened mode=ro, matching
+ persisted_stale_views and copy_sqlite_snapshot, so no reader can mutate a retained
+ experiment database.
+ """
+ uri = f"{db_path.resolve().as_uri()}?mode=ro"
+ with closing(sqlite3.connect(uri, uri=True)) as con:
+ con.text_factory = decode_sqlite_text
+ con.create_function("cbm_source_span_label", 1, sqlite_cbm_source_span_label)
+ return list(con.execute(sql, params))
+
+
+def canonical_query_rows(db_path: Path, project: str, sql: str) -> list[str]:
+ return query_rows(db_path, sql, (project,))
+
+
+def stream_query_fingerprint(
+ db_path: Path, sql: str, params: tuple[Any, ...]
+) -> dict[str, Any]:
+ """Hash an ordered single-column query with O(1) Python memory."""
+ digest = hashlib.sha256()
+ row_count = 0
+ con = sqlite3.connect(str(db_path))
+ con.text_factory = decode_sqlite_text
+ con.create_function("cbm_source_span_label", 1, sqlite_cbm_source_span_label)
+ try:
+ for row in con.execute(sql, params):
+ value = row[0]
+ payload = (
+ value
+ if isinstance(value, bytes)
+ else str(value).encode("utf-8", "surrogateescape")
+ )
+ digest.update(len(payload).to_bytes(8, "big"))
+ digest.update(payload)
+ row_count += 1
+ finally:
+ con.close()
+ return {"row_count": row_count, "sha256": digest.hexdigest()}
+
+
+def first_sorted_query_difference(
+ left_db: Path,
+ right_db: Path,
+ left_sql: str,
+ left_params: tuple[Any, ...],
+ right_sql: str,
+ right_params: tuple[Any, ...],
+) -> tuple[str | None, str | None]:
+ """Return the first merge difference from two ordered queries in O(1) memory."""
+ left_con = sqlite3.connect(str(left_db))
+ right_con = sqlite3.connect(str(right_db))
+ for con in (left_con, right_con):
+ con.text_factory = decode_sqlite_text
+ con.create_function("cbm_source_span_label", 1, sqlite_cbm_source_span_label)
+ try:
+ left_rows = iter(left_con.execute(left_sql, left_params))
+ right_rows = iter(right_con.execute(right_sql, right_params))
+ left = next(left_rows, None)
+ right = next(right_rows, None)
+ while left is not None and right is not None:
+ left_value = str(left[0])
+ right_value = str(right[0])
+ if left_value == right_value:
+ left = next(left_rows, None)
+ right = next(right_rows, None)
+ elif left_value < right_value:
+ return left_value, None
+ else:
+ return None, right_value
+ return (
+ str(left[0]) if left is not None else None,
+ str(right[0]) if right is not None else None,
+ )
+ finally:
+ left_con.close()
+ right_con.close()
+
+
+def compare_query_rows(
+ left_db: Path,
+ right_db: Path,
+ kind: str,
+ left_sql: str,
+ left_params: tuple[Any, ...],
+ right_sql: str,
+ right_params: tuple[Any, ...],
+) -> dict[str, Any]:
+ left = stream_query_fingerprint(left_db, left_sql, left_params)
+ right = stream_query_fingerprint(right_db, right_sql, right_params)
+ if left != right:
+ left_only, right_only = first_sorted_query_difference(
+ left_db, right_db, left_sql, left_params, right_sql, right_params
+ )
+ return {
+ "equal": False,
+ "kind": kind,
+ "left_count": left["row_count"],
+ "right_count": right["row_count"],
+ "left_sha256": left["sha256"],
+ "right_sha256": right["sha256"],
+ "left_only": left_only,
+ "right_only": right_only,
+ }
+ return {"equal": True, "row_count": left["row_count"], "sha256": left["sha256"]}
+
+
+CANONICAL_NODES_SQL = (
+ "SELECT quote(label) || char(9) || quote(name) || char(9) || "
+ "quote(qualified_name) || char(9) || quote(coalesce(file_path,'')) || char(9) || "
+ "start_line || char(9) || end_line || char(9) || "
+ "COALESCE((SELECT group_concat(item, char(30)) FROM ("
+ "SELECT quote(je.key) || '=' || je.type || '=' || "
+ "COALESCE(quote(CAST(je.value AS TEXT)), 'NULL') AS item "
+ "FROM json_each(n.properties) AS je "
+ "ORDER BY je.key, je.type, CAST(je.value AS TEXT)"
+ ")), '') "
+ "FROM nodes n WHERE project = ?1 "
+ "ORDER BY label, name, qualified_name, coalesce(file_path,''), start_line, end_line, "
+ "COALESCE((SELECT group_concat(item, char(30)) FROM ("
+ "SELECT quote(je.key) || '=' || je.type || '=' || "
+ "COALESCE(quote(CAST(je.value AS TEXT)), 'NULL') AS item "
+ "FROM json_each(n.properties) AS je "
+ "ORDER BY je.key, je.type, CAST(je.value AS TEXT)"
+ ")), '')"
+)
+
+
+def build_canonical_edges_sql(edge_predicate: str = "") -> str:
+ return (
+ "SELECT quote(s.label) || char(9) || quote(s.qualified_name) || char(9) || "
+ "quote(coalesce(s.file_path,'')) || char(9) || s.start_line || char(9) || "
+ "s.end_line || char(9) || quote(t.label) || char(9) || quote(t.qualified_name) || "
+ "char(9) || quote(coalesce(t.file_path,'')) || char(9) || t.start_line || char(9) || "
+ "t.end_line || char(9) || quote(e.type) || char(9) || "
+ "COALESCE((SELECT group_concat(item, char(30)) FROM ("
+ "SELECT quote(je.key) || '=' || je.type || '=' || "
+ "COALESCE(quote(CAST(je.value AS TEXT)), 'NULL') AS item "
+ "FROM json_each(e.properties) AS je "
+ "ORDER BY je.key, je.type, CAST(je.value AS TEXT)"
+ ")), '') "
+ "FROM edges e "
+ "JOIN nodes s ON s.id = e.source_id "
+ "JOIN nodes t ON t.id = e.target_id "
+ f"WHERE e.project = ?1 {edge_predicate}"
+ "ORDER BY s.label, s.qualified_name, coalesce(s.file_path,''), s.start_line, s.end_line, "
+ "t.label, t.qualified_name, coalesce(t.file_path,''), t.start_line, t.end_line, "
+ "e.type, COALESCE((SELECT group_concat(item, char(30)) FROM ("
+ "SELECT quote(je.key) || '=' || je.type || '=' || "
+ "COALESCE(quote(CAST(je.value AS TEXT)), 'NULL') AS item "
+ "FROM json_each(e.properties) AS je "
+ "ORDER BY je.key, je.type, CAST(je.value AS TEXT)"
+ ")), '')"
+ )
+
+
+CANONICAL_EDGES_SQL = build_canonical_edges_sql()
+CANONICAL_EDGES_WITHOUT_SEMANTIC_SQL = build_canonical_edges_sql(
+ "AND e.type <> 'SEMANTICALLY_RELATED' "
+)
+
+CANONICAL_HASHES_SQL = (
+ "SELECT quote(rel_path) || char(9) || quote(sha256) || char(9) || mtime_ns || char(9) || "
+ "size FROM file_hashes WHERE project = ?1 ORDER BY rel_path"
+)
+
+CONTENT_HASHES_SQL = (
+ "SELECT quote(rel_path) || char(9) || quote(sha256) || char(9) || size "
+ "FROM file_hashes WHERE project = ?1 ORDER BY rel_path"
+)
+
+STABLE_NODES_SQL = (
+ "SELECT quote(label) || char(9) || "
+ "quote(CASE WHEN label = 'Project' AND name = ?1 THEN '' ELSE name END) || char(9) || "
+ "quote(CASE WHEN qualified_name = ?1 THEN '' "
+ "WHEN substr(qualified_name, 1, length(?1) + 1) = ?1 || '.' "
+ "THEN substr(qualified_name, length(?1) + 2) ELSE qualified_name END) || char(9) || "
+ "quote(coalesce(file_path,'')) || char(9) || start_line || char(9) || end_line "
+ "FROM nodes WHERE project = ?1 ORDER BY 1"
+)
+
+STABLE_EDGES_SQL = (
+ "SELECT quote(CASE WHEN s.qualified_name = ?1 THEN '' "
+ "WHEN substr(s.qualified_name, 1, length(?1) + 1) = ?1 || '.' "
+ "THEN substr(s.qualified_name, length(?1) + 2) ELSE s.qualified_name END) || char(9) || "
+ "quote(CASE WHEN t.qualified_name = ?1 THEN '' "
+ "WHEN substr(t.qualified_name, 1, length(?1) + 1) = ?1 || '.' "
+ "THEN substr(t.qualified_name, length(?1) + 2) ELSE t.qualified_name END) || char(9) || "
+ "quote(e.type) FROM edges e "
+ "JOIN nodes s ON s.id = e.source_id JOIN nodes t ON t.id = e.target_id "
+ "WHERE e.project = ?1 ORDER BY 1"
+)
+
+STABLE_SEMANTIC_SCORES_SQL = (
+ "SELECT quote(CASE WHEN s.qualified_name = ?1 THEN '' "
+ "WHEN substr(s.qualified_name, 1, length(?1) + 1) = ?1 || '.' "
+ "THEN substr(s.qualified_name, length(?1) + 2) ELSE s.qualified_name END) || char(9) || "
+ "quote(CASE WHEN t.qualified_name = ?1 THEN '' "
+ "WHEN substr(t.qualified_name, 1, length(?1) + 1) = ?1 || '.' "
+ "THEN substr(t.qualified_name, length(?1) + 2) ELSE t.qualified_name END) || char(9) || "
+ "quote(e.type) || char(9) || "
+ "coalesce(quote(CAST(json_extract(e.properties, '$.score') AS TEXT)), 'NULL') || char(9) || "
+ "coalesce(quote(CAST(json_extract(e.properties, '$.jaccard') AS TEXT)), 'NULL') "
+ "FROM edges e JOIN nodes s ON s.id = e.source_id JOIN nodes t ON t.id = e.target_id "
+ "WHERE e.project = ?1 AND e.type IN ('SIMILAR_TO','SEMANTICALLY_RELATED') ORDER BY 1"
+)
+
+ACTIVE_OVERLAY_CTE_SQL = (
+ "WITH active_overlay_files AS ("
+ " SELECT project, rel_path, MAX(overlay_generation) AS overlay_generation"
+ " FROM ("
+ " SELECT n.project, n.rel_path, n.overlay_generation"
+ " FROM overlay_nodes n"
+ " JOIN overlay_generations g"
+ " ON g.project = n.project AND g.overlay_generation = n.overlay_generation"
+ " WHERE g.status = ?1 AND n.project = ?4"
+ " UNION"
+ " SELECT e.project, e.rel_path, e.overlay_generation"
+ " FROM overlay_edges e"
+ " JOIN overlay_generations g"
+ " ON g.project = e.project AND g.overlay_generation = e.overlay_generation"
+ " WHERE g.status = ?1 AND e.project = ?4"
+ " UNION"
+ " SELECT t.project, t.rel_path, t.overlay_generation"
+ " FROM overlay_tombstones t"
+ " JOIN overlay_generations g"
+ " ON g.project = t.project AND g.overlay_generation = t.overlay_generation"
+ " WHERE g.status = ?1 AND t.active = ?3 AND t.project = ?4"
+ " ) overlay_files"
+ " GROUP BY project, rel_path"
+ "), active_file_tombstones AS ("
+ " SELECT t.project, t.rel_path, MAX(t.overlay_generation) AS overlay_generation"
+ " FROM overlay_tombstones t"
+ " JOIN overlay_generations g"
+ " ON g.project = t.project AND g.overlay_generation = t.overlay_generation"
+ " WHERE g.status = ?1 AND t.entity_kind = ?2 AND t.active = ?3 AND t.project = ?4"
+ " GROUP BY t.project, t.rel_path"
+ "), active_node_candidates AS ("
+ " SELECT 0 AS overlay_row, n.project, n.label, n.name, n.qualified_name, n.file_path,"
+ " n.start_line, n.end_line, n.properties"
+ " FROM nodes n"
+ " WHERE n.project = ?4"
+ " AND NOT EXISTS (SELECT 1 FROM active_file_tombstones af"
+ " WHERE af.project = n.project AND af.rel_path = n.file_path)"
+ " UNION ALL"
+ " SELECT 1 AS overlay_row, n.project, n.label, n.name, n.qualified_name, n.file_path,"
+ " n.start_line, n.end_line, n.properties"
+ " FROM overlay_nodes n"
+ " JOIN active_overlay_files af"
+ " ON af.project = n.project AND af.rel_path = n.rel_path"
+ " AND af.overlay_generation = n.overlay_generation"
+ " WHERE n.owned = ?5"
+ "), active_nodes AS ("
+ " SELECT project, label, name, qualified_name, file_path, start_line, end_line, properties"
+ " FROM ("
+ " SELECT c.*, ROW_NUMBER() OVER ("
+ " PARTITION BY c.project, c.qualified_name"
+ " ORDER BY cbm_source_span_label(c.label) DESC,"
+ " CASE WHEN cbm_source_span_label(c.label) = 1"
+ " THEN CASE WHEN c.file_path <> '' THEN 1 ELSE 0 END"
+ " ELSE c.overlay_row END DESC,"
+ " CASE WHEN cbm_source_span_label(c.label) = 1"
+ " AND c.start_line > 0 AND c.end_line >= c.start_line"
+ " THEN c.end_line - c.start_line + 1 ELSE 0 END DESC,"
+ " CASE WHEN cbm_source_span_label(c.label) = 1 THEN c.start_line ELSE 0 END ASC,"
+ " CASE WHEN cbm_source_span_label(c.label) = 1 THEN c.end_line ELSE 0 END DESC,"
+ " CASE WHEN cbm_source_span_label(c.label) = 1 THEN c.file_path ELSE '' END ASC,"
+ " c.overlay_row DESC"
+ " ) AS rn"
+ " FROM active_node_candidates c"
+ " ) ranked_nodes"
+ " WHERE rn = 1"
+ "), active_edges AS ("
+ " SELECT e.project, s.qualified_name AS source_qn, t.qualified_name AS target_qn,"
+ " e.type, e.properties"
+ " FROM edges e"
+ " JOIN nodes s ON s.id = e.source_id"
+ " JOIN nodes t ON t.id = e.target_id"
+ " WHERE e.project = ?4"
+ " AND NOT EXISTS (SELECT 1 FROM active_file_tombstones af"
+ " WHERE af.project = s.project AND af.rel_path = s.file_path)"
+ " AND NOT EXISTS (SELECT 1 FROM active_file_tombstones af"
+ " WHERE af.project = t.project AND af.rel_path = t.file_path)"
+ " UNION"
+ " SELECT e.project, e.source_qn, e.target_qn, e.type, e.properties"
+ " FROM overlay_edges e"
+ " JOIN active_overlay_files af"
+ " ON af.project = e.project AND af.rel_path = e.rel_path"
+ " AND af.overlay_generation = e.overlay_generation"
+ " WHERE e.owned = ?5"
+ ") "
+)
+
+ACTIVE_OVERLAY_NODES_SQL = (
+ ACTIVE_OVERLAY_CTE_SQL
+ + "SELECT quote(label) || char(9) || quote(name) || char(9) || "
+ "quote(qualified_name) || char(9) || quote(coalesce(file_path,'')) || char(9) || "
+ "start_line || char(9) || end_line || char(9) || "
+ "COALESCE((SELECT group_concat(item, char(30)) FROM ("
+ "SELECT quote(je.key) || '=' || je.type || '=' || "
+ "COALESCE(quote(CAST(je.value AS TEXT)), 'NULL') AS item "
+ "FROM json_each(n.properties) AS je "
+ "ORDER BY je.key, je.type, CAST(je.value AS TEXT)"
+ ")), '') "
+ "FROM active_nodes n WHERE project = ?4 "
+ "ORDER BY label, name, qualified_name, coalesce(file_path,''), start_line, end_line, "
+ "COALESCE((SELECT group_concat(item, char(30)) FROM ("
+ "SELECT quote(je.key) || '=' || je.type || '=' || "
+ "COALESCE(quote(CAST(je.value AS TEXT)), 'NULL') AS item "
+ "FROM json_each(n.properties) AS je "
+ "ORDER BY je.key, je.type, CAST(je.value AS TEXT)"
+ ")), '')"
+)
+
+ACTIVE_OVERLAY_EDGES_SQL = (
+ ACTIVE_OVERLAY_CTE_SQL
+ + "SELECT quote(s.label) || char(9) || quote(s.qualified_name) || char(9) || "
+ "quote(coalesce(s.file_path,'')) || char(9) || s.start_line || char(9) || "
+ "s.end_line || char(9) || quote(t.label) || char(9) || quote(t.qualified_name) || "
+ "char(9) || quote(coalesce(t.file_path,'')) || char(9) || t.start_line || char(9) || "
+ "t.end_line || char(9) || quote(e.type) || char(9) || "
+ "COALESCE((SELECT group_concat(item, char(30)) FROM ("
+ "SELECT quote(je.key) || '=' || je.type || '=' || "
+ "COALESCE(quote(CAST(je.value AS TEXT)), 'NULL') AS item "
+ "FROM json_each(e.properties) AS je "
+ "ORDER BY je.key, je.type, CAST(je.value AS TEXT)"
+ ")), '') "
+ "FROM active_edges e "
+ "JOIN active_nodes s ON s.project = e.project AND s.qualified_name = e.source_qn "
+ "JOIN active_nodes t ON t.project = e.project AND t.qualified_name = e.target_qn "
+ "WHERE e.project = ?4 "
+ "ORDER BY s.label, s.qualified_name, coalesce(s.file_path,''), s.start_line, s.end_line, "
+ "t.label, t.qualified_name, coalesce(t.file_path,''), t.start_line, t.end_line, "
+ "e.type, COALESCE((SELECT group_concat(item, char(30)) FROM ("
+ "SELECT quote(je.key) || '=' || je.type || '=' || "
+ "COALESCE(quote(CAST(je.value AS TEXT)), 'NULL') AS item "
+ "FROM json_each(e.properties) AS je "
+ "ORDER BY je.key, je.type, CAST(je.value AS TEXT)"
+ ")), '')"
+)
+
+
+def stable_graph_fingerprint(db_path: Path, project: str) -> dict[str, Any]:
+ """Return path-normalized experiment identity with O(1) Python memory."""
+ components: dict[str, dict[str, Any]] = {}
+ aggregate = hashlib.sha256()
+ for name, sql in (
+ ("nodes", STABLE_NODES_SQL),
+ ("edges", STABLE_EDGES_SQL),
+ ("semantic_scores", STABLE_SEMANTIC_SCORES_SQL),
+ ("source_files", CONTENT_HASHES_SQL),
+ ):
+ fingerprint = stream_query_fingerprint(db_path, sql, (project,))
+ components[name] = fingerprint
+ name_payload = name.encode("ascii")
+ aggregate.update(len(name_payload).to_bytes(8, "big"))
+ aggregate.update(name_payload)
+ aggregate.update(fingerprint["row_count"].to_bytes(8, "big"))
+ aggregate.update(bytes.fromhex(fingerprint["sha256"]))
+ return {"sha256": aggregate.hexdigest(), "components": components}
+
+
+def compare_canonical_graph(
+ left_db: Path, right_db: Path, project: str
+) -> dict[str, Any]:
+ for kind, sql in (
+ ("canonical nodes", CANONICAL_NODES_SQL),
+ ("canonical edges", CANONICAL_EDGES_SQL),
+ ("file hashes", CANONICAL_HASHES_SQL),
+ ):
+ result = compare_query_rows(
+ left_db, right_db, kind, sql, (project,), sql, (project,)
+ )
+ if not result["equal"]:
+ return result
+ return {"equal": True}
+
+
+def compare_graph_excluding_declared_stale_views(
+ left_db: Path,
+ right_db: Path,
+ project: str,
+ stale_views: list[str],
+) -> dict[str, Any] | None:
+ """Verify strict graph equality after excluding only explicitly stale derived rows."""
+ if "semantic_edges" not in stale_views:
+ return None
+ excluded_edge_types = ["SEMANTICALLY_RELATED"]
+ for kind, sql in (
+ ("canonical nodes excluding declared stale views", CANONICAL_NODES_SQL),
+ (
+ "canonical edges excluding declared stale views",
+ CANONICAL_EDGES_WITHOUT_SEMANTIC_SQL,
+ ),
+ ("file hashes excluding declared stale views", CANONICAL_HASHES_SQL),
+ ):
+ result = compare_query_rows(
+ left_db, right_db, kind, sql, (project,), sql, (project,)
+ )
+ if not result["equal"]:
+ return {
+ **result,
+ "declared_stale_views": stale_views,
+ "excluded_edge_types": excluded_edge_types,
+ }
+ return {
+ "equal": True,
+ "declared_stale_views": stale_views,
+ "excluded_edge_types": excluded_edge_types,
+ }
+
+
+def compare_active_overlay_graph(
+ left_db: Path, right_db: Path, project: str
+) -> dict[str, Any]:
+ left_params = (
+ OVERLAY_STATUS_READY,
+ OVERLAY_TOMBSTONE_FILE,
+ OVERLAY_TOMBSTONE_ACTIVE,
+ project,
+ OVERLAY_ROW_OWNED,
+ )
+ for kind, left_sql, right_sql in (
+ ("active overlay nodes", ACTIVE_OVERLAY_NODES_SQL, CANONICAL_NODES_SQL),
+ ("active overlay edges", ACTIVE_OVERLAY_EDGES_SQL, CANONICAL_EDGES_SQL),
+ ):
+ result = compare_query_rows(
+ left_db, right_db, kind, left_sql, left_params, right_sql, (project,)
+ )
+ if not result["equal"]:
+ return result
+ return {"equal": True}
+
+
+def graph_gate_for_publish_kind(
+ canonical: dict[str, Any],
+ publish_kind: str | None,
+ oracle_passed: bool | None = None,
+ active_overlay: dict[str, Any] | None = None,
+ freshness_scoped: dict[str, Any] | None = None,
+) -> dict[str, Any]:
+ canonical_equal = bool(canonical.get("equal"))
+ active_overlay_equal = bool(active_overlay and active_overlay.get("equal"))
+ if publish_kind == PUBLISH_INCREMENTAL_OVERLAY and active_overlay is not None:
+ return {
+ "passed": active_overlay_equal,
+ "policy": "overlay_active_graph",
+ "canonical_equal": canonical_equal,
+ "active_overlay_equal": active_overlay_equal,
+ "reason": (
+ "overlay publish leaves canonical rows unchanged; validate active overlay "
+ "nodes and edges against a fresh full graph"
+ ),
+ }
+ if publish_kind == PUBLISH_INCREMENTAL_OVERLAY and oracle_passed is not None:
+ return {
+ "passed": bool(oracle_passed),
+ "policy": "overlay_active_oracles",
+ "canonical_equal": canonical_equal,
+ "reason": (
+ "overlay publish leaves canonical rows unchanged; self-dogfood gates "
+ "on active read oracles and freshness metadata"
+ ),
+ }
+ # A stale ledger entry can describe a disabled or currently unused derived
+ # view. Exact canonical equality is stronger evidence and must not be
+ # downgraded to a scoped-freshness pass or excluded from Pareto analysis.
+ if canonical_equal:
+ return {
+ "passed": True,
+ "policy": "canonical_graph",
+ "canonical_equal": True,
+ }
+ if freshness_scoped is not None and freshness_scoped.get("equal") is True:
+ return {
+ "passed": True,
+ "policy": "declared_stale_derived_views",
+ "canonical_equal": canonical_equal,
+ "freshness_scoped_equal": True,
+ "declared_stale_views": freshness_scoped.get("declared_stale_views", []),
+ "excluded_edge_types": freshness_scoped.get("excluded_edge_types", []),
+ "reason": (
+ "the full graph intentionally retains declared-stale derived rows; "
+ "all non-stale canonical rows equal the fresh graph"
+ ),
+ }
+ return {
+ "passed": canonical_equal,
+ "policy": "canonical_graph",
+ "canonical_equal": canonical_equal,
+ }
+
+
+def frontier_coverage_gate(
+ scenario_metadata: dict[str, Any],
+ incremental: dict[str, Any],
+ exact_cap: int | None = None,
+) -> dict[str, Any]:
+ expected_publish_kind = scenario_metadata.get("expected_publish_kind")
+ expected_reason = scenario_metadata.get("expected_reason")
+ if isinstance(expected_publish_kind, str) and isinstance(expected_reason, str):
+ observed_publish_kind = incremental.get("publish_kind")
+ observed_reason = incremental.get("exact_reason")
+ passed = (
+ observed_publish_kind == expected_publish_kind
+ and observed_reason == expected_reason
+ )
+ result = {
+ "passed": passed,
+ "applicable": True,
+ "contract": "safe_full_rebuild",
+ "expected_publish_kind": expected_publish_kind,
+ "observed_publish_kind": observed_publish_kind,
+ "expected_reason": expected_reason,
+ "observed_reason": observed_reason,
+ }
+ if not passed:
+ result["reason"] = (
+ "observed fallback route does not match the fixture contract"
+ )
+ return result
+ expected = scenario_metadata.get("expected_minimum_affected_files")
+ if not isinstance(expected, int):
+ return {"passed": True, "applicable": False}
+ exact_delta = incremental.get("response", {}).get("exact_delta", {})
+ observed = exact_delta.get("affected_paths")
+ if not isinstance(observed, int):
+ observed = incremental.get("exact_route_detail", {}).get(
+ "frontier_expanded_files"
+ )
+ if isinstance(exact_cap, int) and exact_cap < expected:
+ observed_publish_kind = incremental.get("publish_kind")
+ observed_reason = incremental.get("exact_reason")
+ truncated = exact_delta.get("affected_paths_truncated") is True
+ passed = (
+ observed_publish_kind in {PUBLISH_FULL, PUBLISH_INCREMENTAL_CONTAINMENT}
+ and observed_reason == "frontier_too_large"
+ and truncated
+ )
+ result = {
+ "passed": passed,
+ "applicable": True,
+ "contract": "configured_cap_fallback",
+ "configured_exact_cap": exact_cap,
+ "expected_minimum_affected_files": expected,
+ "observed_affected_files": observed,
+ "observed_publish_kind": observed_publish_kind,
+ "observed_reason": observed_reason,
+ "affected_paths_truncated": truncated,
+ }
+ if not passed:
+ result["reason"] = (
+ "configured cap fallback requires containment/full publication, "
+ "frontier_too_large, and truncation evidence"
+ )
+ return result
+ passed = isinstance(observed, int) and observed >= expected
+ result = {
+ "passed": passed,
+ "applicable": True,
+ "contract": "exact_frontier",
+ "expected_minimum_affected_files": expected,
+ "observed_affected_files": observed,
+ }
+ if not passed:
+ result["reason"] = "observed frontier is smaller than the fixture contract"
+ return result
+
+
+def validate_isolated_cache_dir(cache_dir: Path) -> Path:
+ """Fail before a candidate can mutate a live or previously populated store.
+
+ Cross-version candidates may interpret newer SQLite metadata as corruption and
+ perform their own recovery. Every benchmark phase must therefore start from a
+ harness-owned empty directory, never the caller's active cache or a prior cell.
+ """
+ resolved = cache_dir.expanduser().resolve()
+ active_cache = os.environ.get("CBM_CACHE_DIR")
+ live_caches = {Path.home() / ".cache" / "codebase-memory-mcp"}
+ if active_cache:
+ live_caches.add(Path(active_cache).expanduser())
+ if any(resolved == path.resolve() for path in live_caches):
+ raise RuntimeError(
+ f"benchmark cache resolves to a live cache directory: {resolved}"
+ )
+ if resolved.is_dir():
+ existing = sorted(
+ path.name
+ for path in resolved.iterdir()
+ if path.is_file() and path.name.endswith(PROJECT_DB_SUFFIX)
+ )
+ if existing:
+ raise RuntimeError(
+ "benchmark cache contains an existing project database: "
+ + ", ".join(existing)
+ )
+ return resolved
+
+
+def build_env(
+ cache_dir: Path, product_environment: dict[str, str] | None = None
+) -> dict[str, str]:
+ isolated_cache = validate_isolated_cache_dir(cache_dir)
+ env = {
+ key: value for key, value in os.environ.items() if not key.startswith("CBM_")
+ }
+ explicit_product_environment = validate_product_environment(
+ product_environment or {}
+ )
+ env.update(explicit_product_environment)
+ env["CBM_CACHE_DIR"] = str(isolated_cache)
+ env["CBM_AUTO_INDEX"] = "false"
+ env["CBM_CONTEXT_INJECTION"] = "false"
+ # The supervisor retains successful worker logs only in profile mode. The
+ # harness streams their exact memory/timing markers before cleaning the cache.
+ env["CBM_PROFILE"] = "1"
+ return env
+
+
+def benchmark_environment_policy(
+ product_environment: dict[str, str] | None = None,
+) -> dict[str, Any]:
+ explicit_product_environment = dict(sorted((product_environment or {}).items()))
+ workers = explicit_product_environment.get("CBM_WORKERS")
+ policy = {
+ "inherited_product_environment": "remove_all_CBM_prefix_variables",
+ "harness_overrides": {
+ "CBM_AUTO_INDEX": "false",
+ "CBM_CONTEXT_INJECTION": "false",
+ "CBM_PROFILE": "1",
+ },
+ "worker_selection": (
+ f"explicit_CBM_WORKERS={workers}"
+ if workers is not None
+ else "candidate_default_with_CBM_WORKERS_unset"
+ ),
+ "cache_scope": "isolated_per_benchmark_case",
+ }
+ if explicit_product_environment:
+ policy["explicit_product_environment"] = explicit_product_environment
+ return policy
+
+
+def prepare_matrix_scenario(
+ name: str,
+ repo_dir: Path,
+ files: int,
+ funcs_per_file: int,
+ args: argparse.Namespace,
+ case_root: Path,
+) -> dict[str, Any]:
+ frontier_language = MATRIX_FRONTIER_SCENARIOS.get(name)
+ if frontier_language:
+ return create_inbound_frontier_repo(
+ repo_dir, frontier_language, args.frontier_files
+ )
+ if name in {
+ "go_modify_1",
+ "go_modify_2",
+ "go_create",
+ "go_delete",
+ "go_rename",
+ "go_new_folder",
+ }:
+ create_repo(repo_dir, files, funcs_per_file)
+ return {"source": "synthetic_go"}
+ if name == "route_decorator":
+ create_route_repo(repo_dir, "/api/orders")
+ return {"source": "synthetic_route"}
+ if name == "python_reexport":
+ create_python_reexport_repo(repo_dir)
+ return {"source": "synthetic_python_reexport"}
+ if name == "fastapi_insert_probe":
+ return copy_fastapi_head_to_case(args, repo_dir, case_root)
+ raise ValueError(f"unknown matrix scenario: {name}")
+
+
+def mutate_matrix_scenario(name: str, repo_dir: Path, funcs_per_file: int) -> list[str]:
+ frontier_language = MATRIX_FRONTIER_SCENARIOS.get(name)
+ if frontier_language:
+ return mutate_inbound_frontier_repo(repo_dir, frontier_language)
+ if name == "go_modify_1":
+ return modify_existing_files(repo_dir, 1, funcs_per_file)
+ if name == "go_modify_2":
+ return modify_existing_files(repo_dir, 2, funcs_per_file)
+ if name == "go_create":
+ rel = Path("pkg") / "file_created.go"
+ write_text(repo_dir / rel, go_file_content(9999, 1, funcs_per_file))
+ return [rel.as_posix()]
+ if name == "go_delete":
+ rel = Path("pkg") / "file_0000.go"
+ (repo_dir / rel).unlink()
+ return [rel.as_posix()]
+ if name == "go_rename":
+ old_rel = Path("pkg") / "file_0000.go"
+ new_rel = Path("pkg") / "file_renamed.go"
+ (repo_dir / old_rel).unlink()
+ write_text(repo_dir / new_rel, go_file_content(9998, 1, funcs_per_file))
+ return [old_rel.as_posix(), new_rel.as_posix()]
+ if name == "go_new_folder":
+ rel = Path("newpkg") / "leaf.go"
+ write_text(
+ repo_dir / rel,
+ "package newpkg\n\nfunc NewFolderLeaf() int {\n\treturn 23\n}\n",
+ )
+ return [rel.as_posix()]
+ if name == "route_decorator":
+ create_route_repo(repo_dir, "/api/items")
+ return ["routes.py"]
+ if name == "python_reexport":
+ rel = Path("fastapi") / "__init__.py"
+ write_text(repo_dir / rel, "from .openapi.models import Header\n")
+ return [rel.as_posix()]
+ if name == "fastapi_insert_probe":
+ rel = Path(FASTAPI_PROBE_REL_PATH)
+ path = repo_dir / rel
+ source = path.read_text(encoding="utf-8")
+ insert = (
+ "\n"
+ " def cbm_frontier_noop_mask_probe(self) -> int:\n"
+ f" return {FASTAPI_PROBE_RETURN_VALUE}\n"
+ )
+ if FASTAPI_PROBE_INSERT_BEFORE not in source:
+ raise RuntimeError(
+ f"FastAPI probe insertion point not found: {rel.as_posix()}"
+ )
+ mutated = source.replace(
+ FASTAPI_PROBE_INSERT_BEFORE, insert + FASTAPI_PROBE_INSERT_BEFORE, 1
+ )
+ try:
+ compile(mutated, rel.as_posix(), "exec")
+ except SyntaxError as exc:
+ raise RuntimeError(
+ f"FastAPI probe mutation produced invalid Python: {exc}"
+ ) from exc
+ path.write_text(mutated, encoding="utf-8")
+ return [rel.as_posix()]
+ raise ValueError(f"unknown matrix scenario: {name}")
+
+
+def resolve_git_repo_root(repo_root: Path, timeout: int) -> Path:
+ root = repo_root.expanduser().resolve()
+ return Path(
+ command_stdout(["git", "rev-parse", "--show-toplevel"], timeout, root)
+ ).resolve()
+
+
+def git_metadata(repo_root: Path, timeout: int) -> dict[str, Any]:
+ def maybe(args: list[str]) -> str:
+ try:
+ return command_stdout(["git", *args], timeout, repo_root)
+ except Exception as exc:
+ # Metadata collection must not abort the benchmark measurement.
+ return f""
+
+ return {
+ "repo_root": str(repo_root),
+ "head": maybe(["rev-parse", "HEAD"]),
+ "short_head": maybe(["rev-parse", "--short", "HEAD"]),
+ "branch": maybe(["branch", "--show-current"]),
+ "dirty_status_short": maybe(["status", "--short"]),
+ }
+
+
+def binary_metadata(binary: Path) -> dict[str, Any]:
+ digest = hashlib.sha256()
+ with binary.open("rb") as stream:
+ for chunk in iter(lambda: stream.read(1024 * 1024), b""):
+ digest.update(chunk)
+ stat = binary.stat()
+ return {
+ "path": str(binary.resolve()),
+ "size_bytes": stat.st_size,
+ "sha256": digest.hexdigest(),
+ }
+
+
+def clone_real_repo(url: str, target: Path, timeout: int) -> Path:
+ target.parent.mkdir(parents=True, exist_ok=True)
+ proc, _ = command_result(
+ ["git", "clone", "--depth=1", url, str(target)],
+ dict(os.environ),
+ timeout,
+ )
+ if proc.returncode != 0:
+ raise RuntimeError(f"git clone failed for {url}: {proc.stderr.strip()}")
+ return target
+
+
+def clone_pinned_repo(url: str, revision: str, target: Path, timeout: int) -> Path:
+ """Materialize a corpus: an exact pinned commit, or an unpinned corpus's current tip.
+
+ clone_real_repo uses `git clone --depth=1`, which fetches only the default-branch
+ tip. Every popularity corpus in corpora-v1.json is pinned to an exact commit that is
+ usually NOT the tip, so a shallow clone would silently produce the wrong tree.
+ Fetching the revision directly keeps the download small and the checkout exact.
+
+ The workload corpora declare UNPINNED_REVISION instead, because their value is the
+ query distribution mined against whatever the operator had indexed rather than one
+ frozen tree. Those fetch HEAD. Only that declared sentinel opts in: any other
+ non-sha is rejected, so a typo'd revision cannot silently become "whatever is current"
+ and then be reported as the pinned tree.
+ """
+ if revision == UNPINNED_REVISION:
+ fetch_ref = "HEAD"
+ elif len(revision) == 40:
+ fetch_ref = revision
+ else:
+ raise RuntimeError(
+ "corpus revision must be a full 40-character commit hash or "
+ f"{UNPINNED_REVISION!r}, got {revision!r}"
+ )
+ # The only place this harness mutates a directory with git: init, remote add, fetch
+ # and switch --detach. Callers only ever pass a cache path, but pointed at a real
+ # checkout the detach would move that repository's HEAD and could strand work there.
+ # Refusing an existing repository makes that impossible rather than merely unlikely.
+ if (Path(target) / ".git").exists():
+ raise RuntimeError(
+ f"refusing to clone into {target}: it is already a git repository. "
+ "Pass an empty directory, or point at the existing checkout with "
+ "--corpus-repo =PATH instead of cloning over it."
+ )
+ target.mkdir(parents=True, exist_ok=True)
+ env = dict(os.environ)
+ steps = [
+ ["git", "init", "--quiet"],
+ ["git", "remote", "add", "origin", url],
+ # Fetching the commit itself, rather than a branch, is what makes the checkout
+ # exact. GitHub serves this, and it stays cheap: flask at its pinned commit
+ # fetches in under a second into a ~900 KB object store.
+ ["git", "fetch", "--quiet", "--depth=1", "origin", fetch_ref],
+ # `switch --detach` rather than `checkout`: unambiguous, and it cannot be
+ # confused with the file-restoring form of checkout.
+ ["git", "switch", "--quiet", "--detach", "FETCH_HEAD"],
+ ]
+ for step in steps:
+ proc, _ = command_result(step, env, timeout, target)
+ if proc.returncode != 0:
+ raise RuntimeError(
+ f"{' '.join(step)} failed for {url}@{revision}: {proc.stderr.strip()}"
+ )
+ return target
+
+
+def verify_corpus_pin(repo_root: Path, entry: dict[str, Any], timeout: int) -> None:
+ """Fail loudly when a checkout is not at the commit the registry pins.
+
+ A corpus supplied via --corpus-repo or an env var is whatever the caller had on disk,
+ so the commit is worth asserting. The tree is deliberately NOT compared here:
+ `git rev-parse HEAD^{tree}` returns the committed tree, which is fixed once the
+ commit matches, so the comparison could never fail and would not detect working-tree
+ edits either. The measured tree is validated where it actually matters — the
+ `tree` that copy_git_revision_to_dir returns after `git archive` is what the
+ experiment indexed, and run_capability_quality compares that against the registry.
+ """
+ expected_revision = entry.get("revision")
+ if expected_revision == UNPINNED_REVISION:
+ return # workload corpora resolve their revision at run time by design
+ if not expected_revision or len(expected_revision) != 40:
+ raise RuntimeError(
+ f"corpus {entry.get('id')!r} declares revision {expected_revision!r}, which "
+ f"is neither a 40-character commit hash nor {UNPINNED_REVISION!r}"
+ )
+ head = command_stdout(["git", "rev-parse", "HEAD"], timeout, repo_root).strip()
+ if head != expected_revision:
+ raise RuntimeError(
+ f"corpus {entry['id']!r} is at commit {head}, registry pins {expected_revision}"
+ )
+
+
+def corpus_cache_root() -> Path:
+ """Where benchmark corpora are cached. One definition, used by every resolver."""
+ return BENCH_REPO_CACHE_ROOT
+
+
+def corpus_env_key(corpus_id: str) -> str:
+ """Environment variable that points a corpus id at a checkout.
+
+ One definition because two processes have to agree on it: this resolver reads it,
+ and run_container_experiment.py writes it when staging corpora into a container
+ that has no network. A silent disagreement would look like a missing corpus.
+ """
+ return "CBM_BENCH_CORPUS_" + re.sub(r"[^A-Za-z0-9]", "_", corpus_id).upper()
+
+
+def resolve_benchmark_repo(
+ name: str,
+ *,
+ explicit: Path | None,
+ explicit_hint: str,
+ env_key: str,
+ is_present: Any,
+ timeout: int,
+ clone: Any | None,
+) -> Path:
+ """Find a benchmark repository, cloning only when the caller supplies a cloner.
+
+ The resolution order is the contract, and it is the same for every benchmark
+ repository so there is one convention to learn:
+
+ 1. an explicit path the caller passed
+ 2. the named environment variable
+ 3. ~/.cache/codebase-memory-mcp/bench-repos/
+ 4. clone, only if the caller allowed it
+
+ A miss names every path that was searched, so a typo cannot be mistaken for a
+ network failure.
+ """
+ candidates: list[Path] = []
+ if explicit:
+ candidates.append(Path(explicit).expanduser())
+ from_env = os.environ.get(env_key)
+ if from_env:
+ candidates.append(Path(from_env).expanduser())
+ candidates.append(BENCH_REPO_CACHE_ROOT / name)
+ for candidate in candidates:
+ if is_present(candidate):
+ return resolve_git_repo_root(candidate, timeout)
+ if clone is None:
+ searched = ", ".join(str(path) for path in candidates)
+ raise RuntimeError(
+ f"benchmark repository {name!r} not found; pass {explicit_hint}, set "
+ f"{env_key}, or allow --clone-missing-real-repos. Searched: {searched}"
+ )
+ return clone()
+
+
+def resolve_corpus_source(
+ corpus_id: str,
+ url: str,
+ revision: str,
+ args: argparse.Namespace,
+) -> Path:
+ """Find a corpus checkout, cloning the pinned commit only when allowed.
+
+ Resolution order mirrors resolve_fastapi_source so there is one convention to learn:
+ 1. --corpus-repo = (explicit, wins)
+ 2. CBM_BENCH_CORPUS_ env var
+ 3. ~/.cache/codebase-memory-mcp/bench-repos/
+ 4. clone the pinned commit, only with --clone-missing-real-repos
+ Nothing is ever cloned implicitly: a missing corpus is an error naming every path
+ that was searched, so a typo cannot look like a network problem.
+ """
+ overrides = parse_key_value_arguments(
+ getattr(args, "corpus_repo", None) or [], "--corpus-repo"
+ )
+ allow_clone = bool(getattr(args, "clone_missing_real_repos", False))
+ return resolve_benchmark_repo(
+ corpus_id,
+ explicit=Path(overrides[corpus_id]) if corpus_id in overrides else None,
+ explicit_hint=f"--corpus-repo {corpus_id}=PATH",
+ env_key=corpus_env_key(corpus_id),
+ is_present=lambda candidate: (candidate / ".git").exists(),
+ timeout=args.timeout,
+ clone=(
+ (
+ lambda: clone_pinned_repo(
+ url, revision, BENCH_REPO_CACHE_ROOT / corpus_id, args.timeout
+ )
+ )
+ if allow_clone
+ else None
+ ),
+ )
+
+
+def manifest_digest(explicit_path: str | None, default_path: Path | None) -> str | None:
+ """SHA-256 of the manifest actually used, or None when no manifest applies.
+
+ create_pair_quality_repo records manifest_sha256 for the same reason: without it a
+ report states which corpus id ran but not which registry defined it, so a later
+ edit to the registry silently changes what a published number meant.
+ """
+ path = Path(explicit_path).expanduser() if explicit_path else default_path
+ if path is None or not path.is_file():
+ return None
+ return hashlib.sha256(path.read_bytes()).hexdigest()
+
+
+def load_corpora_manifest(manifest_path: str) -> dict[str, dict[str, Any]]:
+ """Corpus id -> entry, from benchmarks/corpora-v1.json."""
+ path = (
+ Path(manifest_path).expanduser() if manifest_path else DEFAULT_CORPORA_MANIFEST
+ )
+ if not path.is_file():
+ raise ValueError(f"corpora manifest not found: {path}")
+ document = json.loads(path.read_text(encoding="utf-8"))
+ if document.get("schema_version") != 1:
+ raise ValueError(f"unsupported corpora manifest schema: {path}")
+ return {entry["id"]: entry for entry in document.get("corpora", [])}
+
+
+def resolve_fastapi_source(args: argparse.Namespace, case_root: Path) -> Path:
+ """fastapi is an unpinned benchmark repository, resolved by the shared ladder.
+
+ It keeps one extra legacy candidate (~/source/fastapi) and probes for a known file
+ rather than for .git, because that is what it did before the ladder was shared.
+ """
+ if args.fastapi_repo:
+ explicit: Path | None = Path(args.fastapi_repo).expanduser()
+ elif (Path.home() / "source" / "fastapi" / FASTAPI_PROBE_REL_PATH).is_file():
+ explicit = Path.home() / "source" / "fastapi"
+ else:
+ explicit = None
+ return resolve_benchmark_repo(
+ "fastapi",
+ explicit=explicit,
+ explicit_hint="--fastapi-repo PATH",
+ env_key="CBM_FASTAPI_REPO",
+ is_present=lambda candidate: (candidate / FASTAPI_PROBE_REL_PATH).is_file(),
+ timeout=args.timeout,
+ clone=(
+ (
+ lambda: clone_real_repo(
+ args.fastapi_url, case_root / "source-fastapi", args.timeout
+ )
+ )
+ if args.clone_missing_real_repos
+ else None
+ ),
+ )
+
+
+def copy_git_head_to_dir(source_repo: Path, dest: Path, timeout: int) -> None:
+ if dest.exists() and any(dest.iterdir()):
+ raise RuntimeError(f"destination is not empty: {dest}")
+ dest.mkdir(parents=True, exist_ok=True)
+ raw = command_stdout_bytes(
+ ["git", "ls-tree", "-r", "--name-only", "-z", "HEAD"], timeout, source_repo
+ )
+ rel_paths = [
+ item.decode("utf-8", "surrogateescape") for item in raw.split(b"\0") if item
+ ]
+ for rel_path in rel_paths:
+ blob = command_stdout_bytes(
+ ["git", "show", f"HEAD:{rel_path}"], timeout, source_repo
+ )
+ target = dest / rel_path
+ target.parent.mkdir(parents=True, exist_ok=True)
+ target.write_bytes(blob)
+
+
+def copy_git_revision_to_dir(
+ source_repo: Path,
+ dest: Path,
+ revision: str,
+ timeout: int,
+ *,
+ excluded_prefixes: tuple[str, ...] = (),
+) -> dict[str, Any]:
+ """Materialize tracked files from one exact commit without source dirty state."""
+ source_root = resolve_git_repo_root(source_repo, timeout)
+ exact_revision = command_stdout(
+ ["git", "rev-parse", f"{revision}^{{commit}}"], timeout, source_root
+ )
+ tree = command_stdout(
+ ["git", "rev-parse", f"{exact_revision}^{{tree}}"], timeout, source_root
+ )
+ dirty_status = command_stdout(["git", "status", "--short"], timeout, source_root)
+ if dest.exists() and any(dest.iterdir()):
+ raise RuntimeError(f"destination is not empty: {dest}")
+ dest.mkdir(parents=True, exist_ok=True)
+ archive_path = dest.parent / f".cbm-background-{os.getpid()}-{time.time_ns()}.tar"
+ try:
+ proc, _ = command_result(
+ [
+ "git",
+ "archive",
+ "--format=tar",
+ f"--output={archive_path}",
+ exact_revision,
+ ],
+ dict(os.environ),
+ timeout,
+ cwd=source_root,
+ )
+ if proc.returncode != 0:
+ raise RuntimeError(f"git archive failed: {proc.stderr.strip()}")
+ destination_root = dest.resolve()
+ with tarfile.open(archive_path, mode="r:") as archive:
+ excluded_roots = tuple(prefix.rstrip("/") for prefix in excluded_prefixes)
+ members = [
+ member
+ for member in archive.getmembers()
+ if not any(
+ member.name == root or member.name.startswith(f"{root}/")
+ for root in excluded_roots
+ )
+ ]
+ for member in members:
+ target = (dest / member.name).resolve()
+ if (
+ target != destination_root
+ and destination_root not in target.parents
+ ):
+ raise RuntimeError(
+ f"git archive member escapes destination: {member.name}"
+ )
+ archive.extractall(dest, members=members, filter="data")
+ finally:
+ if archive_path.exists():
+ archive_path.unlink()
+ return {
+ "source_repo": str(source_root),
+ "revision": exact_revision,
+ "tree": tree,
+ "source_dirty_status_short": dirty_status,
+ "excluded_prefixes": list(excluded_prefixes),
+ "copy_policy": "git_archive_tracked_files_from_exact_commit",
+ }
+
+
+def copy_fastapi_head_to_case(
+ args: argparse.Namespace, repo_dir: Path, case_root: Path
+) -> dict[str, Any]:
+ source_repo = resolve_fastapi_source(args, case_root)
+ copy_git_head_to_dir(source_repo, repo_dir, args.timeout)
+ return {
+ "source_repo": str(source_repo),
+ "source_git": git_metadata(source_repo, args.timeout),
+ "copy_policy": "git_tracked_files_from_HEAD",
+ }
+
+
+def create_self_dogfood_worktree(
+ source_repo: Path,
+ case_root: Path,
+ timeout: int,
+ revision: str,
+) -> Path:
+ repo_dir = case_root / SELF_DOGFOOD_REPO_SUBDIR
+ if repo_dir.exists():
+ raise RuntimeError(f"self-dogfood worktree already exists: {repo_dir}")
+ proc, _ = command_result(
+ ["git", "worktree", "add", "--detach", str(repo_dir), revision],
+ dict(os.environ),
+ timeout,
+ source_repo,
+ )
+ if proc.returncode != 0:
+ raise RuntimeError(f"git worktree add failed: {proc.stderr.strip()}")
+ return repo_dir
+
+
+def remove_self_dogfood_worktree(
+ source_repo: Path, repo_dir: Path, timeout: int
+) -> dict[str, Any]:
+ cleanup: dict[str, Any] = {
+ "requested": True,
+ "path": str(repo_dir),
+ "removed": False,
+ }
+ proc, _ = command_result(
+ ["git", "worktree", "remove", "--force", str(repo_dir)],
+ dict(os.environ),
+ timeout,
+ source_repo,
+ )
+ if proc.returncode != 0:
+ cleanup["git_worktree_remove_error"] = proc.stderr.strip()
+ shutil.rmtree(repo_dir, ignore_errors=True)
+ cleanup["removed"] = not repo_dir.exists()
+ return cleanup
+
+
+def self_dogfood_marker(name: str) -> str:
+ return f"{SELF_DOGFOOD_MARKER_PREFIX}_{name}"
+
+
+def append_c_marker_function(
+ repo_dir: Path, rel_path: str, marker: str, value: int
+) -> str:
+ append_text(
+ repo_dir / rel_path,
+ (f"\nstatic int {marker}(void) {{\n return {value};\n}}\n"),
+ )
+ return rel_path
+
+
+def create_c_marker_file(repo_dir: Path, rel_path: str, marker: str, value: int) -> str:
+ path = repo_dir / rel_path
+ if path.exists():
+ raise RuntimeError(
+ f"benchmark new-file mutation target already exists: {rel_path}"
+ )
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_text(
+ f"static int {marker}(void) {{\n return {value};\n}}\n",
+ encoding="utf-8",
+ )
+ return rel_path
+
+
+def mutate_self_dogfood_scenario(name: str, repo_dir: Path) -> dict[str, Any]:
+ marker = self_dogfood_marker(name)
+ changed: list[str] = []
+ paths = SELF_DOGFOOD_SCENARIO_PATHS.get(name)
+ if paths is None:
+ raise ValueError(f"unknown self-dogfood scenario: {name}")
+ before_hashes = {
+ path: file_sha256(repo_dir / path) if (repo_dir / path).is_file() else None
+ for path in paths
+ }
+
+ def finish(document: dict[str, Any]) -> dict[str, Any]:
+ document["source_hashes"] = [
+ {
+ "path": path,
+ "before_sha256": before_hashes[path],
+ "after_sha256": (
+ file_sha256(repo_dir / path)
+ if (repo_dir / path).is_file()
+ else None
+ ),
+ }
+ for path in paths
+ ]
+ return document
+
+ if name == "noop":
+ return finish(
+ {
+ "marker": None,
+ "changed_paths": changed,
+ "description": "no source mutation",
+ }
+ )
+ if name == "one_source_file":
+ changed.append(
+ append_c_marker_function(
+ repo_dir, "src/pipeline/pipeline_internal.h", marker, 4101
+ )
+ )
+ return finish(
+ {
+ "marker": marker,
+ "changed_paths": changed,
+ "description": "single C header edit",
+ }
+ )
+ if name == "route_handler":
+ append_text(
+ repo_dir / "src/ui/http_server.c",
+ (
+ "\n"
+ f"static int {marker}(const char *path) {{\n"
+ ' return cbm_http_path_match(path, "/api/pan4-oracle");\n'
+ "}\n"
+ ),
+ )
+ changed.append("src/ui/http_server.c")
+ return finish(
+ {
+ "marker": marker,
+ "changed_paths": changed,
+ "description": "HTTP UI handler source edit with route literal oracle",
+ }
+ )
+ if name == "c_new_leaf":
+ changed.append(
+ create_c_marker_file(
+ repo_dir,
+ "src/cbm_benchmark_leaf.c",
+ marker,
+ 4102,
+ )
+ )
+ return finish(
+ {
+ "marker": marker,
+ "changed_paths": changed,
+ "description": "new isolated C source file",
+ }
+ )
+ if name == "store_pipeline_batch":
+ changed.append(
+ append_c_marker_function(repo_dir, "src/store/store.h", marker, 4103)
+ )
+ second_marker = f"{marker}_pipeline"
+ changed.append(
+ append_c_marker_function(
+ repo_dir, "src/pipeline/pipeline_internal.h", second_marker, 4104
+ )
+ )
+ return finish(
+ {
+ "marker": marker,
+ "secondary_marker": second_marker,
+ "changed_paths": changed,
+ "description": "small store plus pipeline header batch",
+ }
+ )
+ if name == "multi_file_small":
+ changed.append(
+ append_c_marker_function(repo_dir, "src/mcp/mcp.c", marker, 4105)
+ )
+ second_marker = f"{marker}_test"
+ changed.append(
+ append_c_marker_function(repo_dir, "tests/test_mcp.c", second_marker, 4106)
+ )
+ return finish(
+ {
+ "marker": marker,
+ "secondary_marker": second_marker,
+ "changed_paths": changed,
+ "description": "small production plus test source batch",
+ }
+ )
+
+
+def oracle_passed(tool_result: dict[str, Any], marker: str | None) -> bool:
+ if not marker:
+ return True
+ response = tool_result.get("response")
+ return marker in json.dumps(response, sort_keys=True)
+
+
+def canonical_pair(source: str, target: str) -> tuple[str, str]:
+ """Return an order-independent pair identity without losing endpoint names."""
+ if (
+ not isinstance(source, str)
+ or not source
+ or not isinstance(target, str)
+ or not target
+ ):
+ raise ValueError("pair endpoints must be non-empty strings")
+ if source == target:
+ raise ValueError("pair endpoints must be distinct")
+ return (source, target) if source < target else (target, source)
+
+
+def score_pair_classification(
+ observed_pairs: list[dict[str, Any]],
+ judgments: list[dict[str, Any]],
+) -> dict[str, Any]:
+ """Score unordered observed pairs against explicit positive/negative judgments.
+
+ Natural large-repository results outside the bounded judgment set are retained as
+ unjudged observations. They are intentionally excluded from the confusion matrix:
+ incomplete ground truth cannot turn an unknown pair into a false positive.
+ """
+ judgment_by_pair: dict[tuple[str, str], dict[str, Any]] = {}
+ for judgment in judgments:
+ if not isinstance(judgment, dict):
+ raise ValueError("pair judgment must be an object")
+ pair = canonical_pair(judgment.get("source"), judgment.get("target"))
+ if pair in judgment_by_pair:
+ raise ValueError(f"duplicate pair judgment: {pair[0]} <-> {pair[1]}")
+ expected = judgment.get("expected")
+ if not isinstance(expected, bool):
+ raise ValueError("pair judgment expected must be boolean")
+ category = judgment.get("category", "uncategorized")
+ if not isinstance(category, str) or not category:
+ raise ValueError("pair judgment category must be a non-empty string")
+ judgment_by_pair[pair] = {
+ **judgment,
+ "source": pair[0],
+ "target": pair[1],
+ "expected": expected,
+ "category": category,
+ }
+
+ observed_by_pair: dict[tuple[str, str], dict[str, Any]] = {}
+ for observed in observed_pairs:
+ if not isinstance(observed, dict):
+ raise ValueError("observed pair must be an object")
+ pair = canonical_pair(observed.get("source"), observed.get("target"))
+ observed_by_pair.setdefault(
+ pair,
+ {**observed, "source": pair[0], "target": pair[1]},
+ )
+
+ confusion = {"tp": 0, "fp": 0, "fn": 0, "tn": 0}
+ witnesses: dict[str, list[dict[str, Any]]] = {key: [] for key in confusion}
+ categories: dict[str, dict[str, int]] = {}
+ for pair, judgment in judgment_by_pair.items():
+ observed = observed_by_pair.get(pair)
+ if judgment["expected"]:
+ outcome = "tp" if observed is not None else "fn"
+ else:
+ outcome = "fp" if observed is not None else "tn"
+ confusion[outcome] += 1
+ category = judgment["category"]
+ category_counts = categories.setdefault(
+ category,
+ {"tp": 0, "fp": 0, "fn": 0, "tn": 0},
+ )
+ category_counts[outcome] += 1
+ witnesses[outcome].append(
+ {
+ "source": pair[0],
+ "target": pair[1],
+ "category": category,
+ "observed": observed,
+ }
+ )
+
+ unjudged_observed = [
+ observed
+ for pair, observed in sorted(observed_by_pair.items())
+ if pair not in judgment_by_pair
+ ]
+ precision_denominator = confusion["tp"] + confusion["fp"]
+ recall_denominator = confusion["tp"] + confusion["fn"]
+ negative_denominator = confusion["fp"] + confusion["tn"]
+ precision = (
+ confusion["tp"] / precision_denominator if precision_denominator else None
+ )
+ recall = confusion["tp"] / recall_denominator if recall_denominator else None
+ f1 = (
+ 2.0 * precision * recall / (precision + recall)
+ if precision is not None and recall is not None and precision + recall > 0
+ else None
+ )
+ false_positive_rate = (
+ confusion["fp"] / negative_denominator if negative_denominator else None
+ )
+ return {
+ "judgment_count": len(judgment_by_pair),
+ "observed_pair_count": len(observed_by_pair),
+ "confusion": confusion,
+ "precision": precision,
+ "recall": recall,
+ "f1": f1,
+ "false_positive_rate": false_positive_rate,
+ "categories": categories,
+ "witnesses": witnesses,
+ "unjudged_observed_count": len(unjudged_observed),
+ "unjudged_observed": unjudged_observed,
+ "passed": recall_denominator > 0
+ and confusion["fp"] == 0
+ and confusion["fn"] == 0,
+ "ground_truth_boundary": (
+ "Only explicit judgments enter TP/FP/FN/TN; unjudged observed pairs are retained "
+ "but excluded because natural-repository ground truth is incomplete."
+ ),
+ }
+
+
+def score_ranked_relevance(
+ ranked_items: list[Any],
+ judgments: list[dict[str, Any]],
+ *,
+ cutoff: int = 5,
+) -> dict[str, Any]:
+ """Score a bounded ranking with a one-result/one-judgment relevance join.
+
+ The legacy manifest identifies evidence with substrings, so matching remains
+ backward compatible. Each judgment is consumed at most once: otherwise duplicate
+ result rows can reuse one grade indefinitely, making measured DCG exceed ideal DCG
+ and nDCG exceed its mathematical [0, 1] domain. With R results and J judgments this
+ bounded reference join is O(R*J) time and O(J+R) memory; current pages and qrel sets
+ are both small.
+ """
+ if cutoff <= 0:
+ raise ValueError("relevance cutoff must be positive")
+ valid_judgments = [
+ {
+ "expected": str(item["expected_substring"]),
+ "required": [
+ str(value)
+ for value in item.get("required_substrings", [])
+ if isinstance(value, str) and value
+ ],
+ "grade": float(item["relevance"]),
+ }
+ for item in judgments
+ if isinstance(item, dict)
+ and isinstance(item.get("expected_substring"), str)
+ and item["expected_substring"]
+ and isinstance(item.get("relevance"), (int, float))
+ and float(item["relevance"]) > 0
+ ]
+ all_relevance: list[float | int] = []
+ unmatched = set(range(len(valid_judgments)))
+ matched_judgments: list[int | None] = []
+ for ranked_item in ranked_items:
+ serialized = json.dumps(ranked_item, separators=(",", ":"), sort_keys=True)
+ candidates = [
+ index
+ for index in unmatched
+ if valid_judgments[index]["expected"] in serialized
+ and all(
+ required in serialized
+ for required in valid_judgments[index]["required"]
+ )
+ ]
+ # A result is one document in the IR metric. If malformed qrels identify the
+ # same document more than once, consume only its highest grade and expose the
+ # unmatched duplicate in the audit fields below.
+ judgment_index = max(
+ candidates,
+ key=lambda index: (valid_judgments[index]["grade"], -index),
+ default=None,
+ )
+ if judgment_index is None:
+ relevance = 0.0
+ else:
+ unmatched.remove(judgment_index)
+ relevance = valid_judgments[judgment_index]["grade"]
+ matched_judgments.append(judgment_index)
+ all_relevance.append(int(relevance) if relevance.is_integer() else relevance)
+ first_relevant_rank = next(
+ (
+ index
+ for index, relevance in enumerate(all_relevance, start=1)
+ if relevance > 0
+ ),
+ None,
+ )
+ matched_relevance = all_relevance[:cutoff]
+
+ def discounted_gain(grades: list[float | int]) -> float:
+ return sum(
+ (2.0 ** float(relevance) - 1.0) / math.log2(position + 1)
+ for position, relevance in enumerate(grades, start=1)
+ )
+
+ dcg = discounted_gain(matched_relevance)
+ ideal_relevance = sorted((item["grade"] for item in valid_judgments), reverse=True)[
+ :cutoff
+ ]
+ idcg = discounted_gain(ideal_relevance)
+ ndcg = dcg / idcg if idcg > 0 else None
+ if ndcg is not None and not 0.0 <= ndcg <= 1.0:
+ raise AssertionError(f"nDCG escaped [0, 1]: {ndcg}")
+ result = {
+ "cutoff": cutoff,
+ "judgment_count": len(valid_judgments),
+ "first_relevant_rank": first_relevant_rank,
+ "reciprocal_rank": 1.0 / first_relevant_rank if first_relevant_rank else 0.0,
+ "hit_at_1": first_relevant_rank == 1,
+ "hit_at_5": first_relevant_rank is not None and first_relevant_rank <= 5,
+ "dcg": dcg,
+ "ideal_dcg": idcg,
+ "ndcg": ndcg,
+ "matched_relevance": matched_relevance,
+ "matched_judgment_count": len(valid_judgments) - len(unmatched),
+ "unmatched_judgment_count": len(unmatched),
+ "matched_judgment_indices": matched_judgments[:cutoff],
+ "matching_mode": "legacy_substring_one_to_one",
+ "metric_domain_valid": ndcg is None or 0.0 <= ndcg <= 1.0,
+ }
+ result[f"dcg_at_{cutoff}"] = dcg
+ result[f"ideal_dcg_at_{cutoff}"] = idcg
+ result[f"ndcg_at_{cutoff}"] = ndcg
+ return result
+
+
+def score_quality_oracles(
+ oracles: dict[str, Any],
+ expectations: dict[str, Any],
+) -> dict[str, Any]:
+ """Attach auditable per-oracle verdicts and summarize applicable checks."""
+ applicable_count = 0
+ passed_count = 0
+ reciprocal_rank_total = 0.0
+ hit_at_1_count = 0
+ hit_at_5_count = 0
+ ndcg_total = 0.0
+ ndcg_applicable_count = 0
+ for name, result in oracles.items():
+ if not isinstance(result, dict):
+ continue
+ expectation = expectations.get(name, (None, "no quality criterion"))
+ graded = isinstance(expectation, dict)
+ if graded:
+ criterion = str(expectation.get("criterion") or "no quality criterion")
+ judgments = expectation.get("judgments")
+ judgments = judgments if isinstance(judgments, list) else []
+ cutoff = expectation.get("cutoff", 5)
+ cutoff = int(cutoff) if isinstance(cutoff, int) else 5
+ positive_judgments = [
+ item
+ for item in judgments
+ if isinstance(item, dict)
+ and isinstance(item.get("expected_substring"), str)
+ and isinstance(item.get("relevance"), (int, float))
+ and float(item["relevance"]) > 0
+ ]
+ expected = (
+ str(
+ max(positive_judgments, key=lambda item: float(item["relevance"]))[
+ "expected_substring"
+ ]
+ )
+ if positive_judgments
+ else None
+ )
+ required_substrings = (
+ list(
+ max(
+ positive_judgments,
+ key=lambda item: float(item["relevance"]),
+ ).get("required_substrings", [])
+ )
+ if positive_judgments
+ else []
+ )
+ else:
+ expected, criterion = expectation
+ judgments = []
+ cutoff = 5
+ required_substrings = []
+ applicable = bool(judgments) if graded else expected is not None
+ passed = False
+ rank: int | None = None
+ ndcg: float | None = None
+ response = result.get("response")
+ # Recorded for EVERY oracle, not just scorable ones. Behavioral-only probes have
+ # no judgments, so they are not applicable and contribute nothing to MRR, but
+ # their result count is the whole point of running them: it is how a zero-result
+ # or unstable answer becomes visible at all.
+ listed_items = ranked_items_from_response(response)
+ returned_count: int | None = (
+ len(listed_items) if listed_items is not None else None
+ )
+ if applicable:
+ applicable_count += 1
+ # Scoring keeps its original extraction, including the single-item fallback
+ # for responses with no list shape. Widening it here would silently change
+ # rank and MRR for the existing git_history and http_links oracles, which
+ # score query_graph responses; that belongs in its own verified change.
+ ranked_items = (
+ response.get("results")
+ if isinstance(response, dict)
+ and isinstance(response.get("results"), list)
+ else response
+ if isinstance(response, list)
+ else [response]
+ )
+ if graded:
+ ranking = score_ranked_relevance(ranked_items, judgments, cutoff=cutoff)
+ rank = ranking["first_relevant_rank"]
+ reciprocal_rank = float(ranking["reciprocal_rank"])
+ ndcg_value = ranking["ndcg"]
+ ndcg = (
+ float(ndcg_value) if isinstance(ndcg_value, (int, float)) else None
+ )
+ passed = bool(ranking["hit_at_5"])
+ if ndcg is not None:
+ ndcg_total += ndcg
+ ndcg_applicable_count += 1
+ else:
+ passed = expected in json.dumps(
+ response, separators=(",", ":"), sort_keys=True
+ )
+ for position, item in enumerate(ranked_items, start=1):
+ if expected in json.dumps(
+ item, separators=(",", ":"), sort_keys=True
+ ):
+ rank = position
+ break
+ reciprocal_rank = 1.0 / rank if rank is not None else 0.0
+ passed_count += int(passed)
+ reciprocal_rank_total += reciprocal_rank
+ hit_at_1_count += int(rank == 1)
+ hit_at_5_count += int(rank is not None and rank <= 5)
+ else:
+ reciprocal_rank = None
+ result["quality"] = {
+ "applicable": applicable,
+ "passed": passed if applicable else None,
+ "criterion": criterion,
+ "expected_substring": expected,
+ "required_substrings": required_substrings,
+ "rank": rank,
+ "returned_count": returned_count,
+ "reciprocal_rank": reciprocal_rank,
+ "hit_at_1": rank == 1 if applicable else None,
+ "hit_at_5": rank is not None and rank <= 5 if applicable else None,
+ "relevance_judgments": len(judgments) if graded else None,
+ "relevance_cutoff": cutoff if graded else None,
+ "ndcg_at_5": ndcg if graded and cutoff == 5 else None,
+ }
+ mean_reciprocal_rank = (
+ reciprocal_rank_total / applicable_count if applicable_count else None
+ )
+ return {
+ "passed": passed_count == applicable_count,
+ "passed_count": passed_count,
+ "applicable_count": applicable_count,
+ "binary_pass_rate": round(passed_count / applicable_count, 6)
+ if applicable_count
+ else None,
+ "mean_reciprocal_rank": (
+ round(mean_reciprocal_rank, 6) if mean_reciprocal_rank is not None else None
+ ),
+ "hit_at_1": round(hit_at_1_count / applicable_count, 6)
+ if applicable_count
+ else None,
+ "hit_at_5": round(hit_at_5_count / applicable_count, 6)
+ if applicable_count
+ else None,
+ "mean_ndcg_at_5": (
+ round(ndcg_total / ndcg_applicable_count, 6)
+ if ndcg_applicable_count
+ else None
+ ),
+ "ndcg_applicable_count": ndcg_applicable_count,
+ "score": round(mean_reciprocal_rank, 6)
+ if mean_reciprocal_rank is not None
+ else None,
+ }
+
+
+def run_self_dogfood_oracles(
+ transport: str,
+ binary: Path,
+ env: dict[str, str],
+ project: str,
+ mutation: dict[str, Any],
+ args: argparse.Namespace,
+ client: McpClient | None = None,
+) -> dict[str, Any]:
+ marker = mutation.get("marker")
+ changed_paths = list(mutation.get("changed_paths") or [])
+ first_changed = changed_paths[0] if changed_paths else ""
+ oracles: dict[str, Any] = {}
+ expectations: dict[str, tuple[str | None, str]] = {}
+ if marker:
+ search_code_args: dict[str, Any] = {
+ "project": project,
+ "pattern": marker,
+ "limit": 5,
+ }
+ if first_changed:
+ search_code_args["file_pattern"] = Path(first_changed).name
+ search_code_args["path_filter"] = f"^{re.escape(first_changed)}$"
+ oracles["marker_search_graph"] = run_tool_call_for_transport(
+ transport,
+ binary,
+ env,
+ "search_graph",
+ {"project": project, "name_pattern": marker, "limit": 5},
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ expectations["marker_search_graph"] = (
+ marker,
+ "mutated symbol appears in graph search",
+ )
+ oracles["marker_search_code"] = run_tool_call_for_transport(
+ transport,
+ binary,
+ env,
+ "search_code",
+ search_code_args,
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ expectations["marker_search_code"] = (
+ marker,
+ "mutated symbol appears in source search",
+ )
+ if first_changed:
+ oracles["changed_file_query_graph"] = run_tool_call_for_transport(
+ transport,
+ binary,
+ env,
+ "query_graph",
+ {
+ "project": project,
+ "query": (
+ "MATCH (n) WHERE n.file_path CONTAINS "
+ f"'{first_changed}' RETURN n.name, n.label, n.file_path LIMIT 10"
+ ),
+ },
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ expectations["changed_file_query_graph"] = (
+ first_changed,
+ "changed file path appears in graph query",
+ )
+ oracles["scoped_architecture"] = run_tool_call_for_transport(
+ transport,
+ binary,
+ env,
+ "get_architecture",
+ {"project": project, "path": first_changed, "aspects": ["all"]},
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ expectations["scoped_architecture"] = (
+ first_changed,
+ "changed file path appears in scoped architecture",
+ )
+ route_expected = (
+ "/api/pan4-oracle"
+ if mutation.get("description", "").startswith("HTTP UI handler")
+ else None
+ )
+ route_arguments: dict[str, Any] = {"project": project, "label": "Route", "limit": 5}
+ if route_expected:
+ route_arguments["name_pattern"] = "pan4-oracle"
+ oracles["route_freshness_probe"] = run_tool_call_for_transport(
+ transport,
+ binary,
+ env,
+ "search_graph",
+ route_arguments,
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ expectations["route_freshness_probe"] = (
+ route_expected,
+ "new route literal appears in route search"
+ if route_expected
+ else "route mutation not applicable",
+ )
+ quality = score_quality_oracles(oracles, expectations)
+ oracles["quality"] = quality
+ oracles["passed"] = quality["passed"]
+ return oracles
+
+
+# The single query the rank oracle has always issued. Kept as the default so a run
+# without --rank-query-manifest is byte-identical to earlier runs and their cells stay
+# cache-valid (cell identity includes the command, run_experiments.py:93-110).
+DEFAULT_RANK_QUERY_BATTERY: tuple[dict[str, Any], ...] = (
+ {
+ "id": "central_order_search",
+ "family": "D",
+ "tool": "search_graph",
+ "arguments": {"label": "Function", "name_pattern": "order", "limit": 10},
+ "criterion": (
+ "rank the structurally central order workflow ahead of lexical-only decoys"
+ ),
+ "cutoff": 5,
+ "judgments": [{"expected_substring": "zz_order_core", "relevance": 3}],
+ },
+)
+
+# These are the rank modes already exposed by search_graph. The labels name the actual
+# stored statistic used by src/store/store.c:11679-11711; no experimental-only scorer is
+# introduced. The default no-manifest fixture remains byte-compatible and does not run
+# this comparison.
+RANK_QUERY_SORT_VARIANTS: tuple[tuple[str, str], ...] = (
+ ("relevance", "pagerank"),
+ ("degree", "degree"),
+ ("calls", "calls"),
+ ("linkrank", "linkrank_in"),
+)
+
+
+def rank_fixture_overlay_decision(
+ capability: str, background: dict[str, Any] | None, args: argparse.Namespace
+) -> str:
+ """Whether the synthetic rank fixture is written into a materialized corpus tree.
+
+ Returns one of:
+
+ fixture-is-corpus the fixture is the whole indexed repository (no background), or
+ the capability's own established design overlays it deliberately
+ suppressed a real corpus was materialized and the rank fixture is not added
+ overlaid a real corpus was materialized and the fixture is planted anyway
+
+ `create_rank_quality_repo` writes `zz_order_core`, eight lexical decoys and eight
+ callers into `repo_dir` — the same directory `copy_git_revision_to_dir` materializes a
+ pinned corpus into. Overlaying them on a real corpus means the indexed graph is not
+ the tree `corpora-v1.json` pins, and `scaffolding@K` / `leaf_hub_rate@K` /
+ `tau vs degree` are then computed over nine files the corpus does not contain.
+
+ That cost would buy a planted positive control if anything checked it, but no real
+ corpus in `rank-queries-v1/manifest.json` queries those symbols, so today it buys
+ nothing. Hence: suppressed by default for a real corpus, available through
+ `--rank-fixture-overlay`, and when it is on the canary query is appended so the
+ control actually runs (see rank_battery_with_overlay_control).
+
+ Rank-only by construction: similarity and semantic_edges overlay a pair fixture onto
+ background graph mass as their measurement design, and that is left untouched.
+ """
+ if capability != "rank" or background is None:
+ return "fixture-is-corpus"
+ return "overlaid" if getattr(args, "rank_fixture_overlay", False) else "suppressed"
+
+
+def rank_battery_with_overlay_control(
+ battery: tuple[dict[str, Any], ...], *, overlay_active: bool
+) -> tuple[dict[str, Any], ...]:
+ """Append the planted-canary query when the fixture is overlaid on a real corpus.
+
+ An overlay nobody queries is contamination rather than a control. Appending is
+ id-guarded so the synthetic corpus, which already declares this query, does not
+ count it twice in the applicable_count-weighted quality aggregate.
+ """
+ if not overlay_active:
+ return battery
+ declared = {query["id"] for query in battery}
+ return battery + tuple(
+ query for query in DEFAULT_RANK_QUERY_BATTERY if query["id"] not in declared
+ )
+
+
+def load_rank_query_battery(
+ manifest_path: str, corpus_id: str
+) -> tuple[dict[str, Any], ...]:
+ """Load one corpus's query battery from a versioned manifest.
+
+ Returns the built-in single-query battery when no manifest is supplied, which is
+ what keeps historical cells comparable. Path handling mirrors
+ create_pair_quality_repo's manifest discipline: schema pinned, relative paths only.
+ """
+ if not manifest_path:
+ return DEFAULT_RANK_QUERY_BATTERY
+ path = Path(manifest_path).expanduser()
+ if not path.is_file():
+ raise ValueError(f"rank query manifest not found: {path}")
+ document = json.loads(path.read_text(encoding="utf-8"))
+ if document.get("schema_version") != 1:
+ raise ValueError(f"unsupported rank query manifest schema: {path}")
+ corpora = document.get("corpora")
+ if not isinstance(corpora, dict):
+ raise ValueError(f"rank query manifest has no corpora object: {path}")
+ if corpus_id not in corpora:
+ available = ", ".join(sorted(corpora)) or "(none)"
+ raise ValueError(
+ f"corpus {corpus_id!r} is absent from {path.name}; available: {available}"
+ )
+ queries = corpora[corpus_id].get("queries")
+ if not isinstance(queries, list) or not queries:
+ raise ValueError(f"corpus {corpus_id!r} declares no queries in {path.name}")
+ # A manifest-level cutoff is the point of declaring one; without this the loop's
+ # hardcoded 5 silently won and the field was decorative.
+ default_cutoff = document.get("default_cutoff", 5)
+ resolved: list[dict[str, Any]] = []
+ for query in queries:
+ for field in ("id", "tool", "arguments"):
+ if field not in query:
+ raise ValueError(f"query in corpus {corpus_id!r} is missing {field!r}")
+ entry = dict(query)
+ entry.setdefault("cutoff", default_cutoff)
+ repetitions = entry.get("repetitions", 1)
+ if (
+ not isinstance(repetitions, int)
+ or isinstance(repetitions, bool)
+ or repetitions < 1
+ ):
+ raise ValueError(
+ f"query {entry['id']!r} declares repetitions={repetitions!r}; "
+ "it must be a positive integer"
+ )
+ entry["repetitions"] = repetitions
+ resolved.append(entry)
+ return tuple(resolved)
+
+
+def manifest_corpus_disagreements(
+ battery_path: str, corpus_manifest_path: str
+) -> list[str]:
+ """Corpus ids present in one manifest but not the other.
+
+ Drift is easy to introduce and only surfaces mid-run: `--corpus ripgrep` resolves in
+ the registry, then fails when the battery is loaded. Listing both directions makes
+ the gap visible before a campaign starts rather than after.
+ """
+ if not battery_path:
+ return []
+ document = json.loads(Path(battery_path).expanduser().read_text(encoding="utf-8"))
+ battery_ids = set(document.get("corpora") or {})
+ registry_ids = set(load_corpora_manifest(corpus_manifest_path))
+ return [
+ *(
+ f"{name}: has queries but no corpus registry entry"
+ for name in sorted(battery_ids - registry_ids - {"synthetic-rank-v1"})
+ ),
+ *(
+ f"{name}: registered as a corpus but has no queries"
+ for name in sorted(registry_ids - battery_ids)
+ ),
+ ]
+
+
+def ranked_items_from_response(response: Any) -> list[Any] | None:
+ """Extract the ranked list from a tool response, or None if it has no list shape.
+
+ Mirrors the extraction score_quality_oracles performs, so per-query result counts
+ and the graded scores are always computed from the same list.
+ """
+ if isinstance(response, dict):
+ for key in ("results", "matches", "rows"):
+ if isinstance(response.get(key), list):
+ return response[key]
+ total = response.get("total_results")
+ if isinstance(total, int):
+ return [] if total == 0 else [None] * total
+ return None
+ if isinstance(response, list):
+ return response
+ return None
+
+
+def count_ranked_items(response: Any) -> int | None:
+ """Number of items a response listed, or None when it has no list shape."""
+ ranked = ranked_items_from_response(response)
+ return len(ranked) if ranked is not None else None
+
+
+def summarize_zero_result_behavior(oracles: dict[str, Any]) -> dict[str, Any]:
+ """Count zero-result answers across the battery.
+
+ Behavioral-only probes carry no judgments, so score_quality_oracles marks them
+ not-applicable and they contribute nothing to MRR. They still carry the signal the
+ recovered workload showed most often: search_code is 8% of real calls but ~70% of
+ all zero-result failures, and identical calls returned zero non-deterministically
+ (max_hits_per_page returned zero 18 of 54 times against a fixed index).
+ """
+ total = 0
+ zero = 0
+ zero_ids: list[str] = []
+ for name, oracle in oracles.items():
+ if not isinstance(oracle, dict) or "response" not in oracle:
+ continue
+ total += 1
+ ranked = ranked_items_from_response(oracle.get("response"))
+ if ranked is not None and not ranked:
+ zero += 1
+ zero_ids.append(name)
+ return {
+ "query_count": total,
+ "zero_result_count": zero,
+ "zero_result_rate": (zero / total) if total else None,
+ "zero_result_queries": sorted(zero_ids),
+ }
+
+
+def summarize_scorer_variant_quality(oracles: dict[str, Any]) -> dict[str, Any]:
+ """Aggregate paired graded-query quality by search_graph rank mode."""
+ grouped: dict[str, list[dict[str, Any]]] = {}
+ for oracle in oracles.values():
+ if not isinstance(oracle, dict):
+ continue
+ for scorer, variant in (oracle.get("scorer_variants") or {}).items():
+ quality = variant.get("quality") if isinstance(variant, dict) else None
+ if isinstance(quality, dict):
+ grouped.setdefault(scorer, []).append(quality)
+ summary: dict[str, Any] = {}
+ for scorer, rows in sorted(grouped.items()):
+ ndcg = [
+ float(row["ndcg"])
+ for row in rows
+ if isinstance(row.get("ndcg"), (int, float))
+ ]
+ reciprocal_rank = [
+ float(row["reciprocal_rank"])
+ for row in rows
+ if isinstance(row.get("reciprocal_rank"), (int, float))
+ ]
+ summary[scorer] = {
+ "query_count": len(rows),
+ "mean_ndcg": statistics.fmean(ndcg) if ndcg else None,
+ "mean_reciprocal_rank": (
+ statistics.fmean(reciprocal_rank) if reciprocal_rank else None
+ ),
+ "hit_at_1_rate": (
+ sum(bool(row.get("hit_at_1")) for row in rows) / len(rows)
+ if rows
+ else None
+ ),
+ }
+ return summary
+
+
+def run_rank_quality_oracles(
+ transport: str,
+ binary: Path,
+ env: dict[str, str],
+ project: str,
+ args: argparse.Namespace,
+ client: McpClient | None = None,
+) -> dict[str, Any]:
+ battery = rank_battery_with_overlay_control(
+ load_rank_query_battery(
+ getattr(args, "rank_query_manifest", "") or "",
+ getattr(args, "corpus", "") or "synthetic-rank-v1",
+ ),
+ overlay_active=bool(getattr(args, "rank_overlay_active", False)),
+ )
+ oracles: dict[str, Any] = {}
+ expectations: dict[str, Any] = {}
+ for query in battery:
+ arguments = {"project": project, **query["arguments"]}
+ repetitions = int(query.get("repetitions", 1))
+ oracle = run_tool_call_for_transport(
+ transport,
+ binary,
+ env,
+ query["tool"],
+ arguments,
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ if repetitions > 1:
+ # Some recovered calls returned results and zero results non-deterministically
+ # against a fixed index (max_hits_per_page: zero 18 of 54 times). A single
+ # call cannot see that, so repeat and record the spread. The first response is
+ # kept as the scored one so graded metrics stay comparable to a 1-rep run.
+ counts = [count_ranked_items(oracle.get("response"))]
+ for _ in range(repetitions - 1):
+ repeat = run_tool_call_for_transport(
+ transport,
+ binary,
+ env,
+ query["tool"],
+ arguments,
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ counts.append(count_ranked_items(repeat.get("response")))
+ observed = [value for value in counts if value is not None]
+ oracle["repetition_stability"] = {
+ "repetitions": repetitions,
+ "result_counts": counts,
+ "zero_result_repetitions": sum(1 for value in observed if value == 0),
+ "distinct_result_counts": len(set(observed)),
+ "stable": len(set(observed)) <= 1,
+ }
+ # fact_step_rows walks the report for any dict carrying elapsed_ms and emits a
+ # timing fact keyed by this query id, so latency, payload bytes and token
+ # estimates are already published. Only the query's identity is missing, so
+ # record that on the oracle rather than building a parallel measurement list.
+ oracle["query"] = {
+ "id": query["id"],
+ "family": query.get("family"),
+ "tool": query["tool"],
+ "arguments": dict(sorted(query["arguments"].items())),
+ "graded": bool(query.get("judgments")),
+ "behavioral_only": bool(query.get("behavioral_only")),
+ }
+ oracles[query["id"]] = oracle
+ judgments = query.get("judgments") or []
+ if judgments:
+ expectations[query["id"]] = {
+ "criterion": query.get("criterion", query["id"]),
+ "cutoff": query.get("cutoff", 5),
+ "judgments": judgments,
+ }
+ if (
+ getattr(args, "rank_query_manifest", "")
+ and query["tool"] == "search_graph"
+ and judgments
+ and "sort_by" not in query["arguments"]
+ ):
+ variants: dict[str, Any] = {}
+ for sort_by, scorer in RANK_QUERY_SORT_VARIANTS:
+ variant = (
+ {**oracle}
+ if sort_by == "relevance"
+ else run_tool_call_for_transport(
+ transport,
+ binary,
+ env,
+ query["tool"],
+ {**arguments, "sort_by": sort_by},
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ )
+ ranked = ranked_items_from_response(variant.get("response")) or []
+ variant["sort_by"] = sort_by
+ variant["scorer"] = scorer
+ variant["quality"] = score_ranked_relevance(
+ ranked, judgments, cutoff=int(query.get("cutoff", 5))
+ )
+ variants[scorer] = variant
+ oracle["scorer_variants"] = variants
+ quality = score_quality_oracles(oracles, expectations)
+ behavior = summarize_zero_result_behavior(oracles)
+ scorer_variant_quality = summarize_scorer_variant_quality(oracles)
+ oracles["quality"] = quality
+ oracles["scorer_variant_quality"] = scorer_variant_quality
+ oracles["zero_result_behavior"] = behavior
+ oracles["rank_query_battery"] = {
+ "query_count": len(battery),
+ "graded_count": len(expectations),
+ "behavioral_only_count": len(battery) - len(expectations),
+ "rank_sort_variant_query_count": sum(
+ len(oracle.get("scorer_variants") or {})
+ for oracle in oracles.values()
+ if isinstance(oracle, dict)
+ ),
+ "query_ids": [query["id"] for query in battery],
+ }
+ oracles["passed"] = quality["passed"]
+ return oracles
+
+
+def run_dependency_quality_oracles(
+ transport: str,
+ binary: Path,
+ env: dict[str, str],
+ project: str,
+ args: argparse.Namespace,
+ client: McpClient | None = None,
+) -> dict[str, Any]:
+ symbol = "canonicalDependencyAPI"
+ package_name = "cbmbenchdep"
+ oracles = {
+ "dependency_api_search": run_tool_call_for_transport(
+ transport,
+ binary,
+ env,
+ "search_graph",
+ {
+ "project": project,
+ "label": "Function",
+ "name_pattern": symbol,
+ "include_dependencies": True,
+ "limit": 10,
+ },
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ }
+ expectations = {
+ "dependency_api_search": {
+ "criterion": (
+ "retrieve the imported dependency API with dependency, package, and read-only "
+ "provenance on the same result"
+ ),
+ "cutoff": 5,
+ "judgments": [
+ {
+ "expected_substring": symbol,
+ "required_substrings": [
+ '"source":"dependency"',
+ f'"package":"{package_name}"',
+ '"read_only":true',
+ ],
+ "relevance": 3,
+ }
+ ],
+ }
+ }
+ quality = score_quality_oracles(oracles, expectations)
+ oracles["quality"] = quality
+ oracles["passed"] = quality["passed"]
+ return oracles
+
+
+def run_git_history_quality_oracles(
+ transport: str,
+ binary: Path,
+ env: dict[str, str],
+ project: str,
+ args: argparse.Namespace,
+ client: McpClient | None = None,
+) -> dict[str, Any]:
+ oracles = {
+ "file_change_coupling": run_tool_call_for_transport(
+ transport,
+ binary,
+ env,
+ "query_graph",
+ {
+ "project": project,
+ "query": (
+ "MATCH (a)-[r:FILE_CHANGES_WITH]->(b) "
+ "RETURN a.file_path, b.file_path, r.co_changes, r.coupling_score LIMIT 10"
+ ),
+ },
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ }
+ quality = score_quality_oracles(
+ oracles,
+ {
+ "file_change_coupling": {
+ "criterion": (
+ "retrieve the declared four-commit alpha.py/beta.py co-change relationship"
+ ),
+ "cutoff": 5,
+ "judgments": [
+ {
+ "expected_substring": "alpha.py",
+ "required_substrings": ["beta.py", '"4"', '"1.00"'],
+ "relevance": 3,
+ }
+ ],
+ }
+ },
+ )
+ oracles["quality"] = quality
+ oracles["passed"] = quality["passed"]
+ return oracles
+
+
+def run_http_links_quality_oracles(
+ transport: str,
+ binary: Path,
+ env: dict[str, str],
+ project: str,
+ args: argparse.Namespace,
+ client: McpClient | None = None,
+) -> dict[str, Any]:
+ oracles = {
+ "http_call_link": run_tool_call_for_transport(
+ transport,
+ binary,
+ env,
+ "query_graph",
+ {
+ "project": project,
+ "query": (
+ "MATCH (a)-[r:HTTP_CALLS]->(b) "
+ "WHERE b.name = 'configureRouting' "
+ "RETURN a.name, b.name, r.url_path, r.confidence LIMIT 10"
+ ),
+ },
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ }
+ quality = score_quality_oracles(
+ oracles,
+ {
+ "http_call_link": {
+ "criterion": (
+ "retrieve the fetch_order HTTP client link to the declared order route"
+ ),
+ "cutoff": 5,
+ "judgments": [
+ {
+ "expected_substring": "/api/cbmbench-orders/42",
+ "required_substrings": ["fetch_order", "configureRouting"],
+ "relevance": 3,
+ }
+ ],
+ }
+ },
+ )
+ oracles["quality"] = quality
+ oracles["passed"] = quality["passed"]
+ return oracles
+
+
+def observed_pairs_from_query_response(
+ tool_result: dict[str, Any],
+) -> list[dict[str, Any]]:
+ response = tool_result.get("response")
+ if not isinstance(response, dict):
+ return []
+ columns = response.get("columns")
+ rows = response.get("rows")
+ if not isinstance(columns, list) or not isinstance(rows, list):
+ return []
+ column_names = [str(value) for value in columns]
+ observed: list[dict[str, Any]] = []
+ for row in rows:
+ if not isinstance(row, list) or len(row) < 2:
+ continue
+ score = row[2] if len(row) > 2 else None
+ if isinstance(score, str):
+ with suppress(ValueError):
+ score = float(score)
+ values = {
+ column_names[index]: value
+ for index, value in enumerate(row)
+ if index < len(column_names)
+ }
+ observed.append(
+ {
+ "source": str(row[0]),
+ "target": str(row[1]),
+ "score": score,
+ "source_path": row[3] if len(row) > 3 else None,
+ "target_path": row[4] if len(row) > 4 else None,
+ "row": values,
+ }
+ )
+ return observed
+
+
+def compare_pair_oracle_outputs(
+ incremental: dict[str, Any], fresh: dict[str, Any]
+) -> dict[str, Any]:
+ def canonical(output: dict[str, Any]) -> set[tuple[str, str, float | str | None]]:
+ result: set[tuple[str, str, float | str | None]] = set()
+ for item in output.get("observed_pairs", []):
+ source, target = canonical_pair(item.get("source"), item.get("target"))
+ result.add((source, target, item.get("score")))
+ return result
+
+ incremental_pairs = canonical(incremental)
+ fresh_pairs = canonical(fresh)
+
+ def render(
+ values: set[tuple[str, str, float | str | None]],
+ ) -> list[dict[str, Any]]:
+ return [
+ {"source": source, "target": target, "score": score}
+ for source, target, score in sorted(values)
+ ]
+
+ return {
+ "passed": incremental_pairs == fresh_pairs,
+ "incremental_only": render(incremental_pairs - fresh_pairs),
+ "fresh_only": render(fresh_pairs - incremental_pairs),
+ "incremental_pair_count": len(incremental_pairs),
+ "fresh_pair_count": len(fresh_pairs),
+ }
+
+
+def evaluate_pair_incremental_policy(
+ config_overrides: dict[str, str],
+ incremental_index: dict[str, Any],
+ incremental_oracles: dict[str, Any],
+ canonical_graph: dict[str, Any],
+ pair_equality: dict[str, Any],
+) -> dict[str, Any]:
+ explicit_policy = config_overrides.get("incremental_derived_results_refresh")
+ policy = explicit_policy or DERIVED_REFRESH_CANDIDATE_DEFAULT
+ policy_source = "explicit_override" if explicit_policy else "candidate_default"
+ warnings = (
+ incremental_oracles.get("edge_query", {})
+ .get("response", {})
+ .get("warnings", [])
+ )
+ warnings = warnings if isinstance(warnings, list) else []
+ stale_warning_present = any(
+ isinstance(warning, str) and "semantic_edges derived view is stale" in warning
+ for warning in warnings
+ )
+ pair_freshness_met = bool(
+ incremental_oracles.get("passed") and pair_equality.get("passed")
+ )
+ immediate_freshness_met = bool(pair_freshness_met and canonical_graph.get("equal"))
+ if explicit_policy:
+ immediate_freshness_expected: bool | None = policy == "at_publish"
+ policy_conformance_met = (
+ immediate_freshness_met and not stale_warning_present
+ if immediate_freshness_expected
+ else immediate_freshness_met or stale_warning_present
+ )
+ observed_behavior = (
+ "immediate_full_freshness"
+ if immediate_freshness_met and not stale_warning_present
+ else "deferred_with_warning"
+ if stale_warning_present
+ else "unreported_stale"
+ )
+ elif stale_warning_present:
+ immediate_freshness_expected = False
+ policy_conformance_met = True
+ observed_behavior = "deferred_with_warning"
+ elif pair_freshness_met:
+ immediate_freshness_expected = True
+ policy_conformance_met = True
+ observed_behavior = (
+ "immediate_full_freshness"
+ if immediate_freshness_met
+ else "immediate_pair_freshness"
+ )
+ else:
+ immediate_freshness_expected = None
+ policy_conformance_met = False
+ observed_behavior = "unreported_stale"
+ return {
+ "policy": policy,
+ "policy_source": policy_source,
+ "observed_behavior": observed_behavior,
+ "publish_kind": incremental_index.get("publish_kind"),
+ "immediate_freshness_expected": immediate_freshness_expected,
+ "pair_freshness_met": pair_freshness_met,
+ "immediate_freshness_met": immediate_freshness_met,
+ "stale_warning_present": stale_warning_present,
+ "policy_conformance_met": policy_conformance_met,
+ "interpretation": (
+ "at_publish policy requires canonical fresh semantic/similarity results"
+ if explicit_policy == "at_publish"
+ else "explicit deferred policy requires a stale warning or canonical freshness"
+ if explicit_policy
+ else "candidate default is classified from observed pair freshness and warnings"
+ ),
+ }
+
+
+def run_relation_quality_oracles(
+ transport: str,
+ binary: Path,
+ env: dict[str, str],
+ project: str,
+ fixture: dict[str, Any],
+ args: argparse.Namespace,
+ client: McpClient | None = None,
+) -> dict[str, Any]:
+ relationship = str(fixture["relationship"])
+ score_property = str(fixture["score_property"])
+ marker = str(fixture["query_name_marker"])
+ query = (
+ f"MATCH (a)-[r:{relationship}]->(b) "
+ f"WHERE a.name CONTAINS '{marker}' OR b.name CONTAINS '{marker}' "
+ f"RETURN a.name, b.name, r.{score_property}, a.file_path, b.file_path LIMIT 1000"
+ )
+ edge_query = run_tool_call_for_transport(
+ transport,
+ binary,
+ env,
+ "query_graph",
+ {
+ "project": project,
+ "query": query,
+ "format": "json",
+ "max_output_bytes": 1024 * 1024,
+ },
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ observed_pairs = observed_pairs_from_query_response(edge_query)
+ pair_classification = score_pair_classification(
+ observed_pairs,
+ list(fixture["judgments"]),
+ )
+ true_positive_witnesses = pair_classification["witnesses"]["tp"]
+ score_witness_count = sum(
+ 1
+ for witness in true_positive_witnesses
+ if isinstance(witness.get("observed"), dict)
+ and isinstance(witness["observed"].get("score"), (int, float))
+ )
+ score_coverage = (
+ score_witness_count / len(true_positive_witnesses)
+ if true_positive_witnesses
+ else None
+ )
+ response = edge_query.get("response")
+ response_quality = {
+ "correctness": pair_classification["passed"],
+ "relevance": pair_classification["precision"],
+ "completeness": pair_classification["recall"],
+ "actionable_witness_score_coverage": score_coverage,
+ "protocol_shape_valid": (
+ isinstance(response, dict)
+ and isinstance(response.get("columns"), list)
+ and isinstance(response.get("rows"), list)
+ ),
+ "truncated": response.get("truncated") if isinstance(response, dict) else None,
+ "elapsed_ms": edge_query.get("elapsed_ms"),
+ "response_bytes": edge_query.get("response_bytes"),
+ "response_token_estimate": edge_query.get("response_token_estimate"),
+ "hard_gate": (
+ pair_classification["passed"]
+ and score_coverage == 1.0
+ and isinstance(response, dict)
+ and isinstance(response.get("rows"), list)
+ and not bool(response.get("truncated"))
+ ),
+ }
+ return {
+ "relationship": relationship,
+ "edge_query": edge_query,
+ "observed_pairs": observed_pairs,
+ "pair_classification": pair_classification,
+ "response_quality": response_quality,
+ "passed": response_quality["hard_gate"],
+ }
+
+
+def run_index_for_transport(
+ transport: str,
+ binary: Path,
+ env: dict[str, str],
+ repo_dir: Path,
+ timeout: int,
+ include_logs: bool,
+ client: McpClient | None = None,
+ index_mode: str = "fast",
+) -> dict[str, Any]:
+ if transport == "mcp":
+ if client is None:
+ raise RuntimeError("MCP transport requires an active client")
+ return run_index_mcp(client, repo_dir, include_logs, index_mode)
+ return run_index(binary, env, repo_dir, timeout, include_logs, index_mode)
+
+
+def run_pair_quality_lifecycle(
+ args: argparse.Namespace,
+ binary: Path,
+ case_env: dict[str, str],
+ repo_dir: Path,
+ cache_dir: Path,
+ work_root: Path,
+ fixture: dict[str, Any],
+) -> dict[str, Any]:
+ run_config_set(binary, case_env, "incremental_reindex", "always", args.timeout)
+ if args.transport == "mcp":
+ with McpClient(binary, case_env, args.timeout) as client:
+ initial_index = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ client,
+ index_mode=args.index_mode,
+ )
+ project = str(initial_index.get("response", {}).get("project") or "repo")
+ initial_oracles = run_relation_quality_oracles(
+ args.transport, binary, case_env, project, fixture, args, client
+ )
+ initial_graph_fingerprint = stable_graph_fingerprint(
+ find_project_db(cache_dir), project
+ )
+ mutation = apply_pair_quality_mutation(repo_dir, fixture)
+ incremental_index = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ client,
+ index_mode=args.index_mode,
+ )
+ post_fixture = {**fixture, "judgments": mutation["post_judgments"]}
+ incremental_oracles = run_relation_quality_oracles(
+ args.transport, binary, case_env, project, post_fixture, args, client
+ )
+ else:
+ initial_index = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ index_mode=args.index_mode,
+ )
+ project = str(initial_index.get("response", {}).get("project") or "repo")
+ initial_oracles = run_relation_quality_oracles(
+ args.transport, binary, case_env, project, fixture, args
+ )
+ initial_graph_fingerprint = stable_graph_fingerprint(
+ find_project_db(cache_dir), project
+ )
+ mutation = apply_pair_quality_mutation(repo_dir, fixture)
+ incremental_index = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ index_mode=args.index_mode,
+ )
+ post_fixture = {**fixture, "judgments": mutation["post_judgments"]}
+ incremental_oracles = run_relation_quality_oracles(
+ args.transport, binary, case_env, project, post_fixture, args
+ )
+
+ incremental_db = find_project_db(cache_dir)
+ incremental_snapshot = work_root / "incremental.db"
+ copy_sqlite_snapshot(incremental_db, incremental_snapshot)
+
+ fresh_cache = work_root / "fresh-cache"
+ fresh_cache.mkdir(parents=True, exist_ok=True)
+ fresh_env = build_env(fresh_cache, args.product_environment)
+ apply_rank_refresh_override(binary, fresh_env, args.rank_refresh, args.timeout)
+ apply_config_overrides(binary, fresh_env, args.config_overrides, args.timeout)
+ if args.transport == "mcp":
+ with McpClient(binary, fresh_env, args.timeout) as client:
+ fresh_index = run_index_for_transport(
+ args.transport,
+ binary,
+ fresh_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ client,
+ index_mode=args.index_mode,
+ )
+ fresh_project = str(
+ fresh_index.get("response", {}).get("project") or project
+ )
+ fresh_oracles = run_relation_quality_oracles(
+ args.transport,
+ binary,
+ fresh_env,
+ fresh_project,
+ post_fixture,
+ args,
+ client,
+ )
+ else:
+ fresh_index = run_index_for_transport(
+ args.transport,
+ binary,
+ fresh_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ index_mode=args.index_mode,
+ )
+ fresh_project = str(fresh_index.get("response", {}).get("project") or project)
+ fresh_oracles = run_relation_quality_oracles(
+ args.transport, binary, fresh_env, fresh_project, post_fixture, args
+ )
+ fresh_db = find_project_db(fresh_cache)
+ incremental_graph_fingerprint = stable_graph_fingerprint(
+ incremental_snapshot, project
+ )
+ fresh_graph_fingerprint = stable_graph_fingerprint(fresh_db, fresh_project)
+ canonical_graph = compare_canonical_graph(incremental_snapshot, fresh_db, project)
+ pair_equality = compare_pair_oracle_outputs(incremental_oracles, fresh_oracles)
+ incremental_policy = evaluate_pair_incremental_policy(
+ args.config_overrides,
+ incremental_index,
+ incremental_oracles,
+ canonical_graph,
+ pair_equality,
+ )
+ return {
+ "project": project,
+ "initial_index": initial_index,
+ "initial_oracles": initial_oracles,
+ "mutation": mutation,
+ "incremental_index": incremental_index,
+ "incremental_oracles": incremental_oracles,
+ "fresh_index": fresh_index,
+ "fresh_oracles": fresh_oracles,
+ "graph_fingerprints": {
+ "initial": initial_graph_fingerprint,
+ "incremental": incremental_graph_fingerprint,
+ "fresh": fresh_graph_fingerprint,
+ },
+ "canonical_graph": canonical_graph,
+ "pair_equality": pair_equality,
+ "incremental_policy": incremental_policy,
+ "policy_conformance_met": incremental_policy["policy_conformance_met"],
+ "quality_target_met": bool(
+ initial_oracles.get("passed")
+ and incremental_oracles.get("passed")
+ and fresh_oracles.get("passed")
+ and canonical_graph.get("equal")
+ and pair_equality.get("passed")
+ ),
+ }
+
+
+def run_capability_quality(
+ args: argparse.Namespace, binary: Path
+) -> tuple[dict[str, Any], int]:
+ capability = args.capability_quality
+ if capability not in CAPABILITY_QUALITY_CASES:
+ raise ValueError(f"unsupported capability quality case: {capability}")
+ auto_root = not bool(args.work_root)
+ work_root = (
+ Path(args.work_root).expanduser()
+ if args.work_root
+ else Path(tempfile.mkdtemp(prefix=f"cbm-quality-{capability}-"))
+ )
+ repo_dir = work_root / "repo"
+ cache_dir = work_root / "cache"
+ repo_dir.mkdir(parents=True, exist_ok=True)
+ cache_dir.mkdir(parents=True, exist_ok=True)
+ case_env = build_env(cache_dir, args.product_environment)
+ report: dict[str, Any] = {
+ "generated_at_utc": datetime.now(timezone.utc).isoformat(),
+ "binary": str(binary),
+ "binary_metadata": binary_metadata(binary),
+ "work_root": str(work_root),
+ "mode": "capability_quality",
+ "parameters": {
+ "capability": capability,
+ "rank_refresh": args.rank_refresh,
+ "rank_refresh_override_applied": (
+ args.rank_refresh != RANK_REFRESH_CANDIDATE_DEFAULT
+ ),
+ "index_mode": args.index_mode,
+ "capability_applicability": index_mode_capability_applicability(
+ args.index_mode
+ ),
+ "config_profile": args.config_profile,
+ "config_overrides": args.config_overrides,
+ "configuration_environment": benchmark_environment_policy(
+ args.product_environment
+ ),
+ "transport": args.transport,
+ "timeout": args.timeout,
+ "quality_background_repo": args.quality_background_repo or None,
+ "quality_background_revision": (
+ (args.quality_background_revision or "HEAD")
+ if args.quality_background_repo
+ else None
+ ),
+ # These three select what was measured, so they belong in the identity that
+ # feeds run_id. Without them two corpora resolving to the same background
+ # path, or two different query batteries, would hash identically.
+ "corpus": getattr(args, "corpus", "") or None,
+ "corpus_manifest_sha256": manifest_digest(
+ getattr(args, "corpus_manifest", "") or None, DEFAULT_CORPORA_MANIFEST
+ ),
+ "rank_query_manifest_sha256": manifest_digest(
+ getattr(args, "rank_query_manifest", "") or None, None
+ ),
+ },
+ "cleanup": {
+ "requested": auto_root and not args.keep_work_root,
+ "removed": False,
+ },
+ "cases": [],
+ }
+ exit_code = 1
+ try:
+ background = None
+ # `--corpus ` alone is enough: the registry supplies the URL, the pinned
+ # commit and the expected tree, so the caller does not have to restate them as
+ # --quality-background-repo/--revision and cannot accidentally disagree with the
+ # registry. An explicit --quality-background-repo still wins, for one-off runs.
+ corpus_id = getattr(args, "corpus", "") or ""
+ corpus_entry = None
+ expected_tree = None
+ if corpus_id and corpus_id != "synthetic-rank-v1":
+ registry = load_corpora_manifest(getattr(args, "corpus_manifest", ""))
+ if corpus_id not in registry:
+ raise ValueError(
+ f"corpus {corpus_id!r} is absent from the corpus registry; "
+ f"known: {', '.join(sorted(registry))}"
+ )
+ corpus_entry = registry[corpus_id]
+ if not args.quality_background_repo and corpus_entry.get("url"):
+ source = resolve_corpus_source(
+ corpus_id,
+ corpus_entry["url"],
+ corpus_entry["revision"],
+ args,
+ )
+ verify_corpus_pin(source, corpus_entry, args.timeout)
+ args.quality_background_repo = str(source)
+ args.quality_background_revision = corpus_entry["revision"]
+ expected_tree = corpus_entry.get("tree")
+ if args.quality_background_revision and not args.quality_background_repo:
+ raise ValueError(
+ "--quality-background-revision requires --quality-background-repo"
+ )
+ if args.quality_background_repo:
+ if capability not in QUALITY_BACKGROUND_CAPABILITIES:
+ raise ValueError(
+ "quality background repository is supported only for "
+ + ", ".join(sorted(QUALITY_BACKGROUND_CAPABILITIES))
+ )
+ background = copy_git_revision_to_dir(
+ Path(args.quality_background_repo).expanduser(),
+ repo_dir,
+ args.quality_background_revision or "HEAD",
+ args.timeout,
+ excluded_prefixes=("benchmarks/semantic-pairs-v1/",),
+ )
+ # The tree copy_git_revision_to_dir resolved is what git archive actually
+ # materialized, so this validates the bytes the experiment indexed rather
+ # than whatever HEAD happened to point at.
+ if expected_tree and background.get("tree") != expected_tree:
+ raise ValueError(
+ f"corpus {corpus_id!r} materialized tree {background.get('tree')}, "
+ f"registry pins {expected_tree}"
+ )
+ fixture_factory = {
+ "rank": create_rank_quality_repo,
+ "dependencies": create_dependency_quality_repo,
+ "similarity": create_similarity_quality_repo,
+ "semantic_edges": create_semantic_edges_quality_repo,
+ "git_history": create_git_history_quality_repo,
+ "http_links": create_http_links_quality_repo,
+ }[capability]
+ overlay = rank_fixture_overlay_decision(capability, background, args)
+ if overlay == "suppressed":
+ # Index exactly the pinned tree. Recorded either way so a reader of the
+ # result JSON never has to infer which bytes were scored.
+ fixture = {
+ "fixture_version": 1,
+ "capability": capability,
+ "language": "corpus",
+ "ranking_signal": "the corpus's own call graph",
+ }
+ else:
+ fixture = fixture_factory(repo_dir)
+ fixture["corpus_overlay"] = overlay
+ args.rank_overlay_active = overlay == "overlaid"
+ apply_rank_refresh_override(binary, case_env, args.rank_refresh, args.timeout)
+ apply_config_overrides(binary, case_env, args.config_overrides, args.timeout)
+ lifecycle = None
+ if capability in {"similarity", "semantic_edges"}:
+ lifecycle = run_pair_quality_lifecycle(
+ args, binary, case_env, repo_dir, cache_dir, work_root, fixture
+ )
+ indexed = lifecycle["initial_index"]
+ project = lifecycle["project"]
+ oracles = lifecycle["initial_oracles"]
+ elif args.transport == "mcp":
+ with McpClient(binary, case_env, args.timeout) as client:
+ indexed = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ client,
+ index_mode=args.index_mode,
+ )
+ project = str(indexed.get("response", {}).get("project") or "repo")
+ oracle_runner = {
+ "rank": run_rank_quality_oracles,
+ "dependencies": run_dependency_quality_oracles,
+ "git_history": run_git_history_quality_oracles,
+ "http_links": run_http_links_quality_oracles,
+ }[capability]
+ oracles = oracle_runner(
+ args.transport, binary, case_env, project, args, client
+ )
+ else:
+ indexed = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ index_mode=args.index_mode,
+ )
+ project = str(indexed.get("response", {}).get("project") or "repo")
+ oracle_runner = {
+ "rank": run_rank_quality_oracles,
+ "dependencies": run_dependency_quality_oracles,
+ "git_history": run_git_history_quality_oracles,
+ "http_links": run_http_links_quality_oracles,
+ }[capability]
+ oracles = oracle_runner(args.transport, binary, case_env, project, args)
+ case = {
+ "scenario": f"{capability}_quality",
+ "project": project,
+ "fixture": fixture,
+ "background_repository": background,
+ "initial_fast_full": indexed,
+ "oracles": oracles,
+ "corpus": (
+ {
+ "id": corpus_id,
+ "repo": corpus_entry.get("repo"),
+ "revision": corpus_entry.get("revision"),
+ "tree": corpus_entry.get("tree"),
+ "cohort": corpus_entry.get("cohort"),
+ "language": corpus_entry.get("language"),
+ "discriminates": corpus_entry.get("discriminates"),
+ }
+ if corpus_entry
+ else None
+ ),
+ # Both are rank-specific: staleness of the ranking views only bears on a
+ # ranking measurement, and the probes read the ranking tables.
+ "rank_score_staleness": (
+ rank_score_staleness(cache_dir, project, oracles)
+ if capability == "rank"
+ else None
+ ),
+ "rank_score_probes": (
+ run_rank_score_probes(
+ cache_dir,
+ project,
+ python_exports=python_public_exports(
+ Path(args.quality_background_repo).expanduser()
+ )
+ if args.quality_background_repo
+ else frozenset(),
+ scaffolding_paths=(
+ load_scaffolding_paths(corpus_id, args.labels_dir)
+ if getattr(args, "labels_dir", "")
+ else derive_scaffolding_paths(
+ corpus_id,
+ Path(args.quality_background_repo).expanduser()
+ if args.quality_background_repo
+ else None,
+ args.timeout,
+ )
+ ),
+ )
+ if capability == "rank"
+ else None
+ ),
+ # Cheap enough to always emit on a rank run (one indexed scan of the
+ # published table), and it is the only way a later cell comparison can tell
+ # an inert config knob from one that genuinely does not help.
+ "rank_table_fingerprint": (
+ rank_table_fingerprint(cache_dir, project)
+ if capability == "rank"
+ else None
+ ),
+ # Coverage is not rank-specific in principle, but only a corpus run has a
+ # registry prediction to score, and only a real tree has directories worth
+ # attributing. Emitted whenever a corpus was materialized.
+ "corpus_coverage": (
+ run_corpus_coverage_probe(
+ cache_dir,
+ project,
+ predicted_loss=(corpus_entry or {}).get("predicted_loss"),
+ index_mode=args.index_mode,
+ )
+ if corpus_entry
+ else None
+ ),
+ "pair_lifecycle": lifecycle,
+ "execution_passed": True,
+ "quality_target_met": (
+ bool(lifecycle["quality_target_met"])
+ if lifecycle is not None
+ else bool(oracles.get("passed"))
+ ),
+ "passed": True,
+ }
+ report["cases"].append(case)
+ report["derived"] = {
+ "passed": True,
+ "quality_target_met": case["quality_target_met"],
+ "case_count": 1,
+ }
+ exit_code = 0
+ except Exception as exc:
+ record_report_error(report, exc)
+ finally:
+ if auto_root and not args.keep_work_root:
+ shutil.rmtree(work_root, ignore_errors=True)
+ report["cleanup"]["removed"] = not work_root.exists()
+ emit_report(report, args)
+ return report, exit_code
+
+
+def run_matrix_case(
+ scenario: str,
+ binary: Path,
+ env: dict[str, str],
+ case_root: Path,
+ args: argparse.Namespace,
+) -> dict[str, Any]:
+ repo_dir = case_root / "repo"
+ cache_dir = case_root / "cache"
+ case_root.mkdir(parents=True, exist_ok=True)
+ if scenario not in MATRIX_REAL_REPO_SCENARIOS:
+ repo_dir.mkdir(parents=True, exist_ok=True)
+ cache_dir.mkdir(parents=True, exist_ok=True)
+ case_env = dict(env)
+ case_env["CBM_CACHE_DIR"] = str(cache_dir)
+ run_config_set(binary, case_env, "incremental_reindex", "always", args.timeout)
+ apply_rank_refresh_override(binary, case_env, args.rank_refresh, args.timeout)
+ apply_config_overrides(binary, case_env, args.config_overrides, args.timeout)
+
+ scenario_metadata = prepare_matrix_scenario(
+ scenario, repo_dir, args.files, args.functions_per_file, args, case_root
+ )
+ if args.transport == "mcp":
+ with McpClient(binary, case_env, args.timeout) as client:
+ initial = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ client,
+ index_mode=args.index_mode,
+ )
+ changed_paths = mutate_matrix_scenario(
+ scenario, repo_dir, args.functions_per_file
+ )
+ incremental = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ client,
+ index_mode=args.index_mode,
+ )
+ else:
+ initial = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ index_mode=args.index_mode,
+ )
+ changed_paths = mutate_matrix_scenario(
+ scenario, repo_dir, args.functions_per_file
+ )
+ incremental = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ index_mode=args.index_mode,
+ )
+
+ project_db = find_project_db(cache_dir)
+ project = str(incremental.get("response", {}).get("project") or project_db.stem)
+ incremental_snapshot = case_root / "incremental.db"
+ copy_sqlite_snapshot(project_db, incremental_snapshot)
+ removed_dbs = remove_project_dbs(cache_dir)
+
+ if args.transport == "mcp":
+ with McpClient(binary, case_env, args.timeout) as client:
+ full_rebuild = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ client,
+ index_mode=args.index_mode,
+ )
+ else:
+ full_rebuild = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ index_mode=args.index_mode,
+ )
+
+ full_db = find_project_db(cache_dir)
+ canonical = compare_canonical_graph(incremental_snapshot, full_db, project)
+ incremental_reason = incremental.get("exact_reason")
+ publish_kind = incremental.get("publish_kind")
+ active_overlay = None
+ if publish_kind == PUBLISH_INCREMENTAL_OVERLAY:
+ active_overlay = compare_active_overlay_graph(
+ incremental_snapshot, full_db, project
+ )
+ graph_gate = graph_gate_for_publish_kind(
+ canonical, str(publish_kind or ""), active_overlay=active_overlay
+ )
+ configured_cap = args.config_overrides.get("incremental_exact_max_affected_paths")
+ try:
+ exact_cap = int(configured_cap) if configured_cap is not None else None
+ except ValueError:
+ exact_cap = None
+ frontier_gate = frontier_coverage_gate(
+ scenario_metadata, incremental, exact_cap=exact_cap
+ )
+ explicit_route = is_explicit_incremental_route(publish_kind, incremental_reason)
+ passed = (
+ bool(graph_gate.get("passed"))
+ and bool(frontier_gate.get("passed"))
+ and explicit_route
+ )
+ speedup = max(1, int(full_rebuild["elapsed_ms"])) / max(
+ 1, int(incremental["elapsed_ms"])
+ )
+ return {
+ "scenario": scenario,
+ "project": project,
+ "changed_paths": changed_paths,
+ "scenario_metadata": scenario_metadata,
+ "removed_project_dbs": removed_dbs,
+ "initial_fast_full": initial,
+ "incremental": incremental,
+ "fresh_fast_full_after_change": full_rebuild,
+ "canonical_graph": canonical,
+ "active_overlay_graph": active_overlay,
+ "graph_gate": graph_gate,
+ "frontier_coverage_gate": frontier_gate,
+ "explicit_exact_or_fallback": explicit_route,
+ "explicit_incremental_route": explicit_route,
+ "exact_reason": incremental_reason,
+ "speedup_full_rebuild_over_incremental": speedup,
+ "passed": passed,
+ }
+
+
+def run_matrix(args: argparse.Namespace, binary: Path) -> tuple[dict[str, Any], int]:
+ auto_root = not bool(args.work_root)
+ work_root = (
+ Path(args.work_root).expanduser()
+ if args.work_root
+ else Path(tempfile.mkdtemp(prefix="cbm-incr-matrix-"))
+ )
+ work_root.mkdir(parents=True, exist_ok=True)
+ scenarios = [
+ item.strip() for item in args.matrix_scenarios.split(",") if item.strip()
+ ]
+ report: dict[str, Any] = {
+ "generated_at_utc": datetime.now(timezone.utc).isoformat(),
+ "binary": str(binary),
+ "binary_metadata": binary_metadata(binary),
+ "work_root": str(work_root),
+ "mode": "matrix",
+ "parameters": {
+ "files": args.files,
+ "functions_per_file": args.functions_per_file,
+ "frontier_files": args.frontier_files,
+ "rank_refresh": args.rank_refresh,
+ "rank_refresh_override_applied": (
+ args.rank_refresh != RANK_REFRESH_CANDIDATE_DEFAULT
+ ),
+ "index_mode": args.index_mode,
+ "capability_applicability": index_mode_capability_applicability(
+ args.index_mode
+ ),
+ "config_profile": args.config_profile,
+ "config_overrides": args.config_overrides,
+ "configuration_environment": benchmark_environment_policy(
+ args.product_environment
+ ),
+ "timeout": args.timeout,
+ "transport": args.transport,
+ "scenarios": scenarios,
+ },
+ "cleanup": {
+ "requested": auto_root and not args.keep_work_root,
+ "removed": False,
+ },
+ "cases": [],
+ }
+ exit_code = 1
+ try:
+ base_env = build_env(work_root / "cache-base", args.product_environment)
+ for scenario in scenarios:
+ case = run_matrix_case(
+ scenario, binary, base_env, work_root / scenario, args
+ )
+ report["cases"].append(case)
+ report["derived"] = {
+ "passed": all(bool(case.get("passed")) for case in report["cases"]),
+ "case_count": len(report["cases"]),
+ }
+ exit_code = 0 if report["derived"]["passed"] else 1
+ except Exception as exc:
+ record_report_error(report, exc)
+ exit_code = 1
+ finally:
+ if auto_root and not args.keep_work_root:
+ shutil.rmtree(work_root, ignore_errors=True)
+ report["cleanup"]["removed"] = not work_root.exists()
+ emit_report(report, args)
+ return report, exit_code
+
+
+def run_self_dogfood_case(
+ scenario: str,
+ source_repo: Path,
+ binary: Path,
+ case_root: Path,
+ args: argparse.Namespace,
+ revision: str,
+) -> dict[str, Any]:
+ cache_dir = case_root / SELF_DOGFOOD_CACHE_SUBDIR
+ cache_dir.mkdir(parents=True, exist_ok=True)
+ repo_dir = create_self_dogfood_worktree(
+ source_repo, case_root, args.timeout, revision
+ )
+ case_env = build_env(cache_dir, args.product_environment)
+ cleanup: dict[str, Any] = {"requested": not args.keep_work_root, "removed": False}
+ result: dict[str, Any] | None = None
+ try:
+ run_config_set(binary, case_env, "incremental_reindex", "always", args.timeout)
+ apply_rank_refresh_override(binary, case_env, args.rank_refresh, args.timeout)
+ apply_config_overrides(binary, case_env, args.config_overrides, args.timeout)
+ if args.transport == "mcp":
+ with McpClient(binary, case_env, args.timeout) as client:
+ initial = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ client,
+ index_mode=args.index_mode,
+ )
+ project_db = find_project_db(cache_dir)
+ project = str(
+ initial.get("response", {}).get("project") or project_db.stem
+ )
+ indexed_query_probe = measure_indexed_query_probes_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ args.indexed_query_tool,
+ args.indexed_query_probes,
+ project,
+ args.timeout,
+ args.include_logs,
+ client,
+ )
+ mutation = mutate_self_dogfood_scenario(scenario, repo_dir)
+ incremental = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ client,
+ index_mode=args.index_mode,
+ )
+ project = str(incremental.get("response", {}).get("project") or project)
+ oracles = run_self_dogfood_oracles(
+ args.transport, binary, case_env, project, mutation, args, client
+ )
+ else:
+ initial = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ index_mode=args.index_mode,
+ )
+ project_db = find_project_db(cache_dir)
+ project = str(initial.get("response", {}).get("project") or project_db.stem)
+ indexed_query_probe = measure_indexed_query_probes_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ args.indexed_query_tool,
+ args.indexed_query_probes,
+ project,
+ args.timeout,
+ args.include_logs,
+ )
+ mutation = mutate_self_dogfood_scenario(scenario, repo_dir)
+ incremental = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ index_mode=args.index_mode,
+ )
+ project = str(incremental.get("response", {}).get("project") or project)
+ oracles = run_self_dogfood_oracles(
+ args.transport, binary, case_env, project, mutation, args
+ )
+
+ incremental_snapshot = case_root / "incremental.db"
+ copy_sqlite_snapshot(project_db, incremental_snapshot)
+ removed_dbs = remove_project_dbs(cache_dir)
+ if args.transport == "mcp":
+ with McpClient(binary, case_env, args.timeout) as client:
+ full_rebuild = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ client,
+ index_mode=args.index_mode,
+ )
+ else:
+ full_rebuild = run_index_for_transport(
+ args.transport,
+ binary,
+ case_env,
+ repo_dir,
+ args.timeout,
+ args.include_logs,
+ index_mode=args.index_mode,
+ )
+ full_db = find_project_db(cache_dir)
+ canonical = compare_canonical_graph(incremental_snapshot, full_db, project)
+ stale_views = sorted(
+ set(declared_stale_views(oracles))
+ | set(persisted_stale_views(incremental_snapshot, project))
+ )
+ freshness_scoped = compare_graph_excluding_declared_stale_views(
+ incremental_snapshot, full_db, project, stale_views
+ )
+ publish_kind = incremental.get("publish_kind")
+ incremental_reason = incremental.get("exact_reason")
+ active_overlay = None
+ if publish_kind == PUBLISH_INCREMENTAL_OVERLAY:
+ active_overlay = compare_active_overlay_graph(
+ incremental_snapshot, full_db, project
+ )
+ explicit_route = is_explicit_incremental_route(publish_kind, incremental_reason)
+ speedup = max(1, int(full_rebuild["elapsed_ms"])) / max(
+ 1, int(incremental["elapsed_ms"])
+ )
+ graph_gate = graph_gate_for_publish_kind(
+ canonical,
+ str(publish_kind or ""),
+ bool(oracles.get("passed")),
+ active_overlay=active_overlay,
+ freshness_scoped=freshness_scoped,
+ )
+ passed = (
+ bool(graph_gate.get("passed"))
+ and explicit_route
+ and bool(oracles.get("passed"))
+ )
+ result = {
+ "scenario": scenario,
+ "project": project,
+ "repo_dir": str(repo_dir),
+ "mutation": mutation,
+ "removed_project_dbs": removed_dbs,
+ "initial_fast_full": initial,
+ "indexed_query_probe": indexed_query_probe,
+ "incremental": incremental,
+ "fresh_fast_full_after_change": full_rebuild,
+ "canonical_graph": canonical,
+ "freshness_scoped_graph": freshness_scoped,
+ "active_overlay_graph": active_overlay,
+ "graph_gate": graph_gate,
+ "oracles": oracles,
+ "explicit_incremental_route": explicit_route,
+ "exact_reason": incremental_reason,
+ "speedup_full_rebuild_over_incremental": speedup,
+ "passed": passed,
+ }
+ finally:
+ if not args.keep_work_root:
+ cleanup = remove_self_dogfood_worktree(source_repo, repo_dir, args.timeout)
+ if cache_dir.exists() and not args.keep_work_root:
+ shutil.rmtree(cache_dir, ignore_errors=True)
+ cleanup["cache_removed"] = not cache_dir.exists()
+ cleanup["case_root_removed"] = False
+ if not args.keep_work_root and case_root.exists():
+ shutil.rmtree(case_root, ignore_errors=True)
+ cleanup["case_root_removed"] = not case_root.exists()
+ if result is None:
+ raise RuntimeError(f"self-dogfood case did not produce a result: {scenario}")
+ result["cleanup"] = cleanup
+ return result
+
+
+def self_dogfood_scope_manifest(
+ source_revision: str,
+ source_tree: str,
+ scenarios: list[str],
+) -> dict[str, Any]:
+ return {
+ "workload": "self_dogfood",
+ "input_tree": {
+ "revision": source_revision,
+ "tree": source_tree,
+ "identity_source": "git_commit_and_tree_objects",
+ },
+ "mutation_policy": {
+ "kind": "deterministic_named_mutations",
+ "source": "mutate_self_dogfood_scenario",
+ "scenarios": [
+ {
+ "name": scenario,
+ "changed_paths": list(SELF_DOGFOOD_SCENARIO_PATHS[scenario]),
+ }
+ for scenario in scenarios
+ ],
+ },
+ "functions_per_file": {
+ "status": "not_applicable",
+ "reason": "real_repository_workload",
+ },
+ "generated_source_policy": {
+ "kind": "exact_git_tree_plus_deterministic_mutation",
+ "source": "create_self_dogfood_worktree_and_mutate_self_dogfood_scenario",
+ },
+ }
+
+
+def self_dogfood_cache_manifest(args: argparse.Namespace) -> dict[str, Any]:
+ dependency_state = (
+ "disabled_by_explicit_config"
+ if args.config_overrides.get("auto_index_deps") == "false"
+ else "isolated_under_harness_cache_root"
+ )
+ return {
+ "process": {
+ "state": (
+ "persistent_within_lifecycle"
+ if args.transport == "mcp"
+ else "new_per_tool_call"
+ ),
+ "source": "transport_contract",
+ },
+ "repository_graph": {
+ "initial_state": "empty_harness_owned_cache",
+ "reset_procedure": "remove_project_dbs_before_clean_rebuild",
+ },
+ "dependency_artifacts": {
+ "state": dependency_state,
+ "cache_scope": "isolated_per_benchmark_case",
+ },
+ "os_page_cache": {
+ "state": "uncontrolled_by_harness",
+ "measurement_policy": "record_and_compare_only_on_identical_host_manifest",
+ },
+ "sqlite_page_cache": {
+ "state": "candidate_process_local_default",
+ "database_reset": "project_db_files_removed_before_clean_rebuild",
+ },
+ "parser_compiler_cache": {
+ "state": "not_applicable",
+ "reason": "tree_sitter_parsers_are_compiled_into_candidate_binary",
+ },
+ "fixture_cache": {
+ "state": "not_applicable",
+ "reason": "fresh_detached_git_worktree_per_case",
+ },
+ }
+
+
+def run_self_dogfood(
+ args: argparse.Namespace, binary: Path
+) -> tuple[dict[str, Any], int]:
+ auto_root = not bool(args.work_root)
+ work_root = (
+ Path(args.work_root).expanduser()
+ if args.work_root
+ else Path(tempfile.mkdtemp(prefix="cbm-self-dogfood-"))
+ )
+ work_root.mkdir(parents=True, exist_ok=True)
+ source_repo = resolve_git_repo_root(Path(args.repo_root), args.timeout)
+ source_revision = command_stdout(
+ ["git", "rev-parse", f"{args.repo_revision}^{{commit}}"],
+ args.timeout,
+ source_repo,
+ )
+ source_tree = command_stdout(
+ ["git", "rev-parse", f"{source_revision}^{{tree}}"],
+ args.timeout,
+ source_repo,
+ )
+ scenarios = [
+ item.strip() for item in args.self_dogfood_scenarios.split(",") if item.strip()
+ ]
+ for scenario in scenarios:
+ if scenario not in SELF_DOGFOOD_SCENARIO_PATHS:
+ raise ValueError(f"unknown self-dogfood scenario: {scenario}")
+ repository_background = {
+ "repo": str(source_repo),
+ "revision": source_revision,
+ "tree": source_tree,
+ "source_dirty_status_short": command_stdout(
+ ["git", "status", "--short"], args.timeout, source_repo
+ ),
+ "copy_policy": "detached_worktree_from_exact_commit",
+ }
+ report: dict[str, Any] = {
+ "generated_at_utc": datetime.now(timezone.utc).isoformat(),
+ "binary": str(binary),
+ "binary_metadata": binary_metadata(binary),
+ "work_root": str(work_root),
+ "source_repo": str(source_repo),
+ "source_git": git_metadata(source_repo, args.timeout),
+ "repository_background": repository_background,
+ "mode": "self_dogfood",
+ "scope": self_dogfood_scope_manifest(
+ source_revision,
+ source_tree,
+ scenarios,
+ ),
+ "cache": self_dogfood_cache_manifest(args),
+ "parameters": {
+ "rank_refresh": args.rank_refresh,
+ "rank_refresh_override_applied": (
+ args.rank_refresh != RANK_REFRESH_CANDIDATE_DEFAULT
+ ),
+ "index_mode": args.index_mode,
+ "capability_applicability": index_mode_capability_applicability(
+ args.index_mode
+ ),
+ "config_profile": args.config_profile,
+ "config_overrides": args.config_overrides,
+ "configuration_environment": benchmark_environment_policy(
+ args.product_environment
+ ),
+ "timeout": args.timeout,
+ "transport": args.transport,
+ "scenarios": scenarios,
+ "repo_revision": source_revision,
+ "indexed_query_probes": args.indexed_query_probes,
+ "indexed_query_tool": args.indexed_query_tool,
+ },
+ "cleanup": {
+ "requested": auto_root and not args.keep_work_root,
+ "removed": False,
+ },
+ "cases": [],
+ }
+ exit_code = 1
+ try:
+ for scenario in scenarios:
+ case = run_self_dogfood_case(
+ scenario,
+ source_repo,
+ binary,
+ work_root / scenario,
+ args,
+ source_revision,
+ )
+ report["cases"].append(case)
+ report["derived"] = {
+ "passed": all(bool(case.get("passed")) for case in report["cases"]),
+ "case_count": len(report["cases"]),
+ }
+ exit_code = 0 if report["derived"]["passed"] else 1
+ except Exception as exc:
+ record_report_error(report, exc)
+ exit_code = 1
+ finally:
+ if auto_root and not args.keep_work_root:
+ shutil.rmtree(work_root, ignore_errors=True)
+ report["cleanup"]["removed"] = not work_root.exists()
+ emit_report(report, args)
+ return report, exit_code
+
+
+def parse_args() -> argparse.Namespace:
+ parser = argparse.ArgumentParser(
+ description=(
+ "Run one isolated benchmark workload and emit report JSON plus canonical "
+ "fact tables. The default workload compares exact fast-mode incremental "
+ "indexing with a fresh full rebuild."
+ )
+ )
+ parser.add_argument("--binary", default="build/c/codebase-memory-mcp")
+ parser.add_argument(
+ "--describe-terms",
+ choices=("json", "markdown"),
+ default="",
+ help=(
+ "Print the canonical benchmark terminology registry or generated Markdown "
+ f"(version {BENCHMARK_TERMINOLOGY_VERSION}; "
+ "benchmarks/terminology.json), then exit."
+ ),
+ )
+ parser.add_argument(
+ "--candidate-revision",
+ default="",
+ help=(
+ "Commit-ish identifying the candidate binary for a standalone run. It is "
+ "resolved to a full commit in the binary checkout; experiment runs supply the "
+ "immutable cell revision automatically."
+ ),
+ )
+ parser.add_argument(
+ "--build-metadata-json",
+ default="",
+ metavar="JSON",
+ help=(
+ "Standalone build metadata object, for example compiler, target, CFLAGS, "
+ "optimization, sanitizer, and feature flags. Experiment runs supply this from "
+ "the immutable cell automatically."
+ ),
+ )
+ parser.add_argument("--work-root", default="")
+ parser.add_argument("--repo-root", default=".")
+ parser.add_argument("--out", default="")
+ parser.add_argument(
+ "--facts-dir",
+ default="",
+ help=(
+ "Write versioned runs.json, steps.jsonl, results.json, artifacts.json, "
+ f"and manifest.json facts using {BENCHMARK_FACT_SCHEMA}. Defaults to the "
+ "experiment artifact directory or .facts."
+ ),
+ )
+ parser.add_argument(
+ "--import-report",
+ default="",
+ metavar="LEGACY-REPORT.json",
+ help=(
+ "Normalize a retained older benchmark report into canonical fact tables. "
+ "Missing historical metadata is marked unknown; no benchmark binary runs. "
+ "Requires --facts-dir."
+ ),
+ )
+ parser.add_argument("--files", type=int, default=DEFAULT_FILE_COUNT)
+ parser.add_argument(
+ "--functions-per-file", type=int, default=DEFAULT_FUNCTIONS_PER_FILE
+ )
+ parser.add_argument("--changed-files", type=int, default=DEFAULT_CHANGED_FILES)
+ parser.add_argument("--min-speedup", type=float, default=DEFAULT_MIN_SPEEDUP)
+ parser.add_argument(
+ "--index-mode",
+ choices=INDEX_MODES,
+ default="fast",
+ help=(
+ "Indexing mode for every compared run. Use full or moderate when measuring "
+ "SIMILAR_TO or SEMANTICALLY_RELATED quality; fast intentionally skips both."
+ ),
+ )
+ parser.add_argument(
+ "--rank-refresh",
+ choices=(
+ RANK_REFRESH_CANDIDATE_DEFAULT,
+ *RANK_REFRESH_POLICIES,
+ ),
+ default=DEFAULT_RANK_REFRESH,
+ help=(
+ "Preserve the candidate's compiled/configured default unless an explicit policy "
+ "is selected. This is independent of --config-profile."
+ ),
+ )
+ parser.add_argument(
+ "--config-profile",
+ choices=tuple(CONFIG_PROFILES),
+ default=CONFIG_PROFILE_DEFAULT,
+ help=(
+ "Named, auditable configuration profile. The default "
+ "automatic_dependency_source_indexing_disabled sets auto_index_deps=false; "
+ "automatic_dependency_source_indexing_enabled sets it true; "
+ "candidate_native_configuration applies no override for binaries that do not "
+ "support this setting. minimal_indexing disables automatic dependency-source "
+ "indexing plus every optional graph/rank pass. Repeated --config KEY=VALUE "
+ "arguments take priority over the selected profile."
+ ),
+ )
+ parser.add_argument(
+ "--config",
+ action="append",
+ default=[],
+ metavar="KEY=VALUE",
+ help="Additional config override; repeat to set multiple keys. Applied after built-in settings.",
+ )
+ parser.add_argument(
+ "--product-env",
+ action="append",
+ default=[],
+ metavar="CBM_KEY=VALUE",
+ help=(
+ "Explicit candidate process environment; repeat for controlled worker or "
+ "memory sweeps. Keys must start with CBM_. Cache, profiling, auto-index, "
+ "and run-context variables remain owned by the benchmark harness."
+ ),
+ )
+ parser.add_argument("--timeout", type=int, default=DEFAULT_TIMEOUT_SECONDS)
+ parser.add_argument("--keep-work-root", action="store_true")
+ parser.add_argument("--include-logs", action="store_true")
+ parser.add_argument(
+ "--mcp-surface-parity",
+ action="store_true",
+ help=(
+ "Measure classic startup, streamlined pre-reveal, and streamlined post-reveal "
+ "tool discovery without indexing a repository."
+ ),
+ )
+ parser.add_argument(
+ "--list-projects-scaling",
+ action="store_true",
+ help=(
+ "Measure list_projects alone against isolated cloned project databases using "
+ "a fresh MCP server per configured count."
+ ),
+ )
+ parser.add_argument(
+ "--list-project-counts",
+ default=DEFAULT_LIST_PROJECT_COUNTS,
+ help="Strictly increasing positive project counts for --list-projects-scaling.",
+ )
+ parser.add_argument(
+ "--list-project-fixture-max-mb",
+ type=int,
+ default=DEFAULT_LIST_PROJECT_FIXTURE_MAX_MB,
+ help="Hard disk cap for cloned list-project fixtures before any clone is created.",
+ )
+ parser.add_argument(
+ "--search-projection",
+ action="store_true",
+ help=(
+ "Compare compact default/true, selected fields, and compact=false JSON projection "
+ "for identical ranked results."
+ ),
+ )
+ parser.add_argument(
+ "--search-projection-results",
+ type=int,
+ default=30,
+ help="Bounded matching result count for --search-projection.",
+ )
+ parser.add_argument(
+ "--capability-quality",
+ choices=CAPABILITY_QUALITY_CASES,
+ default="",
+ help=(
+ "Run one isolated, deterministic capability-quality fixture. rank measures whether "
+ "structural ranking lifts the central result above lexical decoys; dependencies "
+ "measures local npm API retrieval with source/package/read-only provenance; similarity "
+ "scores SIMILAR_TO structural-clone pairs and semantic_edges scores "
+ "SEMANTICALLY_RELATED control-flow variants against explicit hard negatives; "
+ "git_history measures FILE_CHANGES_WITH retrieval for a deterministic four-commit "
+ "co-change history; http_links measures HTTP_CALLS retrieval for a client-to-route "
+ "fixture."
+ ),
+ )
+ parser.add_argument(
+ "--quality-background-repo",
+ default="",
+ help=(
+ "Optional Git repository whose tracked files at an exact revision form the realistic "
+ "background for similarity or semantic_edges canaries. Dirty and untracked source "
+ "state is excluded."
+ ),
+ )
+ parser.add_argument(
+ "--quality-background-revision",
+ default="",
+ help="Commit-ish copied by git archive for --quality-background-repo; experiments should use a full hash.",
+ )
+ parser.add_argument(
+ "--rank-query-manifest",
+ default="",
+ help=(
+ "Optional versioned query battery for capability-quality rank runs, e.g. "
+ "benchmarks/rank-queries-v1/manifest.json. Defaults to empty, which issues the "
+ "single built-in query so existing cells stay byte-identical and cache-valid."
+ ),
+ )
+ parser.add_argument(
+ "--corpus",
+ default="",
+ help=(
+ "Corpus id this run measures, e.g. cosign. One id keys everything: the query "
+ "set in --rank-query-manifest, the registry entry in --corpus-manifest, and "
+ "any --corpus-repo override. Defaults to synthetic-rank-v1, the built-in "
+ "fixture. An unknown id fails immediately rather than silently running nothing."
+ ),
+ )
+ parser.add_argument(
+ "--corpus-repo",
+ action="append",
+ default=[],
+ metavar="ID=PATH",
+ help=(
+ "Point a corpus id from corpora-v1.json at an existing local checkout, "
+ "repeatable. Otherwise the harness looks at CBM_BENCH_CORPUS_ and then "
+ "~/.cache/codebase-memory-mcp/bench-repos/, and only clones the pinned "
+ "commit when --clone-missing-real-repos is also given."
+ ),
+ )
+ parser.add_argument(
+ "--corpus-manifest",
+ default="",
+ help=(
+ "Corpus registry with pinned revisions and trees; defaults to "
+ "benchmarks/corpora-v1.json."
+ ),
+ )
+ parser.add_argument(
+ "--labels-dir",
+ default="",
+ help=(
+ "Directory of pre-generated Tier-A test labels named .json. "
+ "Defaults to empty, which derives them from the measured checkout instead, "
+ "so no generated label data is stored. Either way a corpus no independent "
+ "source can classify reports scaffolding@K as null rather than inferring it "
+ "from this server's own test predicates."
+ ),
+ )
+ parser.add_argument(
+ "--rank-fixture-overlay",
+ action="store_true",
+ help=(
+ "Plant the synthetic rank fixture (zz_order_core plus eight lexical decoys) "
+ "into a real corpus as a positive control, and append its canary query to "
+ "the battery. Off by default: a real-corpus run indexes exactly the pinned "
+ "tree, so corpus-scoped scores are not diluted by symbols the corpus does "
+ "not contain. Has no effect without a corpus, where the fixture is the repo."
+ ),
+ )
+ parser.add_argument(
+ "--matrix",
+ action="store_true",
+ help="Run the affected-frontier scenario matrix.",
+ )
+ parser.add_argument(
+ "--self-dogfood",
+ action="store_true",
+ help="Run isolated edit-loop scenarios against a detached worktree of --repo-root.",
+ )
+ parser.add_argument(
+ "--repo-revision",
+ default="HEAD",
+ help=(
+ "Exact commit used for --self-dogfood detached worktrees. Experiments should pass "
+ "a full hash so mutable source HEAD cannot change the measured corpus."
+ ),
+ )
+ parser.add_argument(
+ "--matrix-scenarios",
+ default=MATRIX_SCENARIOS_DEFAULT,
+ help="Comma-separated matrix scenarios to run.",
+ )
+ parser.add_argument(
+ "--frontier-files",
+ type=int,
+ default=DEFAULT_FRONTIER_FILES,
+ help=(
+ "Number of inbound-dependent source files created by each *_inbound_frontier "
+ "matrix scenario. The changed definition file is additional."
+ ),
+ )
+ parser.add_argument(
+ "--fastapi-repo",
+ default="",
+ help=(
+ "Existing FastAPI checkout for matrix scenario fastapi_insert_probe. "
+ "Defaults also check CBM_FASTAPI_REPO and common local cache/source paths."
+ ),
+ )
+ parser.add_argument(
+ "--fastapi-url",
+ default=DEFAULT_FASTAPI_URL,
+ help="Clone URL used only with --clone-missing-real-repos.",
+ )
+ parser.add_argument(
+ "--clone-missing-real-repos",
+ action="store_true",
+ help="Clone missing real benchmark repos into the isolated work root.",
+ )
+ parser.add_argument(
+ "--self-dogfood-scenarios",
+ default=SELF_DOGFOOD_SCENARIOS_DEFAULT,
+ help="Comma-separated real-repo edit-loop scenarios to run.",
+ )
+ parser.add_argument(
+ "--transport",
+ choices=("cli", "mcp"),
+ default="cli",
+ help="Measure cold CLI subprocess calls or persistent MCP tool-call latency.",
+ )
+ parser.add_argument(
+ "--overhead-probes",
+ type=int,
+ default=DEFAULT_OVERHEAD_PROBES,
+ help=(
+ "Run N cheap tool-call probes before indexing to estimate invocation overhead; "
+ "0 preserves the historical gate behavior."
+ ),
+ )
+ parser.add_argument(
+ "--overhead-tool",
+ default=DEFAULT_OVERHEAD_TOOL,
+ help="Existing MCP tool used by --overhead-probes.",
+ )
+ parser.add_argument(
+ "--indexed-query-probes",
+ type=int,
+ default=DEFAULT_INDEXED_QUERY_PROBES,
+ help=(
+ "Run N project-scoped tool calls after initial indexing to measure the "
+ "file-backed query path; 0 preserves the historical gate behavior."
+ ),
+ )
+ parser.add_argument(
+ "--indexed-query-tool",
+ default=DEFAULT_INDEXED_QUERY_TOOL,
+ help="Existing project-aware MCP tool used by --indexed-query-probes.",
+ )
+ args = parser.parse_args()
+ if args.build_metadata_json:
+ try:
+ args.build_metadata = json.loads(args.build_metadata_json)
+ except json.JSONDecodeError as exc:
+ parser.error(f"--build-metadata-json must contain valid JSON: {exc}")
+ if not isinstance(args.build_metadata, dict):
+ parser.error("--build-metadata-json must contain a JSON object")
+ else:
+ args.build_metadata = {}
+ args.config_overrides = resolve_config_overrides(args.config_profile, args.config)
+ args.product_environment = parse_product_environment(args.product_env)
+ return args
+
+
+def resolve_binary_path(binary_arg: str) -> Path:
+ binary = Path(binary_arg).expanduser()
+ if binary.is_absolute():
+ return binary.resolve()
+ cwd_candidate = (Path.cwd() / binary).resolve()
+ if cwd_candidate.is_file():
+ return cwd_candidate
+ script_candidate = (Path(__file__).resolve().parents[1] / binary).resolve()
+ return script_candidate
+
+
+def main() -> int:
+ args = parse_args()
+ if args.describe_terms:
+ path = (
+ BENCHMARK_TERMINOLOGY_PATH
+ if args.describe_terms == "json"
+ else BENCHMARK_TERMINOLOGY_MARKDOWN_PATH
+ )
+ try:
+ sys.stdout.write(path.read_text(encoding="utf-8"))
+ except OSError as exc:
+ print(f"error: cannot read benchmark terminology: {exc}", file=sys.stderr)
+ return 2
+ return 0
+ if args.import_report:
+ if not args.facts_dir:
+ print("error: --import-report requires --facts-dir", file=sys.stderr)
+ return 2
+ source = Path(args.import_report).expanduser()
+ try:
+ report = json.loads(source.read_text(encoding="utf-8"))
+ if not isinstance(report, dict):
+ raise ValueError("legacy benchmark report must be a JSON object")
+ embedded_context = report.get("benchmark_run_context")
+ context = embedded_context if isinstance(embedded_context, dict) else {}
+ facts = normalize_benchmark_report(report, context, imported_report=True)
+ facts["artifacts"].append(
+ {
+ "run_id": facts["runs"][0]["run_id"],
+ "artifact_id": hashlib.sha256(
+ canonical_json_bytes(
+ {
+ "path": str(source.resolve()),
+ "sha256": file_sha256(source),
+ }
+ )
+ ).hexdigest()[:24],
+ "artifact_type": "legacy_source_report",
+ "path": str(source.resolve()),
+ "sha256": file_sha256(source),
+ "size_bytes": source.stat().st_size,
+ "schema_version": report.get(
+ "schema_version",
+ unknown_fact("legacy_report_schema_not_recorded"),
+ ),
+ "cleanup_status": "retained",
+ }
+ )
+ manifest = write_benchmark_fact_tables(
+ facts, Path(args.facts_dir).expanduser()
+ )
+ except (OSError, ValueError, json.JSONDecodeError) as exc:
+ print(f"error: cannot import benchmark report: {exc}", file=sys.stderr)
+ return 2
+ print(json.dumps(manifest, indent=2, sort_keys=True))
+ return 0
+ binary = resolve_binary_path(args.binary)
+ if not binary.is_file():
+ print(f"error: binary not found: {binary}", file=sys.stderr)
+ return 2
+ if args.list_projects_scaling:
+ _, list_exit_code = run_list_projects_scaling(args, binary)
+ return list_exit_code
+ if args.search_projection:
+ _, projection_exit_code = run_search_projection(args, binary)
+ return projection_exit_code
+ if args.mcp_surface_parity:
+ _, surface_exit_code = run_mcp_surface_parity(args, binary)
+ return surface_exit_code
+ if args.capability_quality:
+ _, quality_exit_code = run_capability_quality(args, binary)
+ return quality_exit_code
+ if args.matrix:
+ _, matrix_exit_code = run_matrix(args, binary)
+ return matrix_exit_code
+ if args.self_dogfood:
+ _, self_dogfood_exit_code = run_self_dogfood(args, binary)
+ return self_dogfood_exit_code
+
+ auto_root = not bool(args.work_root)
+ work_root = (
+ Path(args.work_root).expanduser()
+ if args.work_root
+ else Path(tempfile.mkdtemp(prefix="cbm-incr-speed-"))
+ )
+ work_root.mkdir(parents=True, exist_ok=True)
+ repo_dir = work_root / "repo"
+ cache_dir = work_root / "cache"
+ repo_dir.mkdir(parents=True, exist_ok=True)
+ cache_dir.mkdir(parents=True, exist_ok=True)
+
+ report: dict[str, Any] = {
+ "generated_at_utc": datetime.now(timezone.utc).isoformat(),
+ "binary": str(binary),
+ "binary_metadata": binary_metadata(binary),
+ "work_root": str(work_root),
+ "parameters": {
+ "files": args.files,
+ "functions_per_file": args.functions_per_file,
+ "changed_files": args.changed_files,
+ "min_speedup": args.min_speedup,
+ "rank_refresh": args.rank_refresh,
+ "rank_refresh_override_applied": (
+ args.rank_refresh != RANK_REFRESH_CANDIDATE_DEFAULT
+ ),
+ "index_mode": args.index_mode,
+ "capability_applicability": index_mode_capability_applicability(
+ args.index_mode
+ ),
+ "config_profile": args.config_profile,
+ "config_overrides": args.config_overrides,
+ "configuration_environment": benchmark_environment_policy(
+ args.product_environment
+ ),
+ "timeout": args.timeout,
+ "transport": args.transport,
+ "overhead_probes": args.overhead_probes,
+ "overhead_tool": args.overhead_tool,
+ "indexed_query_probes": args.indexed_query_probes,
+ "indexed_query_tool": args.indexed_query_tool,
+ },
+ "cleanup": {
+ "requested": auto_root and not args.keep_work_root,
+ "removed": False,
+ },
+ }
+
+ exit_code = 1
+ try:
+ create_repo(repo_dir, args.files, args.functions_per_file)
+ env = build_env(cache_dir, args.product_environment)
+ run_config_set(binary, env, "incremental_reindex", "always", args.timeout)
+ apply_rank_refresh_override(binary, env, args.rank_refresh, args.timeout)
+ apply_config_overrides(binary, env, args.config_overrides, args.timeout)
+
+ if args.transport == "mcp":
+ with McpClient(binary, env, args.timeout) as client:
+ overhead_probe = measure_mcp_overhead_probes(
+ client, args.overhead_tool, args.overhead_probes, args.include_logs
+ )
+ initial = run_index_mcp(
+ client, repo_dir, args.include_logs, args.index_mode
+ )
+ indexed_query_probe = measure_mcp_overhead_probes(
+ client,
+ args.indexed_query_tool,
+ args.indexed_query_probes,
+ args.include_logs,
+ {"project": str(repo_dir)},
+ )
+ changed_paths = modify_existing_files(
+ repo_dir, args.changed_files, args.functions_per_file
+ )
+ incremental = run_index_mcp(
+ client, repo_dir, args.include_logs, args.index_mode
+ )
+ removed_dbs = remove_project_dbs(cache_dir)
+ with McpClient(binary, env, args.timeout) as client:
+ full_rebuild = run_index_mcp(
+ client, repo_dir, args.include_logs, args.index_mode
+ )
+ else:
+ overhead_probe = measure_cli_overhead_probes(
+ binary,
+ env,
+ args.overhead_tool,
+ args.overhead_probes,
+ args.timeout,
+ args.include_logs,
+ )
+ initial = run_index(
+ binary, env, repo_dir, args.timeout, args.include_logs, args.index_mode
+ )
+ indexed_query_probe = measure_cli_overhead_probes(
+ binary,
+ env,
+ args.indexed_query_tool,
+ args.indexed_query_probes,
+ args.timeout,
+ args.include_logs,
+ {"project": str(repo_dir)},
+ )
+ changed_paths = modify_existing_files(
+ repo_dir, args.changed_files, args.functions_per_file
+ )
+ incremental = run_index(
+ binary, env, repo_dir, args.timeout, args.include_logs, args.index_mode
+ )
+ removed_dbs = remove_project_dbs(cache_dir)
+ full_rebuild = run_index(
+ binary, env, repo_dir, args.timeout, args.include_logs, args.index_mode
+ )
+
+ incr_ms = max(1, int(incremental["elapsed_ms"]))
+ full_ms = max(1, int(full_rebuild["elapsed_ms"]))
+ speedup = full_ms / incr_ms
+ incremental_markers = incremental["markers"]
+ explicit_incremental_route = is_incremental_publish_kind(
+ str(incremental.get("publish_kind") or "")
+ )
+ defer_marker = bool(incremental_markers["pagerank_defer"])
+ passed = speedup >= args.min_speedup and explicit_incremental_route
+
+ report.update(
+ {
+ "changed_paths": changed_paths,
+ "removed_project_dbs": removed_dbs,
+ "measurements": {
+ "overhead_probe": overhead_probe,
+ "indexed_query_probe": indexed_query_probe,
+ "initial_fast_full": initial,
+ "incremental_exact": incremental,
+ "incremental": incremental,
+ "fresh_fast_full_after_change": full_rebuild,
+ },
+ "derived": {
+ "speedup_full_rebuild_over_incremental": speedup,
+ "exact_incremental_marker_seen": explicit_incremental_route,
+ "explicit_incremental_route_seen": explicit_incremental_route,
+ "rank_defer_marker_seen": defer_marker,
+ "passed": passed,
+ },
+ }
+ )
+ exit_code = 0 if passed else 1
+ except Exception as exc:
+ record_report_error(report, exc)
+ exit_code = 1
+ finally:
+ if auto_root and not args.keep_work_root:
+ shutil.rmtree(work_root, ignore_errors=True)
+ report["cleanup"]["removed"] = not work_root.exists()
+ emit_report(report, args)
+
+ return exit_code
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/benchmarks/run_container_experiment.py b/benchmarks/run_container_experiment.py
new file mode 100644
index 000000000..3b692f873
--- /dev/null
+++ b/benchmarks/run_container_experiment.py
@@ -0,0 +1,1421 @@
+#!/usr/bin/env python3
+"""Run the existing benchmark matrix in a native, resource-bounded Docker cohort.
+
+The coordinator owns Docker isolation and artifact transfer only. Candidate
+resolution, measurements, correctness gates, immutable plans, and reports remain
+implemented by run_experiments.py and run_benchmark.py.
+"""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import importlib.util
+import json
+import math
+import os
+import platform
+import re
+import shutil
+import subprocess
+import sys
+import tempfile
+from datetime import datetime, timezone
+from pathlib import Path
+from typing import Any
+
+ROOT = Path(__file__).resolve().parents[1]
+DOCKERFILE = ROOT / "test-infrastructure" / "Dockerfile"
+# Staged corpora live beside the bundle on the work volume, outside /results, because
+# they are measured input rather than exported output.
+CONTAINER_CORPUS_ROOT = "/benchmark/corpora"
+CORPUS_FLAG = "--corpus"
+DEFAULT_BUILD_ENVIRONMENT = {
+ "CC": "clang-18",
+ "CXX": "clang++-18",
+}
+OWNED_RUNNER_FLAGS = frozenset(
+ {
+ "--candidate-root",
+ "--candidate-search-root",
+ "--build-jobs",
+ "--experiment-root",
+ "--matrix-spec",
+ "--plan",
+ "--product-env",
+ "--quick",
+ "--full",
+ }
+)
+MEMORY_LIMIT_PATTERN = re.compile(r"^[1-9][0-9]*(?:b|k|m|g|t)$", re.IGNORECASE)
+WORK_VOLUME_RETENTION_FAILED_RUNS = "failed-runs"
+WORK_VOLUME_RETENTION_ALWAYS = "always"
+WORK_VOLUME_RETENTION_CHOICES = (
+ WORK_VOLUME_RETENTION_FAILED_RUNS,
+ WORK_VOLUME_RETENTION_ALWAYS,
+)
+DEFAULT_WORK_VOLUME_RETENTION = WORK_VOLUME_RETENTION_FAILED_RUNS
+WORK_VOLUME_STATUS_REMOVED = "removed_after_successful_export"
+CONTAINER_SCRIPT = r"""
+set -euo pipefail
+source_revision=$1
+bundle_name=$2
+source_key=$3
+shift 3
+export HOME=/benchmark/home
+mkdir -p "$HOME" /benchmark/sources
+repository=/benchmark/sources/$source_key
+if [ ! -d "$repository/.git" ]; then
+ git clone --quiet "/benchmark/$bundle_name" "$repository"
+fi
+git -C "$repository" checkout --quiet --detach "$source_revision"
+if [ -n "$(git -C "$repository" status --porcelain --untracked-files=no)" ]; then
+ echo "benchmark source clone has tracked changes: $repository" >&2
+ exit 65
+fi
+cd "$repository"
+exec python3 benchmarks/run_experiments.py "$@"
+""".strip()
+
+
+def utc_now() -> str:
+ return datetime.now(timezone.utc).isoformat()
+
+
+def file_sha256(path: Path) -> str:
+ digest = hashlib.sha256()
+ with path.open("rb") as stream:
+ for chunk in iter(lambda: stream.read(1024 * 1024), b""):
+ digest.update(chunk)
+ return digest.hexdigest()
+
+
+def write_container_manifest(
+ experiment_root: Path,
+ source_revision: str,
+ bundle_sha256: str,
+ manifest: dict[str, Any],
+) -> Path:
+ """Write an immutable, content-addressed environment record."""
+ payload = (json.dumps(manifest, indent=2, sort_keys=True) + "\n").encode("utf-8")
+ manifest_sha = hashlib.sha256(payload).hexdigest()
+ path = (
+ experiment_root
+ / "manifests"
+ / (
+ f"container-environment-{source_revision[:12]}-{bundle_sha256[:12]}-"
+ f"{manifest_sha[:12]}.json"
+ )
+ )
+ if path.exists() and path.read_bytes() != payload:
+ raise RuntimeError(f"manifest hash collision at {path}")
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_bytes(payload)
+ return path
+
+
+def failure_log_export_root(experiment_root: Path, source_revision: str) -> Path:
+ """Return the commit-keyed destination for failed candidate build logs."""
+ return experiment_root / "container-failures" / source_revision[:12] / "build-logs"
+
+
+def repository_snapshot_sha256(
+ source_revision: str, bundle_heads: list[dict[str, str]]
+) -> str:
+ """Hash Git commit/ref content independently of bundle pack bytes."""
+ identity = {
+ "source_revision": source_revision,
+ "bundle_heads": sorted(
+ (
+ {"ref": head["ref"], "revision": head["revision"]}
+ for head in bundle_heads
+ ),
+ key=lambda head: (head["ref"], head["revision"]),
+ ),
+ }
+ payload = json.dumps(identity, separators=(",", ":"), sort_keys=True).encode(
+ "utf-8"
+ )
+ return hashlib.sha256(payload).hexdigest()
+
+
+def runtime_image_sha256(metadata: dict[str, Any]) -> str:
+ """Hash runtime-relevant image bytes without BuildKit attestation metadata.
+
+ Docker's top-level OCI index digest can change when BuildKit regenerates provenance
+ even though the selected platform's configuration and root filesystem layers are
+ byte-identical. Conversely, an explicit image can retain its tag while changing the
+ compiler or filesystem. The resumable run key therefore uses the stable runtime
+ projection below rather than either the mutable tag or the attestation-bearing index.
+ """
+ architecture = metadata.get("Architecture")
+ operating_system = metadata.get("Os")
+ config = metadata.get("Config")
+ rootfs = metadata.get("RootFS")
+ if not isinstance(architecture, str) or not architecture:
+ raise ValueError("Docker image metadata lacks a non-empty Architecture")
+ if not isinstance(operating_system, str) or not operating_system:
+ raise ValueError("Docker image metadata lacks a non-empty Os")
+ if not isinstance(config, dict):
+ raise ValueError("Docker image metadata Config must be an object")
+ if not isinstance(rootfs, dict):
+ raise ValueError("Docker image metadata RootFS must be an object")
+ layers = rootfs.get("Layers")
+ if (
+ not isinstance(layers, list)
+ or not layers
+ or not all(isinstance(layer, str) and layer for layer in layers)
+ ):
+ raise ValueError(
+ "Docker image metadata RootFS.Layers must be non-empty strings"
+ )
+ identity = {
+ "architecture": architecture,
+ "os": operating_system,
+ "config": config,
+ "rootfs": rootfs,
+ }
+ payload = json.dumps(identity, separators=(",", ":"), sort_keys=True).encode(
+ "utf-8"
+ )
+ return hashlib.sha256(payload).hexdigest()
+
+
+def container_run_key(
+ *,
+ source_revision: str,
+ repository_snapshot_sha256: str,
+ matrix_spec_sha256: str | None,
+ runtime_image_sha256: str,
+ resources: dict[str, Any],
+ runner_arguments: list[str],
+ corpora: list[dict[str, str]] | None = None,
+) -> str:
+ """Identify one resumable measurement cohort inside a named history."""
+ identity = {
+ "source_revision": source_revision,
+ "repository_snapshot_sha256": repository_snapshot_sha256,
+ "matrix_spec_sha256": matrix_spec_sha256,
+ "runtime_image_sha256": runtime_image_sha256,
+ "resources": resources,
+ # Audit-only changes execution, not the measured plan or environment.
+ "runner_arguments": [
+ argument for argument in runner_arguments if argument != "--audit-only"
+ ],
+ }
+ # Staged corpora are measured input: two pins sharing a run key would resume into
+ # one runset and merge cells taken against different source trees. Absent rather
+ # than empty when nothing is staged, so run keys recorded before corpus staging
+ # existed still resolve to the same cohort.
+ if corpora:
+ identity["corpora"] = sorted(
+ ({"id": entry["id"], "revision": entry["revision"]} for entry in corpora),
+ key=lambda entry: entry["id"],
+ )
+ payload = json.dumps(identity, separators=(",", ":"), sort_keys=True).encode(
+ "utf-8"
+ )
+ return hashlib.sha256(payload).hexdigest()[:24]
+
+
+def load_benchmark_module() -> Any:
+ """Reuse run_benchmark.py's corpus logic instead of restating it here.
+
+ Same importlib pattern autotune.py uses for run_experiments.py helpers. The
+ resolution ladder, the pin check and the environment-variable spelling stay defined
+ once, in the module that also reads them inside the container.
+ """
+ cached = sys.modules.get("run_benchmark")
+ if cached is not None:
+ return cached
+ path = Path(__file__).resolve().with_name("run_benchmark.py")
+ spec = importlib.util.spec_from_file_location("run_benchmark", path)
+ if spec is None or spec.loader is None:
+ raise RuntimeError(f"cannot load the benchmark harness from {path}")
+ module = importlib.util.module_from_spec(spec)
+ sys.modules["run_benchmark"] = module
+ spec.loader.exec_module(module)
+ return module
+
+
+def load_experiment_module() -> Any:
+ """Reuse the canonical product-environment parser at the outer boundary."""
+ cached = sys.modules.get("run_experiments")
+ if cached is not None:
+ return cached
+ path = Path(__file__).resolve().with_name("run_experiments.py")
+ spec = importlib.util.spec_from_file_location("run_experiments", path)
+ if spec is None or spec.loader is None:
+ raise RuntimeError(f"cannot load the experiment harness from {path}")
+ module = importlib.util.module_from_spec(spec)
+ sys.modules["run_experiments"] = module
+ spec.loader.exec_module(module)
+ return module
+
+
+def corpus_env_key(corpus_id: str) -> str:
+ """Spelled by run_benchmark.py so the writer and the reader cannot disagree."""
+ return load_benchmark_module().corpus_env_key(corpus_id)
+
+
+def container_corpus_path(corpus_id: str, revision: str) -> str:
+ """Immutable, pin-keyed location for a staged corpus inside the work volume.
+
+ The work volume is retained so a runset can resume, and `docker cp` merges into an
+ existing directory rather than replacing it. Keying only by corpus id would leave
+ files from a previous pin in place and index a tree matching no commit.
+ """
+ return f"{CONTAINER_CORPUS_ROOT}/{corpus_id}-{revision[:12]}"
+
+
+def staged_corpus_revision(entry: dict[str, Any], source: Path, timeout: int) -> str:
+ """The commit a staged corpus is keyed and reported by.
+
+ A pinned entry supplies its own 40-character sha. The four mined-workload corpora
+ declare "resolve-at-runtime" instead, so their commit is read from the checkout;
+ keying on the literal would give every state of that repository one directory and a
+ retained work volume would merge two different trees under one name.
+
+ Reading HEAD is sufficient rather than approximate: copy_git_revision_to_dir
+ materializes the corpus with `git archive`, which only ever sees committed content,
+ so uncommitted edits in the source checkout cannot reach the measured tree.
+ """
+ harness = load_benchmark_module()
+ revision = entry.get("revision") or ""
+ if len(revision) == 40:
+ return revision
+ if revision != harness.UNPINNED_REVISION:
+ # Same rule as verify_corpus_pin. Accepting any non-sha here would let a typo'd
+ # revision be staged as "whatever HEAD is" and then recorded as the measured
+ # commit, which is the failure the sentinel exists to make explicit.
+ raise RuntimeError(
+ f"corpus {entry.get('id')!r} declares revision {revision!r}, which is "
+ f"neither a 40-character commit hash nor {harness.UNPINNED_REVISION!r}"
+ )
+ return harness.command_stdout(["git", "rev-parse", "HEAD"], timeout, source).strip()
+
+
+def corpora_in_arguments(arguments: list[str]) -> list[str]:
+ """Corpus ids named by one benchmark_args list, in either flag spelling."""
+ found: list[str] = []
+ for index, argument in enumerate(arguments):
+ if argument == CORPUS_FLAG and index + 1 < len(arguments):
+ found.append(arguments[index + 1])
+ elif argument.startswith(f"{CORPUS_FLAG}="):
+ found.append(argument.split("=", 1)[1])
+ return found
+
+
+def corpora_required_by_spec(document: Any) -> list[str]:
+ """Corpus ids named by any benchmark_args list anywhere in a matrix spec.
+
+ run_experiments.py accepts benchmark_args at four levels — spec, candidates,
+ profiles and scenarios — and concatenates them (:1677-1680). The scan is recursive
+ rather than four fixed lookups so a level added later is covered without an edit
+ here, and so a corpus named only inside one profile is still staged.
+ """
+ found: list[str] = []
+
+ def visit(node: Any) -> None:
+ if isinstance(node, dict):
+ for key, value in node.items():
+ if key == "benchmark_args" and isinstance(value, list):
+ found.extend(
+ item
+ for item in corpora_in_arguments(value)
+ if isinstance(item, str)
+ )
+ else:
+ visit(value)
+ elif isinstance(node, list):
+ for item in node:
+ visit(item)
+
+ visit(document)
+ return sorted(set(found))
+
+
+def stage_corpora(
+ *,
+ docker: str,
+ image: str,
+ work_volume: str,
+ corpus_ids: list[str],
+ corpus_repo: list[str],
+ corpus_manifest: str,
+ allow_clone: bool,
+ timeout: int,
+ container_name: str,
+) -> list[dict[str, str]]:
+ """Copy each pinned corpus into the work volume and report what was staged.
+
+ The measured container has no network and no host bind mount, so a corpus has to be
+ resolved and pin-verified on the host and then carried in. Resolution is
+ run_benchmark.py's own ladder (--corpus-repo, CBM_BENCH_CORPUS_, the shared
+ cache, then an explicitly allowed clone), so the host and the container agree on
+ which checkout a corpus id means.
+
+ Time and I/O are linear in the staged bytes, once per corpus per run; the work
+ volume is retained, but each pin lands in its own directory so a re-pin cannot
+ merge into stale files.
+ """
+ if not corpus_ids:
+ return []
+ harness = load_benchmark_module()
+ registry = harness.load_corpora_manifest(corpus_manifest)
+ resolution_args = argparse.Namespace(
+ corpus_repo=list(corpus_repo),
+ clone_missing_real_repos=allow_clone,
+ timeout=timeout,
+ )
+ staged: list[dict[str, str]] = []
+ for corpus_id in corpus_ids:
+ if corpus_id not in registry:
+ raise RuntimeError(
+ f"corpus {corpus_id!r} is absent from the corpus registry; known: "
+ + ", ".join(sorted(registry))
+ )
+ entry = registry[corpus_id]
+ source = harness.resolve_corpus_source(
+ corpus_id, entry["url"], entry["revision"], resolution_args
+ )
+ # Verify on the host, where the failure is cheap and the message is visible,
+ # rather than after a candidate build has already run inside the container.
+ harness.verify_corpus_pin(source, entry, timeout)
+ revision = staged_corpus_revision(entry, source, timeout)
+ destination = container_corpus_path(corpus_id, revision)
+ copy_to_volume(
+ docker,
+ image,
+ work_volume,
+ "/benchmark",
+ source,
+ container_name,
+ copy_destination=destination,
+ )
+ staged.append(
+ {
+ "id": corpus_id,
+ "revision": revision,
+ "registry_revision": entry.get("revision", ""),
+ "tree": entry.get("tree", ""),
+ "host_path": str(source),
+ "container_path": destination,
+ }
+ )
+ return staged
+
+
+def native_linux_platform(machine: str) -> str:
+ normalized = machine.strip().lower()
+ if normalized in {"arm64", "aarch64"}:
+ return "linux/arm64"
+ if normalized in {"amd64", "x86_64"}:
+ return "linux/amd64"
+ raise ValueError(
+ f"unsupported host architecture {machine!r}; use a native arm64 or amd64 "
+ "host for performance measurements"
+ )
+
+
+def validate_resources(cpus: float, memory: str, workers: int) -> dict[str, Any]:
+ if not math.isfinite(cpus) or cpus <= 0:
+ raise ValueError("benchmark CPUs must be a finite value greater than zero")
+ if not MEMORY_LIMIT_PATTERN.fullmatch(memory):
+ raise ValueError(
+ "benchmark memory must be an explicit Docker limit such as 8g or 16384m"
+ )
+ if workers <= 0:
+ raise ValueError("benchmark workers must be greater than zero")
+ if workers > cpus:
+ raise ValueError(
+ f"benchmark workers ({workers}) cannot exceed the CPU budget ({cpus:g})"
+ )
+ return {"cpus": cpus, "memory": memory.lower(), "workers": workers}
+
+
+def resolve_build_jobs(cpus: float, requested: int | None) -> int:
+ """Use the container's complete declared CPU capacity unless overridden."""
+ if requested is not None:
+ if requested <= 0:
+ raise ValueError("benchmark build jobs must be greater than zero")
+ return requested
+ return max(1, math.ceil(cpus))
+
+
+def validate_forwarded_arguments(arguments: list[str]) -> list[str]:
+ values = list(arguments)
+ if values[:1] == ["--"]:
+ values.pop(0)
+ conflicts = sorted(
+ item for item in values if item.partition("=")[0] in OWNED_RUNNER_FLAGS
+ )
+ if conflicts:
+ raise ValueError(
+ "runner arguments cannot replace coordinator-owned flags: "
+ + ", ".join(conflicts)
+ )
+ return values
+
+
+def volume_mount(name: str, destination: str) -> str:
+ return f"type=volume,src={name},dst={destination}"
+
+
+def bundle_revision_arguments() -> list[str]:
+ """Include benchmarkable refs without copying stash or recovery namespaces."""
+ return ["HEAD", "--branches", "--tags", "--remotes"]
+
+
+def materialize_container_matrix_spec(
+ source: Path, destination: Path, workers: int
+) -> str:
+ try:
+ document = json.loads(source.read_text(encoding="utf-8"))
+ except json.JSONDecodeError as error:
+ raise ValueError(f"matrix spec is not valid JSON: {source}") from error
+ if not isinstance(document, dict):
+ raise ValueError("matrix spec must be a JSON object")
+ product_environment = document.get("product_environment", {})
+ if not isinstance(product_environment, dict) or not all(
+ isinstance(key, str) and isinstance(value, str)
+ for key, value in product_environment.items()
+ ):
+ raise ValueError("matrix spec product_environment must be string-to-string")
+ declared_workers = product_environment.get("CBM_WORKERS")
+ expected_workers = str(workers)
+ if declared_workers not in {None, expected_workers}:
+ raise ValueError(
+ "matrix spec CBM_WORKERS conflicts with the container resource budget: "
+ f"spec={declared_workers} coordinator={expected_workers}"
+ )
+ document["product_environment"] = {
+ **product_environment,
+ "CBM_WORKERS": expected_workers,
+ }
+ build_environment = document.get("build_environment", {})
+ if not isinstance(build_environment, dict) or not all(
+ isinstance(key, str) and isinstance(value, str)
+ for key, value in build_environment.items()
+ ):
+ raise ValueError("matrix spec build_environment must be string-to-string")
+ declared_compilers = {
+ key for key in DEFAULT_BUILD_ENVIRONMENT if key in build_environment
+ }
+ if declared_compilers and declared_compilers != set(DEFAULT_BUILD_ENVIRONMENT):
+ raise ValueError("container matrix specs must declare CC and CXX together")
+ document["build_environment"] = {
+ **DEFAULT_BUILD_ENVIRONMENT,
+ **build_environment,
+ }
+ payload = (json.dumps(document, indent=2, sort_keys=True) + "\n").encode("utf-8")
+ destination.write_bytes(payload)
+ return hashlib.sha256(payload).hexdigest()
+
+
+def build_measured_command(
+ *,
+ docker: str,
+ image: str,
+ platform_name: str,
+ resources: dict[str, Any],
+ container_name: str,
+ work_volume: str,
+ results_volume: str,
+ source_revision: str,
+ bundle_name: str,
+ repository_snapshot_sha256: str,
+ runner_arguments: list[str],
+ experiment_root: str,
+ uid: int | None,
+ gid: int | None,
+ corpus_environment: dict[str, str] | None = None,
+) -> list[str]:
+ command = [
+ docker,
+ "run",
+ "--rm",
+ # Candidate CLIs can detach supervised workers. Docker's init forwards
+ # stop signals and reaps each exited descendant in O(children) total
+ # work, preventing earlier cells from polluting later process tables.
+ "--init",
+ "--name",
+ container_name,
+ "--platform",
+ platform_name,
+ "--cpus",
+ f"{resources['cpus']:g}",
+ "--memory",
+ resources["memory"],
+ "--mount",
+ volume_mount(work_volume, "/benchmark"),
+ "--mount",
+ volume_mount(results_volume, "/results"),
+ "--entrypoint",
+ "/bin/bash",
+ ]
+ if uid is not None and gid is not None:
+ command.extend(("--user", f"{uid}:{gid}"))
+ for key, value in DEFAULT_BUILD_ENVIRONMENT.items():
+ command.extend(("--env", f"{key}={value}"))
+ # Rung 2 of run_benchmark.py's resolution ladder. Pointing at the staged copy this
+ # way means the container needs no new flag, no network, and no second resolver.
+ for key, value in sorted((corpus_environment or {}).items()):
+ command.extend(("--env", f"{key}={value}"))
+ source_key = repository_snapshot_sha256[:20]
+ command.extend(
+ (
+ image,
+ "-c",
+ CONTAINER_SCRIPT,
+ "cbm-benchmark-container",
+ source_revision,
+ bundle_name,
+ source_key,
+ *runner_arguments,
+ "--experiment-root",
+ experiment_root,
+ )
+ )
+ return command
+
+
+def merge_exported_tree(source: Path, destination: Path) -> None:
+ """Merge immutable exported artifacts without replacing different bytes."""
+ destination.mkdir(parents=True, exist_ok=True)
+ for source_path in sorted(source.rglob("*")):
+ relative = source_path.relative_to(source)
+ destination_path = destination / relative
+ if source_path.is_symlink():
+ raise RuntimeError(f"export contains an unsupported symlink: {source_path}")
+ if source_path.is_dir():
+ destination_path.mkdir(parents=True, exist_ok=True)
+ continue
+ if destination_path.exists():
+ if not destination_path.is_file():
+ raise RuntimeError(
+ f"export destination is not a file: {destination_path}"
+ )
+ if file_sha256(source_path) != file_sha256(destination_path):
+ raise RuntimeError(
+ f"export destination contains different bytes: {destination_path}"
+ )
+ continue
+ destination_path.parent.mkdir(parents=True, exist_ok=True)
+ temporary = destination_path.with_name(
+ f".{destination_path.name}.container-export-{os.getpid()}"
+ )
+ shutil.copy2(source_path, temporary)
+ os.replace(temporary, destination_path)
+
+
+def archive_source_bundle(
+ source: Path, destination: Path, expected_sha256: str
+) -> Path:
+ """Persist the exact measured Git bundle before its work volume is disposable."""
+ expected_name = f"repository-{expected_sha256}.bundle"
+ if source.name != expected_name or file_sha256(source) != expected_sha256:
+ raise RuntimeError("source bundle name or SHA-256 does not match its manifest")
+ merge_exported_tree(source.parent, destination)
+ archived = destination / expected_name
+ if file_sha256(archived) != expected_sha256:
+ raise RuntimeError(
+ f"archived source bundle failed SHA-256 verification: {archived}"
+ )
+ return archived
+
+
+def run_command(
+ command: list[str],
+ *,
+ cwd: Path | None = None,
+ capture: bool = False,
+) -> subprocess.CompletedProcess[str]:
+ process = subprocess.run(
+ command,
+ cwd=cwd,
+ text=True,
+ capture_output=capture,
+ check=False,
+ )
+ if process.returncode != 0:
+ detail = ""
+ if capture:
+ detail = (process.stderr or process.stdout).strip()
+ suffix = f": {detail}" if detail else ""
+ raise RuntimeError(
+ f"command failed with exit {process.returncode}: "
+ f"{' '.join(command[:4])}{suffix}"
+ )
+ return process
+
+
+def docker_json(docker: str, arguments: list[str]) -> dict[str, Any]:
+ process = run_command([docker, *arguments], capture=True)
+ try:
+ value = json.loads(process.stdout)
+ except json.JSONDecodeError as error:
+ raise RuntimeError(
+ f"Docker returned invalid JSON for {' '.join(arguments)}"
+ ) from error
+ if not isinstance(value, dict):
+ raise RuntimeError(f"Docker returned non-object JSON for {' '.join(arguments)}")
+ return value
+
+
+def remove_container(docker: str, name: str) -> None:
+ subprocess.run(
+ [docker, "rm", "--force", name],
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ text=True,
+ check=False,
+ )
+
+
+def acquire_history_lock(docker: str, image: str, name: str) -> str:
+ """Serialize coordinators that share one history-level work volume."""
+ try:
+ created = run_command(
+ [
+ docker,
+ "create",
+ "--name",
+ name,
+ "--label",
+ "com.codebase-memory-mcp.benchmark=true",
+ "--label",
+ "com.codebase-memory-mcp.role=coordinator-lock",
+ "--entrypoint",
+ "/bin/true",
+ image,
+ ],
+ capture=True,
+ )
+ container_id = created.stdout.strip()
+ if not container_id:
+ raise RuntimeError(f"Docker did not return a container ID for {name}")
+ return container_id
+ except RuntimeError as error:
+ raise RuntimeError(
+ f"benchmark history is already locked or Docker refused {name}; "
+ "inspect that exact container and remove it only if no coordinator is active"
+ ) from error
+
+
+def benchmark_volume_labels(role: str) -> dict[str, str]:
+ return {
+ "com.codebase-memory-mcp.benchmark": "true",
+ "com.codebase-memory-mcp.role": role,
+ }
+
+
+def ensure_volume(docker: str, name: str, role: str) -> None:
+ inspect = subprocess.run(
+ [docker, "volume", "inspect", name, "--format", "{{json .Labels}}"],
+ text=True,
+ capture_output=True,
+ check=False,
+ )
+ expected = benchmark_volume_labels(role)
+ if inspect.returncode == 0:
+ labels = json.loads(inspect.stdout)
+ if labels != expected:
+ raise RuntimeError(
+ f"Docker volume {name} exists without the expected benchmark "
+ f"ownership labels; choose a different experiment root"
+ )
+ return
+ run_command(
+ [
+ docker,
+ "volume",
+ "create",
+ "--label",
+ "com.codebase-memory-mcp.benchmark=true",
+ "--label",
+ f"com.codebase-memory-mcp.role={role}",
+ name,
+ ]
+ )
+
+
+def apply_work_volume_retention(
+ docker: str,
+ work_volume: str,
+ retention: str,
+ *,
+ successful: bool,
+) -> str:
+ """Retain failed work; remove only owned scratch after a successful export."""
+ if not successful:
+ return "retained_after_failure"
+ if retention == WORK_VOLUME_RETENTION_ALWAYS:
+ return "retained_by_policy"
+ if retention != DEFAULT_WORK_VOLUME_RETENTION:
+ raise ValueError(f"unsupported work-volume retention policy: {retention}")
+ expected = benchmark_volume_labels("work")
+ labels = docker_json(
+ docker,
+ ["volume", "inspect", work_volume, "--format", "{{json .Labels}}"],
+ )
+ if labels != expected:
+ raise RuntimeError(
+ f"Docker volume {work_volume} does not have the expected benchmark "
+ "ownership labels; it was not removed"
+ )
+ run_command([docker, "volume", "rm", work_volume])
+ return WORK_VOLUME_STATUS_REMOVED
+
+
+def copy_to_volume(
+ docker: str,
+ image: str,
+ volume: str,
+ volume_destination: str,
+ source: Path,
+ container_name: str,
+ *,
+ copy_destination: str | None = None,
+) -> None:
+ destination = copy_destination or volume_destination
+ copy_source = f"{source}{os.sep}." if source.is_dir() else str(source)
+ remove_container(docker, container_name)
+ try:
+ run_command(
+ [
+ docker,
+ "create",
+ "--name",
+ container_name,
+ "--mount",
+ volume_mount(volume, volume_destination),
+ "--entrypoint",
+ "/bin/mkdir",
+ image,
+ "-p",
+ destination,
+ ]
+ )
+ run_command([docker, "start", "--attach", container_name])
+ run_command([docker, "cp", copy_source, f"{container_name}:{destination}"])
+ finally:
+ remove_container(docker, container_name)
+
+
+def export_results(
+ docker: str,
+ image: str,
+ results_volume: str,
+ destination: Path,
+ container_name: str,
+) -> None:
+ remove_container(docker, container_name)
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ with tempfile.TemporaryDirectory(
+ prefix=".cbm-container-export-", dir=destination.parent
+ ) as tmpdir:
+ staging = Path(tmpdir)
+ try:
+ run_command(
+ [
+ docker,
+ "create",
+ "--name",
+ container_name,
+ "--mount",
+ volume_mount(results_volume, "/results"),
+ "--entrypoint",
+ "/bin/true",
+ image,
+ ]
+ )
+ run_command([docker, "cp", f"{container_name}:/results/.", str(staging)])
+ finally:
+ remove_container(docker, container_name)
+ merge_exported_tree(staging, destination)
+
+
+def export_volume_subtree(
+ docker: str,
+ image: str,
+ volume: str,
+ volume_destination: str,
+ subtree: str,
+ destination: Path,
+ container_name: str,
+) -> None:
+ """Export one named-volume subtree through the immutable history merge."""
+ remove_container(docker, container_name)
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ with tempfile.TemporaryDirectory(
+ prefix=".cbm-container-subtree-export-", dir=destination.parent
+ ) as tmpdir:
+ staging = Path(tmpdir)
+ try:
+ run_command(
+ [
+ docker,
+ "create",
+ "--name",
+ container_name,
+ "--mount",
+ volume_mount(volume, volume_destination),
+ "--entrypoint",
+ "/bin/true",
+ image,
+ ]
+ )
+ run_command([docker, "cp", f"{container_name}:{subtree}/.", str(staging)])
+ finally:
+ remove_container(docker, container_name)
+ merge_exported_tree(staging, destination)
+
+
+def parse_bundle_heads(bundle: Path) -> list[dict[str, str]]:
+ process = run_command(
+ ["git", "bundle", "list-heads", str(bundle)], cwd=ROOT, capture=True
+ )
+ heads: list[dict[str, str]] = []
+ for line in process.stdout.splitlines():
+ revision, separator, ref = line.partition(" ")
+ if separator and len(revision) == 40:
+ heads.append({"revision": revision, "ref": ref})
+ return heads
+
+
+def git_output(arguments: list[str]) -> str:
+ return run_command(["git", *arguments], cwd=ROOT, capture=True).stdout.strip()
+
+
+def build_parser() -> argparse.ArgumentParser:
+ parser = argparse.ArgumentParser(description=__doc__)
+ source = parser.add_mutually_exclusive_group()
+ source.add_argument("--matrix-spec", type=Path)
+ source.add_argument("--quick", action="store_true")
+ source.add_argument("--full", action="store_true")
+ parser.add_argument("--experiment-root", type=Path, required=True)
+ parser.add_argument("--cpus", type=float, required=True)
+ parser.add_argument("--memory", required=True)
+ parser.add_argument("--workers", type=int, required=True)
+ parser.add_argument(
+ "--build-jobs",
+ type=int,
+ help=(
+ "candidate build parallelism; defaults to the complete --cpus budget "
+ "rounded up"
+ ),
+ )
+ parser.add_argument("--image")
+ parser.add_argument("--docker", default="docker")
+ parser.add_argument(
+ "--work-volume-retention",
+ choices=WORK_VOLUME_RETENTION_CHOICES,
+ default=DEFAULT_WORK_VOLUME_RETENTION,
+ help=(
+ "failed-runs removes owned work scratch after a successful verified export "
+ "but retains it after failure (default); always retains it after success too"
+ ),
+ )
+ parser.add_argument(
+ "--invocation-surface",
+ choices=("run_container_experiment.py", "run_experiments.py --container"),
+ default="run_container_experiment.py",
+ help=argparse.SUPPRESS,
+ )
+ parser.add_argument(
+ "--product-env",
+ action="append",
+ default=[],
+ metavar="CBM_KEY=VALUE",
+ help="Candidate environment for automatic --quick/--full container presets.",
+ )
+ parser.add_argument(
+ "--corpus",
+ action="append",
+ default=[],
+ metavar="ID",
+ help=(
+ "Stage this corpus into the container in addition to any named by the "
+ "matrix spec's benchmark_args, which are detected automatically. Repeatable."
+ ),
+ )
+ parser.add_argument(
+ "--corpus-repo",
+ action="append",
+ default=[],
+ metavar="ID=PATH",
+ help=(
+ "Resolve a corpus id from an existing local checkout, repeatable. Same "
+ "spelling and precedence as run_benchmark.py: this wins, then "
+ "CBM_BENCH_CORPUS_, then ~/.cache/codebase-memory-mcp/bench-repos/."
+ ),
+ )
+ parser.add_argument(
+ "--corpus-manifest",
+ default="",
+ help="Corpus registry; defaults to benchmarks/corpora-v1.json.",
+ )
+ parser.add_argument(
+ "--clone-missing-real-repos",
+ action="store_true",
+ help=(
+ "Allow cloning a pinned corpus that is not already available. Cloning "
+ "happens on the host before the measured container starts, so the "
+ "measurement itself never depends on the network."
+ ),
+ )
+ parser.add_argument(
+ "--corpus-timeout",
+ type=int,
+ default=1800,
+ help="Seconds allowed for each host-side corpus resolution or clone.",
+ )
+ parser.add_argument(
+ "runner_arguments",
+ nargs=argparse.REMAINDER,
+ help="Additional run_experiments.py arguments after --.",
+ )
+ return parser
+
+
+def parse_arguments(argv: list[str] | None = None) -> argparse.Namespace:
+ parser = build_parser()
+ args = parser.parse_args(argv)
+ if not args.quick and not args.full and args.matrix_spec is None:
+ args.quick = True
+ try:
+ args.resources = validate_resources(args.cpus, args.memory, args.workers)
+ args.build_jobs = resolve_build_jobs(args.cpus, args.build_jobs)
+ args.runner_arguments = validate_forwarded_arguments(args.runner_arguments)
+ args.platform = native_linux_platform(platform.machine())
+ experiment_module = load_experiment_module()
+ args.product_environment = (
+ experiment_module.parse_product_environment_arguments(args.product_env)
+ )
+ declared_workers = args.product_environment.pop("CBM_WORKERS", None)
+ if declared_workers not in {None, str(args.resources["workers"])}:
+ raise ValueError(
+ "--product-env CBM_WORKERS conflicts with the container resource "
+ f"budget: environment={declared_workers} "
+ f"coordinator={args.resources['workers']}"
+ )
+ if args.matrix_spec is not None and args.product_environment:
+ raise ValueError(
+ "--product-env only applies to container --quick/--full; put explicit "
+ "matrix environments in the matrix spec"
+ )
+ except ValueError as error:
+ parser.error(str(error))
+ args.experiment_root = args.experiment_root.expanduser().resolve()
+ if args.matrix_spec is not None:
+ args.matrix_spec = args.matrix_spec.expanduser().resolve()
+ if not args.matrix_spec.is_file():
+ parser.error(f"matrix spec does not exist: {args.matrix_spec}")
+ return args
+
+
+def main(argv: list[str] | None = None) -> int:
+ args = parse_arguments(argv)
+ tracked = git_output(["status", "--porcelain", "--untracked-files=no"])
+ if tracked:
+ raise RuntimeError(
+ "benchmark source worktree has tracked changes; commit or preserve them "
+ "before creating the immutable container input"
+ )
+ source_revision = git_output(["rev-parse", "HEAD"])
+ docker_info = docker_json(args.docker, ["info", "--format", "{{json .}}"])
+ server_platform = native_linux_platform(str(docker_info.get("Architecture", "")))
+ if server_platform != args.platform:
+ raise RuntimeError(
+ f"Docker server architecture {server_platform} does not match native "
+ f"host platform {args.platform}; emulation is not valid for performance"
+ )
+
+ dockerfile_sha = file_sha256(DOCKERFILE)
+ image = args.image or (
+ f"cbm-benchmark-runtime:{dockerfile_sha[:12]}-{args.platform.rsplit('/', 1)[1]}"
+ )
+ if args.image is None:
+ with tempfile.TemporaryDirectory(
+ prefix="cbm-benchmark-empty-build-context-"
+ ) as empty_context:
+ run_command(
+ [
+ args.docker,
+ "build",
+ "--platform",
+ args.platform,
+ "--file",
+ str(DOCKERFILE),
+ "--tag",
+ image,
+ empty_context,
+ ]
+ )
+ image_metadata = docker_json(
+ args.docker,
+ [
+ "image",
+ "inspect",
+ image,
+ "--format",
+ "{{json .}}",
+ ],
+ )
+ if (
+ f"{image_metadata.get('Os')}/{image_metadata.get('Architecture')}"
+ != args.platform
+ ):
+ raise RuntimeError(
+ f"image platform {image_metadata.get('Os')}/"
+ f"{image_metadata.get('Architecture')} does not match {args.platform}"
+ )
+ runtime_image_identity = runtime_image_sha256(image_metadata)
+
+ history_key = hashlib.sha256(str(args.experiment_root).encode("utf-8")).hexdigest()[
+ :16
+ ]
+ work_volume = f"cbm-benchmark-work-{history_key}"
+ results_volume = f"cbm-benchmark-results-{history_key}"
+ history_lock_name = f"cbm-benchmark-lock-{history_key}"
+ history_lock_id = acquire_history_lock(args.docker, image, history_lock_name)
+
+ name_prefix = f"cbm-benchmark-{history_key}-{os.getpid()}"
+ seed_name = f"{name_prefix}-seed"
+ measured_name = f"{name_prefix}-measured"
+ export_name = f"{name_prefix}-export"
+ archived_bundle: Path | None = None
+ benchmark_succeeded = False
+ try:
+ ensure_volume(args.docker, work_volume, "work")
+ ensure_volume(args.docker, results_volume, "results")
+ with tempfile.TemporaryDirectory(prefix="cbm-benchmark-input-") as tmpdir:
+ input_root = Path(tmpdir)
+ bundle_staging = input_root / "source-bundles"
+ bundle_staging.mkdir()
+ bundle = bundle_staging / "repository.bundle"
+ run_command(
+ [
+ "git",
+ "bundle",
+ "create",
+ str(bundle),
+ *bundle_revision_arguments(),
+ ],
+ cwd=ROOT,
+ )
+ run_command(
+ ["git", "bundle", "verify", str(bundle)], cwd=ROOT, capture=True
+ )
+ bundle_sha = file_sha256(bundle)
+ bundle_name = f"repository-{bundle_sha}.bundle"
+ copied_bundle = bundle_staging / bundle_name
+ bundle.replace(copied_bundle)
+ bundle_heads = parse_bundle_heads(copied_bundle)
+ repository_snapshot = repository_snapshot_sha256(
+ source_revision, bundle_heads
+ )
+ archived_bundle = archive_source_bundle(
+ copied_bundle,
+ args.experiment_root / "source-bundles",
+ bundle_sha,
+ )
+ source_key = repository_snapshot[:20]
+ copy_to_volume(
+ args.docker,
+ image,
+ work_volume,
+ "/benchmark",
+ copied_bundle,
+ seed_name,
+ )
+
+ runner_arguments: list[str]
+ matrix_sha: str | None = None
+ effective_matrix_sha: str | None = None
+ if args.matrix_spec is not None:
+ matrix_sha = file_sha256(args.matrix_spec)
+ provisional_matrix = input_root / "matrix-effective.json"
+ effective_matrix_sha = materialize_container_matrix_spec(
+ args.matrix_spec,
+ provisional_matrix,
+ args.resources["workers"],
+ )
+ matrix_name = f"matrix-{effective_matrix_sha}.json"
+ copied_matrix = input_root / matrix_name
+ provisional_matrix.replace(copied_matrix)
+ copy_to_volume(
+ args.docker,
+ image,
+ work_volume,
+ "/benchmark",
+ copied_matrix,
+ seed_name,
+ )
+ runner_arguments = ["--matrix-spec", f"/benchmark/{matrix_name}"]
+ elif args.full:
+ runner_arguments = [
+ "--full",
+ "--product-env",
+ f"CBM_WORKERS={args.resources['workers']}",
+ ]
+ else:
+ runner_arguments = [
+ "--quick",
+ "--product-env",
+ f"CBM_WORKERS={args.resources['workers']}",
+ ]
+ for key, value in sorted(args.product_environment.items()):
+ runner_arguments.extend(("--product-env", f"{key}={value}"))
+ runner_arguments.extend(("--build-jobs", str(args.build_jobs)))
+ runner_arguments.extend(args.runner_arguments)
+
+ # A campaign spec names its corpora in benchmark_args, so the caller does
+ # not have to restate them here and cannot accidentally stage a different
+ # set from the one the cells will ask for. --corpus adds to that.
+ spec_corpora = (
+ corpora_required_by_spec(
+ json.loads(copied_matrix.read_text(encoding="utf-8"))
+ )
+ if args.matrix_spec is not None
+ else []
+ )
+ corpus_ids = sorted(set(spec_corpora) | set(args.corpus))
+ staged_corpora = stage_corpora(
+ docker=args.docker,
+ image=image,
+ work_volume=work_volume,
+ corpus_ids=corpus_ids,
+ corpus_repo=args.corpus_repo,
+ corpus_manifest=args.corpus_manifest,
+ allow_clone=args.clone_missing_real_repos,
+ timeout=args.corpus_timeout,
+ container_name=seed_name,
+ )
+ corpus_environment = {
+ corpus_env_key(entry["id"]): entry["container_path"]
+ for entry in staged_corpora
+ }
+
+ run_key = container_run_key(
+ source_revision=source_revision,
+ repository_snapshot_sha256=repository_snapshot,
+ matrix_spec_sha256=effective_matrix_sha,
+ runtime_image_sha256=runtime_image_identity,
+ resources=args.resources,
+ runner_arguments=runner_arguments,
+ corpora=staged_corpora,
+ )
+ container_experiment_root = f"/results/runsets/{run_key}"
+
+ manifest = {
+ "schema_version": 1,
+ "recorded_at_utc": utc_now(),
+ "source_revision": source_revision,
+ "source_tree": git_output(["rev-parse", "HEAD^{tree}"]),
+ "bundle_sha256": bundle_sha,
+ "bundle_heads": bundle_heads,
+ "repository_snapshot_sha256": repository_snapshot,
+ "matrix_spec_sha256": matrix_sha,
+ "effective_matrix_spec_sha256": effective_matrix_sha,
+ "image": image,
+ "image_id": image_metadata.get("Id"),
+ "image_repo_digests": image_metadata.get("RepoDigests") or [],
+ "runtime_image_sha256": runtime_image_identity,
+ "docker_server": {
+ key: docker_info.get(key)
+ for key in (
+ "Architecture",
+ "Driver",
+ "MemTotal",
+ "NCPU",
+ "OperatingSystem",
+ "OSType",
+ "ServerVersion",
+ )
+ },
+ "platform": args.platform,
+ "resources": args.resources,
+ "build_jobs": args.build_jobs,
+ "default_build_environment": DEFAULT_BUILD_ENVIRONMENT,
+ "invocation_surface": args.invocation_surface,
+ "history_lock_container": history_lock_name,
+ "history_lock_container_id": history_lock_id,
+ "work_volume": work_volume,
+ "results_volume": results_volume,
+ "work_volume_retention": args.work_volume_retention,
+ "results_volume_retained_for_resume": True,
+ # Legacy pre-execution capability field. Final disposition is emitted
+ # only after successful export and ownership-checked cleanup.
+ "volumes_retained_for_resume": True,
+ "source_bundle_archive": str(archived_bundle),
+ "runner_arguments": runner_arguments,
+ "run_key": run_key,
+ "container_experiment_root": container_experiment_root,
+ "container_repository": f"/benchmark/sources/{source_key}",
+ # Which corpus bytes were measured, pin-verified on the host before the
+ # container started. Without this a published number names a corpus id
+ # but not the commit behind it.
+ "staged_corpora": staged_corpora,
+ }
+ manifest_path = write_container_manifest(
+ input_root,
+ source_revision,
+ bundle_sha,
+ manifest,
+ )
+ copy_to_volume(
+ args.docker,
+ image,
+ results_volume,
+ "/results",
+ manifest_path.parent,
+ seed_name,
+ copy_destination="/results/manifests",
+ )
+
+ uid = os.getuid() if hasattr(os, "getuid") else None
+ gid = os.getgid() if hasattr(os, "getgid") else None
+ if uid is not None and gid is not None:
+ run_command(
+ [
+ args.docker,
+ "run",
+ "--rm",
+ "--mount",
+ volume_mount(work_volume, "/benchmark"),
+ "--mount",
+ volume_mount(results_volume, "/results"),
+ "--entrypoint",
+ "/bin/chown",
+ image,
+ "-R",
+ f"{uid}:{gid}",
+ "/benchmark",
+ "/results",
+ ]
+ )
+ measured = build_measured_command(
+ docker=args.docker,
+ image=image,
+ platform_name=args.platform,
+ resources=args.resources,
+ container_name=measured_name,
+ work_volume=work_volume,
+ results_volume=results_volume,
+ source_revision=source_revision,
+ bundle_name=bundle_name,
+ repository_snapshot_sha256=repository_snapshot,
+ runner_arguments=runner_arguments,
+ experiment_root=container_experiment_root,
+ uid=uid,
+ gid=gid,
+ corpus_environment=corpus_environment,
+ )
+ measured_process = subprocess.run(measured, text=True, check=False)
+ export_results(
+ args.docker,
+ image,
+ results_volume,
+ args.experiment_root,
+ export_name,
+ )
+ if measured_process.returncode != 0:
+ failure_logs = failure_log_export_root(
+ args.experiment_root, source_revision
+ )
+ try:
+ export_volume_subtree(
+ args.docker,
+ image,
+ work_volume,
+ "/benchmark",
+ (
+ f"/benchmark/sources/{source_key}/.worktrees/"
+ "benchmark-candidates/build-logs"
+ ),
+ failure_logs,
+ export_name,
+ )
+ failure_log_detail = (
+ f"; candidate build logs exported to {failure_logs}"
+ )
+ except RuntimeError as log_error:
+ failure_log_detail = (
+ "; candidate build logs could not be exported automatically "
+ f"({log_error}); inspect {work_volume} at "
+ f"/benchmark/sources/{source_key}/.worktrees/"
+ "benchmark-candidates/build-logs"
+ )
+ raise RuntimeError(
+ "container benchmark failed with exit "
+ f"{measured_process.returncode}; partial immutable results were "
+ f"exported to {args.experiment_root}{failure_log_detail}"
+ )
+ benchmark_succeeded = True
+ except Exception as error:
+ work_volume_status = apply_work_volume_retention(
+ args.docker,
+ work_volume,
+ args.work_volume_retention,
+ successful=False,
+ )
+ bundle_detail = (
+ f"; source bundle archived at {archived_bundle}"
+ if archived_bundle is not None
+ else ""
+ )
+ raise RuntimeError(
+ f"{error}; work volume {work_volume_status}: {work_volume}; "
+ f"results volume retained for inspection or resume: {results_volume}"
+ f"{bundle_detail}"
+ ) from error
+ finally:
+ for name in (seed_name, measured_name, export_name):
+ remove_container(args.docker, name)
+ if not benchmark_succeeded:
+ remove_container(args.docker, history_lock_id)
+
+ try:
+ try:
+ work_volume_status = apply_work_volume_retention(
+ args.docker,
+ work_volume,
+ args.work_volume_retention,
+ successful=True,
+ )
+ except Exception as error:
+ raise RuntimeError(
+ "container benchmark completed and immutable results were exported to "
+ f"{args.experiment_root}, but work-volume cleanup failed; inspect "
+ f"{work_volume}: {error}"
+ ) from error
+ finally:
+ remove_container(args.docker, history_lock_id)
+
+ print(
+ json.dumps(
+ {
+ "status": "complete",
+ "experiment_root": str(args.experiment_root),
+ "work_volume": work_volume,
+ "results_volume": results_volume,
+ "history_lock_container": history_lock_name,
+ "history_lock_container_id": history_lock_id,
+ "work_volume_retention": args.work_volume_retention,
+ "work_volume_status": work_volume_status,
+ "results_volume_retained_for_resume": True,
+ "volumes_retained_for_resume": (
+ work_volume_status != WORK_VOLUME_STATUS_REMOVED
+ ),
+ "source_bundle_archive": str(archived_bundle),
+ },
+ sort_keys=True,
+ )
+ )
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/benchmarks/run_evidence_suite.py b/benchmarks/run_evidence_suite.py
new file mode 100755
index 000000000..bdda996c6
--- /dev/null
+++ b/benchmarks/run_evidence_suite.py
@@ -0,0 +1,494 @@
+#!/usr/bin/env python3
+"""Describe and gather the unified performance and rank-evidence experiment suite.
+
+This layer does not redefine either benchmark. The production ``--full`` performance
+preset remains 13 logical configurations repeated three times. The fixed rank diagnostic
+is generated by ``campaign_specs.py`` and, like the performance suite, is consumed by
+``run_experiments.py``. This module adds the missing decision contract: stable suite/cell
+names, plain-English questions, PR-review sources, runtime policy, canonical native or
+container commands, and environment metadata in one auditable receipt.
+"""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import json
+import platform
+import shutil
+import subprocess
+import sys
+from pathlib import Path
+from typing import Any
+
+try: # Package import under tests; script-local import for direct execution.
+ from benchmarks import rank_hypotheses as rank_evidence
+except ModuleNotFoundError: # pragma: no cover - direct script execution
+ import rank_hypotheses as rank_evidence
+
+
+ROOT = Path(__file__).resolve().parents[1]
+PERFORMANCE_SUITE_NAME = rank_evidence.PERFORMANCE_SUITE_NAME
+RANK_SUITE_NAME = rank_evidence.RANK_SUITE_NAME
+UNIFIED_SUITE_NAME = rank_evidence.UNIFIED_SUITE_NAME
+PUBLIC_EXPERIMENT_ENTRYPOINT = "benchmarks/run_experiments.py"
+RANK_SPEC_GENERATOR = "benchmarks/campaign_specs.py"
+RANK_QUICK_SPEC_NAME = "rank-hypotheses-quick-v2.json"
+
+PR_DECISION_CONTEXT = {
+ "pull_request": {
+ "number": 1245,
+ "title": (
+ "True incremental indexing: clean-rebuild parity, 6x post-edit indexing "
+ "speedup, explicit freshness, and graph-derived search ranking"
+ ),
+ "url": "https://github.com/DeusData/codebase-memory-mcp/pull/1245",
+ },
+ "maintainer_review": {
+ "url": (
+ "https://github.com/DeusData/codebase-memory-mcp/pull/1245"
+ "#issuecomment-5139755349"
+ ),
+ "evidence_bar": [
+ "retain immutable audit manifests and honest counter-metrics",
+ "measure against current main rather than a stale comparator",
+ "resolve the ranking direction among PageRank, weighted degree, and LinkRank",
+ "separate repeated observations from independent corpora",
+ "treat scope and atomic reviewability as a non-benchmark acceptance blocker",
+ ],
+ },
+ "original_ranking_objection": {
+ "url": (
+ "https://github.com/DeusData/codebase-memory-mcp/pull/151"
+ "#issuecomment-4142397457"
+ ),
+ "question": (
+ "Does PageRank improve task-relevant architectural retrieval over degree "
+ "enough to justify its conceptual and computation cost?"
+ ),
+ },
+ "author_response_and_requested_measurement": {
+ "url": (
+ "https://github.com/DeusData/codebase-memory-mcp/pull/1245"
+ "#issuecomment-5160077201"
+ ),
+ "decision_rule": (
+ "Prefer whichever scorer measures better on real retrieval quality after "
+ "accounting for latency, memory, multilingual stability, and failure modes."
+ ),
+ },
+}
+
+PERFORMANCE_HYPOTHESES: dict[str, dict[str, str]] = {
+ "PERF-H1": {
+ "name": "Exact incremental indexing speed",
+ "question": (
+ "Does post-edit indexing preserve clean-rebuild graph parity while reducing "
+ "latency relative to the current upstream comparator?"
+ ),
+ },
+ "PERF-H2": {
+ "name": "Automatic dependency indexing cost",
+ "question": (
+ "What initial-index, post-edit, query-latency, and memory cost buys automatic "
+ "installed dependency source coverage?"
+ ),
+ },
+ "PERF-H3": {
+ "name": "Derived result freshness tradeoff",
+ "question": (
+ "What latency and correctness tradeoff results from refreshing all derived "
+ "views at publication instead of explicitly deferring them?"
+ ),
+ },
+ "PERF-H4": {
+ "name": "Graph ranking computation overhead",
+ "question": (
+ "How much indexing latency, query latency, and peak memory are attributable "
+ "to graph ranking when rank-enabled and rank-disabled cells are paired?"
+ ),
+ },
+ "PERF-H5": {
+ "name": "Similarity pass overhead",
+ "question": (
+ "How much indexing latency and memory are attributable to SIMILAR_TO clone "
+ "analysis while graph correctness remains fixed?"
+ ),
+ },
+ "PERF-H6": {
+ "name": "Semantic edge pass overhead",
+ "question": (
+ "How much indexing latency and memory are attributable to semantic-edge "
+ "publication while graph correctness remains fixed?"
+ ),
+ },
+ "PERF-H7": {
+ "name": "Git history pass overhead",
+ "question": (
+ "How much indexing latency and memory are attributable to Git-history edge "
+ "publication while graph correctness remains fixed?"
+ ),
+ },
+ "PERF-H8": {
+ "name": "HTTP link pass overhead",
+ "question": (
+ "How much indexing latency and memory are attributable to HTTP call-to-route "
+ "linking while graph correctness remains fixed?"
+ ),
+ },
+ "PERF-H9": {
+ "name": "Optional capability Pareto frontier",
+ "question": (
+ "Which measured capability bundle is non-dominated across correctness, index "
+ "latency, query latency, response size, and peak resident memory?"
+ ),
+ },
+ "PERF-H10": {
+ "name": "Cross-version performance stability",
+ "question": (
+ "Do historical checkpoints, the latest branch, and current upstream preserve "
+ "their claimed correctness and cost ordering under one paired workload?"
+ ),
+ },
+}
+
+_NATIVE_CANDIDATES = ("upstream-main", "pre-today-major", "pre-upstream-merge")
+_LATEST_PROFILES: tuple[tuple[str, tuple[str, ...]], ...] = (
+ ("automatic-dependency-source-indexing-disabled", ("PERF-H1", "PERF-H10")),
+ ("automatic-dependency-source-indexing-enabled", ("PERF-H2",)),
+ ("upstream-equivalent", ("PERF-H1", "PERF-H9", "PERF-H10")),
+ ("derived-results-refresh-at-publish", ("PERF-H3",)),
+ ("rank-disabled", ("PERF-H4", "PERF-H9")),
+ ("similarity-disabled", ("PERF-H5", "PERF-H9")),
+ ("semantic-edges-disabled", ("PERF-H6", "PERF-H9")),
+ ("git-history-disabled", ("PERF-H7", "PERF-H9")),
+ ("http-links-disabled", ("PERF-H8", "PERF-H9")),
+ ("minimal-indexing", ("PERF-H9",)),
+)
+
+
+def question_records(ids: tuple[str, ...]) -> list[dict[str, str]]:
+ return [{"id": item, **PERFORMANCE_HYPOTHESES[item]} for item in ids]
+
+
+def performance_cells(preset: str) -> list[dict[str, Any]]:
+ """Return the external evidence map without changing production experiment cells."""
+ if preset not in {"quick", "full"}:
+ raise ValueError("performance preset must be quick or full")
+ repetitions = 1 if preset == "quick" else 3
+ logical: list[tuple[str, str, tuple[str, ...]]] = [
+ (candidate, "candidate-native-configuration", ("PERF-H1", "PERF-H10"))
+ for candidate in _NATIVE_CANDIDATES
+ ]
+ logical.append(("latest", _LATEST_PROFILES[0][0], _LATEST_PROFILES[0][1]))
+ if preset == "full":
+ logical.extend(
+ ("latest", profile, hypothesis_ids)
+ for profile, hypothesis_ids in _LATEST_PROFILES[1:]
+ )
+ cells = []
+ for repetition in range(1, repetitions + 1):
+ for candidate, profile, hypothesis_ids in logical:
+ cells.append(
+ {
+ "cell_name": (
+ f"PERF-CELL — {candidate} / {profile} / repetition {repetition}"
+ ),
+ "candidate": candidate,
+ "profile": profile,
+ "repetition": repetition,
+ "hypotheses": list(hypothesis_ids),
+ "questions": question_records(hypothesis_ids),
+ }
+ )
+ return cells
+
+
+def automatic_performance_cell_count(preset: str) -> int:
+ return len(performance_cells(preset))
+
+
+def run_text(command: list[str], repository: Path) -> str:
+ process = subprocess.run(
+ command, cwd=repository, text=True, capture_output=True, check=False
+ )
+ return process.stdout.strip() if process.returncode == 0 else "unavailable"
+
+
+def file_metadata(path: Path) -> dict[str, Any]:
+ if not path.is_file():
+ return {"path": str(path), "present": False}
+ stat = path.stat()
+ return {
+ "path": str(path.resolve()),
+ "present": True,
+ "sha256": hashlib.sha256(path.read_bytes()).hexdigest(),
+ "size_bytes": stat.st_size,
+ "mtime_epoch_seconds": stat.st_mtime,
+ "birthtime_epoch_seconds": getattr(stat, "st_birthtime", None),
+ }
+
+
+def environment_metadata(repository: Path) -> dict[str, Any]:
+ installed = shutil.which("codebase-memory-mcp")
+ return {
+ "git": {
+ "revision": run_text(["git", "rev-parse", "HEAD"], repository),
+ "tree": run_text(["git", "rev-parse", "HEAD^{tree}"], repository),
+ "branch": run_text(["git", "branch", "--show-current"], repository),
+ "status_porcelain": run_text(
+ ["git", "status", "--short", "--untracked-files=all"], repository
+ ),
+ },
+ "python": {
+ "executable": sys.executable,
+ "version": platform.python_version(),
+ "implementation": platform.python_implementation(),
+ },
+ "host": {
+ "platform": platform.platform(),
+ "machine": platform.machine(),
+ "processor": platform.processor(),
+ },
+ "binaries": {
+ "repository_build": file_metadata(
+ repository / "build" / "c" / "codebase-memory-mcp"
+ ),
+ "installed_codebase_memory_mcp": file_metadata(Path(installed))
+ if installed
+ else {"present": False},
+ },
+ }
+
+
+def container_command_suffix(container: dict[str, Any] | None) -> list[str]:
+ """Return the one public container flag spelling shared by both suites."""
+ if container is None:
+ return []
+ required = {"cpus", "memory", "workers"}
+ if set(container) != required:
+ raise ValueError(
+ "container execution requires exactly cpus, memory, and workers"
+ )
+ cpus = container["cpus"]
+ workers = container["workers"]
+ memory = container["memory"]
+ if (
+ not isinstance(cpus, (int, float))
+ or isinstance(cpus, bool)
+ or cpus <= 0
+ or not isinstance(workers, int)
+ or isinstance(workers, bool)
+ or workers <= 0
+ or workers > cpus
+ or not isinstance(memory, str)
+ or not memory.strip()
+ ):
+ raise ValueError(
+ "container cpus and workers must be positive, workers may not exceed "
+ "cpus, and memory must be non-empty"
+ )
+ cpus_text = str(int(cpus)) if float(cpus).is_integer() else str(cpus)
+ return [
+ "--container",
+ "--cpus",
+ cpus_text,
+ "--memory",
+ memory,
+ "--workers",
+ str(workers),
+ ]
+
+
+def build_receipt(
+ *,
+ repository: Path,
+ output_root: Path,
+ performance_preset: str,
+ hypotheses_preset: str,
+ rank_build: dict[str, str],
+ container: dict[str, Any] | None = None,
+) -> dict[str, Any]:
+ repository = repository.resolve()
+ output_root = output_root.resolve()
+ if hypotheses_preset != "quick":
+ raise ValueError("the rank evidence preset is currently quick")
+ for key in ("target", "compiler", "cflags"):
+ if not rank_build.get(key):
+ raise ValueError(f"rank build metadata requires non-empty {key}")
+ performance_root = output_root / "performance"
+ rank_root = output_root / "rank-evidence"
+ rank_spec_root = rank_root / "specs"
+ rank_spec = rank_spec_root / RANK_QUICK_SPEC_NAME
+ execution_suffix = container_command_suffix(container)
+ performance_command = [
+ "uv",
+ "run",
+ "python",
+ "benchmarks/run_experiments.py",
+ f"--{performance_preset}",
+ "--experiment-root",
+ str(performance_root),
+ *execution_suffix,
+ ]
+ rank_preparation_command = [
+ "uv",
+ "run",
+ "python",
+ RANK_SPEC_GENERATOR,
+ "--quick-hypotheses",
+ "--out-dir",
+ str(rank_spec_root),
+ ]
+ rank_command = [
+ "uv",
+ "run",
+ "python",
+ PUBLIC_EXPERIMENT_ENTRYPOINT,
+ "--matrix-spec",
+ str(rank_spec),
+ "--experiment-root",
+ str(rank_root),
+ *execution_suffix,
+ ]
+ cells = performance_cells(performance_preset)
+ rank_profiles = rank_evidence.quick_hypothesis_profiles()
+ return {
+ "schema_version": 1,
+ "suite": {"name": UNIFIED_SUITE_NAME},
+ "execution": {
+ "mode": "container" if container is not None else "native",
+ "container_resources": dict(container) if container is not None else None,
+ "public_entrypoint": PUBLIC_EXPERIMENT_ENTRYPOINT,
+ },
+ "decision_context": PR_DECISION_CONTEXT,
+ "performance": {
+ "name": PERFORMANCE_SUITE_NAME,
+ "preset": performance_preset,
+ "expected_cells": len(cells),
+ "cells": cells,
+ "runtime_policy": "run_to_completion",
+ "public_entrypoint": PUBLIC_EXPERIMENT_ENTRYPOINT,
+ "compatibility": (
+ "The production preset, commands, workload, candidates, profiles, index "
+ "mode, and repetitions are unchanged; this receipt adds an external "
+ "cell-to-question map only."
+ ),
+ "command": performance_command,
+ "recovery_command": performance_command,
+ },
+ "hypotheses": {
+ "name": RANK_SUITE_NAME,
+ "preset": hypotheses_preset,
+ "candidate_cells": len(rank_profiles),
+ "candidate_profiles": rank_profiles,
+ "questions": rank_evidence.public_hypothesis_registry(),
+ "runtime_policy": (
+ "one repetition per fixed evidence arm over MCP; measure actual duration; "
+ "no suite wall-clock target or cutoff"
+ ),
+ "public_entrypoint": PUBLIC_EXPERIMENT_ENTRYPOINT,
+ "preparation_command": rank_preparation_command,
+ "matrix_spec": str(rank_spec),
+ "build": dict(sorted(rank_build.items())),
+ "build_provenance": {
+ "status": "declared_expectation_pending_artifact_verification",
+ "expectation": dict(sorted(rank_build.items())),
+ "authority": (
+ "resolved candidate, compiler, flags, and binary hashes retained by "
+ "run_experiments.py are authoritative"
+ ),
+ },
+ "compatibility_frontend": (
+ "benchmarks/autotune.py remains available for retained native binary-path "
+ "workflows; it is not the public unified execution path"
+ ),
+ "command": rank_command,
+ "recovery_command": rank_command,
+ },
+ "environment": environment_metadata(repository),
+ "output_root": str(output_root),
+ }
+
+
+def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("--repository", type=Path, default=ROOT)
+ parser.add_argument(
+ "--output-root",
+ type=Path,
+ default=ROOT / ".worktrees" / "benchmark-experiments" / "unified-evidence",
+ )
+ parser.add_argument(
+ "--performance-preset", choices=("quick", "full"), default="full"
+ )
+ parser.add_argument("--hypotheses-preset", choices=("quick",), default="quick")
+ parser.add_argument(
+ "--build-target",
+ required=True,
+ help="Exact build command/target used for the rank-candidate binary.",
+ )
+ parser.add_argument(
+ "--compiler", required=True, help="Exact compiler identity/version."
+ )
+ parser.add_argument(
+ "--cflags", required=True, help="Exact optimization/profiling flags."
+ )
+ parser.add_argument(
+ "--out",
+ type=Path,
+ help="Receipt path; defaults to OUTPUT_ROOT/evidence-suite-receipt.json.",
+ )
+ parser.add_argument(
+ "--container",
+ action="store_true",
+ help="Emit canonical container commands for both performance and rank suites.",
+ )
+ parser.add_argument("--cpus", type=float)
+ parser.add_argument("--memory")
+ parser.add_argument("--workers", type=int)
+ return parser.parse_args(argv)
+
+
+def main(argv: list[str] | None = None) -> int:
+ args = parse_args(argv)
+ output_root = args.output_root.expanduser().resolve()
+ supplied_resources = (args.cpus, args.memory, args.workers)
+ if args.container and any(value is None for value in supplied_resources):
+ raise ValueError("--container requires --cpus, --memory, and --workers")
+ if not args.container and any(value is not None for value in supplied_resources):
+ raise ValueError("--cpus, --memory, and --workers require --container")
+ receipt = build_receipt(
+ repository=args.repository.expanduser().resolve(),
+ output_root=output_root,
+ performance_preset=args.performance_preset,
+ hypotheses_preset=args.hypotheses_preset,
+ rank_build={
+ "target": args.build_target,
+ "compiler": args.compiler,
+ "cflags": args.cflags,
+ },
+ container=(
+ {"cpus": args.cpus, "memory": args.memory, "workers": args.workers}
+ if args.container
+ else None
+ ),
+ )
+ output_root.mkdir(parents=True, exist_ok=True)
+ destination = (
+ args.out.expanduser().resolve()
+ if args.out
+ else output_root / "evidence-suite-receipt.json"
+ )
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ destination.write_text(
+ json.dumps(receipt, indent=2, sort_keys=True) + "\n", encoding="utf-8"
+ )
+ print(
+ json.dumps({"receipt": str(destination), "suite": UNIFIED_SUITE_NAME}, indent=2)
+ )
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/benchmarks/run_experiments.py b/benchmarks/run_experiments.py
new file mode 100755
index 000000000..44e0c1565
--- /dev/null
+++ b/benchmarks/run_experiments.py
@@ -0,0 +1,3068 @@
+#!/usr/bin/env python3
+"""Run an immutable, resumable benchmark experiment plan and retain an auditable disk trail.
+
+This is the canonical multi-run entry point. Retained flag spellings, persisted keys,
+and `.worktrees/benchmark-campaign/` directories remain readable; new interfaces and
+records use "experiment" consistently.
+"""
+
+from __future__ import annotations
+
+import argparse
+import copy
+import hashlib
+import json
+import math
+import os
+import platform
+import shutil
+import signal
+import socket
+import subprocess
+import sys
+import tempfile
+import time
+import uuid
+from contextlib import suppress
+from datetime import datetime, timezone
+from pathlib import Path, PurePosixPath, PureWindowsPath
+from typing import Any
+
+CONFIG_SPELLING_SPEC_PATH = Path(__file__).with_name("config-spellings-v1.json")
+CONTAINER_COORDINATOR = Path(__file__).with_name("run_container_experiment.py")
+WORK_VOLUME_RETENTION_FAILED_RUNS = "failed-runs"
+WORK_VOLUME_RETENTION_ALWAYS = "always"
+WORK_VOLUME_RETENTION_CHOICES = (
+ WORK_VOLUME_RETENTION_FAILED_RUNS,
+ WORK_VOLUME_RETENTION_ALWAYS,
+)
+DEFAULT_WORK_VOLUME_RETENTION = WORK_VOLUME_RETENTION_FAILED_RUNS
+with CONFIG_SPELLING_SPEC_PATH.open(encoding="utf-8") as stream:
+ CONFIG_SPELLING_SPEC = json.load(stream)
+if CONFIG_SPELLING_SPEC.get("schema_version") != 1:
+ raise RuntimeError(
+ f"unsupported benchmark config spelling schema: {CONFIG_SPELLING_SPEC_PATH}"
+ )
+DERIVED_RESULTS_AT_PUBLISH_PROFILE = CONFIG_SPELLING_SPEC["profiles"][
+ "derived_results_refresh_at_publish"
+]["canonical"]
+DERIVED_RESULTS_AT_PUBLISH_EXPERIMENT_LABEL = CONFIG_SPELLING_SPEC["experiment_labels"][
+ "derived_results_refresh_at_publish"
+]["canonical"]
+CONFIG_OVERRIDE_SPELLINGS = {
+ entry["id"]: entry for entry in CONFIG_SPELLING_SPEC["config_overrides"]
+}
+DERIVED_RESULTS_AT_PUBLISH_OVERRIDE = CONFIG_OVERRIDE_SPELLINGS[
+ "incremental_derived_results_refresh_at_publish"
+]["canonical"]
+
+BENCHMARK_ENVIRONMENT_POLICY_PATH = Path(__file__).with_name(
+ "environment-policy-v1.json"
+)
+with BENCHMARK_ENVIRONMENT_POLICY_PATH.open(encoding="utf-8") as stream:
+ BENCHMARK_ENVIRONMENT_POLICY = json.load(stream)
+if BENCHMARK_ENVIRONMENT_POLICY.get("schema_version") != 1:
+ raise RuntimeError(
+ f"unsupported benchmark environment policy: {BENCHMARK_ENVIRONMENT_POLICY_PATH}"
+ )
+PRODUCT_ENVIRONMENT_PREFIX = BENCHMARK_ENVIRONMENT_POLICY["product_environment_prefix"]
+HARNESS_OWNED_PRODUCT_ENV = frozenset(
+ BENCHMARK_ENVIRONMENT_POLICY["harness_owned_keys"]
+)
+BUILD_ENVIRONMENT_KEYS = frozenset(
+ BENCHMARK_ENVIRONMENT_POLICY["build_environment_keys"]
+)
+
+
+SCHEMA_VERSION = 1
+# Must stay in sync with QUALITY_BACKGROUND_CAPABILITIES in run_benchmark.py: the plan
+# layer rejects a spec the benchmark layer would refuse anyway, so the failure arrives
+# at plan-expansion time instead of hours into a runset.
+QUALITY_BACKGROUND_CAPABILITIES = frozenset({"similarity", "semantic_edges", "rank"})
+EXPERIMENT_DEFINITION_VERSION = 1
+DEFAULT_MINIMUM_FREE_BYTES = 2 * 1024 * 1024 * 1024
+DEFAULT_STALE_LOCK_SECONDS = 6 * 60 * 60
+FILENAME_DATETIME_FORMAT = "%Y-%m-%d-%H%M%S.%fZ"
+DEFAULT_CANDIDATE_REFS = (
+ ("upstream-main", "upstream/main"),
+ ("pre-today-major", "api-consolidation-stable-2026-07-16-semantic-v2"),
+ ("pre-upstream-merge", "pre-upstream-main-merge-2026-07-19"),
+ ("latest", "HEAD"),
+)
+# Fallback chain tried only for the built-in "upstream/main" baseline default, which
+# requires a remote literally named "upstream". Era-pinned tags (pre-today-major,
+# pre-upstream-merge) and every --candidate-ref override stay fail-closed: an
+# unresolvable ref raises rather than silently substituting a different comparison
+# point. Once api-consolidation merges to main and "upstream" stops existing, this
+# lets --quick/--full keep working without editing DEFAULT_CANDIDATE_REFS.
+UPSTREAM_MAIN_FALLBACK_REFS = ("upstream/main", "origin/main", "main")
+CANONICAL_BENCHMARK_SCRIPT = Path(__file__).with_name("run_benchmark.py")
+LEGACY_BENCHMARK_SCRIPT_SUFFIXES = (
+ ("scripts", "benchmark-incremental-speed.py"),
+ ("benchmarks", "incremental_speed.py"),
+)
+IDENTITY_FIELDS = (
+ "identity_version",
+ "revision",
+ "binary_sha256",
+ "build",
+ "capabilities",
+ "capability_support",
+ "transport",
+ "scenario",
+ "repetition",
+ "harness_version",
+ "command",
+ "cwd",
+ "environment",
+ "parameters",
+ "timeout_seconds",
+ "accepted_exit_codes",
+)
+BENCHMARK_ARGS_RESERVED_FLAGS = frozenset(
+ {
+ "--binary",
+ "--build-metadata-json",
+ "--capability-quality",
+ "--candidate-revision",
+ "--config",
+ "--config-profile",
+ "--facts-dir",
+ "--frontier-files",
+ "--include-logs",
+ "--index-mode",
+ "--matrix",
+ "--matrix-scenarios",
+ "--out",
+ "--product-env",
+ "--quality-background-repo",
+ "--quality-background-revision",
+ "--repo-root",
+ "--repo-revision",
+ "--self-dogfood",
+ "--self-dogfood-scenarios",
+ "--timeout",
+ "--transport",
+ "--work-root",
+ }
+)
+
+
+def utc_now() -> str:
+ return datetime.now(timezone.utc).isoformat()
+
+
+def filename_datetime(moment: datetime | None = None) -> str:
+ """Return a sortable, filename-safe UTC datetime with collision-level precision."""
+ current = moment or datetime.now(timezone.utc)
+ return current.astimezone(timezone.utc).strftime(FILENAME_DATETIME_FORMAT)
+
+
+def experiment_version() -> str:
+ """Return the sortable version of the experiment definition, not a run number."""
+ return f"v{EXPERIMENT_DEFINITION_VERSION:04d}"
+
+
+def read_experiment_version(document: dict[str, Any]) -> str | None:
+ """Read the current key or its legacy on-disk spelling without writing the legacy key."""
+ current = document.get("experiment_version")
+ legacy = document.get("campaign_version")
+ if current is not None and legacy is not None and current != legacy:
+ raise ValueError("experiment_version conflicts with legacy campaign_version")
+ value = current if current is not None else legacy
+ if value is not None and value != experiment_version():
+ raise ValueError(f"experiment_version must be {experiment_version()}")
+ return value
+
+
+def runset_identity(spec_payload: bytes) -> str:
+ """Identify an immutable runset so preparing the same spec resumes in place."""
+ return hashlib.sha256(spec_payload).hexdigest()[:12]
+
+
+def automatic_runset_identity(spec: dict[str, Any]) -> str:
+ """Hash semantic inputs while allowing an identical runset to be path-remapped."""
+ normalized = json.loads(json.dumps(spec))
+ normalized.pop("runset_id", None)
+ normalized.pop("benchmark_script", None)
+ normalized.pop("cwd", None)
+ for background_key in ("repository_background", "quality_background"):
+ background = normalized.get(background_key)
+ if isinstance(background, dict):
+ background.pop("repo", None)
+ candidates = normalized.get("candidates")
+ if isinstance(candidates, list):
+ for candidate in candidates:
+ if isinstance(candidate, dict):
+ candidate.pop("binary", None)
+ return runset_identity(canonical_json(normalized))
+
+
+def _validate_runset_identity(runset: str) -> str:
+ if len(runset) != 12 or any(char not in "0123456789abcdef" for char in runset):
+ raise ValueError(
+ f"runset identity must be 12 lowercase hexadecimal characters: {runset!r}"
+ )
+ return runset
+
+
+def automatic_experiment_name(preset: str, source: dict[str, str], runset: str) -> str:
+ """Name a resumable experiment without confusing source and execution datetimes."""
+ if preset not in {"quick", "full"}:
+ raise ValueError(f"automatic preset must be quick or full: {preset!r}")
+ revision = source.get("revision", "")
+ commit_datetime = source.get("commit_datetime_slug", "")
+ if len(revision) != 40 or not commit_datetime:
+ raise ValueError("source must contain a full revision and commit_datetime_slug")
+ return (
+ f"{experiment_version()}-{preset}-commit-{commit_datetime}-{revision[:12]}-"
+ f"runset-{_validate_runset_identity(runset)}"
+ )
+
+
+def automatic_spec_name(preset: str, runset: str) -> str:
+ if preset not in {"quick", "full"}:
+ raise ValueError(f"automatic preset must be quick or full: {preset!r}")
+ return f"spec-{experiment_version()}-{preset}-runset-{_validate_runset_identity(runset)}.json"
+
+
+def generated_artifact_name(
+ kind: str,
+ runset: str,
+ suffix: str,
+ *,
+ preset: str | None = None,
+ moment: datetime | None = None,
+ nonce: str | None = None,
+) -> str:
+ """Name generated evidence while keeping its stable runset identity visible."""
+ if not kind or any(not (char.isalnum() or char == "-") for char in kind):
+ raise ValueError(f"artifact kind is not path-safe: {kind!r}")
+ if preset is not None and preset not in {"quick", "full", "custom"}:
+ raise ValueError(f"artifact preset is invalid: {preset!r}")
+ if not suffix.startswith(".") or "/" in suffix:
+ raise ValueError(f"artifact suffix is invalid: {suffix!r}")
+ if nonce is not None and (
+ not nonce or any(not (char.isalnum() or char in "-_") for char in nonce)
+ ):
+ raise ValueError(f"artifact nonce is not path-safe: {nonce!r}")
+ parts = [kind, experiment_version()]
+ if preset is not None:
+ parts.append(preset)
+ parts.extend(
+ (
+ "runset",
+ _validate_runset_identity(runset),
+ "generated",
+ filename_datetime(moment),
+ )
+ )
+ if nonce is not None:
+ parts.append(nonce)
+ return "-".join(parts) + suffix
+
+
+def _run_text(command: list[str], *, cwd: Path) -> str:
+ process = subprocess.run(
+ command, cwd=cwd, capture_output=True, text=True, check=False
+ )
+ if process.returncode != 0:
+ detail = process.stderr.strip() or process.stdout.strip() or "no diagnostic"
+ raise RuntimeError(
+ f"command failed ({process.returncode}): {' '.join(command)}: {detail}"
+ )
+ return process.stdout.strip()
+
+
+def resolve_commit(repository: Path, ref: str) -> str:
+ """Peel a branch, tag, or commit ref to the full commit object ID."""
+ revision = _run_text(
+ ["git", "rev-parse", "--verify", f"{ref}^{{commit}}"],
+ cwd=repository,
+ )
+ if len(revision) != 40 or any(
+ char not in "0123456789abcdef" for char in revision.lower()
+ ):
+ raise RuntimeError(
+ f"git resolved {ref!r} to an invalid commit ID: {revision!r}"
+ )
+ return revision.lower()
+
+
+def commit_identity(repository: Path, ref: str) -> dict[str, str]:
+ """Return a peeled commit, its repository datetime, and its exact tree."""
+ revision = resolve_commit(repository, ref)
+ committed_at = _run_text(
+ ["git", "show", "-s", "--format=%cI", revision], cwd=repository
+ )
+ try:
+ parsed = datetime.fromisoformat(committed_at.replace("Z", "+00:00"))
+ except ValueError as error:
+ raise RuntimeError(
+ f"git returned an invalid commit datetime for {revision}: {committed_at!r}"
+ ) from error
+ tree = _run_text(
+ ["git", "rev-parse", "--verify", f"{revision}^{{tree}}"], cwd=repository
+ )
+ return {
+ "revision": revision,
+ "committed_at": parsed.isoformat(),
+ "commit_datetime_slug": parsed.strftime("%Y-%m-%d-%H%M"),
+ "tree": tree,
+ }
+
+
+def resolve_default_candidate_ref(repository: Path, label: str, ref: str) -> str:
+ """Resolve a default candidate ref, retrying survivable baseline aliases only.
+
+ Only the built-in "upstream/main" baseline gets a fallback chain (see
+ UPSTREAM_MAIN_FALLBACK_REFS), because it is the one default expected to age past
+ a merge: the remote may be renamed or absent in a fresh clone. Era-pinned tag
+ defaults and explicit --candidate-ref overrides are not touched here and remain
+ fail-closed in materialize_candidate: an unresolvable ref raises a clear error
+ instead of silently running a different comparison.
+ """
+ del label
+ if ref != "upstream/main":
+ return ref
+ for candidate_ref in UPSTREAM_MAIN_FALLBACK_REFS:
+ try:
+ resolve_commit(repository, candidate_ref)
+ except RuntimeError:
+ continue
+ return candidate_ref
+ return ref
+
+
+def parse_candidate_ref_override(value: str) -> tuple[str, str]:
+ """Parse one repeatable --candidate-ref LABEL=REF argument."""
+ label, separator, ref = value.partition("=")
+ if not separator or not label or not ref:
+ raise ValueError(f"--candidate-ref must be LABEL=REF: {value!r}")
+ known_labels = {default_label for default_label, _ in DEFAULT_CANDIDATE_REFS}
+ if label not in known_labels:
+ raise ValueError(
+ f"--candidate-ref label must be one of {sorted(known_labels)}: {label!r}"
+ )
+ return label, ref
+
+
+def _path_within(path: Path, root: Path) -> bool:
+ try:
+ path.resolve().relative_to(root.resolve())
+ except ValueError:
+ return False
+ return True
+
+
+def _candidate_slug(label: str) -> str:
+ if not label or any(not (char.isalnum() or char in "-_") for char in label):
+ raise ValueError(f"candidate label is not path-safe: {label!r}")
+ return label
+
+
+def ensure_clean_tracked_worktree(repository: Path, role: str) -> None:
+ """Reject tracked edits while allowing ignored retained evidence and build output."""
+ tracked_status = _run_text(
+ ["git", "status", "--porcelain", "--untracked-files=no"], cwd=repository
+ )
+ if tracked_status:
+ raise RuntimeError(
+ f"{role} has tracked modifications; commit or restore them before measurement: "
+ f"{repository}"
+ )
+
+
+def _registered_candidate_worktrees(
+ repository: Path, candidate_roots: list[Path], revision: str
+) -> list[Path]:
+ listing = _run_text(["git", "worktree", "list", "--porcelain"], cwd=repository)
+ registered: list[Path] = []
+ for block in listing.split("\n\n"):
+ fields: dict[str, str] = {}
+ for line in block.splitlines():
+ key, separator, value = line.partition(" ")
+ if separator:
+ fields[key] = value
+ path_value = fields.get("worktree")
+ if fields.get("HEAD") == revision and path_value:
+ registered.append(Path(path_value).resolve())
+ matches: list[Path] = []
+ seen: set[Path] = set()
+ for root in candidate_roots:
+ for candidate in sorted(registered):
+ if candidate not in seen and _path_within(candidate, root):
+ matches.append(candidate)
+ seen.add(candidate)
+ return matches
+
+
+def _resolved_candidate_search_roots(
+ candidate_root: Path, candidate_search_roots: list[Path] | None
+) -> list[Path]:
+ roots = [candidate_root]
+ for value in candidate_search_roots or []:
+ root = value.expanduser().resolve()
+ if root in roots:
+ continue
+ if not root.is_dir():
+ raise ValueError(f"candidate search root is not a directory: {root}")
+ roots.append(root)
+ return roots
+
+
+def _make_probe(
+ worktree: Path,
+ target: str,
+ recipe: str,
+ build_environment: dict[str, str] | None = None,
+) -> str:
+ definition = f"{target}:\n\t@{recipe}\n"
+ environment = os.environ.copy()
+ environment.update(build_environment or {})
+ make_variables = [
+ f"{key}={value}" for key, value in sorted((build_environment or {}).items())
+ ]
+ process = subprocess.run(
+ ["make", "-s", "-f", "Makefile.cbm", "-f", "-", *make_variables, target],
+ cwd=worktree,
+ env=environment,
+ input=definition,
+ capture_output=True,
+ text=True,
+ check=False,
+ )
+ if process.returncode != 0:
+ raise RuntimeError(process.stderr.strip() or process.stdout.strip())
+ return process.stdout.strip()
+
+
+def _compiler_identity(
+ worktree: Path,
+ make_variable: str,
+ build_environment: dict[str, str] | None = None,
+) -> str:
+ try:
+ return _make_probe(
+ worktree,
+ f"cbm-print-{make_variable.lower()}-identity",
+ f"$({make_variable}) --version",
+ build_environment,
+ ).splitlines()[0]
+ except (OSError, RuntimeError, IndexError):
+ return "unknown (see datetime-named build log)"
+
+
+def _production_flags(
+ worktree: Path,
+ make_variable: str,
+ build_environment: dict[str, str] | None = None,
+) -> str:
+ """Read canonical candidate flags without duplicating Makefile definitions."""
+ try:
+ value = _make_probe(
+ worktree,
+ f"cbm-print-{make_variable.lower()}",
+ f"printf '%s\\n' '$({make_variable})'",
+ build_environment,
+ )
+ except (OSError, RuntimeError):
+ return "unknown (see candidate Makefile.cbm and build log)"
+ return value or "not declared by candidate Makefile.cbm"
+
+
+def _candidate_capability_support(label: str) -> dict[str, bool]:
+ if label == "upstream-main":
+ return {
+ "rank": False,
+ "dependencies": False,
+ "similarity": True,
+ "semantic_edges": True,
+ "git_history": True,
+ "http_links": False,
+ }
+ return {
+ "rank": True,
+ "dependencies": True,
+ "similarity": True,
+ "semantic_edges": True,
+ "git_history": True,
+ "http_links": True,
+ }
+
+
+def materialize_candidate(
+ repository: Path,
+ candidate_root: Path,
+ label: str,
+ ref: str,
+ *,
+ jobs: int = 2,
+ build_environment: dict[str, str] | None = None,
+ candidate_search_roots: list[Path] | None = None,
+) -> dict[str, Any]:
+ """Resolve, isolate, production-build, and hash one benchmark candidate."""
+ repository = repository.expanduser().resolve()
+ candidate_root = candidate_root.expanduser().resolve()
+ safe_label = _candidate_slug(label)
+ if jobs <= 0:
+ raise ValueError("build jobs must be positive")
+ explicit_build_environment = validate_build_environment(
+ build_environment, "build_environment"
+ )
+ process_environment = os.environ.copy()
+ process_environment.update(explicit_build_environment)
+ source_identity = commit_identity(repository, ref)
+ revision = source_identity["revision"]
+ candidate_root.mkdir(parents=True, exist_ok=True)
+ search_roots = _resolved_candidate_search_roots(
+ candidate_root, candidate_search_roots
+ )
+ intended = candidate_root / f"{safe_label}-{revision[:12]}"
+ matches = _registered_candidate_worktrees(repository, search_roots, revision)
+ if intended in matches:
+ worktree = intended
+ elif matches:
+ worktree = matches[0]
+ else:
+ if intended.exists():
+ raise RuntimeError(
+ f"candidate path exists but is not the registered {revision} worktree: {intended}"
+ )
+ process = subprocess.run(
+ ["git", "worktree", "add", "--detach", str(intended), revision],
+ cwd=repository,
+ capture_output=True,
+ text=True,
+ check=False,
+ )
+ if process.returncode != 0:
+ detail = process.stderr.strip() or process.stdout.strip() or "no diagnostic"
+ raise RuntimeError(
+ f"could not create candidate worktree {intended}: {detail}"
+ )
+ worktree = intended
+ actual_revision = resolve_commit(worktree, "HEAD")
+ if actual_revision != revision:
+ raise RuntimeError(
+ f"candidate worktree HEAD mismatch: expected={revision} actual={actual_revision} path={worktree}"
+ )
+ ensure_clean_tracked_worktree(worktree, "candidate worktree")
+
+ binary = worktree / "build" / "c" / "codebase-memory-mcp"
+ stable_build = {
+ "target": f"make -j{jobs} -f Makefile.cbm cbm",
+ "compiler": _compiler_identity(worktree, "CC", explicit_build_environment),
+ "cflags": _production_flags(
+ worktree, "CFLAGS_PROD", explicit_build_environment
+ ),
+ "cxx_compiler": _compiler_identity(worktree, "CXX", explicit_build_environment),
+ "cxxflags": _production_flags(
+ worktree, "CXXFLAGS_PROD", explicit_build_environment
+ ),
+ "source_commit_datetime": source_identity["committed_at"],
+ "source_tree": source_identity["tree"],
+ }
+ if explicit_build_environment:
+ stable_build["environment"] = explicit_build_environment
+ cache_path = (
+ candidate_root
+ / "cache"
+ / f"candidate-{experiment_version()}-{safe_label}-commit-{revision[:12]}.json"
+ )
+ if cache_path.is_file() and binary.is_file():
+ try:
+ cached = read_json_object(cache_path).get("candidate")
+ if (
+ isinstance(cached, dict)
+ and cached.get("label") == safe_label
+ and cached.get("revision") == revision
+ and cached.get("binary") == str(binary)
+ and cached.get("build") == stable_build
+ and cached.get("tree") == source_identity["tree"]
+ and cached.get("binary_sha256") == file_sha256(binary)
+ ):
+ return cached
+ except (OSError, ValueError, json.JSONDecodeError):
+ pass
+
+ stamp = filename_datetime()
+ log_root = candidate_root / "build-logs"
+ log_root.mkdir(parents=True, exist_ok=True)
+ build_log = (
+ log_root / f"generated-{stamp}-for-{safe_label}-commit-{revision[:12]}.log"
+ )
+ make_variables = [
+ f"{key}={value}" for key, value in explicit_build_environment.items()
+ ]
+ clean_command = [
+ "make",
+ "-f",
+ "Makefile.cbm",
+ *make_variables,
+ "clean-c",
+ ]
+ command = [
+ "make",
+ f"-j{jobs}",
+ "-f",
+ "Makefile.cbm",
+ *make_variables,
+ "cbm",
+ ]
+ clean_returncode: int | None = None
+ build_returncode: int | None = None
+ with build_log.open("w", encoding="utf-8") as stream:
+ stream.write(f"started_at_utc={utc_now()}\n")
+ stream.write(f"revision={revision}\n")
+ if binary.parent.exists():
+ # Make does not normally encode compiler, flags, or environment in
+ # object prerequisites. Once cache identity validation says this is
+ # a different build, retaining build/c can silently link stale
+ # objects into a binary whose metadata claims the new toolchain.
+ stream.write(f"clean_command={' '.join(clean_command)}\n")
+ stream.flush()
+ clean_process = subprocess.run(
+ clean_command,
+ cwd=worktree,
+ env=process_environment,
+ stdout=stream,
+ stderr=subprocess.STDOUT,
+ text=True,
+ check=False,
+ )
+ clean_returncode = clean_process.returncode
+ stream.write(f"clean_exit_code={clean_returncode}\n")
+ stream.flush()
+ stream.write(f"command={' '.join(command)}\n")
+ if clean_returncode in {None, 0}:
+ stream.flush()
+ process = subprocess.run(
+ command,
+ cwd=worktree,
+ env=process_environment,
+ stdout=stream,
+ stderr=subprocess.STDOUT,
+ text=True,
+ check=False,
+ )
+ build_returncode = process.returncode
+ stream.write(f"finished_at_utc={utc_now()}\n")
+ stream.write(
+ f"exit_code={build_returncode if build_returncode is not None else clean_returncode}\n"
+ )
+ if clean_returncode not in {None, 0}:
+ raise RuntimeError(
+ f"candidate build cleanup failed ({clean_returncode}); see {build_log}"
+ )
+ if build_returncode != 0:
+ raise RuntimeError(
+ f"candidate production build failed ({build_returncode}); see {build_log}"
+ )
+ if not binary.is_file():
+ raise RuntimeError(f"candidate build did not produce {binary}; see {build_log}")
+ candidate = {
+ "label": safe_label,
+ "revision": revision,
+ "binary": str(binary),
+ "binary_sha256": file_sha256(binary),
+ "build": stable_build,
+ "capability_support": _candidate_capability_support(safe_label),
+ "commit_datetime": source_identity["committed_at"],
+ "tree": source_identity["tree"],
+ }
+ metadata_root = candidate_root / "metadata"
+ metadata_root.mkdir(parents=True, exist_ok=True)
+ atomic_write_json(
+ metadata_root
+ / f"generated-{stamp}-for-{safe_label}-commit-{revision[:12]}.json",
+ {
+ **candidate,
+ "ref": ref,
+ "worktree": str(worktree),
+ "build_log": str(build_log),
+ "recorded_at_utc": utc_now(),
+ },
+ )
+ atomic_write_json(
+ cache_path,
+ {
+ "schema_version": SCHEMA_VERSION,
+ "experiment_version": experiment_version(),
+ "candidate": candidate,
+ },
+ )
+ return candidate
+
+
+def materialize_matrix_candidates(
+ repository: Path,
+ candidate_root: Path,
+ spec: dict[str, Any],
+ *,
+ jobs: int,
+ candidate_search_roots: list[Path] | None = None,
+) -> dict[str, Any]:
+ """Resolve candidate ``ref`` entries into the existing immutable binary schema.
+
+ A reusable matrix spec may name arbitrary branches, tags, or commits without
+ embedding worktree-specific binary paths. Already resolved candidate entries
+ remain value-equivalent after the defensive deep copy.
+ """
+ resolved = copy.deepcopy(spec)
+ build_environment = validate_build_environment(
+ resolved.get("build_environment"), "build_environment"
+ )
+ candidates = _nonempty_list(resolved.get("candidates"), "candidates")
+ labels: set[str] = set()
+ for index, candidate in enumerate(candidates):
+ if not isinstance(candidate, dict):
+ raise ValueError(f"candidates[{index}] must be an object")
+ label = candidate.get("label")
+ if not isinstance(label, str) or not label:
+ raise ValueError(f"candidates[{index}].label is invalid")
+ _candidate_slug(label)
+ if label in labels:
+ raise ValueError(f"candidates[{index}].label is duplicated: {label!r}")
+ labels.add(label)
+ ref = candidate.get("ref")
+ if ref is None:
+ continue
+ if not isinstance(ref, str) or not ref:
+ raise ValueError(f"candidates[{index}].ref must be a non-empty string")
+ conflicting = sorted(
+ key
+ for key in ("binary", "binary_sha256", "revision", "build")
+ if key in candidate
+ )
+ if conflicting:
+ raise ValueError(
+ f"candidates[{index}] cannot combine ref with " + ", ".join(conflicting)
+ )
+ capability_support = candidate.get("capability_support")
+ if not isinstance(capability_support, dict) or not all(
+ isinstance(key, str) and key and isinstance(value, bool)
+ for key, value in capability_support.items()
+ ):
+ raise ValueError(
+ f"candidates[{index}].capability_support must explicitly declare "
+ "string-to-boolean support for a ref-based candidate; the runner "
+ "cannot infer branch capabilities safely"
+ )
+ _string_map(candidate.get("environment"), f"candidates[{index}].environment")
+ validate_product_environment(
+ candidate.get("product_environment"),
+ f"candidates[{index}].product_environment",
+ )
+ validate_benchmark_args(
+ candidate.get("benchmark_args"),
+ f"candidates[{index}].benchmark_args",
+ )
+
+ for index, candidate in enumerate(candidates):
+ ref = candidate.get("ref")
+ if ref is None:
+ continue
+ label = candidate["label"]
+ passthrough = {
+ key: copy.deepcopy(candidate[key])
+ for key in (
+ "benchmark_args",
+ "capability_support",
+ "environment",
+ "product_environment",
+ )
+ if key in candidate
+ }
+ materialize_options: dict[str, Any] = {
+ "jobs": jobs,
+ "build_environment": build_environment,
+ }
+ if candidate_search_roots:
+ materialize_options["candidate_search_roots"] = candidate_search_roots
+ materialized = materialize_candidate(
+ repository,
+ candidate_root,
+ label,
+ ref,
+ **materialize_options,
+ )
+ materialized.update(passthrough)
+ candidates[index] = materialized
+ return resolved
+
+
+def matrix_spec_has_candidate_refs(spec: dict[str, Any]) -> bool:
+ candidates = spec.get("candidates")
+ return isinstance(candidates, list) and any(
+ isinstance(candidate, dict) and "ref" in candidate for candidate in candidates
+ )
+
+
+def file_sha256(path: Path) -> str:
+ digest = hashlib.sha256()
+ with path.open("rb") as stream:
+ for chunk in iter(lambda: stream.read(1024 * 1024), b""):
+ digest.update(chunk)
+ return digest.hexdigest()
+
+
+def artifact_manifest(root: Path) -> dict[str, Any]:
+ files = []
+ total_bytes = 0
+ if root.is_dir():
+ for path in sorted(item for item in root.rglob("*") if item.is_file()):
+ size = path.stat().st_size
+ total_bytes += size
+ files.append(
+ {
+ "path": path.relative_to(root).as_posix(),
+ "size_bytes": size,
+ "sha256": file_sha256(path),
+ }
+ )
+ return {"file_count": len(files), "total_bytes": total_bytes, "files": files}
+
+
+def canonical_json(value: Any) -> bytes:
+ return json.dumps(value, separators=(",", ":"), sort_keys=True).encode("utf-8")
+
+
+def atomic_write_json(path: Path, value: Any) -> None:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ temporary = path.parent / f".{path.name}.{os.getpid()}.{uuid.uuid4().hex}.tmp"
+ payload = json.dumps(value, indent=2, sort_keys=True) + "\n"
+ try:
+ with temporary.open("w", encoding="utf-8") as stream:
+ stream.write(payload)
+ stream.flush()
+ os.fsync(stream.fileno())
+ os.replace(temporary, path)
+ try:
+ directory_fd = os.open(path.parent, os.O_RDONLY)
+ try:
+ os.fsync(directory_fd)
+ finally:
+ os.close(directory_fd)
+ except OSError:
+ # Some filesystems do not support directory fsync. The file itself
+ # is still synced before the atomic replacement.
+ pass
+ finally:
+ if temporary.exists():
+ temporary.unlink()
+
+
+def atomic_write_bytes(path: Path, payload: bytes) -> None:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ temporary = path.parent / f".{path.name}.{os.getpid()}.{uuid.uuid4().hex}.tmp"
+ try:
+ with temporary.open("wb") as stream:
+ stream.write(payload)
+ stream.flush()
+ os.fsync(stream.fileno())
+ os.replace(temporary, path)
+ finally:
+ if temporary.exists():
+ temporary.unlink()
+
+
+def read_json_object(path: Path) -> dict[str, Any]:
+ with path.open(encoding="utf-8") as stream:
+ value = json.load(stream)
+ if not isinstance(value, dict):
+ raise ValueError(f"expected JSON object: {path}")
+ return value
+
+
+def is_legacy_benchmark_script_path(value: str) -> bool:
+ """Return whether value names a retired single-run benchmark location."""
+ path_parts = (
+ PurePosixPath(value).parts,
+ PureWindowsPath(value).parts,
+ )
+ return any(
+ tuple(parts[-len(suffix) :]) == suffix
+ for parts in path_parts
+ for suffix in LEGACY_BENCHMARK_SCRIPT_SUFFIXES
+ )
+
+
+def resolve_benchmark_script_path(value: str) -> Path:
+ """Resolve current paths and narrowly migrate retained benchmark script paths."""
+ if is_legacy_benchmark_script_path(value):
+ canonical = CANONICAL_BENCHMARK_SCRIPT.resolve()
+ if not canonical.is_file():
+ raise ValueError(f"canonical benchmark script does not exist: {canonical}")
+ return canonical
+ candidate = Path(value).expanduser().resolve()
+ if not candidate.is_file():
+ raise ValueError(f"benchmark script does not exist: {candidate}")
+ return candidate
+
+
+def build_automatic_spec(
+ repository: Path,
+ benchmark_script: Path,
+ candidates: list[dict[str, Any]],
+ *,
+ preset: str,
+ transport: str = "mcp",
+ product_environment: dict[str, str] | None = None,
+) -> dict[str, Any]:
+ """Build the canonical safe quick or repeated full capability matrix."""
+ if preset not in {"quick", "full"}:
+ raise ValueError("preset must be quick or full")
+ if transport not in {"cli", "mcp"}:
+ raise ValueError("transport must be cli or mcp")
+ repository = repository.expanduser().resolve()
+ benchmark_script = benchmark_script.expanduser().resolve()
+ if not benchmark_script.is_file():
+ raise ValueError(f"benchmark script does not exist: {benchmark_script}")
+ expected_labels = [label for label, _ in DEFAULT_CANDIDATE_REFS]
+ actual_labels = [candidate.get("label") for candidate in candidates]
+ if actual_labels != expected_labels:
+ raise ValueError(
+ f"automatic candidates must be ordered {expected_labels}, got {actual_labels}"
+ )
+ repository_identity = commit_identity(repository, "HEAD")
+ repository_revision = repository_identity["revision"]
+ repository_tree = repository_identity["tree"]
+ runner_sha = file_sha256(Path(__file__).resolve())
+ benchmark_sha = file_sha256(benchmark_script)
+ latest_labels = [label for label, ref in DEFAULT_CANDIDATE_REFS if ref == "HEAD"]
+ native_candidate_labels = [
+ label for label, ref in DEFAULT_CANDIDATE_REFS if ref != "HEAD"
+ ]
+ product_defaults = {
+ "auto_index_deps": "false",
+ "rank_enabled": "true",
+ "similarity_enabled": "true",
+ "semantic_edges_enabled": "true",
+ "githistory_enabled": "true",
+ "httplinks_enabled": "true",
+ }
+
+ def capabilities(**changes: str) -> dict[str, str]:
+ values = dict(product_defaults)
+ values.update(changes)
+ return values
+
+ profiles: list[dict[str, Any]] = [
+ {
+ "label": "candidate-native-configuration",
+ "config_profile": "candidate_native_configuration",
+ "candidate_labels": native_candidate_labels,
+ "capabilities": {},
+ },
+ {
+ "label": "automatic-dependency-source-indexing-disabled",
+ "config_profile": "automatic_dependency_source_indexing_disabled",
+ "candidate_labels": latest_labels,
+ "capabilities": capabilities(),
+ },
+ ]
+ if preset == "full":
+ profiles.extend(
+ (
+ {
+ "label": "automatic-dependency-source-indexing-enabled",
+ "config_profile": "automatic_dependency_source_indexing_enabled",
+ "candidate_labels": latest_labels,
+ "capabilities": capabilities(auto_index_deps="true"),
+ },
+ {
+ "label": "upstream-equivalent",
+ "config_profile": "automatic_dependency_source_indexing_disabled",
+ "candidate_labels": latest_labels,
+ "capabilities": capabilities(
+ rank_enabled="false", httplinks_enabled="false"
+ ),
+ "config_overrides": {
+ "auto_index_deps": "false",
+ "rank_enabled": "false",
+ "httplinks_enabled": "false",
+ },
+ },
+ {
+ "label": DERIVED_RESULTS_AT_PUBLISH_EXPERIMENT_LABEL,
+ "config_profile": DERIVED_RESULTS_AT_PUBLISH_PROFILE,
+ "candidate_labels": latest_labels,
+ "capabilities": {
+ **capabilities(),
+ DERIVED_RESULTS_AT_PUBLISH_OVERRIDE[
+ "key"
+ ]: DERIVED_RESULTS_AT_PUBLISH_OVERRIDE["value"],
+ },
+ },
+ {
+ "label": "rank-disabled",
+ "config_profile": "rank_disabled",
+ "candidate_labels": latest_labels,
+ "capabilities": capabilities(rank_enabled="false"),
+ },
+ {
+ "label": "similarity-disabled",
+ "config_profile": "similarity_disabled",
+ "candidate_labels": latest_labels,
+ "capabilities": capabilities(similarity_enabled="false"),
+ },
+ {
+ "label": "semantic-edges-disabled",
+ "config_profile": "semantic_edges_disabled",
+ "candidate_labels": latest_labels,
+ "capabilities": capabilities(semantic_edges_enabled="false"),
+ },
+ {
+ "label": "git-history-disabled",
+ "config_profile": "git_history_disabled",
+ "candidate_labels": latest_labels,
+ "capabilities": capabilities(githistory_enabled="false"),
+ },
+ {
+ "label": "http-links-disabled",
+ "config_profile": "http_links_disabled",
+ "candidate_labels": latest_labels,
+ "capabilities": capabilities(httplinks_enabled="false"),
+ },
+ {
+ "label": "minimal-indexing",
+ "config_profile": "minimal_indexing",
+ "candidate_labels": latest_labels,
+ "capabilities": capabilities(
+ rank_enabled="false",
+ similarity_enabled="false",
+ semantic_edges_enabled="false",
+ githistory_enabled="false",
+ httplinks_enabled="false",
+ ),
+ },
+ )
+ )
+ spec = {
+ "schema_version": SCHEMA_VERSION,
+ "experiment_version": experiment_version(),
+ "identity_version": 2,
+ "harness_version": (
+ f"automatic-{preset}:benchmark-{benchmark_sha}:runner-{runner_sha}"
+ ),
+ "benchmark_script": str(benchmark_script),
+ "workload": "self_dogfood",
+ "repository_background": {
+ "repo": str(repository),
+ "revision": repository_revision,
+ "tree": repository_tree,
+ "commit_datetime": repository_identity["committed_at"],
+ },
+ "index_mode": "fast" if preset == "quick" else "moderate",
+ "execution_order": "paired_interleaved",
+ "cwd": str(repository),
+ "timeout_seconds": 900,
+ "cell_timeout_seconds": 1800,
+ "accepted_exit_codes": [0, 1],
+ "repetitions": 1 if preset == "quick" else 3,
+ "transports": [transport],
+ "candidates": candidates,
+ "profiles": profiles,
+ "scenarios": [{"name": "c_new_leaf"}],
+ }
+ explicit_product_environment = validate_product_environment(
+ product_environment, "product_environment"
+ )
+ if explicit_product_environment:
+ spec["product_environment"] = explicit_product_environment
+ return spec
+
+
+def identity_document(cell: dict[str, Any]) -> dict[str, Any]:
+ if cell.get("identity_version") != 2:
+ return {
+ key: cell.get(key) for key in IDENTITY_FIELDS if key != "identity_version"
+ }
+ document = {key: cell.get(key) for key in IDENTITY_FIELDS}
+
+ command = list(document.get("command") or [])
+ if command:
+ command[0] = "{benchmark_script}"
+ for flag, replacement in (
+ ("--binary", "{candidate_binary}"),
+ ("--repo-root", "{repository_root}"),
+ ("--quality-background-repo", "{quality_background_root}"),
+ ):
+ for index, token in enumerate(command[:-1]):
+ if token == flag:
+ command[index + 1] = replacement
+ document["command"] = command
+ if document.get("cwd") is not None:
+ document["cwd"] = "{working_directory}"
+ parameters = json.loads(json.dumps(document.get("parameters") or {}))
+ for background_key in ("repository_background", "quality_background"):
+ background = parameters.get(background_key)
+ if isinstance(background, dict) and "repo" in background:
+ background["repo"] = f"{{{background_key}_root}}"
+ document["parameters"] = parameters
+ return document
+
+
+def cell_identity(cell: dict[str, Any]) -> str:
+ return hashlib.sha256(canonical_json(identity_document(cell))).hexdigest()[:24]
+
+
+def validate_cell(cell: dict[str, Any], index: int) -> None:
+ required = {
+ "label": str,
+ "revision": str,
+ "binary_sha256": str,
+ "build": dict,
+ "capabilities": dict,
+ "transport": str,
+ "scenario": str,
+ "repetition": int,
+ "harness_version": str,
+ "command": list,
+ }
+ for key, expected_type in required.items():
+ if not isinstance(cell.get(key), expected_type):
+ raise ValueError(f"cells[{index}].{key} must be {expected_type.__name__}")
+ if not cell["label"] or "=" in cell["label"]:
+ raise ValueError(
+ f"cells[{index}].label must be non-empty and cannot contain '='"
+ )
+ if len(cell["revision"]) != 40:
+ raise ValueError(
+ f"cells[{index}].revision must be a full 40-character commit hash"
+ )
+ if len(cell["binary_sha256"]) != 64:
+ raise ValueError(f"cells[{index}].binary_sha256 must be a full SHA-256")
+ if not cell["command"] or not all(
+ isinstance(item, str) for item in cell["command"]
+ ):
+ raise ValueError(f"cells[{index}].command must be a non-empty string array")
+ if not _is_positive_json_integer(cell["repetition"]):
+ raise ValueError(f"cells[{index}].repetition must be a positive integer")
+ timeout_seconds = cell.get("timeout_seconds")
+ if timeout_seconds is not None and not _is_positive_json_number(timeout_seconds):
+ raise ValueError(
+ f"cells[{index}].timeout_seconds must be a positive finite number"
+ )
+ identity_version = cell.get("identity_version", 1)
+ if not _is_json_integer(identity_version) or identity_version not in {1, 2}:
+ raise ValueError(f"cells[{index}].identity_version must be 1 or 2")
+ accepted = cell.get("accepted_exit_codes", [0])
+ if (
+ not isinstance(accepted, list)
+ or not accepted
+ or not all(_is_json_integer(code) for code in accepted)
+ ):
+ raise ValueError(
+ f"cells[{index}].accepted_exit_codes must be a non-empty integer array"
+ )
+ support = cell.get("capability_support")
+ if support is not None and (
+ not isinstance(support, dict)
+ or not all(
+ isinstance(key, str) and isinstance(value, bool)
+ for key, value in support.items()
+ )
+ ):
+ raise ValueError(
+ f"cells[{index}].capability_support must be a string-to-boolean object"
+ )
+
+
+def validate_plan(plan: dict[str, Any]) -> list[dict[str, Any]]:
+ if (
+ not _is_json_integer(plan.get("schema_version"))
+ or plan.get("schema_version") != SCHEMA_VERSION
+ ):
+ raise ValueError(f"schema_version must be {SCHEMA_VERSION}")
+ cells = plan.get("cells")
+ if not isinstance(cells, list) or not cells:
+ raise ValueError("cells must be a non-empty array")
+ typed_cells: list[dict[str, Any]] = []
+ identities: set[str] = set()
+ for index, value in enumerate(cells):
+ if not isinstance(value, dict):
+ raise ValueError(f"cells[{index}] must be an object")
+ validate_cell(value, index)
+ identity = cell_identity(value)
+ if identity in identities:
+ raise ValueError(f"duplicate cell identity at cells[{index}]: {identity}")
+ identities.add(identity)
+ typed_cells.append(value)
+ return typed_cells
+
+
+def _string_map(value: Any, field: str) -> dict[str, str]:
+ if value is None:
+ return {}
+ if not isinstance(value, dict) or not all(
+ isinstance(key, str) and isinstance(item, str) for key, item in value.items()
+ ):
+ raise ValueError(f"{field} must be a string-to-string object")
+ return dict(value)
+
+
+def validate_product_environment(value: Any, field: str) -> dict[str, str]:
+ values = _string_map(value, field)
+ for key in values:
+ if not key.startswith(PRODUCT_ENVIRONMENT_PREFIX):
+ raise ValueError(
+ f"{field} key must start with {PRODUCT_ENVIRONMENT_PREFIX}: {key!r}"
+ )
+ if key in HARNESS_OWNED_PRODUCT_ENV:
+ raise ValueError(f"{field} key is owned by the benchmark harness: {key}")
+ return values
+
+
+def validate_build_environment(value: Any, field: str) -> dict[str, str]:
+ values = _string_map(value, field)
+ unknown = sorted(set(values) - BUILD_ENVIRONMENT_KEYS)
+ if unknown:
+ raise ValueError(
+ f"{field} key is not in the shared build environment policy: "
+ + ", ".join(unknown)
+ )
+ return dict(sorted(values.items()))
+
+
+def parse_product_environment_arguments(items: list[str]) -> dict[str, str]:
+ values: dict[str, str] = {}
+ for item in items:
+ key, separator, value = item.partition("=")
+ if not separator or not key or not value:
+ raise ValueError(f"--product-env must be key=value, got {item!r}")
+ values[key] = value
+ return validate_product_environment(values, "--product-env")
+
+
+def validate_benchmark_args(value: Any, field: str) -> list[str]:
+ """Validate additive workload arguments without surrendering harness ownership."""
+ if value is None:
+ return []
+ if not isinstance(value, list) or not all(
+ isinstance(item, str) and item for item in value
+ ):
+ raise ValueError(f"{field} must be a string array")
+ reserved = sorted(
+ item
+ for item in value
+ if item.partition("=")[0] in BENCHMARK_ARGS_RESERVED_FLAGS
+ )
+ if reserved:
+ raise ValueError(
+ f"{field} cannot override experiment-owned flags: " + ", ".join(reserved)
+ )
+ return list(value)
+
+
+def _is_json_integer(value: Any) -> bool:
+ """Return whether a decoded JSON value is an integer rather than a boolean."""
+ return isinstance(value, int) and not isinstance(value, bool)
+
+
+def _is_positive_json_integer(value: Any) -> bool:
+ return _is_json_integer(value) and value > 0
+
+
+def _is_positive_json_number(value: Any) -> bool:
+ """Accept finite positive JSON numbers while keeping booleans distinct."""
+ return (
+ isinstance(value, (int, float))
+ and not isinstance(value, bool)
+ and math.isfinite(value)
+ and value > 0
+ )
+
+
+def _nonempty_list(value: Any, field: str) -> list[Any]:
+ if not isinstance(value, list) or not value:
+ raise ValueError(f"{field} must be a non-empty array")
+ return value
+
+
+def _optional_iso_datetime(value: Any, field: str) -> str | None:
+ if value is None:
+ return None
+ if not isinstance(value, str) or not value:
+ raise ValueError(f"{field} must be an ISO 8601 datetime string")
+ try:
+ datetime.fromisoformat(value.replace("Z", "+00:00"))
+ except ValueError as error:
+ raise ValueError(f"{field} must be an ISO 8601 datetime string") from error
+ return value
+
+
+def expand_matrix_spec(spec: dict[str, Any]) -> dict[str, Any]:
+ """Expand a compact benchmark grid into immutable experiment cells."""
+ if (
+ not _is_json_integer(spec.get("schema_version"))
+ or spec.get("schema_version") != SCHEMA_VERSION
+ ):
+ raise ValueError(f"schema_version must be {SCHEMA_VERSION}")
+ harness_version = spec.get("harness_version")
+ benchmark_script = spec.get("benchmark_script")
+ cwd = spec.get("cwd")
+ repetitions = spec.get("repetitions")
+ benchmark_timeout = spec.get("timeout_seconds", 240)
+ index_mode = spec.get("index_mode", "fast")
+ accepted_exit_codes = spec.get("accepted_exit_codes", [0])
+ capability_quality = spec.get("capability_quality")
+ workload = spec.get("workload", "matrix")
+ identity_version = spec.get("identity_version", 1)
+ execution_order = spec.get("execution_order")
+ quality_background = spec.get("quality_background")
+ repository_background = spec.get("repository_background")
+ if not isinstance(harness_version, str) or not harness_version:
+ raise ValueError("harness_version must be a non-empty string")
+ if not isinstance(benchmark_script, str) or not benchmark_script:
+ raise ValueError("benchmark_script must be a non-empty string")
+ if not isinstance(cwd, str) or not cwd:
+ raise ValueError("cwd must be a non-empty string")
+ if not _is_positive_json_integer(repetitions):
+ raise ValueError("repetitions must be a positive integer")
+ if not _is_positive_json_integer(benchmark_timeout):
+ raise ValueError("timeout_seconds must be a positive integer")
+ if index_mode not in {"fast", "moderate", "full"}:
+ raise ValueError("index_mode must be fast, moderate, or full")
+ if execution_order not in {None, "grouped", "paired_interleaved"}:
+ raise ValueError("execution_order must be grouped or paired_interleaved")
+ if capability_quality is not None and (
+ not isinstance(capability_quality, str)
+ or not capability_quality
+ or "=" in capability_quality
+ ):
+ raise ValueError("capability_quality must be a non-empty argument value")
+ if workload not in {"matrix", "self_dogfood"}:
+ raise ValueError("workload must be matrix or self_dogfood")
+ if not _is_json_integer(identity_version) or identity_version not in {1, 2}:
+ raise ValueError("identity_version must be 1 or 2")
+ if capability_quality is not None and workload != "matrix":
+ raise ValueError(
+ "capability_quality cannot be combined with a self_dogfood workload"
+ )
+ if quality_background is not None:
+ if capability_quality not in QUALITY_BACKGROUND_CAPABILITIES:
+ raise ValueError(
+ "quality_background requires capability_quality "
+ + ", ".join(sorted(QUALITY_BACKGROUND_CAPABILITIES))
+ )
+ if not isinstance(quality_background, dict):
+ raise ValueError("quality_background must be an object")
+ background_repo = quality_background.get("repo")
+ background_revision = quality_background.get("revision")
+ background_tree = quality_background.get("tree")
+ background_datetime = _optional_iso_datetime(
+ quality_background.get("commit_datetime"),
+ "quality_background.commit_datetime",
+ )
+ if not isinstance(background_repo, str) or not Path(background_repo).is_dir():
+ raise ValueError("quality_background.repo must be an existing directory")
+ if not isinstance(background_revision, str) or len(background_revision) != 40:
+ raise ValueError("quality_background.revision must be a full commit hash")
+ if not isinstance(background_tree, str) or len(background_tree) != 40:
+ raise ValueError("quality_background.tree must be a full tree hash")
+ quality_background = {
+ "repo": str(Path(background_repo).expanduser().resolve()),
+ "revision": background_revision,
+ "tree": background_tree,
+ }
+ if background_datetime is not None:
+ quality_background["commit_datetime"] = background_datetime
+ if repository_background is not None:
+ if workload != "self_dogfood":
+ raise ValueError("repository_background requires workload self_dogfood")
+ if not isinstance(repository_background, dict):
+ raise ValueError("repository_background must be an object")
+ background_repo = repository_background.get("repo")
+ background_revision = repository_background.get("revision")
+ background_tree = repository_background.get("tree")
+ background_datetime = _optional_iso_datetime(
+ repository_background.get("commit_datetime"),
+ "repository_background.commit_datetime",
+ )
+ if not isinstance(background_repo, str) or not Path(background_repo).is_dir():
+ raise ValueError("repository_background.repo must be an existing directory")
+ if not isinstance(background_revision, str) or len(background_revision) != 40:
+ raise ValueError(
+ "repository_background.revision must be a full commit hash"
+ )
+ if not isinstance(background_tree, str) or len(background_tree) != 40:
+ raise ValueError("repository_background.tree must be a full tree hash")
+ repository_background = {
+ "repo": str(Path(background_repo).expanduser().resolve()),
+ "revision": background_revision,
+ "tree": background_tree,
+ }
+ if background_datetime is not None:
+ repository_background["commit_datetime"] = background_datetime
+ elif workload == "self_dogfood":
+ raise ValueError("workload self_dogfood requires repository_background")
+ if (
+ not isinstance(accepted_exit_codes, list)
+ or not accepted_exit_codes
+ or not all(_is_json_integer(code) for code in accepted_exit_codes)
+ ):
+ raise ValueError("accepted_exit_codes must be a non-empty integer array")
+ cell_timeout = spec.get("cell_timeout_seconds", benchmark_timeout * 4)
+ if not _is_positive_json_integer(cell_timeout):
+ raise ValueError("cell_timeout_seconds must be a positive integer")
+ benchmark_path = resolve_benchmark_script_path(benchmark_script)
+ benchmark_sha256 = file_sha256(benchmark_path)
+
+ candidates = _nonempty_list(spec.get("candidates"), "candidates")
+ candidate_labels = {
+ item.get("label") for item in candidates if isinstance(item, dict)
+ }
+ profiles = _nonempty_list(spec.get("profiles"), "profiles")
+ scenarios = (
+ [{"name": f"{capability_quality}_quality"}]
+ if capability_quality is not None
+ else _nonempty_list(spec.get("scenarios"), "scenarios")
+ )
+ transports = _nonempty_list(spec.get("transports"), "transports")
+ if not all(isinstance(item, str) and item for item in transports):
+ raise ValueError("transports must contain non-empty strings")
+ common_environment = _string_map(spec.get("environment"), "environment")
+ common_product_environment = validate_product_environment(
+ spec.get("product_environment"), "product_environment"
+ )
+ common_benchmark_args = validate_benchmark_args(
+ spec.get("benchmark_args"), "benchmark_args"
+ )
+
+ cells: list[dict[str, Any]] = []
+ for candidate_index, candidate in enumerate(candidates):
+ if not isinstance(candidate, dict):
+ raise ValueError(f"candidates[{candidate_index}] must be an object")
+ candidate_label = candidate.get("label")
+ revision = candidate.get("revision")
+ binary_value = candidate.get("binary")
+ build = candidate.get("build")
+ if (
+ not isinstance(candidate_label, str)
+ or not candidate_label
+ or "=" in candidate_label
+ ):
+ raise ValueError(f"candidates[{candidate_index}].label is invalid")
+ if not isinstance(revision, str) or len(revision) != 40:
+ raise ValueError(
+ f"candidates[{candidate_index}].revision must be a full commit hash"
+ )
+ if not isinstance(binary_value, str) or not binary_value:
+ raise ValueError(
+ f"candidates[{candidate_index}].binary must be a path string"
+ )
+ if not isinstance(build, dict):
+ raise ValueError(f"candidates[{candidate_index}].build must be an object")
+ binary = Path(binary_value).expanduser().resolve()
+ if not binary.is_file():
+ raise ValueError(f"candidate binary does not exist: {binary}")
+ binary_sha = file_sha256(binary)
+ declared_sha = candidate.get("binary_sha256")
+ if declared_sha is not None and declared_sha != binary_sha:
+ raise ValueError(
+ f"candidates[{candidate_index}].binary_sha256 does not match {binary}"
+ )
+ candidate_environment = _string_map(
+ candidate.get("environment"), f"candidates[{candidate_index}].environment"
+ )
+ candidate_product_environment = validate_product_environment(
+ candidate.get("product_environment"),
+ f"candidates[{candidate_index}].product_environment",
+ )
+ candidate_benchmark_args = validate_benchmark_args(
+ candidate.get("benchmark_args"),
+ f"candidates[{candidate_index}].benchmark_args",
+ )
+ candidate_support = candidate.get("capability_support")
+ if candidate_support is not None and (
+ not isinstance(candidate_support, dict)
+ or not all(
+ isinstance(key, str) and isinstance(value, bool)
+ for key, value in candidate_support.items()
+ )
+ ):
+ raise ValueError(
+ f"candidates[{candidate_index}].capability_support must be a string-to-boolean object"
+ )
+
+ for profile_index, profile in enumerate(profiles):
+ if not isinstance(profile, dict):
+ raise ValueError(f"profiles[{profile_index}] must be an object")
+ profile_label = profile.get("label")
+ config_profile = profile.get("config_profile")
+ capabilities = profile.get("capabilities")
+ if (
+ not isinstance(profile_label, str)
+ or not profile_label
+ or "=" in profile_label
+ ):
+ raise ValueError(f"profiles[{profile_index}].label is invalid")
+ if not isinstance(config_profile, str) or not config_profile:
+ raise ValueError(f"profiles[{profile_index}].config_profile is invalid")
+ if not isinstance(capabilities, dict):
+ raise ValueError(
+ f"profiles[{profile_index}].capabilities must be an object"
+ )
+ scoped_candidates = profile.get("candidate_labels")
+ if scoped_candidates is not None:
+ if (
+ not isinstance(scoped_candidates, list)
+ or not scoped_candidates
+ or not all(
+ isinstance(item, str) and item for item in scoped_candidates
+ )
+ ):
+ raise ValueError(
+ f"profiles[{profile_index}].candidate_labels must be a non-empty string array"
+ )
+ unknown_candidates = set(scoped_candidates) - candidate_labels
+ if unknown_candidates:
+ raise ValueError(
+ f"profiles[{profile_index}].candidate_labels contains unknown candidates: "
+ f"{', '.join(sorted(unknown_candidates))}"
+ )
+ if candidate_label not in scoped_candidates:
+ continue
+ overrides = _string_map(
+ profile.get("config_overrides"),
+ f"profiles[{profile_index}].config_overrides",
+ )
+ if config_profile == "candidate_native_configuration":
+ for key, claimed_value in capabilities.items():
+ expected = str(claimed_value).strip().lower()
+ if overrides.get(key, "").strip().lower() != expected:
+ raise ValueError(
+ f"profiles[{profile_index}].capabilities claims {key}={expected} "
+ "but the candidate-native profile does not apply that setting; add the "
+ "same value to config_overrides"
+ )
+ if "incremental_exact_max_affected_paths" in overrides:
+ raise ValueError(
+ "exact cap belongs in scenarios[].exact_caps, not profile overrides"
+ )
+ profile_environment = _string_map(
+ profile.get("environment"), f"profiles[{profile_index}].environment"
+ )
+ profile_product_environment = validate_product_environment(
+ profile.get("product_environment"),
+ f"profiles[{profile_index}].product_environment",
+ )
+ profile_benchmark_args = validate_benchmark_args(
+ profile.get("benchmark_args"),
+ f"profiles[{profile_index}].benchmark_args",
+ )
+
+ for scenario_index, scenario in enumerate(scenarios):
+ if not isinstance(scenario, dict):
+ raise ValueError(f"scenarios[{scenario_index}] must be an object")
+ scenario_name = scenario.get("name")
+ if not isinstance(scenario_name, str) or not scenario_name:
+ raise ValueError(f"scenarios[{scenario_index}].name is invalid")
+ scenario_product_environment = validate_product_environment(
+ scenario.get("product_environment"),
+ f"scenarios[{scenario_index}].product_environment",
+ )
+ scenario_benchmark_args = validate_benchmark_args(
+ scenario.get("benchmark_args"),
+ f"scenarios[{scenario_index}].benchmark_args",
+ )
+ if capability_quality is not None or workload == "self_dogfood":
+ frontier_values: list[int | None] = [None]
+ cap_values: list[int | None] = [None]
+ else:
+ frontier_values = _nonempty_list(
+ scenario.get("frontier_files"),
+ f"scenarios[{scenario_index}].frontier_files",
+ )
+ cap_values = _nonempty_list(
+ scenario.get("exact_caps"),
+ f"scenarios[{scenario_index}].exact_caps",
+ )
+ if not all(
+ _is_positive_json_integer(item) for item in frontier_values
+ ):
+ raise ValueError(
+ "frontier_files must contain positive integers"
+ )
+ if not all(
+ item is None or _is_positive_json_integer(item)
+ for item in cap_values
+ ):
+ raise ValueError(
+ "exact_caps must contain positive integers or null"
+ )
+
+ for transport_index, transport in enumerate(transports):
+ for frontier_files in frontier_values:
+ for exact_cap in cap_values:
+ effective_capabilities = dict(capabilities)
+ effective_capabilities.update(overrides)
+ if capability_quality is not None:
+ command = [
+ str(benchmark_path),
+ "--binary",
+ str(binary),
+ "--capability-quality",
+ capability_quality,
+ "--transport",
+ transport,
+ "--config-profile",
+ config_profile,
+ "--index-mode",
+ index_mode,
+ ]
+ if quality_background is not None:
+ command.extend(
+ (
+ "--quality-background-repo",
+ quality_background["repo"],
+ "--quality-background-revision",
+ quality_background["revision"],
+ )
+ )
+ elif workload == "self_dogfood":
+ assert repository_background is not None
+ command = [
+ str(benchmark_path),
+ "--binary",
+ str(binary),
+ "--self-dogfood",
+ "--repo-root",
+ repository_background["repo"],
+ "--repo-revision",
+ repository_background["revision"],
+ "--self-dogfood-scenarios",
+ scenario_name,
+ "--transport",
+ transport,
+ "--config-profile",
+ config_profile,
+ "--index-mode",
+ index_mode,
+ ]
+ else:
+ command = [
+ str(benchmark_path),
+ "--binary",
+ str(binary),
+ "--matrix",
+ "--matrix-scenarios",
+ scenario_name,
+ "--frontier-files",
+ str(frontier_files),
+ "--transport",
+ transport,
+ "--config-profile",
+ config_profile,
+ "--index-mode",
+ index_mode,
+ ]
+ cap_label = "default"
+ if isinstance(exact_cap, int):
+ effective_capabilities[
+ "incremental_exact_max_affected_paths"
+ ] = str(exact_cap)
+ command.extend(
+ (
+ "--config",
+ f"incremental_exact_max_affected_paths={exact_cap}",
+ )
+ )
+ cap_label = str(exact_cap)
+ for key, value in sorted(overrides.items()):
+ command.extend(("--config", f"{key}={value}"))
+ product_environment = {
+ **common_product_environment,
+ **candidate_product_environment,
+ **profile_product_environment,
+ **scenario_product_environment,
+ }
+ for key, value in sorted(product_environment.items()):
+ command.extend(("--product-env", f"{key}={value}"))
+ benchmark_args = [
+ *common_benchmark_args,
+ *candidate_benchmark_args,
+ *profile_benchmark_args,
+ *scenario_benchmark_args,
+ ]
+ command.extend(benchmark_args)
+ if (
+ capability_quality is not None
+ or workload == "self_dogfood"
+ ):
+ command.append("--include-logs")
+ command.extend(
+ (
+ "--timeout",
+ str(benchmark_timeout),
+ "--out",
+ "{result_path}",
+ )
+ )
+ parameters = {
+ "config_profile": config_profile,
+ "config_overrides": dict(sorted(overrides.items())),
+ "benchmark_script_sha256": benchmark_sha256,
+ "index_mode": index_mode,
+ }
+ # Evidence annotations do not alter commands or capabilities.
+ # Carry them into the immutable cell identity and derived report
+ # input so every H experiment remains traceable to its plain-
+ # English question after matrix expansion.
+ for evidence_key in (
+ "cell_name",
+ "informs_hypotheses",
+ "questions",
+ "expected_observable",
+ "parameter_sources",
+ "evidence_scope",
+ ):
+ if evidence_key in profile:
+ parameters[evidence_key] = profile[evidence_key]
+ if product_environment:
+ parameters["product_environment"] = dict(
+ sorted(product_environment.items())
+ )
+ if benchmark_args:
+ parameters["benchmark_args"] = benchmark_args
+ if capability_quality is not None:
+ parameters["capability_quality"] = capability_quality
+ if quality_background is not None:
+ parameters["quality_background"] = (
+ quality_background
+ )
+ label = f"{candidate_label}.{profile_label}.{transport}.{scenario_name}"
+ elif workload == "self_dogfood":
+ assert repository_background is not None
+ parameters["repository_background"] = (
+ repository_background
+ )
+ label = f"{candidate_label}.{profile_label}.{transport}.{scenario_name}"
+ else:
+ parameters["frontier_files"] = frontier_files
+ parameters["exact_cap"] = exact_cap
+ label = (
+ f"{candidate_label}.{profile_label}.{transport}."
+ f"{scenario_name}.f{frontier_files}.cap{cap_label}"
+ )
+ environment = {
+ **common_environment,
+ **candidate_environment,
+ **profile_environment,
+ }
+ for repetition in range(1, repetitions + 1):
+ cell = {
+ "label": label,
+ "revision": revision,
+ "binary_sha256": binary_sha,
+ "build": build,
+ "capabilities": effective_capabilities,
+ "transport": transport,
+ "scenario": scenario_name,
+ "repetition": repetition,
+ "harness_version": harness_version,
+ "command": command,
+ "cwd": str(Path(cwd).expanduser().resolve()),
+ "parameters": parameters,
+ "timeout_seconds": cell_timeout,
+ "accepted_exit_codes": list(accepted_exit_codes),
+ }
+ if identity_version == 2:
+ cell["identity_version"] = 2
+ if environment:
+ cell["environment"] = environment
+ if isinstance(candidate_support, dict):
+ cell["capability_support"] = dict(
+ sorted(candidate_support.items())
+ )
+ cell["_design"] = {
+ "candidate_index": candidate_index,
+ "profile_index": profile_index,
+ "scenario_index": scenario_index,
+ "transport_index": transport_index,
+ "grouped_position": len(cells),
+ }
+ cells.append(cell)
+ if execution_order == "paired_interleaved":
+ cells.sort(
+ key=lambda cell: (
+ cell["repetition"],
+ cell["_design"]["scenario_index"],
+ cell["_design"]["transport_index"],
+ cell["_design"]["candidate_index"],
+ cell["_design"]["profile_index"],
+ cell["_design"]["grouped_position"],
+ )
+ )
+ for position, cell in enumerate(cells, start=1):
+ cell["parameters"] = {
+ **cell["parameters"],
+ "execution_order": execution_order,
+ "execution_block": cell["repetition"],
+ "execution_position": position,
+ }
+ for cell in cells:
+ cell.pop("_design", None)
+ plan = {"schema_version": SCHEMA_VERSION, "cells": cells}
+ experiment_definition = read_experiment_version(spec)
+ if experiment_definition is not None:
+ plan["experiment_version"] = experiment_definition
+ runset = spec.get("runset_id")
+ if runset is not None:
+ plan["runset_id"] = _validate_runset_identity(runset)
+ if execution_order is not None:
+ plan["execution_order"] = execution_order
+ validate_plan(plan)
+ return plan
+
+
+def ensure_disk_space(root: Path, minimum_free_bytes: int) -> None:
+ root.mkdir(parents=True, exist_ok=True)
+ free = shutil.disk_usage(root).free
+ if free < minimum_free_bytes:
+ raise RuntimeError(
+ f"insufficient experiment disk space: free={free} required={minimum_free_bytes} root={root}"
+ )
+
+
+def resource_snapshot(path: Path) -> dict[str, Any]:
+ disk = shutil.disk_usage(path)
+ try:
+ load_average: list[float] | None = [
+ round(value, 6) for value in os.getloadavg()
+ ]
+ except (AttributeError, OSError):
+ load_average = None
+ physical_memory_bytes: int | None = None
+ try:
+ pages = int(os.sysconf("SC_PHYS_PAGES"))
+ page_size = int(os.sysconf("SC_PAGE_SIZE"))
+ if pages > 0 and page_size > 0:
+ physical_memory_bytes = pages * page_size
+ except (AttributeError, OSError, TypeError, ValueError):
+ pass
+ return {
+ "captured_at_utc": utc_now(),
+ "hostname": socket.gethostname(),
+ "load_average": load_average,
+ "cpu_count": os.cpu_count(),
+ "physical_memory_bytes": physical_memory_bytes,
+ "disk": {
+ "path": str(path.resolve()),
+ "total_bytes": disk.total,
+ "used_bytes": disk.used,
+ "free_bytes": disk.free,
+ },
+ }
+
+
+def validate_experiment_root(
+ root: Path, *, allow_temporary: bool = False, temporary_root: Path | None = None
+) -> Path:
+ """Require retained experiment state to live outside the OS temporary tree."""
+ resolved = root.expanduser().resolve()
+ temp = (temporary_root or Path(tempfile.gettempdir())).expanduser().resolve()
+ if not allow_temporary and (resolved == temp or temp in resolved.parents):
+ raise ValueError(
+ f"experiment root is temporary and may be lost after a crash or reboot: {resolved}; "
+ "choose a durable ignored path, or pass --allow-temporary-experiment-root only "
+ "for disposable tests"
+ )
+ return resolved
+
+
+def process_is_live(pid: int) -> bool:
+ if pid <= 0:
+ return False
+ try:
+ os.kill(pid, 0)
+ except ProcessLookupError:
+ return False
+ except PermissionError:
+ return True
+ return True
+
+
+def acquire_lock(
+ cell_root: Path, stale_after_seconds: int
+) -> tuple[Path, dict[str, Any] | None]:
+ cell_root.mkdir(parents=True, exist_ok=True)
+ lock_path = cell_root / "running.lock"
+ stale_record: dict[str, Any] | None = None
+ if lock_path.exists():
+ try:
+ existing = read_json_object(lock_path)
+ except (OSError, ValueError, json.JSONDecodeError):
+ existing = {"invalid": True}
+ try:
+ started_epoch = float(existing.get("started_epoch", 0.0))
+ pid = int(existing.get("pid", -1))
+ except (TypeError, ValueError):
+ started_epoch = 0.0
+ pid = -1
+ age = time.time() - started_epoch
+ same_host = existing.get("hostname") == socket.gethostname()
+ live = same_host and process_is_live(pid)
+ if live or age < stale_after_seconds:
+ raise RuntimeError(f"benchmark cell is already locked: {lock_path}")
+ stale_record = {"recovered_at_utc": utc_now(), "previous_lock": existing}
+ stale_path = (
+ cell_root / f"stale-lock-{filename_datetime()}-{uuid.uuid4().hex[:8]}.json"
+ )
+ atomic_write_json(stale_path, stale_record)
+ lock_path.unlink()
+ document = {
+ "pid": os.getpid(),
+ "hostname": socket.gethostname(),
+ "started_at_utc": utc_now(),
+ "started_epoch": time.time(),
+ }
+ flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
+ descriptor = os.open(lock_path, flags, 0o600)
+ with os.fdopen(descriptor, "w", encoding="utf-8") as stream:
+ stream.write(json.dumps(document, indent=2, sort_keys=True) + "\n")
+ stream.flush()
+ os.fsync(stream.fileno())
+ return lock_path, stale_record
+
+
+def resolve_result_path(cell_root: Path, completion: dict[str, Any]) -> Path:
+ relative = completion.get("result_path")
+ if not isinstance(relative, str):
+ raise ValueError("completion result_path is missing")
+ candidate = (cell_root / relative).resolve()
+ if cell_root.resolve() not in candidate.parents:
+ raise ValueError("completion result_path escapes the cell directory")
+ return candidate
+
+
+def validate_result(path: Path, cell: dict[str, Any]) -> dict[str, Any]:
+ result = read_json_object(path)
+ metadata = result.get("binary_metadata")
+ actual_sha = metadata.get("sha256") if isinstance(metadata, dict) else None
+ if actual_sha != cell["binary_sha256"]:
+ raise ValueError(
+ f"result binary SHA-256 mismatch: expected={cell['binary_sha256']} actual={actual_sha}"
+ )
+ if result.get("error"):
+ raise ValueError(f"benchmark result contains an error: {result['error']}")
+ run_context = result.get("benchmark_run_context")
+ if run_context is not None:
+ if not isinstance(run_context, dict):
+ raise ValueError("benchmark_run_context must be an object")
+ expected_context = {
+ "cell_identity": cell_identity(cell),
+ "label": cell["label"],
+ "revision": cell["revision"],
+ "repetition": cell["repetition"],
+ "build": cell["build"],
+ "capabilities": cell["capabilities"],
+ "capability_support": cell.get("capability_support", {}),
+ "harness_version": cell["harness_version"],
+ }
+ if run_context != expected_context:
+ raise ValueError("benchmark_run_context does not match the experiment cell")
+ derived = result.get("derived")
+ if not isinstance(derived, dict) or not isinstance(derived.get("passed"), bool):
+ raise ValueError("benchmark result must contain derived.passed as a boolean")
+ cases = result.get("cases")
+ measurements = result.get("measurements")
+ if not (isinstance(cases, list) and cases) and not isinstance(measurements, dict):
+ raise ValueError(
+ "benchmark result must contain non-empty cases or measurements"
+ )
+ expected_background = cell.get("parameters", {}).get("quality_background")
+ if expected_background is not None:
+ first_case = cases[0] if isinstance(cases, list) and cases else None
+ actual_background = (
+ first_case.get("background_repository")
+ if isinstance(first_case, dict)
+ else None
+ )
+ if not isinstance(actual_background, dict):
+ raise ValueError(
+ "benchmark result is missing background_repository identity"
+ )
+ for key in ("revision", "tree"):
+ if actual_background.get(key) != expected_background.get(key):
+ raise ValueError(
+ f"background repository {key} mismatch: "
+ f"expected={expected_background.get(key)} actual={actual_background.get(key)}"
+ )
+ expected_repository = cell.get("parameters", {}).get("repository_background")
+ if expected_repository is not None:
+ actual_repository = result.get("repository_background")
+ if not isinstance(actual_repository, dict):
+ raise ValueError(
+ "benchmark result is missing repository_background identity"
+ )
+ for key in ("revision", "tree"):
+ if actual_repository.get(key) != expected_repository.get(key):
+ raise ValueError(
+ f"repository background {key} mismatch: "
+ f"expected={expected_repository.get(key)} "
+ f"actual={actual_repository.get(key)}"
+ )
+ return result
+
+
+def validate_attempt_artifacts(cell_root: Path, completion: dict[str, Any]) -> None:
+ """Re-hash a completed attempt's archived evidence before trusting its audit status."""
+ attempt_id = completion.get("attempt")
+ if attempt_id is None:
+ # Historical hand-authored plans may predate per-attempt evidence. Their
+ # result hash remains validated, but there is no artifact claim to check.
+ return
+ if (
+ not isinstance(attempt_id, str)
+ or not attempt_id
+ or Path(attempt_id).name != attempt_id
+ or attempt_id in {".", ".."}
+ ):
+ raise ValueError("completion attempt identifier is invalid")
+ attempt_root = cell_root / "attempts" / attempt_id
+ attempt = read_json_object(attempt_root / "attempt.json")
+ if attempt.get("cell_identity") != completion.get("cell_identity"):
+ raise ValueError("attempt cell identity does not match the completion")
+ if attempt.get("status") != "completed":
+ raise ValueError("completed cell references a non-completed attempt")
+ expected = attempt.get("artifacts")
+ if not isinstance(expected, dict):
+ raise ValueError("completed attempt artifact manifest is missing")
+ actual = artifact_manifest(attempt_root / "artifacts")
+ if actual != expected:
+ raise ValueError(
+ "completed attempt artifact manifest does not match retained files"
+ )
+
+
+def valid_completion(cell_root: Path, cell: dict[str, Any]) -> dict[str, Any] | None:
+ completion_path = cell_root / "complete.json"
+ if not completion_path.is_file():
+ return None
+ completion = read_json_object(completion_path)
+ if completion.get("cell_identity") != cell_identity(cell):
+ raise ValueError("completion cell identity does not match the plan")
+ result_path = resolve_result_path(cell_root, completion)
+ validate_result(result_path, cell)
+ if file_sha256(result_path) != completion.get("result_sha256"):
+ raise ValueError("completion result SHA-256 does not match the retained result")
+ validate_attempt_artifacts(cell_root, completion)
+ return completion
+
+
+def expanded_command(
+ command: list[str], attempt_root: Path, result_path: Path
+) -> list[str]:
+ replacements = {
+ "{attempt_dir}": str(attempt_root),
+ "{result_path}": str(result_path),
+ }
+ expanded = [replacements.get(item, item) for item in command]
+ if expanded and is_legacy_benchmark_script_path(expanded[0]):
+ expanded[0] = str(resolve_benchmark_script_path(expanded[0]))
+ return expanded
+
+
+def validate_benchmark_script_digest(
+ command: list[str], parameters: dict[str, Any]
+) -> None:
+ """Reject a retained cell when its resolved harness bytes changed."""
+ expected = parameters.get("benchmark_script_sha256")
+ if expected is None:
+ return
+ if not isinstance(expected, str) or len(expected) != 64:
+ raise ValueError("benchmark_script_sha256 must be a SHA-256 string")
+ if not command:
+ raise ValueError("benchmark command must not be empty")
+ script = Path(command[0]).expanduser().resolve()
+ if not script.is_file():
+ raise ValueError(f"benchmark script does not exist: {script}")
+ actual = file_sha256(script)
+ if actual != expected:
+ raise ValueError(
+ "benchmark script SHA-256 mismatch after path resolution: "
+ f"expected {expected}, got {actual}; generate a new experiment plan"
+ )
+
+
+def cell_process_group_options() -> dict[str, Any]:
+ if os.name == "nt":
+ return {"creationflags": subprocess.CREATE_NEW_PROCESS_GROUP}
+ return {"start_new_session": True}
+
+
+def stop_cell_process_tree(
+ process: subprocess.Popen[bytes], initial_signal: int, grace_seconds: float = 30.0
+) -> int | None:
+ """Stop an isolated benchmark process group, allowing harness cleanup first."""
+ if process.poll() is not None:
+ return process.returncode
+ with suppress(OSError, ProcessLookupError):
+ if os.name == "nt":
+ process.send_signal(signal.CTRL_BREAK_EVENT)
+ else:
+ os.killpg(process.pid, initial_signal)
+ try:
+ return process.wait(timeout=grace_seconds)
+ except subprocess.TimeoutExpired:
+ pass
+ if os.name == "nt":
+ subprocess.run(
+ ["taskkill", "/PID", str(process.pid), "/T", "/F"],
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ check=False,
+ )
+ else:
+ with suppress(OSError, ProcessLookupError):
+ os.killpg(process.pid, signal.SIGKILL)
+ try:
+ return process.wait(timeout=10)
+ except subprocess.TimeoutExpired:
+ return process.poll()
+
+
+def run_cell(
+ experiment_root: Path,
+ cell: dict[str, Any],
+ *,
+ minimum_free_bytes: int = DEFAULT_MINIMUM_FREE_BYTES,
+ stale_lock_seconds: int = DEFAULT_STALE_LOCK_SECONDS,
+) -> dict[str, Any]:
+ validate_cell(cell, 0)
+ ensure_disk_space(experiment_root, minimum_free_bytes)
+ identity = cell_identity(cell)
+ cell_root = experiment_root / "runs" / identity
+ try:
+ completion = valid_completion(cell_root, cell)
+ except (OSError, ValueError, json.JSONDecodeError) as exc:
+ return {
+ "cell_identity": identity,
+ "label": cell["label"],
+ "status": "corrupt",
+ "error": str(exc),
+ }
+ if completion is not None:
+ return {"cell_identity": identity, "label": cell["label"], "status": "resumed"}
+
+ lock_path, stale_record = acquire_lock(cell_root, stale_lock_seconds)
+ try:
+ attempt_id = filename_datetime() + f"-{uuid.uuid4().hex[:8]}"
+ attempt_root = cell_root / "attempts" / attempt_id
+ attempt_root.mkdir(parents=True)
+ artifact_root = attempt_root / "artifacts"
+ result_path = attempt_root / "result.json"
+ command = expanded_command(cell["command"], attempt_root, result_path)
+ validate_benchmark_script_digest(command, cell.get("parameters") or {})
+ cwd = Path(cell.get("cwd") or Path.cwd()).expanduser().resolve()
+ environment = dict(os.environ)
+ overrides = cell.get("environment", {})
+ if not isinstance(overrides, dict) or not all(
+ isinstance(key, str) and isinstance(value, str)
+ for key, value in overrides.items()
+ ):
+ raise ValueError("cell environment must be a string-to-string object")
+ environment.update(overrides)
+ environment["CBM_BENCHMARK_ARTIFACT_DIR"] = str(artifact_root)
+ benchmark_run_context = {
+ "cell_identity": identity,
+ "label": cell["label"],
+ "revision": cell["revision"],
+ "repetition": cell["repetition"],
+ "build": cell["build"],
+ "capabilities": cell["capabilities"],
+ "capability_support": cell.get("capability_support", {}),
+ "harness_version": cell["harness_version"],
+ }
+ environment["CBM_BENCHMARK_RUN_CONTEXT"] = canonical_json(
+ benchmark_run_context
+ ).decode("utf-8")
+ command_record = {
+ "cell_identity": identity,
+ "identity": identity_document(cell),
+ "label": cell["label"],
+ "command": command,
+ "cwd": str(cwd),
+ "environment_overrides": overrides,
+ "benchmark_run_context": benchmark_run_context,
+ "artifact_directory": "artifacts",
+ "started_at_utc": utc_now(),
+ "stale_lock_recovered": stale_record is not None,
+ "resource_before": resource_snapshot(experiment_root),
+ }
+ atomic_write_json(attempt_root / "command.json", command_record)
+ started = time.monotonic()
+ returncode: int | None = None
+ error: str | None = None
+ interrupted = False
+ except Exception:
+ if lock_path.exists():
+ lock_path.unlink()
+ raise
+ try:
+ with (
+ (attempt_root / "stdout.log").open("wb") as stdout,
+ (attempt_root / "stderr.log").open("wb") as stderr,
+ ):
+ try:
+ process = subprocess.Popen(
+ command,
+ cwd=cwd,
+ env=environment,
+ stdout=stdout,
+ stderr=stderr,
+ **cell_process_group_options(),
+ )
+ returncode = process.wait(timeout=cell.get("timeout_seconds"))
+ except subprocess.TimeoutExpired as exc:
+ error = f"command timed out after {exc.timeout} seconds"
+ returncode = stop_cell_process_tree(process, signal.SIGTERM)
+ except KeyboardInterrupt:
+ error = "command interrupted by SIGINT"
+ interrupted = True
+ returncode = stop_cell_process_tree(process, signal.SIGINT)
+ accepted_codes = cell.get("accepted_exit_codes", [0])
+ if error is None and returncode not in accepted_codes:
+ error = f"command exited with {returncode}; accepted={accepted_codes}"
+ result: dict[str, Any] | None = None
+ if error is None:
+ try:
+ result = validate_result(result_path, cell)
+ except (OSError, ValueError, json.JSONDecodeError) as exc:
+ error = str(exc)
+ attempt_record = {
+ **command_record,
+ "finished_at_utc": utc_now(),
+ "elapsed_seconds": round(time.monotonic() - started, 6),
+ "returncode": returncode,
+ "status": "completed" if error is None else "failed",
+ "error": error,
+ "resource_after": resource_snapshot(experiment_root),
+ "artifacts": artifact_manifest(artifact_root),
+ }
+ atomic_write_json(attempt_root / "attempt.json", attempt_record)
+ if interrupted:
+ raise KeyboardInterrupt
+ if error is not None:
+ return {
+ "cell_identity": identity,
+ "label": cell["label"],
+ "status": "failed",
+ "error": error,
+ "attempt": attempt_id,
+ }
+ assert result is not None
+ derived = result.get("derived")
+ benchmark_passed = derived.get("passed") if isinstance(derived, dict) else None
+ completion = {
+ "cell_identity": identity,
+ "label": cell["label"],
+ "completed_at_utc": utc_now(),
+ "attempt": attempt_id,
+ "result_path": str(result_path.relative_to(cell_root)),
+ "result_sha256": file_sha256(result_path),
+ "returncode": returncode,
+ "benchmark_passed": benchmark_passed,
+ }
+ atomic_write_json(cell_root / "complete.json", completion)
+ return {
+ "cell_identity": identity,
+ "label": cell["label"],
+ "status": "completed",
+ }
+ finally:
+ if lock_path.exists():
+ lock_path.unlink()
+
+
+def scan_experiment(
+ experiment_root: Path, cells: list[dict[str, Any]]
+) -> dict[str, Any]:
+ expected = {cell_identity(cell): cell for cell in cells}
+ entries: list[dict[str, Any]] = []
+ counts = {
+ "complete": 0,
+ "missing": 0,
+ "corrupt": 0,
+ "duplicate_attempts": 0,
+ "unplanned": 0,
+ }
+ for identity, cell in expected.items():
+ cell_root = experiment_root / "runs" / identity
+ attempts_root = cell_root / "attempts"
+ attempt_count = (
+ sum(1 for path in attempts_root.iterdir() if path.is_dir())
+ if attempts_root.is_dir()
+ else 0
+ )
+ if attempt_count > 1:
+ counts["duplicate_attempts"] += attempt_count - 1
+ status = "missing"
+ error = None
+ try:
+ if valid_completion(cell_root, cell) is not None:
+ status = "complete"
+ except (OSError, ValueError, json.JSONDecodeError) as exc:
+ status = "corrupt"
+ error = str(exc)
+ counts[status] += 1
+ entries.append(
+ {
+ "cell_identity": identity,
+ "label": cell["label"],
+ "status": status,
+ "attempts": attempt_count,
+ "error": error,
+ }
+ )
+ runs_root = experiment_root / "runs"
+ actual = (
+ {path.name for path in runs_root.iterdir() if path.is_dir()}
+ if runs_root.is_dir()
+ else set()
+ )
+ unplanned = sorted(actual - set(expected))
+ counts["unplanned"] = len(unplanned)
+ return {"counts": counts, "cells": entries, "unplanned": unplanned}
+
+
+def environment_snapshot(plan_path: Path) -> dict[str, Any]:
+ return {
+ "captured_at_utc": utc_now(),
+ "plan_path": str(plan_path.resolve()),
+ "plan_sha256": file_sha256(plan_path),
+ "hostname": socket.gethostname(),
+ "platform": platform.platform(),
+ "python": sys.version,
+ "cpu_count": os.cpu_count(),
+ "resources": resource_snapshot(plan_path.parent),
+ }
+
+
+def completed_report_inputs(
+ experiment_root: Path, cells: list[dict[str, Any]]
+) -> list[tuple[str, Path]]:
+ inputs: list[tuple[str, Path]] = []
+ for cell in cells:
+ cell_root = experiment_root / "runs" / cell_identity(cell)
+ completion = valid_completion(cell_root, cell)
+ if completion is not None:
+ result_path = resolve_result_path(cell_root, completion)
+ inputs.append(
+ (
+ cell["label"],
+ materialize_report_input(experiment_root, cell, result_path),
+ )
+ )
+ return inputs
+
+
+def completed_fact_inputs(
+ experiment_root: Path, cells: list[dict[str, Any]]
+) -> tuple[list[Path], list[str]]:
+ inputs: list[Path] = []
+ missing: list[str] = []
+ for cell in cells:
+ identity = cell_identity(cell)
+ cell_root = experiment_root / "runs" / identity
+ completion = valid_completion(cell_root, cell)
+ if completion is None:
+ continue
+ attempt = completion.get("attempt")
+ if not isinstance(attempt, str) or not attempt:
+ missing.append(identity)
+ continue
+ path = cell_root / "attempts" / attempt / "artifacts" / "facts" / "facts.json"
+ if path.is_file():
+ inputs.append(path)
+ else:
+ missing.append(identity)
+ return inputs, missing
+
+
+def generate_fact_comparisons(
+ experiment_root: Path,
+ cells: list[dict[str, Any]],
+ report_output: Path,
+) -> dict[str, Any]:
+ inputs, missing = completed_fact_inputs(experiment_root, cells)
+ if missing or len(inputs) != len(cells):
+ return {
+ "status": "unavailable",
+ "reason": "one or more retained completed cells predate canonical fact bundles",
+ "fact_input_count": len(inputs),
+ "missing_cell_identities": sorted(missing),
+ }
+ comparison_output = report_output.with_suffix(".comparisons.json")
+ appendix_output = report_output.with_suffix(".fact-appendix.md")
+ generator = Path(__file__).resolve().with_name("fact_comparisons.py")
+ command = [sys.executable, str(generator)]
+ for path in inputs:
+ command.extend(("--fact", str(path)))
+ command.extend(
+ (
+ "--out",
+ str(comparison_output),
+ "--markdown-out",
+ str(appendix_output),
+ )
+ )
+ process = subprocess.run(command, capture_output=True, text=True, check=False)
+ if process.returncode != 0:
+ raise RuntimeError(
+ f"fact comparison generator exited with {process.returncode}: "
+ f"{process.stderr.strip()}"
+ )
+ appendix = appendix_output.read_text(encoding="utf-8")
+ report = report_output.read_text(encoding="utf-8").rstrip()
+ atomic_write_bytes(
+ report_output, (report + "\n\n" + appendix.rstrip() + "\n").encode("utf-8")
+ )
+ return {
+ "status": "generated",
+ "path": str(comparison_output),
+ "sha256": file_sha256(comparison_output),
+ "appendix_path": str(appendix_output),
+ "appendix_sha256": file_sha256(appendix_output),
+ "fact_input_count": len(inputs),
+ "generator": str(generator),
+ }
+
+
+def materialize_report_input(
+ experiment_root: Path, cell: dict[str, Any], result_path: Path
+) -> Path:
+ """Create a deterministic derived input with candidate metadata beside immutable raw results."""
+ document = read_json_object(result_path)
+ parameters = document.get("parameters")
+ if not isinstance(parameters, dict):
+ parameters = {}
+ document["parameters"] = parameters
+ support = cell.get("capability_support")
+ if isinstance(support, dict):
+ parameters["capability_support"] = dict(sorted(support.items()))
+ cell_parameters = cell.get("parameters")
+ if isinstance(cell_parameters, dict):
+ for key in (
+ "execution_order",
+ "execution_block",
+ "execution_position",
+ "cell_name",
+ "informs_hypotheses",
+ "questions",
+ "expected_observable",
+ "parameter_sources",
+ "evidence_scope",
+ ):
+ if key in cell_parameters:
+ parameters[key] = cell_parameters[key]
+ source_sha = file_sha256(result_path)
+ identity = cell_identity(cell)
+ provenance = {
+ "cell_identity": identity,
+ "source_result": str(result_path),
+ "source_result_sha256": source_sha,
+ }
+ attempt_path = result_path.with_name("attempt.json")
+ if attempt_path.is_file():
+ attempt = read_json_object(attempt_path)
+ attempt_identity = attempt.get("cell_identity")
+ if attempt_identity is not None and attempt_identity != identity:
+ raise RuntimeError(
+ f"attempt identity {attempt_identity!r} does not match cell {identity!r}"
+ )
+ provenance["attempt"] = {
+ "source_path": str(attempt_path),
+ "source_sha256": file_sha256(attempt_path),
+ **{
+ key: attempt[key]
+ for key in (
+ "elapsed_seconds",
+ "started_at_utc",
+ "finished_at_utc",
+ "returncode",
+ )
+ if key in attempt
+ },
+ }
+ document["experiment_provenance"] = provenance
+ output = (
+ experiment_root / "reports" / "inputs" / f"{identity}-{source_sha[:12]}.json"
+ )
+ atomic_write_json(output, document)
+ return output
+
+
+def generate_report(
+ experiment_root: Path, cells: list[dict[str, Any]], output: Path
+) -> dict[str, Any]:
+ inputs = completed_report_inputs(experiment_root, cells)
+ if not inputs:
+ raise RuntimeError(
+ "cannot generate a report without completed experiment cells"
+ )
+ summarizer = Path(__file__).resolve().with_name("summarize_results.py")
+ command = [sys.executable, str(summarizer)]
+ for label, result_path in inputs:
+ command.extend(("--input", f"{label}={result_path}"))
+ command.extend(("--out", str(output)))
+ process = subprocess.run(command, capture_output=True, text=True, check=False)
+ if process.returncode != 0:
+ raise RuntimeError(
+ f"report generator exited with {process.returncode}: {process.stderr.strip()}"
+ )
+ fact_comparisons = generate_fact_comparisons(experiment_root, cells, output)
+ return {
+ "path": str(output),
+ "sha256": file_sha256(output),
+ "input_count": len(inputs),
+ "generator": str(summarizer),
+ "fact_comparisons": fact_comparisons,
+ }
+
+
+def write_manifest(
+ experiment_root: Path,
+ plan_path: Path,
+ cells: list[dict[str, Any]],
+ report: dict[str, Any] | None = None,
+ *,
+ runset: str | None = None,
+) -> Path:
+ manifest = {
+ "schema_version": SCHEMA_VERSION,
+ "generated_at_utc": utc_now(),
+ "plan_sha256": file_sha256(plan_path),
+ "audit": scan_experiment(experiment_root, cells),
+ "generated_report": report,
+ }
+ effective_runset = runset or file_sha256(plan_path)[:12]
+ name = generated_artifact_name(
+ "manifest",
+ effective_runset,
+ ".json",
+ nonce=uuid.uuid4().hex[:8],
+ )
+ path = experiment_root / "manifests" / name
+ atomic_write_json(path, manifest)
+ return path
+
+
+def build_parser() -> argparse.ArgumentParser:
+ parser = argparse.ArgumentParser(description=__doc__)
+ source = parser.add_mutually_exclusive_group()
+ source.add_argument(
+ "--plan", type=Path, help="Fully expanded immutable experiment plan."
+ )
+ source.add_argument(
+ "--matrix-spec",
+ type=Path,
+ help="Compact deterministic grid expanded and archived before execution.",
+ )
+ source.add_argument(
+ "--quick",
+ dest="preset",
+ action="store_const",
+ const="quick",
+ help="Automatically prepare and run the safe one-repetition smoke (default).",
+ )
+ source.add_argument(
+ "--full",
+ dest="preset",
+ action="store_const",
+ const="full",
+ help="Automatically prepare and run the repeated capability matrix.",
+ )
+ parser.add_argument(
+ "--experiment-root",
+ "--campaign-root",
+ dest="experiment_root",
+ type=Path,
+ help=(
+ "Durable result root (--campaign-root is a legacy alias). "
+ "Automatic modes default to a versioned, commit-qualified, "
+ "content-addressed runset directory under "
+ ".worktrees/benchmark-campaign (legacy path retained for existing runsets)."
+ ),
+ )
+ parser.add_argument(
+ "--candidate-root",
+ type=Path,
+ help=(
+ "Candidate worktree/build root for automatic presets and ref-based matrix "
+ "specs (default: .worktrees/benchmark-candidates)."
+ ),
+ )
+ parser.add_argument(
+ "--candidate-search-root",
+ dest="candidate_search_roots",
+ action="append",
+ type=Path,
+ default=[],
+ help=(
+ "Additional existing root containing registered candidate worktrees. "
+ "Repeat in preferred search order; new worktrees and metadata remain "
+ "under --candidate-root."
+ ),
+ )
+ parser.add_argument(
+ "--build-jobs",
+ type=int,
+ help=(
+ "Candidate build parallelism. Native execution defaults to 2; container "
+ "execution defaults to its declared --cpus budget."
+ ),
+ )
+ parser.add_argument(
+ "--allow-temporary-experiment-root",
+ "--allow-temporary-campaign-root",
+ dest="allow_temporary_experiment_root",
+ action="store_true",
+ help="Allow disposable experiment state under the OS temporary directory.",
+ )
+ parser.add_argument(
+ "--candidate-ref",
+ dest="candidate_ref_overrides",
+ action="append",
+ default=[],
+ metavar="LABEL=REF",
+ help=(
+ "Override one automatic candidate's git ref by label (repeatable), e.g. "
+ "--candidate-ref upstream-main=origin/main. Valid labels: "
+ + ", ".join(label for label, _ in DEFAULT_CANDIDATE_REFS)
+ + ". Only applies to --quick/--full; explicit --plan/--matrix-spec already "
+ "accept any resolvable ref directly in the spec. An override is an explicit "
+ "request and stays fail-closed: an unresolvable override ref raises rather "
+ "than falling back."
+ ),
+ )
+ parser.add_argument(
+ "--transport",
+ choices=("cli", "mcp"),
+ default="mcp",
+ help=(
+ "Transport for automatic --quick/--full cells (default: mcp). "
+ "Cross-build cli cells require an isolated OS account/runtime or a quiescent "
+ "account-wide CBM daemon; mcp requires one compatible build."
+ ),
+ )
+ parser.add_argument(
+ "--product-env",
+ action="append",
+ default=[],
+ metavar="CBM_KEY=VALUE",
+ help=(
+ "Explicit candidate environment for automatic --quick/--full runs. "
+ "Repeat for controlled resource sweeps; harness-owned isolation keys "
+ "are rejected."
+ ),
+ )
+ parser.add_argument("--minimum-free-gb", type=float, default=2.0)
+ parser.add_argument("--stale-lock-hours", type=float, default=6.0)
+ parser.add_argument("--audit-only", action="store_true")
+ parser.add_argument(
+ "--report-out",
+ type=Path,
+ help="Generated Markdown path (default: versioned runset report under EXPERIMENT_ROOT/reports).",
+ )
+ container = parser.add_argument_group(
+ "container execution",
+ "Use the same experiment interface with --container; the existing Docker "
+ "coordinator remains an internal isolation adapter.",
+ )
+ container.add_argument("--container", action="store_true")
+ container.add_argument("--cpus", type=float)
+ container.add_argument("--memory")
+ container.add_argument("--workers", type=int)
+ container.add_argument("--image", dest="container_image")
+ container.add_argument("--docker", default="docker")
+ container.add_argument(
+ "--work-volume-retention",
+ choices=WORK_VOLUME_RETENTION_CHOICES,
+ default=DEFAULT_WORK_VOLUME_RETENTION,
+ help=(
+ "failed-runs removes owned work scratch after a successful verified export "
+ "but retains it after failure (default); always retains it after success too"
+ ),
+ )
+ container.add_argument("--corpus", action="append", default=[])
+ container.add_argument("--corpus-repo", action="append", default=[])
+ container.add_argument("--corpus-manifest", default="")
+ container.add_argument("--clone-missing-real-repos", action="store_true")
+ container.add_argument("--corpus-timeout", type=int, default=1800)
+ return parser
+
+
+def parse_arguments(argv: list[str] | None = None) -> argparse.Namespace:
+ parser = build_parser()
+ args = parser.parse_args(argv)
+ if args.plan is None and args.matrix_spec is None and args.preset is None:
+ args.preset = "quick"
+ if args.preset is None and args.experiment_root is None:
+ parser.error(
+ "--experiment-root (legacy alias: --campaign-root) is required with --plan or --matrix-spec"
+ )
+ if args.build_jobs is not None and args.build_jobs <= 0:
+ parser.error("--build-jobs must be positive")
+ candidate_ref_overrides: dict[str, str] = {}
+ for value in args.candidate_ref_overrides:
+ try:
+ label, ref = parse_candidate_ref_override(value)
+ except ValueError as error:
+ parser.error(str(error))
+ candidate_ref_overrides[label] = ref
+ if candidate_ref_overrides and args.preset is None:
+ parser.error("--candidate-ref only applies to --quick/--full")
+ if args.transport != "mcp" and args.preset is None:
+ parser.error("--transport only applies to --quick/--full")
+ if args.product_env and args.preset is None:
+ parser.error("--product-env only applies to --quick/--full")
+ try:
+ args.product_environment = parse_product_environment_arguments(args.product_env)
+ except ValueError as error:
+ parser.error(str(error))
+ args.candidate_ref = candidate_ref_overrides
+ container_resource_values = (args.cpus, args.memory, args.workers)
+ container_specific = bool(
+ any(value is not None for value in container_resource_values)
+ or args.container_image
+ or args.corpus
+ or args.corpus_repo
+ or args.corpus_manifest
+ or args.clone_missing_real_repos
+ or args.corpus_timeout != 1800
+ or args.work_volume_retention != DEFAULT_WORK_VOLUME_RETENTION
+ )
+ if args.container:
+ if args.plan is not None:
+ parser.error(
+ "--container accepts --quick, --full, or a ref-based --matrix-spec; "
+ "expanded plans contain host binary paths and cannot be remapped safely"
+ )
+ if args.experiment_root is None:
+ parser.error("--experiment-root is required with --container")
+ missing = [
+ flag
+ for flag, value in zip(
+ ("--cpus", "--memory", "--workers"),
+ container_resource_values,
+ strict=True,
+ )
+ if value is None
+ ]
+ if missing:
+ parser.error(
+ "--container requires an explicit resource budget: "
+ + ", ".join(missing)
+ )
+ if args.candidate_root or args.candidate_search_roots:
+ parser.error(
+ "--candidate-root and --candidate-search-root are native paths; "
+ "container candidates use the retained named work volume"
+ )
+ if args.report_out:
+ parser.error(
+ "--report-out cannot name a host path under --container; the canonical "
+ "report is exported under EXPERIMENT_ROOT/runsets//reports"
+ )
+ elif container_specific:
+ parser.error(
+ "container resource, image, and corpus options require --container"
+ )
+ if args.build_jobs is None and not args.container:
+ args.build_jobs = 2
+ return args
+
+
+def build_container_delegate_command(args: argparse.Namespace) -> list[str]:
+ """Translate the canonical CLI into the internal Docker coordinator interface."""
+ if not args.container:
+ raise ValueError("container delegation requires --container")
+ if args.matrix_spec is not None:
+ source = ["--matrix-spec", str(args.matrix_spec.expanduser().resolve())]
+ elif args.preset is not None:
+ source = [f"--{args.preset}"]
+ else: # parse_arguments rejects plans and supplies the quick default.
+ raise ValueError("container delegation requires a matrix or automatic preset")
+ assert args.experiment_root is not None
+ experiment_root = validate_experiment_root(
+ args.experiment_root,
+ allow_temporary=args.allow_temporary_experiment_root,
+ )
+ command = [
+ sys.executable,
+ str(CONTAINER_COORDINATOR),
+ *source,
+ "--experiment-root",
+ str(experiment_root),
+ "--cpus",
+ f"{args.cpus:g}",
+ "--memory",
+ args.memory,
+ "--workers",
+ str(args.workers),
+ "--docker",
+ args.docker,
+ "--corpus-timeout",
+ str(args.corpus_timeout),
+ "--invocation-surface",
+ "run_experiments.py --container",
+ "--work-volume-retention",
+ args.work_volume_retention,
+ ]
+ if args.build_jobs is not None:
+ command.extend(("--build-jobs", str(args.build_jobs)))
+ if args.container_image:
+ command.extend(("--image", args.container_image))
+ for corpus_id in args.corpus:
+ command.extend(("--corpus", corpus_id))
+ for corpus_repo in args.corpus_repo:
+ command.extend(("--corpus-repo", corpus_repo))
+ if args.corpus_manifest:
+ command.extend(("--corpus-manifest", args.corpus_manifest))
+ if args.clone_missing_real_repos:
+ command.append("--clone-missing-real-repos")
+ for key, value in sorted(args.product_environment.items()):
+ command.extend(("--product-env", f"{key}={value}"))
+
+ forwarded: list[str] = []
+ if args.preset is not None:
+ forwarded.extend(("--transport", args.transport))
+ for label, ref in sorted(args.candidate_ref.items()):
+ forwarded.extend(("--candidate-ref", f"{label}={ref}"))
+ forwarded.extend(("--minimum-free-gb", f"{args.minimum_free_gb:g}"))
+ forwarded.extend(("--stale-lock-hours", f"{args.stale_lock_hours:g}"))
+ if args.audit_only:
+ forwarded.append("--audit-only")
+ command.extend(("--", *forwarded))
+ return command
+
+
+def _commit_datetime_slug(repository: Path, revision: str) -> str:
+ return commit_identity(repository, revision)["commit_datetime_slug"]
+
+
+def prepare_automatic_experiment(
+ args: argparse.Namespace,
+) -> tuple[Path, Path]:
+ repository = Path(__file__).resolve().parents[1]
+ ensure_clean_tracked_worktree(repository, "benchmark source worktree")
+ candidate_root = (
+ args.candidate_root.expanduser().resolve()
+ if args.candidate_root
+ else repository / ".worktrees" / "benchmark-candidates"
+ )
+ ensure_disk_space(candidate_root, max(0, int(args.minimum_free_gb * 1024**3)))
+ candidate_ref_overrides: dict[str, str] = getattr(args, "candidate_ref", {}) or {}
+ effective_candidate_refs = [
+ (label, candidate_ref_overrides[label])
+ if label in candidate_ref_overrides
+ else (label, resolve_default_candidate_ref(repository, label, ref))
+ for label, ref in DEFAULT_CANDIDATE_REFS
+ ]
+ candidates = [
+ materialize_candidate(
+ repository,
+ candidate_root,
+ label,
+ ref,
+ jobs=args.build_jobs,
+ candidate_search_roots=args.candidate_search_roots,
+ )
+ for label, ref in effective_candidate_refs
+ ]
+ benchmark_script = CANONICAL_BENCHMARK_SCRIPT
+ spec = build_automatic_spec(
+ repository,
+ benchmark_script,
+ candidates,
+ preset=args.preset,
+ transport=args.transport,
+ product_environment=args.product_environment,
+ )
+ revision = spec["repository_background"]["revision"]
+ tree = spec["repository_background"]["tree"]
+ commit_datetime = _commit_datetime_slug(repository, revision)
+ runset = automatic_runset_identity(spec)
+ spec["runset_id"] = runset
+ spec_payload = (json.dumps(spec, indent=2, sort_keys=True) + "\n").encode("utf-8")
+ source_identity = {
+ "revision": revision,
+ "commit_datetime_slug": commit_datetime,
+ "tree": tree,
+ }
+ experiment_root = (
+ args.experiment_root.expanduser().resolve()
+ if args.experiment_root
+ else repository
+ / ".worktrees"
+ / "benchmark-campaign"
+ / automatic_experiment_name(args.preset, source_identity, runset)
+ )
+ experiment_root = validate_experiment_root(
+ experiment_root,
+ allow_temporary=args.allow_temporary_experiment_root,
+ )
+ spec_path = experiment_root / "inputs" / automatic_spec_name(args.preset, runset)
+ if spec_path.exists():
+ if spec_path.read_bytes() != spec_payload:
+ raise RuntimeError(
+ f"automatic spec path contains different bytes: {spec_path}"
+ )
+ else:
+ atomic_write_bytes(spec_path, spec_payload)
+ return experiment_root, spec_path
+
+
+def main(argv: list[str] | None = None) -> int:
+ args = parse_arguments(argv)
+
+ if args.container:
+ process = subprocess.run(
+ build_container_delegate_command(args),
+ cwd=Path(__file__).resolve().parents[1],
+ check=False,
+ )
+ return process.returncode
+
+ if args.preset is not None:
+ experiment_root, matrix_spec = prepare_automatic_experiment(args)
+ args.matrix_spec = matrix_spec
+ else:
+ assert args.experiment_root is not None
+ experiment_root = validate_experiment_root(
+ args.experiment_root,
+ allow_temporary=args.allow_temporary_experiment_root,
+ )
+
+ minimum_free_bytes = max(0, int(args.minimum_free_gb * 1024**3))
+ stale_lock_seconds = max(1, int(args.stale_lock_hours * 3600))
+ ensure_disk_space(experiment_root, minimum_free_bytes)
+ if args.matrix_spec:
+ spec_path = args.matrix_spec.expanduser().resolve()
+ spec = read_json_object(spec_path)
+ if matrix_spec_has_candidate_refs(spec):
+ repository = Path(__file__).resolve().parents[1]
+ ensure_clean_tracked_worktree(
+ repository, "ref-based benchmark source worktree"
+ )
+ candidate_root = (
+ args.candidate_root.expanduser().resolve()
+ if args.candidate_root
+ else repository / ".worktrees" / "benchmark-candidates"
+ )
+ ensure_disk_space(candidate_root, minimum_free_bytes)
+ source_spec_sha256 = file_sha256(spec_path)
+ source_archive = (
+ experiment_root / "specs" / f"source-{source_spec_sha256}.json"
+ )
+ if not source_archive.exists():
+ atomic_write_bytes(source_archive, spec_path.read_bytes())
+ spec = materialize_matrix_candidates(
+ repository,
+ candidate_root,
+ spec,
+ jobs=args.build_jobs,
+ candidate_search_roots=args.candidate_search_roots,
+ )
+ runset = automatic_runset_identity(spec)
+ declared_runset = spec.get("runset_id")
+ if declared_runset is not None and declared_runset != runset:
+ raise ValueError(
+ "ref-based matrix spec runset_id does not match its resolved "
+ f"candidates: declared={declared_runset} resolved={runset}"
+ )
+ spec["runset_id"] = runset
+ spec["source_matrix_spec_sha256"] = source_spec_sha256
+ resolved_payload = (
+ json.dumps(spec, indent=2, sort_keys=True) + "\n"
+ ).encode("utf-8")
+ spec_path = (
+ experiment_root
+ / "inputs"
+ / f"spec-{experiment_version()}-custom-runset-{runset}.json"
+ )
+ if spec_path.exists():
+ if spec_path.read_bytes() != resolved_payload:
+ raise RuntimeError(
+ f"resolved matrix spec path contains different bytes: {spec_path}"
+ )
+ else:
+ atomic_write_bytes(spec_path, resolved_payload)
+ plan = expand_matrix_spec(spec)
+ plan["matrix_spec_sha256"] = file_sha256(spec_path)
+ archived_spec = experiment_root / "specs" / f"{file_sha256(spec_path)}.json"
+ if not archived_spec.exists():
+ atomic_write_bytes(archived_spec, spec_path.read_bytes())
+ plan_payload = (json.dumps(plan, indent=2, sort_keys=True) + "\n").encode(
+ "utf-8"
+ )
+ plan_digest = hashlib.sha256(plan_payload).hexdigest()
+ plan_path = experiment_root / "plans" / f"{plan_digest}.json"
+ if not plan_path.exists():
+ atomic_write_bytes(plan_path, plan_payload)
+ else:
+ plan_path = args.plan.expanduser().resolve()
+ plan = read_json_object(plan_path)
+ archived_plan = experiment_root / "plans" / f"{file_sha256(plan_path)}.json"
+ if not archived_plan.exists():
+ atomic_write_bytes(archived_plan, plan_path.read_bytes())
+ plan_path = archived_plan
+ cells = validate_plan(plan)
+ runset = plan.get("runset_id", file_sha256(plan_path)[:12])
+ runset = _validate_runset_identity(runset)
+ snapshot_name = generated_artifact_name("environment", runset, ".json")
+ atomic_write_json(
+ experiment_root / "environments" / snapshot_name,
+ environment_snapshot(plan_path),
+ )
+
+ failures = 0
+ if not args.audit_only:
+ for cell in cells:
+ outcome = run_cell(
+ experiment_root,
+ cell,
+ minimum_free_bytes=minimum_free_bytes,
+ stale_lock_seconds=stale_lock_seconds,
+ )
+ print(json.dumps(outcome, sort_keys=True), flush=True)
+ failures += int(outcome["status"] in {"failed", "corrupt"})
+ audit = scan_experiment(experiment_root, cells)
+ report_metadata = None
+ if audit["counts"]["complete"]:
+ report_path = (
+ args.report_out.expanduser().resolve()
+ if args.report_out
+ else experiment_root
+ / "reports"
+ / generated_artifact_name(
+ "report",
+ runset,
+ ".md",
+ preset=args.preset or "custom",
+ )
+ )
+ report_metadata = generate_report(experiment_root, cells, report_path)
+ manifest_path = write_manifest(
+ experiment_root,
+ plan_path,
+ cells,
+ report_metadata,
+ runset=runset,
+ )
+ print(
+ json.dumps(
+ {"manifest": str(manifest_path), "audit": audit}, indent=2, sort_keys=True
+ )
+ )
+ return (
+ 1 if failures or audit["counts"]["missing"] or audit["counts"]["corrupt"] else 0
+ )
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/benchmarks/run_native_extraction_comparison.py b/benchmarks/run_native_extraction_comparison.py
new file mode 100644
index 000000000..2171b8187
--- /dev/null
+++ b/benchmarks/run_native_extraction_comparison.py
@@ -0,0 +1,351 @@
+#!/usr/bin/env python3
+"""Compare production-native extraction runners with interleaved samples."""
+
+from __future__ import annotations
+
+import argparse
+import json
+import os
+import platform
+import re
+import shlex
+import statistics
+import subprocess
+import sys
+from datetime import datetime, timezone
+from pathlib import Path
+from typing import Any
+
+
+STARTUP_SUITE = "startup_baseline"
+SUITES = (STARTUP_SUITE, "shared_parse_baseline", "cs_lsp_bench", "py_lsp_bench", "py_lsp_scale")
+OUTPUT_METRICS = (
+ "lines",
+ "definitions",
+ "calls",
+ "resolved",
+ "usages",
+ "type_refs",
+ "read_write",
+)
+PERFORMANCE_METRICS = (
+ "latency_ms",
+ "small_ms",
+ "medium_ms",
+ "parse_ms",
+ "non_lsp_ms",
+ "lsp_ms",
+ "total_extract_ms",
+ "max_rss_bytes",
+ "peak_footprint_bytes",
+ "incremental_max_rss_bytes",
+ "incremental_peak_footprint_bytes",
+ "incremental_instructions",
+ "incremental_cycles",
+ "instructions",
+ "cycles",
+)
+FIXED_RESULT_RE = re.compile(
+ r"(?:cs )?bench: (?P\d+) lines, (?P\d+) defs, "
+ r"(?P\d+) calls, (?P\d+) resolved \(\d+%\), "
+ r"(?:\d+ high-conf \(\d+%\), )?"
+ r"(?P\d+) usages, (?P\d+) type_refs, "
+ r"(?P\d+) rw, (?P[0-9.]+) ms"
+)
+LEGACY_FIXED_RESULT_RE = re.compile(
+ r"(?:cs )?bench: (?P\d+) lines, "
+ r"(?P\d+) calls, (?P\d+) resolved \(\d+%\), "
+ r"(?:\d+ high-conf \(\d+%\), )?"
+ r"(?P[0-9.]+) ms"
+)
+SCALE_RESULT_RE = re.compile(
+ r"scale: 100=(?P[0-9.]+)ms .*?"
+ r"500=(?P[0-9.]+)ms .*?"
+ r"2000=(?P[0-9.]+)ms "
+ r"\(calls=(?P\d+) resolved=(?P\d+)\)",
+ re.DOTALL,
+)
+PROFILE_RE = re.compile(
+ r"profile: files=(?P\d+) parse=(?P[0-9.]+)ms "
+ r"non_lsp=(?P[0-9.]+)ms lsp=(?P[0-9.]+)ms "
+ r"total_extract=(?P[0-9.]+)ms"
+)
+DARWIN_RESOURCE_PATTERNS = {
+ "max_rss_bytes": r"(?m)^\s*(\d+)\s+maximum resident set size$",
+ "instructions": r"(?m)^\s*(\d+)\s+instructions retired$",
+ "cycles": r"(?m)^\s*(\d+)\s+cycles elapsed$",
+ "peak_footprint_bytes": r"(?m)^\s*(\d+)\s+peak memory footprint$",
+}
+LINUX_MAX_RSS_RE = re.compile(r"Maximum resident set size \(kbytes\):\s*(\d+)")
+
+
+def parse_candidate(value: str) -> tuple[str, Path]:
+ name, separator, raw_path = value.partition("=")
+ if not separator or not name or not raw_path:
+ raise argparse.ArgumentTypeError("candidate must be NAME=/absolute/path/to/runner")
+ path = Path(raw_path).expanduser().resolve()
+ if not path.is_file():
+ raise argparse.ArgumentTypeError(f"candidate runner does not exist: {path}")
+ return name, path
+
+
+def _numeric_groups(match: re.Match[str]) -> dict[str, int | float]:
+ parsed: dict[str, int | float] = {}
+ for key, value in match.groupdict().items():
+ parsed[key] = float(value) if key.endswith("_ms") else int(value)
+ return parsed
+
+
+def _parse_resource_metrics(output: str) -> dict[str, int]:
+ metrics: dict[str, int] = {}
+ for key, pattern in DARWIN_RESOURCE_PATTERNS.items():
+ match = re.search(pattern, output)
+ if match is not None:
+ metrics[key] = int(match.group(1))
+ linux_rss = LINUX_MAX_RSS_RE.search(output)
+ if linux_rss is not None and "max_rss_bytes" not in metrics:
+ metrics["max_rss_bytes"] = int(linux_rss.group(1)) * 1024
+ return metrics
+
+
+def parse_sample(suite: str, output: str) -> dict[str, int | float]:
+ resource_metrics = _parse_resource_metrics(output)
+ if suite == STARTUP_SUITE:
+ if not resource_metrics:
+ raise ValueError("could not parse startup resource metrics")
+ return resource_metrics
+
+ result_match = (SCALE_RESULT_RE if suite == "py_lsp_scale" else FIXED_RESULT_RE).search(output)
+ if result_match is None and suite != "py_lsp_scale":
+ result_match = LEGACY_FIXED_RESULT_RE.search(output)
+ profile_match = PROFILE_RE.search(output)
+ if result_match is None or profile_match is None:
+ raise ValueError(f"could not parse {suite} benchmark output")
+
+ metrics = _numeric_groups(result_match)
+ metrics.update(_numeric_groups(profile_match))
+ metrics.update(resource_metrics)
+ return metrics
+
+
+def timed_command(runner: Path, suite: str) -> list[str]:
+ selector = "__cbm_startup_baseline__" if suite == STARTUP_SUITE else suite
+ system = platform.system()
+ if Path("/usr/bin/time").is_file() and system == "Darwin":
+ return ["/usr/bin/time", "-lp", str(runner), selector]
+ if Path("/usr/bin/time").is_file() and system == "Linux":
+ return ["/usr/bin/time", "-v", str(runner), selector]
+ return [str(runner), selector]
+
+
+def run_sample(runner: Path, suite: str, timeout_seconds: float) -> tuple[dict[str, int | float], str]:
+ command = timed_command(runner, suite)
+ environment = os.environ.copy()
+ environment["CBM_PROFILE"] = "1"
+ completed = subprocess.run(
+ command,
+ check=False,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ text=True,
+ timeout=timeout_seconds,
+ env=environment,
+ )
+ output = completed.stdout
+ expected_returncodes = {0, 2} if suite == STARTUP_SUITE else {0}
+ if completed.returncode not in expected_returncodes:
+ raise RuntimeError(
+ f"benchmark failed with exit {completed.returncode}: "
+ f"{shlex.join(command)}\n{output}"
+ )
+ return parse_sample(suite, output), output
+
+
+def add_incremental_resource_metrics(samples: list[dict[str, Any]]) -> None:
+ """Subtract each process's matching no-work startup resource counters."""
+ startup_by_run = {
+ (sample["candidate"], sample["repetition"]): sample["metrics"]
+ for sample in samples
+ if sample["suite"] == STARTUP_SUITE
+ }
+ for sample in samples:
+ if sample["suite"] == STARTUP_SUITE:
+ continue
+ startup = startup_by_run.get((sample["candidate"], sample["repetition"]))
+ if startup is None:
+ continue
+ for metric in (
+ "max_rss_bytes",
+ "peak_footprint_bytes",
+ "instructions",
+ "cycles",
+ ):
+ if metric in sample["metrics"] and metric in startup:
+ sample["metrics"][f"incremental_{metric}"] = max(
+ 0, sample["metrics"][metric] - startup[metric]
+ )
+
+
+def summarize(samples: list[dict[str, Any]]) -> dict[str, Any]:
+ summary: dict[str, Any] = {}
+ for candidate in sorted({sample["candidate"] for sample in samples}):
+ summary[candidate] = {}
+ for suite in SUITES:
+ selected = [
+ sample["metrics"]
+ for sample in samples
+ if sample["candidate"] == candidate and sample["suite"] == suite
+ ]
+ keys = sorted(set.intersection(*(set(metrics) for metrics in selected)))
+ summary[candidate][suite] = {
+ key: statistics.median(metrics[key] for metrics in selected) for key in keys
+ }
+ return summary
+
+
+def compare_candidates(samples: list[dict[str, Any]]) -> dict[str, Any]:
+ candidates = sorted({sample["candidate"] for sample in samples})
+ by_run = {
+ (sample["candidate"], sample["suite"], sample["repetition"]): sample["metrics"]
+ for sample in samples
+ }
+ comparisons: dict[str, Any] = {}
+ for candidate in candidates:
+ for baseline in candidates:
+ if candidate == baseline:
+ continue
+ comparison_key = f"{candidate}_vs_{baseline}"
+ comparisons[comparison_key] = {}
+ for suite in SUITES:
+ candidate_runs = sorted(
+ repetition
+ for name, sample_suite, repetition in by_run
+ if name == candidate and sample_suite == suite
+ )
+ paired = [
+ (
+ by_run[(candidate, suite, repetition)],
+ by_run[(baseline, suite, repetition)],
+ )
+ for repetition in candidate_runs
+ if (baseline, suite, repetition) in by_run
+ ]
+ output_differences: dict[str, Any] = {}
+ for metric in OUTPUT_METRICS:
+ values = {
+ (candidate_metrics.get(metric), baseline_metrics.get(metric))
+ for candidate_metrics, baseline_metrics in paired
+ }
+ if any(left != right for left, right in values):
+ output_differences[metric] = [
+ {"candidate": left, "baseline": right}
+ for left, right in sorted(values, key=repr)
+ ]
+
+ percent_changes: dict[str, float] = {}
+ for metric in PERFORMANCE_METRICS:
+ changes = [
+ (candidate_metrics[metric] - baseline_metrics[metric])
+ / baseline_metrics[metric]
+ * 100.0
+ for candidate_metrics, baseline_metrics in paired
+ if metric in candidate_metrics
+ and metric in baseline_metrics
+ and baseline_metrics[metric] != 0
+ ]
+ if changes:
+ percent_changes[metric] = statistics.median(changes)
+
+ comparisons[comparison_key][suite] = {
+ "paired_samples": len(paired),
+ "output_parity": not output_differences,
+ "output_differences": output_differences,
+ "paired_median_percent_change": percent_changes,
+ }
+ return comparisons
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "--candidate",
+ action="append",
+ required=True,
+ type=parse_candidate,
+ metavar="NAME=RUNNER",
+ help="named production-native benchmark executable; repeat for each candidate",
+ )
+ parser.add_argument("--repetitions", type=int, default=15)
+ parser.add_argument("--warmups", type=int, default=1)
+ parser.add_argument("--timeout-seconds", type=float, default=120.0)
+ parser.add_argument("--output-dir", type=Path, required=True)
+ args = parser.parse_args()
+ if args.repetitions < 1 or args.warmups < 0:
+ parser.error("repetitions must be positive and warmups must be non-negative")
+ names = [candidate[0] for candidate in args.candidate]
+ if len(names) != len(set(names)):
+ parser.error("candidate names must be unique")
+
+ output_dir = args.output_dir.expanduser().resolve()
+ output_dir.mkdir(parents=True, exist_ok=True)
+ raw_path = output_dir / "native-extraction-raw.txt"
+ json_path = output_dir / "native-extraction-results.json"
+
+ candidates = list(args.candidate)
+ for suite_index, suite in enumerate(SUITES):
+ for warmup in range(args.warmups):
+ offset = (suite_index + warmup) % len(candidates)
+ for _, runner in candidates[offset:] + candidates[:offset]:
+ run_sample(runner, suite, args.timeout_seconds)
+
+ samples: list[dict[str, Any]] = []
+ with raw_path.open("w", encoding="utf-8") as raw:
+ for suite_index, suite in enumerate(SUITES):
+ for repetition in range(args.repetitions):
+ offset = (suite_index + repetition) % len(candidates)
+ ordered = candidates[offset:] + candidates[:offset]
+ for candidate, runner in ordered:
+ metrics, output = run_sample(runner, suite, args.timeout_seconds)
+ sample = {
+ "candidate": candidate,
+ "suite": suite,
+ "repetition": repetition + 1,
+ "metrics": metrics,
+ }
+ samples.append(sample)
+ raw.write(
+ f"BENCH candidate={candidate} suite={suite} "
+ f"run={repetition + 1}\n{output.rstrip()}\n"
+ )
+ raw.flush()
+ print(
+ f"{suite} {repetition + 1}/{args.repetitions} {candidate}: "
+ + (
+ f"{metrics['latency_ms']:.3f} ms"
+ if "latency_ms" in metrics
+ else "resource baseline"
+ ),
+ flush=True,
+ )
+
+ add_incremental_resource_metrics(samples)
+ result = {
+ "schema_version": 2,
+ "generated_at": datetime.now(timezone.utc).isoformat(),
+ "platform": platform.platform(),
+ "python": sys.version.split()[0],
+ "repetitions": args.repetitions,
+ "warmups": args.warmups,
+ "candidates": {name: str(path) for name, path in candidates},
+ "samples": samples,
+ "medians": summarize(samples),
+ "comparisons": compare_candidates(samples),
+ }
+ json_path.write_text(json.dumps(result, indent=2, sort_keys=True) + "\n", encoding="utf-8")
+ print(f"raw: {raw_path}")
+ print(f"results: {json_path}")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/benchmarks/schema/comparisons-v1.schema.json b/benchmarks/schema/comparisons-v1.schema.json
new file mode 100644
index 000000000..87fd75358
--- /dev/null
+++ b/benchmarks/schema/comparisons-v1.schema.json
@@ -0,0 +1,379 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "benchmark-comparisons-v1.schema.json",
+ "title": "Codebase Memory benchmark fact-derived comparisons",
+ "type": "object",
+ "required": [
+ "$schema",
+ "schema_version",
+ "generated_at_utc",
+ "terminology_version",
+ "terminology_sha256",
+ "joins",
+ "formulas",
+ "source_bundles",
+ "cell_groups",
+ "comparisons",
+ "lifecycle_rows"
+ ],
+ "properties": {
+ "$schema": {"const": "benchmarks/schema/comparisons-v1.schema.json"},
+ "schema_version": {"const": 1},
+ "generated_at_utc": {"type": "string", "format": "date-time"},
+ "terminology_version": {"type": "string", "minLength": 1},
+ "terminology_sha256": {"$ref": "#/$defs/sha256"},
+ "joins": {
+ "type": "array",
+ "minItems": 2,
+ "items": {"$ref": "#/$defs/join"}
+ },
+ "formulas": {
+ "type": "array",
+ "minItems": 2,
+ "items": {"$ref": "#/$defs/formula"}
+ },
+ "source_bundles": {
+ "type": "array",
+ "minItems": 1,
+ "items": {"$ref": "#/$defs/sourceBundle"}
+ },
+ "cell_groups": {
+ "type": "array",
+ "minItems": 1,
+ "items": {"$ref": "#/$defs/cellGroup"}
+ },
+ "comparisons": {
+ "type": "array",
+ "items": {"$ref": "#/$defs/comparison"}
+ },
+ "lifecycle_rows": {
+ "type": "array",
+ "items": {"$ref": "#/$defs/lifecycleRow"}
+ }
+ },
+ "additionalProperties": false,
+ "$defs": {
+ "sha256": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{64}$"
+ },
+ "contentId": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{24}$"
+ },
+ "stringArray": {
+ "type": "array",
+ "items": {"type": "string"}
+ },
+ "join": {
+ "type": "object",
+ "required": [
+ "join_id",
+ "fields",
+ "unknown_values_allowed",
+ "ratio_allowed"
+ ],
+ "properties": {
+ "join_id": {
+ "enum": [
+ "parity_manifest_and_contract_v1",
+ "capability_delta_manifest_v1"
+ ]
+ },
+ "fields": {
+ "type": "array",
+ "minItems": 1,
+ "uniqueItems": true,
+ "items": {"type": "string"}
+ },
+ "unknown_values_allowed": {"type": "boolean"},
+ "ratio_allowed": {"type": "boolean"}
+ },
+ "additionalProperties": false
+ },
+ "formula": {
+ "type": "object",
+ "required": ["formula_id", "expression"],
+ "properties": {
+ "formula_id": {
+ "enum": [
+ "median_elapsed_ms_v1",
+ "left_elapsed_divided_by_right_elapsed_v1"
+ ]
+ },
+ "expression": {"type": "string", "minLength": 1}
+ },
+ "additionalProperties": false
+ },
+ "sourceBundle": {
+ "type": "object",
+ "required": ["path", "sha256", "schema_version", "run_id"],
+ "properties": {
+ "path": {"type": "string", "minLength": 1},
+ "sha256": {"$ref": "#/$defs/sha256"},
+ "schema_version": {"enum": [1, 2]},
+ "run_id": {"type": "string", "minLength": 1}
+ },
+ "additionalProperties": false
+ },
+ "stepAggregate": {
+ "type": "object",
+ "required": [
+ "step_id",
+ "formula_id",
+ "count",
+ "median_elapsed_ms",
+ "min_elapsed_ms",
+ "max_elapsed_ms",
+ "source_occurrence_ids"
+ ],
+ "properties": {
+ "step_id": {"type": "string", "minLength": 1},
+ "formula_id": {"const": "median_elapsed_ms_v1"},
+ "count": {"type": "integer", "minimum": 1},
+ "median_elapsed_ms": {"type": "number", "minimum": 0},
+ "min_elapsed_ms": {"type": "number", "minimum": 0},
+ "max_elapsed_ms": {"type": "number", "minimum": 0},
+ "source_occurrence_ids": {"$ref": "#/$defs/stringArray"}
+ },
+ "additionalProperties": false
+ },
+ "resultAggregate": {
+ "type": "object",
+ "required": [
+ "result_id",
+ "kind",
+ "statuses",
+ "all_passed",
+ "source_run_ids"
+ ],
+ "properties": {
+ "result_id": {"type": "string", "minLength": 1},
+ "kind": {"type": "string", "minLength": 1},
+ "statuses": {"$ref": "#/$defs/stringArray"},
+ "all_passed": {"type": "boolean"},
+ "source_run_ids": {"$ref": "#/$defs/stringArray"}
+ },
+ "additionalProperties": false
+ },
+ "cellGroup": {
+ "type": "object",
+ "required": [
+ "cell_group_id",
+ "label",
+ "mode",
+ "implementation",
+ "capabilities",
+ "scope",
+ "cache",
+ "host",
+ "benchmark_contract",
+ "result_contract",
+ "source_run_ids",
+ "source_fact_paths",
+ "step_aggregates",
+ "result_aggregates"
+ ],
+ "properties": {
+ "cell_group_id": {"$ref": "#/$defs/contentId"},
+ "label": {"type": "string", "minLength": 1},
+ "mode": {"type": "string", "minLength": 1},
+ "implementation": {"type": "object"},
+ "capabilities": {"type": "object"},
+ "scope": {"type": "object"},
+ "cache": {"type": "object"},
+ "host": {"type": "object"},
+ "benchmark_contract": {"type": "object"},
+ "result_contract": {"type": "array", "items": {"type": "object"}},
+ "source_run_ids": {
+ "allOf": [
+ {"$ref": "#/$defs/stringArray"},
+ {"minItems": 1, "uniqueItems": true}
+ ]
+ },
+ "source_fact_paths": {
+ "allOf": [
+ {"$ref": "#/$defs/stringArray"},
+ {"minItems": 1, "uniqueItems": true}
+ ]
+ },
+ "step_aggregates": {
+ "type": "array",
+ "items": {"$ref": "#/$defs/stepAggregate"}
+ },
+ "result_aggregates": {
+ "type": "array",
+ "items": {"$ref": "#/$defs/resultAggregate"}
+ }
+ },
+ "additionalProperties": false
+ },
+ "capabilityDifference": {
+ "type": "object",
+ "required": ["capability_id", "left", "right"],
+ "properties": {
+ "capability_id": {"type": "string", "minLength": 1},
+ "left": {},
+ "right": {}
+ },
+ "additionalProperties": false
+ },
+ "stepComparison": {
+ "type": "object",
+ "required": [
+ "step_id",
+ "formula_id",
+ "left_median_elapsed_ms",
+ "right_median_elapsed_ms",
+ "left_elapsed_divided_by_right_elapsed",
+ "left_source_occurrence_ids",
+ "right_source_occurrence_ids"
+ ],
+ "properties": {
+ "step_id": {"type": "string", "minLength": 1},
+ "formula_id": {
+ "const": "left_elapsed_divided_by_right_elapsed_v1"
+ },
+ "left_median_elapsed_ms": {"type": "number", "minimum": 0},
+ "right_median_elapsed_ms": {"type": "number", "minimum": 0},
+ "left_elapsed_divided_by_right_elapsed": {
+ "type": ["number", "null"],
+ "minimum": 0
+ },
+ "left_source_occurrence_ids": {"$ref": "#/$defs/stringArray"},
+ "right_source_occurrence_ids": {"$ref": "#/$defs/stringArray"}
+ },
+ "additionalProperties": false
+ },
+ "comparison": {
+ "type": "object",
+ "required": [
+ "comparison_id",
+ "left_cell_group_id",
+ "right_cell_group_id",
+ "left_source_run_ids",
+ "right_source_run_ids",
+ "comparison_kind",
+ "join_id",
+ "ratio_allowed",
+ "capability_differences",
+ "step_comparisons",
+ "limitations"
+ ],
+ "properties": {
+ "comparison_id": {"$ref": "#/$defs/contentId"},
+ "left_cell_group_id": {"$ref": "#/$defs/contentId"},
+ "right_cell_group_id": {"$ref": "#/$defs/contentId"},
+ "left_source_run_ids": {"$ref": "#/$defs/stringArray"},
+ "right_source_run_ids": {"$ref": "#/$defs/stringArray"},
+ "comparison_kind": {
+ "enum": [
+ "parity_comparison",
+ "capability_delta_comparison",
+ "not_eligible"
+ ]
+ },
+ "join_id": {
+ "enum": [
+ "parity_manifest_and_contract_v1",
+ "capability_delta_manifest_v1",
+ null
+ ]
+ },
+ "ratio_allowed": {"type": "boolean"},
+ "capability_differences": {
+ "type": "array",
+ "items": {"$ref": "#/$defs/capabilityDifference"}
+ },
+ "step_comparisons": {
+ "type": "array",
+ "items": {"$ref": "#/$defs/stepComparison"}
+ },
+ "limitations": {"$ref": "#/$defs/stringArray"}
+ },
+ "allOf": [
+ {
+ "if": {
+ "properties": {"comparison_kind": {"const": "parity_comparison"}},
+ "required": ["comparison_kind"]
+ },
+ "then": {
+ "properties": {
+ "join_id": {"const": "parity_manifest_and_contract_v1"},
+ "ratio_allowed": {"const": true},
+ "capability_differences": {"maxItems": 0},
+ "limitations": {"maxItems": 0}
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "comparison_kind": {"const": "capability_delta_comparison"}
+ },
+ "required": ["comparison_kind"]
+ },
+ "then": {
+ "properties": {
+ "join_id": {"const": "capability_delta_manifest_v1"},
+ "ratio_allowed": {"const": false},
+ "capability_differences": {"minItems": 1},
+ "step_comparisons": {"maxItems": 0}
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {"comparison_kind": {"const": "not_eligible"}},
+ "required": ["comparison_kind"]
+ },
+ "then": {
+ "properties": {
+ "join_id": {"type": "null"},
+ "ratio_allowed": {"const": false},
+ "step_comparisons": {"maxItems": 0},
+ "limitations": {"minItems": 1}
+ }
+ }
+ }
+ ],
+ "additionalProperties": false
+ },
+ "lifecycleRow": {
+ "type": "object",
+ "required": [
+ "cell_group_id",
+ "label",
+ "source_run_ids",
+ "steps",
+ "wall_time_rule"
+ ],
+ "properties": {
+ "cell_group_id": {"$ref": "#/$defs/contentId"},
+ "label": {"type": "string", "minLength": 1},
+ "source_run_ids": {"$ref": "#/$defs/stringArray"},
+ "steps": {
+ "type": "array",
+ "items": {
+ "allOf": [
+ {"$ref": "#/$defs/stepAggregate"},
+ {
+ "properties": {
+ "step_id": {
+ "enum": [
+ "initial_index",
+ "incremental_index",
+ "clean_rebuild_index"
+ ]
+ }
+ }
+ }
+ ]
+ }
+ },
+ "wall_time_rule": {"type": "string", "minLength": 1}
+ },
+ "additionalProperties": false
+ }
+ }
+}
diff --git a/benchmarks/schema/facts-v2.schema.json b/benchmarks/schema/facts-v2.schema.json
new file mode 100644
index 000000000..19b940225
--- /dev/null
+++ b/benchmarks/schema/facts-v2.schema.json
@@ -0,0 +1,155 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "benchmark-facts-v2.schema.json",
+ "title": "Codebase Memory benchmark fact bundle",
+ "type": "object",
+ "required": [
+ "$schema",
+ "schema_version",
+ "terminology_version",
+ "terminology_sha256",
+ "generator_revision",
+ "runs",
+ "steps",
+ "results",
+ "artifacts"
+ ],
+ "properties": {
+ "$schema": {"const": "benchmarks/schema/facts-v2.schema.json"},
+ "schema_version": {"const": 2},
+ "terminology_version": {
+ "type": "string",
+ "pattern": "^[1-9][0-9]*\\.[0-9]+\\.[0-9]+$"
+ },
+ "terminology_sha256": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{64}$"
+ },
+ "generator_revision": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{64}$"
+ },
+ "runs": {
+ "description": "Run-level identity and measurement conditions; exactly one row per fact bundle.",
+ "type": "array",
+ "minItems": 1,
+ "maxItems": 1,
+ "items": {"$ref": "#/$defs/run"}
+ },
+ "steps": {
+ "description": "Measured operation occurrences. Rows may overlap in wall time and are not additive unless a report proves serial execution.",
+ "type": "array",
+ "items": {"$ref": "#/$defs/step"}
+ },
+ "results": {
+ "description": "Correctness, quality, and instrumentation outcomes for the run.",
+ "type": "array",
+ "items": {"$ref": "#/$defs/result"}
+ },
+ "artifacts": {
+ "description": "Content-identified files retained as measurement evidence.",
+ "type": "array",
+ "items": {"$ref": "#/$defs/artifact"}
+ }
+ },
+ "additionalProperties": false,
+ "$defs": {
+ "unknown": {
+ "description": "A value the measurement source did not record; reason states the missing evidence.",
+ "type": "object",
+ "required": ["status", "reason"],
+ "properties": {
+ "status": {"const": "unknown"},
+ "reason": {"type": "string", "minLength": 1}
+ },
+ "additionalProperties": false
+ },
+ "runId": {"type": "string", "pattern": "^[0-9a-f]{24}$"},
+ "run": {
+ "type": "object",
+ "required": [
+ "run_id", "lifecycle_id", "generated_at_utc", "mode", "implementation",
+ "harness", "host", "measurement_checkout", "capabilities", "scope", "cache", "legacy_import"
+ ],
+ "properties": {
+ "run_id": {"$ref": "#/$defs/runId", "description": "Content-derived identity for this measured lifecycle."},
+ "lifecycle_id": {"$ref": "#/$defs/runId", "description": "Identity of the user-observable process-to-gate lifecycle; equal to run_id in schema version 1."},
+ "generated_at_utc": {"description": "Recorded report completion time, or an explicit unknown fact."},
+ "mode": {"type": "string", "minLength": 1, "description": "Benchmark workload/report family."},
+ "cell_identity": {"description": "Immutable experiment-cell identity, or an explicit unknown fact for standalone and legacy runs."},
+ "cell_label": {"description": "Human-readable experiment-cell label, or an explicit unknown fact."},
+ "repetition": {"description": "One-based repetition declared by the experiment, or an explicit unknown fact."},
+ "implementation": {"type": "object", "description": "Candidate revision, revision provenance, binary identity, and build metadata."},
+ "harness": {"type": "object", "description": "Benchmark script path, SHA-256, and fact-schema version."},
+ "host": {"type": "object", "description": "Host facts recorded by the measurement process, or an explicit unknown fact."},
+ "measurement_checkout": {"type": "object", "description": "Git checkout that executed the harness; it is not evidence of the candidate binary revision."},
+ "capabilities": {"type": "object", "description": "Resolved capability/configuration values plus completeness and provenance."},
+ "scope": {"type": "object", "description": "Workload identity, corpus or fixture bounds, and mutation size."},
+ "cache": {"type": "object", "description": "Known process, graph, dependency, OS, parser, and fixture cache states."},
+ "legacy_import": {"type": "boolean", "description": "True when a retained report was normalized without recorded measurement-process context."}
+ },
+ "additionalProperties": false
+ },
+ "step": {
+ "type": "object",
+ "required": [
+ "run_id", "step_id", "occurrence_id", "source_path", "parent_occurrence_id",
+ "dependency_occurrence_ids", "elapsed_ms", "monotonic_start_ns",
+ "monotonic_end_ns", "cpu_ms", "cpu_scope", "queue_wait_ms",
+ "thread_or_worker_id", "critical_path", "peak_rss_mb", "work_counters",
+ "provenance"
+ ],
+ "properties": {
+ "run_id": {"$ref": "#/$defs/runId"},
+ "step_id": {"type": "string", "minLength": 1, "description": "Stable operation-class label; multiple occurrences may share it."},
+ "occurrence_id": {"type": "string", "pattern": "^[0-9a-f]{24}$", "description": "Identity of this operation occurrence within the run."},
+ "source_path": {"type": "string", "description": "JSON path from which the measurement was normalized."},
+ "parent_occurrence_id": {"type": ["string", "null"], "description": "Containing occurrence; containment does not imply serial execution."},
+ "dependency_occurrence_ids": {"type": "array", "items": {"type": "string"}, "description": "Recorded prerequisite occurrences; an empty array means no dependency evidence was recorded."},
+ "elapsed_ms": {"type": "number", "minimum": 0, "description": "Wall-clock duration. Overlapping occurrence durations must not be summed."},
+ "monotonic_start_ns": {"description": "Monotonic start timestamp or an explicit unknown fact."},
+ "monotonic_end_ns": {"description": "Monotonic end timestamp or an explicit unknown fact."},
+ "cpu_ms": {"description": "CPU time consumed by cpu_scope, or an explicit unknown fact."},
+ "cpu_scope": {"type": "string", "description": "Entity covered by cpu_ms, such as thread, process, or process tree."},
+ "queue_wait_ms": {"description": "Runnable-to-execution delay or an explicit unknown fact."},
+ "thread_or_worker_id": {"description": "Recorded execution resource identity or an explicit unknown fact."},
+ "critical_path": {"description": "Whether and how this occurrence lies on the measured dependency critical path, or an explicit unknown fact."},
+ "peak_rss_mb": {"description": "Peak resident memory attributable to the occurrence, or an explicit unknown fact."},
+ "work_counters": {"type": "object", "description": "Operation-specific item counts with named units."},
+ "provenance": {"type": "string", "description": "Measurement source or normalization rule that produced the row."}
+ },
+ "additionalProperties": false
+ },
+ "result": {
+ "type": "object",
+ "required": ["run_id", "result_id", "kind", "status", "value", "provenance"],
+ "properties": {
+ "run_id": {"$ref": "#/$defs/runId"},
+ "result_id": {"type": "string", "minLength": 1},
+ "kind": {"type": "string", "minLength": 1},
+ "status": {"enum": ["passed", "failed", "unknown", "skipped"]},
+ "value": {},
+ "provenance": {"type": "string"}
+ },
+ "additionalProperties": false
+ },
+ "artifact": {
+ "type": "object",
+ "required": [
+ "run_id", "artifact_id", "artifact_type", "path", "sha256", "size_bytes",
+ "schema_version", "cleanup_status"
+ ],
+ "properties": {
+ "run_id": {"$ref": "#/$defs/runId"},
+ "artifact_id": {"type": "string", "pattern": "^[0-9a-f]{24}$"},
+ "artifact_type": {"type": "string", "minLength": 1},
+ "path": {"type": "string", "minLength": 1},
+ "sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
+ "size_bytes": {},
+ "schema_version": {},
+ "cleanup_status": {"type": "string"}
+ },
+ "additionalProperties": false
+ }
+ }
+}
diff --git a/benchmarks/schema/terminology.schema.json b/benchmarks/schema/terminology.schema.json
new file mode 100644
index 000000000..26b516704
--- /dev/null
+++ b/benchmarks/schema/terminology.schema.json
@@ -0,0 +1,103 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "benchmark-terminology.schema.json",
+ "title": "Codebase Memory benchmark terminology registry",
+ "type": "object",
+ "required": [
+ "$schema",
+ "schema_version",
+ "terminology_version",
+ "step_id_order",
+ "entries"
+ ],
+ "properties": {
+ "$schema": {
+ "const": "benchmarks/schema/terminology.schema.json"
+ },
+ "schema_version": {
+ "const": 1
+ },
+ "terminology_version": {
+ "type": "string",
+ "pattern": "^[1-9][0-9]*\\.[0-9]+\\.[0-9]+$"
+ },
+ "step_id_order": {
+ "type": "array",
+ "minItems": 1,
+ "uniqueItems": true,
+ "items": {"$ref": "#/$defs/termId"}
+ },
+ "entries": {
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "$ref": "#/$defs/entry"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "$defs": {
+ "termId": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_]*$"
+ },
+ "entry": {
+ "type": "object",
+ "required": [
+ "term_id",
+ "display_name",
+ "definition",
+ "status",
+ "kind",
+ "data_type",
+ "allowed_values_or_range",
+ "unit",
+ "clock_or_cpu_scope",
+ "boundary_semantics",
+ "aggregation_rule",
+ "concurrency_rule",
+ "missing_or_unsupported_behavior",
+ "configuration_precedence",
+ "capability_or_freshness_implications",
+ "source_anchors",
+ "introduced_version",
+ "deprecated_replacement",
+ "examples"
+ ],
+ "properties": {
+ "term_id": {"$ref": "#/$defs/termId"},
+ "display_name": {"type": "string", "minLength": 1},
+ "definition": {"type": "string", "minLength": 1},
+ "status": {"enum": ["existing", "proposed", "deprecated"]},
+ "kind": {"type": "string", "minLength": 1},
+ "data_type": {"type": "string", "minLength": 1},
+ "allowed_values_or_range": {"type": "string", "minLength": 1},
+ "unit": {"type": "string", "minLength": 1},
+ "clock_or_cpu_scope": {"type": "string", "minLength": 1},
+ "boundary_semantics": {"type": "string", "minLength": 1},
+ "aggregation_rule": {"type": "string", "minLength": 1},
+ "concurrency_rule": {"type": "string", "minLength": 1},
+ "missing_or_unsupported_behavior": {"type": "string", "minLength": 1},
+ "configuration_precedence": {"type": "string", "minLength": 1},
+ "capability_or_freshness_implications": {"type": "string", "minLength": 1},
+ "source_anchors": {
+ "type": "array",
+ "minItems": 1,
+ "items": {"type": "string", "minLength": 1}
+ },
+ "introduced_version": {"type": "string", "minLength": 1},
+ "deprecated_replacement": {
+ "oneOf": [
+ {"$ref": "#/$defs/termId"},
+ {"type": "null"}
+ ]
+ },
+ "examples": {
+ "type": "array",
+ "items": {}
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+}
diff --git a/benchmarks/semantic-pairs-v1/cbmq_records.py b/benchmarks/semantic-pairs-v1/cbmq_records.py
new file mode 100644
index 000000000..2b543a032
--- /dev/null
+++ b/benchmarks/semantic-pairs-v1/cbmq_records.py
@@ -0,0 +1,46 @@
+def cbmq_sanitize(value: str) -> str:
+ return value.strip().lower()
+
+
+def cbmq_lookup(table: dict, key: str) -> str:
+ return table.get(key, "")
+
+
+def cbmq_audit_log(message: str) -> None:
+ print(message)
+
+
+def cbmq_normalize_user_record(record: dict, table: dict) -> dict:
+ """Normalize a user record by sanitizing fields and looking up defaults."""
+ result = {}
+ name = cbmq_sanitize(record.get("name", ""))
+ email = cbmq_sanitize(record.get("email", ""))
+ role = cbmq_lookup(table, name)
+ if name and email:
+ result["name"] = name
+ result["email"] = email
+ result["role"] = role
+ cbmq_audit_log("normalized user record")
+ return result
+
+
+def cbmq_normalize_account_record(record: dict, table: dict) -> dict:
+ """Normalize an account record by sanitizing fields and looking up defaults."""
+ result = {}
+ name = cbmq_sanitize(record.get("name", ""))
+ email = cbmq_sanitize(record.get("email", ""))
+ role = cbmq_lookup(table, name)
+ while name and email:
+ result["name"] = name
+ result["email"] = email
+ result["role"] = role
+ cbmq_audit_log("normalized account record")
+ break
+ return result
+
+
+def cbmq_archive_record_decoy(record: dict, table: dict) -> dict:
+ """Archive record metadata without normalization."""
+ keys = sorted(record.keys())
+ bucket = table.get("archive", "")
+ return {"bucket": bucket, "fields": keys, "count": len(keys)}
diff --git a/benchmarks/semantic-pairs-v1/cbmq_similarity.go b/benchmarks/semantic-pairs-v1/cbmq_similarity.go
new file mode 100644
index 000000000..e68fb0cb7
--- /dev/null
+++ b/benchmarks/semantic-pairs-v1/cbmq_similarity.go
@@ -0,0 +1,92 @@
+package cbmq
+
+import (
+ "errors"
+ "strings"
+)
+
+func cbmqValidateUser(u User) error {
+ if u.Name == "" {
+ return errors.New("name required")
+ }
+ if len(u.Name) > 100 {
+ return errors.New("name too long")
+ }
+ if u.Age < 0 {
+ return errors.New("invalid age")
+ }
+ if u.Age > 200 {
+ return errors.New("age too high")
+ }
+ if u.Email == "" {
+ return errors.New("email required")
+ }
+ if !strings.Contains(u.Email, "@") {
+ return errors.New("invalid email")
+ }
+ if u.Phone == "" {
+ return errors.New("phone required")
+ }
+ if len(u.Phone) < 7 {
+ return errors.New("phone too short")
+ }
+ if u.Country == "" {
+ return errors.New("country required")
+ }
+ for _, value := range u.Tags {
+ if value == "" {
+ return errors.New("empty tag")
+ }
+ }
+ return nil
+}
+
+func cbmqValidateOrder(o Order) error {
+ if o.Title == "" {
+ return errors.New("title required")
+ }
+ if len(o.Title) > 100 {
+ return errors.New("title too long")
+ }
+ if o.Amount < 0 {
+ return errors.New("invalid amount")
+ }
+ if o.Amount > 200 {
+ return errors.New("amount too high")
+ }
+ if o.Status == "" {
+ return errors.New("status required")
+ }
+ if !strings.Contains(o.Status, "@") {
+ return errors.New("invalid status")
+ }
+ if o.Region == "" {
+ return errors.New("region required")
+ }
+ if len(o.Region) < 7 {
+ return errors.New("region too short")
+ }
+ if o.Vendor == "" {
+ return errors.New("vendor required")
+ }
+ for _, value := range o.Items {
+ if value == "" {
+ return errors.New("empty item")
+ }
+ }
+ return nil
+}
+
+func cbmqValidateProfileDecoy(p Profile) error {
+ values := map[string]string{"name": p.Name, "email": p.Email}
+ missing := make([]string, 0)
+ for field, value := range values {
+ if strings.TrimSpace(value) == "" {
+ missing = append(missing, field)
+ }
+ }
+ if len(missing) != 0 {
+ return errors.New(strings.Join(missing, ","))
+ }
+ return nil
+}
diff --git a/benchmarks/semantic-pairs-v1/manifest.json b/benchmarks/semantic-pairs-v1/manifest.json
new file mode 100644
index 000000000..85faf2aaa
--- /dev/null
+++ b/benchmarks/semantic-pairs-v1/manifest.json
@@ -0,0 +1,112 @@
+{
+ "schema_version": 1,
+ "task_set_version": "semantic-pairs-v1",
+ "ground_truth_scope": "explicit generated canary pairs only",
+ "query_name_marker": "cbmq",
+ "cases": {
+ "similarity": {
+ "capability": "similarity",
+ "relationship": "SIMILAR_TO",
+ "score_property": "jaccard",
+ "languages": ["go"],
+ "source_paths": ["cbmq_similarity.go"],
+ "judgments": [
+ {
+ "source": "cbmqValidateUser",
+ "target": "cbmqValidateOrder",
+ "expected": true,
+ "category": "structural_near_clone"
+ },
+ {
+ "source": "cbmqValidateUser",
+ "target": "cbmqValidateProfileDecoy",
+ "expected": false,
+ "category": "lexical_hard_negative"
+ },
+ {
+ "source": "cbmqValidateOrder",
+ "target": "cbmqValidateProfileDecoy",
+ "expected": false,
+ "category": "lexical_hard_negative"
+ }
+ ],
+ "mutation": {
+ "target_path": "cbmq_similarity.go",
+ "replacement_source_path": "variants/cbmq_similarity_after.go",
+ "description": "move the structural-clone relationship from order to profile",
+ "post_judgments": [
+ {
+ "source": "cbmqValidateUser",
+ "target": "cbmqValidateOrder",
+ "expected": false,
+ "category": "removed_structural_near_clone"
+ },
+ {
+ "source": "cbmqValidateUser",
+ "target": "cbmqValidateProfileDecoy",
+ "expected": true,
+ "category": "added_structural_near_clone"
+ },
+ {
+ "source": "cbmqValidateOrder",
+ "target": "cbmqValidateProfileDecoy",
+ "expected": false,
+ "category": "lexical_hard_negative"
+ }
+ ]
+ }
+ },
+ "semantic_edges": {
+ "capability": "semantic_edges",
+ "relationship": "SEMANTICALLY_RELATED",
+ "score_property": "score",
+ "languages": ["python"],
+ "source_paths": ["cbmq_records.py"],
+ "judgments": [
+ {
+ "source": "cbmq_normalize_user_record",
+ "target": "cbmq_normalize_account_record",
+ "expected": true,
+ "category": "semantic_control_flow_variant"
+ },
+ {
+ "source": "cbmq_normalize_user_record",
+ "target": "cbmq_archive_record_decoy",
+ "expected": false,
+ "category": "lexical_hard_negative"
+ },
+ {
+ "source": "cbmq_normalize_account_record",
+ "target": "cbmq_archive_record_decoy",
+ "expected": false,
+ "category": "lexical_hard_negative"
+ }
+ ],
+ "mutation": {
+ "target_path": "cbmq_records.py",
+ "replacement_source_path": "variants/cbmq_records_after.py",
+ "description": "move semantic relatedness from account normalization to archive normalization",
+ "post_judgments": [
+ {
+ "source": "cbmq_normalize_user_record",
+ "target": "cbmq_normalize_account_record",
+ "expected": false,
+ "category": "removed_semantic_control_flow_variant"
+ },
+ {
+ "source": "cbmq_normalize_user_record",
+ "target": "cbmq_archive_record_decoy",
+ "expected": true,
+ "category": "added_semantic_control_flow_variant"
+ },
+ {
+ "source": "cbmq_normalize_account_record",
+ "target": "cbmq_archive_record_decoy",
+ "expected": false,
+ "category": "lexical_hard_negative"
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/benchmarks/semantic-pairs-v1/variants/cbmq_records_after.py b/benchmarks/semantic-pairs-v1/variants/cbmq_records_after.py
new file mode 100644
index 000000000..41e72af72
--- /dev/null
+++ b/benchmarks/semantic-pairs-v1/variants/cbmq_records_after.py
@@ -0,0 +1,47 @@
+def cbmq_sanitize(value: str) -> str:
+ return value.strip().lower()
+
+
+def cbmq_lookup(table: dict, key: str) -> str:
+ return table.get(key, "")
+
+
+def cbmq_audit_log(message: str) -> None:
+ print(message)
+
+
+def cbmq_normalize_user_record(record: dict, table: dict) -> dict:
+ """Normalize a user record by sanitizing fields and looking up defaults."""
+ result = {}
+ name = cbmq_sanitize(record.get("name", ""))
+ email = cbmq_sanitize(record.get("email", ""))
+ role = cbmq_lookup(table, name)
+ if name and email:
+ result["name"] = name
+ result["email"] = email
+ result["role"] = role
+ cbmq_audit_log("normalized user record")
+ return result
+
+
+def cbmq_normalize_account_record(record: dict, table: dict) -> dict:
+ """Archive account field names without normalization."""
+ keys = sorted(record.keys())
+ bucket = table.get("archive", "")
+ return {"bucket": bucket, "fields": keys, "count": len(keys)}
+
+
+def cbmq_archive_record_decoy(record: dict, table: dict) -> dict:
+ """Normalize an archive record by sanitizing fields and looking up defaults."""
+ result = {}
+ name = cbmq_sanitize(record.get("name", ""))
+ email = cbmq_sanitize(record.get("email", ""))
+ role = cbmq_lookup(table, name)
+ for _ in range(1):
+ if not (name and email):
+ continue
+ result["name"] = name
+ result["email"] = email
+ result["role"] = role
+ cbmq_audit_log("normalized archive record")
+ return result
diff --git a/benchmarks/semantic-pairs-v1/variants/cbmq_similarity_after.go b/benchmarks/semantic-pairs-v1/variants/cbmq_similarity_after.go
new file mode 100644
index 000000000..9acfefd52
--- /dev/null
+++ b/benchmarks/semantic-pairs-v1/variants/cbmq_similarity_after.go
@@ -0,0 +1,92 @@
+package cbmq
+
+import (
+ "errors"
+ "strings"
+)
+
+func cbmqValidateUser(u User) error {
+ if u.Name == "" {
+ return errors.New("name required")
+ }
+ if len(u.Name) > 100 {
+ return errors.New("name too long")
+ }
+ if u.Age < 0 {
+ return errors.New("invalid age")
+ }
+ if u.Age > 200 {
+ return errors.New("age too high")
+ }
+ if u.Email == "" {
+ return errors.New("email required")
+ }
+ if !strings.Contains(u.Email, "@") {
+ return errors.New("invalid email")
+ }
+ if u.Phone == "" {
+ return errors.New("phone required")
+ }
+ if len(u.Phone) < 7 {
+ return errors.New("phone too short")
+ }
+ if u.Country == "" {
+ return errors.New("country required")
+ }
+ for _, value := range u.Tags {
+ if value == "" {
+ return errors.New("empty tag")
+ }
+ }
+ return nil
+}
+
+func cbmqValidateOrder(o Order) error {
+ values := map[string]string{"title": o.Title, "status": o.Status}
+ missing := make([]string, 0)
+ for field, value := range values {
+ if strings.TrimSpace(value) == "" {
+ missing = append(missing, field)
+ }
+ }
+ if len(missing) != 0 {
+ return errors.New(strings.Join(missing, ","))
+ }
+ return nil
+}
+
+func cbmqValidateProfileDecoy(p Profile) error {
+ if p.Name == "" {
+ return errors.New("name required")
+ }
+ if len(p.Name) > 100 {
+ return errors.New("name too long")
+ }
+ if p.Age < 0 {
+ return errors.New("invalid age")
+ }
+ if p.Age > 200 {
+ return errors.New("age too high")
+ }
+ if p.Email == "" {
+ return errors.New("email required")
+ }
+ if !strings.Contains(p.Email, "@") {
+ return errors.New("invalid email")
+ }
+ if p.Phone == "" {
+ return errors.New("phone required")
+ }
+ if len(p.Phone) < 7 {
+ return errors.New("phone too short")
+ }
+ if p.Country == "" {
+ return errors.New("country required")
+ }
+ for _, value := range p.Tags {
+ if value == "" {
+ return errors.New("empty tag")
+ }
+ }
+ return nil
+}
diff --git a/benchmarks/summarize_results.py b/benchmarks/summarize_results.py
new file mode 100755
index 000000000..32b769a44
--- /dev/null
+++ b/benchmarks/summarize_results.py
@@ -0,0 +1,3221 @@
+#!/usr/bin/env python3
+"""Aggregate existing CBM benchmark JSON into a quality-first Markdown table."""
+
+from __future__ import annotations
+
+import argparse
+from contextlib import suppress
+import hashlib
+import importlib.util
+import json
+import math
+import os
+import statistics
+import uuid
+from collections import defaultdict
+from pathlib import Path
+from typing import Any
+
+
+CONFIG_SPELLING_SPEC_PATH = Path(__file__).with_name("config-spellings-v1.json")
+with CONFIG_SPELLING_SPEC_PATH.open(encoding="utf-8") as stream:
+ CONFIG_SPELLING_SPEC = json.load(stream)
+if CONFIG_SPELLING_SPEC.get("schema_version") != 1:
+ raise RuntimeError(
+ f"unsupported benchmark config spelling schema: {CONFIG_SPELLING_SPEC_PATH}"
+ )
+
+
+def percentile(values: list[float], quantile: float) -> float | None:
+ if not values:
+ return None
+ ordered = sorted(values)
+ index = max(0, math.ceil(quantile * len(ordered)) - 1)
+ return float(ordered[index])
+
+
+def repeated_query_elapsed_ms(oracle: dict[str, Any]) -> float | None:
+ summary = oracle.get("repeated_json_latency_ms")
+ if isinstance(summary, dict) and isinstance(summary.get("median"), (int, float)):
+ return float(summary["median"])
+ elapsed = oracle.get("elapsed_ms")
+ return float(elapsed) if isinstance(elapsed, (int, float)) else None
+
+
+def ratio(passed: int, applicable: int) -> str:
+ return f"{passed}/{applicable}" if applicable else "n/a"
+
+
+def evidence_lifecycle(reports: list[dict[str, Any]]) -> str:
+ """Describe retained evidence separately from requested cleanup outcomes."""
+ disposed = 0
+ retained = 0
+ failed = 0
+ unknown = 0
+ for report in reports:
+ cleanup = report.get("cleanup")
+ if not isinstance(cleanup, dict) or not isinstance(
+ cleanup.get("requested"), bool
+ ):
+ unknown += 1
+ elif cleanup["requested"] is False:
+ retained += 1
+ elif cleanup.get("removed") is True:
+ disposed += 1
+ else:
+ failed += 1
+ if failed:
+ requested = disposed + failed
+ return f"CLEANUP FAILED {failed}/{requested}"
+ if unknown:
+ return f"unknown {unknown}/{len(reports)}"
+ if disposed and retained:
+ return f"disposed {disposed}/{len(reports)}; retained by request {retained}/{len(reports)}"
+ if disposed:
+ return f"disposed {disposed}/{len(reports)}"
+ return f"retained by request {retained}/{len(reports)}"
+
+
+def cases_from_report(report: dict[str, Any]) -> list[dict[str, Any]]:
+ cases = report.get("cases")
+ if isinstance(cases, list):
+ return [case for case in cases if isinstance(case, dict)]
+ measurements = report.get("measurements")
+ derived = report.get("derived")
+ if isinstance(measurements, dict) and isinstance(derived, dict):
+ return [
+ {
+ "passed": derived.get("passed"),
+ "incremental": measurements.get("incremental", {}),
+ "fresh_fast_full_after_change": measurements.get(
+ "fresh_fast_full_after_change", {}
+ ),
+ "speedup_full_rebuild_over_incremental": derived.get(
+ "speedup_full_rebuild_over_incremental"
+ ),
+ }
+ ]
+ return []
+
+
+PRE_RENAME_CONFIG_OVERRIDES = {
+ (entry["historical"]["key"], entry["historical"]["value"]): (
+ entry["canonical"]["key"],
+ entry["canonical"]["value"],
+ )
+ for entry in CONFIG_SPELLING_SPEC["config_overrides"]
+}
+PRE_RENAME_CONFIG_PROFILES = {
+ historical: details["canonical"]
+ for details in CONFIG_SPELLING_SPEC["profiles"].values()
+ for historical in details["historical"]
+}
+PRE_RENAME_EXPERIMENT_LABELS = {
+ historical: details["canonical"]
+ for details in CONFIG_SPELLING_SPEC["experiment_labels"].values()
+ for historical in details["historical"]
+}
+
+
+def canonical_config_override(key: Any, value: Any) -> tuple[str, str]:
+ raw = str(key), str(value)
+ return PRE_RENAME_CONFIG_OVERRIDES.get(
+ raw,
+ raw,
+ )
+
+
+def canonical_config_overrides(overrides: dict[Any, Any]) -> dict[str, str]:
+ canonical: dict[str, str] = {}
+ for raw_key, raw_value in overrides.items():
+ key, value = canonical_config_override(raw_key, raw_value)
+ previous = canonical.get(key)
+ if previous is not None and previous != value:
+ raise ValueError(
+ f"conflicting retained config values after canonicalization: "
+ f"{key}={previous} and {key}={value}"
+ )
+ canonical[key] = value
+ return canonical
+
+
+def canonical_config_profile(profile: Any) -> Any:
+ return PRE_RENAME_CONFIG_PROFILES.get(profile, profile)
+
+
+def canonical_experiment_label(label: str) -> str:
+ return PRE_RENAME_EXPERIMENT_LABELS.get(label, label)
+
+
+def reports_use_pre_rename_config_spellings(reports: list[dict[str, Any]]) -> bool:
+ for report in reports:
+ parameters = report.get("parameters")
+ overrides = (
+ parameters.get("config_overrides", {})
+ if isinstance(parameters, dict)
+ else {}
+ )
+ if not isinstance(overrides, dict):
+ continue
+ profile = (
+ parameters.get("config_profile") if isinstance(parameters, dict) else None
+ )
+ if canonical_config_profile(profile) != profile or any(
+ canonical_config_override(key, value) != (str(key), str(value))
+ for key, value in overrides.items()
+ ):
+ return True
+ return False
+
+
+def config_label(reports: list[dict[str, Any]]) -> str:
+ labels: set[str] = set()
+ for report in reports:
+ parameters = report.get("parameters", {})
+ overrides = (
+ parameters.get("config_overrides", {})
+ if isinstance(parameters, dict)
+ else {}
+ )
+ profile = (
+ parameters.get("config_profile") if isinstance(parameters, dict) else None
+ )
+ profile = canonical_config_profile(profile)
+ if isinstance(overrides, dict) and overrides:
+ canonical_overrides = canonical_config_overrides(overrides)
+ expanded = ", ".join(
+ f"{key}={canonical_overrides[key]}"
+ for key in sorted(canonical_overrides)
+ )
+ labels.add(
+ f"{profile} ({expanded})"
+ if isinstance(profile, str) and profile
+ else expanded
+ )
+ else:
+ labels.add(
+ str(profile) if isinstance(profile, str) and profile else "defaults"
+ )
+ return " / ".join(sorted(labels))
+
+
+def config_signature(
+ reports: list[dict[str, Any]],
+) -> tuple[tuple[str, str], ...] | None:
+ signatures: set[tuple[tuple[str, str], ...]] = set()
+ for report in reports:
+ parameters = report.get("parameters")
+ overrides = (
+ parameters.get("config_overrides", {})
+ if isinstance(parameters, dict)
+ else {}
+ )
+ if not isinstance(overrides, dict):
+ return None
+ signatures.add(tuple(sorted(canonical_config_overrides(overrides).items())))
+ return next(iter(signatures)) if len(signatures) == 1 else None
+
+
+def report_parameter_values(reports: list[dict[str, Any]], key: str) -> list[str]:
+ """Return stable, deduplicated scalar/list values from retained JSON parameters."""
+ values: set[str] = set()
+ for report in reports:
+ parameters = report.get("parameters")
+ if not isinstance(parameters, dict):
+ continue
+ value = parameters.get(key)
+ items = value if isinstance(value, list) else [value]
+ values.update(
+ str(item)
+ for item in items
+ if isinstance(item, (str, int, float, bool)) and str(item)
+ )
+ return sorted(values)
+
+
+def report_parameter_sources(reports: list[dict[str, Any]]) -> list[dict[str, str]]:
+ """Deduplicate config provenance already carried by each auditable report input."""
+ records: dict[tuple[str, str, str], dict[str, str]] = {}
+ for report in reports:
+ parameters = report.get("parameters")
+ sources = (
+ parameters.get("parameter_sources")
+ if isinstance(parameters, dict)
+ else None
+ )
+ if not isinstance(sources, list):
+ continue
+ for source in sources:
+ if not isinstance(source, dict):
+ continue
+ record = {
+ "option": str(source.get("option") or "unspecified"),
+ "source": str(source.get("source") or "unreported"),
+ "macros": str(source.get("macros") or "unreported"),
+ }
+ records[(record["source"], record["option"], record["macros"])] = record
+ return [records[key] for key in sorted(records)]
+
+
+def quality_oracle_details(cases: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ details: list[dict[str, Any]] = []
+ for case_index, case in enumerate(cases, start=1):
+ scenario = str(case.get("scenario") or f"case {case_index}")
+ case_oracles = case.get("oracles")
+ if not isinstance(case_oracles, dict):
+ continue
+ for name, oracle in case_oracles.items():
+ if name == "quality" or not isinstance(oracle, dict):
+ continue
+ quality = oracle.get("quality")
+ if not isinstance(quality, dict):
+ continue
+ applicable = quality.get("applicable") is not False
+ passed = quality.get("passed")
+ rank = quality.get("rank")
+ returned = quality.get("returned_count")
+ if not applicable:
+ result = "N/A"
+ elif passed is True and isinstance(rank, int) and isinstance(returned, int):
+ result = f"PASS (rank {rank} of {returned})"
+ elif passed is True:
+ result = "PASS"
+ elif isinstance(rank, int) and isinstance(returned, int):
+ result = f"BELOW CUTOFF (rank {rank} of {returned})"
+ elif isinstance(returned, int):
+ result = f"FAIL (not found in {returned})"
+ else:
+ result = "FAIL"
+ details.append(
+ {
+ "scenario": scenario,
+ "oracle": str(name),
+ "criterion": str(quality.get("criterion") or "unspecified"),
+ "expected": str(quality.get("expected_substring") or "n/a"),
+ "result": result,
+ "reciprocal_rank": quality.get("reciprocal_rank"),
+ "hit_at_1": quality.get("hit_at_1"),
+ "hit_at_5": quality.get("hit_at_5"),
+ "ndcg_at_5": quality.get("ndcg_at_5"),
+ "judgments": (
+ f"{quality['relevance_judgments']} judgments"
+ if isinstance(quality.get("relevance_judgments"), int)
+ else "n/a"
+ ),
+ }
+ )
+ return details
+
+
+def rank_scorer_details(cases: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ """One row per persisted score, per case, from case["rank_score_probes"].
+
+ These rows are the head-to-head the tool-level oracles cannot give: search_graph
+ mixes candidate generation with ordering, whereas the probes read each score column
+ over the same graph. "degree" is present because PR #151 rejected PageRank on the
+ grounds that ORDER BY degree DESC "gives you the same ranking signal"; spearman_rho
+ and top_k_jaccard are what test that claim, and leaf_hub_rate is what describes
+ the accompanying claim that PageRank merely surfaces utility popularity.
+ """
+ details: list[dict[str, Any]] = []
+ for case_index, case in enumerate(cases, start=1):
+ probes = case.get("rank_score_probes")
+ if not isinstance(probes, dict) or not probes.get("available"):
+ continue
+ scenario = str(case.get("scenario") or f"case {case_index}")
+ corpus = case.get("corpus")
+ # Never invent a corpus id: a run driven by --quality-background-repo without
+ # --corpus has no registry entry, and labelling it "synthetic-rank-v1" would
+ # misattribute real-corpus numbers to the synthetic fixture.
+ corpus_id = str(corpus.get("id")) if isinstance(corpus, dict) else "n/a"
+ staleness = case.get("rank_score_staleness")
+ rank_views_fresh = (
+ staleness.get("rank_views_fresh") if isinstance(staleness, dict) else None
+ )
+ scorers = probes.get("scorers")
+ comparisons = probes.get("comparisons") or {}
+ if not isinstance(scorers, dict):
+ continue
+ for name, entry in scorers.items():
+ if not isinstance(entry, dict):
+ continue
+ comparison = comparisons.get(f"{name}_vs_degree") or {}
+ common = {
+ "scenario": scenario,
+ "corpus": corpus_id,
+ "scorer": str(name),
+ "spearman_rho": comparison.get("spearman_rho"),
+ "top_k_jaccard": comparison.get("top_k_jaccard"),
+ "elapsed_ms": entry.get("elapsed_ms"),
+ "rank_views_fresh": rank_views_fresh,
+ }
+ if not entry.get("applicable"):
+ details.append(
+ {
+ **common,
+ "status": f"N/A ({entry.get('reason', 'unavailable')})",
+ "top_symbol": "n/a",
+ "cutoff": "n/a",
+ "leaf_hub_rate": None,
+ "scaffolding": None,
+ }
+ )
+ continue
+ top = entry.get("top_ranked") or []
+ top_symbol = str(top[0].get("qualified_name")) if top else "n/a"
+ # One row per cutoff, read from whatever cutoffs the producer emitted.
+ # Hardcoding "10"/"40" here would silently render an all-n/a table the
+ # moment run_rank_score_probes is called with different cutoffs.
+ by_cutoff = entry.get("by_cutoff") or {}
+ for cutoff in sorted(by_cutoff, key=lambda value: int(value)):
+ metrics = by_cutoff[cutoff] or {}
+ details.append(
+ {
+ **common,
+ "status": f"ranked {entry.get('ranked_count')}",
+ "top_symbol": top_symbol,
+ "cutoff": cutoff,
+ # utility_contamination is the pre-rename spelling; read both
+ # so runsets recorded before the rename still render.
+ "leaf_hub_rate": metrics.get(
+ "leaf_hub_rate", metrics.get("utility_contamination")
+ ),
+ "scaffolding": metrics.get("scaffolding"),
+ }
+ )
+ return details
+
+
+def compact_witness(value: Any, limit: int = 96) -> str:
+ if not isinstance(value, str) or not value:
+ return ""
+ single_line = " ".join(value.split())
+ return single_line if len(single_line) <= limit else single_line[: limit - 1] + "…"
+
+
+def canonical_mismatch_finding(
+ canonical: Any,
+ *,
+ graph_gate: Any = None,
+) -> str | None:
+ if not isinstance(canonical, dict) or canonical.get("equal") is not False:
+ return None
+ kind = canonical.get("kind") or "canonical graph"
+ detail = (
+ f"{kind} mismatch (incremental={canonical.get('left_count', 'n/a')}, "
+ f"fresh={canonical.get('right_count', 'n/a')})"
+ )
+ witnesses = [
+ compact_witness(canonical.get("left_only")),
+ compact_witness(canonical.get("right_only")),
+ ]
+ witnesses = [value for value in witnesses if value]
+ if witnesses:
+ detail += "; witness: " + " vs ".join(witnesses)
+ if (
+ isinstance(graph_gate, dict)
+ and graph_gate.get("policy") == "declared_stale_derived_views"
+ and graph_gate.get("passed") is True
+ ):
+ views = graph_gate.get("declared_stale_views")
+ view_text = (
+ ", ".join(str(value) for value in views)
+ if isinstance(views, list)
+ else "unknown"
+ )
+ detail = f"declared stale derived views ({view_text}); " + detail
+ return detail
+
+
+def correctness_findings(
+ cases: list[dict[str, Any]],
+ *,
+ capability_quality: bool = False,
+ disabled_pair_capabilities: set[str] | None = None,
+) -> list[str]:
+ findings: list[str] = []
+ disabled_pair_capabilities = disabled_pair_capabilities or set()
+ for case in cases:
+ canonical = case.get("canonical_graph")
+ detail = canonical_mismatch_finding(
+ canonical,
+ graph_gate=case.get("graph_gate"),
+ )
+ if detail:
+ findings.append(detail)
+
+ case_oracles = case.get("oracles")
+ if isinstance(case_oracles, dict):
+ for name, oracle in case_oracles.items():
+ if not isinstance(oracle, dict) or name == "quality":
+ continue
+ quality = oracle.get("quality")
+ if isinstance(quality, dict) and quality.get("passed") is False:
+ expected = compact_witness(quality.get("expected_substring"))
+ rank = quality.get("rank")
+ cutoff = quality.get("relevance_cutoff")
+ if (
+ capability_quality
+ and isinstance(rank, int)
+ and isinstance(cutoff, int)
+ ):
+ finding = f"{name} below quality cutoff (rank {rank}, cutoff {cutoff})"
+ elif capability_quality:
+ finding = f"{name} did not meet the quality target"
+ else:
+ finding = f"{name} failed"
+ if expected:
+ finding += f" (expected {expected})"
+ findings.append(finding)
+
+ lifecycle = case.get("pair_lifecycle")
+ fixture = case.get("fixture")
+ capability = (
+ str(fixture.get("capability") or "") if isinstance(fixture, dict) else ""
+ )
+ if not isinstance(lifecycle, dict) or capability in disabled_pair_capabilities:
+ continue
+ lifecycle_canonical = lifecycle.get("canonical_graph")
+ if lifecycle_canonical is not canonical:
+ detail = canonical_mismatch_finding(lifecycle_canonical)
+ if detail:
+ findings.append(detail)
+ policy = lifecycle.get("incremental_policy")
+ immediate_expected = (
+ isinstance(policy, dict)
+ and policy.get("immediate_freshness_expected") is True
+ )
+ for stage, key, required in (
+ ("Initial", "initial_oracles", True),
+ ("Post-edit", "incremental_oracles", immediate_expected),
+ ("Fresh", "fresh_oracles", True),
+ ):
+ oracle = lifecycle.get(key)
+ if (
+ not required
+ or not isinstance(oracle, dict)
+ or oracle.get("passed") is not False
+ ):
+ continue
+ classification = oracle.get("pair_classification")
+ confusion = (
+ classification.get("confusion")
+ if isinstance(classification, dict)
+ else None
+ )
+ finding = f"{stage} semantic-pair quality missed the declared target"
+ if isinstance(confusion, dict):
+ tp = int(confusion.get("tp") or 0)
+ tn = int(confusion.get("tn") or 0)
+ fp = int(confusion.get("fp") or 0)
+ fn = int(confusion.get("fn") or 0)
+ finding += f": TP={tp}, TN={tn}, FP={fp}, FN={fn}"
+ consequences = []
+ if fn:
+ consequences.append(f"{fn} expected positive absent")
+ if fp:
+ consequences.append(f"{fp} unexpected positive present")
+ if consequences:
+ finding += " (" + ", ".join(consequences) + ")"
+ findings.append(finding)
+ return list(dict.fromkeys(findings))
+
+
+def mutation_reindex_details(
+ cases: list[dict[str, Any]],
+ *,
+ disabled_pair_capabilities: set[str] | None = None,
+) -> list[dict[str, Any]]:
+ """Aggregate repeated measurements without hiding the mutated source or publish route."""
+ disabled_pair_capabilities = disabled_pair_capabilities or set()
+ grouped: dict[str, dict[str, Any]] = {}
+ for case_index, case in enumerate(cases, start=1):
+ scenario = str(case.get("scenario") or f"case {case_index}")
+ group = grouped.setdefault(
+ scenario,
+ {
+ "descriptions": set(),
+ "changed_paths": set(),
+ "routes": set(),
+ "reasons": set(),
+ "incremental_ms": [],
+ "work_ms": [],
+ "full_ms": [],
+ "speedups": [],
+ "canonical": [],
+ },
+ )
+ lifecycle = case.get("pair_lifecycle")
+ lifecycle = lifecycle if isinstance(lifecycle, dict) else {}
+ mutation = lifecycle.get("mutation", case.get("mutation"))
+ if isinstance(mutation, dict):
+ description = mutation.get("description")
+ if isinstance(description, str) and description:
+ group["descriptions"].add(description)
+ changed_paths = mutation.get("changed_paths")
+ if isinstance(changed_paths, list):
+ group["changed_paths"].update(
+ str(path)
+ for path in changed_paths
+ if isinstance(path, str) and path
+ )
+ # Matrix artifacts predate the self-dogfood mutation object and retain
+ # their changed paths at the case root. Consume both schemas so an
+ # auditable path is never rendered as "not reported".
+ case_changed_paths = case.get("changed_paths")
+ if isinstance(case_changed_paths, list):
+ group["changed_paths"].update(
+ str(path)
+ for path in case_changed_paths
+ if isinstance(path, str) and path
+ )
+ scenario_metadata = case.get("scenario_metadata")
+ if (
+ not group["descriptions"]
+ and isinstance(scenario_metadata, dict)
+ and scenario_metadata.get("source") == "synthetic_inbound_frontier"
+ ):
+ language = scenario_metadata.get("cross_file_resolver_language")
+ if not isinstance(language, str) or not language:
+ language = scenario_metadata.get("language")
+ if isinstance(language, str) and language:
+ group["descriptions"].add(
+ f"synthetic {language} inbound-frontier definition edit"
+ )
+ incremental = lifecycle.get("incremental_index", case.get("incremental"))
+ if isinstance(incremental, dict):
+ if isinstance(incremental.get("elapsed_ms"), (int, float)):
+ group["incremental_ms"].append(float(incremental["elapsed_ms"]))
+ if isinstance(incremental.get("indexed_work_elapsed_ms"), (int, float)):
+ group["work_ms"].append(float(incremental["indexed_work_elapsed_ms"]))
+ route = incremental.get("publish_kind")
+ if isinstance(route, str) and route:
+ group["routes"].add(route)
+ reason = incremental.get("exact_reason")
+ if isinstance(reason, str) and reason:
+ group["reasons"].add(reason)
+ full = lifecycle.get("fresh_index", case.get("fresh_fast_full_after_change"))
+ if isinstance(full, dict) and isinstance(full.get("elapsed_ms"), (int, float)):
+ group["full_ms"].append(float(full["elapsed_ms"]))
+ speedup = case.get("speedup_full_rebuild_over_incremental")
+ if isinstance(speedup, (int, float)):
+ group["speedups"].append(float(speedup))
+ canonical = lifecycle.get("canonical_graph", case.get("canonical_graph"))
+ if isinstance(canonical, dict) and isinstance(canonical.get("equal"), bool):
+ group["canonical"].append(canonical["equal"])
+ fixture = case.get("fixture")
+ capability = (
+ str(fixture.get("capability") or "") if isinstance(fixture, dict) else ""
+ )
+ policy = lifecycle.get("incremental_policy")
+ if capability in disabled_pair_capabilities:
+ group["canonical_policy"] = "capability disabled"
+ elif (
+ isinstance(policy, dict)
+ and policy.get("immediate_freshness_expected") is False
+ and policy.get("policy_conformance_met") is True
+ and policy.get("stale_warning_present") is True
+ ):
+ group["canonical_policy"] = "deferred with warning"
+
+ details: list[dict[str, Any]] = []
+ for scenario, group in grouped.items():
+ routes = sorted(group["routes"])
+ reasons = sorted(group["reasons"])
+ route = ", ".join(routes) if routes else "not reported"
+ if reasons:
+ route += " (" + ", ".join(reasons) + ")"
+ canonical = group["canonical"]
+ details.append(
+ {
+ "scenario": scenario,
+ "mutation": "; ".join(sorted(group["descriptions"])) or "not reported",
+ "changed_paths": ", ".join(sorted(group["changed_paths"]))
+ or "not reported",
+ "publication": route,
+ "incremental_p50_ms": percentile(group["incremental_ms"], 0.50),
+ "work_p50_ms": percentile(group["work_ms"], 0.50),
+ "full_p50_ms": percentile(group["full_ms"], 0.50),
+ "speedup_p50": (
+ float(statistics.median(group["speedups"]))
+ if group["speedups"]
+ else None
+ ),
+ "canonical": group.get("canonical_policy")
+ or ratio(sum(canonical), len(canonical)),
+ }
+ )
+ return details
+
+
+def marker_int(lines: Any, marker: str, field: str) -> int | None:
+ if not isinstance(lines, list):
+ return None
+ prefix = f"{field}="
+ for line in lines:
+ if not isinstance(line, str) or marker not in line:
+ continue
+ for item in line.split():
+ if item.startswith(prefix):
+ try:
+ return int(item.split("=", 1)[1])
+ except ValueError:
+ return None
+ return None
+
+
+def dependency_observation(index_result: Any) -> tuple[int | None, int | None]:
+ """Read dependency cost/count from current and retained benchmark result shapes."""
+ if not isinstance(index_result, dict):
+ return None, None
+ dependency = index_result.get("dependency_indexing")
+ phase_ms = None
+ packages = None
+ if isinstance(dependency, dict):
+ raw_phase = dependency.get("phase_elapsed_ms")
+ raw_packages = dependency.get("packages_indexed")
+ phase_ms = int(raw_phase) if isinstance(raw_phase, (int, float)) else None
+ packages = int(raw_packages) if isinstance(raw_packages, (int, float)) else None
+ if phase_ms is None:
+ phase_ms = marker_int(
+ index_result.get("measurement_log_markers"), "sub=dep_auto_index", "ms"
+ )
+ response = index_result.get("response")
+ if packages is None and isinstance(response, dict):
+ raw_packages = response.get("dependencies_indexed")
+ packages = int(raw_packages) if isinstance(raw_packages, (int, float)) else None
+ return phase_ms, packages
+
+
+def dependency_mode(
+ reports: list[dict[str, Any]], observed_packages: list[float]
+) -> str:
+ support: set[bool] = set()
+ overrides: set[str] = set()
+ for report in reports:
+ parameters = report.get("parameters")
+ if not isinstance(parameters, dict):
+ continue
+ capability_support = parameters.get("capability_support")
+ if isinstance(capability_support, dict):
+ raw_support = capability_support.get(
+ "dependencies", capability_support.get("auto_index_deps")
+ )
+ if isinstance(raw_support, bool):
+ support.add(raw_support)
+ config = parameters.get("config_overrides")
+ if isinstance(config, dict) and "auto_index_deps" in config:
+ overrides.add(str(config["auto_index_deps"]).lower())
+ if support == {False}:
+ return "unsupported"
+ if overrides and overrides <= {"false", "0", "off"}:
+ return "disabled (explicit)"
+ if overrides and overrides <= {"true", "1", "on"}:
+ return "enabled (explicit)"
+ if observed_packages and max(observed_packages) > 0:
+ return "enabled (observed)"
+ return "unknown"
+
+
+ALGORITHM_CAPABILITIES = (
+ "rank",
+ "similarity",
+ "semantic_edges",
+ "git_history",
+ "http_links",
+ "dependencies",
+)
+
+
+def summarize_capability_applicability(
+ reports: list[dict[str, Any]],
+) -> dict[str, str]:
+ summarized: dict[str, str] = {}
+ for capability in ALGORITHM_CAPABILITIES:
+ states: set[tuple[bool, str]] = set()
+ support: set[bool] = set()
+ for report in reports:
+ parameters = report.get("parameters")
+ capability_support = (
+ parameters.get("capability_support")
+ if isinstance(parameters, dict)
+ else None
+ )
+ if isinstance(capability_support, dict) and isinstance(
+ capability_support.get(capability), bool
+ ):
+ support.add(capability_support[capability])
+ applicability = (
+ parameters.get("capability_applicability")
+ if isinstance(parameters, dict)
+ else None
+ )
+ state = (
+ applicability.get(capability)
+ if isinstance(applicability, dict)
+ else None
+ )
+ if isinstance(state, dict) and isinstance(state.get("applicable"), bool):
+ states.add(
+ (state["applicable"], str(state.get("reason") or "unspecified"))
+ )
+ if support == {False}:
+ summarized[capability] = "unsupported by candidate"
+ elif len(support) > 1:
+ summarized[capability] = "mixed support"
+ elif not states:
+ summarized[capability] = "unknown"
+ elif len(states) > 1:
+ summarized[capability] = "mixed"
+ else:
+ applicable, reason = next(iter(states))
+ summarized[capability] = "applicable" if applicable else f"N/A: {reason}"
+ return summarized
+
+
+def quality_miss_is_explicit_ablation(
+ report: dict[str, Any], case: dict[str, Any]
+) -> bool:
+ fixture = case.get("fixture")
+ capability = fixture.get("capability") if isinstance(fixture, dict) else None
+ parameters = report.get("parameters")
+ overrides = (
+ parameters.get("config_overrides") if isinstance(parameters, dict) else None
+ )
+ if not isinstance(overrides, dict):
+ return False
+ key = "rank_enabled" if capability == "rank" else "auto_index_deps"
+ if capability not in {"rank", "dependencies"}:
+ return False
+ value = overrides.get(key)
+ return value is False or (isinstance(value, str) and value.lower() == "false")
+
+
+def semantic_pair_classification(
+ lifecycle: dict[str, Any], stage: str
+) -> tuple[dict[str, int] | None, float | None]:
+ """Return one lifecycle stage's confusion matrix and F1 score."""
+ oracles = lifecycle.get(f"{stage}_oracles")
+ pair = oracles.get("pair_classification") if isinstance(oracles, dict) else None
+ confusion = pair.get("confusion") if isinstance(pair, dict) else None
+ f1 = pair.get("f1") if isinstance(pair, dict) else None
+ return (
+ confusion if isinstance(confusion, dict) else None,
+ float(f1) if isinstance(f1, (int, float)) else None,
+ )
+
+
+def semantic_pair_quality_details(cases: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ details: list[dict[str, Any]] = []
+ for case in cases:
+ lifecycle = case.get("pair_lifecycle")
+ fixture = case.get("fixture")
+ if not isinstance(lifecycle, dict) or not isinstance(fixture, dict):
+ continue
+ policy = lifecycle.get("incremental_policy")
+ policy = policy if isinstance(policy, dict) else {}
+
+ initial_confusion, initial_f1 = semantic_pair_classification(
+ lifecycle, "initial"
+ )
+ incremental_confusion, incremental_f1 = semantic_pair_classification(
+ lifecycle, "incremental"
+ )
+ fresh_confusion, fresh_f1 = semantic_pair_classification(lifecycle, "fresh")
+ if policy.get("immediate_freshness_met") is True:
+ freshness = "fresh and canonical"
+ elif (
+ policy.get("immediate_freshness_expected") is False
+ and policy.get("stale_warning_present") is True
+ ):
+ freshness = "deferred with warning"
+ else:
+ freshness = "unexpected stale or non-canonical"
+ background = case.get("background_repository")
+ freshness_policy = policy.get("policy")
+ if isinstance(freshness_policy, str):
+ freshness_policy = canonical_config_override(
+ "incremental_derived_results_refresh", freshness_policy
+ )[1]
+ details.append(
+ {
+ "capability": fixture.get("capability"),
+ "relationship": fixture.get("relationship"),
+ "task_sha256": fixture.get("task_set_sha256"),
+ "background_revision": (
+ background.get("revision") if isinstance(background, dict) else None
+ ),
+ "background_tree": (
+ background.get("tree") if isinstance(background, dict) else None
+ ),
+ "initial_confusion": initial_confusion,
+ "initial_f1": initial_f1,
+ "incremental_confusion": incremental_confusion,
+ "incremental_f1": incremental_f1,
+ "fresh_confusion": fresh_confusion,
+ "fresh_f1": fresh_f1,
+ "freshness_policy": freshness_policy,
+ "freshness": freshness,
+ "policy_conformance_met": policy.get("policy_conformance_met"),
+ "immediate_freshness_expected": policy.get(
+ "immediate_freshness_expected"
+ ),
+ "immediate_freshness_met": policy.get("immediate_freshness_met"),
+ }
+ )
+ return details
+
+
+def summarize_group(label: str, reports: list[dict[str, Any]]) -> dict[str, Any]:
+ canonical_label = canonical_experiment_label(label)
+ cases = [case for report in reports for case in cases_from_report(report)]
+ report_modes = {str(report.get("mode") or "") for report in reports}
+ capability_quality = report_modes == {"capability_quality"}
+ canonical: list[bool] = []
+ core_graph: list[bool] = []
+ for case in cases:
+ canonical_graph = case.get("canonical_graph")
+ if isinstance(canonical_graph, dict):
+ canonical_equal = bool(canonical_graph.get("equal"))
+ canonical.append(canonical_equal)
+ graph_gate = case.get("graph_gate")
+ core_graph.append(
+ bool(graph_gate.get("passed"))
+ if isinstance(graph_gate, dict)
+ and isinstance(graph_gate.get("passed"), bool)
+ else canonical_equal
+ )
+ continue
+ lifecycle = case.get("pair_lifecycle")
+ if not isinstance(lifecycle, dict):
+ continue
+ policy = lifecycle.get("incremental_policy")
+ lifecycle_graph = lifecycle.get("canonical_graph")
+ if (
+ isinstance(policy, dict)
+ and policy.get("immediate_freshness_expected") is True
+ and isinstance(lifecycle_graph, dict)
+ ):
+ lifecycle_equal = bool(lifecycle_graph.get("equal"))
+ canonical.append(lifecycle_equal)
+ core_graph.append(lifecycle_equal)
+ oracles: list[bool] = []
+ quality_miss_ablation_states: list[bool] = []
+ for report in reports:
+ for case in cases_from_report(report):
+ case_oracles = case.get("oracles")
+ if not isinstance(case_oracles, dict):
+ continue
+ verdict = case_oracles.get("passed")
+ if not isinstance(verdict, bool):
+ quality = case_oracles.get("quality")
+ verdict = quality.get("passed") if isinstance(quality, dict) else None
+ if isinstance(verdict, bool):
+ oracles.append(verdict)
+ if verdict is False and case.get("quality_target_met") is False:
+ quality_miss_ablation_states.append(
+ quality_miss_is_explicit_ablation(report, case)
+ )
+ pair_quality_details = semantic_pair_quality_details(cases)
+ rank_details = rank_scorer_details(cases)
+ signature = config_signature(reports)
+ override_map = dict(signature) if signature is not None else {}
+ capability_config_keys = {
+ "similarity": "similarity_enabled",
+ "semantic_edges": "semantic_edges_enabled",
+ }
+ for detail in pair_quality_details:
+ config_key = capability_config_keys.get(str(detail.get("capability")))
+ configured = override_map.get(config_key) if config_key else None
+ if isinstance(configured, str) and configured.lower() == "false":
+ detail["capability_state"] = "disabled"
+ detail["freshness"] = "capability disabled"
+ else:
+ detail["capability_state"] = "enabled or default"
+ case_passes: list[bool] = []
+ for case in cases:
+ lifecycle = case.get("pair_lifecycle")
+ if isinstance(lifecycle, dict):
+ policy = lifecycle.get("incremental_policy")
+ policy = policy if isinstance(policy, dict) else {}
+ initial_oracles = lifecycle.get("initial_oracles")
+ incremental_oracles = lifecycle.get("incremental_oracles")
+ fresh_oracles = lifecycle.get("fresh_oracles")
+ passed = bool(
+ isinstance(initial_oracles, dict)
+ and initial_oracles.get("passed")
+ and isinstance(fresh_oracles, dict)
+ and fresh_oracles.get("passed")
+ and policy.get("policy_conformance_met")
+ )
+ if policy.get("immediate_freshness_expected") is True:
+ passed = passed and bool(
+ isinstance(incremental_oracles, dict)
+ and incremental_oracles.get("passed")
+ )
+ case_passes.append(passed)
+ elif capability_quality and isinstance(case.get("quality_target_met"), bool):
+ case_passes.append(bool(case.get("quality_target_met")))
+ else:
+ case_passes.append(bool(case.get("passed")))
+ incremental_ms: list[float] = []
+ incremental_work_ms: list[float] = []
+ incremental_peak_rss: list[float] = []
+ initial_full_ms: list[float] = []
+ full_ms: list[float] = []
+ speedups: list[float] = []
+ peak_rss: list[int] = []
+ query_latency_ms: list[float] = []
+ attempt_elapsed_seconds: list[float] = []
+ cold_query_latency_ms: list[float] = []
+ query_response_bytes: list[float] = []
+ query_response_tokens: list[float] = []
+ quality_passed = 0
+ quality_applicable = 0
+ quality_score_weighted = 0.0
+ quality_score_count = 0
+ hit_at_1_weighted = 0.0
+ hit_at_5_weighted = 0.0
+ ndcg_weighted = 0.0
+ ndcg_count = 0
+ dependency_initial_ms: list[float] = []
+ dependency_incremental_ms: list[float] = []
+ dependency_fresh_ms: list[float] = []
+ dependency_packages: list[float] = []
+ for report in reports:
+ provenance = report.get("experiment_provenance")
+ attempt = provenance.get("attempt") if isinstance(provenance, dict) else None
+ elapsed = attempt.get("elapsed_seconds") if isinstance(attempt, dict) else None
+ if isinstance(elapsed, (int, float)):
+ attempt_elapsed_seconds.append(float(elapsed))
+ for case in cases:
+ lifecycle = case.get("pair_lifecycle")
+ if isinstance(lifecycle, dict):
+ initial = lifecycle.get("initial_index", {})
+ incremental = lifecycle.get("incremental_index", {})
+ full = lifecycle.get("fresh_index", {})
+ relation_oracles = [
+ lifecycle.get("initial_oracles"),
+ lifecycle.get("incremental_oracles"),
+ lifecycle.get("fresh_oracles"),
+ ]
+ else:
+ initial = case.get("initial_fast_full", {})
+ incremental = case.get("incremental", {})
+ full = case.get("fresh_fast_full_after_change", {})
+ relation_oracles = []
+ if isinstance(initial, dict):
+ if isinstance(initial.get("elapsed_ms"), (int, float)):
+ initial_full_ms.append(float(initial["elapsed_ms"]))
+ if isinstance(initial.get("peak_rss_mb"), (int, float)):
+ peak_rss.append(int(initial["peak_rss_mb"]))
+ if isinstance(incremental, dict):
+ if isinstance(incremental.get("elapsed_ms"), (int, float)):
+ incremental_ms.append(float(incremental["elapsed_ms"]))
+ if isinstance(incremental.get("indexed_work_elapsed_ms"), (int, float)):
+ incremental_work_ms.append(
+ float(incremental["indexed_work_elapsed_ms"])
+ )
+ if isinstance(incremental.get("peak_rss_mb"), (int, float)):
+ incremental_peak_rss.append(float(incremental["peak_rss_mb"]))
+ peak_rss.append(int(incremental["peak_rss_mb"]))
+ if isinstance(full, dict):
+ if isinstance(full.get("elapsed_ms"), (int, float)):
+ full_ms.append(float(full["elapsed_ms"]))
+ if isinstance(full.get("peak_rss_mb"), int):
+ peak_rss.append(full["peak_rss_mb"])
+ if isinstance(case.get("speedup_full_rebuild_over_incremental"), (int, float)):
+ speedups.append(float(case["speedup_full_rebuild_over_incremental"]))
+ elif (
+ (
+ not isinstance(lifecycle, dict)
+ or isinstance(lifecycle.get("incremental_policy"), dict)
+ and lifecycle["incremental_policy"].get("immediate_freshness_met")
+ is True
+ )
+ and isinstance(full, dict)
+ and isinstance(full.get("elapsed_ms"), (int, float))
+ and isinstance(incremental, dict)
+ and isinstance(incremental.get("elapsed_ms"), (int, float))
+ and float(incremental["elapsed_ms"]) > 0
+ ):
+ speedups.append(
+ float(full["elapsed_ms"]) / float(incremental["elapsed_ms"])
+ )
+ for index_result, timings in (
+ (initial, dependency_initial_ms),
+ (incremental, dependency_incremental_ms),
+ (full, dependency_fresh_ms),
+ ):
+ phase_ms, packages = dependency_observation(index_result)
+ if phase_ms is not None:
+ timings.append(float(phase_ms))
+ if packages is not None:
+ dependency_packages.append(float(packages))
+ case_oracles = case.get("oracles", {})
+ if isinstance(case_oracles, dict) and not isinstance(lifecycle, dict):
+ quality = case_oracles.get("quality", {})
+ if isinstance(quality, dict):
+ applicable = int(quality.get("applicable_count") or 0)
+ quality_passed += int(quality.get("passed_count") or 0)
+ quality_applicable += applicable
+ score = quality.get("score")
+ hit_at_1 = quality.get("hit_at_1")
+ hit_at_5 = quality.get("hit_at_5")
+ mean_ndcg_at_5 = quality.get("mean_ndcg_at_5")
+ ndcg_applicable = int(quality.get("ndcg_applicable_count") or 0)
+ if applicable and isinstance(score, (int, float)):
+ quality_score_weighted += float(score) * applicable
+ quality_score_count += applicable
+ if applicable and isinstance(hit_at_1, (int, float)):
+ hit_at_1_weighted += float(hit_at_1) * applicable
+ if applicable and isinstance(hit_at_5, (int, float)):
+ hit_at_5_weighted += float(hit_at_5) * applicable
+ if ndcg_applicable and isinstance(mean_ndcg_at_5, (int, float)):
+ ndcg_weighted += float(mean_ndcg_at_5) * ndcg_applicable
+ ndcg_count += ndcg_applicable
+ for oracle in case_oracles.values():
+ if not isinstance(oracle, dict):
+ continue
+ if isinstance(oracle.get("elapsed_ms"), (int, float)):
+ cold_query_latency_ms.append(float(oracle["elapsed_ms"]))
+ repeated_elapsed = repeated_query_elapsed_ms(oracle)
+ if repeated_elapsed is not None:
+ query_latency_ms.append(repeated_elapsed)
+ if isinstance(oracle.get("response_bytes"), (int, float)):
+ query_response_bytes.append(float(oracle["response_bytes"]))
+ if isinstance(oracle.get("response_token_estimate"), (int, float)):
+ query_response_tokens.append(
+ float(oracle["response_token_estimate"])
+ )
+ for relation in relation_oracles:
+ response_quality = (
+ relation.get("response_quality") if isinstance(relation, dict) else None
+ )
+ if not isinstance(response_quality, dict):
+ continue
+ if isinstance(response_quality.get("elapsed_ms"), (int, float)):
+ cold_query_latency_ms.append(float(response_quality["elapsed_ms"]))
+ repeated_elapsed = repeated_query_elapsed_ms(response_quality)
+ if repeated_elapsed is not None:
+ query_latency_ms.append(repeated_elapsed)
+ if isinstance(response_quality.get("response_bytes"), (int, float)):
+ query_response_bytes.append(float(response_quality["response_bytes"]))
+ if isinstance(
+ response_quality.get("response_token_estimate"), (int, float)
+ ):
+ query_response_tokens.append(
+ float(response_quality["response_token_estimate"])
+ )
+
+ canonical_failed = any(not value for value in core_graph)
+ oracle_target_missed = any(not value for value in oracles)
+ required_pair_stage_missed = False
+ for case in cases:
+ lifecycle = case.get("pair_lifecycle")
+ if not isinstance(lifecycle, dict):
+ continue
+ policy = lifecycle.get("incremental_policy")
+ immediate_expected = (
+ isinstance(policy, dict)
+ and policy.get("immediate_freshness_expected") is True
+ )
+ required = [lifecycle.get("initial_oracles"), lifecycle.get("fresh_oracles")]
+ if immediate_expected:
+ required.append(lifecycle.get("incremental_oracles"))
+ if any(
+ isinstance(oracle, dict) and oracle.get("passed") is False
+ for oracle in required
+ ):
+ required_pair_stage_missed = True
+ break
+ quality_target_missed = oracle_target_missed or required_pair_stage_missed
+ result_oracle_failed = any(
+ isinstance((case_oracles := case.get("oracles")), dict)
+ and any(
+ isinstance(oracle, dict)
+ and isinstance((quality := oracle.get("quality")), dict)
+ and quality.get("passed") is False
+ for name, oracle in case_oracles.items()
+ if name != "quality"
+ )
+ for case in cases
+ )
+ missed_oracle_count = sum(1 for value in oracles if not value)
+ explicit_ablation_miss = (
+ bool(quality_miss_ablation_states)
+ and len(quality_miss_ablation_states) == missed_oracle_count
+ and all(quality_miss_ablation_states)
+ )
+ deferred_freshness = any(
+ detail["freshness"] == "deferred with warning"
+ for detail in pair_quality_details
+ )
+ declared_stale_views = any(
+ isinstance((gate := case.get("graph_gate")), dict)
+ and gate.get("policy") == "declared_stale_derived_views"
+ and gate.get("passed") is True
+ and not (
+ isinstance((canonical_graph := case.get("canonical_graph")), dict)
+ and canonical_graph.get("equal") is True
+ )
+ for case in cases
+ )
+ freshness_policy_failed = any(
+ detail.get("policy_conformance_met") is False
+ for detail in pair_quality_details
+ if detail.get("capability_state") != "disabled"
+ )
+ cleanup_failed = any(
+ isinstance((cleanup := report.get("cleanup")), dict)
+ and cleanup.get("requested") is True
+ and cleanup.get("removed") is not True
+ for report in reports
+ )
+ if canonical_failed:
+ decision = "REJECT: graph correctness"
+ elif freshness_policy_failed:
+ decision = "REJECT: freshness policy"
+ elif cleanup_failed:
+ decision = "REJECT: lifecycle cleanup"
+ elif quality_target_missed and (capability_quality or explicit_ablation_miss):
+ decision = "BELOW QUALITY TARGET"
+ elif quality_target_missed:
+ decision = "REJECT: task correctness"
+ elif case_passes and not all(case_passes) and not capability_quality:
+ decision = "REJECT: benchmark gate"
+ elif not cases:
+ decision = "REJECT: no cases"
+ elif declared_stale_views:
+ decision = "PASS: DECLARED STALE VIEWS"
+ elif deferred_freshness:
+ decision = "PASS: DEFERRED FRESHNESS"
+ else:
+ decision = "PASS"
+
+ hashes = sorted(
+ {
+ str(report.get("binary_metadata", {}).get("sha256", ""))
+ for report in reports
+ if isinstance(report.get("binary_metadata"), dict)
+ and report.get("binary_metadata", {}).get("sha256")
+ }
+ )
+ pair_f1_values = [
+ value
+ for detail in pair_quality_details
+ for value in (detail.get("initial_f1"), detail.get("fresh_f1"))
+ if isinstance(value, (int, float))
+ ]
+ retrieval_score = (
+ quality_score_weighted / quality_score_count
+ if quality_score_count
+ else quality_passed / quality_applicable
+ if quality_applicable
+ else None
+ )
+ pair_f1_score = statistics.mean(pair_f1_values) if pair_f1_values else None
+ graph_fidelity_score = sum(canonical) / len(canonical) if canonical else None
+ core_graph_fidelity_score = (
+ sum(core_graph) / len(core_graph) if core_graph else None
+ )
+ task_success_score = (
+ quality_passed / quality_applicable
+ if quality_applicable
+ else sum(oracles) / len(oracles)
+ if oracles
+ else None
+ )
+ result_quality_values = [
+ value
+ for value in (retrieval_score, pair_f1_score)
+ if isinstance(value, (int, float))
+ ]
+ result_quality_score = (
+ statistics.mean(result_quality_values) if result_quality_values else None
+ )
+ quality_categories = (
+ result_quality_score,
+ graph_fidelity_score,
+ task_success_score,
+ )
+ overall_quality_score = (
+ math.prod(quality_categories) ** (1.0 / len(quality_categories))
+ if all(isinstance(value, (int, float)) for value in quality_categories)
+ else None
+ )
+ scenarios = {str(case.get("scenario")) for case in cases if case.get("scenario")}
+ workload_backgrounds: set[str] = set()
+ workload_tasks: set[str] = set()
+ for report in reports:
+ parameters = report.get("parameters")
+ if isinstance(parameters, dict):
+ for key in ("repository_background", "quality_background"):
+ background = parameters.get(key)
+ if isinstance(background, dict):
+ workload_backgrounds.add(
+ json.dumps(background, separators=(",", ":"), sort_keys=True)
+ )
+ for case in cases:
+ background = case.get("background_repository")
+ if isinstance(background, dict):
+ workload_backgrounds.add(
+ json.dumps(background, separators=(",", ":"), sort_keys=True)
+ )
+ fixture = case.get("fixture")
+ if isinstance(fixture, dict) and fixture.get("task_set_sha256"):
+ workload_tasks.add(str(fixture["task_set_sha256"]))
+ contracts = {
+ str(gate.get("contract"))
+ for case in cases
+ if isinstance((gate := case.get("frontier_coverage_gate")), dict)
+ and gate.get("contract")
+ }
+ frontier_files = {
+ parameters.get("frontier_files")
+ for report in reports
+ if isinstance((parameters := report.get("parameters")), dict)
+ and isinstance(parameters.get("frontier_files"), int)
+ }
+ exact_caps: set[int] = set()
+ index_modes = {
+ str(parameters.get("index_mode"))
+ for report in reports
+ if isinstance((parameters := report.get("parameters")), dict)
+ and parameters.get("index_mode")
+ }
+ execution_orders = {
+ str(parameters.get("execution_order") or "grouped")
+ for report in reports
+ if isinstance((parameters := report.get("parameters")), dict)
+ }
+ for report in reports:
+ parameters = report.get("parameters")
+ if not isinstance(parameters, dict):
+ continue
+ overrides = parameters.get("config_overrides")
+ if not isinstance(overrides, dict):
+ continue
+ raw_cap = overrides.get("incremental_exact_max_affected_paths")
+ with suppress(TypeError, ValueError):
+ exact_caps.add(int(raw_cap))
+ full_values = full_ms or initial_full_ms
+ disabled_pair_capabilities = {
+ str(detail.get("capability"))
+ for detail in pair_quality_details
+ if detail.get("capability_state") == "disabled"
+ }
+ findings = correctness_findings(
+ cases,
+ capability_quality=capability_quality,
+ disabled_pair_capabilities=disabled_pair_capabilities,
+ )
+ if freshness_policy_failed:
+ findings.append(
+ "The incremental semantic result did not conform to the recorded freshness policy; "
+ "the post-edit pair result and whole-graph canonical comparison must be interpreted "
+ "together."
+ )
+ disabled_pair_controls = [
+ detail
+ for detail in pair_quality_details
+ if detail.get("capability_state") == "disabled"
+ ]
+ if disabled_pair_controls:
+ findings.append(
+ "The explicit capability-off control omitted the judged positive in initial, "
+ "post-edit, and fresh results; this is the expected ablation contrast, not a "
+ "freshness deferral or execution failure."
+ )
+ if deferred_freshness:
+ findings.insert(
+ 0,
+ "Immediate semantic freshness was intentionally deferred under the recorded policy; "
+ "the structured stale warning was present and initial/fresh pair tasks passed",
+ )
+ return {
+ "candidate": canonical_label,
+ "decision": decision,
+ "graph_error": (
+ "**GRAPH ERROR**"
+ if canonical_failed
+ else "**FRESHNESS ERROR**"
+ if freshness_policy_failed
+ else "none"
+ ),
+ "result_error": (
+ "**QUALITY TARGET MISS**"
+ if quality_target_missed and (capability_quality or explicit_ablation_miss)
+ else "**RESULT ERROR**"
+ if quality_target_missed or result_oracle_failed
+ else "none"
+ ),
+ "run_error": (
+ "**CLEANUP ERROR**"
+ if cleanup_failed
+ else "**PROCESSING ERROR**"
+ if case_passes
+ and not all(case_passes)
+ and not canonical_failed
+ and not (quality_target_missed or result_oracle_failed)
+ else "**EVIDENCE ERROR**"
+ if not cases
+ else "none"
+ ),
+ "cases": ratio(sum(case_passes), len(case_passes)),
+ "canonical": ratio(sum(canonical), len(canonical)),
+ "core_graph": ratio(sum(core_graph), len(core_graph)),
+ "oracles": ratio(sum(oracles), len(oracles)),
+ "quality_score": retrieval_score,
+ "pair_f1_score": pair_f1_score,
+ "overall_quality_score": overall_quality_score,
+ "graph_fidelity_score": graph_fidelity_score,
+ "core_graph_fidelity_score": core_graph_fidelity_score,
+ "task_success_score": task_success_score,
+ "hit_at_1": hit_at_1_weighted / quality_score_count
+ if quality_score_count
+ else None,
+ "hit_at_5": hit_at_5_weighted / quality_score_count
+ if quality_score_count
+ else None,
+ "ndcg_at_5": ndcg_weighted / ndcg_count if ndcg_count else None,
+ "quality_checks": ratio(quality_passed, quality_applicable),
+ "query_response_p50_bytes": percentile(query_response_bytes, 0.50),
+ "query_response_p50_tokens": percentile(query_response_tokens, 0.50),
+ "query_latency_p50_ms": percentile(query_latency_ms, 0.50),
+ "cold_query_latency_p50_ms": percentile(cold_query_latency_ms, 0.50),
+ "query_observations": len(query_latency_ms),
+ "query_range_ms": (min(query_latency_ms), max(query_latency_ms))
+ if query_latency_ms
+ else None,
+ "attempt_observations": len(attempt_elapsed_seconds),
+ "attempt_p50_seconds": percentile(attempt_elapsed_seconds, 0.50),
+ "attempt_range_seconds": (
+ min(attempt_elapsed_seconds),
+ max(attempt_elapsed_seconds),
+ )
+ if attempt_elapsed_seconds
+ else None,
+ "incremental_observations": len(incremental_ms),
+ "incremental_range_ms": (min(incremental_ms), max(incremental_ms))
+ if incremental_ms
+ else None,
+ "full_observations": len(full_values),
+ "full_range_ms": (min(full_values), max(full_values)) if full_values else None,
+ "capabilities": config_label(reports),
+ "capability_signature": config_signature(reports),
+ "pre_rename_config_spellings": (
+ canonical_label != label or reports_use_pre_rename_config_spellings(reports)
+ ),
+ "incremental_p50_ms": percentile(incremental_ms, 0.50),
+ "incremental_work_p50_ms": percentile(incremental_work_ms, 0.50),
+ "incremental_peak_p50_mb": percentile(incremental_peak_rss, 0.50),
+ "incremental_p95_ms": percentile(incremental_ms, 0.95),
+ "full_p50_ms": percentile(full_values, 0.50),
+ "speedup_p50": float(statistics.median(speedups)) if speedups else None,
+ "peak_rss_mb": max(peak_rss) if peak_rss else None,
+ "dependency_mode": dependency_mode(reports, dependency_packages),
+ "dependency_packages_p50": percentile(dependency_packages, 0.50),
+ "dependency_initial_p50_ms": percentile(dependency_initial_ms, 0.50),
+ "dependency_incremental_p50_ms": percentile(dependency_incremental_ms, 0.50),
+ "dependency_fresh_p50_ms": percentile(dependency_fresh_ms, 0.50),
+ "index_modes": ", ".join(sorted(index_modes)) if index_modes else "unknown",
+ "execution_orders": ", ".join(sorted(execution_orders))
+ if execution_orders
+ else "unknown",
+ "capability_applicability": summarize_capability_applicability(reports),
+ "lifecycle": evidence_lifecycle(reports),
+ "binary_sha256": ", ".join(value[:12] for value in hashes) or "n/a",
+ "findings": findings,
+ "quality_details": quality_oracle_details(cases),
+ "rank_scorer_details": rank_details,
+ "measured_rank_scorers": sorted(
+ {
+ str(detail["scorer"])
+ for detail in rank_details
+ if not str(detail.get("status", "")).startswith("N/A")
+ }
+ ),
+ "unavailable_rank_scorers": sorted(
+ {
+ str(detail["scorer"])
+ for detail in rank_details
+ if str(detail.get("status", "")).startswith("N/A")
+ }
+ ),
+ "cell_names": report_parameter_values(reports, "cell_name"),
+ "expected_observables": report_parameter_values(reports, "expected_observable"),
+ "evidence_scopes": report_parameter_values(reports, "evidence_scope"),
+ "informs_hypotheses": report_parameter_values(reports, "informs_hypotheses"),
+ "transports": report_parameter_values(reports, "transport"),
+ "parameter_sources": report_parameter_sources(reports),
+ "pair_quality_details": pair_quality_details,
+ "mutation_details": mutation_reindex_details(
+ cases,
+ disabled_pair_capabilities=disabled_pair_capabilities,
+ ),
+ "scenario": next(iter(scenarios)) if len(scenarios) == 1 else None,
+ "pareto_workload": json.dumps(
+ {
+ "backgrounds": sorted(workload_backgrounds),
+ "index_modes": sorted(index_modes),
+ "report_modes": sorted(report_modes),
+ "scenarios": sorted(scenarios),
+ "task_sets": sorted(workload_tasks),
+ },
+ separators=(",", ":"),
+ sort_keys=True,
+ ),
+ "frontier_files": next(iter(frontier_files))
+ if len(frontier_files) == 1
+ else None,
+ "exact_cap": next(iter(exact_caps)) if len(exact_caps) == 1 else None,
+ "frontier_contract": next(iter(contracts)) if len(contracts) == 1 else None,
+ "pareto": "unclassified",
+ "pareto_reason": "not evaluated",
+ }
+
+
+def historical_speedup(
+ baseline: dict[str, Any],
+ latest: dict[str, Any],
+ metric: str,
+ *,
+ comparable: bool,
+) -> float | None:
+ """Return a ratio only when the two quality-gated rows are comparable."""
+ if not comparable:
+ return None
+ old = baseline.get(metric)
+ new = latest.get(metric)
+ return (
+ old / new
+ if isinstance(old, (int, float)) and isinstance(new, (int, float)) and new > 0
+ else None
+ )
+
+
+def historical_delta_rows(rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ latest_by_signature = {
+ row.get("capability_signature"): row
+ for row in rows
+ if str(row.get("candidate", "")).startswith("latest-")
+ and row.get("capability_signature") is not None
+ }
+ comparisons: list[dict[str, Any]] = []
+ for baseline in rows:
+ if str(baseline.get("candidate", "")).startswith("latest-"):
+ continue
+ latest = latest_by_signature.get(baseline.get("capability_signature"))
+ if latest is None:
+ continue
+
+ accepted_decisions = {
+ "PASS",
+ "PASS: DEFERRED FRESHNESS",
+ "PASS: DECLARED STALE VIEWS",
+ }
+ baseline_decision = baseline.get("decision")
+ latest_decision = latest.get("decision")
+ if (
+ baseline_decision not in accepted_decisions
+ or latest_decision not in accepted_decisions
+ ):
+ comparison_status = "not comparable: correctness/quality gate"
+ elif baseline_decision != latest_decision:
+ comparison_status = "not comparable: freshness/quality decision differs"
+ else:
+ quality_axes = (
+ "overall_quality_score",
+ "pair_f1_score",
+ "graph_fidelity_score",
+ "task_success_score",
+ )
+ quality_matches = all(
+ (baseline.get(axis) is None and latest.get(axis) is None)
+ or (
+ isinstance(baseline.get(axis), (int, float))
+ and isinstance(latest.get(axis), (int, float))
+ and math.isclose(
+ float(baseline[axis]),
+ float(latest[axis]),
+ rel_tol=1e-9,
+ abs_tol=1e-12,
+ )
+ )
+ for axis in quality_axes
+ )
+ if not quality_matches:
+ comparison_status = "not comparable: measured quality differs"
+ else:
+ minimum_observations = min(
+ int(baseline.get(key) or 0)
+ for key in (
+ "incremental_observations",
+ "full_observations",
+ "query_observations",
+ )
+ )
+ minimum_observations = min(
+ minimum_observations,
+ *(
+ int(latest.get(key) or 0)
+ for key in (
+ "incremental_observations",
+ "full_observations",
+ "query_observations",
+ )
+ ),
+ )
+ comparison_status = (
+ "quality-matched repeated evidence"
+ if minimum_observations >= 3
+ else f"descriptive only: minimum matched observation count {minimum_observations}"
+ )
+ comparable = not comparison_status.startswith("not comparable")
+
+ comparisons.append(
+ {
+ "latest": latest["candidate"],
+ "baseline": baseline["candidate"],
+ "incremental_speedup": historical_speedup(
+ baseline, latest, "incremental_p50_ms", comparable=comparable
+ ),
+ "full_speedup": historical_speedup(
+ baseline, latest, "full_p50_ms", comparable=comparable
+ ),
+ "query_speedup": historical_speedup(
+ baseline, latest, "query_latency_p50_ms", comparable=comparable
+ ),
+ "latest_quality": latest.get("overall_quality_score"),
+ "baseline_quality": baseline.get("overall_quality_score"),
+ "baseline_decision": baseline.get("decision"),
+ "comparison_status": comparison_status,
+ }
+ )
+ return comparisons
+
+
+def frontier_crossover_rows(rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ """Pair the closest configured fallback and exact run for each frontier."""
+ grouped: dict[tuple[str, int], list[dict[str, Any]]] = defaultdict(list)
+ for row in rows:
+ scenario = row.get("scenario")
+ frontier_files = row.get("frontier_files")
+ if isinstance(scenario, str) and isinstance(frontier_files, int):
+ grouped[(scenario, frontier_files)].append(row)
+
+ crossovers: list[dict[str, Any]] = []
+ for (scenario, frontier_files), candidates in sorted(grouped.items()):
+ fallbacks = [
+ row
+ for row in candidates
+ if row.get("frontier_contract") == "configured_cap_fallback"
+ and isinstance(row.get("exact_cap"), int)
+ ]
+ exact = [
+ row
+ for row in candidates
+ if row.get("frontier_contract") == "exact_frontier"
+ and isinstance(row.get("exact_cap"), int)
+ ]
+ if not fallbacks or not exact:
+ continue
+ fallback = max(fallbacks, key=lambda row: row["exact_cap"])
+ exact_run = min(exact, key=lambda row: row["exact_cap"])
+ fallback_elapsed = fallback.get("incremental_p50_ms")
+ exact_elapsed = exact_run.get("incremental_p50_ms")
+ ratio_value = (
+ exact_elapsed / fallback_elapsed
+ if isinstance(exact_elapsed, (int, float))
+ and isinstance(fallback_elapsed, (int, float))
+ and fallback_elapsed > 0
+ else None
+ )
+ if ratio_value is None:
+ conclusion = "not measured"
+ elif ratio_value < 0.95:
+ conclusion = "exact faster"
+ elif ratio_value <= 1.05:
+ conclusion = "tied"
+ else:
+ conclusion = "fallback faster"
+ crossovers.append(
+ {
+ "scenario": scenario,
+ "affected_files": frontier_files + 1,
+ "fallback_cap": fallback["exact_cap"],
+ "fallback_p50_ms": fallback_elapsed,
+ "fallback_work_p50_ms": fallback.get("incremental_work_p50_ms"),
+ "fallback_rss_p50_mb": fallback.get("incremental_peak_p50_mb"),
+ "exact_cap": exact_run["exact_cap"],
+ "exact_p50_ms": exact_elapsed,
+ "exact_work_p50_ms": exact_run.get("incremental_work_p50_ms"),
+ "exact_rss_p50_mb": exact_run.get("incremental_peak_p50_mb"),
+ "full_p50_ms": exact_run.get("full_p50_ms"),
+ "exact_fallback_ratio": ratio_value,
+ "conclusion": conclusion,
+ }
+ )
+ return crossovers
+
+
+PARETO_MINIMIZE = (
+ "incremental_p50_ms",
+ "query_latency_p50_ms",
+ "query_response_p50_tokens",
+ "peak_rss_mb",
+)
+
+
+def dominates(left: dict[str, Any], right: dict[str, Any]) -> bool:
+ left_quality = left.get("overall_quality_score")
+ right_quality = right.get("overall_quality_score")
+ if not isinstance(left_quality, (int, float)) or not isinstance(
+ right_quality, (int, float)
+ ):
+ return False
+ left_values = [left.get(key) for key in PARETO_MINIMIZE]
+ right_values = [right.get(key) for key in PARETO_MINIMIZE]
+ if not all(isinstance(value, (int, float)) for value in left_values + right_values):
+ return False
+ no_worse = left_quality >= right_quality and all(
+ left_value <= right_value
+ for left_value, right_value in zip(left_values, right_values, strict=True)
+ )
+ strictly_better = left_quality > right_quality or any(
+ left_value < right_value
+ for left_value, right_value in zip(left_values, right_values, strict=True)
+ )
+ return no_worse and strictly_better
+
+
+def mark_pareto_frontier(rows: list[dict[str, Any]]) -> None:
+ """Mark correctness-admissible, fully measured non-dominated candidates."""
+ eligible = [
+ row
+ for row in rows
+ if row.get("decision") == "PASS"
+ and isinstance(row.get("overall_quality_score"), (int, float))
+ and all(isinstance(row.get(key), (int, float)) for key in PARETO_MINIMIZE)
+ ]
+ for row in rows:
+ row["pareto"] = "ineligible"
+ missing = [
+ key
+ for key in ("overall_quality_score", *PARETO_MINIMIZE)
+ if not isinstance(row.get(key), (int, float))
+ ]
+ reasons = []
+ if row.get("decision") != "PASS":
+ reasons.append(str(row.get("decision")))
+ if missing:
+ reasons.append("missing " + ", ".join(missing))
+ row["pareto_reason"] = "; ".join(reasons) or "not eligible"
+ for row in eligible:
+ dominators = [
+ other
+ for other in eligible
+ if other is not row
+ and other.get("pareto_workload") == row.get("pareto_workload")
+ and dominates(other, row)
+ ]
+ if dominators:
+ dominator = dominators[0]
+ row["pareto"] = f"dominated by {dominator['candidate']}"
+ row["pareto_reason"] = (
+ f"{dominator['candidate']} has overall quality "
+ f"{dominator['overall_quality_score']:.3f} >= "
+ f"{row['overall_quality_score']:.3f} and is no slower/larger on every cost axis"
+ )
+ else:
+ row["pareto"] = "frontier"
+ row["pareto_reason"] = (
+ "within the same workload, no passing, fully measured candidate is at least as "
+ "good on overall quality and every cost axis while being strictly better on one "
+ "or more axes"
+ )
+
+
+def display(value: Any, digits: int = 1) -> str:
+ if value is None:
+ return "n/a"
+ if isinstance(value, float):
+ return f"{value:.{digits}f}"
+ return str(value).replace("|", "\\|")
+
+
+def display_range(value: Any) -> str:
+ if not isinstance(value, tuple) or len(value) != 2:
+ return "n/a"
+ return f"[{display(value[0])}, {display(value[1])}]"
+
+
+def display_confusion(value: Any) -> str:
+ if not isinstance(value, dict):
+ return "n/a"
+ return "/".join(str(value.get(key, "n/a")) for key in ("tp", "tn", "fp", "fn"))
+
+
+def atomic_write_text(path: Path, content: str) -> None:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ temporary = path.parent / f".{path.name}.{os.getpid()}.{uuid.uuid4().hex}.tmp"
+ try:
+ with temporary.open("w", encoding="utf-8") as stream:
+ stream.write(content)
+ stream.flush()
+ os.fsync(stream.fileno())
+ os.replace(temporary, path)
+ finally:
+ if temporary.exists():
+ temporary.unlink()
+
+
+def render_search_projection(document: dict[str, Any]) -> str:
+ if document.get("mode") != "search_projection":
+ raise ValueError("expected a search_projection result document")
+ observations = document.get("observations")
+ derived = document.get("derived")
+ if not isinstance(observations, list) or not isinstance(derived, dict):
+ raise ValueError(
+ "search-projection result is missing observations or derived data"
+ )
+ completion = document.get("completion")
+ status = (
+ str(completion.get("status")) if isinstance(completion, dict) else "unknown"
+ )
+ labels = {
+ "compact_default": "compact default",
+ "compact_true": "compact true",
+ "compact_selected_fields": "compact + selected fields",
+ "compact_false": "non-compact",
+ }
+ lines = [
+ "## search_graph JSON projection",
+ "",
+ f"Outcome: {status} — ranked-result identity parity="
+ f"{str(bool(derived.get('identity_parity'))).lower()}, internal fields absent="
+ f"{str(bool(derived.get('internal_fields_absent'))).lower()}.",
+ "",
+ "| Variant | Results | Ranked identities | Property fields | Payload bytes | "
+ "Estimated tokens* | Call ms† | Post-call RSS MiB‡ | Transport | Cleanup |",
+ "|---|---:|---|---|---:|---:|---:|---:|---|---|",
+ ]
+ non_compact_fields: list[str] = []
+ for item in observations:
+ if not isinstance(item, dict):
+ continue
+ fields = item.get("property_fields")
+ typed_fields = list(map(str, fields)) if isinstance(fields, list) else []
+ fields_text = (
+ f"{len(typed_fields)} fields"
+ if len(typed_fields) > 4
+ else (", ".join(typed_fields) if typed_fields else "none")
+ )
+ if item.get("variant") == "compact_false":
+ non_compact_fields = typed_fields
+ rss_kb = item.get("post_call_rss_kb")
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ labels.get(str(item.get("variant")), str(item.get("variant"))),
+ f"{int(item['returned_count']):,}",
+ "Equal" if item.get("identity_equal_to_default") else "Different",
+ fields_text,
+ f"{int(item['response_bytes']):,}",
+ f"{int(item['response_token_estimate']):,}",
+ f"{float(item['elapsed_ms']):.3f}",
+ f"{float(rss_kb) / 1024:.1f}"
+ if isinstance(rss_kb, (int, float))
+ else "n/a",
+ "Survived" if item.get("transport_survived") else "Interrupted",
+ "Reaped" if item.get("server_reaped") else "Incomplete",
+ )
+ )
+ + " |"
+ )
+ compact_bytes = derived.get("compact_bytes")
+ verbose_bytes = derived.get("non_compact_bytes")
+ savings = (
+ 100.0 * (1.0 - float(compact_bytes) / float(verbose_bytes))
+ if isinstance(compact_bytes, (int, float))
+ and isinstance(verbose_bytes, (int, float))
+ and verbose_bytes
+ else None
+ )
+ binary = document.get("binary_metadata")
+ sha = binary.get("sha256") if isinstance(binary, dict) else None
+ cleanup = document.get("cleanup")
+ cleanup_removed = cleanup.get("removed") if isinstance(cleanup, dict) else None
+ lines.extend(
+ (
+ "",
+ "### Interpretation and audit boundary",
+ "",
+ (
+ "- Non-compact property fields: " + ", ".join(non_compact_fields) + "."
+ if non_compact_fields
+ else "- Non-compact property fields: none."
+ ),
+ f"- Compact output uses {savings:.1f}% fewer payload bytes than non-compact output."
+ if savings is not None
+ else "- Compact versus non-compact byte savings were not measured.",
+ "- No fp, sp, or bt indexing fields appear in any variant."
+ if derived.get("internal_fields_absent")
+ else "- One or more internal indexing fields were observed.",
+ f"- Claim boundary: {derived.get('claim_boundary', 'projection-only comparison')}",
+ f"- Run ID: {document.get('run_id', 'n/a')}; binary SHA-256: {sha or 'n/a'}.",
+ f"- Auto-created fixture cleanup confirmed: {str(cleanup_removed).lower()}.",
+ "",
+ "* Tokens are the deterministic ceil(UTF-8 payload bytes / 4) estimate, not a "
+ "model-tokenizer count.",
+ "",
+ "† There is one observation per variant. The table is a response-projection and "
+ "ranked-identity check, not a latency comparison.",
+ "",
+ "‡ RSS is sampled after each call and is not peak RSS.",
+ )
+ )
+ return "\n".join(lines) + "\n"
+
+
+def render_list_projects_scaling(document: dict[str, Any]) -> str:
+ if document.get("mode") != "list_projects_scaling":
+ raise ValueError("expected a list_projects_scaling result document")
+ observations = document.get("observations")
+ derived = document.get("derived")
+ if not isinstance(observations, list) or not isinstance(derived, dict):
+ raise ValueError(
+ "list-project scaling result is missing observations or derived data"
+ )
+ completion = document.get("completion")
+ completion_status = (
+ str(completion.get("status")) if isinstance(completion, dict) else "unknown"
+ )
+ all_valid = bool(derived.get("passed"))
+ outcome_detail = (
+ "all requested inventories returned, follow-up MCP requests succeeded, and server "
+ "resources were reaped"
+ if all_valid
+ else "one or more inventory, transport, or teardown checks were incomplete"
+ )
+ lines = [
+ "## `list_projects` response scaling",
+ "",
+ f"Outcome: {completion_status} — {outcome_detail}.",
+ "",
+ "| Requested projects | Returned projects | Payload bytes | Estimated tokens* | "
+ "Call ms† | Post-call RSS MiB‡ | Transport | Server cleanup | Fixture DB MiB |",
+ "|---:|---:|---:|---:|---:|---:|---|---|---:|",
+ ]
+ for item in observations:
+ if not isinstance(item, dict):
+ continue
+ rss_kb = item.get("post_call_rss_kb")
+ fixture_bytes = item.get("fixture_db_bytes")
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ f"{int(item['requested_projects']):,}",
+ f"{int(item['returned_projects']):,}",
+ f"{int(item['response_bytes']):,}",
+ f"{int(item['response_token_estimate']):,}",
+ f"{float(item['elapsed_ms']):.3f}",
+ f"{float(rss_kb) / 1024:.1f}"
+ if isinstance(rss_kb, (int, float))
+ else "n/a",
+ "Survived" if item.get("transport_survived") else "Interrupted",
+ "Reaped" if item.get("server_reaped") else "Incomplete",
+ (
+ f"{float(fixture_bytes) / (1024 * 1024):.1f}"
+ if isinstance(fixture_bytes, (int, float))
+ else "n/a"
+ ),
+ )
+ )
+ + " |"
+ )
+ growth = derived.get("incremental_response_bytes_per_project")
+ claim_boundary = derived.get("claim_boundary")
+ binary = document.get("binary_metadata")
+ sha = binary.get("sha256") if isinstance(binary, dict) else None
+ cleanup = document.get("cleanup")
+ cleanup_removed = cleanup.get("removed") if isinstance(cleanup, dict) else None
+ lines.extend(
+ (
+ "",
+ "### Interpretation and audit boundary",
+ "",
+ f"- Observed payload growth: {float(growth):.1f} bytes per added project."
+ if isinstance(growth, (int, float))
+ else "- Observed payload growth: not measured.",
+ f"- Claim boundary: {claim_boundary}"
+ if isinstance(claim_boundary, str)
+ else "- Claim boundary: this measures `list_projects` alone.",
+ f"- Run ID: `{document.get('run_id', 'n/a')}`; binary SHA-256: `{sha or 'n/a'}`.",
+ f"- Auto-created fixture cleanup confirmed: {str(cleanup_removed).lower()}.",
+ "",
+ "* Tokens are the deterministic `ceil(UTF-8 payload bytes / 4)` estimate, not a "
+ "model-tokenizer count.",
+ "",
+ "† This pilot has one observation per project count. Latency is descriptive and must "
+ "not be presented as a population estimate or regression threshold.",
+ "",
+ "‡ RSS is sampled after each call and is not peak RSS. Fixture DB size is transient "
+ "isolated-test storage, not response memory or a recommended cache size.",
+ )
+ )
+ return "\n".join(lines) + "\n"
+
+
+def render_mcp_surface_parity(document: dict[str, Any]) -> str:
+ if document.get("mode") != "mcp_surface_parity":
+ raise ValueError("expected an mcp_surface_parity result document")
+ surfaces = document.get("surfaces")
+ comparison = document.get("comparison")
+ if not isinstance(surfaces, dict) or not isinstance(comparison, dict):
+ raise ValueError("MCP surface result is missing surfaces or comparison")
+
+ classic = surfaces.get("classic")
+ pre = surfaces.get("streamlined_pre_reveal")
+ post = surfaces.get("streamlined_post_reveal")
+ pre_comparison = comparison.get("pre_reveal")
+ post_comparison = comparison.get("post_reveal")
+ if not all(
+ isinstance(value, dict)
+ for value in (classic, pre, post, pre_comparison, post_comparison)
+ ):
+ raise ValueError("MCP surface result is missing one or more parity states")
+
+ assert isinstance(classic, dict)
+ assert isinstance(pre, dict)
+ assert isinstance(post, dict)
+ assert isinstance(pre_comparison, dict)
+ assert isinstance(post_comparison, dict)
+ capability_parity = comparison.get("capability_parity")
+ if not isinstance(capability_parity, list):
+ capability_parity = []
+ classic_count = classic.get("tool_count")
+ post_classic = (
+ f"{classic_count}/{classic_count}"
+ if post_comparison.get("classic_name_parity") and isinstance(classic_count, int)
+ else "incomplete"
+ )
+ rows = (
+ (
+ "Pure classic",
+ classic,
+ f"{classic_count}/{classic_count}"
+ if isinstance(classic_count, int)
+ else "n/a",
+ "n/a (advertised directly)",
+ ),
+ (
+ "Streamlined before reveal",
+ pre,
+ pre_comparison.get("advertised_classic_tools"),
+ pre_comparison.get("dispatch_recognized_classic_tools"),
+ ),
+ (
+ "Same streamlined process after reveal",
+ post,
+ post_classic,
+ "n/a (advertised after reveal)",
+ ),
+ )
+ lines = [
+ "## MCP tool-surface parity",
+ "",
+ "These are three separate discovery states. The post-reveal row comes from the same "
+ "streamlined server process as the pre-reveal row.",
+ "",
+ "### Capability outcomes",
+ "",
+ "| Capability outcome | Classic advertised | Streamlined before reveal | "
+ "Streamlined after reveal | Evidence boundary |",
+ "|---|---|---|---|---|",
+ ]
+ for item in capability_parity:
+ if not isinstance(item, dict):
+ continue
+ pre_state = (
+ "advertised"
+ if item.get("streamlined_pre_reveal_advertised")
+ else "callable but hidden"
+ if item.get("streamlined_pre_reveal_callable")
+ else "not demonstrated"
+ )
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ str(item.get("outcome") or item.get("capability") or "unknown"),
+ "yes" if item.get("classic_advertised") else "no",
+ pre_state,
+ "advertised"
+ if item.get("streamlined_post_reveal_advertised")
+ else "not demonstrated",
+ str(item.get("evidence") or "surface evidence only"),
+ )
+ )
+ + " |"
+ )
+ lines.extend(
+ [
+ "",
+ "### Discovery and response cost",
+ "",
+ "| State | Advertised tools | Advertised classic names | Classic handlers recognized* | "
+ "tools/list bytes | Estimated tokens† | tools/list ms‡ |",
+ "|---|---:|---:|---:|---:|---:|---:|",
+ ]
+ )
+ for label, surface, advertised_classic, dispatch in rows:
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ label,
+ display(surface.get("tool_count")),
+ display(advertised_classic),
+ display(dispatch),
+ display(surface.get("response_bytes")),
+ display(surface.get("response_token_estimate")),
+ display(surface.get("list_elapsed_ms"), 3),
+ )
+ )
+ + " |"
+ )
+
+ hidden = pre_comparison.get("intentionally_hidden_classic_tools")
+ alias = pre_comparison.get("get_code_alias")
+ hidden_count = len(hidden) if isinstance(hidden, list) else "unknown"
+ alias_text = "not measured"
+ if isinstance(alias, dict):
+ alias_text = (
+ f"property names equal={str(bool(alias.get('property_names_equal'))).lower()}, "
+ f"required names equal={str(bool(alias.get('required_names_equal'))).lower()}, "
+ f"validation shape equal={str(bool(alias.get('validation_shape_equal'))).lower()}, "
+ f"complete advertised schema identical={str(bool(alias.get('schema_equal'))).lower()}"
+ )
+ lines.extend(
+ (
+ "",
+ "### Parity checks",
+ "",
+ f"- Pre-reveal intentionally hidden classic names: {hidden_count}.",
+ f"- Post-reveal classic name parity: {str(bool(post_comparison.get('classic_name_parity'))).lower()}.",
+ f"- Post-reveal classic input-schema parity: {str(bool(post_comparison.get('classic_schema_parity'))).lower()}.",
+ f"- Post-reveal full MCP contract parity: "
+ f"{str(bool(post_comparison.get('classic_contract_parity'))).lower()}.",
+ f"- `notifications/tools/list_changed` observed after reveal: "
+ f"{str(bool(post_comparison.get('tools_list_changed_observed'))).lower()}.",
+ f"- MCP processes and reader threads reaped: "
+ f"{str(bool(comparison.get('lifecycle_passed'))).lower()}.",
+ f"- `get_code` versus classic `get_code_snippet`: {alias_text}.",
+ "",
+ "\\* Handler recognition uses bounded empty-argument `tools/call` requests and only proves "
+ "that dispatch did not return `unknown tool`; it does not prove successful execution or "
+ "end-to-end behavioral parity. Behavioral parity requires capability fixtures.",
+ "",
+ "† Estimated as `ceil(UTF-8 response bytes / 4)`; this is not a model-tokenizer count.",
+ "",
+ "‡ Each state currently has one `tools/list` observation, so latency is descriptive only "
+ "and has no confidence interval.",
+ )
+ )
+ return "\n".join(lines) + "\n"
+
+
+def compact_configuration(row: dict[str, Any]) -> str:
+ """Render recorded configuration data compactly without inventing missing defaults."""
+ signature = row.get("capability_signature")
+ if signature is None:
+ return str(row.get("capabilities") or "mixed or unreported configuration")
+ if not signature:
+ return "product defaults (exact values not persisted in this input)"
+ pairs = list(signature)
+ values = {value for _, value in pairs}
+ if (
+ len(values) == 1
+ and len(pairs) > 1
+ and all(key.startswith("edge_weight_") for key, _ in pairs)
+ ):
+ return f"all {len(pairs)} edge weights={pairs[0][1]}"
+ return "; ".join(f"{key}={value}" for key, value in pairs)
+
+
+def measurement_with_count(value: Any, count: int) -> str:
+ return f"{display(value, 3)} (n={count})"
+
+
+def parameter_source_summary(row: dict[str, Any]) -> str:
+ grouped: dict[str, list[dict[str, str]]] = defaultdict(list)
+ for record in row.get("parameter_sources") or []:
+ if not isinstance(record, dict):
+ continue
+ source = str(record.get("source") or "unreported")
+ grouped[source].append(record)
+ if not grouped:
+ return "defaults; no override source"
+ summaries: list[str] = []
+ for source, records in sorted(grouped.items()):
+ options = sorted(
+ {str(record.get("option") or "unspecified") for record in records}
+ )
+ if len(records) == 1:
+ macros = str(records[0].get("macros") or "unreported")
+ summaries.append(f"{source} [{macros}] ({options[0]})")
+ else:
+ summaries.append(
+ f"{source} ({len(options)} options: {', '.join(options)}; "
+ "exact macros in retained JSON)"
+ )
+ return "; ".join(summaries)
+
+
+def configuration_interpretation(row: dict[str, Any], tied_best_count: int) -> str:
+ decision = str(row.get("decision") or "unknown")
+ if decision.startswith("REJECT") or decision.startswith("BELOW"):
+ return (
+ "Fails a recorded gate on this workload; do not select this configuration."
+ )
+ if row.get("quality_score") is None:
+ return "Passes recorded gates, but this input has no comparable retrieval-quality score."
+ if tied_best_count > 1:
+ return (
+ "Tied on recorded retrieval quality; latency and memory remain descriptive at "
+ f"n={max(row.get('full_observations', 0), row.get('query_observations', 0))}."
+ )
+ return "Passes recorded gates; compare only with the same workload and evidence contract."
+
+
+def render_executive_assessment(rows: list[dict[str, Any]]) -> list[str]:
+ passing = [row for row in rows if str(row.get("decision", "")).startswith("PASS")]
+ failing = [row for row in rows if row not in passing]
+ quality_values = [
+ float(row["quality_score"])
+ for row in passing
+ if isinstance(row.get("quality_score"), (int, float))
+ ]
+ best_quality = max(quality_values) if quality_values else None
+ tied_best = [
+ row
+ for row in passing
+ if best_quality is not None
+ and isinstance(row.get("quality_score"), (int, float))
+ and math.isclose(float(row["quality_score"]), best_quality)
+ ]
+ baseline = next(
+ (
+ row
+ for row in rows
+ if "baseline" in str(row.get("candidate", "")).lower()
+ or any("baseline" in name.lower() for name in row.get("cell_names") or [])
+ ),
+ None,
+ )
+ recommendations: list[str] = []
+ if baseline in passing:
+ if len(tied_best) > 1 and baseline in tied_best:
+ recommendations.append(
+ "**Keep the recorded baseline.** No configuration winner: "
+ f"{len(tied_best)} passing configurations tie at retrieval quality "
+ f"{display(best_quality, 3)} on the recorded workload."
+ )
+ else:
+ recommendations.append(
+ "**Keep the recorded baseline unless a fully measured eligible alternative "
+ "dominates it.** The current report does not establish such a replacement."
+ )
+ elif tied_best:
+ recommendations.append(
+ "**Do not choose among the quality leaders yet.** "
+ f"{len(tied_best)} configurations share the best recorded retrieval quality."
+ )
+ else:
+ recommendations.append(
+ "**Do not select a configuration from this report.** Comparable task-quality "
+ "evidence is absent or every candidate failed a recorded gate."
+ )
+ if failing:
+ recommendations.append(
+ "**Exclude recorded gate failures from tuning.** "
+ + ", ".join(str(row["candidate"]) for row in failing)
+ + " failed or fell below a declared target on this workload."
+ )
+ if any(
+ row.get("full_observations", 0) < 2 or row.get("query_observations", 0) < 2
+ for row in rows
+ ):
+ recommendations.append(
+ "**Treat latency and memory as diagnostic, not comparative.** At least one row "
+ "has fewer than two full-index or repeated-query observations; run repeated, "
+ "same-workload measurements before claiming a performance winner."
+ )
+
+ lines = [
+ "## Executive assessment",
+ "",
+ "### Top recommendations",
+ "",
+ ]
+ lines.extend(
+ f"{index}. {recommendation}"
+ for index, recommendation in enumerate(recommendations, 1)
+ )
+ lines.extend(
+ [
+ "",
+ "## Configuration and measured performance",
+ "",
+ "| Cell | Recorded configuration / overrides | Decision | MRR | nDCG@5 | End-to-end attempt p50 s | Initial/full index p50 ms | Repeated query p50 ms | Peak RSS MB | Interpretation |",
+ "|---|---|---|---:|---:|---:|---:|---:|---:|---|",
+ ]
+ )
+ for row in rows:
+ cell = ", ".join(row.get("cell_names") or []) or str(row["candidate"])
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(cell),
+ display(compact_configuration(row)),
+ display(row["decision"]),
+ display(row["quality_score"], 3),
+ display(row["ndcg_at_5"], 3),
+ display(
+ measurement_with_count(
+ row["attempt_p50_seconds"],
+ row["attempt_observations"],
+ )
+ ),
+ display(
+ measurement_with_count(
+ row["full_p50_ms"], row["full_observations"]
+ )
+ ),
+ display(
+ measurement_with_count(
+ row["query_latency_p50_ms"], row["query_observations"]
+ )
+ ),
+ display(row["peak_rss_mb"]),
+ display(configuration_interpretation(row, len(tied_best))),
+ )
+ )
+ + " |"
+ )
+ lines.extend(
+ [
+ "",
+ "## Mechanism and workflow coverage",
+ "",
+ "| Cell | Expected observable | Persisted rank scorers measured | Hypotheses | Workflow | Evidence scope | Parameter provenance |",
+ "|---|---|---|---|---|---|---|",
+ ]
+ )
+ for row in rows:
+ cell = ", ".join(row.get("cell_names") or []) or str(row["candidate"])
+ measured = ", ".join(row.get("measured_rank_scorers") or []) or "none reported"
+ unavailable = ", ".join(row.get("unavailable_rank_scorers") or [])
+ scorers = f"{measured}; unavailable: {unavailable}" if unavailable else measured
+ workflow = (
+ f"{row.get('execution_orders') or 'unknown'} / "
+ f"{', '.join(row.get('transports') or []) or 'unknown transport'}"
+ )
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(cell),
+ display(
+ "; ".join(row.get("expected_observables") or []) or "unreported"
+ ),
+ display(scorers),
+ display(
+ ", ".join(row.get("informs_hypotheses") or []) or "unreported"
+ ),
+ display(workflow),
+ display(
+ "; ".join(row.get("evidence_scopes") or []) or "unreported"
+ ),
+ display(parameter_source_summary(row)),
+ )
+ )
+ + " |"
+ )
+ lines.extend(
+ [
+ "",
+ "Mechanisms absent from this table were not measured by these inputs; absence is not "
+ "a zero, failure, or implied equivalence. The retained JSON report inputs and fact "
+ "comparison JSON remain the audit authority for every displayed value.",
+ "",
+ ]
+ )
+ return lines
+
+
+def render_markdown(rows: list[dict[str, Any]]) -> str:
+ mark_pareto_frontier(rows)
+ lines = [
+ "# Codebase Memory performance and quality summary",
+ "",
+ *render_executive_assessment(rows),
+ "## Detailed evidence",
+ "",
+ "The following tables preserve the complete existing benchmark detail behind the concise assessment.",
+ "",
+ "| Candidate | Decision | Overall quality† | Retrieval MRR | Pair F1 | Hit@1 | Hit@5 | nDCG@5 | "
+ "Core graph | Full graph freshness | Task success | Graph error | "
+ "Result / quality error | Run / lifecycle error | Evidence counts (R/Core/Full/S) | "
+ "Response p50 bytes | Response p50 tokens* | Cold/default query p50 ms | "
+ "Repeated JSON query p50 ms | Incremental p50 ms | "
+ "Peak RSS MB | Pareto |",
+ "|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---|---|---|---:|---:|---:|---:|---:|---:|---:|---|",
+ ]
+ for row in rows:
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(row["candidate"]),
+ display(row["decision"]),
+ display(row["overall_quality_score"], 3),
+ display(row["quality_score"], 3),
+ display(row["pair_f1_score"], 3),
+ display(row["hit_at_1"], 3),
+ display(row["hit_at_5"], 3),
+ display(row["ndcg_at_5"], 3),
+ display(row["core_graph_fidelity_score"], 3),
+ display(row["graph_fidelity_score"], 3),
+ display(row["task_success_score"], 3),
+ display(row["graph_error"]),
+ display(row["result_error"]),
+ display(row["run_error"]),
+ display(
+ f"{row['quality_checks']} / {row['core_graph']} / "
+ f"{row['canonical']} / {row['oracles']}"
+ ),
+ display(row["query_response_p50_bytes"]),
+ display(row["query_response_p50_tokens"]),
+ display(row["cold_query_latency_p50_ms"]),
+ display(row["query_latency_p50_ms"]),
+ display(row["incremental_p50_ms"]),
+ display(row["peak_rss_mb"]),
+ display(row["pareto"]),
+ )
+ )
+ + " |"
+ )
+ pair_detail_count = sum(len(row["pair_quality_details"]) for row in rows)
+ if pair_detail_count:
+ lines.extend(
+ (
+ "",
+ "## Semantic pair quality and freshness",
+ "",
+ "Confusion columns are TP/TN/FP/FN over the explicit bounded judgments. "
+ "Natural background pairs outside the judgment set remain unjudged.",
+ "",
+ "| Candidate | Capability | Relationship | Initial TP/TN/FP/FN | Initial F1 | "
+ "Post-edit TP/TN/FP/FN | Post-edit F1 | Fresh TP/TN/FP/FN | Fresh F1 | "
+ "Freshness policy | Freshness result | Policy conforming | Task SHA | Background commit/tree |",
+ "|---|---|---|---:|---:|---:|---:|---:|---:|---|---|---|---|---|",
+ )
+ )
+ for row in rows:
+ for detail in row["pair_quality_details"]:
+ revision = detail.get("background_revision")
+ tree = detail.get("background_tree")
+ background = (
+ f"{str(revision)[:12]}/{str(tree)[:12]}"
+ if revision and tree
+ else "synthetic fixture"
+ )
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(row["candidate"]),
+ display(detail["capability"]),
+ display(detail["relationship"]),
+ display_confusion(detail["initial_confusion"]),
+ display(detail["initial_f1"], 3),
+ display_confusion(detail["incremental_confusion"]),
+ display(detail["incremental_f1"], 3),
+ display_confusion(detail["fresh_confusion"]),
+ display(detail["fresh_f1"], 3),
+ display(detail["freshness_policy"]),
+ display(detail["freshness"]),
+ display(detail["policy_conformance_met"]),
+ display(str(detail.get("task_sha256") or "")[:12]),
+ display(background),
+ )
+ )
+ + " |"
+ )
+ comparisons = historical_delta_rows(rows)
+ if comparisons:
+ lines.extend(
+ (
+ "",
+ "## Quality-constrained cross-version timing",
+ "",
+ "Rows first require matching capability overrides, accepted and identical lifecycle "
+ "decisions, and equal measured quality categories. Ratios are suppressed when those "
+ "conditions differ. Speedup is baseline latency divided by latest latency, so values "
+ "above 1× favor latest; fewer than three matched observations remain descriptive.",
+ "",
+ "| Latest | Baseline | Incremental speedup | Fresh rebuild speedup | "
+ "Query speedup | Latest quality | Baseline quality | Baseline gate | Evidence status |",
+ "|---|---|---:|---:|---:|---:|---:|---|---|",
+ )
+ )
+ for comparison in comparisons:
+
+ def multiple(value: Any) -> str:
+ return f"{value:.2f}×" if isinstance(value, (int, float)) else "n/a"
+
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(comparison["latest"]),
+ display(comparison["baseline"]),
+ multiple(comparison["incremental_speedup"]),
+ multiple(comparison["full_speedup"]),
+ multiple(comparison["query_speedup"]),
+ display(comparison["latest_quality"], 3),
+ display(comparison["baseline_quality"], 3),
+ display(comparison["baseline_decision"]),
+ display(comparison["comparison_status"]),
+ )
+ )
+ + " |"
+ )
+ lines.extend(
+ (
+ "",
+ "## Incremental mutation and reindex breakdown",
+ "",
+ "| Candidate | Scenario | Source mutation | Changed paths | Publication route/reason | "
+ "Incremental p50 ms | Indexing work p50 ms | Fresh rebuild p50 ms | "
+ "Fresh / incremental | Canonical equality |",
+ "|---|---|---|---|---|---:|---:|---:|---:|---:|",
+ )
+ )
+ for row in rows:
+ for detail in row["mutation_details"]:
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(row["candidate"]),
+ display(detail["scenario"]),
+ display(detail["mutation"]),
+ display(detail["changed_paths"]),
+ display(detail["publication"]),
+ display(detail["incremental_p50_ms"]),
+ display(detail["work_p50_ms"]),
+ display(detail["full_p50_ms"]),
+ display(detail["speedup_p50"], 2),
+ display(detail["canonical"]),
+ )
+ )
+ + " |"
+ )
+ lines.extend(
+ (
+ "",
+ "Incremental p50 is the end-to-end response time after applying the named source "
+ "mutation. Indexing work p50 isolates indexing work reported inside that response. "
+ "Fresh rebuild p50 indexes a separate copy of the same post-mutation tree; canonical "
+ "equality compares the incremental graph with that fresh reference graph.",
+ )
+ )
+ lines.extend(
+ (
+ "",
+ "## Dependency-indexing capability and cost",
+ "",
+ "| Candidate | Dependency mode | Packages indexed p50 | Initial dependency p50 ms | "
+ "Incremental dependency p50 ms | Fresh-after-mutation dependency p50 ms |",
+ "|---|---|---:|---:|---:|---:|",
+ )
+ )
+ for row in rows:
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(row["candidate"]),
+ display(row["dependency_mode"]),
+ display(row["dependency_packages_p50"]),
+ display(row["dependency_initial_p50_ms"]),
+ display(row["dependency_incremental_p50_ms"]),
+ display(row["dependency_fresh_p50_ms"]),
+ )
+ )
+ + " |"
+ )
+ lines.extend(
+ (
+ "",
+ "## Observation ranges",
+ "",
+ "| Candidate | Incremental n | Incremental p50 ms | Incremental min–max ms | "
+ "Query n | Repeated JSON query p50 ms | Repeated JSON min–max ms | "
+ "Full n | Full p50 ms | Full min–max ms |",
+ "|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|",
+ )
+ )
+ for row in rows:
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(row["candidate"]),
+ display(row["incremental_observations"]),
+ display(row["incremental_p50_ms"]),
+ display_range(row["incremental_range_ms"]),
+ display(row["query_observations"]),
+ display(row["query_latency_p50_ms"]),
+ display_range(row["query_range_ms"]),
+ display(row["full_observations"]),
+ display(row["full_p50_ms"]),
+ display_range(row["full_range_ms"]),
+ )
+ )
+ + " |"
+ )
+ lines.extend(
+ (
+ "",
+ "These are descriptive min–max ranges, not confidence intervals. Experiments run "
+ "sequentially to avoid resource contention. Rows record grouped or paired-interleaved "
+ "execution explicitly; interleaving reduces configuration-aligned drift but does not "
+ "by itself create an effect-size confidence interval. Medians and ratios remain "
+ "descriptive until sufficient paired repetitions are measured.",
+ )
+ )
+ lines.extend(
+ (
+ "",
+ "`enabled (observed)` requires a positive recorded package count. `disabled "
+ "(explicit)` and `enabled (explicit)` come from exact config overrides; `unsupported` "
+ "requires explicit capability-support metadata. `unknown` is intentionally not guessed "
+ "from an old artifact that lacks those signals.",
+ )
+ )
+ lines.extend(
+ (
+ "",
+ "## Algorithm-quality applicability",
+ "",
+ "| Candidate | Index mode | Rank | Similarity | Semantic edges | Git history | HTTP links | Dependencies |",
+ "|---|---|---|---|---|---|---|---|",
+ )
+ )
+ for row in rows:
+ applicability = row["capability_applicability"]
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(row["candidate"]),
+ display(row["index_modes"]),
+ *(display(applicability[name]) for name in ALGORITHM_CAPABILITIES),
+ )
+ )
+ + " |"
+ )
+ lines.extend(
+ (
+ "",
+ "Applicability is separate from enabled/disabled state. In particular, FAST mode "
+ "does not generate `SIMILAR_TO` or `SEMANTICALLY_RELATED`, so those quality effects "
+ "must be N/A rather than zero, pass, or failure. Retained artifacts without explicit "
+ "mode metadata remain `unknown`.",
+ )
+ )
+ crossovers = frontier_crossover_rows(rows)
+ if crossovers:
+ lines.extend(
+ (
+ "",
+ "## Exact-frontier cap crossover",
+ "",
+ "Each row compares the largest cap that deliberately selected bounded full-index "
+ "fallback with the smallest measured cap that admitted exact incremental work for "
+ "the same mutation. Affected files include the changed root plus the generated frontier.",
+ "",
+ "| Scenario | Affected files | Fallback cap | Fallback p50 ms | Fallback work p50 ms | "
+ "Fallback RSS p50 MB | Exact cap | Exact p50 ms | Exact work p50 ms | "
+ "Exact RSS p50 MB | Fresh full p50 ms | Exact / fallback | Conclusion |",
+ "|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---|",
+ )
+ )
+ for crossover in crossovers:
+ ratio_value = crossover["exact_fallback_ratio"]
+ rendered_ratio = (
+ f"{ratio_value:.2f}×"
+ if isinstance(ratio_value, (int, float))
+ else "n/a"
+ )
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(crossover["scenario"]),
+ display(crossover["affected_files"]),
+ display(crossover["fallback_cap"]),
+ display(crossover["fallback_p50_ms"]),
+ display(crossover["fallback_work_p50_ms"]),
+ display(crossover["fallback_rss_p50_mb"]),
+ display(crossover["exact_cap"]),
+ display(crossover["exact_p50_ms"]),
+ display(crossover["exact_work_p50_ms"]),
+ display(crossover["exact_rss_p50_mb"]),
+ display(crossover["full_p50_ms"]),
+ rendered_ratio,
+ display(crossover["conclusion"]),
+ )
+ )
+ + " |"
+ )
+ lines.extend(
+ (
+ "",
+ "`p50 ms` is end-to-end incremental response latency; `work p50 ms` isolates the "
+ "indexing work reported inside that response. RSS is recorded only in benchmark "
+ "profiling mode. Ratios within ±5% are labelled tied.",
+ )
+ )
+ lines.extend(
+ (
+ "",
+ "## Performance and provenance",
+ "",
+ "| Candidate | Cases meeting gate/target | Capabilities | Execution order | Observations (incremental/full) | Incremental p95 ms | Full p50 ms | "
+ "Speedup p50 | Evidence lifecycle | Binary SHA-256 |",
+ "|---|---:|---|---|---:|---:|---:|---:|---:|---|",
+ )
+ )
+ for row in rows:
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(row["candidate"]),
+ display(row["cases"]),
+ display(row["capabilities"]),
+ display(row["execution_orders"]),
+ display(
+ f"{row['incremental_observations']}/{row['full_observations']}"
+ ),
+ display(row["incremental_p95_ms"]),
+ display(row["full_p50_ms"]),
+ display(row["speedup_p50"], 2),
+ display(row["lifecycle"]),
+ display(row["binary_sha256"]),
+ )
+ )
+ + " |"
+ )
+ lines.extend(
+ (
+ "",
+ "## Persisted ranking score comparison",
+ "",
+ "Each row ranks one persisted score over the same graph, so ordering is "
+ "isolated from candidate generation. `degree` is the baseline arm because "
+ "PR #151 rejected PageRank on the grounds that `ORDER BY degree DESC` "
+ 'already "gives you the same ranking signal"; a high ρ and Jaccard support '
+ "that claim, and a higher utility contamination for `degree` than for "
+ '`pagerank` contradicts the accompanying "just utility popularity" claim. '
+ "Scaffolding is null unless Tier-A labels (a language test runner's own "
+ "verdict) were supplied, because filling it from one of the string "
+ "predicates under test would make the metric circular.",
+ "",
+ "| Candidate | Corpus | Scorer | Status | Top-1 symbol | Cutoff | "
+ "Leaf-hub rate | Scaffolding | ρ vs degree | Jaccard | Probe ms | "
+ "Rank views fresh |",
+ "|---|---|---|---|---|---:|---:|---:|---:|---:|---:|---|",
+ )
+ )
+ scorer_row_count = 0
+ for row in rows:
+ for detail in row.get("rank_scorer_details", []):
+ scorer_row_count += 1
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(row["candidate"]),
+ display(detail["corpus"]),
+ display(detail["scorer"]),
+ display(detail["status"]),
+ display(detail["top_symbol"]),
+ display(detail["cutoff"]),
+ display(detail["leaf_hub_rate"], 3),
+ display(detail["scaffolding"], 3),
+ display(detail["spearman_rho"], 4),
+ display(detail["top_k_jaccard"], 3),
+ display(detail["elapsed_ms"], 1),
+ display(detail["rank_views_fresh"]),
+ )
+ )
+ + " |"
+ )
+ if not scorer_row_count:
+ lines.append(
+ "| all | n/a | n/a | No persisted ranking score probes recorded | n/a | "
+ "n/a | n/a | n/a | n/a | n/a | n/a | n/a |"
+ )
+ lines.extend(
+ (
+ "",
+ "## Named quality-oracle breakdown",
+ "",
+ "| Candidate | Scenario | Oracle | Criterion | Expected evidence | Judgments | Result | RR | Hit@1 | Hit@5 | nDCG@5 |",
+ "|---|---|---|---|---|---|---|---:|---:|---:|---:|",
+ )
+ )
+ detail_count = 0
+ for row in rows:
+ for detail in row["quality_details"]:
+ detail_count += 1
+ lines.append(
+ "| "
+ + " | ".join(
+ (
+ display(row["candidate"]),
+ display(detail["scenario"]),
+ display(detail["oracle"]),
+ display(detail["criterion"]),
+ display(detail["expected"]),
+ display(detail["judgments"]),
+ display(detail["result"]),
+ display(detail["reciprocal_rank"], 3),
+ display(detail["hit_at_1"]),
+ display(detail["hit_at_5"]),
+ display(detail["ndcg_at_5"], 3),
+ )
+ )
+ + " |"
+ )
+ if not detail_count:
+ lines.append(
+ "| all | n/a | n/a | No per-oracle quality evidence recorded | n/a | n/a | "
+ "N/A | n/a | n/a | n/a | n/a |"
+ )
+ lines.extend(
+ (
+ "",
+ "## Correctness and quality findings",
+ "",
+ "| Candidate | Evidence |",
+ "|---|---|",
+ )
+ )
+ for row in rows:
+ if row["findings"]:
+ evidence = row["findings"]
+ elif str(row["decision"]).startswith("PASS"):
+ evidence = ["All applicable canonical-graph and task-oracle checks passed."]
+ else:
+ evidence = [
+ f"{row['decision']}: no stage-level witness was recorded; inspect the retained "
+ "raw result before drawing a causal conclusion."
+ ]
+ lines.append(
+ f"| {display(row['candidate'])} | {display('; '.join(evidence))} |"
+ )
+ lines.extend(
+ (
+ "",
+ "## Pareto eligibility and dominance",
+ "",
+ "| Candidate | Status | Explanation |",
+ "|---|---|---|",
+ )
+ )
+ for row in rows:
+ lines.append(
+ f"| {display(row['candidate'])} | {display(row['pareto'])} | "
+ f"{display(row['pareto_reason'])} |"
+ )
+ lines.extend(
+ (
+ "",
+ "* Response tokens use the recorded `utf8_bytes_div_4_ceil` deterministic estimate; "
+ "bytes remain the exact default tool-response payload measurement.",
+ *(
+ (
+ "",
+ "* Configuration labels are display-canonicalized when retained fact bundles "
+ "contain recorded configuration spellings used before the canonical rename; "
+ "the immutable input artifacts are not rewritten.",
+ )
+ if any(row.get("pre_rename_config_spellings") for row in rows)
+ else ()
+ ),
+ "",
+ "Retrieval MRR is the mean reciprocal rank of the first expected result over applicable "
+ "ranked probes; a missing expected result contributes zero. Hit@1 and Hit@5 are the "
+ "fractions of those same applicable probes whose first expected result appears by the "
+ "stated cutoff. N/A probes are excluded from every retrieval denominator. These definitions "
+ "follow NIST's official TREC QA definition: "
+ "[TREC QA evaluation data](https://trec.nist.gov/data/qa.html).",
+ "Graded probes additionally report nDCG@5, which rewards placing more-relevant "
+ "evidence earlier while normalizing against the ideal judged ordering. MRR and Hit@k "
+ "remain visible because they answer the distinct first-useful-result question. This "
+ "follows Järvelin and Kekäläinen's primary definition in "
+ "[Cumulated Gain-based Evaluation of IR Techniques]"
+ "(https://doi.org/10.1145/582415.582418).",
+ "",
+ "Graph fidelity is split into two visible categories. Core graph is the fraction of "
+ "mutation cases whose non-stale canonical rows equal a "
+ "matching-mode fresh rebuild. A declared-stale gate can pass only when the harness removes "
+ "the specifically named derived rows and every remaining canonical node, edge, property, "
+ "and file hash still matches. Full graph freshness requires unfiltered canonical equality. "
+ "Task success is the fraction of applicable probes that find "
+ "their required evidence. Pair F1 is the mean of the explicit initial and fresh semantic-"
+ "pair classification tasks; an expected deferred post-edit view remains visible separately "
+ "and does not masquerade as retrieval MRR. Evidence counts show retrieval probes / graph comparisons / strict "
+ "whole-scenario passes. The named breakdown above shows why a result is, for example, 4/5 "
+ "rather than hiding the failed task.",
+ "",
+ "† Overall quality is a custom descriptive score: the equal-weight geometric mean of "
+ "result quality, full graph freshness, and task success. Result quality is Pair F1 or "
+ "MRR when only one is measured, and their arithmetic mean when both are measured. It is "
+ "N/A unless all three categories are measured. It never overrides a graph-correctness gate. "
+ "A required mutation oracle can "
+ "reject a correctness benchmark; an algorithm-ablation oracle that misses its declared "
+ "cutoff is labelled BELOW QUALITY TARGET instead of being called broken. Category values "
+ "remain visible so the aggregate cannot hide which capability changed.",
+ "",
+ "Query p50 aggregates the recorded default-response oracle calls. Indexing p50/p95 use only "
+ "the recorded indexing observations; consult Cases and the immutable experiment manifest before "
+ "treating a small pilot as a population estimate.",
+ "Performance ratios require matched experiment identities and enough independent repetitions "
+ "for an effect-size confidence interval. This report shows observation counts and does not "
+ "invent an interval for one- or three-observation pilots. The experiment-design rationale "
+ "follows [Kalibera and Jones, Quantifying Performance Changes with Effect Size Confidence "
+ "Intervals](https://arxiv.org/abs/2007.10899).",
+ "",
+ "Pareto status considers only candidates that meet the declared quality target, pass "
+ "correctness, and have every axis measured. It maximizes overall quality while minimizing "
+ "incremental and query latency, response-token estimate, and peak RSS. This is exact "
+ "pairwise nondominance over the measured candidates, using the Pareto relation described "
+ "by [Deb et al.](https://doi.org/10.1109/4235.996017); it does not run NSGA-II.",
+ "",
+ "A speedup is accepted only when the case gate and every applicable canonical-graph "
+ "and task-oracle check pass. `n/a` means the input artifact did not measure that axis.",
+ )
+ )
+ return "\n".join(lines) + "\n"
+
+
+def parse_input(value: str) -> tuple[str, Path]:
+ label, separator, raw_path = value.partition("=")
+ if not separator or not label or not raw_path:
+ raise argparse.ArgumentTypeError("--input expects LABEL=PATH")
+ return label, Path(raw_path).expanduser()
+
+
+def file_sha256(path: Path) -> str:
+ digest = hashlib.sha256()
+ with path.open("rb") as stream:
+ for chunk in iter(lambda: stream.read(1024 * 1024), b""):
+ digest.update(chunk)
+ return digest.hexdigest()
+
+
+def load_experiment_runner() -> Any:
+ path = Path(__file__).resolve().with_name("run_experiments.py")
+ spec = importlib.util.spec_from_file_location(
+ "run_benchmark_experiment_for_summary", path
+ )
+ if spec is None or spec.loader is None:
+ raise RuntimeError(f"cannot load experiment runner: {path}")
+ module = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(module)
+ return module
+
+
+def _composition_path(base: Path, value: Any, field: str) -> Path:
+ if not isinstance(value, str) or not value:
+ raise ValueError(f"{field} must be a non-empty path string")
+ path = Path(value).expanduser()
+ return (base / path).resolve() if not path.is_absolute() else path.resolve()
+
+
+def load_composition_groups(
+ composition_path: Path, experiment_runner: Any | None = None
+) -> tuple[dict[str, list[dict[str, Any]]], dict[str, Any]]:
+ """Resolve completed experiment cells into exact cross-scenario report groups."""
+ composition_path = composition_path.expanduser().resolve()
+ with composition_path.open(encoding="utf-8") as stream:
+ composition = json.load(stream)
+ if not isinstance(composition, dict) or composition.get("schema_version") != 1:
+ raise ValueError("composition schema_version must be 1")
+ groups = composition.get("groups")
+ if not isinstance(groups, list) or not groups:
+ raise ValueError("composition groups must be a non-empty array")
+ experiments = composition.get("experiments")
+ legacy_experiments = composition.get("campaigns")
+ if experiments is not None and legacy_experiments is not None:
+ raise ValueError("composition must not mix experiments with legacy campaigns")
+ legacy_layout = experiments is None and legacy_experiments is not None
+ if legacy_layout:
+ experiments = legacy_experiments
+ if not isinstance(experiments, dict) or not experiments:
+ raise ValueError("composition experiments must be a non-empty object")
+ runner = experiment_runner or load_experiment_runner()
+ base = composition_path.parent
+ resolved_experiments: dict[str, tuple[list[dict[str, Any]], Path]] = {}
+ experiment_records: list[dict[str, Any]] = []
+ for experiment_name, experiment in experiments.items():
+ if (
+ not isinstance(experiment_name, str)
+ or not experiment_name
+ or not isinstance(experiment, dict)
+ ):
+ raise ValueError(
+ "composition experiment entries must have non-empty names and objects"
+ )
+ prefix = f"experiments.{experiment_name}"
+ matrix_value = experiment.get("matrix_spec")
+ plan_value = experiment.get("plan")
+ if (matrix_value is None) == (plan_value is None):
+ raise ValueError(
+ f"{prefix} must declare exactly one of matrix_spec or plan"
+ )
+ root_value = experiment.get("experiment_root")
+ if root_value is None and legacy_layout:
+ root_value = experiment.get("campaign_root")
+ experiment_root = _composition_path(
+ base, root_value, f"{prefix}.experiment_root"
+ )
+ if plan_value is not None:
+ source_path = _composition_path(base, plan_value, f"{prefix}.plan")
+ with source_path.open(encoding="utf-8") as stream:
+ plan = json.load(stream)
+ cells = runner.validate_plan(plan)
+ source_kind = "immutable_plan"
+ else:
+ source_path = _composition_path(base, matrix_value, f"{prefix}.matrix_spec")
+ with source_path.open(encoding="utf-8") as stream:
+ matrix_spec = json.load(stream)
+ plan = runner.expand_matrix_spec(matrix_spec)
+ cells = plan.get("cells") if isinstance(plan, dict) else None
+ if not isinstance(cells, list):
+ raise ValueError(f"{prefix}.matrix_spec did not expand to cells")
+ source_kind = "live_matrix_expansion"
+ resolved_experiments[experiment_name] = (cells, experiment_root)
+ experiment_records.append(
+ {
+ "experiment": experiment_name,
+ "source_kind": source_kind,
+ "source_path": str(source_path),
+ "source_sha256": file_sha256(source_path),
+ }
+ )
+ grouped: dict[str, list[dict[str, Any]]] = defaultdict(list)
+ input_records: list[dict[str, Any]] = []
+ seen_labels: set[str] = set()
+ for group_index, group in enumerate(groups):
+ if not isinstance(group, dict):
+ raise ValueError(f"groups[{group_index}] must be an object")
+ label = group.get("label")
+ if not isinstance(label, str) or not label or label in seen_labels:
+ raise ValueError(
+ f"groups[{group_index}].label must be non-empty and unique"
+ )
+ seen_labels.add(label)
+ inputs = group.get("inputs")
+ if not isinstance(inputs, list) or not inputs:
+ raise ValueError(f"groups[{group_index}].inputs must be a non-empty array")
+ for source_index, source in enumerate(inputs):
+ if not isinstance(source, dict):
+ raise ValueError(
+ f"groups[{group_index}].inputs[{source_index}] must be an object"
+ )
+ prefix = f"groups[{group_index}].inputs[{source_index}]"
+ experiment_name = source.get("experiment")
+ if experiment_name is None and legacy_layout:
+ experiment_name = source.get("campaign")
+ if (
+ not isinstance(experiment_name, str)
+ or experiment_name not in resolved_experiments
+ ):
+ raise ValueError(f"{prefix}.experiment must name a declared experiment")
+ cells, experiment_root = resolved_experiments[experiment_name]
+ cell_labels = source.get("cell_labels")
+ if (
+ not isinstance(cell_labels, list)
+ or not cell_labels
+ or not all(isinstance(item, str) and item for item in cell_labels)
+ ):
+ raise ValueError(
+ f"{prefix}.cell_labels must be a non-empty string array"
+ )
+ requested = set(cell_labels)
+ selected = [cell for cell in cells if cell.get("label") in requested]
+ found = {cell.get("label") for cell in selected}
+ missing_labels = sorted(requested - found)
+ if missing_labels:
+ raise ValueError(
+ f"{prefix} cell labels not found: {', '.join(missing_labels)}"
+ )
+ inputs = runner.completed_report_inputs(experiment_root, selected)
+ if len(inputs) != len(selected):
+ raise ValueError(
+ f"{prefix} has {len(inputs)} validated completions for {len(selected)} cells"
+ )
+ for cell_label, input_path in inputs:
+ with input_path.open(encoding="utf-8") as stream:
+ document = json.load(stream)
+ if not isinstance(document, dict):
+ raise ValueError(f"expected JSON object in {input_path}")
+ grouped[label].append(document)
+ input_records.append(
+ {
+ "group": label,
+ "cell_label": cell_label,
+ "input_path": str(input_path.resolve()),
+ "input_sha256": file_sha256(input_path),
+ }
+ )
+ provenance = {
+ "schema_version": 1,
+ "spec_path": str(composition_path),
+ "spec_sha256": file_sha256(composition_path),
+ "experiments": experiment_records,
+ "input_count": len(input_records),
+ "inputs": input_records,
+ }
+ return grouped, provenance
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("--input", action="append", default=[], type=parse_input)
+ parser.add_argument(
+ "--composition-spec",
+ type=Path,
+ help="Compose exact labels from validated cells in multiple durable experiments.",
+ )
+ parser.add_argument(
+ "--mcp-surface-parity",
+ action="append",
+ default=[],
+ type=Path,
+ help="Append a three-state MCP surface section from a retained parity JSON result.",
+ )
+ parser.add_argument(
+ "--list-projects-scaling",
+ action="append",
+ default=[],
+ type=Path,
+ help="Append a list_projects response-scaling section from retained JSON.",
+ )
+ parser.add_argument(
+ "--search-projection",
+ action="append",
+ default=[],
+ type=Path,
+ help="Append a search_graph compact-projection section from retained JSON.",
+ )
+ parser.add_argument("--out", default="")
+ args = parser.parse_args()
+ if (
+ not args.input
+ and not args.composition_spec
+ and not args.mcp_surface_parity
+ and not args.list_projects_scaling
+ and not args.search_projection
+ ):
+ parser.error(
+ "at least one --input, --composition-spec, --mcp-surface-parity, "
+ "--list-projects-scaling, or --search-projection is required"
+ )
+ grouped: dict[str, list[dict[str, Any]]] = defaultdict(list)
+ composition_provenance: dict[str, Any] | None = None
+ for label, path in args.input:
+ with path.open(encoding="utf-8") as stream:
+ document = json.load(stream)
+ if not isinstance(document, dict):
+ raise SystemExit(f"error: expected JSON object in {path}")
+ grouped[label].append(document)
+ if args.composition_spec:
+ try:
+ composed, composition_provenance = load_composition_groups(
+ args.composition_spec
+ )
+ except (OSError, ValueError, json.JSONDecodeError) as exc:
+ raise SystemExit(f"error: invalid composition spec: {exc}") from exc
+ for label, documents in composed.items():
+ grouped[label].extend(documents)
+ sections: list[str] = []
+ if grouped:
+ sections.append(
+ render_markdown(
+ [summarize_group(label, reports) for label, reports in grouped.items()]
+ ).rstrip()
+ )
+ for raw_path in args.mcp_surface_parity:
+ path = raw_path.expanduser()
+ with path.open(encoding="utf-8") as stream:
+ document = json.load(stream)
+ if not isinstance(document, dict):
+ raise SystemExit(f"error: expected JSON object in {path}")
+ sections.append(render_mcp_surface_parity(document).rstrip())
+ for raw_path in args.list_projects_scaling:
+ path = raw_path.expanduser()
+ with path.open(encoding="utf-8") as stream:
+ document = json.load(stream)
+ if not isinstance(document, dict):
+ raise SystemExit(f"error: expected JSON object in {path}")
+ sections.append(render_list_projects_scaling(document).rstrip())
+ for raw_path in args.search_projection:
+ path = raw_path.expanduser()
+ with path.open(encoding="utf-8") as stream:
+ document = json.load(stream)
+ if not isinstance(document, dict):
+ raise SystemExit(f"error: expected JSON object in {path}")
+ sections.append(render_search_projection(document).rstrip())
+ if composition_provenance:
+ sections.append(
+ "\n".join(
+ (
+ "## Composition provenance",
+ "",
+ f"- Spec: `{composition_provenance['spec_path']}`",
+ f"- Spec SHA-256: `{composition_provenance['spec_sha256']}`",
+ f"- Validated experiment inputs: {composition_provenance['input_count']}",
+ "- Per-input paths and SHA-256 values are retained in the sidecar manifest.",
+ )
+ )
+ )
+ markdown = "\n\n".join(sections) + "\n"
+ if args.out:
+ output = Path(args.out).expanduser()
+ atomic_write_text(output, markdown)
+ if composition_provenance:
+ manifest_output = output.with_name(output.name + ".manifest.json")
+ atomic_write_text(
+ manifest_output,
+ json.dumps(composition_provenance, indent=2, sort_keys=True) + "\n",
+ )
+ print(markdown, end="")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/benchmarks/terminology.json b/benchmarks/terminology.json
new file mode 100644
index 000000000..20fee5c93
--- /dev/null
+++ b/benchmarks/terminology.json
@@ -0,0 +1,2350 @@
+{
+ "$schema": "benchmarks/schema/terminology.schema.json",
+ "entries": [
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A benchmark run is one execution of the measured product operation with one resolved implementation, capability, scope, and cache manifest.",
+ "deprecated_replacement": null,
+ "display_name": "Benchmark Run",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "benchmark_run",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A repetition is one independently started benchmark run in a cell; repetitions share the cell configuration but not mutable process state unless the cache manifest says otherwise.",
+ "deprecated_replacement": null,
+ "display_name": "Repetition",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "repetition",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A benchmark cell is the set of repetitions that share one declared implementation, workload, effective capability manifest, scope manifest, cache manifest, and correctness contract.",
+ "deprecated_replacement": null,
+ "display_name": "Benchmark Cell",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "benchmark_cell",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A user lifecycle is one user-visible operation measured between two harness-owned monotonic boundary events.",
+ "deprecated_replacement": null,
+ "display_name": "User Lifecycle",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "user_lifecycle",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A step is a registry-defined kind of work performed during a benchmark run.",
+ "deprecated_replacement": null,
+ "display_name": "Step",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "step",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A step occurrence is one execution of a step; every repeated or concurrent occurrence has its own occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Step Occurrence",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "step_occurrence",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A parent relation records structural nesting between two step occurrences and does not by itself impose execution order.",
+ "deprecated_replacement": null,
+ "display_name": "Parent Relation",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "parent_relation",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A dependency relation records that one step occurrence must reach a named event before another occurrence can proceed.",
+ "deprecated_replacement": null,
+ "display_name": "Dependency Relation",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "dependency_relation",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A benchmark result is one recorded correctness, freshness, retrieval, ranking, semantic-quality, skip, error, or product-failure outcome for a benchmark run.",
+ "deprecated_replacement": null,
+ "display_name": "Benchmark Result",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "benchmark_result",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A retained artifact is one benchmark input or output identified by path, content hash, schema version, terminology version, and cleanup state.",
+ "deprecated_replacement": null,
+ "display_name": "Retained Artifact",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "retained_artifact",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "An implementation identity is the source revision, binary hash, and build manifest of the compared executable.",
+ "deprecated_replacement": null,
+ "display_name": "Implementation Identity",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "implementation_identity",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A production build is an executable built with the shipped optimization, sanitizer, and feature flags recorded in its build manifest.",
+ "deprecated_replacement": null,
+ "display_name": "Production Build",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "production_build",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "enabled, disabled, unsupported, or an exact enumerated/numeric value",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines parity eligibility and the work/correctness contract",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "per-call override > environment > persistent config > preset > compiled default",
+ "data_type": "capability record or categorical state",
+ "definition": "A capability is one separately observable product behavior.",
+ "deprecated_replacement": null,
+ "display_name": "Capability",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "capability_state",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "capability",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "enabled, disabled, unsupported, or an exact enumerated/numeric value",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines parity eligibility and the work/correctness contract",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "per-call override > environment > persistent config > preset > compiled default",
+ "data_type": "capability record or categorical state",
+ "definition": "An effective capability value is selected after applying default, preset, persistent-config, environment, and per-call precedence; its winning source is recorded.",
+ "deprecated_replacement": null,
+ "display_name": "Effective Capability Value",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "capability_state",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "effective_capability_value",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "enabled, disabled, unsupported, or an exact enumerated/numeric value",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines parity eligibility and the work/correctness contract",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "per-call override > environment > persistent config > preset > compiled default",
+ "data_type": "capability record or categorical state",
+ "definition": "An enabled capability is implemented by the measured executable and active for the benchmark run.",
+ "deprecated_replacement": null,
+ "display_name": "Enabled Capability",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "capability_state",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "enabled_capability",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "enabled, disabled, unsupported, or an exact enumerated/numeric value",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines parity eligibility and the work/correctness contract",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "per-call override > environment > persistent config > preset > compiled default",
+ "data_type": "capability record or categorical state",
+ "definition": "A disabled capability is implemented by the measured executable but inactive for the benchmark run.",
+ "deprecated_replacement": null,
+ "display_name": "Disabled Capability",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "capability_state",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "disabled_capability",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "enabled, disabled, unsupported, or an exact enumerated/numeric value",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines parity eligibility and the work/correctness contract",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "per-call override > environment > persistent config > preset > compiled default",
+ "data_type": "capability record or categorical state",
+ "definition": "An unsupported capability is unavailable in the measured executable; missing capability metadata instead makes the benchmark record invalid.",
+ "deprecated_replacement": null,
+ "display_name": "Unsupported Capability",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "capability_state",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "unsupported_capability",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A scope manifest identifies every included repository, dependency package, file and byte count, language, generated-source policy, and exclusion.",
+ "deprecated_replacement": null,
+ "display_name": "Scope Manifest",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "scope_manifest",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A cache manifest records the state and reset procedure for every named cache layer; the report does not use an unqualified cold or warm label.",
+ "deprecated_replacement": null,
+ "display_name": "Cache Manifest",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "cache_manifest",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "A core graph contains the source-derived nodes, edges, properties, and file hashes that remain after removing only the optional derived views explicitly listed in the benchmark result.",
+ "deprecated_replacement": null,
+ "display_name": "Core Graph",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "core_graph",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "A core answer is a task answer computed from a core graph whose source generation matches the latest successful source publication.",
+ "deprecated_replacement": null,
+ "display_name": "Core Answer",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "core_answer",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "A derived view is named data recomputed from the source graph.",
+ "deprecated_replacement": null,
+ "display_name": "Derived View",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "derived_view",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "A source generation is the monotonic identifier assigned to one successful publication of source-derived graph data.",
+ "deprecated_replacement": null,
+ "display_name": "Source Generation",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "source_generation",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "A view generation is the source generation used to compute one named derived view.",
+ "deprecated_replacement": null,
+ "display_name": "View Generation",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "view_generation",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "A fresh view is a derived view whose view generation equals the latest successfully published source generation at the measured endpoint.",
+ "deprecated_replacement": null,
+ "display_name": "Fresh View",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "fresh_view",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "A stale view is a derived view whose view generation precedes the latest successfully published source generation.",
+ "deprecated_replacement": null,
+ "display_name": "Stale View",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "stale_view",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "An eager refresh computes and publishes the named derived view before the measured endpoint returns.",
+ "deprecated_replacement": null,
+ "display_name": "Eager Refresh",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "eager_refresh",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "A deferred refresh leaves the named derived view stale at the measured endpoint and reports its stale state and generation.",
+ "deprecated_replacement": null,
+ "display_name": "Deferred Refresh",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "deferred_refresh",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "A requested-fresh endpoint occurs when the core graph and every enabled derived view required by the named task are fresh.",
+ "deprecated_replacement": null,
+ "display_name": "Requested Fresh Endpoint",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "requested_fresh_endpoint",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "An all-fresh endpoint occurs when the core graph and every enabled derived view in the effective capability manifest are fresh.",
+ "deprecated_replacement": null,
+ "display_name": "All Fresh Endpoint",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "all_fresh_endpoint",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "A correctness contract specifies the graph rows, properties, hashes, freshness states, task outcomes, and allowed exclusions that a benchmark result must satisfy.",
+ "deprecated_replacement": null,
+ "display_name": "Correctness Contract",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "correctness_contract",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "A clean-rebuild graph oracle is the canonically normalized graph produced from an empty store using the same source snapshot, effective capability manifest, and scope manifest as the compared run.",
+ "deprecated_replacement": null,
+ "display_name": "Clean Rebuild Graph Oracle",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "clean_rebuild_graph_oracle",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the recorded correctness contract",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "determines whether a lifecycle reached core, requested-fresh, or all-fresh completion",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "freshness, generation, oracle, or endpoint record",
+ "definition": "Graph equality means equality under the recorded canonicalization version and does not require byte-identical SQLite files.",
+ "deprecated_replacement": null,
+ "display_name": "Graph Equality",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "graph_equality",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "derive only from source run, result, and step IDs retained in the record",
+ "allowed_values_or_range": "one comparison whose join and formula identifiers are recorded",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "comparison record",
+ "definition": "A parity comparison compares two benchmark cells whose effective capabilities, input and scope policies, per-layer cache states, timer boundaries, freshness endpoints, and correctness contracts are identical.",
+ "deprecated_replacement": null,
+ "display_name": "Parity Comparison",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "comparison_kind",
+ "missing_or_unsupported_behavior": "reject the comparison when a required join field is unknown",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "parity_comparison",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "derive only from source run, result, and step IDs retained in the record",
+ "allowed_values_or_range": "one comparison whose join and formula identifiers are recorded",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "comparison record",
+ "definition": "A shared-work projection compares the explicitly named intersection of work supported by two implementations and is not whole-product parity.",
+ "deprecated_replacement": null,
+ "display_name": "Shared Work Projection",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "comparison_kind",
+ "missing_or_unsupported_behavior": "reject the comparison when a required join field is unknown",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "shared_work_projection",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "derive only from source run, result, and step IDs retained in the record",
+ "allowed_values_or_range": "one comparison whose join and formula identifiers are recorded",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "comparison record",
+ "definition": "A capability-delta comparison compares cells with an explicitly named capability difference and reports the added or removed work, quality, coverage, and resource cost without a cross-implementation speed ratio.",
+ "deprecated_replacement": null,
+ "display_name": "Capability Delta Comparison",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "comparison_kind",
+ "missing_or_unsupported_behavior": "reject the comparison when a required join field is unknown",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "capability_delta_comparison",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A timer boundary is a registry-defined event, owned by the harness or a named process, that starts or ends a duration.",
+ "deprecated_replacement": null,
+ "display_name": "Timer Boundary",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "timer_boundary",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only occurrence sets selected by an emitted formula; lifecycle wall time is always outer end minus outer start",
+ "allowed_values_or_range": "0 or greater",
+ "boundary_semantics": "the registered start event through the registered end event",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "the named monotonic clock and thread, process, process-tree, or harness scope",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "A step occurrence's elapsed time is its monotonic end timestamp minus its monotonic start timestamp.",
+ "deprecated_replacement": null,
+ "display_name": "Elapsed Time",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "elapsed_time",
+ "unit": "milliseconds in fact tables; source clocks use nanoseconds"
+ },
+ {
+ "aggregation_rule": "aggregate only occurrence sets selected by an emitted formula; lifecycle wall time is always outer end minus outer start",
+ "allowed_values_or_range": "0 or greater",
+ "boundary_semantics": "the registered start event through the registered end event",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "the named monotonic clock and thread, process, process-tree, or harness scope",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "A user lifecycle's wall time is its harness-owned end boundary minus its harness-owned start boundary.",
+ "deprecated_replacement": null,
+ "display_name": "Lifecycle Wall Time",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "lifecycle_wall_time",
+ "unit": "milliseconds in fact tables; source clocks use nanoseconds"
+ },
+ {
+ "aggregation_rule": "aggregate only occurrence sets selected by an emitted formula; lifecycle wall time is always outer end minus outer start",
+ "allowed_values_or_range": "0 or greater",
+ "boundary_semantics": "the registered start event through the registered end event",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "the named monotonic clock and thread, process, process-tree, or harness scope",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "Work time is the sum of selected step-occurrence elapsed times and may exceed lifecycle wall time when occurrences overlap.",
+ "deprecated_replacement": null,
+ "display_name": "Work Time",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "work_time",
+ "unit": "milliseconds in fact tables; source clocks use nanoseconds"
+ },
+ {
+ "aggregation_rule": "aggregate only occurrence sets selected by an emitted formula; lifecycle wall time is always outer end minus outer start",
+ "allowed_values_or_range": "0 or greater",
+ "boundary_semantics": "the registered start event through the registered end event",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "the named monotonic clock and thread, process, process-tree, or harness scope",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "CPU time is processor execution time measured for a named thread, process, or child-process set.",
+ "deprecated_replacement": null,
+ "display_name": "Cpu Time",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "cpu_time",
+ "unit": "milliseconds in fact tables; source clocks use nanoseconds"
+ },
+ {
+ "aggregation_rule": "aggregate only occurrence sets selected by an emitted formula; lifecycle wall time is always outer end minus outer start",
+ "allowed_values_or_range": "0 or greater",
+ "boundary_semantics": "the registered start event through the registered end event",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "the named monotonic clock and thread, process, process-tree, or harness scope",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "A step occurrence's queue wait is its worker-start timestamp minus its enqueue timestamp.",
+ "deprecated_replacement": null,
+ "display_name": "Queue Wait",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "queue_wait",
+ "unit": "milliseconds in fact tables; source clocks use nanoseconds"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "Two step occurrences overlap when their monotonic execution intervals intersect.",
+ "deprecated_replacement": null,
+ "display_name": "Overlap",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "overlap",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A user lifecycle's critical path is the longest-duration path through its explicit dependency relations.",
+ "deprecated_replacement": null,
+ "display_name": "Critical Path",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "critical_path",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "0 or greater; ratio denominators must be nonzero",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "Parallelism is the number of step occurrences actively executing during a declared monotonic interval.",
+ "deprecated_replacement": null,
+ "display_name": "Parallelism",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "parallelism",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "0 or greater; ratio denominators must be nonzero",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "Worker utilization is active worker time divided by available worker time for a named worker pool and interval.",
+ "deprecated_replacement": null,
+ "display_name": "Worker Utilization",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "worker_utilization",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "peak uses max; delta uses end minus start; never add peaks",
+ "allowed_values_or_range": "peak_rss is nonnegative; rss_delta may be negative",
+ "boundary_semantics": "the registered lifecycle or step sampling boundaries",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "the named process or process-tree sampling interval",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "number",
+ "definition": "Peak resident set size is the largest resident-memory sample observed for the named process set within declared boundaries.",
+ "deprecated_replacement": null,
+ "display_name": "Peak RSS",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "peak_rss",
+ "unit": "MiB"
+ },
+ {
+ "aggregation_rule": "peak uses max; delta uses end minus start; never add peaks",
+ "allowed_values_or_range": "peak_rss is nonnegative; rss_delta may be negative",
+ "boundary_semantics": "the registered lifecycle or step sampling boundaries",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "the named process or process-tree sampling interval",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "number",
+ "definition": "Resident-set delta is end-boundary RSS minus start-boundary RSS for the named process set.",
+ "deprecated_replacement": null,
+ "display_name": "RSS delta",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "rss_delta",
+ "unit": "MiB"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "0 or greater; ratio denominators must be nonzero",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "A ratio is a named numerator divided by a named nonzero denominator under one declared comparison contract.",
+ "deprecated_replacement": null,
+ "display_name": "Ratio",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "ratio",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "0 or greater; ratio denominators must be nonzero",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "A speedup is baseline duration divided by candidate duration under one declared parity or shared-work-projection contract; values above 1 mean the candidate completed faster.",
+ "deprecated_replacement": null,
+ "display_name": "Speedup",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "speedup",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "apply only the versioned estimator to one declared repetition set",
+ "allowed_values_or_range": "values permitted by the measured quantity",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "number or bounded interval",
+ "definition": "A median is the versioned 50th-percentile estimator over the recorded repetitions in one benchmark cell.",
+ "deprecated_replacement": null,
+ "display_name": "Median",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "median",
+ "unit": "the unit of the measured quantity"
+ },
+ {
+ "aggregation_rule": "apply only the versioned estimator to one declared repetition set",
+ "allowed_values_or_range": "values permitted by the measured quantity",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "number or bounded interval",
+ "definition": "A p95 value is the versioned 95th-percentile estimator over the recorded repetitions in one benchmark cell.",
+ "deprecated_replacement": null,
+ "display_name": "p95",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "p95",
+ "unit": "the unit of the measured quantity"
+ },
+ {
+ "aggregation_rule": "apply only the versioned estimator to one declared repetition set",
+ "allowed_values_or_range": "values permitted by the measured quantity",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "number or bounded interval",
+ "definition": "A confidence interval is the interval produced by the recorded statistical method, confidence level, and repetition set for one estimator.",
+ "deprecated_replacement": null,
+ "display_name": "Confidence Interval",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "confidence_interval",
+ "unit": "the unit of the measured quantity"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "0 or greater; ratio denominators must be nonzero",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "Mean reciprocal rank is the mean of 1/rank for the first correct returned entity in each applicable retrieval task; higher is better and 1 means every correct entity ranked first.",
+ "deprecated_replacement": null,
+ "display_name": "MRR",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "quality_metric",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "mrr",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "0 or greater; ratio denominators must be nonzero",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "Hit@k is the fraction of applicable retrieval tasks whose named correct entity appears within the first k returned entities; higher is better.",
+ "deprecated_replacement": null,
+ "display_name": "Hit@k",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "quality_metric",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "hit_at_k",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "0 or greater; ratio denominators must be nonzero",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "Normalized discounted cumulative gain at k scores the order of judged returned entities within the first k positions against the ideal order; higher is better and 1 is ideal.",
+ "deprecated_replacement": null,
+ "display_name": "nDCG@k",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "quality_metric",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "ndcg_at_k",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "0 or greater; ratio denominators must be nonzero",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "Semantic Pair F1 is the harmonic mean of precision and recall over the explicitly judged SEMANTICALLY_RELATED code-entity pairs; higher is better and 1 means none are missing or spurious.",
+ "deprecated_replacement": null,
+ "display_name": "Semantic Pair F1",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "quality_metric",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "semantic_pair_f1",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "0 or greater; ratio denominators must be nonzero",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "Task success is the fraction of applicable named tasks that return their required entity or evidence under the task's recorded acceptance rule.",
+ "deprecated_replacement": null,
+ "display_name": "Task Success",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "quality_metric",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "task_success",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "An invalid benchmark record is measurement evidence rejected because its instrumentation, schema, terminology, or oracle requirements failed.",
+ "deprecated_replacement": null,
+ "display_name": "Invalid Benchmark Record",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "invalid_benchmark_record",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A product failure occurs when the indexed or query operation violates its recorded product contract or returns a failing product status.",
+ "deprecated_replacement": null,
+ "display_name": "Product Failure",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "product_failure",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "Observer effect is the latency, CPU, or memory difference caused by instrumentation, measured against profiler-off cells using the same executable and workload.",
+ "deprecated_replacement": null,
+ "display_name": "Observer Effect",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "observer_effect",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "Generated source is machine-produced or vendored source selected by an explicit recorded policy.",
+ "deprecated_replacement": null,
+ "display_name": "Generated Source",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "generated_source",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A semantic vector is the recorded numeric representation of one code entity used by the semantic-similarity algorithm.",
+ "deprecated_replacement": null,
+ "display_name": "Semantic Vector",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "algorithm_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "semantic_vector",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A locality-sensitive-hashing index groups semantic vectors into candidate buckets so the semantic pass need not compare every pair.",
+ "deprecated_replacement": null,
+ "display_name": "LSH index",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "algorithm_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "lsh_index",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "PageRank is the configured graph-centrality score computed from incoming weighted graph links. The same `pagerank` registry ID identifies each measured occurrence of that work; repeated or concurrent occurrences have distinct occurrence IDs.",
+ "deprecated_replacement": null,
+ "display_name": "PageRank",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "pagerank",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "LinkRank is the configured edge score derived from stationary flow between graph nodes. The same `linkrank` registry ID identifies each measured occurrence of that work; repeated or concurrent occurrences have distinct occurrence IDs.",
+ "deprecated_replacement": null,
+ "display_name": "LinkRank",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "linkrank",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "Node degree is the configured weighted, unweighted, or calls-only connection count for one graph node.",
+ "deprecated_replacement": null,
+ "display_name": "Node Degree",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "algorithm_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "node_degree",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "Graph publication is the transaction that makes computed node, edge, property, index, and generation changes visible in the persistent store.",
+ "deprecated_replacement": null,
+ "display_name": "Graph Publication",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "algorithm_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "graph_publication",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "Dependency artifact reuse loads a previously computed dependency graph only when package identity, source hash, parser version, config and schema version, and capability set all match.",
+ "deprecated_replacement": null,
+ "display_name": "Dependency Artifact Reuse",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "algorithm_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "dependency_artifact_reuse",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "Existing behavior is behavior present at the cited source revision and verified at the cited code or experiment anchor.",
+ "deprecated_replacement": null,
+ "display_name": "Existing Behavior",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "evidence_status",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "existing_behavior",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "must not be aggregated unless a referenced formula defines the operation",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "Proposed behavior is design work described by this plan but not implemented at the cited source revision.",
+ "deprecated_replacement": null,
+ "display_name": "Proposed Behavior",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "evidence_status",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/schema/facts-v2.schema.json",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "proposed_behavior",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `startup`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `startup` step ID identifies one occurrence of startup work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Startup",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "startup",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `project_discovery`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `project_discovery` step ID identifies one occurrence of project discovery work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Project Discovery",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "project_discovery",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `change_classification`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `change_classification` step ID identifies one occurrence of change classification work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Change Classification",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "change_classification",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `parse_extract`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `parse_extract` step ID identifies one occurrence of parse extract work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Parse Extract",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "parse_extract",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `exact_delta`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `exact_delta` step ID identifies one occurrence of exact delta work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Exact Delta",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "exact_delta",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `semantic_vectors`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `semantic_vectors` step ID identifies one occurrence of semantic vectors work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Semantic Vectors",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "semantic_vectors",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `semantic_lsh`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `semantic_lsh` step ID identifies one occurrence of semantic lsh work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Semantic Lsh",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "semantic_lsh",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `semantic_pairs`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `semantic_pairs` step ID identifies one occurrence of semantic pairs work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Semantic Pairs",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "semantic_pairs",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `graph_publish_delete`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `graph_publish_delete` step ID identifies one occurrence of graph publish delete work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Graph Publish Delete",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "graph_publish_delete",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `graph_publish_upsert`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `graph_publish_upsert` step ID identifies one occurrence of graph publish upsert work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Graph Publish Upsert",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "graph_publish_upsert",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `graph_publish_indexes`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `graph_publish_indexes` step ID identifies one occurrence of graph publish indexes work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Graph Publish Indexes",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "graph_publish_indexes",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `dependency_discovery`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `dependency_discovery` step ID identifies one occurrence of dependency discovery work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Dependency Discovery",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "dependency_discovery",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `dependency_package_index`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `dependency_package_index` step ID identifies one occurrence of dependency package index work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "Dependency Package Index",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "dependency_package_index",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `first_core_query`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `first_core_query` step ID identifies one occurrence of first core query work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "First Core Query",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "first_core_query",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "aggregate only distinct occurrence IDs selected by an emitted formula",
+ "allowed_values_or_range": "exactly `first_all_fresh_query`",
+ "boundary_semantics": "the occurrence's registered start and end events",
+ "capability_or_freshness_implications": "the enclosing run records the capability and freshness contract; the step ID alone implies neither",
+ "clock_or_cpu_scope": "the thread, worker, process, or harness recorded on each occurrence",
+ "concurrency_rule": "overlapping occurrences remain separate and are not summed into lifecycle wall time",
+ "configuration_precedence": "profiling level and benchmark specification select whether this step is emitted",
+ "data_type": "stable string identifier",
+ "definition": "The `first_all_fresh_query` step ID identifies one occurrence of first all fresh query work; each repeated or concurrent occurrence has a distinct occurrence ID.",
+ "deprecated_replacement": null,
+ "display_name": "First All Fresh Query",
+ "examples": [],
+ "introduced_version": "1.0.0",
+ "kind": "step_id",
+ "missing_or_unsupported_behavior": "omit no required occurrence; mark the benchmark record invalid if detail collection overflows",
+ "source_anchors": [
+ "src/foundation/profile.h",
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "proposed",
+ "term_id": "first_all_fresh_query",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "not_applicable",
+ "allowed_values_or_range": "exactly `parity_manifest_and_contract_v1`",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "requires identical effective capability, scope, cache, host, benchmark-contract, and correctness-contract records",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; compared durations retain their recorded occurrence structure",
+ "configuration_precedence": "not_applicable",
+ "data_type": "stable string identifier",
+ "definition": "The `parity_manifest_and_contract_v1` join ID selects two cells only when mode, effective capabilities, scope, cache state, host, benchmark contract, and correctness contract are canonically equal, both capability manifests are complete, and no required manifest value is unknown.",
+ "deprecated_replacement": null,
+ "display_name": "Parity Manifest and Contract Join v1",
+ "examples": [],
+ "introduced_version": "1.1.0",
+ "kind": "join_id",
+ "missing_or_unsupported_behavior": "classify the pair as not eligible and emit no ratio",
+ "source_anchors": [
+ "benchmarks/schema/comparisons-v1.schema.json",
+ "benchmarks/fact_comparisons.py"
+ ],
+ "status": "existing",
+ "term_id": "parity_manifest_and_contract_v1",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "not_applicable",
+ "allowed_values_or_range": "exactly `capability_delta_manifest_v1`",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "requires one or more explicitly recorded capability differences",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; compared durations retain their recorded occurrence structure",
+ "configuration_precedence": "not_applicable",
+ "data_type": "stable string identifier",
+ "definition": "The `capability_delta_manifest_v1` join ID selects two cells only when mode, scope, cache state, host, benchmark contract, and correctness contract are canonically equal, both capability manifests are complete, and at least one effective capability differs; it never authorizes a cross-implementation speed ratio.",
+ "deprecated_replacement": null,
+ "display_name": "Capability Delta Manifest Join v1",
+ "examples": [],
+ "introduced_version": "1.1.0",
+ "kind": "join_id",
+ "missing_or_unsupported_behavior": "classify the pair as not eligible when required equal fields differ or either capability manifest is incomplete",
+ "source_anchors": [
+ "benchmarks/schema/comparisons-v1.schema.json",
+ "benchmarks/fact_comparisons.py"
+ ],
+ "status": "existing",
+ "term_id": "capability_delta_manifest_v1",
+ "unit": "not_applicable"
+ },
+ {
+ "aggregation_rule": "apply to all recorded elapsed_ms values for one step ID in one exact cell group",
+ "allowed_values_or_range": "exactly `median_elapsed_ms_v1`",
+ "boundary_semantics": "uses each source occurrence's registered monotonic start and end boundaries",
+ "capability_or_freshness_implications": "none beyond the enclosing cell manifest",
+ "clock_or_cpu_scope": "wall time for each named occurrence",
+ "concurrency_rule": "does not sum overlapping occurrences; it takes the median of the selected occurrence durations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "stable string identifier",
+ "definition": "The `median_elapsed_ms_v1` formula ID sorts the selected elapsed_ms values and returns the middle value for an odd count or the arithmetic mean of the two middle values for an even count.",
+ "deprecated_replacement": null,
+ "display_name": "Median Elapsed Milliseconds Formula v1",
+ "examples": [],
+ "introduced_version": "1.1.0",
+ "kind": "formula_id",
+ "missing_or_unsupported_behavior": "omit the aggregate when no numeric elapsed_ms occurrence is recorded",
+ "source_anchors": [
+ "benchmarks/schema/comparisons-v1.schema.json",
+ "benchmarks/fact_comparisons.py"
+ ],
+ "status": "existing",
+ "term_id": "median_elapsed_ms_v1",
+ "unit": "milliseconds"
+ },
+ {
+ "aggregation_rule": "divide the left cell's median_elapsed_ms_v1 result by the right cell's median_elapsed_ms_v1 result for the same step ID",
+ "allowed_values_or_range": "exactly `left_elapsed_divided_by_right_elapsed_v1`",
+ "boundary_semantics": "inherits the source occurrences used by both median operands",
+ "capability_or_freshness_implications": "valid only for a parity_manifest_and_contract_v1 join",
+ "clock_or_cpu_scope": "ratio of wall-time medians",
+ "concurrency_rule": "does not sum component durations; both operands preserve their recorded occurrence boundaries",
+ "configuration_precedence": "not_applicable",
+ "data_type": "stable string identifier",
+ "definition": "The `left_elapsed_divided_by_right_elapsed_v1` formula ID divides the left cell's median elapsed milliseconds by the right cell's median elapsed milliseconds for the same step ID; values above 1 mean the left cell took longer.",
+ "deprecated_replacement": null,
+ "display_name": "Left/Right Elapsed Ratio Formula v1",
+ "examples": [],
+ "introduced_version": "1.1.0",
+ "kind": "formula_id",
+ "missing_or_unsupported_behavior": "emit null when the right median is zero and emit no ratio unless the pair passed the parity join",
+ "source_anchors": [
+ "benchmarks/schema/comparisons-v1.schema.json",
+ "benchmarks/fact_comparisons.py"
+ ],
+ "status": "existing",
+ "term_id": "left_elapsed_divided_by_right_elapsed_v1",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "0 to 1 inclusive",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "Scaffolding@K is the fraction of a score's top K ranked symbols whose file is labeled a test by a source independent of this server: the project's own declared test configuration or the language toolchain's rule. It is null when no independent labels were supplied, and is never inferred from this server's own test predicates, because those predicates are the thing under measurement.",
+ "deprecated_replacement": null,
+ "display_name": "scaffolding@K",
+ "examples": [],
+ "introduced_version": "1.2.0",
+ "kind": "quality_metric",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/run_benchmark.py",
+ "benchmarks/generate_test_labels.py"
+ ],
+ "status": "existing",
+ "term_id": "scaffolding_at_k",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "0 to 1 inclusive",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "Utility contamination@K is the fraction of a score's top K ranked symbols that are logging, formatting or allocation utilities, matched on whole identifier tokens rather than substrings. It tests the objection that a graph score surfaces utility popularity rather than architectural importance.",
+ "deprecated_replacement": null,
+ "display_name": "utility contamination@K",
+ "examples": [],
+ "introduced_version": "1.2.0",
+ "kind": "quality_metric",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "utility_contamination_at_k",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "0 to 1 inclusive",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "nonnegative number",
+ "definition": "Silent drop rate is the fraction of a corpus's source files present under one index mode and absent under another, attributed to the directory name that excluded them. It quantifies coverage lost to built-in skip lists without any diagnostic in the response.",
+ "deprecated_replacement": null,
+ "display_name": "silent drop rate",
+ "examples": [],
+ "introduced_version": "1.2.0",
+ "kind": "quality_metric",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/run_benchmark.py",
+ "src/discover/discover.c"
+ ],
+ "status": "existing",
+ "term_id": "silent_drop_rate",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "Rank score staleness records whether the pagerank, linkrank and node_degree derived views were current when a ranking measurement ran, taking the union of views the tool responses declared stale and views the freshness ledger persisted as stale. A ranking number measured while these are stale describes the degree fallback rather than the requested score.",
+ "deprecated_replacement": null,
+ "display_name": "rank score staleness",
+ "examples": [],
+ "introduced_version": "1.2.0",
+ "kind": "freshness_and_correctness",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/run_benchmark.py",
+ "src/store/store.c"
+ ],
+ "status": "existing",
+ "term_id": "rank_score_staleness",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "Repetition stability is the set of result counts observed when one query is repeated against a fixed index, and whether they all agree. It detects calls that non-deterministically return results and zero results without any change to the index.",
+ "deprecated_replacement": null,
+ "display_name": "repetition stability",
+ "examples": [],
+ "introduced_version": "1.2.0",
+ "kind": "measurement",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "repetition_stability",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A behavioral-only probe is a battery query carrying no relevance judgments. It is excluded from rank-quality aggregates because no ground truth defines a correct answer, while still recording result count, latency and payload size.",
+ "deprecated_replacement": null,
+ "display_name": "behavioral-only probe",
+ "examples": [],
+ "introduced_version": "1.2.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "behavioral_only_probe",
+ "unit": "dimensionless"
+ },
+ {
+ "aggregation_rule": "use the formula and repetition estimator recorded with the result",
+ "allowed_values_or_range": "values defined by the referenced benchmark schema",
+ "boundary_semantics": "not_applicable",
+ "capability_or_freshness_implications": "none beyond the term's normative definition",
+ "clock_or_cpu_scope": "not_applicable",
+ "concurrency_rule": "does not imply serial execution; use recorded occurrence intervals and dependency relations",
+ "configuration_precedence": "not_applicable",
+ "data_type": "object or categorical record",
+ "definition": "A reply detail profile is a named set of response-size configuration values such as search_limit and snippet_max_lines, applied so retrieval quality can be reported per response token rather than per query alone.",
+ "deprecated_replacement": null,
+ "display_name": "reply detail profile",
+ "examples": [],
+ "introduced_version": "1.2.0",
+ "kind": "benchmark_concept",
+ "missing_or_unsupported_behavior": "record an explicit unknown fact; do not infer the value from a label or preset",
+ "source_anchors": [
+ "benchmarks/run_benchmark.py"
+ ],
+ "status": "existing",
+ "term_id": "reply_detail_profile",
+ "unit": "dimensionless"
+ }
+ ],
+ "schema_version": 1,
+ "step_id_order": [
+ "startup",
+ "project_discovery",
+ "change_classification",
+ "parse_extract",
+ "exact_delta",
+ "semantic_vectors",
+ "semantic_lsh",
+ "semantic_pairs",
+ "graph_publish_delete",
+ "graph_publish_upsert",
+ "graph_publish_indexes",
+ "dependency_discovery",
+ "dependency_package_index",
+ "pagerank",
+ "linkrank",
+ "first_core_query",
+ "first_all_fresh_query"
+ ],
+ "terminology_version": "1.2.0"
+}
diff --git a/benchmarks/test_rank_quality.py b/benchmarks/test_rank_quality.py
new file mode 100644
index 000000000..d85c0c32f
--- /dev/null
+++ b/benchmarks/test_rank_quality.py
@@ -0,0 +1,2114 @@
+#!/usr/bin/env python3
+"""Tests for the rank-quality campaign additions to the benchmark harness.
+
+Run: python3 benchmarks/test_rank_quality.py (no pytest required)
+ python3 -m pytest benchmarks/test_rank_quality.py -q
+
+Scope: the campaign code only. Each test names the defect it guards, because several of
+these exist because that exact defect shipped and had to be found by audit rather than
+by a test.
+"""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import importlib.util
+import json
+import math
+import sqlite3
+import statistics
+import subprocess
+import sys
+import tempfile
+from pathlib import Path
+from typing import Any
+
+BENCHMARKS = Path(__file__).resolve().parent
+
+
+def _load(name: str) -> Any:
+ spec = importlib.util.spec_from_file_location(name, BENCHMARKS / f"{name}.py")
+ module = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(module)
+ return module
+
+
+rb = _load("run_benchmark")
+sr = _load("summarize_results")
+re_ = _load("run_experiments")
+rc = _load("run_container_experiment")
+cs = _load("campaign_specs")
+rr = _load("rank_report")
+gl = _load("generate_test_labels")
+
+QUERY_MANIFEST = str(BENCHMARKS / "rank-queries-v1" / "manifest.json")
+
+
+def make_rank_db(
+ directory: Path,
+ rows: list[tuple[str, str, int, float]],
+ labels: list[str] | None = None,
+) -> None:
+ """Minimal project DB with the three ranking tables and an importance property.
+
+ Column order and the label column mirror src/store/store.c:552-563 so a probe that
+ works here works against a real database.
+ """
+ connection = sqlite3.connect(directory / ("p" + rb.PROJECT_DB_SUFFIX))
+ connection.executescript(
+ "CREATE TABLE nodes(id INTEGER PRIMARY KEY, project TEXT, label TEXT,"
+ " name TEXT, qualified_name TEXT,"
+ " file_path TEXT, properties TEXT DEFAULT '{}');"
+ "CREATE TABLE pagerank(node_id INTEGER, project TEXT, rank REAL);"
+ "CREATE TABLE edges(id INTEGER PRIMARY KEY, project TEXT, source_id INT,"
+ " target_id INT, type TEXT, properties TEXT DEFAULT '{}');"
+ "CREATE TABLE linkrank(edge_id INTEGER, project TEXT, rank REAL);"
+ "CREATE TABLE node_degree(node_id INTEGER, project TEXT, total_in INT,"
+ " total_out INT, calls_in INT, calls_out INT, weighted_in REAL,"
+ " weighted_out REAL, linkrank_in REAL);"
+ )
+ for index, (qualified_name, file_path, degree, rank) in enumerate(rows, start=1):
+ label = (labels or ["Function"] * len(rows))[index - 1]
+ connection.execute(
+ "INSERT INTO nodes VALUES(?,?,?,?,?,?,?)",
+ (
+ index,
+ "p",
+ label,
+ qualified_name.rsplit(".", 1)[-1],
+ qualified_name,
+ file_path,
+ json.dumps({"importance": rank / 10}),
+ ),
+ )
+ connection.execute("INSERT INTO pagerank VALUES(?,?,?)", (index, "p", rank))
+ connection.execute(
+ "INSERT INTO node_degree VALUES(?,?,?,?,?,?,?,?,?)",
+ (index, "p", degree, 1, degree, 1, rank, rank / 2, rank / 3),
+ )
+ if index > 1:
+ connection.execute(
+ "INSERT INTO edges VALUES(?,?,?,?,?,?)",
+ (index - 1, "p", index, 1, "CALLS", "{}"),
+ )
+ connection.execute(
+ "INSERT INTO linkrank VALUES(?,?,?)", (index - 1, "p", rank / 4)
+ )
+ connection.commit()
+ connection.close()
+
+
+# --- config-key allowlist -------------------------------------------------------
+
+
+def test_unknown_config_key_is_rejected_at_parse_time() -> None:
+ """Guards: cbm_config_value_is_valid accepts unknown keys, so a typo would run
+ to completion and report a difference of exactly zero."""
+ profile = "automatic_dependency_source_indexing_disabled"
+ try:
+ rb.resolve_config_overrides(profile, ["edge_weight_tsets=0.01"])
+ except ValueError as error:
+ assert "edge_weight_tsets" in str(error)
+ else:
+ raise AssertionError("typo'd config key was accepted")
+ assert (
+ rb.resolve_config_overrides(profile, ["edge_weight_tests=0.01"])[
+ "edge_weight_tests"
+ ]
+ == "0.01"
+ )
+
+
+def test_config_validation_raises_value_error_not_system_exit() -> None:
+ """Guards: SystemExit is a BaseException and would slip past the harness's
+ except-Exception handlers, emitting a report with no error recorded."""
+ try:
+ rb.validate_config_overrides({"definitely_not_a_key": "1"})
+ except ValueError:
+ pass
+ except SystemExit:
+ raise AssertionError("validation raised SystemExit; it escapes error recording")
+
+
+def test_capability_sets_agree_across_the_two_entry_points() -> None:
+ """run_benchmark.py and run_experiments.py do not import each other, so the shared
+ capability set is duplicated. The plan layer rejecting a spec the benchmark layer
+ would accept (or vice versa) fails a runset hours in, so assert they match here
+ rather than trusting a keep-in-sync comment."""
+ assert rb.QUALITY_BACKGROUND_CAPABILITIES == re_.QUALITY_BACKGROUND_CAPABILITIES, (
+ rb.QUALITY_BACKGROUND_CAPABILITIES,
+ re_.QUALITY_BACKGROUND_CAPABILITIES,
+ )
+ assert "rank" in rb.QUALITY_BACKGROUND_CAPABILITIES
+
+
+def test_allowlist_covers_every_tunable_knob() -> None:
+ for key in (
+ "edge_weight_tests",
+ "edge_weight_calls",
+ "pagerank_damping",
+ "search_limit",
+ "trace_max_results",
+ "snippet_max_lines",
+ ):
+ assert key in rb.KNOWN_CONFIG_KEYS, key
+
+
+# --- utility-symbol classification ----------------------------------------------
+
+
+def test_public_api_label_follows_the_language_rule_not_fan_in() -> None:
+ """The label H1/H5 need: independent of degree, so it can adjudicate PR #151's claim
+ that the highest-fan-in symbols are utilities rather than assuming it. Go's rule is
+ definitional — an identifier is exported iff it starts with an upper-case letter."""
+ assert (
+ rb.is_public_api("cmd.cosign.cli.attest.AttestCommand", "a/attest.go") is True
+ )
+ assert rb.is_public_api("pkg.cosign.mockAttestation", "pkg/verify_test.go") is False
+ # Python: a leading underscore anywhere in the dotted path marks the surface private,
+ # which is what makes sklearn._loss.loss internal while sklearn.base.BaseEstimator
+ # is public. The structural leaf-hub definition got that exact pair backwards.
+ assert rb.is_public_api("sklearn.base.BaseEstimator", "sklearn/base.py") is True
+ assert (
+ rb.is_public_api(
+ "sklearn._loss.loss.ArrayAPILossMixin", "sklearn/_loss/loss.py"
+ )
+ is False
+ )
+ assert (
+ rb.is_public_api("flask.app.Flask._find_error_handler", "src/flask/app.py")
+ is False
+ )
+ # Dunders are language protocol, not private surface.
+ assert (
+ rb.is_public_api("sklearn.base.BaseEstimator.__init__", "sklearn/base.py")
+ is True
+ )
+
+
+def test_public_api_label_reports_unknown_rather_than_guessing() -> None:
+ """C publicity needs header parsing and Rust needs `pub`; neither is a name rule.
+ Reporting unknown keeps the metric honest instead of inventing a verdict for redis."""
+ assert rb.is_public_api("server.processCommand", "src/server.c") is None
+ assert (
+ rb.is_public_api("grep.searcher.Searcher", "crates/searcher/src/lib.rs") is None
+ )
+ assert rb.is_public_api("anything", "") is None
+
+
+def test_non_public_rate_is_measured_and_is_null_where_unknown() -> None:
+ """The replacement for leaf_hub_rate in the H1/H5 role. Null, not zero, on a corpus
+ whose language has no name-level publicity rule."""
+ go = Path(tempfile.mkdtemp())
+ make_rank_db(
+ go,
+ [(f"pkg.Exported{i}", "pkg/a.go", 50 - i, float(50 - i)) for i in range(5)]
+ + [("pkg.internalHelper", "pkg/a.go", 900, 99.0)],
+ )
+ window = rb.run_rank_score_probes(go, "p", top_n=6, cutoffs=(1,))["scorers"][
+ "degree"
+ ]["by_cutoff"]["1"]
+ # internalHelper has the highest degree, so it heads the degree ranking and it is
+ # not exported: exactly the shape PR #151 describes, measured without using fan-in.
+ assert window["non_public_rate"] == 1.0
+
+ c = Path(tempfile.mkdtemp())
+ make_rank_db(c, [("server.processCommand", "src/server.c", 5, 1.0)])
+ c_window = rb.run_rank_score_probes(c, "p", top_n=1, cutoffs=(1,))["scorers"][
+ "degree"
+ ]["by_cutoff"]["1"]
+ assert c_window["non_public_rate"] is None
+
+
+def test_leaf_hub_rate_is_named_for_what_it_measures() -> None:
+ """The metric was called utility_contamination and read as adjudicating PR #151's
+ claim that high fan-in means utilities. It cannot: it SELECTS by high fan-in while
+ degree and in_degree RANK by high fan-in, so it approaches 1.0 by construction, and
+ on real corpora it selected sklearn.base.BaseEstimator and hiredis's redisCommand.
+ It is a real structural statistic under an accurate name, and nothing more."""
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(
+ directory,
+ [(f"ordinary{i}", "src/o.c", 5, 1.0) for i in range(20)]
+ + [("zmalloc", "src/z.c", 900, 5.0), ("processCommand", "src/s.c", 40, 90.0)],
+ )
+ window = rb.run_rank_score_probes(directory, "p", top_n=22, cutoffs=(1,))[
+ "scorers"
+ ]["degree"]["by_cutoff"]["1"]
+ assert "leaf_hub_rate" in window
+ assert "lexical_marker_rate" in window
+ # The discredited name must be gone, so no consumer can read a claim into it.
+ assert "utility_contamination" not in window
+
+
+def test_h5_is_not_measurable_without_the_public_api_label() -> None:
+ """A verdict computed from a fan-in-derived metric is worse than no verdict: it
+ looks like evidence. With no public-API verdicts, H5 says so instead of falling back
+ to leaf_hub_rate, which selects on the quantity the degree scorers rank by."""
+ rollup = rr.build_rollup(
+ [
+ rollup_case(name, utility={"degree": 0.9, "pagerank": 0.1})
+ for name in ("cosign", "redis", "runc")
+ ]
+ )
+ verdict = rollup["verdicts"]["H5"]
+ assert verdict["supported"] is None
+ assert verdict["status"] == "not_measurable"
+ assert "public-api" in verdict["statement"].lower()
+ assert "fan-in" in verdict["statement"].lower()
+ assert rollup["validation"]["passed"] is False
+
+
+def test_a_case_with_partial_scorer_coverage_is_dropped_not_compared() -> None:
+ """Guards: on a mixed-language corpus the public-API label can resolve for one
+ scorer's top-K and not another's — redis recorded degree=null with pagerank=0.000,
+ because pagerank's window reached a Python file and degree's stayed in C. Comparing
+ a measured rate against a null-derived one is apples-to-oranges."""
+ partial = rollup_case("redis", non_public={"degree": None, "pagerank": 0.0})
+ both = rollup_case("cosign", non_public={"degree": 0.4, "pagerank": 0.1})
+ verdict = rr.build_rollup([partial, both])["verdicts"]["H5"]
+ assert verdict["signal_corpora"] == ["cosign"]
+ assert verdict["corpora_compared"] == 1
+
+
+def test_python_public_exports_are_read_from_package_init_files() -> None:
+ """scikit-learn, pandas and numpy define in a private module and re-export from
+ __init__.py, so the underscore rule alone calls their public API private."""
+ repo = Path(tempfile.mkdtemp())
+ (repo / "sklearn" / "linear_model").mkdir(parents=True)
+ (repo / "sklearn" / "linear_model" / "__init__.py").write_text(
+ "from ._logistic import LogisticRegression\n"
+ "from ._base import LinearModel\n"
+ '__all__ = ["LogisticRegression", "LinearModel"]\n',
+ encoding="utf-8",
+ )
+ exports = rb.python_public_exports(repo)
+ assert {"LogisticRegression", "LinearModel"} <= exports
+
+ # With the export set, a symbol defined in a private module is public.
+ assert (
+ rb.is_public_api(
+ "sklearn.linear_model._logistic.LogisticRegression",
+ "sklearn/linear_model/_logistic.py",
+ exports,
+ )
+ is True
+ )
+ # A method of an exported class is public too: the class is the exported surface,
+ # and a non-underscore method on it is part of that surface.
+ assert (
+ rb.is_public_api(
+ "sklearn.linear_model._base.LinearModel.fit",
+ "sklearn/linear_model/_base.py",
+ exports,
+ )
+ is True
+ )
+ # A genuinely internal symbol in the same private module stays private.
+ assert (
+ rb.is_public_api(
+ "sklearn.utils._testing.raises", "sklearn/utils/_testing.py", exports
+ )
+ is False
+ )
+ # An underscore-prefixed member of an exported class is still private.
+ assert (
+ rb.is_public_api(
+ "sklearn.linear_model._base.LinearModel._decision",
+ "sklearn/linear_model/_base.py",
+ exports,
+ )
+ is False
+ )
+
+
+def test_public_exports_survive_unparseable_sources() -> None:
+ """A corpus with a syntax error under some Python version must not abort a run."""
+ repo = Path(tempfile.mkdtemp())
+ (repo / "pkg").mkdir()
+ (repo / "pkg" / "__init__.py").write_text("from ._x import (\n", encoding="utf-8")
+ assert rb.python_public_exports(repo) == frozenset()
+ assert rb.python_public_exports(Path("/nonexistent")) == frozenset()
+
+
+def test_h5_reports_an_effect_without_inventing_a_decision_threshold() -> None:
+ """The label is independent of degree, so its direction and magnitude are useful.
+ A supported/refuted label still requires a pre-registered decision rule."""
+ cases = [
+ rollup_case(name, non_public={"degree": 0.8, "pagerank": 0.3})
+ for name in ("cosign", "flask", "runc")
+ ]
+ verdict = rr.build_rollup(cases)["verdicts"]["H5"]
+ assert verdict["metric"] == "non_public_rate"
+ assert verdict["supported"] is None
+ assert verdict["status"] == "measured_descriptive"
+ assert verdict["effect_direction"] == "degree_higher"
+ assert math.isclose(verdict["effect_size"], 0.5)
+ assert "without using fan-in" in verdict["statement"]
+
+
+def test_structural_leaf_hubs_are_derived_from_the_graph_not_a_word_list() -> None:
+ """The campaign's thesis is that hardcoded word lists do not generalize, so a word
+ list cannot be the instrument that decides H5. PR #151's actual claim is structural:
+ "they have the highest fan-in". A utility is a symbol many things call that calls
+ almost nothing itself — measurable per corpus, in any language, with no vocabulary.
+ """
+ # zmalloc: called by 900 things, calls 1. serverCron: balanced. main: pure caller.
+ # None is identified by its name, which is the point. The ordinary symbols are the
+ # distribution the cut is taken from — a quantile over three points means nothing.
+ nodes = [
+ {"qualified_name": f"a.ordinary{i}", "total_in": 5, "total_out": 5}
+ for i in range(20)
+ ] + [
+ {"qualified_name": "a.zmalloc", "total_in": 900, "total_out": 1},
+ {"qualified_name": "a.serverCron", "total_in": 40, "total_out": 35},
+ {"qualified_name": "a.main", "total_in": 0, "total_out": 60},
+ ]
+ utilities = rb.structural_leaf_hubs(nodes)
+ assert "a.zmalloc" in utilities
+ assert "a.serverCron" not in utilities
+ assert "a.main" not in utilities
+
+
+def test_structural_leaf_hubs_scale_the_threshold_to_the_corpus() -> None:
+ """A fixed fan-in threshold would find no utilities in a small repository and label
+ half of a large one. The cut is relative to the corpus's own distribution."""
+ small = [
+ {"qualified_name": f"s.f{i}", "total_in": i, "total_out": 5}
+ for i in range(1, 21)
+ ]
+ small.append({"qualified_name": "s.hub", "total_in": 400, "total_out": 0})
+ assert "s.hub" in rb.structural_leaf_hubs(small)
+ # A flat graph with no hub has no utilities, rather than an arbitrary top slice.
+ flat = [
+ {"qualified_name": f"f.f{i}", "total_in": 10, "total_out": 10}
+ for i in range(30)
+ ]
+ assert rb.structural_leaf_hubs(flat) == frozenset()
+
+
+def test_structural_leaf_hubs_need_enough_symbols_for_a_distribution() -> None:
+ """Three symbols have no distribution to take a quantile of; guessing one would
+ reintroduce exactly the arbitrariness this replaces."""
+ assert (
+ rb.structural_leaf_hubs(
+ [{"qualified_name": "a", "total_in": 9, "total_out": 0}]
+ )
+ is not None
+ )
+ assert rb.structural_leaf_hubs([]) == frozenset()
+
+
+def test_utility_markers_match_tokens_not_substrings() -> None:
+ """Guards: bare substring matching counted this project's own trace_path as a
+ logging utility, inflating utility contamination on our own corpus."""
+ for name in ("zmalloc", "serverLog", "fmt.Sprintf", "printf", "memcpy", "panic"):
+ assert rb.is_utility_symbol(name), name
+ for name in (
+ "trace_path",
+ "cbm_trace_path",
+ "freeze_index",
+ "catalog",
+ "AttestCommand",
+ "url_for",
+ "LatestSnapshot",
+ "debug_symbols",
+ ):
+ assert not rb.is_utility_symbol(name), name
+
+
+# --- rank score probes ----------------------------------------------------------
+
+
+def test_probes_rank_only_callable_symbols() -> None:
+ """Guards: with no label filter the first full campaign ranked go.mod,
+ .github/workflows/build.yaml, Makefile and src/server.h above every function, so
+ utility_contamination measured 0.000 on redis and cosign — the two corpora chosen
+ because they have hub utilities. PR #151's claim is about log.Error() and
+ fmt.Sprintf(); pass_importance.c:172-215 scopes to Function, Method, Class."""
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(
+ directory,
+ [
+ ("repo.go.mod.__file__", "go.mod", 900, 9.0),
+ ("repo.src.server.h.__file__", "src/server.h", 800, 8.0),
+ ("repo.src.zmalloc", "src/zmalloc.c", 100, 7.0),
+ ("repo.src.processCommand", "src/server.c", 40, 6.0),
+ ],
+ labels=["File", "File", "Function", "Function"],
+ )
+ probes = rb.run_rank_score_probes(directory, "p", top_n=10, cutoffs=(2,))
+ ranked = [
+ row["qualified_name"] for row in probes["scorers"]["degree"]["top_ranked"]
+ ]
+ assert ranked == ["repo.src.zmalloc", "repo.src.processCommand"]
+ window = probes["scorers"]["degree"]["by_cutoff"]["2"]
+ assert window["lexical_marker_rate"] == 0.5
+ # Four symbols are too few for a fan-in quantile, so the structural definition
+ # reports nothing rather than guessing. That is the honest answer here.
+ assert window["leaf_hub_rate"] == 0.0
+
+
+def test_probes_exclude_symbols_outside_the_repository() -> None:
+ """builtins.str, builtins.list and builtins.list.append held ranks 1, 3 and 5 of
+ redis's PageRank top 10 — a C repository. They are not repository symbols and cannot
+ be scaffolding, utilities, or architecture.
+
+ Guards the way the first fix missed them: the scope excluded an EMPTY file_path, but
+ the product marks non-file nodes with an angle-bracket sentinel instead
+ (internal/cbm/lsp/py_builtins.c:84 sets file_path = ""). This test
+ used "" and passed while the real data was wrong, so it now uses the real sentinel.
+ """
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(
+ directory,
+ [
+ ("builtins.str", "", 900, 9.0),
+ ("builtins.list", "", 880, 8.0),
+ ("jvm.Thing", "", 870, 7.0),
+ ("repo.src.processCommand", "src/server.c", 5, 1.0),
+ ],
+ labels=["Class", "Class", "Class", "Function"],
+ )
+ probes = rb.run_rank_score_probes(directory, "p", top_n=10, cutoffs=(1,))
+ ranked = [
+ row["qualified_name"] for row in probes["scorers"]["degree"]["top_ranked"]
+ ]
+ assert ranked == ["repo.src.processCommand"]
+
+
+def test_probes_rank_every_scorer_and_expose_degree_utility_bias() -> None:
+ """The H5 shape: raw degree ranks max-fan-in utilities first by construction,
+ which is the claim PR #151 made against PageRank."""
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(
+ directory,
+ # Twenty ordinary symbols supply the fan-in distribution the utility cut is
+ # taken from; a quantile needs a population, and a four-node graph has none.
+ [(f"ordinary{i}", "src/o.c", 5, 1.0) for i in range(20)]
+ + [
+ ("zmalloc", "src/z.c", 900, 5.0),
+ ("serverLog", "src/s.c", 800, 4.0),
+ ("processCommand", "src/s.c", 40, 90.0),
+ ("createClient", "src/n.c", 30, 85.0),
+ ],
+ )
+ probes = rb.run_rank_score_probes(directory, "p", top_n=24, cutoffs=(2, 4))
+ assert probes["available"]
+ assert set(probes["scorers"]) == set(rb.RANK_PROBE_SQL)
+ degree = probes["scorers"]["degree"]["by_cutoff"]["2"]["leaf_hub_rate"]
+ pagerank = probes["scorers"]["pagerank"]["by_cutoff"]["2"]["leaf_hub_rate"]
+ assert degree > pagerank, (degree, pagerank)
+
+
+def test_scaffolding_is_null_without_independent_labels() -> None:
+ """Guards circularity: filling scaffolding from a cbm predicate would measure the
+ classifier against itself."""
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(directory, [("a", "src/a.c", 5, 1.0)])
+ probes = rb.run_rank_score_probes(directory, "p", top_n=1, cutoffs=(1,))
+ assert probes["scaffolding_labels_present"] is False
+ assert probes["scorers"]["degree"]["by_cutoff"]["1"]["scaffolding"] is None
+
+
+def test_probe_timing_key_is_visible_to_the_fact_tables() -> None:
+ """Guards: a bespoke key such as probe_elapsed_ms is skipped by fact_step_rows,
+ which selects dicts carrying elapsed_ms."""
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(directory, [("a", "src/a.c", 5, 1.0)])
+ entry = rb.run_rank_score_probes(directory, "p", top_n=1, cutoffs=(1,))["scorers"][
+ "degree"
+ ]
+ assert "elapsed_ms" in entry and "probe_elapsed_ms" not in entry
+
+
+# --- statistics -----------------------------------------------------------------
+
+
+def test_spearman_delegates_to_stdlib_and_handles_undefined_inputs() -> None:
+ assert rb.spearman_rho([1, 2, 3], [3, 2, 1]) == statistics.correlation(
+ [1, 2, 3], [3, 2, 1], method="ranked"
+ )
+ for left, right in (
+ ([1, 1, 1], [1, 2, 3]),
+ ([1], [2]),
+ ([], []),
+ ([1, 2], [1, 2, 3]),
+ ):
+ assert rb.spearman_rho(left, right) is None
+
+
+def test_rbo_top_weighting_parameter_is_named_and_reproducible() -> None:
+ left = ["a", "b", "c"]
+ right = ["a", "c", "b"]
+ assert 0.0 < rb.RANK_BIASED_OVERLAP_PERSISTENCE < 1.0
+ assert rb.rank_biased_overlap(left, right) == rb.rank_biased_overlap(
+ left, right, persistence=rb.RANK_BIASED_OVERLAP_PERSISTENCE
+ )
+
+
+def test_mcp_early_exit_error_retains_candidate_stderr() -> None:
+ client = rb.McpClient(Path("/nonexistent-cbm"), {}, timeout=1)
+ client.stderr_lines.append(
+ "CBM could not start because a conflicting CBM process is active"
+ )
+ error = client.server_exit_error("initialize")
+ assert "initialize" in str(error)
+ assert "conflicting CBM process is active" in str(error)
+
+
+# --- query battery --------------------------------------------------------------
+
+
+def test_default_battery_preserves_historical_cells() -> None:
+ """Guards: any change to the default path invalidates cached cells, because cell
+ identity includes the command."""
+ battery = rb.load_rank_query_battery("", "synthetic-rank-v1")
+ assert battery is rb.DEFAULT_RANK_QUERY_BATTERY
+ assert len(battery) == 1 and battery[0]["id"] == "central_order_search"
+
+
+def test_every_corpus_names_a_public_clone_url() -> None:
+ """A registry entry that names no source cannot be reproduced by anyone else. Two
+ workload entries previously recorded a local home-relative checkout path instead of
+ the public repository, which described one machine rather than the corpus."""
+ for entry in rb.load_corpora_manifest("").values():
+ url = entry.get("url") or ""
+ assert url.startswith("https://"), f"{entry['id']} has no public url: {url!r}"
+ assert "~" not in url and "/Users/" not in url, entry["id"]
+ assert entry.get("repo") and "local" not in entry["repo"], entry["id"]
+
+
+def test_workload_corpora_clone_their_current_tip() -> None:
+ """The popularity cohort is pinned to an exact commit; the workload cohort resolves
+ at run time by design, because its value is the query distribution mined against
+ whatever the operator actually had. Both must be cloneable from the recorded url."""
+ registry = rb.load_corpora_manifest("")
+ pinned = [e for e in registry.values() if len(e.get("revision", "")) == 40]
+ unpinned = [
+ e for e in registry.values() if e.get("revision") == rb.UNPINNED_REVISION
+ ]
+ assert pinned and unpinned
+ assert len(pinned) + len(unpinned) == len(registry)
+
+
+def test_clone_refuses_to_touch_a_directory_that_is_already_a_repository() -> None:
+ """clone_pinned_repo is the only harness function that mutates a directory: it runs
+ git init, remote add, fetch and switch --detach. Pointed at a real checkout, the
+ detach would move that repository's HEAD. Accepting the unpinned sentinel widened
+ which corpora can reach it, so it refuses a directory that already has a .git."""
+ existing = isolated_git_repo()
+ try:
+ rb.clone_pinned_repo(
+ "https://example.invalid/x", rb.UNPINNED_REVISION, existing, 5
+ )
+ except RuntimeError as error:
+ assert "already a git repository" in str(error)
+ assert str(existing) in str(error)
+ else:
+ raise AssertionError("clone ran against an existing repository")
+ # The existing repository is untouched: still on its own commit, still not detached.
+ head = subprocess.run(
+ ["git", "rev-parse", "--abbrev-ref", "HEAD"],
+ cwd=existing,
+ text=True,
+ capture_output=True,
+ check=True,
+ ).stdout.strip()
+ assert head != "HEAD", "clone detached an existing repository's HEAD"
+
+
+def test_clone_rejects_a_malformed_revision_but_allows_the_declared_sentinel() -> None:
+ """A typo'd sha must not silently clone the default branch and be reported as the
+ pinned tree; only the declared sentinel opts into tip-cloning."""
+ try:
+ rb.clone_pinned_repo(
+ "https://example.invalid/x", "abc123", Path(tempfile.mkdtemp()), 5
+ )
+ except RuntimeError as error:
+ assert "40-character" in str(error) or "resolve-at-run-time" in str(error)
+ else:
+ raise AssertionError("a malformed revision was accepted")
+
+
+def test_unknown_corpus_fails_fast() -> None:
+ try:
+ rb.load_rank_query_battery(QUERY_MANIFEST, "not-a-corpus")
+ except ValueError as error:
+ assert "not-a-corpus" in str(error)
+ else:
+ raise AssertionError("unknown corpus silently accepted")
+
+
+def test_manifest_declared_fields_are_honored() -> None:
+ """Guards: default_cutoff and repetitions were declared and silently ignored."""
+ battery = rb.load_rank_query_battery(QUERY_MANIFEST, "ai-session-search")
+ by_id = {query["id"]: query for query in battery}
+ assert by_id["flaky_max_hits_per_page"]["repetitions"] == 10
+ assert by_id["wl_run_search"]["repetitions"] == 1
+ assert all(query["cutoff"] == 5 for query in battery)
+
+
+def test_registry_and_battery_agree_on_corpus_ids() -> None:
+ """Guards: --corpus ripgrep resolved in the registry and then failed mid-run."""
+ assert rb.manifest_corpus_disagreements(QUERY_MANIFEST, "") == []
+
+
+def test_every_graded_judgment_survives_the_real_scorer() -> None:
+ manifest = json.loads(Path(QUERY_MANIFEST).read_text(encoding="utf-8"))
+ graded = 0
+ for corpus in manifest["corpora"].values():
+ for query in corpus["queries"]:
+ judgments = query.get("judgments") or []
+ if not judgments:
+ continue
+ graded += 1
+ scored = rb.score_ranked_relevance(
+ [], judgments, cutoff=query.get("cutoff", 5)
+ )
+ assert scored["judgment_count"] == len(judgments), query["id"]
+ assert graded >= 2
+
+
+def test_required_substrings_gate_a_wrong_path() -> None:
+ judgments = [
+ {
+ "expected_substring": "AttestCommand",
+ "required_substrings": ["cmd/cosign/cli/attest"],
+ "relevance": 3,
+ }
+ ]
+ right = rb.score_ranked_relevance(
+ [
+ {
+ "qualified_name": "AttestCommand",
+ "file_path": "cmd/cosign/cli/attest/attest.go",
+ }
+ ],
+ judgments,
+ )
+ wrong = rb.score_ranked_relevance(
+ [{"qualified_name": "AttestCommand", "file_path": "elsewhere.go"}], judgments
+ )
+ assert right["reciprocal_rank"] == 1.0 and wrong["reciprocal_rank"] == 0.0
+
+
+def test_one_judgment_cannot_repeatedly_inflate_ndcg_above_one() -> None:
+ """One target duplicated by a tool page is one judgment, not unlimited relevance."""
+ judgment = [{"expected_substring": "same", "relevance": 3}]
+ score = rb.score_ranked_relevance(
+ [{"name": "same"}, {"name": "same"}, {"name": "same"}], judgment, cutoff=3
+ )
+ assert score["matched_relevance"] == [3, 0, 0]
+ assert score["matched_judgment_count"] == 1
+ assert 0.0 <= score["ndcg_at_3"] <= 1.0
+
+
+# --- per-query evidence ---------------------------------------------------------
+
+
+def test_result_count_is_recorded_for_behavioral_only_queries() -> None:
+ """Guards: returned_count sat inside `if applicable:`, so 28 of 31 manifest
+ queries recorded nothing at all."""
+ oracles = {
+ "graded": {"response": {"results": [{"name": "zz_order_core"}, {"name": "x"}]}},
+ "behavioral_zero": {"response": {"results": []}},
+ "behavioral_rows": {"response": {"columns": ["a"], "rows": [1, 2, 3]}},
+ }
+ expectations = {
+ "graded": {
+ "criterion": "c",
+ "cutoff": 5,
+ "judgments": [{"expected_substring": "zz_order_core", "relevance": 3}],
+ }
+ }
+ summary = rb.score_quality_oracles(oracles, expectations)
+ assert oracles["behavioral_zero"]["quality"]["returned_count"] == 0
+ assert oracles["behavioral_rows"]["quality"]["returned_count"] == 3
+ assert summary["mean_reciprocal_rank"] == 1.0 and summary["applicable_count"] == 1
+
+
+def test_repetitions_capture_result_count_instability() -> None:
+ """Guards the observed failure mode: identical calls returned results and zero
+ results against a fixed index (max_hits_per_page: zero 18 of 54 times)."""
+ calls = {"count": 0}
+
+ def flapping(
+ transport, binary, env, tool, arguments, timeout, include_logs, client=None
+ ):
+ calls["count"] += 1
+ results = [{"name": "x"}, {"name": "y"}] if calls["count"] % 2 else []
+ return {"response": {"results": results}, "elapsed_ms": 1.0}
+
+ original_call = rb.run_tool_call_for_transport
+ original_loader = rb.load_rank_query_battery
+ rb.run_tool_call_for_transport = flapping
+ rb.load_rank_query_battery = lambda *args, **kwargs: (
+ {
+ "id": "flaky",
+ "family": "A",
+ "tool": "search_code",
+ "arguments": {"pattern": "p"},
+ "repetitions": 6,
+ "judgments": [],
+ },
+ {
+ "id": "single",
+ "family": "A",
+ "tool": "search_graph",
+ "arguments": {"pattern": "q"},
+ "repetitions": 1,
+ "judgments": [],
+ },
+ )
+ try:
+ args = argparse.Namespace(
+ timeout=10, include_logs=False, corpus="", rank_query_manifest=""
+ )
+ oracles = rb.run_rank_quality_oracles("cli", None, {}, "proj", args)
+ finally:
+ rb.run_tool_call_for_transport = original_call
+ rb.load_rank_query_battery = original_loader
+ stability = oracles["flaky"]["repetition_stability"]
+ assert stability["stable"] is False
+ assert stability["zero_result_repetitions"] == 3
+ assert "repetition_stability" not in oracles["single"]
+
+
+def test_graded_search_graph_queries_compare_every_supported_rank_sort() -> None:
+ """The PR decision is PageRank versus cheaper graph scores, so scoring only the
+ default sort cannot answer it. One graded query must produce paired quality for every
+ rank sort already exposed by search_graph without changing the historical no-manifest
+ path."""
+ calls: list[dict[str, Any]] = []
+
+ def ranked_call(
+ transport, binary, env, tool, arguments, timeout, include_logs, client=None
+ ):
+ calls.append(dict(arguments))
+ sort_by = arguments.get("sort_by", "relevance")
+ results = (
+ [{"name": "target"}, {"name": "decoy"}]
+ if sort_by in {"relevance", "linkrank"}
+ else [{"name": "decoy"}, {"name": "target"}]
+ )
+ return {"response": {"results": results}, "elapsed_ms": 1.0}
+
+ original_call = rb.run_tool_call_for_transport
+ original_loader = rb.load_rank_query_battery
+ rb.run_tool_call_for_transport = ranked_call
+ rb.load_rank_query_battery = lambda *args, **kwargs: (
+ {
+ "id": "graded",
+ "family": "B",
+ "tool": "search_graph",
+ "arguments": {"pattern": "target", "limit": 5},
+ "criterion": "surface target",
+ "cutoff": 5,
+ "repetitions": 1,
+ "judgments": [{"expected_substring": "target", "relevance": 3}],
+ },
+ )
+ try:
+ args = argparse.Namespace(
+ timeout=10,
+ include_logs=False,
+ corpus="fixture",
+ rank_query_manifest="manifest.json",
+ rank_overlay_active=False,
+ )
+ oracles = rb.run_rank_quality_oracles("mcp", None, {}, "proj", args)
+ finally:
+ rb.run_tool_call_for_transport = original_call
+ rb.load_rank_query_battery = original_loader
+
+ variants = oracles["graded"]["scorer_variants"]
+ assert set(variants) == {"pagerank", "degree", "calls", "linkrank_in"}
+ assert variants["pagerank"]["quality"]["first_relevant_rank"] == 1
+ assert variants["degree"]["quality"]["first_relevant_rank"] == 2
+ assert oracles["scorer_variant_quality"]["pagerank"]["query_count"] == 1
+ assert len(calls) == 4
+
+
+# --- staleness ------------------------------------------------------------------
+
+
+def test_staleness_unions_declared_and_persisted_views() -> None:
+ """Guards: the ledger alone misses a view a response declared stale, and a stale
+ ranking view silently degrades search_graph to a degree sort."""
+ directory = Path(tempfile.mkdtemp())
+ connection = sqlite3.connect(directory / ("p" + rb.PROJECT_DB_SUFFIX))
+ connection.execute(
+ "CREATE TABLE derived_view_state (project TEXT, view_name TEXT, status TEXT)"
+ )
+ connection.execute(
+ "INSERT INTO derived_view_state VALUES ('p','node_degree','stale')"
+ )
+ connection.commit()
+ connection.close()
+ oracles = {
+ "q": {"freshness": {"state": "stale_with_warning", "stale_views": ["pagerank"]}}
+ }
+ result = rb.rank_score_staleness(directory, "p", oracles)
+ assert set(result["stale_rank_views"]) == {"pagerank", "node_degree"}
+ assert result["rank_views_fresh"] is False
+
+
+# --- SQLite readers -------------------------------------------------------------
+
+
+def test_query_rows_delegates_and_reads_are_read_only() -> None:
+ directory = Path(tempfile.mkdtemp())
+ database = directory / "t.db"
+ connection = sqlite3.connect(database)
+ connection.execute("CREATE TABLE t(a TEXT, b INT)")
+ connection.executemany("INSERT INTO t VALUES(?,?)", [("x", 1), ("y", 2)])
+ connection.commit()
+ connection.close()
+ assert rb.query_rows(database, "SELECT a,b FROM t ORDER BY a", ()) == ["x", "y"]
+ assert rb.query_tuples(database, "SELECT a,b FROM t ORDER BY a", ()) == [
+ ("x", 1),
+ ("y", 2),
+ ]
+ try:
+ rb.query_tuples(database, "INSERT INTO t VALUES('z',3)", ())
+ except sqlite3.OperationalError:
+ pass
+ else:
+ raise AssertionError("probe handle allowed a write")
+
+
+# --- corpus resolution ----------------------------------------------------------
+
+
+def test_missing_corpus_names_every_path_it_searched() -> None:
+ entry = rb.load_corpora_manifest("")["cosign"]
+ args = argparse.Namespace(
+ corpus_repo=[], clone_missing_real_repos=False, timeout=30
+ )
+ try:
+ rb.resolve_corpus_source(
+ "nonexistent-corpus", entry["url"], entry["revision"], args
+ )
+ except RuntimeError as error:
+ message = str(error)
+ assert "--corpus-repo" in message and "Searched:" in message
+ else:
+ raise AssertionError("resolution succeeded for a corpus that does not exist")
+
+
+def test_pinned_clone_requires_a_full_commit_hash() -> None:
+ try:
+ rb.clone_pinned_repo(
+ "https://example.invalid/x.git", "main", Path(tempfile.mkdtemp()), 5
+ )
+ except RuntimeError as error:
+ assert "40-character" in str(error)
+ else:
+ raise AssertionError("a branch name was accepted as a pin")
+
+
+def test_manifest_digest_changes_when_a_registry_changes() -> None:
+ path = Path(tempfile.mkdtemp()) / "c.json"
+ path.write_text('{"schema_version":1,"corpora":[]}')
+ before = rb.manifest_digest(str(path), None)
+ path.write_text('{"schema_version":1,"corpora":[],"x":1}')
+ assert before != rb.manifest_digest(str(path), None)
+ assert rb.manifest_digest(None, None) is None
+
+
+def test_every_registered_corpus_pins_a_commit_and_tree() -> None:
+ for entry in rb.load_corpora_manifest("").values():
+ if entry.get("cohort") not in {"adversarial", "control"}:
+ continue
+ assert len(entry["revision"]) == 40, entry["id"]
+ assert len(entry["tree"]) == 40, entry["id"]
+ assert entry["stars"] >= 1000, entry["id"]
+
+
+# --- report -------------------------------------------------------------------
+
+
+def test_report_rows_follow_the_emitted_cutoffs() -> None:
+ """Guards: hardcoded "10"/"40" rendered an all-n/a table whenever the producer
+ was called with different cutoffs."""
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(
+ directory,
+ [("zmalloc", "src/z.c", 900, 5.0), ("processCommand", "src/s.c", 40, 90.0)],
+ )
+ probes = rb.run_rank_score_probes(directory, "p", top_n=2, cutoffs=(1, 2))
+ case = {
+ "scenario": "rank_quality",
+ "corpus": {"id": "redis"},
+ "rank_score_staleness": {"available": True, "rank_views_fresh": True},
+ "rank_score_probes": probes,
+ }
+ rows = sr.rank_scorer_details([case])
+ assert rows and any(row["leaf_hub_rate"] is not None for row in rows)
+ assert {row["cutoff"] for row in rows if row["cutoff"] != "n/a"} == {"1", "2"}
+
+
+def test_report_never_invents_a_corpus_id() -> None:
+ """Guards: a --quality-background-repo run with no --corpus was mislabelled as
+ the synthetic fixture."""
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(directory, [("a", "src/a.c", 5, 1.0)])
+ probes = rb.run_rank_score_probes(directory, "p", top_n=1, cutoffs=(1,))
+ rows = sr.rank_scorer_details([{"scenario": "x", "rank_score_probes": probes}])
+ assert rows[0]["corpus"] == "n/a"
+
+
+def test_report_tolerates_cases_without_probes() -> None:
+ assert sr.rank_scorer_details([]) == []
+ assert sr.rank_scorer_details([{"scenario": "x"}]) == []
+
+
+# --- synthetic overlay on real corpora (A16) ------------------------------------
+
+
+def test_synthetic_rank_fixture_is_the_corpus_when_no_background_is_given() -> None:
+ """The synthetic run must keep building the fixture: there is nothing else to index."""
+ args = argparse.Namespace(rank_fixture_overlay=False)
+ assert rb.rank_fixture_overlay_decision("rank", None, args) == "fixture-is-corpus"
+
+
+def test_synthetic_rank_fixture_is_suppressed_on_a_real_corpus() -> None:
+ """Guards: create_rank_quality_repo wrote zz_order_core and eight decoys into the
+ same repo_dir the pinned corpus was materialized into, so a cosign run indexed the
+ real tree plus nine synthetic Python files and every corpus-scoped metric was
+ computed over a graph the registry pin does not describe."""
+ args = argparse.Namespace(rank_fixture_overlay=False)
+ assert (
+ rb.rank_fixture_overlay_decision("rank", {"tree": "abc"}, args) == "suppressed"
+ )
+
+
+def test_synthetic_rank_fixture_is_kept_when_explicitly_requested() -> None:
+ """The planted positive control stays available; it just stops being the default."""
+ args = argparse.Namespace(rank_fixture_overlay=True)
+ assert rb.rank_fixture_overlay_decision("rank", {"tree": "abc"}, args) == "overlaid"
+
+
+def test_other_capabilities_keep_their_established_overlay_behaviour() -> None:
+ """similarity/semantic_edges overlay a pair fixture onto background graph mass by
+ design; A16 is a rank-only decision and must not change them."""
+ args = argparse.Namespace(rank_fixture_overlay=False)
+ for capability in ("similarity", "semantic_edges", "dependencies"):
+ assert (
+ rb.rank_fixture_overlay_decision(capability, {"tree": "abc"}, args)
+ == "fixture-is-corpus"
+ )
+
+
+def test_overlay_control_query_is_appended_when_the_fixture_is_overlaid() -> None:
+ """An overlay nobody queries is contamination, not a control. When the fixture is
+ planted in a real corpus the canary query has to run against it."""
+ battery = rb.load_rank_query_battery(QUERY_MANIFEST, "cosign")
+ with_control = rb.rank_battery_with_overlay_control(battery, overlay_active=True)
+ assert len(with_control) == len(battery) + 1
+ control = with_control[-1]
+ assert control["id"] == "central_order_search"
+ assert any(
+ judgment["expected_substring"] == "zz_order_core"
+ for judgment in control["judgments"]
+ )
+ assert (
+ rb.rank_battery_with_overlay_control(battery, overlay_active=False) == battery
+ )
+
+
+def test_overlay_control_query_is_not_duplicated() -> None:
+ """The synthetic corpus already declares it; appending again would double-count it
+ in the applicable_count-weighted quality aggregate."""
+ battery = rb.load_rank_query_battery(QUERY_MANIFEST, "synthetic-rank-v1")
+ assert rb.rank_battery_with_overlay_control(battery, overlay_active=True) == battery
+
+
+def test_no_real_corpus_battery_queries_the_synthetic_symbols() -> None:
+ """The evidence behind A16, kept executable: if a real corpus ever does query
+ zz_order_core, suppressing the overlay would silently break that query, and this
+ test is the thing that says so."""
+ document = json.loads(Path(QUERY_MANIFEST).read_text(encoding="utf-8"))
+ offenders = [
+ corpus_id
+ for corpus_id, corpus in document["corpora"].items()
+ if corpus_id != "synthetic-rank-v1" and "zz_order_core" in json.dumps(corpus)
+ ]
+ assert not offenders, f"real corpora reference the synthetic fixture: {offenders}"
+
+
+# --- Tier-A scaffolding labels reach the probe ----------------------------------
+
+
+def make_pytest_project(directory: Path) -> Path:
+ """A directory that declares its own pytest configuration. No git, no commits."""
+ (directory / "pyproject.toml").write_text(
+ '[tool.pytest.ini_options]\npython_files = ["test_*.py"]\n', encoding="utf-8"
+ )
+ return directory
+
+
+PYTEST_PROJECT_FILES = ["src/app.py", "src/testing.py", "tests/test_app.py"]
+
+
+def test_scaffolding_labels_are_derived_from_the_measured_checkout() -> None:
+ """Labels are generated data derived from a corpus, so checking them in would put
+ derived JSON in the repository and let a label file drift from the tree actually
+ indexed. Deriving them from the staged corpus keeps one implementation and makes
+ that drift impossible."""
+ project = make_pytest_project(Path(tempfile.mkdtemp()))
+ document = gl.build_labels("fixture", project, PYTEST_PROJECT_FILES)
+ paths = rb.scaffolding_paths_from_document(document)
+ assert paths == frozenset({"tests/test_app.py"})
+ # The declaration decides, not the substring: src/testing.py is production code.
+ assert "src/testing.py" not in paths
+
+
+def test_derived_labels_report_null_when_nothing_can_be_classified() -> None:
+ """A C repository has no independent declaration to read. Null, not an empty set,
+ which would claim the corpus contains no test files."""
+ document = gl.build_labels("fixture", Path(tempfile.mkdtemp()), ["src/server.c"])
+ assert document["counts"] == {"test": 0, "not_test": 0, "unknown": 1}
+ assert rb.scaffolding_paths_from_document(document) is None
+
+
+def test_derived_labels_survive_a_repository_that_cannot_be_read() -> None:
+ """Label derivation must never abort a run that already produced oracles."""
+ assert rb.derive_scaffolding_paths("fixture", Path("/nonexistent-repo"), 5) is None
+ assert rb.derive_scaffolding_paths("fixture", None, 5) is None
+
+
+def test_label_derivation_can_actually_reach_the_labeller() -> None:
+ """Guards a real silent failure: derive_scaffolding_paths called a helper that did
+ not exist, and its `except Exception` turned the NameError into a null label set —
+ scaffolding@K would have reported "no independent labels" on every corpus forever.
+ Asserting the import path separately is what makes the swallow survivable."""
+ module = rb.load_module_beside("generate_test_labels")
+ assert callable(module.build_labels)
+ # One instance, so a caller that also loads it directly sees the same objects.
+ assert rb.load_module_beside("generate_test_labels") is module
+
+
+def test_label_rules_follow_the_language_toolchain_not_a_path_substring() -> None:
+ """Go and Cargo state what a test file is; the label follows that definition rather
+ than any string in the path. Exercised on file names alone, so it needs no corpus
+ checkout and runs in CI."""
+ go = gl.build_labels(
+ "go", Path(tempfile.mkdtemp()), ["cmd/main.go", "pkg/a_test.go"]
+ )
+ verdicts = {row["file_path"]: row["is_test"] for row in go["labels"]}
+ assert verdicts == {"cmd/main.go": False, "pkg/a_test.go": True}
+ assert all(row["source"] == "spec" for row in go["labels"])
+
+ rust = gl.build_labels(
+ "rs", Path(tempfile.mkdtemp()), ["src/lib.rs", "tests/cli.rs"]
+ )
+ verdicts = {row["file_path"]: row["is_test"] for row in rust["labels"]}
+ # Cargo integration tests are declared by location; unit tests live inline in
+ # #[cfg(test)] modules, which no file-level rule can see, so src/lib.rs is unknown.
+ assert verdicts == {"src/lib.rs": None, "tests/cli.rs": True}
+
+
+def test_label_rules_leave_unknown_what_no_source_declares() -> None:
+ """A C project declares nothing a labeller can read. Guessing would reintroduce the
+ circularity these labels exist to remove."""
+ document = gl.build_labels("c", Path(tempfile.mkdtemp()), ["src/server.c"])
+ assert document["labels"][0]["is_test"] is None
+ assert document["labels"][0]["source"] == "unknown"
+
+
+def test_an_all_unknown_label_file_reports_null_not_zero() -> None:
+ """Guards: redis is C and jest declares its test config in JavaScript, so both
+ label files are 100% unknown. An empty frozenset would have claimed the corpus has
+ no test files at all, printing scaffolding@K as a clean 0.000 for a corpus nothing
+ independent could classify."""
+ directory = Path(tempfile.mkdtemp())
+ (directory / "nothing.json").write_text(
+ json.dumps(
+ {
+ "counts": {"test": 0, "not_test": 0, "unknown": 3},
+ "labels": [{"file_path": "a.c", "is_test": None, "source": "unknown"}],
+ }
+ ),
+ encoding="utf-8",
+ )
+ assert rb.load_scaffolding_paths("nothing", str(directory)) is None
+
+ (directory / "genuine.json").write_text(
+ json.dumps(
+ {
+ "counts": {"test": 0, "not_test": 2, "unknown": 0},
+ "labels": [
+ {"file_path": "a.py", "is_test": False, "source": "declared"}
+ ],
+ }
+ ),
+ encoding="utf-8",
+ )
+ # A project the runner classified and found no tests in is a real measurement.
+ assert rb.load_scaffolding_paths("genuine", str(directory)) == frozenset()
+
+
+def test_no_corpus_derived_data_is_tracked_in_the_repository() -> None:
+ """A .gitignore rule can be bypassed with `git add -f`, and staging a directory by
+ name is what put generated label JSON into a commit. This asserts the outcome the
+ rule is meant to produce, so the mistake cannot recur silently."""
+ tracked = subprocess.run(
+ ["git", "ls-files", "benchmarks/"],
+ cwd=BENCHMARKS.parent,
+ text=True,
+ capture_output=True,
+ check=False,
+ )
+ if tracked.returncode != 0: # not a checkout; nothing to enforce
+ return
+ offenders = [
+ path
+ for path in tracked.stdout.split()
+ if path.startswith("benchmarks/labels/")
+ or path.startswith("benchmarks/campaign-specs/")
+ or path.startswith("benchmarks/rollup")
+ ]
+ assert not offenders, f"corpus-derived data is tracked: {offenders}"
+
+
+# --- corpus coverage: which files actually reached the graph ---------------------
+
+
+def test_coverage_probe_counts_files_and_attributes_them_to_directories() -> None:
+ """The silent-drop evidence: a per-directory count is what turns "fewer files" into
+ "scripts/ is absent", which is the claim issues #1406/#1184/#1219 actually make."""
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(
+ directory,
+ [
+ ("a", "cmd/main.go", 1, 1.0),
+ ("b", "cmd/other.go", 1, 1.0),
+ ("c", "scripts/build.go", 1, 1.0),
+ ("d", "README.md", 1, 1.0),
+ ],
+ )
+ coverage = rb.run_corpus_coverage_probe(directory, "p")
+ assert coverage["available"] is True
+ assert coverage["indexed_file_count"] == 4
+ assert coverage["top_level_directories"]["cmd"] == 2
+ assert coverage["top_level_directories"]["scripts"] == 1
+ # A root-level file is not silently attributed to some directory.
+ assert coverage["top_level_directories"][""] == 1
+
+
+def test_coverage_probe_scores_the_registry_prediction() -> None:
+ """corpora-v1.json pre-registers which directories the skip lists should drop. The
+ probe has to say whether that prediction held, or the prediction is decorative."""
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(directory, [("a", "cmd/main.go", 1, 1.0), ("b", "hack/x.go", 1, 1.0)])
+ coverage = rb.run_corpus_coverage_probe(
+ directory,
+ "p",
+ predicted_loss={"fast_skipped_top_dirs": ["scripts", "hack"]},
+ index_mode="fast",
+ )
+ prediction = coverage["predicted_loss_check"]
+ assert prediction["absent_as_predicted"] == ["scripts"]
+ assert prediction["present_despite_prediction"] == ["hack"]
+
+
+def test_coverage_prediction_does_not_apply_fast_skips_to_a_full_run() -> None:
+ """Guards: the flask full-mode pilot reported docs/ and examples/ as
+ "present_despite_prediction". FAST_SKIP_DIRS is gated on mode != CBM_MODE_FULL
+ (src/discover/discover.c:448-452), so under full indexing their presence is the
+ prediction holding, not failing."""
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(directory, [("a", "docs/x.py", 1, 1.0), ("b", "vendor/y.py", 1, 1.0)])
+ prediction = rb.run_corpus_coverage_probe(
+ directory,
+ "p",
+ predicted_loss={
+ "fast_skipped_top_dirs": ["docs"],
+ "always_skipped_top_dirs": ["vendor"],
+ },
+ index_mode="full",
+ )["predicted_loss_check"]
+ assert prediction["applicable_predictions"] == ["vendor"]
+ assert prediction["present_despite_prediction"] == ["vendor"]
+ assert "docs" not in prediction["present_despite_prediction"]
+
+
+def test_coverage_probe_breaks_files_down_by_extension() -> None:
+ """The first campaign showed files lost between full and fast from directories on
+ no published skip list (jest packages 637, redis deps 74). A per-directory count
+ cannot say whether a second mechanism is extension-based; a per-extension count can.
+ """
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(
+ directory,
+ [
+ ("a", "src/a.go", 1, 1.0),
+ ("b", "src/b.go", 1, 1.0),
+ ("c", "docs/c.md", 1, 1.0),
+ ("d", "Makefile", 1, 1.0),
+ ],
+ )
+ coverage = rb.run_corpus_coverage_probe(directory, "p")
+ assert coverage["extensions"][".go"] == 2
+ assert coverage["extensions"][".md"] == 1
+ # A file with no suffix is its own bucket rather than being dropped or guessed.
+ assert coverage["extensions"][""] == 1
+
+
+def test_coverage_probe_reports_unavailability_without_raising() -> None:
+ """A missing database must not abort a run that already produced oracles."""
+ coverage = rb.run_corpus_coverage_probe(Path(tempfile.mkdtemp()), "p")
+ assert coverage["available"] is False and coverage["reason"]
+
+
+# --- knob-efficacy canary -------------------------------------------------------
+
+
+def test_rank_table_fingerprint_changes_with_the_scores() -> None:
+ """The canary compares this across config cells. A fingerprint that ignored the
+ scores would report every knob as live regardless of what it did."""
+ first, second = Path(tempfile.mkdtemp()), Path(tempfile.mkdtemp())
+ make_rank_db(first, [("a", "a.c", 3, 1.0), ("b", "b.c", 2, 2.0)])
+ make_rank_db(second, [("a", "a.c", 3, 1.0), ("b", "b.c", 2, 9.0)])
+ assert rb.rank_table_fingerprint(first, "p") != rb.rank_table_fingerprint(
+ second, "p"
+ )
+ assert rb.rank_table_fingerprint(first, "p") == rb.rank_table_fingerprint(
+ first, "p"
+ )
+
+
+def test_rank_table_fingerprint_is_absent_without_a_database() -> None:
+ assert rb.rank_table_fingerprint(Path(tempfile.mkdtemp()), "p") is None
+
+
+def test_canary_arm_covers_every_ranking_knob() -> None:
+ """A knob with no cell is a knob the campaign never proved does anything, and a
+ sweep over it would report a difference of exactly zero either way."""
+ spec = cs.build_canary_spec("HEAD", 1, 600)
+ labels = {profile["label"] for profile in spec["profiles"]}
+ assert "baseline" in labels
+ swept = {key for profile in spec["profiles"] for key in profile["config_overrides"]}
+ assert cs.RANKING_KNOBS <= swept
+ # The canary runs on the synthetic fixture: a real corpus would cost minutes per
+ # knob for a question the 17-file fixture answers.
+ assert rc.corpora_required_by_spec(spec) == []
+
+
+def test_canary_ignores_config_cells_from_other_arms() -> None:
+ """Guards: the rank arm's reply-detail cells carry search_limit and
+ snippet_max_lines overrides, and the canary counted them as ranking knobs it had
+ proved live — comparing a cosign fingerprint against a synthetic-fixture baseline.
+ The canary is a within-arm comparison on one graph or it is nothing."""
+ detail = rollup_case("cosign")
+ detail["parameters"]["config_overrides"] = {"search_limit": "200"}
+ detail["cases"][0]["rank_table_fingerprint"] = "hash-cosign"
+ canary = rr.knob_canary(
+ rr.rank_cases(
+ [
+ canary_case("baseline", "hash-baseline"),
+ canary_case("edge_weight_tests", "hash-moved"),
+ detail,
+ ]
+ )
+ )
+ assert canary["live"] == ["edge_weight_tests"]
+ assert "search_limit" not in canary["live"] + canary["inert"]
+
+
+def test_canary_verdict_names_a_knob_whose_scores_never_moved() -> None:
+ """Guards the §3.4 defect end to end: cbm_config_value_is_valid accepts an unknown
+ key, so a knob that silently does nothing produces a clean run reporting a
+ difference of exactly zero, indistinguishable from "tuning does not help"."""
+ documents = [
+ canary_case("baseline", "hash-baseline"),
+ canary_case("edge_weight_tests", "hash-moved"),
+ canary_case("edge_weight_writes", "hash-baseline"),
+ ]
+ canary = rr.knob_canary(rr.rank_cases(documents))
+ assert canary["live"] == ["edge_weight_tests"]
+ assert canary["inert"] == ["edge_weight_writes"]
+ assert canary["passed"] is False
+
+
+def canary_case(label: str, fingerprint: str) -> dict[str, Any]:
+ overrides = {} if label == "baseline" else {label: "0.99"}
+ return {
+ "parameters": {"index_mode": "full", "config_overrides": overrides},
+ "cases": [
+ {
+ "scenario": "rank_quality",
+ # A synthetic run records corpus: None. The first version of this
+ # fixture invented an id, which would have hidden a rollup that
+ # silently dropped every canary cell.
+ "corpus": None,
+ "fixture": {"corpus_overlay": "fixture-is-corpus"},
+ "rank_score_staleness": {"available": True, "rank_views_fresh": True},
+ "rank_table_fingerprint": fingerprint,
+ }
+ ],
+ }
+
+
+# --- container corpus staging ---------------------------------------------------
+
+CONTAINER_SPEC = {
+ "benchmark_args": ["--rank-query-manifest", "m.json", "--corpus", "cosign"],
+ "candidates": [{"label": "head", "benchmark_args": ["--corpus=flask"]}],
+ "profiles": [{"label": "lean", "benchmark_args": ["--corpus", "runc"]}],
+ "scenarios": [{"label": "s", "benchmark_args": ["--corpus-manifest", "c.json"]}],
+}
+
+
+def test_container_finds_every_corpus_named_anywhere_in_a_matrix_spec() -> None:
+ """Guards: benchmark_args appear at four nesting levels in run_experiments.py
+ (spec, candidates, profiles, scenarios). Reading only the top level would stage
+ one corpus and let the container fail on the others, hours in."""
+ assert rc.corpora_required_by_spec(CONTAINER_SPEC) == ["cosign", "flask", "runc"]
+
+
+def test_container_corpus_scan_ignores_unrelated_flags() -> None:
+ assert (
+ rc.corpora_required_by_spec({"benchmark_args": ["--index-mode", "fast"]}) == []
+ )
+ assert rc.corpora_required_by_spec({}) == []
+
+
+def test_container_corpus_env_key_is_the_harness_definition() -> None:
+ """The coordinator writes this variable and run_benchmark.py reads it. Two spellings
+ would present as a corpus that resolves on the host and vanishes in the container."""
+ assert (
+ rb.corpus_env_key("ai-session-search") == "CBM_BENCH_CORPUS_AI_SESSION_SEARCH"
+ )
+ for corpus_id in ("cosign", "ai-session-search", "codebase-memory-mcp", "runc"):
+ assert rc.corpus_env_key(corpus_id) == rb.corpus_env_key(corpus_id)
+
+
+def test_container_corpus_staging_path_is_pinned_by_revision() -> None:
+ """The work volume is retained for resume, and docker cp merges into an existing
+ directory. A path keyed only by corpus id would leave files from an older pin in
+ place and index a tree that matches no commit."""
+ first = rc.container_corpus_path("cosign", "a" * 40)
+ assert first != rc.container_corpus_path("cosign", "b" * 40)
+ assert first.startswith("/benchmark/corpora/cosign-")
+
+
+def isolated_git_repo() -> Path:
+ """A throwaway repository with one commit, provably outside any real checkout.
+
+ `staged_corpus_revision` reads `git rev-parse HEAD`, so exercising its unpinned path
+ needs a repository that has a commit. The assertion is the point: it makes isolation
+ an enforced precondition rather than an assumption about what mkdtemp returns, so a
+ future edit cannot quietly point repository-mutating commands at a real checkout.
+ """
+ directory = Path(tempfile.mkdtemp(prefix="cbm-rank-test-")).resolve()
+ system_temp = Path(tempfile.gettempdir()).resolve()
+ assert directory.is_relative_to(system_temp), directory
+ assert not (directory / ".git").exists(), directory
+ for command in (
+ ["git", "init", "--quiet"],
+ [
+ "git",
+ "-c",
+ "user.email=t@e",
+ "-c",
+ "user.name=t",
+ "commit",
+ "--quiet",
+ "--allow-empty",
+ "-m",
+ "c",
+ ],
+ ):
+ subprocess.run(command, cwd=directory, check=True, capture_output=True)
+ return directory
+
+
+def test_container_stages_workload_corpora_by_their_resolved_commit() -> None:
+ """Guards: the four mined-workload corpora carry the unpinned sentinel rather than
+ a sha. Keying their staged directory on that literal would give every
+ state of the repository the same path, so a retained work volume would merge two
+ different trees and the manifest would name a commit that does not exist."""
+ pinned = {"id": "cosign", "revision": "a" * 40}
+ assert rc.staged_corpus_revision(pinned, Path("/nonexistent"), 5) == "a" * 40
+
+ repository = isolated_git_repo()
+ resolved = rc.staged_corpus_revision(
+ {"id": "autorun", "revision": rb.UNPINNED_REVISION}, repository, 30
+ )
+ assert len(resolved) == 40 and resolved != rb.UNPINNED_REVISION
+
+ # A typo'd revision must not be staged as "whatever HEAD is" and recorded as the
+ # measured commit; only the declared sentinel opts into resolving at run time.
+ try:
+ rc.staged_corpus_revision({"id": "x", "revision": "abc123"}, repository, 30)
+ except RuntimeError as error:
+ assert "abc123" in str(error)
+ else:
+ raise AssertionError("a malformed revision was staged")
+
+
+def test_container_run_key_separates_different_corpus_pins() -> None:
+ """Resume is keyed by this. Two pins sharing a key would merge measurements taken
+ against different source trees into one runset."""
+
+ def key(revision: str) -> str:
+ return rc.container_run_key(
+ source_revision="c" * 40,
+ repository_snapshot_sha256="d" * 64,
+ matrix_spec_sha256=None,
+ runtime_image_sha256="e" * 64,
+ resources={"cpus": 4, "memory": "8g", "workers": 4},
+ runner_arguments=["--quick"],
+ corpora=[{"id": "cosign", "revision": revision}],
+ )
+
+ assert key("a" * 40) != key("b" * 40)
+ assert key("a" * 40) == key("a" * 40)
+
+
+# --- campaign matrix specs ------------------------------------------------------
+
+
+def resolved_candidate_spec(spec: dict[str, Any]) -> dict[str, Any]:
+ """Substitute a built candidate so the spec can be validated without a build.
+
+ resolve_matrix_spec_candidates validates and materializes in one pass, so a
+ ref-based spec cannot be checked without compiling a binary. Everything the
+ campaign actually configures — capability_quality, index_mode, profiles,
+ benchmark_args, config_overrides — is downstream of that substitution.
+ """
+ stub_binary = Path(tempfile.mkdtemp()) / "cbm"
+ stub_binary.write_bytes(b"stub")
+ document = json.loads(json.dumps(spec))
+ for candidate in document["candidates"]:
+ candidate.pop("ref", None)
+ candidate["revision"] = "0" * 40
+ candidate["binary"] = str(stub_binary)
+ candidate["binary_sha256"] = hashlib.sha256(
+ stub_binary.read_bytes()
+ ).hexdigest()
+ candidate["build"] = {
+ "target": "make -j1 -f Makefile.cbm cbm",
+ "compiler": "clang",
+ "cflags": "-O2",
+ "cxx_compiler": "clang++",
+ "cxxflags": "-O2",
+ "source_commit_datetime": "2026-01-01T00:00:00Z",
+ "source_tree": "2" * 40,
+ }
+ return document
+
+
+def test_every_generated_campaign_spec_expands() -> None:
+ """A spec that fails validation fails after the container image is built and the
+ corpora are staged, which is the most expensive place to learn about a typo."""
+ for spec in cs.build_all_specs():
+ plan = re_.expand_matrix_spec(resolved_candidate_spec(spec))
+ assert plan["cells"], f"{spec['harness_version']} expanded to no cells"
+
+
+def test_campaign_specs_name_only_registered_corpora() -> None:
+ """A corpus id that is not in corpora-v1.json cannot be staged or resolved, and the
+ failure would land mid-campaign rather than at generation time."""
+ registered = set(rb.load_corpora_manifest(""))
+ for spec in cs.build_all_specs():
+ named = set(rc.corpora_required_by_spec(spec))
+ assert named <= registered, f"unregistered: {sorted(named - registered)}"
+
+
+def test_coverage_specs_differ_only_in_index_mode() -> None:
+ """The silent-drop comparison is only valid if the three arms are otherwise
+ identical; any other difference would confound coverage loss with a config change."""
+ coverage = {
+ spec["index_mode"]: spec
+ for spec in cs.build_all_specs()
+ if spec["campaign_arm"] == "coverage"
+ }
+ assert set(coverage) == {"full", "moderate", "fast"}
+ stripped = [
+ json.dumps(
+ {
+ k: v
+ for k, v in spec.items()
+ if k not in {"index_mode", "harness_version"}
+ },
+ sort_keys=True,
+ )
+ for spec in coverage.values()
+ ]
+ assert len(set(stripped)) == 1
+
+
+def test_spec_generation_writes_every_arm_including_the_corpus_free_canary() -> None:
+ """Guards: main() read profile["benchmark_args"][1] to name each corpus, so the
+ canary — whose profiles carry no workload flags at all — raised IndexError after
+ writing its own file and before writing the other four arms. The campaign then ran
+ one arm and the loop reported success for all five."""
+ out = Path(tempfile.mkdtemp())
+ assert cs.main(["--out-dir", str(out), "--corpora", "flask"]) == 0
+ written = {path.name for path in out.glob("*.json")}
+ assert written == {
+ "knob-canary-v1.json",
+ "rank-quality-v1.json",
+ "coverage-full-v1.json",
+ "coverage-moderate-v1.json",
+ "coverage-fast-v1.json",
+ }
+
+
+def test_campaign_specs_are_deterministic() -> None:
+ """The spec sha is part of the container run key, so a regenerated spec that differs
+ byte-wise would start a new runset instead of resuming the existing one."""
+ assert json.dumps(cs.build_all_specs(), sort_keys=True) == json.dumps(
+ cs.build_all_specs(), sort_keys=True
+ )
+
+
+def test_campaign_pilot_subset_rejects_an_unknown_corpus() -> None:
+ """A pilot is meant to fail cheaply. An unrecognised id would otherwise surface
+ after the image build, the candidate build and corpus staging."""
+ assert cs.selected_corpora(("flask",)) == ("flask",)
+ try:
+ cs.selected_corpora(("flsak",))
+ except ValueError as error:
+ assert "flsak" in str(error) and "flask" in str(error)
+ else:
+ raise AssertionError("unknown corpus id was accepted")
+
+
+def test_campaign_pilot_subset_drops_the_detail_frontier_when_absent() -> None:
+ """The detail sweep runs on cosign. A flask-only pilot must not emit cosign cells
+ whose corpus was never staged."""
+ spec = cs.build_rank_spec("HEAD", 1, 60, ("flask",))
+ assert [profile["label"] for profile in spec["profiles"]] == ["corpus-flask"]
+ assert set(rc.corpora_required_by_spec(spec)) == {"flask"}
+
+
+def test_rank_arm_covers_every_pinned_popularity_corpus() -> None:
+ """H4 and H5 need the test-heavy and hub-utility corpora together; dropping one
+ silently narrows the claim the campaign can make."""
+ rank = [s for s in cs.build_all_specs() if s["campaign_arm"] == "rank"]
+ assert len(rank) == 1
+ named = set(rc.corpora_required_by_spec(rank[0]))
+ assert {"cosign", "jest", "runc", "flask", "redis", "ripgrep"} <= named
+
+
+def test_campaign_declares_only_hypotheses_its_cells_can_evaluate() -> None:
+ rank = cs.build_rank_spec("HEAD", 1, 60, ("flask",))
+ canary = cs.build_canary_spec("HEAD", 1, 60)
+ assert rank["evidence_contract"]["hypotheses"] == ["H1", "H2", "H4", "H5", "H6"]
+ assert rank["evidence_contract"]["not_evaluated"] == ["H3", "H7"]
+ assert canary["evidence_contract"]["role"] == "instrument_validity"
+ assert canary["evidence_contract"]["hypotheses"] == []
+ assert set(canary["evidence_contract"]["option_groups"]) == {
+ "ranking_semantics",
+ "numerical_convergence_controls",
+ }
+
+
+def test_quick_hypothesis_profiles_cover_semantics_numerics_and_lifecycle() -> None:
+ spec = cs.build_quick_hypothesis_spec("HEAD", timeout_seconds=90)
+ overrides = {
+ key
+ for profile in spec["profiles"]
+ for key in profile.get("config_overrides", {})
+ }
+ assert {"pagerank_damping", "pagerank_epsilon", "pagerank_max_iter"} <= overrides
+ assert any(profile["label"] == "rank-disabled" for profile in spec["profiles"])
+ assert any(
+ {"edge_weight_calls", "edge_weight_usage", "edge_weight_tests"}
+ <= set(profile.get("config_overrides", {}))
+ for profile in spec["profiles"]
+ )
+ assert "suite_cutoff" not in spec["runtime_policy"]
+ assert "one repetition" in spec["runtime_policy"]["design"]
+ for profile in spec["profiles"]:
+ assert profile["cell_name"]
+ assert profile["informs_hypotheses"]
+ assert profile["questions"]
+ assert all(question["question"] for question in profile["questions"])
+
+
+def test_campaign_cli_writes_only_the_fixed_quick_hypothesis_spec() -> None:
+ """The Docker coordinator accepts a matrix file, so the fixed nine-cell suite
+ needs a supported generator path rather than an undocumented Python import."""
+ with tempfile.TemporaryDirectory() as tmpdir:
+ output = Path(tmpdir)
+ assert (
+ cs.main(
+ [
+ "--quick-hypotheses",
+ "--out-dir",
+ str(output),
+ "--timeout-seconds",
+ "90",
+ ]
+ )
+ == 0
+ )
+ generated = sorted(output.glob("*.json"))
+
+ assert [path.name for path in generated] == ["rank-hypotheses-quick-v2.json"]
+ document = json.loads(generated[0].read_text(encoding="utf-8"))
+ assert document == json.loads(
+ json.dumps(cs.build_quick_hypothesis_spec("HEAD", timeout_seconds=90))
+ )
+ assert len(document["profiles"]) == 9
+ assert document["repetitions"] == 1
+ assert document["transports"] == ["mcp"]
+
+
+def test_rank_probe_reads_directional_node_scores_and_edge_linkrank_together() -> None:
+ directory = Path(tempfile.mkdtemp())
+ make_rank_db(
+ directory,
+ [("target", "src/a.py", 9, 4.0), ("caller", "src/b.py", 1, 2.0)],
+ )
+ probes = rb.run_rank_score_probes(directory, "p", top_n=2, cutoffs=(1, 2))
+ expected = {
+ "degree_unweighted_in",
+ "degree_unweighted_out",
+ "degree_unweighted_total",
+ "degree_weighted_in",
+ "degree_weighted_out",
+ "degree_weighted_total",
+ "calls_in",
+ "calls_out",
+ "calls_total",
+ }
+ assert expected <= set(probes["scorers"])
+ assert probes["edge_linkrank"]["applicable"] is True
+ assert probes["edge_linkrank"]["top_ranked"][0]["edge_type"] == "CALLS"
+ assert probes["edge_type_counts"] == {"CALLS": 1}
+ assert probes["scorer_registry"]["degree_weighted_out"]["direction"] == "out"
+
+
+# --- cross-corpus campaign rollup -----------------------------------------------
+
+
+def rollup_case(
+ corpus: str,
+ *,
+ index_mode: str = "full",
+ directories: dict[str, int] | None = None,
+ utility: dict[str, float] | None = None,
+ scaffolding: dict[str, float | None] | None = None,
+ rho: dict[str, float] | None = None,
+ fresh: bool = True,
+ discriminates: list[str] | None = None,
+ non_public: dict[str, float] | None = None,
+ language: str = "Python",
+ repetition: int = 1,
+) -> dict[str, Any]:
+ scorers = {
+ name: {
+ "applicable": True,
+ "ranked_count": 40,
+ "by_cutoff": {
+ "10": {
+ "window_size": 10,
+ "leaf_hub_rate": value,
+ # Defaults to the leaf-hub value so one helper can drive either
+ # verdict path; an explicit scaffolding dict overrides it.
+ "scaffolding": (scaffolding or {}).get(name, value)
+ if scaffolding is not None
+ else value,
+ "non_public_rate": (non_public or {}).get(name),
+ }
+ },
+ }
+ for name, value in (utility or {"degree": 0.4, "pagerank": 0.1}).items()
+ }
+ return {
+ "parameters": {"index_mode": index_mode, "repetition": repetition},
+ "cases": [
+ {
+ "scenario": "rank_quality",
+ "corpus": {
+ "id": corpus,
+ "revision": "a" * 40,
+ "language": language,
+ "discriminates": discriminates or ["H4", "H5"],
+ },
+ "fixture": {"corpus_overlay": "suppressed"},
+ "rank_score_staleness": {"available": True, "rank_views_fresh": fresh},
+ "rank_score_probes": {
+ "scorers": scorers,
+ # Key shape copied from run_rank_score_probes, not invented: the
+ # first version of this fixture used spearman_vs_degree and the
+ # rollup silently matched nothing on real data.
+ "comparisons": {
+ f"{name}_vs_degree": {
+ "spearman_rho": value,
+ "top_k_jaccard": value,
+ "top_k": 10,
+ "shared_symbols": 19,
+ }
+ for name, value in (rho or {"pagerank": 0.62}).items()
+ },
+ "scaffolding_labels_present": bool(scaffolding),
+ },
+ "corpus_coverage": {
+ "available": True,
+ "indexed_file_count": sum((directories or {"src": 10}).values()),
+ "top_level_directories": dict(directories or {"src": 10}),
+ },
+ }
+ ],
+ }
+
+
+def test_rollup_reports_utility_contamination_per_scorer() -> None:
+ """H1 and H5 in one table: PR #151 says PageRank surfaces utility popularity and
+ degree gives the same signal more cheaply. Both directions have to be readable."""
+ rollup = rr.build_rollup(
+ [rollup_case("cosign", utility={"degree": 0.6, "pagerank": 0.2})]
+ )
+ row = next(r for r in rollup["leaf_hub_rate"] if r["corpus"] == "cosign")
+ assert row["scores"]["degree"] == 0.6
+ assert row["scores"]["pagerank"] == 0.2
+
+
+def test_rollup_verdict_names_the_direction_including_against_us() -> None:
+ """The campaign has to be able to conclude the maintainer was right. A rollup that
+ can only report a win is not evidence."""
+ degree_worse = rr.build_rollup(
+ [rollup_case("cosign", utility={"degree": 0.6, "pagerank": 0.2})]
+ )["verdicts"]["H4"]
+ assert degree_worse["supported"] is None
+ assert degree_worse["effect_direction"] == "degree_higher"
+ assert math.isclose(degree_worse["effect_size"], 0.4)
+
+ degree_better = rr.build_rollup(
+ [rollup_case("cosign", utility={"degree": 0.1, "pagerank": 0.5})]
+ )["verdicts"]["H4"]
+ assert degree_better["supported"] is None
+ assert degree_better["effect_direction"] == "pagerank_higher"
+ assert "degree" in degree_better["statement"].lower()
+
+
+def test_h2_ignores_the_synthetic_fixture() -> None:
+ """Guards: the canary arm contributes 15 cells measured on a 17-file fixture where
+ degree and PageRank agree at Spearman 0.979 by construction. Folding those in
+ reported H2 as "supported over 15 corpora" — PR #151's claim confirmed — from a
+ fixture built to have exactly one structurally central symbol."""
+ synthetic = rollup_case("cosign", rho={"pagerank": 0.98})
+ synthetic["cases"][0]["corpus"] = None
+ rollup = rr.build_rollup([synthetic, rollup_case("redis", rho={"pagerank": 0.36})])
+ verdict = rollup["verdicts"]["H2"]
+ assert verdict["corpora_compared"] == 1
+ assert verdict["spearman_mean"] == 0.36
+ assert verdict["supported"] is None
+ assert verdict["status"] == "measured_descriptive"
+
+
+def test_rollup_reads_the_comparison_keys_the_probe_actually_emits() -> None:
+ """Guards: run_rank_score_probes emits pagerank_vs_degree.spearman_rho. The rollup
+ first looked for a key named pagerank carrying spearman_vs_degree, so H2 read as
+ inconclusive on a corpus that had measured 0.363 — a result contradicting PR #151's
+ "same ranking signal" claim was reported as no data."""
+ rollup = rr.build_rollup([rollup_case("flask", rho={"pagerank": 0.363})])
+ assert rollup["verdicts"]["H2"]["corpora_compared"] == 1
+ assert rollup["verdicts"]["H2"]["supported"] is None
+ assert rollup["verdicts"]["H2"]["status"] == "measured_descriptive"
+
+
+def test_rollup_calls_a_tie_inconclusive_rather_than_a_win() -> None:
+ """Guards: equal means printed "degree DESC is the cleaner arm (0.000 vs 0.000)".
+ flask has no hub utilities, so every scorer scores 0 there and the campaign would
+ have claimed a refutation from a corpus that measured nothing."""
+ all_zero = rr.build_rollup(
+ [rollup_case("flask", utility={"degree": 0.0, "pagerank": 0.0})]
+ )["verdicts"]["H4"]
+ assert all_zero["supported"] is None
+ # All-zero is the more specific diagnosis and takes precedence: the metric did not
+ # discriminate, which is different from two scores that genuinely tied.
+ assert "did not discriminate" in all_zero["statement"]
+
+ equal_but_measured = rr.build_rollup(
+ [
+ rollup_case(name, utility={"degree": 0.2, "pagerank": 0.2})
+ for name in ("cosign", "redis", "runc")
+ ]
+ )["verdicts"]["H4"]
+ assert equal_but_measured["supported"] is None
+ assert "no measurable difference" in equal_but_measured["statement"]
+
+
+def test_rollup_scores_a_hypothesis_only_on_corpora_registered_for_it() -> None:
+ """corpora-v1.json pre-registers which hypothesis each corpus discriminates. flask
+ carries H4 only; averaging its zero utility contamination into H5 would dilute the
+ corpora that were chosen precisely because they have hub utilities."""
+ cases = [
+ {
+ **rollup_case("flask", utility={"degree": 0.0, "pagerank": 0.0}),
+ },
+ {
+ **rollup_case("redis", utility={"degree": 0.6, "pagerank": 0.2}),
+ },
+ ]
+ cases[0]["cases"][0]["corpus"]["discriminates"] = ["H2"]
+ cases[1]["cases"][0]["corpus"]["discriminates"] = ["H4"]
+ verdict = rr.build_rollup(cases)["verdicts"]["H4"]
+ assert verdict["corpora_compared"] == 1
+ assert verdict["degree_mean"] == 0.6
+ assert verdict["not_discriminating"] == ["flask"]
+
+
+def test_rollup_marks_a_stale_corpus_as_not_evidence() -> None:
+ """search_graph silently falls back to a degree sort when the ranking views are
+ stale (src/store/store.c:11695-11711), so a stale cell measures the fallback."""
+ rollup = rr.build_rollup([rollup_case("redis", fresh=False)])
+ assert rollup["excluded"] and rollup["excluded"][0]["reason"] == "rank_views_stale"
+ assert rollup["verdicts"]["H5"]["corpora_compared"] == 0
+
+
+def test_rollup_diffs_coverage_across_index_modes_with_issue_citations() -> None:
+ """The silent-drop claim is per directory, per mode, and each row has to carry the
+ issue that reported it or it is not sourced evidence."""
+ rollup = rr.build_rollup(
+ [
+ rollup_case(
+ "cosign",
+ index_mode="full",
+ directories={"cmd": 40, "scripts": 5, "hack": 3},
+ ),
+ rollup_case("cosign", index_mode="fast", directories={"cmd": 40}),
+ ]
+ )
+ rows = {row["directory"]: row for row in rollup["silent_drop"]}
+ assert rows["scripts"]["files_lost"] == 5
+ assert rows["scripts"]["index_mode"] == "fast"
+ assert "#1406" in rows["scripts"]["issues"]
+ assert rows["hack"]["files_lost"] == 3
+
+
+def test_rollup_reports_no_silent_drop_when_coverage_matches() -> None:
+ rollup = rr.build_rollup(
+ [
+ rollup_case("flask", index_mode="full", directories={"src": 10}),
+ rollup_case("flask", index_mode="fast", directories={"src": 10}),
+ ]
+ )
+ assert rollup["silent_drop"] == []
+
+
+def test_detail_frontier_reports_quality_per_response_token() -> None:
+ """Upstream #1382 measured recall 0.723 -> 0.525 on jackrabbit-oak purely from the
+ graph arm returning less. A ranking change that lets a smaller page carry the same
+ quality is worth more than one that reorders a large page, and only a per-token
+ view can tell those apart."""
+ lean = rollup_case("cosign")
+ lean["parameters"]["config_overrides"] = {"search_limit": "10"}
+ lean["cases"][0]["oracles"] = {
+ "q1": {"response": {}, "response_token_estimate": 400},
+ "quality": {"mean_ndcg_at_5": 0.8, "mean_reciprocal_rank": 0.9},
+ }
+ rich = rollup_case("cosign")
+ rich["parameters"]["config_overrides"] = {"search_limit": "200"}
+ rich["cases"][0]["oracles"] = {
+ "q1": {"response": {}, "response_token_estimate": 4000},
+ "quality": {"mean_ndcg_at_5": 0.85, "mean_reciprocal_rank": 0.9},
+ }
+ rows = {
+ row["detail"]: row for row in rr.build_rollup([lean, rich])["detail_frontier"]
+ }
+ assert rows["search_limit=10"]["response_tokens"] == 400
+ assert rows["search_limit=10"]["ndcg_per_1k_tokens"] == 2.0
+ # 0.05 more nDCG for 10x the tokens is a worse trade, and the table has to show it.
+ assert rows["search_limit=200"]["ndcg_per_1k_tokens"] < 0.25
+
+
+def test_detail_frontier_omits_cells_that_recorded_no_tokens() -> None:
+ """Dividing by a missing token count would print an infinite efficiency."""
+ assert rr.build_rollup([rollup_case("cosign")])["detail_frontier"] == []
+
+
+def test_a_verdict_from_all_zero_measurements_is_explicitly_non_discriminating() -> (
+ None
+):
+ """Guards all three defects found on the first real run: each printed a confident
+ verdict from corpora whose every scorer measured 0.000. A metric that did not move
+ on any corpus did not measure anything, whatever its mean says."""
+ flat = rollup_case("cosign", utility={"degree": 0.0, "pagerank": 0.0})
+ verdict = rr.build_rollup([flat])["verdicts"]["H4"]
+ assert verdict["corpora_with_signal"] == 0
+ assert verdict["status"] == "measured_descriptive"
+ assert verdict["supported"] is None
+ assert "did not discriminate" in verdict["statement"]
+
+
+def test_a_verdict_counts_only_corpora_where_the_metric_moved() -> None:
+ """cosign and runc measured 0.000 utility contamination for every scorer; redis was
+ the only corpus that moved. Averaging three corpora when one carries all the signal
+ reports a campaign result from a single measurement."""
+ zero = rollup_case("cosign", utility={"degree": 0.0, "pagerank": 0.0})
+ signal = rollup_case("redis", utility={"degree": 0.0, "pagerank": 0.1})
+ verdict = rr.build_rollup([zero, signal])["verdicts"]["H4"]
+ assert verdict["corpora_compared"] == 2
+ assert verdict["corpora_with_signal"] == 1
+ assert verdict["status"] == "measured_descriptive"
+ assert verdict["supported"] is None
+ assert math.isclose(verdict["effect_size"], -0.05)
+
+
+def test_more_signal_corpora_increase_coverage_but_do_not_create_a_decision_rule() -> (
+ None
+):
+ cases = [
+ rollup_case(name, utility={"degree": 0.4, "pagerank": 0.1})
+ for name in ("cosign", "redis", "runc")
+ ]
+ verdict = rr.build_rollup(cases)["verdicts"]["H4"]
+ assert verdict["corpora_with_signal"] == 3
+ assert verdict["status"] == "measured_descriptive"
+ assert verdict["supported"] is None
+ assert verdict["effect_size"] == 0.30000000000000004
+
+
+def test_validation_block_reports_every_precondition() -> None:
+ """A reader has to be able to see why a verdict is provisional without rerunning."""
+ validation = rr.build_rollup([rollup_case("cosign")])["validation"]
+ assert validation["knob_canary_passed"] is None
+ assert validation["no_cells_excluded"] is True
+ assert validation["provisional_verdicts"] == [
+ "H1",
+ "H2",
+ "H3",
+ "H4",
+ "H5",
+ "H6",
+ "H7",
+ ]
+ assert validation["passed"] is False
+
+
+def test_markdown_marks_results_as_not_decision_ready() -> None:
+ text = rr.render_markdown(rr.build_rollup([rollup_case("cosign")]))
+ assert "measured_descriptive" in text
+ assert "NOT DECISION-READY" in text
+
+
+def test_rollup_manifest_is_content_addressed() -> None:
+ """The maintainer's stated bar on #1245 was an immutable manifest with a published
+ SHA. A rollup whose bytes are not addressable cannot be cited later."""
+ cases = [rollup_case("cosign")]
+ first = rr.build_rollup(cases)
+ assert (
+ first["manifest"]["rollup_sha256"]
+ == rr.build_rollup(cases)["manifest"]["rollup_sha256"]
+ )
+ assert (
+ first["manifest"]["rollup_sha256"]
+ != rr.build_rollup(
+ [rollup_case("cosign", utility={"degree": 0.9, "pagerank": 0.1})]
+ )["manifest"]["rollup_sha256"]
+ )
+
+
+def test_rollup_renders_markdown_without_inventing_absent_values() -> None:
+ """scaffolding@K is null for an unlabelled corpus; the table must say so rather
+ than print 0.000, which would read as "no scaffolding in the top 10"."""
+ text = rr.render_markdown(rr.build_rollup([rollup_case("redis")]))
+ assert "leaf-hub rate" in text.lower()
+ assert "0.000" not in text.split("Scaffolding")[-1].split("\n\n")[0]
+
+
+def test_rollup_tolerates_documents_without_rank_probes() -> None:
+ assert rr.build_rollup([])["verdicts"]["H5"]["corpora_compared"] == 0
+ assert rr.build_rollup([{"cases": [{"scenario": "other"}]}])["leaf_hub_rate"] == []
+
+
+def test_rollup_lists_all_hypotheses_with_names_and_honest_lifecycle() -> None:
+ rollup = rr.build_rollup([rollup_case("flask")])
+ assert set(rollup["verdicts"]) == {f"H{index}" for index in range(1, 8)}
+ assert rollup["verdicts"]["H3"]["status"] == "not_run"
+ assert rollup["verdicts"]["H6"]["status"] in {
+ "not_run",
+ "instrumented_not_evaluated",
+ }
+ assert rollup["verdicts"]["H7"]["status"] == "not_run"
+ assert all(
+ "name" in verdict and len(verdict["name"].split()) >= 3
+ for verdict in rollup["verdicts"].values()
+ )
+ text = rr.render_markdown(rollup)
+ assert "H3 — PageRank cost without task benefit" in text
+
+
+def test_repetitions_are_not_counted_as_independent_corpora() -> None:
+ documents = [
+ rollup_case("flask", rho={"pagerank": 0.2}, repetition=1),
+ rollup_case("flask", rho={"pagerank": 0.4}, repetition=2),
+ ]
+ verdict = rr.build_rollup(documents)["verdicts"]["H2"]
+ assert verdict["corpora_compared"] == 1
+ assert verdict["observation_count"] == 2
+ assert math.isclose(verdict["spearman_mean"], 0.3)
+
+
+def test_rollup_reports_paired_task_quality_for_each_search_rank_sort() -> None:
+ document = rollup_case("cosign")
+ document["cases"][0]["oracles"] = {
+ "scorer_variant_quality": {
+ "pagerank": {
+ "query_count": 1,
+ "mean_ndcg": 1.0,
+ "mean_reciprocal_rank": 1.0,
+ "hit_at_1_rate": 1.0,
+ },
+ "degree": {
+ "query_count": 1,
+ "mean_ndcg": 0.5,
+ "mean_reciprocal_rank": 0.5,
+ "hit_at_1_rate": 0.0,
+ },
+ }
+ }
+ rollup = rr.build_rollup([document])
+ rows = rollup["retrieval_quality_by_scorer"]
+ assert {row["scorer"] for row in rows} == {"pagerank", "degree"}
+ assert rollup["verdicts"]["H2"]["task_quality_corpora"] == 1
+ assert (
+ "paired graded-query quality" in rollup["verdicts"]["H2"]["statement"].lower()
+ )
+
+
+def test_rollup_reports_language_strata_without_treating_unknown_as_zero() -> None:
+ rollup = rr.build_rollup(
+ [
+ rollup_case("flask", language="Python"),
+ rollup_case("redis", language="C"),
+ rollup_case("legacy", language=""),
+ ]
+ )
+ assert rollup["language_strata"]["Python"]["corpora"] == ["flask"]
+ assert rollup["language_strata"]["C"]["corpora"] == ["redis"]
+ assert rollup["language_strata"]["unknown"]["corpora"] == ["legacy"]
+
+
+def main() -> int:
+ tests = [
+ (name, value)
+ for name, value in sorted(globals().items())
+ if name.startswith("test_") and callable(value)
+ ]
+ failures = 0
+ for name, test in tests:
+ try:
+ test()
+ except Exception as error: # noqa: BLE001 - report and continue
+ failures += 1
+ print(f"FAIL {name}: {type(error).__name__}: {error}")
+ else:
+ print(f"pass {name}")
+ print(f"\n{len(tests) - failures}/{len(tests)} passed")
+ return 1 if failures else 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/cmd/codebase-memory-mcp/assets/skills/codebase-memory-exploring/SKILL.md b/cmd/codebase-memory-mcp/assets/skills/codebase-memory-exploring/SKILL.md
new file mode 100644
index 000000000..e0904efe4
--- /dev/null
+++ b/cmd/codebase-memory-mcp/assets/skills/codebase-memory-exploring/SKILL.md
@@ -0,0 +1,92 @@
+---
+name: codebase-memory-exploring
+description: >
+ This skill should be used when the user asks to "explore the codebase",
+ "understand the architecture", "what functions exist", "show me the structure",
+ "how is the code organized", "find functions matching", "search for classes",
+ "list all routes", "show API endpoints", or needs codebase orientation.
+---
+
+# Codebase Exploration via Knowledge Graph
+
+Use graph tools for structural code questions. They return scoped graph results instead of broad file-search output.
+
+## Workflow
+
+### Step 1: Check if project is indexed
+
+```
+list_projects
+```
+
+If the project is missing from the list:
+
+```
+index_repository(repo_path="/path/to/project")
+```
+
+If already indexed, skip manual indexing unless you need an immediate refresh; auto-sync can refresh the graph when configured.
+
+### Step 2: Get a structural overview
+
+```
+get_graph_schema
+search_graph(mode="summary") # aggregate counts by label and file (top 20)
+```
+
+`get_graph_schema` returns node/edge counts and relationship patterns. `mode=summary` on `search_graph` gives aggregate counts by label type and top 20 files — useful for understanding codebase scope before drilling down.
+
+### Step 3: Find specific code elements
+
+Find functions by name pattern:
+```
+search_graph(label="Function", name_pattern=".*Handler.*")
+```
+
+Find classes:
+```
+search_graph(label="Class", name_pattern=".*Service.*")
+```
+
+Find all REST routes:
+```
+search_graph(label="Route")
+```
+
+Find modules/packages:
+```
+search_graph(label="Module")
+```
+
+Scope to a specific directory:
+```
+search_graph(label="Function", qn_pattern=".*services\\.order\\..*")
+```
+
+### Step 4: Read source code
+
+After finding a function via search, read its source:
+```
+get_code_snippet(qualified_name="project.path.to.FunctionName")
+```
+
+### Step 5: Understand structure
+
+For file/directory exploration within the indexed project:
+```
+list_directory(path="src/services")
+```
+
+## When to Use Grep Instead
+
+- Searching for **string literals** or error messages → `search_code` or Grep
+- Finding a file by exact name → Glob
+- The graph doesn't index text content, only structural elements
+
+## Key Tips
+
+- Results default to 50 per page. Check `has_more` and use `offset` to paginate. Use `pagination_hint` in the response for next page.
+- Use `compact=true` on `search_graph` to reduce token usage by omitting redundant `name` fields.
+- Use `project` parameter when multiple repos are indexed.
+- Route nodes have a `properties.handler` field with the actual handler function name.
+- `exclude_labels` removes noise (e.g., `exclude_labels=["Route"]` when searching by name pattern).
diff --git a/cmd/codebase-memory-mcp/assets/skills/codebase-memory-quality/SKILL.md b/cmd/codebase-memory-mcp/assets/skills/codebase-memory-quality/SKILL.md
new file mode 100644
index 000000000..f213cab2f
--- /dev/null
+++ b/cmd/codebase-memory-mcp/assets/skills/codebase-memory-quality/SKILL.md
@@ -0,0 +1,90 @@
+---
+name: codebase-memory-quality
+description: >
+ This skill should be used when the user asks about "dead code",
+ "find dead code", "detect dead code", "show dead code", "dead code analysis",
+ "unused functions", "find unused functions", "unreachable code",
+ "identify high fan-out functions", "find complex functions",
+ "code quality audit", "find functions nobody calls",
+ "reduce codebase size", "refactor candidates", "cleanup candidates",
+ or needs code quality analysis.
+---
+
+# Code Quality Analysis via Knowledge Graph
+
+Use graph degree filtering to find dead code, high-complexity functions, and refactor candidates — all in single tool calls.
+
+## Workflow
+
+### Dead Code Detection
+
+Find likely isolated functions with zero CALLS degree, excluding entry points:
+
+```
+search_graph(
+ label="Function",
+ relationship="CALLS",
+ max_degree=0,
+ exclude_entry_points=true
+)
+```
+
+`exclude_entry_points=true` removes route handlers, `main()`, and framework-registered functions that have zero callers by design.
+
+### Verify Dead Code Candidates
+
+Before deleting, verify each candidate truly has no callers:
+
+```
+trace_path(function_name="SuspectFunction", direction="inbound", depth=1)
+```
+
+Also check for read references (callbacks, stored in variables):
+
+```
+query_graph(query="MATCH (a)-[r:USAGE]->(b) WHERE b.name = 'SuspectFunction' RETURN a.name, a.file_path LIMIT 10")
+```
+
+### High Fan-Out Functions (calling 10+ others)
+
+These are often doing too much and are refactor candidates:
+
+```
+query_graph(query="MATCH (f)-[:CALLS]->(g) RETURN f.name, count(g) AS out_degree ORDER BY out_degree DESC LIMIT 20")
+```
+
+### High Fan-In Functions (called by 10+ others)
+
+These are critical functions — changes have wide impact:
+
+```
+query_graph(query="MATCH (f)<-[:CALLS]-(g) RETURN f.name, count(g) AS in_degree ORDER BY in_degree DESC LIMIT 20")
+```
+
+### Files That Change Together (Hidden Coupling)
+
+Find files with high git change coupling:
+
+```
+query_graph(query="MATCH (a)-[r:FILE_CHANGES_WITH]->(b) WHERE r.coupling_score >= 0.5 RETURN a.name, b.name, r.coupling_score, r.co_change_count ORDER BY r.coupling_score DESC LIMIT 20")
+```
+
+High coupling between unrelated files suggests hidden dependencies.
+
+### Unused Imports
+
+```
+search_graph(
+ relationship="IMPORTS",
+ max_degree=0,
+ label="Module"
+)
+```
+
+## Key Tips
+
+- `search_graph` defaults to 50 results per page. Use `limit` for more, or `mode=summary` to see total counts first.
+- Use `compact=true` on `search_graph` to reduce token usage in dead code results.
+- Use `file_pattern` to scope analysis to specific directories: `file_pattern="**/services/**"`.
+- Dead code detection works best after a full index — run `index_repository` if the project was recently set up.
+- Paginate results with `limit` and `offset` — check `has_more` and `pagination_hint` in the response.
diff --git a/cmd/codebase-memory-mcp/assets/skills/codebase-memory-reference/SKILL.md b/cmd/codebase-memory-mcp/assets/skills/codebase-memory-reference/SKILL.md
new file mode 100644
index 000000000..d22b6472e
--- /dev/null
+++ b/cmd/codebase-memory-mcp/assets/skills/codebase-memory-reference/SKILL.md
@@ -0,0 +1,176 @@
+---
+name: codebase-memory-reference
+description: >
+ This skill should be used when the user asks about "codebase-memory-mcp tools",
+ "graph query syntax", "Cypher query examples", "edge types",
+ "how to use search_graph", "query_graph examples", or needs reference
+ documentation for the codebase knowledge graph tools.
+---
+
+# Codebase Memory MCP — Tool Reference
+
+## Tools
+
+| Tool | Purpose |
+|------|---------|
+| `index_repository` | Parse and ingest repo into graph; auto-sync can refresh it when configured |
+| `index_status` | Check indexing status (ready/indexing/not found) |
+| `list_projects` | List all indexed projects with timestamps and counts |
+| `delete_project` | Remove a project from the graph |
+| `search_graph` | Structured search with filters (name, label, degree, file pattern). Supports `mode=summary` for aggregate counts, `compact=true` to reduce tokens. |
+| `search_code` | Grep-like text search within indexed project files |
+| `trace_path` | BFS call chain traversal. Supports `risk_labels=true`, `compact=true`, `max_results`. |
+| `detect_changes` | Map git diff to affected symbols + blast radius with risk scoring |
+| `query_graph` | Cypher-like graph queries. Output capped at `max_output_bytes` (default 32KB). |
+| `get_graph_schema` | Node/edge counts, relationship patterns |
+| `get_code_snippet` | Read source code by qualified name. Supports `mode=signature` (API only) and `mode=head_tail` (preserve start+end). |
+| `get_architecture` | Architecture summary, clusters, routes, dependencies, and key functions |
+| `manage_adr` | Read or update Architecture Decision Records |
+| `ingest_traces` | Ingest OpenTelemetry traces to validate HTTP_CALLS edges |
+| `index_dependencies` | Index local dependency source under `{project}.dep.{name}` |
+
+## Edge Types
+
+| Type | Meaning |
+|------|---------|
+| `CALLS` | Direct function call within same service |
+| `HTTP_CALLS` | Synchronous cross-service HTTP request |
+| `ASYNC_CALLS` | Async dispatch (Cloud Tasks, Pub/Sub, SQS, Kafka) |
+| `IMPORTS` | Module/package import |
+| `DEFINES` / `DEFINES_METHOD` | Module/class defines a function/method |
+| `HANDLES` | Route node handled by a function |
+| `IMPLEMENTS` | Type implements an interface |
+| `OVERRIDE` | Struct method overrides an interface method |
+| `USAGE` | Read reference (callback, variable assignment) |
+| `FILE_CHANGES_WITH` | Git history change coupling |
+| `CONTAINS_FILE` / `CONTAINS_FOLDER` / `CONTAINS_PACKAGE` | Structural containment |
+
+## Node Labels
+
+`Project`, `Package`, `Folder`, `File`, `Module`, `Class`, `Function`, `Method`, `Interface`, `Enum`, `Type`, `Route`
+
+## Qualified Name Format
+
+`..` — file path with `/` replaced by `.`, extension removed.
+
+Examples:
+- `myproject.cmd.server.main.HandleRequest` (Go)
+- `myproject.services.orders.ProcessOrder` (Python)
+- `myproject.src.components.App.App` (TypeScript)
+
+Use `search_graph` to discover qualified names, then pass them to `get_code_snippet`.
+
+## Cypher Subset (for query_graph)
+
+**Supported:**
+- `MATCH` with node labels and relationship types
+- Variable-length paths: `-[:CALLS*1..3]->`
+- `WHERE` with `=`, `<>`, `>`, `<`, `>=`, `<=`, `=~` (regex), `CONTAINS`, `STARTS WITH`
+- `WHERE` with `AND`, `OR`, `NOT`
+- `RETURN` with property access, `COUNT(x)`, `DISTINCT`
+- `ORDER BY` with `ASC`/`DESC`
+- `LIMIT`
+- Edge property access: `r.confidence`, `r.url_path`, `r.coupling_score`
+
+**Not supported:** `WITH`, `COLLECT`, `SUM`, `CREATE/DELETE/SET`, `OPTIONAL MATCH`, `UNION`
+
+## Common Cypher Patterns
+
+```
+# Cross-service HTTP calls with confidence
+MATCH (a)-[r:HTTP_CALLS]->(b) RETURN a.name, b.name, r.url_path, r.confidence LIMIT 20
+
+# Filter by URL path
+MATCH (a)-[r:HTTP_CALLS]->(b) WHERE r.url_path CONTAINS '/orders' RETURN a.name, b.name
+
+# Interface implementations
+MATCH (s)-[r:OVERRIDE]->(i) RETURN s.name, i.name LIMIT 20
+
+# Change coupling
+MATCH (a)-[r:FILE_CHANGES_WITH]->(b) WHERE r.coupling_score >= 0.5 RETURN a.name, b.name, r.coupling_score
+
+# Functions calling a specific function
+MATCH (f:Function)-[:CALLS]->(g:Function) WHERE g.name = 'ProcessOrder' RETURN f.name LIMIT 20
+```
+
+## Regex-Powered Search (No Full-Text Index Needed)
+
+`search_graph` and `search_code` support full Go regex, making full-text search indexes unnecessary. Regex patterns provide precise, composable queries that cover all common discovery scenarios:
+
+### search_graph — name_pattern / qn_pattern
+
+| Pattern | Matches | Use case |
+|---------|---------|----------|
+| `.*Handler$` | names ending in Handler | Find all handlers |
+| `(?i)auth` | case-insensitive "auth" | Find auth-related symbols |
+| `get\|fetch\|load` | any of three words | Find data-loading functions |
+| `^on[A-Z]` | names starting with on + uppercase | Find event handlers |
+| `.*Service.*Impl` | Service...Impl pattern | Find service implementations |
+| `^(Get\|Set\|Delete)` | CRUD prefixes | Find CRUD operations |
+| `.*_test$` | names ending in _test | Find test functions |
+| `.*\\.controllers\\..*` | qn_pattern for directory scoping | Scope to controllers dir |
+
+### search_code — regex=true
+
+| Pattern | Matches | Use case |
+|---------|---------|----------|
+| `TODO\|FIXME\|HACK` | multi-pattern scan | Find tech debt markers |
+| `(?i)password\|secret\|token` | case-insensitive secrets | Security scan |
+| `func\\s+Test` | Go test functions | Find test entry points |
+| `api[._/]v[0-9]` | API version references | Find versioned API usage |
+| `import.*from ['"]@` | scoped npm imports | Find package imports |
+
+### Combining Filters for Surgical Queries
+
+```
+# Find unused auth handlers
+search_graph(name_pattern="(?i).*auth.*handler.*", max_degree=0, exclude_entry_points=true)
+
+# Find high fan-out functions in the services directory
+query_graph(query="MATCH (f)-[:CALLS]->(g) WHERE f.qualified_name =~ '.*\\.services\\..*' RETURN f.name, count(g) AS out_degree ORDER BY out_degree DESC LIMIT 20")
+
+# Find all route handlers matching a URL pattern
+search_code(pattern="(?i)(POST|PUT).*\\/api\\/v[0-9]\\/orders", regex=true)
+```
+
+## Token Reduction Parameters
+
+These parameters reduce response size (tokens) without affecting indexed data:
+
+| Parameter | Tool | Effect |
+|-----------|------|--------|
+| `mode="summary"` | `search_graph` | Return aggregate counts by label/file instead of individual results (~99% reduction) |
+| `mode="signature"` | `get_code_snippet` | Return only function signature, params, return type (~99% reduction) |
+| `mode="head_tail"` | `get_code_snippet` | Return first 60% + last 40% of lines, preserving signature and return/cleanup |
+| `compact=true` | `search_graph`, `trace_path` | Omit `name` field when redundant with `qualified_name` (~15-25% reduction) |
+| `max_lines=N` | `get_code_snippet` | Cap source lines (default 200, set 0 for unlimited) |
+| `max_output_bytes=N` | `query_graph` | Cap response bytes (default 32KB, set 0 for unlimited) |
+| `max_results=N` | `trace_path` | Cap BFS results per direction (default 25) |
+
+All defaults are configurable via `codebase-memory-mcp config set `:
+`search_limit`, `snippet_max_lines`, `trace_max_results`, `query_max_output_bytes`.
+
+## Critical Pitfalls
+
+1. **`search_graph(relationship="HTTP_CALLS")` does NOT return edges** — it filters nodes by degree. Use `query_graph` with Cypher to see actual edges.
+2. **`query_graph` output is capped at 32KB by default** — add LIMIT to your Cypher query or set `max_output_bytes=0` for unlimited.
+3. **`trace_path` works best with exact names** — use `search_graph(name_pattern=".*Partial.*")` first to discover names.
+4. **`direction="outbound"` misses cross-service callers** — use `direction="both"` for full context.
+5. **`search_graph` defaults to 50 results** — use `limit` parameter for more, or `mode=summary` to see total counts first.
+
+## Decision Matrix
+
+| Question | Use |
+|----------|-----|
+| Who calls X? | `trace_path(direction="inbound")` |
+| What does X call? | `trace_path(direction="outbound")` |
+| Full call context | `trace_path(direction="both")` |
+| Find by name pattern | `search_graph(name_pattern="...")` |
+| Dead code | `search_graph(max_degree=0, exclude_entry_points=true)` |
+| Cross-service edges | `query_graph` with Cypher |
+| Impact of local changes | `detect_changes()` |
+| Risk-classified trace | `trace_path(risk_labels=true)` |
+| Text search | `search_code` or Grep |
+| Quick codebase overview | `search_graph(mode="summary")` |
+| Function API only | `get_code_snippet(mode="signature")` |
+| Large function safely | `get_code_snippet(mode="head_tail")` |
diff --git a/cmd/codebase-memory-mcp/assets/skills/codebase-memory-tracing/SKILL.md b/cmd/codebase-memory-mcp/assets/skills/codebase-memory-tracing/SKILL.md
new file mode 100644
index 000000000..532940f8a
--- /dev/null
+++ b/cmd/codebase-memory-mcp/assets/skills/codebase-memory-tracing/SKILL.md
@@ -0,0 +1,127 @@
+---
+name: codebase-memory-tracing
+description: >
+ This skill should be used when the user asks "who calls this function",
+ "what does X call", "trace the call chain", "find callers of",
+ "show dependencies", "what depends on", "trace call path",
+ "find all references to", "impact analysis", or needs to understand
+ function call relationships and dependency chains.
+---
+
+# Call Chain Tracing via Knowledge Graph
+
+Use graph tools to trace function call relationships. One `trace_path` call replaces dozens of grep searches across files.
+
+## Workflow
+
+### Step 1: Discover the exact function name
+
+`trace_path` works best with an exact name. If you don't know the exact name, discover it first with regex:
+
+```
+search_graph(name_pattern=".*Order.*", label="Function")
+```
+
+Use full regex for precise discovery — no full-text search needed:
+- `(?i)order` — case-insensitive
+- `^(Get|Set|Delete)Order` — CRUD variants
+- `.*Order.*Handler$` — handlers only
+- `qn_pattern=".*services\\.order\\..*"` — scope to order service directory
+
+This returns matching functions with their qualified names and file locations.
+
+### Step 2: Trace callers (who calls this function?)
+
+```
+trace_path(function_name="ProcessOrder", direction="inbound", depth=3)
+```
+
+Returns a hop-by-hop list of all functions that call `ProcessOrder`, up to 3 levels deep.
+
+### Step 3: Trace callees (what does this function call?)
+
+```
+trace_path(function_name="ProcessOrder", direction="outbound", depth=3)
+```
+
+### Step 4: Full context (both callers and callees)
+
+```
+trace_path(function_name="ProcessOrder", direction="both", depth=3)
+```
+
+**Use `direction="both"` for complete context.** Cross-service HTTP_CALLS edges from other services appear as inbound edges — `direction="outbound"` alone misses them.
+
+### Step 5: Read suspicious code
+
+After finding interesting callers/callees, read their source:
+
+```
+get_code_snippet(qualified_name="project.path.module.FunctionName")
+get_code_snippet(qualified_name="project.path.module.FunctionName", mode="signature") # API only, saves tokens
+```
+
+## Cross-Service HTTP Calls
+
+To see all HTTP links between services with URLs and confidence scores:
+
+```
+query_graph(query="MATCH (a)-[r:HTTP_CALLS]->(b) RETURN a.name, b.name, r.url_path, r.confidence ORDER BY r.confidence DESC LIMIT 20")
+```
+
+Filter by URL path:
+```
+query_graph(query="MATCH (a)-[r:HTTP_CALLS]->(b) WHERE r.url_path CONTAINS '/orders' RETURN a.name, b.name, r.url_path")
+```
+
+## Async Dispatch (Cloud Tasks, Pub/Sub, etc.)
+
+Find dispatch functions by name pattern, then trace:
+```
+search_graph(name_pattern=".*CreateTask.*|.*send_to_pubsub.*")
+trace_path(function_name="CreateMultidataTask", direction="both")
+```
+
+## Interface Implementations
+
+Find which structs implement an interface method:
+```
+query_graph(query="MATCH (s)-[r:OVERRIDE]->(i) WHERE i.name = 'Read' RETURN s.name, i.name LIMIT 20")
+```
+
+## Read References (callbacks, variable assignments)
+
+```
+query_graph(query="MATCH (a)-[r:USAGE]->(b) WHERE b.name = 'ProcessOrder' RETURN a.name, a.file_path LIMIT 20")
+```
+
+## Risk-Classified Impact Analysis
+
+Add `risk_labels=true` to get risk classification on each node:
+
+```
+trace_path(function_name="ProcessOrder", direction="inbound", depth=3, risk_labels=true)
+```
+
+Returns nodes with `risk` (CRITICAL/HIGH/MEDIUM/LOW) based on hop depth, plus an `impact_summary` with counts. Risk mapping: hop 1=CRITICAL, 2=HIGH, 3=MEDIUM, 4+=LOW.
+
+## Detect Changes (Git Diff Impact)
+
+Map uncommitted changes to affected symbols and their blast radius:
+
+```
+detect_changes()
+detect_changes(scope="staged")
+detect_changes(scope="branch", base_branch="main")
+```
+
+Returns changed files, changed symbols, and impacted callers with risk classification. Scopes: `unstaged`, `staged`, `all` (default), `branch`.
+
+## Key Tips
+
+- Start with `depth=1` for quick answers, increase only if needed (max 5).
+- Edge types in trace results: `CALLS` (direct), `HTTP_CALLS` (cross-service), `ASYNC_CALLS` (async dispatch), `USAGE` (read reference), `OVERRIDE` (interface implementation).
+- `search_graph(relationship="HTTP_CALLS")` filters nodes by degree — it does NOT return edges. Use `query_graph` with Cypher to see actual edges with properties.
+- Default `max_results=25` per direction (configurable). Use `max_results=100` for exhaustive traces.
+- Use `compact=true` on `trace_path` to reduce token usage by omitting redundant `name` fields.
+- `detect_changes` requires git in PATH.
diff --git a/docs/BENCHMARK_CAMPAIGN.md b/docs/BENCHMARK_CAMPAIGN.md
new file mode 100644
index 000000000..6b220690e
--- /dev/null
+++ b/docs/BENCHMARK_CAMPAIGN.md
@@ -0,0 +1,13 @@
+# Legacy benchmark documentation path
+
+This document moved to [`docs/BENCHMARK_EXPERIMENTS.md`](BENCHMARK_EXPERIMENTS.md).
+
+New documentation and interfaces use "experiment". Existing runsets remain readable:
+
+- `--campaign-root` still works as an alias for `--experiment-root`.
+- Automatic runs retain `.worktrees/benchmark-campaign/` so old results resume.
+- Retained `scripts/benchmark-incremental-speed.py` plan entries resolve to
+ `benchmarks/run_benchmark.py` when the recorded path no longer exists.
+
+This file is kept as a short pointer stub (rather than deleted) so existing links
+and bookmarks to `docs/BENCHMARK_CAMPAIGN.md` keep resolving.
diff --git a/docs/BENCHMARK_EXPERIMENTS.md b/docs/BENCHMARK_EXPERIMENTS.md
new file mode 100644
index 000000000..00de54353
--- /dev/null
+++ b/docs/BENCHMARK_EXPERIMENTS.md
@@ -0,0 +1,780 @@
+# Reproducible benchmark experiments
+
+`benchmarks/run_experiments.py` runs a JSON plan sequentially and keeps every
+attempt under a content-addressed cell directory. It is intended for release-build
+comparisons where correctness and query-result quality are gates, not optional
+context around a speed claim. New automation uses this entry point and
+`--experiment-root`. When retained plan or command records name a retired benchmark
+script path, the loader resolves that path to the canonical entry point; no executable
+compatibility wrapper is installed. Legacy flag aliases, persisted JSON keys, and the
+`.worktrees/benchmark-campaign/` location remain readable for retained runs.
+Retained plans may also name the removed `optional_graph_disabled` profile; it resolves
+to the same capability manifest as `minimal_indexing`, which is the only one new
+automatic plans emit.
+
+Use a durable ignored experiment root. Automatic runs continue to use
+`.worktrees/benchmark-campaign/` so existing retained runsets resume in place.
+The runner rejects the operating-system temporary tree by default because a crash
+or reboot can otherwise erase manifests, results, and logs. Do not track generated
+results or the generated Markdown report in Git.
+
+## Repository layout
+
+Branch-created benchmark code, active schemas, terminology, configuration data, and
+fixtures live under `benchmarks/`. The three benchmark shell scripts inherited from
+upstream remain at their established `scripts/` paths. Human-facing guides remain
+under `docs/`, tests under `tests/`, and the generated profiling header under `src/`
+because those files belong to their respective integration surfaces.
+
+New commands and source anchors use `benchmarks/`. The frozen
+`docs/schema/benchmark-facts-v1.schema.json` remains at its original URI because
+retained v1 bundles embed that exact identifier. The loaders accept the former v2
+schema URI and recorded terminology hash, while new bundles emit only the canonical
+`benchmarks/schema/facts-v2.schema.json` URI. The experiment runner resolves the
+retired single-run script path in retained plans without shipping a duplicate
+entry point.
+
+## Cell identity
+
+A cell ID is the first 24 hexadecimal characters of the SHA-256 of these canonical
+JSON fields:
+
+- full revision and binary SHA-256;
+- build metadata, including the compiler and optimization flags;
+- capability configuration;
+- transport, scenario, repetition, and harness version;
+- command, working directory, environment overrides, timeout, and accepted exit codes.
+
+Changing any of those inputs creates a different cell. A completed cell is resumed
+only when its completion marker, retained result, result SHA-256, binary SHA-256,
+current plan identity, and every archived artifact path, size, and SHA-256 agree.
+
+## Canonical fact tables
+
+Every new benchmark result also writes a schema-valid `facts.json` bundle, normalized
+`runs.json`, `steps.jsonl`, `results.json`, and `artifacts.json` tables, and a hashed
+`manifest.json` under the experiment attempt's artifact directory. Standalone runs use
+`--facts-dir DIR`; when only `--out result.json` is given, facts default to
+`result.facts/`. New bundles use `benchmarks/schema/facts-v2.schema.json`;
+the retained v1 schema remains available for earlier runsets. The
+canonical benchmark vocabulary is `benchmarks/terminology.json`; its generated
+human-readable view is [BENCHMARK_TERMINOLOGY.md](BENCHMARK_TERMINOLOGY.md).
+`uv run python benchmarks/run_benchmark.py --describe-terms
+json|markdown` prints either view without requiring a benchmark binary.
+
+The run row records the experiment cell ID and label, exact candidate commit,
+repetition, binary path/hash/size, build metadata, harness hash, host metadata,
+capability arguments, workload scope, and per-layer cache knowledge. Step rows keep
+each occurrence separate and distinguish elapsed work from CPU, queue, worker,
+dependency, and monotonic-boundary fields. A field absent from the historical
+measurement is an explicit `{"status":"unknown","reason":"..."}` value; it is
+never reconstructed from a preset name or treated as suitable for a parity join.
+Every fact bundle records the terminology version, canonical-content SHA-256, and
+benchmark-generator SHA-256. A retained bundle therefore identifies the exact
+definitions and normalizer that gave each field and step ID its meaning.
+Experiment cells supply the candidate commit and build metadata automatically.
+Standalone runs must pass `--candidate-revision FULL_COMMIT` and
+`--build-metadata-json '{...}'` to make those fields authoritative; otherwise the
+current checkout HEAD is retained separately as measurement context and the binary's
+source revision/build flags remain `unknown`.
+
+When every completed experiment cell has a canonical fact bundle, report generation
+also writes `*.comparisons.json` and `*.fact-appendix.md`. The JSON conforms to
+`benchmarks/schema/comparisons-v1.schema.json` and retains the source bundle,
+run, and occurrence IDs behind every derived row. It classifies each cell pair as:
+
+- `parity_comparison`: identical mode, complete effective capabilities, scope,
+ cache state, host, benchmark contract, and correctness contract, with no unknown
+ required value. Only this class may report a cross-implementation elapsed-time
+ ratio.
+- `capability_delta_comparison`: identical mode, scope, cache state, host, benchmark
+ contract, and correctness contract, but explicitly different complete capability
+ manifests. It reports the differences and no speed ratio.
+- `not_eligible`: a required equality failed or required evidence is incomplete or
+ unknown. The record states each rejection reason.
+
+The emitted `join_id` and `formula_id` values have normative definitions in the
+terminology registry. Lifecycle tables select recorded outer lifecycle occurrences;
+they never construct wall time by summing child spans that may overlap or execute on
+different threads or processes. Reports for retained runs that predate fact bundles
+still render, but state that fact-derived comparisons are unavailable.
+
+Retained reports from earlier harness versions remain usable:
+
+```bash
+uv run python benchmarks/run_benchmark.py \
+ --import-report path/to/result.json \
+ --facts-dir path/to/recovered-facts
+```
+
+The importer recovers binary identity, recorded configuration, elapsed phases,
+peak RSS, outcomes, and retained-log hashes when present. It preserves missing
+revision, build, cache, CPU, timestamp, worker, and concurrency evidence as
+`unknown`, so generated comparisons can state the historical limitation rather
+than silently inventing parity.
+
+### Fact vocabulary and timing rules
+
+These terms are normative in the runner, schema, JSON tables, and generated reports:
+
+| Term | Meaning |
+|---|---|
+| Experiment | One declared comparison design: its candidates, capabilities, workloads, transports, repetitions, and execution order. |
+| Runset | The immutable experiment specification identified by the first 12 hexadecimal characters of its canonical JSON SHA-256. Reusing identical semantic inputs resumes the same runset. |
+| Cell | One fully resolved point in the experiment matrix, including one candidate revision, binary, build, capability map, workload, transport, and repetition. |
+| Attempt | One process execution of a cell. Failed or interrupted attempts remain evidence; only a validated attempt creates `complete.json`. |
+| Lifecycle | The user-observable sequence represented by one `run_id`, from process invocation through the benchmark gate. Component steps may overlap within it. |
+| Run row | Identity and conditions shared by every observation in one lifecycle: implementation, harness, host, capability, scope, and cache facts. |
+| Step row | One measured operation occurrence. `step_id` names the operation class; `occurrence_id` identifies this occurrence, so repeated operations are never merged. |
+| Parent occurrence | A containment relation in the recorded operation hierarchy. It does not prove that parent and child executed serially. |
+| Dependency occurrence | A measured predecessor that must finish before the step can proceed. An empty list means no dependency edge was recorded, not that the step was independent. |
+| `elapsed_ms` | Wall-clock duration of that occurrence. Overlapping parent, child, or sibling durations must not be summed. |
+| `cpu_ms` | CPU time consumed by the named `cpu_scope`. It remains `unknown` when the profiler recorded only wall time. |
+| `queue_wait_ms` | Time after the operation became runnable but before its worker began executing. It remains `unknown` without scheduler instrumentation. |
+| Critical path | The dependency-chain duration that determines lifecycle wall time. It remains `unknown` unless timestamped dependency events make the chain recoverable. |
+| Result row | A correctness, quality, or instrumentation outcome. Product-contract failures and harness failures use different `kind` values. |
+| Artifact row | A retained file identified by path, byte count when known, and SHA-256. |
+| Unknown fact | `{"status":"unknown","reason":"..."}`: the source did not record the value. Unknown values prohibit capability-parity joins and arithmetic. |
+
+`timing_components_ms` values parsed from existing worker profile markers become
+separate step occurrences. The current markers provide elapsed wall time and
+containment but not start/end timestamps, worker IDs, CPU time, queue wait, or a
+dependency event graph; those fields therefore remain explicitly `unknown`.
+This preserves parallel implementations without pretending their overlapping work
+was serial. Future low-overhead instrumentation can populate the same fields without
+changing the fact-table contract.
+
+For index results, `elapsed_ms` is the user-visible tool-call boundary.
+`worker_elapsed_ms` is the supervised worker lifetime when that marker exists, and
+`process_overhead_ms` is the non-negative difference between those two recorded
+boundaries. `indexed_work_elapsed_ms` is the narrower full or incremental pipeline
+marker inside the worker. These are nested observations: do not add worker and
+indexed-work durations to the user lifecycle, and do not describe
+`process_overhead_ms` as indexing algorithm time.
+
+## Plan format
+
+```json
+{
+ "schema_version": 1,
+ "cells": [
+ {
+ "label": "final-defaults",
+ "revision": "0123456789abcdef0123456789abcdef01234567",
+ "binary_sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
+ "build": {
+ "target": "make -f Makefile.cbm cbm",
+ "compiler": "Apple clang 17.0.0",
+ "cflags": "-O2 -DCBM_BIND_TS_ALLOCATOR=1"
+ },
+ "capabilities": {},
+ "transport": "mcp",
+ "scenario": "self_dogfood",
+ "repetition": 1,
+ "harness_version": "run_benchmark.py:",
+ "cwd": "/absolute/path/to/codebase-memory-mcp",
+ "command": [
+ "uv", "run", "python", "benchmarks/run_benchmark.py",
+ "--binary", "/absolute/path/to/release-binary",
+ "--self-dogfood", "--repo-root", "/absolute/path/to/codebase-memory-mcp",
+ "--transport", "mcp", "--out", "{result_path}"
+ ],
+ "accepted_exit_codes": [0, 1],
+ "timeout_seconds": 3600
+ }
+ ]
+}
+```
+
+Exit code `1` is explicit in this example because the benchmark harness uses it for
+a valid measurement that fails a quality or performance gate. The experiment runner
+still requires a parseable result whose `binary_metadata.sha256` matches the plan.
+Crashes, timeouts, other exit codes, missing results, and mismatched binaries remain
+failed attempts and never receive `complete.json`.
+
+For compact `--matrix-spec` grids, each scenario requires `frontier_files` and
+`exact_caps` arrays. Use a positive integer cap for an explicit cap sweep. Use
+`null` to preserve each candidate's configured/default
+`incremental_exact_max_affected_paths`; the generated cell is labelled
+`capdefault` and does not inject a config override.
+
+### Reusable ref-based matrices
+
+A compact matrix may name arbitrary Git refs instead of embedding candidate binary
+paths. This is the preferred long-lived interface for comparing new branches,
+capabilities, configuration values, worker counts, memory budgets, and workload
+flags after the built-in dated presets become irrelevant:
+
+```json
+{
+ "schema_version": 1,
+ "identity_version": 2,
+ "harness_version": "development-comparison-v1",
+ "benchmark_script": "benchmarks/run_benchmark.py",
+ "cwd": ".",
+ "repetitions": 3,
+ "execution_order": "paired_interleaved",
+ "transports": ["mcp"],
+ "build_environment": {
+ "CC": "clang",
+ "CXX": "clang++"
+ },
+ "candidates": [
+ {
+ "label": "baseline",
+ "ref": "main",
+ "capability_support": {"rank": true, "dependencies": true}
+ },
+ {
+ "label": "candidate",
+ "ref": "feature/new-design",
+ "capability_support": {"rank": true, "dependencies": true}
+ }
+ ],
+ "profiles": [
+ {
+ "label": "default-workers",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {}
+ },
+ {
+ "label": "four-workers",
+ "config_profile": "candidate_native_configuration",
+ "capabilities": {},
+ "product_environment": {"CBM_WORKERS": "4"},
+ "benchmark_args": ["--overhead-probes", "3"]
+ }
+ ],
+ "scenarios": [
+ {
+ "name": "go_modify_1",
+ "frontier_files": [4, 64],
+ "exact_caps": [null]
+ }
+ ]
+}
+```
+
+Run it from a repository checkout:
+
+```sh
+uv run python benchmarks/run_experiments.py \
+ --matrix-spec /absolute/path/development-comparison.json \
+ --experiment-root /durable/ignored/path/development-comparison
+```
+
+The source spec is archived by SHA-256. Each `ref` is resolved to a full commit,
+built in a detached worktree, and replaced in a separate resolved spec by the
+existing `revision`, `binary`, `binary_sha256`, compiler, flags, tree, and commit
+metadata. The source object is not modified. A ref entry cannot also claim a
+prebuilt binary or revision.
+
+Use the existing axes rather than adding branch-specific code:
+
+| Need | Matrix field | Behavior |
+|---|---|---|
+| Shared compiler/diagnostic settings | `build_environment` | Allowlisted `CC`, `CXX`, `EXTRA_CFLAGS`, and `EXTRA_CXXFLAGS`; passed as environment and argv-safe Make overrides to probes, clean builds, and production builds, then retained beside the effective C/C++ compiler identities and expanded production flags |
+| Product configuration | `config_overrides` | Passed through the versioned config-spelling compatibility path |
+| Process/resource knob | `product_environment` | Explicit `CBM_*` variables only; inherited product variables remain removed |
+| New optional benchmark workload flag | `benchmark_args` | Additive arguments; experiment-owned identity, output, transport, config, and scenario flags are rejected |
+| Candidate compatibility | `capability_support` | Records which correctness gates apply without pretending unsupported features exist |
+| Branch-specific ablation | `candidate_labels` on a profile | Applies a profile only to named compatible candidates |
+
+Top-level product environment is overridden by candidate, then profile, then
+scenario values. Benchmark arguments are appended in that same order.
+Top-level build environment is deliberately shared by every ref candidate so a
+comparison cannot silently build candidates with different compiler settings.
+`CBM_CACHE_DIR`, `CBM_PROFILE`, auto-index isolation, and run-context variables stay
+harness-owned so a matrix cannot redirect live data or suppress measurement logs.
+Fully resolved historical specs remain valid, and specs that omit these new fields
+retain their previous cell shape and identity.
+
+Candidate source/build locations are execution settings rather than matrix
+semantics. New worktrees use `/.worktrees/benchmark-candidates` unless
+`--candidate-root` selects another writable primary. Repeat
+`--candidate-search-root` to search moved existing roots in preferred order:
+
+```sh
+uv run python benchmarks/run_experiments.py \
+ --matrix-spec /absolute/path/development-comparison.json \
+ --experiment-root /durable/ignored/path/development-comparison \
+ --candidate-root /fast-storage/cbm-candidates \
+ --candidate-search-root /archive/previous-candidates \
+ --candidate-search-root /mounted/team-candidates
+```
+
+Only clean worktrees registered to the current Git repository and pinned to the
+exact candidate commit are eligible. The runner creates worktrees, build logs,
+and cache metadata only under the primary root. A selected existing worktree may
+have its ordinary `build/` directory cleaned and rebuilt so the recorded compiler,
+flags, and binary hash are trustworthy. A missing search root fails with its
+resolved path instead of silently falling back. Resolved candidate records retain
+the selected binary path and SHA-256, so moved-root reuse remains auditable without
+embedding machine-specific paths in the reusable source matrix.
+
+### Container isolation
+
+Container execution is selected on the same `run_experiments.py` interface used for
+native experiments. Internally, `run_container_experiment.py` remains a thin isolation
+adapter around that scientific runner. Use `--container` when several exact builds
+must exercise their real daemon-backed CLI or MCP paths without joining the host
+account's active exact-build cohort:
+
+```sh
+uv run python benchmarks/run_experiments.py \
+ --matrix-spec /absolute/path/development-comparison.json \
+ --experiment-root /durable/ignored/path/development-comparison \
+ --container \
+ --cpus 4 \
+ --memory 8g \
+ --workers 4 \
+ --minimum-free-gb 4
+```
+
+Remove only `--container` and its CPU, memory, and worker budget to execute the same
+matrix natively. Matrix paths, experiment roots, transport, candidate refs, product
+environment, resume, and `--audit-only` retain one spelling. The adapter's direct CLI
+remains available for compatibility and low-level diagnosis, but it is not the primary
+user interface.
+
+The coordinator is intentionally smaller than the benchmark engine:
+
+1. It refuses tracked source changes and bundles exact `HEAD`, branch, tag, and
+ remote refs without moving them. Stash and other non-branch/tag/remote namespaces
+ are excluded from benchmark input.
+2. It builds or identifies the digest-pinned
+ `test-infrastructure/Dockerfile` image and rejects emulated architectures.
+ Docker benchmark runs default to Clang 18.1.3; the image also retains GCC for
+ portability and explicit compiler-ablation cohorts. A custom matrix overrides
+ the default with a complete pair such as
+ `"build_environment": {"CC": "gcc", "CXX": "g++"}`. Resolved candidate
+ records retain the actual C/C++ compiler identities and flags.
+3. It requires explicit CPU, memory, and worker budgets. Workers may not exceed the
+ container CPU budget. Candidate builds default to the complete declared CPU
+ capacity (`--cpus 16` selects `make -j16`); fractional budgets round up.
+ `--build-jobs N` provides an explicit positive override for memory-constrained
+ builds, and the resolved value is recorded in the run identity and manifest.
+4. It copies the bundle and optional matrix spec into labeled Docker volumes.
+ The cloned repository retains the experiment runner's normal
+ `/.worktrees/benchmark-candidates` default. Candidate builds, fixture data,
+ caches, daemon state, plans, and reports stay off host bind mounts during
+ measurement.
+5. It invokes the existing experiment runner with `CBM_WORKERS` as an explicit product
+ environment value. The shared `benchmarks/environment-policy-v1.json` registry
+ prevents that value from replacing cache, profiling, auto-index, or run-context
+ isolation.
+6. It exports results through a staging directory. Existing history bytes may be
+ reused, but different bytes at an existing path fail loudly rather than being
+ overwritten.
+7. It stores each container-environment record under the established `manifests/`
+ output directory with a content-derived suffix. Repeating identical bytes is
+ idempotent; changed arguments or timestamps retain a distinct audit record.
+8. On a candidate-build failure, it exports the work volume's build logs to
+ `container-failures//build-logs/`. If Docker cannot export them,
+ the returned error names the retained volume and in-volume path for inspection.
+9. It derives a stable repository snapshot identity from the source revision and
+ sorted Git ref/commit heads, independently of nondeterministic bundle pack bytes.
+ The 24-hexadecimal run key combines that snapshot with the effective matrix, the
+ selected image's runtime configuration and root-filesystem layers, resource budget,
+ and measurement arguments. BuildKit provenance can change the top-level OCI index
+ while those runtime bytes remain identical, so attestation metadata is recorded but
+ does not split a cohort. The exact bundle SHA-256 remains in the environment manifest.
+ Each cohort runs under `runsets//`;
+ `--audit-only` deliberately retains the same key. Valid older cohorts therefore
+ remain reloadable without being confused with genuinely unplanned cell
+ directories in the current cohort.
+10. It removes every transient coordinator and measured container in a `finally`
+ path. Before measurement, it copies the exact verified Git bundle to
+ `EXPERIMENT_ROOT/source-bundles/repository-.bundle`. After a successful result
+ export, the default `--work-volume-retention failed-runs` policy verifies the work
+ volume's ownership labels and removes that multi-gigabyte scratch volume. Failures retain
+ it for inspection and resume. `--work-volume-retention always` preserves the prior
+ successful-run retention behavior. The much smaller results volume remains resumable in
+ both modes.
+11. A deterministic, labeled lock container serializes coordinators using the same experiment
+ root and remains present through successful work-volume cleanup. The coordinator captures its
+ immutable container ID and releases that exact ID, so a later container reusing the lock name
+ cannot be removed by the earlier process. A hard process/host failure may leave that stopped
+ lock as an intentional safety block; the next error names it. Inspect the exact container and
+ confirm that no coordinator is active before removing it.
+
+The experiment root is the human-selected history name; content-addressed source
+specs, resolved specs, plans, cells, reports, environment snapshots, and binary
+hashes remain under `runsets//`; container environment manifests remain
+under the history's `manifests/` directory.
+Rerunning the same source spec and root resumes completed cells. A failed candidate
+still exports partial immutable evidence before the coordinator returns an error.
+
+The audit trail is layered rather than reconstructed from console output:
+
+- the history-level container manifest records invocation surface, exact source and
+ repository snapshot identities, Docker engine/platform metadata, stable runtime
+ image identity plus raw image metadata, resource budget, volume names, and all
+ adapter arguments;
+- the runset archives source and effective matrix bytes with SHA-256, resolved refs,
+ compiler/flags, binary hashes, immutable plan identity, and host/container snapshot;
+- each attempt retains its command, environment overrides, start/end metadata, exit
+ status, stdout, stderr, result bytes, fact tables, artifact hashes, and completion
+ marker; interrupted and failed attempts remain evidence;
+- report and comparison records cite the exact cells and fact occurrences used for
+ every quality result or eligible timing relation;
+- `--audit-only` validates the same run key, plan, cells, hashes, attempts, and report
+ inventory without executing another measured attempt.
+
+This hierarchy makes configuration and results inspectable from retained JSON even
+when terminal logs are unavailable. Console output is operational feedback, not the
+system of record.
+
+The successful default needs no work-volume cleanup. After the host export is audited and no
+volume-backed resume is required, remove only the exact results-volume name printed by the
+coordinator:
+
+```sh
+docker volume rm cbm-benchmark-results-
+```
+
+If a run failed or used `--work-volume-retention always`, its output names the retained work
+volume and its disposition. Remove that exact work volume only after preserving any needed build
+logs and confirming the source bundle exists under `EXPERIMENT_ROOT/source-bundles/`; never use a
+broad volume prune for benchmark cleanup.
+
+Bundle archive and cleanup happen outside the measured container. For bundle size `B`, archive
+copying and SHA-256 verification add `O(B)` setup time, `O(1)` working memory, and `O(B)` durable
+host storage per distinct bundle byte hash. Successful work-volume removal is one Docker metadata
+operation. This trades roughly one repository bundle (about 174 MB in the 2026-07-31 campaigns)
+for avoiding retained work volumes of 3.6–9.4 GB each; exact sizes remain workload-dependent.
+
+The coordinator never stops the Docker backend because that could disrupt unrelated
+containers. After all benchmark work is complete, separately verify that no
+`cbm-benchmark-*` container remains and stop Docker Desktop or the host Docker service
+using the platform's normal administration command.
+
+Interpretation boundary: the container matrix is a controlled same-image,
+same-resource relative comparison. Its Linux kernel, compiler, libc, Docker VM, and
+storage environment differ from native macOS, so do not join absolute container
+latencies or RSS values to native-host series. Use a small scheduled native
+confirmation to establish whether the direction and ranking generalize.
+
+For a Clang-versus-GCC ablation, run two otherwise byte-identical named matrices
+and change only the complete `CC`/`CXX` pair. Keep compiler comparisons in distinct
+histories so they cannot masquerade as product-revision effects. The compiler
+identity, expanded flags, source tree, and binary hash in each resolved candidate
+provide the audit join. Do not add that compiler axis to an unrelated product
+regression experiment.
+
+Set top-level `"accepted_exit_codes": [0, 1]` when the matrix benchmark uses exit
+code 1 for a completed measurement that missed a correctness or quality gate. The
+expanded cells retain that policy in their identities. Result parsing, binary-hash
+validation, and the structured `error` check still prevent crashes or harness
+errors from becoming completed evidence.
+
+Legacy compact specs retain their original grouped cell order and plan hashes. New
+performance experiments should set top-level
+`"execution_order": "paired_interleaved"`. That opt-in order executes every
+candidate/profile cell for repetition 1 before repetition 2, and records the
+repetition block plus absolute execution position in each cell identity. This reduces
+alignment between one configuration and slow host drift while keeping heavy cells
+strictly sequential. It is deterministic rather than randomly shuffled, so the plan
+is exactly reproducible; reports must still retain raw order and variation.
+
+For isolated capability fixtures, set top-level `"capability_quality"` to `"rank"`,
+`"dependencies"`, `"similarity"`, or `"semantic_edges"` and omit `scenarios`.
+The runner expands candidate, profile, transport, and repetition axes without adding
+incremental frontier arguments. Each command records the capability fixture and uses
+`--include-logs`, while named config profiles provide matched enabled/disabled
+ablations. Set top-level `"index_mode": "moderate"` or `"full"` for `similarity`
+and `semantic_edges`; FAST mode intentionally does not generate either relationship.
+
+The semantic pair task set is content-addressed from its version, source hashes,
+relationship, score property, and explicit positive/negative pair judgments.
+`SIMILAR_TO` structural clones and `SEMANTICALLY_RELATED` control-flow variants are
+separate cases because the semantic pass intentionally excludes pairs already above
+the structural MinHash threshold. Pair reports retain TP/FP/FN/TN and witnesses,
+precision, recall, F1, false-positive rate, per-category counts, raw query rows,
+latency, bytes, and estimated tokens. Natural-repository pairs outside the explicit
+judgment set are retained as `unjudged`; incomplete natural ground truth never turns
+an unknown result into a false positive.
+
+For full-index, real-edit incremental, fresh-rebuild, query, response-size, and peak-RSS
+measurements on one pinned repository, use `"workload": "self_dogfood"` with an exact
+repository identity:
+
+```json
+{
+ "workload": "self_dogfood",
+ "repository_background": {
+ "repo": "/absolute/path/to/source-checkout",
+ "revision": "0123456789abcdef0123456789abcdef01234567",
+ "tree": "89abcdef0123456789abcdef0123456789abcdef"
+ },
+ "scenarios": [{"name": "route_handler"}]
+}
+```
+
+Each cell creates a detached worktree from the declared commit rather than mutable
+`HEAD`. The plan identity retains the repository revision and tree, and result
+validation rejects either mismatch. Use a scenario with an actual source edit when
+making incremental-index claims; `noop` measures invocation overhead only.
+
+Older candidates may not expose configuration flags added by a newer branch. A profile
+can therefore declare `"candidate_labels": ["latest"]` to restrict an ablation to
+candidates that accept it. Keep an unrestricted default profile for every candidate,
+and record fixed-default or unsupported capabilities in `capability_support`; do not
+pass an unknown flag to an old binary or pretend that its default is an ablation.
+The harness likewise leaves `rank_refresh` untouched by default, records
+`"rank_refresh": "candidate_default"` and
+`"rank_refresh_override_applied": false`, and therefore measures each candidate's
+real compiled/configured policy. Use `--rank-refresh at_publish`,
+`defer_exact_delta_reindexes`, or `defer_all_incremental_reindexes` only for an
+explicit policy experiment. The harness reads the versioned spelling map and
+translates these values only when running a retained candidate that predates the
+canonical names.
+
+Each semantic pair case also supplies a content-addressed replacement source. A real
+one-file mutation removes one judged positive and adds another, retaining pre/post
+source hashes and changed paths. The harness records initial, incremental, and fresh
+index measurements; pre/post confusion witnesses; freshness warnings; exact publish
+kind; bounded pair equality; and whole canonical-graph equality. This prevents a
+no-op reindex or a stale expected edge from being reported as successful changed-file
+quality.
+
+For a realistic background, add this top-level compact-spec object:
+
+```json
+{
+ "quality_background": {
+ "repo": "/absolute/path/to/source-checkout",
+ "revision": "0123456789abcdef0123456789abcdef01234567",
+ "tree": "89abcdef0123456789abcdef0123456789abcdef"
+ }
+}
+```
+
+This is supported by `similarity` and `semantic_edges` quality cases. The harness
+streams tracked files from that exact commit through `git archive`, excluding the
+source checkout's dirty and untracked state, then overlays the versioned canaries in
+the isolated per-cell repository. It removes its transient tar archive after safe
+extraction. The cell identity binds the resolved source path, commit, and tree;
+result acceptance rejects a missing or mismatched retained commit/tree identity.
+Neither the source checkout nor its worktree registry is modified.
+
+Capability ablations should use the named `--config-profile` values so an important
+cost center cannot be silently omitted. Repeated `--config KEY=VALUE` arguments
+remain available and take priority over the selected profile. The benchmark default,
+`automatic_dependency_source_indexing_disabled`, explicitly pins the current product
+capability values and sets `auto_index_deps=false`. Use
+`automatic_dependency_source_indexing_enabled` for the same capability set with
+`auto_index_deps=true`. `candidate_native_configuration` applies no overrides and is
+reserved for older candidates that do not implement the current configuration keys;
+its unspecified effective values cannot participate in capability-parity joins. The
+PageRank/LinkRank ablation is:
+
+```text
+--config-profile rank_disabled
+```
+
+`benchmarks/autotune.py` is the compatibility frontend for the corresponding fixed
+PageRank profile sweep. It requires exact build metadata, generates a content-addressed
+rank-quality experiment, interleaves candidate-default and ablation repetitions, and
+stores the plan, results, logs, and report under a durable ignored result root. It does
+not choose a winning configuration, tune against real multilingual corpora, or publish
+defaults. New native and container campaigns generate the matrix with
+`benchmarks/campaign_specs.py --quick-hypotheses` and execute it through the canonical
+`benchmarks/run_experiments.py` interface. Use `autotune.py --plan-only` only for retained
+compatibility workflows that need its binary-path plan.
+
+The independent `--mcp-surface-parity` mode records classic, streamlined before
+reveal, and the same streamlined process after reveal. It compares names plus the
+full `tools/list` client contract (description, input/output schemas, and MCP
+annotations), reports user outcomes before tool counts, checks bounded pre-reveal
+handler recognition, and requires server processes and reader threads to be reaped.
+These probes establish discovery and dispatch parity; functional quality claims
+must still come from the capability fixtures and repository workloads below.
+
+The minimal-indexing ablation disables every optional graph cost center and retains
+`auto_index_deps=false`:
+
+```text
+--config-profile minimal_indexing
+```
+
+`optional_graph_disabled` is accepted only when loading retained plans and resolves
+to this same manifest. Do not use the retired spelling in new plans.
+
+The immediate semantic/similarity freshness profile is:
+
+```text
+--config-profile incremental_derived_results_refresh_at_publish
+```
+
+It changes only `incremental_derived_results_refresh=at_publish`. The default
+`defer_all_incremental_reindexes` policy may publish an exact or containment delta
+after marking global `SIMILAR_TO`/`SEMANTICALLY_RELATED` views stale; graph queries
+must then retain an explicit freshness warning until an at-publish or full rebuild.
+Reports score this warning as policy conformance, not an unexplained execution
+failure, but they keep immediate semantic task quality false. The at-publish profile
+must produce the post-mutation judged pair set and edge scores identically to a fresh
+rebuild without a stale warning. Compare both profiles when selecting a
+latency/freshness Pareto point.
+
+Cross-version candidate-default cells do not assume that older binaries share the
+latest binary's derived-refresh default. With no explicit
+`incremental_derived_results_refresh` override, the retained policy is
+`candidate_default` and the harness classifies observed behavior as immediate pair
+freshness, deferred with a structured warning, or unreported stale output. Explicit
+at-publish/deferred profiles continue to validate against the requested policy. This
+keeps an older immediate-refresh default from being judged against a newer deferred
+default.
+
+Large mutation reports keep Core graph and Full graph freshness separate. A
+`PASS: DECLARED STALE VIEWS` decision requires structured `stale_with_warning`
+metadata and a second canonical comparison that excludes only the declared
+`SEMANTICALLY_RELATED` rows. Every remaining node, edge, property, and file hash
+must still equal the matching fresh rebuild. An undeclared difference—or any
+non-semantic difference—remains a core correctness failure. Full graph freshness
+stays zero until the unfiltered graphs match, so the latency/freshness tradeoff is
+visible rather than relabeled as full equality.
+
+The lowest-cost indexing baseline also disables installed-package indexing and is:
+
+```text
+--config-profile minimal_indexing
+```
+
+`minimal_indexing` expands to `auto_index_deps=false`, `rank_enabled=false`,
+`similarity_enabled=false`, `semantic_edges_enabled=false`,
+`githistory_enabled=false`, and `httplinks_enabled=false`. Reports retain both the
+profile name and the fully expanded requested/effective override maps for
+auditability. Each benchmark case removes inherited `CBM_*` product variables,
+uses an isolated cache, and records that worker selection follows the candidate's
+native default with `CBM_WORKERS` unset unless the matrix explicitly declares
+`product_environment`. Explicit values are recorded in the cell identity and report
+environment policy before being applied to the candidate process. Candidate-native
+profiles record effective configuration as unknown instead of inferring defaults
+that an older binary did not report.
+
+Only apply gates a candidate revision actually supports. Record unsupported
+combinations as compatibility findings rather than silently treating them as the
+same configuration.
+
+## Run and resume
+
+```sh
+uv run python benchmarks/run_experiments.py \
+ --plan .worktrees/benchmark-campaign/plan.json \
+ --experiment-root .worktrees/benchmark-campaign/results
+```
+
+The retained `--campaign-root` spelling remains accepted. Archived plans that name
+the former single-run script path resolve it to `benchmarks/run_benchmark.py` at
+execution time without rewriting the archived plan or changing its cell identity.
+
+Rerunning the same command resumes validated cells. The runner executes cells
+sequentially by default so concurrent indexing does not distort latency or peak RSS.
+Each cell retains immutable timestamped attempts with `command.json`, `stdout.log`,
+`stderr.log`, `result.json`, and `attempt.json`. `complete.json` is written with an
+atomic replace only after validation. Per-cell exclusive locks reject a live or
+recent competing run; stale lock recovery is recorded instead of hidden.
+Each benchmark command runs in an isolated process group. Timeout or user interrupt
+signals the whole group, waits up to 30 seconds for the harness to remove its cache
+and detached worktrees, then force-stops any remaining descendants. The immutable
+attempt record is written before an interrupt is re-raised.
+
+`command.json` records a pre-run resource snapshot and `attempt.json` records a
+post-run snapshot: UTC time, hostname, CPU count, physical memory when the platform
+exposes it, 1/5/15-minute load average when available, and experiment-root
+filesystem total, used, and free bytes. The experiment-level environment snapshot
+retains the same host data. These observations diagnose load or disk drift; they
+are not substitutes for per-process peak RSS recorded by the benchmark itself.
+
+Every invocation also writes:
+
+- an immutable copy of the plan keyed by its SHA-256;
+- a timestamped environment snapshot and manifest;
+- counts for planned, complete, missing, corrupt, duplicate-attempt, and unplanned
+ run directories;
+- `reports/summary.md`, regenerated from validated completion records only.
+
+The report lists exact bytes from each tool's default response encoding and a clearly
+labeled deterministic `ceil(UTF-8 bytes / 4)` token estimate. Each quality oracle makes
+a second request with `format=json`; its latency and canonical JSON size are recorded
+separately as `quality_probe_elapsed_ms` and `quality_response_bytes`, so parsing the
+oracle cannot silently replace or inflate the default user-facing measurement. Pareto
+membership is restricted to candidates that pass every applicable quality/correctness
+gate and have query latency, response tokens, incremental latency, and peak RSS
+measurements. It maximizes quality while minimizing those cost axes. Exact bytes remain
+visible so the token estimate is never presented as tokenizer ground truth.
+Peak RSS and internal indexing time are extracted in one streaming pass from the
+worker logfile named by the index response. The harness sets `CBM_PROFILE=1` for
+every candidate because successful supervisors otherwise delete that logfile; this
+also makes the profiling configuration consistent and visible across revisions.
+Only the exact `mem.phase`,
+`pipeline.done`, and `incremental.done` marker lines (at most 512) are retained in
+the result, keeping memory bounded while preserving the evidence after transient
+worker logs are cleaned.
+
+Use `--audit-only` to scan and regenerate the report without running missing cells.
+The audit re-inventories every completed attempt's artifact directory and rejects
+changed, missing, or unlisted worker logs rather than trusting `attempt.json` alone.
+Use `--minimum-free-gb` and `--stale-lock-hours` only when the recorded defaults are
+inappropriate for the host.
+
+`--quick` and `--full` build their candidate set from `DEFAULT_CANDIDATE_REFS`,
+which pins one baseline (`upstream/main`) and two dated tags. The baseline falls
+back from `upstream/main` to `origin/main` to `main` automatically if the pinned
+ref does not resolve (for example, after the `upstream` remote is removed
+post-merge). Use repeatable `--candidate-ref LABEL=REF` (for example
+`--candidate-ref upstream-main=origin/main`) to override any default candidate's
+ref explicitly; an explicit override is fail-closed like the rest of the runner —
+an unresolvable override ref raises rather than silently substituting a different
+comparison point.
+
+Automatic presets use MCP transport by default. That is appropriate when the
+benchmark owns an isolated account/runtime or all candidates are compatible with
+the active account-wide CBM daemon. Neither MCP nor CLI is a valid cross-build setup
+when another CBM build is serving that account: current one-shot `config`, index,
+and query CLI commands enforce the same exact-build cohort and correctly reject a
+different candidate before the benchmark can use its isolated cache.
+
+Select CLI transport explicitly in that situation:
+
+```sh
+uv run python benchmarks/run_experiments.py --full --transport cli \
+ --candidate-ref upstream-main=main \
+ --experiment-root /durable/path/full-head-vs-main
+```
+
+CLI transport runs the same candidate binaries, profiles, scenarios, repetitions,
+quality gates, and isolated caches without MCP framing, but it still participates in
+account-wide exact-build coordination. Run a cross-build CLI matrix in a dedicated
+OS account/runtime or after quiescing that account's daemon, and restore normal
+dogfooding afterward. Changing `CBM_CACHE_DIR`, the Git worktree, or the experiment
+root is not daemon isolation. The runner never silently falls back between CLI and
+MCP. Use MCP to measure protocol/daemon overhead and CLI to isolate framing cost.
+The benchmark runs directly on the host and does not require Docker.
+
+Candidate labels are stable comparison roles. In the example,
+`upstream-main` still appears as the role label even though it resolves the local
+`main` ref. Reports and claims must therefore cite the resolved ref and exact commit
+recorded in the expanded plan, not infer the source ref from the role label.
+
+## Cross-experiment composition
+
+Use `benchmarks/summarize_results.py --composition-spec SPEC --out REPORT`
+to combine incremental correctness and capability-quality evidence into one
+configuration row. A composition input may name an exact matrix spec or the immutable
+expanded plan already archived in its durable experiment root. The generator validates
+the selected plan, requires every selected cell to have a hash-validated completion,
+and consumes the derived report inputs without altering immutable raw results. Using
+an archived plan permits historical report regeneration without requiring the old
+candidate executable path to still exist.
+
+The generated Markdown records the composition-spec SHA-256. A sibling
+`REPORT.manifest.json` records every materialized input path and SHA-256, making the
+uncommitted report reproducible and auditable without committing experiment logs or
+results.
+
+Reports show observation counts, medians, and min–max ranges for incremental, query,
+and full-index latency. The ranges are descriptive, not confidence intervals: the
+default sequential grouped order avoids concurrent contention but is not a paired or
+randomized design suitable for an effect-size interval.
diff --git a/docs/BENCHMARK_TERMINOLOGY.md b/docs/BENCHMARK_TERMINOLOGY.md
new file mode 100644
index 000000000..0266cb0f7
--- /dev/null
+++ b/docs/BENCHMARK_TERMINOLOGY.md
@@ -0,0 +1,161 @@
+# Benchmark terminology
+
+
+
+- Terminology version: `1.2.0`
+- Canonical registry: `benchmarks/terminology.json`
+- Canonical-content SHA-256: `e54dedbcddcf531bf3bb691003d64759816a39c9e41e4cbef2baf1fd65e9f4d7`
+
+Every definition below is normative. Parent relations describe containment, not execution order; overlapping elapsed spans are work-time evidence and must not be summed into lifecycle wall time.
+
+## Algorithm Concept
+
+| ID | Normative definition | Status; type; unit | Boundaries; aggregation; concurrency | Missing/configuration/effect | Sources |
+|---|---|---|---|---|---|
+| `dependency_artifact_reuse` Dependency Artifact Reuse | Dependency artifact reuse loads a previously computed dependency graph only when package identity, source hash, parser version, config and schema version, and capability set all match. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `graph_publication` Graph Publication | Graph publication is the transaction that makes computed node, edge, property, index, and generation changes visible in the persistent store. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `lsh_index` LSH index | A locality-sensitive-hashing index groups semantic vectors into candidate buckets so the semantic pass need not compare every pair. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `node_degree` Node Degree | Node degree is the configured weighted, unweighted, or calls-only connection count for one graph node. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `semantic_vector` Semantic Vector | A semantic vector is the recorded numeric representation of one code entity used by the semantic-similarity algorithm. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+
+## Benchmark Concept
+
+| ID | Normative definition | Status; type; unit | Boundaries; aggregation; concurrency | Missing/configuration/effect | Sources |
+|---|---|---|---|---|---|
+| `behavioral_only_probe` behavioral-only probe | A behavioral-only probe is a battery query carrying no relevance judgments. It is excluded from rank-quality aggregates because no ground truth defines a correct answer, while still recording result count, latency and payload size. | existing; object or categorical record; values defined by the referenced benchmark schema; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/run_benchmark.py` |
+| `benchmark_cell` Benchmark Cell | A benchmark cell is the set of repetitions that share one declared implementation, workload, effective capability manifest, scope manifest, cache manifest, and correctness contract. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `benchmark_result` Benchmark Result | A benchmark result is one recorded correctness, freshness, retrieval, ranking, semantic-quality, skip, error, or product-failure outcome for a benchmark run. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `benchmark_run` Benchmark Run | A benchmark run is one execution of the measured product operation with one resolved implementation, capability, scope, and cache manifest. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `cache_manifest` Cache Manifest | A cache manifest records the state and reset procedure for every named cache layer; the report does not use an unqualified cold or warm label. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `critical_path` Critical Path | A user lifecycle's critical path is the longest-duration path through its explicit dependency relations. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `dependency_relation` Dependency Relation | A dependency relation records that one step occurrence must reach a named event before another occurrence can proceed. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `generated_source` Generated Source | Generated source is machine-produced or vendored source selected by an explicit recorded policy. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `implementation_identity` Implementation Identity | An implementation identity is the source revision, binary hash, and build manifest of the compared executable. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `invalid_benchmark_record` Invalid Benchmark Record | An invalid benchmark record is measurement evidence rejected because its instrumentation, schema, terminology, or oracle requirements failed. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `observer_effect` Observer Effect | Observer effect is the latency, CPU, or memory difference caused by instrumentation, measured against profiler-off cells using the same executable and workload. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `overlap` Overlap | Two step occurrences overlap when their monotonic execution intervals intersect. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `parent_relation` Parent Relation | A parent relation records structural nesting between two step occurrences and does not by itself impose execution order. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `product_failure` Product Failure | A product failure occurs when the indexed or query operation violates its recorded product contract or returns a failing product status. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `production_build` Production Build | A production build is an executable built with the shipped optimization, sanitizer, and feature flags recorded in its build manifest. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `repetition` Repetition | A repetition is one independently started benchmark run in a cell; repetitions share the cell configuration but not mutable process state unless the cache manifest says otherwise. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `reply_detail_profile` reply detail profile | A reply detail profile is a named set of response-size configuration values such as search_limit and snippet_max_lines, applied so retrieval quality can be reported per response token rather than per query alone. | existing; object or categorical record; values defined by the referenced benchmark schema; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/run_benchmark.py` |
+| `retained_artifact` Retained Artifact | A retained artifact is one benchmark input or output identified by path, content hash, schema version, terminology version, and cleanup state. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `scope_manifest` Scope Manifest | A scope manifest identifies every included repository, dependency package, file and byte count, language, generated-source policy, and exclusion. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `step` Step | A step is a registry-defined kind of work performed during a benchmark run. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `step_occurrence` Step Occurrence | A step occurrence is one execution of a step; every repeated or concurrent occurrence has its own occurrence ID. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `timer_boundary` Timer Boundary | A timer boundary is a registry-defined event, owned by the harness or a named process, that starts or ends a duration. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `user_lifecycle` User Lifecycle | A user lifecycle is one user-visible operation measured between two harness-owned monotonic boundary events. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+
+## Capability State
+
+| ID | Normative definition | Status; type; unit | Boundaries; aggregation; concurrency | Missing/configuration/effect | Sources |
+|---|---|---|---|---|---|
+| `capability` Capability | A capability is one separately observable product behavior. | existing; capability record or categorical state; enabled, disabled, unsupported, or an exact enumerated/numeric value; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: per-call override > environment > persistent config > preset > compiled default; effect: determines parity eligibility and the work/correctness contract | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `disabled_capability` Disabled Capability | A disabled capability is implemented by the measured executable but inactive for the benchmark run. | existing; capability record or categorical state; enabled, disabled, unsupported, or an exact enumerated/numeric value; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: per-call override > environment > persistent config > preset > compiled default; effect: determines parity eligibility and the work/correctness contract | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `effective_capability_value` Effective Capability Value | An effective capability value is selected after applying default, preset, persistent-config, environment, and per-call precedence; its winning source is recorded. | existing; capability record or categorical state; enabled, disabled, unsupported, or an exact enumerated/numeric value; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: per-call override > environment > persistent config > preset > compiled default; effect: determines parity eligibility and the work/correctness contract | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `enabled_capability` Enabled Capability | An enabled capability is implemented by the measured executable and active for the benchmark run. | existing; capability record or categorical state; enabled, disabled, unsupported, or an exact enumerated/numeric value; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: per-call override > environment > persistent config > preset > compiled default; effect: determines parity eligibility and the work/correctness contract | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `unsupported_capability` Unsupported Capability | An unsupported capability is unavailable in the measured executable; missing capability metadata instead makes the benchmark record invalid. | existing; capability record or categorical state; enabled, disabled, unsupported, or an exact enumerated/numeric value; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: per-call override > environment > persistent config > preset > compiled default; effect: determines parity eligibility and the work/correctness contract | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+
+## Comparison Kind
+
+| ID | Normative definition | Status; type; unit | Boundaries; aggregation; concurrency | Missing/configuration/effect | Sources |
+|---|---|---|---|---|---|
+| `capability_delta_comparison` Capability Delta Comparison | A capability-delta comparison compares cells with an explicitly named capability difference and reports the added or removed work, quality, coverage, and resource cost without a cross-implementation speed ratio. | existing; comparison record; one comparison whose join and formula identifiers are recorded; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: derive only from source run, result, and step IDs retained in the record; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: reject the comparison when a required join field is unknown; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `parity_comparison` Parity Comparison | A parity comparison compares two benchmark cells whose effective capabilities, input and scope policies, per-layer cache states, timer boundaries, freshness endpoints, and correctness contracts are identical. | existing; comparison record; one comparison whose join and formula identifiers are recorded; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: derive only from source run, result, and step IDs retained in the record; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: reject the comparison when a required join field is unknown; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `shared_work_projection` Shared Work Projection | A shared-work projection compares the explicitly named intersection of work supported by two implementations and is not whole-product parity. | existing; comparison record; one comparison whose join and formula identifiers are recorded; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: derive only from source run, result, and step IDs retained in the record; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: reject the comparison when a required join field is unknown; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+
+## Evidence Status
+
+| ID | Normative definition | Status; type; unit | Boundaries; aggregation; concurrency | Missing/configuration/effect | Sources |
+|---|---|---|---|---|---|
+| `existing_behavior` Existing Behavior | Existing behavior is behavior present at the cited source revision and verified at the cited code or experiment anchor. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `proposed_behavior` Proposed Behavior | Proposed behavior is design work described by this plan but not implemented at the cited source revision. | existing; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+
+## Formula Id
+
+| ID | Normative definition | Status; type; unit | Boundaries; aggregation; concurrency | Missing/configuration/effect | Sources |
+|---|---|---|---|---|---|
+| `left_elapsed_divided_by_right_elapsed_v1` Left/Right Elapsed Ratio Formula v1 | The `left_elapsed_divided_by_right_elapsed_v1` formula ID divides the left cell's median elapsed milliseconds by the right cell's median elapsed milliseconds for the same step ID; values above 1 mean the left cell took longer. | existing; stable string identifier; exactly `left_elapsed_divided_by_right_elapsed_v1`; dimensionless; scope: ratio of wall-time medians | boundaries: inherits the source occurrences used by both median operands; aggregation: divide the left cell's median_elapsed_ms_v1 result by the right cell's median_elapsed_ms_v1 result for the same step ID; concurrency: does not sum component durations; both operands preserve their recorded occurrence boundaries | missing/unsupported: emit null when the right median is zero and emit no ratio unless the pair passed the parity join; configuration: not_applicable; effect: valid only for a parity_manifest_and_contract_v1 join | `benchmarks/schema/comparisons-v1.schema.json`, `benchmarks/fact_comparisons.py` |
+| `median_elapsed_ms_v1` Median Elapsed Milliseconds Formula v1 | The `median_elapsed_ms_v1` formula ID sorts the selected elapsed_ms values and returns the middle value for an odd count or the arithmetic mean of the two middle values for an even count. | existing; stable string identifier; exactly `median_elapsed_ms_v1`; milliseconds; scope: wall time for each named occurrence | boundaries: uses each source occurrence's registered monotonic start and end boundaries; aggregation: apply to all recorded elapsed_ms values for one step ID in one exact cell group; concurrency: does not sum overlapping occurrences; it takes the median of the selected occurrence durations | missing/unsupported: omit the aggregate when no numeric elapsed_ms occurrence is recorded; configuration: not_applicable; effect: none beyond the enclosing cell manifest | `benchmarks/schema/comparisons-v1.schema.json`, `benchmarks/fact_comparisons.py` |
+
+## Freshness And Correctness
+
+| ID | Normative definition | Status; type; unit | Boundaries; aggregation; concurrency | Missing/configuration/effect | Sources |
+|---|---|---|---|---|---|
+| `all_fresh_endpoint` All Fresh Endpoint | An all-fresh endpoint occurs when the core graph and every enabled derived view in the effective capability manifest are fresh. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `clean_rebuild_graph_oracle` Clean Rebuild Graph Oracle | A clean-rebuild graph oracle is the canonically normalized graph produced from an empty store using the same source snapshot, effective capability manifest, and scope manifest as the compared run. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `core_answer` Core Answer | A core answer is a task answer computed from a core graph whose source generation matches the latest successful source publication. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `core_graph` Core Graph | A core graph contains the source-derived nodes, edges, properties, and file hashes that remain after removing only the optional derived views explicitly listed in the benchmark result. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `correctness_contract` Correctness Contract | A correctness contract specifies the graph rows, properties, hashes, freshness states, task outcomes, and allowed exclusions that a benchmark result must satisfy. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `deferred_refresh` Deferred Refresh | A deferred refresh leaves the named derived view stale at the measured endpoint and reports its stale state and generation. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `derived_view` Derived View | A derived view is named data recomputed from the source graph. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `eager_refresh` Eager Refresh | An eager refresh computes and publishes the named derived view before the measured endpoint returns. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `fresh_view` Fresh View | A fresh view is a derived view whose view generation equals the latest successfully published source generation at the measured endpoint. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `graph_equality` Graph Equality | Graph equality means equality under the recorded canonicalization version and does not require byte-identical SQLite files. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `rank_score_staleness` rank score staleness | Rank score staleness records whether the pagerank, linkrank and node_degree derived views were current when a ranking measurement ran, taking the union of views the tool responses declared stale and views the freshness ledger persisted as stale. A ranking number measured while these are stale describes the degree fallback rather than the requested score. | existing; object or categorical record; values defined by the referenced benchmark schema; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/run_benchmark.py`, `src/store/store.c` |
+| `requested_fresh_endpoint` Requested Fresh Endpoint | A requested-fresh endpoint occurs when the core graph and every enabled derived view required by the named task are fresh. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `source_generation` Source Generation | A source generation is the monotonic identifier assigned to one successful publication of source-derived graph data. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `stale_view` Stale View | A stale view is a derived view whose view generation precedes the latest successfully published source generation. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `view_generation` View Generation | A view generation is the source generation used to compute one named derived view. | existing; freshness, generation, oracle, or endpoint record; values defined by the recorded correctness contract; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: determines whether a lifecycle reached core, requested-fresh, or all-fresh completion | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+
+## Join Id
+
+| ID | Normative definition | Status; type; unit | Boundaries; aggregation; concurrency | Missing/configuration/effect | Sources |
+|---|---|---|---|---|---|
+| `capability_delta_manifest_v1` Capability Delta Manifest Join v1 | The `capability_delta_manifest_v1` join ID selects two cells only when mode, scope, cache state, host, benchmark contract, and correctness contract are canonically equal, both capability manifests are complete, and at least one effective capability differs; it never authorizes a cross-implementation speed ratio. | existing; stable string identifier; exactly `capability_delta_manifest_v1`; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: not_applicable; concurrency: does not imply serial execution; compared durations retain their recorded occurrence structure | missing/unsupported: classify the pair as not eligible when required equal fields differ or either capability manifest is incomplete; configuration: not_applicable; effect: requires one or more explicitly recorded capability differences | `benchmarks/schema/comparisons-v1.schema.json`, `benchmarks/fact_comparisons.py` |
+| `parity_manifest_and_contract_v1` Parity Manifest and Contract Join v1 | The `parity_manifest_and_contract_v1` join ID selects two cells only when mode, effective capabilities, scope, cache state, host, benchmark contract, and correctness contract are canonically equal, both capability manifests are complete, and no required manifest value is unknown. | existing; stable string identifier; exactly `parity_manifest_and_contract_v1`; not_applicable; scope: not_applicable | boundaries: not_applicable; aggregation: not_applicable; concurrency: does not imply serial execution; compared durations retain their recorded occurrence structure | missing/unsupported: classify the pair as not eligible and emit no ratio; configuration: not_applicable; effect: requires identical effective capability, scope, cache, host, benchmark-contract, and correctness-contract records | `benchmarks/schema/comparisons-v1.schema.json`, `benchmarks/fact_comparisons.py` |
+
+## Measurement
+
+| ID | Normative definition | Status; type; unit | Boundaries; aggregation; concurrency | Missing/configuration/effect | Sources |
+|---|---|---|---|---|---|
+| `confidence_interval` Confidence Interval | A confidence interval is the interval produced by the recorded statistical method, confidence level, and repetition set for one estimator. | existing; number or bounded interval; values permitted by the measured quantity; the unit of the measured quantity; scope: not_applicable | boundaries: not_applicable; aggregation: apply only the versioned estimator to one declared repetition set; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `cpu_time` Cpu Time | CPU time is processor execution time measured for a named thread, process, or child-process set. | existing; nonnegative number; 0 or greater; milliseconds in fact tables; source clocks use nanoseconds; scope: the named monotonic clock and thread, process, process-tree, or harness scope | boundaries: the registered start event through the registered end event; aggregation: aggregate only occurrence sets selected by an emitted formula; lifecycle wall time is always outer end minus outer start; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `elapsed_time` Elapsed Time | A step occurrence's elapsed time is its monotonic end timestamp minus its monotonic start timestamp. | existing; nonnegative number; 0 or greater; milliseconds in fact tables; source clocks use nanoseconds; scope: the named monotonic clock and thread, process, process-tree, or harness scope | boundaries: the registered start event through the registered end event; aggregation: aggregate only occurrence sets selected by an emitted formula; lifecycle wall time is always outer end minus outer start; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `lifecycle_wall_time` Lifecycle Wall Time | A user lifecycle's wall time is its harness-owned end boundary minus its harness-owned start boundary. | existing; nonnegative number; 0 or greater; milliseconds in fact tables; source clocks use nanoseconds; scope: the named monotonic clock and thread, process, process-tree, or harness scope | boundaries: the registered start event through the registered end event; aggregation: aggregate only occurrence sets selected by an emitted formula; lifecycle wall time is always outer end minus outer start; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `median` Median | A median is the versioned 50th-percentile estimator over the recorded repetitions in one benchmark cell. | existing; number or bounded interval; values permitted by the measured quantity; the unit of the measured quantity; scope: not_applicable | boundaries: not_applicable; aggregation: apply only the versioned estimator to one declared repetition set; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `p95` p95 | A p95 value is the versioned 95th-percentile estimator over the recorded repetitions in one benchmark cell. | existing; number or bounded interval; values permitted by the measured quantity; the unit of the measured quantity; scope: not_applicable | boundaries: not_applicable; aggregation: apply only the versioned estimator to one declared repetition set; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `parallelism` Parallelism | Parallelism is the number of step occurrences actively executing during a declared monotonic interval. | existing; nonnegative number; 0 or greater; ratio denominators must be nonzero; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `peak_rss` Peak RSS | Peak resident set size is the largest resident-memory sample observed for the named process set within declared boundaries. | existing; number; peak_rss is nonnegative; rss_delta may be negative; MiB; scope: the named process or process-tree sampling interval | boundaries: the registered lifecycle or step sampling boundaries; aggregation: peak uses max; delta uses end minus start; never add peaks; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `queue_wait` Queue Wait | A step occurrence's queue wait is its worker-start timestamp minus its enqueue timestamp. | existing; nonnegative number; 0 or greater; milliseconds in fact tables; source clocks use nanoseconds; scope: the named monotonic clock and thread, process, process-tree, or harness scope | boundaries: the registered start event through the registered end event; aggregation: aggregate only occurrence sets selected by an emitted formula; lifecycle wall time is always outer end minus outer start; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `ratio` Ratio | A ratio is a named numerator divided by a named nonzero denominator under one declared comparison contract. | existing; nonnegative number; 0 or greater; ratio denominators must be nonzero; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `repetition_stability` repetition stability | Repetition stability is the set of result counts observed when one query is repeated against a fixed index, and whether they all agree. It detects calls that non-deterministically return results and zero results without any change to the index. | existing; object or categorical record; values defined by the referenced benchmark schema; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/run_benchmark.py` |
+| `rss_delta` RSS delta | Resident-set delta is end-boundary RSS minus start-boundary RSS for the named process set. | existing; number; peak_rss is nonnegative; rss_delta may be negative; MiB; scope: the named process or process-tree sampling interval | boundaries: the registered lifecycle or step sampling boundaries; aggregation: peak uses max; delta uses end minus start; never add peaks; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `speedup` Speedup | A speedup is baseline duration divided by candidate duration under one declared parity or shared-work-projection contract; values above 1 mean the candidate completed faster. | existing; nonnegative number; 0 or greater; ratio denominators must be nonzero; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `work_time` Work Time | Work time is the sum of selected step-occurrence elapsed times and may exceed lifecycle wall time when occurrences overlap. | existing; nonnegative number; 0 or greater; milliseconds in fact tables; source clocks use nanoseconds; scope: the named monotonic clock and thread, process, process-tree, or harness scope | boundaries: the registered start event through the registered end event; aggregation: aggregate only occurrence sets selected by an emitted formula; lifecycle wall time is always outer end minus outer start; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `worker_utilization` Worker Utilization | Worker utilization is active worker time divided by available worker time for a named worker pool and interval. | existing; nonnegative number; 0 or greater; ratio denominators must be nonzero; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+
+## Quality Metric
+
+| ID | Normative definition | Status; type; unit | Boundaries; aggregation; concurrency | Missing/configuration/effect | Sources |
+|---|---|---|---|---|---|
+| `hit_at_k` Hit@k | Hit@k is the fraction of applicable retrieval tasks whose named correct entity appears within the first k returned entities; higher is better. | existing; nonnegative number; 0 or greater; ratio denominators must be nonzero; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `mrr` MRR | Mean reciprocal rank is the mean of 1/rank for the first correct returned entity in each applicable retrieval task; higher is better and 1 means every correct entity ranked first. | existing; nonnegative number; 0 or greater; ratio denominators must be nonzero; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `ndcg_at_k` nDCG@k | Normalized discounted cumulative gain at k scores the order of judged returned entities within the first k positions against the ideal order; higher is better and 1 is ideal. | existing; nonnegative number; 0 or greater; ratio denominators must be nonzero; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `scaffolding_at_k` scaffolding@K | Scaffolding@K is the fraction of a score's top K ranked symbols whose file is labeled a test by a source independent of this server: the project's own declared test configuration or the language toolchain's rule. It is null when no independent labels were supplied, and is never inferred from this server's own test predicates, because those predicates are the thing under measurement. | existing; nonnegative number; 0 to 1 inclusive; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/run_benchmark.py`, `benchmarks/generate_test_labels.py` |
+| `semantic_pair_f1` Semantic Pair F1 | Semantic Pair F1 is the harmonic mean of precision and recall over the explicitly judged SEMANTICALLY_RELATED code-entity pairs; higher is better and 1 means none are missing or spurious. | existing; nonnegative number; 0 or greater; ratio denominators must be nonzero; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `silent_drop_rate` silent drop rate | Silent drop rate is the fraction of a corpus's source files present under one index mode and absent under another, attributed to the directory name that excluded them. It quantifies coverage lost to built-in skip lists without any diagnostic in the response. | existing; nonnegative number; 0 to 1 inclusive; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/run_benchmark.py`, `src/discover/discover.c` |
+| `task_success` Task Success | Task success is the fraction of applicable named tasks that return their required entity or evidence under the task's recorded acceptance rule. | existing; nonnegative number; 0 or greater; ratio denominators must be nonzero; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `utility_contamination_at_k` utility contamination@K | Utility contamination@K is the fraction of a score's top K ranked symbols that are logging, formatting or allocation utilities, matched on whole identifier tokens rather than substrings. It tests the objection that a graph score surfaces utility popularity rather than architectural importance. | existing; nonnegative number; 0 to 1 inclusive; dimensionless; scope: not_applicable | boundaries: not_applicable; aggregation: use the formula and repetition estimator recorded with the result; concurrency: does not imply serial execution; use recorded occurrence intervals and dependency relations | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/run_benchmark.py` |
+
+## Step Id
+
+| ID | Normative definition | Status; type; unit | Boundaries; aggregation; concurrency | Missing/configuration/effect | Sources |
+|---|---|---|---|---|---|
+| `change_classification` Change Classification | The `change_classification` step ID identifies one occurrence of change classification work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `change_classification`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `dependency_discovery` Dependency Discovery | The `dependency_discovery` step ID identifies one occurrence of dependency discovery work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `dependency_discovery`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `dependency_package_index` Dependency Package Index | The `dependency_package_index` step ID identifies one occurrence of dependency package index work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `dependency_package_index`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `exact_delta` Exact Delta | The `exact_delta` step ID identifies one occurrence of exact delta work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `exact_delta`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `first_all_fresh_query` First All Fresh Query | The `first_all_fresh_query` step ID identifies one occurrence of first all fresh query work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `first_all_fresh_query`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `first_core_query` First Core Query | The `first_core_query` step ID identifies one occurrence of first core query work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `first_core_query`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `graph_publish_delete` Graph Publish Delete | The `graph_publish_delete` step ID identifies one occurrence of graph publish delete work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `graph_publish_delete`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `graph_publish_indexes` Graph Publish Indexes | The `graph_publish_indexes` step ID identifies one occurrence of graph publish indexes work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `graph_publish_indexes`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `graph_publish_upsert` Graph Publish Upsert | The `graph_publish_upsert` step ID identifies one occurrence of graph publish upsert work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `graph_publish_upsert`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `linkrank` LinkRank | LinkRank is the configured edge score derived from stationary flow between graph nodes. The same `linkrank` registry ID identifies each measured occurrence of that work; repeated or concurrent occurrences have distinct occurrence IDs. | proposed; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `pagerank` PageRank | PageRank is the configured graph-centrality score computed from incoming weighted graph links. The same `pagerank` registry ID identifies each measured occurrence of that work; repeated or concurrent occurrences have distinct occurrence IDs. | proposed; object or categorical record; values defined by the referenced benchmark schema; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: must not be aggregated unless a referenced formula defines the operation; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: record an explicit unknown fact; do not infer the value from a label or preset; configuration: not_applicable; effect: none beyond the term's normative definition | `benchmarks/schema/facts-v2.schema.json`, `benchmarks/run_benchmark.py` |
+| `parse_extract` Parse Extract | The `parse_extract` step ID identifies one occurrence of parse extract work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `parse_extract`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `project_discovery` Project Discovery | The `project_discovery` step ID identifies one occurrence of project discovery work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `project_discovery`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `semantic_lsh` Semantic Lsh | The `semantic_lsh` step ID identifies one occurrence of semantic lsh work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `semantic_lsh`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `semantic_pairs` Semantic Pairs | The `semantic_pairs` step ID identifies one occurrence of semantic pairs work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `semantic_pairs`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `semantic_vectors` Semantic Vectors | The `semantic_vectors` step ID identifies one occurrence of semantic vectors work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `semantic_vectors`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
+| `startup` Startup | The `startup` step ID identifies one occurrence of startup work; each repeated or concurrent occurrence has a distinct occurrence ID. | proposed; stable string identifier; exactly `startup`; not_applicable; scope: the thread, worker, process, or harness recorded on each occurrence | boundaries: the occurrence's registered start and end events; aggregation: aggregate only distinct occurrence IDs selected by an emitted formula; concurrency: overlapping occurrences remain separate and are not summed into lifecycle wall time | missing/unsupported: omit no required occurrence; mark the benchmark record invalid if detail collection overflows; configuration: profiling level and benchmark specification select whether this step is emitted; effect: the enclosing run records the capability and freshness contract; the step ID alone implies neither | `src/foundation/profile.h`, `benchmarks/run_benchmark.py` |
diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md
index 0ee8058d1..312222b7b 100644
--- a/docs/CONFIGURATION.md
+++ b/docs/CONFIGURATION.md
@@ -75,17 +75,66 @@ Inspect or change values with the CLI:
```bash
codebase-memory-mcp config list
codebase-memory-mcp config get auto_index
+codebase-memory-mcp config describe pagerank_damping
codebase-memory-mcp config set auto_index true
codebase-memory-mcp config set auto_index_limit 50000
codebase-memory-mcp config reset auto_index
```
-Current keys:
+Important keys (`config list` shows common effective values; use `config get `
+for any registry key):
| Key | Default | Meaning |
|---|---|---|
-| `auto_index` | `false` | Automatically index new projects when an MCP session starts. |
+| `build_fingerprint_mode` | `cached_exact` | Exact-build verification cost policy: reuse a checksummed SHA-256 only for an unchanged kernel-bound native file (`cached_exact`), or hash the complete process image at every startup (`always_rehash`). Installer/update and Windows launcher payload verification always rehash. |
+| `auto_index` | `true` | Automatically index new projects at MCP startup or first graph use. |
| `auto_index_limit` | `50000` | Maximum file count allowed for automatic indexing of a new project. |
+| `auto_watch` | `true` | Register indexed projects for automatic background Git-change refresh. |
+| `tool_mode` | `streamlined` | MCP discovery surface: `streamlined` or `classic`. |
+| `context_injection` | `true` | Include bounded project/index status, recovery guidance, freshness, coverage, schema, and graph stats automatically in the first tool response; later responses include only `session_project`. |
+| `rank_enabled` | `true` | Compute PageRank, LinkRank, and degree views used by relevance ranking. |
+| `auto_index_deps` | `false` | Automatically index installed dependency source for cross-package search and tracing. |
+| `auto_dep_limit` | `20` | Import-ranked automatic dependency package cap; `0` is unlimited. |
+| `dep_max_files` | `1000` | Maximum source files per automatically indexed dependency package; larger packages are skipped atomically, and `0` is unlimited. |
+| `similarity_enabled` | `true` | Create MinHash similarity edges in applicable index modes. |
+| `semantic_edges_enabled` | `true` | Create semantic-related edges in applicable index modes. |
+| `githistory_enabled` | `true` | Create Git co-change coupling edges. |
+| `httplinks_enabled` | `true` | Link HTTP clients to discovered routes. |
+| `default_response_format` | `toon` | Tool-response encoding when a call omits `format`: `toon` (compact tables) or `json` (full objects). A per-call `format` argument always wins. |
+
+Normal streamlined exploration uses `search_graph`, `trace_path`, `get_code`, and
+`query_graph` as needed; automatic indexing and first-response context follow their
+settings. Classic structural discovery uses `search_graph`, then `trace_path`, then
+`get_code_snippet`; use `query_graph` or `get_architecture` for broader structure.
+Classic mode advertises advanced tools directly.
+
+### Named presets
+
+Presets atomically apply exact capability sets, so a prior manual setting cannot
+silently leak into a comparison:
+
+```bash
+codebase-memory-mcp config preset list
+codebase-memory-mcp config preset apply streamlined-automatic-dependency-source-indexing-disabled
+codebase-memory-mcp config preset apply streamlined-automatic-dependency-source-indexing-enabled
+codebase-memory-mcp config preset apply classic-automatic-dependency-source-indexing-disabled
+codebase-memory-mcp config preset apply classic-automatic-dependency-source-indexing-enabled
+```
+
+The four product presets pair the `streamlined` or `classic` tool surface with an
+explicit automatic dependency-source indexing state. All four enable the same rank,
+similarity, semantic-edge, Git-history, and HTTP-link capabilities. The disabled
+variants bound default indexing latency, CPU, memory, and stored graph size; the
+enabled variants add installed dependency-source coverage up to `auto_dep_limit`;
+`dep_max_files` skips oversized packages rather than publishing partial API coverage.
+`index_dependencies` remains available for explicit packages. Disabling automation
+stops future automatic dependency indexing but does not delete dependency projects
+already indexed. `rank-disabled` and `minimal-indexing` are benchmark ablations, and
+the CLI labels them accordingly. The `minimal-indexing` preset disables optional graph
+passes and dependency-source automation; the post-edit reindex strategy is unchanged.
+Environment variables remain higher priority than stored preset values, and preset
+application returns nonzero when an active override prevents the requested effective
+configuration.
## 3. UI Settings
@@ -104,9 +153,20 @@ Current format:
}
```
+Read or change these values through the same public config command used for
+runtime settings:
+
+```bash
+codebase-memory-mcp config get ui_enabled
+codebase-memory-mcp config set ui_enabled false
+codebase-memory-mcp config set ui_port 9749
+codebase-memory-mcp config reset ui_port
+```
+
Notes:
-- If a UI-enabled binary finds its verified external asset pack and no UI config file exists yet, the UI auto-enables on first run. Missing or invalid assets leave the MCP/daemon service available and keep the UI disabled.
+- If a binary carries the embedded frontend and no UI config file exists yet, the UI auto-enables on first run. Development builds without the frontend keep the MCP/daemon service available and leave the UI disabled.
+- UI setting changes take effect after the daemon restarts.
- `CBM_CACHE_DIR` changes both the UI config location and the runtime settings database location.
- CBM resolves `CBM_CACHE_DIR` to one canonical per-account cache root. A process configured with a different root fails while any CBM session or command is active; close them before switching roots.
@@ -119,7 +179,7 @@ These environment variables affect runtime behavior:
| `CBM_ALLOWED_ROOT` | *(unset)* | Confine `index_repository` to paths within this directory. When set, a `repo_path` that resolves (after symlink / `..` resolution) outside this root is refused, and the same check now applies to the graph UI's `POST /api/index` route rather than only to the MCP tool. Unset imposes no *containment* restriction — but see the always-on limits below, which apply whether or not this is set. Useful when the server may be driven by an untrusted caller, e.g. agentic or multi-tenant deployments. |
| `CBM_CACHE_DIR` | `~/.cache/codebase-memory-mcp` | Override the cache directory used for indexes, `_config.db`, and UI `config.json`. |
| `CBM_DIAGNOSTICS` | `false` | Enable periodic `snapshot.json` and retained `trajectory.ndjson` below a fresh owner-private directory in the system temp directory. The daemon records the randomized paths in the `diagnostics.start` discovery record (a single JSON line) in `${CBM_CACHE_DIR}/logs/cbm-daemon.log`; that one record is emitted even when `CBM_LOG_LEVEL` suppresses ordinary logging, so the paths always remain discoverable. |
-| `CBM_DOWNLOAD_URL` | GitHub releases | Override the update download URL. |
+| `CBM_DOWNLOAD_URL` | GitHub releases | Override the install-script download base URL; also used by local release-fixture tests. |
| `CBM_LOG_LEVEL` | `info` | Set the log level to `debug`, `info`, `warn`, `error`, or `none` (or `0`-`4`). Thin-frontend messages use that session's stderr; detached daemon events use `${CBM_CACHE_DIR}/logs/cbm-daemon.log`. |
| `CBM_RUNTIME_DIR` | `%LOCALAPPDATA%` (Windows), `/private/tmp` (macOS), `/tmp` (other) | Parent directory for the daemon/CLI rendezvous directory, which CBM creates inside it as `cbm-daemon-` (`cbm-daemon-` on Windows). Set it when the default ancestry cannot pass the private-directory check — see below. `CBM_CACHE_DIR` does **not** move the rendezvous. |
| `CBM_WORKERS` | auto-detected | Override the indexing worker count. |
@@ -184,7 +244,7 @@ not name is permitted.
## 5. Agent and Editor Integration Files
-The `install` command can also write MCP entries and instruction blocks into agent/editor config files such as Claude Code, Codex, Gemini, VS Code, Cursor, Zed, and others.
+The `install` command can also write MCP entries and owned instruction blocks into detected agent/editor config files. Supported targets include Claude Code, Claude Desktop, Codex, Gemini, Qwen Code, ForgeCode, Antigravity, OpenCode, Zed, VS Code and its profiles, Cursor, Windsurf, KiloCode, OpenClaw, Kiro, and Junie; Aider receives CLI-form instructions because it does not expose MCP.
Those target paths vary by tool and platform, so the easiest way to inspect the exact files for your machine is:
@@ -193,3 +253,4 @@ codebase-memory-mcp install --dry-run
```
That prints the specific config files the installer would modify without writing anything.
+`uninstall --dry-run` is also read-only, including when combined with `-y`; it reports the index action that would occur without prompting or deleting indexes.
diff --git a/docs/EVALUATION_PLAN.md b/docs/EVALUATION_PLAN.md
index 5f8bb532c..e5c456a38 100644
--- a/docs/EVALUATION_PLAN.md
+++ b/docs/EVALUATION_PLAN.md
@@ -846,7 +846,7 @@ Deep-Dive section.
> the question — that's exactly the gap symmetric authoring is designed to expose.
>
> **Pinning.** During authoring, the repo's resolved commit SHA is recorded and baked into
-> `clone-bench-repos.sh`, so the run indexes the *same* HEAD the questions were written against.
+> `scripts/clone-bench-repos.sh`, so the run indexes the *same* HEAD the questions were written against.
>
> §14 contains two fully-worked exemplars now; the remaining 157 are generated against their cloned
> repos (§15) following this authoring split.
@@ -1061,7 +1061,7 @@ The plan proposes "3–5 known near-duplicate / copy-pasted function pairs found
| C cross-repo pair (redis/hiredis, RESP protocol) produces 0 CROSS edges | High | Medium | Already flagged — treat as documented gap; consider using a WASM/Wasm-C host if a genuine C HTTP service pair can be found |
| 159-language sweep is not completable in one session without checkpointing | High | Medium | Add explicit checkpoint/resume logic to the script; describe failure-recovery in §13 |
| ~30 flagged ⚠️ repos unavailable, too small, or wrong language on run day | Medium | Medium | Validate all ⚠️ rows before authoring questions; fallback fixture corpus per §8.1 |
-| Shallow clone at run time produces a different HEAD than during question authoring | Medium | Medium | Pin repos by commit SHA during authoring; bake SHA into `clone-bench-repos.sh` |
+| Shallow clone at run time produces a different HEAD than during question authoring | Medium | Medium | Pin repos by commit SHA during authoring; bake SHA into `scripts/clone-bench-repos.sh` |
| 3-pass median of same judge hides variance; passes are correlated not independent | Medium | Medium | Cross-family panel or acknowledge limitation explicitly in §9 |
| Explorer spawn overhead excluded but material; Token Ratio misleads | Medium | Medium | Include full-session token cost as a second metric; label the narrow metric clearly |
@@ -1099,7 +1099,7 @@ If the Graph agent returns zero results on D2 (zero-result rate flagged in §5),
1. **Question authoring source of truth (§12 authoring note):** When you write "questions must cite real symbols, so they are filled in during Phase 0/1" — do you mean you will use the graph to discover those symbols, or will you independently verify them with Grep? If graph-first, you have the bias I described. What is your plan to ensure D1/D3 questions target symbols that Grep can also find?
2. **Judge model identity (§9.4):** What model will be the judge? If it is any Claude model, the same-family self-preference effect applies to every Claude-written Graph and Explorer answer. Have you considered a cross-family judge rotation, or at minimum disclosing the judge model in the report so readers can calibrate?
3. **CROSS edge formation in OTel sub-dirs (§11.1, §15):** Before writing 157 more language chapters, have you actually run `index_repository(mode="cross-repo-intelligence")` on two OTel service sub-dirs and confirmed that CROSS_HTTP_CALLS edges form? This is the load-bearing question for the entire deep-dive block. What is the fallback plan if they don't?
-4. **Session continuity (§13):** What happens when the main session context window fills up or hits the usage limit at language 94? Is there a described checkpoint format — e.g., a manifest of completed languages that `clone-bench-repos.sh` can consult to skip already-done languages — or does the whole run restart from zero?
+4. **Session continuity (§13):** What happens when the main session context window fills up or hits the usage limit at language 94? Is there a described checkpoint format — e.g., a manifest of completed languages that `scripts/clone-bench-repos.sh` can consult to skip already-done languages — or does the whole run restart from zero?
5. **D5 cross-group comparability (§3, §8):** You aggregate D5 scores across all 159 languages. But D5 for Go means `semantic_query=["dispatch","route"]` surfacing functions from a vector index. D5 for gitignore means "naming-pattern / config↔code links." These are different operations using different graph tools. Do you actually intend the cross-language D5 rollup in §10.1 to be meaningful, or is it cosmetic?
6. **S2 ground truth (§11.2):** "3–5 known near-duplicate function pairs" — how will you construct this set for each of the 9 LSP languages? Will you use the simhash output the indexer already produces, or is this a manual read? A 3-pair sample with no inter-rater agreement cannot support a recall claim. What is the minimum ground-truth size you consider credible?
7. **Token exclusion policy (§5):** If a developer is deciding whether to adopt codebase-memory-mcp, they pay the full session cost, including agent spawn, orientation, and formatting. Why should the reported "Token Ratio" exclude the Explorer's orientation cost? Would you consider reporting both the narrow metric and the full-session metric?
diff --git a/docs/index.html b/docs/index.html
index abf053b54..905ea7d17 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -4,7 +4,7 @@
codebase-memory-mcp — Code Intelligence Knowledge Graph for AI Coding Agents
-
+
@@ -12,7 +12,7 @@
-
+
@@ -24,7 +24,7 @@
-
+
@@ -41,7 +41,7 @@
"applicationSubCategory": "Model Context Protocol (MCP) server",
"operatingSystem": "macOS, Linux, Windows",
"softwareVersion": "0.8.1",
- "description": "An open-source MCP server that indexes a codebase into a persistent knowledge graph of functions, classes, call chains, HTTP routes, and cross-service links, so AI coding agents answer structural questions with roughly 120x fewer tokens than file-by-file search. Parses 158 languages via tree-sitter with Hybrid LSP semantic type resolution for 9 language families. Ships as a native executable with authenticated release-owned assets; the native install needs no language runtime.",
+ "description": "An open-source MCP server that indexes a codebase into a persistent knowledge graph of functions, classes, call chains, HTTP routes, and cross-service links, so AI coding agents answer structural questions with roughly 120x fewer tokens than file-by-file search. Parses 158 languages via tree-sitter with Hybrid LSP semantic type resolution for 9 language families. Ships as one self-contained native executable per target; the native install needs no language runtime.",
"url": "https://deusdata.github.io/codebase-memory-mcp/",
"downloadUrl": "https://github.com/DeusData/codebase-memory-mcp/releases/latest",
"codeRepository": "https://github.com/DeusData/codebase-memory-mcp",
@@ -56,7 +56,7 @@
"featureList": [
"Indexes 158 programming languages via vendored tree-sitter grammars",
"Hybrid LSP semantic type resolution for Python, TypeScript/JavaScript, PHP, C#, Go, C/C++, Java, Kotlin, and Rust",
- "15 MCP tools for structural search, call-path tracing, targeted coverage checks, and Cypher graph queries",
+ "Streamlined MCP tools plus 15 classic tools for structural search, call-path tracing, and Cypher graph queries",
"Semantic vector code search via bundled nomic-embed-code embeddings (no API key, fully local)",
"Semantic graph edges (SEMANTICALLY_RELATED) and near-clone detection (SIMILAR_TO, MinHash + LSH)",
"Cross-service linking for HTTP, gRPC, GraphQL, tRPC, and pub/sub channels with confidence scoring",
@@ -67,7 +67,7 @@
"Dead-code detection with entry-point filtering",
"Infrastructure-as-code indexing for Dockerfiles, Kubernetes, and Kustomize",
"Built-in 3D graph visualization UI",
- "Auto-sync background watcher for incremental re-indexing",
+ "Auto-sync background watcher with configurable reindex policy",
"One command configures 43 automatic/conditional client surfaces"
],
"author": {
@@ -125,7 +125,7 @@
"name": "What is codebase-memory-mcp?",
"acceptedAnswer": {
"@type": "Answer",
- "text": "codebase-memory-mcp is an open-source Model Context Protocol (MCP) server that indexes a codebase into a persistent knowledge graph of functions, classes, call chains, HTTP routes, and cross-service links. AI coding agents query that graph instead of reading files one by one, answering structural questions with roughly 120x fewer tokens. It parses 158 languages and ships as a native executable with authenticated release-owned assets; the native install needs no language runtime."
+ "text": "codebase-memory-mcp is an open-source Model Context Protocol (MCP) server that indexes a codebase into a persistent knowledge graph of functions, classes, call chains, HTTP routes, and cross-service links. AI coding agents query that graph instead of reading files one by one, answering structural questions with roughly 120x fewer tokens. It parses 158 languages and ships as one self-contained native executable per target; the native install needs no language runtime."
}
},
{
@@ -157,7 +157,7 @@
"name": "Which AI coding agents work with codebase-memory-mcp?",
"acceptedAnswer": {
"@type": "Answer",
- "text": "A single install command configures 43 automatic/conditional client surfaces. The 37 detected surfaces are Claude Code, Codex CLI, Gemini CLI, Zed, OpenCode, Antigravity, Aider, KiloCode, VS Code, Cursor, Windsurf, Augment / Auggie, OpenClaw, Kiro, Junie, Hermes, OpenHands, Cline, Warp, Qwen Code, GitHub Copilot CLI, Factory Droid, Crush, Goose, Mistral Vibe, Qoder CLI, Kimi Code CLI, GitLab Duo CLI, Rovo Dev CLI, Amp, Devin CLI / Local, Tabnine, Amazon Q Developer IDE, CodeBuddy Code CLI, IBM Bob Shell, Pochi, and Pi. Continue / cn, Visual Studio, TRAE, Roo Code, IBM Bob IDE, and Sourcegraph Cody are conditional or explicit integrations. Qodo, Warp MCP, JetBrains AI/ACP, GitHub Copilot coding agent, Jules, CodeRabbit, Replit, BLACKBOX AI, Plandex, and SWE-agent require manual, UI, cloud, or repository-managed setup and are not counted among the 43."
+ "text": "A single install command configures 43 automatic/conditional client surfaces. The 37 detected surfaces are Claude Code, Codex CLI, Gemini CLI, Zed, OpenCode, Antigravity, Aider, KiloCode, VS Code, Cursor, Windsurf, Augment / Auggie, OpenClaw, Kiro, Junie, Hermes, OpenHands, Cline, Warp, Qwen Code, GitHub Copilot CLI, Factory Droid, Crush, Goose, Mistral Vibe, Qoder CLI, Kimi Code CLI, GitLab Duo CLI, Rovo Dev CLI, Amp, Devin CLI / Local, Tabnine, Amazon Q Developer IDE, CodeBuddy Code CLI, IBM Bob Shell, Pochi, and Pi. Continue / cn, Visual Studio, TRAE, Roo Code, IBM Bob IDE, and Sourcegraph Cody are conditional or explicit integrations."
}
},
{
@@ -444,7 +444,7 @@
codebase-memory-mcp
The fastest, most efficient code intelligence engine for AI coding agents. It indexes any
repository into a persistent knowledge graph — full-indexing an average repo in seconds and the
Linux kernel in 3 minutes — so your agent answers structural questions with ~120x fewer tokens.
- Tree-sitter parsing across 158 languages, Hybrid LSP type resolution, native executable with verified assets.
+ Tree-sitter parsing across 158 languages, Hybrid LSP type resolution, and one self-contained native executable per target.
~120x
fewer tokens
@@ -461,7 +461,7 @@
codebase-memory-mcp
-
Built-in 3D graph visualization (UI variant) — explore your knowledge graph at localhost:9749.
+
Built-in 3D graph visualization — explore your knowledge graph at localhost:9749.
Pure C, no language runtime
-
A native executable with authenticated release-owned assets for macOS, Linux, and Windows. The native install needs no Docker, language runtime, or API keys; fully static Linux builds are available in the -portable archives.
+
One self-contained native executable per macOS, Linux, and Windows target, with the graph UI and integration templates embedded. The native install needs no Docker, language runtime, or API keys; fully static Linux builds are available in the -portable archives.
Call-graph tracing
@@ -728,19 +690,19 @@
Infrastructure-as-code indexing
Auto-sync
-
A background watcher detects changes and re-indexes incrementally. No manual reindex after editing files.
+
A background watcher detects git changes and re-indexes when configured. The reindex policy controls whether refreshes use full or incremental indexing.
Team-shared graph artifact
-
Commit one zstd-compressed snapshot (.codebase-memory/graph.db.zst); teammates bootstrap from it and skip the full reindex.
+
Commit one zstd-compressed snapshot (.codebase-memory/graph.db.zst); teammates can bootstrap from it before any configured refresh.
3D graph visualization
-
The optional UI variant adds one verified, content-addressed frontend pack and serves an interactive 3D graph at localhost:9749 to explore nodes, edges, and clusters visually.
+
The executable embeds the frontend and serves an interactive 3D graph at localhost:9749 to explore nodes, edges, and clusters visually.
-
15 MCP tools
-
search_graph, trace_path, detect_changes, query_graph (Cypher), get_architecture, get_code_snippet, check_index_coverage, manage_adr, and 7 more.
+
Streamlined + classic MCP tools
+
Default tools include search_graph, trace_path, query_graph, search_code, and get_code. Classic mode exposes 15 individual tools including index_repository, get_architecture, get_code_snippet, and manage_adr.
Cypher graph queries
@@ -809,9 +771,9 @@
Do I need Docker or a runtime?
installations naturally use their package runtime.
How does it stay up to date as I edit code?
-
A background watcher detects file changes and re-indexes incrementally — typically a sub-millisecond
- no-op when nothing changed. You only run a manual index for the first build or after a large
- git pull.
+
A background watcher detects git changes and can re-index automatically when configured.
+ The default refresh path favors correctness with a full atomic rebuild; incremental reindexing
+ remains an explicit policy setting.