fix(agent99): gate reboot recovery on full SOP
This commit is contained in:
@@ -36,6 +36,7 @@ def load_latest_agent99_enterprise_ai_automation_work_items(
|
||||
work_items = _require_list(payload, "work_items", path)
|
||||
summary = _require_dict(payload, "summary", path)
|
||||
current_p0 = _require_dict(payload, "current_p0", path)
|
||||
next_execution_order = _require_list(payload, "next_execution_order", path)
|
||||
promotion_contract = _require_dict(payload, "promotion_contract", path)
|
||||
required_p0_fields = _require_list(
|
||||
promotion_contract,
|
||||
@@ -93,12 +94,16 @@ def load_latest_agent99_enterprise_ai_automation_work_items(
|
||||
current_p0_id = current_p0.get("id")
|
||||
if current_p0_id not in active_p0_ids:
|
||||
raise ValueError(f"{path}: current_p0.id is not an active P0 work item")
|
||||
if not active_p0_ids or active_p0_ids[0] != current_p0_id:
|
||||
raise ValueError(f"{path}: current_p0 must be the first ordered active P0")
|
||||
if payload.get("next_execution_order") != active_p0_ids:
|
||||
if any(not isinstance(item_id, str) for item_id in next_execution_order):
|
||||
raise ValueError(f"{path}: next_execution_order must contain work item ids")
|
||||
if len(next_execution_order) != len(set(next_execution_order)):
|
||||
raise ValueError(f"{path}: next_execution_order contains duplicate ids")
|
||||
if set(next_execution_order) != set(active_p0_ids):
|
||||
raise ValueError(
|
||||
f"{path}: next_execution_order must equal ordered active P0 ids"
|
||||
f"{path}: next_execution_order must contain every active P0 exactly once"
|
||||
)
|
||||
if not next_execution_order or next_execution_order[0] != current_p0_id:
|
||||
raise ValueError(f"{path}: current_p0 must be first in next_execution_order")
|
||||
|
||||
_require_count(summary, "p0_count", priority_counts["P0"], path)
|
||||
_require_count(summary, "p1_count", priority_counts["P1"], path)
|
||||
|
||||
@@ -31,7 +31,7 @@ def test_agent99_enterprise_work_items_loader_returns_complete_scope() -> None:
|
||||
"agent99_enterprise_ai_automation_work_items_v1"
|
||||
)
|
||||
assert payload["scope_complete"] is False
|
||||
assert payload["current_p0"]["id"] == "AG99-P0-002"
|
||||
assert payload["current_p0"]["id"] == "AG99-P0-007"
|
||||
assert payload["summary"] == {
|
||||
"host_count": 7,
|
||||
"product_count": 12,
|
||||
@@ -40,13 +40,13 @@ def test_agent99_enterprise_work_items_loader_returns_complete_scope() -> None:
|
||||
"p0_count": 14,
|
||||
"p1_count": 8,
|
||||
"p2_count": 3,
|
||||
"in_progress_count": 5,
|
||||
"in_progress_blocked_count": 3,
|
||||
"in_progress_count": 7,
|
||||
"in_progress_blocked_count": 0,
|
||||
"planned_count": 16,
|
||||
"complete_count": 1,
|
||||
"complete_count": 2,
|
||||
"current_p0_count": 1,
|
||||
}
|
||||
assert payload["next_execution_order"][0] == "AG99-P0-002"
|
||||
assert payload["next_execution_order"][0] == "AG99-P0-007"
|
||||
assert payload["next_execution_order"][-1] == "AG99-P0-014"
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ def test_agent99_enterprise_projection_is_bounded() -> None:
|
||||
payload = load_latest_agent99_enterprise_ai_automation_work_items()
|
||||
projection = build_agent99_enterprise_priority_projection(payload)
|
||||
|
||||
assert projection["current_p0"]["id"] == "AG99-P0-002"
|
||||
assert projection["current_p0"]["id"] == "AG99-P0-007"
|
||||
assert projection["coverage"] == {
|
||||
"host_count": 7,
|
||||
"product_count": 12,
|
||||
@@ -73,7 +73,7 @@ def test_priority_readback_projects_agent99_enterprise_order() -> None:
|
||||
payload = load_latest_awoooi_priority_work_order_readback()
|
||||
projection = payload["agent99_enterprise_ai_automation"]
|
||||
|
||||
assert projection["current_p0"]["id"] == "AG99-P0-002"
|
||||
assert projection["current_p0"]["id"] == "AG99-P0-007"
|
||||
assert projection["work_item_counts"]["p0"] == 14
|
||||
assert (
|
||||
payload["source_refs"]["agent99_enterprise_ai_automation_work_items_api"]
|
||||
@@ -94,6 +94,21 @@ def test_agent99_enterprise_loader_rejects_duplicate_ids(tmp_path: Path) -> None
|
||||
load_latest_agent99_enterprise_ai_automation_work_items(tmp_path)
|
||||
|
||||
|
||||
def test_agent99_enterprise_loader_rejects_incomplete_execution_order(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
source = _OPERATIONS_DIR / (
|
||||
"agent99-enterprise-ai-automation-work-items.snapshot.json"
|
||||
)
|
||||
payload = json.loads(source.read_text(encoding="utf-8"))
|
||||
payload["next_execution_order"].pop()
|
||||
target = tmp_path / source.name
|
||||
target.write_text(json.dumps(payload), encoding="utf-8")
|
||||
|
||||
with pytest.raises(ValueError, match="every active P0 exactly once"):
|
||||
load_latest_agent99_enterprise_ai_automation_work_items(tmp_path)
|
||||
|
||||
|
||||
def test_agent99_enterprise_work_items_endpoint_returns_snapshot() -> None:
|
||||
app = FastAPI()
|
||||
app.include_router(router, prefix="/api/v1")
|
||||
@@ -103,7 +118,7 @@ def test_agent99_enterprise_work_items_endpoint_returns_snapshot() -> None:
|
||||
|
||||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
assert payload["current_p0"]["id"] == "AG99-P0-002"
|
||||
assert payload["current_p0"]["id"] == "AG99-P0-007"
|
||||
assert payload["summary"]["host_count"] == 7
|
||||
assert payload["summary"]["product_count"] == 12
|
||||
assert payload["summary"]["public_surface_count"] == 23
|
||||
|
||||
Reference in New Issue
Block a user