feat(api): expose onboarding template copy receipt
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 21s
CD Pipeline / build-and-deploy (push) Successful in 8m58s
CD Pipeline / post-deploy-checks (push) Has been cancelled

This commit is contained in:
Your Name
2026-06-30 00:26:30 +08:00
parent ff44598b58
commit 6420f4b1eb
8 changed files with 459 additions and 0 deletions

View File

@@ -243,6 +243,10 @@ jobs:
;;
docs/operations/p0-cicd-baseline-source-readiness.snapshot.json)
;;
.gitea/workflows/awoooi-onboarding-warning-step.yaml)
;;
docs/operations/templates/awoooi-gitea-onboarding-warning-step.workflow.yaml)
;;
docs/operations/awoooi-production-deploy-readback-blocker.snapshot.json)
;;
docs/operations/ai-agent-log-intelligence-runtime-sample-readback.snapshot.json)
@@ -309,6 +313,8 @@ jobs:
;;
apps/api/src/services/awoooi_gitea_onboarding_warning_step_template_copy_execution_plan.py)
;;
apps/api/src/services/awoooi_gitea_onboarding_warning_step_template_copy_receipt.py)
;;
apps/api/src/services/awoooi_new_product_onboarding_page_model.py)
;;
apps/api/src/services/awoooi_onboarding_reminder_contract.py)
@@ -552,6 +558,7 @@ jobs:
src/services/awoooi_gitea_onboarding_warning_step_owner_response_preflight.py \
src/services/awoooi_gitea_onboarding_warning_step_template_copy_apply_gate.py \
src/services/awoooi_gitea_onboarding_warning_step_template_copy_execution_plan.py \
src/services/awoooi_gitea_onboarding_warning_step_template_copy_receipt.py \
src/services/awoooi_new_product_onboarding_page_model.py \
src/services/awoooi_onboarding_reminder_contract.py \
src/services/awoooi_onboarding_source_contracts.py \

View File

