Files
aios/tests/test_task_lineage_supersession_initial_projection.py
T

334 lines
12 KiB
Python

from __future__ import annotations
import hashlib
import json
from pathlib import Path
import sqlite3
import sys
import pytest
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "active-runtime" / "app"))
from aios_agent_task_initial_execution_projection import (
InitialExecutionProjectionError,
InitialExecutionProjectionRequest,
InitialExecutionProjectionStore,
)
from aios_online_agent_execution import (
GovernedExecutionBinding,
project_execution_envelope,
)
import aios_task_lineage_supersession as supersession
from aios_task_lineage_supersession_initial_projection import (
PROJECTION_TABLE,
SOURCE_BUSINESS_EXECUTION_DIGEST,
SupersessionChildInitialProjectionStore,
SupersessionChildProjectionIntent,
)
from test_task_lineage_supersession import (
controller,
create_db,
decision,
snapshot,
)
AUTHORIZATION = "owner-supersession-child-initial-projection-20260905"
CAPABILITY = "agent.runtime.openclaw"
BASE_OID = "a" * 40
@pytest.fixture(autouse=True)
def _authorization(monkeypatch):
monkeypatch.setenv(
"AIOS_AGENT_TASK_INITIAL_EXECUTION_PROJECTION_AUTHORIZATION_ID",
AUTHORIZATION,
)
def _sha_json(value):
return hashlib.sha256(
json.dumps(value, sort_keys=True, separators=(",", ":")).encode()
).hexdigest()
def _apply_projection_migration(path: Path) -> None:
sql = (
ROOT
/ "active-runtime"
/ "migrations"
/ "006_task_lineage_supersession_initial_projection.sql"
).read_text()
connection = sqlite3.connect(path)
connection.executescript(sql)
connection.commit()
connection.close()
def _superseded_db(tmp_path: Path) -> tuple[Path, tuple, dict]:
path = create_db(tmp_path)
_apply_projection_migration(path)
source_before = snapshot(path)
supersession_receipt = controller(path).supersede(decision(path))
return path, source_before, supersession_receipt
def _intent(**changes):
value = {
"adapter": "openclaw",
"required_capability": CAPABILITY,
"authorization_id": AUTHORIZATION,
}
value.update(changes)
return value
def _resolver(task_id, job_id, capability, adapter, runtime_input):
binding = GovernedExecutionBinding.from_mapping(
{
"task_id": task_id,
"job_id": job_id,
"repository": supersession.REPOSITORY,
"base_oid": BASE_OID,
"expected_branch_oid": BASE_OID,
"target_branch": supersession.TARGET_BRANCH,
"branch_mode": "CREATE_NEW",
"generation": supersession.GENERATION,
"idempotency_key": "singlehost-lineage-s1-execution-envelope-v1",
}
)
return project_execution_envelope(
binding,
{
"action": "agent_runtime",
"adapter": adapter,
"capability_scope": [capability],
"runtime_input": runtime_input,
},
)
def test_real_projector_abi_derives_distinct_child_digest_and_lineage_receipt(tmp_path):
path, source_before, supersession_receipt = _superseded_db(tmp_path)
result = SupersessionChildInitialProjectionStore(path, _resolver).project(
_intent()
)
assert result["idempotent"] is False
assert result["source_business_execution_digest"] == SOURCE_BUSINESS_EXECUTION_DIGEST
assert result["canonical_child_execution_digest"] != SOURCE_BUSINESS_EXECUTION_DIGEST
assert result["owner_supersession_decision_sha256"] == supersession_receipt["owner_decision_sha256"]
assert snapshot(path) == source_before
connection = sqlite3.connect(path)
connection.row_factory = sqlite3.Row
child = connection.execute(
"SELECT * FROM tasks WHERE task_id=?", (supersession.CHILD_TASK_ID,)
).fetchone()
assert (child["status"], child["revision"], child["attempt"]) == (
"QUEUED",
2,
0,
)
assert child["claimed_by"] is None
metadata = json.loads(child["metadata_json"])
execution = metadata["execution"]
assert execution["task_id"] == supersession.CHILD_TASK_ID
assert execution["job_id"] == supersession.EXTERNAL_JOB_ID
assert execution["repository"] == supersession.REPOSITORY
assert execution["target_branch"] == supersession.TARGET_BRANCH
assert execution["generation"] == supersession.GENERATION
assert execution["execution_digest"] == result["canonical_child_execution_digest"]
assert execution["execution_digest"] != supersession.EXECUTION_DIGEST
assert execution["action"] == "agent_runtime"
assert execution["change_set"] == []
assert execution["verification"] == []
assert json.loads(child["required_capabilities_json"]) == [CAPABILITY]
events = connection.execute(
"SELECT event_type,payload_json FROM events WHERE task_id=? ORDER BY event_id",
(supersession.CHILD_TASK_ID,),
).fetchall()
assert [row["event_type"] for row in events] == [
"TASK_CREATED",
"TASK_INITIAL_EXECUTION_PROJECTION_AUTHORIZED",
]
projected = json.loads(events[-1]["payload_json"])
assert projected["source_business_execution_digest"] == supersession.EXECUTION_DIGEST
assert projected["canonical_child_execution_digest"] == execution["execution_digest"]
assert projected["owner_supersession_decision_sha256"] == supersession_receipt["owner_decision_sha256"]
durable = connection.execute(
f"SELECT * FROM {PROJECTION_TABLE} WHERE task_id=?",
(supersession.CHILD_TASK_ID,),
).fetchone()
assert durable["source_business_execution_digest"] == supersession.EXECUTION_DIGEST
assert durable["canonical_child_execution_digest"] == execution["execution_digest"]
assert durable["expected_revision"] == 1
assert durable["applied_revision"] == 2
with pytest.raises(sqlite3.IntegrityError, match="APPEND_ONLY"):
connection.execute(
f"UPDATE {PROJECTION_TABLE} SET adapter='hermes' WHERE task_id=?",
(supersession.CHILD_TASK_ID,),
)
connection.rollback()
connection.close()
def test_exact_replay_needs_no_bridge_resolution(tmp_path):
path, _, _ = _superseded_db(tmp_path)
first = SupersessionChildInitialProjectionStore(path, _resolver).project(_intent())
def unavailable(*_args):
raise AssertionError("resolver must not run for exact durable replay")
second = SupersessionChildInitialProjectionStore(path, unavailable).project(
_intent()
)
assert second["idempotent"] is True
assert second["canonical_child_execution_digest"] == first["canonical_child_execution_digest"]
def test_generic_initial_projection_cannot_project_a_formal_lineage_child(tmp_path):
path, _, _ = _superseded_db(tmp_path)
execution = _resolver(
supersession.CHILD_TASK_ID,
supersession.EXTERNAL_JOB_ID,
CAPABILITY,
"openclaw",
{
"goal": "Build trust root",
"instructions": "Use the governed writer.",
"success_criteria": [{"id": "complete", "description": "complete"}],
"constraints": {"generation": 1, "production_write": False},
"scope": {"scope_type": "legacy", "tenant_id": None, "project_id": None},
"trace_id": supersession.CHILD_TASK_ID,
},
)
request = 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": supersession.EXTERNAL_JOB_ID,
"expected_execution_digest": execution["execution_digest"],
"required_capability": CAPABILITY,
"adapter": "openclaw",
"authorization_id": AUTHORIZATION,
"idempotency_key": "forbidden-generic-child-projection-v1",
"reason": "must use formal lineage projection endpoint",
}
)
with pytest.raises(
InitialExecutionProjectionError,
match="SUPERSESSION_INITIAL_PROJECTION_ENDPOINT_REQUIRED",
):
InitialExecutionProjectionStore(path, _resolver).project(
supersession.CHILD_TASK_ID, request
)
connection = sqlite3.connect(path)
child = connection.execute(
"SELECT revision,metadata_json FROM tasks WHERE task_id=?",
(supersession.CHILD_TASK_ID,),
).fetchone()
assert child == (1, "{}")
assert connection.execute(
"SELECT count(*) FROM events WHERE task_id=?",
(supersession.CHILD_TASK_ID,),
).fetchone()[0] == 1
connection.close()
def test_intent_rejects_arbitrary_child_payload_and_mismatched_adapter():
with pytest.raises(
InitialExecutionProjectionError,
match="SUPERSESSION_INITIAL_PROJECTION_FIELDS_INVALID",
):
SupersessionChildProjectionIntent.from_mapping(
{**_intent(), "child_payload": {"metadata": {"execution_digest": "x"}}}
)
with pytest.raises(
InitialExecutionProjectionError, match="RUNTIME_CAPABILITY_MISMATCH"
):
SupersessionChildProjectionIntent.from_mapping(
_intent(adapter="hermes")
)
def test_wrong_canonical_binding_fails_without_task_mutation(tmp_path):
path, _, _ = _superseded_db(tmp_path)
def wrong_binding(_task_id, job_id, capability, adapter, runtime_input):
return _resolver(
supersession.SOURCE_TASK_ID,
job_id,
capability,
adapter,
runtime_input,
)
with pytest.raises(
InitialExecutionProjectionError,
match="SUPERSESSION_CANONICAL_EXECUTION_BINDING_MISMATCH",
):
SupersessionChildInitialProjectionStore(path, wrong_binding).project(
_intent()
)
connection = sqlite3.connect(path)
child = connection.execute(
"SELECT revision,metadata_json,required_capabilities_json FROM tasks "
"WHERE task_id=?",
(supersession.CHILD_TASK_ID,),
).fetchone()
assert child == (1, "{}", "[]")
assert connection.execute(f"SELECT count(*) FROM {PROJECTION_TABLE}").fetchone()[0] == 0
connection.close()
def test_projection_receipt_failure_rolls_back_task_event_and_generic_receipt(tmp_path):
path, _, _ = _superseded_db(tmp_path)
connection = sqlite3.connect(path)
connection.execute(
f"""CREATE TRIGGER force_projection_receipt_failure
BEFORE INSERT ON {PROJECTION_TABLE} BEGIN
SELECT RAISE(ABORT, 'FORCED_PROJECTION_RECEIPT_FAILURE');
END"""
)
connection.commit()
connection.close()
with pytest.raises(sqlite3.IntegrityError, match="FORCED_PROJECTION_RECEIPT_FAILURE"):
SupersessionChildInitialProjectionStore(path, _resolver).project(_intent())
connection = sqlite3.connect(path)
child = connection.execute(
"SELECT revision,metadata_json,required_capabilities_json FROM tasks "
"WHERE task_id=?",
(supersession.CHILD_TASK_ID,),
).fetchone()
assert child == (1, "{}", "[]")
assert connection.execute(
"SELECT count(*) FROM events WHERE task_id=?",
(supersession.CHILD_TASK_ID,),
).fetchone()[0] == 1
assert connection.execute(
"SELECT count(*) FROM task_initial_execution_projections WHERE task_id=?",
(supersession.CHILD_TASK_ID,),
).fetchone()[0] == 0
assert connection.execute(f"SELECT count(*) FROM {PROJECTION_TABLE}").fetchone()[0] == 0
connection.close()
def test_projection_migration_is_idempotent(tmp_path):
path = create_db(tmp_path)
_apply_projection_migration(path)
_apply_projection_migration(path)
connection = sqlite3.connect(path)
assert connection.execute(
"SELECT count(*) FROM sqlite_master WHERE type='table' AND name=?",
(PROJECTION_TABLE,),
).fetchone()[0] == 1
connection.close()