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).
304 lines
16 KiB
Python
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))
|