From 4de3c004ae3d62ee5de5738970c241377423b1bb Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 1 Jun 2026 19:34:31 +0800 Subject: [PATCH] fix(web): add IwoooS S4.9 request draft package --- apps/web/messages/en.json | 4 +- apps/web/messages/zh-TW.json | 4 +- apps/web/src/app/[locale]/iwooos/page.tsx | 4 +- docs/LOGBOOK.md | 36 ++++++++ ...VENTORY-OWNER-ATTESTATION-REQUEST-DRAFT.md | 62 +++++++++++++ ...er-attestation-request-draft.snapshot.json | 86 ++++++++++++++++++ .../iwooos-posture-projection.snapshot.json | 9 +- ...ecurity-mirror-status-rollup.snapshot.json | 12 +++ .../security-mirror-progress-guard.py | 90 ++++++++++++++++++- 9 files changed, 300 insertions(+), 7 deletions(-) create mode 100644 docs/security/GITEA-INVENTORY-OWNER-ATTESTATION-REQUEST-DRAFT.md create mode 100644 docs/security/gitea-inventory-owner-attestation-request-draft.snapshot.json diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 92aac7715..468351a9f 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -5624,8 +5624,8 @@ "boundaryTitle": "工作佇列邊界", "items": { "giteaOwner": { - "title": "Gitea 負責人覆核", - "body": "確認專案清冊、可見性、負責人與覆蓋範圍。" + "title": "Gitea 補件草稿包", + "body": "五個負責人證明題目已整理成草稿;尚未送出、未收到、未接受。" }, "githubTarget": { "title": "GitHub 目標來源確認", diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index 92aac7715..468351a9f 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -5624,8 +5624,8 @@ "boundaryTitle": "工作佇列邊界", "items": { "giteaOwner": { - "title": "Gitea 負責人覆核", - "body": "確認專案清冊、可見性、負責人與覆蓋範圍。" + "title": "Gitea 補件草稿包", + "body": "五個負責人證明題目已整理成草稿;尚未送出、未收到、未接受。" }, "githubTarget": { "title": "GitHub 目標來源確認", diff --git a/apps/web/src/app/[locale]/iwooos/page.tsx b/apps/web/src/app/[locale]/iwooos/page.tsx index 593459825..e719b59d2 100644 --- a/apps/web/src/app/[locale]/iwooos/page.tsx +++ b/apps/web/src/app/[locale]/iwooos/page.tsx @@ -945,7 +945,7 @@ const progressEvidenceRailBoundaries = [ ] const evidenceUnlockQueueItems: EvidenceUnlockQueueItem[] = [ - { key: 'giteaOwner', gate: 'S4.9', value: '0/5', icon: ClipboardCheck, tone: 'warn' }, + { key: 'giteaOwner', gate: 'S4.9', value: '草稿 5', icon: ClipboardCheck, tone: 'warn' }, { key: 'githubTarget', gate: 'S4.10', value: '0/8', icon: GitBranch, tone: 'locked' }, { key: 'refTruth', gate: 'S4.11', value: '0/5', icon: Route, tone: 'warn' }, { key: 'workflowSecrets', gate: 'S4.12', value: '0/5', icon: Workflow, tone: 'locked' }, @@ -953,6 +953,8 @@ const evidenceUnlockQueueItems: EvidenceUnlockQueueItem[] = [ const evidenceUnlockQueueBoundaries = [ 'iwooos_evidence_unlock_queue_item_count=4', + 'iwooos_evidence_unlock_queue_s4_9_request_draft_template_count=5', + 'iwooos_evidence_unlock_queue_s4_9_request_draft_ready_count=1', 'iwooos_evidence_unlock_queue_request_sent_count=0', 'iwooos_evidence_unlock_queue_received_count=0', 'iwooos_evidence_unlock_queue_accepted_count=0', diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 2ed47d2c1..a3cb30751 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,39 @@ +## 2026-06-01|IwoooS S4.9 負責人補件草稿包落地 + +**背景**: + +- IwoooS 首屏已把資安進度卡在可理解的 61% 邊界,但 S4.9 的 Gitea 清冊負責人證明仍是第一個實質卡點。 +- 目前階段不能把「整理請求」誤標成「已送出、已收到、已接受」,也不能提前打開 Kali、掃描、SSH、主機更新或 GitHub primary 切換。 + +**本次調整**: + +- 新增 `docs/security/GITEA-INVENTORY-OWNER-ATTESTATION-REQUEST-DRAFT.md`,把 S4.9 五個負責人補件題目整理成可交付草稿包。 +- 新增 `docs/security/gitea-inventory-owner-attestation-request-draft.snapshot.json`,以機器可讀方式記錄 `request_draft_template_count=5`、`request_sent=false`、`owner_response_received_count=0`、`owner_response_accepted_count=0`。 +- `apps/web/src/app/[locale]/iwooos/page.tsx` 與 i18n 文案把首屏證據解鎖佇列的 S4.9 顯示從 `0/5` 改為「草稿 5」,並補上邊界訊號 `iwooos_evidence_unlock_queue_s4_9_request_draft_template_count=5`、`iwooos_evidence_unlock_queue_s4_9_request_draft_ready_count=1`。 +- `docs/security/iwooos-posture-projection.snapshot.json` 與 `security-mirror-status-rollup.snapshot.json` 增加 S2.159 台帳,明確標記這是 framework detail,不是 runtime delta。 +- `scripts/security/security-mirror-progress-guard.py` 新增 guard,防止草稿包被誤讀成 owner response、審查接受、審批紀錄或執行期授權。 + +**驗證**: + +- `python3 -m json.tool apps/web/messages/zh-TW.json` +- `python3 -m json.tool apps/web/messages/en.json` +- `cmp -s apps/web/messages/zh-TW.json apps/web/messages/en.json` +- `python3 -m json.tool docs/security/iwooos-posture-projection.snapshot.json` +- `python3 -m json.tool docs/security/security-mirror-status-rollup.snapshot.json` +- `python3 -m json.tool docs/security/gitea-inventory-owner-attestation-request-draft.snapshot.json` +- `git diff --check` +- `python3 scripts/security/security-mirror-progress-guard.py --root .` → `SECURITY_MIRROR_PROGRESS_GUARD_OK` +- `python3 scripts/security/source-control-owner-response-guard.py --root .` → `SOURCE_CONTROL_OWNER_RESPONSE_GUARD_OK` +- `pnpm --dir apps/web exec tsc --noEmit --tsBuildInfoFile /tmp/iwooos-s49-request-draft-20260601.tsbuildinfo` +- `NEXT_PUBLIC_API_URL=https://awoooi.wooo.work NEXT_PRIVATE_BUILD_WORKER_COUNT=1 pnpm --dir apps/web run build` + +**目前整體進度(本階段完成後)**: + +- 完整 IwoooS / 資安網總進度:維持 `61%`;這次完成的是 S4.9 owner request 草稿包與前端可視化,不是 owner response 驗收。 +- 框架 / 治理 / 文件 / schema / read-only evidence:約 `86-88%`;S4.9 草稿包已可交付,但仍等負責人回覆。 +- Runtime ingestion / GitHub primary / AwoooP production landing:約 `40-45%`;`request_sent_count=0`、`owner_response_received_count=0`、`owner_response_accepted_count=0`、`active_runtime_gate_count=0`。 +- Kali 192.168.0.112 與開發主機 192.168.0.111 / 192.168.0.168 仍維持已納入框架、未啟動掃描 / 修復 / 更新 / 重啟的邊界。 + ## 2026-06-01|治理 SLO 前端顯示已封口觀察中 **背景**: diff --git a/docs/security/GITEA-INVENTORY-OWNER-ATTESTATION-REQUEST-DRAFT.md b/docs/security/GITEA-INVENTORY-OWNER-ATTESTATION-REQUEST-DRAFT.md new file mode 100644 index 000000000..02f6e6005 --- /dev/null +++ b/docs/security/GITEA-INVENTORY-OWNER-ATTESTATION-REQUEST-DRAFT.md @@ -0,0 +1,62 @@ +# Gitea 清冊負責人證明補件草稿 + +| 項目 | 內容 | +|------|------| +| 日期 | 2026-06-01 | +| 狀態 | 草稿已整理,尚未送出 | +| 對應階段 | S4.9 | +| 對應收件包 | `docs/security/GITEA-INVENTORY-OWNER-ATTESTATION-RESPONSE.md` | +| 快照 | `docs/security/gitea-inventory-owner-attestation-request-draft.snapshot.json` | +| 模式 | `owner_request_draft_only` | +| 執行面授權 | `false` | + +## 1. 草稿目的 + +此草稿把 S4.9 需要負責人補齊的五項 Gitea 清冊證明整理成可交付內容。它只用於人工判讀與後續送件準備,不代表已送出請求、不代表已收到回覆,也不代表任何 Gitea / GitHub / refs / workflow / secret / Kali 執行授權。 + +## 2. 五個補件題目 + +| 順序 | Template | 負責人需要回覆 | 目前狀態 | +|------|----------|----------------|----------| +| 1 | `response-public-only-vs-local-gitea-gap` | `wooo/clawbot-v5`、`wooo/wooo-aiops` 是否屬本輪 inventory / migration scope | 草稿完成,未送出 | +| 2 | `response-org-user-endpoint-identity` | `wooo` 在 Gitea 中應以 user、org 或兩者盤點 | 草稿完成,未送出 | +| 3 | `response-internal-110-adjacent-scope` | `bitan-pharmacy`、`root/momo-pro-system`、`tsenyang-website`、`wooo/wooo-infra-config` 是否納入本輪 scope | 草稿完成,未送出 | +| 4 | `response-repo-owner-canonical-scope` | in-scope repo 的 owner、canonical source、GitHub target candidate 與 visibility review owner | 草稿完成,未送出 | +| 5 | `response-legacy-or-inaccessible-disposition` | legacy、inaccessible 或 external repo 的 disposition、理由與後續 owner | 草稿完成,未送出 | + +## 3. 回覆格式 + +每一題都只接受下列欄位: + +- `owner_role_or_team` +- `decision` +- `decision_reason` +- `affected_repos`、`affected_sources` 或 `canonical_namespace` +- `evidence_refs` +- `followup_owner` + +`evidence_refs` 只能指向 repo 內文件、snapshot 或負責人提供的脫敏 metadata。若資料可能包含 token、secret、private key、cookie、session、DB dump、git object pack 或 repo archive,必須改用 quarantine pointer,不得貼原文。 + +## 4. 明確禁止 + +- 不收 token、PAT、webhook secret、repository secret value、runner registration token 或 deploy key private key。 +- 不收 DB dump、repo archive、git object pack、裸 repo tarball 或可還原憑證的 artifact。 +- 不建立、不刪除、不封存、不修改 Gitea repo。 +- 不建立 GitHub repo、不改 visibility、不同步 refs、不刪 refs、不 force push。 +- 不切 GitHub primary、不停用 Gitea、不啟用 GitHub hosted runner。 +- 不啟動 Kali、SSH、掃描、主機更新、修復或部署。 + +## 5. 目前狀態 + +| 指標 | 值 | +|------|----| +| request draft package | ready | +| request draft template count | 5 | +| request sent | false | +| request sent count | 0 | +| recipients confirmed count | 0 | +| owner response received count | 0 | +| owner response accepted count | 0 | +| runtime gate opened | false | +| action buttons allowed | false | + diff --git a/docs/security/gitea-inventory-owner-attestation-request-draft.snapshot.json b/docs/security/gitea-inventory-owner-attestation-request-draft.snapshot.json new file mode 100644 index 000000000..8ea8ba566 --- /dev/null +++ b/docs/security/gitea-inventory-owner-attestation-request-draft.snapshot.json @@ -0,0 +1,86 @@ +{ + "schema_version": "gitea_inventory_owner_attestation_request_draft_v1", + "status": "request_draft_ready_not_sent", + "date": "2026-06-01", + "stage_id": "S4.9", + "mode": "owner_request_draft_only", + "runtime_execution_authorized": false, + "source_packet": "docs/security/GITEA-INVENTORY-OWNER-ATTESTATION-RESPONSE.md", + "source_snapshot": "docs/security/gitea-inventory-owner-attestation-response.snapshot.json", + "summary": { + "request_draft_package_ready": true, + "request_draft_template_count": 5, + "request_sent": false, + "request_sent_count": 0, + "recipients_confirmed_count": 0, + "owner_response_received_count": 0, + "owner_response_accepted_count": 0, + "owner_response_rejected_count": 0, + "audit_events_emitted_count": 0, + "runtime_gate_opened": false, + "action_buttons_allowed": false, + "not_authorization": true + }, + "request_draft_templates": [ + { + "template_id": "response-public-only-vs-local-gitea-gap", + "display_order": 1, + "attestation_item_id": "public_only_vs_local_gitea_gap", + "draft_status": "ready_not_sent", + "owner_question": "判定 wooo/clawbot-v5 與 wooo/wooo-aiops 是否屬本輪 inventory / migration scope。", + "required_fields": ["owner_role_or_team", "decision", "decision_reason", "affected_repos", "evidence_refs", "followup_owner"] + }, + { + "template_id": "response-org-user-endpoint-identity", + "display_order": 2, + "attestation_item_id": "org_user_endpoint_identity", + "draft_status": "ready_not_sent", + "owner_question": "說明 wooo 在 Gitea 中應以 user、org 或兩者盤點。", + "required_fields": ["owner_role_or_team", "decision", "decision_reason", "canonical_namespace", "evidence_refs", "followup_owner"] + }, + { + "template_id": "response-internal-110-adjacent-scope", + "display_order": 3, + "attestation_item_id": "internal_110_adjacent_scope", + "draft_status": "ready_not_sent", + "owner_question": "逐項判定 bitan-pharmacy、root/momo-pro-system、tsenyang-website、wooo/wooo-infra-config 是否納入本輪 scope。", + "required_fields": ["owner_role_or_team", "decision", "decision_reason", "affected_sources", "evidence_refs", "followup_owner"] + }, + { + "template_id": "response-repo-owner-canonical-scope", + "display_order": 4, + "attestation_item_id": "repo_owner_canonical_scope", + "draft_status": "ready_not_sent", + "owner_question": "為 in-scope repo 指定 owner、canonical source、GitHub target candidate 與 visibility review owner。", + "required_fields": ["owner_role_or_team", "decision", "decision_reason", "affected_repos", "evidence_refs", "followup_owner"] + }, + { + "template_id": "response-legacy-or-inaccessible-disposition", + "display_order": 5, + "attestation_item_id": "legacy_or_inaccessible_repo_disposition", + "draft_status": "ready_not_sent", + "owner_question": "對 legacy、inaccessible 或 external repo 留下 disposition、理由與後續 owner。", + "required_fields": ["owner_role_or_team", "decision", "decision_reason", "affected_repos", "evidence_refs", "followup_owner"] + } + ], + "allowed_outputs": [ + "owner role/team metadata", + "decision and decision reason", + "affected repo/source/namespace metadata", + "redacted evidence refs", + "followup owner" + ], + "forbidden_actions": [ + "collect_secret_plaintext", + "collect_repo_archive", + "write_gitea", + "create_github_repo", + "change_repo_visibility", + "sync_or_delete_refs", + "force_push_refs", + "switch_github_primary", + "disable_gitea", + "open_runtime_gate" + ], + "not_authorization": true +} diff --git a/docs/security/iwooos-posture-projection.snapshot.json b/docs/security/iwooos-posture-projection.snapshot.json index 27273beb5..28f640842 100644 --- a/docs/security/iwooos-posture-projection.snapshot.json +++ b/docs/security/iwooos-posture-projection.snapshot.json @@ -10,6 +10,8 @@ "docs/security/security-rollout-policy.snapshot.json", "docs/security/source-control-owner-response-validation-rollup.snapshot.json", "docs/security/source-control-primary-readiness-gate.snapshot.json", + "docs/security/GITEA-INVENTORY-OWNER-ATTESTATION-REQUEST-DRAFT.md", + "docs/security/gitea-inventory-owner-attestation-request-draft.snapshot.json", "docs/security/kali-integration-status.snapshot.json", "apps/web/src/app/[locale]/iwooos/page.tsx", "apps/web/src/app/[locale]/security-compliance/page.tsx", @@ -54,6 +56,8 @@ "progress_evidence_rail_runtime_gate_count": 0, "evidence_unlock_queue_first_layer": true, "evidence_unlock_queue_item_count": 4, + "evidence_unlock_queue_s4_9_request_draft_template_count": 5, + "evidence_unlock_queue_s4_9_request_draft_ready_count": 1, "evidence_unlock_queue_request_sent_count": 0, "evidence_unlock_queue_received_count": 0, "evidence_unlock_queue_accepted_count": 0, @@ -429,7 +433,10 @@ "display_order": 1, "gate": "S4.9", "display_mode": "first_screen_evidence_unlock_queue", - "value": "0/5", + "value": "草稿 5", + "request_draft_package_ready": true, + "request_draft_template_count": 5, + "request_draft_ready_count": 1, "request_sent_count": 0, "received_count": 0, "accepted_count": 0, diff --git a/docs/security/security-mirror-status-rollup.snapshot.json b/docs/security/security-mirror-status-rollup.snapshot.json index 04b74ab4c..728d8cb72 100644 --- a/docs/security/security-mirror-status-rollup.snapshot.json +++ b/docs/security/security-mirror-status-rollup.snapshot.json @@ -2377,6 +2377,18 @@ "runtime_delta": false, "execution_authorized": false, "not_authorization": true + }, + { + "delta_id": "s2_159_iwooos_s49_request_draft_package", + "display_order": 188, + "completed_stage": "S2.159 IwoooS S4.9 負責人補件草稿包", + "progress_axis": "framework_detail", + "headline_percent_delta": 0, + "framework_delta_visible": true, + "why_headline_unchanged": "IwoooS 只把 S4.9 Gitea 清冊負責人證明的五個補件題目整理成可交付草稿包,並在首屏工作佇列顯示草稿 5;iwooos_evidence_unlock_queue_s4_9_request_draft_template_count=5、iwooos_evidence_unlock_queue_s4_9_request_draft_ready_count=1、iwooos_evidence_unlock_queue_request_sent_count=0、iwooos_evidence_unlock_queue_received_count=0、iwooos_evidence_unlock_queue_accepted_count=0、runtime_execution_authorized=false、active_runtime_gate_count=0、action_buttons_allowed=false,不把草稿包當請求送出、負責人回覆收到、審查接受、審批紀錄、掃描、修復、部署、主機更新、GitHub primary 切換或 Gitea 停用。", + "runtime_delta": false, + "execution_authorized": false, + "not_authorization": true } ], "next_safe_actions": [ diff --git a/scripts/security/security-mirror-progress-guard.py b/scripts/security/security-mirror-progress-guard.py index 2b2c10da9..a8fa3ba5e 100755 --- a/scripts/security/security-mirror-progress-guard.py +++ b/scripts/security/security-mirror-progress-guard.py @@ -87,6 +87,7 @@ def validate(root: Path) -> None: primary_gate = load_json(security_dir / "source-control-primary-readiness-gate.snapshot.json") rollout_policy = load_json(security_dir / "security-rollout-policy.snapshot.json") iwooos_projection = load_json(security_dir / "iwooos-posture-projection.snapshot.json") + s49_request_draft = load_json(security_dir / "gitea-inventory-owner-attestation-request-draft.snapshot.json") kali_status = load_json(security_dir / "kali-integration-status.snapshot.json") iwooos_projection_page = ( root / "apps" / "web" / "src" / "app" / "[locale]" / "iwooos" / "page.tsx" @@ -747,6 +748,7 @@ def validate(root: Path) -> None: "s2_156_iwooos_first_screen_depth_map", "s2_157_iwooos_progress_evidence_rail", "s2_158_iwooos_evidence_unlock_queue", + "s2_159_iwooos_s49_request_draft_package", ] assert_equal( "progress_delta_ledger.delta_ids", @@ -1701,6 +1703,16 @@ def validate(root: Path) -> None: iwooos_projection["summary"]["evidence_unlock_queue_item_count"], 4, ) + assert_equal( + "iwooos_projection.summary.evidence_unlock_queue_s4_9_request_draft_template_count", + iwooos_projection["summary"]["evidence_unlock_queue_s4_9_request_draft_template_count"], + 5, + ) + assert_equal( + "iwooos_projection.summary.evidence_unlock_queue_s4_9_request_draft_ready_count", + iwooos_projection["summary"]["evidence_unlock_queue_s4_9_request_draft_ready_count"], + 1, + ) assert_equal( "iwooos_projection.summary.evidence_unlock_queue_request_sent_count", iwooos_projection["summary"]["evidence_unlock_queue_request_sent_count"], @@ -3274,6 +3286,65 @@ def validate(root: Path) -> None: iwooos_projection["summary"]["s4_9_owner_response_request_template_count"], len(expected_s4_9_owner_response_request_template_ids), ) + assert_equal( + "s49_request_draft.schema_version", + s49_request_draft["schema_version"], + "gitea_inventory_owner_attestation_request_draft_v1", + ) + assert_equal("s49_request_draft.status", s49_request_draft["status"], "request_draft_ready_not_sent") + assert_equal("s49_request_draft.stage_id", s49_request_draft["stage_id"], "S4.9") + assert_equal("s49_request_draft.mode", s49_request_draft["mode"], "owner_request_draft_only") + assert_false("s49_request_draft.runtime_execution_authorized", s49_request_draft["runtime_execution_authorized"]) + assert_true( + "s49_request_draft.summary.request_draft_package_ready", + s49_request_draft["summary"]["request_draft_package_ready"], + ) + assert_equal( + "s49_request_draft.summary.request_draft_template_count", + s49_request_draft["summary"]["request_draft_template_count"], + len(expected_s4_9_owner_response_request_template_ids), + ) + assert_false("s49_request_draft.summary.request_sent", s49_request_draft["summary"]["request_sent"]) + assert_equal("s49_request_draft.summary.request_sent_count", s49_request_draft["summary"]["request_sent_count"], 0) + assert_equal( + "s49_request_draft.summary.owner_response_received_count", + s49_request_draft["summary"]["owner_response_received_count"], + 0, + ) + assert_equal( + "s49_request_draft.summary.owner_response_accepted_count", + s49_request_draft["summary"]["owner_response_accepted_count"], + 0, + ) + assert_equal( + "s49_request_draft.summary.owner_response_rejected_count", + s49_request_draft["summary"]["owner_response_rejected_count"], + 0, + ) + assert_equal( + "s49_request_draft.summary.audit_events_emitted_count", + s49_request_draft["summary"]["audit_events_emitted_count"], + 0, + ) + assert_false("s49_request_draft.summary.runtime_gate_opened", s49_request_draft["summary"]["runtime_gate_opened"]) + assert_false("s49_request_draft.summary.action_buttons_allowed", s49_request_draft["summary"]["action_buttons_allowed"]) + assert_true("s49_request_draft.summary.not_authorization", s49_request_draft["summary"]["not_authorization"]) + assert_equal( + "s49_request_draft.request_draft_templates.ids", + [item["template_id"] for item in s49_request_draft["request_draft_templates"]], + expected_s4_9_owner_response_request_template_ids, + ) + assert_equal( + "s49_request_draft.request_draft_templates.display_order", + [item["display_order"] for item in s49_request_draft["request_draft_templates"]], + list(range(1, len(expected_s4_9_owner_response_request_template_ids) + 1)), + ) + for item in s49_request_draft["request_draft_templates"]: + assert_equal( + f"s49_request_draft.request_draft_templates.{item['template_id']}.draft_status", + item["draft_status"], + "ready_not_sent", + ) s4_9_owner_response_request_templates = iwooos_projection["s4_9_owner_response_request_templates"] assert_equal( "iwooos_projection.s4_9_owner_response_request_templates.ids", @@ -12653,7 +12724,7 @@ def validate(root: Path) -> None: assert_equal("iwooos_projection.evidence_unlock_queue_items.refTruth.gate", evidence_unlock_queue_gates["refTruth"], "S4.11") assert_equal("iwooos_projection.evidence_unlock_queue_items.workflowSecrets.gate", evidence_unlock_queue_gates["workflowSecrets"], "S4.12") evidence_unlock_queue_values = {item["item_id"]: item["value"] for item in evidence_unlock_queue_items} - assert_equal("iwooos_projection.evidence_unlock_queue_items.giteaOwner.value", evidence_unlock_queue_values["giteaOwner"], "0/5") + assert_equal("iwooos_projection.evidence_unlock_queue_items.giteaOwner.value", evidence_unlock_queue_values["giteaOwner"], "草稿 5") assert_equal("iwooos_projection.evidence_unlock_queue_items.githubTarget.value", evidence_unlock_queue_values["githubTarget"], "0/8") assert_equal("iwooos_projection.evidence_unlock_queue_items.refTruth.value", evidence_unlock_queue_values["refTruth"], "0/5") assert_equal("iwooos_projection.evidence_unlock_queue_items.workflowSecrets.value", evidence_unlock_queue_values["workflowSecrets"], "0/5") @@ -12682,6 +12753,21 @@ def validate(root: Path) -> None: f"iwooos_projection.evidence_unlock_queue_items.{item_id}.not_authorization", item["not_authorization"], ) + gitea_owner_queue_item = next(item for item in evidence_unlock_queue_items if item["item_id"] == "giteaOwner") + assert_true( + "iwooos_projection.evidence_unlock_queue_items.giteaOwner.request_draft_package_ready", + gitea_owner_queue_item["request_draft_package_ready"], + ) + assert_equal( + "iwooos_projection.evidence_unlock_queue_items.giteaOwner.request_draft_template_count", + gitea_owner_queue_item["request_draft_template_count"], + 5, + ) + assert_equal( + "iwooos_projection.evidence_unlock_queue_items.giteaOwner.request_draft_ready_count", + gitea_owner_queue_item["request_draft_ready_count"], + 1, + ) github_target_queue_item = next(item for item in evidence_unlock_queue_items if item["item_id"] == "githubTarget") assert_equal( "iwooos_projection.evidence_unlock_queue_items.githubTarget.candidate_repo_count", @@ -12821,6 +12907,8 @@ def validate(root: Path) -> None: ) for text in [ "iwooos_evidence_unlock_queue_item_count=4", + "iwooos_evidence_unlock_queue_s4_9_request_draft_template_count=5", + "iwooos_evidence_unlock_queue_s4_9_request_draft_ready_count=1", "iwooos_evidence_unlock_queue_request_sent_count=0", "iwooos_evidence_unlock_queue_received_count=0", "iwooos_evidence_unlock_queue_accepted_count=0",