Skip to content
Merged
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
21 changes: 21 additions & 0 deletions benchmarks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,27 @@ Terminal teardown proof:
make -C benchmarks progressive-host-ladder-inventory OUTPUT_DIR=$OUTPUT_DIR WORK_ROOT=$WORK_ROOT
```

This emits `graphforge-host-work-root-inventory/2` from an actual filesystem
inventory and binds it automatically to the existing native result receipts.
It checks the whole work root, including `tmp/`, failed staging directories,
unexpected files, and dangling links. Only the explicitly retained evidence
directory and empty `workspace/` / `tmp/` scaffolding are excluded; the scope is
recorded in the document. Keep evidence outside the work root or in one direct
child directory. An unreadable tree is an error, never an empty inventory.

Ingest that same output directory with `ingest-ladder-bundle`; native receipts
need no Fly image, provider teardown, or additional manifest. Plans, results,
phase artifacts, admission projections, and cleanup inventory must agree by
identity and digest. Historical provider bundles remain readable as migration
fixtures. Legacy unbound native inventory v1 cannot establish full completion.

`parity-gate` reports structural retirement, accepted prefix parity, and
`full_ladder_evidence_complete` separately. A valid S18/S19 prefix is useful
engineering evidence but does not establish full harness authority or complete
#959. Full completion requires all seven native rungs through S26 and empty
terminal work-root inventory; it does not claim an official Graph500 submission
or replace independent review of the actual #900 lifecycle/parity evidence.

## Progressive Graph500 qualification

**Graph500-compliant generated input; GraphForge lifecycle measurements; no
Expand Down
38 changes: 35 additions & 3 deletions benchmarks/harness/graphforge_bench/ladder_bundle_ingest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from jsonschema import Draft202012Validator

from graphforge_bench.parity_gate import ladder_bundle_root
from graphforge_bench.native_ladder_bundle import NativeBundleError, validate_native_bundle
from graphforge_bench.scale_parity import compare_ladder_bundle

RUNG_NAME = re.compile(r"^s(\d+)-rung\.json$")
Expand Down Expand Up @@ -57,11 +57,41 @@ def _validate_manifest(document: Any) -> None:
raise LadderBundleIngestError("manifest.json commit must be a lowercase Git object ID")


def _has_native_receipts(source: Path) -> bool:
for path in (*source.glob("*-result.json"), *source.glob("*-plan.json")):
document = _read_json(path, f"{path.name} is malformed")
if isinstance(document, dict) and document.get("schema") in {
"graphforge-progressive-host-run-plan/1",
"graphforge-progressive-host-run-result/1",
}:
return True
return False


def validate_ladder_bundle(source: Path) -> dict[str, Any]:
"""Validate a completed #900 bundle directory without copying it."""
if not source.is_dir():
raise LadderBundleIngestError("source ladder bundle directory is missing")

if (
not (source / "manifest.json").exists()
or (source / "work-root-inventory.json").exists()
or _has_native_receipts(source)
):
try:
native = validate_native_bundle(source)
except (NativeBundleError, OSError) as error:
raise LadderBundleIngestError(str(error)) from error
return {
"schema": INGEST_SCHEMA,
"source": str(source),
"manifest_commit": native["commit"],
"rung_files": [f"s{scale}-rung.json" for scale in native["scales"]],
"rung_scales": native["scales"],
"teardown_status": "empty" if native["empty"] else "failed",
"evidence_files": native["files"],
}

manifest_path = source / "manifest.json"
teardown_path = source / "teardown-inventory.json"
if not manifest_path.is_file():
Expand Down Expand Up @@ -104,12 +134,14 @@ def validate_ladder_bundle(source: Path) -> dict[str, Any]:
def ingest_ladder_bundle(source: Path, destination: Path | None = None) -> dict[str, Any]:
"""Validate a #900 bundle and copy it into the parity fixture tree."""
report = validate_ladder_bundle(source)
target = destination or ladder_bundle_root()
target = destination or Path(__file__).resolve().parents[2] / "fixtures/parity/ladder-bundle"
if target.exists() and any(target.glob("*-rung.json")):
raise LadderBundleIngestError("destination already contains ingested rung bundles")

target.mkdir(parents=True, exist_ok=True)
for name in ("manifest.json", "teardown-inventory.json", *report["rung_files"]):
for name in report.get(
"evidence_files", ("manifest.json", "teardown-inventory.json", *report["rung_files"])
):
shutil.copy2(source / name, target / name)

parity = compare_ladder_bundle(target)
Expand Down
151 changes: 151 additions & 0 deletions benchmarks/harness/graphforge_bench/native_ladder_bundle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
"""Read native ladder receipts and bind cleanup inventory to those exact results."""

from __future__ import annotations

import hashlib
import json
from pathlib import Path
from typing import Any

from jsonschema import Draft202012Validator

from graphforge_bench.native_rung import NativeRungError, read_native_rung
from graphforge_bench.progressive_provider_attempt import CANONICAL_RUNGS

INVENTORY_SCHEMA = "graphforge-host-work-root-inventory/2"
HOST_PROFILE_ID = "local-linux-cgroups-v2"


class NativeBundleError(ValueError):
"""Native evidence does not establish a consistent completed prefix."""


def digest(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()


def read_object(path: Path) -> dict[str, Any]:
try:
if path.is_symlink():
raise NativeBundleError(f"linked evidence: {path.name}")
value = json.loads(path.read_text(encoding="utf-8"))
except (OSError, UnicodeError, ValueError) as error:
raise NativeBundleError(f"invalid evidence: {path.name}") from error
if not isinstance(value, dict):
raise NativeBundleError(f"evidence is not an object: {path.name}")
return value


def validate_schema(document: dict[str, Any], name: str) -> None:
root = Path(__file__).resolve().parents[2] / "schemas"
error = next(Draft202012Validator(read_object(root / name)).iter_errors(document), None)
if error is not None:
raise NativeBundleError(f"{name}: {error.message}")


def native_receipts(source: Path) -> dict[str, Any]:
"""Validate existing producer outputs; no second manifest or approval is needed."""
paths = sorted(source.glob("*-rung.json"))
scales = list(CANONICAL_RUNGS[: len(paths)])
if (
not paths
or len(paths) > len(CANONICAL_RUNGS)
or [p.name for p in paths] != [f"s{scale}-rung.json" for scale in scales]
):
raise NativeBundleError("native rung files are not a canonical prefix")
expected_results = [f"s{scale}-result.json" for scale in scales]
if sorted(p.name for p in source.glob("*-result.json")) != expected_results:
raise NativeBundleError("native result files contradict the completed prefix")
files: list[str] = []
results: dict[str, str] = {}
common: dict[str, Any] | None = None
for scale in scales:
prefix = f"s{scale}"
result_path = source / f"{prefix}-result.json"
try:
documents = read_native_rung(Path(__file__).resolve().parents[2], source, scale)
except NativeRungError as error:
raise NativeBundleError(str(error)) from error
result = documents["result"]
identities = result["identities"]
shared = {
key: value
for key, value in identities.items()
if key
not in {
"profile_id",
"profile_sha256",
"admitted_projection_sha256",
}
}
if common is not None and common != shared:
raise NativeBundleError("native rung immutable identities differ")
common = shared
files.extend(
f"{prefix}-{kind}.json" for kind in ("plan", "benchexec", "graphforge", "rung")
)
if scale >= 20:
files.append(f"{prefix}-projection.json")
results[result_path.name] = digest(result_path)
files.append(result_path.name)
assert common is not None
return {"commit": common["commit"], "scales": scales, "results": results, "files": files}


def validate_native_bundle(source: Path) -> dict[str, Any]:
receipt = native_receipts(source)
inventory = read_object(source / "work-root-inventory.json")
validate_schema(inventory, "host-work-root-inventory.json")
if inventory["result_sha256"] != receipt["results"]:
raise NativeBundleError("cleanup inventory belongs to different native results")
if inventory["empty"] != (inventory["entries"] == []):
raise NativeBundleError("cleanup inventory contradicts its entries")
receipt["files"].append("work-root-inventory.json")
receipt["empty"] = inventory["empty"]
receipt["complete"] = inventory["empty"] and receipt["scales"] == list(CANONICAL_RUNGS)
return receipt


def collect_inventory(work_root: Path, output_dir: Path | None = None) -> dict[str, Any]:
"""Inspect the whole work root, retaining only the named evidence directory.

Empty workspace/tmp scaffold directories are harmless. Every other entry
denotes debris, including an entire remaining subtree. We do not enumerate
dataset contents. No directory links are followed; unreadable scaffolding
fails rather than producing an empty inventory.
"""
work_root = work_root.resolve(strict=True)
evidence = output_dir.resolve(strict=True) if output_dir is not None else None
if evidence is not None and (evidence == work_root or work_root.is_relative_to(evidence)):
raise NativeBundleError("evidence directory must not contain the work root")
if evidence is not None and evidence.is_relative_to(work_root) and evidence.parent != work_root:
raise NativeBundleError("retained evidence must be a direct work-root child")
entries = []

def visit(directory: Path) -> None:
for path in sorted(directory.iterdir()):
if path == evidence and not path.is_symlink():
continue
if path.is_dir() and not path.is_symlink():
if path.parent == work_root and path.name in {"workspace", "tmp"}:
visit(path)
else:
entries.append(path.relative_to(work_root).as_posix())
else:
entries.append(path.relative_to(work_root).as_posix())

visit(work_root)
receipt = native_receipts(evidence) if evidence is not None else None
document = {
"schema": INVENTORY_SCHEMA,
"host_profile_id": HOST_PROFILE_ID,
"scope": "work_root_except_evidence_and_empty_scaffolding",
"retained_evidence_directory": evidence.name
if evidence is not None and evidence.parent == work_root
else None,
"result_sha256": receipt["results"] if receipt is not None else {},
"entries": entries,
"empty": entries == [],
}
validate_schema(document, "host-work-root-inventory.json")
return document
Loading
Loading