Merge remote-tracking branch 'origin/main' into codex/sre-typed-automation-20260715
This commit is contained in:
@@ -497,6 +497,68 @@ def _validate_catalog(payload: dict[str, Any], label: str) -> None:
|
||||
raise ValueError(
|
||||
f"{label}: external capability {row.get('capability_id')} cannot deploy without immutable receipts"
|
||||
)
|
||||
if row.get("compatibility_state") != "protocol_schema_compatibility_verified":
|
||||
continue
|
||||
if row.get("replay_status") != "completed_protocol_schema_replay_verified":
|
||||
raise ValueError(
|
||||
f"{label}: verified compatibility requires a completed replay verifier receipt"
|
||||
)
|
||||
if row.get("replay_independent_verifier") is not True:
|
||||
raise ValueError(
|
||||
f"{label}: verified compatibility requires an independent verifier"
|
||||
)
|
||||
if not isinstance(row.get("replay_tool_count"), int) or int(
|
||||
row["replay_tool_count"]
|
||||
) <= 0:
|
||||
raise ValueError(
|
||||
f"{label}: verified compatibility requires a positive replay tool count"
|
||||
)
|
||||
if row.get("replay_process_exit_code") != 0 or row.get(
|
||||
"replay_shutdown_mode"
|
||||
) != "stdin_eof_clean_exit":
|
||||
raise ValueError(
|
||||
f"{label}: verified compatibility requires a clean MCP process terminal"
|
||||
)
|
||||
if row.get("replay_ephemeral_container_removed") is not True:
|
||||
raise ValueError(
|
||||
f"{label}: verified compatibility requires ephemeral container removal"
|
||||
)
|
||||
no_effect_fields = (
|
||||
"replay_browser_started",
|
||||
"replay_tool_call_performed",
|
||||
"replay_navigation_performed",
|
||||
"replay_external_rag_write_performed",
|
||||
"replay_production_write_performed",
|
||||
"replay_promotion_allowed",
|
||||
)
|
||||
if any(row.get(field) is not False for field in no_effect_fields):
|
||||
raise ValueError(
|
||||
f"{label}: compatibility replay must remain no-browser, no-tool, no-write, and no-promotion"
|
||||
)
|
||||
if row.get("deployment_allowed") is not False:
|
||||
raise ValueError(
|
||||
f"{label}: compatibility verification alone cannot enable deployment"
|
||||
)
|
||||
fixed_hex_fields = {
|
||||
"replay_audit_commit": 40,
|
||||
"replay_artifact_audit_commit": 40,
|
||||
"artifact_latest_revalidation_audit_commit": 40,
|
||||
"replay_controller_receipt_sha256": 64,
|
||||
"replay_verifier_receipt_sha256": 64,
|
||||
"replay_tool_name_set_sha256": 64,
|
||||
"replay_tool_schema_manifest_sha256": 64,
|
||||
}
|
||||
if any(
|
||||
not _is_lower_hex(row.get(field), length)
|
||||
for field, length in fixed_hex_fields.items()
|
||||
):
|
||||
raise ValueError(
|
||||
f"{label}: verified compatibility requires immutable audit and replay hashes"
|
||||
)
|
||||
if "compatibility_replay_not_executed" in _strings(row.get("blockers")):
|
||||
raise ValueError(
|
||||
f"{label}: verified compatibility cannot retain replay-not-executed blocker"
|
||||
)
|
||||
|
||||
products = _dict_rows(payload.get("products"))
|
||||
product_ids = {str(row.get("product_id") or "") for row in products}
|
||||
@@ -529,6 +591,14 @@ def _capability_summary(row: dict[str, Any]) -> dict[str, Any]:
|
||||
}
|
||||
|
||||
|
||||
def _is_lower_hex(value: Any, length: int) -> bool:
|
||||
return (
|
||||
isinstance(value, str)
|
||||
and len(value) == length
|
||||
and all(character in "0123456789abcdef" for character in value)
|
||||
)
|
||||
|
||||
|
||||
def _dict_rows(value: Any) -> list[dict[str, Any]]:
|
||||
if not isinstance(value, list):
|
||||
return []
|
||||
|
||||
@@ -52,6 +52,32 @@ def test_catalog_contains_exact_12_products_and_explicit_missing_rows() -> None:
|
||||
"tool_output_contains_cross_tool_prompt_injection"
|
||||
in capabilities["quarantine.agent-bounty-mcp"]["blockers"]
|
||||
)
|
||||
playwright = capabilities["external.playwright-verifier"]
|
||||
assert playwright["compatibility_state"] == (
|
||||
"protocol_schema_compatibility_verified"
|
||||
)
|
||||
assert playwright["replay_status"] == (
|
||||
"completed_protocol_schema_replay_verified"
|
||||
)
|
||||
assert playwright["replay_protocol_version"] == "2025-06-18"
|
||||
assert playwright["replay_tool_count"] == 24
|
||||
assert playwright["replay_independent_verifier"] is True
|
||||
assert playwright["replay_ephemeral_container_removed"] is True
|
||||
assert playwright["replay_browser_started"] is False
|
||||
assert playwright["replay_tool_call_performed"] is False
|
||||
assert playwright["replay_external_rag_write_performed"] is False
|
||||
assert playwright["replay_production_write_performed"] is False
|
||||
assert playwright["replay_promotion_allowed"] is False
|
||||
assert playwright["deployment_allowed"] is False
|
||||
assert "compatibility_replay_not_executed" not in playwright["blockers"]
|
||||
assert playwright["replay_audit_commit"] == (
|
||||
"4a15edb8309a550b6d77f8c1f88b6b1203206045"
|
||||
)
|
||||
assert any(
|
||||
"mcp-replay-receipts@4a15edb8309a550b6d77f8c1f88b6b1203206045"
|
||||
in ref
|
||||
for ref in playwright["evidence_refs"]
|
||||
)
|
||||
assert not any(
|
||||
row["deployment_allowed"]
|
||||
for row in catalog["capabilities"]
|
||||
@@ -107,6 +133,29 @@ def test_catalog_rejects_external_deployment_without_immutable_receipts(
|
||||
raise AssertionError("unsafe external deployment must be rejected")
|
||||
|
||||
|
||||
def test_catalog_rejects_compatibility_replay_with_side_effect(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
catalog = load_mcp_control_plane_catalog(_OPERATIONS_DIR)
|
||||
playwright = next(
|
||||
row
|
||||
for row in catalog["capabilities"]
|
||||
if row["capability_id"] == "external.playwright-verifier"
|
||||
)
|
||||
playwright["replay_tool_call_performed"] = True
|
||||
(tmp_path / "mcp-control-plane-catalog.snapshot.json").write_text(
|
||||
json.dumps(catalog),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
try:
|
||||
load_mcp_control_plane_catalog(tmp_path)
|
||||
except ValueError as exc:
|
||||
assert "no-browser, no-tool, no-write, and no-promotion" in str(exc)
|
||||
else:
|
||||
raise AssertionError("compatibility replay side effects must fail closed")
|
||||
|
||||
|
||||
def test_overview_endpoint_returns_real_committed_catalog_without_runtime() -> None:
|
||||
app = FastAPI()
|
||||
app.include_router(router, prefix="/api/v1")
|
||||
@@ -127,6 +176,16 @@ def test_overview_endpoint_returns_real_committed_catalog_without_runtime() -> N
|
||||
data["operation_boundaries"]["operator_auth_required_for_future_mutation"]
|
||||
is True
|
||||
)
|
||||
playwright = next(
|
||||
row
|
||||
for row in data["capabilities"]
|
||||
if row["capability_id"] == "external.playwright-verifier"
|
||||
)
|
||||
assert playwright["replay_status"] == (
|
||||
"completed_protocol_schema_replay_verified"
|
||||
)
|
||||
assert playwright["replay_run_id"] == "90d0515a-0812-4b04-9913-b210313accff"
|
||||
assert playwright["deployment_allowed"] is False
|
||||
|
||||
|
||||
def test_overview_promotes_durable_lifecycle_receipt_not_static_policy() -> None:
|
||||
|
||||
@@ -202,10 +202,18 @@
|
||||
"scope": "Scope",
|
||||
"version": "Version",
|
||||
"supply": "Digest / SBOM / signature",
|
||||
"replay": "Compatibility replay",
|
||||
"promote": "Deployable"
|
||||
},
|
||||
"allowed": "Deployment allowed",
|
||||
"blocked": "Deployment not allowed"
|
||||
"blocked": "Deployment not allowed",
|
||||
"blockerCount": "{count} blockers remain",
|
||||
"replay": {
|
||||
"verified": "Protocol / schema verified",
|
||||
"pending": "Compatibility replay pending",
|
||||
"protocolTools": "MCP {protocol} · {tools} tools",
|
||||
"receipt": "receipt {id}"
|
||||
}
|
||||
},
|
||||
"lifecycle": {
|
||||
"title": "Version discovery to rollback loop",
|
||||
|
||||
@@ -202,10 +202,18 @@
|
||||
"scope": "Scope",
|
||||
"version": "版本",
|
||||
"supply": "Digest / SBOM / 簽章",
|
||||
"replay": "相容性重播",
|
||||
"promote": "可部署"
|
||||
},
|
||||
"allowed": "已允許部署",
|
||||
"blocked": "尚未允許部署"
|
||||
"blocked": "尚未允許部署",
|
||||
"blockerCount": "仍有 {count} 個 blocker",
|
||||
"replay": {
|
||||
"verified": "Protocol / schema 已驗證",
|
||||
"pending": "尚未完成 compatibility replay",
|
||||
"protocolTools": "MCP {protocol} · {tools} tools",
|
||||
"receipt": "receipt {id}"
|
||||
}
|
||||
},
|
||||
"lifecycle": {
|
||||
"title": "版本發現到回滾循環",
|
||||
|
||||
@@ -38,6 +38,14 @@ interface Capability extends CapabilitySummary {
|
||||
digest_state: string
|
||||
sbom_state: string
|
||||
signature_state: string
|
||||
compatibility_state?: string
|
||||
replay_status?: string
|
||||
replay_protocol_version?: string
|
||||
replay_server_version?: string
|
||||
replay_tool_count?: number
|
||||
replay_run_id?: string
|
||||
replay_independent_verifier?: boolean
|
||||
replay_promotion_allowed?: boolean
|
||||
rag_policy: string
|
||||
blockers: string[]
|
||||
}
|
||||
@@ -633,7 +641,7 @@ export default function McpControlPlanePage({ params }: { params: { locale: stri
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 max-w-full overflow-x-auto overscroll-x-contain">
|
||||
<table className="min-w-[980px] w-full border-collapse text-left text-xs">
|
||||
<table className="min-w-[1160px] w-full border-collapse text-left text-xs">
|
||||
<caption className="sr-only">{t('external.caption')}</caption>
|
||||
<thead>
|
||||
<tr className="border-b border-[#dedbd1] text-[#6c685f]">
|
||||
@@ -643,6 +651,7 @@ export default function McpControlPlanePage({ params }: { params: { locale: stri
|
||||
<th className="px-3 py-3 font-semibold">{t('external.columns.scope')}</th>
|
||||
<th className="px-3 py-3 font-semibold">{t('external.columns.version')}</th>
|
||||
<th className="px-3 py-3 font-semibold">{t('external.columns.supply')}</th>
|
||||
<th className="px-3 py-3 font-semibold">{t('external.columns.replay')}</th>
|
||||
<th className="px-3 py-3 font-semibold">{t('external.columns.promote')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -662,8 +671,32 @@ export default function McpControlPlanePage({ params }: { params: { locale: stri
|
||||
) : null}
|
||||
</td>
|
||||
<td className="px-3 py-3 text-[#5f5b54]">{item.digest_state} / {item.sbom_state} / {item.signature_state}</td>
|
||||
<td className="px-3 py-3 text-[#5f5b54]">
|
||||
{item.compatibility_state === 'protocol_schema_compatibility_verified'
|
||||
&& item.replay_status === 'completed_protocol_schema_replay_verified'
|
||||
&& item.replay_independent_verifier === true ? (
|
||||
<div>
|
||||
<div className="font-semibold text-[#17602a]">{t('external.replay.verified')}</div>
|
||||
<div className="mt-1 text-[10px] text-[#6c685f]">
|
||||
{t('external.replay.protocolTools', {
|
||||
protocol: item.replay_protocol_version ?? '--',
|
||||
tools: item.replay_tool_count ?? 0,
|
||||
})}
|
||||
</div>
|
||||
<div
|
||||
className="mt-1 font-mono text-[10px] text-[#8a867e]"
|
||||
title={item.replay_run_id}
|
||||
>
|
||||
{t('external.replay.receipt', { id: item.replay_run_id?.slice(0, 8) ?? '--' })}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-[#8b5e18]">{t('external.replay.pending')}</span>
|
||||
)}
|
||||
</td>
|
||||
<td className="px-3 py-3">
|
||||
{item.deployment_allowed ? <CheckCircle2 className="h-4 w-4 text-[#2f7d54]" aria-label={t('external.allowed')} /> : <XCircle className="h-4 w-4 text-[#b2432d]" aria-label={t('external.blocked')} />}
|
||||
<p className="mt-1 text-[10px] text-[#8a867e]">{t('external.blockerCount', { count: item.blockers.length })}</p>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user