docs(security): 修正 S4.13 owner response rollup 口徑
All checks were successful
Code Review / ai-code-review (push) Successful in 10s

This commit is contained in:
Your Name
2026-06-12 11:36:18 +08:00
parent b17a28c293
commit f4fb0781e5
3 changed files with 39 additions and 8 deletions

View File

@@ -2,8 +2,8 @@
| 項目 | 內容 |
|------|------|
| 日期 | 2026-06-05 |
| 基準 | `gitea/main=b615bde5 docs(security): 補 S4.9 owner response 缺口稽核 [skip ci]` |
| 日期 | 2026-06-12 |
| 基準 | `gitea/main=b17a28c2 feat(governance): 新增報表 runtime 啟動前閘門` |
| 範圍 | S4.9 Gitea owner attestation response gate 與 S4.13 owner response validation rollup |
| 模式 | 只讀 committed snapshot / 文件稽核 |
| 不可誤讀 | 不是 request sent、不是 owner response received、不是 accepted、不是 repo / refs / workflow / secret / runtime 授權 |
@@ -30,12 +30,13 @@ S4.9 的基礎規範已存在,且已能被 `source-control-owner-response-guar
| 缺口 | 影響 | 下一步 |
|------|------|--------|
| P0 主控總帳的同步基線仍停在較舊 commit | Session 可能誤用舊 `gitea/main` 或舊 P1 狀態 | 將總帳更新到 `f1bad81d`,並標註 P1-001 由另一 Session 進行中 |
| P0 主控總帳與缺口稽核基準需跟上最新 `gitea/main` | 平行 Session 已推進 P2-403I/J/K、Public Gateway Preflight、SRE 戰情室路由、Knowledge Base tenant context 與報表 runtime 啟動前閘門;舊 commit 基準會讓新 Session 誤判下一步 | 本輪已更新到 `b17a28c2`;後續每次推送前仍需 fetch、讀 LOGBOOK 最新段落與同步 runs / deploy marker |
| S4.9 gate 仍只有 request-ready沒有 owner response | IwoooS 64% 不能因規範存在而往前解鎖 | 維持 `0%`,只準備收件缺口,不調高 progress |
| S4.13 rollup 文件曾殘留舊模板總數 | Snapshot 已是 `5 + 9 + 5 + 5 = 24`,但文件仍可能寫成 `22`,會造成 reviewer 誤判 S4.10 目標數 | 已同步文件並把 `source-control-owner-response-guard.py` 納入文件一致性檢查 |
| request packet 的欄位名稱存在同義詞 | `affected_repos``affected_sources``affected_repos_or_sources_or_namespace``evidence_refs` 與使用者要求的 `affected_scope``redacted_evidence_refs` 容易在 UI / handoff 中混用 | 已補 `S4-9-CANONICAL-OWNER-RESPONSE-ENVELOPE.md`,後續顯示層以六欄 canonical envelope 呈現source templates 可保留細分欄位 |
| 沒有實際 dispatch / received audit event | 目前 audit event templates 仍是 template-only不能證明已送件或已收件 | 等人工送件後才增加 request_sent metadata未送前所有 count 維持 0 |
| 尚未有 owner response reviewer outcome | reviewer checklist 存在,但沒有任何可分類 response | 等脫敏 metadata 進來後,才能進補件、隔離、拒收、只讀更新候選 |
| 部分文件仍可能把 P1-305 / P1-306 或 P1-001 當下一步文字混用 | 平行 Session 正在推 P1-001S4.9 仍是獨立 P0 gate | 後續 LOGBOOK / workplan 每次都標註平行 Session最新基線 |
| 部分文件仍可能把近期 P2-403I/J/K 或資安 P1 工作誤當 S4.9 已解鎖 | 平行 Session 已推進 AI Agent 報表 / 告警路由,但 S4.9 owner response 仍是獨立 P0 gate | 後續 LOGBOOK / workplan 每次都標註平行 Session最新基線與 S4.9 received / accepted 仍為 `0 / 0` |
## 4. 需要新增或強化的規範
@@ -87,5 +88,6 @@ S4.9 的基礎規範已存在,且已能被 `source-control-owner-response-guar
| S4.9 現況缺口稽核 | 100% | 已列出已符合、仍不符合、需新增、需調整、五題回覆與 0 / false 邊界 |
| S4.9 canonical owner response envelope | 100% | 已補六欄信封、alias 映射、五題投影、quarantine-first 與 reviewer checklist |
| S4.9 owner response gate | 0% | 沒有收到 owner response不得調高 |
| S4.13 rollup 文件一致性 | 100% | 已把 `22` 舊口徑修正為 `24`,並由 guard 檢查 |
| IwoooS 整體 | 維持 64% | 只讀稽核不改 runtime readiness |
| active runtime gate | 0 | 不變 |

