"""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"])}