feat(capability,gateway): 工具策略落盘 + 主代理代审真接线(裁决 1.1 核对/1.3/10.4.2/13.4.3)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

- 1.1(核对):registry 默认两布尔 false 已一致,零代码改动(设计文档已按裁决改写)
- 1.3 + 10.4.2:新增迁移 0012_tool_policy(tool_policies 表,表名复数 + idx_tool_policies_name);
  新增 registry.PolicyStore/SQLitePolicyStore,启动 Load 覆盖注册初值、SetPolicy 先落库后改内存
  (落盘失败保持旧值并报错);面板保存路径不变但从此重启仍在
- 13.4.3:代审真接线 —— restrict.SensitiveCall 结构化判定(terminal / file write / http POST)、
  restrict.Gate/Reviewer/Resolver(无代审者或代审报错一律 fail-closed 拦截),
  组合根装进 loop.Options.Hooks 的 CallAdmit;gateway.RecordApproval 落 audit_logs
  (who=角色名 / what=approval.<工具> / result=granted|denied)并广播 approval_notice 帧
- 前端:代审小字「xxx 想要干什么,我审查后批准了」进聊天流顶部(帧→store→组件,文案单一来源
  复用 audit.Approval.Explain()),附纯 node 逻辑测试
- 复核:迁移在 data/cyrene.db **副本**上 up/down/up 各一次通过;TestRegistry_PolicyStoreSurvivesRestart
  与 TestAdminSetPolicySurvivesRestart 证明「重启后策略仍在」;terminal 触发代审 + 审计有行有端到端断言
This commit is contained in:
AskaEth committed 2026-10-04 12:30:16 +08:00
1 parent ed5bd92e1b
commit 63236c9b00
20 files changed
+1709 -24

No files matched your search

@@ -0,0 +1,9 @@
-- 0012_tool_policy down: 回滚落盘的工具策略表。
--
-- 回滚后的状态是「策略只活在内存、重启复位」(裁决 1.3/10.4.2 落地前的旧形态):
-- 已配置的标记随表一起丢弃,重启后所有能力回到默认的两布尔 false(owner-only)。
-- 丢弃是安全的——registry 的运行时内存副本与调用路径不读本表以外的东西,
-- 且不存在引用它的外键(内部按能力名匹配,非外键约束)。
DROP INDEX IF EXISTS idx_tool_policies_name;
DROP TABLE IF EXISTS tool_policies;
@@ -0,0 +1,27 @@
-- 0012_tool_policy: 工具级可达性标记落盘(design/11 §3、design/09 §2.1;裁决 1.3/10.4.2)。
--
-- 每个能力(工具/技能/MCP 等)两个独立布尔 allow_in_group / allow_in_stranger,
-- 默认 0 = 仅主人(owner-only);群聊与陌生人环境只有标记为真的能力可被调用
-- (策略引擎读值见 internal/capability/restrict)。
--
-- 为什么必须落盘:裁决 1.3「时 per-tool 为准且必须落盘」——此前标记只活在
-- capability registry 的内存里,管理面板 POST /api/v1/admin/plugins/policy
-- 改完一重启就复位。本表是那份策略的权威载体(registry 启动时 Load,
-- SetPolicy 时先落库再改内存,见 internal/capability/registry/policy_store.go)。
--
-- 口径:一行 = 一个已配置过的能力名;没有行的能力按默认值(两布尔均 0)
-- 处理,因此本表不需要为每个内置工具预填行——默认即最严(fail-closed)。
-- name 是能力名(工具名 / "mcp:<server>" 等),唯一索引承载「一个能力一行」。
-- 表名用复数,援引 AGENTS §10 已登记的例外(既有迁移口径一致)。
CREATE TABLE IF NOT EXISTS tool_policies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
allow_in_group INTEGER NOT NULL DEFAULT 0,
allow_in_stranger INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
);
-- 唯一索引同时承担 upsert 的冲突目标(ON CONFLICT(name) 需要唯一约束/索引)。
CREATE UNIQUE INDEX IF NOT EXISTS idx_tool_policies_name
ON tool_policies (name);