Close PXX automation execution gate

This commit is contained in:
Codex
2026-05-12 09:34:08 +08:00
parent 1e442c5f0f
commit f6eae1da55
7 changed files with 285 additions and 20 deletions
+17 -6
View File
@@ -2,7 +2,7 @@
## Current Goal
Automation execution-layer P24 is closed. Current `HEAD` was deployed to the remote host and P24 remote ops smoke passed across health, runtime status, review packet, alert quality, operator digest, runtime incidents, maintenance summary, visual-watch dry-run, and P23 unattended harness. The default next action is PXX `Automation Execution Closure Gate`.
Automation execution-layer PXX is closed. P15-P24 are all closed, current `HEAD` was deployed to the remote host, P24 remote ops smoke passed, and the PXX closure gate froze the known execution-layer scope. The default state is long-running analysis-decision monitoring with ops rollup; new product phases require explicit user direction.
## Current Branch
@@ -14,8 +14,8 @@ Automation execution-layer P24 is closed. Current `HEAD` was deployed to the rem
## Automation Status
- state: automation_execution_layer_p24_remote_smoke_ops_closure_closed
- current_phase: P24 Remote Smoke And Ops Closure
- state: automation_execution_layer_pxx_known_scope_closed
- current_phase: Long-running Analysis Decision Monitor With Ops Rollup
- latest_p7_selector_choice: continue_periodic_analysis_decision_monitoring_with_maturity_rollup
- latest_p14_slice: webhook_transport_retry
- latest_p15_pxx_tasklist_status: ready
@@ -65,7 +65,10 @@ Automation execution-layer P24 is closed. Current `HEAD` was deployed to the rem
- latest_remote_deploy_status: deployed_current_head
- latest_remote_ops_smoke_status: passed
- latest_remote_ops_smoke_base_url: http://192.168.3.90:8000
- next_execution_layer_phase: PXX Automation Execution Closure Gate
- latest_pxx_slice: automation_execution_closure_gate
- latest_pxx_closure_gate_status: passed
- latest_pxx_new_phase_policy: require_explicit_user_product_decision
- next_execution_layer_phase: Long-running Analysis Decision Monitor With Ops Rollup
- latest_visual_review_script_status: idle
- latest_runtime_visual_watch_task_status: ok
- latest_visual_capture_cleanup_task_status: ok
@@ -155,6 +158,8 @@ Automation execution-layer P24 is closed. Current `HEAD` was deployed to the rem
- Added `scripts/run_remote_ops_smoke.py` for P24 remote API validation.
- Extended password deploy smoke coverage to include alert quality, operator digest, runtime incidents, maintenance summary, and the P23 harness.
- Deployed current `HEAD` to `http://192.168.3.90:8000` and confirmed P24 remote ops smoke passed without warnings or blockers.
- Added `scripts/run_automation_execution_closure_gate.py` for the PXX finite-scope closure check.
- Marked P15-P24 and PXX closed in the state anchors and froze automatic P25/P26 phase creation.
## Current Working State
@@ -188,6 +193,8 @@ Automation execution-layer P24 is closed. Current `HEAD` was deployed to the rem
- P23 is analysis/decision-only: `external_channels_used=false` and `real_trade_required=false`.
- P24 remote deployment is complete for current `HEAD`.
- P24 remote smoke is implemented and passed: `/health`, `/trading/runtime-status`, `/trading/review-packet`, `/trading/alerts/quality-summary`, `/trading/alerts/operator-digest`, `/trading/runtime-incidents`, `/trading/maintenance-summary`, visual-watch cleanup dry-run, and `/trading/unattended-harness` all passed on `http://192.168.3.90:8000`.
- PXX closure gate is implemented and passed: P15-P24 and PXX are checked in `TASKS.md`, PXX state is recorded in `SESSION.md`, final validation evidence is present, and no new Research Council phase was created.
- PXX post-state is frozen: `Long-running Analysis Decision Monitor With Ops Rollup`; new product phases require explicit user direction.
- Latest `scripts/run_visual_review.py` smoke found no pending reviews: attempted=0, reviewed=0, status=idle.
- Latest capture smoke returned `status=ignored` when no watch run was supplied, which is the expected safe no-op.
- Latest cleanup smoke deleted one expired temporary artifact through `scripts/run_visual_capture_cleanup.py`.
@@ -197,7 +204,7 @@ Automation execution-layer P24 is closed. Current `HEAD` was deployed to the rem
- Latest `scripts/run_trading_runtime.py` smoke returned blockers=none and includes a healthy `visual_watch` runtime task.
- Latest local runtime smoke confirmed `runtime_status.tasks.alert_dispatch.details` now exposes retry and silent-window counters with blockers=none.
## P24 Blockers
## PXX Blockers
- none
@@ -222,6 +229,7 @@ Automation execution-layer P24 is closed. Current `HEAD` was deployed to the rem
- P22 maintenance summary remains read-only and uses visual capture retention dry-run statistics only; it must not delete business data or alter execution permission, live readiness, trust bucket, risk governor, or operator confirmation.
- P23 unattended harness remains a local/remote smoke verifier only and must not use external channels, require real trades, or alter execution permission, live readiness, trust bucket, risk governor, or operator confirmation.
- P24 remote ops smoke remains verification only: its visual-watch step uses dry-run cleanup and it must not use external channels, require real trades, or alter execution permission, live readiness, trust bucket, risk governor, or operator confirmation.
- PXX closure gate is verification/state-freeze only and must not create a Research Council phase, alter execution permission, enable real-live readiness, change risk governor/trust bucket behavior, or weaken operator confirmation.
- A final rerun of `scripts/run_alert_dispatcher.py` and `scripts/run_trading_runtime.py` hit local PostgreSQL connection timeout because nothing was listening on `127.0.0.1:5432`; the P14 code path is still covered by full unit tests and earlier successful smoke during implementation.
- P15 dispatcher smoke succeeded with `suppressed_noise_policy`, `workbench_only`, and `policy_external_allowed` counters present. P15 runtime smoke reached `alert_dispatch` successfully, but the overall runtime returned external environment blockers for market stream disconnected and OKX read transport connection refused.
- P16 direct browser smoke succeeded locally with `browser_capture_status=captured`. Script-level capture without a watch run still returns safe no-op `watch_run_missing`.
@@ -246,11 +254,12 @@ Automation execution-layer P24 is closed. Current `HEAD` was deployed to the rem
- P24 focused validation passed: remote ops smoke tests and deploy smoke coverage tests passed; script static checks passed across 72 scripts.
- P24 deploy passed through `scripts/deploy_with_password.py` with 11 HTTP smoke endpoints.
- P24 remote ops smoke passed on `http://192.168.3.90:8000` with 9 passed checks, warnings=[], blockers=[].
- PXX final validation passed: 709 unit tests, 73 script static checks, `node --check src/web/app.js`, P24 remote ops smoke passed, and closure gate passed.
- Real-live order submission remains intentionally disabled because the OKX order adapter is still not a real-live submitter.
## Exact Next Step
P24 is closed. Default next action is PXX `Automation Execution Closure Gate`: verify P15-P24 are all closed, rerun final quality gates, freeze known automation execution-layer scope, and write the final closure status.
PXX is closed. Default next action is long-running analysis-decision monitoring with ops rollup; do not create P25/P26 automatically. Any new real-trading closure, real external media channel, or product capability must be opened as an explicit new user-directed phase.
## Validation Commands Used Recently
@@ -282,4 +291,6 @@ D:\ai-exchange\.venv\Scripts\python.exe -m unittest tests.unit.test_unattended_h
D:\ai-exchange\.venv\Scripts\python.exe scripts\run_unattended_harness.py
D:\ai-exchange\.venv\Scripts\python.exe -m unittest tests.unit.test_run_remote_ops_smoke tests.unit.test_deploy_with_password
D:\ai-exchange\.venv\Scripts\python.exe scripts\run_remote_ops_smoke.py --base-url http://192.168.3.90:8000 --attempts 2 --timeout-seconds 20
D:\ai-exchange\.venv\Scripts\python.exe -m unittest tests.unit.test_run_automation_execution_closure_gate
D:\ai-exchange\.venv\Scripts\python.exe scripts\run_automation_execution_closure_gate.py
```
+15 -8
View File
@@ -13,7 +13,7 @@
## In Progress
- [x] P24 Remote Smoke And Ops Closure complete
- [x] PXX Automation Execution Closure Gate complete
## Next Up
@@ -35,14 +35,14 @@
- [x] P22 local closure complete
- [x] P23 local closure complete
- [x] P24 remote smoke closure complete
- [ ] Start PXX Automation Execution Closure Gate
- [ ] Continue periodic analysis-decision monitoring with maturity rollup in parallel
- [ ] Treat browser screenshot capture and additional external media adapters as future enhancements
- [x] PXX closure gate complete
- [x] Continue periodic analysis-decision monitoring with maturity rollup in parallel
- [x] Treat browser screenshot capture and additional external media adapters as future enhancements
## Automation Status
- [x] state: automation_execution_layer_p24_remote_smoke_ops_closure_closed
- [x] current_phase: P24 Remote Smoke And Ops Closure
- [x] state: automation_execution_layer_pxx_known_scope_closed
- [x] current_phase: Long-running Analysis Decision Monitor With Ops Rollup
- [x] latest_p7_selector_choice: continue_periodic_analysis_decision_monitoring_with_maturity_rollup
- [x] latest_p14_slice: webhook_transport_retry
- [x] latest_p15_pxx_tasklist_status: ready
@@ -92,7 +92,10 @@
- [x] latest_remote_deploy_status: deployed_current_head
- [x] latest_remote_ops_smoke_status: passed
- [x] latest_remote_ops_smoke_base_url: http://192.168.3.90:8000
- [x] next_execution_layer_phase: PXX Automation Execution Closure Gate
- [x] latest_pxx_slice: automation_execution_closure_gate
- [x] latest_pxx_closure_gate_status: passed
- [x] latest_pxx_new_phase_policy: require_explicit_user_product_decision
- [x] next_execution_layer_phase: Long-running Analysis Decision Monitor With Ops Rollup
- [x] latest_visual_review_script_status: idle
- [x] latest_runtime_visual_watch_task_status: ok
- [x] latest_visual_capture_cleanup_task_status: ok
@@ -207,6 +210,8 @@
- [x] Added `scripts/run_remote_ops_smoke.py`
- [x] Extended deploy smoke to include P20-P23 execution-layer routes
- [x] Added focused P24 remote ops smoke and deploy coverage tests
- [x] Added `scripts/run_automation_execution_closure_gate.py`
- [x] Added focused PXX closure gate tests
- [x] Added runtime `visual_watch` task
- [x] Added focused service, script, API, and runtime tests
- [x] Smoked the visual review script with no pending reviews
@@ -241,6 +246,7 @@
- [x] Deployed current `HEAD` to `http://192.168.3.90:8000`
- [x] Completed P24 remote deploy smoke through `scripts/deploy_with_password.py` with 11 HTTP endpoints
- [x] Completed P24 remote ops smoke with 9 passed checks, no warnings, and no blockers
- [x] Completed PXX closure gate with finite-scope freeze and no new Research Council phase creation
## Blocked
@@ -296,6 +302,7 @@
- [x] `automation_execution_layer_p22_maintenance_retention_rollup`
- [x] `automation_execution_layer_p23_end_to_end_unattended_harness`
- [x] `automation_execution_layer_p24_remote_smoke_ops_closure`
- [x] `automation_execution_layer_pxx_known_scope_closed`
## P15-PXX Finite Queue
@@ -309,7 +316,7 @@
- [x] `P22` Maintenance And Retention Rollup
- [x] `P23` End-To-End Unattended Harness
- [x] `P24` Remote Smoke And Ops Closure
- [ ] `PXX` Automation Execution Closure Gate
- [x] `PXX` Automation Execution Closure Gate
## Backlog
@@ -414,6 +414,7 @@ candidate -> decision alert -> dispatcher -> 外部消息 -> delivery record
- 2026-05-12 P22 已完成 `maintenance / retention rollup` 本地闭环:maintenance summary 以只读方式聚合 visual capture retention dry-run、delivery/feedback、runtime watchdog 与 incident journal,输出 P23 harness 可复用的 checks/blockers/warnings/p23_assertions,不执行未纳入 retention policy 的业务数据删除。
- 2026-05-12 P23 已完成 `end-to-end unattended harness` 本地闭环:`UnattendedHarnessService`、脚本与 API 会在 analysis/decision-only 模式下一次性验证 P15-P22 关键路径,输出单一 JSON blockers/warnings/passed-checks 报告,不使用外部通道、不要求真实成交。
- 2026-05-12 P24 已完成 `remote smoke / ops closure` 闭环:当前 `HEAD` 已部署到远端,部署后 11 个 HTTP smoke endpoint 通过,`scripts/run_remote_ops_smoke.py` 对 P15-P23 关键远端能力返回 9 个 passed checks、无 warnings、无 blockers。
- 2026-05-12 PXX 已完成 `automation execution closure gate` 闭环:P15-P24 已冻结,`SESSION.md` / `TASKS.md` / `docs` 已回写,后续默认进入长期 monitor + ops rollup,不再自动发明 P25/P26。
### 验收
- 非重大错误不打断主循环
@@ -134,6 +134,11 @@
2026-05-12 P24 已落地:remote ops smoke 覆盖 health、runtime status、review packet、alert quality、operator digest、runtime incidents、maintenance summary、visual-watch cleanup dry-run 与 P23 unattended harness。该脚本只做远端可用性验证,visual-watch 步骤使用 dry-run,不触发外部通道、不要求真实成交,也不改变任何交易权限或 operator confirmation protocol。
#### `scripts/run_automation_execution_closure_gate.py`
职责:验证 P15-P24 与 PXX finite-scope closure 是否已经完成,并冻结自动扩阶段的默认后续状态。
2026-05-12 PXX 已落地:closure gate 只读取 `SESSION.md`、`TASKS.md` 与 P15-PXX 任务清单,确认 P15-P24 已 closed、PXX 后默认状态已冻结、`new_phase_policy` 要求用户显式打开新阶段。该脚本只做状态校验,不改变任何执行权限、交易权限或 operator confirmation protocol。
#### `src/services/alerts/delivery_policy_service.py`
职责:
@@ -323,6 +323,8 @@
- 2026-05-12 P24 已新增 `scripts/run_remote_ops_smoke.py`,覆盖 `/health`、`/trading/runtime-status`、`/trading/review-packet`、`/trading/alerts/quality-summary`、`/trading/alerts/operator-digest`、`/trading/runtime-incidents`、`/trading/maintenance-summary`、visual-watch cleanup dry-run 与 `/trading/unattended-harness`。
- 2026-05-12 P24 已扩展 `scripts/deploy_with_password.py` 的部署后 HTTP smoke,使远端版本漂移会在 P20-P23 新入口缺失时失败。
- 2026-05-12 P24 已将当前 `HEAD` 部署到 `http://192.168.3.90:8000`;部署脚本 11 个 HTTP smoke endpoint 通过,P24 remote ops smoke 返回 `status=passed`、passed_checks=9、warnings=[]、blockers=[]。
- 2026-05-12 PXX 已新增 `scripts/run_automation_execution_closure_gate.py`,以 finite-scope gate 校验 P15-P24 已闭环、`SESSION.md` / `TASKS.md` 已回写、PXX 后默认状态已冻结。
- 2026-05-12 PXX closure gate 已通过:P15-P24 均为 closed,`SESSION.md` / `TASKS.md` / 本文档均已回写,当前执行层不再自动发明 P25/P26。
---
@@ -357,15 +359,17 @@ PXX 之后,系统默认进入长期 monitor + ops rollup,不再自动发明
## 16. 推荐连续执行入口
默认下一步:
PXX 关闭后默认状态:
```text
P15 Alert Noise Policy Matrix
state: automation_execution_layer_pxx_known_scope_closed
current_phase: Long-running Analysis Decision Monitor With Ops Rollup
next_action: continue_periodic_analysis_decision_monitoring_with_maturity_rollup
new_phase_policy: require_explicit_user_product_decision
```
执行方式:
1. 打开 P15 最小闭环。
2. 完成代码、验证、状态回写、commit。
3. 自动进入 P16。
4. 重复直到 PXX closure gate 或真实 blocker。
1. 保持长期 monitor + ops rollup。
2. 不再自动发明 P25/P26。
3. 若未来需要真实成交闭环、真实外部媒体发送、或新的产品能力,必须由用户明确打开新阶段。
@@ -0,0 +1,159 @@
from __future__ import annotations
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional
import argparse
import json
import os
ROOT = Path(__file__).resolve().parents[1]
TASKS_PATH = Path("TASKS.md")
SESSION_PATH = Path("SESSION.md")
TASKLIST_PATH = Path("docs/AI_ICT_自动化执行层_P15-PXX闭环任务清单_v1.md")
REQUIRED_QUEUE_ITEMS = (
"`P15` Alert Noise Policy Matrix",
"`P16` Browser Screenshot Capture Adapter",
"`P17` Visual Trigger ROI Router",
"`P18` Visual Evidence Media Dispatch",
"`P19` Multi-Channel Alert Routing",
"`P20` Operator Digest And Review Queue",
"`P21` Runtime Incident Journal",
"`P22` Maintenance And Retention Rollup",
"`P23` End-To-End Unattended Harness",
"`P24` Remote Smoke And Ops Closure",
"`PXX` Automation Execution Closure Gate",
)
REQUIRED_GUARDS = (
"execution_allowed",
"real_live_ready",
"risk_governor",
"trust_bucket",
"operator_confirmation_protocol",
)
def run_closure_gate(root: Path = ROOT) -> dict:
tasks = _read_text(root / TASKS_PATH)
session = _read_text(root / SESSION_PATH)
tasklist = _read_text(root / TASKLIST_PATH)
checks = [
_check_queue_closed(tasks),
_check_session_pxx_state(session),
_check_scope_freeze_policy(tasklist),
_check_validation_evidence(session),
_check_guardrails(session),
]
blockers = [check["name"] for check in checks if check["status"] == "blocked"]
return {
"status": "blocked" if blockers else "passed",
"mode": "automation_execution_closure_gate",
"generated_ts": datetime.now(timezone.utc).isoformat(),
"checks": checks,
"passed_checks": [check["name"] for check in checks if check["status"] == "passed"],
"blockers": blockers,
"post_pxx_state": {
"state": "automation_execution_layer_pxx_known_scope_closed",
"current_phase": "Long-running Analysis Decision Monitor With Ops Rollup",
"next_action": "continue_periodic_analysis_decision_monitoring_with_maturity_rollup",
"new_phase_policy": "require_explicit_user_product_decision",
},
}
def _check_queue_closed(tasks: str) -> dict:
missing = []
for item in REQUIRED_QUEUE_ITEMS:
if f"- [x] {item}" not in tasks:
missing.append(item)
if missing:
return _blocked("p15_pxx_queue_closed", f"unchecked queue items: {missing}")
return _passed("p15_pxx_queue_closed", "P15-P24 and PXX are checked in TASKS.md")
def _check_session_pxx_state(session: str) -> dict:
required = (
"state: automation_execution_layer_pxx_known_scope_closed",
"current_phase: Long-running Analysis Decision Monitor With Ops Rollup",
"next_execution_layer_phase: Long-running Analysis Decision Monitor With Ops Rollup",
)
missing = [item for item in required if item not in session]
if missing:
return _blocked("session_pxx_state", f"SESSION.md missing {missing}")
return _passed("session_pxx_state", "SESSION.md records the PXX frozen state")
def _check_scope_freeze_policy(tasklist: str) -> dict:
required = (
"new_phase_policy: require_explicit_user_product_decision",
"不再自动发明 P25/P26",
)
missing = [item for item in required if item not in tasklist]
if missing:
return _blocked("scope_freeze_policy", f"tasklist missing {missing}")
return _passed("scope_freeze_policy", "PXX tasklist freezes automatic phase creation")
def _check_validation_evidence(session: str) -> dict:
required = (
"PXX final validation passed",
"unit tests",
"script static checks",
"P24 remote ops smoke passed",
)
missing = [item for item in required if item not in session]
if missing:
return _blocked("validation_evidence", f"SESSION.md missing {missing}")
return _passed("validation_evidence", "SESSION.md records final quality and remote smoke evidence")
def _check_guardrails(session: str) -> dict:
missing = [guard for guard in REQUIRED_GUARDS if guard not in session]
if missing:
return _blocked("guardrails_unchanged", f"SESSION.md missing guards {missing}")
return _passed("guardrails_unchanged", "guardrail names remain recorded as unchanged")
def _read_text(path: Path) -> str:
return path.read_text(encoding="utf-8")
def _passed(name: str, detail: str) -> dict:
return {"name": name, "status": "passed", "detail": detail}
def _blocked(name: str, detail: str) -> dict:
return {"name": name, "status": "blocked", "detail": detail}
def _get_bool(env, key: str, default: bool) -> bool:
value = env.get(key)
if value is None or value == "":
return default
return str(value).strip().lower() in {"1", "true", "yes", "on"}
def _parse_args(argv: Optional[list[str]]) -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Run the PXX automation execution closure gate.")
parser.add_argument("--root", default=str(ROOT))
return parser.parse_args(argv)
def main(argv: Optional[list[str]] = None, env=None) -> int:
env = os.environ if env is None else env
args = _parse_args(argv)
payload = run_closure_gate(root=Path(args.root))
if _get_bool(env, "CLOSURE_GATE_OUTPUT_JSON", False):
print(json.dumps(payload, ensure_ascii=False, sort_keys=True))
else:
print(f"Closure gate status: {payload['status']}")
print(f"Passed checks: {', '.join(payload['passed_checks']) or 'none'}")
print(f"Blockers: {', '.join(payload['blockers']) or 'none'}")
return 0 if payload["status"] == "passed" else 2
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,78 @@
import tempfile
import unittest
from pathlib import Path
from scripts.run_automation_execution_closure_gate import REQUIRED_QUEUE_ITEMS, run_closure_gate
class AutomationExecutionClosureGateTests(unittest.TestCase):
def test_passes_when_queue_state_and_evidence_are_closed(self) -> None:
with tempfile.TemporaryDirectory() as tmp_dir:
root = Path(tmp_dir)
_write_closure_files(root)
payload = run_closure_gate(root=root)
self.assertEqual(payload["status"], "passed")
self.assertEqual(payload["blockers"], [])
self.assertIn("p15_pxx_queue_closed", payload["passed_checks"])
self.assertEqual(payload["post_pxx_state"]["new_phase_policy"], "require_explicit_user_product_decision")
def test_blocks_when_a_queue_item_is_not_checked(self) -> None:
with tempfile.TemporaryDirectory() as tmp_dir:
root = Path(tmp_dir)
_write_closure_files(root, unchecked_item="`P24` Remote Smoke And Ops Closure")
payload = run_closure_gate(root=root)
self.assertEqual(payload["status"], "blocked")
self.assertIn("p15_pxx_queue_closed", payload["blockers"])
def test_blocks_when_validation_evidence_is_missing(self) -> None:
with tempfile.TemporaryDirectory() as tmp_dir:
root = Path(tmp_dir)
_write_closure_files(root, include_validation=False)
payload = run_closure_gate(root=root)
self.assertEqual(payload["status"], "blocked")
self.assertIn("validation_evidence", payload["blockers"])
def _write_closure_files(root: Path, unchecked_item=None, include_validation: bool = True) -> None:
docs = root / "docs"
docs.mkdir(parents=True)
task_lines = ["## P15-PXX Finite Queue"]
for item in REQUIRED_QUEUE_ITEMS:
checkbox = "[ ]" if item == unchecked_item else "[x]"
task_lines.append(f"- {checkbox} {item}")
(root / "TASKS.md").write_text("\n".join(task_lines), encoding="utf-8")
validation = ""
if include_validation:
validation = "PXX final validation passed: unit tests, script static checks. P24 remote ops smoke passed."
(root / "SESSION.md").write_text(
"\n".join(
[
"state: automation_execution_layer_pxx_known_scope_closed",
"current_phase: Long-running Analysis Decision Monitor With Ops Rollup",
"next_execution_layer_phase: Long-running Analysis Decision Monitor With Ops Rollup",
"guards_unchanged: execution_allowed, real_live_ready, risk_governor, trust_bucket, operator_confirmation_protocol",
validation,
]
),
encoding="utf-8",
)
(docs / "AI_ICT_自动化执行层_P15-PXX闭环任务清单_v1.md").write_text(
"\n".join(
[
"new_phase_policy: require_explicit_user_product_decision",
"PXX 之后不再自动发明 P25/P26。",
]
),
encoding="utf-8",
)
if __name__ == "__main__":
unittest.main()