feat(scaffolding): affected-surface propagation + requirement completeness gate + impact-aware contract generation (SCAFFOLD-TRANCHE-005)

Origin: maintenance:contract-gen-affected-surface (opened by
DEPLOY-MONOTONIC-001's honest closure — planned work appeared as
genuinely_unexpected because generate_contract dropped the Need's
affected surface).

- construction_decision.py:
  * classify_surface/resolve_surface/resolve_affected_surface:
    open-world surface classification (structural entity / source path /
    workflow config / ui component / layout region / unresolved — never
    dropped) with deterministic resolution against authorities via
    identity, recorded path attributes, and Layout Contract bindings
  * check_completeness: bounded structure-grounded gate BEFORE fit —
    affected-surface entities contribute their IMPLEMENTED contracts to
    the material scope; unrepresented ones = MATERIAL_GAP with full
    provenance (derived_from/rule/evidence) + concrete probe questions.
    Verdicts COMPLETE_ENOUGH/MATERIAL_GAP/UNKNOWN; UNKNOWN never
    silently COMPLETE. PREMATURE-FIT GUARD: a concrete verdict
    (REUSE/SATISFIED/COMPOSE/ADAPT_EXISTING) on a materially incomplete
    requirement is downgraded to INSUFFICIENT_EVIDENCE with the
    would-have-been verdict retained — the fit engine was right GIVEN
    its requirement; the requirement was too narrow
  * record_proposed_requirement: model-proposed requirements are
    PENDING evidence, never structural authority by themselves
  * iterative decision trace: prior_iterations retained with why-it-
    changed provenance; final resolution stays singular
  * test-surface derivation: tests/test_<name>.py in an affected
    surface derives the test:<name> expected-new entity (Rune path
    convention; structural consequence, provenance recorded)
  * impact-aware generate_contract: distinct affected_paths /
    affected_ui_surfaces / affected_regions / workflow_config_surfaces /
    unresolved_surfaces / expected_runtime_effects surfaces; file scope
    GENERATED from affected paths + selected impl paths + expected-new
    paths, caller additions provenance-tracked; file scope != structural
    impact != expected new != runtime effect
- scaffold.py: closure classifies expected RUNTIME effects (an observed
  entity matching a predicted effect phrase = expected, not unexpected;
  prediction still cannot self-certify — independent evidence required);
  legacy contracts unaffected (empty lists, no crash)

REAL PROOFS: §23 read-only replay of the deploy incident — ONE pass
identifies MATERIAL_GAP (contract:monotonic_promotion on
module:deploy_stage), blocks the premature REUSE automatically, emits a
concrete probe question; §22 live proof CONTRACT-GEN-REPAIR-001
generated through the improved path with all surfaces propagated,
regeneration proving the planned test surface is now expected-new.

Tests: 28 new (surface/completeness/trace/runtime/compat plans §24-§28);
suite 1525 green; henxels rc=0; pyright clean.
This commit is contained in:
Nick committed 2026-09-13 13:36:50 +01:00
1 parent 6bc31c513e
commit 535c290917
5 files changed
+7212 -149

No files matched your search

