mirror of
https://github.com/hanzoai/datastore.git
synced 2026-10-30 14:48:37 +00:00
Three independent findings from a fresh self-review: 1. **`PR_PERF_TABLE.md:3` referenced a deleted file.** The sample-output template said "_Companion to `PERFORMANCE_GAINS.md`_", but `PERFORMANCE_GAINS.md` was removed in the slim-down round (`3ab7611e82b`). A future Claude reading the canonical per-PR template would chase a dangling reference. Drop the parenthetical; the rest of the sentence stands on its own. 2. **`_common_prefix` was a private helper in `build_commit_diff.py` with no test coverage.** It's a generic 5-line longest-common- prefix function used to rank SHA-typo suggestions. Move it to `_common.py` (rename: drop the leading underscore — it's now part of the shared API surface), import it from `build_commit_diff`, and add 5 unittest cases covering no-overlap / partial-overlap / identical / one-is-prefix / empty-input edges. A regression here would silently degrade suggestion quality without raising. Test count: 18 → 23. 3. **`diff` and `noise` subcommands weren't mentioned in `rebuild.sh`.** They're on-demand by design (you don't run them every pipeline pass), but a reader scanning the orchestrator's bottom would miss the broader skill surface. Add a 4-line trailing comment listing the on-demand subcommands so the CLI surface is discoverable from `rebuild.sh` alone. Smoke parity: `cumulative_gains.tsv` md5 unchanged at `e5a27e01008ef7e23597ee041f68103b`; `#99651` row bit-identical; all 23 unit tests pass; SHA-typo path still ranks `fdf46xxx` suggestions with `fdf46ee1` first.
124 lines
4.7 KiB
Python
124 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Per-(scenario, backend, metric) Δ between two arbitrary commit SHAs.
|
|
|
|
Use case: "compare commit `abcd1234` vs `efgh5678` directly" — the two SHAs
|
|
need not be a PR's pre/post pair. For PR validation, use `compute_deltas`
|
|
instead (it handles the kind-matched fallback baseline; see methodology.md).
|
|
|
|
Output: `commit_diff.tsv` with columns
|
|
scenario, backend, kind, metric, sha_a, sha_b,
|
|
value_a, value_b, delta_abs, delta_pct, verdict
|
|
|
|
`verdict` reuses `_common.classify` so the rubric matches every other
|
|
per-metric Δ output in the skill.
|
|
"""
|
|
import csv
|
|
import sys
|
|
from collections import defaultdict
|
|
from pathlib import Path
|
|
|
|
from _common import HEADLINE_METRICS, classify, common_prefix, is_fault_scenario, to_float
|
|
|
|
ROOT = Path(__file__).parent
|
|
|
|
|
|
def _resolve_sha(prefix, by_sha8):
|
|
"""Resolve a user-provided SHA to the 8-char form present in the index.
|
|
|
|
Accepts an 8-char prefix or a longer SHA; case-insensitive.
|
|
"""
|
|
p = prefix.lower()[:8]
|
|
if p in by_sha8:
|
|
return p
|
|
return None
|
|
|
|
|
|
def main(sha_a_arg, sha_b_arg):
|
|
by_sha8 = defaultdict(dict) # sha8 -> {(scenario, backend) -> row}
|
|
with open(ROOT / "merged_metrics.tsv") as f:
|
|
for r in csv.DictReader(f, delimiter="\t"):
|
|
sha8 = r["commit_sha"][:8].lower()
|
|
by_sha8[sha8][(r["scenario"], r["backend"])] = r
|
|
|
|
sha_a = _resolve_sha(sha_a_arg, by_sha8)
|
|
sha_b = _resolve_sha(sha_b_arg, by_sha8)
|
|
if sha_a is None or sha_b is None:
|
|
# Suggest by-prefix-similarity rather than alphabetical order so a
|
|
# typo like `a1b2c3d5` -> `a1b2c3d4` actually surfaces the close match.
|
|
def _suggest(arg):
|
|
p = arg.lower()[:8]
|
|
scored = sorted(
|
|
by_sha8.keys(),
|
|
key=lambda k: (-len(common_prefix(k, p)), k),
|
|
)
|
|
return scored[:5]
|
|
miss = []
|
|
if sha_a is None:
|
|
miss.append(f"{sha_a_arg!r} → suggestions: {_suggest(sha_a_arg)}")
|
|
if sha_b is None:
|
|
miss.append(f"{sha_b_arg!r} → suggestions: {_suggest(sha_b_arg)}")
|
|
print(
|
|
"build_commit_diff: SHA not found in merged_metrics.tsv:\n "
|
|
+ "\n ".join(miss),
|
|
file=sys.stderr,
|
|
)
|
|
return 2
|
|
|
|
sb_a = set(by_sha8[sha_a].keys())
|
|
sb_b = set(by_sha8[sha_b].keys())
|
|
shared = sorted(sb_a & sb_b)
|
|
only_a = sorted(sb_a - sb_b)
|
|
only_b = sorted(sb_b - sb_a)
|
|
if only_a or only_b:
|
|
print(
|
|
f"build_commit_diff: {len(only_a)} (scenario,backend) pair(s) "
|
|
f"only in {sha_a}, {len(only_b)} only in {sha_b}; emitting "
|
|
f"the {len(shared)}-pair intersection.",
|
|
file=sys.stderr,
|
|
)
|
|
|
|
out_path = ROOT / "commit_diff.tsv"
|
|
cols = ["scenario", "backend", "kind", "metric", "sha_a", "sha_b",
|
|
"value_a", "value_b", "delta_abs", "delta_pct", "verdict"]
|
|
with open(out_path, "w", newline="") as fout:
|
|
w = csv.writer(fout, delimiter="\t", lineterminator="\n")
|
|
w.writerow(cols)
|
|
for sc, be in shared:
|
|
ra = by_sha8[sha_a][(sc, be)]
|
|
rb = by_sha8[sha_b][(sc, be)]
|
|
kind = "fault" if is_fault_scenario(sc) else "no-fault"
|
|
for metric, _ in HEADLINE_METRICS:
|
|
va = to_float(ra.get(metric))
|
|
vb = to_float(rb.get(metric))
|
|
if va is None and vb is None:
|
|
continue
|
|
delta_abs = "" if (va is None or vb is None) else f"{vb - va:.4f}"
|
|
# delta_pct semantics:
|
|
# missing data → "" (don't fabricate a percentage)
|
|
# 0 → 0 → "" (no change, no scale to report against)
|
|
# 0 → positive → "inf" (unbounded relative change)
|
|
# else → standard (post - pre) / |pre| * 100
|
|
if va is None or vb is None:
|
|
delta_pct = ""
|
|
elif va == 0:
|
|
delta_pct = "" if vb == 0 else "inf"
|
|
else:
|
|
delta_pct = f"{(vb - va) / abs(va) * 100:.2f}"
|
|
w.writerow([
|
|
sc, be, kind, metric, sha_a, sha_b,
|
|
"" if va is None else f"{va:.4f}",
|
|
"" if vb is None else f"{vb:.4f}",
|
|
delta_abs, delta_pct,
|
|
classify(metric, va, vb),
|
|
])
|
|
print(f"Wrote {out_path} (sha_a={sha_a}, sha_b={sha_b}, {len(shared)} pairs)",
|
|
file=sys.stderr)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) != 3:
|
|
print("usage: build_commit_diff.py <shaA> <shaB>", file=sys.stderr)
|
|
sys.exit(2)
|
|
sys.exit(main(sys.argv[1], sys.argv[2]) or 0)
|