feat(delivery): expose credential escrow scorecard

This commit is contained in:
Your Name
2026-06-29 10:48:28 +08:00
parent 7191193c71
commit 76e5bbcf47
5 changed files with 246 additions and 6 deletions

View File

@@ -411,6 +411,59 @@ def build_delivery_closure_workbench(
"metric": {
"kind": "readiness_row_count",
"rows": _int(backup_rollups.get("total_rows")),
"credential_escrow_intake_scorecard_schema_version": str(
backup_rollups.get(
"credential_escrow_intake_scorecard_schema_version"
)
or ""
),
"credential_escrow_intake_scorecard_verifier": str(
backup_rollups.get("credential_escrow_intake_scorecard_verifier")
or ""
),
"credential_escrow_intake_status": str(
backup_rollups.get("credential_escrow_intake_status") or ""
),
"credential_escrow_active_gate_present": backup_rollups.get(
"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(
backup_rollups.get("credential_escrow_required_item_count")
),
"credential_escrow_effective_missing_count": _int(
backup_rollups.get("credential_escrow_effective_missing_count")
),
"credential_escrow_owner_response_received_count": _int(
backup_rollups.get(
"credential_escrow_owner_response_received_count"
)
),
"credential_escrow_owner_response_accepted_count": _int(
backup_rollups.get(
"credential_escrow_owner_response_accepted_count"
)
),
"credential_escrow_runtime_gate_count": _int(
backup_rollups.get("credential_escrow_runtime_gate_count")
),
"credential_escrow_secret_value_collection_allowed": (
backup_rollups.get(
"credential_escrow_secret_value_collection_allowed"
)
is True
),
"credential_marker_write_authorized_count": _int(
backup_rollups.get("credential_marker_write_authorized_count")
),
"credential_escrow_forbidden_true_field_count": _int(
backup_rollups.get(
"credential_escrow_forbidden_true_field_count"
)
),
},
"href": "/operations",
"next_action": _first_backup_action(backup.get("readiness_rows")),
@@ -646,6 +699,57 @@ def build_delivery_closure_workbench(
)
)
),
"backup_credential_escrow_intake_scorecard_schema_version": str(
backup_rollups.get(
"credential_escrow_intake_scorecard_schema_version"
)
or ""
),
"backup_credential_escrow_intake_scorecard_verifier": str(
backup_rollups.get("credential_escrow_intake_scorecard_verifier")
or ""
),
"backup_credential_escrow_intake_status": str(
backup_rollups.get("credential_escrow_intake_status") or ""
),
"backup_credential_escrow_active_gate_present": backup_rollups.get(
"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_rollups.get("credential_escrow_required_item_count")
),
"backup_credential_escrow_effective_missing_count": _int(
backup_rollups.get("credential_escrow_effective_missing_count")
),
"backup_credential_escrow_owner_response_received_count": _int(
backup_rollups.get(
"credential_escrow_owner_response_received_count"
)
),
"backup_credential_escrow_owner_response_accepted_count": _int(
backup_rollups.get(
"credential_escrow_owner_response_accepted_count"
)
),
"backup_credential_escrow_runtime_gate_count": _int(
backup_rollups.get("credential_escrow_runtime_gate_count")
),
"backup_credential_escrow_secret_value_collection_allowed": (
backup_rollups.get(
"credential_escrow_secret_value_collection_allowed"
)
is True
),
"backup_credential_marker_write_authorized_count": _int(
backup_rollups.get("credential_marker_write_authorized_count")
),
"backup_credential_escrow_forbidden_true_field_count": _int(
backup_rollups.get("credential_escrow_forbidden_true_field_count")
),
"github_write_channel_ready": github_preflight.get(
"github_write_channel_ready"
)

View File

