跳转至

阶段二十:Agent 运行态势与四层闭环

阶段状态:进行中

计划状态:实施中

当前工作包:P20-5-11 生产页面与 API 最终回读(已完成)

用户已确认按本计划开始执行。P20-0 至 P20-4 已完成本地门禁、精确 SHA 构建、RR 生产部署、生产 API 回读,以及使用临时管理员 API Key 的公网桌面与移动端浏览器验收。

📌 结论摘要

P20 第一版在 Console 中建立“Agent 运行态势”只读总图:把原本分散在节点、网络、CPA、Memory、Web Fetch、Web Search、规则、技能和工具配置中的状态,组织成一张人能看懂的跨域关系图。页面回答三个问题:整个 Agent 系统现在处于什么状态、哪个节点或服务影响了结果、一次对话的四层路由闭环断在什么位置。

后端已实现管理员只读聚合、逐源状态、新鲜度判断和脱敏投影;前端已实现四域关系图、六阶段闭环、节点矩阵、异常列表、30 秒刷新和移动端布局。真实 101 数据投影已验证:101 基线与 Memory 回写可见;明确主机离线的节点显示“离线”并从异常列表排除,在线节点的工具断点仍显示“需关注”;Web Fetch 与 Web Search 只有健康响应、没有最近真实调用证据时显示“未验证”。审计发现的具体故障仍只展示,不在本阶段修复。

状态语义规则:主机离线是可达性状态,不是当前可执行的处理项,因此单独显示“离线”;只有主机在线后,客户端心跳、中央路由、工具目录、规则技能和四层闭环证据才参与“需关注、阻塞、未验证或已过期”的处理判断。节点恢复在线后自动重新计算,不保留离线期间的旧问题作为当前待处理项。

用户在生产截图评审后要求关系图缩小并补充颜色说明。当前桌面端关系图最大宽度已限制为 960px 并居中,图下新增五项图例:正常、需关注、阻塞、未验证、已过期;图例同时写明每类含义,不再只依赖颜色。

用户进一步确认了 P20-5 的中央管理目标:规则和技能在 Memory 中统一管理,通过不可变 Release 分发到各节点的 Codex 运行时镜像,再由 Hook 在 turn 内验证实际加载。P20-4 的现有页面保留,P20-5 完成后再把中央期望、节点安装和 turn 运行统一展示。

🗂️ 目录

🧾 计划状态与工作边界

项目 当前值 依据 影响 / 下一步
当前阶段 P20:Agent 运行态势与四层闭环 docs/plans/state.json P20-4 已发布,P20-5 进入实施
阶段状态 进行中 P20-4 已完成,P20-5 分发器与中枢面板已落地 冲突资产对账完成后评估阶段出口
计划状态 实施中 用户确认按 P20-5 计划开始实施 P20-4 保持已发布,P20-5 按工作包推进
当前工作包 P20-5-11 生产页面、API、节点心跳和网页能力表格最终回读 P20-5 工作包 已完成管理员 API 与真实浏览器双重验收;RR 两容器目标 SHA 5e1dd061 且健康;8 个客户端均返回 web_capabilities;OfficeSummer 离线单独保留
本轮修订 P20-5-12 运行态势对象三分与证据口径收敛 2026-11-04 用户评审确认三分类方案 代码与本地测试完成;生产部署、节点心跳刷新和 Memory 项目侧契约仍未收口,详见文末同名章节
P19 临时收口、可重启,不宣称完整验收 completed-phase-19-temporary-closure.md 未来重启 P19 时从原计划继续,不与 P20 混写
当前实现 本地门禁、同 SHA 镜像构建、RR 主生产部署和最终页面/API 验收通过 管理员会话 role=admin;runtime-status HTTP 200;真实浏览器确认网页能力表格 P20-5-11 完成;OfficeSummer 仍按离线状态观察

P20-4 第一版不包含:修复审计异常、更新节点规则、发布技能、扩散 MCP、重启中心服务、修改 Memory 数据、建立第二套告警系统、恢复旧治理 API/observer、提供页面写操作。P20-5 只新增受控的资产 Release 与节点分发,不恢复旧治理系统;运行态势页面继续只读。

🎯 目标、成果与验收契约

背景

“从节点到 Agent”的讨论先出现了中央服务部署、Agent 客户端安装和 Agent 对齐配置。现在状态域进一步收敛为:中央模型路由、中央服务、Agent 客户端、中央配置与节点镜像。Memory 是规则和技能的中央管理权威,Codex 节点保存经过验证的本地运行时镜像;101 是第一个完整基准和分发 canary,但不再是分散手工配置的终点。Memory 历史记录 6ed6e777d30cb98c1acbc585e489cfe05adc2485e0fcb0ed88c1721f127fadd6 与 6377731c06a6a199c0f8d56d24ab7ebe3b5a9952dacd98b2114a0a0ddd5b88eb 是本计划的讨论依据,但历史快照不能直接代替当前实时状态。

另一条讨论线是配置更新与扩散:Memory 作为中央编辑和版本管理面,发布不可变 Release;101 先作为 canary 接收并验证,通过后再向其他 Codex 节点分发。P20-5 不仅要展示中央资产,还要展示 Release、节点安装、本地镜像和 turn 实际加载的完整状态链。

目标与非目标

类型 本阶段定义 下一步
目标 1 形成四个状态域的跨域总图 中央配置域显示期望、安装、运行三层证据
目标 2 显示四层功能路由闭环的断点 区分规则、Memory Bootstrap、技能、工具、执行/验证、Memory 回写
目标 3 把 Memory 中央资产、Release、节点分发、Codex 镜像和 Agent 客户端连成关系网 主机在线、Agent 在线和规则/技能已加载分开
目标 4 动态只读刷新,未知不得显示为正常 后续处置回到已有管理页面
非目标 立即修复审计发现的问题 等用户评审后另立实施工作包

🧱 技术栈与架构选型

P20 采用“Memory 中央管理 → 不可变 Release → 节点分发与本地镜像 → turn 运行证据 → 只读状态投影”的结构。浏览器不直连 Tailnet 服务,不持有内部凭据;API Gateway 只负责查询和归一化,不成为第二控制面。Memory 管理资产,节点分发器负责安装,Codex Hook 负责运行时校验,P20 页面只展示三种状态之间的关系。

flowchart TB
    Author["Memory 中央管理\n规则集 / 技能资产 / 平台 / 范围"] --> Release["不可变 Release\n版本 / SHA256 / 目标 / dry-run"]
    Release --> Distributor["节点资产分发器\n拉取 / 校验 / 原子安装 / 回执"]
    Distributor --> Mirror["Codex 运行时镜像\nAGENTS.md / 受管 SKILL.md"]
    Mirror --> Hook["Codex Hook\n规则匹配 / 技能正文校验 / RouteContext"]
    Hook --> Runtime["Turn 实际运行\n选择 / 工具 allowlist / 执行验收"]
    Release --> Gateway["API Gateway:只读聚合"]
    Distributor --> Gateway
    Hook --> Gateway
    Runtime --> Gateway
    Gateway --> Console["P20 状态投影\n中央期望 / 节点安装 / Turn 运行 / 漂移"]

架构取舍

方案 可维护性 部署复杂度 性能与扩展性 结论
Console 直接访问每个内部服务 低,前端重复理解协议 高,需暴露多个边界 难统一缓存与状态语义 不采用
新建独立治理/observer 系统 低,会形成第二事实源 高,增加服务、数据和回退面 初期灵活,长期漂移 不采用
API Gateway 只读聚合 + Console 投影 高,沿用现有边界 中,只增加一个查询面 可按 TTL、并发和新数据源扩展 计划采用

🧩 分布式底座接入声明

本阶段接入现有 Console、API Gateway、CPA、Memory、Web Fetch、Web Search、节点登记与 Agent 心跳。不新增 Nomad Job、Worker 或数据库;API Gateway 在进程内并发执行有界只读查询并做归一化,Console 只消费一个管理员接口。

使用层 计划判断 依据与边界
Network 沿用现有内网与受控服务访问 浏览器不直连 Tailnet 服务;不新增公网入口
Nomad 本阶段不接入 不创建 Job,Nomad 仍是唯一任务调度器
Compute 复用 API Gateway 进程内有界查询 不新增 Worker、定时任务或独立 observer
Storage 本阶段不新增 不建立新数据库或复制现有业务状态
Observability 只读复用已有健康、心跳和真实调用证据 只展示,不执行修复或形成第二事实源
Adapter 当前不新增 查询与归一化保持在 API Gateway 内,不改变 Runtime Adapter 边界
凭据 保留在现有服务端 浏览器、模型、普通 Agent 和 MCP 不获得基础设施凭据
生命周期 查询、缓存、刷新和过期状态均有界 故障仅标记未知/过期,不触发配置变更

