fix(telegram): return matrix source gaps as readback
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m1s
CD Pipeline / build-and-deploy (push) Successful in 4m38s
CD Pipeline / post-deploy-checks (push) Successful in 1m51s
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m1s
CD Pipeline / build-and-deploy (push) Successful in 4m38s
CD Pipeline / post-deploy-checks (push) Successful in 1m51s
This commit is contained in:
@@ -81,6 +81,9 @@ def load_latest_telegram_alert_ai_automation_matrix(
|
||||
readability_summary = readability_guard["summary"]
|
||||
digest_rollups = digest_policy["rollups"]
|
||||
source_proof = _inspect_source_contract(repo_root)
|
||||
source_contract_missing_markers = list(
|
||||
source_proof.get("source_contract_missing_markers") or []
|
||||
)
|
||||
learning_writeback_refs_present = bool(
|
||||
source_proof["ai_alert_card_learning_writeback_refs_present"]
|
||||
)
|
||||
@@ -431,6 +434,8 @@ def load_latest_telegram_alert_ai_automation_matrix(
|
||||
"status": (
|
||||
"telegram_alert_ai_automation_matrix_ready_with_direct_send_gaps"
|
||||
if direct_gap_count
|
||||
else "blocked_telegram_alert_ai_automation_matrix_source_contract_gaps"
|
||||
if source_contract_missing_markers
|
||||
else "telegram_alert_ai_automation_matrix_ready"
|
||||
),
|
||||
"mode": "metadata_only_no_secret_no_telegram_send_no_runtime_write",
|
||||
@@ -604,7 +609,7 @@ def _require_safe_boundaries(*payloads: dict[str, Any]) -> None:
|
||||
)
|
||||
|
||||
|
||||
def _inspect_source_contract(repo_root: Path) -> dict[str, int | bool]:
|
||||
def _inspect_source_contract(repo_root: Path) -> dict[str, Any]:
|
||||
source_checks = {
|
||||
"telegram_gateway_mirror_present": (
|
||||
"apps/api/src/services/telegram_gateway.py",
|
||||
@@ -681,9 +686,13 @@ def _inspect_source_contract(repo_root: Path) -> dict[str, int | bool]:
|
||||
1 if present else 0
|
||||
)
|
||||
|
||||
required = [key for key, value in result.items() if key.endswith("_present") and value is not True]
|
||||
if required:
|
||||
raise ValueError(f"Telegram matrix source contract missing markers: {required}")
|
||||
required = [
|
||||
key
|
||||
for key, value in result.items()
|
||||
if key.endswith("_present") and value is not True
|
||||
]
|
||||
result["source_contract_ready"] = not required
|
||||
result["source_contract_missing_markers"] = required
|
||||
return result
|
||||
|
||||
|
||||
@@ -823,7 +832,7 @@ def _build_summary(
|
||||
migration_summary: dict[str, Any],
|
||||
readability_summary: dict[str, Any],
|
||||
digest_rollups: dict[str, Any],
|
||||
source_proof: dict[str, int | bool],
|
||||
source_proof: dict[str, Any],
|
||||
next_priority_action: dict[str, Any],
|
||||
) -> dict[str, Any]:
|
||||
ready = lambda key, prefix: sum(1 for item in matrix if str(item[key]).startswith(prefix))
|
||||
@@ -872,6 +881,13 @@ def _build_summary(
|
||||
"telegram_alert_post_apply_verifier_awooop_surface_count": source_proof[
|
||||
"telegram_alert_post_apply_verifier_awooop_surface_count"
|
||||
],
|
||||
"source_contract_ready": bool(source_proof.get("source_contract_ready")),
|
||||
"source_contract_missing_marker_count": len(
|
||||
source_proof.get("source_contract_missing_markers") or []
|
||||
),
|
||||
"source_contract_missing_markers": list(
|
||||
source_proof.get("source_contract_missing_markers") or []
|
||||
),
|
||||
"next_priority_action_id": next_priority_action["action_id"],
|
||||
"next_priority_work_item_id": "CIR-P0-TG-001",
|
||||
}
|
||||
|
||||
@@ -57,6 +57,9 @@ def test_telegram_alert_ai_automation_matrix_loader_returns_gap_matrix():
|
||||
assert summary["telegram_alert_ai_loop_consumer_context_readback_count"] == 1
|
||||
assert summary["telegram_alert_post_apply_verifier_readback_count"] == 1
|
||||
assert summary["telegram_alert_post_apply_verifier_awooop_surface_count"] == 1
|
||||
assert summary["source_contract_ready"] is True
|
||||
assert summary["source_contract_missing_marker_count"] == 0
|
||||
assert summary["source_contract_missing_markers"] == []
|
||||
assert summary["next_priority_action_id"] == (
|
||||
"audit_all_telegram_monitoring_alerts_db_log_ai_automation_coverage"
|
||||
)
|
||||
@@ -185,6 +188,54 @@ def test_telegram_matrix_source_contract_supports_container_layout(tmp_path):
|
||||
assert proof["telegram_alert_post_apply_verifier_readback_count"] == 1
|
||||
assert proof["telegram_alert_post_apply_verifier_awooop_surface_present"] is True
|
||||
assert proof["telegram_alert_post_apply_verifier_awooop_surface_count"] == 1
|
||||
assert proof["source_contract_ready"] is True
|
||||
assert proof["source_contract_missing_markers"] == []
|
||||
|
||||
|
||||
def test_telegram_matrix_source_contract_reports_missing_web_surface_without_raising(
|
||||
tmp_path,
|
||||
):
|
||||
(tmp_path / "src/services").mkdir(parents=True)
|
||||
(tmp_path / "src/db").mkdir(parents=True)
|
||||
(tmp_path / "src/api/v1/platform").mkdir(parents=True)
|
||||
(tmp_path / "src/services/telegram_gateway.py").write_text(
|
||||
"_mirror_outbound_message\n"
|
||||
"record_outbound_message\n"
|
||||
"ai_automation_alert_card_mirror_v1\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(tmp_path / "src/db/awooop_models.py").write_text(
|
||||
'__tablename__ = "awooop_outbound_message"\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
(tmp_path / "src/api/v1/platform/operator_runs.py").write_text(
|
||||
'"/runs/ai-alert-cards"\n'
|
||||
"learning_writeback_refs\n"
|
||||
"learning_writeback_ready_total\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(tmp_path / "src/services/platform_operator_service.py").write_text(
|
||||
"ai_alert_card_learning_registry_readback_v1\n"
|
||||
"ai_agent_context_ref\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(tmp_path / "src/services/ai_agent_log_controlled_writeback_consumer_readback.py").write_text(
|
||||
"telegram_alert_ai_loop_consumer_context_readback_v1\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(tmp_path / "src/services/telegram_alert_learning_context_post_apply_verifier.py").write_text(
|
||||
"telegram_alert_learning_context_post_apply_verifier_v1\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
proof = _inspect_source_contract(tmp_path)
|
||||
|
||||
assert proof["source_contract_ready"] is False
|
||||
assert proof["telegram_alert_post_apply_verifier_awooop_surface_present"] is False
|
||||
assert proof["telegram_alert_post_apply_verifier_awooop_surface_count"] == 0
|
||||
assert proof["source_contract_missing_markers"] == [
|
||||
"telegram_alert_post_apply_verifier_awooop_surface_present"
|
||||
]
|
||||
|
||||
|
||||
def test_telegram_alert_ai_automation_matrix_endpoint_returns_readback():
|
||||
|
||||
@@ -53402,3 +53402,25 @@ production browser smoke:
|
||||
|
||||
**下一步**:
|
||||
- commit / push 到 Gitea main,讀回新 CD;deploy marker 出現後驗證 `/api/v1/agents/telegram-alert-monitoring-coverage-readback` 與 AwoooP Runs / Work Items / Alerts shared panel。
|
||||
|
||||
## 2026-07-02 — Telegram matrix production 500 source-contract 修正
|
||||
|
||||
**完成內容**:
|
||||
- `#4463` CD 已成功產生 deploy marker `4fd0a4985 chore(cd): deploy 6d1edf6 [skip ci]`,tests 讀回 `AWOOOI_CD_TEST_PROFILE=controlled-runtime` 且 B5 明確跳過;API / Web / Worker rollout、API health 與 production deploy readback 均成功。
|
||||
- deploy 後正式讀回 `/api/v1/agents/telegram-alert-ai-automation-matrix` 與 `/api/v1/agents/telegram-alert-monitoring-coverage-readback` 回 500;根因是 matrix source contract 在 production API container 看不到前端 `apps/web/...` source 時直接 `raise ValueError`。
|
||||
- 已修正 matrix source contract:缺 marker 改為 `source_contract_missing_markers` 與 blocked status / summary,不再讓 readback API 500;coverage service 可繼續消費 matrix blocked payload,將缺口轉成 AI controlled action evidence。
|
||||
- 新增回歸測試,模擬 API container 只有 `src/...` layout 且缺 `apps/web/...` surface 時必須回缺口 evidence、不得 throw。
|
||||
|
||||
**本地驗證結果**:
|
||||
- `DATABASE_URL=postgresql+asyncpg://test:test@localhost/test PYTHONPATH=apps/api python3.11 -m pytest apps/api/tests/test_telegram_alert_ai_automation_matrix_api.py apps/api/tests/test_telegram_alert_monitoring_coverage_readback_api.py -q -p no:cacheprovider`:`7 passed`。
|
||||
- `python3.11 -m pytest ops/runner/test_cd_controlled_runtime_profile.py -q -p no:cacheprovider`:`48 passed`。
|
||||
- `python3.11 -m py_compile apps/api/src/services/telegram_alert_ai_automation_matrix.py apps/api/src/services/telegram_alert_monitoring_coverage_readback.py apps/api/tests/test_telegram_alert_ai_automation_matrix_api.py apps/api/tests/test_telegram_alert_monitoring_coverage_readback_api.py`:通過。
|
||||
- `git diff --check`:通過。
|
||||
|
||||
**仍維持**:
|
||||
- 沒有讀 secret / runner token / `.runner` 內容 / `.env` / raw sessions / SQLite / auth。
|
||||
- 沒有使用 GitHub / gh / GitHub API / GitHub Actions。
|
||||
- 沒有重啟主機,沒有 Docker / Nginx / K3s / DB / firewall restart,沒有 workflow_dispatch,沒有 DROP / TRUNCATE / restore / prune。
|
||||
|
||||
**下一步**:
|
||||
- commit / push 到 Gitea main;等 deploy marker 後重新讀 production matrix / coverage endpoint,再跑 AwoooP Runs / Work Items / Alerts smoke。
|
||||
|
||||
Reference in New Issue
Block a user