diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 75b91aab..014e2f66 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -49474,3 +49474,21 @@ production browser smoke: **仍維持**: - 沒有重啟任何主機;沒有 restart Docker / Nginx / K3s / DB / firewall;沒有讀 secret / token / `.env` / raw sessions / SQLite / auth;沒有使用 GitHub。 - 下一個 P0-006 proof 不是再部署 source,而是等待下一次實際 all-host reboot event,或另開經批准 reboot drill,讓 `max_observed_uptime_seconds<=600` 且上述 service readback 維持綠。 + +## 2026-06-29 — 15:24 P0 ordered readback: P0-006 / P0-005 / P0-003 + +**照優先順序完成的讀回**: +- P0-006:`install-reboot-auto-recovery-slo-110.sh --verify-only` 讀回 110 live timer `enabled/active`,latest artifact `/home/wooo/reboot-recovery/reboot-auto-recovery-slo-20260629-151707`,observed hosts `110,120,121,188`;唯一 blocker 仍是 `host_boot_observation_older_than_target_window`,所以不得宣稱 fresh reboot 10 分鐘 SLO 已證明。 +- P0-005:`backup-status.sh --no-notify --no-refresh` 讀回 backup core / offsite / rclone GDrive freshness green,但 `mark-credential-escrow-verified.sh --status` 顯示五項 escrow refs 仍 missing:`restic_repository_password`、`offsite_provider_credentials`、`break_glass_admin_credentials`、`dns_registrar_recovery`、`oauth_ai_provider_recovery`。 +- P0-003:Gitea user-scope public inventory live refresh 成 4 個 repos:`wooo/awoooi`、`wooo/ewoooc`、`wooo/agent-bounty-protocol`、`wooo/2026FIFAWorldCup`;仍是 `status=partial` / `visibility_scope=public_only` / `token_present=false`,所以 private/internal coverage 仍需脫敏 authenticated/admin export 或 owner coverage attestation。 + +**更新檔案**: +- `docs/operations/awoooi-priority-work-order-readback.snapshot.json` +- `docs/operations/awoooi-gitea-private-inventory-p0-scorecard.snapshot.json` +- `docs/security/gitea-repo-inventory.snapshot.json` +- `docs/security/GITEA-REPO-INVENTORY-SNAPSHOT.md` + +**仍維持**: +- 沒有重啟主機,沒有 restart Docker / Nginx / K3s / DB / firewall。 +- 沒有讀 secret / token / `.env` / raw sessions / SQLite / auth,沒有寫 credential marker。 +- 沒有使用 GitHub / gh / GitHub API / GitHub Actions。 diff --git a/docs/operations/awoooi-gitea-private-inventory-p0-scorecard.snapshot.json b/docs/operations/awoooi-gitea-private-inventory-p0-scorecard.snapshot.json index 69c09c8e..4ca3f3e2 100644 --- a/docs/operations/awoooi-gitea-private-inventory-p0-scorecard.snapshot.json +++ b/docs/operations/awoooi-gitea-private-inventory-p0-scorecard.snapshot.json @@ -1,6 +1,6 @@ { "schema_version": "awoooi_gitea_private_inventory_p0_scorecard_v1", - "generated_at": "2026-06-29T14:09:49+08:00", + "generated_at": "2026-06-29T15:24:00+08:00", "workplan_id": "P0-003", "status": "blocked_waiting_gitea_authenticated_or_owner_export_inventory", "source_control_authority": "gitea", @@ -14,7 +14,13 @@ "schema_version": "gitea_repo_inventory_v1", "status": "partial", "visibility_scope": "public_only", - "repo_count": 2, + "repo_count": 4, + "public_repos": [ + "wooo/awoooi", + "wooo/ewoooc", + "wooo/agent-bounty-protocol", + "wooo/2026FIFAWorldCup" + ], "token_present": false, "blocking_reason": "未提供 token,結果只代表公開可見 repo;private/internal repos 仍需只讀 token 或管理匯出" }, diff --git a/docs/operations/awoooi-priority-work-order-readback.snapshot.json b/docs/operations/awoooi-priority-work-order-readback.snapshot.json index 5fad7ef2..51fed509 100644 --- a/docs/operations/awoooi-priority-work-order-readback.snapshot.json +++ b/docs/operations/awoooi-priority-work-order-readback.snapshot.json @@ -1,11 +1,11 @@ { "schema_version": "awoooi_priority_work_order_readback_v1", - "generated_at": "2026-06-29T15:05:00+08:00", - "status": "p0_006a_reboot_auto_recovery_slo_timer_live_services_green_waiting_reboot_window", + "generated_at": "2026-06-29T15:24:00+08:00", + "status": "p0_ordered_readback_p0_006_timer_live_p0_005_escrow_missing_p0_003_public_inventory_refreshed", "source_refs": { "global_scorecard": "~/.codex/product-runtime-governance-completion-scorecard.snapshot.json", "workstation_dashboard": "~/.codex/codex-workstation-sync-dashboard.snapshot.json", - "post_reboot_summary": "/home/wooo/reboot-recovery/reboot-auto-recovery-slo-20260629-150501/summary.txt", + "post_reboot_summary": "/home/wooo/reboot-recovery/reboot-auto-recovery-slo-20260629-151707/summary.txt", "full_stack_cold_start_check": "scripts/reboot-recovery/full-stack-cold-start-check.sh --monitor-read-only --no-color", "delivery_closure_workbench": "https://awoooi.wooo.work/api/v1/agents/delivery-closure-workbench", "public_gitea_queue_readback": "ops/runner/read-public-gitea-actions-queue.py --json", @@ -13,17 +13,22 @@ "dr_escrow_evidence_checklist_generator": "scripts/reboot-recovery/dr-escrow-evidence-checklist.py", "gitea_private_inventory_p0_scorecard": "docs/operations/awoooi-gitea-private-inventory-p0-scorecard.snapshot.json", "reboot_auto_recovery_slo_scorecard": "docs/operations/awoooi-reboot-auto-recovery-slo-scorecard.snapshot.json", - "reboot_auto_recovery_slo_metric": "/home/wooo/node_exporter_textfiles/reboot_auto_recovery_slo.prom" + "reboot_auto_recovery_slo_metric": "/home/wooo/node_exporter_textfiles/reboot_auto_recovery_slo.prom", + "credential_escrow_live_status": "/tmp/awoooi-p0-005-escrow-status-live.txt", + "dr_escrow_evidence_checklist_latest": "/tmp/awoooi-dr-escrow-evidence-checklist-current.json", + "gitea_repo_inventory_snapshot": "docs/security/gitea-repo-inventory.snapshot.json" }, "current_head": { - "gitea_main_sha": "7ff959b6a8bbdf152da1969687f188ceda4b0561", + "gitea_main_sha": "fe42ed1b4368800fca43ce040f8f498f0e88494f", "latest_successful_deploy_marker": "15824e9ec chore(cd): deploy 57c1df1 [skip ci]", "latest_successful_deployed_source_sha": "57c1df19fca580dafa5980d82d164819de0dbcd5", "latest_source_readiness_commit_sha": "0c8d4e88c39157b92322fa41a92e6b15c317ac49", "latest_source_readiness_cd_run_id": "3882", "latest_source_readiness_cd_run_status": "Success", "source_readiness_ci_fix_required": false, - "no_matching_runner_visible": false + "no_matching_runner_visible": false, + "latest_verified_worktree_base_sha": "8f0c6d300", + "latest_fetched_gitea_main_subject": "feat(awooop): expose ai automation log taxonomy" }, "completed_in_priority_order": [ { @@ -107,7 +112,7 @@ "workplan_id": "P0-005", "title": "產品資料與備份 contract", "status": "checklist_ready_waiting_non_secret_credential_escrow_evidence", - "reason": "Backup core and product freshness are green, and the P0-005 lane now has one no-secret checklist packet for the five remaining credential escrow evidence markers.", + "reason": "Live no-secret backup status is green for backup/offsite freshness, but all five DR credential escrow evidence refs are still missing. This lane stays on the single checklist and one preflight only.", "evidence": { "product_data_green": true, "stock_freshness_status": "ok", @@ -122,7 +127,13 @@ "secret_value_collection_allowed": false, "checklist_generator_present": true, "checklist_schema_version": "awoooi_dr_escrow_evidence_checklist_v1", - "placeholder_preflight_guard_present": true + "placeholder_preflight_guard_present": true, + "offsite_fresh": true, + "rclone_gdrive_configured": true, + "rclone_gdrive_fresh": true, + "escrow_status_live_checked": true, + "live_no_secret_status_path": "/tmp/awoooi-p0-005-escrow-status-live.txt", + "checklist_latest_path": "/tmp/awoooi-dr-escrow-evidence-checklist-current.json" }, "missing_items": [ "restic_repository_password", @@ -152,19 +163,32 @@ "workplan_id": "P0-003", "title": "取得 Gitea private inventory 權限", "status": "blocked_waiting_gitea_authenticated_or_owner_export_inventory", - "reason": "P0-003 now has a Gitea-only scorecard. GitHub is excluded from active P0 blocker math; remaining blockers are Gitea authenticated/admin export payload and owner coverage attestation.", + "reason": "Gitea-only public inventory was refreshed from live 110 readback and now shows four public repos. It is still public_only with no token present, so private/internal coverage requires an authenticated/admin redacted export payload or owner coverage attestation.", "evidence": { "private_inventory_source": "gitea", "github_lane_excluded_from_p0_blocker_count": true, "gitea_inventory_status": "partial", "gitea_visibility_scope": "public_only", - "gitea_public_repo_count": 2, + "gitea_public_repo_count": 4, "accepted_inventory_payload_count": 0, "owner_coverage_attestation_received_count": 0, "expected_product_count": 11, "present_product_row_count": 11, "missing_product_row_count": 0, - "all_active_product_repos_have_gitea_owner_readiness_row": true + "all_active_product_repos_have_gitea_owner_readiness_row": true, + "gitea_public_repos": [ + "wooo/awoooi", + "wooo/ewoooc", + "wooo/agent-bounty-protocol", + "wooo/2026FIFAWorldCup" + ], + "gitea_readonly_token_present": false, + "active_blockers": [ + "gitea_repo_inventory_status_not_ok", + "gitea_visibility_scope_public_only_or_unknown", + "gitea_authenticated_inventory_payload_not_accepted", + "gitea_owner_coverage_attestation_not_received" + ] }, "professional_fix": { "owner": "Gitea inventory lane", @@ -177,13 +201,13 @@ "all_active_product_repos_have_gitea_owner_readiness_row=true" ] }, - "safe_next_step": "validate_gitea_authenticated_or_admin_export_redacted_inventory_payload" + "safe_next_step": "validate_gitea_authenticated_or_admin_export_redacted_inventory_payload_or_owner_coverage_attestation" }, { "workplan_id": "P0-006", "title": "主機重啟自動偵測、自動觸發與 10 分鐘恢復 SLO", "status": "blocked_waiting_fresh_all_host_reboot_window", - "reason": "Boot-triggered SLO timer is enabled and active on host 110; live metric and scorecard observed all required hosts. Service/data/backup/188 readback is green. The 10-minute claim remains fail-closed only because the current boot observation is older than the 600-second target window, so the next proof requires an actual fresh all-host reboot event or an approved reboot drill.", + "reason": "Verify-only readback confirms the live SLO timer remains enabled and active on 110, observes all required hosts, and has only host_boot_observation_older_than_target_window as blocker. The 10-minute claim still requires a fresh all-host reboot event or separately approved reboot drill.", "evidence": { "target_minutes": 10, "can_claim_all_services_recovered_within_target": false, @@ -223,7 +247,8 @@ "host_boot_observation_older_than_target_window" ], "host_188_service_green": true, - "safe_next_step_from_scorecard": "timer_deployed_and_services_readback_green_wait_for_next_all_host_reboot_event_or_approved_reboot_drill_to_prove_10_minute_slo" + "safe_next_step_from_scorecard": "timer_deployed_and_services_readback_green_wait_for_next_all_host_reboot_event_or_approved_reboot_drill_to_prove_10_minute_slo", + "latest_live_slo_artifact": "/home/wooo/reboot-recovery/reboot-auto-recovery-slo-20260629-151707" }, "professional_fix": { "owner": "reboot auto-recovery lane", @@ -242,7 +267,7 @@ "live_slo_metric_present=true" ] }, - "safe_next_step": "wait_for_next_all_host_reboot_event_or_separately_approved_reboot_drill_to_prove_10_minute_slo" + "safe_next_step": "keep_timer_live_wait_for_next_all_host_reboot_event_or_separately_approved_reboot_drill_to_prove_10_minute_slo" } ], "noise_integrated_risk_register": [ @@ -314,8 +339,8 @@ "database_write_or_restore_performed": false }, "next_execution_order": [ - "P0-006: keep the live reboot SLO timer active; next proof is the next fresh all-host reboot event or separately approved reboot drill, not another source deploy.", - "P0-005: fill the single DR escrow evidence checklist with five non-secret refs and rerun one preflight.", - "P0-003: complete Gitea authenticated/admin inventory export and owner coverage attestation; GitHub remains stopped/retired/do_not_use." + "P0-006: keep the live reboot SLO timer active; no reboot or service restart from this lane; next proof is the next fresh all-host reboot event or separately approved reboot drill.", + "P0-005: fill the single DR escrow evidence checklist with five non-secret refs, then rerun one preflight; backup/offsite freshness is already green.", + "P0-003: complete Gitea authenticated/admin redacted inventory export or owner coverage attestation; public-only live inventory is refreshed to four repos; GitHub remains stopped/retired/do_not_use." ] } diff --git a/docs/security/GITEA-REPO-INVENTORY-SNAPSHOT.md b/docs/security/GITEA-REPO-INVENTORY-SNAPSHOT.md index 599438e7..ddee1624 100644 --- a/docs/security/GITEA-REPO-INVENTORY-SNAPSHOT.md +++ b/docs/security/GITEA-REPO-INVENTORY-SNAPSHOT.md @@ -5,31 +5,31 @@ | 狀態 | `partial` | | Gitea base URL | `http://192.168.0.110:3001` | | Org/User | `wooo` | -| GitHub owner 候選 | `owenhytsai` | +| GitHub owner 候選 | `` | | 查詢模式 | `user` | | 查詢字串 | `` | | 可見性範圍 | `public_only` | | 是否提供 token | `False` | | HTTP status | `200` | -| Repo 數量 | `2` | +| Repo 數量 | `4` | | 阻塞原因 | 未提供 token,結果只代表公開可見 repo;private/internal repos 仍需只讀 token 或管理匯出 | -| S4.5 export request | `docs/security/GITEA-AUTHENTICATED-INVENTORY-EXPORT-REQUEST.md` | -| S4.6 import acceptance | `docs/security/GITEA-AUTHENTICATED-INVENTORY-IMPORT-ACCEPTANCE.md` | -| S4.7 coverage attestation | `docs/security/GITEA-INVENTORY-COVERAGE-ATTESTATION.md` | ## Repo 清單 | Gitea repo | GitHub 候選 | default branch | private | archived | |------------|------------------|----------------|---------|----------| -| `wooo/awoooi` | `owenhytsai/awoooi` | `main` | `False` | `False` | -| `wooo/ewoooc` | `owenhytsai/ewoooc` | `main` | `False` | `False` | +| `wooo/awoooi` | `` | `main` | `False` | `False` | +| `wooo/ewoooc` | `` | `main` | `False` | `False` | +| `wooo/agent-bounty-protocol` | `` | `main` | `False` | `False` | +| `wooo/2026FIFAWorldCup` | `` | `main` | `False` | `False` | > 注意:本檔由 read-only Gitea inventory 工具產生,不包含 API token 或 remote URL 帳密。 -S4.5 已將 authenticated inventory / redacted admin export 的欄位、拒收規則與 coverage gap 驗收文件化;本 snapshot 仍是 `partial`,不得視為 server-side 全量。 +## 治理註記 -S4.6 已將後續脫敏 payload 的驗收、拒收與隔離規則文件化;目前尚未收到 payload,`gitea_repo_inventory_v1.status` 仍不得標記為 `ok`。 +S4.5 / S4.6 / S4.7 仍維持等待狀態:本次 live readback 只證明未認證 `user` endpoint 可見 4 個 public repos,不代表 private/internal inventory 完成。 -S4.7 已將 owner coverage attestation 文件化;目前尚未收到 owner attestation,public-only 2 repos、本機 Gitea unique 4 repos、org/user endpoint 與 110 internal adjacent source 的 scope 仍不得視為已完成。 - -2026-06-04 P1 refresh 注意:本檔由工具重產時會覆蓋人工治理註記;後續需把 generator output 與治理補註分層,或在重產後固定補回 S4.5 / S4.6 / S4.7 狀態,避免 AwoooP 只看到 public-only list 而漏掉 owner response gate。 +- Authenticated/admin export payload:尚未收到,`accepted_payload_count=0`。 +- Owner coverage attestation:尚未收到,`received_attestation_count=0`。 +- GitHub:維持 `stopped_retired_do_not_use`,不得作為 P0 下一步或 read-only 查詢來源。 +- 下一步只接受脫敏的 Gitea authenticated/admin export payload 或 owner coverage attestation;不得收 token、secret、cookie、session、DB dump 或 git object pack。 diff --git a/docs/security/gitea-repo-inventory.snapshot.json b/docs/security/gitea-repo-inventory.snapshot.json index acab1415..65cc33ad 100644 --- a/docs/security/gitea-repo-inventory.snapshot.json +++ b/docs/security/gitea-repo-inventory.snapshot.json @@ -2,7 +2,7 @@ "schema_version": "gitea_repo_inventory_v1", "base_url": "http://192.168.0.110:3001", "org": "wooo", - "github_owner": "owenhytsai", + "github_owner": "", "query_mode": "user", "query": "", "visibility_scope": "public_only", @@ -10,7 +10,7 @@ "http_status": 200, "status": "partial", "blocking_reason": "未提供 token,結果只代表公開可見 repo;private/internal repos 仍需只讀 token 或管理匯出", - "repo_count": 2, + "repo_count": 4, "repos": [ { "gitea_repo": "wooo/awoooi", @@ -22,7 +22,7 @@ "default_branch": "main", "clone_url_redacted": "http://192.168.0.110:3001/wooo/awoooi.git", "ssh_url_redacted": "ssh://localhost:2222/wooo/awoooi.git", - "github_repo_candidate": "owenhytsai/awoooi" + "github_repo_candidate": "" }, { "gitea_repo": "wooo/ewoooc", @@ -34,7 +34,31 @@ "default_branch": "main", "clone_url_redacted": "http://192.168.0.110:3001/wooo/ewoooc.git", "ssh_url_redacted": "ssh://localhost:2222/wooo/ewoooc.git", - "github_repo_candidate": "owenhytsai/ewoooc" + "github_repo_candidate": "" + }, + { + "gitea_repo": "wooo/agent-bounty-protocol", + "name": "agent-bounty-protocol", + "owner": "wooo", + "private": false, + "empty": false, + "archived": false, + "default_branch": "main", + "clone_url_redacted": "http://192.168.0.110:3001/wooo/agent-bounty-protocol.git", + "ssh_url_redacted": "ssh://localhost:2222/wooo/agent-bounty-protocol.git", + "github_repo_candidate": "" + }, + { + "gitea_repo": "wooo/2026FIFAWorldCup", + "name": "2026FIFAWorldCup", + "owner": "wooo", + "private": false, + "empty": false, + "archived": false, + "default_branch": "main", + "clone_url_redacted": "http://192.168.0.110:3001/wooo/2026FIFAWorldCup.git", + "ssh_url_redacted": "ssh://localhost:2222/wooo/2026FIFAWorldCup.git", + "github_repo_candidate": "" } ] } diff --git a/scripts/security/gitea-private-inventory-p0-scorecard.py b/scripts/security/gitea-private-inventory-p0-scorecard.py index defd8b2d..85d29b87 100644 --- a/scripts/security/gitea-private-inventory-p0-scorecard.py +++ b/scripts/security/gitea-private-inventory-p0-scorecard.py @@ -103,6 +103,11 @@ def build_scorecard(args: argparse.Namespace) -> dict[str, Any]: visibility_scope = str(gitea_inventory.get("visibility_scope", "unknown")) accepted_payload_count = as_int(import_acceptance.get("accepted_payload_count")) received_attestation_count = as_int(coverage_attestation.get("received_attestation_count")) + public_repos = [ + str(repo.get("gitea_repo", "")) + for repo in as_list(gitea_inventory.get("repos")) + if isinstance(repo, dict) and repo.get("gitea_repo") + ] blockers: list[str] = [] if gitea_status != "ok": @@ -134,6 +139,7 @@ def build_scorecard(args: argparse.Namespace) -> dict[str, Any]: "status": gitea_status, "visibility_scope": visibility_scope, "repo_count": as_int(gitea_inventory.get("repo_count")), + "public_repos": public_repos, "token_present": bool(gitea_inventory.get("token_present", False)), "blocking_reason": str(gitea_inventory.get("blocking_reason", "")), }, diff --git a/scripts/security/tests/test_gitea_private_inventory_p0_scorecard.py b/scripts/security/tests/test_gitea_private_inventory_p0_scorecard.py index b872bbba..cb344021 100644 --- a/scripts/security/tests/test_gitea_private_inventory_p0_scorecard.py +++ b/scripts/security/tests/test_gitea_private_inventory_p0_scorecard.py @@ -41,7 +41,13 @@ def test_scorecard_preserves_current_gitea_inventory_blocker() -> None: assert scorecard["status"] == "blocked_waiting_gitea_authenticated_or_owner_export_inventory" assert scorecard["gitea_inventory"]["status"] == "partial" assert scorecard["gitea_inventory"]["visibility_scope"] == "public_only" - assert scorecard["gitea_inventory"]["repo_count"] == 2 + assert scorecard["gitea_inventory"]["repo_count"] == 4 + assert { + "wooo/awoooi", + "wooo/ewoooc", + "wooo/agent-bounty-protocol", + "wooo/2026FIFAWorldCup", + } <= set(scorecard["gitea_inventory"]["public_repos"]) assert scorecard["authenticated_import_acceptance"]["accepted_payload_count"] == 0 assert scorecard["coverage_attestation"]["received_attestation_count"] == 0 assert "gitea_repo_inventory_status_not_ok" in scorecard["active_blockers"]