feat(api): close credential escrow evidence readback
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 19s
CD Pipeline / build-and-deploy (push) Successful in 5m34s
CD Pipeline / post-deploy-checks (push) Successful in 1m12s
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 19s
CD Pipeline / build-and-deploy (push) Successful in 5m34s
CD Pipeline / post-deploy-checks (push) Successful in 1m12s
This commit is contained in:
@@ -218,6 +218,8 @@ jobs:
|
|||||||
;;
|
;;
|
||||||
docs/operations/awoooi-priority-work-order-readback.snapshot.json)
|
docs/operations/awoooi-priority-work-order-readback.snapshot.json)
|
||||||
;;
|
;;
|
||||||
|
docs/operations/awoooi-credential-escrow-evidence-controlled-closeout-receipt.snapshot.json)
|
||||||
|
;;
|
||||||
docs/operations/awoooi-reboot-auto-recovery-slo-scorecard.snapshot.json)
|
docs/operations/awoooi-reboot-auto-recovery-slo-scorecard.snapshot.json)
|
||||||
;;
|
;;
|
||||||
docs/operations/awoooi-gitea-private-inventory-p0-scorecard.snapshot.json)
|
docs/operations/awoooi-gitea-private-inventory-p0-scorecard.snapshot.json)
|
||||||
|
|||||||
@@ -16,11 +16,18 @@ from typing import Any
|
|||||||
from src.services.backup_dr_readiness_matrix import (
|
from src.services.backup_dr_readiness_matrix import (
|
||||||
load_latest_backup_dr_readiness_matrix,
|
load_latest_backup_dr_readiness_matrix,
|
||||||
)
|
)
|
||||||
from src.services.snapshot_paths import default_security_dir
|
from src.services.snapshot_paths import default_operations_dir, default_security_dir
|
||||||
|
|
||||||
_DEFAULT_SECURITY_DIR = default_security_dir(Path(__file__))
|
_DEFAULT_SECURITY_DIR = default_security_dir(Path(__file__))
|
||||||
|
_DEFAULT_OPERATIONS_DIR = default_operations_dir(Path(__file__))
|
||||||
_OWNER_REQUEST_FILE = "credential-escrow-evidence-owner-request.snapshot.json"
|
_OWNER_REQUEST_FILE = "credential-escrow-evidence-owner-request.snapshot.json"
|
||||||
|
_CLOSEOUT_RECEIPT_FILE = (
|
||||||
|
"awoooi-credential-escrow-evidence-controlled-closeout-receipt.snapshot.json"
|
||||||
|
)
|
||||||
_SCHEMA_VERSION = "credential_escrow_evidence_intake_readiness_v1"
|
_SCHEMA_VERSION = "credential_escrow_evidence_intake_readiness_v1"
|
||||||
|
_CLOSEOUT_RECEIPT_SCHEMA_VERSION = (
|
||||||
|
"credential_escrow_evidence_controlled_closeout_receipt_v1"
|
||||||
|
)
|
||||||
_VALIDATION_SCHEMA_VERSION = "credential_escrow_evidence_owner_response_validation_v1"
|
_VALIDATION_SCHEMA_VERSION = "credential_escrow_evidence_owner_response_validation_v1"
|
||||||
_EVIDENCE_REFS_VALIDATION_SCHEMA_VERSION = (
|
_EVIDENCE_REFS_VALIDATION_SCHEMA_VERSION = (
|
||||||
"credential_escrow_evidence_refs_validation_v1"
|
"credential_escrow_evidence_refs_validation_v1"
|
||||||
@@ -76,9 +83,11 @@ _SECRET_VALUE_PATTERNS = {
|
|||||||
def load_latest_credential_escrow_evidence_intake_readiness(
|
def load_latest_credential_escrow_evidence_intake_readiness(
|
||||||
security_dir: Path | None = None,
|
security_dir: Path | None = None,
|
||||||
backup_dr_readiness_matrix: dict[str, Any] | None = None,
|
backup_dr_readiness_matrix: dict[str, Any] | None = None,
|
||||||
|
operations_dir: Path | None = None,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
"""Load P0-005 credential escrow evidence intake readiness."""
|
"""Load P0-005 credential escrow evidence intake readiness."""
|
||||||
directory = security_dir or _DEFAULT_SECURITY_DIR
|
directory = security_dir or _DEFAULT_SECURITY_DIR
|
||||||
|
receipt_directory = operations_dir or _DEFAULT_OPERATIONS_DIR
|
||||||
path = directory / _OWNER_REQUEST_FILE
|
path = directory / _OWNER_REQUEST_FILE
|
||||||
with path.open(encoding="utf-8") as handle:
|
with path.open(encoding="utf-8") as handle:
|
||||||
owner_request = json.load(handle)
|
owner_request = json.load(handle)
|
||||||
@@ -89,12 +98,21 @@ def load_latest_credential_escrow_evidence_intake_readiness(
|
|||||||
if not isinstance(matrix, dict):
|
if not isinstance(matrix, dict):
|
||||||
raise ValueError("backup_dr_readiness_matrix: expected JSON object")
|
raise ValueError("backup_dr_readiness_matrix: expected JSON object")
|
||||||
|
|
||||||
|
closeout_receipt_path = receipt_directory / _CLOSEOUT_RECEIPT_FILE
|
||||||
|
closeout_receipt = _load_closeout_receipt(closeout_receipt_path)
|
||||||
_require_owner_request(owner_request, str(path))
|
_require_owner_request(owner_request, str(path))
|
||||||
_require_backup_rollups(matrix, "backup_dr_readiness_matrix")
|
_require_backup_rollups(matrix, "backup_dr_readiness_matrix")
|
||||||
payload = _build_payload(owner_request, matrix, path)
|
payload = _build_payload(
|
||||||
|
owner_request,
|
||||||
|
matrix,
|
||||||
|
path,
|
||||||
|
closeout_receipt=closeout_receipt,
|
||||||
|
closeout_receipt_path=closeout_receipt_path if closeout_receipt else None,
|
||||||
|
)
|
||||||
_require_operation_boundaries(payload, str(path))
|
_require_operation_boundaries(payload, str(path))
|
||||||
_require_rollup_consistency(payload, str(path))
|
_require_rollup_consistency(payload, str(path))
|
||||||
_require_single_preflight_intake(payload, str(path))
|
_require_single_preflight_intake(payload, str(path))
|
||||||
|
_require_payload_closeout_consistency(payload, str(path))
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
|
||||||
@@ -394,33 +412,62 @@ def _build_payload(
|
|||||||
owner_request: dict[str, Any],
|
owner_request: dict[str, Any],
|
||||||
matrix: dict[str, Any],
|
matrix: dict[str, Any],
|
||||||
owner_request_path: Path,
|
owner_request_path: Path,
|
||||||
|
*,
|
||||||
|
closeout_receipt: dict[str, Any] | None = None,
|
||||||
|
closeout_receipt_path: Path | None = None,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
rollups = _dict(matrix.get("rollups"))
|
rollups = _dict(matrix.get("rollups"))
|
||||||
missing_items = [_normalize_item(item) for item in _list(owner_request.get("missing_items"))]
|
receipt = _dict(closeout_receipt)
|
||||||
|
receipt_result = _dict(receipt.get("result"))
|
||||||
|
closeout_ready = bool(receipt)
|
||||||
|
closeout_items = _receipt_items_by_id(receipt)
|
||||||
|
missing_items = [
|
||||||
|
_normalize_item(item, closeout_items.get(str(_dict(item).get("item") or _dict(item).get("item_id") or "")))
|
||||||
|
for item in _list(owner_request.get("missing_items"))
|
||||||
|
]
|
||||||
blocked_items = [
|
blocked_items = [
|
||||||
item["item_id"]
|
item["item_id"]
|
||||||
for item in missing_items
|
for item in missing_items
|
||||||
if item.get("status") != "verified"
|
if item.get("status") != "verified"
|
||||||
]
|
]
|
||||||
effective_missing = _int(rollups.get("credential_escrow_effective_missing_count"))
|
effective_missing = (
|
||||||
|
0
|
||||||
|
if closeout_ready
|
||||||
|
else _int(rollups.get("credential_escrow_effective_missing_count"))
|
||||||
|
)
|
||||||
forbidden_values = _strings(owner_request.get("forbidden_values"))
|
forbidden_values = _strings(owner_request.get("forbidden_values"))
|
||||||
status = str(
|
status = str(
|
||||||
rollups.get("credential_escrow_intake_status")
|
rollups.get("credential_escrow_intake_status")
|
||||||
or "blocked_waiting_non_secret_credential_escrow_evidence"
|
or "blocked_waiting_non_secret_credential_escrow_evidence"
|
||||||
)
|
)
|
||||||
if effective_missing == 0 and not blocked_items:
|
if closeout_ready:
|
||||||
|
status = "closed_credential_escrow_evidence_refs_controlled_closeout"
|
||||||
|
elif effective_missing == 0 and not blocked_items:
|
||||||
status = "ready_for_escrow_marker_review"
|
status = "ready_for_escrow_marker_review"
|
||||||
safe_next_step = "collect_redacted_non_secret_evidence_refs_then_rerun_preflight"
|
safe_next_step = (
|
||||||
|
str(receipt.get("safe_next_step") or "")
|
||||||
|
if closeout_ready
|
||||||
|
else "collect_redacted_non_secret_evidence_refs_then_rerun_preflight"
|
||||||
|
)
|
||||||
|
if not safe_next_step:
|
||||||
|
safe_next_step = "continue_to_p0_006_source_to_runtime_drift_cleanup"
|
||||||
rollup_readback = {
|
rollup_readback = {
|
||||||
"required_item_count": len(missing_items),
|
"required_item_count": len(missing_items),
|
||||||
"missing_item_count": len(blocked_items),
|
"missing_item_count": len(blocked_items),
|
||||||
"blocked_item_ids": blocked_items,
|
"blocked_item_ids": blocked_items,
|
||||||
"effective_escrow_missing_count": effective_missing,
|
"effective_escrow_missing_count": effective_missing,
|
||||||
"owner_response_received_count": _int(
|
"accepted_item_count": _int(
|
||||||
rollups.get("credential_escrow_owner_response_received_count")
|
receipt_result.get("accepted_item_count")
|
||||||
),
|
),
|
||||||
"owner_response_accepted_count": _int(
|
"owner_response_received_count": (
|
||||||
rollups.get("credential_escrow_owner_response_accepted_count")
|
_int(receipt_result.get("owner_response_received_count"))
|
||||||
|
if closeout_ready
|
||||||
|
else _int(rollups.get("credential_escrow_owner_response_received_count"))
|
||||||
|
),
|
||||||
|
"owner_response_accepted_count": (
|
||||||
|
_int(receipt_result.get("owner_response_accepted_count"))
|
||||||
|
if closeout_ready
|
||||||
|
else _int(rollups.get("credential_escrow_owner_response_accepted_count"))
|
||||||
),
|
),
|
||||||
"runtime_gate_count": _int(rollups.get("credential_escrow_runtime_gate_count")),
|
"runtime_gate_count": _int(rollups.get("credential_escrow_runtime_gate_count")),
|
||||||
"credential_marker_write_authorized_count": _int(
|
"credential_marker_write_authorized_count": _int(
|
||||||
@@ -432,6 +479,26 @@ def _build_payload(
|
|||||||
"forbidden_true_field_count": _int(
|
"forbidden_true_field_count": _int(
|
||||||
rollups.get("credential_escrow_forbidden_true_field_count")
|
rollups.get("credential_escrow_forbidden_true_field_count")
|
||||||
),
|
),
|
||||||
|
"preflight_status": (
|
||||||
|
"ready_for_reviewer_acceptance_writeback"
|
||||||
|
if closeout_ready
|
||||||
|
else str(
|
||||||
|
rollups.get("credential_escrow_preflight_status")
|
||||||
|
or "blocked_waiting_owner_response_content"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"active_gate_present": (
|
||||||
|
False
|
||||||
|
if closeout_ready
|
||||||
|
else rollups.get("credential_escrow_active_gate_present") is True
|
||||||
|
),
|
||||||
|
"controlled_closeout_status": str(receipt.get("status") or ""),
|
||||||
|
"controlled_closeout_redacted_receipt_writeback_ready_count": _int(
|
||||||
|
receipt_result.get("redacted_receipt_writeback_ready_count")
|
||||||
|
),
|
||||||
|
"controlled_closeout_projected_effective_escrow_missing_count": _int(
|
||||||
|
receipt_result.get("projected_effective_escrow_missing_count")
|
||||||
|
),
|
||||||
"forbidden_value_count": len(forbidden_values),
|
"forbidden_value_count": len(forbidden_values),
|
||||||
"single_preflight_intake_ready_count": 1,
|
"single_preflight_intake_ready_count": 1,
|
||||||
}
|
}
|
||||||
@@ -453,24 +520,51 @@ def _build_payload(
|
|||||||
"source_backup_dr_readiness_matrix_ref": (
|
"source_backup_dr_readiness_matrix_ref": (
|
||||||
"docs/evaluations/backup_dr_readiness_matrix_2026-06-04.json"
|
"docs/evaluations/backup_dr_readiness_matrix_2026-06-04.json"
|
||||||
),
|
),
|
||||||
|
"source_closeout_receipt_ref": (
|
||||||
|
f"docs/operations/{closeout_receipt_path.name}"
|
||||||
|
if closeout_receipt_path
|
||||||
|
else ""
|
||||||
|
),
|
||||||
"single_preflight_intake_schema_version": (
|
"single_preflight_intake_schema_version": (
|
||||||
_SINGLE_PREFLIGHT_INTAKE_SCHEMA_VERSION
|
_SINGLE_PREFLIGHT_INTAKE_SCHEMA_VERSION
|
||||||
),
|
),
|
||||||
"safe_next_step": safe_next_step,
|
"safe_next_step": safe_next_step,
|
||||||
},
|
},
|
||||||
"required_evidence_items": missing_items,
|
"required_evidence_items": missing_items,
|
||||||
|
"controlled_closeout_receipt": receipt,
|
||||||
|
"reviewer_readiness": _build_reviewer_readiness(
|
||||||
|
closeout_ready=closeout_ready,
|
||||||
|
accepted_item_ids=[item["item_id"] for item in missing_items if item.get("status") == "verified"],
|
||||||
|
missing_item_ids=blocked_items,
|
||||||
|
current_effective_missing=_int(
|
||||||
|
rollups.get("credential_escrow_effective_missing_count")
|
||||||
|
),
|
||||||
|
projected_effective_missing=effective_missing,
|
||||||
|
redacted_receipt_writeback_ready_count=_int(
|
||||||
|
receipt_result.get("redacted_receipt_writeback_ready_count")
|
||||||
|
),
|
||||||
|
safe_next_step=safe_next_step,
|
||||||
|
),
|
||||||
"single_preflight_intake_ready": True,
|
"single_preflight_intake_ready": True,
|
||||||
"owner_response_skeleton_required_item_count": len(_REQUIRED_ITEM_ORDER),
|
"owner_response_skeleton_required_item_count": len(_REQUIRED_ITEM_ORDER),
|
||||||
"owner_response_skeleton_secret_value_collection_allowed": False,
|
"owner_response_skeleton_secret_value_collection_allowed": False,
|
||||||
"single_preflight_intake": _build_single_preflight_intake(
|
"single_preflight_intake": _build_single_preflight_intake(
|
||||||
owner_request.get("generated_at"),
|
owner_request.get("generated_at"),
|
||||||
|
closeout_ready=closeout_ready,
|
||||||
),
|
),
|
||||||
"forbidden_values": forbidden_values,
|
"forbidden_values": forbidden_values,
|
||||||
"next_actions": [
|
"next_actions": (
|
||||||
"collect_redacted_non_secret_evidence_refs_for_all_missing_items",
|
[
|
||||||
"rerun_owner_response_preflight_without_secret_values",
|
"keep_credential_marker_write_closed_until_marker_dry_run_gate",
|
||||||
"keep_credential_marker_write_closed_until_preflight_accepts_all_items",
|
"continue_to_p0_006_source_to_runtime_drift_cleanup",
|
||||||
],
|
]
|
||||||
|
if closeout_ready
|
||||||
|
else [
|
||||||
|
"collect_redacted_non_secret_evidence_refs_for_all_missing_items",
|
||||||
|
"rerun_owner_response_preflight_without_secret_values",
|
||||||
|
"keep_credential_marker_write_closed_until_preflight_accepts_all_items",
|
||||||
|
]
|
||||||
|
),
|
||||||
"blocked_operations": [
|
"blocked_operations": [
|
||||||
"credential_marker_write",
|
"credential_marker_write",
|
||||||
"credential_read",
|
"credential_read",
|
||||||
@@ -499,12 +593,20 @@ def _build_payload(
|
|||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
|
||||||
def _build_single_preflight_intake(generated_at: Any) -> dict[str, Any]:
|
def _build_single_preflight_intake(
|
||||||
|
generated_at: Any,
|
||||||
|
*,
|
||||||
|
closeout_ready: bool = False,
|
||||||
|
) -> dict[str, Any]:
|
||||||
return {
|
return {
|
||||||
"schema_version": _SINGLE_PREFLIGHT_INTAKE_SCHEMA_VERSION,
|
"schema_version": _SINGLE_PREFLIGHT_INTAKE_SCHEMA_VERSION,
|
||||||
"generated_at": generated_at,
|
"generated_at": generated_at,
|
||||||
"workplan_id": "P0-005",
|
"workplan_id": "P0-005",
|
||||||
"status": "waiting_for_five_redacted_non_secret_evidence_refs",
|
"status": (
|
||||||
|
"completed_redacted_non_secret_evidence_refs_receipt_ready"
|
||||||
|
if closeout_ready
|
||||||
|
else "waiting_for_five_redacted_non_secret_evidence_refs"
|
||||||
|
),
|
||||||
"active_gate": _GATE_ID,
|
"active_gate": _GATE_ID,
|
||||||
"required_item_count": len(_REQUIRED_ITEM_ORDER),
|
"required_item_count": len(_REQUIRED_ITEM_ORDER),
|
||||||
"required_item_ids": list(_REQUIRED_ITEM_ORDER),
|
"required_item_ids": list(_REQUIRED_ITEM_ORDER),
|
||||||
@@ -760,14 +862,83 @@ def _field(
|
|||||||
return str(payload.get(key) or defaults.get(key) or fallback)
|
return str(payload.get(key) or defaults.get(key) or fallback)
|
||||||
|
|
||||||
|
|
||||||
def _normalize_item(item: Any) -> dict[str, Any]:
|
def _load_closeout_receipt(path: Path) -> dict[str, Any]:
|
||||||
|
if not path.exists():
|
||||||
|
return {}
|
||||||
|
with path.open(encoding="utf-8") as handle:
|
||||||
|
receipt = json.load(handle)
|
||||||
|
if not isinstance(receipt, dict):
|
||||||
|
raise ValueError(f"{path}: expected JSON object")
|
||||||
|
_require_closeout_receipt(receipt, str(path))
|
||||||
|
return receipt
|
||||||
|
|
||||||
|
|
||||||
|
def _receipt_items_by_id(receipt: dict[str, Any]) -> dict[str, dict[str, Any]]:
|
||||||
|
return {
|
||||||
|
str(item.get("item_id") or ""): _dict(item)
|
||||||
|
for item in _list(receipt.get("evidence_refs"))
|
||||||
|
if isinstance(item, dict)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _build_reviewer_readiness(
|
||||||
|
*,
|
||||||
|
closeout_ready: bool,
|
||||||
|
accepted_item_ids: list[str],
|
||||||
|
missing_item_ids: list[str],
|
||||||
|
current_effective_missing: int,
|
||||||
|
projected_effective_missing: int,
|
||||||
|
redacted_receipt_writeback_ready_count: int,
|
||||||
|
safe_next_step: str,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"schema_version": "credential_escrow_reviewer_readiness_v1",
|
||||||
|
"status": (
|
||||||
|
"ready_for_reviewer_acceptance_writeback"
|
||||||
|
if closeout_ready
|
||||||
|
else "not_ready_for_reviewer_acceptance_writeback"
|
||||||
|
),
|
||||||
|
"accepted_required_item_ids": sorted(set(accepted_item_ids)),
|
||||||
|
"missing_required_item_ids": missing_item_ids,
|
||||||
|
"current_effective_escrow_missing_count": current_effective_missing,
|
||||||
|
"projected_effective_escrow_missing_count": projected_effective_missing,
|
||||||
|
"redacted_receipt_writeback_ready_count": redacted_receipt_writeback_ready_count,
|
||||||
|
"credential_marker_write_authorized_count": 0,
|
||||||
|
"runtime_gate_count": 0,
|
||||||
|
"secret_value_collection_allowed": False,
|
||||||
|
"payload_persisted": False,
|
||||||
|
"safe_next_step": safe_next_step,
|
||||||
|
"blocked_operations": [
|
||||||
|
"credential_marker_write",
|
||||||
|
"credential_read",
|
||||||
|
"secret_plaintext_export",
|
||||||
|
"backup_execution",
|
||||||
|
"restore_execution",
|
||||||
|
"offsite_sync_execution",
|
||||||
|
"workflow_dispatch",
|
||||||
|
"host_or_k8s_write",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_item(
|
||||||
|
item: Any,
|
||||||
|
closeout_item: dict[str, Any] | None = None,
|
||||||
|
) -> dict[str, Any]:
|
||||||
data = _dict(item)
|
data = _dict(item)
|
||||||
|
receipt_item = _dict(closeout_item)
|
||||||
|
verified = bool(receipt_item)
|
||||||
return {
|
return {
|
||||||
"item_id": str(data.get("item") or data.get("item_id") or ""),
|
"item_id": str(data.get("item") or data.get("item_id") or ""),
|
||||||
"status": str(data.get("status") or "missing"),
|
"status": "verified" if verified else str(data.get("status") or "missing"),
|
||||||
"allowed_evidence_id_types": _strings(data.get("allowed_evidence_id_types")),
|
"allowed_evidence_id_types": _strings(data.get("allowed_evidence_id_types")),
|
||||||
"contains_secret_value_allowed": False,
|
"contains_secret_value_allowed": False,
|
||||||
"required_non_secret_evidence_ref": True,
|
"required_non_secret_evidence_ref": True,
|
||||||
|
"non_secret_evidence_ref": str(receipt_item.get("non_secret_evidence_ref") or ""),
|
||||||
|
"recovery_owner": str(receipt_item.get("recovery_owner") or ""),
|
||||||
|
"reviewer": str(receipt_item.get("reviewer") or ""),
|
||||||
|
"last_reviewed_at": str(receipt_item.get("last_reviewed_at") or ""),
|
||||||
|
"controlled_closeout_receipt_accepted": verified,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -878,6 +1049,116 @@ def _require_single_preflight_intake(payload: dict[str, Any], label: str) -> Non
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _require_payload_closeout_consistency(payload: dict[str, Any], label: str) -> None:
|
||||||
|
receipt = _dict(payload.get("controlled_closeout_receipt"))
|
||||||
|
if not receipt:
|
||||||
|
return
|
||||||
|
rollups = _dict(payload.get("rollups"))
|
||||||
|
reviewer = _dict(payload.get("reviewer_readiness"))
|
||||||
|
if payload.get("status") != "closed_credential_escrow_evidence_refs_controlled_closeout":
|
||||||
|
raise ValueError(f"{label}: closeout payload status mismatch")
|
||||||
|
if rollups.get("missing_item_count") != 0:
|
||||||
|
raise ValueError(f"{label}: closeout missing_item_count must be zero")
|
||||||
|
if rollups.get("effective_escrow_missing_count") != 0:
|
||||||
|
raise ValueError(f"{label}: closeout effective missing count must be zero")
|
||||||
|
if rollups.get("owner_response_accepted_count") != 1:
|
||||||
|
raise ValueError(f"{label}: closeout accepted count must be one")
|
||||||
|
if (
|
||||||
|
reviewer.get("status")
|
||||||
|
!= "ready_for_reviewer_acceptance_writeback"
|
||||||
|
):
|
||||||
|
raise ValueError(f"{label}: closeout reviewer readiness mismatch")
|
||||||
|
if reviewer.get("credential_marker_write_authorized_count") != 0:
|
||||||
|
raise ValueError(f"{label}: closeout marker write must remain closed")
|
||||||
|
if reviewer.get("secret_value_collection_allowed") is not False:
|
||||||
|
raise ValueError(f"{label}: closeout secret collection must remain false")
|
||||||
|
|
||||||
|
|
||||||
|
def _require_closeout_receipt(receipt: dict[str, Any], label: str) -> None:
|
||||||
|
if receipt.get("schema_version") != _CLOSEOUT_RECEIPT_SCHEMA_VERSION:
|
||||||
|
raise ValueError(f"{label}: controlled closeout receipt schema mismatch")
|
||||||
|
if receipt.get("workplan_id") != "P0-005":
|
||||||
|
raise ValueError(f"{label}: workplan_id must be P0-005")
|
||||||
|
if receipt.get("status") != "ready_for_p0_005_controlled_closeout":
|
||||||
|
raise ValueError(f"{label}: controlled closeout receipt status mismatch")
|
||||||
|
sensitive_hits = _find_sensitive_strings(receipt)
|
||||||
|
if sensitive_hits:
|
||||||
|
raise ValueError(f"{label}: sensitive strings present: {sensitive_hits}")
|
||||||
|
forbidden_hits = _find_forbidden_booleans(receipt)
|
||||||
|
if forbidden_hits:
|
||||||
|
raise ValueError(f"{label}: forbidden boolean fields true: {forbidden_hits}")
|
||||||
|
|
||||||
|
result = _dict(receipt.get("result"))
|
||||||
|
if _int(result.get("required_item_count")) != len(_REQUIRED_ITEM_ORDER):
|
||||||
|
raise ValueError(f"{label}: required item count mismatch")
|
||||||
|
if _int(result.get("accepted_item_count")) != len(_REQUIRED_ITEM_ORDER):
|
||||||
|
raise ValueError(f"{label}: accepted item count mismatch")
|
||||||
|
if _int(result.get("missing_required_item_count")) != 0:
|
||||||
|
raise ValueError(f"{label}: missing item count must be zero")
|
||||||
|
if _int(result.get("owner_response_received_count")) != 1:
|
||||||
|
raise ValueError(f"{label}: owner response received count must be one")
|
||||||
|
if _int(result.get("owner_response_accepted_count")) != 1:
|
||||||
|
raise ValueError(f"{label}: owner response accepted count must be one")
|
||||||
|
if _int(result.get("projected_effective_escrow_missing_count")) != 0:
|
||||||
|
raise ValueError(f"{label}: projected missing count must be zero")
|
||||||
|
if _int(result.get("redacted_receipt_writeback_ready_count")) != 1:
|
||||||
|
raise ValueError(f"{label}: redacted receipt writeback count must be one")
|
||||||
|
if _int(result.get("runtime_gate_count")) != 0:
|
||||||
|
raise ValueError(f"{label}: runtime gate must remain zero")
|
||||||
|
if _int(result.get("credential_marker_write_authorized_count")) != 0:
|
||||||
|
raise ValueError(f"{label}: marker write must remain closed")
|
||||||
|
if result.get("secret_value_collection_allowed") is not False:
|
||||||
|
raise ValueError(f"{label}: secret value collection must remain false")
|
||||||
|
if _int(result.get("forbidden_true_field_count")) != 0:
|
||||||
|
raise ValueError(f"{label}: forbidden true field count must be zero")
|
||||||
|
|
||||||
|
items = [_dict(item) for item in _list(receipt.get("evidence_refs"))]
|
||||||
|
item_ids = [str(item.get("item_id") or "") for item in items]
|
||||||
|
if item_ids != list(_REQUIRED_ITEM_ORDER):
|
||||||
|
raise ValueError(f"{label}: evidence ref item order mismatch")
|
||||||
|
for item in items:
|
||||||
|
item_id = str(item.get("item_id") or "")
|
||||||
|
for key in (
|
||||||
|
"non_secret_evidence_ref",
|
||||||
|
"recovery_owner",
|
||||||
|
"reviewer",
|
||||||
|
"last_reviewed_at",
|
||||||
|
):
|
||||||
|
if _is_placeholder(item.get(key)):
|
||||||
|
raise ValueError(f"{label}: {item_id}.{key} missing")
|
||||||
|
if item.get("contains_secret_value") is not False:
|
||||||
|
raise ValueError(f"{label}: {item_id}.contains_secret_value must be false")
|
||||||
|
|
||||||
|
writeback = _dict(receipt.get("writeback"))
|
||||||
|
if writeback.get("source_readiness_written") is not True:
|
||||||
|
raise ValueError(f"{label}: source readiness writeback missing")
|
||||||
|
if writeback.get("production_runtime_write_requested") is not False:
|
||||||
|
raise ValueError(f"{label}: production runtime write request must remain false")
|
||||||
|
if writeback.get("production_runtime_write_performed") is not False:
|
||||||
|
raise ValueError(f"{label}: production runtime write must remain false")
|
||||||
|
|
||||||
|
boundaries = _dict(receipt.get("operation_boundaries"))
|
||||||
|
if boundaries.get("source_readiness_written") is not True:
|
||||||
|
raise ValueError(f"{label}: source readiness boundary missing")
|
||||||
|
blocked_flags = {
|
||||||
|
"payload_persisted",
|
||||||
|
"backup_execution_performed",
|
||||||
|
"restore_execution_performed",
|
||||||
|
"offsite_sync_execution_performed",
|
||||||
|
"credential_marker_write_performed",
|
||||||
|
"credential_read_performed",
|
||||||
|
"secret_plaintext_read",
|
||||||
|
"secret_value_collection_allowed",
|
||||||
|
"workflow_trigger_performed",
|
||||||
|
"host_or_k8s_write_performed",
|
||||||
|
"raw_session_or_sqlite_read_performed",
|
||||||
|
"runtime_action_performed",
|
||||||
|
}
|
||||||
|
open_flags = sorted(flag for flag in blocked_flags if boundaries.get(flag) is not False)
|
||||||
|
if open_flags:
|
||||||
|
raise ValueError(f"{label}: closeout boundaries opened: {open_flags}")
|
||||||
|
|
||||||
|
|
||||||
def _dict(value: Any) -> dict[str, Any]:
|
def _dict(value: Any) -> dict[str, Any]:
|
||||||
return value if isinstance(value, dict) else {}
|
return value if isinstance(value, dict) else {}
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,10 @@ def build_delivery_closure_workbench(
|
|||||||
)
|
)
|
||||||
credential_intake_rollups = _dict(credential_escrow_intake.get("rollups"))
|
credential_intake_rollups = _dict(credential_escrow_intake.get("rollups"))
|
||||||
credential_intake_readback = _dict(credential_escrow_intake.get("readback"))
|
credential_intake_readback = _dict(credential_escrow_intake.get("readback"))
|
||||||
|
credential_closeout_receipt = _dict(
|
||||||
|
credential_escrow_intake.get("controlled_closeout_receipt")
|
||||||
|
)
|
||||||
|
credential_closeout_result = _dict(credential_closeout_receipt.get("result"))
|
||||||
single_preflight_intake = _dict(
|
single_preflight_intake = _dict(
|
||||||
credential_escrow_intake.get("single_preflight_intake")
|
credential_escrow_intake.get("single_preflight_intake")
|
||||||
)
|
)
|
||||||
@@ -121,10 +125,34 @@ def build_delivery_closure_workbench(
|
|||||||
)
|
)
|
||||||
reboot_blockers = _int(reboot_rollups.get("active_blocker_count"))
|
reboot_blockers = _int(reboot_rollups.get("active_blocker_count"))
|
||||||
credential_escrow_required_items = _int(
|
credential_escrow_required_items = _int(
|
||||||
backup_rollups.get("credential_escrow_required_item_count")
|
credential_intake_rollups.get("required_item_count")
|
||||||
|
if "required_item_count" in credential_intake_rollups
|
||||||
|
else backup_rollups.get("credential_escrow_required_item_count")
|
||||||
)
|
)
|
||||||
credential_escrow_missing_items = _int(
|
credential_escrow_missing_items = _int(
|
||||||
backup_rollups.get("credential_escrow_effective_missing_count")
|
credential_intake_rollups.get("effective_escrow_missing_count")
|
||||||
|
if "effective_escrow_missing_count" in credential_intake_rollups
|
||||||
|
else backup_rollups.get("credential_escrow_effective_missing_count")
|
||||||
|
)
|
||||||
|
credential_escrow_status = str(
|
||||||
|
credential_escrow_intake.get("status")
|
||||||
|
or backup_rollups.get("credential_escrow_intake_status")
|
||||||
|
or "blocked_waiting_non_secret_credential_escrow_evidence"
|
||||||
|
)
|
||||||
|
credential_escrow_preflight_status = str(
|
||||||
|
credential_intake_rollups.get("preflight_status")
|
||||||
|
or backup_rollups.get("credential_escrow_preflight_status")
|
||||||
|
or ""
|
||||||
|
)
|
||||||
|
credential_escrow_active_gate_present = (
|
||||||
|
credential_intake_rollups.get("active_gate_present")
|
||||||
|
if "active_gate_present" in credential_intake_rollups
|
||||||
|
else backup_rollups.get("credential_escrow_active_gate_present")
|
||||||
|
) is True
|
||||||
|
credential_escrow_safe_next_step = str(
|
||||||
|
credential_intake_readback.get("safe_next_step")
|
||||||
|
or credential_escrow_intake.get("safe_next_step")
|
||||||
|
or ""
|
||||||
)
|
)
|
||||||
credential_escrow_completion = _percent(
|
credential_escrow_completion = _percent(
|
||||||
(
|
(
|
||||||
@@ -503,49 +531,56 @@ def build_delivery_closure_workbench(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "credential_escrow",
|
"id": "credential_escrow",
|
||||||
"source_id": "backup_dr_credential_escrow",
|
"source_id": "credential_escrow_evidence_intake_readiness",
|
||||||
"completion_percent": credential_escrow_completion,
|
"completion_percent": credential_escrow_completion,
|
||||||
"status": str(
|
"status": credential_escrow_status,
|
||||||
backup_rollups.get("credential_escrow_intake_status")
|
|
||||||
or "blocked_waiting_non_secret_credential_escrow_evidence"
|
|
||||||
),
|
|
||||||
"blocker_count": credential_escrow_missing_items,
|
"blocker_count": credential_escrow_missing_items,
|
||||||
"metric": {
|
"metric": {
|
||||||
"kind": "credential_escrow_evidence",
|
"kind": "credential_escrow_evidence",
|
||||||
"workplan_id": "P0-005",
|
"workplan_id": "P0-005",
|
||||||
"required_item_count": credential_escrow_required_items,
|
"required_item_count": credential_escrow_required_items,
|
||||||
"effective_missing_count": credential_escrow_missing_items,
|
"effective_missing_count": credential_escrow_missing_items,
|
||||||
"active_gate_present": backup_rollups.get(
|
"active_gate_present": credential_escrow_active_gate_present,
|
||||||
"credential_escrow_active_gate_present"
|
"preflight_status": credential_escrow_preflight_status,
|
||||||
)
|
"accepted_item_count": _int(
|
||||||
is True,
|
credential_intake_rollups.get("accepted_item_count")
|
||||||
"preflight_status": str(
|
|
||||||
backup_rollups.get("credential_escrow_preflight_status") or ""
|
|
||||||
),
|
),
|
||||||
"owner_response_received_count": _int(
|
"owner_response_received_count": _int(
|
||||||
backup_rollups.get(
|
credential_intake_rollups.get("owner_response_received_count")
|
||||||
"credential_escrow_owner_response_received_count"
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
"owner_response_accepted_count": _int(
|
"owner_response_accepted_count": _int(
|
||||||
backup_rollups.get(
|
credential_intake_rollups.get("owner_response_accepted_count")
|
||||||
"credential_escrow_owner_response_accepted_count"
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
"runtime_gate_count": _int(
|
"runtime_gate_count": _int(
|
||||||
backup_rollups.get("credential_escrow_runtime_gate_count")
|
credential_intake_rollups.get("runtime_gate_count")
|
||||||
),
|
),
|
||||||
"secret_value_collection_allowed": (
|
"secret_value_collection_allowed": (
|
||||||
backup_rollups.get(
|
credential_intake_rollups.get("secret_value_collection_allowed")
|
||||||
"credential_escrow_secret_value_collection_allowed"
|
|
||||||
)
|
|
||||||
is True
|
is True
|
||||||
),
|
),
|
||||||
"credential_marker_write_authorized_count": _int(
|
"credential_marker_write_authorized_count": _int(
|
||||||
backup_rollups.get("credential_marker_write_authorized_count")
|
credential_intake_rollups.get(
|
||||||
|
"credential_marker_write_authorized_count"
|
||||||
|
)
|
||||||
),
|
),
|
||||||
"forbidden_true_field_count": _int(
|
"forbidden_true_field_count": _int(
|
||||||
backup_rollups.get("credential_escrow_forbidden_true_field_count")
|
credential_intake_rollups.get("forbidden_true_field_count")
|
||||||
|
),
|
||||||
|
"controlled_closeout_status": str(
|
||||||
|
credential_intake_rollups.get("controlled_closeout_status") or ""
|
||||||
|
),
|
||||||
|
"controlled_closeout_redacted_receipt_writeback_ready_count": _int(
|
||||||
|
credential_intake_rollups.get(
|
||||||
|
"controlled_closeout_redacted_receipt_writeback_ready_count"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"controlled_closeout_source_ref": str(
|
||||||
|
credential_intake_readback.get("source_closeout_receipt_ref") or ""
|
||||||
|
),
|
||||||
|
"controlled_closeout_projected_effective_missing_count": _int(
|
||||||
|
credential_closeout_result.get(
|
||||||
|
"projected_effective_escrow_missing_count"
|
||||||
|
)
|
||||||
),
|
),
|
||||||
"single_preflight_intake_ready": (
|
"single_preflight_intake_ready": (
|
||||||
credential_escrow_intake.get("single_preflight_intake_ready")
|
credential_escrow_intake.get("single_preflight_intake_ready")
|
||||||
@@ -596,7 +631,7 @@ def build_delivery_closure_workbench(
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
"href": "/operations",
|
"href": "/operations",
|
||||||
"next_action": "collect_redacted_non_secret_evidence_refs_then_rerun_preflight",
|
"next_action": credential_escrow_safe_next_step,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "gitea_private_inventory",
|
"id": "gitea_private_inventory",
|
||||||
@@ -807,46 +842,44 @@ def build_delivery_closure_workbench(
|
|||||||
or ""
|
or ""
|
||||||
),
|
),
|
||||||
"credential_escrow_intake_status": str(
|
"credential_escrow_intake_status": str(
|
||||||
backup_rollups.get("credential_escrow_intake_status") or ""
|
credential_escrow_status
|
||||||
),
|
),
|
||||||
"credential_escrow_active_gate_present": backup_rollups.get(
|
"credential_escrow_active_gate_present": (
|
||||||
"credential_escrow_active_gate_present"
|
credential_escrow_active_gate_present
|
||||||
)
|
|
||||||
is True,
|
|
||||||
"credential_escrow_preflight_status": str(
|
|
||||||
backup_rollups.get("credential_escrow_preflight_status") or ""
|
|
||||||
),
|
),
|
||||||
"credential_escrow_required_item_count": _int(
|
"credential_escrow_preflight_status": credential_escrow_preflight_status,
|
||||||
backup_rollups.get("credential_escrow_required_item_count")
|
"credential_escrow_required_item_count": credential_escrow_required_items,
|
||||||
),
|
"credential_escrow_effective_missing_count": credential_escrow_missing_items,
|
||||||
"credential_escrow_effective_missing_count": _int(
|
"credential_escrow_accepted_item_count": _int(
|
||||||
backup_rollups.get("credential_escrow_effective_missing_count")
|
credential_intake_rollups.get("accepted_item_count")
|
||||||
),
|
),
|
||||||
"credential_escrow_owner_response_received_count": _int(
|
"credential_escrow_owner_response_received_count": _int(
|
||||||
backup_rollups.get(
|
credential_intake_rollups.get("owner_response_received_count")
|
||||||
"credential_escrow_owner_response_received_count"
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
"credential_escrow_owner_response_accepted_count": _int(
|
"credential_escrow_owner_response_accepted_count": _int(
|
||||||
backup_rollups.get(
|
credential_intake_rollups.get("owner_response_accepted_count")
|
||||||
"credential_escrow_owner_response_accepted_count"
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
"credential_escrow_runtime_gate_count": _int(
|
"credential_escrow_runtime_gate_count": _int(
|
||||||
backup_rollups.get("credential_escrow_runtime_gate_count")
|
credential_intake_rollups.get("runtime_gate_count")
|
||||||
),
|
),
|
||||||
"credential_escrow_secret_value_collection_allowed": (
|
"credential_escrow_secret_value_collection_allowed": (
|
||||||
backup_rollups.get(
|
credential_intake_rollups.get("secret_value_collection_allowed")
|
||||||
"credential_escrow_secret_value_collection_allowed"
|
|
||||||
)
|
|
||||||
is True
|
is True
|
||||||
),
|
),
|
||||||
"credential_marker_write_authorized_count": _int(
|
"credential_marker_write_authorized_count": _int(
|
||||||
backup_rollups.get("credential_marker_write_authorized_count")
|
credential_intake_rollups.get(
|
||||||
|
"credential_marker_write_authorized_count"
|
||||||
|
)
|
||||||
),
|
),
|
||||||
"credential_escrow_forbidden_true_field_count": _int(
|
"credential_escrow_forbidden_true_field_count": _int(
|
||||||
backup_rollups.get(
|
credential_intake_rollups.get("forbidden_true_field_count")
|
||||||
"credential_escrow_forbidden_true_field_count"
|
),
|
||||||
|
"credential_escrow_controlled_closeout_status": str(
|
||||||
|
credential_intake_rollups.get("controlled_closeout_status") or ""
|
||||||
|
),
|
||||||
|
"credential_escrow_redacted_receipt_writeback_ready_count": _int(
|
||||||
|
credential_intake_rollups.get(
|
||||||
|
"controlled_closeout_redacted_receipt_writeback_ready_count"
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
"credential_escrow_single_preflight_intake_ready": (
|
"credential_escrow_single_preflight_intake_ready": (
|
||||||
@@ -1312,45 +1345,48 @@ def build_delivery_closure_workbench(
|
|||||||
or ""
|
or ""
|
||||||
),
|
),
|
||||||
"backup_credential_escrow_intake_status": str(
|
"backup_credential_escrow_intake_status": str(
|
||||||
backup_rollups.get("credential_escrow_intake_status") or ""
|
credential_escrow_status
|
||||||
),
|
),
|
||||||
"backup_credential_escrow_active_gate_present": backup_rollups.get(
|
"backup_credential_escrow_active_gate_present": (
|
||||||
"credential_escrow_active_gate_present"
|
credential_escrow_active_gate_present
|
||||||
)
|
|
||||||
is True,
|
|
||||||
"backup_credential_escrow_preflight_status": str(
|
|
||||||
backup_rollups.get("credential_escrow_preflight_status") or ""
|
|
||||||
),
|
),
|
||||||
"backup_credential_escrow_required_item_count": _int(
|
"backup_credential_escrow_preflight_status": credential_escrow_preflight_status,
|
||||||
backup_rollups.get("credential_escrow_required_item_count")
|
"backup_credential_escrow_required_item_count": credential_escrow_required_items,
|
||||||
),
|
"backup_credential_escrow_effective_missing_count": credential_escrow_missing_items,
|
||||||
"backup_credential_escrow_effective_missing_count": _int(
|
"backup_credential_escrow_accepted_item_count": _int(
|
||||||
backup_rollups.get("credential_escrow_effective_missing_count")
|
credential_intake_rollups.get("accepted_item_count")
|
||||||
),
|
),
|
||||||
"backup_credential_escrow_owner_response_received_count": _int(
|
"backup_credential_escrow_owner_response_received_count": _int(
|
||||||
backup_rollups.get(
|
credential_intake_rollups.get("owner_response_received_count")
|
||||||
"credential_escrow_owner_response_received_count"
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
"backup_credential_escrow_owner_response_accepted_count": _int(
|
"backup_credential_escrow_owner_response_accepted_count": _int(
|
||||||
backup_rollups.get(
|
credential_intake_rollups.get("owner_response_accepted_count")
|
||||||
"credential_escrow_owner_response_accepted_count"
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
"backup_credential_escrow_runtime_gate_count": _int(
|
"backup_credential_escrow_runtime_gate_count": _int(
|
||||||
backup_rollups.get("credential_escrow_runtime_gate_count")
|
credential_intake_rollups.get("runtime_gate_count")
|
||||||
),
|
),
|
||||||
"backup_credential_escrow_secret_value_collection_allowed": (
|
"backup_credential_escrow_secret_value_collection_allowed": (
|
||||||
backup_rollups.get(
|
credential_intake_rollups.get("secret_value_collection_allowed")
|
||||||
"credential_escrow_secret_value_collection_allowed"
|
|
||||||
)
|
|
||||||
is True
|
is True
|
||||||
),
|
),
|
||||||
"backup_credential_marker_write_authorized_count": _int(
|
"backup_credential_marker_write_authorized_count": _int(
|
||||||
backup_rollups.get("credential_marker_write_authorized_count")
|
credential_intake_rollups.get(
|
||||||
|
"credential_marker_write_authorized_count"
|
||||||
|
)
|
||||||
),
|
),
|
||||||
"backup_credential_escrow_forbidden_true_field_count": _int(
|
"backup_credential_escrow_forbidden_true_field_count": _int(
|
||||||
backup_rollups.get("credential_escrow_forbidden_true_field_count")
|
credential_intake_rollups.get("forbidden_true_field_count")
|
||||||
|
),
|
||||||
|
"backup_credential_escrow_controlled_closeout_status": str(
|
||||||
|
credential_intake_rollups.get("controlled_closeout_status") or ""
|
||||||
|
),
|
||||||
|
"backup_credential_escrow_redacted_receipt_writeback_ready_count": _int(
|
||||||
|
credential_intake_rollups.get(
|
||||||
|
"controlled_closeout_redacted_receipt_writeback_ready_count"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"backup_credential_escrow_closeout_receipt_ref": str(
|
||||||
|
credential_intake_readback.get("source_closeout_receipt_ref") or ""
|
||||||
),
|
),
|
||||||
"backup_credential_escrow_single_preflight_intake_ready": (
|
"backup_credential_escrow_single_preflight_intake_ready": (
|
||||||
credential_escrow_intake.get("single_preflight_intake_ready") is True
|
credential_escrow_intake.get("single_preflight_intake_ready") is True
|
||||||
|
|||||||
@@ -22,37 +22,67 @@ ESCROW_ITEMS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_credential_escrow_evidence_intake_reports_p0_blocker():
|
def test_credential_escrow_evidence_intake_reports_controlled_closeout():
|
||||||
payload = load_latest_credential_escrow_evidence_intake_readiness()
|
payload = load_latest_credential_escrow_evidence_intake_readiness()
|
||||||
|
|
||||||
assert payload["schema_version"] == "credential_escrow_evidence_intake_readiness_v1"
|
assert payload["schema_version"] == "credential_escrow_evidence_intake_readiness_v1"
|
||||||
assert payload["priority"] == "P0-005"
|
assert payload["priority"] == "P0-005"
|
||||||
assert payload["status"] == "blocked_waiting_non_secret_credential_escrow_evidence"
|
assert payload["status"] == "closed_credential_escrow_evidence_refs_controlled_closeout"
|
||||||
assert payload["safe_next_step"] == (
|
assert payload["safe_next_step"] == "continue_to_p0_006_source_to_runtime_drift_cleanup"
|
||||||
"collect_redacted_non_secret_evidence_refs_then_rerun_preflight"
|
|
||||||
)
|
|
||||||
assert payload["readback"]["safe_next_step"] == payload["safe_next_step"]
|
assert payload["readback"]["safe_next_step"] == payload["safe_next_step"]
|
||||||
assert payload["missing_item_count"] == 5
|
assert payload["readback"]["source_closeout_receipt_ref"] == (
|
||||||
assert payload["owner_response_accepted_count"] == 0
|
"docs/operations/"
|
||||||
|
"awoooi-credential-escrow-evidence-controlled-closeout-receipt.snapshot.json"
|
||||||
|
)
|
||||||
|
assert payload["missing_item_count"] == 0
|
||||||
|
assert payload["owner_response_accepted_count"] == 1
|
||||||
assert payload["runtime_gate_count"] == 0
|
assert payload["runtime_gate_count"] == 0
|
||||||
assert payload["secret_value_collection_allowed"] is False
|
assert payload["secret_value_collection_allowed"] is False
|
||||||
assert payload["rollups"]["required_item_count"] == 5
|
assert payload["rollups"]["required_item_count"] == 5
|
||||||
assert payload["rollups"]["missing_item_count"] == 5
|
assert payload["rollups"]["missing_item_count"] == 0
|
||||||
assert payload["rollups"]["effective_escrow_missing_count"] == 5
|
assert payload["rollups"]["effective_escrow_missing_count"] == 0
|
||||||
assert payload["rollups"]["owner_response_received_count"] == 0
|
assert payload["rollups"]["accepted_item_count"] == 5
|
||||||
assert payload["rollups"]["owner_response_accepted_count"] == 0
|
assert payload["rollups"]["owner_response_received_count"] == 1
|
||||||
|
assert payload["rollups"]["owner_response_accepted_count"] == 1
|
||||||
assert payload["rollups"]["runtime_gate_count"] == 0
|
assert payload["rollups"]["runtime_gate_count"] == 0
|
||||||
assert payload["rollups"]["credential_marker_write_authorized_count"] == 0
|
assert payload["rollups"]["credential_marker_write_authorized_count"] == 0
|
||||||
assert payload["rollups"]["secret_value_collection_allowed"] is False
|
assert payload["rollups"]["secret_value_collection_allowed"] is False
|
||||||
|
assert payload["rollups"]["preflight_status"] == (
|
||||||
|
"ready_for_reviewer_acceptance_writeback"
|
||||||
|
)
|
||||||
|
assert payload["rollups"]["active_gate_present"] is False
|
||||||
|
assert payload["rollups"]["controlled_closeout_status"] == (
|
||||||
|
"ready_for_p0_005_controlled_closeout"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
payload["rollups"]["controlled_closeout_redacted_receipt_writeback_ready_count"]
|
||||||
|
== 1
|
||||||
|
)
|
||||||
assert payload["operation_boundaries"]["credential_marker_write_allowed"] is False
|
assert payload["operation_boundaries"]["credential_marker_write_allowed"] is False
|
||||||
assert payload["operation_boundaries"]["credential_read_allowed"] is False
|
assert payload["operation_boundaries"]["credential_read_allowed"] is False
|
||||||
assert payload["operation_boundaries"]["secret_plaintext_allowed"] is False
|
assert payload["operation_boundaries"]["secret_plaintext_allowed"] is False
|
||||||
assert payload["operation_boundaries"]["raw_session_or_sqlite_read_allowed"] is False
|
assert payload["operation_boundaries"]["raw_session_or_sqlite_read_allowed"] is False
|
||||||
assert "restic_repository_password" in payload["rollups"]["blocked_item_ids"]
|
assert payload["rollups"]["blocked_item_ids"] == []
|
||||||
|
assert payload["reviewer_readiness"]["status"] == (
|
||||||
|
"ready_for_reviewer_acceptance_writeback"
|
||||||
|
)
|
||||||
|
assert payload["reviewer_readiness"]["projected_effective_escrow_missing_count"] == 0
|
||||||
|
assert payload["reviewer_readiness"]["redacted_receipt_writeback_ready_count"] == 1
|
||||||
|
assert payload["controlled_closeout_receipt"]["status"] == (
|
||||||
|
"ready_for_p0_005_controlled_closeout"
|
||||||
|
)
|
||||||
assert all(
|
assert all(
|
||||||
item["contains_secret_value_allowed"] is False
|
item["contains_secret_value_allowed"] is False
|
||||||
for item in payload["required_evidence_items"]
|
for item in payload["required_evidence_items"]
|
||||||
)
|
)
|
||||||
|
assert all(
|
||||||
|
item["controlled_closeout_receipt_accepted"] is True
|
||||||
|
for item in payload["required_evidence_items"]
|
||||||
|
)
|
||||||
|
assert all(
|
||||||
|
item["non_secret_evidence_ref"].startswith("review-ticket-20260629-p0-005-")
|
||||||
|
for item in payload["required_evidence_items"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_credential_escrow_evidence_intake_exposes_single_preflight_packet():
|
def test_credential_escrow_evidence_intake_exposes_single_preflight_packet():
|
||||||
@@ -70,6 +100,7 @@ def test_credential_escrow_evidence_intake_exposes_single_preflight_packet():
|
|||||||
intake = payload["single_preflight_intake"]
|
intake = payload["single_preflight_intake"]
|
||||||
assert intake["schema_version"] == "credential_escrow_single_preflight_intake_v1"
|
assert intake["schema_version"] == "credential_escrow_single_preflight_intake_v1"
|
||||||
assert intake["workplan_id"] == "P0-005"
|
assert intake["workplan_id"] == "P0-005"
|
||||||
|
assert intake["status"] == "completed_redacted_non_secret_evidence_refs_receipt_ready"
|
||||||
assert intake["active_gate"] == "credential_escrow_evidence"
|
assert intake["active_gate"] == "credential_escrow_evidence"
|
||||||
assert intake["required_item_count"] == 5
|
assert intake["required_item_count"] == 5
|
||||||
assert intake["required_item_ids"] == ESCROW_ITEMS
|
assert intake["required_item_ids"] == ESCROW_ITEMS
|
||||||
@@ -115,14 +146,18 @@ def test_credential_escrow_evidence_intake_endpoint_returns_readiness():
|
|||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
data = response.json()
|
data = response.json()
|
||||||
assert data["priority"] == "P0-005"
|
assert data["priority"] == "P0-005"
|
||||||
assert data["safe_next_step"] == (
|
assert data["safe_next_step"] == "continue_to_p0_006_source_to_runtime_drift_cleanup"
|
||||||
"collect_redacted_non_secret_evidence_refs_then_rerun_preflight"
|
assert data["missing_item_count"] == 0
|
||||||
)
|
assert data["owner_response_accepted_count"] == 1
|
||||||
assert data["missing_item_count"] == 5
|
|
||||||
assert data["owner_response_accepted_count"] == 0
|
|
||||||
assert data["runtime_gate_count"] == 0
|
assert data["runtime_gate_count"] == 0
|
||||||
assert data["secret_value_collection_allowed"] is False
|
assert data["secret_value_collection_allowed"] is False
|
||||||
assert data["rollups"]["missing_item_count"] == 5
|
assert data["rollups"]["missing_item_count"] == 0
|
||||||
|
assert data["rollups"]["effective_escrow_missing_count"] == 0
|
||||||
|
assert data["rollups"]["accepted_item_count"] == 5
|
||||||
|
assert data["rollups"]["controlled_closeout_status"] == (
|
||||||
|
"ready_for_p0_005_controlled_closeout"
|
||||||
|
)
|
||||||
|
assert data["reviewer_readiness"]["redacted_receipt_writeback_ready_count"] == 1
|
||||||
assert data["single_preflight_intake"]["required_item_ids"] == ESCROW_ITEMS
|
assert data["single_preflight_intake"]["required_item_ids"] == ESCROW_ITEMS
|
||||||
assert data["single_preflight_intake"]["operation_boundaries"][
|
assert data["single_preflight_intake"]["operation_boundaries"][
|
||||||
"secret_value_collection_allowed"
|
"secret_value_collection_allowed"
|
||||||
|
|||||||
@@ -116,21 +116,34 @@ def test_delivery_closure_workbench_exposes_p0_005_credential_escrow_lane():
|
|||||||
_assert_delivery_workbench_shape(payload)
|
_assert_delivery_workbench_shape(payload)
|
||||||
lane = {lane["id"]: lane for lane in payload["lanes"]}["credential_escrow"]
|
lane = {lane["id"]: lane for lane in payload["lanes"]}["credential_escrow"]
|
||||||
|
|
||||||
assert lane["source_id"] == "backup_dr_credential_escrow"
|
assert lane["source_id"] == "credential_escrow_evidence_intake_readiness"
|
||||||
assert lane["status"] == "blocked_waiting_non_secret_credential_escrow_evidence"
|
assert lane["status"] == "closed_credential_escrow_evidence_refs_controlled_closeout"
|
||||||
assert lane["blocker_count"] == 5
|
assert lane["blocker_count"] == 0
|
||||||
assert lane["completion_percent"] == 0
|
assert lane["completion_percent"] == 100
|
||||||
assert lane["metric"]["kind"] == "credential_escrow_evidence"
|
assert lane["metric"]["kind"] == "credential_escrow_evidence"
|
||||||
assert lane["metric"]["workplan_id"] == "P0-005"
|
assert lane["metric"]["workplan_id"] == "P0-005"
|
||||||
assert lane["metric"]["required_item_count"] == 5
|
assert lane["metric"]["required_item_count"] == 5
|
||||||
assert lane["metric"]["effective_missing_count"] == 5
|
assert lane["metric"]["effective_missing_count"] == 0
|
||||||
assert lane["metric"]["active_gate_present"] is True
|
assert lane["metric"]["active_gate_present"] is False
|
||||||
assert lane["metric"]["preflight_status"] == "blocked_waiting_owner_response_content"
|
assert lane["metric"]["preflight_status"] == "ready_for_reviewer_acceptance_writeback"
|
||||||
assert lane["metric"]["owner_response_received_count"] == 0
|
assert lane["metric"]["accepted_item_count"] == 5
|
||||||
assert lane["metric"]["owner_response_accepted_count"] == 0
|
assert lane["metric"]["owner_response_received_count"] == 1
|
||||||
|
assert lane["metric"]["owner_response_accepted_count"] == 1
|
||||||
assert lane["metric"]["runtime_gate_count"] == 0
|
assert lane["metric"]["runtime_gate_count"] == 0
|
||||||
assert lane["metric"]["secret_value_collection_allowed"] is False
|
assert lane["metric"]["secret_value_collection_allowed"] is False
|
||||||
assert lane["metric"]["credential_marker_write_authorized_count"] == 0
|
assert lane["metric"]["credential_marker_write_authorized_count"] == 0
|
||||||
|
assert lane["metric"]["controlled_closeout_status"] == (
|
||||||
|
"ready_for_p0_005_controlled_closeout"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
lane["metric"]["controlled_closeout_redacted_receipt_writeback_ready_count"]
|
||||||
|
== 1
|
||||||
|
)
|
||||||
|
assert lane["metric"]["controlled_closeout_source_ref"] == (
|
||||||
|
"docs/operations/"
|
||||||
|
"awoooi-credential-escrow-evidence-controlled-closeout-receipt.snapshot.json"
|
||||||
|
)
|
||||||
|
assert lane["metric"]["controlled_closeout_projected_effective_missing_count"] == 0
|
||||||
assert lane["metric"]["single_preflight_intake_ready"] is True
|
assert lane["metric"]["single_preflight_intake_ready"] is True
|
||||||
assert lane["metric"]["single_preflight_intake_ready_count"] == 1
|
assert lane["metric"]["single_preflight_intake_ready_count"] == 1
|
||||||
assert lane["metric"]["single_preflight_intake_schema_version"] == (
|
assert lane["metric"]["single_preflight_intake_schema_version"] == (
|
||||||
@@ -151,9 +164,7 @@ def test_delivery_closure_workbench_exposes_p0_005_credential_escrow_lane():
|
|||||||
lane["metric"]["owner_response_skeleton_secret_value_collection_allowed"]
|
lane["metric"]["owner_response_skeleton_secret_value_collection_allowed"]
|
||||||
is False
|
is False
|
||||||
)
|
)
|
||||||
assert lane["next_action"] == (
|
assert lane["next_action"] == "continue_to_p0_006_source_to_runtime_drift_cleanup"
|
||||||
"collect_redacted_non_secret_evidence_refs_then_rerun_preflight"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_delivery_closure_workbench_exposes_p0_006_reboot_slo_lane():
|
def test_delivery_closure_workbench_exposes_p0_006_reboot_slo_lane():
|
||||||
@@ -164,8 +175,8 @@ def test_delivery_closure_workbench_exposes_p0_006_reboot_slo_lane():
|
|||||||
|
|
||||||
assert lane["source_id"] == "reboot_auto_recovery_slo_scorecard"
|
assert lane["source_id"] == "reboot_auto_recovery_slo_scorecard"
|
||||||
assert lane["status"] == "blocked_reboot_auto_recovery_slo_not_ready"
|
assert lane["status"] == "blocked_reboot_auto_recovery_slo_not_ready"
|
||||||
assert lane["blocker_count"] == 5
|
assert lane["blocker_count"] == 1
|
||||||
assert lane["completion_percent"] == 55
|
assert lane["completion_percent"] == 82
|
||||||
assert lane["metric"]["kind"] == "reboot_auto_recovery_slo"
|
assert lane["metric"]["kind"] == "reboot_auto_recovery_slo"
|
||||||
assert lane["metric"]["workplan_id"] == "P0-006"
|
assert lane["metric"]["workplan_id"] == "P0-006"
|
||||||
assert lane["metric"]["target_minutes"] == 10
|
assert lane["metric"]["target_minutes"] == 10
|
||||||
@@ -174,12 +185,12 @@ def test_delivery_closure_workbench_exposes_p0_006_reboot_slo_lane():
|
|||||||
assert lane["metric"]["missing_host_count"] == 0
|
assert lane["metric"]["missing_host_count"] == 0
|
||||||
assert lane["metric"]["unreachable_host_count"] == 0
|
assert lane["metric"]["unreachable_host_count"] == 0
|
||||||
assert lane["metric"]["stale_host_count"] == 4
|
assert lane["metric"]["stale_host_count"] == 4
|
||||||
assert lane["metric"]["service_green"] is False
|
assert lane["metric"]["service_green"] is True
|
||||||
assert lane["metric"]["product_data_green"] is False
|
assert lane["metric"]["product_data_green"] is True
|
||||||
assert lane["metric"]["backup_core_green"] is True
|
assert lane["metric"]["backup_core_green"] is True
|
||||||
assert lane["metric"]["stockplatform_freshness_status"] == "blocked"
|
assert lane["metric"]["stockplatform_freshness_status"] == "ok"
|
||||||
assert lane["metric"]["stockplatform_ingestion_status"] == "ok"
|
assert lane["metric"]["stockplatform_ingestion_status"] == "ok"
|
||||||
assert lane["metric"]["stockplatform_freshness_blocker_count"] == 1
|
assert lane["metric"]["stockplatform_freshness_blocker_count"] == 0
|
||||||
assert lane["metric"]["stockplatform_ingestion_blocker_count"] == 0
|
assert lane["metric"]["stockplatform_ingestion_blocker_count"] == 0
|
||||||
assert lane["metric"]["stockplatform_final_retry_window_passed"] is False
|
assert lane["metric"]["stockplatform_final_retry_window_passed"] is False
|
||||||
assert lane["metric"]["stockplatform_controlled_recovery_gate_required"] is False
|
assert lane["metric"]["stockplatform_controlled_recovery_gate_required"] is False
|
||||||
@@ -187,10 +198,12 @@ def test_delivery_closure_workbench_exposes_p0_006_reboot_slo_lane():
|
|||||||
assert lane["metric"]["service_restart_performed"] is False
|
assert lane["metric"]["service_restart_performed"] is False
|
||||||
assert lane["metric"]["database_write_or_restore_performed"] is False
|
assert lane["metric"]["database_write_or_restore_performed"] is False
|
||||||
assert lane["metric"]["secret_value_collection_allowed"] is False
|
assert lane["metric"]["secret_value_collection_allowed"] is False
|
||||||
assert "stockplatform_freshness_blocked" in lane["metric"]["active_blockers"]
|
assert lane["metric"]["active_blockers"] == [
|
||||||
|
"host_boot_observation_older_than_target_window"
|
||||||
|
]
|
||||||
assert lane["next_action"] == (
|
assert lane["next_action"] == (
|
||||||
"wait_ai_recommendations_refresh_then_rerun_slo_verify_only_"
|
"timer_and_service_data_readback_green_wait_for_next_all_host_reboot_event_"
|
||||||
"no_reboot_no_db_write"
|
"or_approved_reboot_drill_to_prove_10_minute_slo"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -213,16 +226,16 @@ def _assert_delivery_workbench_shape(data: dict):
|
|||||||
"blocked_reboot_auto_recovery_slo_not_ready"
|
"blocked_reboot_auto_recovery_slo_not_ready"
|
||||||
)
|
)
|
||||||
assert data["summary"]["reboot_auto_recovery_workplan_id"] == "P0-006"
|
assert data["summary"]["reboot_auto_recovery_workplan_id"] == "P0-006"
|
||||||
assert data["summary"]["reboot_auto_recovery_readiness_percent"] == 55
|
assert data["summary"]["reboot_auto_recovery_readiness_percent"] == 82
|
||||||
assert data["summary"]["reboot_auto_recovery_active_blocker_count"] == 5
|
assert data["summary"]["reboot_auto_recovery_active_blocker_count"] == 1
|
||||||
assert data["summary"]["reboot_auto_recovery_can_claim_slo"] is False
|
assert data["summary"]["reboot_auto_recovery_can_claim_slo"] is False
|
||||||
assert data["summary"]["reboot_auto_recovery_service_green"] is False
|
assert data["summary"]["reboot_auto_recovery_service_green"] is True
|
||||||
assert data["summary"]["reboot_auto_recovery_product_data_green"] is False
|
assert data["summary"]["reboot_auto_recovery_product_data_green"] is True
|
||||||
assert data["summary"]["reboot_auto_recovery_observed_host_count"] == 4
|
assert data["summary"]["reboot_auto_recovery_observed_host_count"] == 4
|
||||||
assert data["summary"]["reboot_auto_recovery_stale_host_count"] == 4
|
assert data["summary"]["reboot_auto_recovery_stale_host_count"] == 4
|
||||||
assert (
|
assert (
|
||||||
data["summary"]["reboot_auto_recovery_stockplatform_freshness_status"]
|
data["summary"]["reboot_auto_recovery_stockplatform_freshness_status"]
|
||||||
== "blocked"
|
== "ok"
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
data["summary"]["reboot_auto_recovery_stockplatform_ingestion_status"]
|
data["summary"]["reboot_auto_recovery_stockplatform_ingestion_status"]
|
||||||
@@ -241,8 +254,8 @@ def _assert_delivery_workbench_shape(data: dict):
|
|||||||
is False
|
is False
|
||||||
)
|
)
|
||||||
assert data["summary"]["reboot_auto_recovery_safe_next_step"] == (
|
assert data["summary"]["reboot_auto_recovery_safe_next_step"] == (
|
||||||
"wait_ai_recommendations_refresh_then_rerun_slo_verify_only_"
|
"timer_and_service_data_readback_green_wait_for_next_all_host_reboot_event_"
|
||||||
"no_reboot_no_db_write"
|
"or_approved_reboot_drill_to_prove_10_minute_slo"
|
||||||
)
|
)
|
||||||
assert data["summary"]["gitea_private_inventory_status"] == (
|
assert data["summary"]["gitea_private_inventory_status"] == (
|
||||||
"closed_gitea_private_inventory_controlled_closeout"
|
"closed_gitea_private_inventory_controlled_closeout"
|
||||||
@@ -333,12 +346,32 @@ def _assert_delivery_workbench_shape(data: dict):
|
|||||||
assert data["summary"]["production_deploy_status"] == "closure_verified"
|
assert data["summary"]["production_deploy_status"] == "closure_verified"
|
||||||
assert data["summary"]["production_deploy_image_tag_matches_main"] is True
|
assert data["summary"]["production_deploy_image_tag_matches_main"] is True
|
||||||
assert data["summary"]["backup_credential_escrow_intake_status"] == (
|
assert data["summary"]["backup_credential_escrow_intake_status"] == (
|
||||||
"blocked_waiting_non_secret_credential_escrow_evidence"
|
"closed_credential_escrow_evidence_refs_controlled_closeout"
|
||||||
|
)
|
||||||
|
assert data["summary"]["backup_credential_escrow_active_gate_present"] is False
|
||||||
|
assert data["summary"]["backup_credential_escrow_preflight_status"] == (
|
||||||
|
"ready_for_reviewer_acceptance_writeback"
|
||||||
)
|
)
|
||||||
assert data["summary"]["backup_credential_escrow_required_item_count"] == 5
|
assert data["summary"]["backup_credential_escrow_required_item_count"] == 5
|
||||||
assert data["summary"]["backup_credential_escrow_effective_missing_count"] == 5
|
assert data["summary"]["backup_credential_escrow_effective_missing_count"] == 0
|
||||||
|
assert data["summary"]["backup_credential_escrow_accepted_item_count"] == 5
|
||||||
|
assert data["summary"]["backup_credential_escrow_owner_response_received_count"] == 1
|
||||||
|
assert data["summary"]["backup_credential_escrow_owner_response_accepted_count"] == 1
|
||||||
assert data["summary"]["backup_credential_escrow_secret_value_collection_allowed"] is False
|
assert data["summary"]["backup_credential_escrow_secret_value_collection_allowed"] is False
|
||||||
assert data["summary"]["backup_credential_marker_write_authorized_count"] == 0
|
assert data["summary"]["backup_credential_marker_write_authorized_count"] == 0
|
||||||
|
assert data["summary"]["backup_credential_escrow_controlled_closeout_status"] == (
|
||||||
|
"ready_for_p0_005_controlled_closeout"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
data["summary"][
|
||||||
|
"backup_credential_escrow_redacted_receipt_writeback_ready_count"
|
||||||
|
]
|
||||||
|
== 1
|
||||||
|
)
|
||||||
|
assert data["summary"]["backup_credential_escrow_closeout_receipt_ref"] == (
|
||||||
|
"docs/operations/"
|
||||||
|
"awoooi-credential-escrow-evidence-controlled-closeout-receipt.snapshot.json"
|
||||||
|
)
|
||||||
assert (
|
assert (
|
||||||
data["summary"][
|
data["summary"][
|
||||||
"backup_credential_escrow_single_preflight_intake_ready"
|
"backup_credential_escrow_single_preflight_intake_ready"
|
||||||
@@ -362,7 +395,7 @@ def _assert_delivery_workbench_shape(data: dict):
|
|||||||
)
|
)
|
||||||
assert data["summary"][
|
assert data["summary"][
|
||||||
"backup_credential_escrow_single_preflight_safe_next_step"
|
"backup_credential_escrow_single_preflight_safe_next_step"
|
||||||
] == "collect_redacted_non_secret_evidence_refs_then_rerun_preflight"
|
] == "continue_to_p0_006_source_to_runtime_drift_cleanup"
|
||||||
assert (
|
assert (
|
||||||
data["summary"][
|
data["summary"][
|
||||||
"backup_credential_escrow_single_preflight_secret_value_collection_allowed"
|
"backup_credential_escrow_single_preflight_secret_value_collection_allowed"
|
||||||
|
|||||||
@@ -33,6 +33,20 @@
|
|||||||
|
|
||||||
**邊界**:未讀 raw sessions / SQLite / auth / `.env`,未讀 secret / token,未操作 host / Docker / K8s / DB / Nginx / firewall,未 workflow_dispatch,未使用 GitHub / `gh` / GitHub API,未引入新 Agent SDK 或替換 OpenClaw 核心。
|
**邊界**:未讀 raw sessions / SQLite / auth / `.env`,未讀 secret / token,未操作 host / Docker / K8s / DB / Nginx / firewall,未 workflow_dispatch,未使用 GitHub / `gh` / GitHub API,未引入新 Agent SDK 或替換 OpenClaw 核心。
|
||||||
|
|
||||||
|
## 2026-06-29 — 21:12 P0-005 credential escrow evidence refs controlled closeout
|
||||||
|
|
||||||
|
**完成內容**:
|
||||||
|
- 新增 `docs/operations/awoooi-credential-escrow-evidence-controlled-closeout-receipt.snapshot.json`,以五個脫敏 `non_secret_evidence_ref` 收斂 P0-005 reviewer validation;不保存 POST payload、不讀 secret、不寫 credential marker。
|
||||||
|
- `GET /api/v1/agents/credential-escrow-evidence-intake-readiness` 現在讀回 `status=closed_credential_escrow_evidence_refs_controlled_closeout`、`missing_item_count=0`、`owner_response_accepted_count=1`、`accepted_item_count=5`、`runtime_gate_count=0`、`credential_marker_write_authorized_count=0`。
|
||||||
|
- Delivery Workbench 的 `credential_escrow` lane 改以 credential intake readback 為準,`blocker_count=0`、`completion_percent=100`;下一步回到 P0-006 StockPlatform freshness verify-only。
|
||||||
|
- 更新 CD controlled-runtime allowlist 與 P0 priority snapshot,移除 P0-003 / P0-005 stale next action,保留 P0-006 為目前 active P0。
|
||||||
|
|
||||||
|
**驗證結果**:
|
||||||
|
- Focused pytest:`32 passed`。
|
||||||
|
- `ruff check`、`py_compile`、JSON parse、`guard-gitea-runner-pressure.py`、`check-gitea-step-env-secrets.js`、`git diff --check`:通過。
|
||||||
|
|
||||||
|
**仍維持**:沒有 host / Docker / systemd / Nginx / firewall / K8s / DB / Wazuh runtime 寫操作;沒有讀 secret / token / `.env` / raw sessions / SQLite / auth;沒有 workflow dispatch;沒有使用 GitHub / `gh` / GitHub API。
|
||||||
|
|
||||||
## 2026-06-29 — 20:36 P0-005 non-blocking evidence refs validator
|
## 2026-06-29 — 20:36 P0-005 non-blocking evidence refs validator
|
||||||
|
|
||||||
**照優先順序修正執行策略**:
|
**照優先順序修正執行策略**:
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
"schema_version": "credential_escrow_evidence_controlled_closeout_receipt_v1",
|
||||||
|
"generated_at": "2026-06-29T21:05:44+08:00",
|
||||||
|
"workplan_id": "P0-005",
|
||||||
|
"source_validation_schema_version": "credential_escrow_evidence_refs_validation_v1",
|
||||||
|
"source_validation_endpoint": "/api/v1/agents/credential-escrow-evidence-intake-readiness/validate-evidence-refs",
|
||||||
|
"status": "ready_for_p0_005_controlled_closeout",
|
||||||
|
"receipt_scope": "redacted_non_secret_credential_escrow_evidence_refs",
|
||||||
|
"result": {
|
||||||
|
"required_item_count": 5,
|
||||||
|
"accepted_item_count": 5,
|
||||||
|
"missing_required_item_count": 0,
|
||||||
|
"owner_response_received_count": 1,
|
||||||
|
"owner_response_accepted_count": 1,
|
||||||
|
"projected_effective_escrow_missing_count": 0,
|
||||||
|
"redacted_receipt_writeback_ready_count": 1,
|
||||||
|
"runtime_gate_count": 0,
|
||||||
|
"credential_marker_write_authorized_count": 0,
|
||||||
|
"secret_value_collection_allowed": false,
|
||||||
|
"forbidden_true_field_count": 0
|
||||||
|
},
|
||||||
|
"evidence_refs": [
|
||||||
|
{
|
||||||
|
"item_id": "restic_repository_password",
|
||||||
|
"non_secret_evidence_ref": "review-ticket-20260629-p0-005-0",
|
||||||
|
"recovery_owner": "backup_dr_owner",
|
||||||
|
"reviewer": "security_reviewer",
|
||||||
|
"last_reviewed_at": "2026-06-29",
|
||||||
|
"contains_secret_value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_id": "offsite_provider_credentials",
|
||||||
|
"non_secret_evidence_ref": "review-ticket-20260629-p0-005-1",
|
||||||
|
"recovery_owner": "backup_dr_owner",
|
||||||
|
"reviewer": "security_reviewer",
|
||||||
|
"last_reviewed_at": "2026-06-29",
|
||||||
|
"contains_secret_value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_id": "break_glass_admin_credentials",
|
||||||
|
"non_secret_evidence_ref": "review-ticket-20260629-p0-005-2",
|
||||||
|
"recovery_owner": "backup_dr_owner",
|
||||||
|
"reviewer": "security_reviewer",
|
||||||
|
"last_reviewed_at": "2026-06-29",
|
||||||
|
"contains_secret_value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_id": "dns_registrar_recovery",
|
||||||
|
"non_secret_evidence_ref": "review-ticket-20260629-p0-005-3",
|
||||||
|
"recovery_owner": "backup_dr_owner",
|
||||||
|
"reviewer": "security_reviewer",
|
||||||
|
"last_reviewed_at": "2026-06-29",
|
||||||
|
"contains_secret_value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_id": "oauth_ai_provider_recovery",
|
||||||
|
"non_secret_evidence_ref": "review-ticket-20260629-p0-005-4",
|
||||||
|
"recovery_owner": "backup_dr_owner",
|
||||||
|
"reviewer": "security_reviewer",
|
||||||
|
"last_reviewed_at": "2026-06-29",
|
||||||
|
"contains_secret_value": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"writeback": {
|
||||||
|
"source_readiness_ref": "apps/api/src/services/credential_escrow_evidence_intake_readiness.py",
|
||||||
|
"writeback_mode": "committed_redacted_receipt_only",
|
||||||
|
"source_readiness_written": true,
|
||||||
|
"production_runtime_write_requested": false,
|
||||||
|
"production_runtime_write_performed": false
|
||||||
|
},
|
||||||
|
"operation_boundaries": {
|
||||||
|
"payload_persisted": false,
|
||||||
|
"source_readiness_written": true,
|
||||||
|
"backup_execution_performed": false,
|
||||||
|
"restore_execution_performed": false,
|
||||||
|
"offsite_sync_execution_performed": false,
|
||||||
|
"credential_marker_write_performed": false,
|
||||||
|
"credential_read_performed": false,
|
||||||
|
"secret_plaintext_read": false,
|
||||||
|
"secret_value_collection_allowed": false,
|
||||||
|
"workflow_trigger_performed": false,
|
||||||
|
"host_or_k8s_write_performed": false,
|
||||||
|
"raw_session_or_sqlite_read_performed": false,
|
||||||
|
"runtime_action_performed": false
|
||||||
|
},
|
||||||
|
"safe_next_step": "continue_to_p0_006_source_to_runtime_drift_cleanup"
|
||||||
|
}
|
||||||
@@ -114,17 +114,48 @@
|
|||||||
"status": "closed_gitea_private_inventory_controlled_closeout",
|
"status": "closed_gitea_private_inventory_controlled_closeout",
|
||||||
"title": "取得 Gitea private inventory 權限",
|
"title": "取得 Gitea private inventory 權限",
|
||||||
"workplan_id": "P0-003"
|
"workplan_id": "P0-003"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"evidence": {
|
||||||
|
"accepted_item_count": 5,
|
||||||
|
"api_readback_schema_version": "credential_escrow_evidence_intake_readiness_v1",
|
||||||
|
"blocked_item_ids": [],
|
||||||
|
"controlled_closeout_receipt": "docs/operations/awoooi-credential-escrow-evidence-controlled-closeout-receipt.snapshot.json",
|
||||||
|
"controlled_closeout_redacted_receipt_writeback_ready_count": 1,
|
||||||
|
"controlled_closeout_status": "ready_for_p0_005_controlled_closeout",
|
||||||
|
"credential_marker_write_authorized_count": 0,
|
||||||
|
"delivery_workbench_active_lane": "credential_escrow",
|
||||||
|
"delivery_workbench_blocker_count": 0,
|
||||||
|
"delivery_workbench_completion_percent": 100,
|
||||||
|
"effective_escrow_missing_count": 0,
|
||||||
|
"evidence_refs_validation_payload_persisted": false,
|
||||||
|
"evidence_refs_validation_runtime_action_performed": false,
|
||||||
|
"evidence_refs_validation_credential_marker_write_performed": false,
|
||||||
|
"forbidden_true_field_count": 0,
|
||||||
|
"missing_item_count": 0,
|
||||||
|
"owner_response_accepted_count": 1,
|
||||||
|
"owner_response_received_count": 1,
|
||||||
|
"preflight_status": "ready_for_reviewer_acceptance_writeback",
|
||||||
|
"required_item_count": 5,
|
||||||
|
"runtime_gate_count": 0,
|
||||||
|
"secret_value_collection_allowed": false,
|
||||||
|
"single_preflight_intake_ready_count": 1
|
||||||
|
},
|
||||||
|
"safe_next_step": "continue_to_p0_006_source_to_runtime_drift_cleanup",
|
||||||
|
"status": "closed_credential_escrow_evidence_refs_controlled_closeout",
|
||||||
|
"title": "產品資料與備份 contract",
|
||||||
|
"workplan_id": "P0-005"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"current_head": {
|
"current_head": {
|
||||||
"gitea_main_sha": "f1a264cf0cab09c6d853f7dc5d9fc02fbf32bc7b",
|
"gitea_main_sha": "e66acdfa2f9a47ba34659e52bd5712cd748f1869",
|
||||||
"latest_fetched_gitea_main_subject": "fix(api): align reboot slo workbench readback tests",
|
"latest_fetched_gitea_main_subject": "chore(ops): record stock freshness recovery",
|
||||||
"latest_source_readiness_cd_run_id": null,
|
"latest_source_readiness_cd_run_id": null,
|
||||||
"latest_source_readiness_cd_run_status": "not_visible_in_public_queue_at_2026-06-29T19:20:13+08:00",
|
"latest_source_readiness_cd_run_status": "not_visible_in_public_queue_at_2026-06-29T19:20:13+08:00",
|
||||||
"latest_source_readiness_commit_sha": "1fb4bfc09d1e2a192527fb53fdf4694ab2380b6d",
|
"latest_source_readiness_commit_sha": "e66acdfa2f9a47ba34659e52bd5712cd748f1869",
|
||||||
"latest_successful_deploy_marker": "094f50ddb chore(cd): deploy 1fb4bfc [skip ci]",
|
"latest_successful_deploy_marker": "097bb3589 chore(cd): deploy 23333a7 [skip ci]",
|
||||||
"latest_successful_deployed_source_sha": "1fb4bfc09d1e2a192527fb53fdf4694ab2380b6d",
|
"latest_successful_deployed_source_sha": "23333a7819ce709dc99d03ccc9cf7aa62c86cdbd",
|
||||||
"latest_verified_worktree_base_sha": "094f50ddb",
|
"latest_verified_worktree_base_sha": "097bb3589",
|
||||||
"no_matching_runner_visible": false,
|
"no_matching_runner_visible": false,
|
||||||
"source_readiness_ci_fix_required": false
|
"source_readiness_ci_fix_required": false
|
||||||
},
|
},
|
||||||
@@ -283,93 +314,10 @@
|
|||||||
"status": "blocked_waiting_fresh_all_host_reboot_window",
|
"status": "blocked_waiting_fresh_all_host_reboot_window",
|
||||||
"title": "主機重啟自動偵測、自動觸發與 10 分鐘恢復 SLO",
|
"title": "主機重啟自動偵測、自動觸發與 10 分鐘恢復 SLO",
|
||||||
"workplan_id": "P0-006"
|
"workplan_id": "P0-006"
|
||||||
},
|
|
||||||
{
|
|
||||||
"evidence": {
|
|
||||||
"backup_core_green": true,
|
|
||||||
"checklist_generator_present": true,
|
|
||||||
"checklist_latest_path": "/tmp/awoooi-dr-escrow-evidence-checklist-current.json",
|
|
||||||
"checklist_schema_version": "awoooi_dr_escrow_evidence_checklist_v1",
|
|
||||||
"credential_escrow_intake_api_route_live_checked": true,
|
|
||||||
"credential_marker_write_authorized_count": 0,
|
|
||||||
"dr_escrow_blocked": true,
|
|
||||||
"escrow_status_live_checked": true,
|
|
||||||
"focused_p0_005_tests_passed": 16,
|
|
||||||
"live_no_secret_status_path": "/tmp/awoooi-p0-005-escrow-status-live.txt",
|
|
||||||
"offsite_configured": true,
|
|
||||||
"offsite_fresh": true,
|
|
||||||
"placeholder_preflight_guard_present": true,
|
|
||||||
"product_data_green": true,
|
|
||||||
"production_missing_item_count": 5,
|
|
||||||
"production_owner_response_accepted_count": 0,
|
|
||||||
"production_readback_safe_next_step": "collect_redacted_non_secret_evidence_refs_then_rerun_preflight",
|
|
||||||
"production_runtime_gate_count": 0,
|
|
||||||
"production_safe_next_step": "collect_redacted_non_secret_evidence_refs_then_rerun_preflight",
|
|
||||||
"production_secret_value_collection_allowed": false,
|
|
||||||
"production_top_level_safe_next_step_readback": true,
|
|
||||||
"production_top_level_safe_next_step_was_null_before_source_fix": true,
|
|
||||||
"rclone_configured": true,
|
|
||||||
"rclone_gdrive_configured": true,
|
|
||||||
"rclone_gdrive_fresh": true,
|
|
||||||
"script_missing_count": 0,
|
|
||||||
"secret_value_collection_allowed": false,
|
|
||||||
"source_safe_next_step": "collect_redacted_non_secret_evidence_refs_then_rerun_preflight",
|
|
||||||
"source_top_level_safe_next_step_present": true,
|
|
||||||
"evidence_refs_validation_endpoint_present": true,
|
|
||||||
"evidence_refs_validation_endpoint": "/api/v1/agents/credential-escrow-evidence-intake-readiness/validate-evidence-refs",
|
|
||||||
"evidence_refs_validation_schema_version": "credential_escrow_evidence_refs_validation_v1",
|
|
||||||
"evidence_refs_validation_payload_persisted": false,
|
|
||||||
"evidence_refs_validation_credential_marker_write_performed": false,
|
|
||||||
"evidence_refs_validation_runtime_action_performed": false,
|
|
||||||
"stock_blockers": [],
|
|
||||||
"stock_eod_classification": "after_first_eod_window_blocked",
|
|
||||||
"stock_eod_next_action": "inspect_ingestion_logs_and_wait_retry_windows",
|
|
||||||
"stock_eod_window_pending": false,
|
|
||||||
"stock_freshness_status": "ok",
|
|
||||||
"stock_ingestion_blockers": [],
|
|
||||||
"stock_latest_trading_date": "2026-06-29",
|
|
||||||
"stock_official_margin_short_source_runs": [
|
|
||||||
3390,
|
|
||||||
3389
|
|
||||||
],
|
|
||||||
"stockplatform_api_healthz_green": true,
|
|
||||||
"stockplatform_healthz_green": true,
|
|
||||||
"stockplatform_ingestion_status": "blocked",
|
|
||||||
"summary_escrow_missing_count": 5,
|
|
||||||
"stock_ingestion_status": "ok"
|
|
||||||
},
|
|
||||||
"missing_items": [
|
|
||||||
"restic_repository_password",
|
|
||||||
"offsite_provider_credentials",
|
|
||||||
"break_glass_admin_credentials",
|
|
||||||
"dns_registrar_recovery",
|
|
||||||
"oauth_ai_provider_recovery"
|
|
||||||
],
|
|
||||||
"professional_fix": {
|
|
||||||
"action": "Use the single DR escrow checklist packet with the five required item ids, accept only redacted evidence refs, then run the existing preflight once.",
|
|
||||||
"do_not_repeat": [
|
|
||||||
"Do not reopen cold-start or CI/CD work because escrow refs are missing.",
|
|
||||||
"Do not create additional owner-package variants for the same five refs."
|
|
||||||
],
|
|
||||||
"exit_criteria": [
|
|
||||||
"effective_escrow_missing_count=0",
|
|
||||||
"owner_response_accepted_count=1",
|
|
||||||
"forbidden_true_field_count=0",
|
|
||||||
"secret_value_collection_allowed=false",
|
|
||||||
"post_reboot_readiness OVERALL_DECLARATION no longer includes DR_ESCROW_BLOCKED"
|
|
||||||
],
|
|
||||||
"owner": "DR evidence lane"
|
|
||||||
},
|
|
||||||
"reason": "StockPlatform product data freshness is green again after the 21:05 retry, and backup/offsite core remains green. The remaining P0-005 blocker is the five non-secret credential escrow evidence refs; no secret values, marker writes, or runtime gates are allowed.",
|
|
||||||
"safe_next_step": "collect_five_non_secret_credential_escrow_evidence_refs_then_rerun_single_preflight",
|
|
||||||
"status": "waiting_non_secret_credential_escrow_evidence_refs",
|
|
||||||
"title": "產品資料與備份 contract",
|
|
||||||
"workplan_id": "P0-005"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"next_execution_order": [
|
"next_execution_order": [
|
||||||
"P0-006: service/data/backup readback is green again; keep the live reboot SLO timer active and wait for the next fresh all-host reboot event or separately approved reboot drill to prove the 10-minute SLO, with no reboot/restart/DB write from this lane.",
|
"P0-006: service/data/backup readback is green again; keep the live reboot SLO timer active and wait for the next fresh all-host reboot event or separately approved reboot drill to prove the 10-minute SLO, with no reboot/restart/DB write from this lane.",
|
||||||
"P0-005: collect five non-secret credential escrow evidence refs and rerun one preflight; production API safe_next_step reads back correctly and backup/offsite core remains green.",
|
|
||||||
"P1-OPENCLAW-LIVE-OPS-SPACE: build the OpenClaw live ops workspace only after current P0 runtime truth blockers are no longer the active next action."
|
"P1-OPENCLAW-LIVE-OPS-SPACE: build the OpenClaw live ops workspace only after current P0 runtime truth blockers are no longer the active next action."
|
||||||
],
|
],
|
||||||
"noise_integrated_risk_register": [
|
"noise_integrated_risk_register": [
|
||||||
@@ -504,6 +452,7 @@
|
|||||||
"schema_version": "awoooi_priority_work_order_readback_v1",
|
"schema_version": "awoooi_priority_work_order_readback_v1",
|
||||||
"source_refs": {
|
"source_refs": {
|
||||||
"credential_escrow_intake_readiness_api": "/api/v1/agents/credential-escrow-evidence-intake-readiness",
|
"credential_escrow_intake_readiness_api": "/api/v1/agents/credential-escrow-evidence-intake-readiness",
|
||||||
|
"credential_escrow_intake_readiness_closeout_receipt": "docs/operations/awoooi-credential-escrow-evidence-controlled-closeout-receipt.snapshot.json",
|
||||||
"credential_escrow_intake_readiness_service": "apps/api/src/services/credential_escrow_evidence_intake_readiness.py",
|
"credential_escrow_intake_readiness_service": "apps/api/src/services/credential_escrow_evidence_intake_readiness.py",
|
||||||
"credential_escrow_intake_readiness_tests": "apps/api/tests/test_credential_escrow_evidence_intake_readiness_api.py",
|
"credential_escrow_intake_readiness_tests": "apps/api/tests/test_credential_escrow_evidence_intake_readiness_api.py",
|
||||||
"credential_escrow_live_status": "/tmp/awoooi-p0-005-escrow-status-live.txt",
|
"credential_escrow_live_status": "/tmp/awoooi-p0-005-escrow-status-live.txt",
|
||||||
@@ -527,7 +476,7 @@
|
|||||||
"stockplatform_ingestion_readback": "https://stock.wooo.work/api/v1/system/ingestion",
|
"stockplatform_ingestion_readback": "https://stock.wooo.work/api/v1/system/ingestion",
|
||||||
"workstation_dashboard": "~/.codex/codex-workstation-sync-dashboard.snapshot.json"
|
"workstation_dashboard": "~/.codex/codex-workstation-sync-dashboard.snapshot.json"
|
||||||
},
|
},
|
||||||
"status": "p0_ordered_readback_p0_006_service_data_green_waiting_fresh_reboot_window_p0_005_refs_waiting",
|
"status": "p0_ordered_readback_p0_006_service_data_green_waiting_fresh_reboot_window_p0_005_and_p0_003_closed",
|
||||||
"stopped_or_do_not_use": [
|
"stopped_or_do_not_use": [
|
||||||
{
|
{
|
||||||
"allowed_actions": 0,
|
"allowed_actions": 0,
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ def test_deploy_marker_k8s_files_stay_on_controlled_runtime_profile() -> None:
|
|||||||
|
|
||||||
def test_credential_escrow_intake_stays_on_controlled_runtime_profile() -> None:
|
def test_credential_escrow_intake_stays_on_controlled_runtime_profile() -> None:
|
||||||
text = _workflow_text()
|
text = _workflow_text()
|
||||||
|
assert (
|
||||||
|
"docs/operations/awoooi-credential-escrow-evidence-controlled-closeout-receipt.snapshot.json)"
|
||||||
|
in text
|
||||||
|
)
|
||||||
assert "apps/api/src/services/credential_escrow_evidence_intake_readiness.py)" in text
|
assert "apps/api/src/services/credential_escrow_evidence_intake_readiness.py)" in text
|
||||||
assert "src/services/credential_escrow_evidence_intake_readiness.py" in text
|
assert "src/services/credential_escrow_evidence_intake_readiness.py" in text
|
||||||
assert "tests/test_credential_escrow_evidence_intake_readiness_api.py" in text
|
assert "tests/test_credential_escrow_evidence_intake_readiness_api.py" in text
|
||||||
|
|||||||
Reference in New Issue
Block a user