Merge remote-tracking branch 'origin/main' into codex/p0-obs-002-20260715
This commit is contained in:
@@ -389,6 +389,91 @@ def test_reconciliation_persistence_batches_candidate_queries_and_inserts() -> N
|
||||
assert "AND output ->> 'closed' = 'true'" in source
|
||||
|
||||
|
||||
def test_reconcile_once_uses_bounded_worker_live_readback_timeout(
|
||||
monkeypatch: Any,
|
||||
) -> None:
|
||||
captured: dict[str, object] = {}
|
||||
|
||||
async def _fake_live_readback(**kwargs: object) -> dict[str, object]:
|
||||
captured.update(kwargs)
|
||||
return {"live_readback_status": "degraded"}
|
||||
|
||||
monkeypatch.setattr(
|
||||
reconciliation_job,
|
||||
"build_asset_capability_matrix_with_live_readback",
|
||||
_fake_live_readback,
|
||||
)
|
||||
|
||||
result = asyncio.run(
|
||||
reconciliation_job.reconcile_once(
|
||||
triggered_by="controlled_replay",
|
||||
project_id="awoooi",
|
||||
)
|
||||
)
|
||||
|
||||
assert captured == {
|
||||
"project_id": "awoooi",
|
||||
"timeout_seconds": 30.0,
|
||||
"include_live_only_assets": True,
|
||||
}
|
||||
assert result["status"] == "degraded_no_write"
|
||||
|
||||
|
||||
def test_reconcile_once_publishes_closed_public_matrix_cache(
|
||||
monkeypatch: Any,
|
||||
) -> None:
|
||||
live_readback_calls: list[dict[str, object]] = []
|
||||
|
||||
async def _fake_live_readback(**kwargs: object) -> dict[str, object]:
|
||||
live_readback_calls.append(dict(kwargs))
|
||||
if kwargs["include_live_only_assets"] is True:
|
||||
return {"live_readback_status": "ready"}
|
||||
return {"live_readback_status": "ready", "closed": True}
|
||||
|
||||
async def _fake_persist(
|
||||
_matrix: object,
|
||||
_candidates: object,
|
||||
*,
|
||||
project_id: str,
|
||||
) -> dict[str, object]:
|
||||
assert project_id == "awoooi"
|
||||
return {"closed": True, "candidate_count": 0}
|
||||
|
||||
monkeypatch.setattr(
|
||||
reconciliation_job,
|
||||
"build_asset_capability_matrix_with_live_readback",
|
||||
_fake_live_readback,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
reconciliation_job,
|
||||
"build_reconciliation_candidates",
|
||||
lambda _matrix: [],
|
||||
)
|
||||
monkeypatch.setattr(reconciliation_job, "_persist_reconciliation", _fake_persist)
|
||||
|
||||
result = asyncio.run(
|
||||
reconciliation_job.reconcile_once(
|
||||
triggered_by="controlled_replay",
|
||||
project_id="awoooi",
|
||||
)
|
||||
)
|
||||
|
||||
assert live_readback_calls == [
|
||||
{
|
||||
"project_id": "awoooi",
|
||||
"timeout_seconds": 30.0,
|
||||
"include_live_only_assets": True,
|
||||
},
|
||||
{
|
||||
"project_id": "awoooi",
|
||||
"timeout_seconds": 30.0,
|
||||
"include_live_only_assets": False,
|
||||
"bypass_public_cache": True,
|
||||
},
|
||||
]
|
||||
assert result["public_cache_refreshed"] is True
|
||||
|
||||
|
||||
def test_reconciliation_loop_retries_degraded_result_before_daily_wait(
|
||||
monkeypatch: Any,
|
||||
) -> None:
|
||||
@@ -678,6 +763,37 @@ def test_public_matrix_success_warms_cache_for_next_request(
|
||||
assert live_read_count == 1
|
||||
|
||||
|
||||
def test_public_matrix_cache_bypass_forces_shared_refresh(monkeypatch: Any) -> None:
|
||||
stored_payloads: list[dict[str, Any]] = []
|
||||
|
||||
async def _unexpected_cache_read(*_args: Any, **_kwargs: Any) -> dict[str, Any]:
|
||||
raise AssertionError("cache bypass must not read a prior projection")
|
||||
|
||||
async def _live_readback(
|
||||
_project_id: str,
|
||||
) -> tuple[dict[str, Any], list[dict[str, Any]], dict[str, Any]]:
|
||||
return {}, [], {}
|
||||
|
||||
async def _store_cache(_project_id: str, payload: dict[str, Any]) -> None:
|
||||
stored_payloads.append(payload)
|
||||
|
||||
monkeypatch.setattr(
|
||||
matrix_service, "_read_public_matrix_cache", _unexpected_cache_read
|
||||
)
|
||||
monkeypatch.setattr(matrix_service, "_load_live_rows", _live_readback)
|
||||
monkeypatch.setattr(matrix_service, "_store_public_matrix_caches", _store_cache)
|
||||
|
||||
payload = asyncio.run(
|
||||
build_asset_capability_matrix_with_live_readback(
|
||||
bypass_public_cache=True,
|
||||
)
|
||||
)
|
||||
|
||||
assert payload["live_readback_status"] == "ready"
|
||||
assert len(stored_payloads) == 1
|
||||
assert stored_payloads[0]["matrix_fingerprint"] == payload["matrix_fingerprint"]
|
||||
|
||||
|
||||
def test_public_matrix_timeout_uses_last_ready_cache(monkeypatch: Any) -> None:
|
||||
async def _slow_live_readback(
|
||||
_project_id: str,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
import inspect
|
||||
import json
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from types import SimpleNamespace
|
||||
@@ -32,6 +33,7 @@ from src.services.platform_operator_service import (
|
||||
_ai_route_lane_state,
|
||||
_ai_route_policy_order,
|
||||
_ai_route_repair_evidence_item,
|
||||
_apply_run_terminal_truth_precedence,
|
||||
_build_awooop_status_chain,
|
||||
_callback_reply_audit_summary_from_row,
|
||||
_callback_reply_event_item,
|
||||
@@ -2940,6 +2942,128 @@ def test_awooop_status_chain_marks_verified_repair() -> None:
|
||||
assert chain["source_refs"]["refs"]["signoz_alerts"] == ["signoz:abc"]
|
||||
|
||||
|
||||
def test_run_terminal_receipt_overrides_historical_incident_green_state() -> None:
|
||||
historical_chain = {
|
||||
"schema_version": "awooop_status_chain_v1",
|
||||
"source": "truth_chain+adr100_history",
|
||||
"source_id": "INC-BRR-35994B66C2807E74",
|
||||
"incident_ids": ["INC-BRR-35994B66C2807E74"],
|
||||
"current_stage": "execution_succeeded",
|
||||
"stage_status": "success",
|
||||
"verdict": "auto_repaired_verified",
|
||||
"repair_state": "auto_repaired_verified",
|
||||
"verification": "success",
|
||||
"needs_human": False,
|
||||
"next_step": "monitor_for_regression",
|
||||
"operator_outcome": {
|
||||
"state": "completed_verified",
|
||||
"execution_result": {
|
||||
"completion_status": "completed_verified",
|
||||
"terminal": True,
|
||||
},
|
||||
},
|
||||
"evidence": {
|
||||
"auto_repair_records": 1,
|
||||
"operation_records": 4,
|
||||
"mcp_gateway_total": 8,
|
||||
"knowledge_entries": 1,
|
||||
},
|
||||
"writes": {"incident": True, "auto_repair": True},
|
||||
"mcp": {"gateway": {"total": 8, "success": 4}},
|
||||
"execution": {"operation_total": 4, "latest_status": "success"},
|
||||
}
|
||||
run = SimpleNamespace(
|
||||
run_id=UUID("f53d95ac-04d3-5228-ae74-9ab0ad95c013"),
|
||||
state="failed",
|
||||
error_code="E-AGENT99-OUTCOME-TIMEOUT",
|
||||
timeout_at=datetime.fromisoformat("2026-07-15T00:22:32.527349"),
|
||||
completed_at=datetime.fromisoformat("2026-07-15T01:23:15.118099"),
|
||||
error_detail=json.dumps({
|
||||
"outcome_timeout_no_write_terminal": True,
|
||||
"terminalizer_runtime_write_performed": False,
|
||||
"outcome_runtime_write_status": (
|
||||
"unknown_without_authenticated_outcome"
|
||||
),
|
||||
"transport_replayed": False,
|
||||
"incident_resolution_authorized": False,
|
||||
"runtime_closure_verified": False,
|
||||
"safe_next_action": (
|
||||
"await_new_source_recurrence_after_agent99_relay_recovery"
|
||||
),
|
||||
"verifier": {
|
||||
"receipt": {
|
||||
"timeout_at": "2026-07-15T00:22:32.527349",
|
||||
"terminal_at": "2026-07-15T01:23:15.118099",
|
||||
}
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
chain = _apply_run_terminal_truth_precedence(
|
||||
run=run,
|
||||
status_chain=historical_chain,
|
||||
)
|
||||
|
||||
assert chain["source"] == (
|
||||
"run_terminal_receipt>historical_incident_context"
|
||||
)
|
||||
assert chain["stage_status"] == "failed"
|
||||
assert chain["repair_state"] == "failed_no_write_terminal"
|
||||
assert chain["verification"] == "failed_authenticated_outcome_timeout"
|
||||
assert chain["needs_human"] is False
|
||||
assert chain["operator_outcome"]["state"] == "failed_no_write_terminal"
|
||||
assert chain["operator_outcome"]["execution_result"][
|
||||
"completion_status"
|
||||
] == "failed_no_write_terminal"
|
||||
assert chain["writes"] == {"incident": False, "auto_repair": False}
|
||||
assert chain["evidence"]["auto_repair_records"] == 0
|
||||
assert chain["execution"]["operation_total"] == 0
|
||||
assert chain["run_terminal_precedence"] == {
|
||||
"active": True,
|
||||
"reason": "higher_priority_run_terminal_receipt",
|
||||
"run_id": "f53d95ac-04d3-5228-ae74-9ab0ad95c013",
|
||||
"run_state": "failed",
|
||||
"error_code": "E-AGENT99-OUTCOME-TIMEOUT",
|
||||
"outcome_timeout_no_write_terminal": True,
|
||||
"timeout_at": "2026-07-15T00:22:32.527349",
|
||||
"terminal_at": "2026-07-15T01:23:15.118099",
|
||||
"terminalizer_runtime_write_performed": False,
|
||||
"outcome_runtime_write_status": (
|
||||
"unknown_without_authenticated_outcome"
|
||||
),
|
||||
"transport_replayed": False,
|
||||
"incident_resolution_authorized": False,
|
||||
"runtime_closure_verified": False,
|
||||
"safe_next_action": (
|
||||
"await_new_source_recurrence_after_agent99_relay_recovery"
|
||||
),
|
||||
}
|
||||
assert chain["historical_incident_context"]["repair_state"] == (
|
||||
"auto_repaired_verified"
|
||||
)
|
||||
assert chain["historical_incident_context"]["writes"] == {
|
||||
"incident": True,
|
||||
"auto_repair": True,
|
||||
}
|
||||
assert "_apply_run_terminal_truth_precedence" in inspect.getsource(
|
||||
platform_operator_service.get_run_detail
|
||||
)
|
||||
|
||||
|
||||
def test_run_terminal_precedence_leaves_unrelated_failed_run_unchanged() -> None:
|
||||
chain = {"repair_state": "auto_repaired_verified"}
|
||||
run = SimpleNamespace(
|
||||
state="failed",
|
||||
error_code="E-OTHER",
|
||||
error_detail="{}",
|
||||
)
|
||||
|
||||
assert _apply_run_terminal_truth_precedence(
|
||||
run=run,
|
||||
status_chain=chain,
|
||||
) == chain
|
||||
|
||||
|
||||
def test_awooop_status_chain_surfaces_controlled_ansible_apply_proof() -> None:
|
||||
chain = _build_awooop_status_chain(
|
||||
incident_ids=["INC-20260531-D6A3C4"],
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -11,13 +13,20 @@ from src.services.gitea_actions_secret_variable_name_inventory import (
|
||||
|
||||
def test_gitea_actions_secret_variable_name_inventory_loader_is_value_safe() -> None:
|
||||
payload = load_latest_gitea_actions_secret_variable_name_inventory()
|
||||
repo_root = Path(__file__).resolve().parents[3]
|
||||
workflow_dir = repo_root / ".gitea" / "workflows"
|
||||
committed_workflow_file_count = sum(
|
||||
1
|
||||
for path in workflow_dir.iterdir()
|
||||
if path.is_file() and path.suffix.lower() in {".yml", ".yaml"}
|
||||
)
|
||||
|
||||
assert (
|
||||
payload["schema_version"] == "gitea_actions_secret_variable_name_inventory_v1"
|
||||
)
|
||||
assert payload["status"] == "gitea_actions_secret_variable_name_inventory_ready"
|
||||
assert payload["ready"] is True
|
||||
assert payload["summary"]["workflow_file_count"] == 13
|
||||
assert payload["summary"]["workflow_file_count"] == committed_workflow_file_count
|
||||
assert payload["summary"]["referenced_secret_name_count"] == 26
|
||||
assert payload["summary"]["referenced_variable_name_count"] == 0
|
||||
assert payload["summary"]["secret_values_collected"] is False
|
||||
|
||||
@@ -139,6 +139,9 @@ def _readback_payload() -> dict:
|
||||
|
||||
def test_gitea_capability_readback_rolls_up_complete_feature_surface() -> None:
|
||||
payload = _readback_payload()
|
||||
workflow_inventory = payload["workflow_source_inventory"]
|
||||
workflow_rows = workflow_inventory["workflow_rows"]
|
||||
workflow_file_count = len(workflow_rows)
|
||||
|
||||
assert (
|
||||
payload["schema_version"] == "gitea_capability_ci_cd_optimization_readback_v1"
|
||||
@@ -148,20 +151,53 @@ def test_gitea_capability_readback_rolls_up_complete_feature_surface() -> None:
|
||||
assert payload["rollups"]["expected_product_count"] == 12
|
||||
assert payload["rollups"]["ssh_verified_product_repo_count"] == 12
|
||||
assert payload["rollups"]["dev_prod_environment_split_ready_count"] == 12
|
||||
assert payload["workflow_source_inventory"]["workflow_file_count"] == 13
|
||||
professional_feature_rollups = payload["workflow_source_inventory"][
|
||||
assert workflow_inventory["workflow_file_count"] == workflow_file_count
|
||||
professional_feature_rollups = workflow_inventory[
|
||||
"professional_feature_rollups"
|
||||
]
|
||||
assert professional_feature_rollups["gitea_ignored_syntax_workflow_count"] == 10
|
||||
assert professional_feature_rollups["otel_workflow_count"] == 3
|
||||
assert professional_feature_rollups["argocd_gitops_workflow_count"] == 1
|
||||
assert professional_feature_rollups["notification_or_webhook_workflow_count"] == 9
|
||||
assert (
|
||||
professional_feature_rollups["registry_or_package_channel_workflow_count"] == 4
|
||||
ignored_syntax_keys = {
|
||||
"declares_concurrency",
|
||||
"declares_permissions",
|
||||
"declares_timeout_minutes",
|
||||
"declares_continue_on_error",
|
||||
"declares_environment",
|
||||
}
|
||||
assert professional_feature_rollups[
|
||||
"gitea_ignored_syntax_workflow_count"
|
||||
] == sum(
|
||||
any(row.get(key) is True for key in ignored_syntax_keys)
|
||||
for row in workflow_rows
|
||||
)
|
||||
assert professional_feature_rollups["otel_workflow_count"] == sum(
|
||||
row.get("uses_otel") is True for row in workflow_rows
|
||||
)
|
||||
assert professional_feature_rollups["argocd_gitops_workflow_count"] == sum(
|
||||
row.get("uses_argocd_gitops") is True for row in workflow_rows
|
||||
)
|
||||
assert professional_feature_rollups[
|
||||
"notification_or_webhook_workflow_count"
|
||||
] == sum(
|
||||
row.get("uses_notification_or_webhook") is True for row in workflow_rows
|
||||
)
|
||||
assert (
|
||||
professional_feature_rollups["registry_or_package_channel_workflow_count"]
|
||||
== sum(
|
||||
row.get("uses_registry_or_package_channel") is True
|
||||
for row in workflow_rows
|
||||
)
|
||||
)
|
||||
assert professional_feature_rollups[
|
||||
"package_release_promotion_workflow_count"
|
||||
] == sum(
|
||||
row.get("uses_package_release_promotion_contract") is True
|
||||
for row in workflow_rows
|
||||
)
|
||||
assert professional_feature_rollups["sbom_or_provenance_workflow_count"] == sum(
|
||||
row.get("uses_sbom_or_provenance") is True for row in workflow_rows
|
||||
)
|
||||
assert professional_feature_rollups["artifact_transfer_workflow_count"] == sum(
|
||||
row.get("uses_artifact_transfer") is True for row in workflow_rows
|
||||
)
|
||||
assert professional_feature_rollups["package_release_promotion_workflow_count"] == 1
|
||||
assert professional_feature_rollups["sbom_or_provenance_workflow_count"] == 1
|
||||
assert professional_feature_rollups["artifact_transfer_workflow_count"] == 1
|
||||
assert (
|
||||
payload["workflow_source_inventory"]["secret_variable_rollups"][
|
||||
"secret_values_collected"
|
||||
@@ -203,8 +239,8 @@ def test_gitea_capability_readback_rolls_up_complete_feature_surface() -> None:
|
||||
assert capability_by_id["wiki_knowledge_base"]["status"] == "source_ready"
|
||||
assert capability_by_id["gitea_actions_workflows"]["status"] == "verified_ready"
|
||||
assert capability_by_id["gitea_actions_workflows"]["metrics"] == {
|
||||
"workflow_source_file_count": 13,
|
||||
"workflow_contract_count": 13,
|
||||
"workflow_source_file_count": workflow_file_count,
|
||||
"workflow_contract_count": workflow_file_count,
|
||||
}
|
||||
assert capability_by_id["gitea_actions_runners"]["status"] == "verified_ready"
|
||||
assert (
|
||||
|
||||
@@ -20,9 +20,14 @@ def test_gitea_workflow_runner_health_endpoint_returns_committed_snapshot():
|
||||
assert data["program_status"]["current_task_id"] == "P1-002"
|
||||
assert data["program_status"]["next_task_id"] == "P1-003"
|
||||
assert data["program_status"]["read_only_mode"] is True
|
||||
assert data["rollups"]["total_workflows"] == len(data["workflow_records"]) == 13
|
||||
assert data["rollups"]["workflows_with_schedule"] == 5
|
||||
assert data["rollups"]["workflows_with_workflow_dispatch"] == 13
|
||||
workflow_records = data["workflow_records"]
|
||||
assert data["rollups"]["total_workflows"] == len(workflow_records)
|
||||
assert data["rollups"]["workflows_with_schedule"] == sum(
|
||||
"schedule" in row["triggers"] for row in workflow_records
|
||||
)
|
||||
assert data["rollups"]["workflows_with_workflow_dispatch"] == sum(
|
||||
"workflow_dispatch" in row["triggers"] for row in workflow_records
|
||||
)
|
||||
assert data["rollups"]["workflow_ids_requiring_runner_attestation"] == []
|
||||
assert data["rollups"]["runner_contracts_requiring_action"] == []
|
||||
assert data["rollups"]["notification_contracts_quiet_success_count"] == 3
|
||||
@@ -64,5 +69,16 @@ def test_gitea_workflow_runner_health_endpoint_returns_committed_snapshot():
|
||||
if row["workflow_id"] == "harbor_110_local_repair"
|
||||
)
|
||||
assert harbor_repair["runner_evidence_status"] == "non110_host_runner_mapped"
|
||||
mcp_artifact_mirror = next(
|
||||
row
|
||||
for row in workflow_records
|
||||
if row["workflow_id"] == "mcp_external_artifact_mirror"
|
||||
)
|
||||
assert mcp_artifact_mirror["runner_labels"] == ["awoooi-non110-host"]
|
||||
assert mcp_artifact_mirror["runner_evidence_status"] == (
|
||||
"non110_host_runner_mapped"
|
||||
)
|
||||
assert mcp_artifact_mirror["notification_policy"] == "read_only_no_notify"
|
||||
assert mcp_artifact_mirror["notify_bridge_calls"] == 0
|
||||
assert "workflow 修改批准" in data["operator_contract"]["must_not_interpret_as"]
|
||||
assert "Secret 已讀取或可輸出" in data["operator_contract"]["must_not_interpret_as"]
|
||||
|
||||
Reference in New Issue
Block a user