View File

@@ -2,7 +2,7 @@
| 項目 | 內容 |
|------|------|
| 日期 | 2026-06-04 |
| 日期 | 2026-06-12 |
| 狀態 | 草案,等待 owner responsesS4.9 是目前第一優先收件 gate |
| 資料契約 | `docs/schemas/source_control_owner_response_validation_rollup_v1.schema.json` |
| 快照 | `docs/security/source-control-owner-response-validation-rollup.snapshot.json` |
@@ -56,7 +56,7 @@ S4.13 不新增第 36 個主 contract不新增 approval item不啟用 runt
| 項目 | 結果 |
|------|------|
| 日期 | 2026-06-04 |
| 日期 | 2026-06-12 |
| 範圍 | `repo_snapshot_only` |
| 指令 | `python3 scripts/security/source-control-owner-response-guard.py --root .` |
| 結果 | `SOURCE_CONTROL_OWNER_RESPONSE_GUARD_OK` |
@@ -143,7 +143,7 @@ S4.9 回覆即使通過,也只允許更新 read-only Gitea coverage matrix、o
## 3. Cross-Packet 驗收規則
1. 四個 source response packets 都必須可解析,且 summary 欄位存在。
2. response template count 必須對齊來源:`5 + 7 + 5 + 5 = 22`
2. response template count 必須對齊來源:`5 + 9 + 5 + 5 = 24`
3. received / accepted / rejected count 必須明確列出;目前皆為 `0 / 0 / 0`
4. 即使未來 response 通過,也只能更新 read-only wording、matrix 或 readiness 欄位。
5. 四個 packets 都必須保留 rejection rules總數 40。
@@ -170,7 +170,7 @@ S4.9 回覆即使通過,也只允許更新 read-only Gitea coverage matrix、o
| 順序 | Section | 顯示來源 | 邊界 |
|------|---------|----------|------|
| 1 | Owner response validation 總覽 | `summary` | 只顯示四包、22 templates、received / accepted / rejected 皆為 0 與 false flags |
| 1 | Owner response validation 總覽 | `summary` | 只顯示四包、24 templates、received / accepted / rejected 皆為 0 與 false flags |
| 2 | Missing owner response lanes | `missing_response_lanes` | 只顯示四條缺口與下一步 owner action不新增 response |
| 3 | Owner response collection order | `owner_response_collection_order` | 只顯示建議收件順序,不是 execution queue |
| 4 | Next collection candidate | `next_collection_candidate` | 只顯示目前先收 S4.9,不代表 S4.10-S4.12 可提前接受 |

View File

@@ -480,8 +480,37 @@ def assert_true(label: str, actual: Any) -> None:
assert_equal(label, actual, True)
def assert_contains(label: str, text: str, expected: str) -> None:
if expected not in text:
raise SystemExit(f"BLOCKED {label}: missing {expected!r}")
def assert_not_contains(label: str, text: str, forbidden: str) -> None:
if forbidden in text:
raise SystemExit(f"BLOCKED {label}: forbidden {forbidden!r}")
def validate_markdown_consistency(security_dir: Path) -> None:
rollup_doc = (security_dir / "SOURCE-CONTROL-OWNER-RESPONSE-VALIDATION-ROLLUP.md").read_text(
encoding="utf-8"
)
gap_audit_doc = (security_dir / "S4-9-OWNER-RESPONSE-GATE-CURRENT-GAP-AUDIT.md").read_text(
encoding="utf-8"
)
assert_contains("rollup_doc.total_template_formula", rollup_doc, "5 + 9 + 5 + 5 = 24")
assert_contains("rollup_doc.total_template_display", rollup_doc, "24 templates")
assert_not_contains("rollup_doc.stale_formula", rollup_doc, "5 + 7 + 5 + 5 = 22")
assert_not_contains("rollup_doc.stale_display", rollup_doc, "22 templates")
assert_contains("gap_audit_doc.latest_baseline_present", gap_audit_doc, "gitea/main=")
assert_not_contains("gap_audit_doc.stale_baseline_b615", gap_audit_doc, "b615bde5")
assert_not_contains("gap_audit_doc.stale_baseline_f1bad", gap_audit_doc, "f1bad81d")
assert_contains("gap_audit_doc.rollup_consistency", gap_audit_doc, "S4.13 rollup 文件一致性")
def validate(root: Path) -> None:
security_dir = root / "docs" / "security"
validate_markdown_consistency(security_dir)
rollup = load_json(security_dir / "source-control-owner-response-validation-rollup.snapshot.json")
rollup_summary = rollup["summary"]