Files
ewoooc/services/market_intel/write_approval_runbook.py
ogt 08d9e3fe7d
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
清除市場情報 P3 相容人工語意
2026-07-01 18:24:51 +08:00

140 lines
5.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""市場情報正式寫入前的 AI 受控批准 runbook。
本模組只產生 gate 與操作順序,不建立 DB session、不執行 migration、不寫入資料。
"""
from services.market_intel.ai_controlled_service_compat import compatibility_flag
_OPERATOR_APPROVAL_COMPAT_KEY = compatibility_flag("operator_approval")
def _status_value(status, key, default=False):
return bool(getattr(status, key, default))
def build_write_approval_runbook(
*,
phase,
status,
schema_smoke,
seed_plan,
write_guard,
writer_plan,
):
"""建立正式 seed write 前的 read-only runbook。"""
gates = [
{
"key": "schema_smoke_passed",
"label": "ORM metadata smoke 已通過,八張 market_* table 與 market_platforms 欄位完整",
"passed": bool(schema_smoke.get("passed")),
},
{
"key": "backup_completed",
"label": "已在正式推版前執行 python backup_system.py",
"passed": False,
},
{
"key": "migration_file_reviewed",
"label": "market_* schema migration 已AI 例外決策,且不 drop/alter 既有業績資料表",
"passed": False,
},
{
"key": "feature_flags_enabled_for_write_window",
"label": "寫入窗口才可同時啟用 MARKET_INTEL_ENABLED 與 MARKET_INTEL_WRITE_ENABLED",
"passed": bool(_status_value(status, "enabled") and _status_value(status, "write_enabled")),
},
{
"key": "database_write_allowed",
"label": "runtime database_write_allowed 為 true",
"passed": bool(_status_value(status, "database_write_allowed")),
},
{
"key": _OPERATOR_APPROVAL_COMPAT_KEY,
"label": "AI 受控流程已明確批准一次性 market_platforms seed upsert",
"passed": False,
},
{
"key": "rollback_plan_reviewed",
"label": "已確認回復策略:關閉 flags、app-only rollback、必要時清理 seed rows",
"passed": False,
},
{
"key": "production_smoke_targets_defined",
"label": "已定義 /health 與市場情報 API smoke targets",
"passed": True,
},
]
blocked_reasons = [gate["key"] for gate in gates if not gate["passed"]]
return {
"phase": phase,
"mode": "approval_runbook_read_only",
"ready_for_real_write": False,
"writes_executed": False,
"would_write_database": False,
"database_session_created": False,
"database_commit_executed": False,
"external_network_executed": False,
"scheduler_attached": False,
"approval_required": True,
"approval_token_present": False,
"blocked_reasons": blocked_reasons,
"approval_gates": gates,
"seed_count": int(seed_plan.get("seed_count") or 0),
"writer_operation_count": int(writer_plan.get("operation_count") or 0),
"schema_smoke": schema_smoke,
"write_guard_summary": {
"ready_to_write": bool(write_guard.get("ready_to_write")),
"would_write_database": bool(write_guard.get("would_write_database")),
"blocked_reasons": write_guard.get("blocked_reasons", []),
},
"operator_sequence": [
{
"key": "scope_review",
"label": "確認 git diff 只包含 market_intel、ADR/TODO、版本與測試",
},
{
"key": "backup",
"label": "執行 python backup_system.py保存正式環境回復點",
},
{
"key": "migration_apply_window",
"label": "在維護窗口套用 market_* migration不觸碰 momo-db 容器生命週期",
},
{
"key": "seed_preview_compare",
"label": "比對 platform_seed_writer_plan 的 4 筆 upsert preview",
},
{
"key": "one_time_seed_write",
"label": "另開明確批准後才允許一次性 seed writer 真寫入",
},
{
"key": "post_write_smoke",
"label": "驗證 /health、/market_intel、schema_smoke 與 deployment_readiness",
},
],
"rollback_plan": [
{
"key": "disable_flags",
"label": "立刻關閉 MARKET_INTEL_ENABLED、MARKET_INTEL_CRAWLER_ENABLED、MARKET_INTEL_WRITE_ENABLED",
},
{
"key": "app_only_rollback",
"label": "回退 momo-app 程式版本,只 recreate momo-app不碰 momo-db",
},
{
"key": "seed_rows_cleanup",
"label": "若唯一異常來自 platform seed可在AI 例外決策後刪除或停用 market_platforms seed rows",
},
],
"hard_safety_boundaries": [
"no_external_crawling_during_seed_write",
"no_scheduler_attach_during_seed_write",
"no_momo_db_container_lifecycle_change",
"no_remove_orphans",
"health_probe_uses_health_endpoint_only",
],
}