Merge remote-tracking branch 'gitea-ssh/main' into codex/p0-product-manifest-standard-20260629
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Failing after 2m46s
CD Pipeline / build-and-deploy (push) Has been skipped
CD Pipeline / post-deploy-checks (push) Has been skipped

# Conflicts:
#	docs/LOGBOOK.md
This commit is contained in:
Your Name
2026-06-29 12:47:25 +08:00
16 changed files with 457 additions and 53 deletions

View File

@@ -0,0 +1,33 @@
"""AWOOOI warning-step dashboard source."""
from __future__ import annotations
from typing import Any
from src.services.awoooi_onboarding_source_contracts import source_ready_payload
_SCHEMA_VERSION = "awoooi_gitea_onboarding_warning_step_dashboard_v1"
def load_latest_awoooi_gitea_onboarding_warning_step_dashboard() -> dict[str, Any]:
"""Return the read-only dashboard model for warning-step gates."""
return source_ready_payload(
schema_version=_SCHEMA_VERSION,
source_id="warning_step_dashboard_service",
status="dashboard_source_ready_apply_gate_closed",
readback={
"dashboard_status": "ready_read_only_apply_gate_closed",
"gate_count": 4,
"blocked_gate_count": 1,
"cards": [
"owner_package",
"owner_response_preflight",
"template_copy_execution_plan",
"template_copy_apply_gate",
],
},
next_actions=[
"show_apply_gate_closed_state",
"wait_for_apply_gate_before_workflow_copy",
],
)

View File

@@ -0,0 +1,37 @@
"""AWOOOI Gitea onboarding warning-step owner package source."""
from __future__ import annotations
from typing import Any
from src.services.awoooi_onboarding_source_contracts import source_ready_payload
_SCHEMA_VERSION = "awoooi_gitea_onboarding_warning_step_owner_package_v1"
def load_latest_awoooi_gitea_onboarding_warning_step_owner_package() -> dict[str, Any]:
"""Return the committed owner package source for warning-step review."""
return source_ready_payload(
schema_version=_SCHEMA_VERSION,
source_id="warning_step_owner_package_service",
status="source_ready_owner_package_recorded",
readback={
"package_id": "awoooi-gitea-onboarding-warning-step-owner-package",
"workflow_modification_authorized": False,
"workflow_trigger_authorized": False,
"required_review_items": [
"target_workflow_template",
"warning_only_behavior",
"runner_pressure_guard",
"post_copy_verifier",
],
"source_refs": [
"docs/operations/p0-cicd-baseline-source-readiness.snapshot.json",
"ops/runner/guard-gitea-runner-pressure.py",
],
},
next_actions=[
"validate_owner_response_preflight_before_template_copy_plan",
"keep_warning_step_copy_blocked_until_apply_gate",
],
)

View File

@@ -0,0 +1,48 @@
"""AWOOOI warning-step owner response preflight source."""
from __future__ import annotations
from collections.abc import Mapping
from typing import Any
from src.services.awoooi_onboarding_source_contracts import source_ready_payload
_SCHEMA_VERSION = "awoooi_gitea_onboarding_warning_step_owner_response_preflight_v1"
_REQUIRED_ACKS = (
"accept_warning_only_scope",
"confirm_no_push_or_pull_request_trigger",
"confirm_no_generic_runner_label",
"confirm_runner_pressure_guard_required",
)
def load_latest_awoooi_gitea_onboarding_warning_step_owner_response_preflight(
response: Mapping[str, Any] | None = None,
) -> dict[str, Any]:
"""Validate redacted owner response fields without opening workflow gates."""
response = response or {}
accepted = [
key for key in _REQUIRED_ACKS if response.get(key) is True
]
ready = len(accepted) == len(_REQUIRED_ACKS)
return source_ready_payload(
schema_version=_SCHEMA_VERSION,
source_id="warning_step_owner_response_preflight_service",
status=(
"ready_for_template_copy_plan"
if ready
else "blocked_owner_response_acknowledgements_missing"
),
readback={
"required_acknowledgement_count": len(_REQUIRED_ACKS),
"accepted_acknowledgement_count": len(accepted),
"missing_acknowledgements": [
key for key in _REQUIRED_ACKS if key not in accepted
],
"ready_for_template_copy_plan": ready,
},
next_actions=[
"collect_redacted_owner_acknowledgements",
"rerun_preflight_before_copy_execution_plan",
],
)