🧩 四个状态域

四个状态域是“观察对象的分类”,不是四层闭环的替代物。每个状态域均应显示一个人类可读结论、影响范围、最近真实验证和下一处理入口;缺少证据时显示“未验证”或“过期”,不能显示为绿色正常。

状态域 要回答的问题 计划显示 状态边界
中央模型路由 CPA 是否可用,Agent 是否有可用模型入口,以及每个客户端是否正确指向它 CPA 健康、CPA 版本、中央模型目录、逐节点 config.toml 路由、模型目录指纹、真实 /models 探测 CPA 健康不等于每个 Agent 客户端配置正确;客户端目录与 CPA 实际目录不一致时显示“需关注”
中央服务 Memory、Web Fetch、Web Search 等服务是否存在且可验证 服务健康、服务版本、工具面、最近真实调用、客户端连接 configured 不等于 verified;服务健康不等于客户端在线
Agent 客户端 哪些节点的 Agent 真正在线 主机在线、Agent 心跳、版本、节点角色、闭环摘要 主机在线与 Agent 在线分列显示
中央配置与节点镜像 Memory 发布内容是否安装到节点,并被当前 turn 实际加载 Release/版本/哈希、Codex 版本、Memory 版本、CPA 版本、节点安装回执、Codex 镜像、规则/技能选择与加载 中央资产存在、节点已安装、当前 turn 已加载是三件事;版本一致不能替代功能验证

状态词

页面用语 含义 颜色语义
正常 当前证据完整,最近验证通过 绿色
需关注 有降级、部分缺失或客户端不一致 黄色
阻塞 必需链路断开,当前 Agent 无法完成闭环 红色
未验证 配置存在或接口可读,但没有足够真实调用证据 灰色
过期 曾经有证据,但超过新鲜度窗口 紫灰色,不能当正常

🔁 四层功能路由闭环

四层功能路由闭环描述一次对话如何从用户意图走到可验证结果。严格说,运行路径包含意图解析、执行和验证等状态,因此页面将四个核心配置/能力层显示为四层节点,并把意图、执行/验证作为连接节点。契约依据是 /root/.codex/docs/rule-layer-contract.md:规则、技能、工具和 Memory 必须分别有权威源、运行时对象和真实生效证据。

flowchart LR
    Intent["用户意图"] --> Rules["① 规则层\n规则授权 / 范围 / 禁止项"]
    Rules --> Bootstrap["Memory Bootstrap\n历史事实 / 候选 / 新鲜度"]
    Bootstrap --> Skills["② 技能层\n选择 / 加载 / 版本 / SHA256"]
    Skills --> Tools["③ 工具层\ntools/list / schema / allowlist"]
    Tools --> Execute["执行与验证\n真实调用 + 独立回读"]
    Execute --> Memory["④ Memory 层\n观察 / 摘要 / outbox 回写"]
    Memory -. "下一 turn 的可验证上下文" .-> Bootstrap
    Rules -. "缺证据" .-> Blocked["BLOCKED:停止新外部调用"]
    Skills -. "未加载或冲突" .-> Blocked
    Tools -. "未枚举 / 不在 allowlist" .-> Blocked
    Execute -. "结果未验收" .-> Blocked

四层与四域的关系

视角 关注对象 典型问题 页面关系
四个状态域 系统资产和部署关系 中央服务是否健康?哪个 Agent 客户端离线?中央 Release 与节点镜像是否一致? 上方总览、域卡片、节点矩阵
四层路由闭环 当前 turn 的功能链路 规则是否注入?技能是否加载?工具是否进 allowlist?Memory 是否回写? 中部横向链路、断点标记
节点到 Agent 分发后的落地对象 Release 是否安装到该节点?本地镜像是否匹配?turn 是否真实加载? 节点 × 域矩阵、规则技能中枢

核心关系是:状态域告诉人“系统哪里有问题”,四层闭环告诉人“对话为什么因此运行不了”,节点映射告诉人“问题影响哪个 Agent”。缺少任一视角,页面都只能显示孤立的健康灯,不能形成可处置的问题定位。

🧩 节点、配置与中心服务关系

配置更新与扩散主线

flowchart LR
    Memory["Memory 中央资产\nRule Sets / Skill Assets"] --> Release["不可变 Release\n版本 / 平台 / SHA256"]
    Release --> Canary["101 canary\n安装 / 回退 / 真实 turn"]
    Canary --> Fleet["其他 Codex 节点\n按平台安装"]
    Fleet --> Mirror["本地运行时镜像\nAGENTS.md / 受管 SKILL.md"]
    Mirror --> Runtime["Hook RouteContext\n实际加载 / allowlist"]
    Runtime --> Projection["一致 / 预期差异 / 等待安装 / 漂移 / 阻塞"]
    Projection --> Console["P20 只读展示"]

P20 需要同时记录三件事:资产是否存在、运行时是否加载、任务是否真实使用。只能证明第一件事时,状态为“未验证”;节点与 101 不同但属于登记的 Windows 或平台差异时,状态为“预期差异”;没有登记的版本或哈希不一致时,状态为“漂移”;完全没有证据时,状态为“未知”。历史记录中出现的节点名称、版本和配置不能直接当作今日状态。

中心服务关系

flowchart TB
    Agent["Agent turn"] --> CPA["CPA:模型路由"]
    Agent --> Memory["Memory:bootstrap / recall / writeback"]
    Agent --> Fetch["Web Fetch:页面抓取"]
    Agent --> Search["Web Search:搜索发现"]
    Agent --> Other["其他已登记 MCP / CPA 服务"]
    CPA --> Providers["模型与 Provider"]
    Memory --> Relation["历史事实、规则候选、技能候选、工具观察"]
    Fetch --> Context["抓取正文"]
    Search --> Context
    Context --> Verify["结果验证"]
    Verify --> Memory

中心服务必须分别显示“已配置、已发现、已验证、实际调用、最近失败”这些不同证据层级;不能因为服务端口存在就判为 Agent 工具可用,也不能因为一次 Web Fetch 成功就假设 Web Search 已验证。

中央模型路由的节点客户端子层

中央模型路由域不是只显示 CPA 服务本身。它同时显示“CPA 中央模块”和每一个 Codex 客户端的路由配置,形成“中央服务 → 客户端配置 → 本地目录 → 真实模型目录探测”的完整关系。

检查对象 页面显示 真实证据 状态规则
中央 CPA CPA 中央路由(101)、模型数量、健康状态 101 healthz 与 /v1/models 中央服务不可用时为阻塞/需关注
客户端路由配置 provider、目标中央路由、模型名、Responses 协议 各节点 config.toml 的脱敏快照 未上报为未验证,目标不是当前 CPA 为阻塞
本地模型目录 目录存在、目录数量、目标模型是否存在 model_catalog_json 文件与 SHA256 短指纹 DeepSeek 目录缺失、无法解析或目标模型缺失为需关注
目录与中央一致性 本地目录数量与 CPA 实际 /models 数量 节点心跳同时上报本地目录和 /models 探测 数量不一致为需关注,防止客户端拿到过期或额外目录
节点运行新鲜度 最近一次路由探测时间 Memory metrics 心跳 超过新鲜度窗口为已过期,不画成正常
运行版本对齐 Codex、CPA、Memory 的版本是否清楚且符合基线 Codex 客户端 --version、CPA healthz/version 字段、Memory system status 版本缺失为未验证;在线节点版本不一致为需关注;版本一致仍必须保留真实调用证据

本次真实盘点发现:101 与 CPA 都返回 5 项模型;102、RR、Home、Summer 原先本地目录为 10 项,虽然都能访问 CPA,但目录与中央实际目录不一致。按 101 canary 规则,已将 101 的正式目录分发到四台在线节点,保留原文件备份;随后五台在线客户端均回报“CPA 路由正常、目录 5 项、目标模型存在、真实 /models 探测通过”。OfficeSummer 当前离线,页面保持未验证,不计入已同步。

🖥️ 只读页面规划

导航归组

页面不再作为一个孤立入口随意插入导航,而是把现有散落入口整合成一个“Agent 运行态势”组,形成同一组资料和同一观察语境。建议组内顺序如下:

Agent 运行态势
├── 总图:Agent 运行态势与四层闭环
├── 节点与 Agent 客户端
├── 中央服务与工具
├── CPA 模型路由
├── Memory 服务
├── 网络与连接态势
└── 告警与异常

现有页面不立即删除、不复制成第二套管理页;只调整导航归组和入口名称,具体页面仍承担原职责。新增总图只读,不提供重启、更新、发布、写 Memory、改规则、确认告警或同步节点按钮。

页面从上到下的结构

flowchart TB
    Header["页面标题 + 总体状态 + 最近刷新"] --> Summary["总体摘要:影响节点 / 状态新鲜度"]
    Summary --> Relation["四域关系图:中央路由 ↔ 中心服务 ↔ Agent ↔ 101 基线"]
    Relation --> DomainCards["四个状态域卡片"]
    DomainCards --> Loop["四层路由闭环:断点高亮"]
    Loop --> Matrix["节点 × 状态域 × 闭环矩阵"]
    Matrix --> Issues["需要关注:原因 / 影响 / 已有处理入口"]

用户看到的是“正常、需关注、阻塞、未验证、过期、离线”和人类可读原因;原始哈希、端点、调用 ID 和技术日志只作为可折叠证据,不作为首屏主语言。主机离线时只显示“离线”,不把该节点列入在线待处理问题;节点重新上线后再恢复客户端、路由、工具和规则状态判断。节点矩阵使用独立列显示客户端、主机、Agent、版本、中央路由、模型、API、规则、技能、工具、Memory 和结论,避免把同一信息重复写进摘要。中央模型路由域使用同样的表格结构,版本、模型和 API 不再从长文本中解析。所有状态卡必须在桌面和移动端保持稳定尺寸,移动端可纵向排列,不产生页面级横向滚动。

📊 数据、状态与更新策略

只读聚合契约

查询面固定为 GET /api/agent/runtime-status,需要管理员只读会话。返回结构已冻结为以下对象:

对象 内容 必须保留的证据
overall 总体状态、影响节点数、刷新时间、最旧数据年龄 状态计算规则和数据新鲜度
domains 四个状态域的摘要与状态 每个域的来源和最近验证
clients 节点、主机状态、Agent 状态、版本、闭环摘要 主机与客户端分开的证据
clients[].model_route 每个 Codex 客户端的中央路由配置与探测结果 目标路由、模型、协议、目录数量、目标模型存在性、短指纹、最近探测
loop 规则、Bootstrap、技能、工具、执行/验证、回写状态 当前 turn 或最近验证的上下文
rule_skill_authority Memory 中央期望、节点安装、turn 运行和统一裁决 Release 版本/hash、节点回执、规则/技能加载摘要
issues 人类可读问题、影响范围、处理入口 首次/最近观测和状态来源
sources 数据源名称、状态、时间、新鲜度 不暴露密钥、内部凭据和不必要地址

动态刷新与过期

页面每 30 秒刷新只读聚合结果,离开页面时停表,回到页面立即刷新。API 默认使用 15 秒缓存、5 秒单源超时和 1800 秒证据新鲜度;各数据源独立失败、独立标注,不用一个失败覆盖所有域。刷新失败时页面明确显示“状态暂不可读”,不把旧结果继续画成正常。

现有审计事实如何进入计划

CPA 的实际健康路径已验证为 /healthz,不能猜用 /health;Memory 总体健康与客户端心跳必须分开;Web Fetch 要同时看服务状态和真实调用;Web Search 区分 configured、verified、blocked;101 的规则、四层契约和 Memory Hook 哈希可作为基线卡片。它们都是页面设计的输入和验收样本,不是 P20 当前要处理的故障清单。

🛠️ 工作包与依赖

工作包 目标 前置依赖 预期成果 当前边界
P20-0 计划评审与架构冻结 冻结范围、图、状态词、只读边界和导航归组 用户确认“按照这个计划开始执行” 详细计划、Mermaid 图和未决项记录 ✅ 完成
P20-1 数据源盘点与只读契约 将现有来源映射到四域和闭环 P20-0 确认 GET /api/agent/runtime-status、逐源状态和脱敏测试 ✅ 完成
P20-2 Console 信息架构与跨域总图 形成可扫读的总览、卡片、矩阵和异常列表 P20-1 契约冻结 #agentRuntime、动态关系图、六阶段闭环和移动端契约 ✅ 完成
P20-3 101 基线与节点扩散可视化 显示 101 基线和在线 Agent 的规则上下文覆盖 P20-1、真实证据可用 101 基线卡、扩散覆盖、证据过期和未知语义 ✅ 完成
P20-4 实施、测试与只读发布 完成完整门禁、精确 SHA 发布和公网回读 P20-0 至 P20-3 完成 代码、测试、生产只读页面、回退材料 ✅ 已完成
P20-5 规则与技能中央管理 Memory 管理资产,节点接收运行时镜像,P20 展示三层状态 P20-4 完成;用户确认 P20-5 契约 Release、分发器、Hook 证据、API v2、Console 中枢 实施中:101 对账与回执完成,跨节点安装待正文模型

依赖顺序固定为 P20-0 → P20-1 → P20-2/P20-3 → P20-4 → P20-5。P20-5 内部按 Release → 101 canary → Hook 证据 → API/Console → Fleet rollout 串行推进。

🧭 P20-5 规则与技能中央管理计划

目标修正

P20-5 的目标是让 Memory 成为规则和技能的中央管理权威,让各节点的 Codex 获得经过验证的本地运行时镜像。它不把 Memory 变成 turn 内实时内容注入器,也不允许页面直接修改 Codex 规则或技能。

推荐链路如下:

flowchart LR
    Author["Memory 中央管理\n规则集 / 技能资产"] --> Release["不可变发布清单\n版本 / 平台 / 范围 / SHA256"]
    Release --> Distributor["受控节点分发器\n下载 / 校验 / 原子安装 / 回执"]
    Distributor --> Mirror["Codex 本地运行时镜像\nAGENTS.md / 受管 SKILL.md"]
    Mirror --> Hook["Codex Memory Hook\n本地读取 / RouteContext 发布"]
    Hook --> Evidence["Memory 客户端证据\n本轮规则/技能加载摘要"]
    Release --> Gateway["API Gateway"]
    Distributor --> Gateway
    Evidence --> Gateway
    Gateway --> Console["P20 规则与技能中枢"]

选择本地镜像而不是每个 turn 直接从 Memory 拉取技能和规则,原因是 Codex 的规则、技能和工具目录在 turn 开始前已经进入运行时;本地镜像可离线、可复现、可按 SHA 回退,也不会让 Memory 网络故障直接变成每个 turn 的前置失败。

当前真实状态

对象 实测事实 当前结论
Codex 本地规则 全局和 AgentMeshOS 项目 AGENTS.md 存在,override 不存在 101 本地规则源可用
Codex 本地技能 三个技能根目录共 35 个 SKILL.md,去重 32 个技能名 本地已有完整技能集合
Memory 规则资产 5 个 Rule Set、40 条规则;1 个规则集来源不可用 中央资产已存在,但资产质量需单独核对
Memory 技能资产 33 个技能,32 个启用、1 个停用 中央资产已存在
Memory 技能目录 /api/skills/catalog 当前返回 20 项 目录暴露数和资产库存数不是同一口径
101 最近 turn rule_count=6、本轮技能候选 0、rule_source_mismatch=true 规则源与 Memory 期望不一致,中枢判定阻塞
RouteContext ready、TOOLS_READY、published=true、stale=false 当前 turn 路由已发布
技能加载 skills_loaded=0、tool_allowlist_count=2、route_context_published=true 本轮没有选择技能,工具白名单已生成
Memory 全局规则副本 codex-global-resident 指向 101 的 AGENTS.md,当前副本哈希与本地文件不一致 中央资产与本地运行时镜像存在漂移
中央分发链路 没有活跃的 skill_sync、asset_sync 或 global_rules 客户端;import_codex_assets.py 的方向是“本地导入 Memory”,旧 asset sync 只剩 .bak “在 Memory 新增后自动到所有 Codex”目前尚未实现

依据是 /api/rules、/api/skills、/api/skills/catalog、/api/system/capabilities、/api/system/clients、本地技能目录和最近 Hook 调试记录。旧治理 API、observer 和旧资产同步 timer 已退役,不得作为本计划的实现基础复活。

权威与状态模型

