fix(api): normalize priority work order source truth
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 24s
CD Pipeline / build-and-deploy (push) Successful in 9m37s
CD Pipeline / post-deploy-checks (push) Successful in 1m1s

This commit is contained in:
Your Name
2026-06-30 09:29:54 +08:00
parent a7e6de46aa
commit a4abc00d25
4 changed files with 181 additions and 14 deletions

View File

@@ -8,14 +8,18 @@ external SCM APIs.
from __future__ import annotations
import json
import re
from datetime import datetime
from pathlib import Path
from typing import Any
from zoneinfo import ZoneInfo
from src.services.snapshot_paths import default_operations_dir
_DEFAULT_OPERATIONS_DIR = default_operations_dir(Path(__file__))
_SNAPSHOT_FILE = "awoooi-priority-work-order-readback.snapshot.json"
_SCHEMA_VERSION = "awoooi_priority_work_order_readback_v1"
_SHA_RE = re.compile(r"^[0-9a-f]{40}$")
def load_latest_awoooi_priority_work_order_readback(
@@ -117,26 +121,49 @@ def _enrich_from_current_readbacks(payload: dict[str, Any]) -> None:
runtime_sha = str(
workbench_summary.get("production_deploy_runtime_build_commit_sha") or ""
)
).strip().lower()
runtime_short_sha = str(
workbench_summary.get("production_deploy_runtime_build_commit_short_sha") or ""
)
).strip().lower()
desired_short_sha = str(
workbench_summary.get(
"production_deploy_desired_main_api_image_tag_short_sha"
)
or ""
)
).strip().lower()
current_head = _dict(payload.setdefault("current_head", {}))
current_head["latest_verified_worktree_base_sha"] = runtime_short_sha
current_head["latest_successful_deployed_source_sha"] = runtime_sha
current_head["latest_successful_deploy_marker"] = (
f"production desired image tag {desired_short_sha}"
runtime_source_truth_available = _is_sha(runtime_sha)
if runtime_source_truth_available:
runtime_short_sha = runtime_short_sha or runtime_sha[:10]
desired_short_sha = desired_short_sha or runtime_short_sha
production_readback_id = f"production_readback:{desired_short_sha}"
production_subject = f"production desired image tag {desired_short_sha}"
current_head["gitea_main_sha"] = runtime_sha
current_head["latest_fetched_gitea_main_subject"] = production_subject
current_head["latest_source_readiness_cd_run_id"] = production_readback_id
current_head["latest_verified_worktree_base_sha"] = runtime_short_sha
current_head["latest_successful_deployed_source_sha"] = runtime_sha
current_head["latest_successful_deploy_marker"] = production_subject
current_head["latest_source_readiness_cd_run_status"] = (
"production_readback_verified"
)
current_head["latest_source_readiness_commit_sha"] = runtime_sha
state["updated_at"] = _taipei_now_iso()
state["current_main_cd_run_id"] = production_readback_id
state["current_main_cd_run_status"] = "production_readback_verified"
state["current_main_latest_source_sha"] = runtime_sha
state["latest_successful_deployed_source_sha"] = runtime_sha
state["reboot_drill_preflight_source_status"] = "production_endpoint_ready"
state["p0_004_template_copy_apply_gate_source_status"] = (
"production_endpoint_ready"
)
current_head["production_source_truth_available"] = runtime_source_truth_available
current_head["stale_current_head_metadata_normalized"] = (
runtime_source_truth_available
)
current_head["latest_source_readiness_cd_run_status"] = (
"production_readback_verified"
)
current_head["latest_source_readiness_commit_sha"] = runtime_sha
current_head["no_matching_runner_visible"] = False
current_head["source_readiness_ci_fix_required"] = False
@@ -276,6 +303,74 @@ def _enrich_from_current_readbacks(payload: dict[str, Any]) -> None:
"failed CD runs, and retired GitHub lanes must not reorder closed work."
),
]
_set_rollups_and_summary(
payload=payload,
current_head=current_head,
state=state,
p0_004_ready=p0_004_ready,
p0_006_event_gated=p0_006_event_gated,
runtime_source_truth_available=runtime_source_truth_available,
runtime_sha=runtime_sha,
)
def _set_rollups_and_summary(
*,
payload: dict[str, Any],
current_head: dict[str, Any],
state: dict[str, Any],
p0_004_ready: bool,
p0_006_event_gated: bool,
runtime_source_truth_available: bool,
runtime_sha: str,
) -> None:
completed = _list(payload.get("completed_in_priority_order"))
in_progress = _list(payload.get("in_progress_or_blocked_in_priority_order"))
latest_source_sha = (
runtime_sha
if runtime_source_truth_available
else str(current_head.get("latest_successful_deployed_source_sha") or "")
)
active_blockers = _strings(state.get("active_p0_live_active_blockers"))
active_gap_count = _int(state.get("active_p0_immediate_apply_gap_count"))
payload["rollups"] = {
"completed_p0_count": len(completed),
"in_progress_or_blocked_count": len(in_progress),
"active_p0_immediate_apply_gap_count": active_gap_count,
"active_p0_event_gated_by_fresh_reboot_window_only": p0_006_event_gated,
"active_p0_live_active_blocker_count": len(active_blockers),
"p0_004_runtime_readback_ready": p0_004_ready,
"reboot_drill_preflight_runtime_readback_ready": (
state.get("reboot_drill_preflight_runtime_readback_state") == "ready"
),
"production_source_truth_available": runtime_source_truth_available,
"stale_current_head_metadata_normalized": runtime_source_truth_available,
"stale_cd_runs_reopen_closed_work": False,
"break_glass_reboot_drill_required": True,
}
payload["summary"] = {
"status": str(payload.get("status") or ""),
"active_p0_workplan_id": str(state.get("active_p0_workplan_id") or ""),
"active_p0_state": str(state.get("active_p0_state") or ""),
"active_p0_readiness_percent": _int(
state.get("active_p0_readiness_percent")
),
"active_p0_live_active_blockers": active_blockers,
"latest_successful_deployed_source_sha": latest_source_sha,
"latest_successful_deployed_source_short_sha": latest_source_sha[:10],
"latest_successful_deploy_marker": str(
current_head.get("latest_successful_deploy_marker") or ""
),
"next_executable_mainline_workplan_id": str(
state.get("next_executable_mainline_workplan_id") or ""
),
"next_executable_mainline_state": str(
state.get("next_executable_mainline_state") or ""
),
"production_source_truth_available": runtime_source_truth_available,
"stale_current_head_metadata_normalized": runtime_source_truth_available,
}
def _require_schema(payload: dict[str, Any], label: str) -> None:
@@ -358,3 +453,11 @@ def _int(value: Any) -> int:
def _strings(value: Any) -> list[str]:
return [str(item) for item in _list(value)]
def _is_sha(value: str) -> bool:
return bool(_SHA_RE.fullmatch(value))
def _taipei_now_iso() -> str:
return datetime.now(ZoneInfo("Asia/Taipei")).isoformat(timespec="seconds")