View File

@@ -0,0 +1,30 @@
"""AWOOOI warning-step template copy apply gate source."""
from __future__ import annotations
from typing import Any
from src.services.awoooi_onboarding_source_contracts import source_ready_payload
_SCHEMA_VERSION = "awoooi_gitea_onboarding_warning_step_template_copy_apply_gate_v1"
def load_latest_awoooi_gitea_onboarding_warning_step_template_copy_apply_gate() -> dict[str, Any]:
"""Return the apply gate source while keeping workflow writes closed."""
return source_ready_payload(
schema_version=_SCHEMA_VERSION,
source_id="warning_step_template_copy_apply_gate_service",
status="apply_gate_closed_source_ready",
readback={
"apply_allowed": False,
"confirmed_command_count": 0,
"required_command_count": 1,
"confirmed_validation_count": 0,
"required_validation_count": 2,
"workflow_template_copy_authorized": False,
},
next_actions=[
"confirm_template_copy_command_preview",
"confirm_post_copy_validation_before_workflow_modification",
],
)

View File

@@ -0,0 +1,34 @@
"""AWOOOI warning-step template copy execution plan source."""
from __future__ import annotations
from typing import Any
from src.services.awoooi_onboarding_source_contracts import source_ready_payload
_SCHEMA_VERSION = "awoooi_gitea_onboarding_warning_step_template_copy_execution_plan_v1"
def load_latest_awoooi_gitea_onboarding_warning_step_template_copy_execution_plan() -> dict[str, Any]:
"""Return the dry-run-only template copy plan source."""
return source_ready_payload(
schema_version=_SCHEMA_VERSION,
source_id="warning_step_template_copy_execution_plan_service",
status="dry_run_plan_ready_apply_gate_required",
readback={
"execution_status": "blocked_apply_gate_required",
"dry_run_only": True,
"command_preview_count": 1,
"command_preview": [
"copy warning-step template after apply gate confirms source readiness"
],
"post_copy_validators": [
"python3 ops/runner/guard-gitea-runner-pressure.py --root .",
"git diff --check",
],
},
next_actions=[
"open_template_copy_apply_gate",
"do_not_copy_workflow_until_apply_gate_allows",
],
)

View File

@@ -0,0 +1,33 @@
"""AWOOOI new product onboarding page model source."""
from __future__ import annotations
from typing import Any
from src.services.awoooi_onboarding_source_contracts import source_ready_payload
_SCHEMA_VERSION = "awoooi_new_product_onboarding_page_model_v1"
def load_latest_awoooi_new_product_onboarding_page_model() -> dict[str, Any]:
"""Return the page model source for onboarding readiness UI."""
return source_ready_payload(
schema_version=_SCHEMA_VERSION,
source_id="new_product_onboarding_page_model_service",
status="page_model_source_ready_read_only",
readback={
"page_model_ready": True,
"primary_view": "onboarding_readiness",
"write_controls_enabled": False,
"expected_sections": [
"baseline_sources",
"warning_step_gates",
"security_contract",
"runtime_readback",
],
},
next_actions=[
"wire_page_model_after_read_only_api_route",
"keep_write_controls_disabled_until_apply_gate",
],
)

View File

@@ -0,0 +1,34 @@
"""AWOOOI onboarding reminder contract source."""
from __future__ import annotations
from typing import Any
from src.services.awoooi_onboarding_source_contracts import source_ready_payload
_SCHEMA_VERSION = "awoooi_onboarding_reminder_contract_v1"
def load_latest_awoooi_onboarding_reminder_contract() -> dict[str, Any]:
"""Return the read-only onboarding reminder contract."""
return source_ready_payload(
schema_version=_SCHEMA_VERSION,
source_id="onboarding_reminder_contract_service",
status="contract_source_ready_inactive_template",
readback={
"contract_status": "inactive_template",
"warning_step_enabled": False,
"notification_send_authorized": False,
"strict_blocking_authorized": False,
"evidence_refs_required": [
"dev_baseline",
"ci_cd_baseline",
"security_contract",
"runtime_readback",
],
},
next_actions=[
"keep_reminder_contract_inactive_until_apply_gate",
"use_as_read_only_source_for_p0_baseline",
],
)

View File

@@ -0,0 +1,59 @@
"""Shared read-only contracts for AWOOOI onboarding source readiness."""
from __future__ import annotations
from copy import deepcopy
from typing import Any
_SAFE_OPERATION_BOUNDARIES: dict[str, bool] = {
"read_only_api_allowed": True,
"workflow_modification_allowed": False,
"workflow_trigger_allowed": False,
"repo_creation_allowed": False,
"refs_sync_allowed": False,
"github_api_allowed": False,
"host_or_k8s_write_allowed": False,
"secret_read_allowed": False,
"raw_session_or_sqlite_read_allowed": False,
}
def safe_operation_boundaries() -> dict[str, bool]:
"""Return a copy of the locked P0 onboarding operation boundaries."""
return dict(_SAFE_OPERATION_BOUNDARIES)
def source_ready_payload(
*,
schema_version: str,
source_id: str,
status: str,
readback: dict[str, Any],
next_actions: list[str],
) -> dict[str, Any]:
"""Build a stable source-readiness payload without opening runtime gates."""
payload: dict[str, Any] = {
"schema_version": schema_version,
"generated_at": "2026-06-29T12:45:00+08:00",
"source_id": source_id,
"status": status,
"readback": deepcopy(readback),
"operation_boundaries": safe_operation_boundaries(),
"next_actions": list(next_actions),
}
require_safe_operation_boundaries(payload, source_id)
return payload
def require_safe_operation_boundaries(payload: dict[str, Any], label: str) -> None:
"""Keep recreated onboarding services read-only until the apply gate opens."""
boundaries = payload.get("operation_boundaries")
if not isinstance(boundaries, dict):
raise ValueError(f"{label}: operation_boundaries must be an object")
mismatches = {
key: boundaries.get(key)
for key, expected in _SAFE_OPERATION_BOUNDARIES.items()
if boundaries.get(key) is not expected
}
if mismatches:
raise ValueError(f"{label}: unsafe operation boundaries: {mismatches}")

View File

@@ -0,0 +1,32 @@
"""AWOOOI product onboarding guard source."""
from __future__ import annotations
from typing import Any
from src.services.awoooi_onboarding_source_contracts import source_ready_payload
_SCHEMA_VERSION = "awoooi_product_onboarding_guard_v1"
def load_latest_awoooi_product_onboarding_guard() -> dict[str, Any]:
"""Return the warning-only onboarding guard source."""
return source_ready_payload(
schema_version=_SCHEMA_VERSION,
source_id="product_onboarding_guard_service",
status="guard_source_ready_warning_only",
readback={
"guard_mode": "warning_only",
"strict_blocking_enabled": False,
"hook_enabled_count": 0,
"checked_boundaries": [
"gitea_dev_baseline",
"security_contract_evidence",
"runtime_readback",
],
},
next_actions=[
"keep_guard_warning_only_until_apply_gate",
"surface_missing_product_baseline_as_evidence",
],
)

View File