层级 权威 记录内容 不能证明
中央期望状态 Memory Release 规则/技能 ID、版本、平台、目标范围、SHA256、启用状态 不能证明节点已经安装
节点安装状态 节点分发器 已安装版本、目标路径、原子替换结果、回执时间、last-known-good 不能证明当前 turn 已加载
turn 运行状态 Codex Hook 本地规则源、技能候选、技能正文校验、RouteContext、allowlist 不能证明中央资产仍是最新版
治理结论 API Gateway 归一化 aligned、expected_difference、pending、drift、blocked、unknown、stale 只展示,不代替实际修复

规则和技能的中央管理对象分开建模:

对象 建议目标 所有权标记 回退方式
全局规则 Release 平台对应的 AGENTS.md 完整镜像 rule set ID、version、platform、SHA256 原子替换回上一 Release
技能 Release 节点共享技能目录中的受管技能目录 .agentmeshos-managed.json 清单和技能 version/hash 按上一清单恢复或删除受管项
项目规则 项目仓库 AGENTS.md 项目 ID、范围、版本 不自动覆盖用户项目规则
系统/插件技能 不纳入中央改写 只读 保留原厂或插件自身升级路径

数据契约

API Gateway 为每个 Agent 返回 rule_skill_authority_v1,原始正文、完整路径和原始哈希不进入浏览器:

{
  "status": "healthy",
  "classification": "aligned",
  "desired": {
    "rules_version": 45,
    "skills_release": "release-2026-10-28.1",
    "rule_sets": 5,
    "skill_assets": 33,
    "source_fresh": true
  },
  "applied": {
    "rules_version": 45,
    "skills_release": "release-2026-10-28.1",
    "last_applied_at": 1793144000,
    "last_result": "ok"
  },
  "runtime": {
    "rule_candidates": 6,
    "rule_sources_loaded": true,
    "rule_source_mismatch": false,
    "skill_candidates": 5,
    "skills_selected": 5,
    "skills_loaded": 5,
    "required_skills_missing": 0,
    "skill_warnings": 0,
    "selection_status": "selected",
    "tool_allowlist_count": 5,
    "route_context_status": "ready",
    "route_context_published": true,
    "snapshot_stale": false
  },
  "issues": []
}

classification 与 status 分离:平台差异或未选择可选技能可以标为 expected_difference,仍显示正常;已发布但节点尚未拉取标为 pending;同一版本出现不同内容才是 drift。

发布与分发

  1. Memory 规则/技能编辑后先生成 dry-run manifest,列出受影响平台、节点、目标文件和变更类型。
  2. 正式发布生成不可变 Release,原资产可保留历史版本,节点只能消费完整 Release。
  3. 节点分发器使用受控只读凭据或 Tailnet 身份拉取,校验 Release、平台、目标和 SHA256。
  4. 先写临时目录,校验后原子替换;规则文件与受管技能清单分别保存 last-known-good。
  5. 安装后回读版本、hash 和文件可见性,再向 Memory 的节点资产状态上报 applied。
  6. Codex 下一 turn 由 Hook 读取本地文件并发布 RouteContext;中央页面用它区分“安装成功”和“真实加载成功”。

首版不直接删除无法映射的本地技能,也不接管 .system 或插件技能。受管技能若被删除,只清理 .agentmeshos-managed.json 中登记的所有项。

工作包

工作包 目标 主要改动 退出条件
P20-5-0 语义与发布契约 冻结中央期望、节点安装、turn 运行三态 Memory asset ID/version/hash、平台差异、expected_difference 定义 用户确认路径、所有权和回退规则
P20-5-1 Central Release 把规则/技能资产组织为不可变 Release Memory release manifest、dry-run、历史版本 能列出 101/Windows 的目标与差异
P20-5-2 Node Asset Sync 建立单节点受控分发器和原子安装 拉取、校验、安装、回执、last-known-good 101 canary 安装与回退通过
P20-5-3 Hook 证据 发布真实规则/技能加载摘要 mismatch、skill candidate/selected/loaded、required、warnings、allowlist 每个 turn 都有完整脱敏摘要
P20-5-4 API v2 聚合 desired/applied/runtime 三层 agent_runtime.py schema v2、兼容 v1 缺失字段 单测覆盖全部 classification/status
P20-5-5 Console 增加“规则与技能中枢”只读面板 来源、安装、运行、问题、下一步 桌面/390px 可读,不出现正文和路径
P20-5-6 Fleet Rollout 101 完成后扩展其他 Agent 节点 平台映射、逐节点 canary、失败关闭 至少一个非 101 Agent 安装和真实 turn 通过
P20-5-7 Model Route Clients 把中央 CPA 与各 Codex 客户端配置、目录和真实探测纳入中央模型路由域 心跳路由快照、客户端目录一致性、节点矩阵和异常项 在线节点回报目标路由、模型、协议、目录和 /models 探测;离线节点保持未验证
P20-5-8 Runtime Version Alignment 把 Codex、CPA、Memory 版本纳入四域对齐对象 版本来源、基线版本、节点版本差异、未上报状态和页面摘要 版本可见、缺失不伪装正常、版本一致不替代功能验收
P20-5-9 Web Capability Routing 在 Agent 客户端域展示中央 Fetch、本地 Fetch 兜底、中央 Search 和浏览器升级能力 心跳本地依赖盘点、API web_capabilities、Console 网页能力表格 本地门禁、浏览器契约和 API 单测通过;代码进入可发布镜像
P20-5-10 RR Primary Release 将 Console/API 镜像部署到 RR 主生产 console-site、api-gateway 同 SHA 发布、RR 健康和回滚材料 ✅ 完成:RR 运行镜像 SHA 等于目标提交;两个服务健康
P20-5-11 Production Readback 验证主生产页面和真实状态接口 管理员会话、runtime-status、网页能力表格、客户端心跳和移动端页面 ✅ 完成:管理员 API 200;8 个客户端带 web_capabilities;真实浏览器显示网页能力路由表格;OfficeSummer 单独离线

页面规划

不新增第五个顶层状态域;“101 对齐配置”内部增加子项,并在四个状态域之后增加独立只读面板:

区域 内容
中央期望 规则 Release、技能 Release、平台、目标节点、发布时间和新鲜度
节点安装 已安装版本、最近安装时间、last-known-good、失败节点
Turn 运行 规则源匹配、技能候选/选中/加载、必需技能缺失、RouteContext、allowlist
统一裁决 一致、预期差异、等待安装、漂移、阻塞、未验证、过期
需要关注 按影响列出节点、问题、影响范围和下一步入口

规则与技能分别显示,不合并成一个数字。页面首屏不显示完整 SHA、文件路径、规则正文或技能正文。

状态与告警

场景 分类 健康状态 是否告警
中央 Release 与节点安装一致,turn 已加载 aligned 正常 否
Windows 使用登记的平台差异 expected_difference 正常 否
中央发布成功,节点尚未拉取 pending 需关注 超过窗口后告警
本地受管文件被手工修改 drift 阻塞 立即告警
规则源缺失、必需技能缺失或 hash 不一致 blocked 阻塞 立即告警
只有 Memory 资产,没有节点安装证据 unknown 未验证 首个观察窗口后提醒
安装或 turn 证据超时 stale 已过期 立即告警

可选技能未被选择、Memory catalog 与总资产数量不同,不单独告警;但节点本地模型目录与 CPA 实际 /models 目录不一致属于客户端路由漂移,必须显示“需关注”。

验收

验收项 方法
新增技能可下发 在隔离 Memory 测试空间生成技能 Release,101 canary 安装并由下一 turn 真实加载
修改全局规则可下发 修改测试规则 Release,101 原子更新 AGENTS.md,回读版本/hash 和实际 prompt
平台差异 Windows 安装同一 Release 的 T2 变体,状态显示预期差异
负向漂移 手工篡改受管技能,记录 drift 并拒绝宣称 loaded
负向缺失 删除必需技能候选对应文件,RouteContext 进入 BLOCKED
回退 恢复上一 Release,规则、技能和 turn 状态均回到 aligned
节点离线 中央显示 pending,不把离线节点标成中央发布失败
页面只读 无发布、安装、删除、编辑按钮,原管理入口保留

回退

中央 Release 只追加不覆盖;节点保留上一 Release 和 .agentmeshos-managed.json。回退时分发器先安装上一版本、校验 hash、重启/新建 Codex turn,再确认 RouteContext ready。API 与 Console 可独立回滚,不影响已安装本地文件;Memory Release 不删除时可直接重新发布。

