fix(telegram): close Wazuh lifecycle dedupe loop
All checks were successful
CD Pipeline / select-latest-carrier (push) Successful in 56s
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
AI 技術雷達監控 / ai-technology-watch (push) Successful in 42s
CD Pipeline / tests (push) Successful in 2m53s
CD Pipeline / revalidate-deploy-carrier (push) Successful in 44s
CD Pipeline / build-and-deploy (push) Successful in 15m53s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 24s
CD Pipeline / revalidate-post-deploy-carrier (push) Successful in 38s
CD Pipeline / post-deploy-checks (push) Successful in 3m18s

This commit is contained in:
Your Name
2026-07-22 19:55:23 +08:00
parent 0a3b8363cc
commit 6b87cf6d7f
7 changed files with 537 additions and 132 deletions

View File

@@ -1575,7 +1575,7 @@ async def test_no_write_replay_receipt_never_claims_runtime_apply(monkeypatch) -
@pytest.mark.asyncio
async def test_healthy_posture_readback_is_suppressed_and_never_claims_apply(
async def test_historical_healthy_posture_is_shadowed_and_never_claims_apply(
monkeypatch,
) -> None:
gateway = TelegramGateway()
@@ -1621,7 +1621,11 @@ async def test_healthy_posture_readback_is_suppressed_and_never_claims_apply(
duration_ms=8649,
verifier_written=True,
learning_written=True,
rag_written=True,
mcp_context_ready=True,
playbook_trust_written=True,
execution_kind="no_write_posture_readback",
provider_delivery="shadow_only",
project_id="awoooi",
)
@@ -1642,11 +1646,12 @@ async def test_healthy_posture_readback_is_suppressed_and_never_claims_apply(
assert policy["provider_delivery"] == "shadow_only"
assert policy["disposition"] == "suppressed"
assert policy["provider_send_performed"] is False
assert policy["lifecycle_state"] == "recovered"
assert policy["runtime_write_performed"] is False
@pytest.mark.asyncio
async def test_healthy_wazuh_posture_is_recipient_visible_once_per_run(
async def test_healthy_wazuh_posture_uses_stable_lifecycle_transition(
monkeypatch,
) -> None:
gateway = TelegramGateway()
@@ -1702,16 +1707,16 @@ async def test_healthy_wazuh_posture_is_recipient_visible_once_per_run(
method, payload = sent_requests[0]
assert method == "sendMessage"
assert "Runtime write: <code>0</code>" in payload["text"]
assert "本次 run 僅外送一次" in payload["text"]
assert "狀態轉換僅外送一次" in payload["text"]
policy = payload["_awooop_source_envelope_extra"]["notification_policy"]
assert policy["policy_version"] == (
"telegram_wazuh_posture_same_run_receipt_v1"
"telegram_posture_lifecycle_transition_v1"
)
assert policy["provider_delivery"] == "state_transition"
assert policy["disposition"] == "send_once_per_run"
assert policy["group_scope"] == "controlled_asset_same_run"
assert policy["disposition"] == "send_on_transition"
assert policy["group_scope"] == "controlled_asset_lifecycle"
assert policy["delivery_semantics"] == (
"at_least_once_per_run_after_unknown_ack_lease"
"at_least_once_after_unknown_ack_lease"
)
assert policy["lifecycle_state"] == "recovered"
assert policy["runtime_write_performed"] is False
@@ -1723,7 +1728,6 @@ async def test_healthy_wazuh_posture_is_recipient_visible_once_per_run(
playbook_path=(
"infra/ansible/playbooks/wazuh-manager-posture-readback.yml"
),
scope_discriminator="00000000-0000-0000-0000-000000000013",
)
)
@@ -1762,7 +1766,7 @@ def test_controlled_apply_lifecycle_scope_preserves_legacy_and_separates_runs(
@pytest.mark.asyncio
async def test_failed_posture_readback_is_digest_deduplicated_and_queues_repair(
async def test_failed_wazuh_posture_uses_lifecycle_transition_and_queues_repair(
monkeypatch,
) -> None:
gateway = TelegramGateway()
@@ -1808,10 +1812,16 @@ async def test_failed_posture_readback_is_digest_deduplicated_and_queues_repair(
assert "AI 自動修復摘要|姿態檢查待修復" in payload["text"]
assert "transport_or_playbook_repair_queued" in payload["text"]
assert "Runtime write: <code>0</code>" in payload["text"]
assert "狀態轉換僅外送一次" in payload["text"]
policy = payload["_awooop_source_envelope_extra"]["notification_policy"]
assert policy["provider_delivery"] == "digest"
assert policy["digest_window_minutes"] == 30
assert len(policy["failure_fingerprint"]) == 24
assert policy["policy_version"] == (
"telegram_posture_lifecycle_transition_v1"
)
assert policy["provider_delivery"] == "state_transition"
assert policy["disposition"] == "send_on_transition"
assert policy["lifecycle_state"] == "failed"
assert "digest_window_minutes" not in policy
assert "failure_fingerprint" not in policy
def test_callback_reply_awooop_status_chain_snapshot_marks_manual_gate() -> None: