Files
rune/scripts/gen_layout_contract_truth.py
T
Nick 4bbed58d2c feat(layout_contract): close PARTIAL gaps — dichotomy wave-5
Audit 2/6 -> 6/6 FULL (RUST): the four audit-missing fns ported
name-preserving (define_region, bind_component, amend_layout_contract,
record_layout_observation) as pure doc-in/doc-out Rust kernels
(now is an argument — no-clock law; structural_store add_entity/entity
merge law replicated: high-water maturity, sorted-set evidence union,
identities key-level update, alias-following resolution).

Freeze rig scripts/lc_freeze_seams (PYTHONPATH auto-import, used by BOTH
generator and --verify): blanket RUNE_*_CORE=python + EXPLICIT
RUNE_LC_CORE/RUNE_STRUCTURAL_CORE pins (the blanket loop only pins vars
already in the env — an unpinned first re-freeze ran through live
delegation and CAUGHT the absorb divergence), frozen clock on both now
seams, DOC-CARRYING wrappers ({result, doc:{entities,observations}}),
errors frozen as {error: Type: message}.

Truth: 35-case frozen corpus (frozen_lc_gap_truth.json, envelope with
frozen_now) via the shared harness, embedded VERBATIM in gap_battery.rs;
regeneration byte-identical; freeze_truth --verify OK.

Real bugs the ladder caught (fixed pre-commit): (1) re-bind ASSIGNS a
fresh amendments ledger — insert-if-missing diverged from assignment
(live-facade smoke, discriminating frozen case added); (2) identities
merge is wholesale key assignment (add_entity .update() law — tech
reset on no-op re-define; recursive-merge absorb diverged, caught by the
parity LIVE layer); (3) bind_component has NO framework_attrs param —
framework detail rides **framework_attrs, dispatch collects unknown
kwargs; (4) serde_json preserve_order keeps observed-dict insertion
order (json insertion-order quirk).

FFI: lc_define_region/lc_bind_component/lc_amend_layout_contract/
lc_record_observation (doc-envelope) + lc_replay (raw replay surface).
Facade delegates with RuntimeError->ValueError translation and
identity-preserving absorb (lc_loader.absorb — returned entity IS the
stored one; aliasing survives round-trips).

Battery 10/10 (verbatim replay + FFI roundtrip + 6 branch proofs);
clippy -D warnings clean; parity 100% (35/35 frozen + byte-identical
live re-freeze); layout+consumer tests 64/64 BOTH pins. Full-suite
baseline failures pre-exist identically with/without this port
(coordinator-owned debt).
2026-10-14 06:20:13 +01:00