View File

@@ -42,12 +42,12 @@ from src.services.gitea_workflow_runner_owner_attestation_request import (
from src.services.p0_cicd_baseline_source_readiness import (
load_latest_p0_cicd_baseline_source_readiness,
)
from src.services.reboot_auto_recovery_slo_scorecard import (
load_latest_reboot_auto_recovery_slo_scorecard,
)
from src.services.reboot_auto_recovery_drill_preflight import (
load_latest_reboot_auto_recovery_drill_preflight,
)
from src.services.reboot_auto_recovery_slo_scorecard import (
load_latest_reboot_auto_recovery_slo_scorecard,
)
from src.services.runtime_surface_inventory import (
load_latest_runtime_surface_inventory,
)

View File

@@ -74,6 +74,50 @@ def test_awoooi_priority_work_order_readback_endpoint_returns_snapshot():
assert "do not reboot" in data["next_execution_order"][0]
def test_awoooi_priority_work_order_readback_normalizes_runtime_source_truth(
monkeypatch: pytest.MonkeyPatch,
):
runtime_sha = "b4dc407ce05c68a3908b993437a61b869d83810f"
runtime_short_sha = runtime_sha[:10]
monkeypatch.setenv("AWOOOI_BUILD_COMMIT_SHA", runtime_sha)
monkeypatch.setenv("AWOOOI_DESIRED_API_IMAGE_TAG", runtime_sha)
payload = load_latest_awoooi_priority_work_order_readback()
current_head = payload["current_head"]
state = payload["mainline_execution_state"]
assert current_head["gitea_main_sha"] == runtime_sha
assert current_head["latest_source_readiness_commit_sha"] == runtime_sha
assert current_head["latest_source_readiness_cd_run_id"] == (
f"production_readback:{runtime_short_sha}"
)
assert current_head["latest_fetched_gitea_main_subject"] == (
f"production desired image tag {runtime_short_sha}"
)
assert current_head["stale_current_head_metadata_normalized"] is True
assert state["current_main_latest_source_sha"] == runtime_sha
assert state["latest_successful_deployed_source_sha"] == runtime_sha
assert state["current_main_cd_run_status"] == "production_readback_verified"
assert state["p0_004_template_copy_apply_gate_source_status"] == (
"production_endpoint_ready"
)
assert state["reboot_drill_preflight_source_status"] == "production_endpoint_ready"
assert payload["rollups"]["stale_current_head_metadata_normalized"] is True
assert payload["summary"]["latest_successful_deployed_source_sha"] == runtime_sha
current_truth = json.dumps(
{
"current_head": current_head,
"mainline_execution_state": state,
},
ensure_ascii=False,
sort_keys=True,
)
assert "3973" not in current_truth
assert "49637ee7" not in current_truth
assert "f426522" not in current_truth
def test_awoooi_priority_work_order_readback_rejects_reordered_active_p0(tmp_path):
operations_dir = tmp_path / "docs" / "operations"
operations_dir.mkdir(parents=True)

View File

@@ -50156,3 +50156,23 @@ production browser smoke:
- 沒有讀 secret / token / `.env` / raw sessions / SQLite / auth沒有寫 credential marker。
- 沒有重啟主機,沒有 restart Docker / Nginx / K3s / DB / firewall。
- 沒有使用 GitHub / gh / GitHub API / GitHub Actions。
## 2026-06-30 — 09:28 P0 priority work-order runtime source truth 正規化
**完成內容**
- 修正 `apps/api/src/services/awoooi_priority_work_order_readback.py`:當 Delivery Workbench 讀到合法 production runtime deploy SHA 時,將 `current_head``mainline_execution_state` 的 current main / CD / deployed source 欄位正規化為 `production_readback:<short_sha>`,不再讓舊 snapshot 的 `#3973``49637ee7``f426522` 混入目前主線進度。
- 新增 `rollups` / `summary`,明確輸出 `production_source_truth_available``stale_current_head_metadata_normalized``stale_cd_runs_reopen_closed_work=false`、P0-006 fresh reboot event gate 與 P0-004 / reboot preflight readiness。
- 補 `apps/api/tests/test_awoooi_priority_work_order_readback_api.py` regression`AWOOOI_BUILD_COMMIT_SHA` / `AWOOOI_DESIRED_API_IMAGE_TAG` 模擬 production env鎖住 priority readback 不再回吐舊 CD/run/source metadata。
**本地驗證結果**
- rebase 到 `a7e6de46a feat(delivery): expose p0 reboot drill readback` 後,`DATABASE_URL=postgresql+asyncpg://test:test@localhost:5432/test PYTHONPATH=apps/api python3.11 -m pytest apps/api/tests/test_awoooi_priority_work_order_readback_api.py apps/api/tests/test_delivery_closure_workbench_api.py ops/runner/test_cd_controlled_runtime_profile.py -q``35 passed`
- `PYTHONPATH=apps/api python3.11 -m py_compile apps/api/src/services/awoooi_priority_work_order_readback.py apps/api/tests/test_awoooi_priority_work_order_readback_api.py apps/api/src/services/delivery_closure_workbench.py apps/api/tests/test_delivery_closure_workbench_api.py`:通過。
- `PYTHONPATH=apps/api python3.11 -m ruff check apps/api/src/services/awoooi_priority_work_order_readback.py apps/api/tests/test_awoooi_priority_work_order_readback_api.py apps/api/src/services/delivery_closure_workbench.py apps/api/tests/test_delivery_closure_workbench_api.py`:通過。
- `python3.11 ops/runner/guard-gitea-runner-pressure.py --root .`:通過,`auto_branch_events_on_110=0``generic_runner_labels=0`
- `node scripts/ci/check-gitea-step-env-secrets.js`:通過。
- `git diff --check`:通過。
**仍維持**
- 沒有讀 secret / token / `.env` / raw sessions / SQLite / auth。
- 沒有使用 GitHub / gh / GitHub API / GitHub Actions。
- 沒有重啟主機,沒有 workflow_dispatch沒有 host / Docker / K8s / DB / firewall runtime 寫入。