2026-09-23·by Sijie Wang#standmeet#architecture#design

ui-mcp-parity

UI—MCP 对等:UI 能做的,handle 都能做

上级:service-handle

状态:

已构建。 机制是 internal/infra/facadeparity —— 每个域把自己的 op 声明成数据(fp.Op:id、说明、入参 schema、种类、可达面),每一个面都是这一份注册表的投影convergence-inbound-and-outbound)。由 paritymanifest 加一条棘轮强制。它暴露出来的 owner-MCP↔admin 缺口是真的,而且比估的大 —— 56 条,不是猜的那 ~15 条 —— 已经 56→0 还清。2026-09-07 于 36789537d 复核:paritymanifest.KnownMCPGaps() 返回空表(gaps.go:17),棘轮(outward_test.go)在任何没有 MCP 孪生的新 admin 路由上都会变红;MCP 面是从 dispatcher 长出来的(routes/mcphandle/from_dispatcher.go:45),有意的不对称写成 fp.Only(reason, facade) —— keypairs.create/list/delete 就是 Only(FacadeAdmin),与下文的预测一致(manifest_table.go:41-49)。 在那之前(直到 2026-07),路线图把"MCP 与 HTTP 管理对等"列在外部化迁移之下,却没有任何强制机制——管理端 HTTP 接口和 service handle 的工具接口是两份手工维护的清单,二者之间的漂移是无声的。下面三个选项是促成这次构建的分析;②以 fp.Op 的形式落地(不是 Command{} 那个草图),①以棘轮 + Only(...) 例外的形式落地。

想要的不变量

每一个能通过管理 UI 触达的 owner 操作,也必须能通过 service handle(StandMeet-as-MCP-server)触达——这样 owner 的 AI 会话就永远不会沦为浏览器的二等公民。例外必须是显式的,绝不能是意外产生的。

三种机制,强度递增

① 对等闸门(成本低——先构建这个)。 一个 CI 测试遍历 chi 管理路由表 × OwnerMCPBindings(),并将两者对照一张带例外清单的显式映射表进行检查;任何未被映射、又未被列入例外的管理端点都会让构建失败。和 check-connector-boundarymechanical-guardrails)同属一类。例外清单本身就是审查材料——漂移要么被修复,要么被书面承认。合法的例外确实存在:密钥对创建(循环依赖——你需要一个密钥对才能调用 handle)、登录/认领(引导阶段)、上传形态的 UX。

② 声明一次,投影两次(结构性——真正的修复)。 漂移之所以存在,是因为有两份手写的接口。把每个 owner 操作只注册一次——Command{name, input schema, handler}——然后从同一份注册表中同时派生出 HTTP 路由和 MCP 工具。对等不再是一个需要被检查的属性,而变成在结构上不可违反。这正是平台自身的清单哲学(manifest philosophy)套用在了自己身上(OwnerMCPBindings 本来就已经是一份被遍历的声明;HTTP 那一侧只是还没有并进来),也是单一真相来源纪律(judgment-audit 维度 3:派生之物不应手写)的又一体现。

③ UI 反过来消费 handle(激进——目前不推荐)。 让管理 UI 本身成为 service handle 的一个客户端:这样对等在定义上就成立。这在哲学上与 entry-agnostic-agent("UI 只是另一个消费者")一致,但代价是实实在在的——内部调用要缴纳线协议(wire-protocol)税,session-cookie 与 Sigv1 之间要做桥接,上传/SSE 的形态也很难套进 MCP。机制②能在进程内拿到同样的保证,却不用付这份税。

建议

对所有新东西用②作规则,对遗留部分和例外用①作闸门。 ②从根本上消灭这一漂移;①捕捉回归,并让例外清单保持诚实。只有当一个真正的第二 UI(IM 网关)让"UI 作为消费者"这件事本身变得举足轻重时,才值得重新考虑③。

about this entry

One of sijie's wiki entries. The AI on this site is grounded in the same corpus and answers in sijie's voice, with citations back to entries like this one — answering costs sijie money, so it waits behind a code: enter an access code →