Scaffold: construction_commands dispatch — the serving wire (T5.15 slice 2) #2472

Merged
conductor merged 2 commits from feat/wire-construction-commands-dispatch into master 2026-10-06 03:11:44 +01:00
2 changed files with 168 additions and 0 deletions

No files matched your search

+95
View File
@@ -171,3 +171,98 @@ def _accept(command_id: str, construction_id: str, correlation_id: str,
"recorded_at": time.strftime("%Y-%m-%dT%H:%M:%SZ",
time.gmtime()),
"idempotent_replay": False}
def dispatch(command_type: str, *, construction_id: str,
correlation_id: str = "", command_id: str = "",
payload: dict | None = None,
store_path: str = "store/scaffold") -> dict:
"""The SERVING layer (T5.15 slice 2): validate the command against the
canonical store, execute the accepted intent through the Construction
Interface, and return the interface's envelope with the command
provenance attached.
Single entry point for `rune scaffold <command>` (the Go proxy) and
any future transport. Idempotency: a repeated command_id replays the
recorded outcome without re-executing.
Refusal still returns success=False envelope? NO — a refused command
is a VALID protocol outcome: the envelope carries accepted=False and
success=True (the dispatch itself worked; the lifecycle refused the
intent). Execution failures carry success=False.
"""
iface_path = None
if store_path and store_path != "store/scaffold":
iface_path = store_path
try:
from rune import construction_interface as ci
# store_path carries the serving layer's "path|project_id" contract
# (a bare path = last segment is the project id, matching how the
# Go proxy and the interface's own default name it).
if iface_path:
path_part, _, proj_part = iface_path.partition("|")
proj = proj_part or path_part.rstrip("/").split("/")[-1]
iface = ci.ConstructionInterface(builder="substrate",
project_store=path_part,
project_id=proj)
else:
iface = ci.ConstructionInterface(builder="substrate")
except Exception as exc: # noqa: BLE001 — serving failure is an envelope, not a crash
return {"accepted": False, "executed": False,
"success": False, "error": f"serving unavailable: {exc}"[:200],
"command_type": command_type,
"construction_id": construction_id}
intent = command(command_type, construction_id=construction_id,
correlation_id=correlation_id, command_id=command_id,
payload=payload, scaffold=iface.scaffold)
if intent.get("idempotent_replay"):
# Repeated delivery: return the recorded outcome WITHOUT executing
# again (the ledger's whole point). The first execution's envelope
# is not re-derivable here, so the replay carries the intent and
# the flag — the caller knows the effect already happened.
return {"accepted": True, "executed": False,
"success": True, "idempotent_replay": True,
"op": intent.get("op"),
"command_type": command_type,
"construction_id": construction_id,
"correlation_id": intent.get("correlation_id", ""),
"command_id": intent.get("command_id", "")}
if not intent.get("accepted"):
return {"accepted": False, "executed": False, "success": True,
"reason": intent.get("reason"),
"command_type": command_type,
"construction_id": construction_id,
"correlation_id": intent.get("correlation_id", ""),
"command_id": intent.get("command_id", ""),
"idempotent_replay": intent.get("idempotent_replay", False)}
op = intent["op"]
args = intent["args"]
ops = {
"resume": lambda: iface.resume(args["contract_id"]),
"transition": lambda: iface.transition(
args["contract_id"], args["phase"],
evidence_ref=f"command:{intent['command_id']}"
+ (f" approved_by:{args['approved_by']}" if args.get("approved_by") else "")),
"amend_scope": lambda: iface.amend_scope(
args["contract_id"], args["add_paths"],
reason=args.get("reason", "substrate context"),
authority=args.get("authority", "substrate")),
}
fn = ops.get(op)
if fn is None:
return {"accepted": True, "executed": False, "success": False,
"error": f"no executor for op {op!r}",
"command_type": command_type,
"construction_id": construction_id}
env = fn()
return {"accepted": True, "executed": True,
"success": bool(env.get("success")),
"envelope": env,
"command_type": command_type,
"construction_id": construction_id,
"correlation_id": intent.get("correlation_id", ""),
"command_id": intent.get("command_id", ""),
"idempotent_replay": False}
+73
View File
@@ -174,3 +174,76 @@ def test_16k_projection_schema_validated(tmp_path):
assert proj.validate(bad) != []
bad2 = dict(p, schema_version=999)
assert proj.validate(bad2) != []
# ── T5.15 slice 2: the dispatch wire (command → interface execution) ────────
def test_dispatch_executes_accepted_transition_end_to_end(tmp_path):
"""A START command on a draft contract executes through the interface:
the phase actually moves — not just an accepted intent."""
store = str(tmp_path / ".rune" / "scaffold")
iface = cmds if False else None # noqa: F841 — readability anchor
from rune import construction_interface as ci
ciface = ci.ConstructionInterface(builder="seed", project_store=store, project_id="proj")
ciface.scaffold.init(purpose="t")
doc = ciface.scaffold.load()
sc.add_entity(doc, id="contract:disp-1", kind="contract",
identities={"objective": "dispatch"}, evidence_refs=["e"])
doc["entities"][-1]["phase"] = "draft"
ciface.scaffold.commit(doc, what="seed")
out = cmds.dispatch("START", construction_id="disp-1",
store_path=store + "|proj")
# external-project store path: dispatch builds its own interface bound
# to the same store
assert out["executed"] is True, out
assert out["success"] is True, out
doc2 = ciface.scaffold.load()
c = sc.entity(doc2, "contract:disp-1")
assert c["phase"] == "approved"
def test_dispatch_refusal_is_a_valid_protocol_outcome(tmp_path):
"""START on a non-draft contract: the lifecycle refuses — the dispatch
itself succeeds (success=True) with accepted=False."""
store = str(tmp_path / ".rune" / "scaffold")
from rune import construction_interface as ci
ciface = ci.ConstructionInterface(builder="seed", project_store=store, project_id="proj")
ciface.scaffold.init(purpose="t")
doc = ciface.scaffold.load()
sc.add_entity(doc, id="contract:disp-2", kind="contract",
identities={"objective": "x"}, evidence_refs=["e"])
doc["entities"][-1]["phase"] = "draft"
ciface.scaffold.commit(doc, what="seed")
out = cmds.dispatch("START", construction_id="disp-2",
payload={"phase": "building"},
store_path=store + "|proj")
# contract starts in draft so START is ACCEPTED here; drive to building
# first to prove the refusal shape:
assert out["executed"] and out["success"]
out2 = cmds.dispatch("START", construction_id="disp-2",
store_path=store + "|proj")
assert out2["accepted"] is False and out2["executed"] is False
assert out2["success"] is True
assert "draft" in out2["reason"]
def test_dispatch_idempotent_replay_does_not_double_execute(tmp_path):
"""Same command_id twice: the second is a replay — the phase does not
move twice and idempotent_replay=True comes back."""
store = str(tmp_path / ".rune" / "scaffold")
from rune import construction_interface as ci
ciface = ci.ConstructionInterface(builder="seed", project_store=store, project_id="proj")
ciface.scaffold.init(purpose="t")
doc = ciface.scaffold.load()
sc.add_entity(doc, id="contract:disp-3", kind="contract",
identities={"objective": "idem"}, evidence_refs=["e"])
doc["entities"][-1]["phase"] = "draft"
ciface.scaffold.commit(doc, what="seed")
first = cmds.dispatch("START", construction_id="disp-3",
command_id="fixed-cmd-1", store_path=store + "|proj")
assert first["executed"] and first["success"]
second = cmds.dispatch("START", construction_id="disp-3",
command_id="fixed-cmd-1", store_path=store + "|proj")
assert second["idempotent_replay"] is True
assert second.get("executed") in (False, None) # replay ≠ execution