diff --git a/docs/memory/claude_inventory_validation_20260513.md b/docs/memory/claude_inventory_validation_20260513.md index aef2f7a..7375182 100644 --- a/docs/memory/claude_inventory_validation_20260513.md +++ b/docs/memory/claude_inventory_validation_20260513.md @@ -31,6 +31,7 @@ - `app.py` 的 `SYSTEM_VERSION` 已從 `config.py` import,app 內只留版本註解。 - V2 提到的 `app.py` 死 import 與 `scheduler.py import schedule` 已不成立;`app.py` 仍使用 `schedule.run_pending()` 等呼叫。 - Cron 盲區清單多數已補 `_notify_scheduler_failure()`;ROI 月報已避開 09:00 改 09:05,AI smoke 已是 09:10。 +- V2 指出的 9 個 cron 盲區已補回歸守門:8 個 `run_scheduler.py` wrapper 必須呼叫 `_notify_scheduler_failure()`,`scheduler.py::run_promo_event_task` 必須呼叫 `notify_failure()`。 - 0-byte `database/momo*.db` 迷惑檔已不存在;真實 SQLite 僅在 `data/momo_database.db`。 - `.gitignore` 已涵蓋 `.claude/worktrees/`、`.tmp_*`、`MOMO Pro/`、uploads/screenshots。 - `cache_service.py` 已成為 `cache_manager.py` 的相容 shim,`_SALES_CACHE_TTL` 單一來源有測試鎖住。 @@ -87,3 +88,4 @@ - `f44c429` 補強 AI logger best-effort 診斷 - `8a36856` 補強 Telegram callback 診斷 - `5b52af9` 補強 cache best-effort 診斷 +- `497c376` 記錄 AI smoke service 入口驗證 diff --git a/tests/test_run_scheduler_embed_consistency.py b/tests/test_run_scheduler_embed_consistency.py index 6819eae..cd925b4 100644 --- a/tests/test_run_scheduler_embed_consistency.py +++ b/tests/test_run_scheduler_embed_consistency.py @@ -1,5 +1,7 @@ import importlib import inspect +import ast +from pathlib import Path def _load_run_scheduler(monkeypatch): @@ -8,6 +10,15 @@ def _load_run_scheduler(monkeypatch): return importlib.import_module("run_scheduler") +def _function_source(path, function_name): + source = Path(path).read_text() + tree = ast.parse(source) + for node in tree.body: + if isinstance(node, ast.FunctionDef) and node.name == function_name: + return ast.get_source_segment(source, node) or "" + raise AssertionError(f"{function_name} not found in {path}") + + def test_embed_consistency_mismatch_notifies_event_router(monkeypatch): run_scheduler = _load_run_scheduler(monkeypatch) import services.rag_service as rag_service @@ -108,3 +119,23 @@ def test_scheduler_observability_wrappers_notify_on_exception(monkeypatch): ]: source = inspect.getsource(getattr(run_scheduler, fn_name)) assert "_notify_scheduler_failure(" in source + + +def test_v2_cron_blind_spot_list_has_failure_notifications(monkeypatch): + run_scheduler = _load_run_scheduler(monkeypatch) + + for fn_name in [ + "run_daily_token_report_task", + "run_promotion_gate_worker", + "run_awaiting_review_push", + "run_expire_stale_reviews", + "run_cost_throttle_evaluate", + "run_cost_throttle_reset_if_new_month", + "run_ppt_vision_audit", + "run_embed_consistency_check", + ]: + source = inspect.getsource(getattr(run_scheduler, fn_name)) + assert "_notify_scheduler_failure(" in source + + promo_source = _function_source("scheduler.py", "run_promo_event_task") + assert "notify_failure(" in promo_source