Files
rune/tests/test_toolchain.py
Nick 3dadf2d3f5 feat(scaffolding): capability-fit discovery, gap decisions, toolchain resolution, layout contracts (SCAFFOLD-TRANCHE-003)
- capability_fit.py: open-world CapabilityRequirement; deterministic
  candidate discovery over Spine/Scaffold stores (kind + providing-
  relationship eligible; environment-contradiction excluded); fit levels
  EXACT/PARTIAL/INCOMPATIBLE/UNKNOWN from contracts+health, never names;
  resolution surface SATISFIED/REUSE/CONFIGURE/COMPOSE/ADAPT_EXISTING/
  ACQUIRE_EXTERNAL/BUILD_NEW/INSUFFICIENT_EVIDENCE — BUILD_NEW never
  silent (insufficient evidence blocks it), brittle-coupling check
  (load-bearing missing contracts) forces BUILD_NEW or ACQUIRE with
  recorded rationale; composition covers via contract union, flagged
  temporary (permanence user-controlled); LLM semantic-fit seam records
  provider/model/reason/evidence/confidence — prose never authority
- toolchain.py: EXISTING PROJECT TOOLCHAIN WINS; constraint keys fixed
  and language-free, values open-world; language change = CHANGE_MAJOR
  requiring user approval, never silent; unknown constraints ->
  INSUFFICIENT_EVIDENCE (no invented certainty); Python only selected
  because the project uses it — fixtures prove rust/ts/zig resolve
- layout_contract.py: open-world regions (web/tui/qt coexist); stable
  ui:<component> identity surviving implementation changes; LOCKED
  requires user provenance (mechanically enforced); locked amendment
  requires authorized_by=user (enforced, reason required); deterministic
  adapter-observation gate PASS/FAIL/UNKNOWN — UNKNOWN never PASS;
  USER-LOCKED drift preserves the contract (deliberate exception to
  reality-wins), marks DRIFTING, creates maintenance item; flexible
  violation fails gate until repaired
- REAL TUI PROOF: Rune's actual version display (issue #105, plan
  plans/2026-09-03-tui-footer.md) observed from source via deterministic
  adapter — footer-bar first child; gate cycle PASS -> controlled
  violation FAIL -> restore PASS; binding encoded scaffold-provenance
  (durable records establish placement; USER LOCK upgrade NEEDS
  CONFIRMATION — not fabricated)
- capability/layout integration proven: version-display requirement
  discovers the existing capability + layout binding (REUSE), never
  builds another widget
- 3 modules registered in Spine authority + canonical build + manifest
  regenerated (Tranche 2 lesson applied: no hand-edited structural facts)

Tests: 53 new (fit 24 + toolchain 9 + layout 16 + real proof 4);
suite 1439 green; henxels rc=0; pyright 0 errors on new modules.
2026-09-13 04:16:48 +01:00

118 lines
4.1 KiB
Python

"""test_toolchain.py — SCAFFOLD-TRANCHE-003 §28 test plan (A-G)."""
import os
import sys
import pytest
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
from rune.toolchain import (
CONSTRAINT_KEYS,
DecisionRecord, # noqa: E402
ToolchainConstraints,
resolve_toolchain,
)
# A. existing project language strongly preferred
def test_existing_toolchain_wins():
d = resolve_toolchain(ToolchainConstraints(existing_language="python", target_platform="linux"))
assert d.resolution == "KEEP_EXISTING"
assert d.selected_language == "python"
assert d.user_approval_required is False
# B. Python selected when it's actually the project constraint (not by default)
def test_python_only_because_project_uses_it():
d = resolve_toolchain(ToolchainConstraints(existing_language="python", performance_sensitive=False))
assert d.selected_language == "python"
# and Python is never picked without the project constraint or a request
d2 = resolve_toolchain(ToolchainConstraints(target_platform="linux", deployment="server"))
assert d2.resolution == "INSUFFICIENT_EVIDENCE"
assert d2.selected_language == ""
# C. non-Python selected when the project clearly favors it
def test_rust_project_gets_rust():
d = resolve_toolchain(
ToolchainConstraints(existing_language="rust", existing_runtime="tokio", performance_sensitive=True)
)
assert d.selected_language == "rust"
assert d.resolution == "KEEP_EXISTING"
def test_typescript_project_gets_typescript():
d = resolve_toolchain(
ToolchainConstraints(existing_language="typescript", existing_framework="svelte", target_platform="web")
)
assert d.selected_language == "typescript"
# D. language change requires user approval — never silent
def test_requested_change_requires_approval():
d = resolve_toolchain(ToolchainConstraints(existing_language="python"), requested_language="rust")
assert d.resolution == "CHANGE_MAJOR"
assert d.user_approval_required is True
assert d.selected_language == "rust"
def test_change_with_performance_evidence_still_requires_approval():
d = resolve_toolchain(
ToolchainConstraints(existing_language="python", performance_sensitive=True),
requested_language="rust",
performance_evidence={"significant_benefit": True, "basis": "measured 10x on streaming parse"},
)
assert d.user_approval_required is True
def test_same_language_request_is_not_major():
d = resolve_toolchain(ToolchainConstraints(existing_language="python"), requested_language="python")
assert d.resolution == "KEEP_EXISTING"
assert d.user_approval_required is False
# E. rationale + full record persisted
def test_decision_record_is_complete_and_serializable():
d = resolve_toolchain(
ToolchainConstraints(existing_language="rust", existing_runtime="tokio", performance_sensitive=True),
evidence_refs=["bench-2026-09-13"],
)
r = d.to_dict()
for k in (
"selected_language",
"runtime",
"rationale",
"decisive_constraints",
"evidence_refs",
"confidence",
"user_approval_required",
"resolution",
):
assert k in r
assert "bench-2026-09-13" in r["evidence_refs"]
assert "existing project toolchain wins" in r["rationale"]
# F. unknown constraints → INSUFFICIENT_EVIDENCE, not invented certainty
def test_unknown_constraints_insufficient():
d = resolve_toolchain(ToolchainConstraints(target_platform="linux"))
assert d.resolution == "INSUFFICIENT_EVIDENCE"
assert d.selected_language == ""
assert d.confidence == 0.0
# G. languages/runtimes/frameworks stay open-world data
def test_open_world_values_roundtrip():
c = ToolchainConstraints(
existing_language="zig", existing_runtime="custom-rt", wibble="future-unknown-thing"
) # unknown key
assert c.unknown["wibble"] == "future-unknown-thing"
d = resolve_toolchain(c)
assert d.selected_language == "zig"
def test_constraint_keys_never_name_a_language():
langs = {"python", "rust", "typescript", "go", "c++", "zig", "java"}
assert not (CONSTRAINT_KEYS & langs)