@@ -322,6 +322,9 @@ from src.services.awoooi_gitea_onboarding_warning_step_template_copy_apply_gate
from src.services.awoooi_gitea_onboarding_warning_step_template_copy_execution_plan import (
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_execution_plan,
)
from src.services.awoooi_gitea_onboarding_warning_step_template_copy_receipt import (
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_receipt,
)
from src.services.awoooi_status_cleanup_dashboard import (
load_latest_awoooi_status_cleanup_dashboard,
)
@@ -1162,6 +1165,36 @@ async def get_awoooi_gitea_onboarding_warning_step_template_copy_execution_plan(
) from exc
@router.get(
"/awoooi-gitea-onboarding-warning-step-template-copy-receipt",
response_model=dict[str, Any],
summary="取得 AWOOOI Gitea onboarding warning-step template copy receipt",
description=(
"讀取 P0-004 warning-step template copy 的受控 receipt"
"此端點檢查 template 已提交、workflow 已複製且 fail-closed、"
"無 branch auto trigger、無泛用 runner label並回傳 rollback / verifier / "
"post-copy boundary。它不觸發 workflow、不建立 repo、不同步 refs、"
"不呼叫 GitHub、不讀 secret、不操作 host / K8s。"
),
)
async def get_awoooi_gitea_onboarding_warning_step_template_copy_receipt() -> dict[str, Any]:
"""回傳 P0-004 warning-step template copy receipt 只讀讀回。"""
try:
payload = await asyncio.to_thread(
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_receipt
)
return redact_public_lan_topology(payload)
except (json.JSONDecodeError, ValueError) as exc:
logger.error(
"awoooi_gitea_onboarding_warning_step_template_copy_receipt_invalid",
error=str(exc),
)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="P0-004 warning-step template copy receipt 無效",
) from exc
@router.get(
"/reboot-auto-recovery-slo-scorecard",
response_model=dict[str, Any],

View File

@@ -0,0 +1,218 @@
"""AWOOOI warning-step template copy receipt readback."""
from __future__ import annotations
import hashlib
import re
from pathlib import Path
from typing import Any
from src.services.awoooi_gitea_onboarding_warning_step_template_copy_apply_gate import (
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_apply_gate,
)
from src.services.snapshot_paths import resolve_repo_root
_SCHEMA_VERSION = "awoooi_gitea_onboarding_warning_step_template_copy_receipt_v1"
_TEMPLATE_RELATIVE_PATH = (
"docs/operations/templates/awoooi-gitea-onboarding-warning-step.workflow.yaml"
)
_WORKFLOW_RELATIVE_PATH = ".gitea/workflows/awoooi-onboarding-warning-step.yaml"
_AUTO_BRANCH_EVENTS = ("push", "pull_request", "pull_request_target")
_GENERIC_LABEL_PATTERNS = (
re.compile(r"^\s*runs-on:\s*.*\bubuntu-[A-Za-z0-9_.-]+\b", re.MULTILINE),
re.compile(r"^\s*runs-on:\s*.*\bself-hosted\b", re.MULTILINE),
)
def load_latest_awoooi_gitea_onboarding_warning_step_template_copy_receipt(
repo_root: Path | None = None,
) -> dict[str, Any]:
"""Return the fail-closed warning-step workflow copy receipt."""
root = repo_root or resolve_repo_root(Path(__file__))
template_path = root / _TEMPLATE_RELATIVE_PATH
workflow_path = root / _WORKFLOW_RELATIVE_PATH
template_text = template_path.read_text(encoding="utf-8") if template_path.exists() else ""
workflow_text = workflow_path.read_text(encoding="utf-8") if workflow_path.exists() else ""
apply_gate = load_latest_awoooi_gitea_onboarding_warning_step_template_copy_apply_gate()
gate_readback = _dict(apply_gate.get("readback"))
active_blockers = _active_blockers(
template_path=template_path,
workflow_path=workflow_path,
template_text=template_text,
workflow_text=workflow_text,
gate_readback=gate_readback,
)
workflow_sha = _short_content_sha(workflow_text) if workflow_text else ""
return {
"schema_version": _SCHEMA_VERSION,
"priority": "P0-004",
"scope": "gitea_onboarding_warning_step_template_copy",
"status": (
"controlled_template_copy_receipt_ready"
if not active_blockers
else "blocked_template_copy_receipt_invalid"
),
"readback": {
"workplan_id": "P0-004-TEMPLATE-COPY-CONTROLLED-APPLY",
"source_apply_gate_status": apply_gate.get("status"),
"template_copy_performed": workflow_path.is_file()
and template_text == workflow_text,
"source_template_path": _TEMPLATE_RELATIVE_PATH,
"destination_workflow_path": _WORKFLOW_RELATIVE_PATH,
"workflow_content_sha256_12": workflow_sha,
"safe_next_step": (
"open_next_gate_for_warning_step_runtime_enablement_after_pressure_guard"
),
},
"target_selector": {
"selector_type": "controlled_workflow_template_copy",
"source_template_path": _TEMPLATE_RELATIVE_PATH,
"destination_workflow_path": _WORKFLOW_RELATIVE_PATH,
"active_workflow_file_created": True,
},
"source_of_truth_diff": {
"source": "controlled_apply_gate_readback",
"apply_gate_endpoint": (
"/api/v1/agents/"
"awoooi-gitea-onboarding-warning-step-template-copy-apply-gate"
),
"receipt_endpoint": (
"/api/v1/agents/"
"awoooi-gitea-onboarding-warning-step-template-copy-receipt"
),
"source_template_path": _TEMPLATE_RELATIVE_PATH,
"destination_workflow_path": _WORKFLOW_RELATIVE_PATH,
},
"check_mode": {
"enabled": True,
"required": True,
"checks": [
"template_file_exists",
"workflow_file_exists",
"workflow_matches_source_template",
"workflow_has_no_auto_branch_event",
"workflow_has_no_generic_runner_label",
"workflow_runtime_execution_switch_defaults_off",
"runner_pressure_guard_required",
"git_diff_check_required",
],
},
"rollback": {
"required": True,
"strategy": "remove_copied_workflow_and_receipt_before_commit",
"paths": [
_WORKFLOW_RELATIVE_PATH,
"apps/api/src/services/"
"awoooi_gitea_onboarding_warning_step_template_copy_receipt.py",
],
},
"post_apply_verifier": {
"required": True,
"verifier_refs": [
"python3 ops/runner/guard-gitea-runner-pressure.py --root .",
"git diff --check",
"pytest apps/api/tests/test_p0_cicd_baseline_source_readiness_api.py",
],
},
"rollups": {
"template_file_present": template_path.is_file(),
"workflow_file_present": workflow_path.is_file(),
"workflow_matches_template": template_text == workflow_text,
"workflow_dispatch_declared": "workflow_dispatch:" in workflow_text,
"auto_branch_event_count": len(_auto_branch_event_hits(workflow_text)),
"generic_runner_label_count": len(_generic_label_hits(workflow_text)),
"fail_closed_execution_switch_present": _fail_closed_switch_present(
workflow_text
),
"apply_gate_ready": _gate_ready(gate_readback),
"active_blocker_count": len(active_blockers),
"active_workflow_file_created": workflow_path.is_file(),
"workflow_trigger_performed": False,
"runner_pressure_guard_required": True,
},
"active_blockers": active_blockers,
"operation_boundaries": {
"controlled_template_copy_only": True,
"workflow_modification_allowed_by_gate": True,
"active_workflow_file_created": workflow_path.is_file(),
"workflow_dispatch_declared": "workflow_dispatch:" in workflow_text,
"workflow_trigger_performed": False,
"auto_push_or_pull_request_trigger_allowed": False,
"generic_runner_label_allowed": False,
"github_api_used": False,
"secret_value_collection_allowed": False,
"host_or_k8s_write_performed": False,
"raw_session_or_sqlite_read_allowed": False,
},
}
def _active_blockers(
*,
template_path: Path,
workflow_path: Path,
template_text: str,
workflow_text: str,
gate_readback: dict[str, Any],
) -> list[str]:
blockers: list[str] = []
if not _gate_ready(gate_readback):
blockers.append("template_copy_apply_gate_not_ready")
if not template_path.is_file():
blockers.append("source_template_file_missing")
if not workflow_path.is_file():
blockers.append("destination_workflow_file_missing")
if template_text != workflow_text:
blockers.append("destination_workflow_differs_from_source_template")
if _auto_branch_event_hits(workflow_text):
blockers.append("auto_branch_event_present_in_workflow")
if _generic_label_hits(workflow_text):
blockers.append("generic_runner_label_present_in_workflow")
if not _fail_closed_switch_present(workflow_text):
blockers.append("fail_closed_execution_switch_missing")
return blockers
def _gate_ready(gate_readback: dict[str, Any]) -> bool:
return (
gate_readback.get("apply_allowed") is True
and gate_readback.get("controlled_apply_allowed") is True
and gate_readback.get("workflow_template_copy_authorized") is True
and gate_readback.get("workflow_trigger_authorized") is False
and gate_readback.get("auto_push_or_pull_request_trigger_authorized") is False
and gate_readback.get("generic_runner_label_authorized") is False
and gate_readback.get("runner_pressure_guard_required") is True
)
def _auto_branch_event_hits(template_text: str) -> list[str]:
return [
event
for event in _AUTO_BRANCH_EVENTS
if re.search(rf"^\s*{event}\s*:", template_text, re.MULTILINE)
or re.search(rf"\bon:\s*\[[^\]]*\b{event}\b", template_text)
]
def _generic_label_hits(template_text: str) -> list[str]:
hits: list[str] = []
for pattern in _GENERIC_LABEL_PATTERNS:
hits.extend(pattern.findall(template_text))
return hits
def _short_content_sha(template_text: str) -> str:
return hashlib.sha256(template_text.encode("utf-8")).hexdigest()[:12]
def _fail_closed_switch_present(template_text: str) -> bool:
return (
'AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED: "0"' in template_text
and "AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED == '1'" in template_text
)
def _dict(value: Any) -> dict[str, Any]:
return value if isinstance(value, dict) else {}

View File

@@ -12,6 +12,9 @@ from typing import Any
from src.services.awoooi_gitea_onboarding_warning_step_template_copy_apply_gate import (
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_apply_gate,
)
from src.services.awoooi_gitea_onboarding_warning_step_template_copy_receipt import (
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_receipt,
)
from src.services.awoooi_production_deploy_readback_blocker import (
load_latest_awoooi_production_deploy_readback_blocker,
)
@@ -52,6 +55,9 @@ def load_delivery_closure_workbench() -> dict[str, Any]:
cicd_template_copy_apply_gate = (
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_apply_gate()
)
cicd_template_copy_receipt = (
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_receipt()
)
gitea = load_latest_gitea_workflow_runner_health()
runtime = load_latest_runtime_surface_inventory()
backup = load_latest_backup_dr_readiness_matrix()
@@ -63,6 +69,7 @@ def load_delivery_closure_workbench() -> dict[str, Any]:
private_inventory=private_inventory,
cicd_baseline=cicd_baseline,
cicd_template_copy_apply_gate=cicd_template_copy_apply_gate,
cicd_template_copy_receipt=cicd_template_copy_receipt,
gitea=gitea,
runtime=runtime,
backup=backup,
@@ -78,6 +85,7 @@ def build_delivery_closure_workbench(
private_inventory: dict[str, Any],
cicd_baseline: dict[str, Any],
cicd_template_copy_apply_gate: dict[str, Any],
cicd_template_copy_receipt: dict[str, Any],
gitea: dict[str, Any],
runtime: dict[str, Any],
backup: dict[str, Any],
@@ -104,6 +112,15 @@ def build_delivery_closure_workbench(
cicd_apply_gate_boundaries = _dict(
cicd_template_copy_apply_gate.get("operation_boundaries")
)
cicd_template_copy_receipt_readback = _dict(
cicd_template_copy_receipt.get("readback")
)
cicd_template_copy_receipt_rollups = _dict(
cicd_template_copy_receipt.get("rollups")
)
cicd_template_copy_receipt_boundaries = _dict(
cicd_template_copy_receipt.get("operation_boundaries")
)
production_deploy_readback = _dict(production_deploy.get("readback"))
production_deploy_rollups = _dict(production_deploy.get("rollups"))
gitea_status = _dict(gitea.get("program_status"))
@@ -798,6 +815,64 @@ def build_delivery_closure_workbench(
cicd_apply_gate_readback.get("runner_pressure_guard_required")
is True
),
"template_copy_receipt_status": str(
cicd_template_copy_receipt.get("status") or ""
),
"template_copy_receipt_ready": (
cicd_template_copy_receipt.get("status")
== "controlled_template_copy_receipt_ready"
),
"template_copy_receipt_active_blocker_count": _int(
cicd_template_copy_receipt_rollups.get("active_blocker_count")
),
"source_template_path": str(
cicd_template_copy_receipt_readback.get("source_template_path")
or ""
),
"destination_workflow_path": str(
cicd_template_copy_receipt_readback.get(
"destination_workflow_path"
)
or ""
),
"source_template_file_present": (
cicd_template_copy_receipt_rollups.get("template_file_present")
is True
),
"destination_workflow_file_present": (
cicd_template_copy_receipt_rollups.get("workflow_file_present")
is True
),
"destination_workflow_matches_template": (
cicd_template_copy_receipt_rollups.get("workflow_matches_template")
is True
),
"destination_workflow_dispatch_declared": (
cicd_template_copy_receipt_rollups.get(
"workflow_dispatch_declared"
)
is True
),
"destination_workflow_auto_branch_event_count": _int(
cicd_template_copy_receipt_rollups.get("auto_branch_event_count")
),
"destination_workflow_generic_runner_label_count": _int(
cicd_template_copy_receipt_rollups.get(
"generic_runner_label_count"
)
),
"destination_workflow_active_file_created": (
cicd_template_copy_receipt_boundaries.get(
"active_workflow_file_created"
)
is True
),
"destination_workflow_trigger_performed": (
cicd_template_copy_receipt_boundaries.get(
"workflow_trigger_performed"
)
is True
),
"required_source_count": _int(
cicd_baseline_rollups.get("required_source_count")
),
@@ -1191,6 +1266,53 @@ def build_delivery_closure_workbench(
cicd_apply_gate_readback.get("runner_pressure_guard_required")
is True
),
"p0_cicd_template_copy_receipt_status": str(
cicd_template_copy_receipt.get("status") or ""
),
"p0_cicd_template_copy_receipt_ready": (
cicd_template_copy_receipt.get("status")
== "controlled_template_copy_receipt_ready"
),
"p0_cicd_template_copy_receipt_active_blocker_count": _int(
cicd_template_copy_receipt_rollups.get("active_blocker_count")
),
"p0_cicd_template_copy_source_template_path": str(
cicd_template_copy_receipt_readback.get("source_template_path")
or ""
),
"p0_cicd_template_copy_destination_workflow_path": str(
cicd_template_copy_receipt_readback.get("destination_workflow_path")
or ""
),
"p0_cicd_template_copy_source_template_file_present": (
cicd_template_copy_receipt_rollups.get("template_file_present")
is True
),
"p0_cicd_template_copy_destination_workflow_file_present": (
cicd_template_copy_receipt_rollups.get("workflow_file_present") is True
),
"p0_cicd_template_copy_destination_workflow_matches_template": (
cicd_template_copy_receipt_rollups.get("workflow_matches_template")
is True
),
"p0_cicd_template_copy_workflow_dispatch_declared": (
cicd_template_copy_receipt_rollups.get("workflow_dispatch_declared")
is True
),
"p0_cicd_template_copy_auto_branch_event_count": _int(
cicd_template_copy_receipt_rollups.get("auto_branch_event_count")
),
"p0_cicd_template_copy_generic_runner_label_count": _int(
cicd_template_copy_receipt_rollups.get("generic_runner_label_count")
),
"p0_cicd_template_copy_active_workflow_file_created": (
cicd_template_copy_receipt_boundaries.get("active_workflow_file_created")
is True
),
"p0_cicd_template_copy_workflow_trigger_performed": (
cicd_template_copy_receipt_boundaries.get("workflow_trigger_performed")
is True
),
"production_deploy_status": str(production_deploy.get("status") or ""),
"production_deploy_source_control_main_ready": production_deploy_rollups.get(
"source_control_main_ready"

View File

@@ -352,6 +352,25 @@ def _assert_delivery_workbench_shape(data: dict):
assert data["summary"]["p0_cicd_template_copy_auto_branch_trigger_authorized"] is False
assert data["summary"]["p0_cicd_template_copy_generic_runner_label_authorized"] is False
assert data["summary"]["p0_cicd_template_copy_runner_pressure_guard_required"] is True
assert data["summary"]["p0_cicd_template_copy_receipt_status"] == (
"controlled_template_copy_receipt_ready"
)
assert data["summary"]["p0_cicd_template_copy_receipt_ready"] is True
assert data["summary"]["p0_cicd_template_copy_receipt_active_blocker_count"] == 0
assert data["summary"]["p0_cicd_template_copy_source_template_file_present"] is True
assert (
data["summary"]["p0_cicd_template_copy_destination_workflow_file_present"]
is True
)
assert (
data["summary"]["p0_cicd_template_copy_destination_workflow_matches_template"]
is True
)
assert data["summary"]["p0_cicd_template_copy_workflow_dispatch_declared"] is True
assert data["summary"]["p0_cicd_template_copy_auto_branch_event_count"] == 0
assert data["summary"]["p0_cicd_template_copy_generic_runner_label_count"] == 0
assert data["summary"]["p0_cicd_template_copy_active_workflow_file_created"] is True
assert data["summary"]["p0_cicd_template_copy_workflow_trigger_performed"] is False
assert data["summary"]["production_deploy_status"] == "closure_verified"
assert data["summary"]["production_deploy_image_tag_matches_main"] is True
assert data["summary"]["backup_credential_escrow_intake_status"] == (

View File

@@ -22,6 +22,9 @@ from src.services.awoooi_gitea_onboarding_warning_step_template_copy_apply_gate
from src.services.awoooi_gitea_onboarding_warning_step_template_copy_execution_plan import (
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_execution_plan,
)
from src.services.awoooi_gitea_onboarding_warning_step_template_copy_receipt import (
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_receipt,
)
from src.services.awoooi_new_product_onboarding_page_model import (
load_latest_awoooi_new_product_onboarding_page_model,
)
@@ -276,3 +279,46 @@ def test_warning_step_template_copy_is_fail_closed_and_pressure_guarded():
assert "runs-on: awoooi-non110-host" in workflow
assert 'AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED: "0"' in workflow
assert "ops/runner/guard-gitea-runner-pressure.py --root ." in workflow
def test_template_copy_receipt_loader_confirms_template_copy():
payload = load_latest_awoooi_gitea_onboarding_warning_step_template_copy_receipt()
_assert_template_copy_receipt(payload)
def test_template_copy_receipt_endpoint_returns_controlled_receipt():
app = FastAPI()
app.include_router(router, prefix="/api/v1")
client = TestClient(app)
response = client.get(
"/api/v1/agents/"
"awoooi-gitea-onboarding-warning-step-template-copy-receipt"
)
assert response.status_code == 200
_assert_template_copy_receipt(response.json())
def _assert_template_copy_receipt(payload: dict):
assert (
payload["schema_version"]
== "awoooi_gitea_onboarding_warning_step_template_copy_receipt_v1"
)
assert payload["priority"] == "P0-004"
assert payload["status"] == "controlled_template_copy_receipt_ready"
assert payload["active_blockers"] == []
assert payload["readback"]["template_copy_performed"] is True
assert payload["target_selector"]["active_workflow_file_created"] is True
assert payload["rollups"]["template_file_present"] is True
assert payload["rollups"]["auto_branch_event_count"] == 0
assert payload["rollups"]["generic_runner_label_count"] == 0
assert payload["rollups"]["apply_gate_ready"] is True
assert payload["rollups"]["workflow_trigger_performed"] is False
assert payload["operation_boundaries"]["controlled_template_copy_only"] is True
assert payload["operation_boundaries"]["active_workflow_file_created"] is True
assert payload["operation_boundaries"]["workflow_trigger_performed"] is False
assert payload["operation_boundaries"]["github_api_used"] is False
assert payload["operation_boundaries"]["secret_value_collection_allowed"] is False
assert payload["operation_boundaries"]["raw_session_or_sqlite_read_allowed"] is False

View File

@@ -1,3 +1,13 @@
## 2026-06-30 — 00:16 P0-004 warning-step template copy receipt
**照優先順序完成的實作**
- 接續 production 已讀回 `controlled_template_copy_apply_gate_ready`,推進同一條 P0-004 主線的下一段 controlled applyGitea warning-step source template `docs/operations/templates/awoooi-gitea-onboarding-warning-step.workflow.yaml` 已複製到 `.gitea/workflows/awoooi-onboarding-warning-step.yaml`
- workflow 只宣告 `workflow_dispatch`,不含 `push` / `pull_request` / `pull_request_target`runner label 為 `awoooi-non110-host`,且 `AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED="0"` 讓 job 預設 fail-closed本輪未觸發 workflow。
- 新增 GET `/api/v1/agents/awoooi-gitea-onboarding-warning-step-template-copy-receipt`,由 service 讀 committed template / copied workflow 並檢查 source/destination 一致、no branch auto trigger、no generic runner label、apply gate ready、rollback 與 post-copy verifier。
- `.gitea/workflows/cd.yaml` controlled-runtime profile 已納入 active workflow path、source template path、新 receipt service 與 focused tests避免 template/readback 變更被送到重型 runner path。
**邊界**:未 workflow_dispatch、未改 runner、未操作 host / Docker / K8s / DB / firewall未使用 GitHub / `gh` / GitHub API未讀 secret / token / raw sessions / SQLite / `.env`
## 2026-06-29 — 23:45 P0-006 final retry window readback source closure
**照優先順序完成的實作**

View File

@@ -64,6 +64,7 @@ def test_p0_onboarding_readiness_sources_stay_on_controlled_runtime_profile() ->
"awoooi_gitea_onboarding_warning_step_owner_response_preflight.py",
"awoooi_gitea_onboarding_warning_step_template_copy_apply_gate.py",
"awoooi_gitea_onboarding_warning_step_template_copy_execution_plan.py",
"awoooi_gitea_onboarding_warning_step_template_copy_receipt.py",
"awoooi_new_product_onboarding_page_model.py",
"awoooi_onboarding_reminder_contract.py",
"awoooi_onboarding_source_contracts.py",
@@ -72,6 +73,9 @@ def test_p0_onboarding_readiness_sources_stay_on_controlled_runtime_profile() ->
for source in expected_sources:
assert f"apps/api/src/services/{source})" in text
assert f"src/services/{source}" in text
assert ".gitea/workflows/awoooi-onboarding-warning-step.yaml)" in text
assert "docs/operations/templates/awoooi-gitea-onboarding-warning-step.workflow.yaml)" in text
assert "tests/test_p0_cicd_baseline_source_readiness_api.py" in text
def test_iwooos_security_operation_api_stays_on_controlled_runtime_profile() -> None: