diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json
index 7a46730eb..7aea0d7de 100644
--- a/apps/web/messages/en.json
+++ b/apps/web/messages/en.json
@@ -2787,6 +2787,45 @@
}
}
},
+ "s49OwnerResponseRequestTemplates": {
+ "title": "S4.9 Owner Response Five Templates",
+ "subtitle": "S2.49 surfaces the five S4.9 templates the owner must answer one by one. This is only a request-ready list: the request is not sent, there is no chasing or autofill, no received / accepted marking, and no template is treated as Gitea inventory or GitHub migration approval.",
+ "templateLabel": "Template",
+ "ownerActionLabel": "Owner response",
+ "guardLabel": "Still forbidden",
+ "items": {
+ "publicOnlyVsLocalGiteaGap": {
+ "title": "Public-only / local Gitea gap",
+ "body": "Decide whether `wooo/clawbot-v5` and `wooo/wooo-aiops` belong in the current inventory / migration scope.",
+ "ownerAction": "Reply per repo with in scope, out of scope, legacy archived, external system, inaccessible, or needs more evidence, plus redacted evidence refs.",
+ "guard": "request_ready_not_sent; received=0; accepted=0; no Gitea writes, repo creation, or refs sync."
+ },
+ "orgUserEndpointIdentity": {
+ "title": "Gitea `wooo` org/user endpoint",
+ "body": "Clarify whether `wooo` in Gitea should be inventoried as a user, an org, or both, without treating endpoint 404 as absence.",
+ "ownerAction": "Reply with canonical endpoint identity, verification method, and follow-up owner.",
+ "guard": "No admin API calls, token use, or endpoint decision as inventory completed."
+ },
+ "internal110AdjacentScope": {
+ "title": "110 adjacent source scope",
+ "body": "Decide whether `bitan-pharmacy`, `root/momo-pro-system`, `tsenyang-website`, and `wooo/wooo-infra-config` belong in this scope.",
+ "ownerAction": "Classify each as in scope / out of scope / legacy / external / inaccessible, with redacted source evidence.",
+ "guard": "No private repo content reads, archive imports, or automatic migration inclusion."
+ },
+ "repoOwnerCanonicalScope": {
+ "title": "Repo owner / canonical / GitHub target",
+ "body": "Assign owner, canonical source, GitHub target candidate, and visibility review owner for in-scope repos.",
+ "ownerAction": "Reply with owner role/team, canonical source, GitHub target candidate, visibility review owner, and rationale.",
+ "guard": "No GitHub repo creation, visibility change, primary switch, or target candidate as approval."
+ },
+ "legacyOrInaccessibleDisposition": {
+ "title": "Legacy / inaccessible disposition",
+ "body": "Record disposition, rationale, and follow-up owner for legacy, inaccessible, or external repos.",
+ "ownerAction": "Mark archive, exclude, follow-up evidence, or external owner, with redacted trace.",
+ "guard": "No deletion, disabling, or repo archival; disposition is human classification, not execution."
+ }
+ }
+ },
"s49OwnerResponsePreflight": {
"title": "S4.9 Owner Response Intake Preflight",
"subtitle": "S2.48 surfaces the 6 S4.9 intake preflight checks in IwoooS: known attestation item, complete fields, allowed decision, redacted evidence, no execution request, and no accepted state until all five items are covered. This is preflight display only: no request send, received marking, or audit event creation.",
diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json
index 3792a4a6f..a46010c66 100644
--- a/apps/web/messages/zh-TW.json
+++ b/apps/web/messages/zh-TW.json
@@ -2788,6 +2788,45 @@
}
}
},
+ "s49OwnerResponseRequestTemplates": {
+ "title": "S4.9 Owner Response 五個回覆 Template",
+ "subtitle": "S2.49 將 S4.9 owner 要逐項回答的五個 template 顯示在 IwoooS。這裡只是 request-ready 清單:request 仍未送出、不催收、不代填、不標記 received / accepted,也不把任何 template 當成 Gitea inventory 或 GitHub migration approval。",
+ "templateLabel": "Template",
+ "ownerActionLabel": "Owner 要回覆",
+ "guardLabel": "仍禁止",
+ "items": {
+ "publicOnlyVsLocalGiteaGap": {
+ "title": "Public-only / local Gitea gap",
+ "body": "判定 `wooo/clawbot-v5` 與 `wooo/wooo-aiops` 是否屬於本輪 inventory / migration scope。",
+ "ownerAction": "逐 repo 回覆 in scope、out of scope、legacy archived、external system、inaccessible 或 needs more evidence,並引用脫敏 evidence refs。",
+ "guard": "request_ready_not_sent;received=0;accepted=0;不寫 Gitea、不建立 repo、不 sync refs。"
+ },
+ "orgUserEndpointIdentity": {
+ "title": "Gitea `wooo` org/user endpoint",
+ "body": "釐清 `wooo` 在 Gitea 中應以 user、org 或兩者盤點,避免把 endpoint 404 誤讀成不存在。",
+ "ownerAction": "回覆 canonical endpoint 身分、查證方式與後續 owner。",
+ "guard": "不呼叫 admin API、不使用 token、不把 endpoint 判定當成 inventory completed。"
+ },
+ "internal110AdjacentScope": {
+ "title": "110 adjacent source scope",
+ "body": "判定 `bitan-pharmacy`、`root/momo-pro-system`、`tsenyang-website`、`wooo/wooo-infra-config` 是否納入本輪 scope。",
+ "ownerAction": "逐項標示 in scope / out of scope / legacy / external / inaccessible,並補脫敏來源證據。",
+ "guard": "不讀取私有 repo 內容、不匯入 archive、不把 110 adjacent source 自動納入 migration。"
+ },
+ "repoOwnerCanonicalScope": {
+ "title": "Repo owner / canonical / GitHub target",
+ "body": "為 in-scope repo 指定 owner、canonical source、GitHub target candidate 與 visibility review owner。",
+ "ownerAction": "回覆 owner role/team、canonical source、GitHub target candidate、visibility review owner 與理由。",
+ "guard": "不建立 GitHub repo、不改 visibility、不切 primary、不把 target candidate 當 approval。"
+ },
+ "legacyOrInaccessibleDisposition": {
+ "title": "Legacy / inaccessible disposition",
+ "body": "對 legacy、inaccessible 或 external repo 留下 disposition、理由與 follow-up owner。",
+ "ownerAction": "標示 archive、exclude、follow-up evidence 或 external owner,並保留脫敏 trace。",
+ "guard": "不刪除、不停用、不封存 repo;disposition 只是人工分類,不是執行命令。"
+ }
+ }
+ },
"s49OwnerResponsePreflight": {
"title": "S4.9 Owner Response 收件前 Preflight",
"subtitle": "S2.48 把 S4.9 的 6 個收件前檢查拉到 IwoooS:先確認回覆是否對應已知 attestation item、欄位完整、decision 合法、evidence 脫敏、沒有執行要求,且五個 items 到齊前不得 accepted。這裡只顯示 preflight,不寄送 request、不標記 received、不建立 audit event。",
diff --git a/apps/web/src/app/[locale]/iwooos/page.tsx b/apps/web/src/app/[locale]/iwooos/page.tsx
index ccb93012f..b9840fab5 100644
--- a/apps/web/src/app/[locale]/iwooos/page.tsx
+++ b/apps/web/src/app/[locale]/iwooos/page.tsx
@@ -52,6 +52,13 @@ type S49OwnerResponsePreflightCheck = {
tone: 'steady' | 'warn' | 'locked'
}
+type S49OwnerResponseRequestTemplate = {
+ key: string
+ template: string
+ icon: typeof ShieldCheck
+ tone: 'steady' | 'warn' | 'locked'
+}
+
type Pillar = {
key: string
icon: typeof ShieldCheck
@@ -353,6 +360,14 @@ const s49OwnerResponsePreflightChecks: S49OwnerResponsePreflightCheck[] = [
{ key: 'allFiveItemsBeforeAccepted', check: 'P6', icon: ShieldCheck, tone: 'locked' },
]
+const s49OwnerResponseRequestTemplates: S49OwnerResponseRequestTemplate[] = [
+ { key: 'publicOnlyVsLocalGiteaGap', template: 'T1', icon: GitBranch, tone: 'warn' },
+ { key: 'orgUserEndpointIdentity', template: 'T2', icon: SearchCheck, tone: 'warn' },
+ { key: 'internal110AdjacentScope', template: 'T3', icon: Radar, tone: 'warn' },
+ { key: 'repoOwnerCanonicalScope', template: 'T4', icon: ClipboardCheck, tone: 'warn' },
+ { key: 'legacyOrInaccessibleDisposition', template: 'T5', icon: FileWarning, tone: 'locked' },
+]
+
const posturePillars: Pillar[] = [
{ key: 'exposure', icon: Radar, tone: 'warn' },
{ key: 'sourceControl', icon: GitBranch, tone: 'warn' },
@@ -926,6 +941,38 @@ function S49OwnerResponsePreflightCard({ item }: { item: S49OwnerResponsePreflig
)
}
+function S49OwnerResponseRequestTemplateCard({ item }: { item: S49OwnerResponseRequestTemplate }) {
+ const t = useTranslations('iwooos.s49OwnerResponseRequestTemplates')
+ const Icon = item.icon
+ return (
+
{t('s49OwnerResponsePreflight.title')}
diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md
index 176c4ddca..3fdc098f6 100644
--- a/docs/LOGBOOK.md
+++ b/docs/LOGBOOK.md
@@ -1,3 +1,17 @@
+## 2026-05-20 | 資安供應鏈 S2.49:IwoooS S4.9 Owner Response Request Templates
+
+**背景**:S2.48 已把 S4.9 收件前 preflight 顯示在 IwoooS;本輪把 owner 真正要逐項回覆的五個 request templates 顯示出來,讓下一個 P0 owner response 不只知道「如何驗收」,也知道「要回覆哪五題」。
+
+**完成**:
+- `/iwooos` 新增「S4.9 Owner Response 五個回覆 Template」,顯示 public-only / local Gitea gap、Gitea `wooo` org/user endpoint、110 adjacent source scope、repo owner / canonical / GitHub target、legacy / inaccessible disposition 五個 request-ready-not-sent templates。
+- `iwooos_posture_projection_v1` schema / snapshot 新增 `s4_9_owner_response_request_templates` 與 `s4_9_owner_response_request_template_count=5`,每個 template 固定 request sent / received / accepted / rejected / audit emitted = 0,auto chase / autofill / request send / mark received / mark accepted / approval record / Gitea inventory completed / Gitea write / repo or refs mutation / GitHub primary ready / secret value collection / runtime execution / action button = false。
+- `security_mirror_status_rollup_v1` micro progress ledger 新增 `s2_49_iwooos_s4_9_owner_response_request_templates`,headline progress 仍維持 58%。
+- `security-mirror-progress-guard.py` 開始驗證 5 個 S4.9 request templates、template ids、attestation item ids、request-ready-not-sent 狀態與 zero / false 邊界。
+
+**仍禁止**:
+- S4.9 owner response request templates 不代表 request sent、owner response received / accepted / rejected、audit event emitted、approval record、Gitea inventory completed、Gitea write、repo / refs mutation、token collection、GitHub primary readiness、runtime gate、Kali `/execute`、SSH、主機變更、Kali 更新或 blocking control。
+- 真正進度仍要等 owner 以脫敏 evidence 回覆五個 templates,通過 S4.9 preflight / S4.13 rollup,並保持 runtime gate 與 source-control cutover 獨立批准。
+
## 2026-05-20 | 資安供應鏈 S2.48:IwoooS S4.9 Owner Response Preflight
**背景**:S2.47 已把下一個 P0 owner response 焦點固定在 S4.9 Gitea owner attestation;本輪把 S4.9 真正收件前需要確認的 preflight 條件顯示在 IwoooS,讓後續 owner response 可被準備與人工判讀,但不把 preflight 誤認成 request sent、received、accepted 或 runtime authorization。
diff --git a/docs/schemas/iwooos_posture_projection_v1.schema.json b/docs/schemas/iwooos_posture_projection_v1.schema.json
index 7fa5e0af3..b898645f7 100644
--- a/docs/schemas/iwooos_posture_projection_v1.schema.json
+++ b/docs/schemas/iwooos_posture_projection_v1.schema.json
@@ -17,6 +17,7 @@
"progress_acceleration_lanes",
"owner_response_next_action_focus_items",
"s4_9_owner_response_preflight_checks",
+ "s4_9_owner_response_request_templates",
"posture_pillars",
"non_blocking_lane_ids",
"existing_frontend_surfaces",
@@ -149,7 +150,8 @@
"progress_acceleration_lane_count",
"action_buttons_allowed",
"owner_response_next_action_focus_item_count",
- "s4_9_owner_response_preflight_check_count"
+ "s4_9_owner_response_preflight_check_count",
+ "s4_9_owner_response_request_template_count"
],
"properties": {
"route_path": {
@@ -358,6 +360,10 @@
"s4_9_owner_response_preflight_check_count": {
"type": "integer",
"const": 6
+ },
+ "s4_9_owner_response_request_template_count": {
+ "type": "integer",
+ "const": 5
}
},
"additionalProperties": false
@@ -4043,6 +4049,147 @@
"additionalProperties": false
}
},
+ "s4_9_owner_response_request_templates": {
+ "type": "array",
+ "minItems": 5,
+ "maxItems": 5,
+ "items": {
+ "type": "object",
+ "required": [
+ "template_id",
+ "display_order",
+ "source_template_status_id",
+ "attestation_item_id",
+ "request_status",
+ "current_state",
+ "next_owner_action_summary",
+ "display_mode",
+ "request_sent_count",
+ "owner_response_received_count",
+ "owner_response_accepted_count",
+ "owner_response_rejected_count",
+ "audit_events_emitted_count",
+ "auto_chase_allowed",
+ "autofill_allowed",
+ "request_send_allowed",
+ "mark_received_allowed",
+ "mark_accepted_allowed",
+ "approval_record_created",
+ "gitea_inventory_completed",
+ "gitea_write_allowed",
+ "repo_or_refs_mutation_allowed",
+ "github_primary_ready",
+ "secret_value_collection_allowed",
+ "runtime_execution_authorized",
+ "action_buttons_allowed",
+ "not_authorization"
+ ],
+ "properties": {
+ "template_id": {
+ "type": "string"
+ },
+ "display_order": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "source_template_status_id": {
+ "type": "string"
+ },
+ "attestation_item_id": {
+ "type": "string"
+ },
+ "request_status": {
+ "const": "request_ready_not_sent"
+ },
+ "current_state": {
+ "const": "waiting_owner_response"
+ },
+ "next_owner_action_summary": {
+ "type": "string"
+ },
+ "display_mode": {
+ "const": "s4_9_owner_response_request_template_only"
+ },
+ "request_sent_count": {
+ "type": "integer",
+ "const": 0
+ },
+ "owner_response_received_count": {
+ "type": "integer",
+ "const": 0
+ },
+ "owner_response_accepted_count": {
+ "type": "integer",
+ "const": 0
+ },
+ "owner_response_rejected_count": {
+ "type": "integer",
+ "const": 0
+ },
+ "audit_events_emitted_count": {
+ "type": "integer",
+ "const": 0
+ },
+ "auto_chase_allowed": {
+ "type": "boolean",
+ "const": false
+ },
+ "autofill_allowed": {
+ "type": "boolean",
+ "const": false
+ },
+ "request_send_allowed": {
+ "type": "boolean",
+ "const": false
+ },
+ "mark_received_allowed": {
+ "type": "boolean",
+ "const": false
+ },
+ "mark_accepted_allowed": {
+ "type": "boolean",
+ "const": false
+ },
+ "approval_record_created": {
+ "type": "boolean",
+ "const": false
+ },
+ "gitea_inventory_completed": {
+ "type": "boolean",
+ "const": false
+ },
+ "gitea_write_allowed": {
+ "type": "boolean",
+ "const": false
+ },
+ "repo_or_refs_mutation_allowed": {
+ "type": "boolean",
+ "const": false
+ },
+ "github_primary_ready": {
+ "type": "boolean",
+ "const": false
+ },
+ "secret_value_collection_allowed": {
+ "type": "boolean",
+ "const": false
+ },
+ "runtime_execution_authorized": {
+ "type": "boolean",
+ "const": false
+ },
+ "action_buttons_allowed": {
+ "type": "boolean",
+ "const": false
+ },
+ "not_authorization": {
+ "type": "boolean",
+ "const": true
+ }
+ },
+ "additionalProperties": false
+ }
+ },
"s4_9_owner_response_preflight_checks": {
"type": "array",
"minItems": 6,
diff --git a/docs/security/IWOOOS-POSTURE-PROJECTION.md b/docs/security/IWOOOS-POSTURE-PROJECTION.md
index c5f96a14f..3ef4f04ee 100644
--- a/docs/security/IWOOOS-POSTURE-PROJECTION.md
+++ b/docs/security/IWOOOS-POSTURE-PROJECTION.md
@@ -76,6 +76,7 @@ IwoooS 首版只讀取或對齊以下已提交 evidence:
44. 6 條 progress acceleration lanes,直接顯示 58% 為何維持、哪些高層 gate 能解鎖下一輪進度判讀,以及後續節奏要改成 milestone batch,但不把 acceleration lane 當授權、加分、owner response、runtime gate、GitHub primary 或 production execution。
45. 4 個 owner response next-action focus items,直接顯示 S4.9 目前是下一個收件焦點,S4.10 / S4.11 / S4.12 依序排隊,但不催收、不代填、不標記 received / accepted、不建立 approval record、不開 runtime gate。
46. 6 個 S4.9 owner response preflight checks,直接顯示第一個 P0 owner response 在收件前要確認的已知 item、必填欄位、allowed decision、脫敏 evidence、無 execution request 與五項到齊規則,但不寄送 request、不標記 received / accepted、不建立 audit event、不寫 Gitea、不 sync refs、不開 runtime gate。
+47. 5 個 S4.9 owner response request templates,直接顯示 owner 要逐項回覆的 public-only / local gap、org/user endpoint、110 adjacent source、repo owner / canonical scope、legacy / inaccessible disposition,但不送出 request、不催收、不代填、不標記 received / accepted、不完成 Gitea inventory、不寫 Gitea、不 sync refs、不切 GitHub primary。
## 3.1 既有前端資安頁面整合
@@ -778,6 +779,22 @@ S2.48 將 S4.9 owner response 的收件前 preflight 從 Gitea owner attestation
這個 preflight board 不代表 S4.9 request 已送出、owner response 已收到、owner response 已接受、audit event 已建立或 Gitea / GitHub migration 可執行。它只把第一個能真正推動 58% 的 owner response 收件條件顯示清楚。
+## 3.40 S4.9 Owner Response Request Templates
+
+S2.49 將 S4.9 owner response 的五個 request templates 拉到 IwoooS 可見面板。這一層只回答「owner 要逐項回覆哪五題」,不送出 request、不催收、不代填、不標記 received、不標記 accepted、不建立 audit event、不完成 Gitea inventory、不寫 Gitea、不 sync refs、不切 GitHub primary。
+
+| 順序 | Template | Attestation item | 目前狀態 |
+|------|----------|------------------|----------|
+| 1 | Public-only / local Gitea gap | `public_only_vs_local_gitea_gap` | request ready not sent |
+| 2 | Gitea `wooo` org/user endpoint | `org_user_endpoint_identity` | request ready not sent |
+| 3 | 110 adjacent source scope | `internal_110_adjacent_scope` | request ready not sent |
+| 4 | Repo owner / canonical / GitHub target | `repo_owner_canonical_scope` | request ready not sent |
+| 5 | Legacy / inaccessible disposition | `legacy_or_inaccessible_repo_disposition` | request ready not sent |
+
+每個 S4.9 owner response request template 都固定 `display_mode=s4_9_owner_response_request_template_only`、`request_status=request_ready_not_sent`、`current_state=waiting_owner_response`、`request_sent_count=0`、`owner_response_received_count=0`、`owner_response_accepted_count=0`、`owner_response_rejected_count=0`、`audit_events_emitted_count=0`、`auto_chase_allowed=false`、`autofill_allowed=false`、`request_send_allowed=false`、`mark_received_allowed=false`、`mark_accepted_allowed=false`、`approval_record_created=false`、`gitea_inventory_completed=false`、`gitea_write_allowed=false`、`repo_or_refs_mutation_allowed=false`、`github_primary_ready=false`、`secret_value_collection_allowed=false`、`runtime_execution_authorized=false`、`action_buttons_allowed=false`、`not_authorization=true`。
+
+這個 request template board 不代表 S4.9 request 已寄出、owner response 已收到、owner response 已接受或 Gitea 清冊已完成。它只把第一個 owner response 收件包需要 owner 回覆的五題顯示清楚,讓後續真正收件時不再模糊。
+
## 4. 仍禁止
IwoooS 不得提供下列輸出:
@@ -823,7 +840,8 @@ IwoooS 不得提供下列輸出:
39. 把 progress acceleration lane 當成授權、進度自動加分、owner response received、runtime gate、GitHub primary readiness 或 production execution。
40. 把 owner response next-action focus 當成催收、代填、received、accepted、approval record、runtime gate、repo / refs mutation、secret value collection 或 GitHub primary switch。
41. 把 S4.9 owner response preflight 當成 request sent、owner response received / accepted、preflight passed、audit emitted、approval record、Gitea write、repo / refs mutation、runtime gate 或 GitHub primary switch。
-42. 把 58% progress、contract count、mirror readiness 或前端可見狀態當成授權。
+42. 把 S4.9 owner response request template 當成 request sent、owner response received / accepted、audit emitted、Gitea inventory completed、Gitea write、repo / refs mutation、token collection、runtime gate 或 GitHub primary switch。
+43. 把 58% progress、contract count、mirror readiness 或前端可見狀態當成授權。
## 5. 驗證
diff --git a/docs/security/SECURITY-MIRROR-STATUS-ROLLUP.md b/docs/security/SECURITY-MIRROR-STATUS-ROLLUP.md
index b5f26ca04..b9e636300 100644
--- a/docs/security/SECURITY-MIRROR-STATUS-ROLLUP.md
+++ b/docs/security/SECURITY-MIRROR-STATUS-ROLLUP.md
@@ -35,7 +35,7 @@
| Owner response validation | S4.13 已建立;四包 owner response 目前 received/accepted 皆為 0;4 條 missing response lanes、4 步 collection order、next collection candidate、6 條 evidence routing rules、8 個 display sections、7 條 state transition rules、9 個 reviewer checklist items、7 條 reviewer outcome lanes、4 個 reviewer audit event templates、5 個 reviewer audit display sections、6 個 reviewer audit collection checks、5 個 reviewer audit redaction examples、5 條 reviewer audit retention rules、6 個 reviewer audit retention checks、6 個 reviewer audit handoff packets、6 個 reviewer audit handoff checks、6 個 parallel session sync checks、6 條 parallel session conflict lanes、6 個 parallel session recovery checks 與 7 條 parallel session recovery outcome lanes 可供 AwoooP 直接顯示;下一個建議收件為 S4.9 Gitea owner attestation;latest local validation 為 `SOURCE_CONTROL_OWNER_RESPONSE_GUARD_OK`,reviewer audit emitted 仍為 0,不代表 owner response 已收到或任何執行授權 |
| Low-friction rollout policy | S1.3 已補 7 條 non-blocking escalation lanes;LOW / MEDIUM、缺 owner response、partial mirror、source-control drift、Kali observe finding、workflow / secret name gap 與 headline holding 初期只能 observe / warn;`owner_review_required_before_blocking=true`、`runtime_blocking_allowed=false` |
| IwoooS frontend posture | S2.8 已新增 `/iwooos` read-only Information Security 入口;顯示 Security Posture / Exposure、source-control supply chain、Kali 112 Mesh、approval boundary、non-blocking lanes 與 evidence refs;不新增執行按鈕 |
-| IwoooS posture projection | S2.9 已新增 `iwooos_posture_projection_v1`;S2.10 已把 10 個既有前端資安相關頁面納入 projection;S2.11 已補 4 個 coverage groups 與 5 個 conflict controls;S2.12 已補 6 個只讀 operator journey steps;S2.13 已補 7 個 owner evidence readiness items;S2.14 已補 3 個 host coverage items:Kali 112、開發主機 168、開發主機 111;S2.15 已補 6 個 host action gate items;S2.16 已補 7 個 host evidence readiness items;S2.17 已補 7 個 host evidence collection order steps;S2.18 已補 7 個 host evidence intake preflight checks;S2.19 已補 7 個 host evidence review outcome lanes;S2.20 已補 7 個 host evidence review handoff packets;S2.21 已補 7 個 host evidence reviewer checklist items;S2.22 已補 7 個 host evidence reviewer outcome lanes;S2.23 已補 7 個 host owner decision candidate packets;S2.24 已補 7 個 host owner decision review checklist items;S2.25 已補 7 個 host owner decision review outcome lanes;S2.26 已補 7 個 host owner decision record draft packets;S2.27 已補 7 個 host owner decision record draft review checklist items;S2.28 已補 7 個 host owner decision record draft review outcome lanes;S2.29 已補 7 個 host owner decision record write-up packets;S2.30 已補 7 個 host owner decision record write-up review checklist items;S2.31 已補 7 個 host owner decision record write-up review outcome lanes;S2.32 已補 7 個 host owner decision record formal candidate packets;S2.33 已補 7 個 host owner decision record formal candidate review checklist items;S2.34 已補 8 個 host owner decision record formal candidate review outcome lanes;S2.35 已補 8 個 host owner decision record formal record queue packets;S2.36 已補 8 個 host owner decision record formal record queue review checklist items;S2.37 已補 8 個 host owner decision record formal record queue review outcome lanes;S2.38 已補 8 個 host owner decision record human handoff readiness packets;S2.39 已補 8 個 host owner decision record human handoff readiness review checklist items;S2.40 已補 9 個 host owner decision record human handoff readiness review outcome lanes;S2.41 已補 9 個 host owner decision record human record owner review candidate packets;S2.42 已補 9 個 host owner decision record human record owner review candidate checklist items;S2.43 已補 9 個 host owner decision record human record owner review candidate outcome lanes;S2.44 已補 9 個 host owner decision record human record owner review preparation packets;S2.45 已補 9 個 host owner decision record human record owner review preparation checklist items;S2.46 已補 6 條 progress acceleration lanes,顯示 58% holding 原因與下一個高層解鎖 gate;S2.47 已補 4 個 owner response next-action focus items,顯示 S4.9 為下一個收件焦點且 S4.10-S4.12 依序排隊;S2.48 已補 6 個 S4.9 owner response preflight checks,讓下一個 P0 owner response 的可收件條件可見;仍不新增 action button |
+| IwoooS posture projection | S2.9 已新增 `iwooos_posture_projection_v1`;S2.10 已把 10 個既有前端資安相關頁面納入 projection;S2.11 已補 4 個 coverage groups 與 5 個 conflict controls;S2.12 已補 6 個只讀 operator journey steps;S2.13 已補 7 個 owner evidence readiness items;S2.14 已補 3 個 host coverage items:Kali 112、開發主機 168、開發主機 111;S2.15 已補 6 個 host action gate items;S2.16 已補 7 個 host evidence readiness items;S2.17 已補 7 個 host evidence collection order steps;S2.18 已補 7 個 host evidence intake preflight checks;S2.19 已補 7 個 host evidence review outcome lanes;S2.20 已補 7 個 host evidence review handoff packets;S2.21 已補 7 個 host evidence reviewer checklist items;S2.22 已補 7 個 host evidence reviewer outcome lanes;S2.23 已補 7 個 host owner decision candidate packets;S2.24 已補 7 個 host owner decision review checklist items;S2.25 已補 7 個 host owner decision review outcome lanes;S2.26 已補 7 個 host owner decision record draft packets;S2.27 已補 7 個 host owner decision record draft review checklist items;S2.28 已補 7 個 host owner decision record draft review outcome lanes;S2.29 已補 7 個 host owner decision record write-up packets;S2.30 已補 7 個 host owner decision record write-up review checklist items;S2.31 已補 7 個 host owner decision record write-up review outcome lanes;S2.32 已補 7 個 host owner decision record formal candidate packets;S2.33 已補 7 個 host owner decision record formal candidate review checklist items;S2.34 已補 8 個 host owner decision record formal candidate review outcome lanes;S2.35 已補 8 個 host owner decision record formal record queue packets;S2.36 已補 8 個 host owner decision record formal record queue review checklist items;S2.37 已補 8 個 host owner decision record formal record queue review outcome lanes;S2.38 已補 8 個 host owner decision record human handoff readiness packets;S2.39 已補 8 個 host owner decision record human handoff readiness review checklist items;S2.40 已補 9 個 host owner decision record human handoff readiness review outcome lanes;S2.41 已補 9 個 host owner decision record human record owner review candidate packets;S2.42 已補 9 個 host owner decision record human record owner review candidate checklist items;S2.43 已補 9 個 host owner decision record human record owner review candidate outcome lanes;S2.44 已補 9 個 host owner decision record human record owner review preparation packets;S2.45 已補 9 個 host owner decision record human record owner review preparation checklist items;S2.46 已補 6 條 progress acceleration lanes,顯示 58% holding 原因與下一個高層解鎖 gate;S2.47 已補 4 個 owner response next-action focus items,顯示 S4.9 為下一個收件焦點且 S4.10-S4.12 依序排隊;S2.48 已補 6 個 S4.9 owner response preflight checks,讓下一個 P0 owner response 的可收件條件可見;S2.49 已補 5 個 S4.9 owner response request templates,讓 owner 要逐項回覆的五題可見;仍不新增 action button |
| Dry-run | `contract_defined_not_executed`;已納入 `CHECK_PROGRESS_GUARD` 與 `CHECK_OWNER_RESPONSE_GUARD`,latest local validation 為 `repo_snapshot_guard_pass`,仍不代表 production ingestion |
| Runtime actions | `false` |
| Payload ingestion | `false` |
@@ -132,6 +132,7 @@
| S2.46 IwoooS progress acceleration lanes | framework detail | 0 | 只顯示 owner response、redacted ingestion、runtime gate、GitHub readiness、AwoooP landing 與 cadence compression 六條解鎖 lane;headline percent、owner response、payload ingestion、runtime gate、GitHub primary、production execution 與 action button 仍全部鎖住 |
| S2.47 IwoooS owner response next-action focus | framework detail | 0 | 只顯示 S4.9 為下一個 owner response 收件焦點,S4.10 / S4.11 / S4.12 依序排隊;received、accepted、rejected、audit emitted、approval record、runtime gate、repo / refs mutation、secret value collection 與 action button 仍全部鎖住 |
| S2.48 IwoooS S4.9 owner response preflight | framework detail | 0 | 只顯示 S4.9 六個收件前檢查與 failure lanes;request sent、received、accepted、rejected、preflight passed、audit emitted、Gitea write、repo / refs mutation、runtime gate、GitHub primary 與 action button 仍全部鎖住 |
+| S2.49 IwoooS S4.9 owner response request templates | framework detail | 0 | 只顯示 S4.9 五個 request-ready-not-sent templates;request sent、received、accepted、rejected、audit emitted、Gitea inventory completed、Gitea write、repo / refs mutation、token collection、runtime gate、GitHub primary 與 action button 仍全部鎖住 |
headline 進度要再往上,至少需要下列任一高層 gate 有實質 evidence:
diff --git a/docs/security/SECURITY-SUPPLY-CHAIN-PROGRESS.md b/docs/security/SECURITY-SUPPLY-CHAIN-PROGRESS.md
index 01a36296a..7d2625754 100644
--- a/docs/security/SECURITY-SUPPLY-CHAIN-PROGRESS.md
+++ b/docs/security/SECURITY-SUPPLY-CHAIN-PROGRESS.md
@@ -27,7 +27,7 @@ python3 scripts/security/security-mirror-progress-guard.py
### 0.2 Headline 58% 不代表停滯
-近期 S4.10 request packet、template status ledger、audit event templates、redaction examples、collection checks、intake preflight checks、S4.11 request packet / template status ledger / audit event templates / redaction examples / collection checks / intake preflight checks、S4.12 request packet / template status ledger / audit event templates / redaction examples / collection checks / intake preflight checks、S4.13 evidence routing rules / display sections / state transition rules / reviewer checklist / reviewer outcome lanes / reviewer audit event templates / reviewer audit display sections / reviewer audit collection checks / reviewer audit redaction examples / reviewer audit retention rules / reviewer audit retention checks / reviewer audit handoff packets / reviewer audit handoff checks / parallel session sync checks / parallel session conflict lanes / parallel session recovery checks / recovery outcome lanes、S1.3 non-blocking escalation lanes、S2.8 IwoooS frontend posture entry,以及 S2.9-S2.48 IwoooS posture projection contract 都是有效進展,但它們是 framework detail,不是 owner response、runtime gate、production ingestion 或 GitHub primary readiness。因此 headline 仍維持 58%,避免把只讀框架誤算成已落地執行。
+近期 S4.10 request packet、template status ledger、audit event templates、redaction examples、collection checks、intake preflight checks、S4.11 request packet / template status ledger / audit event templates / redaction examples / collection checks / intake preflight checks、S4.12 request packet / template status ledger / audit event templates / redaction examples / collection checks / intake preflight checks、S4.13 evidence routing rules / display sections / state transition rules / reviewer checklist / reviewer outcome lanes / reviewer audit event templates / reviewer audit display sections / reviewer audit collection checks / reviewer audit redaction examples / reviewer audit retention rules / reviewer audit retention checks / reviewer audit handoff packets / reviewer audit handoff checks / parallel session sync checks / parallel session conflict lanes / parallel session recovery checks / recovery outcome lanes、S1.3 non-blocking escalation lanes、S2.8 IwoooS frontend posture entry,以及 S2.9-S2.49 IwoooS posture projection contract 都是有效進展,但它們是 framework detail,不是 owner response、runtime gate、production ingestion 或 GitHub primary readiness。因此 headline 仍維持 58%,避免把只讀框架誤算成已落地執行。
| 最近完成 | 目前狀態 | headline delta |
|----------|----------|----------------|
@@ -108,6 +108,7 @@ python3 scripts/security/security-mirror-progress-guard.py
| S2.46 IwoooS progress acceleration lanes | 已完成草案,將 owner response、redacted ingestion、runtime gate、GitHub readiness、AwoooP landing 與 cadence compression 六個真正會影響進度感的解鎖 lane 顯示在 IwoooS;headline 仍只在高層 gate 有 evidence 時 review | 0 |
| S2.47 IwoooS owner response next-action focus | 已完成草案,將 S4.9 Gitea owner attestation 固定為下一個收件焦點,S4.10 / S4.11 / S4.12 依序排隊;received / accepted 仍為 0 | 0 |
| S2.48 IwoooS S4.9 owner response preflight | 已完成草案,將 S4.9 六個收件前檢查顯示在 IwoooS;request sent、received / accepted / rejected、preflight passed、audit emitted 仍為 0 | 0 |
+| S2.49 IwoooS S4.9 owner response request templates | 已完成草案,將 S4.9 五個 request-ready-not-sent templates 顯示在 IwoooS;request sent、received / accepted / rejected、audit emitted 仍為 0 | 0 |
headline 要再往上,需要 S4.9 / S4.10 / S4.11 / S4.12 任一 owner response 收到並通過脫敏驗收,或人工批准後出現 active runtime gate、redacted payload ingestion、GitHub primary readiness 這類落地 evidence。
@@ -175,6 +176,7 @@ headline 要再往上,需要 S4.9 / S4.10 / S4.11 / S4.12 任一 owner respons
| S2.46 IwoooS Progress Acceleration Lanes | 完成草案 | `/iwooos` 新增進度加速與 58% 解鎖面板,顯示 owner response、redacted ingestion、runtime gate、GitHub readiness、AwoooP landing 與 cadence compression 六條 acceleration lanes | 使用者能理解前面看起來慢是因為 S2.38-S2.45 都是防止誤讀的 framework detail;後續改採 milestone batch,但 acceleration lane 仍不是 owner response、進度加分、runtime gate、GitHub primary 或 production execution |
| S2.47 IwoooS Owner Response Next-Action Focus | 完成草案 | `/iwooos` 新增 owner response 下一步收件焦點,顯示 S4.9 Gitea owner attestation 先收、S4.10 GitHub target、S4.11 refs truth、S4.12 workflow / secret name 依序排隊 | 使用者能理解下一個有感工作是收斂 P0 owner response;focus 仍不是催收、代填、received、accepted、approval record、runtime gate、repo / refs mutation、secret value collection 或 GitHub primary |
| S2.48 IwoooS S4.9 Owner Response Preflight | 完成草案 | `/iwooos` 新增 S4.9 owner response 收件前 preflight,顯示 known attestation item、required owner fields、allowed decision、redacted evidence only、no execution request、all five items before accepted 六個檢查 | 使用者能理解下一步不是再拆 checklist,而是把第一個 P0 owner response 的可收件條件說清楚;preflight 仍不是 request sent、received、accepted、audit emitted、Gitea write、refs sync、runtime gate 或 GitHub primary |
+| S2.49 IwoooS S4.9 Owner Response Request Templates | 完成草案 | `/iwooos` 新增 S4.9 owner response 五個回覆 template,顯示 public-only / local gap、org/user endpoint、110 adjacent source scope、repo owner / canonical scope、legacy / inaccessible disposition | 使用者能理解第一個 owner response 要回哪五題;templates 仍不是 request sent、received、accepted、audit emitted、Gitea inventory completed、Gitea write、refs sync、token collection、runtime gate 或 GitHub primary |
| S3 approval gate | 進行中 | `security_approval_gate_v1` 已建立 8 個人工 gate items:7 pending、1 block candidate、0 approved | 不得繞過人工批准;批准後仍需 follow-up runtime gate |
| S3.0 人工批准 Gate 契約 | 完成草案 | 定義批准範圍、決策選項、required reviewers、still forbidden 與 follow-up runtime gate | AwoooP 可記錄決策,不可執行 gate item |
| S3.1 人工決策紀錄契約 | 完成草案 | `security_approval_decision_record_v1` 已建立;目前 0 筆 decision records、0 個 runtime action 授權 | AwoooP 可稽核決策,不可把決策當執行 |
diff --git a/docs/security/iwooos-posture-projection.snapshot.json b/docs/security/iwooos-posture-projection.snapshot.json
index 605f95533..460d7fecb 100644
--- a/docs/security/iwooos-posture-projection.snapshot.json
+++ b/docs/security/iwooos-posture-projection.snapshot.json
@@ -74,7 +74,8 @@
"host_owner_decision_record_human_record_owner_review_preparation_checklist_item_count": 9,
"progress_acceleration_lane_count": 6,
"owner_response_next_action_focus_item_count": 4,
- "s4_9_owner_response_preflight_check_count": 6
+ "s4_9_owner_response_preflight_check_count": 6,
+ "s4_9_owner_response_request_template_count": 5
},
"progress": {
"overall_percent": 58,
@@ -185,7 +186,8 @@
"display_host_owner_decision_record_human_record_owner_review_preparation_packets",
"display_host_owner_decision_record_human_record_owner_review_preparation_checklist",
"display_owner_response_next_action_focus",
- "display_s4_9_owner_response_preflight_checks"
+ "display_s4_9_owner_response_preflight_checks",
+ "display_s4_9_owner_response_request_templates"
],
"forbidden_frontend_outputs": [
"add_scan_button",
@@ -365,7 +367,17 @@
"open_runtime_gate_from_s4_9_preflight",
"write_gitea_from_s4_9_preflight",
"sync_refs_from_s4_9_preflight",
- "switch_primary_from_s4_9_preflight"
+ "switch_primary_from_s4_9_preflight",
+ "send_s4_9_owner_response_request_from_iwooos",
+ "treat_s4_9_template_as_request_sent",
+ "mark_s4_9_template_received_from_iwooos",
+ "mark_s4_9_template_accepted_from_iwooos",
+ "autofill_s4_9_template_from_iwooos",
+ "create_gitea_inventory_from_s4_9_template",
+ "write_gitea_from_s4_9_template",
+ "sync_refs_from_s4_9_template",
+ "switch_primary_from_s4_9_template",
+ "collect_token_from_s4_9_template"
],
"runtime_execution_authorized": false,
"action_buttons_allowed": false,
@@ -6072,6 +6084,153 @@
"not_authorization": true
}
],
+ "s4_9_owner_response_request_templates": [
+ {
+ "template_id": "response-public-only-vs-local-gitea-gap",
+ "display_order": 1,
+ "source_template_status_id": "response-public-only-vs-local-gitea-gap",
+ "attestation_item_id": "public_only_vs_local_gitea_gap",
+ "request_status": "request_ready_not_sent",
+ "current_state": "waiting_owner_response",
+ "next_owner_action_summary": "Owner 需逐項判定 wooo/clawbot-v5 與 wooo/wooo-aiops 是否屬本輪 inventory / migration scope,並只引用脫敏 evidence refs。",
+ "display_mode": "s4_9_owner_response_request_template_only",
+ "request_sent_count": 0,
+ "owner_response_received_count": 0,
+ "owner_response_accepted_count": 0,
+ "owner_response_rejected_count": 0,
+ "audit_events_emitted_count": 0,
+ "auto_chase_allowed": false,
+ "autofill_allowed": false,
+ "request_send_allowed": false,
+ "mark_received_allowed": false,
+ "mark_accepted_allowed": false,
+ "approval_record_created": false,
+ "gitea_inventory_completed": false,
+ "gitea_write_allowed": false,
+ "repo_or_refs_mutation_allowed": false,
+ "github_primary_ready": false,
+ "secret_value_collection_allowed": false,
+ "runtime_execution_authorized": false,
+ "action_buttons_allowed": false,
+ "not_authorization": true
+ },
+ {
+ "template_id": "response-org-user-endpoint-identity",
+ "display_order": 2,
+ "source_template_status_id": "response-org-user-endpoint-identity",
+ "attestation_item_id": "org_user_endpoint_identity",
+ "request_status": "request_ready_not_sent",
+ "current_state": "waiting_owner_response",
+ "next_owner_action_summary": "Owner 需說明 wooo 在 Gitea 中應以 user、org 或兩者盤點,且不得把 404 當成 private/internal repo 不存在。",
+ "display_mode": "s4_9_owner_response_request_template_only",
+ "request_sent_count": 0,
+ "owner_response_received_count": 0,
+ "owner_response_accepted_count": 0,
+ "owner_response_rejected_count": 0,
+ "audit_events_emitted_count": 0,
+ "auto_chase_allowed": false,
+ "autofill_allowed": false,
+ "request_send_allowed": false,
+ "mark_received_allowed": false,
+ "mark_accepted_allowed": false,
+ "approval_record_created": false,
+ "gitea_inventory_completed": false,
+ "gitea_write_allowed": false,
+ "repo_or_refs_mutation_allowed": false,
+ "github_primary_ready": false,
+ "secret_value_collection_allowed": false,
+ "runtime_execution_authorized": false,
+ "action_buttons_allowed": false,
+ "not_authorization": true
+ },
+ {
+ "template_id": "response-internal-110-adjacent-scope",
+ "display_order": 3,
+ "source_template_status_id": "response-internal-110-adjacent-scope",
+ "attestation_item_id": "internal_110_adjacent_scope",
+ "request_status": "request_ready_not_sent",
+ "current_state": "waiting_owner_response",
+ "next_owner_action_summary": "Owner 需逐項判定 bitan-pharmacy、root/momo-pro-system、tsenyang-website、wooo/wooo-infra-config 是否納入本輪 scope。",
+ "display_mode": "s4_9_owner_response_request_template_only",
+ "request_sent_count": 0,
+ "owner_response_received_count": 0,
+ "owner_response_accepted_count": 0,
+ "owner_response_rejected_count": 0,
+ "audit_events_emitted_count": 0,
+ "auto_chase_allowed": false,
+ "autofill_allowed": false,
+ "request_send_allowed": false,
+ "mark_received_allowed": false,
+ "mark_accepted_allowed": false,
+ "approval_record_created": false,
+ "gitea_inventory_completed": false,
+ "gitea_write_allowed": false,
+ "repo_or_refs_mutation_allowed": false,
+ "github_primary_ready": false,
+ "secret_value_collection_allowed": false,
+ "runtime_execution_authorized": false,
+ "action_buttons_allowed": false,
+ "not_authorization": true
+ },
+ {
+ "template_id": "response-repo-owner-canonical-scope",
+ "display_order": 4,
+ "source_template_status_id": "response-repo-owner-canonical-scope",
+ "attestation_item_id": "repo_owner_canonical_scope",
+ "request_status": "request_ready_not_sent",
+ "current_state": "waiting_owner_response",
+ "next_owner_action_summary": "Owner 需為 in-scope repo 指定 owner、canonical source、GitHub target candidate 與 visibility review owner。",
+ "display_mode": "s4_9_owner_response_request_template_only",
+ "request_sent_count": 0,
+ "owner_response_received_count": 0,
+ "owner_response_accepted_count": 0,
+ "owner_response_rejected_count": 0,
+ "audit_events_emitted_count": 0,
+ "auto_chase_allowed": false,
+ "autofill_allowed": false,
+ "request_send_allowed": false,
+ "mark_received_allowed": false,
+ "mark_accepted_allowed": false,
+ "approval_record_created": false,
+ "gitea_inventory_completed": false,
+ "gitea_write_allowed": false,
+ "repo_or_refs_mutation_allowed": false,
+ "github_primary_ready": false,
+ "secret_value_collection_allowed": false,
+ "runtime_execution_authorized": false,
+ "action_buttons_allowed": false,
+ "not_authorization": true
+ },
+ {
+ "template_id": "response-legacy-or-inaccessible-disposition",
+ "display_order": 5,
+ "source_template_status_id": "response-legacy-or-inaccessible-disposition",
+ "attestation_item_id": "legacy_or_inaccessible_repo_disposition",
+ "request_status": "request_ready_not_sent",
+ "current_state": "waiting_owner_response",
+ "next_owner_action_summary": "Owner 需對 legacy、inaccessible 或 external repo 留下 disposition、理由與後續 owner。",
+ "display_mode": "s4_9_owner_response_request_template_only",
+ "request_sent_count": 0,
+ "owner_response_received_count": 0,
+ "owner_response_accepted_count": 0,
+ "owner_response_rejected_count": 0,
+ "audit_events_emitted_count": 0,
+ "auto_chase_allowed": false,
+ "autofill_allowed": false,
+ "request_send_allowed": false,
+ "mark_received_allowed": false,
+ "mark_accepted_allowed": false,
+ "approval_record_created": false,
+ "gitea_inventory_completed": false,
+ "gitea_write_allowed": false,
+ "repo_or_refs_mutation_allowed": false,
+ "github_primary_ready": false,
+ "secret_value_collection_allowed": false,
+ "runtime_execution_authorized": false,
+ "action_buttons_allowed": false,
+ "not_authorization": true
+ }
+ ],
"s4_9_owner_response_preflight_checks": [
{
"preflight_id": "s4_9_preflight_known_attestation_item",
diff --git a/docs/security/security-mirror-status-rollup.snapshot.json b/docs/security/security-mirror-status-rollup.snapshot.json
index d05e8fa39..32e1bb39a 100644
--- a/docs/security/security-mirror-status-rollup.snapshot.json
+++ b/docs/security/security-mirror-status-rollup.snapshot.json
@@ -1046,6 +1046,18 @@
"runtime_delta": false,
"execution_authorized": false,
"not_authorization": true
+ },
+ {
+ "delta_id": "s2_49_iwooos_s4_9_owner_response_request_templates",
+ "display_order": 78,
+ "completed_stage": "S2.49 IwoooS S4.9 owner response request templates",
+ "progress_axis": "framework_detail",
+ "headline_percent_delta": 0,
+ "framework_delta_visible": true,
+ "why_headline_unchanged": "S4.9 request templates 只顯示五個 request-ready-not-sent owner response templates;request sent、owner response received/accepted/rejected、audit emitted、Gitea inventory complete、Gitea write、refs mutation、GitHub primary readiness 與 production landing 仍未改變。",
+ "runtime_delta": false,
+ "execution_authorized": false,
+ "not_authorization": true
}
],
"next_safe_actions": [
@@ -1443,7 +1455,8 @@
"S2.45 只新增 IwoooS host owner decision record human record owner review preparation checklist;host_owner_decision_record_human_record_owner_review_preparation_checklist_item_count=9、human_record_owner_review_prepared_count=0、human_record_owner_review_check_passed_count=0、human_record_owner_review_started_count=0、human_record_owner_review_ready_count=0、human_record_owner_handoff_review_passed_count=0、human_record_owner_handoff_started_count=0、human_record_owner_handoff_ready_count=0、formal_record_queue_review_passed_count=0、formal_record_queue_enqueued_count=0、decision_record_created=false、owner_decision_received_count=0、owner_decision_accepted_count=0、owner_approval_record_created=false、runtime_gate_opened=false,不把 review preparation checklist 當 preparation completed、checklist passed、review started、review ready、owner decision、正式 decision record、批准或 runtime gate。",
"S2.46 新增 IwoooS progress acceleration lanes;progress_acceleration_lane_count=6、headline_percent_after_this_stage=58、owner_response_received_count=0、owner_response_accepted_count=0、payloads_ingested=false、active_runtime_gate_count=0、github_primary_ready_count=0、production_landing_enabled=false,不把 acceleration lane 當授權、進度加分、runtime gate、owner response received、GitHub primary 或 production execution。",
"S2.47 新增 IwoooS owner response next-action focus;owner_response_next_action_focus_item_count=4,顯示 S4.9 Gitea owner attestation 為下一個收件焦點,S4.10/S4.11/S4.12 依序排隊;owner response received/accepted/rejected 與 audit events emitted 仍為 0,不自動催收、代填、標記 received/accepted、建立 approval record、開 runtime gate 或切 GitHub primary。",
- "S2.48 新增 IwoooS S4.9 owner response preflight;s4_9_owner_response_preflight_check_count=6,顯示 known item、required owner fields、allowed decision、redacted evidence only、no execution request、all five items before accepted 六個收件前檢查;request sent、owner response received/accepted/rejected、preflight passed 與 audit events emitted 仍為 0,不標記 sent/received/accepted、不建立 approval record、不寫 Gitea、不 sync refs、不開 runtime gate 或切 GitHub primary。"
+ "S2.48 新增 IwoooS S4.9 owner response preflight;s4_9_owner_response_preflight_check_count=6,顯示 known item、required owner fields、allowed decision、redacted evidence only、no execution request、all five items before accepted 六個收件前檢查;request sent、owner response received/accepted/rejected、preflight passed 與 audit events emitted 仍為 0,不標記 sent/received/accepted、不建立 approval record、不寫 Gitea、不 sync refs、不開 runtime gate 或切 GitHub primary。",
+ "S2.49 新增 IwoooS S4.9 owner response request templates;s4_9_owner_response_request_template_count=5,顯示 public-only/local gap、org/user endpoint、110 adjacent scope、repo owner/canonical scope、legacy/inaccessible disposition 五個 request-ready-not-sent templates;request sent、owner response received/accepted/rejected 與 audit events emitted 仍為 0,不自動催收、代填、送出 request、標記 received/accepted、完成 Gitea inventory、寫 Gitea、sync refs 或切 GitHub primary。"
],
"forbidden_actions": [
"start_kali_scan",
diff --git a/scripts/security/security-mirror-progress-guard.py b/scripts/security/security-mirror-progress-guard.py
index fbcf03761..a862e8df4 100755
--- a/scripts/security/security-mirror-progress-guard.py
+++ b/scripts/security/security-mirror-progress-guard.py
@@ -200,6 +200,7 @@ def validate(root: Path) -> None:
"s2_46_iwooos_progress_acceleration_lanes",
"s2_47_iwooos_owner_response_next_action_focus",
"s2_48_iwooos_s4_9_owner_response_preflight",
+ "s2_49_iwooos_s4_9_owner_response_request_templates",
]
assert_equal(
"progress_delta_ledger.delta_ids",
@@ -1060,6 +1061,109 @@ def validate(root: Path) -> None:
f"iwooos_projection.owner_response_next_action_focus_items.{item['focus_id']}.not_authorization",
item["not_authorization"],
)
+ expected_s4_9_owner_response_request_template_ids = [
+ "response-public-only-vs-local-gitea-gap",
+ "response-org-user-endpoint-identity",
+ "response-internal-110-adjacent-scope",
+ "response-repo-owner-canonical-scope",
+ "response-legacy-or-inaccessible-disposition",
+ ]
+ assert_equal(
+ "iwooos_projection.summary.s4_9_owner_response_request_template_count",
+ iwooos_projection["summary"]["s4_9_owner_response_request_template_count"],
+ len(expected_s4_9_owner_response_request_template_ids),
+ )
+ 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",
+ [item["template_id"] for item in s4_9_owner_response_request_templates],
+ expected_s4_9_owner_response_request_template_ids,
+ )
+ assert_equal(
+ "iwooos_projection.s4_9_owner_response_request_templates.display_order",
+ [item["display_order"] for item in s4_9_owner_response_request_templates],
+ list(range(1, len(expected_s4_9_owner_response_request_template_ids) + 1)),
+ )
+ assert_equal(
+ "iwooos_projection.s4_9_owner_response_request_templates.source_template_status_ids",
+ [item["source_template_status_id"] for item in s4_9_owner_response_request_templates],
+ expected_s4_9_owner_response_request_template_ids,
+ )
+ assert_equal(
+ "iwooos_projection.s4_9_owner_response_request_templates.attestation_item_ids",
+ [item["attestation_item_id"] for item in s4_9_owner_response_request_templates],
+ [
+ "public_only_vs_local_gitea_gap",
+ "org_user_endpoint_identity",
+ "internal_110_adjacent_scope",
+ "repo_owner_canonical_scope",
+ "legacy_or_inaccessible_repo_disposition",
+ ],
+ )
+ for item in s4_9_owner_response_request_templates:
+ assert_equal(
+ f"iwooos_projection.s4_9_owner_response_request_templates.{item['template_id']}.request_status",
+ item["request_status"],
+ "request_ready_not_sent",
+ )
+ assert_equal(
+ f"iwooos_projection.s4_9_owner_response_request_templates.{item['template_id']}.current_state",
+ item["current_state"],
+ "waiting_owner_response",
+ )
+ assert_equal(
+ f"iwooos_projection.s4_9_owner_response_request_templates.{item['template_id']}.display_mode",
+ item["display_mode"],
+ "s4_9_owner_response_request_template_only",
+ )
+ assert_equal(
+ f"iwooos_projection.s4_9_owner_response_request_templates.{item['template_id']}.request_sent_count",
+ item["request_sent_count"],
+ 0,
+ )
+ assert_equal(
+ f"iwooos_projection.s4_9_owner_response_request_templates.{item['template_id']}.owner_response_received_count",
+ item["owner_response_received_count"],
+ 0,
+ )
+ assert_equal(
+ f"iwooos_projection.s4_9_owner_response_request_templates.{item['template_id']}.owner_response_accepted_count",
+ item["owner_response_accepted_count"],
+ 0,
+ )
+ assert_equal(
+ f"iwooos_projection.s4_9_owner_response_request_templates.{item['template_id']}.owner_response_rejected_count",
+ item["owner_response_rejected_count"],
+ 0,
+ )
+ assert_equal(
+ f"iwooos_projection.s4_9_owner_response_request_templates.{item['template_id']}.audit_events_emitted_count",
+ item["audit_events_emitted_count"],
+ 0,
+ )
+ for flag in [
+ "auto_chase_allowed",
+ "autofill_allowed",
+ "request_send_allowed",
+ "mark_received_allowed",
+ "mark_accepted_allowed",
+ "approval_record_created",
+ "gitea_inventory_completed",
+ "gitea_write_allowed",
+ "repo_or_refs_mutation_allowed",
+ "github_primary_ready",
+ "secret_value_collection_allowed",
+ "runtime_execution_authorized",
+ "action_buttons_allowed",
+ ]:
+ assert_false(
+ f"iwooos_projection.s4_9_owner_response_request_templates.{item['template_id']}.{flag}",
+ item[flag],
+ )
+ assert_true(
+ f"iwooos_projection.s4_9_owner_response_request_templates.{item['template_id']}.not_authorization",
+ item["not_authorization"],
+ )
expected_s4_9_owner_response_preflight_ids = [
"s4_9_preflight_known_attestation_item",
"s4_9_preflight_required_owner_fields",
@@ -4125,6 +4229,7 @@ def validate(root: Path) -> None:
"display_progress_acceleration_lanes",
"display_owner_response_next_action_focus",
"display_s4_9_owner_response_preflight_checks",
+ "display_s4_9_owner_response_request_templates",
"display_non_blocking_lanes",
"display_existing_frontend_security_surfaces",
"display_frontend_surface_coverage_matrix",
@@ -4341,6 +4446,16 @@ def validate(root: Path) -> None:
"write_gitea_from_s4_9_preflight",
"sync_refs_from_s4_9_preflight",
"switch_primary_from_s4_9_preflight",
+ "send_s4_9_owner_response_request_from_iwooos",
+ "treat_s4_9_template_as_request_sent",
+ "mark_s4_9_template_received_from_iwooos",
+ "mark_s4_9_template_accepted_from_iwooos",
+ "autofill_s4_9_template_from_iwooos",
+ "create_gitea_inventory_from_s4_9_template",
+ "write_gitea_from_s4_9_template",
+ "sync_refs_from_s4_9_template",
+ "switch_primary_from_s4_9_template",
+ "collect_token_from_s4_9_template",
"apply_runtime_blocking_control",
"switch_github_primary",
"production_deploy",