Files
rune/scripts/gen_construction_interface_truth.py
T
Nick 192c63b36e feat(construction_interface): close PARTIAL gaps — dichotomy wave
Audit 25/27 → 27/27 FULL (main + _programme_continuation were the two
unmatched fns; the port carries the full envelope surface). Freeze rig
scripts/ci_freeze_seams/sitecustomize.py (PYTHONPATH auto-import, used by
BOTH generator and --verify): every RUNE_*_CORE gate pinned python for
the whole dependency cone, frozen clock on structural_store.now +
scaffold.now + capability_ledger._now + programme_continuation.time,
deterministic uuid mint (counter resets per rig helper), hermetic
per-case stores under CI_FREEZE_HOME (mini-doc paths replay
byte-identically), doc-carrying seam bindings for every stateful method.

Truth: 85-case frozen corpus + 5-case hash corpus (obligation ids carry
Python's process-randomized str hash — captured with PYTHONHASHSEED=0,
SHAPE-pinned downstream, the memory_consolidation law). Regeneration
byte-identical; freeze_truth --verify OK both corpora.

Rust kernels (src/rust/construction_interface): kernel.rs adds the
doc-in/doc-out halves of submit_need (need assembly + envelope over the
construction_decision make_decision kernel + contract generation twin),
verify (scope check + layout gate via the layout_contract kernel),
transition (guard canary over frozen command outcomes + legality map +
checkpoint/session assembly + normalize_sorted commit twin),
close (close_contract + observed-impact + close_quality bucket math +
contract_quality projection), _programme_continuation (load/save shape
twins + continuation canary), _auto_material_change (via the
capability_ledger op_material_change kernel), main (CLI dispatch + exit
law), ladder_walk (full ladder in ONE process); projection.rs the pure
helpers (to_stage_check, guard_specs, obligations projection with the
FNV-1a stand-in id, envelope with extra merge, _match).

Store-normalization law discovered: the oracle's commit path sorts
lists by canonical JSON (structural_store._sorted) — the kernel applies
the same normalization at its commit points or read-back projections
(patterns_considered) diverge.

Battery: 25 tests — the 85-case corpus replays VERBATIM through
kernel::dispatch, the 5 hash cases shape-pinned, gap-fns-are-real-ports
probe. clippy --all-targets -D warnings 0. Parity
scripts/check_construction_interface_parity.py: FROZEN layer 85/85 + 5
through the ci_replay ctypes FFI of the built cdylib; LIVE layer
fresh re-freeze byte-identical. Python 37/37 both pins (floors pinned
python + live cores).
2026-10-13 19:03:37 +01:00

304 lines
16 KiB
Python

