From 4fd3fe9f859cf43358a200ad5b59f2cfab3737b2 Mon Sep 17 00:00:00 2001 From: ogt Date: Wed, 15 Jul 2026 16:36:26 +0800 Subject: [PATCH 1/2] fix(security): persist scheduled Wazuh lifecycle defaults --- .../api/src/jobs/awooop_ansible_candidate_backfill_job.py | 8 ++++++++ apps/api/tests/test_wazuh_alertmanager_integration.py | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/apps/api/src/jobs/awooop_ansible_candidate_backfill_job.py b/apps/api/src/jobs/awooop_ansible_candidate_backfill_job.py index 29f877c8a..428d19dba 100644 --- a/apps/api/src/jobs/awooop_ansible_candidate_backfill_job.py +++ b/apps/api/src/jobs/awooop_ansible_candidate_backfill_job.py @@ -666,6 +666,8 @@ def _public_safe_wazuh_scheduled_incident_record( ensure_ascii=False, ), "proposal_ids": "[]", + "ttl_days": 7, + "vectorized": False, "alertname": alertname, "notification_type": "TYPE-5S" if ingress_lane else "TYPE-2", "alert_category": "security", @@ -691,6 +693,7 @@ async def ensure_iwooos_wazuh_scheduled_incident( INSERT INTO incidents ( incident_id, project_id, status, severity, signals, affected_services, proposal_ids, + ttl_days, vectorized, alertname, notification_type, alert_category, created_at, updated_at ) VALUES ( @@ -698,6 +701,7 @@ async def ensure_iwooos_wazuh_scheduled_incident( CAST(:signals AS json), CAST(:affected_services AS json), CAST(:proposal_ids AS json), + :ttl_days, :vectorized, :alertname, :notification_type, :alert_category, :created_at, :updated_at ) @@ -714,6 +718,8 @@ async def ensure_iwooos_wazuh_scheduled_incident( alertname, notification_type, alert_category, + ttl_days, + vectorized, json_array_length(signals) AS signal_count, json_array_length(affected_services) AS affected_service_count FROM incidents @@ -734,6 +740,8 @@ async def ensure_iwooos_wazuh_scheduled_incident( and row.get("alertname") == record["alertname"] and row.get("notification_type") == record["notification_type"] and row.get("alert_category") == "security" + and int(row.get("ttl_days") or 0) == 7 + and row.get("vectorized") is False and int(row.get("signal_count") or 0) > 0 and int(row.get("affected_service_count") or 0) > 0 ) diff --git a/apps/api/tests/test_wazuh_alertmanager_integration.py b/apps/api/tests/test_wazuh_alertmanager_integration.py index 07b7cdf00..e6594c28f 100644 --- a/apps/api/tests/test_wazuh_alertmanager_integration.py +++ b/apps/api/tests/test_wazuh_alertmanager_integration.py @@ -464,6 +464,8 @@ async def test_wazuh_scheduled_incident_bind_is_idempotent_and_public_safe( "alertname": "WazuhAlertmanagerIntegrationConvergence", "notification_type": "TYPE-5S", "alert_category": "security", + "ttl_days": 7, + "vectorized": False, "signal_count": 1, "affected_service_count": 2, } @@ -496,6 +498,9 @@ async def test_wazuh_scheduled_incident_bind_is_idempotent_and_public_safe( inserted = calls[0][1] assert inserted["notification_type"] == "TYPE-5S" assert inserted["severity"] == "P1" + assert inserted["ttl_days"] == 7 + assert inserted["vectorized"] is False + assert "ttl_days, vectorized" in calls[0][0] encoded = json.dumps(inserted, default=str, sort_keys=True) assert "sensor-agent" in encoded assert "raw" not in encoded.lower() From e403d87210b853ee8229f980e6f459843b1cd4d6 Mon Sep 17 00:00:00 2001 From: ogt Date: Wed, 15 Jul 2026 16:53:18 +0800 Subject: [PATCH 2/2] refactor(iwooos): prioritize live security closure --- ...wooos_wazuh_controlled_executor_runtime.py | 34 +++++++++++++++++++ apps/web/src/app/[locale]/iwooos/page.tsx | 14 +------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/apps/api/tests/test_iwooos_wazuh_controlled_executor_runtime.py b/apps/api/tests/test_iwooos_wazuh_controlled_executor_runtime.py index ef49b528a..0310f7f9c 100644 --- a/apps/api/tests/test_iwooos_wazuh_controlled_executor_runtime.py +++ b/apps/api/tests/test_iwooos_wazuh_controlled_executor_runtime.py @@ -861,3 +861,37 @@ def test_wazuh_runtime_api_is_public_safe(monkeypatch: pytest.MonkeyPatch) -> No assert "stdout" not in response.text assert "ssh_key" not in response.text assert "WAZUH_API_PASSWORD" not in response.text + + +def test_iwooos_runtime_workspace_defaults_to_live_closure_without_legacy_text_wall() -> None: + repo_root = Path(__file__).resolve().parents[3] + source = ( + repo_root / "apps/web/src/app/[locale]/iwooos/page.tsx" + ).read_text(encoding="utf-8") + + assert "useState('runtime')" in source + runtime_panel = source.split( + "", 1 + )[1].split("", 1)[0] + ledger_panel = source.split( + "", 1 + )[1].split("", 1)[0] + + assert "" in runtime_panel + assert "" in runtime_panel + legacy_boards = ( + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + ) + assert all(board not in runtime_panel for board in legacy_boards) + assert all(board in ledger_panel for board in legacy_boards) diff --git a/apps/web/src/app/[locale]/iwooos/page.tsx b/apps/web/src/app/[locale]/iwooos/page.tsx index 717406809..d209347c5 100644 --- a/apps/web/src/app/[locale]/iwooos/page.tsx +++ b/apps/web/src/app/[locale]/iwooos/page.tsx @@ -25114,7 +25114,7 @@ function HostOwnerDecisionRecordHumanRecordOwnerReviewPreparationChecklistCard({ export default function IwoooSPage({ params }: { params: { locale: string } }) { const t = useTranslations('iwooos') const ia = useTranslations('iwooos.informationArchitecture') - const [workspaceView, setWorkspaceView] = useState('overview') + const [workspaceView, setWorkspaceView] = useState('runtime') return ( @@ -25146,18 +25146,6 @@ export default function IwoooSPage({ params }: { params: { locale: string } }) { - - - - - - - - - - - -