279 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""gen_layout_contract_truth.py — freeze the layout_contract gap truth
(define_region / bind_component / amend_layout_contract /
record_layout_observation) through the SHARED harness
(scripts/freeze_truth.py — one law).
The oracle fns mutate a doc argument and stamp observed_at through
structural_store.now, so this generator runs under the freeze rig
(scripts/lc_freeze_seams/sitecustomize.py): pinned RUNE_*_CORE=python
floors, frozen clock on both now seams, and DOC-CARRYING wrappers that
record {"result", "doc": {entities, observations}} — the Rust kernel is a
pure doc-in/doc-out membrane (the store stays with the facade), so every
case carries the full input doc in its args and replays in the battery
with no store. Errors freeze as {"error": "Type: message"}
(construction_decision convention). The input docs are LITERAL dicts that
match add_entity output exactly — built by hand here, deterministic by
construction (no store IO; this module has no file-IO surface).
Run (from the repo root):
PYTHONPATH=scripts/lc_freeze_seams:src \
python3 scripts/gen_layout_contract_truth.py
Verify (byte-identical, same rig):
PYTHONPATH=scripts/lc_freeze_seams:src \
python3 scripts/freeze_truth.py --verify \
src/rust/layout_contract/frozen_lc_gap_truth.json \
--module rune.layout_contract
Every ported function and branch is exercised:
define_region new (defaults / all kwargs), merge-update
(identities refresh, evidence union, maturity
high-water, tags union), empty evidence_refs
bind_component ui:-prefixing (both forms), unknown region,
lock/provenance law (2 rejections), re-bind merge
(amendments preserved, DRIFTING→ACTIVE, evidence
union), order/parent_of, framework_attrs
amend_layout_contract no contract, flexible amend (region/order),
ui:-prefixed, USER-LOCKED rejections (non-user
auth ×2, missing reason), authorized amend,
unlock (authorized + rejected), unknown region,
prior amendments append + reason[:200] truncation
record_layout_observation empty adapter, empty observed, prefix mix,
append to existing observations, empty obs dict
"""
import os
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_envelope # noqa: E402
import sitecustomize as rig # noqa: E402 (rig-bound: pinned cores + clock)
NOW = rig.FROZEN_NOW
OUT = Path(os.environ.get("LC_TRUTH_OUT")
or REPO / "src" / "rust" / "layout_contract" / "frozen_lc_gap_truth.json")
def new_doc():
return {"schema_version": 1, "generated_at": NOW,
"entities": [], "relationships": [], "observations": []}
# ── literal fixtures (match add_entity output exactly) ──────────────────────
def region(rid, **ids):
ident = {"parent": "", "orientation": "", "sizing": "",
"visibility": "", "provenance": "scaffold", "tech": {}}
ident.update(ids)
return {"id": f"region:{rid}", "kind": "layout_region",
"maturity": "DECLARED", "tags": [], "identities": ident,
"evidence_refs": ["region-defined:scaffold"],
"observed_at": NOW}
DOC_REGIONS = new_doc()
DOC_REGIONS["entities"] = [
region("header", orientation="horizontal", sizing="auto",
visibility="visible"),
region("sidebar", parent="header", order=1, orientation="vertical",
sizing="fill", visibility="visible", provenance="user",
tech={"tui": "pane"}),
{"id": "region:main", "kind": "layout_region", "maturity": "DECLARED",
"tags": [], "identities": {"parent": "", "orientation": "",
"sizing": "", "visibility": "",
"provenance": "scaffold", "tech": {}},
"evidence_refs": ["spec-layout"], "observed_at": NOW},
]
def contract(component, region_id, *, lock=False, provenance="scaffold",
order=None, anchor="", framework_attrs=None, status="ACTIVE",
evidence="layout-bind:scaffold", amendments=None,
last_violation=None):
ident = {"component": component, "region": region_id, "lock": lock,
"provenance": provenance, "anchor": anchor, "sizing": "",
"visibility": "", "implementation": "",
"framework_attrs": dict(framework_attrs or {})}
if order is not None:
ident["order"] = order
ext = {"amendments": amendments or []}
if last_violation is not None:
ext["last_violation"] = last_violation
return {"id": f"layout:{component}", "kind": "layout_contract",
"maturity": "DECLARED", "tags": [], "identities": ident,
"evidence_refs": [evidence], "observed_at": NOW,
"ext": ext, "status": status}
def with_contracts(**kw):
doc = new_doc()
doc["entities"] = list(DOC_REGIONS["entities"]) + [
contract("ui:version-info", "sidebar", lock=True, provenance="user",
order=1, anchor="top", evidence="issue-105", **kw),
contract("ui:status-bar", "main",
framework_attrs={"qt": "QStatusBar"})]
return doc
DOC_WITH_CONTRACTS = with_contracts()
DOC_DRIFTING = with_contracts(
status="DRIFTING",
last_violation={"at": NOW, "observed": {"region": "main"},
"reason": "region 'main' != required 'sidebar'"},
)
DOC_AMENDED = new_doc()
DOC_AMENDED["entities"] = list(DOC_REGIONS["entities"]) + [
contract("ui:version-info", "sidebar", lock=True, provenance="user",
order=1, anchor="top", evidence="issue-105",
amendments=[{"at": NOW, "authorized_by": "user",
"reason": "first move",
"evidence": "am-0",
"changes": {"anchor": "top"}}]),
contract("ui:status-bar", "main",
framework_attrs={"qt": "QStatusBar"}),
]
DOC_MATURE = new_doc()
_mature_sidebar = region("sidebar", parent="header")
_mature_sidebar["maturity"] = "WIRED"
_mature_sidebar["tags"] = ["layout"]
DOC_MATURE["entities"] = [
region("header"),
_mature_sidebar,
{"id": "region:main", "kind": "layout_region", "maturity": "DECLARED",
"tags": [], "identities": {"parent": "", "orientation": "",
"sizing": "", "visibility": "",
"provenance": "scaffold", "tech": {}},
"evidence_refs": ["spec-layout"], "observed_at": NOW},
]
DOC_WITH_OBS = new_doc()
DOC_WITH_OBS["observations"] = [
{"kind": "layout_observed", "component": "ui:footer",
"adapter": "prev", "observed": {"region": "main"},
"observed_at": NOW},
]
cases = [
# ── define_region: new entity, defaults ─────────────────────────────────
("define_region", (new_doc(), "header"), {}),
# all kwargs (tech dict, explicit provenance/evidence)
("define_region", (new_doc(), "sidebar"),
{"parent": "header", "order": 1, "orientation": "vertical",
"sizing": "fill", "visibility": "visible", "tech": {"tui": "pane"},
"provenance": "user", "evidence_refs": ["spec-11"]}),
# explicit empty evidence_refs mints the region-defined default too
# (Python `x or [default]` falsiness law)
("define_region", (new_doc(), "r-empty"),
{"evidence_refs": []}),
# unsorted evidence_refs freeze sorted
("define_region", (new_doc(), "multi"),
{"evidence_refs": ["b", "a", "c"]}),
# ── define_region: merge-update paths ───────────────────────────────────
# no-op re-define (identities overwritten with defaults, observed_at
# refreshed)
("define_region", (DOC_REGIONS, "sidebar"), {}),
# union merge: identities refresh + evidence union, order re-set
("define_region", (DOC_REGIONS, "sidebar"),
{"order": 2, "orientation": "horizontal", "evidence_refs": ["spec-12"]}),
# mature sidebar: maturity high-water (DECLARED does NOT downgrade
# WIRED), tags union (none added via this API)
("define_region", (DOC_MATURE, "sidebar"),
{"evidence_refs": ["fresh"]}),
# ── bind_component: new contracts ───────────────────────────────────────
# USER-LOCKED bind (lock + user provenance)
("bind_component", (DOC_REGIONS, "version-info", "sidebar"),
{"lock": True, "provenance": "user", "order": 1, "anchor": "top",
"evidence_ref": "issue-105"}),
# flexible bind, all defaults
("bind_component", (DOC_REGIONS, "status-bar", "main"), {}),
# ui:-prefixed component + open-world framework attrs (they ride the
# **framework_attrs catch-all — passed as bare kwargs, like real callers)
# + implementation
("bind_component", (DOC_REGIONS, "ui:footer", "main"),
{"sizing": "1-line", "visibility": "always",
"implementation": "src/ui/footer.py",
"css": "flex", "qt": "QStatusBar"}),
# parent_of + order on a bare name
("bind_component", (DOC_REGIONS, "panel", "sidebar"),
{"parent_of": "ui:version-info", "order": 2}),
# ── bind_component: rejections (the lock/provenance law) ────────────────
("bind_component", (DOC_REGIONS, "x", "nope"), {}),
("bind_component", (DOC_REGIONS, "x", "sidebar"), {"lock": True}),
("bind_component", (DOC_REGIONS, "x", "sidebar"),
{"lock": True, "provenance": "builder"}),
# ── bind_component: re-bind merges ──────────────────────────────────────
# identities refresh (anchor), ACTIVE kept; the amendments ledger is
# RESET by re-binding (fresh binding — the oracle assigns [], not
# appends)
("bind_component", (DOC_WITH_CONTRACTS, "version-info", "sidebar"),
{"lock": True, "provenance": "user", "order": 1, "anchor": "top-left",
"evidence_ref": "rebind-1"}),
# re-bind over a NON-EMPTY amendments ledger: cleared (the
# discriminating case — empty-ledger re-binds can't tell)
("bind_component", (DOC_AMENDED, "version-info", "sidebar"),
{"lock": True, "provenance": "user", "order": 1, "anchor": "top"}),
# DRIFTING contract re-bound returns to ACTIVE
("bind_component", (DOC_DRIFTING, "version-info", "sidebar"),
{"lock": True, "provenance": "user", "order": 1, "anchor": "top"}),
# ui:-prefixed re-bind: region change + evidence union
("bind_component", (DOC_WITH_CONTRACTS, "ui:status-bar", "sidebar"),
{"evidence_ref": "move-1"}),
# ── amend_layout_contract: rejections ───────────────────────────────────
("amend_layout_contract", (new_doc(), "version-info"), {}),
("amend_layout_contract", (DOC_WITH_CONTRACTS, "version-info"),
{"new_region": "main"}),
("amend_layout_contract", (DOC_WITH_CONTRACTS, "version-info"),
{"authorized_by": "model"}),
("amend_layout_contract", (DOC_WITH_CONTRACTS, "version-info"),
{"authorized_by": "user"}),
("amend_layout_contract", (DOC_WITH_CONTRACTS, "version-info"),
{"unlock": True, "authorized_by": "user"}),
("amend_layout_contract", (DOC_WITH_CONTRACTS, "status-bar"),
{"unlock": True}),
("amend_layout_contract", (DOC_WITH_CONTRACTS, "status-bar"),
{"new_region": "nope"}),
# ── amend_layout_contract: mutations ────────────────────────────────────
# flexible builder amend (region + order + evidence)
("amend_layout_contract", (DOC_WITH_CONTRACTS, "status-bar"),
{"new_region": "sidebar", "new_order": 0, "authorized_by": "builder",
"reason": "reorganize", "evidence_ref": "am-1"}),
# ui:-prefixed component, order-only amend
("amend_layout_contract", (DOC_WITH_CONTRACTS, "ui:status-bar"),
{"new_order": 3}),
# authorized USER-LOCKED amend
("amend_layout_contract", (DOC_WITH_CONTRACTS, "version-info"),
{"new_region": "main", "authorized_by": "user",
"reason": "user wants it in main"}),
# authorized unlock
("amend_layout_contract", (DOC_WITH_CONTRACTS, "version-info"),
{"unlock": True, "authorized_by": "user", "reason": "free it"}),
# append to a prior amendments ledger + reason[:200] truncation
("amend_layout_contract", (DOC_AMENDED, "version-info"),
{"new_order": 5, "authorized_by": "user", "reason": "R" * 300,
"evidence_ref": "am-2"}),
# ── record_layout_observation ───────────────────────────────────────────
("record_layout_observation", (new_doc(), "", {}), {}),
("record_layout_observation", (new_doc(), "qt-adapter", {}), {}),
# prefix mix (bare, ui:-prefixed, new) + multi-field obs
("record_layout_observation",
(new_doc(), "tui",
{"version-info": {"region": "sidebar", "order": 1},
"ui:status-bar": {"region": "main"},
"footer": {"region": "main", "parent": "header"}}), {}),
# append to existing observations
("record_layout_observation",
(DOC_WITH_OBS, "tui", {"version-info": {"region": "main"}}), {}),
# empty obs dict passthrough
("record_layout_observation", (new_doc(), "web-dom", {"x": {}}), {}),
]
truth = freeze("rune.layout_contract", cases,
oracle_module="rune.layout_contract")
write_envelope(NOW, truth, OUT)
print(f"froze {len(truth)} cases -> {OUT}")