+418 -27
View File
@@ -119,6 +119,293 @@ def normalize_need(need: Need) -> tuple[cf.CapabilityRequirement, list[str]]:
return req, missing
# ── affected-surface classification + resolution (Tranche 5 §3-5) ──────────
_SURFACE_UI = "ui:"
_SURFACE_REGION = "region:"
_SURFACE_CONTRACT = "contract:"
_SURFACE_MODULE = "module:"
def classify_surface(surface: str) -> str:
"""Classify one affected-surface entry (open-world; Tranche 5 §3).
Kinds: structural_entity | source_path | workflow_config | ui_component |
layout_region | unresolved. Never drops an entry — unresolved is a
first-class kind."""
if surface.startswith((_SURFACE_UI,)):
return "ui_component"
if surface.startswith((_SURFACE_REGION,)):
return "layout_region"
if surface.startswith(
(
_SURFACE_CONTRACT,
_SURFACE_MODULE,
_SURFACE_CAPABILITY,
)
):
return "structural_entity"
if surface.endswith(".yml") or surface.endswith(".yaml") or surface.endswith(".json") or surface.endswith(".toml"):
return "workflow_config"
if (
surface.endswith(".py")
or "/" in surface
or surface.endswith(".md")
or surface.endswith(".rs")
or surface.endswith(".ts")
):
return "source_path"
return "unresolved"
_SURFACE_CAPABILITY = "capability:"
def resolve_surface(surface: str, kind: str, authorities: dict[str, dict]) -> dict:
"""Deterministically resolve one surface against the structural
authorities (Tranche 5 §5). No Memory, no LLM archaeology: identity
lookups and recorded path->module mappings only.
Returns {surface, kind, resolved: [...], unresolved_reason: ""}.
resolved entries: {entity_id, authority, via} where via records HOW the
mapping was established (identity | path_attribute | provides)."""
out = {"surface": surface, "kind": kind, "resolved": [], "unresolved_reason": ""}
if kind == "structural_entity":
for name, doc in authorities.items():
e = ss_entity(doc, surface)
if e is not None:
out["resolved"].append({"entity_id": surface, "authority": name, "via": "identity"})
break
if not out["resolved"]:
out["unresolved_reason"] = "entity id not found in any authority"
elif kind == "source_path":
# path -> module via recorded identities.path in any authority
for name, doc in authorities.items():
for e in doc["entities"]:
p = e.get("identities", {}).get("path", "")
if p and (p == surface or p.endswith("/" + surface) or surface.endswith(p)):
out["resolved"].append({"entity_id": e["id"], "authority": name, "via": "path_attribute"})
if not out["resolved"]:
out["unresolved_reason"] = "no authority records this path as an entity (path remains file-scope only)"
elif kind == "ui_component":
for name, doc in authorities.items():
cid = surface if surface.startswith("ui:") else f"ui:{surface}"
e = ss_entity(doc, f"layout:{cid}")
if e is not None:
out["resolved"].append({"entity_id": f"layout:{cid}", "authority": name, "via": "layout_contract"})
if not out["resolved"]:
out["unresolved_reason"] = "no Layout Contract bound for component"
elif kind == "layout_region":
for name, doc in authorities.items():
e = ss_entity(doc, surface if surface.startswith("region:") else f"region:{surface}")
if e is not None:
out["resolved"].append({"entity_id": e["id"], "authority": name, "via": "identity"})
if not out["resolved"]:
out["unresolved_reason"] = "region not defined in any authority"
else:
out["unresolved_reason"] = f"kind {kind} has no deterministic resolver"
return out
def ss_entity(doc: dict, eid: str):
from rune.structural_store import entity as _e
return _e(doc, eid)
def implemented_contracts(doc: dict, entity_id: str) -> list[str]:
"""Contracts an entity implements/exposes/provides (structural fact)."""
out = []
for r in relationships(doc, from_id=entity_id):
if r["type"] in {"implements", "exposes", "provides", "serves"}:
out.append(r["to"])
return sorted(out)
def resolve_affected_surface(need: Need, authorities: dict[str, dict]) -> dict:
"""Classify + resolve the WHOLE affected surface (Tranche 5 §3-5, §13).
Produces the propagated representation the generated contract carries:
affected_existing_entities structural ids (resolved)
affected_paths file-scope entries (mechanical scope)
affected_ui_surfaces ui components / regions found
unresolved_surfaces retained, never dropped
File scope != structural impact: a path stays a path for scope checking
even when it also resolves to a module entity (no authority duplication)."""
result = {
"affected_existing_entities": [],
"affected_paths": [],
"affected_ui_surfaces": [],
"affected_regions": [],
"workflow_config_surfaces": [],
"unresolved_surfaces": [],
"resolutions": [],
}
for surface in need.affected_surface:
kind = classify_surface(surface)
res = resolve_surface(surface, kind, authorities)
result["resolutions"].append(res)
if kind == "source_path":
result["affected_paths"].append(surface)
elif kind == "workflow_config":
result["workflow_config_surfaces"].append(surface)
elif kind == "ui_component":
result["affected_ui_surfaces"].append(surface)
elif kind == "layout_region":
result["affected_regions"].append(surface)
for r in res["resolved"]:
eid = r["entity_id"]
if eid not in result["affected_existing_entities"] and not eid.startswith("layout:"):
result["affected_existing_entities"].append(eid)
if res["unresolved_reason"] and not res["resolved"]:
result["unresolved_surfaces"].append({"surface": surface, "kind": kind, "reason": res["unresolved_reason"]})
for k in (
"affected_existing_entities",
"affected_paths",
"affected_ui_surfaces",
"affected_regions",
"workflow_config_surfaces",
):
result[k] = sorted(set(result[k]))
# §9/§17 DERIVED EXPECTATION (structural consequence, not invention): a
# Rune test path (tests/test_<name>.py) affected by the work implies the
# "test:<name>" surface participates in the build. Derived only when not
# already an existing entity nor explicitly declared; provenance records
# the derivation for closure accounting.
derived = []
for surface in need.affected_surface:
if surface.startswith("tests/test_") and surface.endswith(".py"):
stem = surface[len("tests/test_") : -len(".py")]
test_entity = f"test:{stem}"
exists = any(ss_entity(doc, test_entity) is not None for doc in authorities.values())
if test_entity not in need.constraints.get("expected_new_entities", []) and not exists:
derived.append(
{
"entity": test_entity,
"derived_from": surface,
"rule": "Rune test-path convention: tests/test_<name>.py implies "
"the test:<name> surface participates in the build",
"evidence": f"affected_surface entry {surface}",
}
)
result["derived_expected_new"] = derived
return result
# ── requirement completeness gate (Tranche 5 §6-9) ──────────────────────────
COMPLETE_ENOUGH = "COMPLETE_ENOUGH"
MATERIAL_GAP = "MATERIAL_GAP"
COMPLETENESS_UNKNOWN = "UNKNOWN"
def check_completeness(
req: cf.CapabilityRequirement, need: Need, authorities: dict[str, dict], surface_result: dict
) -> dict:
"""Bounded, structure-grounded completeness check run BEFORE fit.
Rule (deterministic, no model vibes): every affected-surface entry that
resolves to a structural entity contributes that entity's IMPLEMENTED
contracts to the requirement's material scope. If an affected entity
implements contracts NOT represented in the normalized requirement, the
requirement is materially incomplete — the need touches a component
whose obligations it has not stated. That is exactly the deploy-incident
shape: the affected promotion implementation carried an unrepresented
ordering contract while the requirement named only qualification.
Verdicts (Tranche 5 §8):
COMPLETE_ENOUGH all affected entities' contracts are represented
(or none implement contracts) — fit may proceed
MATERIAL_GAP uncovered implemented contracts exist on affected
entities — named with provenance, routed to probe
UNKNOWN no surface resolved — completeness undeterminable;
never silently COMPLETE (§8)
Derived requirements (§9) are structural consequences, not inventions:
each uncovered contract carries derived_from (the entity that
implements it) + evidence (the implements relationship) + rule.
"""
gaps = []
resolved_any = False
for res in surface_result["resolutions"]:
for r in res["resolved"]:
resolved_any = True
for name, doc in authorities.items():
e = ss_entity(doc, r["entity_id"])
if e is None:
continue
for contract in implemented_contracts(doc, r["entity_id"]):
if contract not in req.contracts:
gaps.append(
{
"missing_contract": contract,
"derived_from": r["entity_id"],
"surface": res["surface"],
"authority": name,
"rule": "affected-surface entity implements a "
"contract not represented in the "
"normalized requirement",
"evidence": f"{r['entity_id']} implements {contract} (authority: {name})",
}
)
break # entity found in one authority is enough
if gaps:
# dedupe by (missing_contract, derived_from)
seen = set()
unique = []
for g in gaps:
key = (g["missing_contract"], g["derived_from"])
if key not in seen:
seen.add(key)
unique.append(g)
return {
"verdict": MATERIAL_GAP,
"gaps": sorted(unique, key=lambda g: (g["missing_contract"], g["derived_from"])),
"probe_questions": [
f"does the need's stated failure implicate {g['derived_from']}'s {g['missing_contract']} obligation?"
for g in unique[:5]
],
"note": "MATERIAL_GAP: affected surface carries obligations "
"the requirement does not represent — refine before "
"trusting an apparently-complete fit",
}
if resolved_any:
return {
"verdict": COMPLETE_ENOUGH,
"gaps": [],
"probe_questions": [],
"note": "all resolved affected entities' implemented contracts are represented in the requirement",
}
return {
"verdict": COMPLETENESS_UNKNOWN,
"gaps": [],
"probe_questions": [f"which structural entities does '{s}' map to?" for s in need.affected_surface[:5]],
"note": "no affected surface resolved — completeness undeterminable; UNKNOWN never silently becomes COMPLETE",
}
def record_proposed_requirement(
contract_id: str, *, provider: str, model: str, evidence: list[str], confidence: float
) -> dict:
"""Record a MODEL-PROPOSED requirement addition (Tranche 5 §12). It is
evidence with a verification state — never structural authority by
itself. It becomes accepted only via existing authority, research
evidence, implementation evidence, or explicit user decision; until
then normalize_need excludes it from the requirement's contract set."""
if not provider or not model:
raise ValueError("model-proposed requirement requires provider+model")
if not 0.0 <= confidence <= 1.0:
raise ValueError("confidence must be in [0,1]")
return {
"kind": "model_proposed_requirement",
"contract": contract_id,
"provider": provider,
"model": model,
"evidence": sorted(evidence),
"confidence": confidence,
"verification_state": "PENDING",
}
# ── research routing seam (§6 — honest: recorded route, not execution) ─────
@@ -224,11 +511,22 @@ def make_decision(
authorities: dict[str, dict],
toolchain_constraints: tc.ToolchainConstraints | None = None,
project_toolchain: dict | None = None,
prior_iterations: list[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)."""
constraint (existing toolchain wins — §12).
`prior_iterations` (Tranche 5 §11): earlier decision iterations being
refined — retained in the trace with why-it-changed provenance; the
final resolution stays singular.
Order of operations (Tranche 5 §6): affected-surface resolution →
REQUIREMENT COMPLETENESS GATE → discovery/fit → merge. A MATERIAL_GAP
downgrades premature concrete verdicts (REUSE/SATISFIED/COMPOSE/
ADAPT_EXISTING) to INSUFFICIENT_EVIDENCE with the gap recorded — the
fit engine was right GIVEN its requirement; the requirement was too
narrow."""
req, missing = normalize_need(need)
trace: dict = {
"need": need.to_dict(),
@@ -243,8 +541,17 @@ def make_decision(
"approval": {},
"resolution": "",
"rationale": "",
"iterations": list(prior_iterations or []),
}
# affected-surface classification + resolution (Tranche 5 §3-5)
surface_result = resolve_affected_surface(need, authorities)
trace["affected_surfaces"] = surface_result
# REQUIREMENT COMPLETENESS GATE (Tranche 5 §6-8) — before fit
completeness = check_completeness(req, need, authorities, surface_result)
trace["completeness"] = completeness
# live discovery + fit + resolution per authority (§7-8)
results = []
all_fits = []
@@ -273,6 +580,30 @@ def make_decision(
"resolution": "INSUFFICIENT_EVIDENCE",
"rationale": f"requirement normalization incomplete: {missing}; refusing to build on guesses",
}
if completeness["verdict"] == MATERIAL_GAP and merged["resolution"] in (
"SATISFIED",
"REUSE",
"COMPOSE",
"ADAPT_EXISTING",
"CONFIGURE",
):
# PREMATURE-FIT GUARD (Tranche 5 §6-7): the fit engine was correct
# GIVEN its requirement — but the requirement is materially
# incomplete (affected surface carries unrepresented obligations).
# A concrete verdict on an incomplete requirement is not trustworthy.
merged = {
"resolution": "INSUFFICIENT_EVIDENCE",
"rationale": (
"premature fit blocked: requirement is materially incomplete "
f"({len(completeness['gaps'])} unrepresented obligation(s) on "
"affected surfaces); refine the requirement before trusting "
"an apparently-complete fit"
),
"premature_fit_blocked": {
"would_have_been": merged["resolution"],
"gaps": completeness["gaps"],
},
}
trace["resolution"] = merged["resolution"]
trace["rationale"] = merged.get("rationale", "")
if missing and trace["resolution"] == "INSUFFICIENT_EVIDENCE":
@@ -395,26 +726,68 @@ def obligations_from_trace(trace: dict, req: cf.CapabilityRequirement) -> dict:
def generate_contract(
s, doc: dict, trace: dict, *, contract_id: str, scope: list[str], proposer_note: str = ""
s, doc: dict, trace: dict, *, contract_id: str, scope: list[str] | None = None, 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."""
"""Populate a Construction Contract from the decision trace (Tranche 5
§13-17 IMPACT-AWARE generation). The Need's affected surface is never
lost — it is classified and propagated into distinct surfaces:
affected_entities structural entity ids (existing)
expected_new_entities planned new structural entities
ext.affected_paths file-scope entries (mechanical scope check)
ext.affected_ui_surfaces ui components (layout obligations follow)
ext.unresolved_surfaces retained, never dropped
ext.expected_runtime_effects operational effects (deployment:current
advances etc.) — accounting metadata, NOT a
workflow engine; closure requires independent
observation before marking them observed.
File scope: generated from affected paths + selected capability
implementation paths + explicit expected-new paths — NOT unrestricted
repo scope. `scope` param may still extend it; generated paths are
recorded as such (provenance: affected-surface).
"""
merged = trace["_merged"]
req = trace["requirement"]
surfaces = trace.get("affected_surfaces", {})
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", []
# structural affected: selected candidates + requirement contracts +
# resolved surface entities — the union the old generator partially lost
affected = {c["id"] for c in trace["candidates"] if c["id"] in selected}
affected |= set(trace["requirement"].get("contracts", []))
affected |= set(surfaces.get("affected_existing_entities", []))
# file scope: generated (affected paths + selected impl paths + expected
# new paths) UNION caller-supplied additions, provenance-tracked
affected_paths = list(surfaces.get("affected_paths", []))
impl_paths = []
for c in trace["candidates"]:
if c["id"] in selected:
p = c.get("identities", {}).get("path", "")
if p:
impl_paths.append(p)
expected_new_paths = trace["need"]["constraints"].get("expected_new_source_paths", [])
generated_scope = sorted(
set(affected_paths)
| set(surfaces.get("workflow_config_surfaces", []))
| set(impl_paths)
| set(expected_new_paths)
)
caller_scope = sorted(set(scope or []) - set(generated_scope))
final_scope = sorted(set(generated_scope) | set(caller_scope))
expected_runtime = sorted(trace["need"]["constraints"].get("expected_runtime_effects", []))
obl = trace["obligations"]
s.new_contract(
doc,
contract_id=contract_id,
need=trace["need"]["objective"],
origin=trace["need"]["origin"],
scope=sorted(scope),
scope=final_scope,
requirement=req.get("objective", ""),
gap_evidence=merged.get("rationale", ""),
research_refs=(
@@ -423,8 +796,10 @@ def generate_contract(
),
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", []),
affected_entities=sorted(affected),
expected_new_entities=sorted(set(
trace["need"]["constraints"].get("expected_new_entities", [])
) | {d["entity"] for d in surfaces.get("derived_expected_new", [])}),
expected_consumers=[],
regression_obligations=obl["regression"],
verification_obligations=sorted(set(obl["verification"])),
@@ -433,23 +808,39 @@ def generate_contract(
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",
)
}
e.setdefault("ext", {}).update(
{
"decision_trace": {
k: trace[k]
for k in (
"need",
"requirement",
"candidates",
"fits",
"resolution",
"rationale",
"research",
"toolchain",
"approval",
"obligations",
"layout_obligations",
"normalization_missing",
"completeness",
"affected_surfaces",
"iterations",
)
},
# distinct impact surfaces (Tranche 5 §13) — file scope != structural
# impact != expected new != runtime effect
"affected_paths": affected_paths,
"affected_ui_surfaces": surfaces.get("affected_ui_surfaces", []),
"affected_regions": surfaces.get("affected_regions", []),
"workflow_config_surfaces": surfaces.get("workflow_config_surfaces", []),
"unresolved_surfaces": surfaces.get("unresolved_surfaces", []),
"expected_runtime_effects": expected_runtime,
"scope_provenance": {"generated_from_affected_surface": generated_scope, "caller_added": caller_scope},
}
)
if proposer_note:
e["ext"]["decision_trace"]["proposer_note"] = proposer_note
return e
+17 -1
View File
@@ -465,6 +465,12 @@ class Scaffold:
predicted = e.get("ext", {}).get("predicted_frontier")
affected = e.get("identities", {}).get("affected_entities", [])
expected_new = set(e.get("identities", {}).get("expected_new_entities", []))
# Tranche 5 §14: expected RUNTIME effects (deployment:current advances
# etc.) are prediction/accounting metadata, not workflow steps. An
# observed entity matching an expected runtime effect is EXPECTED,
# not genuinely unexpected — but only when independently observed
# (§15: prediction never self-certifies; the evidence item must exist).
expected_runtime = set(e.get("ext", {}).get("expected_runtime_effects", []))
quality: dict = {"contract": contract_id, "captured_at": now()}
# independent observed impact (§17): evidence items only
@@ -484,7 +490,14 @@ class Scaffold:
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)
# effect strings are phrases ("deployment:current advances"); an
# observed entity matches when an expected effect STARTS with its id
matched_runtime = {o for o in obs_set if any(eff.startswith(o) for eff in expected_runtime)}
expected_runtime_observed = sorted(
eff for eff in expected_runtime if any(eff.startswith(o) for o in matched_runtime)
)
expected_runtime_missing = sorted(expected_runtime - set(expected_runtime_observed))
genuinely_unexpected_new = sorted(obs_set - pred_existing - expected_new - matched_runtime)
quality.update(
{
@@ -497,6 +510,9 @@ class Scaffold:
"predicted_but_unaffected": predicted_but_unaffected,
"expected_new_observed": expected_new_observed,
"expected_new_missing": expected_new_missing,
"expected_runtime_effects": sorted(expected_runtime),
"expected_runtime_observed": expected_runtime_observed,
"expected_runtime_missing": sorted(expected_runtime - obs_set),
"genuinely_unexpected_new": genuinely_unexpected_new,
# legacy aliases (Tranche 2/3 consumers)
"missed": genuinely_unexpected_new,
File diff suppressed because it is too large. Load diff
+137 -121
View File
@@ -2,7 +2,7 @@
"authority_generations": {
"ast-import-projector": {
"generation": 0,
"last_success": "2026-09-13T12:08:10Z",
"last_success": "2026-09-13T12:30:19Z",
"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-13T12:08:10Z",
"last_success": "2026-09-13T12:30:19Z",
"observed": [
"deployed_as|module:abstraction|deployment:current",
"deployed_as|module:adaptive_router|deployment:current",
@@ -502,7 +502,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code",
"self-model"
@@ -522,7 +522,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": []
},
{
@@ -539,7 +539,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": []
},
{
@@ -556,7 +556,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": []
},
{
@@ -573,7 +573,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": []
},
{
@@ -590,7 +590,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": []
},
{
@@ -607,7 +607,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": []
},
{
@@ -616,14 +616,14 @@
],
"id": "deployment:current",
"identities": {
"deployed_at": "2026-09-13T12:03:08Z",
"deployed_sha": "386137dc14b5",
"deployed_at": "2026-09-13T12:09:52Z",
"deployed_sha": "6bc31c513e77",
"deployed_version": "0.66.38",
"observed_from": "/mnt/workdrive/rune-code/current"
},
"kind": "deployment_surface",
"maturity": "LIVE_PROVEN",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": []
},
{
@@ -639,7 +639,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -657,7 +657,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -675,7 +675,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -693,7 +693,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -711,7 +711,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -729,7 +729,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -747,7 +747,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -765,7 +765,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -783,7 +783,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -801,7 +801,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -819,7 +819,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -837,7 +837,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -855,7 +855,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -873,7 +873,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -891,7 +891,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -909,7 +909,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -927,7 +927,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -945,7 +945,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -963,7 +963,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -981,7 +981,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -999,7 +999,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1017,7 +1017,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1035,7 +1035,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1053,7 +1053,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1071,7 +1071,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1089,7 +1089,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1106,7 +1106,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1124,7 +1124,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1142,7 +1142,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1160,7 +1160,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1177,7 +1177,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1195,7 +1195,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1213,7 +1213,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1230,7 +1230,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1247,7 +1247,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1265,7 +1265,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1282,7 +1282,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1300,7 +1300,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1317,7 +1317,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1334,7 +1334,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1350,7 +1350,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1366,7 +1366,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1382,7 +1382,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1400,7 +1400,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1418,7 +1418,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1436,7 +1436,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1454,7 +1454,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1472,7 +1472,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1490,7 +1490,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1508,7 +1508,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1526,7 +1526,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1544,7 +1544,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1562,7 +1562,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1580,7 +1580,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1598,7 +1598,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1615,7 +1615,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1632,7 +1632,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1649,7 +1649,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1667,7 +1667,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1684,7 +1684,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1701,7 +1701,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1719,7 +1719,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1737,7 +1737,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1755,7 +1755,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1773,7 +1773,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1790,7 +1790,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1808,7 +1808,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1825,7 +1825,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1842,7 +1842,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1860,7 +1860,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1878,7 +1878,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1896,7 +1896,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1913,7 +1913,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1931,7 +1931,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1949,7 +1949,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1966,7 +1966,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -1983,7 +1983,7 @@
},
"kind": "module",
"maturity": "WIRED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2001,7 +2001,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2019,7 +2019,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2037,7 +2037,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2055,7 +2055,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2073,7 +2073,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2091,7 +2091,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2109,7 +2109,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2127,7 +2127,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2145,7 +2145,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2163,7 +2163,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2181,7 +2181,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2199,7 +2199,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2217,7 +2217,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2235,7 +2235,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2253,7 +2253,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2271,7 +2271,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2289,7 +2289,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2307,7 +2307,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2324,7 +2324,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2340,7 +2340,7 @@
},
"kind": "module",
"maturity": "PRESENT",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2357,7 +2357,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2373,7 +2373,7 @@
},
"kind": "module",
"maturity": "PRESENT",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2389,7 +2389,7 @@
},
"kind": "module",
"maturity": "PRESENT",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2405,7 +2405,7 @@
},
"kind": "module",
"maturity": "PRESENT",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2422,7 +2422,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2438,7 +2438,7 @@
},
"kind": "module",
"maturity": "PRESENT",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2455,7 +2455,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2471,7 +2471,7 @@
},
"kind": "module",
"maturity": "PRESENT",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2487,7 +2487,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2503,7 +2503,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2519,7 +2519,7 @@
},
"kind": "module",
"maturity": "EXERCISED",
"observed_at": "2026-09-13T12:08:10Z",
"observed_at": "2026-09-13T12:30:19Z",
"tags": [
"code"
]
@@ -2788,7 +2788,7 @@
"tags": []
}
],
"generated_at": "2026-09-13T12:08:10Z",
"generated_at": "2026-09-13T12:30:19Z",
"observations": [
{
"authority": "cli-invocation",
@@ -3359,6 +3359,22 @@
"observed_at": "2026-09-13T12:08:10Z",
"observed_from": "/mnt/workdrive/rune-code/current"
},
{
"deployed_at": "2026-09-13T12:09:52Z",
"deployed_sha": "6bc31c513e77",
"deployed_version": "0.66.38",
"kind": "deployed_identity",
"observed_at": "2026-09-13T12:19:03Z",
"observed_from": "/mnt/workdrive/rune-code/current"
},
{
"deployed_at": "2026-09-13T12:09:52Z",
"deployed_sha": "6bc31c513e77",
"deployed_version": "0.66.38",
"kind": "deployed_identity",
"observed_at": "2026-09-13T12:30:19Z",
"observed_from": "/mnt/workdrive/rune-code/current"
},
{
"deployed_sha": "2731db03f4bd",
"deployed_version": "0.66.33",
+464
View File
@@ -0,0 +1,464 @@
"""test_surface_completeness.py — SCAFFOLD-TRANCHE-005 test plans
§24 (affected surfaces), §25 (requirement completeness), §26 (iterative
trace), §27 (expected runtime effects), §28 (backward compat)."""
import json
import os
import subprocess
import sys
import pytest
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
from rune import construction_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
def _authorities():
"""Spine-like authority: deploy module with a promotion contract the
requirement does NOT represent (the deploy-incident shape), plus a
path-mapped module, plus a UI component with a Layout Contract."""
spine = ss.new_doc()
ss.add_entity(
spine,
id="module:deploy_stage",
kind="module",
identities={"path": "scripts/deploy_stage.py"},
maturity="WIRED",
evidence_refs=["f"],
)
ss.add_entity(spine, id="contract:monotonic_promotion", kind="contract", identities={}, evidence_refs=["f"])
ss.add_relationship(
spine,
type="implements",
from_id="module:deploy_stage",
to_id="contract:monotonic_promotion",
evidence_refs=["f"],
)
ss.add_entity(spine, id="contract:fail_closed_deployment", kind="contract", identities={}, evidence_refs=["f"])
ss.add_entity(
spine,
id="module:deploy_qualify",
kind="module",
identities={"path": "scripts/deploy_qualify.py"},
maturity="WIRED",
evidence_refs=["f"],
)
ss.add_relationship(
spine,
type="implements",
from_id="module:deploy_qualify",
to_id="contract:fail_closed_deployment",
evidence_refs=["f"],
)
scaffold = ss.new_doc()
lc.define_region(scaffold, "footer-bar", provenance="scaffold")
lc.bind_component(
scaffold, "version_display", "footer-bar", provenance="scaffold", order=0, implementation="src/rune/rune_tui.py"
)
return {"rune_spine": spine, "project_scaffold": scaffold}
def _need(**kw):
d = dict(
need_id="n5",
objective="prevent deploy regression",
origin="user",
constraints={"contracts": ["contract:fail_closed_deployment"]},
affected_surface=["scripts/deploy_qualify.py"],
evidence_refs=["x"],
approval_context="covered",
)
d.update(kw)
return cd.Need(**d)
# ── §24 affected surfaces ───────────────────────────────────────────────────
def test_24a_source_path_propagates_to_file_scope(tmp_path):
s, doc = _gen(tmp_path)
c = s.contract(doc, "G5")
assert "scripts/deploy_qualify.py" in c["ext"]["affected_paths"]
assert "scripts/deploy_qualify.py" in c["identities"]["scope"]
def test_24b_mapped_path_resolves_to_module():
res = cd.resolve_affected_surface(_need(), _authorities())
assert "module:deploy_qualify" in res["affected_existing_entities"]
r = next(r for r in res["resolutions"] if r["surface"] == "scripts/deploy_qualify.py")
assert r["resolved"][0]["via"] == "path_attribute"
def test_24c_unresolved_path_retained_not_dropped():
need = _need(affected_surface=["scripts/brand_new_thing.py"])
res = cd.resolve_affected_surface(need, _authorities())
assert any(u["surface"] == "scripts/brand_new_thing.py" for u in res["unresolved_surfaces"])
assert "scripts/brand_new_thing.py" in res["affected_paths"] # still scoped
def test_24d_ui_component_pulls_layout_contract():
need = _need(affected_surface=["ui:version_display"])
res = cd.resolve_affected_surface(need, _authorities())
assert "ui:version_display" in res["affected_ui_surfaces"]
r = res["resolutions"][0]
assert r["resolved"][0]["via"] == "layout_contract"
trace = cd.make_decision(need, authorities=_authorities())
assert any(o["component"] == "ui:version_display" for o in trace["layout_obligations"])
def test_24e_region_surface_pulls_layout_obligations():
need = _need(affected_surface=["region:footer-bar"])
trace = cd.make_decision(need, authorities=_authorities())
assert any(o["region"] == "footer-bar" for o in trace["layout_obligations"])
def test_24f_workflow_config_mechanically_scoped(tmp_path):
s, doc = _gen(tmp_path, affected_surface=["scripts/deploy_qualify.py", ".gitea/workflows/deploy.yml"])
c = s.contract(doc, "G5")
assert ".gitea/workflows/deploy.yml" in c["ext"]["workflow_config_surfaces"]
assert ".gitea/workflows/deploy.yml" in c["identities"]["scope"]
def test_24g_affected_surface_not_auto_expected_new(tmp_path):
s, doc = _gen(tmp_path)
c = s.contract(doc, "G5")
# affected existing entities never leak into expected-new
assert c["identities"]["expected_new_entities"] == []
assert c["identities"]["affected_entities"] # but affected is populated
def test_24h_expected_new_path_entity_distinct(tmp_path):
s = sc.Scaffold(tmp_path / ".rune" / "scaffold", "p5")
doc = s.init(purpose="t")
need = _need(
constraints={
"contracts": ["contract:fail_closed_deployment"],
"expected_new_entities": ["module:fresh_thing"],
"expected_new_source_paths": ["scripts/fresh_thing.py"],
},
affected_surface=["scripts/deploy_qualify.py"],
evidence_refs=["x"],
)
trace = cd.make_decision(need, authorities=_authorities())
cd.generate_contract(s, doc, trace, contract_id="G5H", scope=None)
c = s.contract(doc, "G5H")
assert c["identities"]["expected_new_entities"] == ["module:fresh_thing"]
assert "scripts/fresh_thing.py" in c["identities"]["scope"] # expected-new path scoped
assert "scripts/fresh_thing.py" not in c["ext"]["affected_paths"]
def test_24i_contract_roundtrip_preserves_surfaces(tmp_path):
s, doc = _gen(tmp_path, affected_surface=["scripts/deploy_qualify.py", "ui:version_display", "scripts/unmapped.py"])
s.save(doc)
doc2 = sc.Scaffold(tmp_path / ".rune" / "scaffold", "p5").load()
c = doc2 and sc.Scaffold(tmp_path / ".rune" / "scaffold", "p5").contract(doc2, "G5")
assert c["ext"]["affected_paths"] == ["scripts/deploy_qualify.py", "scripts/unmapped.py"]
assert c["ext"]["affected_ui_surfaces"] == ["ui:version_display"]
assert any(u["surface"] == "scripts/unmapped.py" for u in c["ext"]["unresolved_surfaces"])
# ── §25 requirement completeness ────────────────────────────────────────────
def _gen(tmp_path, **need_kw):
s = sc.Scaffold(tmp_path / ".rune" / "scaffold", "p5")
doc = s.init(purpose="t5")
need = _need(**need_kw)
trace = cd.make_decision(need, authorities=_authorities(), project_toolchain={"existing_language": "python"})
cd.generate_contract(s, doc, trace, contract_id="G5", scope=None)
return s, doc
def test_25a_complete_requirement_complete_enough():
need = _need(
constraints={"contracts": ["contract:fail_closed_deployment"]}, affected_surface=["scripts/deploy_qualify.py"]
)
trace = cd.make_decision(need, authorities=_authorities())
assert trace["completeness"]["verdict"] == cd.COMPLETE_ENOUGH
assert trace["resolution"] == "REUSE" # fit proceeds
def test_25b_affected_stage_missing_material_gap():
"""THE deploy-incident shape: requirement names qualification only, but
the affected surface includes the promotion implementation carrying an
unrepresented ordering contract."""
need = _need(affected_surface=["scripts/deploy_qualify.py", "scripts/deploy_stage.py"])
trace = cd.make_decision(need, authorities=_authorities())
assert trace["completeness"]["verdict"] == cd.MATERIAL_GAP
gaps = {g["missing_contract"] for g in trace["completeness"]["gaps"]}
assert "contract:monotonic_promotion" in gaps
# PREMATURE-FIT GUARD: without the guard this resolves REUSE/SATISFIED
assert trace["resolution"] == "INSUFFICIENT_EVIDENCE"
assert trace["_merged"].get("premature_fit_blocked", {}).get("gaps")
# gap provenance: derived_from the entity, with rule + evidence
g = next(g for g in trace["completeness"]["gaps"] if g["missing_contract"] == "contract:monotonic_promotion")
assert g["derived_from"] == "module:deploy_stage"
assert g["rule"] and g["evidence"]
def test_25c_no_resolution_unknown():
need = _need(affected_surface=["totally/unknown.xyz"])
trace = cd.make_decision(need, authorities=_authorities())
assert trace["completeness"]["verdict"] == cd.COMPLETENESS_UNKNOWN
def test_25d_unknown_never_becomes_complete():
need = _need(affected_surface=["totally/unknown.xyz"])
trace = cd.make_decision(need, authorities=_authorities())
assert trace["completeness"]["verdict"] != cd.COMPLETE_ENOUGH
assert "undeterminable" in trace["completeness"]["note"]
def test_25e_derived_requirement_provenance():
need = _need(affected_surface=["scripts/deploy_qualify.py", "scripts/deploy_stage.py"])
trace = cd.make_decision(need, authorities=_authorities())
g = trace["completeness"]["gaps"][0]
assert g["derived_from"] and g["evidence"] and g["rule"]
def test_25f_model_proposal_not_structural_authority():
"""A model-proposed contract is recorded with provider/confidence and
verification state PENDING — it does not enter the requirement's
contract set as authority."""
proposed = cd.record_proposed_requirement(
"contract:model_claimed", provider="local-model", model="m", evidence=["hunch"], confidence=0.4
)
assert proposed["verification_state"] == "PENDING"
assert proposed["provider"] == "local-model"
# normalization does not accept it as a contract
need = _need(constraints={"contracts": ["contract:fail_closed_deployment"], "model_proposed": [proposed]})
req, _ = cd.normalize_need(need)
assert "contract:model_claimed" not in req.contracts
def test_25g_consumer_contracts_derive_regression():
spine = _authorities()["rune_spine"]
ss.add_entity(spine, id="module:consumer", kind="module", identities={}, evidence_refs=["f"])
ss.add_relationship(
spine, type="consumes", from_id="module:consumer", to_id="module:deploy_qualify", evidence_refs=["f"]
)
need = _need(affected_surface=["scripts/deploy_qualify.py"])
trace = cd.make_decision(need, authorities={"rune_spine": spine})
assert trace["resolution"] == "REUSE"
reg = " ".join(trace["obligations"]["regression"])
assert "module:consumer" in reg
def test_25h_adapt_existing_includes_old_plus_new():
spine = _authorities()["rune_spine"]
ss.add_entity(spine, id="contract:extra_obligation", kind="contract", identities={}, evidence_refs=["f"])
ss.add_relationship(
spine,
type="implements",
from_id="module:deploy_qualify",
to_id="contract:extra_obligation",
evidence_refs=["f"],
)
need = _need(affected_surface=["scripts/deploy_qualify.py"])
need.constraints["contracts"] = ["contract:fail_closed_deployment", "contract:extra_obligation"]
trace = cd.make_decision(need, authorities={"rune_spine": spine})
assert trace["completeness"]["verdict"] == cd.COMPLETE_ENOUGH
assert trace["resolution"] == "REUSE" # exact fit on both contracts
assert "new behavior proven by tests" in " ".join(trace["obligations"]["verification"])
def test_25i_compose_derives_boundary_verification():
spine = _authorities()["rune_spine"]
need = _need(affected_surface=["scripts/deploy_qualify.py", "scripts/deploy_stage.py"])
need.constraints["contracts"] = ["contract:fail_closed_deployment", "contract:monotonic_promotion"]
trace = cd.make_decision(need, authorities={"rune_spine": spine})
assert trace["resolution"] == "COMPOSE"
assert "composition boundary behavior verified end-to-end" in " ".join(trace["obligations"]["verification"])
comp = trace["obligations"]["composition"][0]
assert set(comp["components"]) == {"module:deploy_qualify", "module:deploy_stage"}
def test_25j_layout_lock_derives_preservation():
scaffold = _authorities()["project_scaffold"]
lc.bind_component(
scaffold, "status_bar", "footer-bar", lock=True, provenance="user", order=1, evidence_ref="user-2026"
)
need = _need(affected_surface=["ui:status_bar"])
trace = cd.make_decision(need, authorities=_authorities() | {"project_scaffold": scaffold})
lo = [o for o in trace["layout_obligations"] if o["component"] == "ui:status_bar"]
assert lo and lo[0]["lock"] is True
assert "explicit user authorization" in lo[0]["obligation"]
# and the approval gate fires for the locked surface
assert any("USER-LOCKED" in r for r in trace["approval"]["reasons"]) or trace["approval"]["covered_by"]
def test_25k_completeness_prevents_premature_reuse():
"""§23 core test, fixture form: the deploy-like Need must NOT resolve
REUSE while the affected promotion surface carries an unrepresented
contract."""
need = _need(affected_surface=["scripts/deploy_qualify.py", "scripts/deploy_stage.py"])
trace = cd.make_decision(need, authorities=_authorities())
assert trace["resolution"] != "REUSE"
assert trace["completeness"]["verdict"] == cd.MATERIAL_GAP
blocked = trace["_merged"]["premature_fit_blocked"]
assert blocked["would_have_been"] in ("REUSE", "SATISFIED")
# ── §26 iterative trace ──────────────────────────────────────────────────────
def test_26_iterative_trace_durable(tmp_path):
"""initial normalization → gap → refinement → revised → final decision;
all retained; fresh process reconstructs without transcript."""
s = sc.Scaffold(tmp_path / ".rune" / "scaffold", "p26")
doc = s.init(purpose="t26")
# iteration 1: narrow requirement → premature fit blocked
need1 = _need(affected_surface=["scripts/deploy_qualify.py", "scripts/deploy_stage.py"])
t1 = cd.make_decision(need1, authorities=_authorities())
assert t1["resolution"] == "INSUFFICIENT_EVIDENCE"
assert t1["_merged"]["premature_fit_blocked"]["would_have_been"] == "REUSE"
# evidence/refinement: the promotion contract is added to the requirement
need2 = _need(
constraints={"contracts": ["contract:fail_closed_deployment", "contract:monotonic_promotion"]},
affected_surface=["scripts/deploy_qualify.py", "scripts/deploy_stage.py"],
evidence_refs=["x", "refinement:completeness-gap-iter1"],
)
t2 = cd.make_decision(
need2,
authorities=_authorities(),
prior_iterations=[
{
"iteration": 1,
"normalized_contracts": need1.constraints["contracts"],
"completeness": t1["completeness"]["verdict"],
"gaps": [g["missing_contract"] for g in t1["completeness"]["gaps"]],
"resolution": t1["resolution"],
"refined_by": "completeness gap evidence",
}
],
)
assert t2["resolution"] == "COMPOSE"
assert t2["iterations"][0]["gaps"] == ["contract:monotonic_promotion"]
cd.generate_contract(s, doc, t2, contract_id="IT1", scope=None)
s.transition_contract(doc, "IT1", "approved")
s.save(doc)
# fresh process
script = (
"import sys, json;"
"sys.path.insert(0, %r);"
"from rune import scaffold;"
"s = scaffold.Scaffold(%r, 'p26');"
"doc = s.load();"
"c = s.contract(doc, 'IT1');"
"t = c['ext']['decision_trace'];"
"print(json.dumps({'iterations': len(t['iterations']),"
"'iter1_gaps': t['iterations'][0]['gaps'],"
"'iter1_resolution': t['iterations'][0]['resolution'],"
"'refined_by': t['iterations'][0]['refined_by'],"
"'final_resolution': t['resolution'],"
"'final_contracts': t['requirement']['contracts']}))"
) % (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)
assert rec["iterations"] == 1
assert rec["iter1_gaps"] == ["contract:monotonic_promotion"]
assert rec["iter1_resolution"] == "INSUFFICIENT_EVIDENCE"
assert rec["refined_by"] == "completeness gap evidence"
assert rec["final_resolution"] == "COMPOSE"
assert "contract:monotonic_promotion" in rec["final_contracts"]
# ── §27 expected runtime effects ─────────────────────────────────────────────
def _close_with(tmp_path, expected_runtime, observed):
s = sc.Scaffold(tmp_path / ".rune" / "scaffold", "p27")
doc = s.init(purpose="t27")
s.new_contract(
doc, contract_id="R1", need="n", scope=["src/x"], affected_entities=["module:a"], expected_new_entities=[]
)
c = s.contract(doc, "R1")
c.setdefault("ext", {})["expected_runtime_effects"] = expected_runtime
s.transition_contract(doc, "R1", "approved")
s.transition_contract(doc, "R1", "building")
s.transition_contract(doc, "R1", "verifying")
s.close_contract(doc, "R1", observed_evidence=observed)
return s.contract(doc, "R1")["ext"]["contract_quality"]
def test_27a_expected_runtime_observed_not_unexpected(tmp_path):
q = _close_with(
tmp_path, ["deployment:current advances"], [{"entity": "deployment:current", "source": "deployed-identity"}]
)
assert q["expected_runtime_observed"] == ["deployment:current advances"]
assert "deployment:current" not in q["genuinely_unexpected_new"]
def test_27b_expected_runtime_missing(tmp_path):
q = _close_with(tmp_path, ["cache invalidated"], [])
assert q["expected_runtime_missing"] == ["cache invalidated"]
assert q["expected_runtime_observed"] == []
def test_27c_unpredicted_runtime_genuinely_unexpected(tmp_path):
q = _close_with(tmp_path, [], [{"entity": "deployment:current", "source": "deployed-identity"}])
assert "deployment:current" in q["genuinely_unexpected_new"]
def test_27d_no_self_certification(tmp_path):
"""Predicting the runtime effect does not observe it: no evidence item →
missing, and correctly_predicted unaffected."""
q = _close_with(tmp_path, ["deployment:current advances"], [])
assert q["expected_runtime_missing"] == ["deployment:current advances"]
assert q["expected_runtime_observed"] == []
def test_27e_deployment_current_fixture(tmp_path):
"""The DEPLOY-MONOTONIC-001 defect shape, now correct: a release-class
contract that predicts the deployment advance closes clean."""
q = _close_with(
tmp_path,
["deployment:current advances"],
[{"entity": "module:a", "source": "git-diff"}, {"entity": "deployment:current", "source": "deployed-identity"}],
)
assert q["correctly_predicted"] == ["module:a"]
assert q["expected_runtime_observed"] == ["deployment:current advances"]
assert q["genuinely_unexpected_new"] == []
# ── §28 backward compatibility ───────────────────────────────────────────────
def test_28_old_contract_closes_without_new_fields(tmp_path):
s = sc.Scaffold(tmp_path / ".rune" / "scaffold", "p28")
doc = s.init(purpose="t28")
# old-shape: no expected_runtime_effects, no expected_new_entities
s.new_contract(doc, contract_id="OLD", need="old", scope=["src/x"], affected_entities=["module:a"])
c = s.contract(doc, "OLD")
assert not c.get("ext", {}).get("expected_runtime_effects") # empty, not crash
s.transition_contract(doc, "OLD", "approved")
s.transition_contract(doc, "OLD", "building")
s.transition_contract(doc, "OLD", "verifying")
s.close_contract(doc, "OLD", observed_evidence=[{"entity": "module:a", "source": "git-diff"}])
q = s.contract(doc, "OLD")["ext"]["contract_quality"]
assert q["correctly_predicted"] == ["module:a"]
assert q["expected_runtime_effects"] == [] # empty, not crash
def test_28_tranche4_contract_data_still_readable(tmp_path):
s = sc.Scaffold(tmp_path / ".rune" / "scaffold", "p28b")
doc = s.init(purpose="t28b")
s.new_contract(
doc,
contract_id="T4SHAPE",
need="n",
scope=["src/x"],
affected_entities=["module:a"],
expected_new_entities=["module:b"],
)
s.transition_contract(doc, "T4SHAPE", "approved")
s.transition_contract(doc, "T4SHAPE", "building")
s.transition_contract(doc, "T4SHAPE", "verifying")
s.close_contract(doc, "T4SHAPE", observed_evidence=[{"entity": "module:b", "source": "file-added"}])
q = s.contract(doc, "T4SHAPE")["ext"]["contract_quality"]
assert q["expected_new_observed"] == ["module:b"]