Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/hqiv-arena.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ jobs:
path: _lean_artifacts
continue-on-error: true

- name: Protected mirror source integrity (AST gate)
run: python3 scripts/check_arena_source_integrity.py --verbose

- name: Run Lean ↔ Python Alignment Gate
id: align
run: |
Expand Down Expand Up @@ -247,7 +250,7 @@ jobs:
# On branches we compare against it; on main we will update it after merge.
run: |
curl -fsSL -o arena/baseline.json \
"https://raw.githubusercontent.com/disregardfiat/pyhqiv/main/arena/baseline.json" || \
"https://raw.githubusercontent.com/HQIV/pyhqiv/main/arena/baseline.json" || \
echo '{"overall_score": 1000, "metrics": []}' > arena/baseline.json
mkdir -p arena

Expand Down Expand Up @@ -296,7 +299,7 @@ jobs:
Full results artifact: `arena-score-${{ github.run_id }}` → `arena_results.json`

*Sigma everywhere*: broad error reduction across observables is rewarded. Single-metric gaming is discouraged.
See [CONTRIBUTING.md](https://github.com/disregardfiat/pyhqiv/blob/main/CONTRIBUTING.md#hqiv-arena) for details.
See [CONTRIBUTING.md](https://github.com/HQIV/pyhqiv/blob/main/CONTRIBUTING.md#hqiv-arena) for details.
"""
pr = os.environ.get("PR_NUMBER") or "${{ github.event.number }}"
if pr and pr != "null":
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

- (None in this release.)

[0.4.0]: https://github.com/disregardfiat/pyhqiv/releases/tag/v0.4.0
[0.4.0]: https://github.com/HQIV/pyhqiv/releases/tag/v0.4.0
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ authors:
orcid: ""
date-released: 2026-02-27
doi: 10.5281/zenodo.18794889
url: "https://github.com/disregardfiat/pyhqiv"
url: "https://github.com/HQIV/pyhqiv"
version: "0.3.0"
license: MIT
repository-code: "https://github.com/disregardfiat/pyhqiv"
repository-code: "https://github.com/HQIV/pyhqiv"
preferred-citation:
type: article
title: "Horizon-Quantized Informational Vacuum (HQIV): A Unified Framework from Causal Horizon Monogamy and Discrete Null-Lattice Combinatorics"
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ All development happens on branches:
- See the workflow in hqiv-lean and the lean job in pyhqiv's arena workflow.

2. **Lean ↔ Python Alignment Gate** (hard)
- `python scripts/validate_hqiv_alignment.py`
- Must pass 100%. Uses Lean-exported `witnesses.json` + functional mirror checks in pyhqiv (lightcone, metric, so8 generators, etc.).
- `python scripts/check_arena_source_integrity.py` — AST gate on `lightcone.py` / `metric.py` (no import creep, no literal-return cheats in Ω_k mirrors).
- `python scripts/validate_hqiv_alignment.py` — must pass 100%. Uses Lean-exported `witnesses.json` + functional mirror checks in pyhqiv (lightcone, metric, so8 generators, etc.).
- If you changed a Lean definition that affects a numerical value, update the export and the py mirror (or the alignment will fail).

3. **Python Test Gate** (hard)
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# pyhqiv — Horizon-Quantized Informational Vacuum (HQIV) Calculator

[![PyPI version](https://badge.fury.io/py/pyhqiv.svg)](https://badge.fury.io/py/pyhqiv)
[![CI](https://github.com/disregardfiat/pyhqiv/actions/workflows/ci.yml/badge.svg)](https://github.com/disregardfiat/pyhqiv/actions/workflows/ci.yml)
[![CI](https://github.com/HQIV/pyhqiv/actions/workflows/ci.yml/badge.svg)](https://github.com/HQIV/pyhqiv/actions/workflows/ci.yml)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.18794889.svg)](https://doi.org/10.5281/zenodo.18794889)

> **⚠️ Experimental status.** All features in this package are experimental. APIs and numerical results may change. Public contribution and feedback are greatly appreciated — please open issues or pull requests on [GitHub](https://github.com/disregardfiat/pyhqiv).
> **⚠️ Experimental status.** All features in this package are experimental. APIs and numerical results may change. Public contribution and feedback are greatly appreciated — please open issues or pull requests on [GitHub](https://github.com/HQIV/pyhqiv).

**pyhqiv** is the clean, first-principles Python calculator for the HQIV framework (discrete null-lattice combinatorics + horizon monogamy + octonionic carriers). It exactly mirrors the Lean formalization in [HQIV/hqiv-lean](https://github.com/HQIV/hqiv-lean) and the paper series in `HQIV_LEAN/papers/`.

Expand Down Expand Up @@ -41,7 +41,7 @@ pip install pyhqiv
From source (editable, for development/arena):

```bash
git clone https://github.com/disregardfiat/pyhqiv.git && cd pyhqiv
git clone https://github.com/HQIV/pyhqiv.git && cd pyhqiv
pip install -e ".[dev]"
```

Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ dev = ["pytest>=7", "pytest-cov>=4", "matplotlib>=3.5"]
all = ["pyhqiv[ase,mda,qutip,jax,pyvista]"]

[project.urls]
Documentation = "https://github.com/disregardfiat/pyhqiv"
Repository = "https://github.com/disregardfiat/pyhqiv"
"Bug Tracker" = "https://github.com/disregardfiat/pyhqiv/issues"
Documentation = "https://github.com/HQIV/pyhqiv"
Repository = "https://github.com/HQIV/pyhqiv"
"Bug Tracker" = "https://github.com/HQIV/pyhqiv/issues"

[project.scripts]
hqiv-arena = "pyhqiv.arena_cli:main"
Expand Down
197 changes: 197 additions & 0 deletions scripts/check_arena_source_integrity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
#!/usr/bin/env python3
"""
Static integrity gate for HQIV Arena Lean-mirror Python modules.

Complements scripts/validate_hqiv_alignment.py by rejecting import creep and
literal-return shortcuts in lightcone.py / metric.py before numeric alignment runs.
"""

from __future__ import annotations

import argparse
import ast
import sys
from dataclasses import dataclass
from pathlib import Path
from typing import Iterable

REPO_ROOT = Path(__file__).resolve().parents[1]

ALLOWED_RETURN_FLOATS = frozenset({0.0, 1.0})
ALLOWED_MODULE_BINDINGS = frozenset({"ALPHA_EXACT", "__all__"})

IMPORT_ALLOWLIST: dict[str, frozenset[str | None]] = {
"src/pyhqiv/lightcone.py": frozenset({None, "fractions", "math", "__future__"}),
"src/pyhqiv/metric.py": frozenset({None, "dataclasses", "math", "__future__", "pyhqiv"}),
}

REQUIRED_CALLEES: dict[str, dict[str, frozenset[str]]] = {
"src/pyhqiv/lightcone.py": {
"omega_k_at_horizon": frozenset({"curvature_integral", "x_over_theta_from_horizons"}),
"omega_k_partial": frozenset({"omega_k_at_horizon", "reference_m"}),
"reference_m": frozenset({"qcd_shell", "lattice_step_count"}),
"curvature_norm_combinatorial": frozenset(
{"cube_directions", "octonion_imaginary_dim", "unit_cube_half_diagonal"}
),
},
"src/pyhqiv/metric.py": {
"gamma_hqiv": frozenset({"alpha"}),
},
}

PROTECTED_PATHS = tuple(IMPORT_ALLOWLIST.keys())


@dataclass
class Violation:
file: str
rule: str
detail: str


def _import_roots(tree: ast.Module) -> set[str | None]:
roots: set[str | None] = set()
for node in ast.walk(tree):
if isinstance(node, ast.Import):
for alias in node.names:
roots.add(alias.name.split(".")[0])
elif isinstance(node, ast.ImportFrom):
if node.module is None:
roots.add(None)
else:
roots.add(node.module.split(".")[0])
return roots


def _calls_in_function(func: ast.FunctionDef | ast.AsyncFunctionDef) -> set[str]:
names: set[str] = set()
for node in ast.walk(func):
if isinstance(node, ast.Call):
if isinstance(node.func, ast.Name):
names.add(node.func.id)
elif isinstance(node.func, ast.Attribute):
names.add(node.func.attr)
return names


def _bad_literal_returns(func: ast.FunctionDef | ast.AsyncFunctionDef) -> list[float]:
bad: list[float] = []
for node in ast.walk(func):
if not isinstance(node, ast.Return) or node.value is None:
continue
val = node.value
if isinstance(val, ast.Constant) and isinstance(val.value, (int, float)):
f = float(val.value)
if f not in ALLOWED_RETURN_FLOATS:
bad.append(f)
return bad


def _module_float_assignments(tree: ast.Module) -> list[str]:
bad: list[str] = []
for node in tree.body:
if isinstance(node, ast.Assign):
for target in node.targets:
if isinstance(target, ast.Name):
name = target.id
if name in ALLOWED_MODULE_BINDINGS:
continue
if isinstance(node.value, ast.Constant) and isinstance(
node.value.value, float
):
bad.append(name)
return bad


def _function_defs(tree: ast.Module) -> dict[str, ast.FunctionDef]:
return {n.name: n for n in tree.body if isinstance(n, ast.FunctionDef)}


def check_file(rel_path: str) -> list[Violation]:
path = REPO_ROOT / rel_path
if not path.exists():
return [Violation(rel_path, "missing_file", str(path))]

tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path))
violations: list[Violation] = []

allowed_imports = IMPORT_ALLOWLIST[rel_path]
extra = _import_roots(tree) - allowed_imports
if extra:
violations.append(
Violation(
rel_path,
"imports",
f"disallowed import roots: {sorted(extra)}",
)
)

for name in _module_float_assignments(tree):
violations.append(Violation(rel_path, "module_float", f"module-level float: {name}"))

funcs = _function_defs(tree)
for func_name, must_call in REQUIRED_CALLEES.get(rel_path, {}).items():
func = funcs.get(func_name)
if func is None:
violations.append(
Violation(rel_path, "missing_function", f"expected {func_name}")
)
continue
missing = must_call - _calls_in_function(func)
if missing:
violations.append(
Violation(
rel_path,
"structural_calls",
f"{func_name} must call {sorted(missing)}",
)
)
bad_returns = _bad_literal_returns(func)
if bad_returns:
violations.append(
Violation(
rel_path,
"literal_return",
f"{func_name} forbidden literal return(s): {bad_returns}",
)
)
if func_name == "hqvm_lapse":
for node in ast.walk(func):
if isinstance(node, ast.Return) and isinstance(node.value, ast.Constant):
if isinstance(node.value.value, (int, float)):
violations.append(
Violation(
rel_path,
"literal_return",
f"{func_name} must be 1 + Phi + phi*t, not a constant",
)
)

return violations


def run_checks(paths: Iterable[str] | None = None) -> list[Violation]:
all_v: list[Violation] = []
for rel in list(paths) if paths else list(PROTECTED_PATHS):
all_v.extend(check_file(rel))
return all_v


def main(argv: list[str] | None = None) -> int:
p = argparse.ArgumentParser(description="HQIV Arena protected-source integrity gate")
p.add_argument("--verbose", "-v", action="store_true")
p.add_argument("paths", nargs="*", help="Optional module paths under repo root")
args = p.parse_args(argv)

violations = run_checks(args.paths or None)
if args.verbose or violations:
print("=== HQIV Arena source integrity ===")
for v in violations:
print(f"[FAIL] {v.file} ({v.rule}): {v.detail}")
if not violations:
print("All protected modules passed.")
return 1 if violations else 0


if __name__ == "__main__":
sys.exit(main())
27 changes: 11 additions & 16 deletions src/pyhqiv/arena/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: hqiv-arena
description: "Use when helping a solver or coding agent use the hqiv-arena CLI for the HQIV physics improvement benchmark (HQIV/hqiv-lean + pyhqiv): login, config, benchmark, clone, setup, run, submit, note, submissions, sync, reset, version, update, and install-skill. Explains the GitHub-native workflow, repo context (Lean + Python alignment), API/PAT keys, dirty-worktree safety, and how local scoring feeds the public leaderboard at disregardfiat.tech/#arena."
description: "Use when helping a solver or coding agent use the hqiv-arena CLI for the HQIV physics improvement benchmark (HQIV/hqiv-lean + HQIV/pyhqiv): login, config, benchmark, clone, setup, run, submit, note, submissions, sync, reset, version, update, and install-skill. Explains dual auth (hqiv_ Arena API key + GitHub PAT/gh for PRs), repo context, dirty-worktree safety, and how local scoring feeds the public leaderboard at disregardfiat.tech/#arena."
---

# HQIV Arena CLI Usage
Expand All @@ -9,32 +9,27 @@ Use this skill to operate the `hqiv-arena` solver CLI from a terminal for improv

The CLI is configured for the HQIV "fixed benchmark" (improving formal + numerical physics results across hqiv-lean and pyhqiv while keeping Lean ↔ Python alignment and increasing scores under the "sigma everywhere" rules).

## Setup & GitHub Login / API Key (PAT)
## Setup & authentication (two credentials)

The HQIV Arena is GitHub-native. You authenticate with a GitHub Personal Access Token (PAT) that has `repo` scope (for pushing branches and opening PRs). The token is stored locally.
1. **Arena API key (`hqiv_…`)** — from [disregardfiat.tech/#arena](https://disregardfiat.tech/#arena) (Sign in with GitHub). Used for provisional leaderboard entries via the public Arena API. No GitHub PAT required for this step.

```bash
hqiv-arena login
hqiv-arena login hqiv_YourKeyFromTheSite
export HQIV_ARENA_API_URL=https://disregardfiat.tech/api/v1 # optional override
```

This prints instructions and a link:

- Visit https://github.com/settings/tokens/new
- Give it a name like "HQIV Arena"
- Select the `repo` scope (full control of private repos is not needed; public repo is sufficient for HQIV)
- Generate the token (classic PAT)
- Paste it: `hqiv-arena login ghp_YourTokenHere`

You can also pass it directly:
2. **GitHub PAT (`ghp_…`)** — for `hqiv-arena submit` to push branches and open PRs on `HQIV/pyhqiv` (authoritative CI scoring). Or use `gh auth login` instead of storing a PAT.

```bash
hqiv-arena login ghp_YourTokenHere
```

Environment overrides (useful for agents):
Run `login` twice to store both keys in `~/.config/hqiv-arena/config.json`.

Environment overrides (agents):

- `HQIV_ARENA_TOKEN`: the GitHub PAT
- `HQIV_ARENA_API_URL`: (future) if a custom arena API is used
- `HQIV_ARENA_TOKEN`: `hqiv_…` **or** GitHub PAT (prefix selects behavior)
- `HQIV_ARENA_API_URL`: Arena API base (default `https://disregardfiat.tech/api/v1`)

Check config:

Expand Down
Loading
Loading