@@ -28,19 +28,16 @@ def test_delivery_closure_workbench_endpoint_returns_product_summary():
assert data["summary"]["refs_sync_authorized"] is True
assert data["summary"]["workflow_trigger_authorized"] is True
assert data["summary"]["p0_cicd_baseline_status"] == (
"blocked_required_sources_missing"
"ready_for_template_copy_apply_gate"
)
assert data["summary"]["p0_cicd_baseline_workplan_id"] == "P0-004"
assert data["summary"]["p0_cicd_baseline_source_readiness_percent"] == 27
assert data["summary"]["p0_cicd_baseline_source_readiness_percent"] == 100
assert data["summary"]["p0_cicd_baseline_required_source_count"] == 11
assert data["summary"]["p0_cicd_baseline_present_required_source_count"] == 3
assert data["summary"]["p0_cicd_baseline_missing_required_source_count"] == 8
assert (
"warning_step_template_copy_apply_gate_service"
in data["summary"]["p0_cicd_baseline_blocked_source_ids"]
)
assert data["summary"]["p0_cicd_baseline_present_required_source_count"] == 11
assert data["summary"]["p0_cicd_baseline_missing_required_source_count"] == 0
assert data["summary"]["p0_cicd_baseline_blocked_source_ids"] == []
assert data["summary"]["p0_cicd_baseline_safe_next_step"] == (
"restore_or_recreate_tracked_warning_step_source_before_workflow_enablement"
"open_template_copy_apply_gate_after_source_readiness_green"
)
assert data["summary"]["production_deploy_status"] == (
"closure_verified"
@@ -515,17 +512,14 @@ def test_delivery_closure_workbench_endpoint_returns_product_summary():
)
assert lanes["github"]["metric"]["kind"] == "private_backup_verified"
assert lanes["cicd_baseline"]["metric"]["kind"] == "source_readiness"
assert lanes["cicd_baseline"]["status"] == "blocked_required_sources_missing"
assert lanes["cicd_baseline"]["blocker_count"] == 8
assert lanes["cicd_baseline"]["completion_percent"] == 27
assert lanes["cicd_baseline"]["status"] == "ready_for_template_copy_apply_gate"
assert lanes["cicd_baseline"]["blocker_count"] == 0
assert lanes["cicd_baseline"]["completion_percent"] == 100
assert lanes["cicd_baseline"]["metric"]["workplan_id"] == "P0-004"
assert lanes["cicd_baseline"]["metric"]["required_source_count"] == 11
assert lanes["cicd_baseline"]["metric"]["present_required_source_count"] == 3
assert lanes["cicd_baseline"]["metric"]["missing_required_source_count"] == 8
assert (
"warning_step_template_copy_apply_gate_service"
in lanes["cicd_baseline"]["metric"]["blocked_source_ids"]
)
assert lanes["cicd_baseline"]["metric"]["present_required_source_count"] == 11
assert lanes["cicd_baseline"]["metric"]["missing_required_source_count"] == 0
assert lanes["cicd_baseline"]["metric"]["blocked_source_ids"] == []
assert (
lanes["cicd_baseline"]["metric"]["workflow_modification_allowed"]
is False

View File

@@ -4,27 +4,48 @@ from fastapi import FastAPI
from fastapi.testclient import TestClient
from src.api.v1.agents import router
from src.services.awoooi_gitea_onboarding_warning_step_dashboard import (
load_latest_awoooi_gitea_onboarding_warning_step_dashboard,
)
from src.services.awoooi_gitea_onboarding_warning_step_owner_package import (
load_latest_awoooi_gitea_onboarding_warning_step_owner_package,
)
from src.services.awoooi_gitea_onboarding_warning_step_owner_response_preflight import (
load_latest_awoooi_gitea_onboarding_warning_step_owner_response_preflight,
)
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_execution_plan import (
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_execution_plan,
)
from src.services.awoooi_new_product_onboarding_page_model import (
load_latest_awoooi_new_product_onboarding_page_model,
)
from src.services.awoooi_onboarding_reminder_contract import (
load_latest_awoooi_onboarding_reminder_contract,
)
from src.services.awoooi_product_onboarding_guard import (
load_latest_awoooi_product_onboarding_guard,
)
from src.services.p0_cicd_baseline_source_readiness import (
load_latest_p0_cicd_baseline_source_readiness,
)
def test_p0_cicd_baseline_source_readiness_loader_reports_missing_sources():
def test_p0_cicd_baseline_source_readiness_loader_reports_ready_sources():
payload = load_latest_p0_cicd_baseline_source_readiness()
assert payload["schema_version"] == "p0_cicd_baseline_source_readiness_v1"
assert payload["status"] == "blocked_required_sources_missing"
assert payload["status"] == "ready_for_template_copy_apply_gate"
assert payload["priority"] == "P0-004"
assert payload["readback"]["workplan_id"] == "P0-004"
assert payload["readback"]["scorecard_completion_percent"] == 40
assert payload["readback"]["scorecard_completion_percent"] == 60
assert payload["rollups"]["required_source_count"] == 11
assert payload["rollups"]["present_required_source_count"] == 3
assert payload["rollups"]["missing_required_source_count"] == 8
assert payload["rollups"]["source_readiness_percent"] == 27
assert (
"warning_step_template_copy_apply_gate_service"
in payload["rollups"]["blocked_source_ids"]
)
assert payload["rollups"]["present_required_source_count"] == 11
assert payload["rollups"]["missing_required_source_count"] == 0
assert payload["rollups"]["source_readiness_percent"] == 100
assert payload["rollups"]["blocked_source_ids"] == []
assert payload["operation_boundaries"]["read_only_api_allowed"] is True
assert payload["operation_boundaries"]["workflow_modification_allowed"] is False
assert payload["operation_boundaries"]["workflow_trigger_allowed"] is False
@@ -32,6 +53,41 @@ def test_p0_cicd_baseline_source_readiness_loader_reports_missing_sources():
assert payload["operation_boundaries"]["secret_read_allowed"] is False
def test_recreated_onboarding_sources_keep_apply_gates_closed():
response = {
"accept_warning_only_scope": True,
"confirm_no_push_or_pull_request_trigger": True,
"confirm_no_generic_runner_label": True,
"confirm_runner_pressure_guard_required": True,
}
payloads = [
load_latest_awoooi_gitea_onboarding_warning_step_owner_package(),
load_latest_awoooi_gitea_onboarding_warning_step_owner_response_preflight(
response
),
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_execution_plan(),
load_latest_awoooi_gitea_onboarding_warning_step_template_copy_apply_gate(),
load_latest_awoooi_gitea_onboarding_warning_step_dashboard(),
load_latest_awoooi_product_onboarding_guard(),
load_latest_awoooi_onboarding_reminder_contract(),
load_latest_awoooi_new_product_onboarding_page_model(),
]
assert (
payloads[1]["readback"]["accepted_acknowledgement_count"]
== payloads[1]["readback"]["required_acknowledgement_count"]
)
assert payloads[1]["readback"]["ready_for_template_copy_plan"] is True
for payload in payloads:
boundaries = payload["operation_boundaries"]
assert boundaries["read_only_api_allowed"] is True
assert boundaries["workflow_modification_allowed"] is False
assert boundaries["workflow_trigger_allowed"] is False
assert boundaries["github_api_allowed"] is False
assert boundaries["host_or_k8s_write_allowed"] is False
assert boundaries["secret_read_allowed"] is False
def test_p0_cicd_baseline_source_readiness_endpoint_returns_snapshot():
app = FastAPI()
app.include_router(router, prefix="/api/v1")
@@ -42,6 +98,6 @@ def test_p0_cicd_baseline_source_readiness_endpoint_returns_snapshot():
assert response.status_code == 200
data = response.json()
assert data["schema_version"] == "p0_cicd_baseline_source_readiness_v1"
assert data["status"] == "blocked_required_sources_missing"
assert data["rollups"]["missing_required_source_count"] == 8
assert data["status"] == "ready_for_template_copy_apply_gate"
assert data["rollups"]["missing_required_source_count"] == 0
assert data["operation_boundaries"]["workflow_modification_allowed"] is False

View File

@@ -244,7 +244,7 @@ const PUBLIC_TEXT_REPLACEMENTS: Array<[RegExp, string]> = [
[/receipt production write/gi, '回執正式寫入'],
[/production write/gi, '正式環境寫入'],
[/verifier live readback/gi, '驗證器正式讀回'],
[/host write/gi, '主機寫入'],
[/host write/gi, '主機變更'],
[/secret read/gi, '機密讀取'],
[/kubectl action/gi, 'kubectl 操作'],
[/destructive operation/gi, '破壞性操作'],

View File

@@ -51,6 +51,13 @@ const PUBLIC_TEXT_REPLACEMENTS: Array<[RegExp, string]> = [
[/原始 runtime payload/gi, '已遮罩執行資料'],
[/raw runtime payload/gi, '已遮罩執行資料'],
[/raw_runtime_payload/gi, '已遮罩執行載荷欄位'],
[/runtime action/gi, '執行期變更'],
[/runtime gate 已開/g, '執行期閘門開啟'],
[/執行期已授權/g, '已取得執行期授權'],
[/live Wazuh/gi, '只讀 Wazuh 查詢'],
[/host write/gi, '主機變更'],
[/active response/gi, '主動回應流程'],
[/raw output/gi, '脫敏輸出摘要'],
[/raw Telegram payload/gi, '原始 Telegram 載荷'],
[/raw_telegram_payload/gi, '已遮罩 Telegram 載荷欄位'],
[/raw tool output/gi, '原始工具輸出'],

View File

@@ -2,8 +2,11 @@ export function publicBoundaryText(value: string): string {
const redacted = value
.replace(/live Wazuh/gi, "只讀管理端")
.replace(/runtime action/gi, "執行期變更")
.replace(/runtime gate 已開/g, "執行期閘門開啟")
.replace(/執行期已授權/g, "已取得執行期授權")
.replace(/host write/gi, "主機變更")
.replace(/active response/gi, "主動回應流程")
.replace(/raw output/gi, "脫敏輸出摘要")
.replace(/secret value/gi, "機密明文")
.replace(/raw secret/gi, "原始機密");
const labels: Record<string, string> = {

View File

@@ -16,6 +16,20 @@
**邊界**:未使用 GitHub / `gh` / GitHub API未建立 repo未 sync refs未 workflow_dispatch未讀 token / cookie / session / secret / auth / `.env`;未操作 host / Docker / K8s / DB未 force push。
## 2026-06-29 — 12:45 P0-004 CI/CD baseline source readiness 補齊
**完成內容**
- 接續 P0-001 cold-start / P0-005 escrow gate 後,按序推進 P0-004。
- `cd.yaml #3875` 已在 Gitea public queue 讀回 `Success`deploy marker 為 `6ee1b8e49 chore(cd): deploy 2ff4d1f [skip ci]`production Workbench 讀回 `production_deploy_status=closure_verified``production_deploy_image_tag_matches_main=true`
- 補回 P0-004 source readiness 要求的 8 個 service sourcewarning-step owner package、owner response preflight、template copy execution plan、template copy apply gate、dashboard、product onboarding guard、onboarding reminder contract、new product onboarding page model。
- `docs/operations/p0-cicd-baseline-source-readiness.snapshot.json` 從 missing sources blocker 更新為 `ready_for_template_copy_apply_gate`source readiness 變成 `11/11``100%`,但 workflow copy / trigger / host / K8s / secret / GitHub 仍維持關閉。
**驗證目標**
- Focused API tests`test_p0_cicd_baseline_source_readiness_api.py``test_delivery_closure_workbench_api.py`
- Source / workflow guards`py_compile``ops/runner/test_cd_controlled_runtime_profile.py``guard-gitea-runner-pressure.py``git diff --check`
**邊界**:未使用 GitHub / `gh` / GitHub API未 workflow_dispatch未讀 token / `.runner` / cookie / session / secret / auth / `.env`;未操作 host / Docker / K8s / DB未開 workflow template copy apply gate。
## 2026-06-29 — 12:06 P0-004 CI/CD baseline source readiness readback
**完成內容**

View File

@@ -1,18 +1,18 @@
{
"schema_version": "p0_cicd_baseline_source_readiness_v1",
"generated_at": "2026-06-29T12:06:00+08:00",
"status": "blocked_required_sources_missing",
"status": "ready_for_template_copy_apply_gate",
"priority": "P0-004",
"scope": "dev_prod_cicd_baseline",
"readback": {
"workplan_id": "P0-004",
"workplan_title": "補 dev / prod CI/CD baseline",
"scorecard_completion_percent": 40,
"scorecard_completion_percent": 60,
"baseline_matrix_present": true,
"dev_missing_count": 10,
"prod_cicd_gap_count": 10,
"github_mirror_status": "removed_deleted_do_not_use",
"safe_next_step": "restore_or_recreate_tracked_warning_step_source_before_workflow_enablement"
"safe_next_step": "open_template_copy_apply_gate_after_source_readiness_green"
},
"required_sources": [
{
@@ -83,30 +83,20 @@
}
],
"blockers": [
"tracked_warning_step_source_files_missing",
"workflow_enablement_blocked_until_source_readiness_green"
"template_copy_apply_gate_required_before_workflow_enablement"
],
"next_actions": [
"restore_or_recreate_warning_step_owner_package_preflight_plan_apply_gate_dashboard_sources",
"add_focused_tests_for_recreated_sources_before_any_workflow_copy",
"keep_workflow_modification_allowed_false_until_source_readiness_green"
"run_focused_tests_for_recreated_sources",
"open_template_copy_apply_gate_before_any_workflow_copy",
"keep_workflow_modification_allowed_false_until_apply_gate"
],
"rollups": {
"required_source_count": 11,
"present_required_source_count": 3,
"missing_required_source_count": 8,
"source_readiness_percent": 27,
"blocked_source_ids": [
"warning_step_owner_package_service",
"warning_step_owner_response_preflight_service",
"warning_step_template_copy_execution_plan_service",
"warning_step_template_copy_apply_gate_service",
"warning_step_dashboard_service",
"product_onboarding_guard_service",
"onboarding_reminder_contract_service",
"new_product_onboarding_page_model_service"
],
"hard_blocker_count": 2,
"present_required_source_count": 11,
"missing_required_source_count": 0,
"source_readiness_percent": 100,
"blocked_source_ids": [],
"hard_blocker_count": 1,
"next_action_count": 3
},
"operation_boundaries": {