Merge remote-tracking branch 'gitea-ssh/main' into codex/aia-p0-006-security-truth-20260722
All checks were successful
CD Pipeline / select-latest-carrier (push) Successful in 1m7s
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m40s
CD Pipeline / revalidate-deploy-carrier (push) Successful in 19s
CD Pipeline / build-and-deploy (push) Successful in 14m11s
CD Pipeline / revalidate-post-deploy-carrier (push) Successful in 45s
CD Pipeline / post-deploy-checks (push) Successful in 4m31s
All checks were successful
CD Pipeline / select-latest-carrier (push) Successful in 1m7s
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m40s
CD Pipeline / revalidate-deploy-carrier (push) Successful in 19s
CD Pipeline / build-and-deploy (push) Successful in 14m11s
CD Pipeline / revalidate-post-deploy-carrier (push) Successful in 45s
CD Pipeline / post-deploy-checks (push) Successful in 4m31s
This commit is contained in:
@@ -1256,8 +1256,9 @@ async def get_sre_k3s_controlled_automation_work_items() -> dict[str, Any]:
|
||||
description=(
|
||||
"唯讀彙總 PostgreSQL incident、run 與 provider budget receipts,計算 "
|
||||
"MTTA、MTTR、誤判、復發、人工介入、verifier、rollback、freshness、"
|
||||
"asset coverage 與模型成本。缺 evidence 時保持 partial,不執行修復、"
|
||||
"不呼叫模型、不讀 secret。"
|
||||
"asset coverage 與模型成本,並輸出去識別、可重算分母的 24h learning "
|
||||
"corpus。缺 evidence 時保持 partial;shadow/no-write 不計 production "
|
||||
"execution,不執行修復、不呼叫模型、不讀 secret。"
|
||||
),
|
||||
)
|
||||
async def get_sre_automation_slo_scorecard_24h(
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
from collections.abc import Mapping, Sequence
|
||||
from datetime import UTC, datetime, timedelta
|
||||
@@ -25,6 +27,8 @@ _INCIDENT_SAMPLES_SQL = text(
|
||||
COALESCE(operation.incident_id, operation.id::text) AS sample_id,
|
||||
operation.event_type::text AS event_type,
|
||||
operation.created_at,
|
||||
operation.action_detail,
|
||||
operation.success,
|
||||
operation.context,
|
||||
incident.resolved_at AS incident_resolved_at,
|
||||
COALESCE(
|
||||
@@ -43,6 +47,66 @@ _INCIDENT_SAMPLES_SQL = text(
|
||||
NULLIF(operation.context ->> 'project_id', ''),
|
||||
'awoooi'
|
||||
) = :project_id
|
||||
), execution_evidence AS (
|
||||
SELECT
|
||||
*,
|
||||
(
|
||||
event_type IN (
|
||||
'EXECUTION_STARTED', 'EXECUTION_COMPLETED',
|
||||
'CHANGE_APPLIED'
|
||||
)
|
||||
) AS execution_like_event,
|
||||
(
|
||||
event_type = 'CHANGE_APPLIED'
|
||||
OR lower(COALESCE(context ->> 'execution_mode', ''))
|
||||
IN ('production', 'controlled_apply')
|
||||
OR lower(COALESCE(context ->> 'execution_kind', ''))
|
||||
= 'executable'
|
||||
OR lower(COALESCE(context ->> 'side_effect_performed', ''))
|
||||
IN ('true', '1', 'yes')
|
||||
OR lower(COALESCE(context ->> 'repair_executed', ''))
|
||||
IN ('true', '1', 'yes')
|
||||
OR lower(COALESCE(
|
||||
context ->> 'controlled_apply_executed', ''
|
||||
)) IN ('true', '1', 'yes')
|
||||
OR lower(COALESCE(context ->> 'runtime_apply_executed', ''))
|
||||
IN ('true', '1', 'yes')
|
||||
OR lower(COALESCE(action_detail, '')) LIKE 'controlled_apply_%'
|
||||
) AS production_execution_evidence,
|
||||
(
|
||||
lower(COALESCE(context ->> 'is_shadow', 'false'))
|
||||
IN ('true', '1', 'yes')
|
||||
OR lower(COALESCE(context ->> 'execution_mode', '')) IN (
|
||||
'shadow', 'canary', 'check_mode', 'dry_run',
|
||||
'read_only', 'no_write', 'no_write_replay',
|
||||
'controlled_retry_check_mode_replay',
|
||||
'stdin_boundary_check_mode_replay'
|
||||
)
|
||||
OR lower(COALESCE(context ->> 'execution_kind', ''))
|
||||
IN ('shadow', 'no_action', 'no_write', 'no_write_replay')
|
||||
OR lower(COALESCE(context ->> 'side_effect_performed', ''))
|
||||
IN ('false', '0', 'no')
|
||||
OR lower(COALESCE(action_detail, '')) LIKE ANY (ARRAY[
|
||||
'%shadow%', '%no_write%', '%check_mode%', '%dry_run%'
|
||||
])
|
||||
) AS execution_exclusion_evidence
|
||||
FROM scoped_events
|
||||
), classified_events AS (
|
||||
SELECT
|
||||
*,
|
||||
(
|
||||
execution_like_event
|
||||
AND production_execution_evidence
|
||||
AND NOT execution_exclusion_evidence
|
||||
) AS production_execution_event,
|
||||
(
|
||||
execution_like_event
|
||||
AND NOT (
|
||||
production_execution_evidence
|
||||
AND NOT execution_exclusion_evidence
|
||||
)
|
||||
) AS excluded_execution_event
|
||||
FROM execution_evidence
|
||||
), per_incident AS (
|
||||
SELECT
|
||||
sample_id,
|
||||
@@ -79,17 +143,24 @@ _INCIDENT_SAMPLES_SQL = text(
|
||||
) AS recurrence,
|
||||
bool_or(event_type IN ('USER_ACTION', 'MANUAL_FIX_RECORDED'))
|
||||
AS human_intervention,
|
||||
bool_or(event_type IN (
|
||||
'AUTO_REPAIR_TRIGGERED', 'EXECUTION_STARTED',
|
||||
'EXECUTION_COMPLETED', 'CHANGE_APPLIED'
|
||||
)) AS execution_observed,
|
||||
bool_or(event_type = 'AUTO_REPAIR_TRIGGERED') AS repair_observed,
|
||||
bool_or(
|
||||
event_type = 'AUTO_REPAIR_TRIGGERED' AND success IS TRUE
|
||||
) AS repair_accepted,
|
||||
bool_or(production_execution_event) AS execution_observed,
|
||||
bool_or(excluded_execution_event)
|
||||
AS shadow_or_no_write_execution_observed,
|
||||
bool_or(
|
||||
context ? 'verifier_passed'
|
||||
OR context ? 'post_verifier_passed'
|
||||
OR context ? 'verification_result'
|
||||
) AS verifier_observed,
|
||||
bool_or(
|
||||
lower(COALESCE(context ->> 'verifier_passed', 'false'))
|
||||
IN ('true', '1', 'yes')
|
||||
OR lower(COALESCE(
|
||||
context ->> 'post_verifier_passed', 'false'
|
||||
)) IN ('true', '1', 'yes')
|
||||
OR lower(COALESCE(context ->> 'verification_result', ''))
|
||||
IN ('success', 'passed', 'verified')
|
||||
) AS verifier_passed,
|
||||
@@ -109,7 +180,7 @@ _INCIDENT_SAMPLES_SQL = text(
|
||||
AND COALESCE(context ->> 'asset_identity_status', 'resolved')
|
||||
<> 'asset_identity_unresolved'
|
||||
) AS asset_identity_resolved
|
||||
FROM scoped_events
|
||||
FROM classified_events
|
||||
GROUP BY sample_id
|
||||
)
|
||||
SELECT *
|
||||
@@ -196,6 +267,21 @@ def _average(values: Sequence[float]) -> float | None:
|
||||
return round(sum(values) / len(values), 2) if values else None
|
||||
|
||||
|
||||
def _iso_timestamp(value: object) -> str | None:
|
||||
parsed = _as_datetime(value)
|
||||
return parsed.isoformat() if parsed else None
|
||||
|
||||
|
||||
def _sha256_json(value: object) -> str:
|
||||
canonical = json.dumps(
|
||||
value,
|
||||
ensure_ascii=True,
|
||||
separators=(",", ":"),
|
||||
sort_keys=True,
|
||||
)
|
||||
return hashlib.sha256(canonical.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def _metrics_for(
|
||||
samples: Sequence[Mapping[str, Any]],
|
||||
) -> tuple[dict[str, Any], dict[str, int]]:
|
||||
@@ -213,8 +299,11 @@ def _metrics_for(
|
||||
total = len(samples)
|
||||
false_observed = sum(_flag(row.get("false_positive_observed")) for row in samples)
|
||||
recurrence_observed = sum(_flag(row.get("recurrence_observed")) for row in samples)
|
||||
execution_observed = sum(_flag(row.get("execution_observed")) for row in samples)
|
||||
verifier_observed = sum(_flag(row.get("verifier_observed")) for row in samples)
|
||||
execution_samples = [row for row in samples if _flag(row.get("execution_observed"))]
|
||||
execution_observed = len(execution_samples)
|
||||
verifier_observed = sum(
|
||||
_flag(row.get("verifier_observed")) for row in execution_samples
|
||||
)
|
||||
freshness_observed = sum(_flag(row.get("freshness_observed")) for row in samples)
|
||||
denominators = {
|
||||
"alert_count": total,
|
||||
@@ -222,8 +311,17 @@ def _metrics_for(
|
||||
"mttr_sample_count": len(mttr),
|
||||
"false_positive_classified_count": false_observed,
|
||||
"recurrence_classified_count": recurrence_observed,
|
||||
"repair_observed_count": sum(
|
||||
_flag(row.get("repair_observed")) for row in samples
|
||||
),
|
||||
"repair_accepted_count": sum(
|
||||
_flag(row.get("repair_accepted")) for row in samples
|
||||
),
|
||||
"execution_observed_count": execution_observed,
|
||||
"verifier_observed_count": verifier_observed,
|
||||
"shadow_or_no_write_execution_excluded_count": sum(
|
||||
_flag(row.get("shadow_or_no_write_execution_observed")) for row in samples
|
||||
),
|
||||
"freshness_observed_count": freshness_observed,
|
||||
}
|
||||
metrics = {
|
||||
@@ -242,11 +340,15 @@ def _metrics_for(
|
||||
total,
|
||||
),
|
||||
"verifier_pass_rate": _rate(
|
||||
sum(_flag(row.get("verifier_passed")) for row in samples),
|
||||
sum(
|
||||
_flag(row.get("verifier_observed"))
|
||||
and _flag(row.get("verifier_passed"))
|
||||
for row in execution_samples
|
||||
),
|
||||
verifier_observed,
|
||||
),
|
||||
"rollback_rate": _rate(
|
||||
sum(_flag(row.get("rollback_performed")) for row in samples),
|
||||
sum(_flag(row.get("rollback_performed")) for row in execution_samples),
|
||||
execution_observed,
|
||||
),
|
||||
"signal_freshness_slo_pass_rate": _rate(
|
||||
@@ -267,6 +369,198 @@ def _metrics_for(
|
||||
return metrics, denominators
|
||||
|
||||
|
||||
def _build_learning_corpus(
|
||||
*,
|
||||
project_id: str,
|
||||
incident_samples: Sequence[Mapping[str, Any]],
|
||||
safe_runs: Mapping[str, int],
|
||||
provider_usage: Mapping[str, Any],
|
||||
window_start: datetime,
|
||||
window_end: datetime,
|
||||
) -> dict[str, Any]:
|
||||
records: list[dict[str, Any]] = []
|
||||
missing_source_identity_count = 0
|
||||
for sample in incident_samples:
|
||||
source_identity = str(sample.get("sample_id") or "").strip()
|
||||
if not source_identity:
|
||||
missing_source_identity_count += 1
|
||||
identity_material = f"{project_id}\0{source_identity}".encode()
|
||||
record_id = (
|
||||
f"sha256:{hashlib.sha256(identity_material).hexdigest()}"
|
||||
if source_identity
|
||||
else ""
|
||||
)
|
||||
lane = str(sample.get("lane") or "unclassified")[:64]
|
||||
execution_observed = _flag(sample.get("execution_observed"))
|
||||
verifier_observed = execution_observed and _flag(
|
||||
sample.get("verifier_observed")
|
||||
)
|
||||
recurrence_observed = _flag(sample.get("recurrence_observed"))
|
||||
false_positive_observed = _flag(sample.get("false_positive_observed"))
|
||||
freshness_observed = _flag(sample.get("freshness_observed"))
|
||||
asset_identity_resolved = _flag(sample.get("asset_identity_resolved"))
|
||||
received_at = _iso_timestamp(sample.get("received_at"))
|
||||
resolved_at = _iso_timestamp(sample.get("resolved_at"))
|
||||
learning_eligible = bool(
|
||||
record_id
|
||||
and received_at
|
||||
and resolved_at
|
||||
and lane != "unclassified"
|
||||
and recurrence_observed
|
||||
and false_positive_observed
|
||||
and freshness_observed
|
||||
and asset_identity_resolved
|
||||
and (not execution_observed or verifier_observed)
|
||||
)
|
||||
records.append(
|
||||
{
|
||||
"record_id": record_id,
|
||||
"lane": lane,
|
||||
"timestamps": {
|
||||
"alert_received_at": received_at,
|
||||
"first_action_at": _iso_timestamp(sample.get("first_action_at")),
|
||||
"resolved_at": resolved_at,
|
||||
},
|
||||
"outcomes": {
|
||||
"repair_observed": _flag(sample.get("repair_observed")),
|
||||
"repair_accepted": _flag(sample.get("repair_accepted")),
|
||||
"production_execution_observed": execution_observed,
|
||||
"shadow_or_no_write_execution_excluded": _flag(
|
||||
sample.get("shadow_or_no_write_execution_observed")
|
||||
),
|
||||
"verifier_observed": verifier_observed,
|
||||
"verifier_passed": (
|
||||
_flag(sample.get("verifier_passed"))
|
||||
if verifier_observed
|
||||
else None
|
||||
),
|
||||
"recurrence_observed": recurrence_observed,
|
||||
"recurrence": (
|
||||
_flag(sample.get("recurrence")) if recurrence_observed else None
|
||||
),
|
||||
"false_positive_observed": false_positive_observed,
|
||||
"false_positive": (
|
||||
_flag(sample.get("false_positive"))
|
||||
if false_positive_observed
|
||||
else None
|
||||
),
|
||||
"human_intervention": _flag(sample.get("human_intervention")),
|
||||
"rollback_performed": (
|
||||
_flag(sample.get("rollback_performed"))
|
||||
if execution_observed
|
||||
else None
|
||||
),
|
||||
},
|
||||
"quality": {
|
||||
"signal_freshness_observed": freshness_observed,
|
||||
"signal_freshness_slo_passed": (
|
||||
_flag(sample.get("freshness_passed"))
|
||||
if freshness_observed
|
||||
else None
|
||||
),
|
||||
"asset_identity_resolved": asset_identity_resolved,
|
||||
},
|
||||
"learning_eligible": learning_eligible,
|
||||
}
|
||||
)
|
||||
|
||||
records.sort(
|
||||
key=lambda row: (
|
||||
str(row["timestamps"].get("alert_received_at") or ""),
|
||||
str(row.get("record_id") or ""),
|
||||
)
|
||||
)
|
||||
denominators = {
|
||||
"alert_count": len(records),
|
||||
"repair_observed_count": sum(
|
||||
row["outcomes"]["repair_observed"] for row in records
|
||||
),
|
||||
"repair_accepted_count": sum(
|
||||
row["outcomes"]["repair_accepted"] for row in records
|
||||
),
|
||||
"production_execution_observed_count": sum(
|
||||
row["outcomes"]["production_execution_observed"] for row in records
|
||||
),
|
||||
"verifier_observed_execution_count": sum(
|
||||
row["outcomes"]["verifier_observed"] for row in records
|
||||
),
|
||||
"recurrence_classified_count": sum(
|
||||
row["outcomes"]["recurrence_observed"] for row in records
|
||||
),
|
||||
"controlled_non_shadow_run_count": int(
|
||||
safe_runs.get("controlled_runs_with_steps") or 0
|
||||
),
|
||||
"provider_call_count": int(provider_usage.get("call_count") or 0),
|
||||
}
|
||||
excluded_from_execution = {
|
||||
"shadow_run_count": max(
|
||||
int(safe_runs.get("total_runs") or 0)
|
||||
- int(safe_runs.get("non_shadow_runs") or 0),
|
||||
0,
|
||||
),
|
||||
"non_shadow_no_step_run_count": max(
|
||||
int(safe_runs.get("non_shadow_runs") or 0)
|
||||
- int(safe_runs.get("controlled_runs_with_steps") or 0),
|
||||
0,
|
||||
),
|
||||
"alert_count_with_shadow_or_no_write_execution_evidence": sum(
|
||||
row["outcomes"]["shadow_or_no_write_execution_excluded"] for row in records
|
||||
),
|
||||
}
|
||||
eligible_record_count = sum(row["learning_eligible"] for row in records)
|
||||
status = (
|
||||
"no_runtime_sample_fail_closed"
|
||||
if not records
|
||||
else "partial_missing_receipt_coverage"
|
||||
if eligible_record_count < len(records) or missing_source_identity_count
|
||||
else "learning_corpus_ready_same_run_verification_pending"
|
||||
)
|
||||
fingerprint_payload = {
|
||||
"window": {
|
||||
"start": window_start.astimezone(UTC).isoformat(),
|
||||
"end": window_end.astimezone(UTC).isoformat(),
|
||||
},
|
||||
"records": records,
|
||||
"denominators": denominators,
|
||||
"excluded_from_execution": excluded_from_execution,
|
||||
"provider_usage": provider_usage,
|
||||
}
|
||||
return {
|
||||
"schema_version": "sre_alert_learning_corpus_v1",
|
||||
"window": fingerprint_payload["window"],
|
||||
"status": status,
|
||||
"runtime_closed": False,
|
||||
"read_only": True,
|
||||
"raw_context_included": False,
|
||||
"record_count": len(records),
|
||||
"learning_eligible_record_count": eligible_record_count,
|
||||
"missing_source_identity_count": missing_source_identity_count,
|
||||
"records": records,
|
||||
"denominators": denominators,
|
||||
"provider_usage": dict(provider_usage),
|
||||
"provider_cost_usd": str(provider_usage.get("cost_usd") or "0.0000"),
|
||||
"excluded_from_execution": excluded_from_execution,
|
||||
"recomputation_contract": {
|
||||
"alert": "count(records)",
|
||||
"repair": "count(records where outcomes.repair_observed=true)",
|
||||
"execution": (
|
||||
"count(records where outcomes.production_execution_observed=true); "
|
||||
"shadow, canary, check-mode, dry-run and no-write are excluded"
|
||||
),
|
||||
"verifier": (
|
||||
"count(executed records where outcomes.verifier_observed=true)"
|
||||
),
|
||||
"recurrence": ("count(records where outcomes.recurrence_observed=true)"),
|
||||
"cost": (
|
||||
"sum(provider_usage.rows.call_count) and "
|
||||
"sum(provider_usage.rows.cost_usd)"
|
||||
),
|
||||
},
|
||||
"corpus_sha256": _sha256_json(fingerprint_payload),
|
||||
"same_run_receipt_verification": "pending",
|
||||
}
|
||||
|
||||
|
||||
def build_automation_slo_scorecard(
|
||||
*,
|
||||
project_id: str,
|
||||
@@ -349,6 +643,21 @@ def build_automation_slo_scorecard(
|
||||
"controlled_failed_runs",
|
||||
)
|
||||
}
|
||||
provider_usage = {
|
||||
"rows": costs,
|
||||
"call_count": sum(row["call_count"] for row in costs),
|
||||
"prompt_tokens": sum(row["prompt_tokens"] for row in costs),
|
||||
"completion_tokens": sum(row["completion_tokens"] for row in costs),
|
||||
"cost_usd": f"{total_cost:.4f}",
|
||||
}
|
||||
learning_corpus = _build_learning_corpus(
|
||||
project_id=project_id,
|
||||
incident_samples=incident_samples,
|
||||
safe_runs=safe_runs,
|
||||
provider_usage=provider_usage,
|
||||
window_start=window_start,
|
||||
window_end=window_end,
|
||||
)
|
||||
return {
|
||||
"schema_version": SCHEMA_VERSION,
|
||||
"project_id": project_id,
|
||||
@@ -363,13 +672,8 @@ def build_automation_slo_scorecard(
|
||||
"denominators": denominators,
|
||||
"lane_scorecards": lane_scorecards,
|
||||
"runs": safe_runs,
|
||||
"provider_usage": {
|
||||
"rows": costs,
|
||||
"call_count": sum(row["call_count"] for row in costs),
|
||||
"prompt_tokens": sum(row["prompt_tokens"] for row in costs),
|
||||
"completion_tokens": sum(row["completion_tokens"] for row in costs),
|
||||
"cost_usd": f"{total_cost:.4f}",
|
||||
},
|
||||
"provider_usage": provider_usage,
|
||||
"learning_corpus": learning_corpus,
|
||||
"missing_metrics": missing_metrics,
|
||||
"coverage_blockers": coverage_blockers,
|
||||
"evidence": {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import json
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
@@ -20,8 +21,10 @@ def _sample(
|
||||
action_seconds: int,
|
||||
resolve_seconds: int,
|
||||
positive: bool,
|
||||
sample_id: str | None = None,
|
||||
) -> dict:
|
||||
return {
|
||||
"sample_id": sample_id or f"{lane}:{int(start.timestamp())}",
|
||||
"lane": lane,
|
||||
"received_at": start,
|
||||
"first_action_at": start + timedelta(seconds=action_seconds),
|
||||
@@ -31,7 +34,10 @@ def _sample(
|
||||
"recurrence_observed": True,
|
||||
"recurrence": positive,
|
||||
"human_intervention": positive,
|
||||
"repair_observed": True,
|
||||
"repair_accepted": True,
|
||||
"execution_observed": True,
|
||||
"shadow_or_no_write_execution_observed": False,
|
||||
"verifier_observed": True,
|
||||
"verifier_passed": not positive,
|
||||
"rollback_performed": positive,
|
||||
@@ -53,6 +59,7 @@ def test_scorecard_computes_all_required_metrics_and_provider_cost() -> None:
|
||||
action_seconds=10,
|
||||
resolve_seconds=100,
|
||||
positive=False,
|
||||
sample_id="INC-REAL-1",
|
||||
),
|
||||
_sample(
|
||||
start + timedelta(hours=2),
|
||||
@@ -60,6 +67,7 @@ def test_scorecard_computes_all_required_metrics_and_provider_cost() -> None:
|
||||
action_seconds=20,
|
||||
resolve_seconds=200,
|
||||
positive=True,
|
||||
sample_id="INC-REAL-2",
|
||||
),
|
||||
],
|
||||
run_summary={
|
||||
@@ -115,6 +123,11 @@ def test_scorecard_computes_all_required_metrics_and_provider_cost() -> None:
|
||||
assert scorecard["runs"]["completed_runs"] == 4
|
||||
assert scorecard["runs"]["controlled_completed_runs"] == 1
|
||||
assert scorecard["runs"]["controlled_failed_runs"] == 1
|
||||
assert scorecard["denominators"]["repair_observed_count"] == 2
|
||||
assert scorecard["denominators"]["repair_accepted_count"] == 2
|
||||
assert scorecard["denominators"]["execution_observed_count"] == 2
|
||||
assert scorecard["denominators"]["verifier_observed_count"] == 2
|
||||
assert scorecard["denominators"]["shadow_or_no_write_execution_excluded_count"] == 0
|
||||
assert scorecard["provider_usage"] == {
|
||||
"rows": [
|
||||
{
|
||||
@@ -139,6 +152,40 @@ def test_scorecard_computes_all_required_metrics_and_provider_cost() -> None:
|
||||
"completion_tokens": 350,
|
||||
"cost_usd": "0.0123",
|
||||
}
|
||||
corpus = scorecard["learning_corpus"]
|
||||
assert corpus["schema_version"] == "sre_alert_learning_corpus_v1"
|
||||
assert corpus["window"] == {
|
||||
"start": start.astimezone(UTC).isoformat(),
|
||||
"end": end.astimezone(UTC).isoformat(),
|
||||
}
|
||||
assert corpus["runtime_closed"] is False
|
||||
assert corpus["read_only"] is True
|
||||
assert corpus["raw_context_included"] is False
|
||||
assert corpus["record_count"] == 2
|
||||
assert corpus["learning_eligible_record_count"] == 1
|
||||
assert corpus["status"] == "partial_missing_receipt_coverage"
|
||||
assert corpus["denominators"] == {
|
||||
"alert_count": 2,
|
||||
"repair_observed_count": 2,
|
||||
"repair_accepted_count": 2,
|
||||
"production_execution_observed_count": 2,
|
||||
"verifier_observed_execution_count": 2,
|
||||
"recurrence_classified_count": 2,
|
||||
"controlled_non_shadow_run_count": 2,
|
||||
"provider_call_count": 4,
|
||||
}
|
||||
assert corpus["provider_usage"] == scorecard["provider_usage"]
|
||||
assert corpus["provider_cost_usd"] == "0.0123"
|
||||
assert corpus["excluded_from_execution"] == {
|
||||
"shadow_run_count": 2,
|
||||
"non_shadow_no_step_run_count": 1,
|
||||
"alert_count_with_shadow_or_no_write_execution_evidence": 0,
|
||||
}
|
||||
assert all(row["record_id"].startswith("sha256:") for row in corpus["records"])
|
||||
assert len(corpus["corpus_sha256"]) == 64
|
||||
serialized_corpus = json.dumps(corpus)
|
||||
assert "INC-REAL-1" not in serialized_corpus
|
||||
assert "INC-REAL-2" not in serialized_corpus
|
||||
assert scorecard["evidence"] == {
|
||||
"source": "postgresql_read_only_aggregate",
|
||||
"same_run_receipt_verification": "pending",
|
||||
@@ -171,6 +218,90 @@ def test_scorecard_does_not_false_green_missing_runtime_samples() -> None:
|
||||
"verifier_pass_rate",
|
||||
}
|
||||
assert scorecard["provider_usage"]["cost_usd"] == "0.0000"
|
||||
assert scorecard["learning_corpus"]["status"] == ("no_runtime_sample_fail_closed")
|
||||
assert scorecard["learning_corpus"]["record_count"] == 0
|
||||
|
||||
|
||||
def test_learning_corpus_excludes_shadow_and_no_write_from_execution() -> None:
|
||||
end = datetime(2026, 7, 19, 4, 0, tzinfo=UTC)
|
||||
real = _sample(
|
||||
end - timedelta(hours=2),
|
||||
lane="kubernetes_workload",
|
||||
action_seconds=10,
|
||||
resolve_seconds=100,
|
||||
positive=False,
|
||||
sample_id="INC-PRODUCTION",
|
||||
)
|
||||
excluded = _sample(
|
||||
end - timedelta(hours=1),
|
||||
lane="host_systemd",
|
||||
action_seconds=20,
|
||||
resolve_seconds=200,
|
||||
positive=False,
|
||||
sample_id="INC-SHADOW",
|
||||
)
|
||||
excluded["execution_observed"] = False
|
||||
excluded["shadow_or_no_write_execution_observed"] = True
|
||||
|
||||
scorecard = build_automation_slo_scorecard(
|
||||
project_id="awoooi",
|
||||
incident_samples=[real, excluded],
|
||||
run_summary={
|
||||
"total_runs": 3,
|
||||
"non_shadow_runs": 2,
|
||||
"controlled_runs_with_steps": 1,
|
||||
"completed_runs": 3,
|
||||
"failed_runs": 0,
|
||||
"controlled_completed_runs": 1,
|
||||
"controlled_failed_runs": 0,
|
||||
},
|
||||
provider_cost_rows=[],
|
||||
window_start=end - timedelta(hours=24),
|
||||
window_end=end,
|
||||
)
|
||||
|
||||
assert scorecard["denominators"]["execution_observed_count"] == 1
|
||||
assert scorecard["denominators"]["verifier_observed_count"] == 1
|
||||
assert scorecard["denominators"]["shadow_or_no_write_execution_excluded_count"] == 1
|
||||
corpus = scorecard["learning_corpus"]
|
||||
assert corpus["status"] == ("learning_corpus_ready_same_run_verification_pending")
|
||||
assert corpus["denominators"]["production_execution_observed_count"] == 1
|
||||
assert corpus["denominators"]["verifier_observed_execution_count"] == 1
|
||||
assert corpus["excluded_from_execution"] == {
|
||||
"shadow_run_count": 1,
|
||||
"non_shadow_no_step_run_count": 1,
|
||||
"alert_count_with_shadow_or_no_write_execution_evidence": 1,
|
||||
}
|
||||
excluded_record = next(
|
||||
row
|
||||
for row in corpus["records"]
|
||||
if row["outcomes"]["shadow_or_no_write_execution_excluded"]
|
||||
)
|
||||
assert excluded_record["outcomes"]["production_execution_observed"] is False
|
||||
assert excluded_record["outcomes"]["verifier_observed"] is False
|
||||
|
||||
|
||||
def test_incident_query_classifies_only_non_shadow_runtime_execution() -> None:
|
||||
statement = " ".join(str(scorecard_module._INCIDENT_SAMPLES_SQL).split())
|
||||
execution_events = statement.split("), execution_evidence AS (", 1)[1].split(
|
||||
"AS execution_like_event", 1
|
||||
)[0]
|
||||
|
||||
assert "AUTO_REPAIR_TRIGGERED" not in execution_events
|
||||
assert (
|
||||
"event_type IN ( 'EXECUTION_STARTED', 'EXECUTION_COMPLETED', "
|
||||
"'CHANGE_APPLIED' )" in execution_events
|
||||
)
|
||||
assert "AS production_execution_evidence" in statement
|
||||
assert "AS execution_exclusion_evidence" in statement
|
||||
assert "context ->> 'is_shadow'" in statement
|
||||
assert "context ->> 'execution_mode'" in statement
|
||||
assert "context ->> 'side_effect_performed'" in statement
|
||||
assert "'%no_write%'" in statement
|
||||
assert "context ->> 'execution_mode', 'production'" not in statement
|
||||
assert "context ->> 'execution_kind', 'executable'" not in statement
|
||||
assert "bool_or(production_execution_event) AS execution_observed" in statement
|
||||
assert "context ? 'post_verifier_passed'" in statement
|
||||
|
||||
|
||||
def test_run_query_excludes_shadow_and_no_step_runs_from_controlled_outcomes() -> None:
|
||||
@@ -182,8 +313,7 @@ def test_run_query_excludes_shadow_and_no_step_runs_from_controlled_outcomes() -
|
||||
)
|
||||
assert (
|
||||
"WHERE is_shadow IS FALSE AND step_count > 0 "
|
||||
"AND state IN ('failed', 'cancelled', 'timeout')"
|
||||
in statement
|
||||
"AND state IN ('failed', 'cancelled', 'timeout')" in statement
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -155,8 +155,8 @@ def test_loader_returns_fixed_architecture_provider_order_and_agent99_bridge() -
|
||||
"active_or_completed_commitments": 68,
|
||||
"by_status": {
|
||||
"analysis_or_governance_complete": 6,
|
||||
"source_implemented_runtime_pending": 35,
|
||||
"in_progress": 26,
|
||||
"source_implemented_runtime_pending": 36,
|
||||
"in_progress": 25,
|
||||
"not_started_or_no_current_evidence": 1,
|
||||
"superseded": 2,
|
||||
},
|
||||
@@ -206,6 +206,12 @@ def test_loader_returns_fixed_architecture_provider_order_and_agent99_bridge() -
|
||||
assert "independent exit-code and freshness receipts" in " ".join(
|
||||
commitments["AIA-CONV-041"]["source_evidence"]
|
||||
)
|
||||
assert commitments["AIA-CONV-045"]["status"] == (
|
||||
"source_implemented_runtime_pending"
|
||||
)
|
||||
assert "deterministically recomputable" in " ".join(
|
||||
commitments["AIA-CONV-045"]["source_evidence"]
|
||||
)
|
||||
assert "Host112" in commitments["AIA-CONV-049"]["title"]
|
||||
assert commitments["AIA-CONV-049"]["status"] == (
|
||||
"source_implemented_runtime_pending"
|
||||
|
||||
Reference in New Issue
Block a user