mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-30 18:56:16 +00:00
Squash the four overlapping feature branches into a single change set against main, eliminating cross-PR merge conflicts and the duplicated CI-fix scripts. What this brings in (merge order #79 -> #80 -> #81 -> #89): - #79 refactor(infra): shared utilities (4-Infrastructure/lib/*: q16, hashing, jsonl, fraction_utils) + the scripts/math-first/* validators that the math-check CI requires. - #80 feat(lean): Semantics.E8Sidon (1025 lines) -- Eisenstein coefficient identity E4^2 = E8 and the Sidon framework. E4_sq_eq_E8_coeff is fully proved (all Fourier-coefficient extraction machine-checked); the single residual gap is pinned to E4_sq_eq_E8_qExpansion (Mathlib lacks the valence formula / dim M8 = 1). 4 sorries + 1 axiom (e8_additive_completeness), all TODO(lean-port). - #81 refactor(lean): Float-free FixedPoint core (integer-only sqrt/log2/expNeg). E8Sidon.lean kept at #80's final 1025-line version (the #81 intermediate 438-line copy was overridden by merge order). - #89 feat(lean): Semantics.RRC.PolyFactorIdentity -- short-sleeve polynomial detection at the zerocopy limb boundary; now imports Semantics.E8Sidon for sigma3/sigma7/convolutionLHS (single source of truth) instead of inlining them. Conflict resolution: - flake.nix -> canonical rs-surface removal (Garnix shutdown). - scripts/math-first/* -> byte-identical across branches, clean. - .cursorrules / AGENTS.md -> unified; baselines + sorry inventory refreshed. Verification: - lake build (default aggregator): 3573 jobs, 0 errors. - lake build Semantics.RRC.PolyFactorIdentity (E8Sidon + FixedPoint + PolyFactor): 3655 jobs, 0 errors. Witnesses verified (sigma7 4 = 16513, convolutionLHS 6 = 2350). - Python tests: 68/68 pass. Note: the "Workers Builds: researchstack" check is a preexisting external Cloudflare build unrelated to this change (no branch touches 4-Infrastructure/cloudflare/). Build: 3573 jobs (default), 3655 jobs (narrow), 0 errors Co-Authored-By: Allaun Silverfox <bigdataiscoming+9i37y6j2@protonmail.com>
122 lines
3.8 KiB
Python
Executable file
122 lines
3.8 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""Require math evidence (receipt or Lean change) alongside math-track edits.
|
|
|
|
This script enforces the math-first contract: if a commit or PR touches files
|
|
in a math-track surface, at least one evidence file must also be present.
|
|
|
|
Usage:
|
|
# CI mode: compare against a base ref
|
|
python3 scripts/math-first/require_math_evidence.py --from-git-diff origin/main
|
|
|
|
# Pre-commit mode: check staged files
|
|
python3 scripts/math-first/require_math_evidence.py --staged
|
|
|
|
Exits 0 if:
|
|
- No math-track files are present in the changeset, OR
|
|
- At least one evidence file is also in the changeset
|
|
|
|
Exits 1 if math-track files are present but no evidence file accompanies them.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# Math-track surface prefixes: files under these paths require evidence
|
|
MATH_TRACK_PREFIXES = (
|
|
"0-Core-Formalism/lean/Semantics/",
|
|
"6-Documentation/docs/distilled/",
|
|
"shared-data/data/stack_solidification/",
|
|
)
|
|
|
|
# Evidence patterns: if any changed file matches, the requirement is satisfied
|
|
EVIDENCE_PREFIXES = (
|
|
"shared-data/artifacts/deepseek_review/",
|
|
"0-Core-Formalism/lean/Semantics/",
|
|
)
|
|
EVIDENCE_FILES = (
|
|
"claims.yaml",
|
|
)
|
|
|
|
|
|
def get_changed_files_git_diff(base_ref: str) -> list[str]:
|
|
"""Get changed files by diffing against a base ref."""
|
|
result = subprocess.run(
|
|
["git", "diff", "--name-only", base_ref + "...HEAD"],
|
|
capture_output=True, text=True, check=False,
|
|
)
|
|
if result.returncode != 0:
|
|
# Fall back to two-dot diff
|
|
result = subprocess.run(
|
|
["git", "diff", "--name-only", base_ref],
|
|
capture_output=True, text=True, check=True,
|
|
)
|
|
return [f for f in result.stdout.strip().split("\n") if f]
|
|
|
|
|
|
def get_changed_files_staged() -> list[str]:
|
|
"""Get staged files for pre-commit hook."""
|
|
result = subprocess.run(
|
|
["git", "diff", "--cached", "--name-only"],
|
|
capture_output=True, text=True, check=True,
|
|
)
|
|
return [f for f in result.stdout.strip().split("\n") if f]
|
|
|
|
|
|
def is_math_track(path: str) -> bool:
|
|
return any(path.startswith(p) for p in MATH_TRACK_PREFIXES)
|
|
|
|
|
|
def is_evidence(path: str) -> bool:
|
|
if any(path.startswith(p) for p in EVIDENCE_PREFIXES):
|
|
return True
|
|
if path in EVIDENCE_FILES:
|
|
return True
|
|
return False
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
group = parser.add_mutually_exclusive_group(required=True)
|
|
group.add_argument("--from-git-diff", metavar="BASE_REF",
|
|
help="Compare HEAD against BASE_REF")
|
|
group.add_argument("--staged", action="store_true",
|
|
help="Check staged files (pre-commit mode)")
|
|
args = parser.parse_args()
|
|
|
|
if args.staged:
|
|
changed = get_changed_files_staged()
|
|
else:
|
|
changed = get_changed_files_git_diff(args.from_git_diff)
|
|
|
|
if not changed:
|
|
print("No changed files")
|
|
return 0
|
|
|
|
math_files = [f for f in changed if is_math_track(f)]
|
|
if not math_files:
|
|
print("No math-track files in changeset — skipping evidence check")
|
|
return 0
|
|
|
|
evidence_files = [f for f in changed if is_evidence(f)]
|
|
if evidence_files:
|
|
print(f"OK: {len(math_files)} math-track file(s) with "
|
|
f"{len(evidence_files)} evidence file(s)")
|
|
return 0
|
|
|
|
# Math-track files present but no evidence
|
|
print("FAIL: math-track files changed but no evidence accompanies them:")
|
|
for f in math_files:
|
|
print(f" - {f}")
|
|
print("\nPlease include at least one of:")
|
|
print(" - A DeepSeek review receipt under shared-data/artifacts/deepseek_review/")
|
|
print(" - A Lean source file under 0-Core-Formalism/lean/Semantics/")
|
|
print(" - An update to claims.yaml")
|
|
return 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|