@@ -169,6 +169,40 @@ def test_delivery_closure_workbench_endpoint_returns_product_summary():
data["summary"]["production_deploy_non110_runner_remaining_blocker_count"]
== 3
)
assert (
data["summary"][
"backup_credential_escrow_intake_scorecard_schema_version"
]
== "awoooi_post_reboot_credential_escrow_intake_scorecard_v1"
)
assert (
"scripts/reboot-recovery/post-reboot-credential-escrow-intake-scorecard.py"
in data["summary"]["backup_credential_escrow_intake_scorecard_verifier"]
)
assert data["summary"]["backup_credential_escrow_intake_status"] == (
"blocked_waiting_non_secret_credential_escrow_evidence"
)
assert data["summary"]["backup_credential_escrow_active_gate_present"] is True
assert data["summary"]["backup_credential_escrow_preflight_status"] == (
"blocked_waiting_owner_response_content"
)
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_owner_response_received_count"]
== 0
)
assert (
data["summary"]["backup_credential_escrow_owner_response_accepted_count"]
== 0
)
assert data["summary"]["backup_credential_escrow_runtime_gate_count"] == 0
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_escrow_forbidden_true_field_count"] == 0
assert data["summary"]["github_write_channel_ready"] is False
assert data["summary"]["github_account_status"] == "suspended"
assert data["summary"]["github_account_suspended"] is True
@@ -380,6 +414,37 @@ def test_delivery_closure_workbench_endpoint_returns_product_summary():
assert lanes["gitea"]["metric"]["kind"] == "workflow_count"
assert lanes["runtime"]["metric"]["kind"] == "surface_count"
assert lanes["backup"]["metric"]["kind"] == "readiness_row_count"
assert (
lanes["backup"]["metric"][
"credential_escrow_intake_scorecard_schema_version"
]
== "awoooi_post_reboot_credential_escrow_intake_scorecard_v1"
)
assert lanes["backup"]["metric"]["credential_escrow_intake_status"] == (
"blocked_waiting_non_secret_credential_escrow_evidence"
)
assert lanes["backup"]["metric"]["credential_escrow_active_gate_present"] is True
assert (
lanes["backup"]["metric"]["credential_escrow_effective_missing_count"]
== 5
)
assert (
lanes["backup"]["metric"]["credential_escrow_owner_response_received_count"]
== 0
)
assert (
lanes["backup"]["metric"]["credential_escrow_owner_response_accepted_count"]
== 0
)
assert lanes["backup"]["metric"]["credential_escrow_runtime_gate_count"] == 0
assert (
lanes["backup"]["metric"][
"credential_escrow_secret_value_collection_allowed"
]
is False
)
assert lanes["backup"]["metric"]["credential_marker_write_authorized_count"] == 0
assert lanes["backup"]["metric"]["credential_escrow_forbidden_true_field_count"] == 0
assert sources["github_private_backup"]["loaded"] is True
assert sources["production_deploy_readback"]["loaded"] is True
assert (

View File

@@ -2584,6 +2584,19 @@ export interface DeliveryClosureWorkbenchSnapshot {
production_deploy_non110_runner_ready_registration_count: number
production_deploy_non110_runner_safe_next_step: string
production_deploy_non110_runner_remaining_blocker_count: number
backup_credential_escrow_intake_scorecard_schema_version: string
backup_credential_escrow_intake_scorecard_verifier: string
backup_credential_escrow_intake_status: string
backup_credential_escrow_active_gate_present: boolean
backup_credential_escrow_preflight_status: string
backup_credential_escrow_required_item_count: number
backup_credential_escrow_effective_missing_count: number
backup_credential_escrow_owner_response_received_count: number
backup_credential_escrow_owner_response_accepted_count: number
backup_credential_escrow_runtime_gate_count: number
backup_credential_escrow_secret_value_collection_allowed: boolean
backup_credential_marker_write_authorized_count: number
backup_credential_escrow_forbidden_true_field_count: number
github_write_channel_ready: boolean
github_account_status: string
github_account_suspended: boolean
@@ -2664,7 +2677,23 @@ export interface DeliveryClosureWorkbenchSnapshot {
}
| { kind: 'workflow_count'; count: number }
| { kind: 'surface_count'; total: number }
| { kind: 'readiness_row_count'; rows: number }
| {
kind: 'readiness_row_count'
rows: number
credential_escrow_intake_scorecard_schema_version: string
credential_escrow_intake_scorecard_verifier: string
credential_escrow_intake_status: string
credential_escrow_active_gate_present: boolean
credential_escrow_preflight_status: string
credential_escrow_required_item_count: number
credential_escrow_effective_missing_count: number
credential_escrow_owner_response_received_count: number
credential_escrow_owner_response_accepted_count: number
credential_escrow_runtime_gate_count: number
credential_escrow_secret_value_collection_allowed: boolean
credential_marker_write_authorized_count: number
credential_escrow_forbidden_true_field_count: number
}
href: string
operator_unblock?: DeliveryOperatorUnblock
next_action: string
@@ -14655,6 +14684,19 @@ export interface BackupDrReadinessMatrixSnapshot {
by_offsite_status: Record<string, number>
blocked_row_ids: string[]
action_required_row_ids: string[]
credential_escrow_intake_scorecard_schema_version: string
credential_escrow_intake_scorecard_verifier: string
credential_escrow_intake_status: string
credential_escrow_active_gate_present: boolean
credential_escrow_preflight_status: string
credential_escrow_required_item_count: number
credential_escrow_effective_missing_count: number
credential_escrow_owner_response_received_count: number
credential_escrow_owner_response_accepted_count: number
credential_escrow_runtime_gate_count: number
credential_escrow_secret_value_collection_allowed: boolean
credential_marker_write_authorized_count: number
credential_escrow_forbidden_true_field_count: number
}
readiness_rows: Array<{
target_id: string

View File

@@ -7,6 +7,21 @@
**邊界**:只改 committed source / snapshot / API type / tests / docs未使用 GitHub未讀 token / `.runner` 內容 / cookie / session / secret未操作 host / Docker / K8s / runner service未 workflow_dispatch。
## 2026-06-29 — 10:42 Delivery Workbench credential escrow scorecard 投影
**完成內容**
- 將 `post-reboot-credential-escrow-intake-scorecard.py` 的 no-secret scorecard contract 投影到 Backup / DR readiness rollups、Delivery Workbench summary 與 backup lane metric。
- Workbench 現在可讀回 `blocked_waiting_non_secret_credential_escrow_evidence`、active gate present、5 個 escrow item missing、owner response / runtime gate / marker write / forbidden true fields 皆為 `0`
- 同步 web API type避免前端將 credential escrow gate 退回只靠文件或人工語意。
**驗證結果**
- `jq empty docs/evaluations/backup_dr_readiness_matrix_2026-06-04.json`:通過。
- `PYTHONPATH=apps/api python3.11 -m pytest apps/api/tests/test_delivery_closure_workbench_api.py apps/api/tests/test_backup_dr_readiness_matrix.py apps/api/tests/test_backup_dr_readiness_matrix_api.py -q``8 passed`
- `pnpm --dir apps/web typecheck`:通過。
- `git diff --check`:通過。
**邊界**:只改 committed source / snapshot / API type / tests未讀 password / token / `.runner` / raw session / SQLite / auth / `.env`,未寫 credential marker未操作 host / Docker / K8s / runner service未使用 GitHub。
## 2026-06-29 — 09:36 credential escrow intake scorecard no-secret readback
**完成內容**

View File

@@ -6,7 +6,8 @@
"docs/runbooks/BACKUP-STATUS.md",
"docs/evaluations/backup_dr_target_inventory_2026-06-04.json",
"scripts/backup/backup-status.sh",
"scripts/backup/verify-offsite-full-sync.sh"
"scripts/backup/verify-offsite-full-sync.sh",
"scripts/reboot-recovery/post-reboot-credential-escrow-intake-scorecard.py"
],
"program_status": {
"overall_completion_percent": 91,
@@ -43,7 +44,20 @@
"action_required_row_ids": [
"signoz",
"velero_k8s_resources"
]
],
"credential_escrow_intake_scorecard_schema_version": "awoooi_post_reboot_credential_escrow_intake_scorecard_v1",
"credential_escrow_intake_scorecard_verifier": "scripts/reboot-recovery/post-reboot-credential-escrow-intake-scorecard.py --summary-file <summary.txt> --owner-packet-file <owner-packets.json> --response-file <owner-response.json> --offsite-report-file <offsite-report.txt> --escrow-status-file <escrow-status.txt> --json",
"credential_escrow_intake_status": "blocked_waiting_non_secret_credential_escrow_evidence",
"credential_escrow_active_gate_present": true,
"credential_escrow_preflight_status": "blocked_waiting_owner_response_content",
"credential_escrow_required_item_count": 5,
"credential_escrow_effective_missing_count": 5,
"credential_escrow_owner_response_received_count": 0,
"credential_escrow_owner_response_accepted_count": 0,
"credential_escrow_runtime_gate_count": 0,
"credential_escrow_secret_value_collection_allowed": false,
"credential_marker_write_authorized_count": 0,
"credential_escrow_forbidden_true_field_count": 0
},
"readiness_rows": [
{
@@ -282,9 +296,9 @@
"notification_policy": "missing markers must stay action-required不得成功洗版。",
"gate_status": "credential_approval_required",
"evidence_level": "blocked_live_evidence",
"evidence_refs": ["docs/runbooks/BACKUP-STATUS.md", "scripts/backup/mark-credential-escrow-verified.sh", "scripts/backup/offsite-escrow-evidence-report.sh"],
"blocker_summary": "Five evidence markers missing不得自動寫 marker 或暴露 credential。",
"next_action": "P1-105 起草人工 escrow review 批准包。"
"evidence_refs": ["docs/runbooks/BACKUP-STATUS.md", "scripts/backup/mark-credential-escrow-verified.sh", "scripts/backup/offsite-escrow-evidence-report.sh", "scripts/reboot-recovery/post-reboot-credential-escrow-intake-scorecard.py"],
"blocker_summary": "Five evidence markers missing不得自動寫 marker、不得讀或暴露 credential value可收斂 redacted non-secret evidence refs。",
"next_action": "用 credential escrow intake scorecard 收斂 no-secret evidence refspreflight 通過前維持 marker write/runtime gate 為 0。"
},
{
"target_id": "velero_k8s_resources",