Gap-closing port of construction_decision.py (#2479): 4/20 → 19/20 fns. Name-preserving 1:1 ports of normalize_need (JSON view), resolve_surface, ss_entity, implemented_contracts, resolve_affected_surface, check_completeness, record_proposed_requirement, needs_user_approval, _project_exists_evidence, make_decision (+ layout_obligations_for, obligations_from_trace, need_new/need_to_dict); merge_resolutions fixed to the oracle precedence law (SATISFIED>REUSE>…>BUILD_NEW, never a fallback); language_placement reshaped to the live scaffold_core verdict ({placement, rule, evidence}, characteristic fit for non-rune) — the old flat W6-era shape was stale against the retired oracle. resolve_status is carried oracle-verbatim (ANY truthy status string returned as-is): the structural_store crate collapses unknown statuses (STALE) to UNKNOWN, silently un-staling candidates — proven by test_stale_candidate_rejected_in_live_path. FFI: cdec_ doc-envelope symbols (one per public fn), freed via capability_scoring's cs_free_string (never re-exported). Loader src/rune/cdec_loader.py mirrors broker_loader.py. Facade delegates with RUNE_CONSTRUCTION_DECISION_CORE=python pin; Python remains the parity authority. Composes capability_fit/toolchain/construction_mode/ construction_pattern/patterns_builtin kernels (no cross-crate rewrites). Truth: scripts/gen_construction_decision_truth.py via the shared freeze_truth harness — 134 cases byte-identical (--verify OK) + 5 Need + 8 project-existence cases, embedded VERBATIM in branch_battery.rs (17/17). Live parity 147/147 (auto→Rust vs pinned Python). pytest 21/21 both pins; clippy --all-targets -D warnings 0.
38 lines
1.3 KiB
Python
38 lines
1.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Open the #2479 dichotomy-wave construction contract for construction_decision
|
|
(gap-closing port). Full lifecycle in ONE process — close happens after the
|
|
commits land (SHAs reported at close)."""
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
|
|
|
from rune.construction_interface import ConstructionInterface
|
|
|
|
iface = ConstructionInterface(builder="factory-gap-cd")
|
|
|
|
r = iface.submit_need(
|
|
"Close construction_decision PARTIAL gaps (dichotomy factory, issue #2479 "
|
|
"tranche): port audit-named missing functions name-preserving 1:1, "
|
|
"doc-envelope FFI (cs_free_string — never re-export), loader mirroring "
|
|
"broker_loader.py, facade delegation with RUNE_CONSTRUCTION_DECISION_CORE "
|
|
"pin, shared freeze_truth harness battery, live parity 100% on new fns, "
|
|
"Phase B language-advantage pass.",
|
|
origin="builder",
|
|
)
|
|
print("submit_need:", json.dumps(r)[:400])
|
|
if not r.get("success"):
|
|
print("NEED FAILED — aborting")
|
|
sys.exit(1)
|
|
cid = r["ids"]["contract_id"]
|
|
print("contract_id:", cid)
|
|
|
|
for phase in ("approved", "building"):
|
|
t = iface.transition(cid, phase)
|
|
print(f"transition->{phase}:", json.dumps(t)[:300])
|
|
if not t.get("success"):
|
|
sys.exit(1)
|
|
|
|
print("CONTRACT", cid, "OPEN in building")
|