From 7d7d0028df7dc81b61f9e2e013628038f3fffd53 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 30 Jun 2026 01:33:35 +0800 Subject: [PATCH] fix(api): expose runtime switch completion readback --- .../awoooi-onboarding-warning-step.yaml | 16 +++--- ...ng_warning_step_runtime_enablement_gate.py | 53 ++++++++++++------- ...ding_warning_step_template_copy_receipt.py | 33 +++++++++--- .../services/delivery_closure_workbench.py | 27 ++++++++++ .../test_delivery_closure_workbench_api.py | 18 ++++++- ...t_p0_cicd_baseline_source_readiness_api.py | 22 +++++--- docs/LOGBOOK.md | 29 +++++----- ...g-step-template-copy-receipt.snapshot.json | 9 ++-- ...itea-onboarding-warning-step.workflow.yaml | 16 +++--- 9 files changed, 158 insertions(+), 65 deletions(-) diff --git a/.gitea/workflows/awoooi-onboarding-warning-step.yaml b/.gitea/workflows/awoooi-onboarding-warning-step.yaml index 0faee9f4..3b805808 100644 --- a/.gitea/workflows/awoooi-onboarding-warning-step.yaml +++ b/.gitea/workflows/awoooi-onboarding-warning-step.yaml @@ -1,10 +1,10 @@ # AWOOOI Gitea Onboarding Warning Step template. # -# Controlled-runtime default: +# Controlled runtime: # - no push / pull_request / pull_request_target trigger # - no generic runner labels -# - runtime warning-step job is enabled only for manual workflow_dispatch -# - no secrets, host writes, workflow dispatch from Codex, or runtime apply +# - runtime warning-step job is enabled for controlled workflow_dispatch only +# - no secrets, host writes, workflow dispatch from this commit, or product writes name: AWOOOI Onboarding Warning Step @@ -17,13 +17,13 @@ env: jobs: workflow-shape: # Gitea 1.25 can mark a workflow invalid when every root job has a job-level - # `if`. Keep this no-op root job so the template remains parseable while - # the runtime warning-step job below is gated by the explicit env switch. + # `if`. Keep this no-op root job so the workflow remains parseable while + # the runtime warning-step job below stays behind the controlled switch. runs-on: awoooi-non110-host timeout-minutes: 1 steps: - - name: Confirm fail-closed warning-step workflow shape - run: echo "warning-step runtime job is enabled for manual dispatch only." + - name: Confirm controlled warning-step workflow shape + run: echo "warning-step runtime job is enabled for controlled workflow_dispatch only." warning-step: if: ${{ env.AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED == '1' }} @@ -39,5 +39,5 @@ jobs: git diff --check cat <<'SUMMARY' AWOOOI onboarding warning step template is present. - Runtime execution is enabled only for manual workflow_dispatch. + Runtime execution is enabled only for controlled workflow_dispatch boundary validation. SUMMARY diff --git a/apps/api/src/services/awoooi_gitea_onboarding_warning_step_runtime_enablement_gate.py b/apps/api/src/services/awoooi_gitea_onboarding_warning_step_runtime_enablement_gate.py index 15fe178b..38849c0d 100644 --- a/apps/api/src/services/awoooi_gitea_onboarding_warning_step_runtime_enablement_gate.py +++ b/apps/api/src/services/awoooi_gitea_onboarding_warning_step_runtime_enablement_gate.py @@ -22,8 +22,11 @@ def load_latest_awoooi_gitea_onboarding_warning_step_runtime_enablement_gate() - receipt_rollups = _dict(receipt.get("rollups")) receipt_boundaries = _dict(receipt.get("operation_boundaries")) receipt_readback = _dict(receipt.get("readback")) - switch_value = str(receipt_rollups.get("runtime_execution_switch_value") or "0") - switch_enabled = switch_value == "1" + switch_value = str( + receipt_rollups.get("runtime_execution_switch_value") + or ("1" if receipt_rollups.get("runtime_execution_enabled") is True else "0") + ) + runtime_enabled = switch_value == "1" receipt_ready = ( receipt.get("status") == _RECEIPT_READY_STATUS and receipt.get("active_blockers") == [] @@ -46,11 +49,11 @@ def load_latest_awoooi_gitea_onboarding_warning_step_runtime_enablement_gate() - "priority": "P0-004", "scope": "gitea_onboarding_warning_step_runtime_enablement", "status": ( - "controlled_warning_step_runtime_enabled" - if switch_enabled and not active_blockers + "blocked_warning_step_runtime_enablement_gate" + if active_blockers + else "controlled_warning_step_runtime_enabled" + if runtime_enabled else "controlled_warning_step_runtime_enablement_gate_ready" - if not active_blockers - else "blocked_warning_step_runtime_enablement_gate" ), "readback": { "workplan_id": "P0-004-WARNING-STEP-RUNTIME-ENABLEMENT", @@ -68,19 +71,24 @@ def load_latest_awoooi_gitea_onboarding_warning_step_runtime_enablement_gate() - "workflow_content_sha256_12" ), "runtime_enablement_switch": "AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED", + "previous_switch_value_before_controlled_apply": "0", "current_switch_default": switch_value, "desired_switch_value_after_controlled_apply": "1", "safe_next_step": ( - "runtime_enablement_switch_enabled_wait_for_manual_dispatch_evidence" - if switch_enabled + "verify_production_runtime_switch_readback_then_open_controlled_dispatch_gate_after_pressure_guard" + if runtime_enabled else "prepare_controlled_switch_flip_with_pressure_guard_then_verify_no_auto_branch_trigger" ), }, "controlled_apply": { - "mode": "controlled_apply_prepared", - "controlled_apply_allowed": not active_blockers and not switch_enabled, - "workflow_runtime_enablement_authorized": not active_blockers - and not switch_enabled, + "mode": ( + "controlled_apply_completed" + if runtime_enabled + else "controlled_apply_prepared" + ), + "controlled_apply_allowed": not active_blockers, + "controlled_apply_completed": runtime_enabled and not active_blockers, + "workflow_runtime_enablement_authorized": not active_blockers, "workflow_dispatch_authorized": False, "auto_push_or_pull_request_trigger_authorized": False, "generic_runner_label_authorized": False, @@ -95,17 +103,18 @@ def load_latest_awoooi_gitea_onboarding_warning_step_runtime_enablement_gate() - "selector_type": "workflow_runtime_enablement_switch", "workflow_path": _WORKFLOW_PATH, "env_key": "AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED", + "previous_expected_value_before_controlled_apply": "0", "expected_current_value": switch_value, "desired_value_after_controlled_apply": "1", "allowed_runner_label": "awoooi-non110-host", }, "source_of_truth_diff": { "current_state": ( - "warning_step_runtime_job_enabled_for_manual_dispatch_only" - if switch_enabled + "warning_step_runtime_job_enabled_for_controlled_dispatch_only" + if runtime_enabled else "warning_step_runtime_job_fail_closed_disabled" ), - "desired_state": "warning_step_runtime_job_enabled_for_manual_dispatch_only", + "desired_state": "warning_step_runtime_job_enabled_for_controlled_dispatch_only", "delta_kind": "env_switch_value_change", "auto_branch_event_delta_allowed": False, "generic_runner_label_delta_allowed": False, @@ -120,7 +129,11 @@ def load_latest_awoooi_gitea_onboarding_warning_step_runtime_enablement_gate() - "run_runner_pressure_guard", "verify_no_push_pull_request_triggers", "verify_no_generic_runner_labels", - "verify_switch_currently_fail_closed", + ( + "verify_switch_enabled_for_controlled_dispatch_only" + if runtime_enabled + else "verify_switch_currently_fail_closed" + ), "verify_git_diff_contains_only_switch_change", ], }, @@ -164,12 +177,16 @@ def load_latest_awoooi_gitea_onboarding_warning_step_runtime_enablement_gate() - receipt_rollups.get("runtime_execution_switch_controlled") is True ), "runtime_execution_switch_value": switch_value, - "runtime_execution_switch_enabled": switch_enabled, + "runtime_execution_switch_enabled": runtime_enabled, + "runtime_enablement_switch_present": ( + receipt_rollups.get("runtime_enablement_switch_present") is True + ), + "runtime_execution_enabled": runtime_enabled, "runner_pressure_guard_required": True, "controlled_runtime_enablement_ready": not active_blockers, "active_blocker_count": len(active_blockers), "workflow_trigger_performed": False, - "runtime_switch_changed": switch_enabled, + "runtime_switch_changed": runtime_enabled, }, "active_blockers": active_blockers, "operation_boundaries": { diff --git a/apps/api/src/services/awoooi_gitea_onboarding_warning_step_template_copy_receipt.py b/apps/api/src/services/awoooi_gitea_onboarding_warning_step_template_copy_receipt.py index e5b54171..f08df995 100644 --- a/apps/api/src/services/awoooi_gitea_onboarding_warning_step_template_copy_receipt.py +++ b/apps/api/src/services/awoooi_gitea_onboarding_warning_step_template_copy_receipt.py @@ -1,4 +1,4 @@ -"""AWOOOI warning-step template copy receipt readback.""" +"""AWOOOI warning-step template copy and runtime-switch receipt readback.""" from __future__ import annotations @@ -17,7 +17,7 @@ _SCHEMA_VERSION = "awoooi_gitea_onboarding_warning_step_template_copy_receipt_v1 _RECEIPT_SCHEMA_VERSION = ( "awoooi_gitea_onboarding_warning_step_template_copy_receipt_snapshot_v1" ) -_EXPECTED_WORKFLOW_SHA256_12 = "23b59f29cb77" +_EXPECTED_WORKFLOW_SHA256_12 = "980ff5452f59" _TEMPLATE_RELATIVE_PATH = ( "docs/operations/templates/awoooi-gitea-onboarding-warning-step.workflow.yaml" ) @@ -36,7 +36,7 @@ _GENERIC_LABEL_PATTERNS = ( def load_latest_awoooi_gitea_onboarding_warning_step_template_copy_receipt( repo_root: Path | None = None, ) -> dict[str, Any]: - """Return the warning-step workflow copy receipt.""" + """Return the warning-step workflow copy receipt across controlled stages.""" root = repo_root or resolve_repo_root(Path(__file__)) template_path = root / _TEMPLATE_RELATIVE_PATH workflow_path = root / _WORKFLOW_RELATIVE_PATH @@ -55,7 +55,8 @@ def load_latest_awoooi_gitea_onboarding_warning_step_template_copy_receipt( _short_content_sha(effective_workflow_text) if effective_workflow_text else "" ) runtime_switch_value = _runtime_execution_switch_value( - receipt, effective_workflow_text + receipt, + effective_workflow_text, ) template_copy_recorded = _template_copy_recorded( receipt=receipt, @@ -140,7 +141,7 @@ def load_latest_awoooi_gitea_onboarding_warning_step_template_copy_receipt( "workflow_matches_source_template_or_receipt_hash_matches", "workflow_has_no_auto_branch_event", "workflow_has_no_generic_runner_label", - "workflow_runtime_execution_switch_controlled", + "workflow_runtime_execution_switch_declared", "runner_pressure_guard_required", "git_diff_check_required", ], @@ -186,11 +187,20 @@ def load_latest_awoooi_gitea_onboarding_warning_step_template_copy_receipt( ) or receipt.get("fail_closed_execution_switch_present") is True, "runtime_execution_switch_controlled": _runtime_execution_switch_controlled( - receipt, effective_workflow_text + receipt, + effective_workflow_text, ), "runtime_execution_switch_value": runtime_switch_value, "runtime_execution_switch_enabled": runtime_switch_value == "1", "runtime_enablement_switch_changed": runtime_switch_value == "1", + "runtime_enablement_switch_present": _runtime_enablement_switch_present( + effective_workflow_text + ) + or receipt.get("runtime_enablement_switch_present") is True, + "runtime_execution_enabled": _runtime_execution_enabled( + effective_workflow_text + ) + or receipt.get("runtime_execution_enabled") is True, "apply_gate_ready": _gate_ready(gate_readback), "active_blocker_count": len(active_blockers), "active_workflow_file_created": template_copy_recorded, @@ -384,5 +394,16 @@ def _runtime_execution_switch_controlled( ) or receipt.get("runtime_execution_switch_controlled") is True +def _runtime_enablement_switch_present(template_text: str) -> bool: + return ( + "AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED:" in template_text + and "AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED == '1'" in template_text + ) + + +def _runtime_execution_enabled(template_text: str) -> bool: + return 'AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED: "1"' in template_text + + def _dict(value: Any) -> dict[str, Any]: return value if isinstance(value, dict) else {} diff --git a/apps/api/src/services/delivery_closure_workbench.py b/apps/api/src/services/delivery_closure_workbench.py index 94bc9841..7d9d53a8 100644 --- a/apps/api/src/services/delivery_closure_workbench.py +++ b/apps/api/src/services/delivery_closure_workbench.py @@ -901,6 +901,7 @@ def build_delivery_closure_workbench( in { "controlled_warning_step_runtime_enablement_gate_ready", "controlled_warning_step_runtime_enabled", + "controlled_warning_step_runtime_enabled_receipt_ready", } ), "runtime_enablement_gate_active_blocker_count": _int( @@ -912,6 +913,19 @@ def build_delivery_closure_workbench( ) is True ), + "runtime_enablement_controlled_apply_completed": ( + cicd_runtime_enablement_controlled_apply.get( + "controlled_apply_completed" + ) + is True + ), + "runtime_enablement_runtime_execution_enabled": ( + cicd_runtime_enablement_rollups.get("runtime_execution_enabled") + is True + ), + "runtime_enablement_switch_changed": ( + cicd_runtime_enablement_rollups.get("runtime_switch_changed") is True + ), "runtime_enablement_workflow_dispatch_authorized": ( cicd_runtime_enablement_controlled_apply.get( "workflow_dispatch_authorized" @@ -1443,6 +1457,7 @@ def build_delivery_closure_workbench( in { "controlled_warning_step_runtime_enablement_gate_ready", "controlled_warning_step_runtime_enabled", + "controlled_warning_step_runtime_enabled_receipt_ready", } ), "p0_cicd_warning_step_runtime_enablement_active_blocker_count": _int( @@ -1454,6 +1469,18 @@ def build_delivery_closure_workbench( ) is True ), + "p0_cicd_warning_step_runtime_enablement_controlled_apply_completed": ( + cicd_runtime_enablement_controlled_apply.get( + "controlled_apply_completed" + ) + is True + ), + "p0_cicd_warning_step_runtime_enablement_runtime_execution_enabled": ( + cicd_runtime_enablement_rollups.get("runtime_execution_enabled") is True + ), + "p0_cicd_warning_step_runtime_enablement_switch_changed": ( + cicd_runtime_enablement_rollups.get("runtime_switch_changed") is True + ), "p0_cicd_warning_step_runtime_enablement_workflow_dispatch_authorized": ( cicd_runtime_enablement_controlled_apply.get( "workflow_dispatch_authorized" diff --git a/apps/api/tests/test_delivery_closure_workbench_api.py b/apps/api/tests/test_delivery_closure_workbench_api.py index 7b946e40..760690bc 100644 --- a/apps/api/tests/test_delivery_closure_workbench_api.py +++ b/apps/api/tests/test_delivery_closure_workbench_api.py @@ -427,7 +427,23 @@ def _assert_delivery_workbench_shape(data: dict): data["summary"][ "p0_cicd_warning_step_runtime_enablement_controlled_apply_allowed" ] - is False + is True + ) + assert ( + data["summary"][ + "p0_cicd_warning_step_runtime_enablement_controlled_apply_completed" + ] + is True + ) + assert ( + data["summary"][ + "p0_cicd_warning_step_runtime_enablement_runtime_execution_enabled" + ] + is True + ) + assert ( + data["summary"]["p0_cicd_warning_step_runtime_enablement_switch_changed"] + is True ) assert ( data["summary"][ diff --git a/apps/api/tests/test_p0_cicd_baseline_source_readiness_api.py b/apps/api/tests/test_p0_cicd_baseline_source_readiness_api.py index 9a74738f..2cc73994 100644 --- a/apps/api/tests/test_p0_cicd_baseline_source_readiness_api.py +++ b/apps/api/tests/test_p0_cicd_baseline_source_readiness_api.py @@ -284,7 +284,7 @@ def test_warning_step_template_copy_is_fail_closed_and_pressure_guarded(): assert "workflow_dispatch:" in workflow assert "workflow-shape:" in workflow - assert "Confirm fail-closed warning-step workflow shape" in workflow + assert "Confirm controlled warning-step workflow shape" in workflow assert "runs-on: awoooi-non110-host" in workflow assert 'AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED: "1"' in workflow assert "ops/runner/guard-gitea-runner-pressure.py --root ." in workflow @@ -377,7 +377,7 @@ def _assert_template_copy_receipt(payload: dict): assert payload["status"] == "controlled_template_copy_receipt_ready" assert payload["active_blockers"] == [] assert payload["readback"]["template_copy_performed"] is True - assert payload["readback"]["workflow_content_sha256_12"] == "23b59f29cb77" + assert payload["readback"]["workflow_content_sha256_12"] == "980ff5452f59" assert payload["target_selector"]["active_workflow_file_created"] is True assert payload["rollups"]["template_file_present"] is True assert payload["rollups"]["receipt_snapshot_present"] is True @@ -385,12 +385,14 @@ def _assert_template_copy_receipt(payload: dict): assert payload["rollups"]["workflow_matches_template"] is True assert payload["rollups"]["auto_branch_event_count"] == 0 assert payload["rollups"]["generic_runner_label_count"] == 0 - assert payload["rollups"]["expected_workflow_sha256_12"] == "23b59f29cb77" + assert payload["rollups"]["expected_workflow_sha256_12"] == "980ff5452f59" assert payload["rollups"]["fail_closed_execution_switch_present"] is False assert payload["rollups"]["runtime_execution_switch_controlled"] is True assert payload["rollups"]["runtime_execution_switch_value"] == "1" assert payload["rollups"]["runtime_execution_switch_enabled"] is True assert payload["rollups"]["runtime_enablement_switch_changed"] is True + assert payload["rollups"]["runtime_enablement_switch_present"] is True + assert payload["rollups"]["runtime_execution_enabled"] is True 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 @@ -416,16 +418,19 @@ def _assert_runtime_enablement_gate(payload: dict): assert payload["readback"]["runtime_enablement_switch"] == ( "AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED" ) + assert payload["readback"]["previous_switch_value_before_controlled_apply"] == "0" assert payload["readback"]["current_switch_default"] == "1" assert payload["readback"]["desired_switch_value_after_controlled_apply"] == "1" - assert payload["controlled_apply"]["controlled_apply_allowed"] is False - assert payload["controlled_apply"]["workflow_runtime_enablement_authorized"] is False + assert payload["controlled_apply"]["controlled_apply_allowed"] is True + assert payload["controlled_apply"]["controlled_apply_completed"] is True + assert payload["controlled_apply"]["workflow_runtime_enablement_authorized"] is True assert payload["controlled_apply"]["workflow_dispatch_authorized"] is False assert payload["controlled_apply"]["auto_push_or_pull_request_trigger_authorized"] is False assert payload["controlled_apply"]["generic_runner_label_authorized"] is False assert payload["target_selector"]["env_key"] == ( "AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED" ) + assert payload["target_selector"]["previous_expected_value_before_controlled_apply"] == "0" assert payload["target_selector"]["expected_current_value"] == "1" assert payload["target_selector"]["desired_value_after_controlled_apply"] == "1" assert payload["source_of_truth_diff"]["delta_kind"] == "env_switch_value_change" @@ -434,11 +439,14 @@ def _assert_runtime_enablement_gate(payload: dict): assert payload["post_apply_verifier"]["required"] is True assert payload["rollups"]["template_copy_receipt_ready"] is True assert payload["rollups"]["controlled_runtime_enablement_ready"] is True - assert payload["rollups"]["active_blocker_count"] == 0 - assert payload["rollups"]["workflow_trigger_performed"] is False + assert payload["rollups"]["fail_closed_execution_switch_present"] is False assert payload["rollups"]["runtime_execution_switch_controlled"] is True assert payload["rollups"]["runtime_execution_switch_value"] == "1" assert payload["rollups"]["runtime_execution_switch_enabled"] is True + assert payload["rollups"]["runtime_enablement_switch_present"] is True + assert payload["rollups"]["runtime_execution_enabled"] is True + assert payload["rollups"]["active_blocker_count"] == 0 + assert payload["rollups"]["workflow_trigger_performed"] is False assert payload["rollups"]["runtime_switch_changed"] is True assert payload["operation_boundaries"]["readback_only"] is True assert payload["operation_boundaries"]["controlled_runtime_enablement_gate_open"] is True diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 1beea907..84d7212a 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -7,6 +7,21 @@ **邊界**:不使用 GitHub,不讀 secret / raw session / SQLite,不觸發 workflow,不重啟主機,不 restart service,不寫 DB / K8s / Docker / firewall。 +## 2026-06-30 — 01:22 P0-004 runtime enablement switch controlled apply + +**照優先順序完成的實作**: +- Production deploy marker `93ae219a1 chore(cd): deploy 6d0d964 [skip ci]` 已上線;正式 `/api/v1/agents/awoooi-gitea-onboarding-warning-step-runtime-enablement-gate` 回 `controlled_warning_step_runtime_enablement_gate_ready`、`active_blockers=[]`、current switch `0`、desired switch `1`。 +- 本輪接續該 ready gate 做 controlled apply:`.gitea/workflows/awoooi-onboarding-warning-step.yaml` 與 source template 的 `AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED` 已從 `0` 改為 `1`,仍只允許 `workflow_dispatch`,不新增 `push` / `pull_request` / `pull_request_target`,runner label 維持 `awoooi-non110-host`。 +- receipt / runtime gate / Delivery Workbench readback 已升級成 `controlled_warning_step_runtime_enabled`,明確回報 `runtime_execution_enabled=true`、`controlled_apply_completed=true`、`runtime_switch_changed=true`、`workflow_trigger_performed=false`。 +- 同步執行正式 LOG metadata controlled writeback:`POST /api/v1/agents/agent-log-controlled-writeback-dispatch` 新增 6 筆 idempotent ledger receipt;`agent-autonomous-runtime-control` 讀回 `live_log_controlled_writeback_dispatch_count=6`、`live_log_controlled_writeback_recent_dispatch_count=6`。 + +**驗證**: +- Local focused verifier:P0-004 / Delivery Workbench / LOG dispatch / runtime-control / CD profile `50 passed`。 +- `ruff`、`py_compile`、`git diff --check`、Gitea runner pressure guard、Gitea step env secret guard:通過。 +- Local loader 讀回 `receipt_status=controlled_template_copy_receipt_ready`、`gate_status=controlled_warning_step_runtime_enabled`、`gate_completed=true`、`gate_runtime_enabled=true`、`gate_dispatch_authorized=false`、`gate_trigger_performed=false`。 + +**邊界**:未 workflow_dispatch,未改 runner label,未操作 host / Docker / K8s / firewall,未寫 KM / RAG / PlayBook,未呼叫 MCP tool,未發 Telegram,未保存 raw log payload;正式寫入僅限 metadata-only automation ledger;未使用 GitHub / `gh` / GitHub API,未讀 secret / token / raw sessions / SQLite / `.env`。 + ## 2026-06-30 — 01:02 P0-006 drill preflight machine-readback shape **照優先順序完成的實作**: @@ -21,20 +36,6 @@ **邊界**:未重啟主機,未 restart service,未 workflow_dispatch,未操作 host / Docker / K8s / DB / firewall,未使用 GitHub / `gh` / GitHub API,未讀 secret / token / raw sessions / SQLite / `.env`。 -## 2026-06-30 — 01:25 P0-004 warning-step runtime switch controlled apply - -**照優先順序完成的實作**: -- production 已讀回 `/api/v1/agents/awoooi-gitea-onboarding-warning-step-runtime-enablement-gate` 為 `controlled_warning_step_runtime_enablement_gate_ready`,因此推進 P0-004 下一段 controlled apply。 -- 將 `.gitea/workflows/awoooi-onboarding-warning-step.yaml` 與 source template 的 `AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED` 從 `"0"` 改為 `"1"`;workflow 仍只允許 `workflow_dispatch`,runner 仍是 `awoooi-non110-host`,沒有新增 push / pull_request / pull_request_target。 -- 更新 template-copy receipt hash 與 runtime switch readback,runtime gate 現在本地讀回 `controlled_warning_step_runtime_enabled`、`runtime_switch_changed=true`、`workflow_trigger_performed=false`,Delivery Workbench 同步投影 enabled 狀態。 - -**驗證**: -- `py_compile`、ruff focused check、P0-004 / Delivery Workbench / CD profile focused pytest `37 passed`。 -- Gitea runner pressure guard:`auto_branch_events_on_110=0`、`generic_runner_labels=0`。 -- Local readback:receipt ready、switch value `1`、gate active blockers `[]`、controlled apply already consumed、workflow dispatch performed `false`。 - -**邊界**:未 workflow_dispatch,未改 runner,未操作 host / Docker / K8s / DB / firewall,未使用 GitHub / `gh` / GitHub API,未讀 secret / token / raw sessions / SQLite / `.env`。 - ## 2026-06-30 — 00:41 P0-004 template copy receipt runtime-image readback 修正 **照優先順序完成的實作**: diff --git a/docs/operations/awoooi-gitea-onboarding-warning-step-template-copy-receipt.snapshot.json b/docs/operations/awoooi-gitea-onboarding-warning-step-template-copy-receipt.snapshot.json index 89c6a8cb..874e5ed6 100644 --- a/docs/operations/awoooi-gitea-onboarding-warning-step-template-copy-receipt.snapshot.json +++ b/docs/operations/awoooi-gitea-onboarding-warning-step-template-copy-receipt.snapshot.json @@ -1,11 +1,11 @@ { "schema_version": "awoooi_gitea_onboarding_warning_step_template_copy_receipt_snapshot_v1", - "generated_at": "2026-06-30T01:27:00+08:00", + "generated_at": "2026-06-30T01:35:00+08:00", "workplan_id": "P0-004-TEMPLATE-COPY-CONTROLLED-APPLY", "source_template_path": "docs/operations/templates/awoooi-gitea-onboarding-warning-step.workflow.yaml", "destination_workflow_path": ".gitea/workflows/awoooi-onboarding-warning-step.yaml", - "source_template_content_sha256_12": "23b59f29cb77", - "destination_workflow_content_sha256_12": "23b59f29cb77", + "source_template_content_sha256_12": "980ff5452f59", + "destination_workflow_content_sha256_12": "980ff5452f59", "template_copy_recorded": true, "destination_workflow_runtime_visible_required": false, "runtime_image_excludes_dot_gitea": true, @@ -13,7 +13,10 @@ "fail_closed_execution_switch_present": false, "runtime_execution_switch_controlled": true, "runtime_execution_switch_value": "1", + "runtime_execution_switch_enabled": true, "runtime_enablement_switch_changed": true, + "runtime_enablement_switch_present": true, + "runtime_execution_enabled": true, "workflow_trigger_performed": false, "auto_branch_event_count": 0, "generic_runner_label_count": 0, diff --git a/docs/operations/templates/awoooi-gitea-onboarding-warning-step.workflow.yaml b/docs/operations/templates/awoooi-gitea-onboarding-warning-step.workflow.yaml index 0faee9f4..3b805808 100644 --- a/docs/operations/templates/awoooi-gitea-onboarding-warning-step.workflow.yaml +++ b/docs/operations/templates/awoooi-gitea-onboarding-warning-step.workflow.yaml @@ -1,10 +1,10 @@ # AWOOOI Gitea Onboarding Warning Step template. # -# Controlled-runtime default: +# Controlled runtime: # - no push / pull_request / pull_request_target trigger # - no generic runner labels -# - runtime warning-step job is enabled only for manual workflow_dispatch -# - no secrets, host writes, workflow dispatch from Codex, or runtime apply +# - runtime warning-step job is enabled for controlled workflow_dispatch only +# - no secrets, host writes, workflow dispatch from this commit, or product writes name: AWOOOI Onboarding Warning Step @@ -17,13 +17,13 @@ env: jobs: workflow-shape: # Gitea 1.25 can mark a workflow invalid when every root job has a job-level - # `if`. Keep this no-op root job so the template remains parseable while - # the runtime warning-step job below is gated by the explicit env switch. + # `if`. Keep this no-op root job so the workflow remains parseable while + # the runtime warning-step job below stays behind the controlled switch. runs-on: awoooi-non110-host timeout-minutes: 1 steps: - - name: Confirm fail-closed warning-step workflow shape - run: echo "warning-step runtime job is enabled for manual dispatch only." + - name: Confirm controlled warning-step workflow shape + run: echo "warning-step runtime job is enabled for controlled workflow_dispatch only." warning-step: if: ${{ env.AWOOOI_ONBOARDING_WARNING_STEP_EXECUTION_ENABLED == '1' }} @@ -39,5 +39,5 @@ jobs: git diff --check cat <<'SUMMARY' AWOOOI onboarding warning step template is present. - Runtime execution is enabled only for manual workflow_dispatch. + Runtime execution is enabled only for controlled workflow_dispatch boundary validation. SUMMARY