Files
rune/scripts/gen_construction_pattern_truth.py
Nick 2c273574a4 feat(construction_pattern): close PARTIAL gaps to FULL — dichotomy wave
Audit PARTIAL 7/13 -> FULL 13/13 (headline 74/192, fn 1358/2278).

Ported: _need_dict (FFI need envelope, wired into cp_evaluate/cp_derive),
_surface_text (evidence token union, set semantics). Renamed to exact
Python names per the name-preserving law: _path_matches, _entity_matches,
_obligation_when_hit (were path_matches/entity_matches/obligation_when_hit)
and the evaluate_applicability _check closure — same bodies, exact names;
precedent: structural_store _sorted/_ss_core, construction_decision _sc_core.

Truth: frozen_cp_truth.json 70->96 cases (path_match/entity_match/
need_dict/surface_text/when_hit families, incl. re.split empty-quirk and
truthy-not-True always cases); harness surface frozen_truth.json 18 cases
(from_dict/revise stay in the bespoke battery — bare instances are not
harness-serializable). Battery 14 tests replay all 96 VERBATIM.

Verification (verification/summary.md, all exit 0): battery 14/14, clippy
0 warnings, harness verify 18/18, live parity 192/192 both pins (new
check_construction_pattern_parity.py; class ops via cp_loader under the
kernel pin), pytest 30/30 module + 20/20 consumers under
RUNE_CP_CORE=python and auto.
2026-10-13 18:30:24 +01:00

487 lines
25 KiB
Python

