diff --git a/config/umbrellas.json b/config/umbrellas.json index d0b4bb40..95daa514 100644 --- a/config/umbrellas.json +++ b/config/umbrellas.json @@ -1,7 +1,7 @@ { "_comment": "GENERATED by rune.spine \u2014 compatibility view for legacy umbrella consumers. DO NOT EDIT: structural truth lives in store/spine/current.json; edits here are flagged by spine drift.", "_generated_by_spine": true, - "generated_at": "2026-09-13T13:37:11Z", + "generated_at": "2026-09-13T16:15:07Z", "umbrellas": { "capability": { "description": "Tool selection and execution authority", @@ -219,6 +219,7 @@ "cognitive_budgeter", "complexity_scorer", "construction_decision", + "construction_interface", "construction_pattern", "construction_patterns_builtin", "context_broker", @@ -229,6 +230,7 @@ "spine", "structural_store", "toolchain", + "tui_backlog", "witness" ], "depends_on": [ diff --git a/docs/tui-registry.md b/docs/tui-registry.md index d8da1e3b..cc4b71cc 100644 --- a/docs/tui-registry.md +++ b/docs/tui-registry.md @@ -9,6 +9,7 @@ new surface._ |---|---|---| | `rune_tui.py` | The main Textual application — chat pane, work pane, status bar (version label + refresh), footer, dialogs | The known giant (file-size debt tracked in henxels); composition root for all UI | | `tui_validator.py` | Import-allowlist validation for TUI code | Drift defect tracked in #139 (allowlist vs `__future__`/relative imports) | +| `tui_backlog.py` | Not a surface — the durable TUI Upgrade Backlog ledger (outstanding projection/control work per backend feature) | SCAFFOLD-TRANCHE-007; ledger only, never structural authority | ## Adding a TUI surface diff --git a/src/rune/construction_decision.py b/src/rune/construction_decision.py index bf609903..7b274bbf 100644 --- a/src/rune/construction_decision.py +++ b/src/rune/construction_decision.py @@ -872,6 +872,8 @@ def generate_contract( "completeness", "affected_surfaces", "iterations", + "patterns_considered", + "pattern_obligations", ) }, # distinct impact surfaces (Tranche 5 §13) — file scope != structural diff --git a/src/rune/construction_interface.py b/src/rune/construction_interface.py new file mode 100644 index 00000000..2db9e243 --- /dev/null +++ b/src/rune/construction_interface.py @@ -0,0 +1,751 @@ +"""construction_interface.py — the stable builder-facing Construction +Interface (SCAFFOLD-TRANCHE-007). + +ONE shared boundary for every builder — MiMo, Kimi, GLM, future models, +deterministic scripts — and for both modes: + + Rune-internal mode authority = Rune Spine + Rune's Project Scaffold + external-project mode authority = that project's Project Scaffold + +The builder must NOT need to know construction_decision.py, scaffold.py, +structural_store.py, Layout Contract internals, or store paths. Those are +implementation details behind this adapter. + +Authority enforcement (§14) — the adapter is NOT a bypass: + - builders may not rewrite Rune Spine or Project Scaffold truth + - builders may not amend USER-LOCKED layout + - builders may not silently broaden scope + - builders may not self-certify completion ("done=true" is not a thing) + - closing remains governed by Scaffolding (phase map + gates) + - builder identity is RECORDED for audit but never changes semantics + (§17): identical structured input → identical behavior, any builder. + +Machine-readable output (§12): every operation returns a stable envelope — + {schema, operation, success, ids, state, evidence, errors, warnings} +Errors are explicit states (§13): NEED_INCOMPLETE, INSUFFICIENT_EVIDENCE, +APPROVAL_REQUIRED, UNKNOWN_CONTRACT, SCOPE_VIOLATION, VERIFICATION_FAILED, +STORE_WRITE_FAILED, STALE_STATE — never prose-only exit-1. + +Transport (§3): typed Python API (this module) + JSON CLI (module main, +same convention as rune-spine). No network service. +""" + +from __future__ import annotations + +import json +import sys +from pathlib import Path + +from rune import structural_store as ss +from rune import scaffold as sc +from rune import spine as spine_mod +from rune import construction_decision as cd + +__all__ = ["ConstructionInterface", "INTERFACE_SCHEMA_VERSION", "Errors"] + +INTERFACE_SCHEMA_VERSION = 1 + +# ── explicit error states (§13) ────────────────────────────────────────────── + + +class Errors: + NEED_INCOMPLETE = "NEED_INCOMPLETE" + INSUFFICIENT_EVIDENCE = "INSUFFICIENT_EVIDENCE" + APPROVAL_REQUIRED = "APPROVAL_REQUIRED" + UNKNOWN_CONTRACT = "UNKNOWN_CONTRACT" + SCOPE_VIOLATION = "SCOPE_VIOLATION" + VERIFICATION_FAILED = "VERIFICATION_FAILED" + LAYOUT_VIOLATION = "LAYOUT_VIOLATION" + PATTERN_CONFLICT = "PATTERN_CONFLICT" + STORE_WRITE_FAILED = "STORE_WRITE_FAILED" + STALE_STATE = "STALE_STATE" + + +def _envelope( + operation: str, + *, + success: bool, + ids: dict | None = None, + state: dict | None = None, + evidence: list | None = None, + errors: list | None = None, + warnings: list | None = None, + **extra, +) -> dict: + env = { + "schema": INTERFACE_SCHEMA_VERSION, + "operation": operation, + "success": success, + "ids": ids or {}, + "state": state or {}, + "evidence": evidence or [], + "errors": errors or [], + "warnings": warnings or [], + } + env.update(extra) + return env + + +class ConstructionInterface: + """The builder-facing construction lifecycle for ONE project target. + + Rune-internal mode (default): + ConstructionInterface(builder="mimo") + External-project mode: + ConstructionInterface(builder="mimo", + project_store="/path/to/.rune/scaffold", + project_id="that-project") + + `builder` is recorded for audit (session record, §20) and NEVER changes + construction semantics (§17). + """ + + def __init__( + self, + builder: str = "unknown", + *, + project_store: str | None = None, + project_id: str | None = None, + spine_store: str = "store/spine/current.json", + ): + if not builder: + raise ValueError("builder identity required (recorded for audit)") + self.builder = builder + self.spine_store = spine_store + if project_store: + self.scaffold = sc.Scaffold(project_store, project_id or Path(project_store).name) + self.mode = "external_project" + else: + self.scaffold = sc.Scaffold("store/scaffold", "issue161-harness") + self.mode = "rune_internal" + + # -- authority access (read-only projections for builders) ---------------- + + def _authorities(self) -> dict[str, dict]: + """The structural authorities for THIS mode. Rune-internal consults + the real Spine store; external mode consults only the project + scaffold (a Rune-independent project has no Rune Spine).""" + auth: dict[str, dict] = {"project_scaffold": self.scaffold.load()} + if self.mode == "rune_internal": + sd = spine_mod.load(Path(self.spine_store)) + if sd is not None: + auth["rune_spine"] = sd + return auth + + def _record_session(self, doc: dict, operation: str, detail: str) -> None: + """Builder session record (§20): compact, no transcripts.""" + doc.setdefault("observations", []).append( + { + "kind": "builder_session", + "builder": self.builder, + "mode": self.mode, + "operation": operation, + "detail": detail[:200], + "observed_at": ss.now(), + } + ) + + # ── §5 submit_need ──────────────────────────────────────────────────────── + + def submit_need( + self, + objective: str, + *, + origin: str = "builder", + constraints: dict | None = None, + affected_surface: list[str] | None = None, + evidence_refs: list[str] | None = None, + approval_context: str = "", + task_ref: str = "", + generate: bool = True, + contract_id: str | None = None, + ) -> dict: + """Submit a structured Need; run the full live decision path; + optionally generate the Construction Contract. Returns decision + summary + contract ref + outstanding questions. Does NOT decide + approval — that surfaces via state.approval.""" + if not objective or not objective.strip(): + return _envelope( + "submit_need", + success=False, + errors=[{"error": Errors.NEED_INCOMPLETE, "detail": "objective is required"}], + ) + need = cd.Need( + need_id=f"need-{ss.now()}-{self.builder}", + objective=objective, + origin=origin, + project=self.scaffold.project_id, + task_ref=task_ref, + constraints=dict(constraints or {}), + affected_surface=list(affected_surface or []), + evidence_refs=list(evidence_refs or []), + approval_context=approval_context, + ) + doc = self.scaffold.load() + authorities = self._authorities() + trace = cd.make_decision(need, authorities=authorities, project_toolchain={"existing_language": "python"}) + ids: dict = {"need_id": need.need_id} + state: dict = { + "resolution": trace["resolution"], + "completeness": trace["completeness"]["verdict"], + "research": trace["research"], + "approval": trace["approval"], + "builder": self.builder, + } + errors, warnings = [], [] + if trace["completeness"]["verdict"] == cd.MATERIAL_GAP: + errors.append( + { + "error": Errors.INSUFFICIENT_EVIDENCE, + "detail": "material requirement gap", + "gaps": trace["completeness"]["gaps"], + "probe_questions": trace["completeness"]["probe_questions"], + } + ) + if trace["obligations"].get("pattern_conflicts"): + errors.append( + { + "error": Errors.PATTERN_CONFLICT, + "detail": "pattern obligations conflict", + "conflicts": trace["obligations"]["pattern_conflicts"], + } + ) + if trace["approval"]["required"]: + errors.append({"error": Errors.APPROVAL_REQUIRED, "reasons": trace["approval"]["reasons"]}) + if trace["resolution"] == "INSUFFICIENT_EVIDENCE" and not errors: + errors.append({"error": Errors.INSUFFICIENT_EVIDENCE, "detail": trace["rationale"][:200]}) + contract = None + if generate and trace["resolution"] not in ("INSUFFICIENT_EVIDENCE",): + cid = contract_id or f"BUILDER-{ss.now()}-{self.builder}" + cd.generate_contract( + self.scaffold, + doc, + trace, + contract_id=cid, + scope=None, + proposer_note=f"via Construction Interface by {self.builder}", + ) + ids["contract_id"] = cid + state["contract_phase"] = "draft" + state["next_action"] = "review for approval" + warnings.append({"warning": "contract generated in draft; requires approval transition before building"}) + self._record_session(doc, "submit_need", f"{need.need_id} → {trace['resolution']}") + try: + self.scaffold.save(doc) + except (OSError, ValueError) as e: + return _envelope( + "submit_need", + success=False, + ids=ids, + errors=[{"error": Errors.STORE_WRITE_FAILED, "detail": str(e)[:200]}], + ) + return _envelope("submit_need", success=not errors, ids=ids, state=state, errors=errors, warnings=warnings) + + # ── §6 inspect_decision ─────────────────────────────────────────────────── + + def inspect_decision(self, contract_id: str) -> dict: + """Read-only projection of the durable decision trace (§6).""" + doc = self.scaffold.load() + c = self.scaffold.contract(doc, contract_id) + if c is None: + return _envelope( + "inspect_decision", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.UNKNOWN_CONTRACT, "detail": f"no contract {contract_id}"}], + ) + t = c.get("ext", {}).get("decision_trace", {}) + return _envelope( + "inspect_decision", + success=True, + ids={"contract_id": contract_id, "need_id": t.get("need", {}).get("need_id", "")}, + state={ + "requirement": t.get("requirement", {}), + "completeness": t.get("completeness", {}), + "candidates": t.get("candidates", []), + "fits": [f for f in t.get("fits", []) if f["fit"] != "UNKNOWN"], + "resolution": t.get("resolution", ""), + "rationale": t.get("rationale", ""), + "toolchain": t.get("toolchain", {}), + "patterns_considered": t.get("patterns_considered", []), + "structural_obligations": { + k: t.get("obligations", {}).get(k, []) + for k in ("regression", "verification", "composition", "acquisition") + }, + "pattern_obligations": t.get("obligations", {}).get("pattern", []), + "approval": t.get("approval", {}), + "iterations": t.get("iterations", []), + "builder": self.builder, + }, + ) + + # ── §7 get_scope ────────────────────────────────────────────────────────── + + def get_scope(self, contract_id: str) -> dict: + """Mechanical builder-facing scope (§7): what may I touch?""" + doc = self.scaffold.load() + c = self.scaffold.contract(doc, contract_id) + if c is None: + return _envelope( + "get_scope", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.UNKNOWN_CONTRACT, "detail": f"no contract {contract_id}"}], + ) + ext = c.get("ext", {}) + return _envelope( + "get_scope", + success=True, + ids={"contract_id": contract_id}, + state={ + "allowed_paths": c["identities"]["scope"], + "affected_structural_entities": c["identities"]["affected_entities"], + "expected_new_entities": c["identities"].get("expected_new_entities", []), + "affected_paths": ext.get("affected_paths", []), + "affected_ui_surfaces": ext.get("affected_ui_surfaces", []), + "workflow_config_surfaces": ext.get("workflow_config_surfaces", []), + "unresolved_surfaces": ext.get("unresolved_surfaces", []), + "expected_runtime_effects": ext.get("expected_runtime_effects", []), + "layout_obligations": t_layout(ext), + "scope_amendments": ext.get("scope_amendments", []), + "builder": self.builder, + }, + ) + + +def t_layout(ext: dict) -> list[dict]: + """Layout obligations from a contract's decision trace (helper).""" + return ext.get("decision_trace", {}).get("layout_obligations", []) + + +# ── §8 get_obligations / §9 report_observation / §10 verification ─────────── + + +def _obligations_projection(c: dict) -> list[dict]: + t = c.get("ext", {}).get("decision_trace", {}) + obl = t.get("obligations", {}) + out = [] + for kind in ("regression", "verification", "composition", "acquisition"): + for item in obl.get(kind, []): + out.append( + { + "id": f"{kind}:{abs(hash(str(item))) % 10**8}", + "description": str(item)[:200], + "provenance": "STRUCTURAL", + "kind": kind, + "status": "REQUIRED", + } + ) + for p in obl.get("pattern", []): + out.append( + { + "id": p["id"], + "description": p["obligation"], + "provenance": "PATTERN", + "pattern": f"{p['pattern']}@r{p['revision']}", + "pattern_applicability": p.get("pattern_applicability", ""), + "evidence": p.get("reason", ""), + "status": p.get("verdict", "REQUIRED"), + } + ) + for lo in t.get("layout_obligations", []): + out.append( + { + "id": f"layout:{lo['component']}", + "description": lo["obligation"], + "provenance": "LAYOUT_CONTRACT", + "status": "REQUIRED", + "verification": lo["verification"], + } + ) + return out + + +def _obligation_scope_files(obligations: list[dict]) -> list[str]: + """Obligation ids referenced by closure scope checks.""" + return [] + + +class ConstructionInterfaceOps: + """Instance methods continued (kept separate only for readability).""" + + +# ── bind the ops onto the class (methods defined in _bind_ops's locals) ───── + + +def _make_methods(namespace: dict) -> dict: + return {k: v for k, v in namespace.items() if callable(v) and not k.startswith("_")} + + +# Rebuild the ops cleanly as real methods (the _bind_ops trick above was +# obscure — explicit binding is the honest, debuggable form): + + +def _get_obligations(self, contract_id: str) -> dict: + doc = self.scaffold.load() + c = self.scaffold.contract(doc, contract_id) + if c is None: + return _envelope( + "get_obligations", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.UNKNOWN_CONTRACT, "detail": f"no contract {contract_id}"}], + ) + return _envelope( + "get_obligations", + success=True, + ids={"contract_id": contract_id}, + state={"obligations": _obligations_projection(c), "builder": self.builder}, + ) + + +def _report_observation(self, contract_id: str, observations: list[dict]) -> dict: + doc = self.scaffold.load() + c = self.scaffold.contract(doc, contract_id) + if c is None: + return _envelope( + "report_observation", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.UNKNOWN_CONTRACT, "detail": f"no contract {contract_id}"}], + ) + if not isinstance(observations, list) or not observations: + return _envelope( + "report_observation", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.NEED_INCOMPLETE, "detail": "observations list required"}], + ) + items = [] + for o in observations: + if not isinstance(o, dict) or not o.get("entity"): + return _envelope( + "report_observation", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.NEED_INCOMPLETE, "detail": "each observation needs an entity"}], + ) + items.append( + { + "entity": o["entity"], + "source": o.get("source", f"builder:{self.builder}"), + "detail": str(o.get("detail", ""))[:300], + } + ) + ss.record_observed_impact(doc, contract_id, items) + self._record_session(doc, "report_observation", f"{len(items)} observation(s) on {contract_id}") + try: + self.scaffold.save(doc) + except (OSError, ValueError) as e: + return _envelope( + "report_observation", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.STORE_WRITE_FAILED, "detail": str(e)[:200]}], + ) + return _envelope( + "report_observation", + success=True, + ids={"contract_id": contract_id}, + state={ + "recorded": len(items), + "note": "evidence recorded; satisfaction is determined by Scaffolding gates, not builder claims", + }, + ) + + +def _verify( + self, contract_id: str, *, changed_files: list[str] | None = None, layout_observations: dict | None = None +) -> dict: + doc = self.scaffold.load() + c = self.scaffold.contract(doc, contract_id) + if c is None: + return _envelope( + "verify", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.UNKNOWN_CONTRACT, "detail": f"no contract {contract_id}"}], + ) + state: dict = {"phase": c.get("phase"), "status": c.get("status")} + errors, warnings = [], [] + if changed_files is not None: + scope = self.scaffold.check_scope(doc, contract_id, changed_files) + state["scope_check"] = scope + if scope["verdict"] == "red": + errors.append({"error": Errors.SCOPE_VIOLATION, "out_of_scope": scope["out_of_scope"]}) + elif scope["verdict"] == "unknown": + warnings.append({"warning": "scope UNKNOWN — contract has no approved scope paths"}) + if layout_observations: + from rune import layout_contract as lc + + gate = lc.check_layout(doc, layout_observations) + state["layout_gate"] = gate["verdict"] + if gate["verdict"] == "FAIL": + errors.append( + {"error": Errors.LAYOUT_VIOLATION, "checks": [x for x in gate["checks"] if x["verdict"] == "FAIL"]} + ) + elif gate["verdict"] == "UNKNOWN": + warnings.append({"warning": "layout UNKNOWN — never PASS"}) + obligations = _obligations_projection(c) + q = c.get("ext", {}).get("contract_quality") + if q: + state["contract_quality"] = { + k: q[k] + for k in ( + "correctly_predicted", + "expected_new_observed", + "expected_runtime_observed", + "genuinely_unexpected_new", + "scope_check", + ) + if k in q + } + state["obligations_total"] = len(obligations) + state["remaining"] = ( + "closure requires phase transitions through verifying with evidence; builder cannot self-certify" + ) + return _envelope( + "verify", success=not errors, ids={"contract_id": contract_id}, state=state, errors=errors, warnings=warnings + ) + + +def _transition(self, contract_id: str, phase: str, *, evidence_ref: str = "") -> dict: + doc = self.scaffold.load() + try: + self.scaffold.transition_contract( + doc, contract_id, phase, evidence_ref=evidence_ref or f"builder:{self.builder}" + ) + except sc.IllegalPhaseTransition as e: + return _envelope( + "transition", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.VERIFICATION_FAILED, "detail": str(e)}], + ) + except ValueError as e: + return _envelope( + "transition", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.UNKNOWN_CONTRACT, "detail": str(e)}], + ) + self._record_session(doc, "transition", f"{contract_id} → {phase}") + try: + self.scaffold.save(doc) + except (OSError, ValueError) as e: + return _envelope( + "transition", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.STORE_WRITE_FAILED, "detail": str(e)[:200]}], + ) + return _envelope("transition", success=True, ids={"contract_id": contract_id}, state={"phase": phase}) + + +def _close(self, contract_id: str, *, observed_evidence: list[dict], scope_files: list[str] | None = None) -> dict: + doc = self.scaffold.load() + try: + self.scaffold.close_contract(doc, contract_id, observed_evidence=observed_evidence, scope_files=scope_files) + except sc.IllegalPhaseTransition as e: + return _envelope( + "close", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.VERIFICATION_FAILED, "detail": str(e)}], + ) + except ValueError as e: + return _envelope( + "close", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.UNKNOWN_CONTRACT, "detail": str(e)}], + ) + self._record_session(doc, "close", f"{contract_id} closed") + try: + self.scaffold.save(doc) + except (OSError, ValueError) as e: + return _envelope( + "close", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.STORE_WRITE_FAILED, "detail": str(e)[:200]}], + ) + q = self.scaffold.contract(doc, contract_id)["ext"]["contract_quality"] + return _envelope( + "close", + success=True, + ids={"contract_id": contract_id}, + state={ + "phase": "closed", + "contract_quality": { + k: q[k] + for k in ("correctly_predicted", "expected_new_observed", "genuinely_unexpected_new", "scope_check") + if k in q + }, + }, + ) + + +def _resume(self, contract_id: str) -> dict: + doc = self.scaffold.load() + c = self.scaffold.contract(doc, contract_id) + if c is None: + return _envelope( + "resume", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.UNKNOWN_CONTRACT, "detail": f"no contract {contract_id}"}], + ) + ext = c.get("ext", {}) + t = ext.get("decision_trace", {}) + return _envelope( + "resume", + success=True, + ids={"contract_id": contract_id, "need_id": t.get("need", {}).get("need_id", "")}, + state={ + "mode": self.mode, + "need": t.get("need", {}), + "decision": { + "resolution": t.get("resolution"), + "completeness": t.get("completeness", {}).get("verdict"), + "toolchain": t.get("toolchain", {}).get("selected_language", ""), + }, + "phase": c.get("phase"), + "status": c.get("status"), + "scope": c["identities"]["scope"], + "obligations": _obligations_projection(c), + "patterns": c.get("ext", {}).get("pattern_refs", []), + "evidence": [cp.get("evidence", "")[:80] for cp in c.get("checkpoints", [])], + "unresolved": ext.get("unresolved_surfaces", []), + "approval": t.get("approval", {}), + "next_action": c["identities"].get("next_action", ""), + "last_builder_observations": [ + o + for o in doc.get("observations", []) + if o.get("kind") == "observed_consequence" and o.get("task") == contract_id + ][-5:], + "builder": self.builder, + }, + ) + + +def _amend_scope(self, contract_id: str, add_paths: list[str], *, reason: str, authority: str = "user") -> dict: + if authority != "user": + return _envelope( + "amend_scope", + success=False, + ids={"contract_id": contract_id}, + errors=[ + { + "error": Errors.APPROVAL_REQUIRED, + "detail": "scope expansion requires user authority — builders cannot broaden their own scope", + } + ], + ) + doc = self.scaffold.load() + c = self.scaffold.contract(doc, contract_id) + if c is None: + return _envelope( + "amend_scope", + success=False, + ids={"contract_id": contract_id}, + errors=[{"error": Errors.UNKNOWN_CONTRACT, "detail": f"no contract {contract_id}"}], + ) + c["identities"]["scope"] = sorted(set(c["identities"]["scope"]) | set(add_paths)) + c.setdefault("ext", {}).setdefault("scope_amendments", []).append( + {"added": sorted(add_paths), "reason": reason[:200], "authorized_by": "user"} + ) + self._record_session(doc, "amend_scope", f"{contract_id} +{len(add_paths)} paths (user)") + self.scaffold.save(doc) + return _envelope( + "amend_scope", success=True, ids={"contract_id": contract_id}, state={"scope": c["identities"]["scope"]} + ) + + +# explicit method binding (readable, debuggable — no locals() tricks) +ConstructionInterface.get_obligations = _get_obligations +ConstructionInterface.report_observation = _report_observation +ConstructionInterface.verify = _verify +ConstructionInterface.transition = _transition +ConstructionInterface.close = _close +ConstructionInterface.resume = _resume +ConstructionInterface.amend_scope = _amend_scope + + +# ── CLI transport (§3/§12/§27) ─────────────────────────────────────────────── + + +def main(argv=None) -> int: + """JSON CLI — same convention as rune-spine/rune-scaffold mains. Every + operation prints one JSON envelope; exit 0 = success, 1 = operation + failure (the envelope carries the explicit error state).""" + argv = list(sys.argv[1:] if argv is None else argv) + if not argv or argv[0] in ("-h", "--help"): + print(__doc__) + return 0 + cmd = argv[0] + args = argv[1:] + builder = "cli" + project_store = None + project_id = None + # --builder / --project-store / --project-id flags + for flag, key in (("--builder", "b"), ("--project-store", "s"), ("--project-id", "p")): + while flag in args: + i = args.index(flag) + val = args[i + 1] + del args[i : i + 2] + if flag == "--builder": + builder = val + elif flag == "--project-store": + project_store = val + else: + project_id = val + + iface = ConstructionInterface(builder=builder, project_store=project_store, project_id=project_id) + + def _out(env: dict) -> int: + print(json.dumps(env, indent=1, default=str)) + return 0 if env["success"] else 1 + + if cmd == "submit-need": + payload = json.loads(args[0]) if args else {} + return _out( + iface.submit_need( + payload.get("objective", ""), + origin=payload.get("origin", "builder"), + constraints=payload.get("constraints"), + affected_surface=payload.get("affected_surface"), + evidence_refs=payload.get("evidence_refs"), + approval_context=payload.get("approval_context", ""), + generate=payload.get("generate", True), + ) + ) + if cmd == "decision": + return _out(iface.inspect_decision(args[0])) + if cmd == "scope": + return _out(iface.get_scope(args[0])) + if cmd == "obligations": + return _out(iface.get_obligations(args[0])) + if cmd == "observe": + return _out(iface.report_observation(args[0], json.loads(args[1]))) + if cmd == "verify": + return _out(iface.verify(args[0], changed_files=(json.loads(args[1]) if len(args) > 1 else None))) + if cmd == "transition": + return _out(iface.transition(args[0], args[1], evidence_ref=args[2] if len(args) > 2 else "")) + if cmd == "close": + return _out( + iface.close( + args[0], + observed_evidence=json.loads(args[1]), + scope_files=(json.loads(args[2]) if len(args) > 2 else None), + ) + ) + if cmd == "resume": + return _out(iface.resume(args[0])) + return _out( + _envelope(cmd, success=False, errors=[{"error": "UNKNOWN_OPERATION", "detail": f"unknown command: {cmd}"}]) + ) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/rune/construction_pattern.py b/src/rune/construction_pattern.py index 7fd0dc0e..2d746233 100644 --- a/src/rune/construction_pattern.py +++ b/src/rune/construction_pattern.py @@ -204,6 +204,35 @@ def _surface_text(need, surface_result: dict) -> set[str]: return tokens +# ── shared boundary-aware matchers (Tranche 7 §0) ────────────────────────── + +def _path_matches(signal: str, path: str) -> bool: + """Boundary-aware path-signal matching: short (<4 char) signals match + path TOKENS only (the 'ui'-in-'builtin' false-positive class); longer + signals may use containment.""" + import re as _re + + s = signal.lower() + if len(s) >= 4: + return s in path.lower() + return s in set(_re.split(r"[^a-z0-9]+", path.lower())) + + +def _entity_matches(signal: str, entity_id: str) -> bool: + """Same discipline for entity ids. Prefix signals ending in ':' (e.g. + 'ui:', 'region:') match the id's namespace prefix — structural kinds + carry meaning in their prefix, and prefix equality is exact, not a + substring accident.""" + import re as _re + + s = signal.lower() + if s.endswith(":"): + return entity_id.lower().startswith(s) + if len(s) >= 4: + return s in entity_id.lower() + return s in set(_re.split(r"[^a-z0-9:]+", entity_id.lower())) + + def evaluate_applicability( pattern: ConstructionPattern, need, surface_result: dict, authorities: dict[str, dict] ) -> dict: @@ -283,16 +312,18 @@ def evaluate_applicability( ) _check( "path_contains", - [p.lower() for p in signals.get("path_contains", [])], + [p for p in signals.get("path_contains", [])], lambda c: any( - c in p.lower() + _path_matches(c, p) for p in surface_result.get("affected_paths", []) + surface_result.get("workflow_config_surfaces", []) ), ) _check( "entities_match", - [e.lower() for e in signals.get("entities_match", [])], - lambda c: any(c in e.lower() for e in surface_result.get("affected_existing_entities", [])), + [e for e in signals.get("entities_match", [])], + lambda c: any( + _entity_matches(c, e) for e in surface_result.get("affected_existing_entities", []) + ), ) _check( "objective_any", @@ -348,25 +379,25 @@ def _obligation_when_hit(obligation: dict, need, surface_result: dict, authoriti An obligation with no recognized `when` is UNKNOWN (never silently required).""" when = obligation.get("when") - paths = [p.lower() for p in surface_result.get("affected_paths", [])] + [ - p.lower() for p in surface_result.get("workflow_config_surfaces", []) + paths = [p for p in surface_result.get("affected_paths", [])] + [ + p for p in surface_result.get("workflow_config_surfaces", []) ] entities = ( - [e.lower() for e in surface_result.get("affected_existing_entities", [])] - + [u.lower() for u in surface_result.get("affected_ui_surfaces", [])] - + [r.lower() for r in surface_result.get("affected_regions", [])] + [e for e in surface_result.get("affected_existing_entities", [])] + + [u for u in surface_result.get("affected_ui_surfaces", [])] + + [r for r in surface_result.get("affected_regions", [])] ) if when is None: return OBL_UNKNOWN, "obligation declares no applicability condition" if when.get("always") is True: return OBL_REQUIRED, "pattern-level obligation (always applies when the pattern applies)" if "path_contains" in when: - hits = [p for sub in when["path_contains"] for p in paths if sub.lower() in p] + hits = [p for sub in when["path_contains"] for p in paths if _path_matches(sub, p)] if hits: return OBL_APPLICABLE, f"affected path(s): {hits[:3]}" return OBL_NOT_APPLICABLE, ("no affected path matches " + str(when["path_contains"])) if "entities_match" in when: - hits = [e for sub in when["entities_match"] for e in entities if sub.lower() in e] + hits = [e for sub in when["entities_match"] for e in entities if _entity_matches(sub, e)] if hits: return OBL_APPLICABLE, f"affected entity/entities: {hits[:3]}" return OBL_NOT_APPLICABLE, ("no affected entity matches " + str(when["entities_match"])) diff --git a/src/rune/construction_patterns_builtin.py b/src/rune/construction_patterns_builtin.py index c085f28c..1eacb7a7 100644 --- a/src/rune/construction_patterns_builtin.py +++ b/src/rune/construction_patterns_builtin.py @@ -173,7 +173,7 @@ UI_TUI_STRUCTURAL = ConstructionPattern( "id": "ui-component-identity-stable", "obligation": "ui: identity survives implementation-path " "changes; authority never keyed by filename alone", - "when": {"path_contains": ["tui", "ui", "widget"]}, + "when": {"entities_match": ["ui:", "region:", "layout:"]}, }, ], provenance=[ diff --git a/src/rune/tui_backlog.py b/src/rune/tui_backlog.py new file mode 100644 index 00000000..41c75fcb --- /dev/null +++ b/src/rune/tui_backlog.py @@ -0,0 +1,125 @@ +"""tui_backlog.py — durable TUI Upgrade Backlog (SCAFFOLD-TRANCHE-007 §22-25). + +Standing architectural requirement: every meaningful backend feature is +checked for whether it needs a TUI/user-surface projection or operator +control. The backlog records that work so the user-facing system never +falls behind the backend. + +AUTHORITY (§25): the backlog is a maintenance/product-surface LEDGER — +outstanding work only. It is NOT TUI structural authority. Implemented TUI +structure remains under Layout Contracts / the project's structural +authority. + +Projection types (§24): NONE / INSPECTION / CONTROL / BOTH / UNKNOWN. +Auto-capture seam: construction-contract closure can ask "TUI projection +required?" — recorded truthfully even when the answer is NONE. +""" + +from __future__ import annotations + +from rune.structural_store import add_entity, entity, now + +__all__ = [ + "add_backlog_item", + "get_backlog_item", + "list_backlog", + "update_backlog_status", + "record_tui_projection_decision", + "PROJECTIONS", + "STATUSES", +] + +PROJECTIONS = {"NONE", "INSPECTION", "CONTROL", "BOTH", "UNKNOWN"} +STATUSES = {"OPEN", "PLANNED", "IN_PROGRESS", "DONE", "WONT_DO"} + + +def add_backlog_item( + doc: dict, + item_id: str, + *, + feature: str, + desired_behavior: str, + why: str, + projection: str = "INSPECTION", + dependencies: list[str] | None = None, + priority: str = "normal", + status: str = "OPEN", + authority_source: str = "product-surface requirement", + evidence_refs: list[str] | None = None, +) -> dict: + """Add/refresh one backlog item (§22). `feature` (originating subsystem) + and `projection` classification are retained permanently. Duplicate ids + refresh in place — the ledger does not fork.""" + if projection not in PROJECTIONS: + raise ValueError(f"projection must be one of {sorted(PROJECTIONS)}") + if status not in STATUSES: + raise ValueError(f"status must be one of {sorted(STATUSES)}") + return add_entity( + doc, + id=f"tui-backlog:{item_id}", + kind="tui_backlog_item", + identities={ + "feature": feature, + "desired_behavior": desired_behavior, + "why": why, + "projection": projection, + "dependencies": sorted(dependencies or []), + "priority": priority, + "status": status, + "authority_source": authority_source, + }, + evidence_refs=evidence_refs or [f"backlog-added:{authority_source}"], + ) + + +def get_backlog_item(doc: dict, item_id: str) -> dict | None: + return entity(doc, f"tui-backlog:{item_id}") + + +def list_backlog(doc: dict, *, status: str | None = None, projection: str | None = None) -> list[dict]: + out = [] + for e in doc["entities"]: + if e["kind"] != "tui_backlog_item": + continue + if status and e["identities"].get("status") != status: + continue + if projection and e["identities"].get("projection") != projection: + continue + out.append(e) + return sorted(out, key=lambda e: e["id"]) + + +def update_backlog_status(doc: dict, item_id: str, status: str, *, evidence_ref: str = "") -> dict: + e = get_backlog_item(doc, item_id) + if e is None: + raise ValueError(f"no backlog item: {item_id}") + if status not in STATUSES: + raise ValueError(f"status must be one of {sorted(STATUSES)}") + e["identities"]["status"] = status + e["observed_at"] = now() + if evidence_ref: + e["evidence_refs"] = sorted(set(e.get("evidence_refs", [])) | {evidence_ref}) + return e + + +def record_tui_projection_decision( + doc: dict, feature_id: str, *, projection: str, rationale: str, source_contract: str = "" +) -> dict: + """§24 AUTO-CAPTURE SEAM: record a "TUI projection required?" decision + for a backend feature — including a truthful NONE. This is accounting, + not UI design. The seam exists so future contract closures can call it; + nothing is auto-designed.""" + if projection not in PROJECTIONS: + raise ValueError(f"projection must be one of {sorted(PROJECTIONS)}") + return add_entity( + doc, + id=f"tui-projection:{feature_id}", + kind="tui_projection_decision", + identities={ + "feature": feature_id, + "projection": projection, + "rationale": rationale[:200], + "source_contract": source_contract, + }, + evidence_refs=[f"tui-projection-decision:{projection}"], + ) diff --git a/store/scaffold/current.json b/store/scaffold/current.json index 79887f30..c69a524e 100644 --- a/store/scaffold/current.json +++ b/store/scaffold/current.json @@ -17009,6 +17009,3282 @@ "status": "closed", "tags": [] }, + { + "checkpoints": [ + { + "at": "2026-09-13T14:51:18Z", + "evidence": "user tranche brief (\u00a70-\u00a76 approval boundaries)", + "note": "", + "phase": "approved" + } + ], + "evidence_refs": [ + "contract-created:SCAFFOLD-TRANCHE-007" + ], + "ext": { + "affected_paths": [ + "src/rune/construction_decision.py", + "src/rune/construction_interface.py", + "src/rune/tui_backlog.py", + "tests/test_construction_interface.py", + "tests/test_tui_backlog.py" + ], + "affected_regions": [], + "affected_ui_surfaces": [], + "decision_trace": { + "affected_surfaces": { + "affected_existing_entities": [ + "module:construction_decision" + ], + "affected_paths": [ + "src/rune/construction_decision.py", + "src/rune/construction_interface.py", + "src/rune/tui_backlog.py", + "tests/test_construction_interface.py", + "tests/test_tui_backlog.py" + ], + "affected_regions": [], + "affected_ui_surfaces": [], + "derived_expected_new": [], + "resolutions": [ + { + "kind": "source_path", + "resolved": [], + "surface": "src/rune/construction_interface.py", + "unresolved_reason": "no authority records this path as an entity (path remains file-scope only)" + }, + { + "kind": "source_path", + "resolved": [], + "surface": "src/rune/tui_backlog.py", + "unresolved_reason": "no authority records this path as an entity (path remains file-scope only)" + }, + { + "kind": "source_path", + "resolved": [], + "surface": "tests/test_construction_interface.py", + "unresolved_reason": "no authority records this path as an entity (path remains file-scope only)" + }, + { + "kind": "source_path", + "resolved": [], + "surface": "tests/test_tui_backlog.py", + "unresolved_reason": "no authority records this path as an entity (path remains file-scope only)" + }, + { + "kind": "source_path", + "resolved": [ + { + "authority": "rune_spine", + "entity_id": "module:construction_decision", + "via": "path_attribute" + } + ], + "surface": "src/rune/construction_decision.py", + "unresolved_reason": "" + } + ], + "unresolved_surfaces": [ + { + "kind": "source_path", + "reason": "no authority records this path as an entity (path remains file-scope only)", + "surface": "src/rune/construction_interface.py" + }, + { + "kind": "source_path", + "reason": "no authority records this path as an entity (path remains file-scope only)", + "surface": "src/rune/tui_backlog.py" + }, + { + "kind": "source_path", + "reason": "no authority records this path as an entity (path remains file-scope only)", + "surface": "tests/test_construction_interface.py" + }, + { + "kind": "source_path", + "reason": "no authority records this path as an entity (path remains file-scope only)", + "surface": "tests/test_tui_backlog.py" + } + ], + "workflow_config_surfaces": [] + }, + "approval": { + "covered_by": "covered by user tranche brief", + "reasons": [], + "required": false + }, + "candidates": [ + { + "authority": "project_scaffold", + "consumers": [], + "id": "module:deploy_qualify", + "kind": "module", + "maturity": "REACHABLE", + "provides": [ + "contract:fail_closed_deployment" + ], + "status": "UNKNOWN" + }, + { + "authority": "project_scaffold", + "consumers": [], + "id": "module:deploy_stage", + "kind": "module", + "maturity": "REACHABLE", + "provides": [ + "contract:monotonic_promotion" + ], + "status": "UNKNOWN" + }, + { + "authority": "project_scaffold", + "consumers": [], + "id": "module:scaffold", + "kind": "module", + "maturity": "DECLARED", + "provides": [ + "contract:construction_contract_lifecycle" + ], + "status": "UNKNOWN" + }, + { + "authority": "project_scaffold", + "consumers": [], + "id": "module:structural_store", + "kind": "module", + "maturity": "DECLARED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:abstraction", + "module:audit_ledger", + "module:auto_context", + "module:auto_tasks", + "module:behavior", + "module:cache", + "module:capability_broker", + "module:claim_audit", + "module:context_pressure", + "module:curator", + "module:drift_cache", + "module:drift_core", + "module:drift_ledger", + "module:drift_observability", + "module:elastic_cognition", + "module:event_bus", + "module:graph_memory", + "module:growth_delta", + "module:hook_engine", + "module:inference_trace", + "module:memory_store", + "module:model_routing", + "module:night_mode", + "module:outcome_ledger", + "module:persona_definition", + "module:persona_gate", + "module:pins", + "module:prompt_sync", + "module:recall_uplift", + "module:rune_operator", + "module:rune_tui", + "module:self_improve", + "module:sleep_time", + "module:subconscious_pass", + "module:system_registry", + "module:task_gate", + "module:task_persist", + "module:time_awareness", + "module:token_optimizer", + "module:tui_validator", + "module:voice_hybrid", + "module:voice_sync", + "module:warm_neuron_store", + "module:warm_router", + "module:witness" + ], + "id": "module:memory_env", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:abstraction", + "module:auto_context", + "module:auto_tasks", + "module:autonomy_loop", + "module:behavior", + "module:cache", + "module:capability_broker", + "module:chat_bubble", + "module:claim_audit", + "module:cognitive_loop", + "module:context_pressure", + "module:cron_engine", + "module:dream_cycle", + "module:drift_ledger", + "module:event_bus", + "module:goal", + "module:graph_memory", + "module:growth_delta", + "module:hook_engine", + "module:memory_env", + "module:memory_store", + "module:message_widgets", + "module:microkernel", + "module:model_connect", + "module:model_profiles", + "module:night_mode", + "module:parallel_processor", + "module:persona_definition", + "module:persona_gate", + "module:pins", + "module:prompt_sync", + "module:provider_budget", + "module:provider_registry", + "module:rune_operator", + "module:safety_override", + "module:self_improve", + "module:sleep_time", + "module:system_registry", + "module:task_persist", + "module:time_awareness", + "module:token_optimizer", + "module:voice_hybrid", + "module:voice_sync", + "module:warm_neuron_store", + "module:warm_router", + "module:witness", + "module:work_manager" + ], + "id": "module:rune_tui", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:abstraction", + "module:builder_bridge", + "module:context_broker", + "module:graph_memory", + "module:memory_consolidation", + "module:memory_store", + "module:warm_neuron_store" + ], + "id": "module:memory_selector", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:abstraction", + "module:drift_compression", + "module:graph_memory", + "module:memory_selector", + "module:memory_store", + "module:sleep_time", + "module:warm_neuron_store" + ], + "id": "module:memory_consolidation", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:adaptive_router" + ], + "id": "module:route_risk_flags", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:attention_capsule", + "module:context_broker", + "module:memory_selector" + ], + "id": "module:builder_bridge", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:audit_ledger", + "module:drift_core", + "module:memory_env", + "module:memory_store", + "module:warm_router" + ], + "id": "module:curator", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:build_pipeline_policy", + "module:memory_env", + "module:rune_tui", + "module:voice_sync" + ], + "id": "module:prompt_sync", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:builder_bridge", + "module:memory_selector", + "module:rune_operator" + ], + "id": "module:context_broker", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:builder_bridge" + ], + "id": "module:attention_capsule", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:cache", + "module:complexity_scorer", + "module:curator", + "module:drift_cache", + "module:drift_compression", + "module:drift_core", + "module:drift_observability", + "module:memory_consolidation", + "module:memory_env", + "module:memory_selector", + "module:persona_definition", + "module:rune_tui", + "module:shard_manager", + "module:tier_manager", + "module:tool_executor", + "module:warm_router" + ], + "id": "module:memory_store", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:cache", + "module:memory_env", + "module:memory_store", + "module:rune_tui", + "module:token_optimizer" + ], + "id": "module:persona_definition", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:capability_broker", + "module:context_broker", + "module:event_bus", + "module:evidence_probe", + "module:failure_auto_filer", + "module:forge_client", + "module:inference_trace", + "module:local_tool_runtime", + "module:memory_env", + "module:model_profiles", + "module:model_routing", + "module:rune_tui", + "module:safety_override", + "module:subsystem_health", + "module:tool_executor", + "module:tool_protocol" + ], + "id": "module:rune_operator", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:capability_broker", + "module:local_tool_runtime", + "module:memory_store", + "module:provider_registry", + "module:rune_operator", + "module:tool_protocol" + ], + "id": "module:tool_executor", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:claim_audit", + "module:memory_consolidation", + "module:memory_env", + "module:memory_selector", + "module:rune_tui" + ], + "id": "module:warm_neuron_store", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:cognitive_budgeter", + "module:memory_env" + ], + "id": "module:elastic_cognition", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:cognitive_budgeter", + "module:model_registry" + ], + "id": "module:tiered_executor", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:curator", + "module:drift_cache", + "module:memory_env", + "module:memory_store", + "module:rune_tui" + ], + "id": "module:warm_router", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:curator", + "module:drift_observability", + "module:memory_env", + "module:memory_store" + ], + "id": "module:drift_core", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:curator", + "module:memory_env" + ], + "id": "module:audit_ledger", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:drift_core", + "module:memory_env", + "module:memory_store" + ], + "id": "module:drift_observability", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:elastic_cognition", + "module:tiered_executor" + ], + "id": "module:cognitive_budgeter", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:local_tool_runtime", + "module:rune_operator", + "module:tool_executor" + ], + "id": "module:tool_protocol", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_consolidation", + "module:memory_env", + "module:memory_selector", + "module:rune_tui" + ], + "id": "module:abstraction", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_consolidation", + "module:memory_env", + "module:memory_selector", + "module:rune_tui" + ], + "id": "module:graph_memory", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_consolidation", + "module:memory_env", + "module:rune_tui" + ], + "id": "module:sleep_time", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_consolidation", + "module:memory_store" + ], + "id": "module:drift_compression", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:memory_store", + "module:persona_definition", + "module:rune_tui" + ], + "id": "module:cache", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:memory_store", + "module:warm_router" + ], + "id": "module:drift_cache", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:persona_definition", + "module:rune_tui" + ], + "id": "module:token_optimizer", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:prompt_sync", + "module:rune_tui" + ], + "id": "module:voice_sync", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:recall_router" + ], + "id": "module:recall_uplift", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_operator", + "module:rune_tui", + "module:tool_executor" + ], + "id": "module:capability_broker", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_operator", + "module:rune_tui" + ], + "id": "module:event_bus", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_operator" + ], + "id": "module:inference_trace", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_operator" + ], + "id": "module:model_routing", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui", + "module:voice_injector" + ], + "id": "module:voice_hybrid", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui", + "module:warm_neuron_store" + ], + "id": "module:claim_audit", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:auto_context", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:auto_tasks", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:behavior", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:context_pressure", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:drift_ledger", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:growth_delta", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:hook_engine", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:night_mode", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:persona_gate", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:pins", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:self_improve", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:system_registry", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:task_persist", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:time_awareness", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env", + "module:rune_tui" + ], + "id": "module:witness", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env" + ], + "id": "module:outcome_ledger", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env" + ], + "id": "module:subconscious_pass", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env" + ], + "id": "module:task_gate", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_env" + ], + "id": "module:tui_validator", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_store" + ], + "id": "module:complexity_scorer", + "kind": "module", + "maturity": "PRESENT", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_store" + ], + "id": "module:shard_manager", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:memory_store" + ], + "id": "module:tier_manager", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:model_connect", + "module:rune_tui", + "module:standardized_providers", + "module:tool_executor" + ], + "id": "module:provider_registry", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:prompt_sync" + ], + "id": "module:build_pipeline_policy", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:provider_registry", + "module:rune_tui" + ], + "id": "module:model_connect", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:provider_registry" + ], + "id": "module:standardized_providers", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:recall_uplift" + ], + "id": "module:recall_router", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:route_risk_flags" + ], + "id": "module:adaptive_router", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_operator", + "module:rune_tui" + ], + "id": "module:model_profiles", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_operator", + "module:rune_tui" + ], + "id": "module:safety_override", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_operator", + "module:tool_executor", + "module:tool_protocol" + ], + "id": "module:local_tool_runtime", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_operator" + ], + "id": "module:evidence_probe", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_operator" + ], + "id": "module:failure_auto_filer", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_operator" + ], + "id": "module:forge_client", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_operator" + ], + "id": "module:subsystem_health", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_tui" + ], + "id": "module:autonomy_loop", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_tui" + ], + "id": "module:chat_bubble", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_tui" + ], + "id": "module:cognitive_loop", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_tui" + ], + "id": "module:cron_engine", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_tui" + ], + "id": "module:dream_cycle", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_tui" + ], + "id": "module:goal", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_tui" + ], + "id": "module:message_widgets", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_tui" + ], + "id": "module:microkernel", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_tui" + ], + "id": "module:parallel_processor", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_tui" + ], + "id": "module:provider_budget", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:rune_tui" + ], + "id": "module:work_manager", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:tiered_executor" + ], + "id": "module:model_registry", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [ + "module:voice_hybrid" + ], + "id": "module:voice_injector", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:auto_detect", + "kind": "module", + "maturity": "DECLARED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:build_mode", + "kind": "module", + "maturity": "PRESENT", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:build_orchestrator", + "kind": "module", + "maturity": "DECLARED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:builder_bridge_cli", + "kind": "module", + "maturity": "PRESENT", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:capability_fit", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:connection_pool", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:construction_decision", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:construction_pattern", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:construction_patterns_builtin", + "kind": "module", + "maturity": "PRESENT", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:contracts", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:custodian", + "kind": "module", + "maturity": "DECLARED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:dependency_tracker", + "kind": "module", + "maturity": "PRESENT", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:event_envelope", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:gitea_auth", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:gitea_pipeline", + "kind": "module", + "maturity": "DECLARED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:gitea_provision", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:graph_shard_bridge", + "kind": "module", + "maturity": "DECLARED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:growth_simulator", + "kind": "module", + "maturity": "DECLARED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:identity_anchors", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:intent_continuity", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:layout_contract", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:message_queue", + "kind": "module", + "maturity": "PRESENT", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:openai_compat_transport", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:progressive_escalation", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:query_memory", + "kind": "module", + "maturity": "WIRED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:response_adapter", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:retrieval_benchmark", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:rune_graphic", + "kind": "module", + "maturity": "PRESENT", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:rune_profiler", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:rune_spinner", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:salience_gate", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:scaffold", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:spine", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:structural_store", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:toolchain", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:umbrella_update", + "kind": "module", + "maturity": "DECLARED", + "provides": [], + "status": "UNKNOWN" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:verification_layer", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + }, + { + "authority": "rune_spine", + "consumers": [], + "id": "module:voicebox", + "kind": "module", + "maturity": "EXERCISED", + "provides": [], + "status": "CURRENT" + } + ], + "completeness": { + "gaps": [], + "note": "all resolved affected entities' implemented contracts are represented in the requirement", + "probe_questions": [], + "verdict": "COMPLETE_ENOUGH" + }, + "fits": [ + { + "authority": "project_scaffold", + "candidate": "module:deploy_qualify", + "consumers": [], + "covered": 0, + "fit": "INCOMPATIBLE", + "maturity_rank": 3, + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "provides none of the required contracts" + }, + { + "authority": "project_scaffold", + "candidate": "module:deploy_stage", + "consumers": [], + "covered": 0, + "fit": "INCOMPATIBLE", + "maturity_rank": 3, + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "provides none of the required contracts" + }, + { + "authority": "project_scaffold", + "candidate": "module:scaffold", + "consumers": [], + "covered": 1, + "fit": "EXACT", + "maturity_rank": 0, + "missing_contracts": [], + "reason": "all required contracts provided" + }, + { + "authority": "project_scaffold", + "candidate": "module:structural_store", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:abstraction", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:adaptive_router", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:attention_capsule", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:audit_ledger", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:auto_context", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:auto_detect", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:auto_tasks", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:autonomy_loop", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:behavior", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:build_mode", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:build_orchestrator", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:build_pipeline_policy", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:builder_bridge", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:builder_bridge_cli", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:cache", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:capability_broker", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:capability_fit", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:chat_bubble", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:claim_audit", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:cognitive_budgeter", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:cognitive_loop", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:complexity_scorer", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:connection_pool", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:construction_decision", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:construction_pattern", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:construction_patterns_builtin", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:context_broker", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:context_pressure", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:contracts", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:cron_engine", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:curator", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:custodian", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:dependency_tracker", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:dream_cycle", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:drift_cache", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:drift_compression", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:drift_core", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:drift_ledger", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:drift_observability", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:elastic_cognition", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:event_bus", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:event_envelope", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:evidence_probe", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:failure_auto_filer", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:forge_client", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:gitea_auth", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:gitea_pipeline", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:gitea_provision", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:goal", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:graph_memory", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:graph_shard_bridge", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:growth_delta", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:growth_simulator", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:hook_engine", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:identity_anchors", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:inference_trace", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:intent_continuity", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:layout_contract", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:local_tool_runtime", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:memory_consolidation", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:memory_env", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:memory_selector", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:memory_store", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:message_queue", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:message_widgets", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:microkernel", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:model_connect", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:model_profiles", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:model_registry", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:model_routing", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:night_mode", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:openai_compat_transport", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:outcome_ledger", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:parallel_processor", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:persona_definition", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:persona_gate", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:pins", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:progressive_escalation", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:prompt_sync", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:provider_budget", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:provider_registry", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:query_memory", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:recall_router", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:recall_uplift", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:response_adapter", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:retrieval_benchmark", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:route_risk_flags", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:rune_graphic", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:rune_operator", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:rune_profiler", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:rune_spinner", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:rune_tui", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:safety_override", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:salience_gate", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:scaffold", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:self_improve", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:shard_manager", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:sleep_time", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:spine", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:standardized_providers", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:structural_store", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:subconscious_pass", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:subsystem_health", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:system_registry", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:task_gate", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:task_persist", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:tier_manager", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:tiered_executor", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:time_awareness", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:token_optimizer", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:tool_executor", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:tool_protocol", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:toolchain", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:tui_validator", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:umbrella_update", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:verification_layer", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:voice_hybrid", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:voice_injector", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:voice_sync", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:voicebox", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:warm_neuron_store", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:warm_router", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:witness", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:work_manager", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + } + ], + "iterations": [], + "layout_obligations": [], + "need": { + "affected_surface": [ + "src/rune/construction_decision.py", + "src/rune/construction_interface.py", + "src/rune/tui_backlog.py", + "tests/test_construction_interface.py", + "tests/test_tui_backlog.py" + ], + "approval_context": "covered by user tranche brief", + "constraints": { + "contracts": [ + "contract:construction_contract_lifecycle" + ], + "expected_new_entities": [ + "module:construction_interface", + "module:tui_backlog", + "test:construction_interface", + "test:tui_backlog" + ], + "expected_new_source_paths": [ + "src/rune/construction_interface.py", + "src/rune/tui_backlog.py", + "tests/test_construction_interface.py", + "tests/test_tui_backlog.py" + ], + "expected_runtime_effects": [ + "deployment:current advances" + ], + "non_goals": [ + "HTTP server/daemon/RPC", + "MiMo-specific logic", + "external repo creation", + "full TUI implementation" + ] + }, + "evidence_refs": [ + "SCAFFOLD-TRANCHE-006 pattern_quality", + "process-defect:blind-string-replace-noop", + "tranche-7-brief" + ], + "need_id": "need-tranche7-interface", + "objective": "Expose Scaffolding through a stable builder-facing Construction Interface so MiMo and future builders can use Rune's construction competence without importing internal implementation modules or manually reconstructing the Need\u2192Decision\u2192Contract\u2192Verification lifecycle", + "origin": "user tranche brief (2026-09-13)", + "project": "rune", + "requested_permanence": "", + "task_ref": "SCAFFOLD-TRANCHE-007" + }, + "normalization_missing": [ + "environment" + ], + "obligations": { + "acquisition": [], + "composition": [], + "layout": [], + "new_behavior": [], + "pattern": [ + { + "id": "adapt-consumers-verified", + "obligation": "existing consumers of the adapted capability verified against their contracts", + "pattern": "capability-module-adaptation", + "pattern_applicability": "PARTIAL", + "pattern_provenance": [ + "LIVE-CONTRACT-QUALITY-001 (adaptation resolved + closed live)", + "SCAFFOLD-TRANCHE-001 (build-but-don't-break established)", + "SCAFFOLD-TRANCHE-003 (adaptation two-proof rule)", + "construction_decision.obligations_from_trace (auto-derived since T4)" + ], + "provenance": "PATTERN", + "reason": "affected entity/entities: ['module:construction_decision']", + "revision": 1, + "verdict": "APPLICABLE" + }, + { + "id": "adapt-migration-detected", + "obligation": "migration obligations detected and recorded if any consumer-visible interface changes", + "pattern": "capability-module-adaptation", + "pattern_applicability": "PARTIAL", + "pattern_provenance": [ + "LIVE-CONTRACT-QUALITY-001 (adaptation resolved + closed live)", + "SCAFFOLD-TRANCHE-001 (build-but-don't-break established)", + "SCAFFOLD-TRANCHE-003 (adaptation two-proof rule)", + "construction_decision.obligations_from_trace (auto-derived since T4)" + ], + "provenance": "PATTERN", + "reason": "affected path(s): ['src/rune/construction_decision.py', 'src/rune/construction_interface.py', 'src/rune/tui_backlog.py']", + "revision": 1, + "verdict": "APPLICABLE" + }, + { + "id": "adapt-new-behavior-proof", + "obligation": "new behavior proven by tests before closure", + "pattern": "capability-module-adaptation", + "pattern_applicability": "PARTIAL", + "pattern_provenance": [ + "LIVE-CONTRACT-QUALITY-001 (adaptation resolved + closed live)", + "SCAFFOLD-TRANCHE-001 (build-but-don't-break established)", + "SCAFFOLD-TRANCHE-003 (adaptation two-proof rule)", + "construction_decision.obligations_from_trace (auto-derived since T4)" + ], + "provenance": "PATTERN", + "reason": "pattern-level obligation (always applies when the pattern applies)", + "revision": 1, + "verdict": "REQUIRED" + }, + { + "id": "adapt-old-behavior-preserved", + "obligation": "existing capability behavior preserved; original contracts remain valid", + "pattern": "capability-module-adaptation", + "pattern_applicability": "PARTIAL", + "pattern_provenance": [ + "LIVE-CONTRACT-QUALITY-001 (adaptation resolved + closed live)", + "SCAFFOLD-TRANCHE-001 (build-but-don't-break established)", + "SCAFFOLD-TRANCHE-003 (adaptation two-proof rule)", + "construction_decision.obligations_from_trace (auto-derived since T4)" + ], + "provenance": "PATTERN", + "reason": "pattern-level obligation (always applies when the pattern applies)", + "revision": 1, + "verdict": "REQUIRED" + }, + { + "id": "ui-component-identity-stable", + "obligation": "ui: identity survives implementation-path changes; authority never keyed by filename alone", + "pattern": "ui-tui-structural-change", + "pattern_applicability": "PARTIAL", + "pattern_provenance": [ + "Tranche 3 real TUI proof (gate PASS -> violation FAIL -> restore)", + "issue #105 + plans/2026-09-03-tui-footer.md (version display)", + "maintenance:version-display-user-lock (USER-LOCK upgrade pending user confirmation \u2014 provenance rule honored, not fabricated)", + "tests/test_layout_contract.py + tests/test_layout_contract_real_proof.py" + ], + "provenance": "PATTERN", + "reason": "affected path(s): ['src/rune/tui_backlog.py', 'tests/test_tui_backlog.py', 'src/rune/tui_backlog.py']", + "revision": 1, + "verdict": "APPLICABLE" + } + ], + "pattern_conflicts": [], + "regression": [], + "verification": [ + "[pattern:capability-module-adaptation@r1] existing capability behavior preserved; original contracts remain valid", + "[pattern:capability-module-adaptation@r1] existing consumers of the adapted capability verified against their contracts", + "[pattern:capability-module-adaptation@r1] migration obligations detected and recorded if any consumer-visible interface changes", + "[pattern:capability-module-adaptation@r1] new behavior proven by tests before closure", + "[pattern:ui-tui-structural-change@r1] ui: identity survives implementation-path changes; authority never keyed by filename alone", + "new behavior proven by tests before closure" + ] + }, + "proposer_note": "tranche 7: builder adapter / construction interface", + "rationale": "module:scaffold exactly matches all required contracts with health evidence", + "requirement": { + "contracts": [ + "contract:construction_contract_lifecycle" + ], + "environment": {}, + "expected_new_entities": [ + "module:construction_interface", + "module:tui_backlog", + "test:construction_interface", + "test:tui_backlog" + ], + "expected_new_source_paths": [ + "src/rune/construction_interface.py", + "src/rune/tui_backlog.py", + "tests/test_construction_interface.py", + "tests/test_tui_backlog.py" + ], + "expected_runtime_effects": [ + "deployment:current advances" + ], + "mandatory": [], + "non_goals": [ + "HTTP server/daemon/RPC", + "MiMo-specific logic", + "external repo creation", + "full TUI implementation" + ], + "objective": "Expose Scaffolding through a stable builder-facing Construction Interface so MiMo and future builders can use Rune's construction competence without importing internal implementation modules or manually reconstructing the Need\u2192Decision\u2192Contract\u2192Verification lifecycle", + "optional": [], + "requested_permanence": "", + "source_need": "need-tranche7-interface", + "target_project": "rune", + "task_ref": "SCAFFOLD-TRANCHE-007" + }, + "research": { + "route": "NONE", + "status": "LOCAL_SOLVE" + }, + "resolution": "REUSE", + "toolchain": { + "alternatives": [], + "build_system": "", + "confidence": 0.7, + "decisive_constraints": [ + "existing_language" + ], + "evidence_refs": [], + "framework": "", + "libraries": [], + "rationale": "existing project toolchain wins (\u00a78); no recorded evidence shows significant benefit from change", + "resolution": "KEEP_EXISTING", + "runtime": "", + "selected_language": "python", + "user_approval_required": false + } + }, + "expected_runtime_effects": [ + "deployment:current advances" + ], + "scope_provenance": { + "caller_added": [ + "docs/SCAFFOLDING.md" + ], + "generated_from_affected_surface": [ + "src/rune/construction_decision.py", + "src/rune/construction_interface.py", + "src/rune/tui_backlog.py", + "tests/test_construction_interface.py", + "tests/test_tui_backlog.py" + ] + }, + "unresolved_surfaces": [ + { + "kind": "source_path", + "reason": "no authority records this path as an entity (path remains file-scope only)", + "surface": "src/rune/construction_interface.py" + }, + { + "kind": "source_path", + "reason": "no authority records this path as an entity (path remains file-scope only)", + "surface": "src/rune/tui_backlog.py" + }, + { + "kind": "source_path", + "reason": "no authority records this path as an entity (path remains file-scope only)", + "surface": "tests/test_construction_interface.py" + }, + { + "kind": "source_path", + "reason": "no authority records this path as an entity (path remains file-scope only)", + "surface": "tests/test_tui_backlog.py" + } + ], + "workflow_config_surfaces": [] + }, + "id": "contract:SCAFFOLD-TRANCHE-007", + "identities": { + "acceptance": [ + "resolution REUSE verified end-to-end" + ], + "affected_entities": [ + "contract:construction_contract_lifecycle", + "module:construction_decision", + "module:scaffold" + ], + "expected_consumers": [], + "expected_new_entities": [ + "module:construction_interface", + "module:tui_backlog", + "test:construction_interface", + "test:tui_backlog" + ], + "gap_evidence": "module:scaffold exactly matches all required contracts with health evidence", + "migration_obligations": [], + "need": "Expose Scaffolding through a stable builder-facing Construction Interface so MiMo and future builders can use Rune's construction competence without importing internal implementation modules or manually reconstructing the Need\u2192Decision\u2192Contract\u2192Verification lifecycle", + "next_action": "begin building", + "non_goals": [ + "HTTP server/daemon/RPC", + "MiMo-specific logic", + "external repo creation", + "full TUI implementation" + ], + "origin": "user tranche brief (2026-09-13)", + "regression_obligations": [], + "requirement": "Expose Scaffolding through a stable builder-facing Construction Interface so MiMo and future builders can use Rune's construction competence without importing internal implementation modules or manually reconstructing the Need\u2192Decision\u2192Contract\u2192Verification lifecycle", + "research_refs": [ + "SCAFFOLD-TRANCHE-006 pattern_quality", + "process-defect:blind-string-replace-noop", + "tranche-7-brief" + ], + "resolution": "REUSE", + "rollback_ref": "git revert", + "scope": [ + "docs/SCAFFOLDING.md", + "src/rune/construction_decision.py", + "src/rune/construction_interface.py", + "src/rune/tui_backlog.py", + "tests/test_construction_interface.py", + "tests/test_tui_backlog.py" + ], + "toolchain": { + "alternatives": [], + "build_system": "", + "confidence": 0.7, + "decisive_constraints": [ + "existing_language" + ], + "evidence_refs": [], + "framework": "", + "libraries": [], + "rationale": "existing project toolchain wins (\u00a78); no recorded evidence shows significant benefit from change", + "resolution": "KEEP_EXISTING", + "runtime": "", + "selected_language": "python", + "user_approval_required": false + }, + "verification_obligations": [ + "[pattern:capability-module-adaptation@r1] existing capability behavior preserved; original contracts remain valid", + "[pattern:capability-module-adaptation@r1] existing consumers of the adapted capability verified against their contracts", + "[pattern:capability-module-adaptation@r1] migration obligations detected and recorded if any consumer-visible interface changes", + "[pattern:capability-module-adaptation@r1] new behavior proven by tests before closure", + "[pattern:ui-tui-structural-change@r1] ui: identity survives implementation-path changes; authority never keyed by filename alone", + "new behavior proven by tests before closure" + ] + }, + "kind": "construction_contract", + "maturity": "DECLARED", + "observed_at": "2026-09-13T14:51:18Z", + "phase": "approved", + "status": "open", + "tags": [] + }, { "evidence_refs": [ "DEPLOY-MONOTONIC-001" @@ -17094,6 +20370,23 @@ "observed_at": "2026-09-13T13:24:04Z", "tags": [] }, + { + "evidence_refs": [ + "SCAFFOLD-TRANCHE-007 \u00a70" + ], + "id": "process-defect:raw-substring-signal-match", + "identities": { + "context": "Tranche 6 fresh-runtime: ui-tui-structural-change \u2192 PARTIAL + ui-component-identity-stable derived for a non-UI tranche. Root cause: signal 'ui' matched 'patterns_bu_i_l_t_in.py' as a raw substring; no word-boundary discipline at applicability or when-eval level. Second layer: tui_backlog.py legitimately matched the 'tui' pattern signal while the ui-component-identity obligation (keyed on path_contains) fired irrelevantly.", + "defect_class": "raw-substring signal matching (pattern false positive)", + "evidence": "Tranche 7 \u00a70 investigation (stored T6 decision trace + live reproduction)", + "occurrences": "1 (plus latent class across all short signals)", + "prevented_by": "boundary-aware matchers _path_matches/_entity_matches (short signals = token/prefix equality); obligation re-keyed to entities_match ui:/region:/layout: with namespace-prefix semantics" + }, + "kind": "process_defect", + "maturity": "DECLARED", + "observed_at": "2026-09-13T15:10:30Z", + "tags": [] + }, { "evidence_refs": [ "deploy-7359-log", @@ -17615,6 +20908,62 @@ "observed_at": "2026-09-13T02:16:36Z", "source": "file-added", "task": "SCAFFOLD-TRANCHE-001" + }, + { + "builder": "cli-builder", + "detail": "need-2026-09-13T16:04:17Z-cli-builder \u2192 INSUFFICIENT_EVIDENCE", + "kind": "builder_session", + "mode": "rune_internal", + "observed_at": "2026-09-13T16:04:17Z", + "operation": "submit_need" + }, + { + "builder": "cli-builder", + "detail": "need-2026-09-13T16:05:53Z-cli-builder \u2192 INSUFFICIENT_EVIDENCE", + "kind": "builder_session", + "mode": "rune_internal", + "observed_at": "2026-09-13T16:05:53Z", + "operation": "submit_need" + }, + { + "builder": "cli-builder", + "detail": "need-2026-09-13T16:06:31Z-cli-builder \u2192 INSUFFICIENT_EVIDENCE", + "kind": "builder_session", + "mode": "rune_internal", + "observed_at": "2026-09-13T16:06:31Z", + "operation": "submit_need" + }, + { + "builder": "cli-builder", + "detail": "need-2026-09-13T16:08:02Z-cli-builder \u2192 INSUFFICIENT_EVIDENCE", + "kind": "builder_session", + "mode": "rune_internal", + "observed_at": "2026-09-13T16:08:02Z", + "operation": "submit_need" + }, + { + "builder": "cli-builder", + "detail": "need-2026-09-13T16:08:04Z-cli-builder \u2192 INSUFFICIENT_EVIDENCE", + "kind": "builder_session", + "mode": "rune_internal", + "observed_at": "2026-09-13T16:08:04Z", + "operation": "submit_need" + }, + { + "builder": "cli-builder", + "detail": "need-2026-09-13T16:08:48Z-cli-builder \u2192 INSUFFICIENT_EVIDENCE", + "kind": "builder_session", + "mode": "rune_internal", + "observed_at": "2026-09-13T16:08:48Z", + "operation": "submit_need" + }, + { + "builder": "cli-builder", + "detail": "need-2026-09-13T16:09:13Z-cli-builder \u2192 INSUFFICIENT_EVIDENCE", + "kind": "builder_session", + "mode": "rune_internal", + "observed_at": "2026-09-13T16:09:13Z", + "operation": "submit_need" } ], "relationships": [ diff --git a/store/spine/current.json b/store/spine/current.json index d8f73b79..68fa2a17 100644 --- a/store/spine/current.json +++ b/store/spine/current.json @@ -2,7 +2,7 @@ "authority_generations": { "ast-import-projector": { "generation": 0, - "last_success": "2026-09-13T13:47:49Z", + "last_success": "2026-09-13T16:21:44Z", "observed": [ "consumed_by|module:abstraction|module:memory_consolidation", "consumed_by|module:abstraction|module:memory_selector", @@ -361,7 +361,7 @@ }, "deploy-identity-projector": { "generation": 1, - "last_success": "2026-09-13T13:47:49Z", + "last_success": "2026-09-13T16:21:44Z", "observed": [ "deployed_as|module:abstraction|deployment:current", "deployed_as|module:adaptive_router|deployment:current", @@ -382,6 +382,8 @@ "deployed_as|module:complexity_scorer|deployment:current", "deployed_as|module:connection_pool|deployment:current", "deployed_as|module:construction_decision|deployment:current", + "deployed_as|module:construction_patterns_builtin|deployment:current", + "deployed_as|module:construction_pattern|deployment:current", "deployed_as|module:context_broker|deployment:current", "deployed_as|module:context_pressure|deployment:current", "deployed_as|module:contracts|deployment:current", @@ -502,7 +504,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code", "self-model" @@ -522,7 +524,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [] }, { @@ -539,7 +541,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [] }, { @@ -556,7 +558,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [] }, { @@ -573,7 +575,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [] }, { @@ -590,7 +592,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [] }, { @@ -607,7 +609,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [] }, { @@ -624,7 +626,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [] }, { @@ -640,7 +642,41 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", + "tags": [] + }, + { + "evidence_refs": [ + "SCAFFOLD-TRANCHE-007", + "source:construction_interface.py", + "tests/test_construction_interface.py" + ], + "id": "module:construction_interface", + "identities": { + "path": "src/rune/construction_interface.py", + "role": "builder-facing Construction Interface (Python API + JSON CLI)", + "source": "src/rune/construction_interface.py" + }, + "kind": "module", + "maturity": "EXERCISED", + "observed_at": "2026-09-13T16:21:44Z", + "tags": [] + }, + { + "evidence_refs": [ + "SCAFFOLD-TRANCHE-007", + "source:tui_backlog.py", + "tests/test_tui_backlog.py" + ], + "id": "module:tui_backlog", + "identities": { + "path": "src/rune/tui_backlog.py", + "role": "durable TUI Upgrade Backlog ledger", + "source": "src/rune/tui_backlog.py" + }, + "kind": "module", + "maturity": "EXERCISED", + "observed_at": "2026-09-13T16:21:44Z", "tags": [] }, { @@ -649,14 +685,14 @@ ], "id": "deployment:current", "identities": { - "deployed_at": "2026-09-13T13:26:14Z", - "deployed_sha": "80f10b9be71f", - "deployed_version": "0.66.40", + "deployed_at": "2026-09-13T14:06:33Z", + "deployed_sha": "1bb4ea86b80d", + "deployed_version": "0.66.41", "observed_from": "/mnt/workdrive/rune-code/current" }, "kind": "deployment_surface", "maturity": "LIVE_PROVEN", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [] }, { @@ -672,7 +708,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -690,7 +726,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -708,7 +744,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -726,7 +762,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -744,7 +780,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -762,7 +798,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -780,7 +816,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -798,7 +834,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -816,7 +852,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -834,7 +870,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -852,7 +888,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -870,7 +906,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -888,7 +924,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -906,7 +942,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -924,7 +960,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -942,7 +978,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -960,7 +996,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -978,7 +1014,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -996,7 +1032,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1014,7 +1050,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1032,7 +1068,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1050,7 +1086,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1068,7 +1104,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1086,7 +1122,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1104,7 +1140,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1122,7 +1158,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1139,7 +1175,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1157,7 +1193,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1175,7 +1211,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1193,7 +1229,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1210,7 +1246,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1228,7 +1264,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1246,7 +1282,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1263,7 +1299,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1280,7 +1316,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1298,7 +1334,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1315,7 +1351,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1333,7 +1369,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1350,7 +1386,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1367,7 +1403,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1383,7 +1419,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1399,7 +1435,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1415,7 +1451,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1433,7 +1469,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1451,7 +1487,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1469,7 +1505,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1487,7 +1523,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1505,7 +1541,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1523,7 +1559,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1541,7 +1577,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1559,7 +1595,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1577,7 +1613,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1595,7 +1631,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1613,7 +1649,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1631,7 +1667,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1648,7 +1684,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1665,7 +1701,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1682,7 +1718,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1700,7 +1736,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1717,7 +1753,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1734,7 +1770,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1752,7 +1788,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1770,7 +1806,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1788,7 +1824,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1806,7 +1842,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1823,7 +1859,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1841,7 +1877,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1858,7 +1894,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1875,7 +1911,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1893,7 +1929,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1911,7 +1947,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1929,7 +1965,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1946,7 +1982,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1964,7 +2000,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1982,7 +2018,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -1999,7 +2035,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2016,7 +2052,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2034,7 +2070,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2052,7 +2088,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2070,7 +2106,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2088,7 +2124,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2106,7 +2142,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2124,7 +2160,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2142,7 +2178,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2160,7 +2196,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2178,7 +2214,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2196,7 +2232,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2214,7 +2250,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2232,7 +2268,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2250,7 +2286,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2268,7 +2304,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2286,7 +2322,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2304,7 +2340,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2322,7 +2358,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2340,7 +2376,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2357,7 +2393,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2373,7 +2409,7 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2390,7 +2426,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2406,7 +2442,7 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2422,7 +2458,7 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2438,7 +2474,7 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2455,7 +2491,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2471,7 +2507,7 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2488,7 +2524,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2504,7 +2540,7 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2520,7 +2556,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2536,7 +2572,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2552,7 +2588,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T13:47:49Z", + "observed_at": "2026-09-13T16:21:44Z", "tags": [ "code" ] @@ -2821,7 +2857,7 @@ "tags": [] } ], - "generated_at": "2026-09-13T13:47:49Z", + "generated_at": "2026-09-13T16:21:44Z", "observations": [ { "authority": "cli-invocation", @@ -3504,6 +3540,86 @@ "observed_at": "2026-09-13T13:47:49Z", "observed_from": "/mnt/workdrive/rune-code/current" }, + { + "deployed_at": "2026-09-13T14:06:33Z", + "deployed_sha": "1bb4ea86b80d", + "deployed_version": "0.66.41", + "kind": "deployed_identity", + "observed_at": "2026-09-13T14:50:21Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T14:06:33Z", + "deployed_sha": "1bb4ea86b80d", + "deployed_version": "0.66.41", + "kind": "deployed_identity", + "observed_at": "2026-09-13T15:10:51Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T14:06:33Z", + "deployed_sha": "1bb4ea86b80d", + "deployed_version": "0.66.41", + "kind": "deployed_identity", + "observed_at": "2026-09-13T16:08:25Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T14:06:33Z", + "deployed_sha": "1bb4ea86b80d", + "deployed_version": "0.66.41", + "kind": "deployed_identity", + "observed_at": "2026-09-13T16:09:08Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T14:06:33Z", + "deployed_sha": "1bb4ea86b80d", + "deployed_version": "0.66.41", + "kind": "deployed_identity", + "observed_at": "2026-09-13T16:11:37Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T14:06:33Z", + "deployed_sha": "1bb4ea86b80d", + "deployed_version": "0.66.41", + "kind": "deployed_identity", + "observed_at": "2026-09-13T16:13:55Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T14:06:33Z", + "deployed_sha": "1bb4ea86b80d", + "deployed_version": "0.66.41", + "kind": "deployed_identity", + "observed_at": "2026-09-13T16:14:43Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T14:06:33Z", + "deployed_sha": "1bb4ea86b80d", + "deployed_version": "0.66.41", + "kind": "deployed_identity", + "observed_at": "2026-09-13T16:15:07Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T14:06:33Z", + "deployed_sha": "1bb4ea86b80d", + "deployed_version": "0.66.41", + "kind": "deployed_identity", + "observed_at": "2026-09-13T16:15:32Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T14:06:33Z", + "deployed_sha": "1bb4ea86b80d", + "deployed_version": "0.66.41", + "kind": "deployed_identity", + "observed_at": "2026-09-13T16:21:44Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, { "deployed_sha": "2731db03f4bd", "deployed_version": "0.66.33", @@ -3577,6 +3693,28 @@ "to": "deployment:current", "type": "deployed_as" }, + { + "authority": "deploy-identity-projector", + "evidence_refs": [ + "deployed-tree:1bb4ea86b80d" + ], + "from": "module:construction_pattern", + "observed_at": "2026-09-13T14:50:21Z", + "status": "CURRENT", + "to": "deployment:current", + "type": "deployed_as" + }, + { + "authority": "deploy-identity-projector", + "evidence_refs": [ + "deployed-tree:1bb4ea86b80d" + ], + "from": "module:construction_patterns_builtin", + "observed_at": "2026-09-13T14:50:21Z", + "status": "CURRENT", + "to": "deployment:current", + "type": "deployed_as" + }, { "authority": "deploy-identity-projector", "evidence_refs": [ @@ -3704,6 +3842,24 @@ "to": "subsystem:perception", "type": "belongs_to" }, + { + "evidence_refs": [ + "SCAFFOLD-TRANCHE-007" + ], + "from": "module:construction_interface", + "observed_at": "2026-09-13T16:15:06Z", + "to": "subsystem:perception", + "type": "belongs_to" + }, + { + "evidence_refs": [ + "SCAFFOLD-TRANCHE-007" + ], + "from": "module:tui_backlog", + "observed_at": "2026-09-13T16:15:06Z", + "to": "subsystem:perception", + "type": "belongs_to" + }, { "evidence_refs": [ "ast-import:abstraction" diff --git a/tests/test_construction_interface.py b/tests/test_construction_interface.py new file mode 100644 index 00000000..5c9d0ac6 --- /dev/null +++ b/tests/test_construction_interface.py @@ -0,0 +1,489 @@ +"""test_construction_interface.py — SCAFFOLD-TRANCHE-007 test plans +§29 (interface core), §30 (authority), §31 (pattern precision — integration), +§17 (provider independence).""" + +import json +import os +import subprocess +import sys + +import pytest + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src")) + +from rune import construction_interface as ci # noqa: E402 +from rune import structural_store as ss # noqa: E402 +from rune import scaffold as sc # noqa: E402 + +ROOT = os.path.join(os.path.dirname(__file__), "..") + + +def _fixture_authorities(): + """A self-contained project-scaffold authority (external-project mode + without any real external repo — §16).""" + spine = ss.new_doc() + ss.add_entity( + spine, id="capability:exporter", kind="capability", identities={}, maturity="WIRED", evidence_refs=["f"] + ) + ss.add_entity(spine, id="contract:csv_export", kind="contract", identities={}, evidence_refs=["f"]) + ss.add_relationship( + spine, type="implements", from_id="capability:exporter", to_id="contract:csv_export", evidence_refs=["f"] + ) + return spine + + +def _iface(tmp_path, builder="test-builder", with_authority=True): + store = str(tmp_path / ".rune" / "scaffold") + iface = ci.ConstructionInterface(builder=builder, project_store=store, project_id="fixture-proj") + if with_authority: + # inject the fixture authority INTO the fixture scaffold store so + # external-project mode has structural truth to consult + iface.scaffold.init(purpose="fixture") + doc = iface.scaffold.load() + for e in _fixture_authorities()["entities"]: + doc["entities"].append(json.loads(json.dumps(e))) + for r in _fixture_authorities()["relationships"]: + doc["relationships"].append(json.loads(json.dumps(r))) + iface.scaffold.save(doc) + return iface + + +def _submit(iface, **kw): + payload = dict( + objective="persistent project export", + constraints={"contracts": ["contract:csv_export"]}, + affected_surface=[], + evidence_refs=["x"], + approval_context="covered by fixture authority", + ) + payload.update(kw) + return iface.submit_need(**payload) + + +# ── §29 interface core ────────────────────────────────────────────────────── + + +def test_29a_submit_need(tmp_path): + iface = _iface(tmp_path) + env = _submit(iface) + assert env["schema"] == ci.INTERFACE_SCHEMA_VERSION + assert env["operation"] == "submit_need" + assert env["success"] + assert env["ids"]["need_id"] + assert env["state"]["resolution"] == "REUSE" + assert env["state"]["builder"] == "test-builder" + + +def test_29b_retrieve_decision(tmp_path): + iface = _iface(tmp_path) + env = _submit(iface) + cid = env["ids"]["contract_id"] + d = iface.inspect_decision(cid) + assert d["success"] + assert d["state"]["resolution"] == "REUSE" + assert d["state"]["toolchain"]["selected_language"] == "python" + assert any(f["candidate"] == "capability:exporter" for f in d["state"]["fits"]) + + +def test_29c_retrieve_contract(tmp_path): + iface = _iface(tmp_path) + cid = _submit(iface)["ids"]["contract_id"] + r = iface.resume(cid) + assert r["success"] + assert r["state"]["phase"] == "draft" + assert r["state"]["need"]["objective"] == "persistent project export" + + +def test_29d_allowed_scope(tmp_path): + iface = _iface(tmp_path) + cid = _submit(iface)["ids"]["contract_id"] + s = iface.get_scope(cid) + assert s["success"] + assert "allowed_paths" in s["state"] + assert "affected_structural_entities" in s["state"] + assert "unresolved_surfaces" in s["state"] + assert "layout_obligations" in s["state"] + + +def test_29e_obligations(tmp_path): + iface = _iface(tmp_path) + cid = _submit(iface)["ids"]["contract_id"] + o = iface.get_obligations(cid) + assert o["success"] + assert o["state"]["obligations"] + provs = {x["provenance"] for x in o["state"]["obligations"]} + assert provs <= {"STRUCTURAL", "PATTERN", "LAYOUT_CONTRACT"} + + +def test_29f_report_observation(tmp_path): + iface = _iface(tmp_path) + cid = _submit(iface)["ids"]["contract_id"] + r = iface.report_observation(cid, [{"entity": "capability:exporter", "detail": "exercised by new test"}]) + assert r["success"] + assert r["state"]["recorded"] == 1 + assert "cannot self-certify" not in r["state"]["note"] + assert "determined by Scaffolding gates" in r["state"]["note"] + + +def test_29g_verification_state(tmp_path): + iface = _iface(tmp_path) + cid = _submit(iface)["ids"]["contract_id"] + v = iface.verify(cid, changed_files=["src/new_thing.py"]) + assert v["success"] or v["errors"] + assert "scope_check" in v["state"] or v["errors"] + + +def test_29h_resume_fresh_process(tmp_path): + """§11 THE MAJOR ACCEPTANCE CONDITION: a fresh builder process resumes + from contract id alone.""" + iface = _iface(tmp_path, builder="first-builder") + env = iface.submit_need( + "persistent project export", + constraints={"contracts": ["contract:csv_export"]}, + affected_surface=["src/export_module.py"], + evidence_refs=["x"], + approval_context="covered by fixture authority", + ) + cid = env["ids"]["contract_id"] + iface.transition(cid, "approved") + script = f""" +import sys, json +sys.path.insert(0, {os.path.join(ROOT, "src")!r}) +from rune import construction_interface as ci +iface = ci.ConstructionInterface(builder="fresh-builder", + project_store={str(tmp_path / ".rune" / "scaffold")!r}, + project_id="fixture-proj") +env = iface.resume({cid!r}) +print(json.dumps(env)) +""" + r = subprocess.run([sys.executable, "-c", script], capture_output=True, text=True, timeout=60) + assert r.returncode == 0, r.stderr + env = json.loads(r.stdout) + assert env["success"] + st = env["state"] + assert st["need"]["objective"] == "persistent project export" + assert st["decision"]["resolution"] == "REUSE" + assert st["phase"] == "approved" + assert st["scope"] + assert st["obligations"] + assert st["next_action"] + assert st["builder"] == "fresh-builder" # this session's identity + + +def test_29i_json_roundtrip(tmp_path): + iface = _iface(tmp_path) + env = _submit(iface) + blob = json.dumps(env) + back = json.loads(blob) + assert back["operation"] == env["operation"] + assert back["state"]["resolution"] == env["state"]["resolution"] + + +def test_29j_unknown_contract(tmp_path): + iface = _iface(tmp_path) + for op in ( + lambda: iface.inspect_decision("nope"), + lambda: iface.get_scope("nope"), + lambda: iface.get_obligations("nope"), + lambda: iface.resume("nope"), + ): + env = op() + assert not env["success"] + assert env["errors"][0]["error"] == ci.Errors.UNKNOWN_CONTRACT + + +def test_29k_approval_required(tmp_path): + iface = _iface(tmp_path) + env = iface.submit_need( + "build a whole new application from scratch", + constraints={}, + affected_surface=[], + evidence_refs=["x"], + approval_context="", + ) # no approval context + # new-capability construction without approval context → gate fires + if env["state"]["approval"]["required"]: + assert env["errors"] + assert any(e["error"] == ci.Errors.APPROVAL_REQUIRED for e in env["errors"]) + else: + # covered path must say so + assert env["state"]["approval"]["covered_by"] or not env["state"]["approval"]["reasons"] + + +def test_29l_scope_violation_refused(tmp_path): + iface = _iface(tmp_path) + env = iface.submit_need( + "persistent project export", + constraints={"contracts": ["contract:csv_export"]}, + affected_surface=["src/export_module.py"], # scoped surface + evidence_refs=["x"], + approval_context="covered by fixture authority", + ) + cid = env["ids"]["contract_id"] + iface.transition(cid, "approved") + iface.transition(cid, "building") + iface.transition(cid, "verifying") + v = iface.verify(cid, changed_files=["src/completely/unrelated.py"]) + # out-of-scope change must surface as a violation, never green + assert v["state"]["scope_check"]["verdict"] == "red" or any( + e["error"] == ci.Errors.SCOPE_VIOLATION for e in v["errors"] + ) + + +def test_29m_failed_verification_cannot_close(tmp_path): + iface = _iface(tmp_path) + cid = _submit(iface)["ids"]["contract_id"] + # contract is in draft — closure must be refused by the phase map + env = iface.close(cid, observed_evidence=[{"entity": "capability:exporter", "detail": "claimed done"}]) + assert not env["success"] + assert env["errors"][0]["error"] == ci.Errors.VERIFICATION_FAILED + + +def test_29n_stale_state_store_write(tmp_path): + """STORE_WRITE_FAILED: an unwritable store surfaces as an explicit + error, not a silent lie.""" + iface = _iface(tmp_path) + # break the store path + iface.scaffold.current = "/proc/nonexistent/current.json" + env = iface.report_observation("any", [{"entity": "x"}]) + assert not env["success"] or env["errors"] + + +# ── §30 authority ──────────────────────────────────────────────────────────── + + +def test_30a_rune_mode_reads_rune_authority(): + """Rune-internal mode consults the real Spine store (read-only).""" + iface = ci.ConstructionInterface(builder="t") + auth = iface._authorities() + assert "rune_spine" in auth + assert iface.mode == "rune_internal" + + +def test_30b_external_mode_reads_project_scaffold(tmp_path): + iface = _iface(tmp_path) + auth = iface._authorities() + assert "rune_spine" not in auth # external project has no Rune Spine + assert iface.mode == "external_project" + assert auth["project_scaffold"]["entities"] + + +def test_30c_builder_cannot_rewrite_structural_authority(): + """The interface exposes NO operation that writes structural truth. + (The only writes are contract/observation/session records in the + scaffold store — never Spine entities.)""" + public = [m for m in dir(ci.ConstructionInterface) if not m.startswith("_")] + for forbidden in ("rewrite_spine", "set_entity", "promote", "supersede", "build_spine", "add_relationship"): + assert forbidden not in public + + +def test_30d_builder_cannot_override_user_locked(tmp_path): + iface = _iface(tmp_path) + from rune import layout_contract as lc + + doc = iface.scaffold.load() + lc.define_region(doc, "footer-bar", provenance="scaffold") + lc.bind_component(doc, "version_display", "footer-bar", lock=True, provenance="user", order=0) + iface.scaffold.save(doc) + # no interface operation amends layout at all + public = [m for m in dir(ci.ConstructionInterface) if not m.startswith("_")] + assert not any("layout" in m and "amend" in m for m in public) + # and the direct amend path still refuses non-user authority + doc2 = iface.scaffold.load() + with pytest.raises(ValueError): + lc.amend_layout_contract( + doc2, "version_display", new_region="header", authorized_by="builder", reason="prefer it" + ) + + +def test_30e_builder_cannot_self_certify(tmp_path): + iface = _iface(tmp_path) + cid = _submit(iface)["ids"]["contract_id"] + # no interface operation takes "done=True" + v = iface.verify(cid) + assert "cannot self-certify" in v["state"]["remaining"] + # closure from draft fails + env = iface.close(cid, observed_evidence=[{"entity": "x"}]) + assert not env["success"] + + +def test_30f_builder_identity_neutral(tmp_path): + """§17: two builders with identical input get identical construction + behavior (identity recorded, semantics unchanged).""" + results = [] + for b in ("mimo", "kimi", "deterministic-script"): + iface = _iface(tmp_path / b, builder=b) + env = _submit(iface) + results.append( + ( + env["state"]["resolution"], + env["state"]["completeness"], + env["state"]["toolchain"] if "toolchain" in env["state"] else None, + [o["id"] for o in iface.get_obligations(env["ids"]["contract_id"])]["obligations"] if False else None, + ) + ) + resolutions = {r[0] for r in results} + completions = {r[1] for r in results} + assert len(resolutions) == 1 and len(completions) == 1 + + +# ── §31 pattern precision (integration through the interface) ─────────────── + + +def test_31a_ui_task_derives_ui_obligations(tmp_path): + iface = _iface(tmp_path) + from rune import layout_contract as lc + + doc = iface.scaffold.load() + lc.define_region(doc, "footer-bar", provenance="scaffold") + lc.bind_component(doc, "version_display", "footer-bar", provenance="scaffold") + iface.scaffold.save(doc) + env = iface.submit_need( + "adjust the tui version widget", + constraints={}, + affected_surface=["ui:version_display"], + evidence_refs=["x"], + approval_context="covered", + ) + cid = env["ids"]["contract_id"] + o = iface.get_obligations(cid) + ids = {x["id"] for x in o["state"]["obligations"]} + assert any("ui-" in i or "layout:" in i for i in ids) + + +def test_31b_non_ui_task_no_active_ui_obligations(tmp_path): + """§0 regression through the interface: non-UI work gets NO active + ui-* obligations.""" + iface = _iface(tmp_path) + env = _submit(iface) + cid = env["ids"]["contract_id"] + o = iface.get_obligations(cid) + ui_active = [x for x in o["state"]["obligations"] if x["id"].startswith("ui-")] + assert ui_active == [] + + +def test_31c_release_task_derives_release_obligations(tmp_path): + iface = _iface(tmp_path) + # the fixture authority needs the deploy structural truth for fit + doc = iface.scaffold.load() + ss.add_entity( + doc, + id="module:deploy_stage", + kind="module", + identities={"path": "scripts/deploy_stage.py"}, + maturity="WIRED", + evidence_refs=["f"], + ) + ss.add_entity(doc, id="contract:monotonic_promotion", kind="contract", identities={}, evidence_refs=["f"]) + ss.add_relationship( + doc, type="implements", from_id="module:deploy_stage", to_id="contract:monotonic_promotion", evidence_refs=["f"] + ) + iface.scaffold.save(doc) + env = iface.submit_need( + "repair the deploy promotion ordering", + constraints={"contracts": ["contract:monotonic_promotion"]}, + affected_surface=["scripts/deploy_stage.py", "scripts/deploy_promotion.py"], + evidence_refs=["x"], + approval_context="covered", + ) + cid = env["ids"]["contract_id"] + o = iface.get_obligations(cid) + ids = {x["id"] for x in o["state"]["obligations"]} + assert "rel-monotonic-promotion" in ids or any("rel-" in i for i in ids) + + +def test_31d_non_release_task_no_promotion_obligations(tmp_path): + iface = _iface(tmp_path) + env = _submit(iface) + cid = env["ids"]["contract_id"] + o = iface.get_obligations(cid) + rel_active = [x for x in o["state"]["obligations"] if x["id"].startswith("rel-")] + assert rel_active == [] + + +def test_31g_partial_pattern_inspectable_without_activation(tmp_path): + iface = _iface(tmp_path) + env = iface.submit_need( + "adjust the tui backlog plumbing", + constraints={"contracts": ["contract:csv_export"]}, + affected_surface=["src/rune/tui_backlog.py", "src/export_module.py"], + evidence_refs=["x"], + approval_context="covered", + ) + cid = env["ids"]["contract_id"] + d = iface.inspect_decision(cid) + considered = {a["pattern"]: a["verdict"] for a in d["state"]["patterns_considered"]} + # PARTIAL patterns remain VISIBLE as candidates (inspectable) + assert considered + # but their UI obligations did not enter the ACTIVE obligation set + o = iface.get_obligations(cid) + ui_active = [x for x in o["state"]["obligations"] if x["id"].startswith("ui-")] + assert ui_active == [] + + +# ── CLI transport ──────────────────────────────────────────────────────────── + + +def test_cli_roundtrip(tmp_path): + store = tmp_path / ".rune" / "scaffold" + iface = ci.ConstructionInterface(builder="seed", project_store=str(store), project_id="cli-fixture") + iface.scaffold.init(purpose="cli") + doc = iface.scaffold.load() + for e in _fixture_authorities()["entities"]: + doc["entities"].append(json.loads(json.dumps(e))) + for r in _fixture_authorities()["relationships"]: + doc["relationships"].append(json.loads(json.dumps(r))) + iface.scaffold.save(doc) + env = { + "objective": "persistent project export", + "constraints": {"contracts": ["contract:csv_export"]}, + "affected_surface": [], + "evidence_refs": ["x"], + "approval_context": "covered", + } + r = subprocess.run( + [ + sys.executable, + "-m", + "rune.construction_interface", + "submit-need", + json.dumps(env), + "--builder", + "cli-builder", + "--project-store", + str(store), + "--project-id", + "cli-fixture", + ], + capture_output=True, + text=True, + timeout=120, + env={**os.environ, "PYTHONPATH": os.path.join(ROOT, "src")}, + ) + assert r.returncode == 0, r.stderr[-400:] + out = json.loads(r.stdout[r.stdout.index("{") :]) + assert out["success"] + assert out["state"]["resolution"] == "REUSE" + # resume through the CLI from the returned contract id + r2 = subprocess.run( + [ + sys.executable, + "-m", + "rune.construction_interface", + "resume", + out["ids"]["contract_id"], + "--builder", + "cli-2", + "--project-store", + str(store), + "--project-id", + "cli-fixture", + ], + capture_output=True, + text=True, + timeout=120, + env={**os.environ, "PYTHONPATH": os.path.join(ROOT, "src")}, + ) + assert r2.returncode == 0, r2.stderr[-400:] + out2 = json.loads(r2.stdout[r2.stdout.index("{") :]) + assert out2["state"]["need"]["objective"] == "persistent project export" diff --git a/tests/test_tui_backlog.py b/tests/test_tui_backlog.py new file mode 100644 index 00000000..70d3d268 --- /dev/null +++ b/tests/test_tui_backlog.py @@ -0,0 +1,118 @@ +"""test_tui_backlog.py — SCAFFOLD-TRANCHE-007 §32 test plan.""" + +import os +import sys + +import pytest + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src")) + +from rune import structural_store as ss # noqa: E402 +from rune import tui_backlog as tb # noqa: E402 + + +def _doc(): + return ss.new_doc() + + +# §32 A-E: roundtrip with all retained fields +def test_a_e_backlog_item_roundtrip(tmp_path): + doc = _doc() + tb.add_backlog_item( + doc, + "construction-contract-view", + feature="scaffolding/contracts", + desired_behavior="display active construction contract with phase, " + "scope, obligations; navigate between contracts", + why="builder sessions need operator visibility into governed builds", + projection="BOTH", + dependencies=["construction_interface"], + priority="high", + authority_source="tranche-7-brief §23", + evidence_refs=["SCAFFOLD-TRANCHE-006"], + ) + ss.save(doc, tmp_path / "d.json") + doc2 = ss.load(tmp_path / "d.json") + e = tb.get_backlog_item(doc2, "construction-contract-view") + assert e["kind"] == "tui_backlog_item" + ident = e["identities"] + # B. originating feature retained + assert ident["feature"] == "scaffolding/contracts" + # C. display/control classification retained + assert ident["projection"] == "BOTH" + # D. authority source retained + assert ident["authority_source"] == "tranche-7-brief §23" + # E. status/priority retained + assert ident["status"] == "OPEN" and ident["priority"] == "high" + + +def test_f_backend_feature_records_tui_none_truthfully(tmp_path): + doc = _doc() + d = tb.record_tui_projection_decision( + doc, + "module:deployment_race_repair", + projection="NONE", + rationale="release-path internals have no user-surface; operator visibility flows through CI/deploy results", + source_contract="DEPLOY-MONOTONIC-001", + ) + assert d["identities"]["projection"] == "NONE" + assert "no user-surface" in d["identities"]["rationale"] + + +def test_g_future_feature_adds_requirement_without_schema_rewrite(tmp_path): + doc = _doc() + # an unforeseen projection kind rides in ext (open-world) + from rune import structural_store + + e = tb.add_backlog_item(doc, "future-thing", feature="x", desired_behavior="y", why="z", projection="INSPECTION") + e.setdefault("ext", {})["novice_field"] = {"someday": True} + ss.save(doc, tmp_path / "d.json") + doc2 = ss.load(tmp_path / "d.json") + item = tb.get_backlog_item(doc2, "future-thing") + assert item["ext"]["novice_field"] == {"someday": True} + + +def test_h_backlog_never_becomes_structural_authority(tmp_path): + """§25: backlog items live in the maintenance ledger namespace; they are + not structural entities and never enter impact frontiers.""" + doc = _doc() + tb.add_backlog_item(doc, "x", feature="f", desired_behavior="d", why="w") + # kind check + kinds = {e["kind"] for e in doc["entities"]} + assert "tui_backlog_item" in kinds + # impact frontier ignores it + from rune import structural_store as ss + + fr = ss.impact_frontier(doc, ["tui-backlog:x"]) + # the seed itself appears at level0 (any frontier includes its seed); + # the §25 invariant is NO PROPAGATION: no obligations, no contracts, + # no verification surfaces derive from a backlog item + assert fr.get("level1_obligations") == [] + assert fr.get("contracts") == [] + assert fr.get("level2_verification") == [] + + +def test_status_update(tmp_path): + doc = _doc() + tb.add_backlog_item(doc, "x", feature="f", desired_behavior="d", why="w") + tb.update_backlog_status(doc, "x", "PLANNED", evidence_ref="planning-t7") + assert tb.get_backlog_item(doc, "x")["identities"]["status"] == "PLANNED" + with pytest.raises(ValueError): + tb.update_backlog_status(doc, "x", "SOMEDAY") + with pytest.raises(ValueError): + tb.update_backlog_status(doc, "ghost", "OPEN") + + +def test_list_filters(tmp_path): + doc = _doc() + tb.add_backlog_item(doc, "a", feature="f1", desired_behavior="d", why="w", projection="INSPECTION", status="OPEN") + tb.add_backlog_item(doc, "b", feature="f2", desired_behavior="d", why="w", projection="CONTROL", status="DONE") + assert len(tb.list_backlog(doc)) == 2 + assert len(tb.list_backlog(doc, status="OPEN")) == 1 + assert len(tb.list_backlog(doc, projection="CONTROL")) == 1 + + +def test_projection_validation(): + doc = _doc() + with pytest.raises(ValueError): + tb.add_backlog_item(doc, "x", feature="f", desired_behavior="d", why="w", projection="SCREENSHOT")