仍未决

编号 决策 结论
D7 中央技能统一安装到哪个目录 已定:Codex 技能根 + 受管标记;未受管同名项不覆盖
D8 全局规则采用整文件发布还是受管块 已定:整文件 Release + last-known-good,默认不写
D9 P20-5 首批范围 已定:101 canary,冲突对账通过后再扩
D10 发布是否需要人工审批 已定:不引入审批;用只读计划、失败关闭和显式写入开关兜底
D11 跨节点安装所需的完整 SKILL.md 原文 待实现:Memory 当前只存正文和原始文件哈希;建议新增 raw_text 字段并在导出返回,分发器按原文安装

🧪 P20-5 本轮实施记录

已完成

交付物 证据 影响 / 下一步
节点资产分发器 scripts/maintenance/agentmeshos-agent-assets-sync.py:plan / apply / rollback / status,原子写入、受管标记、last-known-good、目标越界阻断 默认只读;规则写入需显式 --apply-rules
分发器回归 scripts/maintenance/tests/agent-assets-sync-test.py:过滤、幂等、冲突保护、外部技能根、漂移修复、回退、越界、受管删除 已接入 scripts/ci/run-local-tests.sh
Hook 运行证据 备份 codex-memory-hook.py.bak-20261028-p20-assets(SHA256 215c83eb…),现行 Hook 为 cc5a7f65…;新增规则源、技能选择/加载、必需缺失、告警数、allowlist、RouteContext、资产 Release 摘要 规则匹配支持跨平台路径;插件快照差异不再阻断 turn
中枢 API rule_skill_authority 返回 desired / applied / runtime、aligned/pending/blocked/unknown/stale 分类与问题项 浏览器只看到计数、短指纹和人类可读结论
Console 面板 #agent-runtime-authority 四张只读卡片,覆盖中央期望、节点安装、最近一次 Turn、统一裁决 桌面四列,640px 以下单列;不出现正文、绝对路径或完整哈希
工具与 MCP 目录 #agent-runtime-tools 逐节点显示核心能力的配置、依赖安装和运行证据 Playwright、Kimi WebBridge、CUA、Memory、Web Search、Web Fetch、Context7 不再隐藏在四层摘要里;可选 MCP 自 2026-11-04 起单独进入“可选扩展”表
工具目录实测 101 的 Playwright/WebBridge/CUA 均可用;102/RR/Summer 的 Playwright 已安装并配置为本地 cli.js;Summer CUA 已安装但 Session 0,WebBridge 未安装 配置、安装和运行状态已分开显示;OfficeSummer/Home 待在线复验
部署工作流 reusable-rr-deploy.yml 的资源下载增加 6 次有界重试,生产部署门禁校验该契约 消除 release 资产可见性滞后导致的假失败邮件
全局规则 /root/.codex/AGENTS.md 新增“GitHub 远程同步与 Action 闭环(强制)”,备份为 .bak-20261028-github-action-gate 规则从 v45 升到 v46,并已回灌 Memory
中央模型路由客户端态势 agentmeshos-agent-assets-sync.py 心跳新增无凭据 model_route 快照;API 将其挂入中央模型路由域和客户端矩阵 101、102、RR、Home、Summer 均指向 CPA /v1,Responses 协议,模型目录 5 项,真实 /models 探测通过;OfficeSummer 离线
运行版本对齐 API 新增 versions 和“运行版本对齐”子项;Codex 版本来自客户端 --version,Memory 版本来自实时 system status,CPA 版本只接受 health/version 字段 当前 Codex 为 0.163.0,Memory 为 12.1.1;CPA healthz 只返回 status=ok,因此 CPA 版本显示未上报,不把它当作故障
路由目录漂移修复 101 正式目录与 CPA 实际目录均为 5 项;102、RR、Home、Summer 原为 10 项 已按 101 基准分发 5 项目录,逐节点备份与 SHA256 校验后,五台在线节点回报一致
Home 心跳根因修复 Home 计划任务原先未显式传 --codex-home,导致任务环境读取错误目录 已补充显式 Codex Home 与 Agent 类型参数;任务结果回读为 0,路由状态恢复正常
网页能力路由子层 原页面只展示中央 Web Fetch/Web Search,未把节点本地 Fetch 兜底与 Playwright/WebBridge/CUA 分层呈现 API 新增逐节点网页能力契约;页面独立显示中央 Fetch、本地 Fetch 兜底、中央 Search 和三种升级工具,中央正常不再代表节点本地兜底已验证
状态投影去重与统一 Memory MCP 别名、工具目录与网页能力表、模型路由域与节点矩阵存在重复展示 后端统一 MCP 别名;工具目录与网页能力表共用中文状态单元格;节点矩阵移除重复的路由/模型/API列,模型路由域保留唯一明细

双源裁决流程

flowchart LR
    Central["Memory 中央资产\nRule Sets / Skill Assets"] --> Release["不可变 Release\ncontent_digest / 版本 / SHA256"]
    Release --> Plan["节点只读计划\n安装 / 更新 / 一致 / 冲突 / 外部提供"]
    Plan -->|无冲突| Apply["原子安装 + 受管标记\nlast-known-good"]
    Plan -->|冲突| Reconcile["人工对账\n确认以哪一侧为准"]
    Apply --> Hook["Hook 校验本地正文\n规则源 / 技能 SHA / RouteContext"]
    Hook --> Verdict["统一裁决\naligned / pending / drift / blocked / unknown / stale"]
    Reconcile --> Central
    Verdict --> Console["P20 规则与技能中枢"]

状态判定

分类 触发条件 页面状态 是否告警
aligned 中央内容指纹与节点安装回执一致,本轮规则源与必需技能校验通过 正常 否
pending 节点有安装回执,但内容指纹落后于中央 需关注 是
blocked 规则源哈希不一致、必需技能缺失或 RouteContext 未发布 阻塞 是
unknown 只有中央资产,没有节点安装证据 未验证 否,首个窗口后提醒
stale 安装回执超过新鲜度窗口 已过期 是

101 只读计划实测

命令:python3 scripts/maintenance/agentmeshos-agent-assets-sync.py plan --codex-home /root/.codex(--memory-base 取自 Hook 现用地址,不写入文档)。

阶段 结果 说明
对账前 8 个同名技能内容不一致、9 个由其他技能根提供、1 条规则不一致 哈希按“正文”比较时误报;实际是 Memory 只保存正文、原始文件哈希在 metadata
对账动作 回灌 16 个本地技能,重建 codex-global-resident;新增全局 Action 闭环规则后为 v46(SHA256 5e21513a…) Memory 中央副本与 101 运行时一致
对账后 8 个本地受管技能一致、9 个由 ~/.agents/skills 提供且一致、1 条规则一致、0 冲突 只读计划 blocked=false
回执 release=c3700497faab、content=7849ee740747,16 技能 + 1 规则 没有写入任何技能文件或 AGENTS.md

结论:101 的运行时镜像已经与中央期望对齐,且回执内容指纹与 API desired 完全一致。

四节点分发结果

按 101 基准把 AGENTS.md、Hook、16 个技能和资产回执同步到 102、RR、Home、Summer,每台均保留本机备份并逐文件校验 SHA256。

节点 规则哈希 Hook 技能 资产回执 客户端状态
101 7ee4d51b… cc5a7f65… 16 c3700497faab / 7849ee740747 在线
102 7ee4d51b… cc5a7f65… 16 同上 在线;旧 AGENTS.override.md 已备份停用
RR 7ee4d51b… cc5a7f65… 16 同上 在线
Home 7ee4d51b… cc5a7f65… 16 同上 在线
Summer 7ee4d51b… cc5a7f65… 16 同上 在线;旧 override 已备份停用,主机登记待验证
OfficeSummer 7ee4d51b… b1e7a6f5… 16 c3700497faab / 7849ee740747 在线

102 与 Summer 原先存在 AGENTS.override.md,会完全覆盖全局规则;两份都已改名备份,当前不再阻断规则源匹配。102 上 6 个重复的 Paseo 技能已移入 .agentmeshos-quarantine-20261031-083945,由共享技能根提供一致版本。

客户端心跳

Memory 的在线判定是 5 分钟 TTL、15 分钟转离线。为区分“空闲”和“掉线”,已给五个 Codex 客户端加 4 分钟心跳:

平台 节点 机制 结果
Linux 101、102、RR agentmeshos-client-heartbeat.timer active,服务 Result=success
Windows Home、Summer 计划任务 AgentMeshOS-Client-Heartbeat Ready,LastTaskResult=0,允许电池启动和错过补跑
Linux 101 agentmeshos-paseo-heartbeat.timer、agentmeshos-opencode-heartbeat.timer active,Paseo/OpenCode 客户端在线

心跳只上报客户端在线与版本,不产生模型调用、turn 或 Memory 写入。

资产回执是持久事实,API 按 7 天判断是否过期;实时性由客户端心跳负责,避免安装完成 30 分钟后被误判为“已过期”。

Hook 的 PostToolUse 现在上报 tool_call 通道;101 的规则、Bootstrap、技能、工具、执行和 Memory 回写六层已全部取得健康证据。Summer 的主机别名已从错误的 summer 修正为 windows-summer,与节点登记表一致。

Web Search 现在由网关执行一次真实 SearXNG 搜索并记录 last_success_at,且要求结果数大于 0;Web Fetch 已在服务端增加真实调用计数,/healthz 返回 last_success_at 与 call_count。

SearXNG 容器本身正常,但 Brave 超时/429、DuckDuckGo CAPTCHA、Google CSE 超限、Wikidata 超时,导致直连查询返回 0 条。搜索 MCP 已增加 SearXNG → Serper → Tavily 兜底,实测 SearXNG 0 条时 Serper 返回 5 条;页面会如实显示“上游搜索源返回 0 条结果”,不再把 0 条画成健康。

兜底 MCP(f04609c6…)与 search.env 凭据已同步到 102、RR、Summer、OfficeSummer;凭据只走 SSH 传输,Linux 权限 0600,Windows 使用受限 ACL。102 实测 SearXNG 0 条时 Serper 返回 3 条。Home 当前离线,恢复后补发。

控制台的中央服务现在同时显示主机与实际工具:Memory(102)、Web Fetch(101 · agentmeshos-web-fetch)、Web Search(101 · SearXNG)。Web Search 的说明还会写出“兜底:Serper → Tavily”,不再把一个大面写成单一服务名。

Console 的“中央 Web 搜索”入口已改为 #webSearch 内嵌视图,地址固定为同源路径 /__agentmeshos/searxng/。RR 私有回源网关先执行 A-Auth admin 检查,再按 Tailnet DNS 解析 101 并转发到其 8090;SearXNG 的公开基址同步为 Console 子路径,因此页面、静态资源、表单、重定向和偏好设置都不会把 101 节点地址带回浏览器。该入口不再使用 window.location.assign 离开 Console,也不在菜单文案中显示节点 IP。

SearXNG 虽然部署在 101,但它只是元搜索聚合器,真正检索仍要访问 Brave、DuckDuckGo、Google CSE、Wikidata 等外部引擎。限流来自这些外部引擎对 101 公网出口 IP 的 429、CAPTCHA 和超时,不是容器本地故障;兜底 Serper/Tavily 通过 API Key 走授权通道,因此不受同一套网页反爬限制。

OfficeSummer 原先只有 WindowsApps 的 Python 占位符。已安装 Python 3.13.9(安装包经官方源与镜像 SHA256 对验),并把旧 Hook 引用的 .codex\python313 做成指向标准安装目录的目录联接;资产回执与心跳均已通过。

工具目录的边界

Playwright 是可由节点包管理器自动安装的本地 MCP,102、RR、Summer 已安装 @playwright/mcp 0.0.83,并改为固定本地 cli.js,避免每次启动依赖 npx 下载。Kimi WebBridge 不是普通 MCP 包:它要求 daemon、真实 Chrome 扩展和扩展连接地址三件套,官方操作边界要求由用户从 Kimi 官方入口安装,分发器只展示状态,不静默安装。CUA Driver 依赖真实桌面会话;RR 不适用,Summer 的 driver 已安装但当前 SSH 在 Session 0,不能把服务会话当成 GUI 可用。

因此,这些工具现在属于“Agent 客户端”状态域下的“工具与 MCP 目录”子层,而不是遗漏在状态域之外。页面在核心表逐项显示配置、安装和运行证据,避免把 config.toml 里出现一段配置误判成工具已可用;不属于核心必检的可选 MCP 单独进入“可选扩展”表,平台角色不适用的工具直接不进入该节点核心表,不再用“不适用”填充单元格。

工具目录分发结果

下表是 2026-10-31 的历史盘点快照,其中“不适用”是按当时的展示口径记录的;2026-11-04 起的运行态势页面已改为“核心表只列核心能力、可选扩展单独成表、非 Codex Agent 使用自有检查”的口径。

工具 101 102 RR Summer OfficeSummer Home
Playwright MCP 本地包、Node、Chrome 可用 已安装本地 @playwright/mcp 0.0.83,配置已改为固定 cli.js 同上 已安装并配置为固定 cli.js 节点暂时连接超时,待复验 离线
Kimi WebBridge daemon + Chrome 扩展已连接 不适用 不适用 未安装 未安装 未知
CUA Driver socket 可用 已安装;socket/daemon 状态需单独启动验收 不适用 已安装;桌面运行证据待验证 已安装;桌面运行证据待验证 未知
Web Search MCP SearXNG + Serper/Tavily MCP/凭据已同步,实测 Serper 兜底 同上 MCP/凭据已同步 MCP/凭据已同步 离线
Web Fetch MCP 中央 101 中央 101 中央 101 中央 101 中央 101 中央 101
Context7 已配置 未配置 未配置 配置存在但本地包缺失 待复验 未知

结论:工具缺口之前确实没有被状态域完整覆盖。现在工具目录是“Agent 客户端”状态域的显式子层;配置存在、依赖安装、实际运行和平台不适用分开显示。WebBridge 的 daemon 与浏览器扩展安装遵循官方边界,不由分发器静默安装;Playwright 则可由节点包管理器安装。

运行态势聚合在冷启动时可能耗时约 46 秒。网关已改为“缓存完成后计时 + 后台刷新 + 启动预热”,页面等待 60 秒;后续请求直接返回缓存快照,不再出现首次加载误报“状态暂不可读”。

验证

项目 命令 结果
分发器回归 python3 scripts/maintenance/tests/agent-assets-sync-test.py agent-assets-sync=passed
Hook 证据(桩) 本地 stub 调用 _bootstrap_recall,覆盖匹配与哈希不一致 hook-evidence=passed,py_compile 通过
Hook 证据(真实回执) Memory codex-pcdell-101 的 recall 通道已出现 rule_source_mismatch、skill_candidates、skills_loaded、tool_allowlist_count、route_context_published、asset_* 字段 规则源当前确实不一致,页面判定为阻塞
中枢 API .venv/bin/python tests/test_agent_runtime.py agent_runtime=passed
真实投影 用真实 Memory 导出调用 build_agent_runtime_status desired 为 1 个规则集 / 17 项受管技能;分类为 blocked,脱敏扫描通过
Console 契约 bash tools/console-site/tests/browser-contract.sh 四组浏览器契约全部 PASS
生产 API 回读 管理员 API Key 登录后读取 https://api.yohan.fun/api/agent/runtime-status 返回 rule_skill_authority;分类 blocked,desired 1 个规则集 / 17 项技能,runtime 报告规则源不一致
生产 API(对账后) 同一管理员会话重新读取 desired 与 applied 均为 7849ee740747,分类 aligned;规则源匹配
公网浏览器验收 Playwright 1440×1000 与 390×844 打开 #agentRuntime 图例位于关系图右侧(248px 栏),图标 14px;中枢在四域之前;scrollWidth == clientWidth
镜像构建 实现提交 0a24e90 的 API Gateway(Run 40609509862)与 Console(Run 40609509776)均成功;37b5b10 只改维护脚本 生产运行的是包含中枢代码的 0a24e90 镜像

回退

分发器回退依赖 <CODEX_HOME>/state/agentmesh-assets/last-known-good/,逐文件校验 SHA256 后恢复,并交换 current / previous Release。Hook 回退使用同目录备份文件;Memory 与 Console 可独立回滚,不影响已安装镜像。

🚦 实施评审结果

P20-4 已通过