#!/usr/bin/env python3
"""Freeze the dichotomy-wave gap truth for src/rune/construction_interface
through the SHARED harness (scripts/freeze_truth.py — one law).
The oracle is a stateful facade (ConstructionInterface over a Scaffold
store) with clock/uuid nondeterminism, so this generator runs under the
freeze rig (scripts/ci_freeze_seams/sitecustomize.py):
pinned RUNE_*_CORE=python floors, frozen clock, deterministic uuid mint,
hermetic per-case stores (deterministic per-case dirs — envelopes that
carry paths, like mini_doc, replay byte-identically), and DOC-CARRYING
seam bindings the shared harness can getattr: the Rust kernel is a pure
doc-in/doc-out membrane, so every stateful case carries the full input
doc in its args and replays in the battery with no store.
Run (from the repo root):
rm -rf /tmp/ci_gap_freeze_home
CI_FREEZE_HOME=/tmp/ci_gap_freeze_home \
PYTHONPATH=scripts/ci_freeze_seams:src \
python3 scripts/gen_construction_interface_truth.py
Verify (byte-identical, same rig):
CI_FREEZE_HOME=/tmp/ci_gap_freeze_home \
PYTHONPATH=scripts/ci_freeze_seams:src \
python3 scripts/freeze_truth.py --verify \
src/rust/construction_interface/frozen_ci_truth.json \
--module rune.construction_interface
Every public function and branch is exercised. The obligation-id seam
(_obligations_projection carries process-randomized str hash) lives in
the SEPARATE frozen_ci_truth_hash.json battery (captured + verified with
PYTHONHASHSEED=0) and is SHAPE-pinned downstream — never value-frozen
here.
"""
import os
import subprocess
import sys
from pathlib import Path
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "scripts"))
from freeze_truth import freeze, write # noqa: E402
import sitecustomize as rig # noqa: E402
# ── deterministic input docs (builder helpers; NOT frozen fns) ──
DOC0 = rig.build_doc() # fixture authority, no contract
DOC_SUBMITTED = rig.submit_doc("b-submitted", rig.build_doc())
DOC_WALKED = rig.walk_doc("b-walked", rig.build_doc())
DOC_WITH_LEDGER_CAPS = rig.build_ledger_caps()
PROGRAMMES_BOUND = [{
"programme_id": "prog-gap-ci", "objective": "close the gap",
"stages": [
{"stage_id": rig._submitted_cid(DOC_SUBMITTED),
"objective": "the gap stage"},
{"stage_id": "next-stage", "objective": "the next stage"},
],
}]
GUARD_FAIL = [{"name": "always-fail", "kind": "command", "argv": ["false"]}]
GUARD_PASS = [{"name": "always-pass", "kind": "command", "argv": ["true"]}]
GUARD_ASSERT = [{"name": "truthy", "kind": "assert",
"description": "always true"}]
cases = [
# ── _envelope: success + failure shapes, extra keys ──
("_envelope", ("op",), {"success": True}),
("_envelope", ("op",), {"success": False,
"errors": [{"error": "X"}],
"warnings": [{"warning": "W"}],
"ids": {"a": "b"}, "state": {"k": 1},
"extra": {"extra_key": "extra"}}),
# ── _to_stage_check: full spec, defaults ──
("ci_to_stage_check", ({"name": "g", "kind": "command",
"argv": ["true"], "output_pattern": "ok",
"path": "/x", "description": "d"},), {}),
("ci_to_stage_check", ({},), {}),
# ── _guard_specs_from_obligations: guard rows, junk, bad JSON ──
("_guard_specs_from_obligations",
({"identities": {"verification_obligations": [
'guard:{"name": "g1", "kind": "command", "argv": ["true"]}',
"free-text obligation",
"guard:not-json{{{",
'["not", "a", "dict"]',
'guard:{"name": "g2"}',
]}},), {}),
("_guard_specs_from_obligations", ({},), {}),
# ── t_layout: present + absent ──
("t_layout", ({"decision_trace": {"layout_obligations": [
{"component": "c", "obligation": "o"}]}},), {}),
("t_layout", ({},), {}),
# ── _obligations_projection: synthetic hash-free fixtures (empty,
# pattern-only, layout-only — the contract/structural id branches
# carry process-randomized hash → hash battery) ──
("_obligations_projection", ({},), {}),
("_obligations_projection",
({"ext": {"decision_trace": {"obligations": {"pattern": [
{"id": "pat-1", "pattern": "seed_loop", "revision": 3,
"obligation": "keep the seed loop closed", "verdict": "SATISFIED",
"reason": "evidence row 1", "pattern_applicability": "always"}]}}}},),
{}),
("_obligations_projection",
({"ext": {"decision_trace": {"layout_obligations": [
{"component": "ui:header", "obligation": "stay in region top",
"verification": "adapter observation"}]}}},), {}),
# ── _obligation_scope_files: passthrough stub ──
("_obligation_scope_files", ([{"id": "x"}],), {}),
("_obligation_scope_files", ([],), {}),
# ── _authorities: external mode, rune-internal w/ + w/o spine ──
("_authorities", (rig.build_doc(),), {}),
("_authorities", (rig.build_doc(), {"schema_version": 1,
"entities": []}),
{"mode": "rune_internal"}),
("_authorities", (rig.build_doc(), None), {"mode": "rune_internal"}),
# ── _record_session: append + long-detail truncation ──
("_record_session", (rig.build_doc(), "submit_need", "short detail"), {}),
("_record_session", (rig.build_doc(), "close", "d" * 500), {}),
# ── classify: envelope assembly over classifier results ──
("classify", ({"mode": "UNKNOWN", "evidence": ["probe: which surface?"],
"probe_questions": ["q1"]},), {}),
("classify", ({"mode": "EXISTING_PROJECT_CHANGE", "evidence": ["e1"],
"probe_questions": []},), {}),
("classify", ({"mode": "LOCAL_CHANGE"},),
{"builder": "other-builder"}),
# ── construction_context: none active, explicit unknown id (the
# ACTIVE projection carries obligation ids → hash battery) ──
("construction_context", ("cc-none", rig.build_doc()), {}),
("construction_context", ("cc-unknown", DOC_SUBMITTED, "NOPE"), {}),
# ── capabilities: the full discovery envelope, both modes ──
("capabilities", (), {"mode": "external_project"}),
("capabilities", (), {"mode": "rune_internal",
"project": "issue161-harness"}),
# ── submit_need: happy, empty objective, MATERIAL_GAP, approval,
# no-generate, custom contract id, task_ref ──
("submit_need", ("sn-ok", rig.build_doc(), "persistent project export"), {}),
("submit_need", ("sn-empty", rig.build_doc(), ""), {}),
("submit_need", ("sn-gap", rig.build_doc(),
"change the exporter widget colors"),
{"affected_surface": ["capability:exporter"], "constraints": {},
"evidence_refs": ["x"]}),
("submit_need", ("sn-appr", rig.build_doc(),
"start a brand new repository for billing"),
{"constraints": {"new_repository": True}, "evidence_refs": ["x"]}),
("submit_need", ("sn-nogen", rig.build_doc(), "persistent project export"),
{"generate": False}),
("submit_need", ("sn-cid", rig.build_doc(), "persistent project export"),
{"contract_id": "MY-CID"}),
("submit_need", ("sn-task", rig.build_doc(), "persistent project export"),
{"task_ref": "task-1"}),
# ── inspect_decision: ok + unknown ──
("inspect_decision", ("in-ok", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED)), {}),
("inspect_decision", ("in-no", DOC_SUBMITTED, "NOPE"), {}),
# ── get_scope: ok + unknown ──
("get_scope", ("gs-ok", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED)), {}),
("get_scope", ("gs-no", DOC_SUBMITTED, "NOPE"), {}),
# ── get_obligations: unknown (ok carries hash ids → hash battery) ──
("get_obligations", ("go-no", DOC_SUBMITTED, "NOPE"), {}),
# ── report_observation: ok, bare-dict, missing entity, unknown ──
("report_observation", ("ro-ok", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED),
[{"entity": "contract:csv_export",
"detail": "observed while building"}]), {}),
("report_observation", ("ro-bare", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED),
{"entity": "x"}), {}),
("report_observation", ("ro-noent", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED),
[{"detail": "x"}]), {}),
("report_observation", ("ro-no", DOC_SUBMITTED, "NOPE",
[{"entity": "x"}]), {}),
# ── verify: unknown, scope unknown/green/red, layout PASS/FAIL/UNKNOWN,
# walked-contract contract-quality projection ──
("verify", ("vf-no", DOC_SUBMITTED, "NOPE"), {}),
("verify", ("vf-base", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED)), {}),
("verify", ("vf-green", DOC_SUBMITTED, rig._submitted_cid(DOC_SUBMITTED)),
{"changed_files": ["src/allowed.py"]}),
("verify", ("vf-red", DOC_SUBMITTED, rig._submitted_cid(DOC_SUBMITTED)),
{"changed_files": ["src/evil.py"]}),
("verify", ("vf-pass", DOC_SUBMITTED, rig._submitted_cid(DOC_SUBMITTED)),
{"layout_observations": {"components": []}}),
("verify", ("vf-fail", DOC_SUBMITTED, rig._submitted_cid(DOC_SUBMITTED)),
{"layout_observations": {"header": {"region": "bottom"}}}),
("verify", ("vf-unk", DOC_SUBMITTED, rig._submitted_cid(DOC_SUBMITTED)),
{"layout_observations": {"header": {"region": "top"}}}),
# ── transition: happy edge, illegal edge, unknown, guard block/pass ──
("transition", ("tr-appr", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED), "approved"), {}),
("transition", ("tr-ill", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED), "closed"), {}),
("transition", ("tr-no", DOC_SUBMITTED, "NOPE", "approved"), {}),
("transition", ("tr-block", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED), "approved"),
{"guard_checks": GUARD_FAIL}),
("transition", ("tr-pass", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED), "approved"),
{"guard_checks": GUARD_PASS}),
("transition", ("tr-assert", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED), "approved"),
{"guard_checks": GUARD_ASSERT}),
# ── close: full ladder doc, unknown, custom scope files ──
("close", ("cl-ok", DOC_WALKED, rig._submitted_cid(DOC_WALKED),
[{"kind": "port_evidence", "detail": "gap closed"}]), {}),
("close", ("cl-scope", DOC_WALKED, rig._submitted_cid(DOC_WALKED),
[{"kind": "port_evidence", "detail": "gap closed"}]),
{"scope_files": ["src/export.py"]}),
("close", ("cl-no", DOC_WALKED, "NOPE", [{"entity": "x"}]), {}),
# ── _programme_continuation: bound, unbound stage, no programme dir ──
("_programme_continuation",
("pc-hit", DOC_SUBMITTED, rig._submitted_cid(DOC_SUBMITTED)),
{"programmes": PROGRAMMES_BOUND}),
("_programme_continuation",
("pc-miss", DOC_SUBMITTED, "other-stage"),
{"programmes": PROGRAMMES_BOUND}),
("_programme_continuation",
("pc-none", DOC_SUBMITTED, rig._submitted_cid(DOC_SUBMITTED)), {}),
# ── _auto_material_change: hit, miss, no ledger ──
("_auto_material_change",
("mc-hit", DOC_SUBMITTED, ["src/export.py"]),
{"capabilities": DOC_WITH_LEDGER_CAPS}),
("_auto_material_change",
("mc-miss", DOC_SUBMITTED, ["src/zzz.py"]),
{"capabilities": DOC_WITH_LEDGER_CAPS}),
("_auto_material_change",
("mc-nol", DOC_SUBMITTED, ["src/export.py"]), {}),
# ── discover_active_contract: seeded store, empty store ──
("discover_active_contract", ("dc-seed",
[{"project": "alpha", "doc": rig._discover_doc("old", "2026-10-01T00:00:00Z", "alpha")},
{"project": None, "doc": rig._discover_doc("main-latest", "2026-10-03T00:00:00Z", "gamma")}]),
{}),
("discover_active_contract", ("dc-empty", []), {}),
# ── resume: unknown (ok carries hash ids → hash battery) ──
("resume", ("rs-no", DOC_SUBMITTED, "NOPE"), {}),
# ── amend_scope: ok, non-user, unknown ──
("amend_scope", ("am-ok", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED), ["src/a.py"]),
{"reason": "user asked"}),
("amend_scope", ("am-nouser", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED), ["src/a.py"]),
{"reason": "x", "authority": "builder"}),
("amend_scope", ("am-no", DOC_SUBMITTED, "NOPE", ["a"]),
{"reason": "x"}),
# ── main: every CLI command ──
("main", ("m-help",), {"argv": ["--help"]}),
("main", ("m-unk",), {"argv": ["frobnicate"]}),
("main", ("m-caps",), {"argv": ["capabilities"]}),
("main", ("m-cls",), {"argv": ["classify",
'{"objective": "fix typo"}']}),
("main", ("m-ctx",), {"argv": ["context"]}),
("main", ("m-sub",), {"argv": ["submit-need",
'{"objective": "x"}']}),
("main", ("m-dec",), {"argv": ["decision", "NOPE"]}),
("main", ("m-scope",), {"argv": ["scope", "NOPE"]}),
("main", ("m-obl",), {"argv": ["obligations", "NOPE"]}),
("main", ("m-obs",), {"argv": ["observe", "NOPE", "[]"]}),
("main", ("m-ver",), {"argv": ["verify", "NOPE"]}),
("main", ("m-tr",), {"argv": ["transition", "NOPE", "approved"]}),
("main", ("m-close",), {"argv": ["close", "NOPE", "[]"]}),
("main", ("m-res",), {"argv": ["resume", "NOPE"]}),
# ── the FULL ladder in ONE process (shared-store clobber law) ──
("ladder_walk", ("walk1",), {}),
("ladder_walk", ("walk2", "start a brand new repository for billing"), {}),
]
truth = freeze("rune.construction_interface", cases,
oracle_module="rune.construction_interface")
write(truth, REPO / "src" / "rust" / "construction_interface"
/ "frozen_ci_truth.json")
print(f"froze {len(truth)} cases")
# ── §2 hash battery: every envelope carrying obligation ids. Captured +
# verified with PYTHONHASHSEED=0 (set at INTERPRETER start — the seed
# cannot be changed mid-process, so the main run re-execs itself for
# this part); the Rust battery SHAPE-pins these ids (prefix before ":",
# stable description/kind/provenance/status) — never value-freezes the
# randomized suffix. ──
HASH_CASES = [
("_obligations_projection", (rig.contract_of(DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED)),), {}),
("construction_context", ("hc-active", DOC_SUBMITTED), {}),
("construction_context", ("hc-explicit", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED)), {}),
("get_obligations", ("ho-ok", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED)), {}),
("resume", ("hr-ok", DOC_SUBMITTED,
rig._submitted_cid(DOC_SUBMITTED)), {}),
]
if os.environ.get("CI_GEN_HASH_ONLY") == "1":
assert os.environ.get("PYTHONHASHSEED") == "0", \
"hash battery requires PYTHONHASHSEED=0 at interpreter start"
hash_truth = freeze("rune.construction_interface", HASH_CASES,
oracle_module="rune.construction_interface")
write(hash_truth, REPO / "src" / "rust" / "construction_interface"
/ "frozen_ci_truth_hash.json")
print(f"froze {len(hash_truth)} hash cases (PYTHONHASHSEED=0)")
else:
env = dict(os.environ, PYTHONHASHSEED="0", CI_GEN_HASH_ONLY="1",
PYTHONPATH="scripts/ci_freeze_seams:src")
subprocess.run([sys.executable, str(Path(__file__).resolve())],
check=True, env=env, cwd=str(REPO))