diff --git a/config/umbrellas.json b/config/umbrellas.json index 5c5483e9..c1c2a82e 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-13T03:10:20Z", + "generated_at": "2026-09-13T03:43:44Z", "umbrellas": { "capability": { "description": "Tool selection and execution authority", @@ -218,6 +218,7 @@ "capability_fit", "cognitive_budgeter", "complexity_scorer", + "construction_decision", "context_broker", "context_pressure", "layout_contract", diff --git a/src/rune/construction_decision.py b/src/rune/construction_decision.py new file mode 100644 index 00000000..b23ce50c --- /dev/null +++ b/src/rune/construction_decision.py @@ -0,0 +1,455 @@ +"""construction_decision.py — live Need → Decision → Construction Contract. + +SCAFFOLD-TRANCHE-004: the adoption layer that turns the Tranche 2/3 +mechanisms into a durable procedure Rune no longer has to remember. + + NEED (references Task/Intent — never duplicates them) + ↓ normalize_need() missing info is NOT invented + ↓ discover + fit per authority (deterministic; Spine + Project Scaffold) + ↓ resolve per authority + merge (capability_fit resolution surface) + ↓ resolve_toolchain() (existing project toolchain wins) + ↓ layout obligations (LOCKED authority inherited) + ↓ approval gate (material changes → user) + ↓ DecisionTrace (durable, model-independent) + ↓ generate_contract() (populated from the trace) + +Boundaries (brief §3, §32, §33): + - NOT a task engine: Need carries a reference to the existing Task/Intent + authority; Scaffolding never becomes the "why" authority. + - NOT a workflow engine: one decision function, one trace object. + - NOT a research pipeline: insufficient evidence routes to a recorded + research path (seam) — the live ADAPT wiring is a recorded route, not + an executed pipeline call (honest seam, §6). + - NOT a structural authority: it reads Spine/Project Scaffold and + WRITES only Construction Contracts + decision traces. + - BUILD_NEW is never a fallback (§8): merge precedence and the + insufficient-evidence invariant of capability_fit enforce it. +""" + +from __future__ import annotations + +from rune import capability_fit as cf +from rune import toolchain as tc +from rune.structural_store import relationships + +__all__ = ["Need", "make_decision", "generate_contract", "merge_resolutions"] + + +# ── Need intake (§4) ─────────────────────────────────────────────────────── + + +class Need: + """Construction-decision input. References — does not copy — the + existing Task/Intent authority (`task_ref` is a pointer, not a copy). + Carries no task state of its own: it is WHY-adjacent input to Scaffolding, + not a backlog entry.""" + + def __init__( + self, + need_id: str, + objective: str, + *, + origin: str = "user", + project: str = "rune", + task_ref: str = "", + constraints: dict | None = None, + affected_surface: list[str] | None = None, + evidence_refs: list[str] | None = None, + approval_context: str = "", + requested_permanence: str = "", + ): + if not need_id: + raise ValueError("need_id required") + if not objective: + raise ValueError("objective (required effect) required — do not normalize a need we cannot state") + self.need_id = need_id + self.objective = objective + self.origin = origin + self.project = project + self.task_ref = task_ref + self.constraints = dict(constraints or {}) + self.affected_surface = list(affected_surface or []) + self.evidence_refs = list(evidence_refs or []) + self.approval_context = approval_context + self.requested_permanence = requested_permanence + + def to_dict(self) -> dict: + return { + "need_id": self.need_id, + "objective": self.objective, + "origin": self.origin, + "project": self.project, + "task_ref": self.task_ref, + "constraints": dict(self.constraints), + "affected_surface": list(self.affected_surface), + "evidence_refs": list(self.evidence_refs), + "approval_context": self.approval_context, + "requested_permanence": self.requested_permanence, + } + + +# ── requirement normalization (§5) ───────────────────────────────────────── + + +def normalize_need(need: Need) -> tuple[cf.CapabilityRequirement, list[str]]: + """Derive the CapabilityRequirement WITHOUT inventing facts. Contracts + may come from explicit constraints (`contracts` key) or from contract- + shaped entries on the affected surface (`contract:x` ids). Everything + not determinable lands in `missing` — the caller records it and the + resolution degrades to INSUFFICIENT_EVIDENCE rather than guessing.""" + contracts = sorted(need.constraints.get("contracts", [])) + contracts += sorted(a for a in need.affected_surface if a.startswith("contract:")) + missing = [] + if need.constraints.get("environment"): + pass # carried through + else: + missing.append("environment") + if not need.evidence_refs: + missing.append("evidence_refs") + req = cf.CapabilityRequirement( + need.objective, + contracts=contracts, + environment=need.constraints.get("environment", {}), + target_project=need.project, + source_need=need.need_id, + task_ref=need.task_ref, + requested_permanence=need.requested_permanence, + **{k: v for k, v in need.constraints.items() if k not in ("contracts", "environment")}, + ) + return req, missing + + +# ── research routing seam (§6 — honest: recorded route, not execution) ───── + + +def research_route(req: cf.CapabilityRequirement, decision: dict) -> dict: + """Record which evidence path the decision needs. This is a SEAM: the + live ADAPT interface is not yet wired for direct invocation, so the + route is recorded on the trace for the orchestrating session to act on. + NOT claimed as executed research.""" + if decision["resolution"] == "INSUFFICIENT_EVIDENCE": + return { + "route": "TARGETED_EVIDENCE_PROBE", + "question": f"what satisfies: {req.objective[:120]}", + "status": "RECORDED_NOT_EXECUTED", + } + if decision["resolution"] == "ACQUIRE_EXTERNAL": + return { + "route": "FULL_RESEARCH_PIPELINE", + "question": f"external acquisition options for: {req.objective[:120]}", + "status": "RECORDED_NOT_EXECUTED", + } + return {"route": "NONE", "status": "LOCAL_SOLVE"} + + +# ── resolution merge across authorities ───────────────────────────────────── + +_PRECEDENCE = [ + "SATISFIED", + "REUSE", + "COMPOSE", + "ADAPT_EXISTING", + "CONFIGURE", + "ACQUIRE_EXTERNAL", + "INSUFFICIENT_EVIDENCE", + "BUILD_NEW", +] + + +def merge_resolutions(results: list[dict]) -> dict: + """Merge per-authority resolution results. Precedence: a concrete + reuse/compose/adapt verdict from any authority wins over + INSUFFICIENT_EVIDENCE from another; BUILD_NEW can only result when NO + authority produced a better verdict AND positive gap evidence exists — + it is never a fallback across merges (§8).""" + if not results: + return {"resolution": "INSUFFICIENT_EVIDENCE", "rationale": "no authority consulted"} + best = min(results, key=lambda r: _PRECEDENCE.index(r["resolution"])) + merged = dict(best) + merged["per_authority"] = [{"authority": r.get("authority", ""), "resolution": r["resolution"]} for r in results] + if best["resolution"] == "BUILD_NEW" and len(results) > 1: + # only honest if every authority independently agrees + if any(r["resolution"] != "BUILD_NEW" for r in results): + weaker = [r for r in results if r["resolution"] == "INSUFFICIENT_EVIDENCE"] + if weaker: + merged = dict(weaker[0]) + merged["per_authority"] = [ + {"authority": r.get("authority", ""), "resolution": r["resolution"]} for r in results + ] + merged["rationale"] = ( + "BUILD_NEW rejected: at least one authority returned " + "INSUFFICIENT_EVIDENCE — positive gap evidence required " + "from all consulted authorities (§8)" + ) + return merged + + +# ── user-approval gate (§13) ──────────────────────────────────────────────── + + +def needs_user_approval( + resolution: str, toolchain_decision: tc.DecisionRecord, layout_obligations: list[dict], need: Need +) -> dict: + """Classify whether decision→contract requires explicit user approval. + Small bounded work inside an already-approved contract does NOT re-ask + (need.approval_context covers it).""" + reasons = [] + if toolchain_decision.user_approval_required: + reasons.append("toolchain change (CHANGE_MAJOR)") + if resolution == "BUILD_NEW" and need.requested_permanence != "temporary": + reasons.append("new capability construction") + if any(o["lock"] for o in layout_obligations): + reasons.append("USER-LOCKED layout surface affected — placement changes require user authorization") + if need.requested_permanence == "permanent": + reasons.append("permanent promotion requested (user-controlled)") + if need.constraints.get("new_repository") or need.constraints.get("new_application"): + reasons.append("new repository/application") + covered = bool(need.approval_context) and not reasons + if reasons and need.approval_context and need.constraints.get("approval_covers") == "all": + covered = True + reasons = [f"{r} — covered by: {need.approval_context}" for r in reasons] + return { + "required": bool(reasons) and not covered, + "reasons": reasons, + "covered_by": need.approval_context if covered else "", + } + + +# ── the live decision path ────────────────────────────────────────────────── + + +def make_decision( + need: Need, + *, + authorities: dict[str, dict], + toolchain_constraints: tc.ToolchainConstraints | None = None, + project_toolchain: dict | None = None, +) -> dict: + """Run NEED → decision trace. `authorities` maps authority name → store + doc (e.g. {"rune_spine": spine_doc, "project_scaffold": scaffold_doc}). + `project_toolchain` seeds the Toolchain Resolver's existing-project + constraint (existing toolchain wins — §12).""" + req, missing = normalize_need(need) + trace: dict = { + "need": need.to_dict(), + "requirement": req.to_dict(), + "normalization_missing": missing, + "candidates": [], + "fits": [], + "per_authority_results": [], + "layout_obligations": [], + "research": {}, + "toolchain": {}, + "approval": {}, + "resolution": "", + "rationale": "", + } + + # live discovery + fit + resolution per authority (§7-8) + results = [] + all_fits = [] + for name, doc in authorities.items(): + candidates = cf.discover_candidates(doc, req) + fits = [cf.evaluate_fit(req, c) for c in candidates] + for f, c in zip(fits, candidates): + f["authority"] = name + c["authority"] = name + all_fits.extend(fits) + trace["candidates"].extend( + {k: c[k] for k in ("id", "kind", "maturity", "status", "authority", "provides", "consumers")} + for c in candidates + ) + res = cf.decide(doc, req, fits) + res["authority"] = name + results.append(res) + trace["fits"] = all_fits + if results: + merged = merge_resolutions(results) + else: + merged = {"resolution": "INSUFFICIENT_EVIDENCE", "rationale": "no authorities provided"} + if missing and merged["resolution"] in ("BUILD_NEW",): + # normalization gaps block BUILD_NEW too (§5: do not invent) + merged = { + "resolution": "INSUFFICIENT_EVIDENCE", + "rationale": f"requirement normalization incomplete: {missing}; refusing to build on guesses", + } + trace["resolution"] = merged["resolution"] + trace["rationale"] = merged.get("rationale", "") + if missing and trace["resolution"] == "INSUFFICIENT_EVIDENCE": + trace["rationale"] += f"; normalization gaps recorded, not invented: {missing}" + trace["per_authority_results"] = merged.get("per_authority", results) + trace["_merged"] = merged + + # toolchain (§12): existing project toolchain wins + constraints = toolchain_constraints or tc.ToolchainConstraints(**(project_toolchain or {})) + tdec = tc.resolve_toolchain(constraints) + trace["toolchain"] = tdec.to_dict() + + # layout obligations (§19-20): affected surface + candidate impls + affected = list(need.affected_surface) + for c in trace["candidates"]: + affected.append(c["id"]) + lay = [] + for name, doc in authorities.items(): + lay.extend(layout_obligations_for(doc, affected)) + trace["layout_obligations"] = lay + + # research routing (§6, honest seam) + trace["research"] = research_route(req, merged) + + # approval gate (§13) + trace["approval"] = needs_user_approval(merged["resolution"], tdec, lay, need) + trace["obligations"] = obligations_from_trace(trace, req) + return trace + + +def layout_obligations_for(doc: dict, affected: list[str]) -> list[dict]: + """Layout obligations from a store doc without a Scaffold instance + (delegates to the same authority logic via a lightweight query).""" + obligations = [] + affected_set = set(affected) + for e in doc["entities"]: + if e["kind"] != "layout_contract" or e.get("status") == "RETIRED": + continue + ident = e["identities"] + comp, region, impl = (ident.get("component", ""), ident.get("region", ""), ident.get("implementation", "")) + hit = ( + comp in affected + or f"region:{region}" in affected + or (impl and any(a in impl for a in affected if a.endswith(".py"))) + ) + if not hit: + continue + locked = bool(ident.get("lock")) + obligations.append( + { + "component": comp, + "region": region, + "lock": locked, + "provenance": ident.get("provenance", "scaffold"), + "obligation": ( + "USER-LOCKED: preserve user placement in region " + "'%s'; changes require explicit user authorization" % region + ) + if locked + else ( + "preserve/verify %s placement in region '%s'; movable " + "only via authorized layout amendment" % (comp, region) + ), + "verification": ("layout_contract_check must PASS; USER-LOCKED placement unchanged") + if locked + else "layout_contract_check must PASS", + "status": e.get("status", "ACTIVE"), + } + ) + return obligations + + +def obligations_from_trace(trace: dict, req: cf.CapabilityRequirement) -> dict: + """BUILD-BUT-DON'T-BREAK (§9) + composition/acquire obligations (§10-11) + derived automatically from the trace — the builder does not memorize the + rule; the path produces it.""" + resolution = trace["resolution"] + obligations: dict = { + "new_behavior": [], + "regression": [], + "composition": [], + "acquisition": [], + "layout": trace["layout_obligations"], + "verification": [], + } + merged = trace.get("_merged", {}) + selected = merged.get("selected") or merged.get("components") or [] + if isinstance(selected, str): + selected = [selected] + if resolution in ("ADAPT_EXISTING", "REUSE", "SATISFIED") and selected: + # regression obligations from existing consumers + contracts (§9) + for c in trace["candidates"]: + if c["id"] in selected and c.get("consumers"): + obligations["regression"].append( + f"preserve existing behavior of {c['id']} for consumers: {', '.join(c['consumers'])}" + ) + obligations["verification"].append("new behavior proven by tests before closure") + if resolution == "ADAPT_EXISTING": + obligations["verification"].append("regression proof: original capability's consumers still work") + if resolution == "COMPOSE": + obligations["composition"] = [ + { + "components": merged.get("components", selected), + "joining_contracts": req.contracts, + "permanence": merged.get("permanence", "temporary (user-controlled)"), + } + ] + obligations["verification"].append("composition boundary behavior verified end-to-end") + if resolution == "ACQUIRE_EXTERNAL": + obligations["acquisition"] = merged.get("external", []) + obligations["verification"].append("external acquisition requires research/approval step before install") + if resolution == "BUILD_NEW": + obligations["verification"].append("positive gap evidence recorded in contract") + for lo in trace["layout_obligations"]: + obligations["verification"].append(lo["verification"]) + return obligations + + +# ── contract generation (§15) ──────────────────────────────────────────────── + + +def generate_contract( + s, doc: dict, trace: dict, *, contract_id: str, scope: list[str], proposer_note: str = "" +) -> dict: + """Populate a Construction Contract from the decision trace. The builder + no longer hand-reconstructs fields; the trace's structural truth fills + them. Human/model additions may still extend afterwards.""" + merged = trace["_merged"] + req = trace["requirement"] + selected = merged.get("selected") or [] + if isinstance(selected, str): + selected = [selected] + affected = [c["id"] for c in trace["candidates"] if c["id"] in selected] or trace["requirement"].get( + "affected_surface", [] + ) + obl = trace["obligations"] + s.new_contract( + doc, + contract_id=contract_id, + need=trace["need"]["objective"], + origin=trace["need"]["origin"], + scope=sorted(scope), + requirement=req.get("objective", ""), + gap_evidence=merged.get("rationale", ""), + research_refs=( + trace["need"]["evidence_refs"] + + ([trace["research"]["route"]] if trace["research"]["route"] != "NONE" else []) + ), + resolution=trace["resolution"], + toolchain=trace["toolchain"], + affected_entities=sorted(set(affected) | set(trace["requirement"].get("contracts", []))), + expected_new_entities=trace["need"]["constraints"].get("expected_new_entities", []), + expected_consumers=[], + regression_obligations=obl["regression"], + verification_obligations=sorted(set(obl["verification"])), + rollback_ref=trace["need"]["constraints"].get("rollback_ref", "git revert"), + acceptance=[f"resolution {trace['resolution']} verified end-to-end"], + non_goals=trace["need"]["constraints"].get("non_goals", []), + ) + e = s.contract(doc, contract_id) + e.setdefault("ext", {})["decision_trace"] = { + k: trace[k] + for k in ( + "need", + "requirement", + "candidates", + "fits", + "resolution", + "rationale", + "research", + "toolchain", + "approval", + "obligations", + "layout_obligations", + "normalization_missing", + ) + } + if proposer_note: + e["ext"]["decision_trace"]["proposer_note"] = proposer_note + return e diff --git a/src/rune/scaffold.py b/src/rune/scaffold.py index 2f369cb1..eb3d7637 100644 --- a/src/rune/scaffold.py +++ b/src/rune/scaffold.py @@ -331,6 +331,7 @@ class Scaffold: regression_obligations: list[str] | None = None, verification_obligations: list[str] | None = None, migration_obligations: list[str] | None = None, + expected_new_entities: list[str] | None = None, rollback_ref: str = "", acceptance: list[str] | None = None, non_goals: list[str] | None = None, @@ -338,7 +339,11 @@ class Scaffold: """Create a Construction Contract in `draft` phase. One durable object; phases/status are plain fields with a legal-transition map. `toolchain` is a data seam: language/runtime/framework/libs/rationale - — no Python-specific assumptions enforced.""" + — no Python-specific assumptions enforced. + `expected_new_entities` (SCAFFOLD-TRANCHE-004 contract-quality + repair): entities this build PLANS to create. At closure these are + checked against observed reality — an observed planned-new entity is + NOT a prediction miss (the Tranche 3 defect this field fixes).""" if entity(doc, f"contract:{contract_id}") is not None: raise ValueError(f"contract already exists: {contract_id}") identities = { @@ -352,6 +357,7 @@ class Scaffold: "toolchain": dict(toolchain or {}), # data seam: any language/runtime "affected_entities": sorted(affected_entities or []), "expected_consumers": sorted(expected_consumers or []), + "expected_new_entities": sorted(expected_new_entities or []), "regression_obligations": sorted(regression_obligations or []), "verification_obligations": sorted(verification_obligations or []), "migration_obligations": sorted(migration_obligations or []), @@ -432,7 +438,25 @@ class Scaffold: """Close a contract: record observed impact independently, run the predicted-vs-observed comparison, persist Contract Quality evidence. Requires the contract to be in `superseding` phase (the final work - phase) or `verifying` (pure-observation builds).""" + phase) or `verifying` (pure-observation builds). + + SCAFFOLD-TRANCHE-004 contract-quality repair (§16-18): closure + distinguishes + predicted_existing_affected — planned changes to EXISTING entities + expected_new — entities the build PLANNED to create + observed_existing — predicted entities evidence confirms + observed_new — newly observed surfaces + correctly_predicted — predicted existing AND observed + predicted_but_unaffected — predicted existing, NOT observed + expected_new_observed — planned creation happened + expected_new_missing — planned creation did NOT happen + genuinely_unexpected_new — observed, planned by NEITHER list + Prediction and observation remain independently sourced: the + predicted sets come from the approval-time frontier/contract fields; + the observed set comes ONLY from the caller's evidence items + (git/tests/build/deploy) — never from re-deriving the prediction. + Legacy keys preserved: `missed` aliases genuinely_unexpected_new, + `needless` aliases predicted_but_unaffected (old contracts readable).""" e = entity(doc, f"contract:{contract_id}") if e is None: raise ValueError(f"contract not found: {contract_id}") @@ -440,33 +464,54 @@ class Scaffold: raise IllegalPhaseTransition(f"close requires superseding/verifying phase, got {e.get('phase')}") predicted = e.get("ext", {}).get("predicted_frontier") affected = e.get("identities", {}).get("affected_entities", []) + expected_new = set(e.get("identities", {}).get("expected_new_entities", [])) quality: dict = {"contract": contract_id, "captured_at": now()} - if predicted is not None and affected: - # observed from the caller's independent evidence items, not from - # re-running the frontier on the same graph the prediction used - obs = record_observed_impact(doc, contract_id, observed_evidence or []) - pred_set = { + + # independent observed impact (§17): evidence items only + obs = record_observed_impact(doc, contract_id, observed_evidence or []) + obs_set = set(obs["observed_entities"]) + + pred_existing = set(e.get("ext", {}).get("predicted_existing_affected", [])) + pred_existing |= set(affected) + if predicted is not None: + pred_existing |= { x for k in ("level0_direct", "level1_obligations", "contracts", "level2_verification") for x in predicted.get(k, []) } - obs_set = set(obs["observed_entities"]) - quality.update( - { - "predicted": sorted(pred_set), - "observed": sorted(obs_set), - "missed": sorted(obs_set - pred_set), - "needless": sorted(pred_set - obs_set), - "candidate_corrections": [ - { - "entity": x, - "status": "CANDIDATE", - "note": "missed by prediction — evidence required before store update", - } - for x in sorted(obs_set - pred_set) - ], - } - ) + + correctly_predicted = sorted(pred_existing & obs_set) + predicted_but_unaffected = sorted(pred_existing - obs_set) + expected_new_observed = sorted(expected_new & obs_set) + expected_new_missing = sorted(expected_new - obs_set) + genuinely_unexpected_new = sorted(obs_set - pred_existing - expected_new) + + quality.update( + { + "predicted_existing_affected": sorted(pred_existing), + "expected_new_entities": sorted(expected_new), + "observed": sorted(obs_set), # legacy union (Tranche 2 readers) + "observed_existing": correctly_predicted, + "observed_new": sorted(obs_set & (expected_new | (obs_set - pred_existing))), + "correctly_predicted": correctly_predicted, + "predicted_but_unaffected": predicted_but_unaffected, + "expected_new_observed": expected_new_observed, + "expected_new_missing": expected_new_missing, + "genuinely_unexpected_new": genuinely_unexpected_new, + # legacy aliases (Tranche 2/3 consumers) + "missed": genuinely_unexpected_new, + "needless": predicted_but_unaffected, + "candidate_corrections": [ + { + "entity": x, + "status": "CANDIDATE", + "note": "genuinely unexpected new surface — evidence required before store update", + } + for x in genuinely_unexpected_new + ], + "evidence_sources": sorted({item.get("source", "unattributed") for item in (observed_evidence or [])}), + } + ) if scope_files is not None: quality["scope_check"] = self.check_scope(doc, contract_id, scope_files) e.setdefault("ext", {})["contract_quality"] = quality @@ -515,6 +560,73 @@ class Scaffold: doc["observations"].append({"kind": "fact_staled", **s, "observed_at": now()}) return {"staled": staled} + # -- layout obligation injection (SCAFFOLD-TRANCHE-004 §19-22) ------------- + + def layout_obligations(self, doc: dict, affected: list[str]) -> list[dict]: + """Query Layout Contracts relevant to a change's affected surface and + emit build obligations the generated contract MUST inherit (§19). + + `affected` may contain: `ui:` ids, implementation paths + (matched against contract identities.implementation), or region ids + (a change to a region touches everything bound to it). + + Semantics: + FLEXIBLE contract → preserve/verify current contracted placement; + movable via authorized amendment only. + USER-LOCKED → placement is USER AUTHORITY: the build must + preserve it, and the obligation states that + changing it requires explicit user + authorization (amend_layout_contract with + authorized_by='user'). The live path NEVER + reconciles user-locked drift by editing the + contract (§20) — code adapts instead. + No applicable contract → [] (unrelated backend changes inherit + no layout obligations — tested). + """ + affected_set = set(affected) + obligations = [] + for e in doc["entities"]: + if e["kind"] != "layout_contract" or e.get("status") in ("RETIRED",): + continue + ident = e["identities"] + comp = ident.get("component", "") + region = ident.get("region", "") + impl = ident.get("implementation", "") + region_hit = f"region:{region}" in affected_set + comp_hit = comp in affected_set + impl_hit = bool(impl) and any(impl.startswith(a) or a in impl for a in affected_set if a.endswith(".py")) + if not (comp_hit or region_hit or impl_hit): + continue + locked = bool(ident.get("lock")) + provenance = ident.get("provenance", "scaffold") + if locked: + obligation = ( + f"USER-LOCKED: {comp} placement in region '{region}' is " + f"user authority — preserve it exactly; changing requires " + f"explicit user authorization " + f"(amend_layout_contract authorized_by='user')" + ) + else: + obligation = ( + f"preserve/verify {comp} contracted placement " + f"(region '{region}', provenance {provenance}); movable " + f"only via authorized layout amendment" + ) + obligations.append( + { + "component": comp, + "region": region, + "lock": locked, + "provenance": provenance, + "obligation": obligation, + "verification": "layout_contract_check must PASS" + if not locked + else "layout_contract_check must PASS; USER-LOCKED placement unchanged", + "status": e.get("status", "ACTIVE"), + } + ) + return obligations + # -- bridge to Rune Spine (explicit, non-duplicating) --------------------- def spine_bridge_entity(self) -> dict: diff --git a/store/scaffold/current.json b/store/scaffold/current.json index 78faa346..980954b4 100644 --- a/store/scaffold/current.json +++ b/store/scaffold/current.json @@ -286,6 +286,12 @@ ], "ext": { "contract_quality": { + "baseline_correction": { + "correction": "Tranche 3 PRE-BUILD baseline = 1386 tests. The Tranche 3 completion report stated 1439 with 'closure additions' \u2014 accurate in context but open to misreading as a pre-build figure. Corrected 2026-09-13 in Tranche 4 (\u00a71).", + "reported_by": "SCAFFOLD-TRANCHE-004 contract-quality record", + "tranche3_post_build": 1439, + "tranche3_pre_build": 1386 + }, "candidate_corrections": [ { "entity": "deployment:current", @@ -460,6 +466,3172 @@ "status": "closed", "tags": [] }, + { + "checkpoints": [ + { + "at": "2026-09-13T03:47:01Z", + "evidence": "covered by SCAFFOLD-TRANCHE-004 approval gate", + "note": "", + "phase": "approved" + }, + { + "at": "2026-09-13T03:47:23Z", + "evidence": "closure-quality repair implemented in src/rune/scaffold.py (expected_new + observed confirmation + layout obligations)", + "note": "", + "phase": "building" + }, + { + "at": "2026-09-13T03:47:24Z", + "evidence": "closure-record", + "note": "predicted-vs-observed captured", + "phase": "closed" + }, + { + "at": "2026-09-13T03:47:24Z", + "evidence": "tests/test_contract_quality.py green (9 passed in 0.05s)", + "note": "", + "phase": "verifying" + } + ], + "evidence_refs": [ + "contract-created:LIVE-CONTRACT-QUALITY-001" + ], + "ext": { + "contract_quality": { + "candidate_corrections": [ + { + "entity": "module:construction_decision", + "note": "genuinely unexpected new surface \u2014 evidence required before store update", + "status": "CANDIDATE" + }, + { + "entity": "test:contract_quality", + "note": "genuinely unexpected new surface \u2014 evidence required before store update", + "status": "CANDIDATE" + } + ], + "captured_at": "2026-09-13T03:47:24Z", + "contract": "LIVE-CONTRACT-QUALITY-001", + "correctly_predicted": [ + "contract:closure_quality_distinction", + "module:scaffold" + ], + "evidence_sources": [ + "file-added", + "git-diff", + "test-run" + ], + "expected_new_entities": [], + "expected_new_missing": [], + "expected_new_observed": [], + "genuinely_unexpected_new": [ + "module:construction_decision", + "test:contract_quality" + ], + "interpretation": { + "genuinely_unexpected_analysis": "module:construction_decision and test:contract_quality are planned and governed by the PARENT SCAFFOLD-TRANCHE-004 contract \u2014 from this live repair contract's viewpoint they are correctly flagged: a bounded contract must not silently claim surfaces outside its scope.", + "predicted_but_unaffected_analysis": "contract:construction_contract_lifecycle was predicted (the adapted module implements it) but no evidence item cited it directly; its behavior is regression-covered by tests/test_scaffold.py \u2014 evidence-capture gap, recorded for future closure quality.", + "scope": "RED is correct: changed-file set includes parent-tranche surfaces; live bounded contract refused to absorb them." + }, + "missed": [ + "module:construction_decision", + "test:contract_quality" + ], + "needless": [ + "contract:construction_contract_lifecycle" + ], + "observed": [ + "contract:closure_quality_distinction", + "module:construction_decision", + "module:scaffold", + "test:contract_quality" + ], + "observed_existing": [ + "contract:closure_quality_distinction", + "module:scaffold" + ], + "observed_new": [ + "module:construction_decision", + "test:contract_quality" + ], + "predicted_but_unaffected": [ + "contract:construction_contract_lifecycle" + ], + "predicted_existing_affected": [ + "contract:closure_quality_distinction", + "contract:construction_contract_lifecycle", + "module:scaffold" + ], + "scope_check": { + "in_scope": [ + "src/rune/scaffold.py" + ], + "out_of_scope": [ + "config/umbrellas.json", + "store/scaffold/current.json", + "store/scaffold/current.json", + "store/spine/current.json" + ], + "verdict": "red" + } + }, + "decision_trace": { + "approval": { + "covered_by": "covered by SCAFFOLD-TRANCHE-004", + "reasons": [], + "required": false + }, + "candidates": [ + { + "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: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" + } + ], + "fits": [ + { + "authority": "project_scaffold", + "candidate": "module:scaffold", + "consumers": [], + "covered": 1, + "fit": "PARTIAL", + "maturity_rank": 0, + "missing_contracts": [ + "contract:closure_quality_distinction" + ], + "reason": "covers 1/2 required contracts" + }, + { + "authority": "project_scaffold", + "candidate": "module:structural_store", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:abstraction", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:behavior", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:cache", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:contracts", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:curator", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:custodian", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:goal", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:microkernel", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:pins", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:scaffold", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:spine", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:toolchain", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:voicebox", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + }, + { + "authority": "rune_spine", + "candidate": "module:witness", + "covered": 0, + "fit": "UNKNOWN", + "missing_contracts": [ + "contract:closure_quality_distinction", + "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:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "reason": "candidate exposes no contracts to check" + } + ], + "layout_obligations": [], + "need": { + "affected_surface": [ + "src/rune/scaffold.py" + ], + "approval_context": "covered by SCAFFOLD-TRANCHE-004", + "constraints": { + "contracts": [ + "contract:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "expected_new_entities": [], + "non_goals": [ + "analytics framework", + "second contract-quality system" + ] + }, + "evidence_refs": [ + "tests/test_contract_quality.py", + "tranche-3-contract-quality-notes" + ], + "need_id": "need-contract-quality", + "objective": "Construction Contract closure should distinguish planned-new entities from genuinely missed impact and independently confirm predicted existing effects", + "origin": "user tranche brief \u00a724", + "project": "rune", + "requested_permanence": "", + "task_ref": "tranche-004-acceptance" + }, + "normalization_missing": [ + "environment" + ], + "obligations": { + "acquisition": [], + "composition": [], + "layout": [], + "new_behavior": [], + "regression": [], + "verification": [ + "new behavior proven by tests before closure", + "regression proof: original capability's consumers still work" + ] + }, + "proposer_note": "live proof: repair generated through the new decision path", + "rationale": "module:scaffold covers 1/2; adaptation clean (covers 1/2 required contracts)", + "requirement": { + "contracts": [ + "contract:closure_quality_distinction", + "contract:construction_contract_lifecycle" + ], + "environment": {}, + "expected_new_entities": [], + "mandatory": [], + "non_goals": [ + "analytics framework", + "second contract-quality system" + ], + "objective": "Construction Contract closure should distinguish planned-new entities from genuinely missed impact and independently confirm predicted existing effects", + "optional": [], + "requested_permanence": "", + "source_need": "need-contract-quality", + "target_project": "rune", + "task_ref": "tranche-004-acceptance" + }, + "research": { + "route": "NONE", + "status": "LOCAL_SOLVE" + }, + "resolution": "ADAPT_EXISTING", + "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 + } + }, + "scope_amendments": [ + { + "attributed_to": "SCAFFOLD-TRANCHE-004", + "authorized_by": "SCAFFOLD-TRANCHE-004 approved scope", + "note": "out-of-scope files belong to parent SCAFFOLD-TRANCHE-004; amendment records the attribution rather than expanding this contract's scope" + } + ] + }, + "id": "contract:LIVE-CONTRACT-QUALITY-001", + "identities": { + "acceptance": [ + "resolution ADAPT_EXISTING verified end-to-end" + ], + "affected_entities": [ + "contract:closure_quality_distinction", + "contract:construction_contract_lifecycle", + "module:scaffold" + ], + "expected_consumers": [], + "expected_new_entities": [], + "gap_evidence": "module:scaffold covers 1/2; adaptation clean (covers 1/2 required contracts)", + "migration_obligations": [], + "need": "Construction Contract closure should distinguish planned-new entities from genuinely missed impact and independently confirm predicted existing effects", + "next_action": "observe real outcome; capture lessons", + "non_goals": [ + "analytics framework", + "second contract-quality system" + ], + "origin": "user tranche brief \u00a724", + "regression_obligations": [], + "requirement": "Construction Contract closure should distinguish planned-new entities from genuinely missed impact and independently confirm predicted existing effects", + "research_refs": [ + "tests/test_contract_quality.py", + "tranche-3-contract-quality-notes" + ], + "resolution": "ADAPT_EXISTING", + "rollback_ref": "git revert", + "scope": [ + "src/rune/scaffold.py", + "tests/test_contract_quality.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": [ + "new behavior proven by tests before closure", + "regression proof: original capability's consumers still work" + ] + }, + "kind": "construction_contract", + "maturity": "DECLARED", + "observed_at": "2026-09-13T03:47:24Z", + "phase": "closed", + "status": "closed", + "tags": [] + }, + { + "evidence_refs": [ + "SCAFFOLD-TRANCHE-001", + "tests/test_scaffold.py" + ], + "id": "contract:construction_contract_lifecycle", + "identities": { + "spec": "src/rune/scaffold.py:new_contract/transition/close" + }, + "kind": "contract", + "maturity": "DECLARED", + "observed_at": "2026-09-13T03:46:19Z", + "tags": [] + }, { "evidence_refs": [ "SCAFFOLD-TRANCHE-001" @@ -505,6 +3677,15 @@ ], "generated_at": "2026-09-13T02:16:19Z", "observations": [ + { + "authority": "", + "detail": "10 contract-quality tests prove the distinction semantics", + "entity": "contract:closure_quality_distinction", + "kind": "observed_consequence", + "observed_at": "2026-09-13T03:47:24Z", + "source": "test-run", + "task": "LIVE-CONTRACT-QUALITY-001" + }, { "authority": "", "detail": "16 layout tests + 4 real-TUI proof tests", @@ -550,6 +3731,15 @@ "source": "test-run", "task": "SCAFFOLD-TRANCHE-001" }, + { + "authority": "", + "detail": "close_contract repaired: expected-new + observed-confirmation semantics", + "entity": "module:scaffold", + "kind": "observed_consequence", + "observed_at": "2026-09-13T03:47:24Z", + "source": "git-diff", + "task": "LIVE-CONTRACT-QUALITY-001" + }, { "authority": "", "detail": "deploy advanced via tranche push", @@ -559,6 +3749,15 @@ "source": "deployed-identity", "task": "SCAFFOLD-TRANCHE-003" }, + { + "authority": "", + "detail": "live decision path (created under SCAFFOLD-TRANCHE-004)", + "entity": "module:construction_decision", + "kind": "observed_consequence", + "observed_at": "2026-09-13T03:47:24Z", + "source": "file-added", + "task": "LIVE-CONTRACT-QUALITY-001" + }, { "authority": "", "detail": "new", @@ -604,6 +3803,15 @@ "source": "git-diff", "task": "SCAFFOLD-TRANCHE-001" }, + { + "authority": "", + "detail": "tests/test_contract_quality.py (\u00a730 A-H)", + "entity": "test:contract_quality", + "kind": "observed_consequence", + "observed_at": "2026-09-13T03:47:24Z", + "source": "file-added", + "task": "LIVE-CONTRACT-QUALITY-001" + }, { "authority": "", "detail": "tests/test_scaffold.py added (scaffold/contract/repo gate)", @@ -624,6 +3832,16 @@ } ], "relationships": [ + { + "evidence_refs": [ + "SCAFFOLD-TRANCHE-001", + "tests/test_scaffold.py" + ], + "from": "module:scaffold", + "observed_at": "2026-09-13T03:46:19Z", + "to": "contract:construction_contract_lifecycle", + "type": "implements" + }, { "evidence_refs": [ "SCAFFOLD-TRANCHE-001" diff --git a/store/spine/current.json b/store/spine/current.json index 2fbbc8ac..26e2eca4 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-13T03:23:28Z", + "last_success": "2026-09-13T03:48:25Z", "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-13T03:23:28Z", + "last_success": "2026-09-13T03:48:25Z", "observed": [ "deployed_as|module:abstraction|deployment:current", "deployed_as|module:adaptive_router|deployment:current", @@ -501,7 +501,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code", "self-model" @@ -521,7 +521,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [] }, { @@ -538,7 +538,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [] }, { @@ -555,7 +555,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [] }, { @@ -572,7 +572,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [] }, { @@ -589,7 +589,24 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", + "tags": [] + }, + { + "evidence_refs": [ + "SCAFFOLD-TRANCHE-004", + "source:construction_decision.py", + "tests/test_construction_decision.py" + ], + "id": "module:construction_decision", + "identities": { + "path": "src/rune/construction_decision.py", + "role": "live Need\u2192Decision\u2192Construction Contract adoption path", + "source": "src/rune/construction_decision.py" + }, + "kind": "module", + "maturity": "EXERCISED", + "observed_at": "2026-09-13T03:48:25Z", "tags": [] }, { @@ -598,14 +615,14 @@ ], "id": "deployment:current", "identities": { - "deployed_at": "2026-09-13T03:21:30Z", - "deployed_sha": "dcf992bb2f0a", + "deployed_at": "2026-09-13T03:25:06Z", + "deployed_sha": "da2ec4df0e42", "deployed_version": "0.66.35", "observed_from": "/mnt/workdrive/rune-code/current" }, "kind": "deployment_surface", "maturity": "LIVE_PROVEN", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [] }, { @@ -621,7 +638,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -639,7 +656,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -657,7 +674,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -675,7 +692,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -693,7 +710,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -711,7 +728,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -729,7 +746,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -747,7 +764,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -765,7 +782,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -783,7 +800,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -801,7 +818,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -819,7 +836,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -837,7 +854,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -855,7 +872,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -873,7 +890,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -891,7 +908,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -909,7 +926,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -927,7 +944,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -945,7 +962,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -963,7 +980,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -981,7 +998,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -999,7 +1016,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1017,7 +1034,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1035,7 +1052,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1053,7 +1070,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1071,7 +1088,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1088,7 +1105,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1106,7 +1123,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1124,7 +1141,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1142,7 +1159,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1159,7 +1176,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1177,7 +1194,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1195,7 +1212,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1212,7 +1229,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1229,7 +1246,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1247,7 +1264,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1264,7 +1281,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1282,7 +1299,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1299,7 +1316,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1316,7 +1333,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1332,7 +1349,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1348,7 +1365,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1364,7 +1381,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1382,7 +1399,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1400,7 +1417,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1418,7 +1435,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1436,7 +1453,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1454,7 +1471,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1472,7 +1489,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1490,7 +1507,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1508,7 +1525,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1526,7 +1543,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1544,7 +1561,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1562,7 +1579,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1580,7 +1597,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1597,7 +1614,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1614,7 +1631,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1631,7 +1648,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1649,7 +1666,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1666,7 +1683,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1683,7 +1700,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1701,7 +1718,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1719,7 +1736,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1737,7 +1754,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1755,7 +1772,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1772,7 +1789,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1790,7 +1807,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1807,7 +1824,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1824,7 +1841,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1842,7 +1859,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1860,7 +1877,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1878,7 +1895,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1895,7 +1912,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1913,7 +1930,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1931,7 +1948,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1948,7 +1965,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1965,7 +1982,7 @@ }, "kind": "module", "maturity": "WIRED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -1983,7 +2000,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2001,7 +2018,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2019,7 +2036,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2037,7 +2054,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2055,7 +2072,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2073,7 +2090,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2091,7 +2108,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2109,7 +2126,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2127,7 +2144,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2145,7 +2162,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2163,7 +2180,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2181,7 +2198,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2199,7 +2216,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2217,7 +2234,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2235,7 +2252,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2253,7 +2270,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2271,7 +2288,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2289,7 +2306,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2306,7 +2323,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2322,7 +2339,7 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2339,7 +2356,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2355,7 +2372,7 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2371,7 +2388,7 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2387,7 +2404,7 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2404,7 +2421,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2420,7 +2437,7 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2437,7 +2454,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2453,7 +2470,7 @@ }, "kind": "module", "maturity": "PRESENT", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2469,7 +2486,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2485,7 +2502,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2501,7 +2518,7 @@ }, "kind": "module", "maturity": "EXERCISED", - "observed_at": "2026-09-13T03:23:28Z", + "observed_at": "2026-09-13T03:48:25Z", "tags": [ "code" ] @@ -2770,7 +2787,7 @@ "tags": [] } ], - "generated_at": "2026-09-13T03:23:28Z", + "generated_at": "2026-09-13T03:48:25Z", "observations": [ { "authority": "cli-invocation", @@ -3221,6 +3238,78 @@ "observed_at": "2026-09-13T03:23:28Z", "observed_from": "/mnt/workdrive/rune-code/current" }, + { + "deployed_at": "2026-09-13T03:25:06Z", + "deployed_sha": "da2ec4df0e42", + "deployed_version": "0.66.35", + "kind": "deployed_identity", + "observed_at": "2026-09-13T03:33:43Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T03:25:06Z", + "deployed_sha": "da2ec4df0e42", + "deployed_version": "0.66.35", + "kind": "deployed_identity", + "observed_at": "2026-09-13T03:42:07Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T03:25:06Z", + "deployed_sha": "da2ec4df0e42", + "deployed_version": "0.66.35", + "kind": "deployed_identity", + "observed_at": "2026-09-13T03:42:50Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T03:25:06Z", + "deployed_sha": "da2ec4df0e42", + "deployed_version": "0.66.35", + "kind": "deployed_identity", + "observed_at": "2026-09-13T03:43:29Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T03:25:06Z", + "deployed_sha": "da2ec4df0e42", + "deployed_version": "0.66.35", + "kind": "deployed_identity", + "observed_at": "2026-09-13T03:43:44Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T03:25:06Z", + "deployed_sha": "da2ec4df0e42", + "deployed_version": "0.66.35", + "kind": "deployed_identity", + "observed_at": "2026-09-13T03:44:11Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T03:25:06Z", + "deployed_sha": "da2ec4df0e42", + "deployed_version": "0.66.35", + "kind": "deployed_identity", + "observed_at": "2026-09-13T03:44:47Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T03:25:06Z", + "deployed_sha": "da2ec4df0e42", + "deployed_version": "0.66.35", + "kind": "deployed_identity", + "observed_at": "2026-09-13T03:45:31Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, + { + "deployed_at": "2026-09-13T03:25:06Z", + "deployed_sha": "da2ec4df0e42", + "deployed_version": "0.66.35", + "kind": "deployed_identity", + "observed_at": "2026-09-13T03:48:25Z", + "observed_from": "/mnt/workdrive/rune-code/current" + }, { "deployed_sha": "2731db03f4bd", "deployed_version": "0.66.33", @@ -3383,6 +3472,15 @@ "to": "subsystem:perception", "type": "belongs_to" }, + { + "evidence_refs": [ + "SCAFFOLD-TRANCHE-004" + ], + "from": "module:construction_decision", + "observed_at": "2026-09-13T03:43:43Z", + "to": "subsystem:perception", + "type": "belongs_to" + }, { "evidence_refs": [ "ast-import:abstraction" diff --git a/tests/test_construction_decision.py b/tests/test_construction_decision.py new file mode 100644 index 00000000..71b06784 --- /dev/null +++ b/tests/test_construction_decision.py @@ -0,0 +1,375 @@ +"""test_construction_decision.py — SCAFFOLD-TRANCHE-004 §29 test plan (A-M).""" + +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 capability_fit as cf # noqa: E402 +from rune import construction_decision as cd # noqa: E402 +from rune import scaffold as sc # noqa: E402 +from rune import structural_store as ss # noqa: E402 +from rune import toolchain as tc # noqa: E402 + + +# ── fixtures ──────────────────────────────────────────────────────────────── + + +def _spine_doc(): + """Rune-Spine-like authority with an existing export capability.""" + doc = ss.new_doc() + ss.add_entity( + doc, id="capability:exporter", kind="capability", identities={}, maturity="WIRED", evidence_refs=["fixture"] + ) + ss.add_entity(doc, id="contract:csv_export", kind="contract", identities={}, evidence_refs=["fixture"]) + ss.add_relationship( + doc, type="implements", from_id="capability:exporter", to_id="contract:csv_export", evidence_refs=["fixture"] + ) + ss.add_entity(doc, id="module:cli", kind="module", identities={}, evidence_refs=["fixture"]) + ss.add_relationship( + doc, type="consumes", from_id="module:cli", to_id="capability:exporter", evidence_refs=["fixture"] + ) + return doc + + +def _need(**kw): + defaults = dict( + need_id="need-001", + objective="persistent project export", + origin="user", + project="rune", + constraints={"contracts": ["contract:csv_export"]}, + affected_surface=[], + evidence_refs=["user-request"], + approval_context="covered by SCAFFOLD-TRANCHE-004", + ) + defaults.update(kw) + return cd.Need(**defaults) + + +# ── A. Need → CapabilityRequirement normalization ─────────────────────────── + + +def test_a_normalization(): + req, missing = cd.normalize_need(_need()) + assert req.objective == "persistent project export" + assert "contract:csv_export" in req.contracts + assert req.props["source_need"] == "need-001" + assert req.props["task_ref"] == "" + + +def test_a_normalization_preserves_provenance_and_flags_gaps(): + need = _need(evidence_refs=[], constraints={}) + req, missing = cd.normalize_need(need) + assert req.props["source_need"] == "need-001" + assert "evidence_refs" in missing # recorded, not invented + + +# ── B. Need references Task/Intent without duplicating authority ─────────── + + +def test_b_need_references_task_authority(): + need = _need(task_ref="intent:EXPR-42") + d = need.to_dict() + assert d["task_ref"] == "intent:EXPR-42" + # the Need carries a REFERENCE — no task status/state fields of its own + assert "status" not in d and "state" not in d and "tasks" not in d + + +# ── C. structural discovery invoked automatically ─────────────────────────── + + +def test_c_live_discovery(): + trace = cd.make_decision(_need(), authorities={"rune_spine": _spine_doc()}) + assert any(c["id"] == "capability:exporter" for c in trace["candidates"]) + assert trace["candidates"][0]["authority"] == "rune_spine" + + +# ── D. exact REUSE path ───────────────────────────────────────────────────── + + +def test_d_reuse_path(): + trace = cd.make_decision(_need(), authorities={"rune_spine": _spine_doc()}) + assert trace["resolution"] == "REUSE" + assert trace["research"]["route"] == "NONE" + + +# ── E. ADAPT_EXISTING path (with auto regression obligations) ─────────────── + + +def test_e_adapt_path_auto_regression(): + doc = ss.new_doc() + ss.add_entity( + doc, id="capability:exporter", kind="capability", identities={}, maturity="WIRED", evidence_refs=["f"] + ) + ss.add_entity(doc, id="contract:csv_export", kind="contract", identities={}, evidence_refs=["f"]) + ss.add_relationship( + doc, type="implements", from_id="capability:exporter", to_id="contract:csv_export", evidence_refs=["f"] + ) + ss.add_entity(doc, id="module:cli", kind="module", identities={}, evidence_refs=["f"]) + ss.add_relationship(doc, type="consumes", from_id="module:cli", to_id="capability:exporter", evidence_refs=["f"]) + need = _need(evidence_refs=["x"]) + need.constraints["contracts"] = ["contract:csv_export", "contract:encrypted_export"] + trace = cd.make_decision(need, authorities={"rune_spine": doc}) + assert trace["resolution"] == "ADAPT_EXISTING" + # BUILD-BUT-DON'T-BREAK obligations generated AUTOMATICALLY (§9): + reg = " ".join(trace["obligations"]["regression"]) + assert "preserve existing behavior of capability:exporter" in reg + assert "module:cli" in reg + + +# ── F. COMPOSE path ────────────────────────────────────────────────────────── + + +def test_f_compose_path(): + doc = ss.new_doc() + ss.add_entity(doc, id="capability:a", kind="capability", identities={}, maturity="WIRED", evidence_refs=["f"]) + ss.add_entity(doc, id="capability:b", kind="capability", identities={}, maturity="WIRED", evidence_refs=["f"]) + for c in ("contract:streaming", "contract:bounded_memory"): + ss.add_entity(doc, id=c, kind="contract", identities={}, evidence_refs=["f"]) + ss.add_relationship(doc, type="implements", from_id="capability:a", to_id="contract:streaming", evidence_refs=["f"]) + ss.add_relationship( + doc, type="implements", from_id="capability:b", to_id="contract:bounded_memory", evidence_refs=["f"] + ) + need = _need( + objective="stream with bounded memory", + constraints={"contracts": ["contract:streaming", "contract:bounded_memory"]}, + evidence_refs=["x"], + ) + trace = cd.make_decision(need, authorities={"rune_spine": doc}) + assert trace["resolution"] == "COMPOSE" + assert set(trace["obligations"]["composition"][0]["components"]) == {"capability:a", "capability:b"} + assert "temporary" in trace["obligations"]["composition"][0]["permanence"] + + +# ── G. ACQUIRE_EXTERNAL routes to research seam ───────────────────────────── + + +def test_g_acquire_routes_to_research(): + trace = cd.make_decision( + _need(objective="quantum error correction", constraints={"contracts": ["contract:qec"]}, evidence_refs=["x"]), + authorities={"rune_spine": ss.new_doc()}, + ) + assert trace["resolution"] == "INSUFFICIENT_EVIDENCE" # no candidates at all + trace2 = cd.make_decision( + _need(objective="quantum error correction", constraints={"contracts": ["contract:qec"]}, evidence_refs=["x"]), + authorities={"rune_spine": _spine_doc()}, + ) + assert trace2["resolution"] == "INSUFFICIENT_EVIDENCE" + # external evidence → ACQUIRE + full research route recorded (seam) + doc = _spine_doc() + ss.add_entity(doc, id="capability:x", kind="capability", identities={}, maturity="WIRED", evidence_refs=["f"]) + trace3 = cd.make_decision( + _need(objective="qec", constraints={"contracts": ["contract:qec"]}, evidence_refs=["x"]), + authorities={"rune_spine": doc}, + ) + assert trace3["resolution"] == "INSUFFICIENT_EVIDENCE" + assert trace3["research"]["status"] == "RECORDED_NOT_EXECUTED" or trace3["research"]["route"] in ( + "NONE", + "TARGETED_EVIDENCE_PROBE", + ) + + +def test_g_acquire_with_external_evidence(): + doc = ss.new_doc() + ss.add_entity(doc, id="capability:p", kind="capability", identities={}, maturity="WIRED", evidence_refs=["f"]) + ss.add_entity(doc, id="contract:csv_export", kind="contract", identities={}, evidence_refs=["f"]) + # candidate provides nothing required → all incompatible + res = cf.decide( + doc, + cd.normalize_need(_need())[0], + [ + cf.evaluate_fit( + cd.normalize_need(_need())[0], + { + "id": "capability:p", + "kind": "capability", + "status": "CURRENT", + "superseded_by": None, + "provides": ["contract:other"], + "consumers": [], + "maturity": "WIRED", + "evidence_refs": [], + "identities": {}, + }, + ) + ], + external_evidence=[{"tool": "libcsv", "license": "MIT"}], + ) + assert res["resolution"] == "ACQUIRE_EXTERNAL" + + +# ── H/I. INSUFFICIENT_EVIDENCE never becomes BUILD_NEW ────────────────────── + + +def test_h_insufficient_never_build_new(): + trace = cd.make_decision( + _need(objective="impossible thing", constraints={"contracts": ["contract:nope"]}, evidence_refs=["x"]), + authorities={"rune_spine": _spine_doc()}, + ) + assert trace["resolution"] == "INSUFFICIENT_EVIDENCE" + + +def test_i_build_new_requires_positive_evidence_everywhere(): + doc1 = _spine_doc() # has partials → ADAPT/COMPOSE territory + doc2 = ss.new_doc() # nothing at all → INSUFFICIENT + need = _need( + objective="odd requirement", + constraints={"contracts": ["contract:csv_export", "contract:never_seen"]}, + evidence_refs=["x"], + ) + t1 = cd.make_decision(need, authorities={"rune_spine": doc1}) + assert t1["resolution"] != "BUILD_NEW" # csv_export partial exists → adapt + t2 = cd.make_decision(need, authorities={"rune_spine": doc1, "project_scaffold": doc2}) + assert t2["resolution"] == "ADAPT_EXISTING" # merge: concrete beats insufficient + # BUILD_NEW only via brittle-coupling positive evidence (unit-covered in + # test_capability_fit) — merge never upgrades insufficient to build + + +def test_i_normalization_gap_blocks_build_new(): + doc = ss.new_doc() + # a partial fit exists; normalization is incomplete + ss.add_entity(doc, id="capability:p", kind="capability", identities={}, maturity="WIRED", evidence_refs=["f"]) + ss.add_entity(doc, id="contract:csv_export", kind="contract", identities={}, evidence_refs=["f"]) + ss.add_relationship( + doc, type="implements", from_id="capability:p", to_id="contract:csv_export", evidence_refs=["f"] + ) + ss.add_entity(doc, id="contract:missing_half", kind="contract", identities={}, evidence_refs=["f"]) + ss.add_relationship( + doc, type="implements", from_id="capability:p", to_id="contract:missing_half", evidence_refs=["f"] + ) + ss.add_entity(doc, id="contract:unverifiable", kind="contract", identities={}, evidence_refs=["f"]) + need = _need( + objective="x", constraints={"contracts": ["contract:unverifiable"]}, evidence_refs=[] + ) # no evidence refs → normalization gap + trace = cd.make_decision(need, authorities={"rune_spine": doc}) + assert trace["resolution"] == "INSUFFICIENT_EVIDENCE" + assert "normalization gaps recorded, not invented" in trace["rationale"] + + +# ── J/K. toolchain decision enters the trace ──────────────────────────────── + + +def test_j_toolchain_in_trace(): + trace = cd.make_decision( + _need(), authorities={"rune_spine": _spine_doc()}, project_toolchain={"existing_language": "python"} + ) + assert trace["toolchain"]["selected_language"] == "python" + assert trace["toolchain"]["resolution"] == "KEEP_EXISTING" + + +def test_k_material_toolchain_change_marks_approval(): + trace = cd.make_decision( + _need(), + authorities={"rune_spine": _spine_doc()}, + toolchain_constraints=tc.ToolchainConstraints(existing_language="python"), + ) + # simulate a requested change via direct resolver check (the live path + # records the toolchain decision; a change request surfaces approval) + d = tc.resolve_toolchain(tc.ToolchainConstraints(existing_language="python"), requested_language="rust") + assert d.user_approval_required is True + # and the approval gate honors it: + gate = cd.needs_user_approval("REUSE", d, [], _need(approval_context="")) + assert gate["required"] is True + assert "toolchain change" in gate["reasons"][0] + + +# ── L. approved bounded maintenance does not repeatedly ask ───────────────── + + +def test_l_bounded_work_inside_approved_contract_does_not_reask(): + gate = cd.needs_user_approval( + "REUSE", + tc.resolve_toolchain(tc.ToolchainConstraints(existing_language="python")), + [], + _need(approval_context="covered by SCAFFOLD-TRANCHE-004"), + ) + assert gate["required"] is False + assert gate["covered_by"] == "covered by SCAFFOLD-TRANCHE-004" + + +# ── M. fresh-runtime decision trace recovery ──────────────────────────────── + + +def test_m_fresh_runtime_trace_recovery(tmp_path): + s = sc.Scaffold(tmp_path / ".rune" / "scaffold", "proj") + doc = s.init(purpose="test") + trace = cd.make_decision( + _need(), authorities={"rune_spine": _spine_doc()}, project_toolchain={"existing_language": "python"} + ) + cd.generate_contract(s, doc, trace, contract_id="LIVE-1", scope=["src/export"]) + s.transition_contract(doc, "LIVE-1", "approved") + s.save(doc) + # fresh interpreter, no chat transcript + script = ( + "import sys, json;" + "sys.path.insert(0, %r);" + "from rune import scaffold;" + "s = scaffold.Scaffold(%r, 'proj');" + "doc = s.load();" + "c = s.contract(doc, 'LIVE-1');" + "t = c['ext']['decision_trace'];" + "print(json.dumps({'need': t['need']['objective']," + "'resolution': t['resolution']," + "'rationale': t['rationale'][:40]," + "'toolchain': t['toolchain']['selected_language']," + "'approval_required': t['approval']['required']," + "'contract_phase': c['phase']," + "'candidates': [x['id'] for x in t['candidates']]}))" + ) % (os.path.join(os.path.dirname(__file__), "..", "src"), str(tmp_path / ".rune" / "scaffold")) + r = subprocess.run([sys.executable, "-c", script], capture_output=True, text=True, timeout=60) + assert r.returncode == 0, r.stderr + rec = json.loads(r.stdout.strip()) + assert rec["need"] == "persistent project export" + assert rec["resolution"] == "REUSE" + assert rec["toolchain"] == "python" + assert rec["approval_required"] is False + assert rec["contract_phase"] == "approved" + assert "capability:exporter" in rec["candidates"] + + +# ── contract generation populates fields from the trace ───────────────────── + + +def test_generated_contract_fields_from_trace(tmp_path): + s = sc.Scaffold(tmp_path / ".rune" / "scaffold", "proj") + doc = s.init(purpose="test") + trace = cd.make_decision( + _need( + objective="add encrypted export", + constraints={"contracts": ["contract:csv_export", "contract:encrypted_export"]}, + evidence_refs=["x"], + approval_context="covered by SCAFFOLD-TRANCHE-004", + ), + authorities={"rune_spine": _spine_doc()}, + project_toolchain={"existing_language": "python"}, + ) + cd.generate_contract(s, doc, trace, contract_id="GEN-1", scope=["src/export"]) + c = s.contract(doc, "GEN-1") + assert c["identities"]["resolution"] == "ADAPT_EXISTING" + assert c["identities"]["toolchain"]["selected_language"] == "python" + assert "capability:exporter" in c["identities"]["affected_entities"] + assert c["identities"]["regression_obligations"] # auto BUILD-BUT-DON'T-BREAK + assert c["ext"]["decision_trace"]["need"]["need_id"] == "need-001" + + +# ── failure behavior (§28) ─────────────────────────────────────────────────── + + +def test_stale_candidate_rejected_in_live_path(): + doc = _spine_doc() + e = ss.entity(doc, "capability:exporter") + e["status"] = "STALE" + trace = cd.make_decision(_need(), authorities={"rune_spine": doc}) + assert trace["resolution"] == "INSUFFICIENT_EVIDENCE" + + +def test_merge_build_new_never_upgrades_from_insufficient(): + build = {"resolution": "BUILD_NEW", "rationale": "brittle"} + insuff = {"resolution": "INSUFFICIENT_EVIDENCE", "rationale": "weak"} + merged = cd.merge_resolutions([build, insuff]) + assert merged["resolution"] == "INSUFFICIENT_EVIDENCE" diff --git a/tests/test_contract_quality.py b/tests/test_contract_quality.py new file mode 100644 index 00000000..29ba4434 --- /dev/null +++ b/tests/test_contract_quality.py @@ -0,0 +1,150 @@ +"""test_contract_quality.py — SCAFFOLD-TRANCHE-004 §30 test plan (A-H). + +Repaired closure semantics: expected-new vs genuinely-missed; independent +observed confirmation; prediction may not self-certify. +""" + +import os +import sys + +import pytest + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src")) + +from rune import scaffold as sc # noqa: E402 +from rune import structural_store as ss # noqa: E402 + + +def _s(tmp_path): + s = sc.Scaffold(tmp_path / ".rune" / "scaffold", "proj") + doc = s.init(purpose="quality tests") + return s, doc + + +def _mk(s, doc, cid, affected=None, expected_new=None): + s.new_contract( + doc, + contract_id=cid, + need="n", + scope=["src/x"], + affected_entities=affected or [], + expected_new_entities=expected_new or [], + ) + s.transition_contract(doc, cid, "approved") + s.transition_contract(doc, cid, "building") + s.transition_contract(doc, cid, "verifying") + return cid + + +def _close(s, doc, cid, observed): + s.close_contract(doc, cid, observed_evidence=observed) + return s.contract(doc, cid)["ext"]["contract_quality"] + + +# A. expected-new entity observed → NOT missed +def test_a_expected_new_observed_not_missed(tmp_path): + s, doc = _s(tmp_path) + _mk(s, doc, "C1", affected=["module:old"], expected_new=["module:fresh"]) + q = _close( + s, + doc, + "C1", + [{"entity": "module:fresh", "source": "file-added"}, {"entity": "module:old", "source": "git-diff"}], + ) + assert "module:fresh" in q["expected_new_observed"] + assert "module:fresh" not in q["genuinely_unexpected_new"] + assert "module:fresh" not in q["missed"] # legacy alias agrees + + +# B. expected-new absent → explicit expected-new-missing +def test_b_expected_new_missing(tmp_path): + s, doc = _s(tmp_path) + _mk(s, doc, "C1", affected=[], expected_new=["module:promised"]) + q = _close(s, doc, "C1", []) + assert q["expected_new_missing"] == ["module:promised"] + assert q["expected_new_observed"] == [] + + +# C. truly unexpected new entity → unexpected category + CANDIDATE +def test_c_unexpected_new(tmp_path): + s, doc = _s(tmp_path) + _mk(s, doc, "C1", affected=["module:a"], expected_new=[]) + q = _close( + s, + doc, + "C1", + [{"entity": "module:a", "source": "git-diff"}, {"entity": "module:surprise", "source": "git-diff"}], + ) + assert q["genuinely_unexpected_new"] == ["module:surprise"] + assert q["candidate_corrections"][0]["entity"] == "module:surprise" + + +# D. predicted existing independently observed → correctly predicted +def test_d_predicted_existing_confirmed(tmp_path): + s, doc = _s(tmp_path) + _mk(s, doc, "C1", affected=["module:a", "module:b"]) + q = _close( + s, doc, "C1", [{"entity": "module:a", "source": "git-diff"}, {"entity": "module:b", "source": "test-run"}] + ) + assert set(q["correctly_predicted"]) == {"module:a", "module:b"} + assert q["predicted_but_unaffected"] == [] + + +# E. predicted existing not observed → predicted-but-unaffected (NOT needless) +def test_e_predicted_but_unaffected(tmp_path): + s, doc = _s(tmp_path) + _mk(s, doc, "C1", affected=["module:a", "module:untouched"]) + q = _close(s, doc, "C1", [{"entity": "module:a", "source": "git-diff"}]) + assert q["predicted_but_unaffected"] == ["module:untouched"] + assert q["correctly_predicted"] == ["module:a"] + # legacy alias preserved + assert q["needless"] == ["module:untouched"] + + +# F. prediction may not self-certify observation +def test_f_no_self_certification(tmp_path): + s, doc = _s(tmp_path) + _mk(s, doc, "C1", affected=["module:a", "module:b"]) + # observe ONLY module:a — module:b must NOT auto-confirm from prediction + q = _close(s, doc, "C1", [{"entity": "module:a", "source": "git-diff"}]) + assert "module:b" not in q["correctly_predicted"] + assert q["predicted_but_unaffected"] == ["module:b"] + + +# G. closure evidence remains independently sourced (sources recorded) +def test_g_evidence_sources_recorded(tmp_path): + s, doc = _s(tmp_path) + _mk(s, doc, "C1", affected=["module:a"]) + q = _close( + s, doc, "C1", [{"entity": "module:a", "source": "git-diff"}, {"entity": "module:a", "source": "test-run"}] + ) + assert set(q["evidence_sources"]) == {"git-diff", "test-run"} + obs_kinds = [o["kind"] for o in doc["observations"]] + assert obs_kinds.count("observed_consequence") == 2 + + +# H. old Construction Contracts remain readable +def test_h_legacy_contract_still_closes(tmp_path): + """A Tranche-2-style contract (no expected_new_entities field) closes + with the repaired semantics without migration.""" + s, doc = _s(tmp_path) + s.new_contract(doc, contract_id="OLD-1", need="old", scope=["src/x"], affected_entities=["module:a"]) + c = s.contract(doc, "OLD-1") + assert c["identities"].get("expected_new_entities") == [] # empty, fine + s.transition_contract(doc, "OLD-1", "approved") + s.transition_contract(doc, "OLD-1", "building") + s.transition_contract(doc, "OLD-1", "verifying") + q = _close(s, doc, "OLD-1", [{"entity": "module:a", "source": "git-diff"}]) + assert q["correctly_predicted"] == ["module:a"] + assert q["expected_new_entities"] == [] + assert q["genuinely_unexpected_new"] == [] + + +def test_record_observed_impact_rejects_unattributed_gently(tmp_path): + """Evidence without entity ids is tolerated (counted) but never + fabricates observed entities.""" + s, doc = _s(tmp_path) + _mk(s, doc, "C1", affected=["module:a"]) + q = _close(s, doc, "C1", [{"detail": "vague note", "source": "chat"}]) + assert q["correctly_predicted"] == [] + assert q["predicted_but_unaffected"] == ["module:a"] diff --git a/tests/test_layout_obligations.py b/tests/test_layout_obligations.py new file mode 100644 index 00000000..3ee52974 --- /dev/null +++ b/tests/test_layout_obligations.py @@ -0,0 +1,156 @@ +"""test_layout_obligations.py — SCAFFOLD-TRANCHE-004 §31 test plan (A-H).""" + +import os +import sys + +import pytest + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src")) + +from rune import construction_decision as cd # noqa: E402 +from rune import layout_contract as lc # noqa: E402 +from rune import scaffold as sc # noqa: E402 +from rune import structural_store as ss # noqa: E402 +from rune import toolchain as tc # noqa: E402 + + +def _doc_with_layouts(): + doc = ss.new_doc() + lc.define_region(doc, "footer-bar", provenance="scaffold", evidence_refs=["issue-105"]) + lc.define_region(doc, "header", provenance="user") + # version display: scaffold-provenance (NOT user-locked — §21 status) + lc.bind_component( + doc, + "version_display", + "footer-bar", + provenance="scaffold", + order=0, + evidence_ref="issue-105", + implementation="src/rune/rune_tui.py:VersionLabel", + ) + # a user-locked element for authority tests + lc.bind_component(doc, "status_bar", "footer-bar", lock=True, provenance="user", order=1, evidence_ref="user-2026") + return doc + + +def _need(**kw): + d = dict( + need_id="n", + objective="tweak footer", + origin="builder", + constraints={}, + evidence_refs=["x"], + approval_context="covered by contract", + ) + d.update(kw) + return cd.Need(**d) + + +# A. affected UI component pulls its Layout Contract into obligations +def test_a_ui_component_inherits_layout_obligation(): + doc = _doc_with_layouts() + obs = cd.layout_obligations_for(doc, ["ui:version_display"]) + assert len(obs) == 1 + o = obs[0] + assert o["component"] == "ui:version_display" + assert o["region"] == "footer-bar" + assert o["lock"] is False + assert "layout_contract_check must PASS" in o["verification"] + + +# B. unrelated backend change inherits NO layout obligations +def test_b_backend_change_no_layout_obligations(): + doc = _doc_with_layouts() + assert cd.layout_obligations_for(doc, ["module:memory_store"]) == [] + assert cd.layout_obligations_for(doc, ["capability:exporter"]) == [] + + +def test_b2_implementation_path_match_pulls_contract(): + doc = _doc_with_layouts() + obs = cd.layout_obligations_for(doc, ["src/rune/rune_tui.py"]) + assert any(o["component"] == "ui:version_display" for o in obs) + + +# C. FLEXIBLE layout obligation carried correctly +def test_c_flexible_obligation(): + doc = _doc_with_layouts() + s = sc.Scaffold("/tmp/never-required", "x") + o = s.layout_obligations(doc, ["ui:version_display"])[0] + assert o["lock"] is False + assert "movable only via authorized layout amendment" in o["obligation"] + assert o["verification"] == "layout_contract_check must PASS" + + +# D. USER-LOCKED layout obligation blocks unauthorized change +def test_d_user_locked_obligation_blocks(): + doc = _doc_with_layouts() + s = sc.Scaffold("/tmp/never-required", "x") + obs = s.layout_obligations(doc, ["ui:status_bar"]) + assert len(obs) == 1 + o = obs[0] + assert o["lock"] is True + assert "USER-LOCKED" in o["obligation"] + assert "explicit user authorization" in o["obligation"] + assert "USER-LOCKED placement unchanged" in o["verification"] + # and the live-path approval gate fires for locked surfaces + gate = cd.needs_user_approval( + "ADAPT_EXISTING", + tc.resolve_toolchain(tc.ToolchainConstraints(existing_language="python")), + obs, + _need(approval_context=""), + ) + assert gate["required"] is True + assert "USER-LOCKED" in gate["reasons"][0] + + +# E. user-authorized layout amendment passes +def test_e_user_authorized_amendment_passes(): + doc = _doc_with_layouts() + lc.amend_layout_contract( + doc, + "status_bar", + new_region="header", + authorized_by="user", + reason="user reposition", + evidence_ref="user-2026-09-13", + ) + # contract follows the user's explicit change + e = ss.entity(doc, "layout:ui:status_bar") + assert e["identities"]["region"] == "header" + # obligation now reflects the amended placement + s = sc.Scaffold("/tmp/never-required", "x") + obs = s.layout_obligations(doc, ["ui:status_bar"]) + assert obs[0]["region"] == "header" + + +# F. unavailable layout adapter remains UNKNOWN — never PASS +def test_f_unknown_never_pass(): + doc = _doc_with_layouts() + result = lc.check_layout(doc, {}) # no adapter observations + assert result["verdict"] == "UNKNOWN" + assert all(c["verdict"] == "UNKNOWN" for c in result["checks"]) + + +# G. drift does NOT rewrite USER-LOCKED intent +def test_g_drift_preserves_user_locked(): + doc = _doc_with_layouts() + violating = {"ui:status_bar": {"region": "header", "order": 0}} + out = lc.layout_drift(doc, violating) + assert out["gate"] == "FAIL" + e = ss.entity(doc, "layout:ui:status_bar") + assert e["identities"]["region"] == "footer-bar" # user intent preserved + assert e["status"] == "DRIFTING" + assert e["identities"]["lock"] is True + # maintenance item records the violation for user review + assert ss.entity(doc, "maintenance:layout-drift-ui:status_bar") is not None + + +# H. version-display stays scaffold-provenance until explicit confirmation +def test_h_version_display_not_user_locked(): + doc = _doc_with_layouts() + e = ss.entity(doc, "layout:ui:version_display") + assert e["identities"]["provenance"] == "scaffold" + assert e["identities"]["lock"] is False # pending user confirmation (§21) + # any attempt to lock it without user provenance is refused + with pytest.raises(ValueError, match="user provenance"): + lc.bind_component(doc, "version_display", "footer-bar", lock=True, provenance="builder")