用户已经在 2026-10-28 明确回复“好,按照这个计划开始执行”,P20-0 评审门已通过。确认内容如下:

  1. 用户确认四个状态域的名称、范围和页面归组。
  2. 用户确认四层闭环图的表达:规则、Memory Bootstrap、技能、工具、执行/验证、Memory 回写,以及 BLOCKED 的失败关闭含义。
  3. 用户确认页面只读,问题只展示、不在 P20 第一版修复。
  4. 用户确认 101 是第一个分发 canary,Memory 是中央管理权威。
  5. 用户确认导航整合方式,不再把 CPA、Memory、节点、网络等入口继续分散在不同组。
  6. 计划正文、state.json、当前摘要、计划看板、路线图、文档索引和 MkDocs 导航已经同步,并通过计划状态与 Markdown 门禁。

P20-5 的发布、节点安装和回退仍需用户确认 D7 至 D10 后才能实施。P20 状态页继续保持只读;发布和节点安装属于分发器职责,不在页面提供按钮。

P20-5 实施边界

用户已确认按计划开始实施,以下边界已冻结;它们是实现依据,不再是待确认项:

  • 受管技能安装在 Codex 技能根,带 .agentmeshos-managed.json 标记;系统、插件和其他 Agent 技能不接管。
  • 已有未受管同名技能一律不覆盖;~/.agents/skills 已提供的同名技能不重复安装。
  • 全局规则采用整文件 Release 与 last-known-good;默认只做差异检查,写入必须显式 --apply-rules。
  • 101 是第一个 canary,冲突对账完成后才向其他节点扩展。
  • 安装前先跑只读计划,冲突或阻断必须失败关闭,不静默覆盖。
  • 运行态势页面只读;发布、安装、删除和回退动作保留在分发器与管理入口。

🧪 验收、回退与风险

当前实施验收

验收项 通过条件 证据
计划完整性 有目标、非目标、图、数据关系、工作包、验收、回退、未决项 本页正文
状态口径 计划状态与阶段状态分离,P20-4 已完成、P20-5 修订中 state.json 与计划状态检查
图示可读性 有总体架构、配置扩散、四层闭环、中心服务和页面流程图 本页 Mermaid 图示
文档库一致性 看板、摘要、路线图、索引和导航都指向 P20 文档链接检查与 MkDocs 配置
实施隔离 代码测试不等于生产发布;审计问题只展示、不修复 工作包状态与本页边界声明
API 契约 六阶段闭环、四域状态、未知/过期语义和脱敏字段通过单测 tools/api-gateway/tests/test_agent_runtime.py
浏览器行为 四域卡片、六阶段闭环、960px 紧凑关系图、五项颜色图例、单刷新按钮和 390px 无页面级溢出 tools/console-site/tests/browser-contract.cjs
真实数据投影 101 基线、工具通道断点、Web 服务未验证状态按实际证据出现 本机只读 Memory/CPA/Web 数据投影
完整本地门禁 Runtime 211 passed、Auth 22 passed、API/Console 契约、脱敏扫描、计划与文档门禁、MkDocs strict 全部通过 bash scripts/ci/run-local-tests.sh
同 SHA 发布 历史版本曾完成 RR 部署;本次 466e7ca2 目前只有 API/Console 构建和 102 standby 部署证据,RR 主生产尚未验收 466e7ca2 Build Runs 41394576970、41394576999;Standby Run 41394981670
生产 API 回读 管理员会话返回 role=admin;runtime-status 返回 200、schema agentmeshos.agent-runtime/v1、8 个客户端均有 web_capabilities P20-5-11 API 回读与真实浏览器页面验收
中央模型路由客户端回读 中央 CPA 与每个在线 Codex 客户端配置、模型、协议、目录和真实目录探测均可见;目录漂移必须被标记 Memory metrics 心跳 + build_agent_runtime_status 单测 + 101/102/RR/Home/Summer 真实回读
公网登录验收 临时管理员 API Key 换取管理员只读会话;页面账号为“API Key 管理员身份”,角色为管理员 #account-button 与 /__agentmeshos/session 双回读
公网桌面布局 四域、六阶段、五项图例、单刷新按钮均可见;关系图宽度 960px,页面级横向溢出为 0 1440px Playwright 实拍
公网移动布局 图例两列排列,页面级横向溢出为 0 390px Playwright 实拍

后续实施验收原则

实施阶段必须验证四域均有状态、主机和 Agent 分列、未知/过期不显示绿色、六阶段断点可定位、页面无写操作、动态刷新可见、数据源失败可分别解释、桌面和移动端无页面级横向溢出。每项必须有真实 API 回读或浏览器验收证据;“配置存在”不能替代“实际加载/调用”。

回退方案

P20 采用增量、可撤回设计:回退时撤下新增总图入口和只读聚合路由,恢复原导航分组;不回滚 CPA、Memory、Web 服务、节点配置、规则、技能、MCP 或生产数据库。API Gateway 和 Console 部署脚本各自保留上一可用镜像,计划文档和真实审计事实保留,便于重新评审。

风险

风险 影响 计划处理
把历史快照当实时状态 页面误报健康或漂移 所有结论带来源和新鲜度,缺证据显示未验证
主机在线被误当 Agent 在线 无法定位真实客户端断点 永久分列展示并分别取证
状态图变成第二套治理系统 页面越权执行修复 API 只读,处理入口回到原页面
配置扩散只看文件哈希 误判规则、技能或工具已生效 增加实际注入、tools/list 和真实调用证据
数据源慢导致总图假正常 隐藏局部故障 每源独立超时,结果标过期/未知
中央 Release 与节点镜像漂移 Memory 显示最新,但 Codex 实际加载旧规则/技能 三层状态分开;哈希不一致和安装超时明确告警
分发器误删非受管技能 破坏系统或插件技能 只处理 .agentmeshos-managed.json 登记项,原子替换并可回退

⚠️ 未决项 / 需要用户决策

编号 需要确认的事项 当前建议 未确认时的处理
D1 页面总入口名称 已确认使用 Agent 运行态势 已冻结
D2 导航归组 已确认增加独立“Agent 状态”组,先放置总图;后续可讨论把其他入口整体迁入同组 第一版不删除原管理入口
D3 四个状态域命名 采用中央模型路由、中央服务、Agent 客户端、中央配置与节点镜像 P20-5 页面迁移时替换旧“101 对齐配置”标签
D4 闭环表达 已采用规则、Memory Bootstrap、技能、工具、执行与验证、Memory 回写 已冻结
D5 只读边界 第一版严格只读,只保留刷新按钮 已冻结
D6 中央配置权威 Memory 中央管理,101 作为第一个分发 canary 其他节点按 P20-5 计划逐步接入

📌 本轮收口

P20-5-9 已完成分发器、Hook 证据、中枢 API、网页能力路由子层、只读面板、中央模型路由客户端子层和版本对齐代码及本地验收。P20-5-10 已完成:目标 SHA 5e1dd061 的 Console/API 已部署到 RR 主生产并健康运行。P20-5-11 现已完成:凭据文件已修正为标准 export CONSOLE_API_KEY=... 格式并轮换旧 Key;管理员 API 会话、runtime-status 和真实浏览器页面均验收通过,页面可见“网页能力路由”表格。OfficeSummer 离线保持单独状态,不影响 P20-5-11 收口。

🔁 主生产回读与状态口径统一(2026-11-02 23:40)

结论:7e24b791 的中文额外 MCP 显示名与 312e4288 的别名去重已经进入 RR 主生产 API 和页面,不需要重新发布后端;剩余的唯一不一致是工具目录徽标取前端本地映射、网页能力表取后端 status_label,本轮已统一到后端口径。

生产 API 回读

