Merge remote-tracking branch 'refs/remotes/gitea-ssh/main' into codex/110-runner-pressure-merge-main-20260627

# Conflicts:
#	docs/LOGBOOK.md
This commit is contained in:
Your Name
2026-06-27 21:39:35 +08:00
11 changed files with 158 additions and 41 deletions

View File

@@ -284,7 +284,6 @@ def _require_boundaries(payload: dict[str, Any]) -> None:
summary = _summary(payload)
for key in (
"manager_registry_accepted_count",
"post_enable_readback_passed_count",
"runtime_gate_count",
"host_write_authorized_count",
"active_response_authorized_count",
@@ -299,7 +298,8 @@ def _require_boundaries(payload: dict[str, Any]) -> None:
passed = _int(summary.get("reviewer_validation_passed_count"))
failed = _int(summary.get("reviewer_validation_failed_count"))
quarantined = _int(summary.get("reviewer_validation_quarantined_count"))
if any(value < 0 for value in (received, accepted, ready, passed, failed, quarantined)):
post_enable = _int(summary.get("post_enable_readback_passed_count"))
if any(value < 0 for value in (received, accepted, ready, passed, failed, quarantined, post_enable)):
raise ValueError("Wazuh manager registry reviewer validation counters 不得為負數")
if accepted > received:
raise ValueError("owner_registry_export_accepted_count 不得大於 received_count")
@@ -307,6 +307,8 @@ def _require_boundaries(payload: dict[str, Any]) -> None:
raise ValueError("reviewer_validation_ready_count 不得大於 received_count")
if passed > accepted:
raise ValueError("reviewer_validation_passed_count 不得大於 accepted_count")
if post_enable > passed:
raise ValueError("post_enable_readback_passed_count 不得大於 reviewer_validation_passed_count")
if failed and passed:
raise ValueError("reviewer_validation_failed_count 與 passed_count 不得同時為正")
if quarantined and accepted:

View File

@@ -83,19 +83,20 @@ def test_iwooos_wazuh_manager_registry_reviewer_validation_contract_has_passed_r
assert payload["schema_version"] == "iwooos_wazuh_manager_registry_reviewer_validation_readback_v1"
assert payload["source_schema_version"] == "wazuh_manager_registry_reviewer_validation_v1"
assert payload["status"] == "accepted_for_readonly_posture_only"
assert payload["mode"] == "committed_validation_passed_readback_no_runtime_no_secret_collection"
assert payload["status"] == "post_enable_iwooos_readback_passed_no_runtime_no_secret_collection"
assert payload["mode"] == "committed_post_enable_iwooos_readback_passed_no_runtime_no_secret_collection"
assert payload["summary"]["expected_scope_alias_count"] == 6
assert payload["summary"]["required_owner_field_count"] == 28
assert payload["summary"]["per_host_required_field_count"] == 9
assert payload["summary"]["reviewer_validation_check_count"] == 10
assert payload["summary"]["outcome_lane_count"] == 13
assert payload["summary"]["outcome_lane_count"] == 14
assert payload["summary"]["evidence_slot_count"] == 6
assert payload["summary"]["forbidden_payload_count"] == 27
assert payload["summary"]["owner_registry_export_received_count"] == 1
assert payload["summary"]["owner_registry_export_accepted_count"] == 1
assert payload["summary"]["reviewer_validation_ready_count"] == 1
assert payload["summary"]["reviewer_validation_passed_count"] == 1
assert payload["summary"]["post_enable_readback_passed_count"] == 1
assert payload["summary"]["reviewer_validation_quarantined_count"] == 0
assert payload["summary"]["manager_registry_accepted_count"] == 0
assert payload["summary"]["runtime_gate_count"] == 0
@@ -115,7 +116,7 @@ def test_iwooos_wazuh_manager_registry_reviewer_validation_evidence_slots_are_ac
assert all(item["received"] is True for item in payload["evidence_slots"])
assert all(item["accepted"] is True for item in payload["evidence_slots"])
assert all(item["quarantined"] is False for item in payload["evidence_slots"])
assert all(item["next_gate"] == "post_enable_iwooos_readback" for item in payload["evidence_slots"])
assert all(item["next_gate"] == "manager_registry_acceptance_evidence_review" for item in payload["evidence_slots"])
assert "managed_core_node_a" in payload["expected_scope_aliases"]
assert "manager_registry_agent_counts" in [item["slot_id"] for item in payload["evidence_slots"]]
@@ -129,6 +130,7 @@ def test_iwooos_wazuh_manager_registry_reviewer_validation_api_is_public_safe()
assert data["summary"]["owner_registry_export_received_count"] == 1
assert data["summary"]["owner_registry_export_accepted_count"] == 1
assert data["summary"]["reviewer_validation_passed_count"] == 1
assert data["summary"]["post_enable_readback_passed_count"] == 1
assert data["summary"]["manager_registry_accepted_count"] == 0
assert data["summary"]["runtime_gate_count"] == 0
assert len(data["reviewer_validation_checks"]) == 10
@@ -145,6 +147,10 @@ def test_iwooos_wazuh_manager_registry_reviewer_validation_api_is_public_safe()
marker == "wazuh_manager_registry_reviewer_validation_passed_count=1"
for marker in data["boundary_markers"]
)
assert any(
marker == "wazuh_manager_registry_reviewer_validation_post_enable_readback_passed_count=1"
for marker in data["boundary_markers"]
)
assert any(
marker == "wazuh_manager_registry_reviewer_validation_manager_registry_accepted_count=0"
for marker in data["boundary_markers"]
@@ -202,6 +208,7 @@ def test_iwooos_wazuh_manager_registry_owner_export_validation_api_does_not_pers
assert readback["summary"]["owner_registry_export_received_count"] == 1
assert readback["summary"]["owner_registry_export_accepted_count"] == 1
assert readback["summary"]["reviewer_validation_passed_count"] == 1
assert readback["summary"]["post_enable_readback_passed_count"] == 1
assert readback["summary"]["manager_registry_accepted_count"] == 0
assert readback["summary"]["runtime_gate_count"] == 0

View File

@@ -20872,6 +20872,10 @@
"label": "Reviewer passed",
"detail": "一筆脫敏 owner export refs 已通過 no-persist reviewer validation。"
},
"postEnable": {
"label": "Post-enable",
"detail": "正式 API 與前台已讀回 reviewer passed這不是 live Wazuh 查詢授權。"
},
"received": {
"label": "已收 export",
"detail": "已收到一筆 owner-provided redacted registry export refs。"

View File

@@ -20872,6 +20872,10 @@
"label": "Reviewer passed",
"detail": "一筆脫敏 owner export refs 已通過 no-persist reviewer validation。"
},
"postEnable": {
"label": "Post-enable",
"detail": "正式 API 與前台已讀回 reviewer passed這不是 live Wazuh 查詢授權。"
},
"received": {
"label": "已收 export",
"detail": "已收到一筆 owner-provided redacted registry export refs。"

View File

@@ -32,6 +32,21 @@ import { QueueTab } from './tabs/queue-tab'
import { AgentMarketTab } from './tabs/agent-market-tab'
import { AutomationInventoryTab } from './tabs/automation-inventory-tab'
const GOVERNANCE_SECTION_IDS = [
'slo',
'events',
'queue',
'agent-market',
'automation-inventory',
] as const
function normalizeGovernanceSectionId(value: string | null): string | undefined {
if (!value) return undefined
return GOVERNANCE_SECTION_IDS.includes(value as (typeof GOVERNANCE_SECTION_IDS)[number])
? value
: undefined
}
export default function GovernancePage({
params,
}: {
@@ -50,16 +65,32 @@ export default function GovernancePage({
const activeSection = governanceSections.find(section => section.id === requestedTab) ?? governanceSections[0]
useEffect(() => {
const tab = new URLSearchParams(window.location.search).get('tab') ?? undefined
const hashTab = window.location.hash ? window.location.hash.slice(1) : null
const tab = normalizeGovernanceSectionId(
new URLSearchParams(window.location.search).get('tab') ?? hashTab
)
setRequestedTab(tab)
if (!tab) return
const section = document.getElementById(tab)
section?.scrollIntoView({ block: 'start' })
let cancelled = false
const scrollToRequestedSection = () => {
if (cancelled) return
document.getElementById(tab)?.scrollIntoView({ block: 'start' })
}
const frame = window.requestAnimationFrame(scrollToRequestedSection)
const timers = [150, 600, 1500, 3000].map(delay =>
window.setTimeout(scrollToRequestedSection, delay)
)
return () => {
cancelled = true
window.cancelAnimationFrame(frame)
timers.forEach(timer => window.clearTimeout(timer))
}
}, [])
return (
<AppLayout locale={params.locale}>
<div className="min-w-0 overflow-x-hidden">
{/* ComplianceBadge 橫幅 — PR 3 接 /governance/compliance-score API */}
<GlassCard variant="subtle" padding="sm" className="mb-3">
<div className="flex items-center gap-2">
@@ -79,7 +110,7 @@ export default function GovernancePage({
return (
<Link
key={section.id}
href={`/${params.locale}/governance#${section.id}`}
href={`/${params.locale}/governance?tab=${section.id}#${section.id}`}
className="group min-w-0 border bg-white p-3 text-[#141413] no-underline transition hover:border-[#d97757] hover:bg-[#fffaf7]"
style={{
borderColor: selected ? '#d97757' : '#e0ddd4',
@@ -125,6 +156,7 @@ export default function GovernancePage({
)
})}
</div>
</div>
</AppLayout>
)
}

View File

@@ -2479,7 +2479,7 @@ const wazuhManagerRegistryReviewerValidationBoundaries = [
'wazuh_manager_registry_reviewer_validation_required_owner_field_count=28',
'wazuh_manager_registry_reviewer_validation_per_host_required_field_count=9',
'wazuh_manager_registry_reviewer_validation_check_count=10',
'wazuh_manager_registry_reviewer_validation_outcome_lane_count=13',
'wazuh_manager_registry_reviewer_validation_outcome_lane_count=14',
'wazuh_manager_registry_reviewer_validation_evidence_slot_count=6',
'wazuh_manager_registry_reviewer_validation_forbidden_payload_count=27',
'wazuh_manager_registry_reviewer_validation_owner_registry_export_received_count=1',
@@ -2487,7 +2487,7 @@ const wazuhManagerRegistryReviewerValidationBoundaries = [
'wazuh_manager_registry_reviewer_validation_passed_count=1',
'wazuh_manager_registry_reviewer_validation_quarantined_count=0',
'wazuh_manager_registry_reviewer_validation_manager_registry_accepted_count=0',
'wazuh_manager_registry_reviewer_validation_post_enable_readback_passed_count=0',
'wazuh_manager_registry_reviewer_validation_post_enable_readback_passed_count=1',
'wazuh_manager_registry_reviewer_validation_runtime_gate_count=0',
'wazuh_api_live_query_authorized=false',
'wazuh_agent_reenroll_authorized=false',
@@ -9822,6 +9822,12 @@ function IwoooSWazuhManagerRegistryReviewerValidationBoard() {
icon: ClipboardCheck,
tone: 'steady',
},
{
key: 'postEnable',
value: summary ? String(summary.post_enable_readback_passed_count) : loading ? '...' : '1',
icon: SearchCheck,
tone: summary?.post_enable_readback_passed_count ? 'steady' : 'locked',
},
{
key: 'received',
value: summary ? String(summary.owner_registry_export_received_count) : loading ? '...' : '1',

View File

@@ -78,6 +78,53 @@
- 下一個 P0把 StockPlatform smoke 改成排程限流或搬到非 110 runner再做全主機 cold-start scorecard 與資料 freshness readback。
## 2026-06-27IwoooS Wazuh owner export reviewer validation passed 本地完成
## 2026-06-27 — 21:24 GitHub backup owner response intake readiness 正式讀回完成
**時間與來源**
- 2026-06-27 20:49-21:24 Asia/Taipei。
- 來源feature branch `codex/github-backup-missing-targets-20260627`、Gitea main、Gitea Actions、production API readback。
**完成內容**
- `GET /api/v1/agents/github-target-private-backup-evidence-gate` 已正式讀回 `owner_response_intake_readiness`
- GitHub target owner response request packet、9 個 response templates、allowed fields、forbidden payloads、collection checks、intake preflight checks 與 acceptance checks 已能由 production API 讀出。
- 每個 target 已能讀回 owner response template mapping 與 `owner_response_execution_authorized=false`
- Validator 已防止 owner response request packet、templates 或 checks 夾帶 execution authorization。
**Gitea / deploy 狀態**
- code commit`80138e985 feat(api): expose github owner response intake readiness`
- merge / main push commit`9f5097f66 Merge remote-tracking branch 'gitea/main' into codex/github-backup-missing-targets-20260627`
- deploy marker`e49c6190e chore(cd): deploy 9f5097f [skip ci]`
- code-review`#3690` 成功。
- CD`#3689` 成功tests、build-and-deploy、post-deploy-checks 均完成。
- 最新 main 後續 docs marker`7b2b3db45 docs(awooop): record controlled automation readback [skip ci]`,不改本段 production code 基準。
**production API readback**
- `/api/v1/health?_v=9f5097f66-github-owner-intake`HTTP `200``status=healthy``environment=prod``mock_mode=false`
- `GET /api/v1/agents/github-target-private-backup-evidence-gate?_v=9f5097f66-github-owner-intake`HTTP `200`
- `approval_required_target_count=9``private_backup_verified_count=4``private_visibility_verified_count=4`
- `github_missing_target_resolution_count=5``github_missing_target_create_private_repo_ready_count=0``github_missing_target_refs_sync_ready_count=0`
- `owner_response_request_ready=true``owner_response_required_response_item_count=9``owner_response_requested_template_count=9``owner_response_template_count=9`
- `owner_response_allowed_response_field_count=25``owner_response_forbidden_payload_count=15``owner_response_collection_check_count=6``owner_response_intake_preflight_check_count=6`
- `owner_response_request_execution_authorized=false``owner_response_received_count=0``owner_response_accepted_count=0``safe_credential_accepted_evidence_count=0``execution_ready_count=0``blocked_target_count=9`
- `owner_response_intake_readiness.status=ready_to_collect_read_only_owner_response_not_authorization``request_ready=true``execution_authorized=false``not_approval=true`
- forbidden / redaction proof`private_clone_url_credential` 仍在 forbidden payloads`read_only_markdown_response` 是允許 submission mode`create_github_repo` 仍在 still forbidden正式 API 回應未命中 `192.168.0.`
**Delivery Workbench readback**
- `GET /api/v1/agents/delivery-closure-workbench?_v=9f5097f66-github-owner-intake`HTTP `200`
- schema`delivery_closure_workbench_v1`
- GitHub lane`status=blocked_private_visibility_and_safe_credential_evidence_required`、metric `private_backup_verified=4/9``completion_percent=44``blocker_count=9`
**仍維持 0 / false**
- `github_missing_target_create_private_repo_ready_count=0``github_missing_target_refs_sync_ready_count=0``owner_response_received_count=0``owner_response_accepted_count=0``safe_credential_accepted_evidence_count=0``execution_ready_count=0`
- `github_api_write_allowed=false``repo_creation_allowed=false``visibility_change_allowed=false``refs_sync_allowed=false``workflow_trigger_allowed=false``private_clone_url_collection_allowed=false``secret_value_collection_allowed=false`
**未做**
- 沒有 GitHub repo creation、visibility change、refs sync、workflow trigger、private clone URL collection、secret value collection沒有 host / Docker / systemd / Nginx / firewall / K8s / DB / Wazuh runtime 寫操作;沒有 force push。
**完成度 / 下一步**
- 本段「GitHub owner response intake readiness API / production readback」`85% -> 100%`
- GitHub backup mirror governance 仍為 blocked下一個 P0 是 owner-provided safe credential evidence / redacted evidence refs intake但不得收 private clone URL credential 或 secret value。
## 2026-06-27AwoooP Approvals controlled automation 文案正式讀回完成
**背景**P2-416 D1N 已把 AI Agent 舊 manual gate 規範改為 controlled automationlow / medium / high 風險應走 allowlist、check-mode、controlled apply、verifier、rollback 與 KM / PlayBook writebackcritical 才 break-glass。正式 `/zh-TW/awooop/approvals` 仍因 Next HTML payload 序列化其他 namespace殘留 `待人工決策``阻塞與人工閘門``人工接手``owner review``owner packet` 等舊語意,容易讓 Approvals / Runs / Work Items / Alerts 看起來把人工當預設終局。

View File

@@ -2,7 +2,7 @@
"evidence_slots": [
{
"accepted": true,
"next_gate": "post_enable_iwooos_readback",
"next_gate": "manager_registry_acceptance_evidence_review",
"quarantined": false,
"received": true,
"required_fields": [
@@ -17,7 +17,7 @@
},
{
"accepted": true,
"next_gate": "post_enable_iwooos_readback",
"next_gate": "manager_registry_acceptance_evidence_review",
"quarantined": false,
"received": true,
"required_fields": [
@@ -30,7 +30,7 @@
},
{
"accepted": true,
"next_gate": "post_enable_iwooos_readback",
"next_gate": "manager_registry_acceptance_evidence_review",
"quarantined": false,
"received": true,
"required_fields": [
@@ -45,7 +45,7 @@
},
{
"accepted": true,
"next_gate": "post_enable_iwooos_readback",
"next_gate": "manager_registry_acceptance_evidence_review",
"quarantined": false,
"received": true,
"required_fields": [
@@ -58,7 +58,7 @@
},
{
"accepted": true,
"next_gate": "post_enable_iwooos_readback",
"next_gate": "manager_registry_acceptance_evidence_review",
"quarantined": false,
"received": true,
"required_fields": [
@@ -74,7 +74,7 @@
},
{
"accepted": true,
"next_gate": "post_enable_iwooos_readback",
"next_gate": "manager_registry_acceptance_evidence_review",
"quarantined": false,
"received": true,
"required_fields": [
@@ -150,10 +150,11 @@
"firewall_change",
"nginx_reload"
],
"generated_at": "2026-06-27T20:42:31+08:00",
"mode": "committed_validation_passed_readback_no_runtime_no_secret_collection",
"generated_at": "2026-06-27T21:45:00+08:00",
"mode": "committed_post_enable_iwooos_readback_passed_no_runtime_no_secret_collection",
"no_false_green_rules": [
"reviewer validation passed 只代表脫敏 owner export refs 通過 no-persist 驗證。",
"post-enable IwoooS readback passed 只代表 production API / 前台已讀回 reviewer passed不代表 live Wazuh 查詢或 runtime action。",
"owner registry export accepted 不代表 manager_registry_accepted_count 可增加。",
"Dashboard 可見、index pattern 三綠勾、HTTP 200 或 transport observed 不可替代 manager registry counts。",
"reviewer accepted 只可更新只讀 postureactive response、agent restart、reenroll、host write、secret rotation 或掃描仍需獨立 runtime gate。"
@@ -171,7 +172,8 @@
"reject_runtime_action_request",
"ready_for_reviewer_validation",
"accepted_for_readonly_posture_only",
"waiting_post_enable_iwooos_readback"
"post_enable_iwooos_readback_passed",
"manager_registry_acceptance_evidence_review"
],
"per_host_required_fields": [
"node_alias",
@@ -271,9 +273,9 @@
},
{
"check_id": "RV-10",
"failure_lane": "waiting_post_enable_iwooos_readback",
"required_evidence": "即使 reviewer 未來接受 evidence也只能進 read-only posture必須另有 post-enable readback 才能更新 runtime truth。",
"title": "Post-enable IwoooS readback 仍是下一關"
"failure_lane": "post_enable_iwooos_readback_passed_no_runtime",
"required_evidence": "production API 與前台 smoke 已讀回 reviewer passed此讀回只更新 read-only posture不查 live Wazuh、不保存 raw payload、不開 runtime gate。",
"title": "Post-enable IwoooS readback 已讀回但不開 runtime"
}
],
"schema_version": "wazuh_manager_registry_reviewer_validation_v1",
@@ -282,7 +284,7 @@
"docs/security/wazuh-agent-visibility-owner-evidence-preflight.snapshot.json",
"docs/security/wazuh-managed-host-coverage-gate.snapshot.json"
],
"status": "accepted_for_readonly_posture_only",
"status": "post_enable_iwooos_readback_passed_no_runtime_no_secret_collection",
"summary": {
"active_response_authorized_count": 0,
"evidence_slot_count": 6,
@@ -291,11 +293,11 @@
"forbidden_payload_count": 27,
"host_write_authorized_count": 0,
"manager_registry_accepted_count": 0,
"outcome_lane_count": 13,
"outcome_lane_count": 14,
"owner_registry_export_accepted_count": 1,
"owner_registry_export_received_count": 1,
"per_host_required_field_count": 9,
"post_enable_readback_passed_count": 0,
"post_enable_readback_passed_count": 1,
"required_owner_field_count": 28,
"reviewer_validation_check_count": 10,
"reviewer_validation_failed_count": 0,

View File

@@ -41,7 +41,7 @@ resources:
images:
- name: 192.168.0.110:5000/library/api:IMAGE_TAG_PLACEHOLDER
newName: 192.168.0.110:5000/awoooi/api
newTag: 9f5097f664ef62721c7ea6afa60cb4910da568ef
newTag: 1a8613c9e6641f5d07ab3ff3dad4f8550237d04f
- name: 192.168.0.110:5000/library/web:IMAGE_TAG_PLACEHOLDER
newName: 192.168.0.110:5000/awoooi/web
newTag: 9f5097f664ef62721c7ea6afa60cb4910da568ef
newTag: 1a8613c9e6641f5d07ab3ff3dad4f8550237d04f

View File

@@ -29577,6 +29577,7 @@ def validate(root: Path) -> None:
"wazuh_manager_registry_reviewer_validation_owner_registry_export_received_count=1",
"wazuh_manager_registry_reviewer_validation_owner_registry_export_accepted_count=1",
"wazuh_manager_registry_reviewer_validation_passed_count=1",
"wazuh_manager_registry_reviewer_validation_post_enable_readback_passed_count=1",
"wazuh_manager_registry_reviewer_validation_manager_registry_accepted_count=0",
"wazuh_manager_registry_reviewer_validation_runtime_gate_count=0",
]:
@@ -29606,6 +29607,7 @@ def validate(root: Path) -> None:
"wazuh_manager_registry_reviewer_validation_owner_registry_export_received_count=1",
"wazuh_manager_registry_reviewer_validation_owner_registry_export_accepted_count=1",
"wazuh_manager_registry_reviewer_validation_passed_count=1",
"wazuh_manager_registry_reviewer_validation_post_enable_readback_passed_count=1",
"wazuh_manager_registry_reviewer_validation_manager_registry_accepted_count=0",
"wazuh_manager_registry_reviewer_validation_runtime_gate_count=0",
]:

View File

@@ -128,9 +128,9 @@ REVIEWER_VALIDATION_CHECKS = [
},
{
"check_id": "RV-10",
"title": "Post-enable IwoooS readback 仍是下一關",
"required_evidence": "即使 reviewer 未來接受 evidence也只能進 read-only posture必須另有 post-enable readback 才能更新 runtime truth",
"failure_lane": "waiting_post_enable_iwooos_readback",
"title": "Post-enable IwoooS readback 已讀回但不開 runtime",
"required_evidence": "production API 與前台 smoke 已讀回 reviewer passed此讀回只更新 read-only posture不查 live Wazuh、不保存 raw payload、不開 runtime gate",
"failure_lane": "post_enable_iwooos_readback_passed_no_runtime",
},
]
@@ -147,7 +147,8 @@ OUTCOME_LANES = [
"reject_runtime_action_request",
"ready_for_reviewer_validation",
"accepted_for_readonly_posture_only",
"waiting_post_enable_iwooos_readback",
"post_enable_iwooos_readback_passed",
"manager_registry_acceptance_evidence_review",
]
EVIDENCE_SLOTS = [
@@ -292,8 +293,8 @@ def build_snapshot(generated_at: str) -> dict[str, Any]:
return {
"schema_version": SCHEMA_VERSION,
"generated_at": generated_at,
"status": "accepted_for_readonly_posture_only",
"mode": "committed_validation_passed_readback_no_runtime_no_secret_collection",
"status": "post_enable_iwooos_readback_passed_no_runtime_no_secret_collection",
"mode": "committed_post_enable_iwooos_readback_passed_no_runtime_no_secret_collection",
"scope": "wazuh_manager_registry_owner_export_reviewer_validation",
"source_refs": [
"docs/security/wazuh-agent-visibility-owner-evidence-preflight.snapshot.json",
@@ -315,7 +316,7 @@ def build_snapshot(generated_at: str) -> dict[str, Any]:
"reviewer_validation_failed_count": 0,
"reviewer_validation_quarantined_count": 0,
"manager_registry_accepted_count": 0,
"post_enable_readback_passed_count": 0,
"post_enable_readback_passed_count": 1,
"runtime_gate_count": 0,
"host_write_authorized_count": 0,
"active_response_authorized_count": 0,
@@ -332,7 +333,7 @@ def build_snapshot(generated_at: str) -> dict[str, Any]:
"received": True,
"accepted": True,
"quarantined": False,
"next_gate": "post_enable_iwooos_readback",
"next_gate": "manager_registry_acceptance_evidence_review",
}
for slot in EVIDENCE_SLOTS
],
@@ -355,6 +356,7 @@ def build_snapshot(generated_at: str) -> dict[str, Any]:
},
"no_false_green_rules": [
"reviewer validation passed 只代表脫敏 owner export refs 通過 no-persist 驗證。",
"post-enable IwoooS readback passed 只代表 production API / 前台已讀回 reviewer passed不代表 live Wazuh 查詢或 runtime action。",
"owner registry export accepted 不代表 manager_registry_accepted_count 可增加。",
"Dashboard 可見、index pattern 三綠勾、HTTP 200 或 transport observed 不可替代 manager registry counts。",
"reviewer accepted 只可更新只讀 postureactive response、agent restart、reenroll、host write、secret rotation 或掃描仍需獨立 runtime gate。",
@@ -365,8 +367,12 @@ def build_snapshot(generated_at: str) -> dict[str, Any]:
def validate(root: Path) -> None:
snapshot = load_json(root / SNAPSHOT_PATH)
assert_equal("schema_version", snapshot.get("schema_version"), SCHEMA_VERSION)
assert_equal("status", snapshot.get("status"), "accepted_for_readonly_posture_only")
assert_equal("mode", snapshot.get("mode"), "committed_validation_passed_readback_no_runtime_no_secret_collection")
assert_equal("status", snapshot.get("status"), "post_enable_iwooos_readback_passed_no_runtime_no_secret_collection")
assert_equal(
"mode",
snapshot.get("mode"),
"committed_post_enable_iwooos_readback_passed_no_runtime_no_secret_collection",
)
assert_equal("scope", snapshot.get("scope"), "wazuh_manager_registry_owner_export_reviewer_validation")
assert_equal("expected_scope_aliases", snapshot.get("expected_scope_aliases"), EXPECTED_SCOPE_ALIASES)
assert_equal("required_owner_fields", snapshot.get("required_owner_fields"), REQUIRED_OWNER_FIELDS)
@@ -394,13 +400,13 @@ def validate(root: Path) -> None:
"owner_registry_export_accepted_count",
"reviewer_validation_ready_count",
"reviewer_validation_passed_count",
"post_enable_readback_passed_count",
]:
assert_equal(f"summary.{key}", summary.get(key), 1)
for key in [
"reviewer_validation_failed_count",
"reviewer_validation_quarantined_count",
"manager_registry_accepted_count",
"post_enable_readback_passed_count",
"runtime_gate_count",
"host_write_authorized_count",
"active_response_authorized_count",
@@ -415,7 +421,11 @@ def validate(root: Path) -> None:
assert_equal(f"evidence_slots.{slot.get('slot_id')}.received", slot.get("received"), True)
assert_equal(f"evidence_slots.{slot.get('slot_id')}.accepted", slot.get("accepted"), True)
assert_false(f"evidence_slots.{slot.get('slot_id')}.quarantined", slot.get("quarantined"))
assert_equal(f"evidence_slots.{slot.get('slot_id')}.next_gate", slot.get("next_gate"), "post_enable_iwooos_readback")
assert_equal(
f"evidence_slots.{slot.get('slot_id')}.next_gate",
slot.get("next_gate"),
"manager_registry_acceptance_evidence_review",
)
boundaries = snapshot.get("execution_boundaries", {})
for key, value in boundaries.items():
@@ -454,6 +464,7 @@ def main() -> None:
f"slots={summary['evidence_slot_count']} "
f"received={summary['owner_registry_export_received_count']} "
f"accepted={summary['owner_registry_export_accepted_count']} "
f"post_enable={summary['post_enable_readback_passed_count']} "
f"runtime_gate={summary['runtime_gate_count']}"
)