549 lines
22 KiB
Python
549 lines
22 KiB
Python
"""Canonical initial projection for the exact Single-Host supersession child.
|
|
|
|
The source business execution digest is lineage evidence. It is deliberately
|
|
not used as the child execution-envelope digest: the canonical envelope binds
|
|
the child Task id and therefore has its own server-derived digest.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
import hashlib
|
|
import json
|
|
import sqlite3
|
|
from typing import Any, Mapping
|
|
|
|
from aios_agent_task_initial_execution_projection import (
|
|
InitialExecutionProjectionError,
|
|
InitialExecutionProjectionRequest,
|
|
InitialExecutionProjectionStore,
|
|
RUNTIME_CAPABILITY_RE,
|
|
_now,
|
|
_require_string,
|
|
_required_authorization_id,
|
|
)
|
|
from aios_online_agent_execution import (
|
|
ExecutionProjectionError,
|
|
GovernedExecutionBinding,
|
|
validate_execution_envelope,
|
|
)
|
|
from aios_task_lineage_supersession import (
|
|
CANONICAL_PROFILE,
|
|
CANONICAL_PROFILE_VERSION,
|
|
CHILD_TASK_ID,
|
|
DECISION_SCHEMA,
|
|
EXECUTION_DIGEST as SOURCE_BUSINESS_EXECUTION_DIGEST,
|
|
EXTERNAL_JOB_ID,
|
|
GENERATION,
|
|
OWNER_KEY_ID,
|
|
OWNER_NAMESPACE,
|
|
OWNER_PRINCIPAL,
|
|
RECEIPT_SCHEMA as SUPERSESSION_RECEIPT_SCHEMA,
|
|
REPOSITORY,
|
|
SOURCE_TASK_ID,
|
|
SUPERSESSION_ORDINAL,
|
|
TARGET_BRANCH,
|
|
canonical_json,
|
|
decision_payload,
|
|
)
|
|
|
|
|
|
PROJECTION_INTENT_SCHEMA = "aios.task-lineage-supersession-initial-projection-intent.v1"
|
|
PROJECTION_RECEIPT_SCHEMA = "aios.task-lineage-supersession-initial-projection-receipt.v1"
|
|
PROJECTION_IDEMPOTENCY_KEY = "task-lineage-supersession-s1-initial-projection-v1"
|
|
PROJECTION_REASON = "canonical-initial-projection-for-formal-supersession-child"
|
|
PROJECTION_TABLE = "task_lineage_supersession_initial_projections"
|
|
|
|
|
|
def _sha_text(value: str) -> str:
|
|
return hashlib.sha256(value.encode("utf-8")).hexdigest()
|
|
|
|
|
|
def _sha_json(value: Any) -> str:
|
|
return _sha_text(canonical_json(value))
|
|
|
|
|
|
def _json_object(raw: Any, code: str) -> dict[str, Any]:
|
|
if not isinstance(raw, str):
|
|
raise InitialExecutionProjectionError(code, 409)
|
|
try:
|
|
value = json.loads(raw)
|
|
except (TypeError, ValueError) as exc:
|
|
raise InitialExecutionProjectionError(code, 409) from exc
|
|
if not isinstance(value, Mapping):
|
|
raise InitialExecutionProjectionError(code, 409)
|
|
return dict(value)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class SupersessionChildProjectionIntent:
|
|
"""Caller-selectable portion of the exact child projection.
|
|
|
|
Task identity, CAS values, Job identity, projection profile, reason and
|
|
idempotency are intentionally absent from the request and server-owned.
|
|
"""
|
|
|
|
adapter: str
|
|
required_capability: str
|
|
authorization_id: str
|
|
|
|
@classmethod
|
|
def from_mapping(
|
|
cls, value: Mapping[str, Any]
|
|
) -> "SupersessionChildProjectionIntent":
|
|
if not isinstance(value, Mapping) or set(value) != {
|
|
"adapter",
|
|
"required_capability",
|
|
"authorization_id",
|
|
}:
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_INITIAL_PROJECTION_FIELDS_INVALID", 400
|
|
)
|
|
adapter = _require_string(value["adapter"], "RUNTIME_ADAPTER_INVALID")
|
|
capability = _require_string(
|
|
value["required_capability"],
|
|
"RUNTIME_CAPABILITY_INVALID",
|
|
RUNTIME_CAPABILITY_RE,
|
|
)
|
|
if adapter not in {"hermes", "openclaw"} or capability != f"agent.runtime.{adapter}":
|
|
raise InitialExecutionProjectionError("RUNTIME_CAPABILITY_MISMATCH", 400)
|
|
authorization_id = _require_string(
|
|
value["authorization_id"], "AUTHORIZATION_ID_INVALID"
|
|
)
|
|
return cls(adapter, capability, authorization_id)
|
|
|
|
def public(self) -> dict[str, Any]:
|
|
return {
|
|
"schema": PROJECTION_INTENT_SCHEMA,
|
|
"source_task_id": SOURCE_TASK_ID,
|
|
"child_task_id": CHILD_TASK_ID,
|
|
"supersession_ordinal": SUPERSESSION_ORDINAL,
|
|
"canonical_projection_profile": CANONICAL_PROFILE,
|
|
"canonical_projection_version": CANONICAL_PROFILE_VERSION,
|
|
"expected_status": "QUEUED",
|
|
"expected_revision": 1,
|
|
"expected_attempt": 0,
|
|
"expected_metadata_sha256": _sha_json({}),
|
|
"expected_required_capabilities_sha256": _sha_json([]),
|
|
"expected_job_id": EXTERNAL_JOB_ID,
|
|
"adapter": self.adapter,
|
|
"required_capability": self.required_capability,
|
|
"authorization_id": self.authorization_id,
|
|
"idempotency_key": PROJECTION_IDEMPOTENCY_KEY,
|
|
"reason": PROJECTION_REASON,
|
|
}
|
|
|
|
def initial_request(self, canonical_execution_digest: str) -> InitialExecutionProjectionRequest:
|
|
return InitialExecutionProjectionRequest.from_mapping(
|
|
{
|
|
"expected_status": "QUEUED",
|
|
"expected_revision": 1,
|
|
"expected_attempt": 0,
|
|
"expected_metadata_sha256": _sha_json({}),
|
|
"expected_required_capabilities_sha256": _sha_json([]),
|
|
"expected_job_id": EXTERNAL_JOB_ID,
|
|
"expected_execution_digest": canonical_execution_digest,
|
|
"required_capability": self.required_capability,
|
|
"adapter": self.adapter,
|
|
"authorization_id": self.authorization_id,
|
|
"idempotency_key": PROJECTION_IDEMPOTENCY_KEY,
|
|
"reason": PROJECTION_REASON,
|
|
}
|
|
)
|
|
|
|
|
|
def _table_names(connection: sqlite3.Connection) -> set[str]:
|
|
return {
|
|
str(row[0])
|
|
for row in connection.execute(
|
|
"SELECT name FROM sqlite_master WHERE type='table'"
|
|
)
|
|
}
|
|
|
|
|
|
def _load_lineage_context(
|
|
connection: sqlite3.Connection, *, expect_projected: bool
|
|
) -> dict[str, Any]:
|
|
required_tables = {
|
|
"tasks",
|
|
"events",
|
|
"task_lineage_supersessions",
|
|
"task_lineage_supersession_receipts",
|
|
PROJECTION_TABLE,
|
|
}
|
|
if not required_tables.issubset(_table_names(connection)):
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_INITIAL_PROJECTION_SCHEMA_UNAVAILABLE", 503
|
|
)
|
|
relation = connection.execute(
|
|
"SELECT * FROM task_lineage_supersessions "
|
|
"WHERE source_task_id=? AND supersession_ordinal=? AND child_task_id=?",
|
|
(SOURCE_TASK_ID, SUPERSESSION_ORDINAL, CHILD_TASK_ID),
|
|
).fetchone()
|
|
if relation is None:
|
|
raise InitialExecutionProjectionError("FORMAL_SUPERSESSION_REQUIRED", 409)
|
|
receipt_row = connection.execute(
|
|
"SELECT * FROM task_lineage_supersession_receipts "
|
|
"WHERE decision_id=? AND source_task_id=? AND supersession_ordinal=? "
|
|
"AND child_task_id=?",
|
|
(
|
|
relation["decision_id"],
|
|
SOURCE_TASK_ID,
|
|
SUPERSESSION_ORDINAL,
|
|
CHILD_TASK_ID,
|
|
),
|
|
).fetchone()
|
|
if receipt_row is None:
|
|
raise InitialExecutionProjectionError("SUPERSESSION_RECEIPT_REQUIRED", 409)
|
|
decision = _json_object(receipt_row["decision_json"], "SUPERSESSION_DECISION_INVALID")
|
|
receipt = _json_object(receipt_row["receipt_json"], "SUPERSESSION_RECEIPT_INVALID")
|
|
decision_sha256 = _sha_text(canonical_json(decision_payload(decision)))
|
|
exact_decision = {
|
|
"schema": DECISION_SCHEMA,
|
|
"source_task_id": SOURCE_TASK_ID,
|
|
"child_task_id": CHILD_TASK_ID,
|
|
"supersession_ordinal": SUPERSESSION_ORDINAL,
|
|
"repository": REPOSITORY,
|
|
"target_branch": TARGET_BRANCH,
|
|
"generation": GENERATION,
|
|
"execution_digest": SOURCE_BUSINESS_EXECUTION_DIGEST,
|
|
"external_job_id": EXTERNAL_JOB_ID,
|
|
"canonical_projection_profile": CANONICAL_PROFILE,
|
|
"canonical_projection_version": CANONICAL_PROFILE_VERSION,
|
|
"owner_identity": OWNER_PRINCIPAL,
|
|
"signature_namespace": OWNER_NAMESPACE,
|
|
"signature_principal": OWNER_PRINCIPAL,
|
|
"key_id": OWNER_KEY_ID,
|
|
"one_time_use": True,
|
|
}
|
|
if any(decision.get(key) != expected for key, expected in exact_decision.items()):
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_DECISION_SCOPE_MISMATCH", 409
|
|
)
|
|
if (
|
|
decision_sha256 != relation["owner_decision_sha256"]
|
|
or decision_sha256 != receipt_row["owner_decision_sha256"]
|
|
or decision.get("source_task_identity_sha256")
|
|
!= relation["source_task_identity_sha256"]
|
|
or decision.get("source_metadata_sha256") != relation["source_metadata_sha256"]
|
|
or receipt.get("schema") != SUPERSESSION_RECEIPT_SCHEMA
|
|
or receipt.get("owner_decision_sha256") != decision_sha256
|
|
or receipt.get("source_task_id") != SOURCE_TASK_ID
|
|
or receipt.get("child_task_id") != CHILD_TASK_ID
|
|
or receipt.get("supersession_ordinal") != SUPERSESSION_ORDINAL
|
|
):
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_LINEAGE_EVIDENCE_MISMATCH", 409
|
|
)
|
|
events = connection.execute(
|
|
"SELECT event_type,payload_json FROM events WHERE task_id=? ORDER BY event_id",
|
|
(CHILD_TASK_ID,),
|
|
).fetchall()
|
|
expected_events = ["TASK_CREATED"]
|
|
if expect_projected:
|
|
expected_events.append("TASK_INITIAL_EXECUTION_PROJECTION_AUTHORIZED")
|
|
if [str(row["event_type"]) for row in events] != expected_events:
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_CHILD_EVENT_CHAIN_INVALID", 409
|
|
)
|
|
created = _json_object(events[0]["payload_json"], "SUPERSESSION_CREATED_EVENT_INVALID")
|
|
exact_created = {
|
|
"task_id": CHILD_TASK_ID,
|
|
"supersedes_task_id": SOURCE_TASK_ID,
|
|
"supersession_ordinal": SUPERSESSION_ORDINAL,
|
|
"source_task_identity_sha256": relation["source_task_identity_sha256"],
|
|
"source_metadata_sha256": relation["source_metadata_sha256"],
|
|
"owner_supersession_decision_sha256": decision_sha256,
|
|
"canonical_projection_profile": CANONICAL_PROFILE,
|
|
"canonical_projection_version": CANONICAL_PROFILE_VERSION,
|
|
}
|
|
if any(created.get(key) != expected for key, expected in exact_created.items()):
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_CREATED_EVENT_SCOPE_MISMATCH", 409
|
|
)
|
|
return {
|
|
"source_task_identity_sha256": relation["source_task_identity_sha256"],
|
|
"source_metadata_sha256": relation["source_metadata_sha256"],
|
|
"owner_decision_sha256": decision_sha256,
|
|
}
|
|
|
|
|
|
def _validate_canonical_child_execution(
|
|
resolved: Mapping[str, Any],
|
|
*,
|
|
intent: SupersessionChildProjectionIntent,
|
|
runtime_input: Mapping[str, Any],
|
|
) -> dict[str, Any]:
|
|
try:
|
|
binding = GovernedExecutionBinding.from_mapping(resolved)
|
|
execution = validate_execution_envelope(resolved, binding=binding)
|
|
except ExecutionProjectionError as exc:
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_CANONICAL_EXECUTION_INVALID", 409
|
|
) from exc
|
|
exact_binding = {
|
|
"task_id": CHILD_TASK_ID,
|
|
"job_id": EXTERNAL_JOB_ID,
|
|
"repository": REPOSITORY,
|
|
"target_branch": TARGET_BRANCH,
|
|
"generation": GENERATION,
|
|
}
|
|
if any(execution.get(key) != expected for key, expected in exact_binding.items()):
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_CANONICAL_EXECUTION_BINDING_MISMATCH", 409
|
|
)
|
|
if (
|
|
execution.get("action") != "agent_runtime"
|
|
or execution.get("adapter") != intent.adapter
|
|
or execution.get("capability_scope") != [intent.required_capability]
|
|
or execution.get("runtime_input") != dict(runtime_input)
|
|
or execution.get("change_set") != []
|
|
or execution.get("verification") != []
|
|
or execution.get("governance", {}).get("writer_lease") is not False
|
|
):
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_AGENT_RUNTIME_ENVELOPE_INVALID", 409
|
|
)
|
|
if execution["execution_digest"] == SOURCE_BUSINESS_EXECUTION_DIGEST:
|
|
raise InitialExecutionProjectionError(
|
|
"CHILD_CANONICAL_DIGEST_COLLIDES_WITH_SOURCE_BUSINESS_DIGEST", 409
|
|
)
|
|
return execution
|
|
|
|
|
|
class _SupersessionProjectionTransactionStore(InitialExecutionProjectionStore):
|
|
"""Per-invocation store that adds immutable lineage evidence atomically."""
|
|
|
|
allows_supersession_child = True
|
|
|
|
def __init__(self, db_path, resolved: Mapping[str, Any], intent):
|
|
self._resolved = dict(resolved)
|
|
self.intent = intent
|
|
super().__init__(db_path, self._resolve_once)
|
|
|
|
def _resolve_once(self, *_args):
|
|
return dict(self._resolved)
|
|
|
|
def _projection_event_extension(
|
|
self, connection, task_id, request, execution, applied_revision
|
|
):
|
|
if task_id != CHILD_TASK_ID:
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_CHILD_TASK_ID_MISMATCH", 409
|
|
)
|
|
context = _load_lineage_context(connection, expect_projected=False)
|
|
return {
|
|
"source_task_id": SOURCE_TASK_ID,
|
|
"supersession_ordinal": SUPERSESSION_ORDINAL,
|
|
"source_task_identity_sha256": context["source_task_identity_sha256"],
|
|
"source_metadata_sha256": context["source_metadata_sha256"],
|
|
"owner_supersession_decision_sha256": context["owner_decision_sha256"],
|
|
"source_business_execution_digest": SOURCE_BUSINESS_EXECUTION_DIGEST,
|
|
"canonical_child_execution_digest": execution["execution_digest"],
|
|
"canonical_projection_profile": CANONICAL_PROFILE,
|
|
"canonical_projection_version": CANONICAL_PROFILE_VERSION,
|
|
}
|
|
|
|
def _insert_projection_extension(
|
|
self,
|
|
connection,
|
|
task_id,
|
|
request,
|
|
execution,
|
|
event_payload,
|
|
applied_revision,
|
|
):
|
|
context = _load_lineage_context(connection, expect_projected=True)
|
|
task = connection.execute(
|
|
"SELECT metadata_json,required_capabilities_json FROM tasks WHERE task_id=?",
|
|
(CHILD_TASK_ID,),
|
|
).fetchone()
|
|
if task is None:
|
|
raise InitialExecutionProjectionError("TASK_NOT_FOUND", 404)
|
|
intent_json = canonical_json(self.intent.public())
|
|
intent_sha256 = _sha_text(intent_json)
|
|
receipt = {
|
|
"schema": PROJECTION_RECEIPT_SCHEMA,
|
|
"projection_id": "sha256:" + intent_sha256,
|
|
"task_id": CHILD_TASK_ID,
|
|
"source_task_id": SOURCE_TASK_ID,
|
|
"supersession_ordinal": SUPERSESSION_ORDINAL,
|
|
"source_task_identity_sha256": context["source_task_identity_sha256"],
|
|
"source_metadata_sha256": context["source_metadata_sha256"],
|
|
"owner_supersession_decision_sha256": context["owner_decision_sha256"],
|
|
"source_business_execution_digest": SOURCE_BUSINESS_EXECUTION_DIGEST,
|
|
"canonical_child_execution_digest": execution["execution_digest"],
|
|
"external_job_id": EXTERNAL_JOB_ID,
|
|
"repository": REPOSITORY,
|
|
"target_branch": TARGET_BRANCH,
|
|
"generation": GENERATION,
|
|
"adapter": self.intent.adapter,
|
|
"required_capability": self.intent.required_capability,
|
|
"expected_revision": 1,
|
|
"applied_revision": applied_revision,
|
|
"attempt": 0,
|
|
"metadata_sha256": _sha_text(task["metadata_json"]),
|
|
"required_capabilities_sha256": _sha_text(
|
|
task["required_capabilities_json"]
|
|
),
|
|
"projection_event_sha256": _sha_json(dict(event_payload)),
|
|
}
|
|
receipt_json = canonical_json(receipt)
|
|
receipt_sha256 = _sha_text(receipt_json)
|
|
connection.execute(
|
|
f"""INSERT INTO {PROJECTION_TABLE}(
|
|
projection_id,task_id,source_task_id,supersession_ordinal,
|
|
intent_sha256,intent_json,owner_decision_sha256,
|
|
source_task_identity_sha256,source_metadata_sha256,
|
|
source_business_execution_digest,canonical_child_execution_digest,
|
|
external_job_id,repository,target_branch,generation,adapter,
|
|
required_capability,expected_revision,applied_revision,metadata_sha256,
|
|
required_capabilities_sha256,projection_event_sha256,receipt_json,
|
|
receipt_sha256,created_at)
|
|
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
|
|
(
|
|
receipt["projection_id"],
|
|
CHILD_TASK_ID,
|
|
SOURCE_TASK_ID,
|
|
SUPERSESSION_ORDINAL,
|
|
intent_sha256,
|
|
intent_json,
|
|
context["owner_decision_sha256"],
|
|
context["source_task_identity_sha256"],
|
|
context["source_metadata_sha256"],
|
|
SOURCE_BUSINESS_EXECUTION_DIGEST,
|
|
execution["execution_digest"],
|
|
EXTERNAL_JOB_ID,
|
|
REPOSITORY,
|
|
TARGET_BRANCH,
|
|
GENERATION,
|
|
self.intent.adapter,
|
|
self.intent.required_capability,
|
|
1,
|
|
applied_revision,
|
|
receipt["metadata_sha256"],
|
|
receipt["required_capabilities_sha256"],
|
|
receipt["projection_event_sha256"],
|
|
receipt_json,
|
|
receipt_sha256,
|
|
_now(),
|
|
),
|
|
)
|
|
|
|
|
|
class SupersessionChildInitialProjectionStore:
|
|
"""Server-owned adapter from exact supersession lineage to current ABI."""
|
|
|
|
def __init__(self, db_path, resolver):
|
|
self.db_path = db_path
|
|
self.resolver = resolver
|
|
|
|
def _connect(self):
|
|
connection = sqlite3.connect(self.db_path, timeout=30.0)
|
|
connection.row_factory = sqlite3.Row
|
|
connection.execute("PRAGMA foreign_keys=ON")
|
|
connection.execute("PRAGMA busy_timeout=30000")
|
|
return connection
|
|
|
|
@staticmethod
|
|
def _replay(connection, intent: SupersessionChildProjectionIntent):
|
|
if PROJECTION_TABLE not in _table_names(connection):
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_INITIAL_PROJECTION_SCHEMA_UNAVAILABLE", 503
|
|
)
|
|
row = connection.execute(
|
|
f"SELECT * FROM {PROJECTION_TABLE} WHERE task_id=?", (CHILD_TASK_ID,)
|
|
).fetchone()
|
|
if row is None:
|
|
tables = _table_names(connection)
|
|
if "task_initial_execution_projections" in tables:
|
|
generic = connection.execute(
|
|
"SELECT 1 FROM task_initial_execution_projections "
|
|
"WHERE task_id=? AND idempotency_key=?",
|
|
(CHILD_TASK_ID, PROJECTION_IDEMPOTENCY_KEY),
|
|
).fetchone()
|
|
if generic is not None:
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_PROJECTION_RECEIPT_MISSING", 500
|
|
)
|
|
return None
|
|
intent_sha256 = _sha_json(intent.public())
|
|
if row["intent_sha256"] != intent_sha256:
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_INITIAL_PROJECTION_INTENT_CONFLICT", 409
|
|
)
|
|
receipt = _json_object(
|
|
row["receipt_json"], "SUPERSESSION_PROJECTION_RECEIPT_INVALID"
|
|
)
|
|
if (
|
|
_sha_text(row["receipt_json"]) != row["receipt_sha256"]
|
|
or receipt.get("schema") != PROJECTION_RECEIPT_SCHEMA
|
|
or receipt.get("canonical_child_execution_digest")
|
|
!= row["canonical_child_execution_digest"]
|
|
):
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_PROJECTION_RECEIPT_DIGEST_MISMATCH", 500
|
|
)
|
|
_load_lineage_context(connection, expect_projected=True)
|
|
task = connection.execute(
|
|
"SELECT * FROM tasks WHERE task_id=?", (CHILD_TASK_ID,)
|
|
).fetchone()
|
|
if (
|
|
task is None
|
|
or task["status"] != "QUEUED"
|
|
or int(task["revision"]) != int(row["applied_revision"])
|
|
or int(task["attempt"]) != 0
|
|
or task["claimed_by"] is not None
|
|
or task["lease_token_hash"] is not None
|
|
or task["lease_expires_at"] is not None
|
|
or _sha_text(task["metadata_json"]) != row["metadata_sha256"]
|
|
or _sha_text(task["required_capabilities_json"])
|
|
!= row["required_capabilities_sha256"]
|
|
):
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_PROJECTED_TASK_CAS_MISMATCH", 409
|
|
)
|
|
return {**receipt, "idempotent": True}
|
|
|
|
def project(self, value: Mapping[str, Any]) -> dict[str, Any]:
|
|
intent = SupersessionChildProjectionIntent.from_mapping(value)
|
|
if intent.authorization_id != _required_authorization_id():
|
|
raise InitialExecutionProjectionError("AUTHORIZATION_ID_MISMATCH", 403)
|
|
with self._connect() as connection:
|
|
replay = self._replay(connection, intent)
|
|
if replay is not None:
|
|
return replay
|
|
probe_request = intent.initial_request("0" * 64)
|
|
probe_store = _SupersessionProjectionTransactionStore(
|
|
self.db_path, {}, intent
|
|
)
|
|
task, _, _, _ = probe_store._load_and_validate(
|
|
connection, CHILD_TASK_ID, probe_request
|
|
)
|
|
_load_lineage_context(connection, expect_projected=False)
|
|
runtime_input = probe_store._runtime_input(task)
|
|
resolved = dict(
|
|
self.resolver(
|
|
CHILD_TASK_ID,
|
|
EXTERNAL_JOB_ID,
|
|
intent.required_capability,
|
|
intent.adapter,
|
|
runtime_input,
|
|
)
|
|
)
|
|
execution = _validate_canonical_child_execution(
|
|
resolved, intent=intent, runtime_input=runtime_input
|
|
)
|
|
store = _SupersessionProjectionTransactionStore(
|
|
self.db_path, resolved, intent
|
|
)
|
|
result = store.project(
|
|
CHILD_TASK_ID, intent.initial_request(execution["execution_digest"])
|
|
)
|
|
with self._connect() as connection:
|
|
receipt = self._replay(connection, intent)
|
|
if receipt is None:
|
|
raise InitialExecutionProjectionError(
|
|
"SUPERSESSION_PROJECTION_RECEIPT_MISSING", 500
|
|
)
|
|
return {**receipt, "idempotent": bool(result["idempotent"])}
|