以管理员 API Key 换取真实会话(POST https://auth.yohan.fun/api-key-login 返回 200、role=admin),再读取 https://api.yohan.fun/api/agent/runtime-status:

检查项 实测结果
接口状态 HTTP 200,schema_version=agentmeshos.agent-runtime/v1
客户端数量 8 个(101/102/RR/Home/Summer/OfficeSummer 的 Codex,外加 101 的 Paseo、OpenCode)
工具 ID 重复 每个客户端 0 个重复 ID
Memory 列 每个客户端恰好 1 个 agentmeshos_memory
额外 MCP 中文化 fetch→网页读取、node_repl→Node.js 运行环境、sequential-thinking→结构化推理、time→时间工具
网页能力 8 个客户端均返回 web_capabilities,标签为中文(正常/未验证/需关注)

生产页面回读

检查项 实测结果
Console 首页 https://console.yohan.fun/ HTTP 200,81202 字节
静态脚本 /app.js?v=29f37596…c96eb,386333 字节,与源码一致包含“工具与 MCP 目录”“网页能力路由”“Agent 运行态势”
节点矩阵表头 客户端、主机、Agent、版本、规则、技能、工具、Memory、结论;没有模型、API、中央路由重复列
工具目录单元格 只渲染状态徽标与“配置/安装/运行”证据,不重复工具名

本轮统一改动

工具目录单元格原来调用 agentRuntimeToolStatusLabel(status) 自行翻译,网页能力单元格使用后端 status_label,同一个 healthy 在前者显示“可用”、在后者显示“正常”。现在工具目录改为 status_label || agentRuntimeToolStatusLabel(status),两张表同源同词,旧载荷仍可回退到本地映射。对应静态契约新增断言 item?.status_label || agentRuntimeToolStatusLabel(status),防止再次漂移。

测试

检查 结果
node --check tools/console-site/src/app.js 通过
bash tools/console-site/tests/workspace-contract.sh PASS
node tools/console-site/tests/browser-contract.cjs PASS
tools/api-gateway/tests/test_agent_runtime.py agent_runtime=passed

发布与备用控制面

事项 证据
主生产 Console 已更新 统一后的生产脚本为 /app.js?v=48b70f84…eacf8(386355 字节),包含 status_label || agentRuntimeToolStatusLabel
备用控制面 102 已追平 Run 41479214334(b2d1315d):dedupe、verify、build、deploy 全部 success;Sync RR snapshot and deploy standby control plane 与 Verify standby read-only contract 均 success
GHCR 拉取瞬时故障已加固 首次 docker pull 出现 TLS handshake timeout;Verify standby images 现改为 3 次有界重试(间隔 15/30 秒),后续运行构建步骤成功

残余风险

  • OfficeSummer 仍按离线状态保留,不参与在线验收结论。
  • 真实 Chrome 会话未在本轮复用(改用真实管理员 API 会话加生产静态资源回读),如需像素级页面证据,应补一次真实浏览器截图。
  • 备用控制面只在镜像类工作流触发时自动追平;纯文档或纯工作流提交期间它会短暂落后,直到下一次带镜像变更的提交。

本轮“未验证 / 需关注”收敛(2026-11-03)

问题 根因 处理
101 本地 Fetch 兜底显示“节点尚未上报工具目录” 101 安装的资产分发脚本是 11 月 1 日旧版,缺“本地兜底盘点” 安装仓库版脚本并回读,工具目录出现独立的本地兜底行
Hook 与心跳各维护一份工具清单 codex_memory_hook._tool_inventory_snapshot 硬编码 7 项,不含本地兜底 Hook 改为复用资产分发脚本的盘点结果,工具目录只保留一个采集器
远程 MCP 入口长期停在“未验证” 聚合要求安装状态为 installed,远程入口记录的是 remote 聚合接受 installed 与 remote,并补回归断言
工具目录缺少 mcp_servers 时整页聚合抛异常 reported_servers 可能为 None 补空值兜底,缺字段时按空列表处理
本地兜底只有安装检查,无法证明可用 从未执行过不依赖中央网关的真实抓取 新增 scripts/maintenance/web-fetch-local-acceptance.mjs,真实抓取后写入 acceptance.json;状态读取该证据,7 天后自动过期
备用控制面校验步骤没有网络重试 verify-image-pair.sh 的 GHCR 清单读取是单次调用 改为 4 次有界重试,内部镜像清单读取改为 3 次有界重试
中央 Web Search 长期显示“最近真实调用未验证” 状态页探测沿用 5 秒通用超时,聚合搜索经常超时;且每 15 秒探测一次会加重上游负担 探测改为 20 秒独立超时、失败重试一次、结果缓存 10 分钟
心跳与 Hook 各自上报工具目录,旧快照会覆盖新结果 聚合按固定通道顺序覆盖,不看时间 改为取 reported_at 最新的一份清单
本地兜底状态无法引用真实调用 盘点只看文件是否存在 盘点读取 Hook 的 web_route_events 与本地 acceptance.json,成功与失败都有时间证据

真实证据:101 本地兜底直接用本机 Router 抓取 https://example.com,返回 HTTP 200、后端 mcp-server-fetch、正文 190 字符,写入 acceptance.json 后运行态势显示“本地兜底已真实验收”。

🩺 运行态势对象三分与证据口径收敛(2026-11-04,P20-5-12)

结论:运行态势不再要求每个客户端都套用 Codex 六层闭环,而是按“Codex 核心能力、可选扩展、非 Codex Agent 自有运行态势”三类对象分别取证。在线对象的正常状态必须来自真实证据;缺证据就显示“未验证”并进入异常清单,不能靠隐藏单元格变绿。

问题与判定

现象 根因 判定
在线 Codex 出现“不适用”单元格 工具清单按平台角色把不适用的工具写成 not_applicable 行 这不是状态,而是采集器替页面做了结论;改为不进入核心表
Paseo/OpenCode 在 Codex 六层里全部“不适用” 六层是 Codex Hook 契约,非 Codex Agent 没有 Bootstrap、技能选择和写回链路 复用会把不存在的能力当成故障;改为该 Agent 自有心跳与服务检查
Memory 专项缺失时停在“未验证” Memory 诊断行不一定覆盖每个客户端 不能用规则、技能、工具层“推导”出绿色;只允许使用该客户端在 Memory 侧的通道证据
工具目录与网页能力表部分重复 两张表来自同一份工具清单的不同投影 允许重叠,但核心表不再混入可选扩展

三类对象

对象 成员 证据 页面位置 禁止
Codex 核心能力 agentmeshos_memory、local_search_registry、web_fetch、web_fetch_local、playwright、kimi_webbridge、cua-driver、context7 配置、安装、运行、真实调用与最近成功时间 工具与 MCP 目录、网页能力路由 缺证据时隐藏,或标成“不适用”
可选扩展 node_repl、sequential-thinking、time、旧 fetch 配置、安装、最近使用 新增“可选扩展”表 计入核心必检,或删除节点配置
非 Codex Agent 101 的 Paseo、OpenCode 客户端心跳加本地服务检查 新增“非 Codex Agent 运行态势”表 套用 Codex 六层或 Codex 工具目录

非 Codex Agent 的本地服务检查固定为:Paseo 检查 paseo.service;OpenCode 检查 opencode-headless.service 与 opencode-mem-web.service。任一服务未运行即“需关注”,并写入异常清单,不等到用户翻表才发现。

Memory 专项证据

规则 说明
优先 Memory 诊断行 存在 codex-observability 行时直接使用该行结论
缺行时只投影 Memory 侧通道 必检 bootstrap、event_ingest、tool_call,参考 recall、write
不用外层六层洗绿 规则、技能、工具层成功不能替代 Memory 内部证据
没有通道证据仍是“未验证” 保留未验证并进入异常清单,不生成绿色兜底

新鲜度口径

项 原值 现值 依据
实时通道与工具证据 30 分钟 6 小时 30 分钟会把空闲节点的真实正常状态误判为过期
资产安装回执 7 天 7 天 属于持久事实,实时性由客户端心跳负责

实施映射

文件 变更
tools/api-gateway/src/agent_runtime.py 核心工具不再产出 not_applicable 行;可选工具标记 optional;非 Codex Agent 生成 agent_status 并参与状态与异常;Memory 专项按通道证据投影
scripts/maintenance/agentmeshos-agent-assets-sync.py 心跳新增 local_services 检查;CUA 增加 status 探测
tools/console-site/src/app.js、tools/console-site/src/index.html 核心表排除可选工具;新增“可选扩展”与“非 Codex Agent 运行态势”两张表;Codex 六层矩阵只展示 Codex
测试 test_agent_runtime.py、agent-assets-sync-test.py、browser-contract.cjs 同步断言

验证与剩余动作

检查 结果
tools/api-gateway/tests/test_agent_runtime.py agent_runtime=passed
scripts/maintenance/tests/agent-assets-sync-test.py 通过
bash tools/console-site/tests/browser-contract.sh 通过
python3 -m py_compile 两个 Python 文件 通过
git diff --check 通过

本节的代码与测试已完成,生产侧还没有收口:

事项 当前状态 影响
Memory 项目侧的在线判定 TTL 与缺行诊断契约 待实施(mcp-memory-server 仓库) 在线客户端缺行应成为真实问题,而不是靠 AgentMeshOS 投影
RR 主生产 API 与 Console 部署 待执行 用户当前访问的页面仍是旧版
各节点资产同步器刷新与心跳重启 待执行 非 Codex Agent 的本地服务检查需要在节点上真正运行