feat(governance): 新增 Agent 版本新鮮度快照
All checks were successful
CD Pipeline / tests (push) Successful in 1m24s
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / build-and-deploy (push) Successful in 4m0s
CD Pipeline / post-deploy-checks (push) Successful in 1m51s

This commit is contained in:
Your Name
2026-06-11 12:55:03 +08:00
parent 5aa60acd84
commit c1821d9652
13 changed files with 1354 additions and 35 deletions

View File

@@ -58,6 +58,9 @@ from src.services.ai_agent_deployment_layout import (
from src.services.ai_agent_proactive_operations_contract import (
load_latest_ai_agent_proactive_operations_contract,
)
from src.services.ai_agent_version_freshness_snapshot import (
load_latest_ai_agent_version_freshness_snapshot,
)
from src.services.ai_provider_route_matrix import (
load_latest_ai_provider_route_matrix,
)
@@ -584,6 +587,33 @@ async def get_agent_proactive_operations_contract() -> dict[str, Any]:
) from exc
@router.get(
"/agent-version-freshness-snapshot",
response_model=dict[str, Any],
summary="取得 AI Agent repo-only 版本新鮮度快照",
description=(
"讀取最新已提交的 AI Agent repo-only 版本新鮮度快照;此端點不啟用每日排程、"
"不查外部 registry/CVE、不安裝或升級套件、不寫 lockfile、不 build/pull image、"
"不 probe 主機、不建立 PR、不發 Telegram、不呼叫付費服務、不修改生產路由。"
),
)
async def get_agent_version_freshness_snapshot() -> dict[str, Any]:
"""Return the latest read-only AI Agent version freshness snapshot."""
try:
return await asyncio.to_thread(load_latest_ai_agent_version_freshness_snapshot)
except FileNotFoundError as exc:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=str(exc),
) from exc
except (json.JSONDecodeError, ValueError) as exc:
logger.error("ai_agent_version_freshness_snapshot_invalid", error=str(exc))
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="AI Agent 版本新鮮度快照無效",
) from exc
@router.get(
"/runtime-surface-inventory",
response_model=dict[str, Any],

View File

@@ -0,0 +1,180 @@
"""
AI Agent version freshness snapshot.
Loads the latest committed, read-only version freshness snapshot for OpenClaw,
Hermes, and NemoTron. This module never enables schedules, queries external
registries, installs or upgrades packages, writes lockfiles, builds or pulls
images, probes hosts, creates PRs, sends Telegram messages, or changes
production routing.
"""
from __future__ import annotations
import json
from pathlib import Path
from typing import Any
from src.services.snapshot_paths import default_evaluations_dir
_DEFAULT_EVALUATIONS_DIR = default_evaluations_dir(Path(__file__))
_SNAPSHOT_PATTERN = "ai_agent_version_freshness_snapshot_*.json"
_SCHEMA_VERSION = "ai_agent_version_freshness_snapshot_v1"
_RUNTIME_AUTHORITY = "repo_only_snapshot_no_external_lookup_or_update"
def load_latest_ai_agent_version_freshness_snapshot(
evaluations_dir: Path | None = None,
) -> dict[str, Any]:
"""Load the newest committed AI Agent version freshness snapshot."""
directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR
candidates = sorted(directory.glob(_SNAPSHOT_PATTERN))
if not candidates:
raise FileNotFoundError(
f"no AI Agent version freshness snapshots found in {directory}"
)
latest = candidates[-1]
with latest.open(encoding="utf-8") as handle:
payload = json.load(handle)
if not isinstance(payload, dict):
raise ValueError(f"{latest}: expected JSON object")
_require_schema(payload, _SCHEMA_VERSION, str(latest))
_require_read_only_boundaries(payload, str(latest))
_require_rollup_consistency(payload, str(latest))
_require_source_safety(payload, str(latest))
return payload
def _require_schema(payload: dict[str, Any], expected: str, label: str) -> None:
actual = payload.get("schema_version")
if actual != expected:
raise ValueError(f"{label}: expected schema_version={expected}, got {actual!r}")
def _require_read_only_boundaries(payload: dict[str, Any], label: str) -> None:
program_status = payload.get("program_status") or {}
if program_status.get("read_only_mode") is not True:
raise ValueError(f"{label}: program_status.read_only_mode must be true")
if program_status.get("runtime_authority") != _RUNTIME_AUTHORITY:
raise ValueError(f"{label}: runtime_authority must stay {_RUNTIME_AUTHORITY}")
scan_boundaries = payload.get("scan_boundaries") or {}
if scan_boundaries.get("read_only_repo_snapshot_allowed") is not True:
raise ValueError(f"{label}: read_only_repo_snapshot_allowed must be true")
blocked_scan_flags = {
"schedule_activation_allowed",
"workflow_write_allowed",
"external_registry_lookup_allowed",
"external_cve_lookup_allowed",
"package_installation_allowed",
"package_upgrade_allowed",
"lockfile_write_allowed",
"docker_build_allowed",
"image_pull_allowed",
"host_probe_allowed",
"auto_pr_allowed",
"auto_merge_allowed",
"telegram_direct_send_allowed",
"paid_external_service_allowed",
"production_route_change_allowed",
}
enabled_scan_flags = sorted(
flag for flag in blocked_scan_flags if scan_boundaries.get(flag) is not False
)
if enabled_scan_flags:
raise ValueError(f"{label}: scan boundaries must remain false: {enabled_scan_flags}")
approval_boundaries = payload.get("approval_boundaries") or {}
blocked_approval_flags = {
"daily_schedule_enabled",
"external_source_lookup_allowed",
"package_or_model_upgrade_allowed",
"host_or_k3s_probe_allowed",
"telegram_digest_send_allowed",
"gitea_pr_creation_allowed",
"production_route_change_allowed",
}
enabled_approval_flags = sorted(
flag
for flag in blocked_approval_flags
if approval_boundaries.get(flag) is not False
)
if enabled_approval_flags:
raise ValueError(
f"{label}: approval boundaries must remain false: {enabled_approval_flags}"
)
def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None:
sources = payload.get("freshness_sources") or []
agents = payload.get("agent_roles") or []
steps = payload.get("daily_snapshot_design") or []
rollups = payload.get("rollups") or {}
expected_counts = {
"source_count": len(sources),
"repo_only_source_count": sum(
1 for source in sources if source.get("source_type") == "repo_only"
),
"agent_count": len(agents),
"daily_step_count": len(steps),
}
mismatched = {
key: {"expected": expected, "actual": rollups.get(key)}
for key, expected in expected_counts.items()
if rollups.get(key) != expected
}
if mismatched:
raise ValueError(f"{label}: rollup counts must match payload sections: {mismatched}")
action_required = sorted(
source.get("source_id")
for source in sources
if source.get("status") == "action_required"
or source.get("action_required") is True
)
if sorted(rollups.get("action_required_source_ids") or []) != action_required:
raise ValueError(f"{label}: rollups.action_required_source_ids mismatch")
blocked_external_lookup = sorted(
source.get("source_id")
for source in sources
if source.get("external_lookup_allowed") is False
)
if sorted(rollups.get("blocked_external_lookup_source_ids") or []) != blocked_external_lookup:
raise ValueError(f"{label}: rollups.blocked_external_lookup_source_ids mismatch")
mutation_allowed_count = sum(
1 for source in sources if source.get("mutation_allowed") is True
)
if rollups.get("mutation_allowed_source_count") != mutation_allowed_count:
raise ValueError(f"{label}: rollups.mutation_allowed_source_count mismatch")
if rollups.get("schedule_enabled_count") != 0:
raise ValueError(f"{label}: rollups.schedule_enabled_count must remain 0")
if rollups.get("telegram_direct_send_count") != 0:
raise ValueError(f"{label}: rollups.telegram_direct_send_count must remain 0")
def _require_source_safety(payload: dict[str, Any], label: str) -> None:
unsafe_sources = [
source.get("source_id")
for source in payload.get("freshness_sources") or []
if source.get("source_type") != "repo_only"
or source.get("external_lookup_allowed") is not False
or source.get("mutation_allowed") is not False
or not source.get("evidence_refs")
or not source.get("next_action")
]
if unsafe_sources:
raise ValueError(f"{label}: freshness sources must stay repo-only: {unsafe_sources}")
unsafe_steps = [
step.get("step_id")
for step in payload.get("daily_snapshot_design") or []
if step.get("allowed_now") is not True
]
if unsafe_steps:
raise ValueError(f"{label}: daily snapshot design steps must stay read-only: {unsafe_steps}")

View File

@@ -13,9 +13,9 @@ def test_load_latest_ai_agent_proactive_operations_contract_reads_committed_snap
data = load_latest_ai_agent_proactive_operations_contract()
assert data["schema_version"] == "ai_agent_proactive_operations_contract_v1"
assert data["program_status"]["overall_completion_percent"] == 30
assert data["program_status"]["current_task_id"] == "P2-402A"
assert data["program_status"]["next_task_id"] == "P2-402B"
assert data["program_status"]["overall_completion_percent"] == 42
assert data["program_status"]["current_task_id"] == "P2-402B"
assert data["program_status"]["next_task_id"] == "P2-402C"
assert data["program_status"]["read_only_mode"] is True
assert data["program_status"]["runtime_authority"] == "contract_only_no_version_or_runtime_update"
assert data["approval_boundaries"]["runtime_version_update_allowed"] is False

View File

@@ -16,9 +16,9 @@ def test_ai_agent_proactive_operations_contract_endpoint_returns_committed_snaps
assert response.status_code == 200
data = response.json()
assert data["schema_version"] == "ai_agent_proactive_operations_contract_v1"
assert data["program_status"]["overall_completion_percent"] == 30
assert data["program_status"]["current_task_id"] == "P2-402A"
assert data["program_status"]["next_task_id"] == "P2-402B"
assert data["program_status"]["overall_completion_percent"] == 42
assert data["program_status"]["current_task_id"] == "P2-402B"
assert data["program_status"]["next_task_id"] == "P2-402C"
assert data["program_status"]["read_only_mode"] is True
assert data["approval_boundaries"]["runtime_version_update_allowed"] is False
assert data["approval_boundaries"]["package_upgrade_allowed"] is False

View File

@@ -0,0 +1,175 @@
from __future__ import annotations
import json
import pytest
from src.services.ai_agent_version_freshness_snapshot import (
load_latest_ai_agent_version_freshness_snapshot,
)
def test_load_latest_ai_agent_version_freshness_snapshot_reads_committed_snapshot():
data = load_latest_ai_agent_version_freshness_snapshot()
assert data["schema_version"] == "ai_agent_version_freshness_snapshot_v1"
assert data["program_status"]["overall_completion_percent"] == 42
assert data["program_status"]["current_task_id"] == "P2-402B"
assert data["program_status"]["next_task_id"] == "P2-402C"
assert data["program_status"]["read_only_mode"] is True
assert (
data["program_status"]["runtime_authority"]
== "repo_only_snapshot_no_external_lookup_or_update"
)
assert data["scan_boundaries"]["read_only_repo_snapshot_allowed"] is True
assert data["scan_boundaries"]["schedule_activation_allowed"] is False
assert data["scan_boundaries"]["external_registry_lookup_allowed"] is False
assert data["scan_boundaries"]["package_upgrade_allowed"] is False
assert data["scan_boundaries"]["lockfile_write_allowed"] is False
assert data["scan_boundaries"]["telegram_direct_send_allowed"] is False
assert data["approval_boundaries"]["daily_schedule_enabled"] is False
assert data["approval_boundaries"]["package_or_model_upgrade_allowed"] is False
assert data["rollups"]["source_count"] == len(data["freshness_sources"]) == 12
assert data["rollups"]["repo_only_source_count"] == 12
assert data["rollups"]["agent_count"] == 3
assert data["rollups"]["daily_step_count"] == 5
assert data["rollups"]["mutation_allowed_source_count"] == 0
assert data["rollups"]["schedule_enabled_count"] == 0
assert data["rollups"]["telegram_direct_send_count"] == 0
assert "javascript_workspace_manifests" in data["rollups"]["action_required_source_ids"]
assert "dockerfiles" in data["rollups"]["action_required_source_ids"]
def test_ai_agent_version_freshness_snapshot_rejects_schedule_activation(tmp_path):
snapshot = _snapshot()
snapshot["scan_boundaries"]["schedule_activation_allowed"] = True
(tmp_path / "ai_agent_version_freshness_snapshot_2026-06-11.json").write_text(
json.dumps(snapshot),
encoding="utf-8",
)
with pytest.raises(ValueError, match="scan boundaries"):
load_latest_ai_agent_version_freshness_snapshot(tmp_path)
def test_ai_agent_version_freshness_snapshot_rejects_rollup_mismatch(tmp_path):
snapshot = _snapshot()
snapshot["rollups"]["source_count"] = 99
(tmp_path / "ai_agent_version_freshness_snapshot_2026-06-11.json").write_text(
json.dumps(snapshot),
encoding="utf-8",
)
with pytest.raises(ValueError, match="rollup counts"):
load_latest_ai_agent_version_freshness_snapshot(tmp_path)
def test_ai_agent_version_freshness_snapshot_rejects_external_lookup_source(tmp_path):
snapshot = _snapshot()
snapshot["freshness_sources"][0]["external_lookup_allowed"] = True
(tmp_path / "ai_agent_version_freshness_snapshot_2026-06-11.json").write_text(
json.dumps(snapshot),
encoding="utf-8",
)
with pytest.raises(ValueError, match="blocked_external_lookup_source_ids|repo-only"):
load_latest_ai_agent_version_freshness_snapshot(tmp_path)
def _snapshot() -> dict:
return {
"schema_version": "ai_agent_version_freshness_snapshot_v1",
"generated_at": "2026-06-11T22:45:00+08:00",
"program_status": {
"overall_completion_percent": 42,
"current_priority": "P2",
"current_task_id": "P2-402B",
"next_task_id": "P2-402C",
"read_only_mode": True,
"runtime_authority": "repo_only_snapshot_no_external_lookup_or_update",
"status_note": "測試。",
},
"scan_boundaries": {
"read_only_repo_snapshot_allowed": True,
"schedule_activation_allowed": False,
"workflow_write_allowed": False,
"external_registry_lookup_allowed": False,
"external_cve_lookup_allowed": False,
"package_installation_allowed": False,
"package_upgrade_allowed": False,
"lockfile_write_allowed": False,
"docker_build_allowed": False,
"image_pull_allowed": False,
"host_probe_allowed": False,
"auto_pr_allowed": False,
"auto_merge_allowed": False,
"telegram_direct_send_allowed": False,
"paid_external_service_allowed": False,
"production_route_change_allowed": False,
},
"agent_roles": [
{
"agent_id": "hermes",
"role": "測試。",
"autonomy_level": "L1_report_only",
"outputs": ["snapshot"],
"approval_gate": "read_only",
}
],
"repo_scan_summary": {
"javascript_workspace_count": 1,
"javascript_direct_dependency_count": 2,
"python_manifest_count": 1,
"dockerfile_count": 1,
"runtime_surface_count": 1,
"committed_inventory_refs": ["docs/evaluations/example.json"],
"stale_committed_inventory_refs": ["docs/evaluations/example.json"],
},
"daily_snapshot_design": [
{
"step_id": "collect",
"sequence": 1,
"owner_agent": "hermes",
"allowed_now": True,
"planned_output": "snapshot",
"blocked_now": ["upgrade"],
}
],
"freshness_sources": [
{
"source_id": "javascript_workspace_manifests",
"domain": "javascript_packages",
"source_type": "repo_only",
"owner_agent": "hermes",
"status": "action_required",
"freshness_basis": "manifest",
"current_signal": "test",
"external_lookup_allowed": False,
"mutation_allowed": False,
"action_required": True,
"evidence_refs": ["package.json"],
"next_action": "review",
}
],
"approval_boundaries": {
"daily_schedule_enabled": False,
"external_source_lookup_allowed": False,
"package_or_model_upgrade_allowed": False,
"host_or_k3s_probe_allowed": False,
"telegram_digest_send_allowed": False,
"gitea_pr_creation_allowed": False,
"production_route_change_allowed": False,
},
"rollups": {
"source_count": 1,
"repo_only_source_count": 1,
"agent_count": 1,
"daily_step_count": 1,
"action_required_source_ids": ["javascript_workspace_manifests"],
"blocked_external_lookup_source_ids": ["javascript_workspace_manifests"],
"mutation_allowed_source_count": 0,
"schedule_enabled_count": 0,
"telegram_direct_send_count": 0,
"next_approval_task_ids": ["P2-402C"],
},
}

View File

@@ -0,0 +1,35 @@
from __future__ import annotations
from fastapi import FastAPI
from fastapi.testclient import TestClient
from src.api.v1.agents import router
def test_ai_agent_version_freshness_snapshot_endpoint_returns_committed_snapshot():
app = FastAPI()
app.include_router(router, prefix="/api/v1")
client = TestClient(app)
response = client.get("/api/v1/agents/agent-version-freshness-snapshot")
assert response.status_code == 200
data = response.json()
assert data["schema_version"] == "ai_agent_version_freshness_snapshot_v1"
assert data["program_status"]["overall_completion_percent"] == 42
assert data["program_status"]["current_task_id"] == "P2-402B"
assert data["program_status"]["next_task_id"] == "P2-402C"
assert data["program_status"]["read_only_mode"] is True
assert data["scan_boundaries"]["schedule_activation_allowed"] is False
assert data["scan_boundaries"]["external_registry_lookup_allowed"] is False
assert data["scan_boundaries"]["package_upgrade_allowed"] is False
assert data["scan_boundaries"]["telegram_direct_send_allowed"] is False
assert data["approval_boundaries"]["daily_schedule_enabled"] is False
assert data["rollups"]["source_count"] == 12
assert data["rollups"]["repo_only_source_count"] == 12
assert data["rollups"]["mutation_allowed_source_count"] == 0
assert data["rollups"]["schedule_enabled_count"] == 0
assert any(
source["source_id"] == "agent_model_governance_snapshots"
for source in data["freshness_sources"]
)

View File

@@ -297,6 +297,24 @@
- Nginx reload / restart、DNS 修改、TLS renew、ArgoCD sync、kubectl、SSH 主機修改、workflow 修改、runner 啟用、secret rotation、active scan、agent-bounty runtime、payout / withdrawal、deploy 或 runtime execution本階段全部未執行。
- IwoooS 整體仍維持 `64%`active runtime gate 仍為 `0`owner response received / accepted 仍為 `0 / false`
## 2026-06-11P2-402B Repo-only 版本新鮮度快照
**背景**:統帥批准繼續推進 AI Agent 主動更新版本情報與可委派營運工作。本波承接 P2-402A不直接啟用 schedule、不查外部 registry、不升級套件或模型、不 probe 主機、不發 Telegram而是先建立 repo-only daily version freshness snapshot 的正式資料面與 API。
**完成內容:**
- 新增 `docs/schemas/ai_agent_version_freshness_snapshot_v1.schema.json`,定義 repo-only 版本新鮮度快照、3 Agent 角色、daily snapshot design、freshness sources、approval boundaries 與 rollups。
- 新增 `docs/evaluations/ai_agent_version_freshness_snapshot_2026-06-11.json`,覆蓋 12 類 repo-only sourceJavaScript、Python、pnpm lockfile、Dockerfile、K8s、Gitea workflow、observability、Ansible host manifest、committed evaluation snapshots、Agent/model governance、backup/DR、public web/admin surfaces。
- 新增 `apps/api/src/services/ai_agent_version_freshness_snapshot.py`,只讀載入最新 committed snapshot並強制 `schedule_activation_allowed``external_registry_lookup_allowed``package_upgrade_allowed``lockfile_write_allowed``docker_build_allowed``image_pull_allowed``host_probe_allowed``telegram_direct_send_allowed` 等維持 false。
- 新增 `GET /api/v1/agents/agent-version-freshness-snapshot`,只回傳 committed snapshot不觸發掃描、不查外部、不改 repo、不發 Telegram。
- 更新 `docs/evaluations/ai_agent_proactive_operations_contract_2026-06-11.json`:整體 AI Agent 主動營運與版本生命週期完成度調整為 `42%`current task `P2-402B`next task `P2-402C`
- 更新 MASTER §3.2.1c / §5、`docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md``docs/ai/AI_AGENT_PROACTIVE_OPERATIONS_2026-06-11.md`
- 新增 `apps/api/tests/test_ai_agent_version_freshness_snapshot.py``apps/api/tests/test_ai_agent_version_freshness_snapshot_api.py`
**完成度與下一步:**
- P2-402B repo-only 版本新鮮度快照:`100%`
- 整體 AI Agent 主動營運與版本生命週期:`42%`
- 下一步:`P2-402C` Renovate / OSV / Trivy / Syft / Grype 工具採用批准包;仍不得直接安裝工具、改 CI、查外部、升級套件、建立 PR 或送 Telegram。
## 2026-06-11OpenClaw / Hermes / NemoTron 佈建布局第一波
**背景**:統帥要求將 OpenClaw、Hermes、NemoTron 依各自專長安排到所有主機、套件、工具、服務、專案、網站前後台,並納入主動學習、互相溝通、持續成長與 Telegram Bot 告警鏈路。本波先建立可驗證的只讀佈建布局,避免把尚未批准的 runtime deploy、SDK/API、Telegram 發送或主機操作誤當已授權。

View File

@@ -13,7 +13,7 @@
| 工具 / 服務 / 套件 AI 自動化 | 92% | P0 已完成P1 服務 / runtime / 監控 / provider / service health / 備份 / DR / 套件與供應鏈只讀基線已完成P1-007 失敗限定通知合約與前端 redaction 合約已完成;下一主線是 P2-004 依賴 / 供應鏈漂移監控 | 狀態分類、盤點 schema、權限矩陣、靜態盤點種子、只讀 API、UI 骨架、驗證、自動化待辦 schema / 快照 / API / 分組 UI、Backup / DR 目標盤點、準備度矩陣、備份通知政策、Backup / DR 證據 UI、復原演練批准包模板、異地 / escrow 準備度狀態、任務批准邊界、確定性進度彙總、Python 套件 / 供應鏈只讀基線、JS pnpm/npm 只讀基線、Docker build surface 只讀基線、CVE / license / drift 嚴重度政策、定期依賴漂移與外部資料來源檢查設計、依賴升級批准包模板、runtime_surface_inventory_v1 schema / snapshot / API / UI、gitea_workflow_runner_health_v1 schema / snapshot / API / UI、observability_contract_matrix_v1 schema / snapshot / API / UI、ai_provider_route_matrix_v1 schema / snapshot / API / UI、service_health_gap_matrix_v1 schema / snapshot / API / UI、service health evidence cards UI、service_health_failure_notification_policy_v1 schema / snapshot / API / UI 已完成 |
| OpenClaw / Hermes / NemoTron 佈建布局 | 45% | P1-401 / P1-402 已完成;仍是只讀 layout 與治理頁顯示,不是 runtime deploy | `ai_agent_deployment_layout_v1` schema、`ai_agent_deployment_layout_2026-06-11.json``GET /api/v1/agents/agent-deployment-layout`、治理頁自動化盤點 UI、`AI_AGENT_DEPLOYMENT_LAYOUT_2026-06-11.md` |
| OpenClaw / Hermes / NemoTron 主動溝通與學習契約 | 35% | P2-401A 已完成只讀 contractruntime worker、DB migration、Telegram 實發、SDK / 付費服務仍未開 gate | `ai_agent_communication_learning_contract_v1` schema、`ai_agent_communication_learning_contract_2026-06-11.json``GET /api/v1/agents/agent-communication-learning-contract`、MASTER §3.2.1b / §3.4.3 |
| AI Agent 主動營運委派與版本生命週期 | 30% | P2-402A 已完成只讀 contract定期排程、外部版本查詢、套件升級、主機更新、container pull、auto merge、Telegram 實發仍未開 gate | `ai_agent_proactive_operations_contract_v1` schema`ai_agent_proactive_operations_contract_2026-06-11.json``GET /api/v1/agents/agent-proactive-operations-contract`、MASTER §3.2.1c |
| AI Agent 主動營運委派與版本生命週期 | 42% | P2-402A / P2-402B 已完成;已建立 repo-only 版本新鮮度快照與 API。定期排程、外部版本查詢、套件升級、主機更新、container pull、auto merge、Telegram 實發仍未開 gate | `ai_agent_proactive_operations_contract_v1``ai_agent_version_freshness_snapshot_v1``GET /api/v1/agents/agent-proactive-operations-contract``GET /api/v1/agents/agent-version-freshness-snapshot`MASTER §3.2.1c |
| 本工作清單與分析報告 | 100% | 已完成 | 本 MD 文件 |
AI Agent 自動化工作包目前完成度:**92%**。本工作清單文件本身完成度:**100%**。
@@ -22,7 +22,7 @@ AI Agent 自動化工作包目前完成度:**92%**。本工作清單文件本
三 Agent 主動溝通與學習契約目前完成度:**35%**。已完成只讀 schema / snapshot / API / 測試與 MASTER 同步;下一步依優先順序推 `P2-401B` AgentSession / Redis Streams migration 與 worker gate但在批准前仍不得啟動 runtime loop。
AI Agent 主動營運委派與版本生命週期目前完成度:**30%**。已完成 12 類版本 domain、24 類可委派能力、5 種 cadence、8 類 MCP、4 類 RAG memory只讀 API;下一步是 `P2-402B` repo-only daily version freshness snapshot外部 registry / package source / host probe / Telegram 實發仍需 gate。
AI Agent 主動營運委派與版本生命週期目前完成度:**42%**。已完成 12 類版本 domain、24 類可委派能力、5 種 cadence、8 類 MCP、4 類 RAG memory只讀 API,以及 `P2-402B` repo-only daily version freshness snapshot schema / committed snapshot / API / 測試;下一步是 `P2-402C` Renovate / OSV / Trivy / Syft / Grype 工具採用批准包,外部 registry / package source / host probe / Telegram 實發仍需 gate。
完成度計算模型:
@@ -952,7 +952,7 @@ UI
| P2-401D | 待辦 | 0 | Hermes | RAG Hot / Warm / Cold memory ingestion、dedupe、freshness、redaction policy | RAG 記憶治理提案 | schema migration + owner review |
| P2-401E | 待辦 | 0 | Nemotron | sanitized replay scorer 與 5-record smoke 設計 | NemoTron replay smoke 批准包 | cost / data approval |
| P2-402A | 完成 | 100 | Hermes + OpenClaw + Nemotron | 定義 AI Agent 主動營運委派與版本生命週期12 類版本 domain、24 類可委派能力、MCP/RAG/Telegram policy | `ai_agent_proactive_operations_contract_v1` / snapshot / 只讀 API / MASTER 同步 | 只讀;不啟用排程、不升級、不 host update、不 pull image、不 auto merge、不發 Telegram |
| P2-402B | 待辦 | 0 | Hermes | 建立 repo-only daily version freshness snapshot | manifest / lockfile / Dockerfile / K8s YAML / snapshot freshness | workflow schedule approval |
| P2-402B | 完成 | 100 | Hermes | 建立 repo-only daily version freshness snapshot | `ai_agent_version_freshness_snapshot_v1` / snapshot / 只讀 API / 測試12 類 repo-only source、5 個 daily step、3 Agent role | 只讀workflow schedule 未啟用、外部 lookup 未開、不得升級或發 Telegram |
| P2-402C | 待辦 | 0 | OpenClaw | 建立 Renovate / OSV / Trivy / Syft / Grype 工具採用批准包 | 工具 / 費用 / secret / CI 變更批准包 | tool install + CI change approval |
| P2-402D | 待辦 | 0 | OpenClaw | 建立 Telegram action-required digest policy | critical / action-required / failure-only digest | Telegram Gateway E2E |
| P2-402E | 待辦 | 0 | Hermes | 設計 Gitea PR 草案 lane | grouping、automerge=false、tests、rollback、owner response | bot / branch policy approval |

View File

@@ -1,14 +1,15 @@
# AI Agent 主動營運委派與版本生命週期分析報告
> 日期2026-06-11台北時間
> 文件定位P2-402A 只讀契約摘要。權威細節以 MASTER §3.2.1c`ai_agent_proactive_operations_contract_v1` 為準。
> 文件定位P2-402A / P2-402B 只讀契約摘要。權威細節以 MASTER §3.2.1c`ai_agent_proactive_operations_contract_v1` 與 `ai_agent_version_freshness_snapshot_v1` 為準。
## 1. 本波完成度
| 範圍 | 完成度 | 狀態 |
|---|---:|---|
| 主動營運委派契約 | 100% | 已完成 schema / snapshot / API / 測試 |
| 整體主動營運與版本生命週期 | 30% | 已完成架構與邊界runtime 排程與更新尚未開 gate |
| Repo-only 版本新鮮度快照 | 100% | P2-402B 已完成 schema / committed snapshot / API / 測試 |
| 整體主動營運與版本生命週期 | 42% | 已完成架構、邊界與 repo-only freshnessruntime 排程與更新尚未開 gate |
## 2. 可交給 AI Agent 的工作分類
@@ -30,19 +31,35 @@
| `docs/schemas/ai_agent_proactive_operations_contract_v1.schema.json` | 主動營運委派與版本生命週期 schema |
| `docs/evaluations/ai_agent_proactive_operations_contract_2026-06-11.json` | 12 類版本 domain、24 類可委派能力、5 種 cadence、8 類 MCP、4 類 RAG memory |
| `GET /api/v1/agents/agent-proactive-operations-contract` | 只讀 API不啟用排程、不升級、不發 Telegram |
| `docs/schemas/ai_agent_version_freshness_snapshot_v1.schema.json` | Repo-only 版本新鮮度 schema所有外部查詢與更新權限預設 false |
| `docs/evaluations/ai_agent_version_freshness_snapshot_2026-06-11.json` | 12 類 repo-only source、5 個 daily step、3 Agent role、5 個 action-required source |
| `GET /api/v1/agents/agent-version-freshness-snapshot` | 只讀 API不觸發掃描、不查外部、不改 repo、不發 Telegram |
## 4. 下一步優先順序
## 4. P2-402B Repo-only 版本新鮮度快照
| Source | 主責 | 狀態 | 下一步 |
|---|---|---|---|
| JavaScript workspace manifests | Hermes | action_required | P2-402C 前只比較 repo specifier / lockfile不查 npm registry |
| Python package manifests | Hermes | action_required | 只讀比較 pyproject / requirements不 pip / uv install |
| Dockerfiles | Hermes | action_required | P2-402C 評估 Trivy / Syft / Grype / Docker Scout 採用,不 build / pull |
| Committed evaluation snapshots | Hermes | action_required | 將 2026-06-04~06-05 舊基線列入 stale refs不假裝是外部最新 |
| Agent / model governance snapshots | NemoTron | action_required | 只做離線 freshness note不進 shadow / canary / production route |
| K8s / Gitea / observability / Ansible / backup / web surfaces | OpenClaw + Hermes | baseline_ready / planned_next | 分別等待 P2-402D / P2-402F / P2-402G gate |
本波只把「每天要看哪些 repo 內版本來源」定義成可驗證資料面。每日排程、外部 registry 查詢、主機/K3s live probe、Telegram digest 與 Gitea PR lane 都仍是下一階段 gate。
## 5. 下一步優先順序
| ID | 優先 | 任務 | 關卡 |
|---|---|---|---|
| P2-402B | 1 | repo-only daily version freshness snapshot | workflow schedule approval |
| P2-402C | 2 | Renovate / OSV / Trivy / Syft / Grype 採用批准包 | tool install / CI approval |
| P2-402D | 3 | Telegram action-required digest policy | Telegram Gateway E2E |
| P2-402E | 4 | Gitea PR 草案 lane | bot / branch policy approval |
| P2-402F | 5 | host OS / K3s / stateful services 版本只讀盤點 | host probe / maintenance approval |
| P2-402G | 6 | governance UI 顯示可委派能力 | frontend UI approval |
| P2-402B | 0 | repo-only daily version freshness snapshot | 已完成,只讀;workflow schedule 未啟用 |
| P2-402C | 1 | Renovate / OSV / Trivy / Syft / Grype 採用批准包 | tool install / CI approval |
| P2-402D | 2 | Telegram action-required digest policy | Telegram Gateway E2E |
| P2-402E | 3 | Gitea PR 草案 lane | bot / branch policy approval |
| P2-402F | 4 | host OS / K3s / stateful services 版本只讀盤點 | host probe / maintenance approval |
| P2-402G | 5 | governance UI 顯示可委派能力 | frontend UI approval |
## 5. 仍維持 false 的安全邊界
## 6. 仍維持 false 的安全邊界
- `runtime_version_update_allowed=false`
- `package_upgrade_allowed=false`
@@ -54,3 +71,6 @@
- `secret_plaintext_allowed=false`
- `paid_external_service_allowed=false`
- `production_route_change_allowed=false`
- `external_registry_lookup_allowed=false`
- `daily_schedule_enabled=false`
- `gitea_pr_creation_allowed=false`

View File

@@ -2,13 +2,13 @@
"schema_version": "ai_agent_proactive_operations_contract_v1",
"generated_at": "2026-06-11T21:30:00+08:00",
"program_status": {
"overall_completion_percent": 30,
"overall_completion_percent": 42,
"current_priority": "P2",
"current_task_id": "P2-402A",
"next_task_id": "P2-402B",
"current_task_id": "P2-402B",
"next_task_id": "P2-402C",
"read_only_mode": true,
"runtime_authority": "contract_only_no_version_or_runtime_update",
"status_note": "本快照定義 AI Agent 可主動處理的營運工作與版本生命週期;本波不啟用排程、不升級套件、不更新主機、不 pull image、不 auto merge、不發 Telegram。"
"status_note": "P2-402B 已建立 repo-only 版本新鮮度快照與只讀 API;本波不啟用排程、不升級套件、不更新主機、不 pull image、不 auto merge、不發 Telegram。"
},
"external_source_evidence": [
{
@@ -612,15 +612,15 @@
"summary": "定義 AI Agent 主動營運委派與版本生命週期契約、schema、snapshot、只讀 API 與文件同步。",
"next_gate": "正式部署驗證"
},
{
"task_id": "P2-402B",
"priority": "P2",
"status": "planned",
"completion_percent": 0,
"owner_agent": "Hermes",
"summary": "建立 repo-only daily version freshness snapshot不查外部 registry、不改 workflow。",
"next_gate": "workflow_schedule_approval_required"
},
{
"task_id": "P2-402B",
"priority": "P2",
"status": "done",
"completion_percent": 100,
"owner_agent": "Hermes",
"summary": "建立 repo-only daily version freshness snapshot schema、committed snapshot、只讀 API 與測試;不查外部 registry、不改 workflow。",
"next_gate": "P2-402C_tool_adoption_approval_package"
},
{
"task_id": "P2-402C",
"priority": "P2",

View File

@@ -0,0 +1,427 @@
{
"schema_version": "ai_agent_version_freshness_snapshot_v1",
"generated_at": "2026-06-11T22:45:00+08:00",
"program_status": {
"overall_completion_percent": 42,
"current_priority": "P2",
"current_task_id": "P2-402B",
"next_task_id": "P2-402C",
"read_only_mode": true,
"runtime_authority": "repo_only_snapshot_no_external_lookup_or_update",
"status_note": "P2-402B 建立 repo-only 版本新鮮度快照格式與 API本波不啟用每日排程、不查外部 registry、不升級套件/模型、不 pull image、不建立 PR、不發 Telegram。"
},
"scan_boundaries": {
"read_only_repo_snapshot_allowed": true,
"schedule_activation_allowed": false,
"workflow_write_allowed": false,
"external_registry_lookup_allowed": false,
"external_cve_lookup_allowed": false,
"package_installation_allowed": false,
"package_upgrade_allowed": false,
"lockfile_write_allowed": false,
"docker_build_allowed": false,
"image_pull_allowed": false,
"host_probe_allowed": false,
"auto_pr_allowed": false,
"auto_merge_allowed": false,
"telegram_direct_send_allowed": false,
"paid_external_service_allowed": false,
"production_route_change_allowed": false
},
"agent_roles": [
{
"agent_id": "hermes",
"role": "讀取 repo 內 manifest / lockfile / Dockerfile / K8s / workflow / committed snapshot產生 version freshness evidence packet。",
"autonomy_level": "L1_report_only",
"outputs": [
"repo-only version freshness snapshot",
"stale source list",
"next approval package inputs"
],
"approval_gate": "read_only_repo_snapshot_allowed"
},
{
"agent_id": "openclaw",
"role": "仲裁 stale / action_required 訊號,判斷是否進入 P2-402C 工具採用批准包或 P2-402D Telegram digest policy。",
"autonomy_level": "L2_approval_package_only",
"outputs": [
"risk note",
"approval boundary check",
"human review packet"
],
"approval_gate": "human_review_required_before_any_update"
},
{
"agent_id": "nemotron",
"role": "離線檢查 Agent / model / replay / prompt governance 快照是否過期,協助建立模型評測 replay 清單。",
"autonomy_level": "L1_report_only",
"outputs": [
"offline model freshness note",
"replay candidate list"
],
"approval_gate": "offline_replay_only_until_shadow_gate"
}
],
"repo_scan_summary": {
"javascript_workspace_count": 6,
"javascript_direct_dependency_count": 51,
"python_manifest_count": 6,
"dockerfile_count": 2,
"runtime_surface_count": 22,
"committed_inventory_refs": [
"docs/evaluations/javascript_package_inventory_2026-06-04.json",
"docs/evaluations/package_supply_chain_inventory_2026-06-04.json",
"docs/evaluations/dependency_drift_check_plan_2026-06-04.json",
"docs/evaluations/docker_build_surface_inventory_2026-06-04.json",
"docs/evaluations/runtime_surface_inventory_2026-06-05.json",
"docs/evaluations/ai_agent_proactive_operations_contract_2026-06-11.json"
],
"stale_committed_inventory_refs": [
"docs/evaluations/javascript_package_inventory_2026-06-04.json",
"docs/evaluations/package_supply_chain_inventory_2026-06-04.json",
"docs/evaluations/dependency_drift_check_plan_2026-06-04.json",
"docs/evaluations/docker_build_surface_inventory_2026-06-04.json",
"docs/evaluations/runtime_surface_inventory_2026-06-05.json"
]
},
"daily_snapshot_design": [
{
"step_id": "collect_repo_version_sources",
"sequence": 1,
"owner_agent": "hermes",
"allowed_now": true,
"planned_output": "freshness_sources[] with evidence_refs and repo-only current_signal",
"blocked_now": [
"external registry lookup",
"host probe",
"package install",
"lockfile write"
]
},
{
"step_id": "compare_committed_inventory_age",
"sequence": 2,
"owner_agent": "hermes",
"allowed_now": true,
"planned_output": "stale_committed_inventory_refs and action_required source ids",
"blocked_now": [
"rewrite historical snapshots",
"claim latest upstream version",
"query package registries"
]
},
{
"step_id": "openclaw_boundary_review",
"sequence": 3,
"owner_agent": "openclaw",
"allowed_now": true,
"planned_output": "approval boundary decision for P2-402C / P2-402D / P2-402F",
"blocked_now": [
"approve own changes",
"enable auto merge",
"change production route"
]
},
{
"step_id": "nemotron_offline_agent_model_review",
"sequence": 4,
"owner_agent": "nemotron",
"allowed_now": true,
"planned_output": "offline model / agent snapshot freshness note",
"blocked_now": [
"shadow traffic",
"canary traffic",
"production provider routing"
]
},
{
"step_id": "emit_action_required_digest_draft",
"sequence": 5,
"owner_agent": "hermes",
"allowed_now": true,
"planned_output": "AwoooP / Telegram digest draft only; no send",
"blocked_now": [
"Telegram direct send",
"Alertmanager route change",
"workflow schedule activation"
]
}
],
"freshness_sources": [
{
"source_id": "javascript_workspace_manifests",
"domain": "javascript_packages",
"source_type": "repo_only",
"owner_agent": "hermes",
"status": "action_required",
"freshness_basis": "package.json workspace manifests + previous javascript_package_inventory snapshot",
"current_signal": "6 workspaces / 51 direct dependencies; prior inventory is 2026-06-04 and should be refreshed by repo-only scanner before any registry comparison.",
"external_lookup_allowed": false,
"mutation_allowed": false,
"action_required": true,
"evidence_refs": [
"package.json",
"apps/web/package.json",
"packages/shared-types/package.json",
"packages/lewooogo-core/package.json",
"packages/eslint-config/package.json",
"packages/tsconfig/package.json",
"pnpm-lock.yaml",
"docs/evaluations/javascript_package_inventory_2026-06-04.json"
],
"next_action": "P2-402C 前先建立 registry/tool 採用批准包;未批准前只能比較 repo 內 specifier 與 lockfile。"
},
{
"source_id": "python_package_manifests",
"domain": "python_packages",
"source_type": "repo_only",
"owner_agent": "hermes",
"status": "action_required",
"freshness_basis": "pyproject.toml / requirements.txt manifests + package_supply_chain_inventory snapshot",
"current_signal": "6 Python manifest surfacesapps/api pyproject and requirements are high-impact and still require read-only drift refresh.",
"external_lookup_allowed": false,
"mutation_allowed": false,
"action_required": true,
"evidence_refs": [
"apps/api/pyproject.toml",
"apps/api/requirements.txt",
"apps/sensor/requirements.txt",
"packages/lewooogo-brain/pyproject.toml",
"packages/lewooogo-data/pyproject.toml",
"scripts/aider_watch_client/pyproject.toml",
"docs/evaluations/package_supply_chain_inventory_2026-06-04.json"
],
"next_action": "只讀比較 dependency specifiers不得 pip/uv install不得重寫 requirements。"
},
{
"source_id": "pnpm_lockfile",
"domain": "javascript_lockfile",
"source_type": "repo_only",
"owner_agent": "hermes",
"status": "baseline_ready",
"freshness_basis": "pnpm-lock.yaml importer consistency",
"current_signal": "P1-202 snapshot reported 0 manifest/lock mismatch; P2-402B keeps this as repo-only baseline, not upstream latest evidence.",
"external_lookup_allowed": false,
"mutation_allowed": false,
"action_required": false,
"evidence_refs": [
"pnpm-lock.yaml",
"docs/evaluations/javascript_package_inventory_2026-06-04.json"
],
"next_action": "Future daily run may fail only on repo mismatch; remediation still requires approval package."
},
{
"source_id": "dockerfiles",
"domain": "container_images",
"source_type": "repo_only",
"owner_agent": "hermes",
"status": "action_required",
"freshness_basis": "Dockerfile FROM / COPY --from / build-time fetch surfaces",
"current_signal": "2 Dockerfiles; prior inventory shows 0 digest-pinned image refs and 2 action_required surfaces.",
"external_lookup_allowed": false,
"mutation_allowed": false,
"action_required": true,
"evidence_refs": [
"apps/api/Dockerfile",
"apps/web/Dockerfile",
"docs/evaluations/docker_build_surface_inventory_2026-06-04.json"
],
"next_action": "P2-402C 工具批准包需評估 Trivy / Syft / Grype / Docker Scout本波不 build、不 pull、不查 registry。"
},
{
"source_id": "k8s_prod_manifests",
"domain": "kubernetes_k3s_components",
"source_type": "repo_only",
"owner_agent": "openclaw",
"status": "baseline_ready",
"freshness_basis": "committed k8s/awoooi-prod manifests and runtime_surface_inventory",
"current_signal": "22 runtime surfaces mapped; live K3s / version skew remains outside P2-402B and requires P2-402F gate.",
"external_lookup_allowed": false,
"mutation_allowed": false,
"action_required": false,
"evidence_refs": [
"k8s/awoooi-prod/kustomization.yaml",
"k8s/awoooi-prod/06-deployment-api.yaml",
"k8s/awoooi-prod/05-deployment-web.yaml",
"k8s/awoooi-prod/08-deployment-worker.yaml",
"docs/evaluations/runtime_surface_inventory_2026-06-05.json"
],
"next_action": "P2-402F 才能建立 host/K3s/stateful 只讀版本盤點;本波不 kubectl、不 host probe。"
},
{
"source_id": "gitea_workflows",
"domain": "ci_cd_and_runner_tools",
"source_type": "repo_only",
"owner_agent": "hermes",
"status": "baseline_ready",
"freshness_basis": ".gitea/workflows committed YAML",
"current_signal": "可讀取 workflow schedule / runner / image refsP2-402B 不新增或修改 schedule。",
"external_lookup_allowed": false,
"mutation_allowed": false,
"action_required": false,
"evidence_refs": [
".gitea/workflows/cd.yaml",
".gitea/workflows/agent-market-watch.yaml",
".gitea/workflows/e2e-health.yaml"
],
"next_action": "若要啟用 daily freshness schedule需 P2-402D notification policy 與 workflow approval。"
},
{
"source_id": "observability_manifests",
"domain": "observability_stack",
"source_type": "repo_only",
"owner_agent": "openclaw",
"status": "baseline_ready",
"freshness_basis": "Prometheus / Alertmanager / SigNoz committed configs",
"current_signal": "只讀檢查 alert and scrape config refs不改 Alertmanager route不發通知。",
"external_lookup_allowed": false,
"mutation_allowed": false,
"action_required": false,
"evidence_refs": [
"k8s/monitoring/prometheus.yml",
"ops/alertmanager/alertmanager.yml",
"ops/signoz/otel-collector-config-phase-o.yaml"
],
"next_action": "P2-402D 定義 failure-only digest 後,才能接 Telegram/AwoooP 通知。"
},
{
"source_id": "ansible_host_manifests",
"domain": "host_os_packages",
"source_type": "repo_only",
"owner_agent": "openclaw",
"status": "planned_next",
"freshness_basis": "infra/ansible inventory and playbooks",
"current_signal": "Repo contains host roles and playbooks, but live package/kernel/K3s versions require P2-402F host readonly probe approval.",
"external_lookup_allowed": false,
"mutation_allowed": false,
"action_required": false,
"evidence_refs": [
"infra/ansible/inventory/hosts.yml",
"infra/ansible/playbooks/site.yml",
"infra/ansible/roles/runner-guardrails/tasks/main.yml"
],
"next_action": "P2-402F 建立 host OS / K3s / stateful version inventory未批准前不得 SSH probe、apt upgrade、restart 或 reboot。"
},
{
"source_id": "committed_evaluation_snapshots",
"domain": "governance_snapshots",
"source_type": "repo_only",
"owner_agent": "hermes",
"status": "action_required",
"freshness_basis": "docs/evaluations committed JSON snapshots",
"current_signal": "Core package / Docker / drift / runtime snapshots are 2026-06-04~2026-06-05 baselines; P2-402B establishes the 2026-06-11 freshness envelope.",
"external_lookup_allowed": false,
"mutation_allowed": false,
"action_required": true,
"evidence_refs": [
"docs/evaluations/javascript_package_inventory_2026-06-04.json",
"docs/evaluations/package_supply_chain_inventory_2026-06-04.json",
"docs/evaluations/dependency_drift_check_plan_2026-06-04.json",
"docs/evaluations/docker_build_surface_inventory_2026-06-04.json",
"docs/evaluations/runtime_surface_inventory_2026-06-05.json"
],
"next_action": "每日快照正式啟用前,先由 committed API 顯示 stale refs不得假裝已查到外部最新版本。"
},
{
"source_id": "agent_model_governance_snapshots",
"domain": "ai_agents_models",
"source_type": "repo_only",
"owner_agent": "nemotron",
"status": "action_required",
"freshness_basis": "agent-market / NemoTron / OpenClaw committed governance evidence",
"current_signal": "Agent market and Nemotron replay sources remain gate-bound; repo-only snapshot may only flag stale committed evidence.",
"external_lookup_allowed": false,
"mutation_allowed": false,
"action_required": true,
"evidence_refs": [
"docs/evaluations/ai_agent_proactive_operations_contract_2026-06-11.json",
"docs/ai/AI_AGENT_PROACTIVE_OPERATIONS_2026-06-11.md",
"docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md"
],
"next_action": "P2-402C/P2-402D 之前不得新增 SDK、shadow/canary、production route 或付費 market source。"
},
{
"source_id": "backup_dr_tooling_refs",
"domain": "backup_dr_tooling",
"source_type": "repo_only",
"owner_agent": "openclaw",
"status": "planned_next",
"freshness_basis": "backup scripts / DR runbooks / readiness snapshots",
"current_signal": "Repo-only source can track script refs, but live backup outcome remains separate and must use current production evidence.",
"external_lookup_allowed": false,
"mutation_allowed": false,
"action_required": false,
"evidence_refs": [
"scripts/backup/backup-gitea.sh",
"docs/runbooks/BACKUP-STATUS.md",
"docs/runbooks/FULL-STACK-COLD-START-SOP.md"
],
"next_action": "Keep backup/DR live truth separate; no automatic restore, prune, or backup mutation from version freshness snapshot."
},
{
"source_id": "public_web_admin_surfaces",
"domain": "public_web_admin_surfaces",
"source_type": "repo_only",
"owner_agent": "hermes",
"status": "baseline_ready",
"freshness_basis": "apps/web routes, i18n messages, and API client refs",
"current_signal": "Can detect whether governance UI knows the latest committed API; no browser automation or UI deploy change is implied.",
"external_lookup_allowed": false,
"mutation_allowed": false,
"action_required": false,
"evidence_refs": [
"apps/web/src/lib/api-client.ts",
"apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx",
"apps/web/messages/zh-TW.json",
"apps/web/messages/en.json"
],
"next_action": "P2-402G 才接 UI 顯示;本波只提供 API不改前端頁面。"
}
],
"approval_boundaries": {
"daily_schedule_enabled": false,
"external_source_lookup_allowed": false,
"package_or_model_upgrade_allowed": false,
"host_or_k3s_probe_allowed": false,
"telegram_digest_send_allowed": false,
"gitea_pr_creation_allowed": false,
"production_route_change_allowed": false
},
"rollups": {
"source_count": 12,
"repo_only_source_count": 12,
"agent_count": 3,
"daily_step_count": 5,
"action_required_source_ids": [
"javascript_workspace_manifests",
"python_package_manifests",
"dockerfiles",
"committed_evaluation_snapshots",
"agent_model_governance_snapshots"
],
"blocked_external_lookup_source_ids": [
"javascript_workspace_manifests",
"python_package_manifests",
"pnpm_lockfile",
"dockerfiles",
"k8s_prod_manifests",
"gitea_workflows",
"observability_manifests",
"ansible_host_manifests",
"committed_evaluation_snapshots",
"agent_model_governance_snapshots",
"backup_dr_tooling_refs",
"public_web_admin_surfaces"
],
"mutation_allowed_source_count": 0,
"schedule_enabled_count": 0,
"telegram_direct_send_count": 0,
"next_approval_task_ids": [
"P2-402C",
"P2-402D",
"P2-402E",
"P2-402F",
"P2-402G"
]
}
}

View File

@@ -0,0 +1,424 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://awoooi.wooo.work/schemas/ai_agent_version_freshness_snapshot_v1.schema.json",
"title": "AI Agent Version Freshness Snapshot v1",
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"generated_at",
"program_status",
"scan_boundaries",
"agent_roles",
"repo_scan_summary",
"daily_snapshot_design",
"freshness_sources",
"approval_boundaries",
"rollups"
],
"properties": {
"schema_version": {
"const": "ai_agent_version_freshness_snapshot_v1"
},
"generated_at": {
"type": "string"
},
"program_status": {
"type": "object",
"additionalProperties": false,
"required": [
"overall_completion_percent",
"current_priority",
"current_task_id",
"next_task_id",
"read_only_mode",
"runtime_authority",
"status_note"
],
"properties": {
"overall_completion_percent": {
"type": "integer",
"minimum": 0,
"maximum": 100
},
"current_priority": {
"type": "string"
},
"current_task_id": {
"type": "string"
},
"next_task_id": {
"type": "string"
},
"read_only_mode": {
"const": true
},
"runtime_authority": {
"const": "repo_only_snapshot_no_external_lookup_or_update"
},
"status_note": {
"type": "string"
}
}
},
"scan_boundaries": {
"type": "object",
"additionalProperties": false,
"required": [
"read_only_repo_snapshot_allowed",
"schedule_activation_allowed",
"workflow_write_allowed",
"external_registry_lookup_allowed",
"external_cve_lookup_allowed",
"package_installation_allowed",
"package_upgrade_allowed",
"lockfile_write_allowed",
"docker_build_allowed",
"image_pull_allowed",
"host_probe_allowed",
"auto_pr_allowed",
"auto_merge_allowed",
"telegram_direct_send_allowed",
"paid_external_service_allowed",
"production_route_change_allowed"
],
"properties": {
"read_only_repo_snapshot_allowed": {
"const": true
},
"schedule_activation_allowed": {
"const": false
},
"workflow_write_allowed": {
"const": false
},
"external_registry_lookup_allowed": {
"const": false
},
"external_cve_lookup_allowed": {
"const": false
},
"package_installation_allowed": {
"const": false
},
"package_upgrade_allowed": {
"const": false
},
"lockfile_write_allowed": {
"const": false
},
"docker_build_allowed": {
"const": false
},
"image_pull_allowed": {
"const": false
},
"host_probe_allowed": {
"const": false
},
"auto_pr_allowed": {
"const": false
},
"auto_merge_allowed": {
"const": false
},
"telegram_direct_send_allowed": {
"const": false
},
"paid_external_service_allowed": {
"const": false
},
"production_route_change_allowed": {
"const": false
}
}
},
"agent_roles": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"agent_id",
"role",
"autonomy_level",
"outputs",
"approval_gate"
],
"properties": {
"agent_id": {
"type": "string"
},
"role": {
"type": "string"
},
"autonomy_level": {
"type": "string"
},
"outputs": {
"type": "array",
"items": {
"type": "string"
}
},
"approval_gate": {
"type": "string"
}
}
}
},
"repo_scan_summary": {
"type": "object",
"additionalProperties": false,
"required": [
"javascript_workspace_count",
"javascript_direct_dependency_count",
"python_manifest_count",
"dockerfile_count",
"runtime_surface_count",
"committed_inventory_refs",
"stale_committed_inventory_refs"
],
"properties": {
"javascript_workspace_count": {
"type": "integer",
"minimum": 0
},
"javascript_direct_dependency_count": {
"type": "integer",
"minimum": 0
},
"python_manifest_count": {
"type": "integer",
"minimum": 0
},
"dockerfile_count": {
"type": "integer",
"minimum": 0
},
"runtime_surface_count": {
"type": "integer",
"minimum": 0
},
"committed_inventory_refs": {
"type": "array",
"items": {
"type": "string"
}
},
"stale_committed_inventory_refs": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"daily_snapshot_design": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"step_id",
"sequence",
"owner_agent",
"allowed_now",
"planned_output",
"blocked_now"
],
"properties": {
"step_id": {
"type": "string"
},
"sequence": {
"type": "integer",
"minimum": 1
},
"owner_agent": {
"type": "string"
},
"allowed_now": {
"const": true
},
"planned_output": {
"type": "string"
},
"blocked_now": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"freshness_sources": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"source_id",
"domain",
"source_type",
"owner_agent",
"status",
"freshness_basis",
"current_signal",
"external_lookup_allowed",
"mutation_allowed",
"action_required",
"evidence_refs",
"next_action"
],
"properties": {
"source_id": {
"type": "string"
},
"domain": {
"type": "string"
},
"source_type": {
"const": "repo_only"
},
"owner_agent": {
"type": "string"
},
"status": {
"enum": [
"baseline_ready",
"action_required",
"planned_next"
]
},
"freshness_basis": {
"type": "string"
},
"current_signal": {
"type": "string"
},
"external_lookup_allowed": {
"const": false
},
"mutation_allowed": {
"const": false
},
"action_required": {
"type": "boolean"
},
"evidence_refs": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
},
"next_action": {
"type": "string"
}
}
}
},
"approval_boundaries": {
"type": "object",
"additionalProperties": false,
"required": [
"daily_schedule_enabled",
"external_source_lookup_allowed",
"package_or_model_upgrade_allowed",
"host_or_k3s_probe_allowed",
"telegram_digest_send_allowed",
"gitea_pr_creation_allowed",
"production_route_change_allowed"
],
"properties": {
"daily_schedule_enabled": {
"const": false
},
"external_source_lookup_allowed": {
"const": false
},
"package_or_model_upgrade_allowed": {
"const": false
},
"host_or_k3s_probe_allowed": {
"const": false
},
"telegram_digest_send_allowed": {
"const": false
},
"gitea_pr_creation_allowed": {
"const": false
},
"production_route_change_allowed": {
"const": false
}
}
},
"rollups": {
"type": "object",
"additionalProperties": false,
"required": [
"source_count",
"repo_only_source_count",
"agent_count",
"daily_step_count",
"action_required_source_ids",
"blocked_external_lookup_source_ids",
"mutation_allowed_source_count",
"schedule_enabled_count",
"telegram_direct_send_count",
"next_approval_task_ids"
],
"properties": {
"source_count": {
"type": "integer",
"minimum": 0
},
"repo_only_source_count": {
"type": "integer",
"minimum": 0
},
"agent_count": {
"type": "integer",
"minimum": 0
},
"daily_step_count": {
"type": "integer",
"minimum": 0
},
"action_required_source_ids": {
"type": "array",
"items": {
"type": "string"
}
},
"blocked_external_lookup_source_ids": {
"type": "array",
"items": {
"type": "string"
}
},
"mutation_allowed_source_count": {
"const": 0
},
"schedule_enabled_count": {
"const": 0
},
"telegram_direct_send_count": {
"const": 0
},
"next_approval_task_ids": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}

View File

@@ -670,14 +670,17 @@ Repo / registry / release notes / K8s / host / observability / backup evidence
| 檔案 / API | 用途 |
|---|---|
| `docs/schemas/ai_agent_proactive_operations_contract_v1.schema.json` | 主動營運委派、版本生命週期、MCP、RAG、Telegram policy、approval boundary 契約 |
| `docs/evaluations/ai_agent_proactive_operations_contract_2026-06-11.json` | 12 類版本 domain、24 類可委派能力、5 種 cadence、8 類 MCP、4 類 RAG memory完成度 `30%` |
| `docs/evaluations/ai_agent_proactive_operations_contract_2026-06-11.json` | 12 類版本 domain、24 類可委派能力、5 種 cadence、8 類 MCP、4 類 RAG memory完成度 `42%` |
| `apps/api/src/services/ai_agent_proactive_operations_contract.py` | 只讀 loader強制 runtime update / package upgrade / host upgrade / workflow schedule / auto merge / Telegram direct send 全部 false |
| `GET /api/v1/agents/agent-proactive-operations-contract` | 治理 API只回傳 committed snapshot不啟用排程、不升級、不呼叫付費服務 |
| `docs/schemas/ai_agent_version_freshness_snapshot_v1.schema.json` | P2-402B repo-only 版本新鮮度 schema鎖定 schedule / external lookup / upgrade / Telegram / PR / host probe 全部 false |
| `docs/evaluations/ai_agent_version_freshness_snapshot_2026-06-11.json` | P2-402B committed snapshot12 類 repo-only 版本來源、5 個每日設計步驟、3 Agent 角色、5 個 action-required source |
| `GET /api/v1/agents/agent-version-freshness-snapshot` | 只讀 API回傳 repo-only freshness snapshot不觸發掃描、不查外部、不改 repo、不送 Telegram |
**採用順序:**
1. 先做 repo-only daily freshnessmanifest / lockfile / Dockerfile / K8s YAML / runbook / snapshot。
2. 再評估 external primary source weekly watchRenovate、OSV-Scanner、Trivy、Syft、Grype、Kubernetes skew policy、Docker Scout。
1. 先做 repo-only daily freshnessmanifest / lockfile / Dockerfile / K8s YAML / runbook / snapshot。✅ P2-402B 已建立 committed snapshot/API每日排程仍未授權。
2. 再評估 external primary source weekly watchRenovate、OSV-Scanner、Trivy、Syft、Grype、Kubernetes skew policy、Docker Scout。下一步 P2-402C 只建立工具採用批准包。
3. 再進 Gitea PR 草案 lanegrouping、automerge=false、tests、rollback、owner response。
4. 最後才進人工批准後的 dry-run / smoke / canary / production rollout。
@@ -1314,6 +1317,7 @@ Repo / registry / release notes / K8s / host / observability / backup evidence
| 決策路由 | `services/decision_manager.py` | 新路徑:收到 EvidenceSnapshot → 送 Orchestrator → 等 Coordinator 結果 | L4×D2 |
| 主動溝通與學習契約 | `docs/evaluations/ai_agent_communication_learning_contract_2026-06-11.json` + `GET /api/v1/agents/agent-communication-learning-contract` | 先固定 OpenClaw / Hermes / NemoTron 主動溝通、MCP、RAG、學習與 redaction 邊界;不啟動 runtime worker | L4×D2 / L7×D4 |
| 主動營運委派與版本生命週期契約 | `docs/evaluations/ai_agent_proactive_operations_contract_2026-06-11.json` + `GET /api/v1/agents/agent-proactive-operations-contract` | 先固定 12 類版本 domain、24 類可委派能力、MCP/RAG/Telegram 邊界;不啟用排程、不自動升版 | L4×D2 / L7×D4 / L6×D6 |
| Repo-only 版本新鮮度快照 | `docs/evaluations/ai_agent_version_freshness_snapshot_2026-06-11.json` + `GET /api/v1/agents/agent-version-freshness-snapshot` | P2-402B讓 Hermes 可每日產生 repo-only freshness evidence packet目前只讀 API不啟用 schedule、不查外部、不升級 | L4×D2 / L7×D4 / L6×D6 |
**退出條件(量化)**
@@ -1685,6 +1689,12 @@ Phase 6 完成後
- 新增 `ai_agent_proactive_operations_contract_v1` committed snapshot12 類版本 domain、24 類可委派能力、5 種 cadence、8 類 MCP、4 類 RAG memory。
- 新增 `GET /api/v1/agents/agent-proactive-operations-contract`;本波只讀,完成度 30%未授權排程、升級、host update、container pull、auto merge、Telegram direct send、付費服務或 production route。
### 2026-06-11 22:45 (台北) — §3.2 / §5 — 完成 P2-402B repo-only 版本新鮮度快照 — 回應統帥要求讓 Agent 定期掌握套件、服務、工具、主機版本狀態
- 新增 `ai_agent_version_freshness_snapshot_v1` schema / committed snapshot / loader / API / 測試,定義 12 類 repo-only version source、5 個 daily snapshot design step、3 Agent 角色與 action-required source。
- 更新 `ai_agent_proactive_operations_contract_2026-06-11.json`:整體完成度 `42%`current task `P2-402B`next task `P2-402C`
- 本波仍不啟用 workflow schedule、不查外部 registry/CVE、不安裝或升級套件、不寫 lockfile、不 build/pull image、不 probe host、不建立 PR、不發 TelegramP2-402C 才建立 Renovate / OSV / Trivy / Syft / Grype 工具採用批准包。
### 2026-04-15 (台北) — 全檔 — 建立 v2 骨架§0/§1 完成 — 統帥批准「單 MASTER + 4 道閘門」結構
- 從 v1plans/2026-04-15-MASTER-ai-autonomous-flywheel.md繼承核心發現