#!/usr/bin/env python3
"""Freeze construction_pattern oracle truth for the Rust port battery
(dichotomy wave #2479 tranche, batch: construction_pattern).
Exercises EVERY public function and branch of
src/rune/construction_pattern.py:
ConstructionPattern.__init__ (defaults, sorting, ext, all validation errors)
ConstructionPattern.to_dict / from_dict (roundtrip incl. ext)
ConstructionPattern.revise (changes, history accumulation, 200-char
reason truncation, sorted evidence/changed)
record_pattern_proposal (bounds errors, evidence sorting, 0/1 bounds)
evaluate_applicability (exclusions by objective-substring and by
constraint membership, first-match-wins,
no-signals UNKNOWN, no-groups UNKNOWN,
surface_kinds via surface lists AND via
resolutions, short-token vs containment path
and entity matching, ':'-prefix entities,
objective_any '/' splitting (dashes NOT
split), contracts_match via authorities
(implements/exposes/provides/serves),
APPLIES / PARTIAL / DOES_NOT_APPLY,
evidence [:5] truncation)
derive_pattern_obligations (when None, always True vs truthy-not-True,
path_contains hit/miss + [:3] truncation,
entities_match via paths/ui/regions,
contracts_touched via need constraints and
via authority relationships, unrecognized
shapes, EXCEPTED with defaults,
accepted/rejected/unresolved routing)
combine_pattern_obligations (duplicate collapse + also_from, same-id
different-text conflicts, id sort, empty)
_need_dict (envelope shape: objective/affected_surface/
constraints only — extras dropped)
_surface_text (5 surface lists + affected_surface +
objective / and - word tokens, deduped)
_path_matches / _entity_matches (boundary discipline: short tokens,
containment, ':' prefixes, empty-signal
re.split leading/trailing-empty quirks)
_obligation_when_hit (every when shape incl. truthy-not-True
always, path [:3] truncation, contracts via
need constraints and authorities,
unrecognized shapes, empty when dict)
Each case records its INPUT and the oracle's EXPECTED output/error; replayed
VERBATIM by src/rust/construction_pattern/src/branch_battery.rs.
Output: src/rust/construction_pattern/src/frozen_cp_truth.json
"""
from __future__ import annotations
import json
import os
import sys
from pathlib import Path
os.environ["RUNE_CP_CORE"] = "python" # POISONED-TRUTH LAW: freeze the ORACLE
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from rune import construction_pattern as cp # noqa: E402
OUT = Path(__file__).resolve().parents[1] / "src" / "rust" / "construction_pattern" / "src" / "frozen_cp_truth.json"
cases = []
def need(objective="repair the deploy promotion ordering",
affected_surface=("scripts/deploy_stage.py", "scripts/deploy_promotion.py"),
constraints=None):
class N:
pass
n = N()
n.objective = objective
n.affected_surface = list(affected_surface)
n.constraints = dict(constraints if constraints is not None else {"contracts": ["contract:monotonic_promotion"]})
return n
def serialize_need(n):
return {"objective": n.objective, "affected_surface": n.affected_surface, "constraints": n.constraints}
SPINE = {
"entities": [
{"id": "module:deploy_stage", "kind": "module"},
{"id": "contract:monotonic_promotion", "kind": "contract"},
{"id": "module:deploy_qualify", "kind": "module"},
{"id": "contract:fail_closed_deployment", "kind": "contract"},
],
"relationships": [
{"type": "implements", "from": "module:deploy_stage", "to": "contract:monotonic_promotion"},
{"type": "exposes", "from": "module:deploy_stage", "to": "contract:exposed_api"},
{"type": "serves", "from": "module:deploy_stage", "to": "contract:served_edge"},
{"type": "implements", "from": "module:deploy_qualify", "to": "contract:fail_closed_deployment"},
{"type": "provides", "from": "module:deploy_qualify", "to": "contract:provided_gate"},
{"type": "serves", "from": "module:deploy_qualify", "to": "contract:second_edge"},
{"type": "depends_on", "from": "module:deploy_stage", "to": "module:deploy_qualify"},
],
}
AUTH = {"rune_spine": SPINE}
SURFACE = {
"affected_paths": [
"scripts/deploy_stage.py", "scripts/deploy_promotion.py",
"src/rune/rune_tui.py", "src/rune/builtin.py",
],
"affected_existing_entities": ["module:deploy_stage", "module:deploy_qualify", "ui:chat"],
"affected_ui_surfaces": ["ui:version_display"],
"affected_regions": ["region:left"],
"workflow_config_surfaces": [".gitea/workflows/deploy.yml"],
"resolutions": [
{"id": "module:deploy_stage", "kind": "source_path", "verdict": "FOUND"},
{"id": "ui:version_display", "kind": "ui_component", "verdict": "FOUND"},
{"id": "region:left", "kind": "layout_region", "verdict": "FOUND"},
{"id": "cfg:deploy", "kind": "workflow_config", "verdict": "FOUND"},
{"id": "module:deploy_stage", "kind": "structural_entity", "verdict": "FOUND"},
],
}
def case(name, op, inp, fn):
import copy as _copy
# Deep-copy the input BEFORE running the oracle: to_dict() shares
# nested references (ext) with the live object, and revise() mutates
# revision_history in place — without the copy the recorded input
# aliases oracle-mutated state.
inp = _copy.deepcopy(inp)
try:
expected = fn()
except ValueError as e:
expected = {"error": str(e)}
cases.append({"name": name, "op": op, "input": inp, "expected": expected})
# ── ConstructionPattern.__init__ / to_dict / from_dict ──────────────────────
FULL_KW = dict(
revision=3, maturity="EXERCISED",
signals={"path_contains": ["deploy"], "objective_any": ["promotion"]},
obligations=[
{"id": "o2", "obligation": "second duty", "when": {"always": True}},
{"id": "o1", "obligation": "first duty", "when": {"path_contains": ["deploy"]}},
],
provenance=["incident:zeta", "incident:alpha"],
exclusions=["queue-only-project", "no-deploy-zone"],
toolchain_notes=["zinc", "amber"],
runtime_effects=["r2", "r1"],
)
def construct_case(name, kwargs):
case(name, "construct", {"kwargs": kwargs},
lambda: cp.ConstructionPattern.from_dict(kwargs).to_dict())
construct_case("construct-full", {"pattern_id": "p.full", "purpose": "full pattern",
"wibble": "future-data", **FULL_KW})
construct_case("construct-minimal", {"pattern_id": "p.min", "purpose": "minimal pattern"})
construct_case("construct-ext-open-world", {"pattern_id": "p.ext", "purpose": "open world",
"wibble": "future-data", "count": 7})
construct_case("construct-empty-id", {"pattern_id": "", "purpose": "purpose"})
construct_case("construct-empty-purpose", {"pattern_id": "p", "purpose": ""})
construct_case("construct-obl-missing-id",
{"pattern_id": "p", "purpose": "purpose",
"obligations": [{"obligation": "x", "when": {}}]})
construct_case("construct-obl-missing-text",
{"pattern_id": "p", "purpose": "purpose", "obligations": [{"id": "x", "when": {}}]})
construct_case("construct-obl-missing-when",
{"pattern_id": "p", "purpose": "purpose", "obligations": [{"id": "x", "obligation": "x"}]})
construct_case("construct-from-dict-roundtrip",
cp.ConstructionPattern("p.rt", "roundtrip", wibble={"deep": [1, 2]}, **FULL_KW).to_dict())
# ── revise ───────────────────────────────────────────────────────────────────
REV_BASE = dict(revision=2, maturity="UNIT-PROVEN",
provenance=["contract:c9"], exclusions=["b-ex", "a-ex"])
def revise_case(name, base_kwargs, reason, evidence, changes, ext=None):
base = cp.ConstructionPattern("p.rev", "revisable", **(ext or {}), **base_kwargs)
case(name, "revise",
{"pattern": base.to_dict(), "reason": reason, "evidence": evidence, "changes": changes},
lambda: base.revise(reason=reason, evidence=evidence, changes=changes).to_dict())
revise_case("revise-with-changes", REV_BASE, "new incident evidence",
["z-evidence", "a-evidence"], {"maturity": "EXERCISED"})
revise_case("revise-history-accumulates", {"revision": 2, "revision_history": [
{"prior_revision": 1, "reason": "initial correction", "evidence": ["old-evidence"], "changed": ["signals"]}]},
"second revision", ["new-evidence"], {})
revise_case("revise-reason-truncated-200", {}, "r" * 250, ["e"], None)
revise_case("revise-open-world-ext-carried", {}, "carries ext", ["e"], {"purpose": "revised purpose"},
ext={"wibble": "kept"})
# ── record_pattern_proposal ─────────────────────────────────────────────────
def propose_case(name, pattern_id="x", provider="p", model="m", evidence=(), confidence=0.5):
case(name, "propose",
{"pattern_id": pattern_id, "provider": provider, "model": model,
"evidence": list(evidence), "confidence": confidence},
lambda: cp.record_pattern_proposal(pattern_id, provider=provider, model=model,
evidence=list(evidence), confidence=confidence))
propose_case("propose-valid", pattern_id="some-pattern", provider="local", model="m1",
evidence=["z-hunch", "a-hunch"], confidence=0.5)
case("propose-bounds-zero-one", "propose",
{"pattern_id": "x", "provider": "p", "model": "m", "evidence": [], "confidence": [0.0, 1.0]},
lambda: [cp.record_pattern_proposal("x", provider="p", model="m", evidence=[], confidence=0.0),
cp.record_pattern_proposal("x", provider="p", model="m", evidence=[], confidence=1.0)])
propose_case("propose-empty-provider", provider="")
propose_case("propose-empty-model", model="")
propose_case("propose-confidence-above-1", confidence=1.5)
propose_case("propose-confidence-below-0", confidence=-0.1)
# ── evaluate_applicability ──────────────────────────────────────────────────
def eval_case(name, pattern_kwargs, n=None, surface=None, authorities=None):
p = cp.ConstructionPattern("p.eval", "evaluated pattern", **pattern_kwargs)
nn = n or need()
s = surface or SURFACE
a = authorities or AUTH
case(name, "evaluate",
{"pattern": p.to_dict(), "need": serialize_need(nn), "surface_result": s, "authorities": a},
lambda: cp.evaluate_applicability(p, nn, s, a))
eval_case("eval-all-groups-applies",
{"signals": {"surface_kinds": ["source_path", "ui_component", "layout_region",
"workflow_config", "structural_entity"],
"path_contains": ["deploy"], "entities_match": ["module:"],
"objective_any": ["promotion"],
"contracts_match": ["contract:monotonic_promotion"]}})
eval_case("eval-partial",
{"signals": {"path_contains": ["deploy"], "entities_match": ["nope-never", "zzz"],
"objective_any": ["zzzneverword"]}})
eval_case("eval-none-declared-does-not-apply",
{"signals": {"path_contains": ["/nonexistent/xyz/"], "objective_any": ["zzznever"]}})
eval_case("eval-no-signals-unknown", {})
eval_case("eval-no-groups-declared-unknown", {"signals": {"surface_kinds": [], "path_contains": []}})
eval_case("eval-exclusion-objective-substring",
{"signals": {"path_contains": ["deploy"]}, "exclusions": ["no deployment system in this project"]})
eval_case("eval-exclusion-constraint-membership",
{"signals": {"path_contains": ["deploy"]}, "exclusions": ["message-queue-only"]},
n=need(constraints={"contracts": [], "pattern_exclusions": ["message-queue-only"]}))
eval_case("eval-exclusion-first-match-wins",
{"signals": {"path_contains": ["deploy"]},
"exclusions": ["no deployment system in this project", "message-queue-only"]},
n=need(constraints={"contracts": [], "pattern_exclusions": ["message-queue-only"]}))
eval_case("eval-exclusion-declared-but-unmatched",
{"signals": {"path_contains": ["deploy"]}, "exclusions": ["totally-unrelated-exclusion"]},
n=need(constraints={"contracts": [], "pattern_exclusions": ["another-unrelated"]}))
eval_case("eval-surface-kinds-via-resolutions",
{"signals": {"surface_kinds": ["structural_entity", "nope_kind"]}})
eval_case("eval-path-short-token",
{"signals": {"path_contains": ["ui", "tui", "cfg", "deploy"]}})
eval_case("eval-entity-prefix-and-tokens",
{"signals": {"entities_match": ["ui:", "module:", "ui", "spine", "zzz"]}})
eval_case("eval-objective-slash-split",
{"signals": {"objective_any": ["deploy", "release", "widget"]}},
n=need(objective="adjust the release/deploy widget", constraints={"contracts": []}))
eval_case("eval-objective-dash-not-split",
{"signals": {"objective_any": ["deploy", "pre-deploy"]}},
n=need(objective="verify the pre-deploy check", constraints={"contracts": []}))
eval_case("eval-contracts-all-rel-kinds",
{"signals": {"contracts_match": ["contract:monotonic_promotion", "contract:exposed_api",
"contract:served_edge", "contract:fail_closed_deployment",
"contract:provided_gate", "contract:second_edge"]}})
eval_case("eval-contracts-miss-non-rel-type",
{"signals": {"contracts_match": ["module:deploy_qualify"]}})
eval_case("eval-contracts-second-authority",
{"signals": {"contracts_match": ["contract:scaffold_only"]}},
authorities={"rune_spine": SPINE,
"project_scaffold": {"relationships": [
{"type": "implements", "from": "module:deploy_stage", "to": "contract:scaffold_only"}]}})
eval_case("eval-empty-entity-id-quirk",
{"signals": {"contracts_match": ["contract:monotonic_promotion"]}},
surface={**SURFACE, "affected_existing_entities": ["", "module:deploy_qualify"]})
# ── derive_pattern_obligations ──────────────────────────────────────────────
O = lambda oid, text, when: {"id": oid, "obligation": text, "when": when}
def derive_case(name, obligations, n=None, exceptions=None, surface=None, authorities=None):
p = cp.ConstructionPattern("p.derive", "deriving pattern",
provenance=["incident:prov-1", "contract:prov-0"],
obligations=obligations)
nn = n or need()
s = surface or SURFACE
a = authorities or AUTH
case(name, "derive",
{"pattern": p.to_dict(), "need": serialize_need(nn), "surface_result": s,
"authorities": a, "project_exceptions": exceptions},
lambda: cp.derive_pattern_obligations(p, nn, s, a, project_exceptions=exceptions))
derive_case("derive-when-none-unknown", [O("mystery", "do the unconditioned thing", None)])
derive_case("derive-always-required", [O("always-ob", "regression proof", {"always": True})])
derive_case("derive-always-truthy-not-true",
[O("truthy-ob", "truthy always is not always", {"always": 1})])
derive_case("derive-path-hit-truncation",
[O("path-ob", "touch the deploy paths", {"path_contains": ["deploy", "rune"]})])
derive_case("derive-path-miss", [O("path-ob", "touch nothing real", {"path_contains": ["/absent/xyz/"]})])
derive_case("derive-entities-via-ui-and-regions",
[O("ui-ob", "respect the ui surface", {"entities_match": ["version_display"]}),
O("region-ob", "respect the region", {"entities_match": ["left"]}),
O("entity-ob", "respect the module", {"entities_match": ["module:"]}),
O("miss-ob", "matches nothing", {"entities_match": ["zzz-never"]})])
derive_case("derive-contracts-from-need-constraints",
[O("ct-ob", "honor the explicit contract",
{"contracts_touched": ["contract:explicit_need", "contract:absent"]})],
n=need(constraints={"contracts": ["contract:explicit_need"]}))
derive_case("derive-contracts-from-authorities",
[O("ct-ob", "honor the authority-implied contract",
{"contracts_touched": ["contract:provided_gate", "contract:served_edge", "contract:nowhere"]})])
derive_case("derive-contracts-miss",
[O("ct-ob", "cannot honor the unknown contract", {"contracts_touched": ["contract:not_anywhere"]})])
derive_case("derive-unrecognized-shape", [O("weird-ob", "do the unknown thing", {"unsupported_shape": True})])
derive_case("derive-mixed-routing",
[O("acc-ob", "always applies", {"always": True}),
O("rej-ob", "path never matches", {"path_contains": ["/absent/xyz/"]}),
O("unres-ob", "unknown shape", {"weird": 1})])
derive_case("derive-exception-with-defaults",
[O("exc-ob", "suppressed obligation", {"always": True}),
O("kept-ob", "surviving obligation", {"always": True})],
exceptions=[{"obligation": "exc-ob"}])
derive_case("derive-exception-full",
[O("exc-ob", "suppressed obligation", {"always": True})],
exceptions=[{"obligation": "exc-ob", "reason": "project policy documented",
"evidence": "policy doc", "authority": "user"}])
# ── combine_pattern_obligations ─────────────────────────────────────────────
def derivation(pattern_id, rows, revision=1):
"""rows: (id, verdict, text) — mirrors derive_pattern_obligations output."""
out = {"pattern": pattern_id, "revision": revision, "accepted": [], "rejected": [], "unresolved": []}
for oid, verdict, text in rows:
entry = {"id": oid, "obligation": text, "pattern": pattern_id, "revision": revision,
"provenance": "PATTERN", "pattern_provenance": [f"prov:{pattern_id}"],
"verdict": verdict, "reason": "reason"}
out[{"REQUIRED": "accepted", "APPLICABLE": "accepted",
"NOT_APPLICABLE": "rejected"}.get(verdict, "unresolved")].append(entry)
return out
def combine_case(name, derivs):
case(name, "combine", {"derivations": derivs}, lambda: cp.combine_pattern_obligations(derivs))
combine_case("combine-empty", [])
combine_case("combine-single", [derivation("a", [("shared", "REQUIRED", "regression proof"),
("z-only", "APPLICABLE", "z duty")])])
combine_case("combine-duplicate-collapse", [
derivation("a", [("shared", "REQUIRED", "regression proof")]),
derivation("b", [("shared", "REQUIRED", "regression proof")]),
derivation("c", [("shared", "REQUIRED", "regression proof")])])
combine_case("combine-conflict-different-text", [
derivation("x", [("shared", "REQUIRED", "version A of the rule")]),
derivation("y", [("shared", "REQUIRED", "version B of the rule")])])
combine_case("combine-sort-by-id", [
derivation("p1", [("zz", "REQUIRED", "last"), ("aa", "REQUIRED", "first")]),
derivation("p2", [("mm", "APPLICABLE", "middle")])])
combine_case("combine-conflict-then-continue", [
derivation("x", [("bad", "REQUIRED", "text one"), ("ok", "REQUIRED", "fine duty")]),
derivation("y", [("bad", "REQUIRED", "text two")])])
# ── _path_matches / _entity_matches (boundary discipline + split quirks) ───
def path_case(signal, path):
case(f"path-match:{signal!r}@{path!r}", "path_match",
{"signal": signal, "path": path},
lambda: cp._path_matches(signal, path))
path_case("tui", "src/rune/rune_tui.py") # short signal, real token
path_case("ui", "src/rune/rune_tui.py") # rune_tui is ONE token — miss
path_case("ui", "src/rune/builtin.py") # 'ui'-in-'builtin' FP class
path_case("deploy", "scripts/deploy_stage.py") # >=4 chars: containment
path_case("xyz", "scripts/deploy_stage.py") # containment miss
path_case("abc", "abc") # 3-char: whole-token only
path_case("AbC", "a/abc/b") # case folding, token hit
path_case("", "abc") # no empties in split — miss
path_case("", "/abc") # leading sep — leading empty
path_case("", "abc/") # trailing sep — trailing empty
path_case("", "") # re.split('') == ['']
def entity_case(signal, entity_id):
case(f"entity-match:{signal!r}@{entity_id!r}", "entity_match",
{"signal": signal, "entity_id": entity_id},
lambda: cp._entity_matches(signal, entity_id))
entity_case("ui:", "ui:chat") # ':'-prefix namespace hit
entity_case("ui:", "region:left") # prefix miss
entity_case("ui", "ui:chat") # colon glues the token — short miss
entity_case("chat", "ui:chat") # 4 chars: containment hit
entity_case("ui", "ui chat") # space separator — token hit
entity_case("spine", "module:spine") # long containment
entity_case("", "abc") # no empties — miss
entity_case("", ":abc") # colon is a token char — leading empty
entity_case("", "") # [''] — hit
# ── _need_dict (the FFI need envelope) ───────────────────────────────────────
def need_dict_case(name, n, extra=None):
payload = serialize_need(n)
if extra:
payload.update(extra)
case(name, "need_dict", {"need": payload}, lambda: cp._need_dict(n))
need_dict_case("need-dict-basic", need())
need_dict_case("need-dict-drops-extras", need(),
extra={"need_id": "need-x", "origin": "builder"})
# ── _surface_text (evidence token union; sorted projection of the set) ──────
def surface_text_case(name, n=None, surface=None):
nn = n or need()
s = surface or SURFACE
case(name, "surface_text",
{"need": serialize_need(nn), "surface_result": s},
lambda: sorted(cp._surface_text(nn, s)))
surface_text_case("surface-text-all-lists")
surface_text_case("surface-text-objective-splits",
n=need(objective="adjust the release/deploy widget"))
surface_text_case("surface-text-dash-split",
n=need(objective="verify the pre-deploy check"))
surface_text_case("surface-text-dedup-and-fold",
surface={"affected_paths": ["scripts/Deploy_Stage.py"],
"affected_existing_entities": ["module:deploy_stage"],
"affected_ui_surfaces": [], "affected_regions": [],
"workflow_config_surfaces": []})
# ── _obligation_when_hit (every when shape) ─────────────────────────────────
def when_case(name, when, n=None, surface=None, authorities=None):
nn = n or need()
s = surface or SURFACE
a = authorities or AUTH
o = {"id": "ob-1", "obligation": "duty", "when": when}
case(name, "when_hit",
{"obligation": o, "need": serialize_need(nn),
"surface_result": s, "authorities": a},
lambda: list(cp._obligation_when_hit(o, nn, s, a)))
when_case("when-none", None)
when_case("when-always-true", {"always": True})
when_case("when-always-truthy-not-true", {"always": 1})
when_case("when-always-false-key-present", {"always": False})
when_case("when-path-hit-truncated",
{"path_contains": ["py"]}) # 4 affected .py paths -> [:3]
when_case("when-path-miss", {"path_contains": ["/absent/xyz/"]})
when_case("when-path-empty-list", {"path_contains": []})
when_case("when-entities-via-ui-and-regions",
{"entities_match": ["version_display", "left"]})
when_case("when-entities-miss", {"entities_match": ["zzz-never"]})
when_case("when-contracts-from-need",
{"contracts_touched": ["contract:explicit_need", "contract:absent"]},
n=need(constraints={"contracts": ["contract:explicit_need"]}))
when_case("when-contracts-from-authorities",
{"contracts_touched": ["contract:provided_gate"]})
when_case("when-contracts-miss",
{"contracts_touched": ["contract:not_anywhere"]})
when_case("when-unrecognized-shape", {"unsupported_shape": True})
when_case("when-empty-dict", {})
# ── write truth ──────────────────────────────────────────────────────────────
OUT.write_text(json.dumps({"generator": "scripts/gen_construction_pattern_truth.py",
"module": "src/rune/construction_pattern.py", "cases": cases}, indent=1) + "\n")
print(f"{len(cases)} cases -> {OUT}")