Files
rune/scripts/gen_construction_mode_truth.py
T
Nick 662dfa8af1 feat(construction_mode): close PARTIAL gaps — dichotomy wave
Oracle src/rune/construction_mode.py 412 lines / 5 fns: 2/5 -> 5/5 per
scripts/dichotomy_audit.py (name-preserving match). The three audit-named
gaps land as ported Rust functions: ConstructionMode::to_dict (the ten-key
projection in the oracle's insertion order, construction_mode.py:155-167),
ConstructionMode::from_dict (known-keys-only + dataclass defaults, mode
required — TypeError message carried on the err envelope,
construction_mode.py:169-187), and _contains_any (renamed to the oracle's
name; lowering moved inside to mirror the Python signature). classify_mode
now routes every return through the ported ConstructionMode struct.

PARITY BUGS FIXED WITH PROOF (frozen truth from the live oracle):
1. Early-return defaults law — the override/NOT_CONSTRUCTION/empty-objective
   branches left target_project/project_authority/proposed_by_model at
   their dataclass defaults in the oracle but leaked kwargs through in the
   port (construction_mode.py:249-259/276/279-286). Frozen cases
   'what is a chord' + target_project/model_proposal and '' + kwargs pin
   the None/None/None shape.
2. model_proposal falsy collapse — 'model_proposal if model_proposal else
   None' (construction_mode.py:400): empty dict now collapses to None.
3. Evidence list rendering — Rust {:?} emitted double quotes where Python
   repr emits single ('affected surface known: [\'module:deploy_stage\']');
   py_repr_list/py_repr_tuple reproduce the oracle's repr, including the
   MODES tuple in the invalid-override ValueError text.
4. Lexicon set-iteration order — the oracle's lexicons are Python sets, so
   multi-hit evidence order is hash-random per process (dichotomy quirk);
   truth is frozen under PYTHONHASHSEED=0 (generator re-execs itself,
   memory_consolidation precedent) and the Rust const arrays reproduce
   the seed-0 order.

COLLATERAL (fix-first): construction_decision's frozen truth was frozen
with RUNE_CM_CORE unpinned, so its construction_mode trace captured the
old divergent Rust output (double-quoted evidence). gen_construction_decision_truth.py
now pins RUNE_CM_CORE=python (transitive-core law) + the seed; truth
regenerated (11 evidence lines corrected), byte-identical verify green,
cd battery 18/18.

Truth: scripts/gen_construction_mode_truth.py via the shared freeze_truth.py
harness + rig scripts/cm_freeze_seams (pins RUNE_CM_CORE +
RUNE_CONSTRUCTION_DECISION_CORE for the file-scope branch's transitive
classify_surface import; binds the cm_classify_to_dict seam — classify_mode
returns a dataclass instance, the frozen contract is its to_dict projection).
39 harness cases (36 classify + 3 to_dict receivers) + 5 from_dict
projections + 3 error shapes in the battery envelope; freeze_truth --verify
byte-identical. Battery replays the corpus VERBATIM via include_str!
(frozen_cm_truth.json + frozen_cm_truth.verify.json pinned together by
envelope_cases_match_verify_file) with FULL structural equality.

FFI: cm_to_dict / cm_from_dict doc-envelope externs; cm_loader gains
to_dict/from_dict bindings. Live parity scripts/check_construction_mode_parity.py:
100% — 36 classify + 3 to_dict + 5 from_dict + 4 error shapes, rust == oracle
== frozen (92 comparisons; oracle side subprocessed under PYTHONHASHSEED=0).
clippy --all-targets -D warnings clean (construction_mode +
construction_decision + construction_interface). Python suite green in BOTH
pins (RUNE_CM_CORE=python and delegation live): 138 passed each.

Audit: construction_mode 5/5 FULL (85/192 modules at FULL).
2026-10-14 05:09:26 +01:00

240 lines
12 KiB
Python

#!/usr/bin/env python3
"""Freeze construction_mode oracle truth for the Rust gap-closing port
battery (dichotomy wave #2479, shared harness scripts/freeze_truth.py).
Run with the rig on PYTHONPATH so the oracle floor is pinned for the
whole cone:
PYTHONPATH=scripts/cm_freeze_seams python3 scripts/gen_construction_mode_truth.py
Exercises EVERY function and branch of src/rune/construction_mode.py:
cm_classify_to_dict (seam -> the REAL classify_mode + its own
to_dict) — all five modes, every branch of the
decision tree: explicit override (valid/UNKNOWN,
authority provenance, target_project carried,
project_authority/proposed_by_model left at their
dataclass defaults — the early-return defaults
law), NOT_CONSTRUCTION (no verb, verb with
non-constructible object, standalone-evidence
rescue), empty objective (with kwargs that must
NOT leak into the early return), standalone with
all three project_exists states, article-standalone
(guards: local/scope/file/target/exists), LOCAL_CHANGE
(scoped/file/target/exists corroboration, [:3]
evidence slices), EXISTING_PROJECT_CHANGE (scope/
target/exists, authority rune/issue161-harness/
other), UNKNOWN (verb-only, no-evidence, structural
contradiction, proven non-existence probe), and the
affected_surface escalation (UNKNOWN -> EPC 0.6
with probes retained, [:2] slice, LOCAL passthrough).
ConstructionMode.to_dict (full instance, defaults instance, override-
carrying instance — recv receiver form)
ConstructionMode.from_dict (auxiliary from_dict_cases column: full dict
+ unknown keys, minimal, partial, explicit
nulls honored verbatim, override/proposed
carried; plus error-shape column for missing
mode / non-dict / missing attribute)
Output:
src/rust/construction_mode/src/frozen_cm_truth.json (battery
envelope: generator/module/from_dict_cases/error_shapes/cases)
src/rust/construction_mode/src/frozen_cm_truth.verify.json (bare
harness array — the `freeze_truth.py --verify` law, byte-identical)
Verify (both pins required — seed for the set-iteration order, rig for
the oracle floor):
PYTHONHASHSEED=0 PYTHONPATH=scripts/cm_freeze_seams \
python3 scripts/freeze_truth.py --verify \
src/rust/construction_mode/src/frozen_cm_truth.verify.json \
--module rune.construction_mode
"""
from __future__ import annotations
import json
import os
import sys
from pathlib import Path
# HASH-RANDOMIZATION LAW (memory_consolidation precedent): the oracle's
# lexicons are Python SETS — multi-hit evidence order is hash-random per
# process. Truth is frozen under PYTHONHASHSEED=0; re-exec to pin it.
if os.environ.get("PYTHONHASHSEED") != "0":
os.execve(sys.executable, [sys.executable, __file__],
{**os.environ, "PYTHONHASHSEED": "0"})
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from freeze_truth import freeze, write as _harness_write # noqa: E402
import rune.construction_mode as cm # noqa: E402
OUT = Path(__file__).resolve().parents[1] / "src" / "rust" / "construction_mode" / "src"
assert hasattr(cm, "cm_classify_to_dict"), "run with PYTHONPATH=scripts/cm_freeze_seams"
FD = "cm_classify_to_dict"
# ── classify_mode: every branch of the decision tree ───────────────────────
classify_cases = [
# PROJECT_BUILD — standalone + from scratch, exists=False
(FD, ["build a standalone scheduler service from scratch"], {"project_exists": False}),
# LOCAL_CHANGE — known extensionless file binds a scoped target
(FD, ["fix the typo in the README"], {}),
# LOCAL_CHANGE — smallness + scoping corroboration
(FD, ["small patch to the module"], {}),
# EPC — "this project" scope + article guard (scoped blocks standalone)
(FD, ["add a flag to this project's deploy script"], {"project_exists": True}),
# EPC — "the codebase" scope
(FD, ["implement the new feature in the codebase"], {"project_exists": True}),
# NOT_CONSTRUCTION — question intent, no construction verb
(FD, ["what is the confidence score"], {}),
# NOT_CONSTRUCTION — verb present, object not buildable
(FD, ["make a list of items"], {}),
# UNKNOWN — empty objective
(FD, [""], {}),
# UNKNOWN — verb, no scope, no standalone
(FD, ["build the thing"], {}),
# UNKNOWN — standalone contradicted by existing project
(FD, ["build a standalone scheduler"], {"project_exists": True}),
# UNKNOWN — standalone with no existence evidence
(FD, ["build a standalone scheduler"], {"project_exists": None}),
# UNKNOWN — scoped change against proven-nonexistent project
(FD, ["refactor the module"], {"project_exists": False}),
# PROJECT_BUILD — indefinite-article new-artifact language
(FD, ["build me a program that renames photos"], {"project_exists": False}),
# UNKNOWN — article + creation verb but "fix a bug" is local-guarded
(FD, ["fix a bug"], {"project_exists": False}),
# PROJECT_BUILD — article + artifact noun, no scope evidence
(FD, ["add a flag to the deploy script"], {"project_exists": False}),
# EPC — "the module" scope (module is a construction word)
(FD, ["explain how the module works"], {}),
# EPC — explicit target project (rune -> rune_internal authority)
(FD, ["create a CLI that sorts files"], {"target_project": "rune", "project_exists": True}),
# EPC — "the service" scope
(FD, ["write tests for the service"], {"project_exists": True}),
# UNKNOWN — verb-only, export feature
(FD, ["implement export feature"], {}),
# LOCAL_CHANGE — "that module" scoping
(FD, ["quick fix for that module"], {}),
# override — valid PROJECT_BUILD with named authority
(FD, ["build something"], {"explicit_override": "PROJECT_BUILD", "override_authority": "operator_bob"}),
# override — target_project carried; project_authority/proposed stay None
(FD, ["build a standalone export tool"],
{"explicit_override": "EXISTING_PROJECT_CHANGE", "target_project": "rune",
"override_authority": "operator"}),
# override — UNKNOWN forces clarification_required
(FD, ["anything"], {"explicit_override": "UNKNOWN"}),
# NOT_CONSTRUCTION early return drops target_project + model_proposal
(FD, ["what is a chord"], {"target_project": "rune", "model_proposal": {"mode": "LOCAL_CHANGE"}}),
# NOT_CONSTRUCTION verb-object branch also drops model_proposal
(FD, ["make a list of items"], {"model_proposal": {"mode": "PROJECT_BUILD"}}),
# empty objective early return drops target_project + model_proposal
(FD, [""], {"target_project": "webapp", "model_proposal": {"mode": "X"}}),
# NOT_CONSTRUCTION skipped: standalone evidence rescues a verb+list
(FD, ["make a list of ideas for a new app"], {}),
# affected_surface escalates UNKNOWN -> EPC 0.6, probes retained
(FD, ["build the thing"], {"affected_surface": ["module:deploy_stage"]}),
# affected_surface on LOCAL_CHANGE — [:2] evidence slice
(FD, ["small patch to the module"], {"affected_surface": ["module:a", "module:b", "module:c"]}),
# affected_surface escalates standalone-UNKNOWN too
(FD, ["build a standalone scheduler"], {"project_exists": None, "affected_surface": ["module:x"]}),
# model_proposal falsy (empty dict) collapses to None
(FD, ["implement export feature"], {"model_proposal": {}}),
# model_proposal recorded verbatim, never authority
(FD, ["implement export feature"],
{"model_proposal": {"pattern_id": "x", "provider": "p", "confidence": 0.4}}),
# authority — issue161-harness maps to rune_internal
(FD, ["refactor the module"], {"target_project": "issue161-harness", "project_exists": True}),
# authority + proven-nonexistent probe names the target
(FD, ["refactor the module"], {"target_project": "webapp", "project_exists": False}),
# target_project alone scopes (no project_exists kwarg)
(FD, ["refactor the module"], {"target_project": "webapp"}),
# LOCAL_CHANGE — dotted source file binds a scoped target
(FD, ["small fix in scheduler.py"], {}),
]
# ── ConstructionMode.to_dict — receiver form (instance rebuilt by the
# harness's shape-matched receiver reconstruction) ────────────────────────
to_dict_cases = [
{"fn": "ConstructionMode.to_dict",
"recv": {"cls": "ConstructionMode", "mode": "PROJECT_BUILD",
"evidence": ["standalone/new-lifecycle language: ['standalone']"],
"target_project": "webapp", "project_authority": "webapp",
"confidence": 0.9, "clarification_required": False,
"probe_questions": [], "bootstrap_required": True,
"override": None, "proposed_by_model": {"mode": "LOCAL_CHANGE"}},
"args": [], "kwargs": {}},
{"fn": "ConstructionMode.to_dict",
# every attr explicit at its dataclass default — the harness rebuilds
# receivers via __new__, so "minimal" means "all defaults present"
"recv": {"cls": "ConstructionMode", "mode": "UNKNOWN",
"evidence": [], "target_project": None, "project_authority": None,
"confidence": 0.0, "clarification_required": False,
"probe_questions": [], "bootstrap_required": False,
"override": None, "proposed_by_model": None},
"args": [], "kwargs": {}},
{"fn": "ConstructionMode.to_dict",
"recv": {"cls": "ConstructionMode", "mode": "LOCAL_CHANGE",
"evidence": ["explicit override by operator"], "target_project": None,
"project_authority": None, "confidence": 1.0,
"clarification_required": False, "probe_questions": [],
"bootstrap_required": False,
"override": {"authority": "operator", "from_mode": None},
"proposed_by_model": None},
"args": [], "kwargs": {}},
]
cases = classify_cases + to_dict_cases
truth = freeze("rune.construction_mode", cases, oracle_module="rune.construction_mode")
# ── auxiliary columns (cd envelope precedent): from_dict projections and
# error shapes — classmethod returns an instance (not JSON-serializable
# for the shared-harness writer), so these ride the battery envelope ────
FD_INPUTS = [
{"mode": "PROJECT_BUILD", "evidence": ["a"], "target_project": "webapp",
"project_authority": "webapp", "confidence": 0.9,
"clarification_required": False, "probe_questions": ["q?"],
"bootstrap_required": True, "override": {"authority": "op", "from_mode": None},
"proposed_by_model": {"mode": "X"}, "wibble": "future-data"},
{"mode": "UNKNOWN"},
{"mode": "EXISTING_PROJECT_CHANGE", "evidence": ["e1", "e2"], "confidence": 0.8},
{"mode": "LOCAL_CHANGE", "target_project": None, "evidence": None,
"proposed_by_model": None},
{"mode": "NOT_CONSTRUCTION", "override": {"authority": "user", "from_mode": "UNKNOWN"}},
]
from_dict_cases = [
{"args": d, "expected": cm.ConstructionMode.from_dict(d).to_dict()}
for d in FD_INPUTS
]
error_shapes = {}
try:
cm.ConstructionMode.from_dict({"evidence": []})
except TypeError as e:
error_shapes["from_dict_missing_mode"] = str(e)
try:
cm.ConstructionMode.from_dict(123)
except TypeError as e:
error_shapes["from_dict_non_dict"] = str(e)
_broken = cm.ConstructionMode.__new__(cm.ConstructionMode)
_broken.mode = "X"
try:
_broken.to_dict()
except AttributeError as e:
error_shapes["to_dict_missing_attribute"] = str(e)
doc = json.loads(json.dumps(truth)) # harness array (serializable projection)
envelope = {
"generator": "scripts/gen_construction_mode_truth.py",
"module": "src/rune/construction_mode.py",
"from_dict_cases": from_dict_cases,
"error_shapes": error_shapes,
"cases": doc,
}
(OUT / "frozen_cm_truth.json").write_text(json.dumps(envelope, indent=2, ensure_ascii=False) + "\n")
_harness_write(truth, OUT / "frozen_cm_truth.verify.json")
print(f"wrote {len(truth)} harness cases "
f"(+{len(from_dict_cases)} from_dict projections) -> {OUT}")