Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e0cdae1bf | ||
|
|
7bd4e17827 | ||
|
|
10b442169c | ||
|
|
b096191a84 | ||
|
|
a7ff466d9a | ||
|
|
1f3bd54cfb | ||
|
|
3cf263962b | ||
|
|
ba9d76426d | ||
|
|
30bceb748f | ||
|
|
b4a2573742 | ||
|
|
1f83bb7ffe | ||
|
|
064d4b5f68 | ||
|
|
2d5398e988 | ||
|
|
129cc3579d | ||
|
|
8375057829 | ||
|
|
32d6c8487a | ||
|
|
047d362c72 | ||
|
|
6c096b9360 | ||
|
|
c023551f2a | ||
|
|
b8fcf01062 | ||
|
|
f1a44fdac6 | ||
|
|
b91e298c15 | ||
|
|
61e0aef39c | ||
|
|
2cc00da9e0 | ||
|
|
a088809dc8 | ||
|
|
407e49d2ba | ||
|
|
652be93a60 | ||
|
|
ba4044d57e | ||
|
|
5a06acf7cd | ||
|
|
0b290b7461 | ||
|
|
267327671d | ||
|
|
a73c84b5be | ||
|
|
05c13a42b1 | ||
|
|
53354996f2 | ||
|
|
cf74a200e8 | ||
|
|
f7ae1ecce6 | ||
|
|
b184bfb109 | ||
|
|
f76cce9e32 | ||
|
|
95c2ec260c | ||
|
|
b8df6f3c2a | ||
|
|
733f32c671 | ||
|
|
8d8600024d | ||
|
|
cb7e25439a |
@@ -8,9 +8,9 @@ product_contract_source: ce-plan-bootstrap
|
||||
|
||||
# 多人协作存储与分布式演进方案 - Plan
|
||||
|
||||
修订:r2.1;确认状态:**已批准(2026-10-11 用户指示「按方案开始改造」)**;推进状态:U1–U7 **代码与测试已合入**(Backend [#164](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/164);Dev [#410](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/410)/[#439](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/439)/[#442](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/442);闭卡 [#424](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/424) 等)。正确性 A1–A7 与 B1 已绿(CI/SELF)。容量合同 B2/B3/B5 contract 与双实例 C2 **本机 SELF 窗口已跑通**(见[容量报告](../records/2026-10-12-u7-capacity-window-report.md));**SELF≠GATE/REPLAY**,双主机 C3、运维演练 C4/C5 未做——**仍不放行第二实例承接写请求**。
|
||||
修订:r2.3;确认状态:**已批准(2026-10-11 用户指示「按方案开始改造」)**;推进状态:U1–U7 **代码与测试已合入**(Backend [#164](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/164);Dev [#410](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/410)/[#439](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/439)/[#442](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/442);闭卡 [#424](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/424) 等)。正确性 A1–A7 与 B1 已绿(CI/SELF)。容量合同 B2/B3/B5 contract 与双实例 C2 **本机 SELF 窗口已跑通**(见[容量报告](../records/2026-10-12-u7-capacity-window-report.md))。2026-10-12 用户决定不做容量重放;同日 B6 pgbench、C4 断连、C5 库恢复已有本机 SELF(见[运维演练报告](../records/2026-10-12-u7-ops-drill-report.md))。2026-10-13 未配置对象存储时的上传 panic 已修,C5 工件恢复 K4 重测为 SELF 通过。**SELF≠GATE/REPLAY**,双主机 C3 未做——**仍不放行第二实例承接写请求**。
|
||||
需求来源:2026-10-11 用户要求完善 SQLite、PostgreSQL/pgvector、Redis 分工;随后确认“10–100 人,多人多项目多会话并行,未来支持多服务分布式”。
|
||||
需求负责人:weichen;方案编制:Codex;实施及运维负责人:待指定。更新时间:2026-10-12(Asia/Shanghai)。
|
||||
需求负责人:weichen;方案编制:Codex;实施及运维负责人:待指定。更新时间:2026-10-13(Asia/Shanghai)。
|
||||
关联任务:方案与 U1–U7 实施卡已归档;容量收尾见 Dev `.task/feature-u7-capacity-wrap-measure.md`。放行检查单:Dev `docs/release-multi-instance.md`。
|
||||
正文中的源码路径以 Agent-System-Dev 为根;工作包中的 `internal/` 简写指 `modules/backend/internal/`;文内相对链接以本文为根。
|
||||
|
||||
@@ -246,8 +246,8 @@ SQLite 本身支持可靠事务与多人经同一应用访问;WAL 提升读写
|
||||
|
||||
必需观测:API P95/P99与预期/非预期错误,DB pool wait/连接数/慢查询/锁等待,队列长度/最老年龄,run 租约/过期写拒绝/未知副作用,SSE cursor lag/补查次数,Redis 错误与降级,检索耗时/召回抽样,备份时间与恢复结果。日志只记录 request/run/owner 的安全标识,不记录 DSN、密钥或文档正文。
|
||||
|
||||
r1 为方案与 SELF 调查记录。r2 起:U1–U7 代码与测试已合入且正确性 CI 绿。r2.1:本机双实例 contract 容量窗口(ladder / 60m / 2h)SELF 全过,见[容量报告](../records/2026-10-12-u7-capacity-window-report.md)。本地 SELF 不能冒充 GATE/REPLAY 放行;双主机与运维演练仍缺。部署与第二实例写流量仍未授权。
|
||||
r1 为方案与 SELF 调查记录。r2 起:U1–U7 代码与测试已合入且正确性 CI 绿。r2.1:本机双实例 contract 容量窗口(ladder / 60m / 2h)SELF 全过,见[容量报告](../records/2026-10-12-u7-capacity-window-report.md)。r2.2:用户于 2026-10-12 明确不做容量重放;同日完成 B6 pgbench、C4 PG/Redis 断连、C5 物理备份与 pg_dump 恢复的本机 SELF,见[运维演练报告](../records/2026-10-12-u7-ops-drill-report.md)。C4 通过。C5 的库恢复通过(RPO 64 秒,RTO 4 秒),工件上传在未配置对象存储时 panic,K4 失败,产品代码未改。r2.3:2026-10-13 在 store 边界把带类型的空对象存储当作未配置并回落本地目录;同日 C5 重测 K1–K7 均为 SELF 通过(RPO 65 秒,RTO 3 秒,K4 五个工件 sha256 一致且跨用户拒绝)。本地 SELF 不能冒充 GATE/REPLAY 放行;双主机仍缺。部署与第二实例写流量仍未授权。
|
||||
|
||||
方案静态审阅及修订处置见[审阅记录](../records/2026-10-11-collaboration-storage-plan-review.md)。进程级黑盒相对库级 Manager 测试的漏检教训见[经验条目](../records/2026-10-12-lesson-http-multi-instance-vs-manager-tests.md)。Agent 审阅不替代人工批准或实现验收。
|
||||
|
||||
首选下一增量是 **独立 REPLAY 最小容量集**(至少 `run_load.sh --seed contract --profile ladder --instances 2`)以提升放行证据等级;或其候选项:**C3 双主机验证**(需用户指定第二主机)或 **C4/C5 运维演练**。在 GATE/REPLAY 与 C3 未齐前,不要开放第二实例写。各实现任务启动前复核在途 PR 与依赖 SHA,再按 Dev 的 evidence/task-sync/组合验证流程交付。
|
||||
首选下一增量不要自动开工。剩余放行门槛是:独立 REPLAY,或把 C4/C5 快速档接入 CI 形成 GATE(需平台准入);以及 C3 双主机(需第二台机器)。2026-10-13 的上传修复与 K4 SELF 重测不替代这两项。GATE/REPLAY 与 C3 未齐前,不要开放第二实例写。各实现任务启动前复核在途 PR 与依赖 SHA,再按 Dev 的 evidence/task-sync/组合验证流程交付。
|
||||
|
||||
@@ -501,3 +501,7 @@ stateDiagram-v2
|
||||
原始来源:S:35–76 与 D:75–88;RDM requirements/README、00、01/03/04/08/09/10;U0、V2.2 已批准裁定。矩阵中给出每条需求的原文位置。
|
||||
设计依赖:两树一网展示方案 r1、多人存储方案 r1、模板对话生成方案及 69 类资产盘点。涉及 API 的名称均为候选设计,正式符号由公开契约申请确定。
|
||||
本轮没有联网核验法律或标准条款,也没有声称系统已符合任何特定法规;本方案讨论项目既定需求、数据追溯与实现验收。
|
||||
|
||||
## 2026-10-13 项目成员闭环增量
|
||||
|
||||
用户复现宿主项目成员保存成功、成员登录不见项目且不能建对话,已批准针对 U2/U3/U5 的方向与阶段 1–9 连续推进。具体实施主记录为 [系统项目、成员工作入口与私域协作闭环 r1.1](2026-10-13-system-project-membership.md),验证/组件/PR/CI 结果在关联 Dev 任务卡维护。当前实现候选已覆盖统一项目、全局名称、成员个人会话、领域分片、私域与发布知识,以及旧项目显式修复;组合验收与正式 tag 消费仍推进中,不据此声明全部 U2/U3/U5 或总目标完成。部署、8788 数据修复与清理仍未授权。
|
||||
|
||||
@@ -9,7 +9,7 @@ product_contract_source: ce-plan-bootstrap
|
||||
|
||||
# RDM 两树一网集成、完善与追溯审计展示方案
|
||||
|
||||
修订:r1(2026-10-11 并入用户裁定);确认状态:用户评审通过(2026-10-11,需求拆解至实施计划五阶段一并,含 KTD4 双层管理员裁定);推进状态:U1–U5 全部实施并合入(RDM PR #195/#197/#201/#213;Dev PR #368,2026-10-11);管理区「项目追溯与审计」入口经通用声明机制补齐(扩展面 2.9.0 Registry.AddAdminZone;Backend #165、Frontend #63/#64、RDM #240、Dev #414,2026-10-12;rdm.audit 分区随 rdm 插件声明,区内能力仍由 rdm.inspect.* fail-closed);管理页插件清单另合并编译插件条目(Dev #404,2026-10-12)。U6(团队存储)独立后续;运行验收属部署环境。
|
||||
修订:r1(2026-10-11 并入用户裁定);确认状态:用户评审通过(2026-10-11,需求拆解至实施计划五阶段一并,含 KTD4 双层管理员裁定);推进状态:U1–U4 已合入。U5 的 #213 只交付了导出工件生命周期,水位重放、报告三段、草稿门和页面入口仍在进行(RDM #301、Frontend #73、Dev #488,2026-10-12,未合入)。管理区「项目追溯与审计」入口经通用声明机制补齐(扩展面 2.9.0 Registry.AddAdminZone;Backend #165、Frontend #63/#64、RDM #240、Dev #414,2026-10-12;rdm.audit 分区随 rdm 插件声明,区内能力仍由 rdm.inspect.* fail-closed);管理页插件清单另合并编译插件条目(Dev #404,2026-10-12)。U6(团队存储)独立后续;运行验收属部署环境。
|
||||
需求负责人:weichen;方案编制:Codex;实施负责人:待实施立项时指定。
|
||||
来源:2026-10-11 用户要求检查两树一网现状,并设计简单直观的项目追溯、审计展示;同轮明确选择“完善 RDM,并补齐必要的基座能力”。
|
||||
目标仓:Agent-System-RDM;下文 `RDM:` 路径相对于该仓,`Dev:` 路径相对于 Agent-System-Dev;所有建议接口名均为候选契约。
|
||||
@@ -331,7 +331,8 @@ U1 同批接通旧客户端的项目选择和命令封装,并解析可信会
|
||||
验证:导出中途有新写入不改变已固定内容;历史来源软删除仍可按授权追溯;未归属/缺失事件可见;跨项目下载、过期下载、权限撤销均拒绝。
|
||||
完成条件:同一版本在 UI 与报告中结论一致,并有正式 GATE/REPLAY 证据。
|
||||
|
||||
进展(2026-10-11,RDM PR #213 merge 1dce69d):U5 已实施合入——`export_artifact.go` 导出工件生命周期(`rdm_export_artifacts` 表+磁盘存储+sha256 完整性+24h 过期);`rdm.inspect.export.{create,status,download}` 三命令(审计面授权、截止水位固定、跨项目绑定拒绝、下载重鉴权);导出文件名携带 `wm<seq>` 水印标记。U1–U5 五个实施单元全部完成,进入部署验收阶段。
|
||||
进展(2026-10-11,RDM PR #213 merge 1dce69d):#213 只交付了导出工件生命周期——`rdm_export_artifacts`、三条 `rdm.inspect.export.*` 命令、截止水位被记录、文件名带 `wm<seq>`。导出内容当时仍读实时世界,报告没有三段,页面没有导出入口。
|
||||
进展(2026-10-12,未合入):RDM #301 补水位重放、三段、草稿门和遮蔽;Frontend #73 与 Dev #488 补概览导出区。这些 PR 的 CI 结论以各自 HEAD 的作业为准,本文不把本地测试写成 GATE。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -9,9 +9,11 @@ product_contract_source: ce-plan-bootstrap
|
||||
|
||||
# 服务重启与全量数据恢复方案 r3
|
||||
|
||||
确认状态:原 r2 批准记录保留(Dev PROJECT.md 记录 2026-10-12 五阶段批准);**r3 本轮增补待人工评审**。本轮仅调查、修订方案及本地文档核查,不代签历史批准,不授权业务实施、账户变更、迁移、故障注入、部署、推送或合入。
|
||||
确认状态:原 r2 批准记录保留。**r3 新增(R11/R12、KTD13–KTD15、U8)于 2026-10-12 已批准**,当时授权连续推进到 PR 可合入;该历史批准不代替当前交付准入。合入按现行规范由智能体执行。
|
||||
U8 进展(2026-10-12,未合入):Backend #183 与 Dev #482;旧记录在 `ef66bfb` 上记有 vet-and-test success(历史 SELF 引用,非本轮 GATE)。Dev 侧在允许 `app → instanceguard` 与 `instanceguard → store` 两条架构边后的提交是 `4464255`,该 HEAD 的 CI 以作业结论为准,不在本文升为 GATE。
|
||||
r3.1=同日增补 D1/D2/D3(部署根治;编号避开本案 U1–U8)。映射:D1 补 U1 身份消费缺口,D2 补 U6 部署回退,D3 补 U7 真实组合门禁。确认状态:用户 2026-10-12 授权按实施计划连续推进到 PR 可合入;D1–D3 仍供人工评审,不因 U8 批准而代签。
|
||||
修订记录:r1=2026-10-12 初稿并完成六角色文档自审(见同名审阅记录第一轮);r2=2026-10-12 吸收外部源码复核(U1/U3/U4/第9节四处修订,见审阅记录第二轮),需求范围与量化指标未变。
|
||||
r3=同日根据 dev 8788 账户故障续查刷新源码/运行事实,保留 R1–R10、KTD1–KTD12、U1–U7;补充 R11/R12、KTD13–KTD15、U8 单实例保护及近期验证合同。原故障档和时间指标保持候选值,未宣称实测达标。
|
||||
r3=同日根据 dev 8788 账户故障续查刷新源码/运行事实,保留 R1–R10、KTD1–KTD12、U1–U7;补充 R11/R12、KTD13–KTD15、U8 单实例保护及近期验证合同。原故障档和时间指标保持候选值,未宣称实测达标。上述 r3 新增已于 2026-10-12 批准。
|
||||
需求来源:2026-10-12(Asia/Shanghai)用户要求“系统应该在停止并再次启动(通过 svc 或异常终止)后,应当能够恢复所有服务和数据,给我一个完善方案”。负责人:weichen;编制:Codex;实施与运维负责人在启动对应增量时指定。
|
||||
主记录:本文;任务卡:Dev `.task/feature-service-restart-recovery-plan.md`。本文的源码路径以 Dev 根目录为基准。
|
||||
|
||||
@@ -330,10 +332,53 @@ T8-6:参数来自应用实际连接;SQLite FULL/PG 同步设置按批准合
|
||||
|
||||
实施批准时需要固定:目标实例/服务组及独占管理权、实际数据归属清单、故障档与RPO/RTO、正常停机预算、既有在途任务分工。本文已给默认建议;没有这些确认不在共享运行环境做故障/迁移/监管切换。后台是否自动重做模型回合可按任务政策配置,但未知副作用不得靠默认重试放行。
|
||||
|
||||
下一任务建议为 U8 与账户方案 U7/U5 的首批设计/实施评审:先保护 dev 原数据,补足账户一致性与登录语义;随后 U3 停机/就绪、U4/U5 任务恢复、U6/U7 文件与灾难演练。新增 U8 未批准前不实施。数据清单、故障档预算、正式组合验证仍为放行条件;PG 迁移、监管切换、备份恢复、部署和故障实验分别授权。
|
||||
r3 编制期的历史下一任务建议(不是当前批准状态)为 U8 与账户方案 U7/U5 的首批设计/实施评审:先保护 dev 原数据,补足账户一致性与登录语义;随后 U3 停机/就绪、U4/U5 任务恢复、U6/U7 文件与灾难演练。新增 U8 未批准前不实施。数据清单、故障档预算、正式组合验证仍为放行条件;PG 迁移、监管切换、备份恢复、部署和故障实验分别授权。
|
||||
|
||||
## 10. 全系统完成条件
|
||||
|
||||
只有在所有启用的必需服务/插件被纳入清单、R1–R12均有当前组合与运行对象的重放证据、第8节故障矩阵通过、未知副作用有可处理隔离状态、组合备份实际恢复成功、人工验收及代码Review通过并完成合入/部署后,才可声明“系统停止或异常终止后能够恢复所有服务和数据”。
|
||||
|
||||
本轮交付状态止于**待审核方案**;不以记录、源码能力、桩测试、健康接口或本地文档检查代替上述完成条件。
|
||||
编制期历史交付状态止于**待审核方案**;当前批准与进展见页首及第 11 节。批准不等于全系统恢复已验收,不以记录、源码能力、桩测试、健康接口或本地文档检查代替上述完成条件。
|
||||
|
||||
## 11. D1/D2/D3 部署根治补充(r3.1)
|
||||
|
||||
编号 D1/D2/D3 只属于本补充,避免与本案 U1–U8 重名。已合入且不再重做:Dev #474(按实例重置身份变量、停旧前候选门禁、update 走 manifest 迁移、普通启动只验证)、Backend #180(`pkg/identity`)、RDM #276(identity 子命令与未知位置参数退出)、Dev #477(backend pin 到含 #180 的 `acabb85`)。
|
||||
|
||||
### 11.1 现场快照与 rdmcand 数据归属(SELF,2026-10-12T13:39:21Z)
|
||||
|
||||
快照目录(在线 `sqlite3 .backup` / RDM `VACUUM INTO`,未停服务):
|
||||
|
||||
- `runtime-backups/{dev,rdm1,rdmcand}/20261012T133921Z`
|
||||
- `runtime-backups/{dev,rdm1,rdmcand}/domain-20261012T133921Z`
|
||||
|
||||
只读核对副本,未移动任何业务数据。rdmcand 在 `2026-10-12T06:51:14Z`–`10:02:40Z` 使用 `runtime/dev/data`。该窗口内:
|
||||
|
||||
- dev 库的会话、消息、事件均不落在窗口内。最后一条消息时间 `06:50:43Z`,早于 rdmcand 挂上该目录。会话与用户属于 dev(owner `weichen`、`genui-smoke`)。
|
||||
- 窗口内仅有 13 条 `command_audit`,全部是 `rdm.inspect.*`,owner `weichen`,没有领域事件。
|
||||
- 三份 `rdm.db` 的 `events` 均为 0。dev 的领域库更大(含权限表,schema_version=6),rdm1/rdmcand 的领域库只有字典与 schema 行。
|
||||
- rdm1/rdmcand 的 `agent-system.db` 只有 `2026-10-12T13:19:47Z` / `13:20:12Z` 由候选门禁写入的身份行,没有业务行。
|
||||
|
||||
处置(未执行,需逐项授权):不把 dev 的会话或领域库迁到 rdmcand。没有一份应属于 rdmcand 的历史领域数据需要回迁,因此不触发身份 `adopt` 重审。rdm1/rdmcand 当前库是空壳加已建立的身份行。
|
||||
|
||||
### 11.2 D1 身份流程收尾
|
||||
|
||||
对应 U1 的消费缺口。完成条件:
|
||||
|
||||
- 身份 CLI 只打开既有库:不建文件、不建目录、不迁移。`agent_system_identity` 表(v27 起,列冻结为 instance_id/dbref/schema_version/created_at)缺失则拒绝并提示受控迁移。比本二进制更旧或更新的 schema,只要该表仍在,verify 仍可读。
|
||||
- verify 输出带 `schema_version`。DSN 走 `AGENT_SYSTEM_DSN` 或权限恰好 0600 的 `--dsn-file`;`--dsn` 保留并告警。
|
||||
- 能力文档一份 JSON,经 `version --json` 与 `identity capabilities` 输出。探测只跑 `version --json`,在空目录、清空环境、超时内执行。非 JSON 视为无能力。
|
||||
- 顶层未知子命令 exit 2,不以 `-` 开头才拦截,避免落入 serve。
|
||||
- manifest `identity.db_marker`:`fresh` | `pending` | `established`。新实例首次部署目标目录必须为空,启动建库后 ensure 变为 established。领养时有能力且库已存在则 ensure,否则 pending。pending 只在库文件存在时补齐,不迁移。established 缺行或不匹配时,start/restart/deploy/update/recover/init 全部拒绝;唯一修复入口是显式 `adopt --confirm <instance_id>`,并先打印库大小、关键表行数和最近写入时间。
|
||||
- `svc_lifecycle` 是 start/restart/deploy/update/recover 的共同入口。update 与 recover 逐服务以 `env -i` 启动子进程,不传入 `AGENT_SYSTEM_*`。serve 使用显式环境,并写入 0600 的 `serve.env` 供裸启动与 recover 复用。
|
||||
|
||||
### 11.3 D2 切换事务
|
||||
|
||||
对应 U6 的部署回退。制品进入 `runtime/<name>/releases/<rid>/`,`current` 用临时符号链接加 `mv -T` 切换。`bin`/`plugins`/`htdocs` 改为指向 `current/` 的稳定链接。切换日志 `deploy-journal.json`(0600)先写 phase 再执行。失败回到上一版本并恢复原期望运行态,不覆盖业务库。schema 不兼容时在停旧服务前拒绝。前进迁移必须 `deploy --migrate-schema --confirm <instance_id>` 且先 backup,日志标记 forward-only。能力文档增加 `schema.target` 与 `schema.compatFloor`;每条迁移登记是否破坏旧版读取,漏登记则测试失败。
|
||||
|
||||
### 11.4 D3 真实组合门禁
|
||||
|
||||
对应 U7 的故障验收入口,范围限于部署生命周期。Dev 用 `tests/integration/lifecycle/rdm.pin` 固定 RDM SHA(当前、上一版、无 identity 的旧版)。CI test-pg 按 pin 取固定 SHA,白名单加入 RDM 及其 pins。`make test-lifecycle` 缺 PG、源码或制品即失败,不静默跳过。桩测试不能代替该门禁。RDM 登录入口与账户 CLI 的 DSN 退出命令行依赖账户方案 U7/U5;未就绪的项保持 NOT_RUN,D3 不得标完成。
|
||||
|
||||
### 11.5 验收
|
||||
|
||||
缺一项则对应增量保持未完成:双向混合批次身份不串用;无 manifest 时 deploy/update/recover 一致;无能力、缺行、不匹配在停旧前拒绝且不建库;两次裸重启及换端口、换版本、换目录后身份不变;构建失败、启动即退、健康超时、工作台失败可回滚;切换中断后登记与制品一致;真实 PG 绑定与多实例检查通过且凭据不进命令行、日志和证据;RDM 页面、登录、领域命令和原有数据可验证,不能只看 HTTP 200。
|
||||
|
||||
@@ -7,11 +7,13 @@ execution: code
|
||||
product_contract_source: ce-plan-bootstrap
|
||||
---
|
||||
|
||||
# svc 统一部署与一次性登录 Key 方案 r2
|
||||
# svc 统一部署与一次性登录 Key 方案 r3
|
||||
|
||||
确认状态:**r1 原批准保留;r2 本轮增补待人工评审**。r1 的批准记录为 2026-10-12 用户「批准,继续推进」(五阶段及 U1/U4 规格,允许对应实施和 PR)。本轮用户要求仔细调研、详细方案并「继续」,覆盖方案修订及本地文档准备,不扩展为业务实施、账户变更、迁移、部署、故障注入、推送或合入授权。
|
||||
确认状态:**r1 原批准保留;r2 新增(R13–R15、KTD11–KTD14、U7)的 2026-10-12 批准记录保留;r3 登录恢复实施记录待人工评审**。r2 的批准来自原状态任务 Documents #89(来源提交 `b8df6f3c2a3180b06c61d2303bbfea9a3914f186`),不由 #87 的合入推定。2026-10-14 用户已明确授权智能体接管 Dev #489/#488/#486,继续验证、试行、合入及清理;本轮全部合入由智能体执行,不扩展到部署、共享数据库或其他未纳入任务。
|
||||
U7 进展(历史记录,2026-10-12,未合入):Backend #185 与 Dev #486 的旧候选曾记录 CI success,来源为旧任务记录,不能放行本轮候选。原 U7/U8 候选都占用迁移 28;本轮须同步后按当前主干已用版本顺延,保留主干已有迁移与账户保护。账户 U5 的登录恢复接线见 r3 与 §11;账户 U8 消费审计按其独立范围推进,不由 U7 批准代签。
|
||||
修订记录:r1=2026-10-12 草案经源码复核后定稿(四项取舍采纳;补齐 §6 合同;对齐恢复方案 KTD 与已合入的 recovery U1 实例身份);同日获批并进入推送与 U1/U4 实施。
|
||||
r2=同日复核 dev 登录故障、当前 U1/U4 源码和帮助缺口;保留 R1–R12、KTD1–KTD10、U1–U6 的含义与编号,补充 R13–R15、KTD11–KTD14、U7/U8,并细化 U5。新增内容未批准;不以原批准记录代签新增范围。
|
||||
r2=同日复核 dev 登录故障、当前 U1/U4 源码和帮助缺口;保留 R1–R12、KTD1–KTD10、U1–U6 的含义与编号,补充 R13–R15、KTD11–KTD14、U7/U8,并细化 U5。保留原 r2 批准记录,不以该批准代签其他新增范围。
|
||||
r3=2026-10-13 用户提交《登录流程方案》并指示「按此方案实施」——该指示即登录恢复范围的实施批准;当日实施合入(Backend #187、Frontend #76、Dev #504),合同定稿于 Dev `docs/svc-deploy/2026-10-13-login-recovery-contract.md`,实施记录见 §11。r3 为实施记录与三裁定回写,不改动 R/KTD/U 编号语义。
|
||||
需求来源:2026-10-12 用户提出将 `svc.sh` 增强为统一部署入口(二进制与源码、环境准备、无初始密码开户与账户恢复),并要求一次性 API Key 只能兑换「设置密码」受限会话。负责人:weichen;编制:Cursor Agent。
|
||||
主记录:本文;任务卡:Dev `.task/feature-svc-unified-deploy-login-key.md`。源码路径以 Dev 根目录为基准。
|
||||
|
||||
@@ -232,14 +234,58 @@ flowchart LR
|
||||
|
||||
凭据规则:独立前缀;只存摘要;用途 `activate`|`recover`;状态未使用/已消费/已撤销/已过期;密码变更后旧恢复凭据不可再用。符合 [OWASP Forgot Password](https://cheatsheetseries.owasp.org/cheatsheets/Forgot_Password_Cheat_Sheet.html) 与 [Session Management](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html);保留现有 CSRF 校验。
|
||||
|
||||
## 9. 风险与未授权范围
|
||||
## 9. r2 编制期历史记录:风险与当时未授权范围
|
||||
|
||||
- 实施、故障注入、真机部署、浏览器验收:**未授权 / NOT_RUN**。
|
||||
本节与第 10 节保留 r2 编制时点的原始边界,不表述本轮当前状态。当前批准、接管与交付范围见页首及 Dev #486;登录恢复实施记录见第 11 节。历史 NOT_RUN 保持原对象范围,部署及共享数据库操作仍须另行授权。
|
||||
|
||||
- 编制时点的实施、故障注入、真机部署、浏览器验收:**未授权 / NOT_RUN**。
|
||||
- 本轮交付终点:r2 本地草案、恢复配套修订、任务卡与索引、文档核查和审阅记录;以本地文档提交固定审阅对象并满足同步门禁。新增修订仍待批准,不推进 Dev gitlink、不推送/建 PR;启动/同步工具的任务元数据提交单独记录。
|
||||
- 与 recovery U1 重叠处只做增量,不重做已合入的 manifest 层。
|
||||
|
||||
## 10. 规划进展与下一步
|
||||
## 10. r2 编制期历史记录:规划进展与当时下一步
|
||||
|
||||
- r1 已批准;U1/U4 基础实现存在于当前固定源码,完整浏览器/故障/运行验收不可据此推断通过。r2 的新增需求和设计仍待人工评审。
|
||||
- 首选下一任务(待授权):恢复方案 U8 的 SQLite 服务隔离+本案 U7 账户一致性;先消除共享测试数据和不可归因密码变化,再落实 U5。U2/U3 保持后续。
|
||||
- 前置:审核新增 R13–R15、U7/U8 及 U5 更新,明确实现和隔离测试范围/owner;实现、测试、部署分别授权。Documents 与 Dev 文档草案位于各自独立工作区;正式组合、gitlink 推进与运行验收未执行。
|
||||
|
||||
## 11. r3 实施记录:登录恢复流程(2026-10-13)
|
||||
|
||||
授权:用户 2026-10-13「按此方案实施」(会话指示,覆盖登录恢复范围的实施与合入;
|
||||
代码 Review 与 PR 合入按 Dev `policy/delivery.md` 由智能体执行)。
|
||||
|
||||
### 三项裁定(对 r2/U5 合同的分歧,用户按新方案裁定)
|
||||
|
||||
| 分歧 | r2 表述 | r3 裁定 |
|
||||
|---|---|---|
|
||||
| 登录页长期 API 密钥入口 | 保留并标注集成用途 | 移除日常登录入口;程序化客户端直接带 Authorization 头 |
|
||||
| 管理员网页恢复方式 | 直接设置新密码 | 改为签发一次性登录 Key(旧 HTTP 端点兼容保留,仅前端 UI 下线) |
|
||||
| must-change 首登会话 | full 会话 + 动态拦截 | 登录即建 `set_password_only` 受限会话,`me.sessionScope` 统一驱动设密门 |
|
||||
|
||||
### 已合入(2026-10-13)
|
||||
|
||||
- Backend #187(`f103540d`):迁移 v28(`users/sessions.auth_version` + `account_events` 审计);
|
||||
管理员 `POST/GET /api/admin/users/{owner}/login-keys`、`DELETE .../login-keys/{id}`;
|
||||
改密事务内复验会话与认证版本;登录会话创建绑定认证版本(竞态窗口关闭);
|
||||
主动改密/管理员与 CLI 重置统一单事务;兑换入口按 IP 退避;TLS 下 Secure cookie。
|
||||
- Frontend #76(`0655bc3`):登录页双入口(密码默认 + 一次性 Key,移除 `ask_`);
|
||||
设密门免当前密码、成功后回登录页(消费 `reloginRequired`);刷新按 `sessionScope` 恢复门;
|
||||
用户管理改签发/撤销 Key(明文仅一次)。
|
||||
- Dev #504(`268ef29`):合同文档 + 组件 pin。
|
||||
|
||||
覆盖判定:R7/R8/R9 及 U5 的浏览器接线主体已实现;U7 的登录恢复事务部分已实现,
|
||||
**原子开户/引导、CLI 凭据安全交付与 PG 锁串行仍未实施**,U7 不得据此记完成。
|
||||
|
||||
### 验收证据
|
||||
|
||||
- GATE:Dev #504 HEAD CI 三作业(test / test-pg / svc-realcombo)success;Backend #187 CI success。
|
||||
test-pg 即真实 PostgreSQL 运行本任务 store 测试(含 100 并发兑换单胜、登录竞态)。
|
||||
- SELF(收据,绑定 Dev HEAD `268ef29`):真实浏览器全流程验收 PASS——
|
||||
`login-key.playwright.ts` + `changepw-form.playwright.ts` 于隔离 auth-on 实例
|
||||
(`serve --data /tmp/lr-e2e-data --auth on`,二进制 backend=467718a+frontend=9fc7da2):
|
||||
管理员签发 → 只输 Key 兑换 → 免旧密码设密 → 新密码登录进工作台 → 同 Key 重复兑换被拒。
|
||||
收据 sha256:`be7ae9a2…`(验收)、`b3a9e691…`(终态)。用例文件待 Dev 工作区解封后入库。
|
||||
|
||||
### 遗留(另行任务与授权)
|
||||
|
||||
SSE 存量长连接断流通知;`e2e/login-key.playwright.ts` 入库与 Dev pin;U7 余量;
|
||||
部署与 live 账户验收。详见合同文档「遗留项」。
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
---
|
||||
title: 面向非专业用户的工作台整体界面重设计
|
||||
revision: r0.2
|
||||
status: approved-for-continuous-implementation
|
||||
date: 2026-10-12
|
||||
owner: weichen
|
||||
scope: requirements-and-design
|
||||
implementation: implemented
|
||||
delivery: tracked-in-dev-task-record
|
||||
project-record: persisted
|
||||
---
|
||||
|
||||
# 工作台整体界面重设计 r0.2
|
||||
|
||||
用户在评审 r0.1 后明确授权“开始实施直到完成”。本稿 r0.2 保留已选设计,并通过本次独立任务连续实施、验证、Review 与合入。已有快慢通道执行方案的其他增量不由界面授权自动扩大。
|
||||
|
||||
## 1. 设计目标
|
||||
|
||||
让不懂命令、脚本、模型和代理的用户,通过表达目标、提供材料、查看结果、完成必要确认来推进工作。
|
||||
|
||||
默认界面回答三件事:现在在做什么,已经得到什么,下一步是否需要我处理。用户能够只用对话完成主要工作,也能在需要时展开工作摘要、阅读文件、核对依据。
|
||||
|
||||
用户明确要求:不要过于复杂;以辅助工作为中心;渐进、多层级展示;减少命令和脚本细节;大气、现代、简约、美观、易用。
|
||||
|
||||
本稿的场景假设:主要工作包括材料整理、分析比较、问题审查和文档生成,兼顾日常问答。业务领域的具体审批和发布入口按当前服务端能力提供。
|
||||
|
||||
## 2. 推荐形态与备选
|
||||
|
||||
推荐**渐进展开的三栏工作台**。左侧找项目与历史,中间通过对话推进工作,右侧按需处理工作或文件。普通问答默认收起右栏,复杂工作时提供概览;用户手动收起后不因普通更新反复打开。
|
||||
|
||||
| 形态 | 适用和取舍 | 本稿选择 |
|
||||
|---|---|---|
|
||||
| 渐进三栏 | 对话入口清晰,复杂任务可展开,文件有稳定位置 | 推荐 |
|
||||
| 纯对话 | 学习成本低;长文件、并行工作和多次确认容易淹没在历史消息中 | 作为轻量状态 |
|
||||
| 总览仪表盘 | 跨任务监控方便;默认要求用户理解更多指标和导航 | 仅在确有项目总览需求时另审 |
|
||||
|
||||
不单独建设快通道页、慢通道页或后台管理页。新增功能先判断能否放进现有对话、工作和文件入口。
|
||||
|
||||
## 3. 界面布局
|
||||
|
||||
**左栏:上下文。** 项目身份集中出现一次;新建对话、最近对话、搜索;文件和已启用的领域工作区放底部;账户与个人设置沉底。管理员操作只由管理员入口提供。
|
||||
|
||||
**中栏:推进工作。** 当前对话标题;用户的目标和材料;助手的结论、简短说明、必要动作;输入区上方一条工作状态。附件入口始终易找。权限设置保留清晰入口,展开说明其实际含义;初次使用采用现有默认值,不暗中扩大授权。
|
||||
|
||||
**右栏:工作 / 文件。** 工作按需要你处理、当前关注的工作、其他进行中或排队、新成果排列。完成历史收纳后仍可找回。文件负责列表、预览、编辑和下载;全屏阅读是同一个预览的放大。来源点击也进入同一预览对象,定位能力不足时说明定位范围。
|
||||
|
||||
左栏约 200–240,工作右栏约 320–420,中央弹性。正式落地继续消费已有拖拽宽度和文件阅读档规则。空间不足时先隐藏辅助栏;手机显示一个主视图,工作和文件按需打开,并有明确返回对话入口。
|
||||
|
||||
## 4. 渐进展示层级
|
||||
|
||||
| 层级 | 显示内容 | 打开方式 |
|
||||
|---|---|---|
|
||||
| L0 概览 | 后台工作数量、必要确认、新成果 | 一条状态行或小徽标 |
|
||||
| L1 摘要 | 业务目标、真实状态、当前工作、最多 3 条重要发现、缺项、下一步 | 当前任务卡或对话锚点 |
|
||||
| L2 依据与范围 | 阶段结果、来源、覆盖范围、未决问题和结论更正 | 原位置展开 |
|
||||
| L3 执行记录 | 按工作阶段分组的动作、结果和有权限查看的诊断信息 | 明确点击执行记录 |
|
||||
|
||||
默认 L0/L1,不展开所有任务。必要确认、重要限制和失败影响不能藏在 L2/L3。L3 不是模型内部思考的展示入口,也不改变日志和来源的访问权限。
|
||||
|
||||
示例任务卡:
|
||||
|
||||
> 整理三份项目材料 · 进行中
|
||||
> 正在核对:会议结论与需求说明
|
||||
> 当前发现:上线时间出现两种说法;3 项需求缺少验收条件
|
||||
> 待核查:评审意见中的补充要求
|
||||
> 查看依据与范围
|
||||
|
||||
没有阶段成果时诚实显示“尚无阶段结论,正在读取材料”。以上业务发现是示例数据,当前 U1 骨架并不证明已经具备真实阶段发现发布能力。
|
||||
|
||||
## 5. 快慢通道的连续体验
|
||||
|
||||
用户界面主要使用“助手正在处理”“后台继续整理”等业务语言。快通道是当前对话回合,慢通道是后台工作,不是由用户选择的快慢速度档位。
|
||||
|
||||
| 时刻 | 用户看到的内容 | 表述边界 |
|
||||
|---|---|---|
|
||||
| 发消息或材料 | 接收结果、可先回答的内容、接下来处理的范围 | 已选文件不等于上传成功;解析不等于分析完成 |
|
||||
| 任务登记或排队 | 同一工作对象显示已登记、排队中 | 登记成功才能说已登记;未开跑不能写进行中 |
|
||||
| 工作进行中 | 当前工作、真实阶段结果、缺项 | 没有可信进度就不显示百分比或预计完成时间 |
|
||||
| 用户继续输入 | 后台继续工作时可继续对话;前台忙时说明消息排队 | 发送不等于即时执行,不承诺已改变正在跑的任务 |
|
||||
| 有新成果 | 更新原卡;重要结果提供一条对话通知 | 不逐条回投工具动作,不把所有任务复制成另一条聊天流 |
|
||||
| 等待用户 | 操作、范围、影响和明确选择 | 等待、执行、生成、用户认可和正式发布分开 |
|
||||
| 完成或失败 | 结论、最多 3 个要点、范围或缺项、文件和下一步 | 保存失败不得声称已交付;部分完成不能冒充完整结果 |
|
||||
|
||||
后台更新不切换用户正在读的文件,不抢焦点,不把历史阅读强行滚到底部。状态恢复期间保留最后已知内容并注明“正在重新连接,最新进展待确认”。
|
||||
|
||||
## 6. 按工作选择展示形式
|
||||
|
||||
统一骨架保持稳定,内容形态随任务改变。默认由工作目的决定,用户无需先学习或配置一种展示模式。
|
||||
|
||||
| 工作 | 默认成果形式 | 进一步展开 |
|
||||
|---|---|---|
|
||||
| 简单问答 | 一段结论,必要说明 | 依据与例子 |
|
||||
| 材料整理 | 主要结论、问题和缺项 | 材料覆盖清单、来源 |
|
||||
| 方案比较 | 一条建议、关键差异表 | 判断依据、取舍和适用条件 |
|
||||
| 问题审查 | 按影响排列的问题清单 | 原文、影响、处理建议 |
|
||||
| 文档生成 | 草稿文件、完成范围、需要评审的事项 | 文件预览与后续修订 |
|
||||
| 多步骤流程 | 当前阶段、已完成阶段、必要动作 | 阶段结果与历史 |
|
||||
| 用户确认 | 简明操作说明、影响、选择 | 参数与诊断详情 |
|
||||
|
||||
图表仅在数量、趋势或关系能帮助判断时使用;可理解的短表不升级成图表。生成式任务页面作为可选增强,关闭插件后仍能通过任务卡、文字和文件读到主要结果。领域审批不能成为所有基座任务的固定步骤。
|
||||
|
||||
## 7. 等待确认与异常
|
||||
|
||||
确认卡先写操作及影响,例如“依据三份材料新增 1 份项目草稿,保留原件,不对外发送”。涉及覆盖、发送、发布或权限变化时,关键对象和影响必须在默认层显示。避免只有“是否执行”而没有范围。
|
||||
|
||||
对话和右栏操作同一确认对象。提交中阻止重复提交;已处理同步更新;超时显示“正在核实处理结果”,查清后再允许后续动作。示例稿只演示本地状态同步,不证明服务端幂等和恢复。
|
||||
|
||||
异常表述使用“发生了什么 → 对结果的影响 → 用户可以做什么”。例:“评审意见未能读取;已整理另外两份材料,完整结论尚未生成;可补充清晰版本或先讨论已有结果”。错误代码、脚本与输出置于授权可读的详情。动作只按服务端当前能力显示;未核验的暂停、独立取消、续跑、自动重试不进入默认设计。
|
||||
|
||||
## 8. 视觉规则
|
||||
|
||||
沿用 DESIGN.md 和 @ui/tokens.css:灰白表面阶梯、单色反色主按钮、发丝边框、克制语义色;清晰的标题与正文层级;常用信息保持可读,不以缩小字号装下所有内容。
|
||||
|
||||
大气来自稳定分栏、整齐对齐、合理阅读行长和区块间距;简约来自减少同时出现的内容。没有营销式大标题、装饰渐变、速度表盘、满屏彩色卡片或默认工具日志。
|
||||
|
||||
字型走 --fs-ui-*,界面字号可调。状态同时有文字和形状。折叠消费 @ui Collapsible,动效只用 mk-* 并响应减少动效。交互稿复制固定 UI 令牌,实际使用当前 Collapsible 源码与 MotionKit,不新建颜色和动效体系。
|
||||
|
||||
## 9. 当前依据与依赖
|
||||
|
||||
本轮只读源码核对,来源 SELF;没有对生产或当前 dev 服务作功能验收。
|
||||
|
||||
| 对象 | 固定提交 | 核对点 |
|
||||
|---|---|---|
|
||||
| Dev | 4d362537d0e8755a03b1757b5bad92779a064b33 | DESIGN.md、policy/delivery.md、既有规划 |
|
||||
| Frontend | 1edd872c554f666ba43353da7e6f0605ecec311b | Workbench.tsx、Conversation.tsx、Workspaces.tsx |
|
||||
| Backend | acabb85e2ae970f834defae916c7539d0a47993d | spawnBackgroundOpts、CancelRun、createBackgroundCard、finishBackgroundCard |
|
||||
| UI | 83e80f5648649c3cc070f4dbc6bf118996828ae8 | tokens.css、Collapsible.tsx、motion.css |
|
||||
| Documents | 3cc6438030803b8e2355d2867766e9654203f265 | 快慢通道展示 r1.1 及 U1 实施计划 |
|
||||
|
||||
当前读到的源码已有三栏“工作 / 文件”、前台忙时输入排队、后台并行限制、排队工作、精炼卡片骨架以及失败 CardFailed 映射。这里只说明源码形状,不推断已部署与运行表现。
|
||||
|
||||
与既有方案衔接:`modules/documents/docs/proposals/2026-10-12-fast-slow-channel-display.md` 是快慢通道摘要与异步投影的已有主记录;本稿补充整体交互与各种成果形式,不另起一套状态或快照契约。U2/U3/U4 的真实阶段发现、持久恢复、确认闭环和窄屏完善继续以原记录及后续批准为准。
|
||||
|
||||
## 10. 实施需求
|
||||
|
||||
以下为本次界面实施与验收范围;实现消费真实已有能力,不伪造尚未发布的阶段发现。
|
||||
|
||||
| ID | 需求 | 优先级 | 可判定的验收方向 |
|
||||
|---|---|---|---|
|
||||
| UI01 | 对话能完成主要工作 | P0 | 关右栏仍能读摘要、核对依据、处理确认、打开成果 |
|
||||
| UI02 | 普通问答保持轻量 | P0 | 无后台工作时不生成空任务卡和空进度条 |
|
||||
| UI03 | 默认内容可支持下一步 | P0 | 用户能说明当前工作、结果范围、必要下一动作 |
|
||||
| UI04 | 快慢通道连续展现 | P0 | 前后台并行、排队和完成状态归属正确且不重复刷屏 |
|
||||
| UI05 | 四层渐进阅读 | P0 | 默认无命令日志,关键限制和确认不被折叠藏起 |
|
||||
| UI06 | 成果按目的呈现 | P1 | 整理、比较、审查和生成各能支持对应工作判断 |
|
||||
| UI07 | 状态与动作忠实 | P0 | 不伪造进度,不暴露未支持控制,不把失败显示成功 |
|
||||
| UI08 | 同一文件同一预览 | P0 | 对话、来源、文件列表均进入同一预览位置 |
|
||||
| UI09 | 确认结果一致 | P0 | 双入口、重复点击、超时未知和已处理均有一致表现 |
|
||||
| UI10 | 阅读稳定 | P0 | 普通后台更新不抢焦点、换文件或改阅读位置 |
|
||||
| UI11 | 窄屏和大字可用 | P0 | 320/390/736/1024/1440 及 18px 字号必要动作可达 |
|
||||
| UI12 | 遵守设计系统 | P0 | 令牌、Collapsible、MotionKit、对比度守护符合规范 |
|
||||
| UI13 | 能力与权限匹配 | P0 | 未启用领域入口不显示;摘要与来源不绕过访问控制 |
|
||||
|
||||
最终产品验收场景:三个附件无文字发送;前后台并行及排队;确认双入口;完整/部分/失败结果;查看来源与文件;刷新和断线;新对话;窄屏、大字、键盘及减少动效。r0.1 设计评审时,真实模型、真实后端和真实浏览器任务验收均为 NOT_RUN;实施期结果见第 13 节,示例交互稿不能代替验收。
|
||||
|
||||
## 11. 落地次序建议
|
||||
|
||||
1. **整体界面与文案。** 在既有三栏和 U1 上整理默认内容、必要操作和阅读路径。优先确定 UI01–UI03/UI05/UI08/UI12;不在此增量改变后台执行契约。
|
||||
2. **动态工作摘要。** 接续既有快慢通道 U2/U3,在真实快照与检查点之上显示业务发现、范围和恢复状态;避免另外安排重复任务。
|
||||
3. **成果形式与适配。** 衔接 U4,完成比较、审查、可选任务页面、窄屏和具体领域入口。先用结构化文字/表格,再增强生成式展示。
|
||||
|
||||
r0.1 布局与展示已获连续实施授权,当前按 r1 计划交付界面。完成本增量后的首选衔接仍是既有快慢通道 U2/U3 的真实阶段发现与恢复验收;需先核对其在途任务和批准范围,不能由本界面任务重复启动或改变路由。
|
||||
|
||||
## 12. 授权与实施记录
|
||||
|
||||
来源:2026-10-12 用户在本聊天评审 r0.1 后指示“开始实施直到完成”。模式 authorized-continuous;阶段 1–10 在本稿界面范围内连续推进,平台门禁和高后果双钥匙保留。启动检查从已登记干净 Dev 检出捕获,后由 make task-start 创建 feature/work-companion-ui,并导入原始 SELF 收据。保护主检出的 Frontend 更新与其他任务现场。
|
||||
|
||||
实施计划见 [r1](2026-10-12-work-companion-ui-plan.md);进展和原始证据仅维护于 Dev .task/feature-work-companion-ui.md。PR、CI、Review、合入与部署分别记载,不因本授权预先标为通过。
|
||||
|
||||
## 13. 实施进展与能力边界
|
||||
|
||||
2026-10-12:渐进任务卡、轻量对话/输入、响应三栏和单一异步状态投影已形成可审阅候选。SELF 验证包括 Frontend 210 与 UI 155 单元测试、类型/设计守护/knip、Dev make test 与 make build;现有 Playwright 11 个展示场景、6 个移动导航场景及隔离 HTTP/MockRunner 2 个真实接口链路场景通过。原始命令、精确对象和完整输出以 Dev 任务卡为准,测试成功不推断已经合入或部署。
|
||||
|
||||
原始独立代码 Review 已完成,必要问题均已有整改候选;最终精确版本复审、组合 CI 与合入进展只维护在 Dev 任务主记录,方案正文不复制第二份交付状态。UI 仓原 CI 在下载 GitHub action 时失败,交付补充改用既有平台固定 SHA 检出和 Node22 镜像,保留原测试;安全和规范 Review 及实际平台结果均须记录。
|
||||
|
||||
动态摘要只消费系统发布的真实内容:缺少阶段发现时显示诚实占位,不生成示例百分比、ETA 或虚构成果。真实模型阶段发现质量 NOT_RUN,后台自动路由和模型提示词未在本增量修改。旧运行服务未更新;最终组合、Review、GATE 和本任务安全收口以 Dev 主记录为准。
|
||||
@@ -0,0 +1,154 @@
|
||||
# Work companion interface implementation plan r1
|
||||
|
||||
> **For agentic workers:** Implement in independent units with ce-work native workers; the orchestrator owns integration, evidence, commits, Review and Gitea delivery. Use test-first coverage for behavior changes. User authorization: “开始实施直到完成”; continuous execution is limited to the approved interface design.
|
||||
|
||||
**Goal:** Deliver the approved simple, modern, progressive workbench through real project, conversation, activity-card, confirmation and file APIs.
|
||||
|
||||
**Architecture:** Keep the three existing pane responsibilities. Project existing ActivityCard bodies into readable summaries in the UI library; Frontend integrates them into conversation and work panes. Preserve server authority and harden event, query and action races in the one Frontend store. No new task executor, model routing, database schema or UI vocabulary is required.
|
||||
|
||||
**Tech Stack:** React 19, TypeScript, existing @ui Collapsible/MotionKit/tokens, Vitest, Playwright, Go backend with existing API and SSE.
|
||||
|
||||
**Spec:** [Approved interface design](2026-10-12-work-companion-ui-design.md), UI01–UI13; [existing fast/slow design](2026-10-12-fast-slow-channel-display.md), U1 skeleton and applicable presentation rules. Dynamic model-generated findings remain dependent on the existing U2/U3 work; this interface renders real available content and an honest placeholder otherwise.
|
||||
|
||||
## Global constraints
|
||||
|
||||
- Settled user decision: three pane workbench, conversation first, “工作 / 文件” in the same right pane, one preview object.
|
||||
- Settled user decision: concise default content and progressive depth; necessary confirmation and outcome limits stay visible.
|
||||
- Colors/radii/type consume @ui/tokens.css, type uses --fs-ui-*, motion only mk-*, folds use Collapsible.
|
||||
- No percentage, ETA, pause, independent cancel, resume or retry buttons unless supplied by a verified server action.
|
||||
- State is derived from real cards, runs, files and responses; no prototype example data enters production.
|
||||
- Model internal thinking and command parameters/output do not occupy the normal reading layer.
|
||||
- Main checkout and other task worktrees are protected. All owned changes live in feature/work-companion-ui.
|
||||
- Evidence uses the Dev make evidence tool. Local checks are SELF; current PR HEAD CI is GATE.
|
||||
- Component branches are based on their authoritative origin/main. Dev is based on R0 4d362537d0e8755a03b1757b5bad92779a064b33.
|
||||
- No deployment/restart of existing services, data migration, credentials or branch-protection changes.
|
||||
|
||||
## Review focus
|
||||
|
||||
1. Older SSE frames or delayed queries must not replace newer cards or inject data into a different conversation/project.
|
||||
2. Replay of a currently running conversation must still reconstruct its live output while duplicates are dropped.
|
||||
3. A confirmation submitted through either view must block duplicate submission and represent unknown results honestly.
|
||||
4. Closing auxiliary panes and opening files must leave necessary work and confirmation paths accessible at 320px and 18px UI type.
|
||||
5. New background results must not take over an existing file, focus or reading position; result summaries must retain failure and coverage limits.
|
||||
|
||||
## U1 — Progressive activity cards and work groups
|
||||
|
||||
**Own files:** UI src/ActivityCardView.tsx, src/InlineConfirmCard.tsx, src/InboxList.tsx, src/index.ts, src/ui.css, new src/activitySummary.ts, src/ProgressCardBody.tsx and focused UI tests. Do not change generated contracts or tokens.
|
||||
|
||||
**Consumes:** Existing ActivityCard/UINode and DocBridge; U1 body keys 状态/正在做/当前发现/剩余/下一步. Unknown words remain supported by the generic renderer.
|
||||
|
||||
**Produces:** Existing ActivityCardView remains source-compatible; export activitySummary/cardStatusLabel/groupActivityCards as pure projections. CardViewCallbacks and InlineConfirmCallbacks may add `actionState?: (card: ActivityCard) => 'submitting' | 'unknown' | undefined`; existing callbacks remain optional. Core vocabulary is unchanged.
|
||||
|
||||
- [ ] Add tests for queued and running labels, modern failed and legacy done+danger, no-findings placeholder, internal material keys hidden by default, real document nodes still reachable, and confirmation buttons disabled for submitting/unknown.
|
||||
- [ ] Run the focused Vitest tests before production edits; record expected red assertions through evidence.
|
||||
- [ ] Build the projection with literal canonical body keys and card states; never interpret arbitrary output as a new execution fact.
|
||||
- [ ] Render L1 summary first, remaining body and source/range information in Collapsible, diagnostic metadata behind a nested explicit record entry. Known failure/remaining/next-step content must remain visible.
|
||||
- [ ] Keep unknown/legacy bodies intact in the generic detail renderer. Tables, structured lists and document references retain their current renderer.
|
||||
- [ ] Group unpinned work as needs-action, active, results, history, preserving order inside each group. Pinned items remain stable.
|
||||
- [ ] Simplify chrome; use text plus status shape and existing neutral surfaces.
|
||||
- [ ] Verify full UI suite, tsc and design/contrast guards; hand off files and red/green evidence without committing.
|
||||
|
||||
Example behavioral expectation:
|
||||
|
||||
```ts
|
||||
const queued = { ...card, status: 'active', body: [{ type: 'kv', kv: [['状态', '排队中'], ['材料键', 'mk_private']] }] }
|
||||
expect(cardStatusLabel(queued)).toBe('排队中')
|
||||
expect(groupActivityCards([completed, pending, queued]).map(g => g.key)).toEqual(['needs-action', 'active', 'results'])
|
||||
```
|
||||
|
||||
## U2 — Conversation, input and inline work reading
|
||||
|
||||
**Own files:** Frontend src/components/Conversation.tsx, src/components/ProcessTimeline.tsx, src/messageparts.ts if required by process policy, new src/components/ConversationWork.tsx, new src/companion-conversation.css, focused conversation/messagepart tests. Do not edit styles.css, App, Workbench or store.
|
||||
|
||||
**Consumes:** Existing store fields and actions; existing UI ActivityCardView/Collapsible/DocBridge, including the additive actionState callback. The orchestrator supplies state.cardActionStates.
|
||||
|
||||
**Produces:** ConversationWork renders current cards from the same store in an inline Collapsible; default ordinary Q&A has no empty progress. Component CSS imports live in the owned component file.
|
||||
|
||||
- [ ] Add failing behavior tests for normal Q&A without progress, task summary reachable while right pane is closed, progress record folded by default, failure/limits visible, and process final answer outside its fold.
|
||||
- [ ] Replace command-oriented empty states with goal/material prompts and three optional natural-language examples that fill input rather than trigger hidden work.
|
||||
- [ ] Simplify header; keep execution profile, cross-reading and session settings inside a clearly labeled settings fold, preserving existing behavior and consent.
|
||||
- [ ] Keep add-materials and send visible; move permission selector into operation settings without changing its effective value. Explain queue state and upload failures in user language.
|
||||
- [ ] Show a light continuity line from real runs/cards with confirmed counts; inline work uses the same cards/actions as the work pane.
|
||||
- [ ] Fold tool parameters and output even during running by default; keep a compact real phase label and preserve manual expansion. Do not display model internal thinking as ordinary content.
|
||||
- [ ] Protect scroll reading and reset compose/expanded context correctly on conversation switches; do not remove artifact or rewind capabilities.
|
||||
- [ ] Verify focused tests and the integrated Frontend suite; hand off files and evidence without committing.
|
||||
|
||||
Example behavioral expectation:
|
||||
|
||||
```ts
|
||||
expect(showProcessInline(live, true)).toBe(false)
|
||||
expect(showProcessInline(live, false)).toBe(true)
|
||||
// Render real ConversationWork with zero cards: no progress object is produced.
|
||||
// Render with a real active progress card: summary is present independent of rightCollapsed.
|
||||
```
|
||||
|
||||
## U3 — Responsive shell and context navigation
|
||||
|
||||
**Own files:** Frontend src/App.tsx, src/components/TopBar.tsx, src/components/TaskSidebar.tsx, new src/companion-shell.css, new src/workbenchLayout.ts and focused shell/layout tests. Do not edit store, Conversation, Workbench, shared styles.css or UI.
|
||||
|
||||
**Consumes:** Existing leftCollapsed/rightCollapsed/rightTab/previewExpanded and store pane/file operations. May add only local ephemeral responsive state, not another asynchronous task owner.
|
||||
|
||||
**Produces:** Desktop three pane layout; narrow screen one active pane with clear contextual return actions, using the same Workbench/PreviewPane objects. Export a pure layout selector if a decision is needed for tests.
|
||||
|
||||
- [ ] Write failing behavioral tests for single-pane navigation, restoring conversation, expanded file reading, and no hidden-only essential operation.
|
||||
- [ ] Match the approved calm prototype through spacing and type hierarchy, preserving canonical palette and default existing theme preferences.
|
||||
- [ ] Keep project identity on the left, conversation identity central, work/files on the right. Rename primary creation to 新建对话 where it actually creates a conversation.
|
||||
- [ ] Reduce duplicate permanent chrome; retain project creation/search/account/admin/available workspace paths.
|
||||
- [ ] Adapt to 320/390/736/1024/1440; hide/return controls remain keyboard- and touch-accessible. Do not let stored pane widths force horizontal overflow.
|
||||
- [ ] Keep file expansion as one preview enlargement, not another overlay or fourth pane.
|
||||
- [ ] Verify layout tests and report desktop/mobile screenshots after integration; hand off owned files without committing.
|
||||
|
||||
## U4 — One state owner, safe updates and confirmation feedback
|
||||
|
||||
**Own files:** Frontend src/store.ts, new src/eventProjection.ts if a pure helper is useful, src/components/Workbench.tsx, src/components/PreviewPane.tsx only when integration requires it, focused store tests. Orchestrator implements this unit.
|
||||
|
||||
**Consumes:** Existing SSE event identity/seq/runId, conversation detail resumeSeq/lastSeq, cards API, project events, cardAction and resolveHITL APIs.
|
||||
|
||||
**Produces:** Store `cardActionStates: Record<string, 'submitting' | 'unknown'>`; both work and inline confirmation callbacks read this same map. Current session/project cursors and query generation checks remain in one store.
|
||||
|
||||
- [ ] Add red tests for duplicated and stale cards; delayed conversation/project list queries after switching contexts; foreground replay versus background agent notes; duplicate action submission; unknown response followed by a server query; new Surface while reading a file.
|
||||
- [ ] Guard event application by current context and per-stream applied sequence. Live replay uses its own replay cursor and never re-applies older card/plan/status projection effects.
|
||||
- [ ] Guard asynchronous queries by their requested context and generation/sequence so slow snapshots do not wipe newer events or another context's state.
|
||||
- [ ] Suppress background progress in foreground token output; update actual runs/cards instead of creating an unrelated LiveState.
|
||||
- [ ] Lock confirmation/action submission by card or HITL identity before awaiting. Clear on observed server outcome. Unknown results remain disabled until read-only reconciliation determines the current state; do not blindly resend an effect.
|
||||
- [ ] Show submitting and unknown feedback at both entrances. Preserve all server-supplied actions and their original scope.
|
||||
- [ ] Leave current file/Surface selection and explicit pane preference intact on background updates; show a small new-result cue rather than auto-opening.
|
||||
- [ ] Default new users to a light, compact conversation layout with right pane closed; keep saved theme/layout choices and explicit file opening.
|
||||
- [ ] Verify focused store tests, integrated Frontend tests, and browser cross-view flows.
|
||||
|
||||
Example behavioral expectations:
|
||||
|
||||
```ts
|
||||
store.applyEvent({ ...newerStatus, seq: 12 })
|
||||
store.applyEvent({ ...olderStatus, seq: 11 })
|
||||
expect(store.getState().cards[0].status).toBe('done')
|
||||
// Hold the first action response; call through the second view and assert one API request.
|
||||
// Resolve or query the real returned card and assert both views leave submitting together.
|
||||
```
|
||||
|
||||
## U5 — Integration, browser acceptance and delivery
|
||||
|
||||
**Own files:** Dev DESIGN.md, PROJECT.md, task card and exact gitlinks; Documents design/plan/index and delivery record; Frontend e2e/work-companion.playwright.ts and isolated browser fixtures if required; external screenshots and receipts.
|
||||
|
||||
- [x] Record authorization and implementation units; retain original startup evidence unchanged.
|
||||
- [x] Integrate all workers, inspect owned paths and contracts, run authoritative focused tests, and commit logical component changes with Why/Evidence/Impact/Refs bodies.
|
||||
- [x] Update DESIGN §9.6 and information architecture to the approved progressive behavior; no palette changes are planned, so do not change canonical token values merely to create a paired diff.
|
||||
- [ ] Run make task-sync through evidence at acceptance, review and merge checkpoints; resolve any parent/component conflicts without altering unrelated owner work.
|
||||
- [x] Pin exact committed component revisions and run Dev make test plus make build through evidence.
|
||||
- [x] Browser checks: normal conversation; three selected attachments; background task plus foreground input/queue; pending confirmation through either entrance; done/failed/partial results; real file preview; reading preserved during update; duplicate/stale updates; refresh/switch; all five widths and 18px type.
|
||||
- [x] UI fixture-driven browser cases validate presentation only. Use an isolated real backend/browser smoke for API wiring, file/confirmation/card persistence where feasible. No mock model findings are reported as live-model acceptance.
|
||||
- [ ] Run required simplification and independent code review; fix findings, re-run affected checks, and record reviewer/object identity.
|
||||
- [ ] Push component branches, create and attach Gitea PRs, verify their current HEAD required CI and merge in dependency order. Update Dev pins to merged revisions, verify combination CI at current Dev HEAD, Review and merge Dev PR.
|
||||
- [ ] Fold/close only this task card under continuous authorization. Preserve or safely reclaim only owned workspace artifacts. Do not modify active main checkout state for other tasks.
|
||||
|
||||
## Definition of done
|
||||
|
||||
UI01–UI13 are mapped to observed source/tests/browser outcomes or an explicit inherited capability limit; no prototype fixture enters product state. All changed components compile and relevant tests pass. Current-head mandatory CI is verified before merge. Review findings are closed. The actual merged Dev combination and saved evidence are recorded. Existing running services remain unchanged; deployment is a separately identified operation.
|
||||
|
||||
Continuous authorization covers implementation, verification, reversible isolation, documentation, commit/push/PR, agent Review/merge and task-specific safe closure. Stops apply to genuine scope changes, unowned content collisions, missing current-head platform gates and high-consequence dual-key operations. These conditions do not require re-approval of routine already-authorized work.
|
||||
|
||||
## Delivery status
|
||||
|
||||
2026-10-12: U1–U4 implementation candidates are integrated; U5 local combination and browser checks passed as SELF evidence. Original independent review is complete; the required fixes are implemented and locally verified. Final fixed-version review, current-head platform CI/merge and safe closure are tracked only in the Dev task main record; this plan does not maintain a second delivery-status copy. Code review may produce small corrective iterations; each has its own fixed object and relevant replay. The UI CI bootstrap repair is required to run the retained checks, not a waiver of them. Actual merged versions and final verification remain recorded in the Dev task card; no existing service is deployed by this task.
|
||||
|
||||
2026-10-12 corrective candidate: UI0da2e3a / Frontend43d1933. SELF: UI155 and Frontend210 tests with type/knip checks, 11 presentation plus6 mobile-navigation browser cases,2 isolated realHTTP/MockRunner cases. The live attachment case now proves exact upload→send→persist associations across reload. The review repairs cover source links, per-option context, real browser scroll/focus, terminal reconciliation, action feedback ownership, explicit preview intent, latest outcomes and visible public explanations. These are interface and state-projection corrections; no live-model routing, prompt or existing-service deployment change. Final delivery facts are recorded in the linked Dev PR/task archive.
|
||||
@@ -0,0 +1,52 @@
|
||||
# IAM I1 阶段 7 正式测试与验收候选
|
||||
|
||||
日期:2026-10-13(北京时间);负责人:weichen;测试执行:Codex;状态:用户已通过阶段 7。正式代码 Review、PR、CI、合入和部署分别记录,不由本页代签。
|
||||
|
||||
用户在本会话回复“确认”,对应 Dev `4af5956`、Documents `064d4b5`、RDM `70e27b08` 的阶段 7 报告及下述明确缺项。按 Dev `policy/delivery.md` 进入智能体负责的阶段 8–9;同步后的新组合须重新验证与独立 Review。工作区清理、部署和 U3–U9 仍需各自授权。
|
||||
|
||||
## 批准与范围
|
||||
|
||||
用户回复“批准”,对应 [阶段 6 实施交付](2026-10-13-iam-i1-review.md) 的 Documents c023551、RDM b93908e、Dev 72ed8b4。批准原版本保留,恢复同步后的测试版本另列。本次按已获批 [统一方案 r1](2026-10-13-identity-role-permission-plan.md) 的 I1=U1–U2 及 [权限合同](2026-10-13-iam-i1-permission-contract.md) 验证当前公开命令/API边界;不关闭 R1–R20 全部目标,不实施 U3–U9,不操作现有服务、生产数据库或真实账号。
|
||||
|
||||
恢复处理包括:Dev Documents 同步冲突保留上游项目成员规划及三份 I1 批准文档原文;RDM 采用上游 `rdm.project.member.set-role` 合法命令 ID,保留 I1 身份包装。没有恢复旧权限旁路,没有变更 RDM pins;所有失败、恢复、同步收据保留。
|
||||
|
||||
## 固定对象与完整收据
|
||||
|
||||
| 对象 | 固定版本及结果 | 原始记录 |
|
||||
|---|---|---|
|
||||
| Dev 集成组合 | `10789653f989da6dc8a5ecc72d996dc2764208db`,同步目标 `ee9b437b22b49f96e1bc65f79417b22e8e82a37c`;`make test` 退出 0 | Dev 任务卡 SELF 收据 `ea7b77587b568d968594b0cb90c5362cab27d8eab1492da8cdea14d74e43d11d` |
|
||||
| RDM 完整组合及 HTTP | `70e27b08c65d8e966a11b1d30723414ec3e36f8e`,同步目标 `6c689caa1fa271c2a16174427df51a9b8919c4e0`;`make test`+真实 HTTP+产物/测试摘要检查退出 0 | RDM 任务卡 SELF 收据 `6e684a9047e43b0bdafbc71604ab5debe06bf437d1e3c95c4169d310f11d70c0` |
|
||||
| 独立最小重放 | `/root/i1_phase7_review` 未参与源码修改;先在 `58a23f8c` 重跑 39 个顶层 TestIAMI1,再审查作者材料并重跑最终 HTTP 10 组;退出 0 | 已导入 RDM 卡的完整 SELF 工具收据 `6bbb0f747e41c28d3c2327c587e162072a69495573def6f97a6d1657eb0b0d76`、`c7edde369566552acf4060500985a4a80ea004af80455446de9a215f64f89587`;工具标签不自行升级 |
|
||||
| RDM 二进制 | SHA256 `93aabc13041cf5a5c5636ebd0c88979a4d0f6fd0f79ba1272defc75176a75d81`;从实际组合产物运行,没有使用 Vite 或仅源码模拟 | `bin/PRODUCT_MANIFEST.json` 与上述工具收据 |
|
||||
| HTTP helper | SHA256 `a7d1d3260f4a62f0cb14b91339506419e9be306f2d0e3f7c74a6e77e76a458d4` | RDM `.task/artifacts/iam-i1-http-acceptance.py`;代码与测试材料已提交 |
|
||||
|
||||
RDM 固定 Backend `0f192a481388184df39f81c28b0587a7e16ec3ca`、Frontend `4965de269a441a7df02b46d8533067f044e79b8b`、UI `bfecf8b51f9a0fdbd9a13590cddf8fc06b7ae700`;前端 dist 摘要为 `13acbec506086fe8`。Dev 新组合与 RDM 产品各自固定、各自检查;不能用 Dev 新接口存在证明旧 RDM pins 已消费其能力。后续只记录文本的提交不改变这些行为对象;最终记录提交及工作树检查另见任务卡。
|
||||
|
||||
完整命令输出由 evidence 工具保存于两个任务卡,本文只提供判据和结果摘要,不转写输出、不提升来源等级。测试本地来源为 SELF;用户批准、受信 CI、平台账号独立批准及部署各自独立。
|
||||
|
||||
## 需求到证据
|
||||
|
||||
| I1 要求 | 正常/异常/边界判据 | 当前结果与测试 |
|
||||
|---|---|---|
|
||||
| R6/R12 系统与项目作用域 | 合法管理员创建/配置/任命角色成功;获 A 的 project.settings 者可改 A 名称,但全局 role/cap/admin transfer 被权限拒绝;body 伪造 actor/owner 不改变认证身份 | PASS;注册命令 TestIAMI1+真实 Bearer HTTP,先检查命令已注册,再要求权限原因,不把未知命令或 schema 拒绝计通过 |
|
||||
| R7/R8 管理资格不授 B 业务访问 | /api/me 明确实际平台管理员身份;A 创建者且管理员对 B 的成员、权限、归档和审计操作拒绝,当前项目清单不显示 B;合法角色获授者可建 B | PASS;真实新实例 /api/commands/{id}+项目/审计相关 Go 正反例 |
|
||||
| R9 创建者也受硬 cap | 已确认 Alice 在 A 的 doc.write 允许并有 allow 覆盖;保留 default=true,只关闭 cap;实际高危命令确认后因上限拒绝 | PASS;HTTP 隔离 cap 变量;Go 创建者 cap、平台 cap、未知角色动作与读策略故障等边界 |
|
||||
| R11 停用/换岗/旧覆盖 | 旧 doc.write allow 后换到未定义该动作角色,执行及解释拒绝;停用前 doc.read 允许,停用后消失,执行/矩阵均显示已停用原因 | PASS;HTTP 精确原因与前后矩阵+TestIAMI1;没有借其他已存在拒绝原因替代停用测试 |
|
||||
| R18 私人原件/草稿与读取范围 | 真实 held 原件仅上传者可确认;管理员与未知 batch 获相同不透明拒绝且无实际 B 项目或文件信息;私人候选、差异、快照、审核状态、聚合读面/模型输入按当前 owner/阶段/grant 判定 | PASS;真实 HTTP 上传确认+SQLite/已注册命令实际正文和持久状态负例;本次不声称完整 U5/U6 资源职责模型已实现 |
|
||||
| R12/R18 幂等回执和 outbox | 操作/项目/主体/资源不匹配 opID 不返回他人回执;合法重放保留;outbox 归属与业务在同 Tx 写入,仅送到实际 owner Host,未知旧归属保持 pending | PASS;TestIAMI1 实际回执和 SQLite 状态+既有原子/失败重试回归 |
|
||||
| 注册和组合回归 | 当前 set-role 等命令 ID 正确注册并保留身份校验;根页为实际 React embed、未认证命令 401;RDM 29 项 Web、全部 Go;Dev 治理、公开边界/pins、库、Core、Backend、Frontend/UI、命令检查 | PASS;两套 make test 及当前产物真实 HTTP;不把 HTML 获取等同于浏览器交互验收 |
|
||||
|
||||
## HTTP 测试过程及独立复核
|
||||
|
||||
实际 HTTP 使用全新临时 SQLite、三名合成主体和随机 API Key;平台首位管理员在其他开户之前由可信 CLI 建立,/api/me 核验其真实身份。服务仅绑定随机回环端口,强制关闭执行工具,环境不继承 DSN、服务实例绑定或模型密钥,HTTP 禁用代理。真实私有会话和确认卡到最终回执的路径执行高危命令;native 项目仅为确认上下文,不作为 RDM project.create 政策的通过证据。测试结束只终止自己的 PID;成功临时场景回收,失败场景保留用于诊断,不修改既有实例。
|
||||
|
||||
初次 HTTP 在未经过高危确认流程时拒绝,该结果没有被计为权限通过;补齐确认路径后重验。首位管理员创建顺序错误同样保留失败证据,不关闭原防接管机制。独立审阅又指出停用/默认与 cap 的两处测试假阳性风险;已分别加停用前后读权及原因检查、保留 default/allow 只关 cap。最终独立 HTTP 重跑 10 组通过,审阅范围内无剩余 Critical/Important。
|
||||
|
||||
## 缺项、兼容边界与验收决定
|
||||
|
||||
- 全产品浏览器交互和真实模型任务级前后对照:NOT_RUN。本轮 I1 没有业务 UI 实现,已规划出口为直接命令/API与当前回归;完整浏览器及 Agent 闭合属后续单元。工具描述真实模型对照仍是明确缺项:本轮未建立固定模型/配置/任务集/费用范围,mock 与 HTTP 不能替代模型行为。补救为另行明确测试条件后执行任务级对照,在后续 Agent/全产品验收前闭合;不能计 PASS。
|
||||
- PostgreSQL、多实例、在途后台最终提交 epoch、账号有效态/恢复、多职位/项目选用及完整三权:本轮完整验收未执行;按 U3–U9 依赖和各自授权推进,不迁移生产 DB。
|
||||
- 已批准的 I1 默认拒绝保留:无范围证明的 whole-prefix 知识撤销和公共全量自举拒绝;没有可信 Host 项目证明/资源分类的共享读取拒绝;audit.read 不随管理员或创建者自动授予;旧未知归属 outbox 不推测 owner。恢复这些能力须新公开提供者/消费者合同,不由此次测试擅自补接口或改 pins。
|
||||
- PR/受信 CI/GATE、正式阶段 8 Review、合入、部署及工作区回收:NOT_RUN。独立提前审阅和本地重跑不代替平台条件。
|
||||
|
||||
原提交给用户的阶段 7 决定范围:固定 I1 U1–U2 的命令/API边界与回归结果,以及上述明确缺项/既定兼容限制。提交时结论为“本地测试已通过,待人工验收”;用户随后回复“确认”,已在页首记录为阶段 7 通过。原长期方向及下一任务仍为获批方案 I2/U3,需另行授权,当前不启动。
|
||||
@@ -0,0 +1,193 @@
|
||||
# IAM I1 权限边界与公开扩展合同 r1
|
||||
|
||||
负责人:weichen;编制:Codex;更新时间:2026-10-13。
|
||||
依据:[用户、职位角色与分层权限统一方案 r1](2026-10-13-identity-role-permission-plan.md)
|
||||
(Documents `a088809`,原文 SHA256 `39b8e9a6e078dc509bd80118c1807ce6ed23e4466e5902b51f4bfa255d55c0a1`)。
|
||||
用户已批准该方案并授权 I1=U1–U2,原实施终点为本地人工评审;阶段 6、7 已分别获用户“批准”“确认”。当前按 Dev policy/delivery.md 进入智能体 Review、PR、CI 与合入,状态及固定对象见[验收记录](2026-10-13-iam-i1-acceptance.md)。迁移、部署、工作区清理及后续增量未授权。
|
||||
本合同为 U1 产物,冻结已批准语义与提供者/消费者责任;新增公开接口仍须对应模块实现、固定版本及合同验证,不能据此宣称能力已提供。
|
||||
源码、业务测试及运行验收结果以 I1 任务卡的工具收据为准;本文不复制测试结果。
|
||||
|
||||
## 1. 当前增量与最终目标
|
||||
|
||||
最新用户裁定取代旧“管理员拥有全部业务权限”“创建者不受职位 cap”“每人仅一个生效职位”的现行解释。
|
||||
历史会议、原方案、旧批准记录和 `.tmp` 原件保留;旧结论只用于解释历史行为。
|
||||
系统管理员管理系统与授权主数据;读取他人业务内容必须有具体项目和资源授权。
|
||||
职位支持一职多人、一人多职,项目明确选用有效职位绑定;新任命不自动增加既有项目权限。
|
||||
通用职位、绑定、默认/上限与系统授权迁至 Backend 是已批准设计;RDM 保留项目成员、项目选用绑定、项目覆盖、资源及文档职责/状态。
|
||||
|
||||
| 层 | I1 范围 | 后续范围 |
|
||||
|---|---|---|
|
||||
| 文档 U1 | 需求裁定、动作目录、角色 cap、隐私、公开扩展申请与验收合同 | 按固定公开版本补提供者/消费者验证 |
|
||||
| 执行端 U2 | 在现有 RDM 单绑定和旧管理台账上收口可达越权路径;实际结果另见任务卡 | 账号有效态、受控目录及恢复能力 U3;通用职位与多绑定 U4;项目明确选用 U5 |
|
||||
| UI/Agent/迁移 | 不以文档保存证明能力已就位 | 矩阵、统一工具、完整撤权与数据迁移分别按 U7–U9 授权实施 |
|
||||
|
||||
I1 的 legacy 单绑定适配不是最终多职模型:旧账号至多一个专业角色,项目尚无显式 bindingId 集合。
|
||||
已有绑定必须先检查角色有效态、动作定义与 cap,再计算默认/项目覆盖;停用或失效不能回落为无绑定成员默认。
|
||||
未绑定旧会员的关系默认只能作为已登记的 legacy 兼容来源,仍受平台 cap、项目关系和资源限制;不能伪装成新的职位绑定或最终模型的资格证明。
|
||||
U4/U5 迁移后无有效选用绑定的业务动作默认拒绝;迁移差异须单独评审,不在 I1 静默改造数据。
|
||||
旧 RDM 管理台账在 I1 仅为明确系统管理动作的兼容来源,不能生成项目成员关系、业务 grant 或资源 bypass;`Host.IsAdmin()` 同样不能代替业务授权。
|
||||
I1 还将当前分发 Host 的平台管理员身份显式适配为上述四项受保护系统动作;必须同时满足认证 actor 与 Host.Owner 一致,不接受 body 的管理员声明,也不把该适配扩展到其他未知动作或业务动作。细粒度系统 grant 的通用权威仍属 U4。
|
||||
|
||||
## 2. 动作目录与配置主体
|
||||
|
||||
scope 由受信 `ActionMeta`/权限注册表确定,不接受请求自报 scope,不按字符串前缀推断。
|
||||
系统动作只消费系统来源;项目动作限定实际项目;资源读取还须匹配实际资源、分类与读取动作。
|
||||
下表为 I1 稳定动作合同。“后续”项仅冻结目录,当前尚未提供相关接口。
|
||||
|
||||
| actionId | scope | 配置/执行主体 | 附加边界 |
|
||||
|---|---|---|---|
|
||||
| `system.roles.manage` | system | 受保护系统管理者 | 角色创建/编辑/停用/读取;不能经项目覆盖获取 |
|
||||
| `system.roles.assign` | system | 受保护任命者 | 任命在可委派上限内;不能间接授予受保护系统权限 |
|
||||
| `system.policy.manage` | system | 受保护策略管理者 | 平台 cap 与权限政策;保护最后有效管理者 |
|
||||
| `system.admin.transfer` | system | 当前有移交资格的系统管理者 | 明确移交目标;旧 `rdm.perm.transfer` 映射此门禁 |
|
||||
| `project.create` | system | 有明确系统/职位建项 grant 的有效用户 | 创建者管理 cap 资格见 §3;不接受项目 allow |
|
||||
| `project.archive` | project | 目标项目的合法管理者 | 保留稳定 ID;纠正旧目录误标的 system scope |
|
||||
| `project.settings` | project | 目标项目创建者/委任管理者或合法获授者 | 仅本项目设置与覆盖;不能进入全局角色、cap 或管理员移交 |
|
||||
| `member.manage` | project | 本项目合法管理者 | 成员及选用角色管理;不得替他人做本人受限重选 |
|
||||
| `duty.assign` | project | 本项目合法分配者 | 候选有效成员+对应资格 cap+三权异人;分配不代签 |
|
||||
| `stage.advance` | project | 有阶段推进 grant 的成员 | 阶段准入准出、当前状态 |
|
||||
| `doc.read` | project | 有读取 grant 的成员 | 文档阶段范围+受控正文职责/明确资源授权 |
|
||||
| `doc.write` | project | 有编制资格的指定编制人 | 具体文档、当前状态、冻结版本;不因管理权取得 |
|
||||
| `doc.publish` | project | 有发布资格及对应职责的成员 | 固定整文版本及已批准状态,不替代批准签字 |
|
||||
| `review.participate` | project | 有评审资格的指定审核/批准人 | 按具体职责决定可执行动作;只能批注及通过/驳回 |
|
||||
| `trace.edit` | project | 有追溯编辑 grant 的成员 | 文档层/项目层裁定范围与状态分别检查 |
|
||||
| `knowledge.publish` | project | 有发布 grant 的成员 | 明确提交/发布;不能借发布读取私人原件 |
|
||||
| `audit.read` | project | 有明确业务审计 grant 的当前成员 | 独立于正文读取;当前角色动作 cap、平台 cap 与范围均满足 |
|
||||
| `system.settings.read`/`system.settings.write`及设置子项 | system,后续目录 | 对应系统管理者 | 模型、插件、Agent、检索等设置分项授权 |
|
||||
| `system.users.view`/`create`/`edit`/`disable`、`credential.recover` | system,后续目录 | 对应账号管理者/恢复提案者 | 编辑资料不能改管理员资格;恢复见 §6 |
|
||||
| `permission.manage`、`knowledge.read`、`trace.read`、`document.read`/`export`、业务审计导出 | 后续目录,project | 按注册元数据和当前业务关系 | 当前 `doc.*` 等 ID 不静默重命名;新增需公开版本映射 |
|
||||
|
||||
`audit.read` 是 I1 新独立项目动作:必须由合法项目管理者在上限内明确授予,或来自明确配置的角色默认 grant;管理身份本身不提供审计 grant。
|
||||
非成员 admin、仅持 `Host.IsAdmin()` 的主体、无审计 grant 的创建者、cap 已收紧的旧获授者均拒绝。
|
||||
系统安全日志只披露必要安全动作、结果及不透明对象标识,不能包含业务正文、文件名、项目名、内容摘要或完整业务差异;业务审计仍走 `audit.read`。
|
||||
|
||||
| 旧入口/元数据 | I1 兼容规则 |
|
||||
|---|---|
|
||||
| `rdm.role.create`/`action`/`disable`/`list` | 命令 ID 保留,系统门禁改为 `system.roles.manage` |
|
||||
| `rdm.role.assign` | 命令 ID 保留,系统门禁改为 `system.roles.assign` |
|
||||
| `rdm.perm.cap` | 命令 ID 保留,系统门禁改为 `system.policy.manage` |
|
||||
| `rdm.perm.transfer` | 命令 ID 保留,系统门禁改为 `system.admin.transfer` |
|
||||
| 旧 `project.archive` scope=system | 目录版本标记改为 project;具体项目重验;旧系统覆盖写法不继续接受 |
|
||||
| `project.settings` 作为全局门禁 | 不兼容保留;项目 grant 不被翻译成系统 grant |
|
||||
| 未登记 ID、旧示例 `admin.transfer`/`business-audit.read` | 不是隐式别名;拒绝执行/写入,采用上表稳定 ID 或显式版本映射 |
|
||||
|
||||
## 3. cap、创建者资格与撤权
|
||||
|
||||
最终系统动作路径为:有效账号 ∩ 受信系统动作 ∩ 平台允许范围 ∩ 受保护规则 ∩ 明确系统 grant 或完整系统职位默认路径;项目覆盖不能参与。
|
||||
最终项目动作对每个有效且本项目选用的 binding 建立完整路径:
|
||||
|
||||
`有效成员/管理关系 ∩ 已定义动作 ∩ 平台 cap ∩ 本职位 cap(含范围) ∩ 项目覆盖/当前默认 ∩ 资源关系 ∩ 阶段/状态 ∩ 文档职责`。
|
||||
|
||||
至少一条完整路径允许才放行,不拼接不同职位的 grant 与资源范围;平台禁止、项目明确 deny 和资源禁止对所有路径生效。
|
||||
`allow` 只能替换默认 grant,不能创造未配置动作或越 cap;`deny` 阻断该成员该项目该动作的全部路径;`inherit` 使用当前默认。
|
||||
停用、解绑、换岗、cap 收紧、账号停用和成员移除后重验当前资格;遗留 allow 不能复活旧权。
|
||||
创建者关系只提供本项目管理默认,其有效角色 cap 与平台 cap 仍先验;A 创建者不能管理 B,不能读取私人资源或代签。
|
||||
|
||||
建项前校验创建者角色组合具备 `project.settings`、`member.manage`、`duty.assign` cap 资格;这些角色 default 可关闭,由创建者关系提供项目内管理默认。
|
||||
最终创建项目、创建者成员关系及所选 binding 在同一领域事务落地;宿主绑定以可恢复状态和幂等对账处理。
|
||||
已有项目遇 cap 收紧保留 `createdBy` 与历史归属,阻断受影响动作并说明等待重新任命;不能扩大 cap 恢复管理。
|
||||
|
||||
受限“重新选择本人项目职位”是后续独立动作,不复用 `project.settings`:仅当前有效负责人本人,从账号当前有效任命中明确选取具备管理 cap 的 binding,按项目当前版本确认。
|
||||
仅此动作可使用尚未被本项目选用的任命;它不改变负责人、不恢复遗留 allow、不清除 deny、不授予资源读取或三权。
|
||||
系统任命者不能代选;无合格任命时保持等待。项目内移除最后负责人须保护实际可操作管理资格;系统必要撤权不因这一保护而被阻止。
|
||||
|
||||
## 4. 资源、正文与审计读取合同
|
||||
|
||||
认证 actor、资源真实 owner/projectId/resourceId/分类来自执行端受信上下文;客户端标识只能定位对象,不能授予访问。
|
||||
本人的私聊、私人原件和个人草稿属于私人资源;在当前账号有效且资源确属本人时按自有资源规则读取,不因放在项目下变为受控正文。
|
||||
受控文档正文即使物理由本人生成,也须具体文档职责或明确资源授权、当前项目资格及当前 cap;真实 owner 相等不绕过受控规则。
|
||||
审核/批准职责仅开放送审正文与明确关联材料,不开放未分享原件、私聊或私人草稿;分享只授予指定资源的只读能力,不授予编写或签字。
|
||||
项目知识只由明确提交/发布产生;成员身份不意味着私人资源或所有受控正文全量可读。
|
||||
历史签字、职责与事件保留;历史内容读取依旧使用当前授权,时间点重建不恢复当时权限。
|
||||
读取、下载、列表、搜索、stream、模型上下文均遵循同一分类和当前判定;裁剪列表后再返回数量/分页,拒绝不得泄露存在性。
|
||||
I1 现有项目聚合审计 DTO 含正文预览,故除 `audit.read` 外还必须具备当前完整项目 `doc.read`;阶段范围受限者不能通过全项目聚合审计取得范围外正文,按资源裁剪的细粒度审计由 U5 完善。具体文档导出检查该文档的 `doc.read` 和阶段范围,不把审计 grant 当成导出 grant。
|
||||
I1 私人 pending/rejected 草稿仅提案人可读与决定;知道 proposalId、拥有项目管理权或文档职责都不能采纳/拒绝他人私稿。已采纳正文仍按当前文档读取授权逐项过滤。原件批次确认只限上传者本人,管理台账可披露经当前管理授权限定的业务元数据,不能因此读取或确认私人原件。
|
||||
|
||||
## 5. 公开扩展:现有能力与四要素申请
|
||||
|
||||
以下现有公开面是 I1 原合同的 Backend `0f192a481388184df39f81c28b0587a7e16ec3ca` 快照,参考 `pkg/extension/extension.go`、`host.go` 与 `surface.txt`,不导入 Backend internal。
|
||||
该快照的 `SurfaceVersion=2.11.0-experimental` 源码声明不是部署或消费者可用性证明,也不代表后续主干能力;同步后的组合必须重新核对提供者及消费者实际固定版本。
|
||||
|
||||
| 现有能力 | 提供者/消费者 | 足够性与边界 |
|
||||
|---|---|---|
|
||||
| EXT-18 `AdminProvider.IsAdmin()`/`Request.HostProjectID` | Backend 分发 Host → RDM | 平台管理身份与宿主项目定位;不能证明系统分项授权、账号有效态、RDM 项目关系或业务访问 |
|
||||
| EXT-19 `AccountLister.ListAccounts(cursor, limit)`,`AccountEntry{Owner,Valid}` | Backend → 授权目录消费者 | 最小身份目录,非资料页;不提供姓名、联系方式、多职绑定或写权;缺能力不允许新增产品路径无校验继续 |
|
||||
| EXT-8b `ResourceAuthzQuery`/`ResourceAuthorizerV2`/注册口 | Backend 构造受信查询 → RDM 提供策略 → Backend 执行 | 现有六要素为 actor/action/resourceType/resourceId/owner/projectId;读取专用,V2 对域内读权威(含自有命中);未注册的 V1 回落不能替代 I1 必需的资源限制 |
|
||||
|
||||
以下是 U1 冻结的公开扩展申请四要素,符号为合同草案,I1 不新增导出实现、不更改 surface 版本。
|
||||
|
||||
| 申请 | 场景 | 希望的公开符号/路径 | 现有注册点为何不足 | 兼容方式 |
|
||||
|---|---|---|---|---|
|
||||
| IAM-P 政策与动作目录 | UI/命令/工具需查询 scope、cap、有效绑定、权限解释与版本;角色通用权威迁移后供 RDM 同源判定 | 可选 `PermissionCatalogProvider`、`AuthorizationProvider`;公开目录/判定/解释与授权管理预览提交服务 | `IsAdmin` 只有布尔身份;`ActionMeta` 在 RDM 内部;EXT-8b 仅资源读,无法供系统管理或管理写入事务使用 | 新可选接口及版本化 DTO;旧 Host 不加必实现方法;RDM legacy 适配与新权威切换分别固定版本 |
|
||||
| IAM-D 受控人员目录 | 项目选人需要稳定身份、有效态和最小辨识字段,系统资料管理需独立授权 | 可选 `AccountDirectoryProvider` 与版本化查询/投影 DTO;既有 EXT-19 保留 | `AccountEntry` 仅 owner+valid,没有字段权限、搜索模式、可披露辨识资料及多职;私自扩展所有账号资料会扩大披露 | 新可选接口;旧 `ListAccounts` 不改变返回隐私范围;不得向旧消费者塞入联系方式 |
|
||||
| IAM-R 资源与当前政策上下文 | 跨原件/草稿/正文/审计分类,查询当前 policy/duty epoch,撤权影响读面与后台提交 | 新版资源查询/决策 DTO 及可选政策上下文提供者;保留 `ResourceAuthorizerV2` | 六要素无分类、职责/版本/epoch;bool 返回不能携带可披露原因与版本,读适配器不能承担写入事务 | 新版本资源接口或明确 DTO 增补;禁止未知字段零值放行,必需提供者缺失即拒绝;版本协商与双读仅作诊断 |
|
||||
| IAM-C 账号本人恢复 | 管理者只能提出恢复,账号本人经独立证明才能取得可兑换设密能力 | 公开恢复提案/本人确认/兑换回执合同,隔离恢复凭据与业务会话 | `IsAdmin`、目录、资源授权均不提供本人证明或安全凭据交付,不能用个人资料代替 | 新路径/可选能力,不向普通管理员交付目标账户可兑换 Key;旧不满足证明的线上路径明确拒绝 |
|
||||
|
||||
| DTO | 必须冻结的字段与版本语义 |
|
||||
|---|---|
|
||||
| `PermissionDescriptor` | `actionId`、`label`、`description`、`scope`、`resourceTypes`、`group`、`conditions`、`delegationLevel`、`risk`、`descriptorVersion`;稳定 ID 不随改名变化,新增项默认拒绝 |
|
||||
| 授权查询/解释 | 受信 actor、actionId、资源定位与实际归属、当前状态/版本、选用 binding;输出 allow/deny、可披露 reason、来源链、`authorityEpoch`;解释只限本人或有权管理对象 |
|
||||
| 目录查询/投影 | 稳定 userId/owner、valid、获授权姓名/登录名/工号/职位投影、cursor/limit、精确/模糊模式及字段/状态过滤、`directoryVersion`;未授权字段不返回、不参与匹配;电话、邮箱、部门、备注只在独立授权资料面披露 |
|
||||
| 管理 patch/预览 | 固定对象 ID、expectedVersion、authorityEpoch、patch 摘要、幂等键;预览不代替提交授权,非法对象/越 cap/冲突整体拒绝;跨模块写入不冒充单库事务 |
|
||||
| 资源决策扩展 | 受信分类(私人/发布知识/受控正文/业务审计)、resourceVersion、policyVersion、dutyVersion、authorityEpoch 与决策原因;缺失或不认识分类拒绝,禁止请求自报归属 |
|
||||
|
||||
目录 r1 的 scope 修订不能只改显示标签;执行端必须同时拒绝错误作用域写入。公开版本须同时登记导出面快照、版本号、变更表、提供者/消费者合同及固定组合。
|
||||
缺必需能力、未知动作/字段/状态、政策读取失败、归属不一致、过期版本、失效绑定均 fail-closed;不能用 `Host.IsAdmin()`、缓存 allow、V1 粗粒度授权或手填 owner 兜底。
|
||||
通用迁移前 legacy 台账只在其声明范围使用;迁移时保留 userId/owner/roleId/projectId/createdBy,禁止双主写入,不生成旧管理员的永久业务 grant,回滚不复活旧越权。
|
||||
|
||||
## 5a. 当前公开能力缺口的 I1 处理
|
||||
|
||||
以下是 U2 收口所需的默认拒绝策略,不是后续能力已实现声明;本地候选的实际验证见 I1 评审记录。
|
||||
|
||||
- 未归属事件盘点、归属迁移、全量 outbox 队列必须另有 owner 批准的精确资源范围。I1 的 `Runtime.SetLegacyAccessAuthorizer` 为实例内受信集成点,查询绑定 actor/action/project/seq;不存在用户自授命令,不持久化、不跨重启继承。无提供者或提供者失败即拒绝。迁移另检查目标 `knowledge.publish`。
|
||||
- 当前 `Host.KnowledgeDelete` 仅能删当前 owner 的整个插件前缀,不能限定项目。`rdm.knowledge.revoke` 先验证目标项目 `knowledge.publish`,再明确拒绝执行,不能借 A 项目 grant 删除 B 项目索引。
|
||||
- `rdm.init` 当前实现读服务器路径并写全量未归属域,公开命令拒绝;可信本地 CLI/bootstrap 仍需操作授权。本轮不另造公开目录读取和项目初始化能力。
|
||||
- Host↔RDM 绑定须证明两个项目的管理资格;旧映射行与请求中的 HostProjectID 都不是此证明。I1 的实例内受信 Host 项目授权集成点必须绑定 actor/action/两个实际项目,缺失即拒绝绑定、解绑及基于映射的共享访问。旧映射不自动升级成授权证明。
|
||||
- 现 Backend `project/list` 授权成功后会返回项目下全部 owner 工件元数据,缺少逐资源 owner 裁剪,I1 拒绝此聚合共享。项目级 search 无发布分类证明时也拒绝跨 owner 检索;自有私人资源的具体读取路径保留。
|
||||
- 项目聚合 DTO 尚无安全的按阶段裁剪投影时,要求当前完整 `doc.read`;章节/文档接口按实际对象检查阶段。业务审计另需显式 `audit.read`。后续安全裁剪不得用 UI 隐藏代替执行端检查。
|
||||
- 新 outbox 回执以事务内 `rdm_audit_outbox_scope` 记录实际 project/owner,只送入对应 owner 的 Host;旧未知归属回执保持 pending,禁止按下一调用者猜测归属。该关联表为新增领域元数据,无历史自动归属,本轮未执行生产数据库变更。
|
||||
- status/resume/cancel 按私人批次的真实 owner 判定;恢复另检查当前项目写权及生命周期,取消仅保留本人停止私人任务的能力。opID 重放必须绑定操作、项目、主体与实际资源,冲突不能返回另一资源回执。
|
||||
|
||||
| 扩展申请补充 | 场景 | 希望的公开符号/路径 | 现有注册点不足 | 兼容方式 |
|
||||
|---|---|---|---|---|
|
||||
| IAM-K 项目级知识撤销 | 合法 A 项目发布者仅撤销 A 已发布资源 | 可选项目/资源限定的知识撤销 DTO 与提供者;实际命名待模块评审 | EXT-9 whole-prefix 删除跨同一 owner 多项目;无可靠逐 ref 删除契约 | 新可选公开接口,旧缺失拒绝;固定提供者/消费者版本,不改 pins 猜测能力 |
|
||||
| IAM-H 宿主项目管理证明与资源裁剪 | 绑定需双方管理证明,共享读取需当前项目授权与实际资源分类 | 受信 Host 项目授权查询/证明及逐件资源投影提供者;实际命名待模块评审 | EXT-18 仅给当前 actor 的管理员位与项目定位;EXT-8b project/list 是整面 bool,无逐件过滤 | 新可选契约、权威对象与版本;旧映射只作定位,缺失默认拒绝;RDM 私有受信适配不能冒充 Backend 公共实现 |
|
||||
|
||||
## 6. 账号恢复证明与交付
|
||||
|
||||
普通管理员仅发起恢复提案;本人须使用管理员不能单方改写或取得的既有有效会话确认,或预先建立的本人恢复证明,才取得可兑换设密能力。
|
||||
姓名、电话、邮箱、工号均为可选资料,不自动成为恢复证明;新证明建立或更换不能由恢复提案管理员单独完成。
|
||||
无独立本人验证条件时拒绝线上恢复,不向普通管理员签发可兑换的目标账户 Key;异常人工恢复由另行批准的 owner 操作处理。
|
||||
恢复能力限制为一次消费、目标账号、设密用途与有效期,不生成业务会话;消费后本人使用正式凭证重新认证。
|
||||
本合同不证明恢复实现已具备;U3须验证“管理员提出恢复后自行设密接管业务身份”负例,旧路径未收口前 R7 不得闭合。
|
||||
|
||||
## 7. 验收矩阵与证据边界
|
||||
|
||||
R1–R20 到 RDM 原 UR/SR 的映射由 RDM `docs/proposals/2026-10-13-iam-i1-contract-adoption.md` 维护,原需求 ID 不重新编号。
|
||||
|
||||
| 判据 | I1 文档核对 | 行为验收归属 |
|
||||
|---|---|---|
|
||||
| 系统动作不可由项目 override 或 `project.settings` 获取 | §2逐动作 scope/旧命令映射 | U2:普通成员合法本项目设置成功,全局角色/cap/移交拒绝 |
|
||||
| 创建者仍受有效角色 cap,遗留覆盖不越界 | §1/§3 | U2:创建者 cap=false、角色动作未定义、停用/换岗及旧 allow 负例 |
|
||||
| 管理员无业务身份旁路,审计独立授权 | §2/§4 | U2:admin/Host.IsAdmin 非成员及无 audit grant 拒绝;合法成员 audit grant∩cap 正例 |
|
||||
| 私人资源与受控正文分开 | §4/EXT-8b 消费边界 | U2 可达路径;U5/U6 统一资源及职责、当前版本完整验收 |
|
||||
| 一职多人、一人多职、项目明确选用 | §1/§3/IAM-P | U4/U5:新任命不扩既有项目、解绑再任命不复活、完整路径不拼接 |
|
||||
| 账号目录敏感投影与本人恢复 | §5/§6 | U3:未授权字段不匹配/不返回;管理员不能取得本人兑换凭据 |
|
||||
| 冻结文档轮次、撤权与迟到事件 | §3/§4/IAM-R | U6/U8:当前职责与 cap 重验;旧卡/Surface/SSE/后台最终提交拒旧 |
|
||||
| 单权威迁移、版本兼容、完整组合 | §1/§5 | U4/U9:旧→新差异、双主拒绝、当前固定提供者/消费者和制品验收 |
|
||||
|
||||
U1 只检查文档差异、链接、动作与 scope 一致性、R1–R20 追溯及原方案摘要保持;无行为变更,不运行业务测试。
|
||||
本地检查来源为 SELF;审核与正式验收须按任务规则同步对象、独立重放并核验 GATE/REPLAY 身份及 SHA。
|
||||
公开实现、业务测试、浏览器、真实模型、数据库迁移、服务运行、部署与正式验收均不能用本合同的保存结果代替。
|
||||
|
||||
## 8. I1 宿主改名投影的已批准修订(2026-10-13)
|
||||
|
||||
用户已批准[委任改名契约修订与修复计划 r1](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/src/commit/4ee4eb99a95460d6660f05a67181357b67e2e956/docs/proposals/2026-10-13-iam-i1-host-projection-amendment.md),批准对象原文摘要为 `3eee5714cce974ce13229b3e184bc3aa763a5e0819fdf7dcf088dafe68b1ed2a`。正文维护在 RDM 一处;批准状态与实际实现、测试、Review、CI 和合入分开记录。
|
||||
|
||||
合法项目 `project.settings` 可以委任改名;现有 `ProjectHost` 的管理修改保持 owner-only。RDM 仅对这一动作建立受信的单目标投影适配:先以实际认证 actor 判定当前项目设置权及状态,再核对域/宿主绑定/物理项目的完整身份,只用受信创建者的 scoped Host 执行该 hostID 的改名。不借创建者身份重新授权,不把投影句柄返回或传入其他业务动作;无需额外 `doc.read`,私人读取和 Native work 不扩权。
|
||||
|
||||
首次改名要求 ready;失败恢复必须对应同事务持久的改名意图、同一主体/项目/host/创建者/目标与版本,并再次检查实际 actor 的当前资格。未知 failed/create 不恢复,未就绪时读/work 仍拒绝。该元数据只属于 RDM 项目投影,不修改旧账号或项目身份,不实施生产迁移,也不冒称完整跨库 epoch。
|
||||
|
||||
命令与 HTTP lifecycle 都使用原请求 Host 审计实际操作者。Backend 审计的 `Actor=plugin:rdm` 继续表示插件来源;业务 actor 由受信 Host.Owner 和审计 evidence.actor 记录。命令保留既有 DTO,HTTP 保留 core.Project 及公开元数据的脱敏设置;不得带出物理 owner 的原始管理设置。
|
||||
|
||||
本修订不新增 Backend 公开符号或放宽其 owner-only 管理规则。正式通过须覆盖合法委任及无读取权管理、cap/停用/非成员、实际归属变化、失败/重启/未知恢复、两入口审计和真实 HTTP;未通过当前组合验证时不能声称 I1 完成。
|
||||
@@ -0,0 +1,73 @@
|
||||
# IAM I1 实施候选与人工评审记录
|
||||
|
||||
负责人:weichen;实施协调:Codex;日期:2026-10-13;状态:阶段 6 已由用户批准;阶段 7 测试候选已形成,待用户验收。原阶段 6 对象与收据保留,最新状态见下方批准记录及验收报告。
|
||||
|
||||
本页维护已批准统一方案 I1 的实际进展;原方案原文摘要保持不变。本轮只执行 U1–U2,交付终点为“给我评审”,不启动后续增量。
|
||||
|
||||
## 批准对象与当前候选
|
||||
|
||||
- [统一方案 r1](2026-10-13-identity-role-permission-plan.md):用户已批准并授权 I1=U1–U2;原文 SHA256 `39b8e9a6e078dc509bd80118c1807ce6ed23e4466e5902b51f4bfa255d55c0a1`,Documents `a088809` 保存原批准快照。
|
||||
- [I1 权限合同 r1](2026-10-13-iam-i1-permission-contract.md):稳定动作与 scope、角色/平台 cap、独立业务审计、隐私及公开扩展申请。提供者缺失默认拒绝,合同文档不能证明接口已提供。
|
||||
- RDM 初始 R0:`b1fe932883d2a55f0373bb0930950da3d12d2b5e`;同步后的 main:`2f1a36f55a4979262e386150af26085d4d15b2a1`,包含职责批量分配与权限覆盖删除。两项注册冲突已保留主干功能并接入身份包装;组合结果须重新测试。
|
||||
- RDM 已独立审阅的行为候选:`dfb9c407858173ba501a623631c17643bd1985b5`(代码截至 `4e3d7665e973838b77d6e81164b8d70540de907d`,后者之后仅同步任务卡;之后旧测试断言/import与证据记录继续收口)。最终收据与记录提交可能前进,测试有效性按行为文件/组件是否变化核对。
|
||||
- [Dev 任务卡](/home/weichen/projects/Agent-System-Dev-wt-feature-iam-i1-permission-boundaries/.task/feature-iam-i1-permission-boundaries.md) 与 [RDM 任务卡](/home/weichen/projects/Agent-System-RDM-wt-feature-iam-i1-permission-boundaries/.task/feature-iam-i1-permission-boundaries.md) 保存启动、红测、失败、同步、绿测完整工具输出,来源均为本地 SELF。
|
||||
|
||||
## 本次行为变化
|
||||
|
||||
| 边界 | 候选中的具体变化 | 对应要求 |
|
||||
|---|---|---|
|
||||
| 系统与项目 | role/cap/任命/移交走独立受保护系统 action;项目 settings 不能授予这些动作;当前 actor 必须匹配 Host.Owner。新增 unset 也检查注册项目 scope、实际成员与当前管理权 | R6/R8/R12 的 I1 部分 |
|
||||
| 当前资格与 cap | 创建者、管理者与成员均受平台 cap;已绑定职位先检查存在/有效/动作定义与 cap;停用、换岗及旧 allow 不能回落或越界。矩阵解释与执行共用评估器 | R9/R11 的当前单绑定部分 |
|
||||
| 项目业务访问 | 去掉域管理员和 Host.IsAdmin 的跨项目业务旁路;项目清单按当前成员关系;归档仍可由合法 archive 权限恢复,其他业务写入拒绝 | R7/R8/R11 的 I1 部分 |
|
||||
| 业务审计 | 新独立 audit.read,平台 cap 初始关闭,关系默认不授予;实际授权成员还须当前完整 doc.read。聚合审计含正文预览,不能借阶段受限读权读全项目 | R7/R18 的 I1 部分 |
|
||||
| 正文读取与导出 | 章节/文档按真实对象检查阶段;标题导出只接受唯一匹配、按同一解析目标授权与生成;差异、审核状态、法规快照检查阶段/真实项目归属。无法安全阶段裁剪的聚合 DTO 要求完整读权 | R12/R18 的 I1 部分 |
|
||||
| 私人原件与草稿 | pending/rejected 私人提案只允许提案人查看/采纳/拒绝,采纳还验编制职责;上传原件只允许本人确认;管理上传视图为元数据;历史上传清单不跨项目混入 | R18 的当前可达路径 |
|
||||
| 私人批次 | status/resume/cancel 先按真实 owner 判定;私有与不存在统一不透明拒绝;恢复另验当前 doc.write/成员关系/职位/cap/生命周期,不能凭旧属主身份重新入队;本人停止私人流程保留 | R11/R12/R18 的当前入口 |
|
||||
| 模型输入与写回结果 | draft.compose 发模型前需要目标正文读取范围;结论确认在返回 stored text 前需完整 doc.read。写权不能代替读权 | R12/R18 的当前入口 |
|
||||
| 回执归属 | opID 使用 JSON 元组绑定操作/项目/主体/资源,短路与事务内重放一致,旧不可信 key 拒绝。outbox 新回执以同事务关联真实项目与 owner,只送入对应 Host;旧未知归属项保留 pending | R12/R18/R20 的当前入口 |
|
||||
|
||||
完整多职位、项目明确选用绑定、账号有效态、恢复证明、三权全模型、政策 epoch 与所有后台最终提交撤权均未在 I1 实现。这里的 R 行不是完整 R1–R20 关闭声明。
|
||||
|
||||
## 验证与证据
|
||||
|
||||
U1 为规范文本更新:核对本地链接、17 个稳定 action/scope、R1–R20 追溯、批准原文摘要及固定 RDM 初始基线的 08 核心 R1–R5;无业务行为,不制造文本单元测试。
|
||||
U2 先运行真实临时 SQLite 与已注册命令负例,再修改实现并保留相应合法流程。旧测试中期待 admin 跨项目、停用角色回落、他人代确认等断言按批准合同修正,正常路径仍通过真实授权夹具运行;没有删除失败用例以绕过测试。
|
||||
|
||||
| 检查 | 当前结果 | 证据边界 |
|
||||
|---|---|---|
|
||||
| 初始负例与审阅补漏 | 已真实复现并记录;红测保留 | 包含越权写入、实际正文/原件元数据回执、未知归属写入与跨 owner 审计投递;编译失败与夹具失败也保留,不冒充行为证据 |
|
||||
| 新回归与相关旧流程 | 通过(SELF);独立重跑 39 个顶层 I1 回归 | 工具记录命令、HEAD、dirty 摘要与完整输出;本轮编译失败、夹具失败和“no tests to run”均保留,不计为行为通过 |
|
||||
| RDM make test | 通过(SELF),对象 ef075bd1 | 完整收据 ab592b80c858543f…见 RDM 任务卡:组合产品构建、29 项 Web 检查、Go 全量均退出 0;不包含部署/生产数据验收 |
|
||||
| Dev make test/文档检查 | 已通过(SELF),对象 0ab70b0c;最终文档记录后的对象另见任务卡 | 完整收据 b12914e5136cc405…见 Dev 任务卡;含工作树、gitlink、治理、模块/UI/命令组合检查,本任务未改业务 UI。最终文字记录收口后按固定 gitlink 再核验,新增收据由工具记录,不复制输出 |
|
||||
| 独立提前源码审阅与 focused 重放 | 通过,39 组顶层回归全部通过(本地) | 审阅者 /root/i1_security_review 未参与源码写入;对象 dfb9c407,独立重跑命令与完整 SELF 工具收据见 RDM 任务卡;不是用户批准、平台账号独立批准或受信 CI |
|
||||
| 正式验收/CI/浏览器/真实模型/生产迁移/部署 | NOT_RUN | 模型注册描述已按实际拒绝边界改写;未建立本轮固定模型任务级前后基线,测试使用 mock Host,不能声称模型行为通过。正式阶段应固定模型/配置/任务集,补真实对照及浏览器链路 |
|
||||
|
||||
## 必须审阅的兼容影响
|
||||
|
||||
1. 新 audit.read 初始不授予任何人。合法系统管理者先开平台上限,角色有资格后由合法项目管理者授予业务审计;此前 admin/创建者自动审计行为停止。
|
||||
2. KnowledgeDelete 只能按当前账号整插件前缀删除,故项目 revoke 明确拒绝,等待项目/资源限定公开接口;公开 rdm.init 也因读服务器目录并写全量未归属域而拒绝,可信本地操作保留。
|
||||
3. Host↔RDM 绑定、解绑及映射共享读取需可信双方项目授权提供者;当前未安装生产提供者,缺失默认拒绝。project/list 的整批私人工件元数据共享关闭;现项目级跨 owner search 缺发布分类证明也拒绝。自有资源具体读取和明确的 RDM 项目知识读面保留;不是完整共享 RAG 已验收声明。
|
||||
4. 存量未归属盘点/迁移/全量 outbox 状态需独立范围授权;实例内可信集成不是用户自授接口,重启不继承。旧未知归属 outbox 保留 pending,新增关联表仅处理之后的可证明来源;不推测历史 owner、不丢记录。本轮未变更生产 DB。
|
||||
5. 有阶段范围的用户无法读取尚未安全裁剪的全项目聚合 DTO;后续应逐对象投影与重算计数。失效绑定和旧不可信 opID 回执拒绝,不能把兼容回退当作当前资格。
|
||||
|
||||
这些限制是避免当前公开契约不足扩大授权的 I1 处理;正式产品恢复对应能力需固定提供者/消费者的新公开版本与独立正反例,不能靠当前平台管理员位补足。
|
||||
|
||||
## 进展与下一步
|
||||
|
||||
U1 权限合同与需求追溯已完成;U2 当前 RDM 可达路径整改、本地组合自检和独立提前复审已完成,等待用户阶段 6 评审。独立提前源码复审已通过;后续测试记录更新必须确认生产源码与此对象等价。未推送、未创建 PR、未合入、未部署,保留两个独立工作区及全部失败收据。
|
||||
|
||||
首选下一任务为已规划 I2/U3:账号可选资料、受控人员目录与本人恢复证明。推荐理由是先建立可信身份/有效态与安全恢复边界,随后才能实施 Backend 通用角色和多绑定 U4。前置条件:用户批准 I1 实施结果并另行授权 U3;核对已有账号目录实现,复用最小 EXT-19 边界;公开提供者先审接口,不能绕过 pins。预期产物:资料全空合法、字段授权搜索不泄漏、项目目录只投影获准辨识字段、普通管理员不能获取目标本人可兑换设密能力的真实负例及成功本人流程。此建议不启动新任务。
|
||||
|
||||
公开 Host 能力缺口另有 IAM-H/IAM-K 申请;可与 U3 的公开提供者工作协调,恢复共享/撤销前先完成固定契约,不以设计文档存在放行。
|
||||
|
||||
## 实施调用与单元记录
|
||||
|
||||
实施引擎为 native Codex,委派单元为权限合同、初始负例、旧测试对齐、幂等隐私补漏与独立提前审阅;无外部模型路由绑定/回退/detached run,实际服务模型未独立证明。source_kind=plan,source_digest 为上方批准原文摘要;plan_checkpoint 为 Documents a088809。行为单元 U2 的原始红→绿观察保存于当时工具收据,不能从最终 diff 重构;U1 为非行为文档核对。单位 canonical commit 和完整 changed_files 由所属仓的当前分支与任务卡追溯。此本地交付跳过推送、PR、CI与合入 shipping tail。
|
||||
|
||||
Dev 同步 main 到 143e636736 后随主干物化 Backend 15566f9a、Core 5773e740、Frontend c294835f、UI 2c4322ef;本任务相对该 main 只改变 Documents、PROJECT 导航与任务卡。RDM 产品仍按自身 pins 固定 Backend 0f192a48、Frontend 4965de26、UI bfecf8b5,未自行推进 pins;两套组合的检验与状态分开,不用 Dev 测试证明 RDM 的提供者能力。
|
||||
|
||||
## 阶段 6 人工批准(2026-10-13,北京时间)
|
||||
|
||||
用户在本页 c023551 对应的实施候选与兼容影响交付后回复“批准”。阶段 6 实施与自检结论:通过;对象为 Documents c023551、RDM b93908e、Dev 72ed8b4。该结论不代签尚未完成的阶段 7 验收,也不启动后续 U3–U9 或生产部署。恢复时已有主干推进,正式测试将固定同步后的对象,报告正常/异常/边界/回归证据与缺项,再请求用户验收;原获批对象和所有早期失败收据保留。
|
||||
|
||||
阶段 7 当前产物:[正式测试与验收候选](2026-10-13-iam-i1-acceptance.md)。上述阶段 6 测试与缺项记录为当时快照;新的真实 HTTP 结果、独立重跑及仍未执行项目以阶段 7 报告和工具收据为准。
|
||||
@@ -0,0 +1,574 @@
|
||||
---
|
||||
title: 用户、职位角色与分层权限统一设计及实施计划 r1
|
||||
date: 2026-10-13
|
||||
type: refactor
|
||||
execution: code
|
||||
artifact_contract: ce-unified-plan/v1
|
||||
product_contract_source: legacy-requirements
|
||||
---
|
||||
|
||||
# 用户、职位角色与分层权限统一设计及实施计划 r1
|
||||
|
||||
负责人:weichen;编制:Codex;更新时间:2026-10-13(北京时间)。
|
||||
确认状态:本轮两项用户裁定已确认;完整需求表、架构调整、迁移与实施计划待人工评审。
|
||||
推进状态:源码调研与方案编制;业务修改、业务测试、数据库迁移、部署及运行验收均为 NOT_RUN。
|
||||
本文是本次改造的唯一方案主记录;任务卡与索引引用本文,不复制推进状态。
|
||||
|
||||
## Goal Capsule
|
||||
|
||||
让管理员按企业职位管理人员与能力,让创建者在自己的项目管理成员和文档责任,并让用户清楚知道自己能操作什么、为什么可以或不可以。
|
||||
复用现有账号、职位角色、项目成员、权限解释与整文审签能力,修正作用域混用,再补齐资料、搜索、单对象配置与批量矩阵。
|
||||
本轮交付终点为完整方案及分阶段计划,业务实施与运行操作需取得对应阶段授权。
|
||||
|
||||
用户已明确选择:系统管理员管理账号、角色与权限上限,访问他人项目业务内容需要明确授权;首期支持一人多职,每个项目明确选用该用户的哪些职位角色。
|
||||
这两项决定来自本轮对话,完整方案仍为待评审草案。
|
||||
|
||||
---
|
||||
|
||||
## Product Contract
|
||||
|
||||
### Problem Frame
|
||||
|
||||
当前存在四种概念:系统账号、企业职位、项目管理关系、文档编制/审核/批准职责。
|
||||
它们在部分命名、管理入口和授权函数中混用,导致项目设置权限能够进入全局管理、管理员自动获得业务访问、角色停用或换岗后权限不一致。
|
||||
改造的重点是统一权限语义和执行端判定,同时把配置权、作用域和具体资源责任说清楚。
|
||||
|
||||
“系统权限、角色权限、项目权限”是同一套权限模型的不同配置来源与作用范围。
|
||||
角色是能力模板,系统权限是系统范围的动作,项目权限是限定到一个项目的授权。
|
||||
文档三权进一步确定谁对某个版本履行哪项职责。
|
||||
|
||||
### Sources and Current Evidence
|
||||
|
||||
权威顺序采用 RDM `docs/requirements/README.md`:最新用户指示 → 当前 U0/Q 裁定与权威需求正文 → 当前矩阵 → 未被取代的旧设计 → 原始会议。
|
||||
`.tmp` 原件作为设计来源保留,不回写历史原稿。
|
||||
本轮优先阅读 `.tmp/Discussion-Meetings/2026-10-08_12-24/Outputs/11-角色与权限管理方案.md`,并与 01/03/08 系列、RDM 当前需求和后续计划交叉核对。
|
||||
|
||||
| 对象 | 本轮读取的固定版本 | 证据边界 |
|
||||
|---|---|---|
|
||||
| Dev 源码基线 | `3fb8210f6495a78e70a67af3661bdfe9c00fb9de` | 本地源码与启动检查,SELF |
|
||||
| Dev Backend | `dc736e339d01c59e658abc63c81909059bd6ea02` | 本地源码,SELF |
|
||||
| Dev Frontend | `dcd2699933eff51c06193cac7beb15c3d20a01ff` | 本地源码,SELF |
|
||||
| Documents / UI | `05c13a42b14d70f878cc8a51c543e018a7f7a663` / `0da2e3acd6c8ae8957825b64ddb54b250c0979c0` | 文档与设计约束 |
|
||||
| RDM | `255f9cba0c9e6f981fbff66142be92532d5c5f2d` | 本地源码,SELF |
|
||||
|
||||
RDM 自己的 Backend/Frontend pins 与 Dev 组合不同,不能把某一工作树的能力视为另一组合已部署的能力。
|
||||
命令、对象与脱敏输出由任务卡的 evidence 收据保存;本稿的源码事实不等于部署重现、GATE 通过或正式验收。
|
||||
|
||||
| 已核实的源码情况 | 对方案的影响 | 源码位置,路径以所列仓为根 |
|
||||
|---|---|---|
|
||||
| 已有独立职位角色、多账号可绑定同一角色;账号当前只能绑定一个角色 | 扩展已有模型,支持多职、描述和编辑 | RDM `internal/perms/roles.go` |
|
||||
| 用户资料没有电话、邮箱、工号等;公开目录仅 owner+valid | 账号资料和受控目录必须有 Backend 公开契约 | Backend `internal/store/auth.go`、`pkg/extension/extension.go`、`internal/app/hostcaps.go` |
|
||||
| 角色/全局上限/管理员移交复用 `project.settings` | 首批拆开系统动作与项目动作 | RDM `internal/rdmapp/perms_api.go` 中 `AuthorizeGlobal`、`roleAdminGate` |
|
||||
| 域管理员和基座超管在多处自动读取项目、审计、导出、原件或草稿 | 同步修订所有业务读面,取消身份式业务放行 | RDM `perms_api.go`、`runtime.go`、`upload.go`、`draftproposal.go` |
|
||||
| owner 跳过职位上限;角色停用回落内置 member;换岗后遗留 override 可跳过未配置动作的角色上限 | 采用完整授权链,覆盖创建者、停用与换岗负例 | RDM `perms_api.go` 中 `evalPerm`、`internal/perms/roles.go` |
|
||||
| “权限矩阵”是单成员有效权限解释;角色页每次编辑一个动作 | 保留解释能力,补可编辑角色矩阵与成员矩阵 | Frontend `src/components/adminRdmSections.tsx` |
|
||||
| 用户、角色、三权候选主要手输 owner/docId;入口依赖 isAdmin | 接受服务端能力与目录查询结果,使用稳定 ID 选择 | Frontend `adminSections.tsx`、`adminRdmSections.tsx`、`AdminZone.tsx` |
|
||||
| 基座建项接口与 RDM 建项命令的门禁不同 | 统一产品入口;区分宿主项目与研发项目后封闭旁路 | Backend `internal/server/server.go`;RDM `plugins/rdm/plugin.go` |
|
||||
|
||||
### Requirements
|
||||
|
||||
需求编号仅用于本方案,不替换原有 UR/SR 编号。
|
||||
|
||||
**身份、职位与人员查找**
|
||||
|
||||
| ID | 需求与可判定验收条件 | 来源 |
|
||||
|---|---|---|
|
||||
| R1 | 角色是独立职位对象,有稳定 ID、名称、可选描述、状态和版本;改名不改变人员身份或历史 | 本轮用户;SR-G7 |
|
||||
| R2 | 同一职位可关联多人;一人可关联多个职位;项目只采用明确选定的有效绑定,新增职位不自动扩张既有项目 | 本轮用户裁定;当前概念模型 |
|
||||
| R3 | 姓名、电话、邮箱、工号、部门与备注均可选;全部留空仍能建号;资料不成为登录凭证或授权主键 | 本轮用户 |
|
||||
| R4 | 支持精确与模糊搜索、字段选择、状态/职位等过滤、分页与同名辨识;最终授权对象是稳定用户 ID | 本轮用户 |
|
||||
| R5 | 系统管理者可维护账号资料;本人可编辑非授权资料;项目选人只获得必要目录投影,无权读取完整联系方式或凭证 | 本轮用户;隐私边界 |
|
||||
|
||||
**系统与项目授权**
|
||||
|
||||
| ID | 需求与可判定验收条件 | 来源 |
|
||||
|---|---|---|
|
||||
| R6 | 系统设置、用户管理、角色管理、策略管理与建项采用明确系统动作;项目权限编辑不能写入系统动作 | SR-G6/G7/G8;本轮用户 |
|
||||
| R7 | 系统管理员无项目/资源授权时不能读取他人业务正文、原件、草稿、业务审计、导出、搜索命中或模型上下文 | 本轮管理员裁定;修订旧跨项目审计口径 |
|
||||
| R8 | A 创建者不能凭 A 的管理权管理 B;创建事实固定,负责人接替采用明确委任记录 | SR-G9/G10 |
|
||||
| R9 | 创建者在本项目管理成员、覆盖权限与分配三权;项目覆盖可覆盖角色默认,但不能突破平台和角色上限 | SR-G8/G9 |
|
||||
| R10 | 多角色按完整授权路径合成;平台禁止、项目明确拒绝与资源限制不能被另一角色绕过 | 本轮多职裁定;SR-G2/G8 |
|
||||
| R11 | 角色停用、解绑、换岗、上限收紧、账号停用和成员移除及时撤权;遗留覆盖不能复活旧权 | 当前源码缺口;SR-G8/N4 |
|
||||
| R12 | 同一动作的 UI、HTTP、命令、工具、任务恢复与最终提交遵循同一服务端判定;未知或失败状态拒绝 | SR-G2;U0 D1 |
|
||||
|
||||
**配置体验与文档职责**
|
||||
|
||||
| ID | 需求与可判定验收条件 | 来源 |
|
||||
|---|---|---|
|
||||
| R13 | 单角色编辑与角色×权限矩阵是同一数据的两种视图,支持分组、精确/模糊搜索、过滤与批量草稿 | 本轮用户 |
|
||||
| R14 | 单成员编辑与成员×权限矩阵共享草稿;显示继承/授予/拒绝、角色默认、上限、最终结果与原因 | 本轮用户;SR-G8 |
|
||||
| R15 | 批量保存有具体差异、影响预览、版本冲突保护、原子提交和审计;隐藏行不丢草稿,不逐格即时落库 | 配置完整性与当前缺口 |
|
||||
| R16 | 每份受控文档编制一人、批准一人、审核至少一人,三类人员互异;候选必须是有效成员并具备对应能力上限 | SR-C7/G9 |
|
||||
| R17 | 职位能力只提供资格;实际编写、审核、批准同时检查具体职责、文档状态与冻结版本;管理权不代签 | SR-C7/C8;U0 D2/D5 |
|
||||
| R18 | 私聊、私人原件与个人草稿保持私有;项目知识由明确提交/发布产生;受控文档按职责或明确授权读取 | SR-G11/G12;U0 D3 |
|
||||
| R19 | 权限变化同步影响已开页面、旧卡、Surface、下载、检索、SSE 和后台任务;迟到事件不能恢复权限 | SR-G2/G11/N4;根 AGENTS.md |
|
||||
| R20 | 保留用户/项目/角色稳定标识与历史;迁移输出旧→新差异,不把旧管理员全权转成永久业务授权 | 持久化与兼容要求 |
|
||||
|
||||
### Confirmed Decisions and Scope
|
||||
|
||||
管理员业务访问边界已经用户选择确认(session-settled: user-directed — chosen over 管理员自动获得全部项目业务访问: 业务访问需要明确授权;Governs R7)。
|
||||
首期多职及项目明确选用已经用户更正确认(session-settled: user-directed — chosen over 每人仅一个生效职位: 用户改为采用多职建议;Governs R2/R10)。
|
||||
|
||||
本次覆盖用户资料、职位模型、系统/项目授权、配置界面、文档职责与读取授权、Agent 同源执行、迁移及验收。
|
||||
飞书/SSO、组织树与岗位继承、全自动任命/签字、全量模板补齐、整个工作流引擎重建和外部权限服务采购不纳入本次。
|
||||
本次修订需要更新 RDM 权威需求与相关方案,但 `.tmp` 历史稿保留。
|
||||
|
||||
---
|
||||
|
||||
## Planning Contract
|
||||
|
||||
### KTD1. 数据职责与统一入口
|
||||
|
||||
建议把通用账号资料、职位定义、用户—职位绑定、系统动作授权及平台/角色上限集中到 Backend 的通用身份与授权服务。
|
||||
RDM 负责项目成员、项目选用角色、项目覆盖、资源归属、阶段状态和文档三权,注册领域动作及资源策略;UI 和 Agent 消费同一公开服务。
|
||||
用户主身份沿用基座稳定 ID 与现有 owner 映射,不另建账号;RDM 历史 owner 标识保留。
|
||||
|
||||
这是对现行“专业角色主表在 RDM”的明确架构调整建议,须在方案阶段评审,不能借旧 U0 D1 当作已经批准。
|
||||
集中通用职位定义可以让账号管理、建项与项目业务共同消费一份授权事实,并避免两个角色台账同步漂移。
|
||||
RDM 专有的职责与状态规则仍留在 RDM,基座只知道注册动作、约束及判定协议。
|
||||
下游通过正式公开扩展及固定版本消费,禁止修改 pins 源码或导入 Backend internal。
|
||||
|
||||
主要备选:保留 RDM 角色主表并让基座经公开策略提供者查询。
|
||||
该路径减少角色数据搬迁,但系统管理动作会依赖领域插件及其可用性;若采用,必须冻结单一权威、插件缺失时拒绝策略和根管理恢复通道,不能再建第二套独立职位表。
|
||||
不推荐仅补 UI:它不能解决已经存在的服务端 scope 混用。
|
||||
|
||||
### KTD2. 概念模型
|
||||
|
||||
| 对象 | 核心字段/关系 | 权威 |
|
||||
|---|---|---|
|
||||
| User / Profile | 稳定 userId、owner 映射、账号有效态;可选姓名、电话、邮箱、工号、部门、备注;profileVersion | Backend |
|
||||
| Role | roleId、名称、描述、状态、roleVersion、创建/变更主体 | Backend,拟迁移现有 RDM 角色 |
|
||||
| UserRoleBinding | bindingId、userId、roleId、有效态、任命主体/时间、版本;支持多对多 | Backend |
|
||||
| PermissionDescriptor | 稳定 actionId、中文名、说明、scope、资源类型、分组、条件、委派级别、风险与版本 | Backend 注册表,RDM 注册领域项 |
|
||||
| RolePermission | roleId+actionId、默认 grant、cap、允许的资源范围;default 范围不得超 cap | Backend |
|
||||
| SystemGrant | 明确系统动作授予与上限;受保护管理员/策略管理授权独立记录 | Backend |
|
||||
| Project / Membership | 稳定 projectId、固定 createdBy、当前负责人委任;成员身份、明确选用的 bindingId、版本 | RDM |
|
||||
| ProjectOverride | 项目+成员+动作的 inherit/allow/deny,以及资源范围收缩、版本 | RDM |
|
||||
| ResourceGrant | 资源稳定 ID、类型、真实属主、项目、分类、明确接收者/职责、只读范围、撤销版本 | 资源 owner;统一公开判定 |
|
||||
| DocumentDuty / Round | 文档职责、冻结正文/职责/策略版本、轮次与真实操作者 | RDM |
|
||||
|
||||
这些是逻辑模型,具体表名与迁移编号在实施时确定。
|
||||
删除有引用的用户和角色采用停用/归档,保留审计身份;无引用对象才允许物理删除。
|
||||
同名职位的规范化重复检查独立于显示名;同名人员允许存在,工号与联系方式不作为强制唯一标识。
|
||||
可选资料做长度与格式校验,空值合法;电话仅按明确规则规范化,避免错误匹配。
|
||||
|
||||
### KTD3. 权限目录与系统权限
|
||||
|
||||
权限目录的 scope 由受信注册表确定,不能凭动作字符串前缀或请求体自报作用域。
|
||||
旧 actionId 通过版本化映射兼容,作用域冲突的旧项不继续接受写入。
|
||||
|
||||
| 权限类别 | 动作示例 | 谁能配置/怎样生效 |
|
||||
|---|---|---|
|
||||
| 系统设置 | system.settings.read/write,model/plugin/agent 设置子项 | 具备对应系统管理权者;平台策略限制 |
|
||||
| 用户管理 | system.users.view/create/edit/disable;credential.recover 单列 | 分项授权;普通资料编辑不允许改管理员资格 |
|
||||
| 职位管理 | system.roles.manage/assign | 管理职位与普通任命;不能越可委派上限 |
|
||||
| 高权限管理 | system.policy.manage/privileges.manage;admin.transfer | 受保护动作;项目覆盖和普通职位任命不可间接获得 |
|
||||
| 创建项目 | project.create,scope=system | 有效系统/职位 grant;选定产品与创建者角色上下文 |
|
||||
| 项目管理 | project.settings、member.manage、permission.manage、duty.assign、stage.advance/archive | 具体项目创建者或明确委任;受 cap 与状态约束 |
|
||||
| 项目内容 | knowledge.read/publish、trace.read/edit、business-audit.read/export | 项目关系、角色范围和资源关系同时满足 |
|
||||
| 文档动作 | document.read/export、author/review/approve 等资格项 | 能力资格+具体文档职责/授权+状态 |
|
||||
|
||||
管理员徽标由受保护系统授权产生,职位名称叫“管理员”不会改变其权限。
|
||||
首期保留至少一个有效策略管理者与安全恢复通道;并发撤销最后管理者必须在事务中拒绝。
|
||||
普通角色管理者不能编辑受保护权限,也不能给自己或别人任命超出其可委派范围的角色。
|
||||
系统管理员不自动加入项目,不自动获得业务统计或业务审计。
|
||||
系统安全日志仅披露必要的账号、安全动作、结果与不透明对象标识,不含业务正文、文件名、项目名称、内容摘要或完整历史差异。
|
||||
访问业务审计采用对应项目的明确授权,与正文授权分别显示。
|
||||
|
||||
### KTD4. 单一权限判定与多角色合成
|
||||
|
||||
输入由认证会话、受信资源存储和实际执行上下文组成:主体、动作、资源类型/ID、真实项目/属主、当前版本与当前状态。
|
||||
请求体里的 actor、owner、projectId 不能替代受信归属;资源与项目不一致时拒绝。
|
||||
服务端返回 allow/deny、来源链、拒绝原因及 authorityEpoch,UI 不重新计算权限。
|
||||
解释接口只能解释调用者自己或其有权管理的对象,不能成为探测他人资料的旁路。
|
||||
|
||||
系统动作只读系统授权来源,不接受 ProjectOverride。
|
||||
其有效值为当前有效账号、平台允许范围、对应受保护规则,以及明确 SystemGrant 或一条完整的系统职位默认授权路径;不依赖项目所选职位,也不接受项目 allow 作为系统授权来源。
|
||||
项目动作先确认成员/创建者/明确委任与资源归属,再对每个有效且本项目选用的职位绑定建立完整候选路径:
|
||||
|
||||
`角色动作已定义且启用 ∩ 角色 cap(含范围) ∩ 平台 cap ∩ 项目 grant/默认 ∩ 资源关系 ∩ 阶段/状态 ∩ 文档职责`。
|
||||
|
||||
对具体动作,至少一条完整路径通过才允许。
|
||||
一个角色的动作授权不能与另一个角色的资源范围拼接;角色 cap=false 只关闭该角色的路径,平台禁止、项目明确 deny 和资源禁止对全部路径生效。
|
||||
项目 override=allow 仅替换默认 grant,不能创造不存在的动作、突破任一 cap 或跳过资源关系。
|
||||
override=deny 阻断该成员在该项目对此动作的全部角色路径;inherit 使用当前有效默认。
|
||||
多个角色可共同授予不同动作,但一次动作必须有完整证据来源。
|
||||
|
||||
加入项目时明确选择该用户的有效 bindingId;只有一个有效角色可预选,多角色需明确选择。
|
||||
新任命角色不自动加入已有项目;解绑后旧 binding 立即无效,重新任命产生新 binding,旧项目配置不自动复活。
|
||||
停用角色没有回落授予;无有效角色仅保留显式最小账号自助能力,业务动作拒绝并说明缺少资格。
|
||||
新增权限默认拒绝;读取策略失败、缺元数据、未知动作或必需提供者缺失时拒绝。
|
||||
|
||||
创建者关系提供本项目管理默认,仍经过其有效角色 cap 和平台 cap,不能自动读私域或代签。
|
||||
建项前检查创建者角色组合具备本项目设置、成员管理与三权分配的 cap 资格,避免建成无法管理的项目;role default 可关闭这些动作,由创建者关系提供项目内默认。
|
||||
已有项目遇 cap 收紧时保留归属,阻断受影响动作,并向授权管理者显示需要调整任命的原因。
|
||||
为避免唯一负责人换岗后无法重新选用职位,提供受限的“重新选择本人项目职位”动作:仅当前有效负责人本人,可从其账号当前有效任命中显式选择具备平台和项目管理 cap 资格的 binding,并按当前项目版本确认保存。
|
||||
仅该动作可使用尚未被项目选用的当前任命;普通项目动作仍只使用项目已选用的 binding。
|
||||
它只修复本人在本项目的角色选择,不改变项目负责人、不恢复旧 allow 覆盖、不清除明确 deny,也不授予资源读取或三权;完成后普通动作重新经过完整判定。
|
||||
角色任命者只能处理系统任命,不能代选项目职位;没有合格任命时项目保持等待,不能扩大 cap 恢复。
|
||||
项目内移除/降权最后负责人时保护实际可操作的管理资格,而不仅计数 owner 关系;系统 cap 收紧造成的暂停则明确记录与提示,不能阻止管理员执行必要撤权。
|
||||
创建项目、创建者成员关系与所选 binding 在同一领域事务落地;宿主绑定采用可恢复状态与幂等对账,失败不能留下可使用的无负责人项目。
|
||||
|
||||
判定、解释与所有入口共同调用该服务。
|
||||
设计采用最小权限、默认拒绝和每次请求重验,也结合项目关系与资源状态;依据 [OWASP Authorization Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html)。
|
||||
|
||||
### High-Level Technical Design
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
U[用户及多个职位绑定] --> I[基座身份与通用授权服务]
|
||||
C[系统动作与权限目录] --> I
|
||||
R[角色默认与角色上限] --> I
|
||||
P[项目成员 所选绑定 项目覆盖] --> D[统一判定]
|
||||
I --> D
|
||||
A[资源归属 明确分享 文档职责] --> D
|
||||
S[阶段 文档状态 当前版本] --> D
|
||||
D --> E[HTTP 命令 工具 任务提交与读取]
|
||||
D --> X[有效权限解释与矩阵]
|
||||
```
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
Q[受信主体与资源定位] --> A{账号 动作与归属有效}
|
||||
A -->|否| N[拒绝并给出可披露原因]
|
||||
A -->|是| B{系统动作}
|
||||
B -->|是| C[系统来源与受保护权限检查]
|
||||
B -->|否| D[项目资格与硬限制检查]
|
||||
D --> E[逐角色建立完整路径]
|
||||
E --> F[资源 职责 状态 版本检查]
|
||||
C --> G{当前授权通过}
|
||||
F --> G
|
||||
G -->|否| N
|
||||
G -->|是| H[允许 在提交或输出边界再检查]
|
||||
```
|
||||
|
||||
### KTD5. 文档三权与读取范围
|
||||
|
||||
复用现有整文审签,不建立另一套审批引擎。
|
||||
项目创建者通过统一服务选择有效项目成员,系统验证职位资格与文档三权异人要求,再记录真实分配者和受指派人员。
|
||||
审核人可多人,全部指定审核人通过后才允许批准;审核/批准只能批注和通过/驳回,不能修改正文。
|
||||
审核与批准人员因实际职责可读提交审阅的正文和明确关联材料;这不开放私人对话、未分享原件或私人草稿。
|
||||
共享授权只增加规定资源的读取能力,不转为编写或签字资格。
|
||||
|
||||
审签轮次冻结正文版本、职责版本与政策版本;人员停用、解绑、移除或权限收紧后,待处理轮次进入明确等待/失效状态,重新指派及提交。
|
||||
历史已完成的签字和操作者身份保留,不因换岗改写;历史内容读取仍使用当前授权。
|
||||
批准后修改采用既定撤回重审+影响提示;职责替换不能清洗同一版本实际编制者的记录。
|
||||
未分配三权的文档显示等待分配,并阻断受控编写/提交,不回落为全成员可写。
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> WaitingDuty
|
||||
WaitingDuty --> Drafting: 指派有效三权
|
||||
Drafting --> Reviewing: 编制人提交固定整文版本
|
||||
Reviewing --> Drafting: 驳回或撤回
|
||||
Reviewing --> Approving: 全部指定审核通过
|
||||
Approving --> Drafting: 驳回或撤回
|
||||
Approving --> Approved: 指定批准人签字
|
||||
Approved --> Drafting: 撤回并开启新版本
|
||||
Reviewing --> WaitingDuty: 职责或必要资格失效
|
||||
Approving --> WaitingDuty: 职责或必要资格失效
|
||||
```
|
||||
|
||||
### KTD6. 查找与配置界面
|
||||
|
||||
沿用系统管理区、项目设置和文档入口,遵守 Dev `DESIGN.md`,不新增无用途的权限仪表盘。
|
||||
|
||||
1. 系统管理 → 用户:可搜索列表、职位/状态过滤、用户详情;详情显示可选资料、职位绑定、系统能力及来源。创建账号不要求填写人员资料。
|
||||
2. 系统管理 → 角色与权限:角色列表+名称/描述/状态/绑定人数;选中角色后编辑默认与上限,也可切角色×权限矩阵。系统级受保护项按操作者资格显示。
|
||||
3. 项目设置 → 成员与权限:选人、选择项目生效职位、项目覆盖;单成员视图与成员×权限矩阵共用草稿,显示最终解释。
|
||||
4. 文档现有入口 → 三权:文档×编制/审核/批准矩阵与单文档选择器;候选范围、资格不足、多人审核及冻结状态直接说明。
|
||||
|
||||
精确搜索按选定字段规范化后完全匹配,稳定 ID/登录名优先;模糊搜索首期采用包含匹配和明确的前缀排序,不默认增加拼音/向量/模型识人。
|
||||
搜索资料范围遵循目录权限;被禁字段既不返回,也不参与未经授权的匹配,防止通过命中数量探测联系方式。
|
||||
过滤包括权限 scope、分组、默认/上限/最终允许、继承/覆盖、职位与账号状态、当前修改;精确/模糊与过滤可以组合。
|
||||
共享“职位”不代表可查看所有同职位人员的私密资料。
|
||||
同名候选显示姓名(如有)、登录名、职位与工号的授权投影;人名不清楚时必须选择具体对象,模糊匹配不能直接完成任命。
|
||||
|
||||
矩阵不是一张无限扩展的大表:按分组及分页显示,固定对象标签,提供单元格说明和键盘导航。
|
||||
单角色视图的 default 与 cap 两列,成员视图的 inherit/allow/deny,与最终“允许/拒绝”的只读结果有明确区分。
|
||||
过滤隐藏项不清空草稿;“全选”只选当前明确列出的结果,服务端提交固定 ID 清单与选择数量,不能把模糊查询直接当成授权范围。
|
||||
|
||||
### KTD7. 批量变更、撤权与 Agent
|
||||
|
||||
所有配置走“草稿 → 差异及影响预览 → 提交确认 → 服务端重验 → 原子写入与审计回执”。
|
||||
预览绑定操作者、对象 ID、策略版本及 patch 摘要;它不能作为跳过提交授权的凭证。
|
||||
一批多个角色/成员的修改采用 expectedVersion/authorityEpoch 与事务,任一非法对象、越上限或冲突均不部分提交。
|
||||
跨 Backend 与 RDM 的一项业务变更不伪装成单库原子事务;按明确 owner 分开提交,显示实际状态和可恢复步骤。
|
||||
超时结果标为未知,以幂等键查询事务回执,避免重复授权或错误声称失败。
|
||||
|
||||
权限 epoch 的权威落在存储和服务端判定;进程通知用于使缓存尽快失效,通知丢失不能继续使用旧授权。
|
||||
HTTP/检索/下载在输出边界检查当前权限;任务入队、恢复、使用资源和最终提交分别检查;持续流在新输出前重验并在撤权后终止受影响订阅。
|
||||
已经交付到客户端或既有模型上下文的内容无法追回,撤权会清除应用缓存并阻断后续读取、工具执行和结果披露;对含已撤数据的模型运行终止并重新构造上下文。
|
||||
|
||||
UI、对话、Agent 工具共用权限目录查询、候选选择、解释、预览与提交 primitives。
|
||||
沿用公开命令总线,但明确声明工具投影和风险级别;管理写入经宿主的人类确认,模型不能确认自己的授权提案或签署三权。
|
||||
管理区发起的确认使用现有确认卡/弹层能力,并提供可发现的返回路径;不能只报“请到对话确认”而丢掉当前草稿。
|
||||
异步状态只由一个 store 管理,按 actor+project+对象版本+request generation+seq 丢弃过期响应,失败时清空对应旧能力。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant H as 人类管理者
|
||||
participant UI as 单对象或矩阵视图
|
||||
participant API as 公开授权服务
|
||||
participant DB as 权威存储
|
||||
H->>UI: 选择固定对象并修改草稿
|
||||
UI->>API: 请求差异和影响预览
|
||||
API->>DB: 读取当前版本与授权
|
||||
API-->>UI: 返回具体变更和拒绝原因
|
||||
H->>UI: 确认变更
|
||||
UI->>API: patch 版本 幂等键
|
||||
API->>DB: 重验并事务写入与审计
|
||||
API-->>UI: 完成 冲突 拒绝或未知结果
|
||||
```
|
||||
|
||||
### Compatibility and Migration
|
||||
|
||||
迁移必须保持账号 owner/userId、roleId、projectId、createdBy、资源标识及历史签字身份。
|
||||
既有单角色绑定导入一个有效 binding;项目只选用该绑定,不自动加入新增角色。
|
||||
旧 profile 字段映射到可选资料;未知资料留空,不推断人员姓名或联系方式。
|
||||
现有两套管理员身份仅映射为明确的系统动作来源,不生成全项目业务 grant;旧 owner 的正文默认、停用回落与遗留越 cap 覆盖列为权限收缩差异。
|
||||
|
||||
角色权威迁移采用版本化清单与冻结写窗口:导出带来源版本及摘要的角色/绑定/cap,导入 Backend 后核对数量、稳定 ID、逐项范围和所有引用,再切换消费者。
|
||||
禁止双主写入;过渡 RDM 旧管理命令转发新权威服务或明确只读,旧表只保留可核对历史。
|
||||
冻结期间不能取得一致快照时停止迁移,不做无事务的跨库复制。
|
||||
|
||||
先在隔离副本执行迁移与双评估,输出用户×项目×动作的旧→新差异;双评估只用于记录,新算法上线时只有一个执行权威。
|
||||
扩权项必须有明确新授权;收缩项逐项列出原因和处理人,不能为消除差异恢复旧越权。
|
||||
生产迁移前完成备份及恢复演练、固定程序/配置/数据身份,按发布和迁移授权切换。
|
||||
回滚不得重新启用身份式业务全权或复活撤销记录;不能满足这一条件时进入维护/拒绝状态,先修复迁移或程序。
|
||||
账号恢复需修订既有账户方案的信任与交付合同,防止管理员拿一次性 Key 设密后接管业务身份;一次性本身不满足 R7。
|
||||
普通管理员仅发起恢复提案,账号本人须使用管理员不能单方改写或取得的既有有效会话确认或预先建立的本人恢复证明,才能取得可兑换设密能力。
|
||||
可选姓名、电话、邮箱和工号只是人员资料,不自动成为恢复证明;新证明的建立或更换不能由发起恢复的管理员单独完成。
|
||||
若没有独立本人验证条件,线上恢复拒绝,不向普通管理员交付可兑换的目标账户 Key;异常人工恢复采用另行批准的 owner 操作,不纳入普通角色管理权限。
|
||||
U1 冻结证明与交付合同,U3 消费已批准能力并验证该负例;既有恢复命令未收口前不能宣称 R7 完成。
|
||||
|
||||
### Dependencies and Existing Work
|
||||
|
||||
本方案衔接 [RDM 功能与实现整改方案](2026-10-12-rdm-function-implementation-plan.md)、[RDM 完整交付方案](2026-10-11-rdm-final-target-completion.md)、[两树一网追溯审计方案](2026-10-11-rdm-two-trees-trace-audit-integration.md) 与 [账户和登录 Key 方案](2026-10-12-svc-unified-deploy-and-login-key.md)。
|
||||
本轮管理员决定将修订前述审计方案的跨全部项目业务审计放行口径,以及权威 SR-G6 的“所有权限”表述;旧批准记录保留,新候选条款须按本方案评审和切换。
|
||||
账户方案中恢复 Key 可交付给签发者的既有口径同样需要按 R7 修订;对已有业务账号不能只保留短时设密限制。
|
||||
多职选择将修订 10-12 方案的首版单角色建议。
|
||||
U0 D2/D3/D5 的管理不代签、私域与冻结整文规则继续作为约束。
|
||||
|
||||
现有 `feature/admin-notes-repair` 涉及管理样式与角色勾选同步;其他 RDM 工作区有审计/导出/pins 相关任务。
|
||||
这些仅依据本地任务记录和分支阅读,不代表本轮已经核验远端 PR 或 CI。
|
||||
实施启动时查询最新权威 base/head、实际公开契约、已合入内容和在途负责范围,复用有效改动,避免平行修改同一管理页面与审签引擎。
|
||||
基座公开扩展的实现、兼容验证及固定版本消费是 U4/U5 的依赖;发布版本仍由用户按高后果双钥匙执行。
|
||||
|
||||
---
|
||||
|
||||
## Implementation Units
|
||||
|
||||
以下均为待批准工作项;U 编号带本方案名称使用,避免与其他方案的 U 编号混淆。
|
||||
文件范围以指定仓根目录为基准;标“新增”的文件为规划位置,实施可按项目模块规范调整。
|
||||
|
||||
### U1. 冻结需求、权限目录与公开扩展合同
|
||||
|
||||
目标:将本轮两项裁定和 R1–R20 落到权威需求、动作 scope、通用服务/领域规则边界及公开提供者/消费者合同。
|
||||
依赖:人工确认本方案需求与 KTD1;负责人为产品负责人和基座/RDM 模块 owner。
|
||||
文件:RDM `docs/requirements/01-用户需求与系统需求.md`、`03-产品设计方案.md`、`08-核心数据模型-两树一网.md`;Documents 相关方案与扩展申请;Backend `pkg/extension/extension.go` 合同草案。
|
||||
方法:冻结权限目录、敏感字段投影、系统管理恢复条件、账号本人恢复证明与凭据交付、项目创建与角色 cap 关系、公开版本兼容和旧命令映射。
|
||||
验证:文档差异与链接核对、动作×scope×配置主体表逐项评审;本单元不实施业务,也不制造业务测试 PASS。
|
||||
出口:阶段 1–5 对应产物和人工结论齐备,明确选择通用角色权威位置后才能进入其实施。
|
||||
|
||||
### U2. 收口现有系统与项目越权路径
|
||||
|
||||
目标:先修 R6–R12/R18 的当前路径,为后续迁移建立安全基线。
|
||||
依赖:U1 对动作与边界的批准;RDM 执行端 owner 负责。
|
||||
文件:RDM `internal/rdmapp/perms_api.go`、`runtime.go`、`upload.go`、`draftproposal.go`、`plugins/rdm/plugin.go`;测试扩展 `plugins/rdm/roles_test.go`、`draft_visibility_test.go`、`internal/rdmapp/perms_test.go`、`u1_auth_test.go`、`resource_authz_test.go`。
|
||||
方法:系统管理使用独立资格;清除自动业务 admin 放行;先验证角色动作存在和 cap,再考虑覆盖;停用不回落更宽默认;创建者走相同硬约束。
|
||||
执行方向:以当前源码触发方式先建立会失败的公开执行负例,避免仅测试新帮助函数。
|
||||
|
||||
测试场景:
|
||||
|
||||
- 普通角色获 project.settings 后,全局 cap、角色管理、admin 移交仍拒绝。
|
||||
- A 创建者改 B 的成员、权限、职责和归档均拒绝;矩阵解释一致。
|
||||
- 管理员未获 B 业务授权,正文/业务审计/原件/私人草稿/导出均拒绝。
|
||||
- 先设 allow 覆盖,再换到未配置该动作角色,当前执行与解释均拒绝。
|
||||
- 停用受限角色不新增权限;owner 遇 cap=false 同样拒绝;有效合法成员仍可执行原有合法动作。
|
||||
|
||||
出口:直接 API/命令负例与正常回归闭合;不得宣称完整迁移或最终产品已验收。
|
||||
|
||||
### U3. 基座账号资料、有效态与受控目录
|
||||
|
||||
目标:实现 R3–R5/R11,提供真实人员查找而不复制账号。
|
||||
依赖:U1 目录及系统管理合同;Backend owner 负责。
|
||||
文件:Backend `internal/store/auth.go`、迁移、`internal/server/accounts.go`、`internal/app/hostcaps.go`、`pkg/extension/extension.go`;新增账号资料/有效态测试及扩展 `internal/app/account_lister_test.go`、服务器账户测试。
|
||||
方法:资料 CRUD 与停用有明确系统资格;目录查询按系统管理/项目选人/职责候选投影字段,分页稳定;停用同步终止会话与能力。
|
||||
|
||||
测试场景:
|
||||
|
||||
- 姓名电话邮箱工号均空成功建号;填写和清空资料不改身份。
|
||||
- 两名同名用户精确按 ID/登录名正确选定;模糊结果要求再次选择对象。
|
||||
- 项目选人未经联系方式权限不能按电话号码探测命中,不能批量导出完整目录。
|
||||
- 本人改备注不能改角色、管理员位或有效态;停用账号不能继续操作或作为三权候选。
|
||||
- 管理员持有 credential.recover 仍不能取得目标用户可兑换凭据或正常登录能力;无本人验证条件时恢复拒绝;管理员改可选资料不能改变恢复证明。
|
||||
- SQLite 与 PostgreSQL 的空值、格式、分页和并发版本冲突行为一致。
|
||||
|
||||
出口:公开提供者/消费者契约验证及后台真实目录数据闭合。
|
||||
|
||||
### U4. 通用职位、多职、默认与上限及原子批量服务
|
||||
|
||||
目标:实现 R1/R2/R6/R10/R13/R15/R20。
|
||||
依赖:U1、U3、U2 安全基线;Backend 与 RDM owner 共同负责迁移窗口。
|
||||
文件:Backend 新增 `internal/authz/` 通用目录、角色、binding、版本与系统授权存储和测试;公开扩展与注册面;RDM `internal/perms/roles.go` 和 `perms_api.go` 兼容转发;新增 `internal/authz/roles_test.go`、`policy_batch_test.go` 和迁移测试;RDM `plugins/rdm/roles_test.go` 消费契约。
|
||||
方法:KTD1–KTD4/KTD7;保留 roleId;用户绑定多职;角色默认与上限范围成对校验;保护高权限任命与最后管理者;预览及提交均授权。
|
||||
|
||||
测试场景:
|
||||
|
||||
- 一个职位绑定两人,同一人绑定两个职位;编辑说明不影响用户/项目 ID。
|
||||
- 默认 grant 超 cap、未知动作、停用角色任命、无权编辑受保护项均拒绝。
|
||||
- 一角色有动作无目标范围,另一角色有目标范围无该动作,组合仍拒绝。
|
||||
- 批量里一对象非法或版本冲突,全部不写;同一幂等请求只生成一次变更及审计。
|
||||
- 旧单角色数据导入保持 ID/绑定,双主写入被阻断;失败迁移恢复不复活撤权。
|
||||
|
||||
出口:角色与绑定只有一个权威来源,系统动作与新旧公开消费者结果一致。
|
||||
|
||||
### U5. 项目角色选择、覆盖和统一资源读取
|
||||
|
||||
目标:实现 R2/R7–R12/R14/R18/R19。
|
||||
依赖:U3/U4 与公开版本就位;RDM 项目 owner、Backend 资源接口 owner 配合。
|
||||
文件:RDM `internal/members/members.go`、`internal/projects/projects.go`、`internal/rdmapp/projects_api.go`、`perms_api.go`、`runtime.go`、`plugins/rdm/plugin.go`;Backend 项目 API、`internal/server/resource_authz_test.go`、`resource_authz_consumption_test.go`、`internal/app/resource_authz_v2_test.go`;RDM `member_guards_test.go`、`resource_authz_test.go`、`perms_test.go`。
|
||||
方法:加入和建项保存明确 binding;项目覆盖只操作本项目;资源策略消费完整 action/type/id/owner/project;列表、计数、检索、历史和导出均过滤;宿主项目和领域项目稳定绑定。
|
||||
|
||||
测试场景:
|
||||
|
||||
- 新增用户职位不改变已有项目;项目选择新增 binding 后才生效。
|
||||
- 解绑再重新任命不能自动恢复旧项目选择/旧覆盖。
|
||||
- 唯一负责人解绑后重新任命合格职位,可经受限入口由本人明确重选并恢复管理;普通管理员、前负责人或 cap 不足者不能代修复,也不能借此读资源或恢复旧 allow。
|
||||
- 项目明确 deny 在另一角色可 grant 时仍拒绝;allow 超所有可用 cap 拒绝。
|
||||
- 创建者可以管理本项目,不能读私聊或未分享原件;无管理资格建项不留下可使用半成品。
|
||||
- 篡改 projectId、资源 ID、owner 以及使用基座直连建项/下载/检索不能绕过域策略。
|
||||
- 策略提供者错误、缺失或权限通知丢失时拒绝;分页与数量不泄露被过滤对象。
|
||||
|
||||
出口:HTTP/Host/命令/模型上下文的直接入口均有同一作用域和资源边界。
|
||||
|
||||
### U6. 三权资格、冻结轮次及真实分配者审计
|
||||
|
||||
目标:实现 R16/R17/R18,复用已有整文审签能力。
|
||||
依赖:U4/U5;RDM 文档模块 owner 负责。
|
||||
文件:RDM `internal/domain/review.go`、`internal/rdmapp/docsubmission.go`、`draft.go`、`plugins/rdm/plugin.go`;扩展 `write_duty_stage_test.go`、整文审签测试和职责候选测试。
|
||||
方法:统一分配服务检查有效账号、项目成员、选用职位、cap 与异人;审计记录真实操作者;轮次冻结与资格撤销处理按 KTD5。
|
||||
|
||||
测试场景:
|
||||
|
||||
- 跨项目、停用、非成员和 cap 不足候选拒绝;编制/审核/批准同人拒绝。
|
||||
- 多审核人未全部通过时批准拒绝;旧票不能签新正文。
|
||||
- 管理员/创建者未被指派不能代编、代审、代批;审核人能读提交正文但不能读取未分享原件。
|
||||
- 在途撤权或换职责使待处理轮次失效;历史已签版本和主体保留。
|
||||
- 分配者与受指派编制人不同,审计 actor 是真实分配者。
|
||||
|
||||
出口:一份整文由真实三个职责完成与拒绝链,资格解释和执行一致。
|
||||
|
||||
### U7. 用户、角色、项目权限与三权界面
|
||||
|
||||
目标:实现 R4/R5/R13–R16,形成完整管理操作路径。
|
||||
依赖:U3–U6 相应服务合同稳定;Frontend/UI owner 负责。
|
||||
文件:Frontend `src/components/adminSections.tsx`、`adminRdmSections.tsx`、`AdminZone.tsx`、`rdmManagement.ts`、`api.ts`、`store.ts`;复用 `test/rdmroles-reject.test.ts`,新增角色矩阵/成员矩阵/目录与三权交互测试;沿用两个仓的 `design-guard.test.ts`。
|
||||
方法:KTD6/KTD7;先整合在途管理页面改动;消费服务端权限目录与 capabilities,共用草稿模型,选择稳定 ID。
|
||||
|
||||
测试场景:
|
||||
|
||||
- 单角色与矩阵产生等价 patch;过滤和翻页不丢草稿;全选范围与预览一致。
|
||||
- 姓名同名但登录名不同不误选;资料空值正确展示;无资格者看到明确拒绝原因。
|
||||
- 两窗口并发编辑返回冲突并保留草稿;等待确认/已完成/结果未知分开显示。
|
||||
- 快速切项目/角色/搜索词,迟到结果不能覆盖新目标;403 不被当成登录失效或永久加载。
|
||||
- 明暗主题、键盘导航、焦点、窄屏及广告过滤环境可用;令牌和折叠原语门禁成立。
|
||||
|
||||
出口:真实用户通过既有页面完成建号/任命/项目选人/覆盖/三权,没有手填 ID 的必要主流程。
|
||||
|
||||
### U8. Agent 同源工具、撤权与后台提交
|
||||
|
||||
目标:实现 R12/R19,并验证 UI 与对话动作 parity。
|
||||
依赖:U4–U7;命令总线与运行时 owner 负责。
|
||||
文件:RDM `plugins/rdm/plugin.go` 工具声明和描述、任务资源使用/提交位置;Backend `internal/cmdbus/`、`internal/runmgr/`、公开策略集成测试;Frontend 卡片/Surface/能力 store 相关测试。
|
||||
方法:查询、解释、预览和提交用同一 primitives;对角色/项目/三权写操作使用宿主确认;任务恢复与新输出重验,终止含已撤数据的运行。
|
||||
|
||||
测试场景:
|
||||
|
||||
- 同一动作 UI/命令/工具的允许、拒绝、审计和对象一致,模型不能伪造 actor 或确认自己的提案。
|
||||
- 入队后撤权、恢复旧任务、确认旧卡、使用旧 Surface 均不能提交。
|
||||
- 已开 SSE/下载/检索遇撤权终止后续读取,权限通知丢失仍由当前存储判定拒绝。
|
||||
- 含已撤资料的模型上下文不被继续使用或披露,恢复从新授权上下文开始。
|
||||
- 真实模型能查询候选、解释权限和请求人确认;遇歧义人名停止在选人步骤。
|
||||
|
||||
出口:mechanism 测试与适用真实模型任务级验证分别留证,不用 mock 代替模型验收。
|
||||
|
||||
### U9. 迁移演练、精确组合及正式验收
|
||||
|
||||
目标:闭合 R1–R20,交付单一权威的实际产品行为。
|
||||
依赖:U2–U8 完成对应评审;迁移、部署和运行测试各有明确授权;集成 owner 与用户验收人负责。
|
||||
文件:各仓迁移与验收记录;Dev task evidence、组合 pins 和功能规划;新增多账号权限端到端用例按仓内测试规范保存。
|
||||
方法:先隔离副本、SQLite/PG 同构迁移、差异审阅和恢复演练;固定 base/head/pins/config/data identity,再在授权环境执行真实账号验证。
|
||||
|
||||
测试场景:
|
||||
|
||||
- 至少两个独立项目;系统管理员、A 创建者、B 创建者、同职位两人、一人多职、两名审核人、批准人、普通成员和无关用户。
|
||||
- 完成资料/职位/系统能力/项目选择及覆盖/文档三权全过程,并逐项执行跨项目、换岗、停用、上限收紧与私域负例。
|
||||
- 重启后任命/覆盖/职责与撤销保持;两实例缓存失效、并发编辑和任务恢复一致。
|
||||
- 迁移 diff 无未经批准扩权;回滚保留撤权事实,不启用旧管理员业务旁路。
|
||||
- 实际浏览器由最终固定产物提供;系统角色变化、公开契约、模型工具、文档正文和审计结果同一对象。
|
||||
|
||||
出口:用户正式验收、独立 Review、当前 HEAD 的权威 CI、合入及部署记录各自齐备;不能用其中一项替代其余。
|
||||
|
||||
### Phased Delivery
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
U1[U1 需求与公开合同评审] --> U2[U2 当前授权路径收口]
|
||||
U1 --> U3[U3 用户资料与目录]
|
||||
U2 --> U4[U4 统一职位与多职服务]
|
||||
U3 --> U4
|
||||
U4 --> U5[U5 项目与资源授权]
|
||||
U5 --> U6[U6 三权资格与轮次]
|
||||
U3 --> U7[U7 管理界面]
|
||||
U4 --> U7
|
||||
U5 --> U7
|
||||
U6 --> U7
|
||||
U7 --> U8[U8 Agent及撤权全链]
|
||||
U8 --> U9[U9 迁移组合与正式验收]
|
||||
```
|
||||
|
||||
建议分四个可验增量:I1=U1+U2 的边界修正;I2=U3+U4 的人员/职位与目录;I3=U5–U7 的项目、三权及配置体验;I4=U8+U9 的全链和迁移验收。
|
||||
各增量遵循 policy/delivery.md 的需求、方案、实施、验收人工出口;阶段内可继续调查、自检与整改。
|
||||
既有公开契约只读、UI 单对象/矩阵模型设计可在依赖批准后并行;服务端迁移和同一页面写入按 owner 协调。
|
||||
实施工期在 U1 完成、实际在途任务及公开版本核定后估算,不把未验证的迁移规模写成日期承诺。
|
||||
|
||||
---
|
||||
|
||||
## Verification Contract
|
||||
|
||||
以下是后续验证计划,本轮业务结果全部 NOT_RUN。
|
||||
|
||||
| 层 | 验证内容 | 命令/环境与证据要求 |
|
||||
|---|---|---|
|
||||
| 文档 | 当前引用、需求追溯、两项裁定、规则一致性 | 文档 diff 与链接检查;SELF |
|
||||
| 账号与通用授权 | 正常/越权/停用/并发/多职/批量/迁移 | Backend 相关 Go 测试与合同测试;执行时固定 SHA |
|
||||
| RDM 领域 | 项目隔离、角色选用、范围、三权、私域和状态 | RDM 相关 Go 测试、公开 HTTP/命令集成;`make test` |
|
||||
| UI | 搜索、选择、两种矩阵、确认、冲突与拒旧 | Dev `make test-frontend`、`make test-ui`;固定组合实际浏览器 |
|
||||
| 产品组合 | 基座提供者/RDM 消费者/正式前端产物 | 各仓和 Dev `make test`、`make build`,核对实际 pins 与制品 |
|
||||
| 存储与恢复 | SQLite/PG 迁移、并发、重启与多实例撤权 | 隔离数据与授权运行环境;最小权限真实账号集 |
|
||||
| Agent | 查询/解释/确认/拒绝/恢复/资源使用 | 真实模型任务级测试;机制单测与模型结果分开 |
|
||||
| 正式交付 | 同步、测试、Review、CI、合入及部署 | 当前 base/head;precheck/task-sync/检查输出经 evidence;GATE 运行身份+SHA 或独立 REPLAY |
|
||||
|
||||
本地 evidence 为 SELF,不因标签或摘要提升可信级别。
|
||||
正式验收固定被测源码、组件 SHA、配置与数据身份;Reviewer 按最小重放集独立核验。
|
||||
未执行、跳过、零用例或源代码存在不能写为业务 PASS。
|
||||
文档保存只检查文档,不启动业务测试、数据库迁移或服务操作。
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
本轮方案交付:本文包含当前差距、完整需求、明确模型与合成规则、界面方案、迁移与兼容、工作项/文件/测试/依赖和评审出口;两项用户决定有准确来源;主入口与任务卡可接续。
|
||||
完整功能交付:R1–R20 均能映射至实际实现及固定对象证据,所有必要正常、异常、边界和权限负例成立;用户正式验收后按仓库规则完成独立 Review、当前 CI 与组合核验。
|
||||
|
||||
启动实施前需完成的评审选择:KTD1 通用职位权威迁移、创建者管理与角色 cap 的耦合和本人重选规则、受控目录可披露字段、账号本人恢复证明及交付合同,以及生产迁移/切换范围。
|
||||
这些是当前草案中已给推荐方案但尚未批准的设计选择,不影响本轮方案交付,不授权实施者自行替换路线。
|
||||
实施时再确定的细节:表名/迁移编号、最终 package 位置、目录分页与搜索索引阈值、通知实现和隔离环境,不改变上述产品边界。
|
||||
|
||||
停止条件:范围或需求改变;必要公开契约不兼容;角色数据无法取得一致快照;发现未批准扩权;实际制品/数据身份不明;在途任务 owner 冲突;越出迁移/部署授权。
|
||||
发生时保存当前证据与现场,返回受影响方案或计划评审,不能放宽授权继续。
|
||||
|
||||
推荐下一步为评审 U1 和 I1,先批准本次权限边界与公开合同,再实施已有可达授权路径的收口。
|
||||
这项建议不自动启动业务任务;完整用户资料与矩阵设计已有后续依赖和验收,不会在首批完成后遗漏。
|
||||
@@ -0,0 +1,336 @@
|
||||
# 最终验证与合入调度 Implementation Plan r1
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use `executing-plans` for native execution or `subagent-driven-development` when that method is selected. Read the specification and this plan; implement and verify one work item at a time. Checkboxes describe required steps; current progress and fixed objects are recorded in the Dev task card.
|
||||
|
||||
**Goal:** 减少多个就绪分支因其他正常合入而反复同步、解决冲突和重跑最终 CI,同时保证实际合入候选通过既有检查。
|
||||
|
||||
**Architecture:** 开发并行;同一目标由一个明确协调者安排最终同步至合入核验的串行窗口。首版使用源码外 Gitea 调度 Issue、幂等同步和分级恢复入口;保留现有 workflow 及平台准入,不建设自动调度 daemon。
|
||||
|
||||
**Tech Stack:** 现有 Bash/Git 任务脚本、Python 标准库 evidence 工具、Makefile、unittest 临时真实仓库夹具、Gitea PR/Actions。
|
||||
|
||||
**Spec:** Agent-System-Dev `policy/merge-queue.md` r1(本地来源提交 `913b214f2826a50b3dab65f79d9ebf83e84f2519`);Development-Guidelines `standards/merge-queue.md` 与 `templates/merge-queue.md`(本地候选提交 `606f21db99b971aae82c2348a9b7959e6aa2060c`,draft.11)。两项来源尚未推送/合入,不生成不可访问的远端源码链接。
|
||||
|
||||
**Status:** approved(阶段 5);编制日期 2026-10-13(Asia/Shanghai);负责人 weichen。用户在本计划 r1@ba4044d57e38d0887dd425d052abf26b20a28bf4 交付后回复「批准」,按推荐的原生方式实施。源码与自检已在 Dev 任务分支推进,证据和当前对象以任务卡为准;平台所有者操作及真实三任务 CI 试行 NOT_RUN。
|
||||
|
||||
**Document baseline:** Documents `origin/main=5a06acf7cded07797ec4ebfea42c89331359b0bb`。本计划正文只维护于 Documents;任务进度、命令证据和批准依据仍以 Dev 任务卡为准。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- 共同起点及最终交付实际同步最新目标保留;正式验收、审核、合入仍分别核验新鲜度与候选身份。
|
||||
- 一个目标最多一个交付窗口,覆盖最终同步、正式验证、必要复审、合入及真实内容核对。
|
||||
- 队列更新、CI 链接和候选固定后的本地收据位于被测源码之外;不能向 main 提交调度心跳或状态。
|
||||
- 当前 HEAD 的全部必需 CI 必须实际通过;不复制旧绿色状态,不把跳过必需作业当通过。
|
||||
- 人工阶段结论、独立 Review、SELF/REPLAY/GATE 的身份边界不变。入队与领取不是批准或新的工作授权。
|
||||
- 修改治理脚本必须执行 `make test-governance`;跨仓指针推进前执行 Dev `make test`,最终精确 HEAD 的平台 CI 另核验。
|
||||
- 首版人工预算沿用规格:无进展 20 分钟、窗口 90 分钟、已知基础设施失败最多额外重试一次、等待队列每 30 分钟复查。实际 runner 容量及长期预算在试行前核验。
|
||||
- 分支保护变更由 Agent 准备、用户确认并亲手执行;本计划不授权绕过保护、改写历史或发布版本。
|
||||
- 不隐式 stash/reset/强推,不覆盖组件 feature 分支,不丢失现有收据或他人现场。
|
||||
|
||||
## Review Focus
|
||||
|
||||
1. 同步已经完成,但为记录再创建提交:U1 对有任务卡的真实仓库重复调用,断言 HEAD、索引和卡片不变。
|
||||
2. LOCAL_READY 被当作可启动新任务或可合入:U2 覆盖启动拒绝、严格恢复拒绝、未知远端及脏现场继续阻断。
|
||||
3. evidence 写回任务卡后才确认候选,或最终 SHA 仍指向记录提交之前:U1 核对输出真实 HEAD,U3 对源码外收据流程核对前后身份。
|
||||
4. 队列 Issue 被误认为互斥锁,或失联协调者被盲目接管:U4/U6 分别检查 manual 登记、旧执行者退出确认和未知结果对账。
|
||||
5. 分支 CI 绿色但其语义组合、组件或平台必需检查无效:U4/U5/U6 覆盖外部推进、组件版本不回退、精确对象与真实拒绝路径。
|
||||
|
||||
## 1. 范围、决策及来源核对
|
||||
|
||||
### 本增量
|
||||
|
||||
U1–U3 为可在隔离仓库验证的任务与证据改进;U4 将已批准条文和实际能力接到交付入口;
|
||||
U5 准备并验证平台准入条件;U6 在已授权真实任务上试行。实施顺序固定 U1 → U2 → U3 → U4 → U5 → U6。
|
||||
三个源码单元完成后可先提交实施产物供阶段 6 评审;模式切换需 U4/U5 条件齐备,不能把脚本通过当线上启用。
|
||||
|
||||
首版不修改 `.gitea/workflows/ci.yaml` 的触发、必需作业或检查上下文。节省重复最终 CI 的方法是:
|
||||
其他就绪分支不因 main 前进推送同步提交;当前窗口分支完成所有必要记录后只推送固定最终候选。
|
||||
现有开发提交仍可能运行完整 CI,首版不声称已自动区分轻重检查或能抢占 runner。
|
||||
后续 workflow 分流、自动原子领取和执行端 fencing 单独立项,不能为完成本计划顺手建设。
|
||||
|
||||
### 已确定的选择
|
||||
|
||||
| 决策 | 采用方式与理由 |
|
||||
|---|---|
|
||||
| 调度方式 | 人工首版:一份共享 Issue、一个协调者;与已批准规格一致,先控制实际推进顺序 |
|
||||
| 同步方式 | 保留 merge 历史;只有目标尚未包含时发生同步写入,同基线节点只核验 |
|
||||
| 启动/恢复 | 新任务和默认交付模式仍严格;仅既有合法任务可以显式选择局部恢复 |
|
||||
| 收据格式 | 本增量保留 schema 1 及原始校验和;局部模式由真实 precheck 输出及验证用途区分,不随意添加 snapshot 字段 |
|
||||
| 固定后证据 | 使用已有 RECEIPT 捕获模式,不增加冻结数据库或签名协议;manual 流程每个节点核对实际对象 |
|
||||
| 独立审核 | 建议原生逐项实施,末尾按现有交付规范安排独立 Review;编制时仅为计划,尚未启动审阅/实施代理 |
|
||||
|
||||
### 编制时实现基线(源码观察 SELF)
|
||||
|
||||
| 路径/符号 | 本次确认的行为 | 对计划的约束 |
|
||||
|---|---|---|
|
||||
| Dev `scripts/task.sh:cmd_sync` | 先获取目标并检查/物化组件;有任务卡时每次追加记录并提交;输出 head 在记录提交前取值 | U1 必须消除无变更提交,并输出记录完成后的 HEAD |
|
||||
| Dev `scripts/task.sh:cmd_precheck` | 远端失败为 REMOTE_UNVERIFIED;脏现场为 SHARED_WORKSPACE_BUSY;落后为 SYNC_REQUIRED | U2 不整体改成 READY,保持默认严格 |
|
||||
| Dev `scripts/evidence.py:validate_precheck` | 只接受真实 precheck 命令、READY、成功及固定源/目标;用于 task-start | 新任务不能消费局部恢复收据 |
|
||||
| Dev `scripts/evidence.py:read_receipt/validate_snapshot` | schema 1 和 snapshot 字段集合严格校验,允许可选 capture_note | 无必要不改 wire schema;历史收据不重写 |
|
||||
| Dev `scripts/evidence.py:main/write_receipt` | RECEIPT 模式已存在,绝对未用路径、0600、完整输出、before/after;默认模式写任务卡 | U3 复用能力,最终窗口明确选择源码外路径 |
|
||||
| Dev `scripts/zcode/write_guard.py:check_location` | 检查目标实际仓库及分支,未读取 precheck 收据或判断目标落后 | 不把当前守卫描述为阶段/新鲜度强制闸;保留分支检查与负例 |
|
||||
| Dev `.gitea/workflows/ci.yaml` | PR/main push 触发 test、test-pg、svc-realcombo;checkout 核对固定 SHA 与仓库 allowlist | 不凭 queue label 跳过检查;不能直接复制此 workflow 到临时仓当作合法等价 CI |
|
||||
|
||||
以上为编制时源码观察;当前能力与执行进展见任务主记录及固定候选的 PR/源码外收据。源码单元实施前再次读取实际符号,记录新的 base/head;行号变动不改变接口选择。
|
||||
平台配置、runner 容量和在途任务用当场记录核验,不复用旧观察作当前准入证明。
|
||||
|
||||
## 2. 公共入口与兼容约定
|
||||
|
||||
以下是本计划拟新增或调整的接口;编制时均未声明已实现,当前状态以任务主记录及其固定候选证据为准。
|
||||
|
||||
| 入口 | 默认/输入 | 结果及兼容 |
|
||||
|---|---|---|
|
||||
| `make task-sync` | 正常严格同步;来源仍为权威 origin/目标 | 保留 `[synced]`;完整 sync_base、最终 tested_head、checked_at,追加 changed=0/1;未变不提交卡片 |
|
||||
| `make precheck` | `TASK_WORK_MODE=delivery` 默认;可显式 local | delivery 保留 READY/SYNC_REQUIRED;local 仅既有登记任务输出 LOCAL_READY,不称可合入 |
|
||||
| `make task-resume PRECHECK_RECEIPT=...` | 复用登记任务;TASK_WORK_MODE 与 precheck 一致 | 验证相应用途的原始收据后原样导入,不建分支、不后台同步 |
|
||||
| `make task-start` | 始终用途 start、严格 READY | 无视外部试图选择局部验证用途的参数;LOCAL_READY 必须拒绝 |
|
||||
| `VALIDATE_RECEIPT_PURPOSE` | evidence 内部验证用途;默认 start | start、resume-delivery、resume-local 三值;未知值拒绝,两个任务入口显式设置用途 |
|
||||
| `RECEIPT=... CMD=... make evidence` | 既有捕获接口 | 保留 schema 1、原命令状态、完整脱敏输出及来源 SELF;固定候选期间路径在当前 checkout 与 Git 元数据之外 |
|
||||
|
||||
`LOCAL_READY` 是局部工作的检查结果,不能提升为交付准入。旧的 schema 1 收据和 READY 输出继续可读。
|
||||
`VALIDATE_RECEIPT_PURPOSE` 不传给被测命令子进程,避免改变测试环境;不能由它改变来源等级。
|
||||
|
||||
## 3. 工作项
|
||||
|
||||
### U1:同步幂等化及最终对象输出(R1/R2,MQ3/MQ4)
|
||||
|
||||
**Files(Dev 仓):** Modify `scripts/task.sh`;Test `tests/test_task.py`;对应说明在 U4 同步。
|
||||
|
||||
**Interfaces:** 消费 `fetch_target`、`check_worktree` 和原任务卡;产出第 2 节的 `[synced]` 协议。
|
||||
|
||||
- [ ] 在现有 `TaskLifecycleTests` 中补有任务卡的夹具。使用已有 `self.git/self.worktree`,记录实际 R0,不创建假测试证据:
|
||||
|
||||
```python
|
||||
def record_task_card(self, wt):
|
||||
branch = self.git(wt, "branch", "--show-current").stdout.strip()
|
||||
r0 = self.git(wt, "rev-parse", "origin/main").stdout.strip()
|
||||
card = wt / ".task" / (branch.replace("/", "-") + ".md")
|
||||
card.parent.mkdir(exist_ok=True)
|
||||
card.write_text(
|
||||
f"# {branch}\n状态:进行中;owner:Lifecycle Test\n"
|
||||
f"- 权威仓:fixture;目标分支:main;R0(initial_base_sha)= {r0}\n"
|
||||
f"- 工作区:{wt}(worktree);分支:{branch}\n"
|
||||
)
|
||||
self.git(wt, "add", str(card.relative_to(wt)))
|
||||
self.git(wt, "commit", "-m", "Record fixture task")
|
||||
return card
|
||||
|
||||
def test_sync_same_base_preserves_head_and_card(self):
|
||||
wt = self.worktree()
|
||||
card = self.record_task_card(wt)
|
||||
head = self.git(wt, "rev-parse", "HEAD").stdout.strip()
|
||||
content = card.read_bytes()
|
||||
for _ in range(2):
|
||||
result = self.task(wt, "sync")
|
||||
self.assertEqual(self.git(wt, "rev-parse", "HEAD").stdout.strip(), head)
|
||||
self.assertEqual(card.read_bytes(), content)
|
||||
self.assertEqual(self.git(wt, "status", "--porcelain").stdout, "")
|
||||
self.assertIn("changed=0", result.stdout)
|
||||
self.assertIn(f"tested_head={head}", result.stdout)
|
||||
```
|
||||
|
||||
- [ ] 执行 `PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -p 'test_task.py' -k sync -v`,确认当前无变更提交行为导致新例失败,再改实现。
|
||||
- [ ] 同步前检查父仓未保存内容和活动操作;脏父仓/子仓拒绝,不自动 stash。成功 fetch 后区分祖先检查的 0、1 和其他错误。
|
||||
- [ ] 已包含目标时仍核对/物化必要组件,未变则不追加卡片、不提交;未包含时保留 merge、冲突处置和一次必要记录。记录提交完成后再读取最终 HEAD 输出。
|
||||
- [ ] 补新增目标成功纳入、重复调用保持 HEAD/索引/卡片、输出等于实际最终 HEAD、脏父仓/子仓/离线拒绝、组件 feature 分支保留和冲突不误报成功的测试。复用原组件夹具和已存在负例。
|
||||
- [ ] 重跑上述直接检查,输出经 evidence 保存;按本仓四段提交格式保存此单元,不捎带其他任务文件。
|
||||
|
||||
### U2:既有任务局部恢复与严格准入分开(R1/R5,MQ4)
|
||||
|
||||
**Files(Dev 仓):** Modify `scripts/task.sh`、`scripts/evidence.py`、`Makefile`;Test `tests/test_task.py`、`tests/test_evidence.py`、`tests/test_write_guard.py`;独立恢复集成场景放 `tests/test_task_recovery.py`,复用原真实 Git 夹具。
|
||||
`scripts/zcode/write_guard.py` 的现有分支级规则保留;无已证实兼容问题时不改它。
|
||||
|
||||
**Interfaces:** 使用 TASK_WORK_MODE 和第 2 节验证用途;`task-resume` 验证后复用 IMPORT_RECEIPT,不建立新工作区。
|
||||
|
||||
- [ ] 先补局部模式与默认严格模式的对照测试:
|
||||
|
||||
```python
|
||||
def test_local_precheck_allows_existing_clean_task_behind_target(self):
|
||||
wt = self.worktree()
|
||||
self.record_task_card(wt)
|
||||
head = self.git(wt, "rev-parse", "HEAD").stdout.strip()
|
||||
self.advance_remote()
|
||||
strict = self.task(wt, "precheck", check=False)
|
||||
self.assertNotEqual(strict.returncode, 0)
|
||||
self.assertIn("SYNC_REQUIRED", strict.stdout)
|
||||
local = self.task(wt, "precheck", check=False,
|
||||
env=self.env | {"TASK_WORK_MODE": "local"})
|
||||
self.assertEqual(local.returncode, 0, local.stdout)
|
||||
self.assertIn("[verdict] LOCAL_READY", local.stdout)
|
||||
self.assertEqual(self.git(wt, "rev-parse", "HEAD").stdout.strip(), head)
|
||||
```
|
||||
|
||||
- [ ] 执行 `PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -p 'test_task.py' -k precheck -v`,确认新例失败。新任务入口仍消费严格收据。
|
||||
- [ ] local 只允许登记的合法任务 worktree/分支/任务卡,原 R0 必须仍是当前任务及权威目标的祖先;无卡、集成分支、错误归属、异常历史均拒绝。允许已知落后,不允许脏现场、活动操作、组件漂移、远端未知。
|
||||
- [ ] `validate_precheck` 增加用途参数,由任务入口显式选择。保留命令、原始输出、源 HEAD、common_dir 等校验;start/resume-delivery 仍要求严格 READY 与当前目标一致。
|
||||
- [ ] 测试夹具显式清理 TASK_WORK_MODE/VALIDATE_RECEIPT_PURPOSE,再由目标用例注入,避免开发终端环境污染默认严格模式的测试。
|
||||
- [ ] resume-local 接受实际 LOCAL_READY;收到同一来源任务的历史观察后重新 fetch 核对当前目标及 R0,目标正常前进不要求改写原收据或同步分支。读取失败、源 HEAD 变更或 R0 不适用拒绝,两个观察的来源与对象分别记录。
|
||||
- [ ] 补 LOCAL_READY 不能 task-start、不能严格恢复、用途未知拒绝、伪造任意命令拒绝、收据串仓/损坏拒绝、旧 READY 兼容、局部恢复不改 HEAD、已知目标前进与异常历史的对照。写守卫原有 main/detached/软链接拒绝测试继续通过,不宣称它已校验阶段批准。
|
||||
- [ ] 执行上述 precheck 检查及 `test_evidence.py`、`test_write_guard.py` 的 unittest discover;记录实际输出后提交此单元。
|
||||
|
||||
### U3:候选固定前后使用不同证据保存位置(R2/R3,MQ3/MQ4)
|
||||
|
||||
**Files(Dev 仓):** Modify `policy/governance.md` 的证据流程;Test `tests/test_evidence.py`;同步任务卡模板说明于 U4。
|
||||
现有 `scripts/evidence.py` 的捕获/导入协议复用;本单元不改 schema,也不增加冻结状态库。
|
||||
|
||||
**Interfaces:** RECEIPT 捕获、IMPORT_RECEIPT 导入、真实 snapshot;只有源码外记录满足固定后的流程。
|
||||
|
||||
- [ ] 用已有 `tests/test_evidence.py` 的真实仓库夹具补完整使用流程:捕获到仓外唯一路径,断言卡片字节、HEAD、索引不变,校验原始命令输出、before/after 和 0600;重复目标拒绝,旧收据原样导入且幂等。
|
||||
|
||||
以下用例放入既有 `EvidenceTests`,复用已核对的 `self.git/self.capture/self.card/self.receipt`:
|
||||
|
||||
```python
|
||||
def test_fixed_candidate_capture_preserves_checkout(self):
|
||||
self.git("add", ".task/main.md")
|
||||
self.git("commit", "-qm", "Save fixture card before validation")
|
||||
head = self.git("rev-parse", "HEAD")
|
||||
card = self.card.read_bytes()
|
||||
index = self.git("ls-files", "--stage")
|
||||
data = self.capture("printf 'fixed candidate check\\n'")
|
||||
self.assertEqual(data["before"]["head"], head)
|
||||
self.assertEqual(data["after"]["head"], head)
|
||||
self.assertEqual(data["output"], "fixed candidate check\n")
|
||||
self.assertEqual(self.git("rev-parse", "HEAD"), head)
|
||||
self.assertEqual(self.git("ls-files", "--stage"), index)
|
||||
self.assertEqual(self.card.read_bytes(), card)
|
||||
self.assertEqual(self.git("status", "--porcelain"), "")
|
||||
self.assertEqual(self.receipt.stat().st_mode & 0o777, 0o600)
|
||||
```
|
||||
|
||||
- [ ] 这项是既有能力的流程回归,允许先通过,不伪造“新增机制失败”结果。执行 `PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -p 'test_evidence.py' -v`。
|
||||
- [ ] 固定前流程:同步 → 所有必要本地检查及任务卡收据 → 保存/提交卡片 → 核对干净组合 → 读取最终 HEAD → 推送并记录当前 CI 对象。
|
||||
- [ ] 固定后流程使用以下既有接口,候选 SHA/组件/相关配置由调度尝试引用;路径须位于 checkout 和 Git 元数据之外:
|
||||
|
||||
```bash
|
||||
RECEIPT=/tmp/mq-attempt-unique-check.json CMD="make test-worktree" make evidence
|
||||
```
|
||||
|
||||
每个调用使用新的未占用路径,例中 unique 由执行者替换为该次尝试唯一名称。命令期间若对象变了,保留实际新旧对象和输出,不作为固定候选通过依据,返回 preparing 或退出整改。
|
||||
- [ ] 未通过必要检查、未保存内容或新增提交时建立新尝试;既有最终 CI 不能沿用。合入/清理之后再按既有授权闭合,原始收据不能补写成预期输出。
|
||||
- [ ] 文档与直接回归记录保存后提交;能力矩阵将此登记为 manual 流程+现有工具捕获能力,不宣称 OS 级冻结保护。
|
||||
|
||||
### U4:将窗口接到实际交付规则及单一记录(R1–R5,MQ1/MQ2/MQ5/MQ6)
|
||||
|
||||
**Files:** Guidelines 已有 draft.11 候选;Dev Modify `AGENTS.md`、`PROJECT.md`、`policy/delivery.md`、`policy/governance.md`、`policy/merge-queue.md`、`policy/adoption.md`、`policy/tool-adaptation-matrix.md`、`scripts/task.sh` 的任务卡模板;Test `tests/test_task.py` 的模板行为;Documents 保留本计划及索引。
|
||||
|
||||
**Interfaces:** 通用正文固定 SHA+项目采纳记录;一份实际平台调度 Issue;原任务卡只引用 entry_id/attempt_id。
|
||||
|
||||
- [ ] 按既有规范完成 Guidelines 文档 Review 与 PR 交付;Dev 采纳实际合入的完整 SHA,不能直接引用本地候选提交作为远端已交付事实。父仓指针正式推进前完成组合 `make test`。
|
||||
- [ ] 根入口只路由到权威条文,修改 AGENTS.md 前应用 writing-for-agents;阶段 7–9 的核验职责不删,改为同一窗口内对象未变只核验。U1–U3 的入口和恢复语义同步到采纳记录、模板与矩阵。
|
||||
- [ ] 文档先记录 approved/pending-activation;只在 U5 准入条件满足、协调者和记录建立后切换 active。源码改进可先交付,不由指针更新或本地测试替代上线切换。
|
||||
- [ ] 在已获该动作授权的实施阶段建立一份 Gitea 调度 Issue,复制通用模板,填写实际协调者、目标、现有写入者清单、CI 预算与接管者;没有协调者则不开放领取。
|
||||
- [ ] 所有正常合入者、闭合 PR、机器人和紧急通道按记录安排。manual 状态由协调者串行修改;Issue 无原子领取能力,不能用编辑成功证明互斥。窗口失联先对账,确认旧执行者停止后交接。
|
||||
- [ ] CI 首版按可用资源和实际运行状态安排当前最终候选,不自动取消其他任务、改 runner 配置或建立定时自动化;30 分钟复查由协调者负责。
|
||||
- [ ] 模板核对必含记录位置、entry_id、attempt_id、固定对象及实际结果引用。治理脚本/模板变更完成后执行 `CMD="make test-governance" make evidence`,正式交付另核验精确对象的全部 CI。
|
||||
|
||||
### U5:平台条件准备及所有者验证(R3/R5,MQ4/MQ8)
|
||||
|
||||
**Files(Dev 仓):** Modify `policy/platform-admission.md`、`policy/tool-adaptation-matrix.md`;必要事实更新经当场验证写 `policy/facts.md`。
|
||||
|
||||
**Interfaces:** 现有 Gitea 分支保护、PR head 状态/运行、所有者亲手执行;不新增本地合入权威。
|
||||
|
||||
- [ ] 当场读取当前 main、保护配置、合法固定 PR 的状态上下文及运行身份;输出经 evidence 脱敏保存。旧 SELF 观察仅作定位。
|
||||
- [ ] 准备保留禁直推与陈旧候选保护、要求实际全部必需 PR 检查的具体配置和恢复步骤;从当次状态确认完整名称,不只保留历史 test 上下文。批准数和身份策略不随本计划擅自调整。
|
||||
- [ ] 与所有者确认隔离验证对象与影响范围;Agent 不自行变更分支保护。用户亲手执行后,取得缺检查、失败检查、陈旧候选、无权推进被拒及合法候选可合入的实际结果。
|
||||
- [ ] 临时平台仓可验证保护机制,但其 fixture CI 不能宣称覆盖 Dev 的完整业务组合。现有 Dev workflow 有仓库 allowlist,不修改 allowlist/凭据范围来让临时仓冒充 Dev;Dev 精确 HEAD 的实际 CI 另核验。
|
||||
- [ ] 已知无法验证的能力标 NOT_RUN/manual;原子准入条件未满足时不切换新模式。自动接管的旧代次拒绝不是人工首版的通过断言,留待后续执行端实现。
|
||||
- [ ] 回填真实对象、身份、运行/拒绝链接及 GATE/REPLAY;仅 API 配置成功仍为观察,不标 enforced。
|
||||
|
||||
### U6:三个真实任务的受控试行与复盘(R1–R5,MQ1–MQ8)
|
||||
|
||||
**Files:** Dev 创建 `tests/test_merge_queue_trial.py`(仅本地临时仓库场景);Documents 试行后创建 `docs/records/2026-10-13-merge-queue-trial.md`,实际日期不同则用真实日期;状态仍以各任务/调度记录为准。
|
||||
|
||||
**Interfaces:** U1–U5 的命令、调度记录和平台入口;不同目标/跨仓依赖使用已有任务授权,不新建业务需求。
|
||||
|
||||
- [ ] 隔离真实 Git 夹具覆盖 A/B/C 共同 R0,按窗口顺序最终同步、检查、合入;断言每条目第一次最终同步后重复核验不产生提交,后继不被要求提前同步。该测试的执行次数不冒充真实 Actions CI 次数。
|
||||
|
||||
新文件复用已有夹具对象,不继承整套 TestCase,避免旧测试被重复发现。下面固定正常路径;故障用例在同一类内复用该夹具:
|
||||
|
||||
```python
|
||||
import unittest
|
||||
import test_task as lifecycle
|
||||
|
||||
class QueueTrialTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.fixture = lifecycle.TaskLifecycleTests(methodName="runTest")
|
||||
self.fixture.setUp()
|
||||
self.addCleanup(self.fixture.doCleanups)
|
||||
|
||||
def test_sequential_delivery_does_not_sync_waiting_branches(self):
|
||||
f = self.fixture
|
||||
branches = ["feature/a", "feature/b", "feature/c"]
|
||||
worktrees = {}
|
||||
waiting_heads = {}
|
||||
for branch in branches:
|
||||
wt = f.root / branch.replace("/", "-")
|
||||
f.git(f.repo, "worktree", "add", "-b", branch, str(wt), "origin/main")
|
||||
f.record_task_card(wt)
|
||||
name = branch.split("/")[1]
|
||||
(wt / name).write_text(name + "\n")
|
||||
f.git(wt, "add", name)
|
||||
f.git(wt, "commit", "-m", "Add independent fixture change")
|
||||
worktrees[branch] = wt
|
||||
waiting_heads[branch] = f.git(wt, "rev-parse", "HEAD").stdout
|
||||
f.advance_remote()
|
||||
for position, branch in enumerate(branches):
|
||||
wt = worktrees[branch]
|
||||
f.task(wt, "sync")
|
||||
candidate = f.git(wt, "rev-parse", "HEAD").stdout
|
||||
f.task(wt, "sync")
|
||||
self.assertEqual(f.git(wt, "rev-parse", "HEAD").stdout, candidate)
|
||||
self.assertEqual(f.git(wt, "status", "--porcelain").stdout, "")
|
||||
f.git(f.repo, "merge", "--no-ff", branch, "-m", "Merge fixture candidate")
|
||||
f.git(f.repo, "push", "origin", "main")
|
||||
for waiting in branches[position + 1:]:
|
||||
self.assertEqual(f.git(worktrees[waiting], "rev-parse", "HEAD").stdout,
|
||||
waiting_heads[waiting])
|
||||
```
|
||||
|
||||
- [ ] 注入冲突、已知失败、紧急插队、目标外部推进、依赖未满足和未知合入结果,核对允许继续的健康对照;不同目标互不阻塞,组件组合不回退。
|
||||
|
||||
本地自动用例证明 Git/脚本行为;Issue 状态、失联交接及平台结果未知的处置由受控操作清单和实际对账记录验证,不因本地测试通过而宣称人工流程已自动互斥。
|
||||
- [ ] 执行 `PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -p 'test_merge_queue_trial.py' -v` 和 `make test-governance`;回归实际 stdout/对象,不制造 GATE 标签。
|
||||
- [ ] U5 条件满足且用户批准试行后,由协调者选择三个已经获实施/合入授权且就绪的真实任务;不足三个时保留待试行,不为凑数生成生产 PR,也不干预未纳入的任务。
|
||||
- [ ] 记录每个尝试的实际最终同步次数、全部 CI 尝试/运行耗时、因目标移动废弃的运行、等待时长、恢复次数及真实结果。区分开发 CI、最终 CI 和 main 合入后 CI,不能只统计省下的一类。
|
||||
- [ ] 正常顺序交付的验收目标是没有因其他正常排队任务的合入而废弃最终 CI;整改、插队等另计。无可比历史数据时只报告本次观察,不给节省百分比。
|
||||
- [ ] 人工评审试行结果后决定继续/调整/回退。回退先停止领取、对账活动合入,再恢复旧流程;保留全部记录,不删除未知结果历史。
|
||||
|
||||
## 4. 验证、交付与停止条件
|
||||
|
||||
| 对象 | 最小验证 | 结果权威 |
|
||||
|---|---|---|
|
||||
| U1 | 有卡片的重复同步、新目标、真实最终 SHA、父子仓/网络/冲突保护 | 本地 SELF;正式交付补对应 GATE/REPLAY |
|
||||
| U2 | 严格/局部对照、启动/恢复用途、历史收据、分支守卫负例 | 同上 |
|
||||
| U3 | 原始仓外捕获、固定身份、原样导入、无重复写入 | 同上;不把流程约定标工具冻结 |
|
||||
| U4 | 权威条文、采纳、模板、全部写者/协调者安排及 make test-governance | 规范批准与命令证据分别记录 |
|
||||
| U5 | 实际缺检查/失败/陈旧/无权拒绝及合法路径 | 固定对象的 GATE/REPLAY,配置观察不替代 |
|
||||
| U6 | 临时真实 Git 故障/健康对照+真实三任务与全部 CI 成本 | 临时测试 SELF,实际平台运行 GATE,人工验收另记 |
|
||||
|
||||
每个源码单元只提交其拥有文件。所有完成声明保留 precheck、task-sync 与直接相关检查的工具收据;
|
||||
新对象需重新判断结论,固定后收据位于源码之外。验收、Review、合入分别遵循当时仍有效的门禁,不抢先使用未启用的新语义。
|
||||
Docs、Guidelines、Dev 各仓 PR 和实际合入 SHA 分别核验;文档计划合入不授权执行所有者操作或启动业务试行。
|
||||
|
||||
停止条件:需求/契约或优先顺序变化,原 R0 不再适用,现场归属不明,当前平台/CI 身份无法核验,
|
||||
用户批准缺失,或实际合入结果未知。只暂停受影响范围;符合授权的其他局部工作继续。
|
||||
|
||||
## 5. 自审与完成定义
|
||||
|
||||
| 规格要求 | 计划覆盖 |
|
||||
|---|---|
|
||||
| 调度对象、记录和共同基线 | U2/U4/U6 |
|
||||
| 最终同步至核验串行窗口 | U1/U4/U6 |
|
||||
| 源码外证据及真实候选 | U1/U3/U5 |
|
||||
| CI 分配、去重与结果适用性 | U4/U5/U6;首版明确现有 workflow 不分流 |
|
||||
| 依赖、插队、失败与恢复 | U4/U6;自动接管明确不在首版 |
|
||||
| 采纳、能力登记与回退 | U4/U5/U6 |
|
||||
|
||||
计划通过评审后,U1–U3 可以开始隔离实施;U4–U6 依前置条件推进。
|
||||
源码已实现、规范已采纳、平台已核验、模式已切换、三任务试行通过分别记录,不用一个“完成”代替。
|
||||
计划编制时源码与平台试验均 NOT_RUN;编制检查仅覆盖计划来源、路径、链接、状态和需求覆盖。
|
||||
|
||||
实施续办:U1–U3 在 Dev 任务分支实现并保留实际验证收据;U4 的规则/模板和待启用 Issue #518 已准备;
|
||||
U5 仅完成只读观察、配置与恢复材料;U6 临时真实 Git 场景已运行,真实 CI/业务试行仍待 U5 和相应批准。
|
||||
当前源码/自检不从历史计划推断,统一回链
|
||||
Dev `.task/feature-merge-queue-policy-draft.md` 的完整对象与原始输出。
|
||||
|
||||
建议采用原生逐项实施:三个源码单元紧密依赖同一套任务/evidence 接口,由一个写者修改更易保持兼容。
|
||||
实施产物和计划仍需既有人工阶段评审;最终代码 Review 按仓库职责安排独立审阅,不由作者自签。
|
||||
@@ -0,0 +1,243 @@
|
||||
---
|
||||
title: RDM 设置归属、成员、文档职责与权限矩阵完善增量方案
|
||||
date: 2026-10-13
|
||||
type: feature
|
||||
execution: code
|
||||
artifact_contract: rdm-increment-plan/v1
|
||||
product_contract_source: legacy-requirements
|
||||
---
|
||||
|
||||
# RDM 设置归属、成员、文档职责与权限矩阵完善增量方案 r1
|
||||
|
||||
负责人:weichen;编制:ZCode;核对日期:2026-10-13(北京时间)。
|
||||
上游方案:[2026-10-12 RDM 功能、实现与计划矩阵及整改方案](2026-10-12-rdm-function-implementation-plan.md)(下称"总案"),本增量承接其本稿 U3、U4、U6,涉及职责一致性的部分衔接 U5。
|
||||
|
||||
评审状态:2026-10-13 用户评审通过(同意方案及技术评审意见),并授权按本方案实施(P1–P8 两批推进;正式验收与清理回收节点保留人工确认)。技术评审对源码声明的逐项核查结论见文末「评审核查记录」。
|
||||
|
||||
## Goal Capsule
|
||||
|
||||
以现有 RDM 实施总案的一个完整增量,先厘清设置归属和服务端权限,再补齐搜索、选择、职责分配与权限矩阵交互,保证界面显示、保存结果和实际执行一致。终点:创建者、普通成员、职责人员在真实账号浏览器流程中完成成员添加、职责分配、权限查看与设置保存,且服务端边界(受管设置、成员校验、原子职责变更、权限范围)全部经真实请求验证。
|
||||
|
||||
非目标:不扩展飞书集成、组织架构、多角色叠加或全量文档生成工程。
|
||||
|
||||
## 一、当前实现与需要补齐的内容
|
||||
|
||||
| 方面 | 当前源码情况 | 本次需要完成 |
|
||||
|---|---|---|
|
||||
| 设置归属 | 项目设置展示完整 schema;用户、项目设置都能覆盖模型等配置 | 设置作用域、管理员系统设置入口、写入与最终生效值双重约束 |
|
||||
| 成员管理 | 手填账号;已有分页账号目录,但只有账号和有效态 | 账号/姓名搜索、提示选择、下拉浏览、专业角色过滤、明确的项目身份修改 |
|
||||
| 文档职责 | 手填文档 ID 和人员账号;主要读取提交快照 | 文档搜索/列表/树选择、当前职责回填、项目成员选择、提交校验 |
|
||||
| 权限查看 | 已有单成员权限解释表 | 单成员详情与多人矩阵、中文标签、项目动作范围、上限内配置 |
|
||||
| 一致性 | 存在职责目标未校验成员、职责更新与审签失效分步执行等缺口 | 服务端统一校验、原子变更、版本冲突、撤权及历史保全 |
|
||||
|
||||
对应实现锚点:Frontend `src/components/ProjectSettingsModal.tsx`、`src/components/adminRdmSections.tsx`;Backend `internal/settings/settings.go`(覆盖链 `defaults → system → user → project`);RDM `plugins/rdm/plugin.go`、`internal/perms/perms.go`、`internal/rdmapp/docsubmission.go`。
|
||||
|
||||
## 二、设置归属与界面结构
|
||||
|
||||
沿用现有设置入口和 `SettingsShell`,项目设置收敛为四个页面:
|
||||
|
||||
| 页面 | 内容 |
|
||||
|---|---|
|
||||
| 项目设置 | 真正属于本项目的共享配置与协作规则 |
|
||||
| 项目成员 | 成员搜索、添加、项目身份调整、移除 |
|
||||
| 文档职责 | 文档查找、职责查看与分配、相关审签状态 |
|
||||
| 项目权限 | 单成员权限详情、成员权限矩阵、允许范围内的配置 |
|
||||
|
||||
系统管理中补齐“模型与服务配置”,承接主模型、轻量模型、Embedding、Rerank、模型密钥与 Tavily 等系统配置;Agent 工具限制、系统插件、全局专业角色和权限上限也归系统管理。个人设置只保留个人偏好。
|
||||
|
||||
实施时需要处理三个层面:
|
||||
|
||||
- **展示范围**:设置描述携带允许作用域、管理资格、生效时机;项目页面只消费项目项。
|
||||
- **写入范围**:用户/项目 API 拒绝写入系统受管项,包括嵌套字段和点路径形式,插件设置也遵守同一规则。
|
||||
- **实际生效**:旧用户/项目覆盖值不能继续影响系统模型;个人画像的模型路由及个人模型密钥也必须纳入受管校验,堵住其他覆盖入口。
|
||||
|
||||
另外,当前“项目设置”实际上按“用户+项目”保存(Backend `Effective(owner, projectID)`,project scope 物理存储在各 owner 名下)。需要区分:
|
||||
|
||||
- **共享项目业务配置**:以项目为权威,同一项目不同成员读取一致。
|
||||
- **个人在该项目中的偏好**:继续属于个人。
|
||||
|
||||
跨会话读取必须保留本人会话的隐私边界,不能因项目配置共享而开放其他成员的私聊、上传原件或个人草稿。
|
||||
|
||||
## 三、成员管理交互
|
||||
|
||||
采用**一个可搜索的人员选择器**,同时支持输入、提示选择和下拉浏览,不为每种途径增加独立页面。
|
||||
|
||||
添加流程:打开人员选择器 → 输入账号或姓名,或浏览候选 → 可按专业角色过滤 → 选择人员 → 设置项目身份 → 添加。
|
||||
|
||||
具体行为:
|
||||
|
||||
- 输入账号支持精确匹配;姓名、账号支持模糊检索。
|
||||
- 未输入时显示分页候选;选择器内提供“全部专业角色/系统工程师/软件工程师……”筛选。
|
||||
- 候选显示“姓名、账号、专业角色”;同名人员通过账号区分,姓名为空时使用账号。
|
||||
- 已加入人员标记“已加入”,避免重复添加造成隐式身份变更。
|
||||
- 最终提交稳定账号标识,不能直接提交搜索文字。
|
||||
- 成员表分别展示“专业角色”和“项目身份”,不混用两者。
|
||||
|
||||
项目身份使用“项目负责人/项目成员”等中文名称。成员行提供明确的“调整项目身份”和“移除”操作;继续保护最后一位负责人。
|
||||
|
||||
服务端复用已有 `rdm.account.list`,补齐受限的姓名搜索、精确账号校验和专业角色摘要。**不能直接把管理员用户列表或包含全部账号绑定的角色管理接口开放给项目负责人。**
|
||||
|
||||
角色筛选只帮助找到人员;项目负责人不能借此修改账号的全局专业角色。账号有效状态必须来自基座实际能力,不能把当前简单的 `valid=true` 当作完整的账号停用机制。
|
||||
|
||||
## 四、文档查找与职责分配
|
||||
|
||||
文档职责页面采用“**文档清单+选中文档的职责详情**”:
|
||||
|
||||
- 上方提供统一搜索框,支持文档 ID 精确检索、标题精确/模糊匹配。
|
||||
- 支持文档列表与树形浏览;阶段、文档类型、未分配/已分配、审签状态可用于筛选。
|
||||
- 树形视图忠实呈现当前文档结构,只有文档节点可以作为职责分配对象,章节不能误作 `docId`。
|
||||
- 搜索、列表和树选择共用同一目录与选中状态。
|
||||
- 结果显示名称、阶段/类型、职责概况和状态;ID 保留为辅助定位信息。
|
||||
|
||||
已有文档树查询属于审计面,不能降低它的授权规则来供选择器使用。应补齐专用的职责管理元数据读面:
|
||||
|
||||
- 有职责分配权的管理者可以读取必要的管理元数据。
|
||||
- 普通成员只获得其有权查看的文档范围。
|
||||
- 标题、数量、筛选结果和树节点均在服务端过滤,避免通过搜索泄露不可见资源。
|
||||
|
||||
选中文档后,立即读取并回填**当前职责**,包括尚未提交过审签的文档。当前职责与“某轮提交冻结的职责名单”分别展示,不能混为一份数据。
|
||||
|
||||
人员选择规则:
|
||||
|
||||
| 职责 | 选择方式 | 约束 |
|
||||
|---|---|---|
|
||||
| 编制人 | 搜索、下拉、专业角色过滤 | 单选 |
|
||||
| 审核人 | 搜索、下拉、专业角色过滤 | 多选,至少一人 |
|
||||
| 批准人 | 搜索、下拉、专业角色过滤 | 单选 |
|
||||
|
||||
**所有候选只能来自当前项目成员。**保存时服务端再次校验账号、项目成员关系、对象归属、操作资格和职责版本;文档级(`rdm.review.assign.doc`)、章节级(`rdm.review.assign`)及旧命令入口均遵守同一规则。
|
||||
|
||||
保留编制、审核、批准互异的规则。专业角色筛选不自动授予文档职责;管理权也不自动获得代编、代审或代批资格。
|
||||
|
||||
职责变更需要补齐以下行为:
|
||||
|
||||
- 在途审签受影响时,先显示受影响轮次与“需要重新提交”的提示。
|
||||
- 明确确认后,职责更新、在途审签失效和事件记录原子完成。
|
||||
- 保留旧冻结名单、审核记录和已批准历史,不把旧票带入新轮次。
|
||||
- 无变化保存保持幂等;并发修改返回明确冲突。
|
||||
- 移除仍承担当前职责的成员前,展示受影响文档并引导处理,防止留下无人可执行的职责。
|
||||
|
||||
总案要求的批量分配放在同一文档清单中:勾选文档、预览统一职责方案、确认提交。首版采用有界批次,任一文档校验失败则整批不写入,并列出原因。
|
||||
|
||||
## 五、单成员权限与多人矩阵
|
||||
|
||||
“项目权限”提供两个视图,共享同一服务端权限解释:
|
||||
|
||||
| 视图 | 默认行为 | 用途 |
|
||||
|---|---|---|
|
||||
| 按成员查看 | 普通成员查看自己;管理者可搜索其他成员 | 查看具体权限、配置来源和拒绝原因 |
|
||||
| 权限矩阵 | 管理者查看成员×项目动作 | 比较成员权限,发现缺失或差异 |
|
||||
|
||||
矩阵支持成员搜索、专业角色/项目身份过滤、分页及权限分组。点击单元格可展开解释,显示角色默认、管理员上限、项目覆盖及结果。
|
||||
|
||||
项目覆盖使用三态:沿用角色默认/项目内允许/项目内禁止。管理员上限禁止的动作不能通过项目覆盖授予;“恢复默认”需要实际撤销覆盖,不能用一个布尔值模拟。
|
||||
|
||||
权限目录必须明确动作所属范围:
|
||||
|
||||
| 内部标识 | 显示名称 | 所属范围 |
|
||||
|---|---|---|
|
||||
| `project.create` | 创建项目 | 系统角色权限,项目页面不出现 |
|
||||
| `member.manage` | 管理项目成员 | 项目 |
|
||||
| `duty.assign` | 分配文档职责 | 项目 |
|
||||
| `stage.advance` | 推进项目阶段 | 项目 |
|
||||
| `doc.read` | 读取文档 | 项目动作,具体文档仍须授权 |
|
||||
| `doc.write` | 编制与编辑文档 | 项目动作,仍受职责和状态限制 |
|
||||
| `knowledge.publish` | 发布项目知识 | 项目 |
|
||||
|
||||
这个范围划分同时约束矩阵读面和覆盖写面:**不能只是隐藏 `project.create`,服务端也必须拒绝在项目中配置它。**
|
||||
|
||||
权限名称、项目身份、来源、状态及拒绝原因统一使用人类可读文案。内部标识只保留在按需展开的技术详情中。
|
||||
|
||||
同时核对每项权限与真实操作门禁。例如当前项目归档还有创建者/域管理员条件,矩阵解释必须反映真实条件。矩阵中的“允许编制文档”也不能意味着能修改项目内所有文档。
|
||||
|
||||
普通成员自查权限的条件收敛为“当前有效项目成员”,避免文档读取权限被收回后,连自身权限与原因也无法查看。
|
||||
|
||||
## 六、技术划分与实施工作包
|
||||
|
||||
基座负责身份、基本资料、受管设置机制与通用契约;RDM 负责项目成员、专业角色、权限策略及文档职责;Frontend 负责业务交互;UI 仓提供通用选择器原语。
|
||||
|
||||
| 工作包 | 内容与主要范围 | 依赖 | 完成条件 |
|
||||
|---|---|---|---|
|
||||
| P1 契约与需求固定 | 设置作用域、项目动作目录、人员/文档候选 DTO、能力与版本语义;更新关联方案 | 无 | 本次五项要求都有稳定验收条件,四类身份/角色/职责概念明确 |
|
||||
| P2 系统设置闭环 | Core 设置描述、Backend 设置 API/存储/生效链/模型及密钥解析;系统管理入口 | P1;**基座发版与 RDM/Dev 升 pins**(见评审补充 1) | 系统受管项只能由有权管理员配置,旧个人/项目值不能覆盖 |
|
||||
| P3 人员与成员接口 | 扩展公开账号搜索;RDM 专业角色摘要、成员查询、项目身份调整与提交校验 | P1;姓名来源核实(见评审补充 3) | 账号/姓名/角色过滤同源,添加与身份调整明确分离 |
|
||||
| P4 文档与职责接口 | 专用文档目录、当前职责读取、统一职责服务、版本校验、变更失效及成员移除联动 | P1、P3 | 跨项目/非成员指派被拒,职责与审签变更全成或全败 |
|
||||
| P5 通用选择器 | UI 仓搜索选择、单/多选、键盘操作、分页与状态;Frontend 人员/文档适配 | P1,接线依赖 P3、P4 | 三类使用场景共享交互,无自由文本误提交 |
|
||||
| P6 权限解释与矩阵 | RDM 项目动作目录、单人/批量解释、覆盖三态、来源与拒绝原因 | P1、P3 | 矩阵与执行规则一致,系统动作无法写入项目覆盖 |
|
||||
| P7 项目设置集成 | 重构现有项目页,连接四个页面、能力状态、读取回填与保存结果 | P2—P6 | 创建者、普通成员、职责人员均有对应可用流程 |
|
||||
| P8 迁移与组合验收 | 旧配置处置、真实数据库与浏览器验收、精确组件组合验证、证据回填 | P2—P7 | 需求到证据闭合,无越权、隐私泄露或数据丢失 |
|
||||
|
||||
前端主要改动落在现有 `ProjectSettingsModal`、`adminRdmSections`、`rdmManagement`、`api` 和 `store`;按业务拆分成员、职责及权限组件,避免继续扩大一个管理组件文件。
|
||||
|
||||
目前 Dev 与 RDM 固定的 Backend 版本存在能力差异。实施时必须按公开契约推进相关版本,再完成组合验证,不能因为独立 RDM 仓已有某个接口就假定 Dev 组合可直接使用。
|
||||
|
||||
## 七、界面与异步状态要求
|
||||
|
||||
按根目录 `DESIGN.md` 实施,复用现有令牌、动效、设置外壳和折叠原语。
|
||||
|
||||
- 一种对象只有一个主要选择路径,搜索和浏览在同一选择器完成。
|
||||
- 姓名、文档名为主要信息,账号和 ID 为辅助信息。
|
||||
- 下拉支持键盘移动、确认、关闭;审核人多选使用清晰标签。
|
||||
- 加载、空结果、权限不足、接口未装配、查询失败分别呈现。
|
||||
- 切项目、切文档、改筛选时清除不适用的选中项和结果;迟到响应不能覆盖当前对象。
|
||||
- 异步状态只有一个所有者,按请求代次/事件顺序丢弃过期结果。
|
||||
- 保存后读取服务端结果;网络断开且结果未知时先核对状态,避免盲目重放。
|
||||
- 未保存改动提供轻量离开提示;需重启的设置明确显示待生效,不能统一宣称即时生效。
|
||||
- 窄屏按成员查看权限,矩阵可横向浏览,不压缩成不可读的小格子。
|
||||
|
||||
## 八、迁移、验证与交付安排
|
||||
|
||||
旧配置先做脱敏盘点,列出配置路径、来源和冲突状态。不能任取某个用户/项目的模型配置提升为全系统配置。先确定并验证系统配置,再启用受管策略;旧值保留受保护的恢复依据,退出生效链。
|
||||
|
||||
旧项目内 `project.create` 覆盖退出项目策略,保留历史依据。历史职责、审核与批准记录保留;无效的当前职责列入修复清单,不自动替换人员。
|
||||
|
||||
正式验收至少覆盖:
|
||||
|
||||
| 验收场景 | 预期结果 |
|
||||
|---|---|
|
||||
| 项目与个人设置写入系统模型项,包括手造请求 | 拒绝;旧覆盖也不影响运行结果 |
|
||||
| 账号、姓名、下拉、专业角色过滤查找成员 | 能找到并选择稳定账号;同名不会误选 |
|
||||
| 重复添加已有负责人、并发修改最后负责人 | 不发生隐式降级,不破坏负责人约束 |
|
||||
| 文档 ID、标题、列表、树查找 | 指向同一文档;章节及其他项目对象不能误提交 |
|
||||
| 搜索后人员被移出项目,再保存职责 | 服务端拒绝 |
|
||||
| 职责变更中途失败 | 职责、审签状态与事件完整回滚 |
|
||||
| 单成员详情与多人矩阵对照实际操作 | 结果与原因一致;具体资源限制清晰 |
|
||||
| 项目覆盖授予超上限动作或 `project.create` | 拒绝;恢复默认真正生效 |
|
||||
| 快速切项目/文档、断网、迟到响应 | 不显示旧对象数据,不误报成功 |
|
||||
| 同项目多成员使用、刷新及重启 | 共享配置一致,个人会话与原件仍私有 |
|
||||
|
||||
验证分为领域与契约测试、真实 SQLite/PostgreSQL 集成、真实身份浏览器流程,以及 Dev 精确组合的 `make test`、`make build`。浏览器需要覆盖非管理员项目负责人、普通成员、互异的编制/审核/批准人员及两个项目;不能用全管理员账号代替权限验收。
|
||||
|
||||
分两批形成可审查实现:先完成 P1—P4、P6 的服务端边界与契约,再完成 P5、P7 和 P8 的交互及组合验收。界面设计可在第一批同时评审。
|
||||
|
||||
## 评审补充(2026-10-13 技术评审并入,随方案一并批准)
|
||||
|
||||
1. **P2 显式依赖基座发版。** 受管设置机制是基座(Backend/Core)公开契约扩展,按总案交付顺序走“扩展申请评审→基座实现→基座发版→RDM/Dev 升 pins→组合验证”。P2 完成条件在原基础上追加:基座版本已发、pins 已升、Dev 组合 `make test` 通过。
|
||||
2. **项目共享配置的存储迁移规则。** 当前 project scope 物理存储在各 owner 名下;改为“以项目为权威”需要:新项目作用域存储、存量多 owner 副本的合并策略(默认规则:同键取最近写入时间,冲突清单列出不自动合并的键并交项目负责人裁定)、旧键退出生效链并保留只读恢复依据。P8 交付物含迁移清单与执行记录。
|
||||
3. **姓名来源与账号停用能力须先过 facts。** 基座账号目录当前明确“不含姓名/联系方式”。P3 的姓名搜索依赖基座账号模型是否存有姓名/显示名字段;P1 契约先定姓名来源(基座扩契约,或 RDM 专业角色档案补姓名)。账号停用机制现状同样按 `policy/facts.md` 登记验证,未证实前不把 `valid=true` 当作停用语义。
|
||||
|
||||
## 顺序裁定(2026-10-13)
|
||||
|
||||
本增量按自身 P1→P8 顺序推进;P2 的基座契约扩展按总案 369 行发版顺序执行,与总案 U1/U9 残余项的交织在扩展申请评审时统一排队,不因本增量跳过 U1(正式产物)与 U9(公开授权契约)的既有优先级。
|
||||
|
||||
## 评审核查记录(2026-10-13,源码 3fb8210 / RDM 255f9cb)
|
||||
|
||||
评审对方案“当前源码情况”逐项核查,全部属实:
|
||||
|
||||
| 声明 | 证据 |
|
||||
|---|---|
|
||||
| 项目设置按“用户+项目”保存 | Backend `settings.go` `Effective(owner, projectID)`,project scope 以 owner 为键 |
|
||||
| user/project 覆盖可改模型设置,无受管拦截 | 同上覆盖链,无“系统受管”概念 |
|
||||
| 成员手填账号 | `adminRdmSections.tsx` RdmMembersSection |
|
||||
| 账号目录仅 owner+有效态 | RDM `rdm.account.list` 描述“owner+有效态;不含姓名/联系方式” |
|
||||
| 职责手填 docId 与账号 | RdmDutiesSection placeholder |
|
||||
| 已有单成员权限解释表 | `rdm.perm.check`(动作/生效/来源/原因),前端默认自省 |
|
||||
| 权限标识与所属范围 | RDM `internal/perms/perms.go:21-31`,`project.create` 注释即“全局动作” |
|
||||
| 职责目标未校验成员 | `rdmReviewAssign` handler 注释“数据,非身份”——按 G1-5 旧裁定绕过成员校验;**本方案 P4 推翻该裁定,属规则变更,在 P1 契约中记录** |
|
||||
| 职责更新与审签失效分步 | 文档级 assign 先写职责再调 `InvalidateActiveDocSubmission`,两步顺序非原子;**章节级 assign 完全未接失效** |
|
||||
|
||||
## 主记录与推进
|
||||
|
||||
- 主记录:本文件(唯一正文);任务卡 `.task/feature-rdm-increment-settings-duties.md` 承载需求表、证据与阶段结论。
|
||||
- 来源:`.tmp/Discussion-Meetings/2026-10-08_12-24/.tmp/user-supplement.txt`(原始用户补充)、2026-10-13 会话评审。
|
||||
- 下一步:P1 已随本稿固定;按两批顺序进入 P2(基座受管设置契约扩展申请)与 P3/P4/P6 服务端实现。
|
||||
@@ -0,0 +1,84 @@
|
||||
# 系统项目、成员工作入口与私域协作闭环 r1.1
|
||||
|
||||
状态:用户 2026-10-13 已批准方向并授权阶段 1–9 连续推进;实现与隔离验证进行中。发布版本、部署、8788 数据修复及工作区清理不在本次授权内。
|
||||
|
||||
本增量补齐总案 [RDM 最终目标核对与完整交付方案 r1](2026-10-11-rdm-final-target-completion.md) 的 U2,以及 U3/U5 与项目成员协作直接相关的边界。需求来源为 2026-10-13 用户复现和 `.tmp` 会议补充中“同名项目唯一、加入后可见且能新建对话、会话私有、每项目共享两树一网”。这不是模板全量迁移或三权流程重设计。
|
||||
|
||||
## 已定位的问题
|
||||
|
||||
8788 的成员添加记录已保存,但用的是宿主项目 ID;该 ID 没有领域注册或宿主绑定。列表和对话创建的共享适配器因此拒绝它。新建项目走宿主 owner 表,而成员管理、两树一网走领域表,缺少统一生命周期。会话列表还只检查宿主 owner,领域的名称 UNIQUE 也没有覆盖宿主创建入口。
|
||||
|
||||
r1.1 增量:合并现行主干的成员 Picker、职责目录和权限矩阵,并闭合其独立重放发现的首次提交、渲染确认、迟到响应、职责幂等和持久版本问题;范围仍为本次成员与私域协作。
|
||||
|
||||
运行制品仅有短来源标记,不能把当前源码视为其已证明的组件组合。只读现场证据、对象 SHA 和完整脱敏输出保存在 Dev 本任务卡,不在本文复制命令输出或线上数据。
|
||||
|
||||
## 职责与公开契约
|
||||
|
||||
RDM 保持项目、成员、职责与领域数据权威。Backend 管认证、宿主技术投影、私人会话/工件和通用资源执行边界。Frontend 只消费服务端身份与状态。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
U[认证用户] --> P[统一项目应用服务]
|
||||
P --> D[RDM 项目与成员]
|
||||
P --> H[宿主一对一投影]
|
||||
H --> C[按用户归属的个人会话和原件]
|
||||
D --> W[按项目分片的两树一网]
|
||||
W --> K[成功发布的知识切片]
|
||||
K --> R[当前项目的授权检索与模型上下文]
|
||||
```
|
||||
|
||||
基座扩展申请的四要素:
|
||||
|
||||
| 要素 | 结论 |
|
||||
|---|---|
|
||||
| 场景 | 统一产品项目创建/改名/归档,验证映射两端,并允许项目成员创建个人会话 |
|
||||
| 公开能力 | 可选 `extension.ProjectHost`、`ProjectLifecycle`、`ProjectLifecycleRegistry`;复用 `/api/projects` 与其会话路径;资源查询追加可选 `Source` |
|
||||
| 现有能力不足 | 只读 V1/V2 不承担生命周期、跨库初始化和动作授权;原 Host 没有项目技术投影与管理验证接口;仅项目布尔或已知切片 ID 不能证明索引行仍是发布来源 |
|
||||
| 兼容 | 保留必需 Host/Registry 接口;新能力经可选接口注册。未注册生命周期保留通用基座行为。RDM 产品缺该能力拒绝注册,防止悄然回到宿主个人项目路径 |
|
||||
|
||||
`ProjectHost` 由执行端按认证主体构造;投影修改和管理查找保持 owner 限制,共享 metadata 经过授权和脱敏。`ProjectLifecycle` 的 List/Create/Rename/Archive/Work 是完整注册的一组回调,公共项目入口委托给它。客户端传入的 projectId 或 `rdm.projectId` 均是定位符。
|
||||
|
||||
## 项目身份、名称和恢复
|
||||
|
||||
- 领域项目、名称保留和创建者负责人同库事务提交。跨库投影使用确定的宿主 ID 和持久 `provisioning/failed/ready` 映射;失败重试保持身份,不持有领域事务跨宿主调用。
|
||||
- 本增量名称为去首尾空白后的精确名称;数据库唯一保护覆盖不同账号和并发。改名、归档后保留旧名归属。Unicode/大小写归一没有在本增量自动引入。
|
||||
- 所有产品创建、改名、归档路径使用应用服务;归档保存会话、原件和数据,不能继续新工作。管理重试可定位未完成映射,但仍须 owner/动作检查。
|
||||
- 新绑定验证真实宿主的存在和当前主体管理资格;既有绑定的 metadata/工作还验证物理宿主 owner 与映射创建者相符,不能只信映射存在。
|
||||
- 现有孤立宿主项目通过 `rdm.project.adopt` 先预览、再显式 apply;保留宿主 ID 和 owner,将成员关系移到领域根。不能凭名称猜测已有领域身份,不把未归属历史默认搬入新根。
|
||||
|
||||
## 共享与私域
|
||||
|
||||
| 数据 | 默认边界 |
|
||||
|---|---|
|
||||
| 个人会话/消息/原件/附件 | owner 私有;成员加入不使其对其他成员可读 |
|
||||
| 个人 pending/rejected 草稿 | 仅提案人;管理角色及其他职责不自动取得正文 |
|
||||
| 受控正文、差异与导出 | 当前项目成员身份、阶段/动作及有效章节或文档职责;审计许可不代替正文许可 |
|
||||
| 已采纳提案的本人不可变历史 | 本人自己的原始提案可保留;其他人读取受控内容走职责 |
|
||||
| 树结构、元信息、快照哈希 | 项目协作所需的结构视图;不能用元信息入口夹带正文预览 |
|
||||
| 历史正文预览 | 当前有效权限,不从历史重放恢复已撤销的职责 |
|
||||
| 原件台账、待处理数量 | 当前 actor 在目标项目的条目;管理角色不自动得全员原件视图 |
|
||||
| 项目发布知识 | 成员、明确领域根、成功发布台账、当前撤销代际与存活切片共同授权 |
|
||||
|
||||
发布切片保留其 ID、owner、原件锚点,索引 `ProjectID` 为领域 ID,来源为 `plugin:rdm:published`。跨 owner 查询还检查实际存储行的 `Source`;手工/私人来源不能借已知切片 ID 绕行。撤销代际阻止已排队或在途任务重新授予共享。替换按 owner、精确项目(含空 ID)、ref、插件命名空间隔离。
|
||||
|
||||
会话使用宿主 ID;HTTP、Host 和模型上下文通过服务端 provider 的可信 metadata 解析领域检索范围。每个实际知识对象再经过 V2,不能先按错误 ID 查空,也不能把 private 候选截断置于授权之前而隐藏合法结果。
|
||||
|
||||
## 界面与执行
|
||||
|
||||
沿用现有侧栏与项目设置,不新增管理屏。服务端 metadata 提供平面的 `rdm.projectId` / `rdm.state`,领域命令用 canonical ID,通用会话接口保留宿主 ID。未就绪项目不能回退创建默认项目;归档/关闭项目仍能读成员、权限和审签状态,不能新工作或修改。
|
||||
|
||||
账号切换使所有待返回的列表、工件、卡片和工作续接失效。执行在确认后、排队恢复以及写入前重验当前权限,撤权后的 HITL 回复不能产生工件或恢复执行。
|
||||
|
||||
项目 SSE 的历史重放和实时发送也必须按对象过滤。旧上传卡没有可信共享声明,不能因加入成员而暴露文件名、解析器或预览。权限从实际卡片/运行归属取值;明确共享由内部发布入口写入与 channel、seq、type 和 payload hash 绑定的声明,客户端 payload 不授予共享。未知或损坏证明拒绝,跳过私域事件仍推进扫描游标,保留未注册基座兼容。此为内部事件数据约束,不增加下游必需接口。
|
||||
|
||||
职责保存先校验对象、三权、成员及版本;无变化不使在途轮次失效,仅实际变更生效前执行既有失效规则。职责版本随事件持久化,旧载荷按实际角色变化重建;写入失败不修改内存职责。
|
||||
|
||||
## 验证与交付
|
||||
|
||||
追溯:R1 名称→并发/碰撞/旧名保留;R2 身份→真实创建/失败重试/物理 owner/绑定;R3 成员→真实登录、同 ID 项目、个人对话;R4 项目分片→两项目隔离;R5 私域→所有查询/预览/台账/模型上下文及撤权;R6 旧数据→显式预览/幂等修复/保留;R7 真实组合→浏览器、真实模型任务对照、独立 Review 和当前 HEAD CI。
|
||||
|
||||
测试原始输出由 evidence 工具写入任务卡,来源分开。单测、桩适配器、源码存在均不作为用户流程已完成的证明。当前完整运行/CI结果在任务卡维护,不在本文预写 PASS。
|
||||
|
||||
RDM README/AGENTS 要求合入前回到基座 tag pin;开发期采用隔离 modfile组合验证。发布新 tag 属用户亲手执行的高后果操作,必须先形成已评审且 CI 通过的具体基座候选。tag、合入、部署、运行库修复和清理分别核验,不能合并成一个“完成”。
|
||||
|
||||
下一步:完成本增量的组合验收与 tag 消费闭环;随后建议由用户授权在 8788 部署精确组合,并预览/修复已确认的孤立项目。未知历史归属、名称碰撞或身份不一致保留现场交人工裁定。
|
||||
+17
-1
@@ -6,6 +6,12 @@
|
||||
|
||||
## 先看哪一份
|
||||
|
||||
- [IAM I1 权限边界与公开扩展合同 r1](2026-10-13-iam-i1-permission-contract.md):
|
||||
依据已批准的[用户、职位角色与分层权限统一方案 r1](2026-10-13-identity-role-permission-plan.md)
|
||||
(Documents `a088809`)冻结系统/项目/资源边界、管理员无业务 bypass、创建者 cap、独立 `audit.read` 与公开扩展四要素。
|
||||
2026-10-13 已授权 I1(U1–U2);多职、通用角色迁移、资料目录、矩阵及完整运行验收仍按后续单元推进,不以合同保存宣称已交付。
|
||||
实际进展与证据见 [I1 实施候选与评审记录](2026-10-13-iam-i1-review.md),用户实施评审及[阶段 7 验收](2026-10-13-iam-i1-acceptance.md) 已通过,当前进入智能体 Review、PR、CI 与合入。
|
||||
|
||||
- [快慢通道展示与动态工作摘要方案 r1.1](2026-10-12-fast-slow-channel-display.md):
|
||||
运行卡呈现状态、已完成工作、当前发现与剩余项;四层阅读、阶段成果、来源、异常恢复及 U1–U4。
|
||||
2026-10-12 方案设计已批准(阶段 1–4);首批仅 U1;[U1 实施计划 r1](2026-10-12-fast-slow-channel-display-u1-plan.md) 待阶段 5 批准;业务实施和运行验收 NOT_RUN。
|
||||
@@ -170,9 +176,15 @@ RDM 总案把库分期作为支撑与依赖,不覆盖库分期的原始范围
|
||||
后续维护:主案或任务变化时先更新其唯一主记录,再更新这里的导航和核验快照。
|
||||
更换 Docs/Dev 基线后重新核对 PR、版本与在途任务;新的索引状态不自动产生实施授权。
|
||||
|
||||
## 2026-10-13 规划补充
|
||||
|
||||
- [最终验证与合入调度实施计划 r1](2026-10-13-merge-queue-implementation-plan.md):阶段 5 已于 2026-10-13 经用户「批准」确认,原生逐项实施;U1–U3 源码与自检在 Dev 任务分支推进,U4 待启用记录及规则已准备,U5 平台所有者操作与 U6 真实三任务 CI 试行仍 NOT_RUN。实际对象、证据和进度回链 Dev 任务卡,不把本索引当第二进度权威。
|
||||
|
||||
- [RDM 设置归属、成员、文档职责与权限矩阵完善增量方案 r1](2026-10-13-rdm-settings-members-duties-perms-increment.md):承接总案 U3/U4/U6(衔接 U5)的完整增量——设置作用域与受管项、可搜索人员选择器、文档清单+职责分配、单成员/多人权限矩阵与三态项目覆盖;含服务端一致性修复(职责目标成员校验推翻 G1-5 旧裁定、职责变更与审签失效原子化)与 P1–P8 工作包。**2026-10-13 用户评审通过并授权实施**(两批推进;正式验收与清理回收保留人工节点);P1 契约随本稿固定,P2 基座契约扩展按总案发版顺序排队。
|
||||
|
||||
## 2026-10-12 规划补充
|
||||
|
||||
- [svc 统一部署与一次性登录 Key 方案 r1](2026-10-12-svc-unified-deploy-and-login-key.md):将 `svc.sh` 增强为二进制/源码统一部署入口,并补齐无初始密码开户与账户恢复;一次性登录 Key 只能兑换设密受限会话。r1 含源码复核与四项取舍定案;复用恢复方案 KTD 与已合入的 recovery U1(Dev #415)。**2026-10-12 已批准**(五阶段+U1/U4 规格);授权推送/PR 与 U1/U4 实施启动;合入由 owner 执行。规格见 Dev `docs/svc-deploy/`。
|
||||
- [svc 统一部署与一次性登录 Key 方案 r1](2026-10-12-svc-unified-deploy-and-login-key.md):将 `svc.sh` 增强为二进制/源码统一部署入口,并补齐无初始密码开户与账户恢复;一次性登录 Key 只能兑换设密受限会话。r1 含源码复核与四项取舍定案;复用恢复方案 KTD 与已合入的 recovery U1(Dev #415)。**2026-10-12 已批准**(五阶段+U1/U4 规格);r2 增补经 #87 合入;**2026-10-13 r3:登录恢复流程按用户「按此方案实施」批准并合入**(Backend #187 / Frontend #76 / Dev #504,浏览器验收 PASS;三裁定与实施记录见 §11)。规格与合同见 Dev `docs/svc-deploy/`。
|
||||
|
||||
- [服务重启与全量数据恢复方案 r2](2026-10-12-service-restart-data-recovery.md):2026-10-12 用户要求 svc 停止/再次启动及异常退出后恢复所有服务与数据;覆盖服务依赖/监管、持久配置和数据身份、run/HITL/命令/通知、未知副作用隔离、文件一致性与组合备份。r1 经六角色自审,r2 吸收外部源码复核(见同名 review 记录两轮)。**2026-10-12 用户批准 r2(五阶段一并)**;实施/故障注入/部署/运行验收 NOT_RUN。关联协作存储 R7;U2 首切片已由 svc-autorecover 任务合入 main(PR #396/#401,2026-10-11);U1 实例身份已合入(Dev #415,2026-10-12),余量按 KTD 对齐后续增量。
|
||||
|
||||
@@ -183,3 +195,7 @@ RDM 总案把库分期作为支撑与依赖,不覆盖库分期的原始范围
|
||||
- [RDM 模板与两树一网对话文档生成方案 r1.1](2026-10-11-rdm-template-dialog-generation.md):69 类旧资产、4 个当前注册模板的盘点及生成闭环设计;待评审,实施/迁移/模型试验/运行验收 NOT_RUN。与两树一网集成方案共用项目授权、原子事件与历史能力。 首批项目建议书/竞品分析、随后扩展全部文档已确认(2026-10-11),其余方案与实施仍待评审。
|
||||
|
||||
- [RDM 最终目标核对与完整交付方案 r1](2026-10-11-rdm-final-target-completion.md):本轮用户确认系统级唯一项目、管理员上限内覆盖、私域与三权读取边界;覆盖 34 UR/68 SR/10 F、全部69类模板及现有XLSX,当前源复核 RDM d8d7e743。总体方案待评审,实施/迁移/运行验收 NOT_RUN;模板方案为子方案。
|
||||
|
||||
- [工作台界面重设计 r0.2](2026-10-12-work-companion-ui-design.md)及[实施计划 r1](2026-10-12-work-companion-ui-plan.md):对话优先、渐进任务摘要、窄屏与单一状态投影;已获本次连续实施授权。
|
||||
|
||||
- [系统项目、成员工作入口与私域协作闭环 r1.1](2026-10-13-system-project-membership.md):2026-10-13 已批准方向及阶段 1–9 连续推进;统一生命周期、成员个人会话、每项目两树一网与私域权限;组合验收/CI/tag 消费推进中,部署和线上修复未授权。
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# U7 运维演练与数据库基线报告(SELF,2026-10-12)
|
||||
|
||||
来源标注:**SELF**(本机隔离栈执行;非 CI GATE、非独立 REPLAY)。用户 2026-10-12 决定不做容量重放。不得据此放行第二实例写流量。
|
||||
|
||||
## 1. 被测对象
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| Backend gitlink | `8e509775d39d1455b69be44803037faa7af844b4` |
|
||||
| B6 Dev HEAD | `b2e129ab3f3bdf222f16040fcd0513872d0e2a3c` |
|
||||
| C4 Dev HEAD | `308f33665eb2dfaf9ae661e87df8898c3c2ecb3a` |
|
||||
| C5 Dev HEAD | `792574692609d9bfdf113e2dc5af6f43c9a176dd` |
|
||||
| 主机 | 32 逻辑 CPU,122 GiB RAM;演练开始时 load average 见各 `host.txt` |
|
||||
| 入口 | `tests/load/collaboration/run_pgbench.sh`;`tests/ops/run_fault_drill.sh`;`tests/ops/run_backup_drill.sh` |
|
||||
|
||||
原始输出在测量 worktree 的 `results/`(gitignore),不入库。任务卡 evidence 为 SELF。
|
||||
|
||||
## 2. B6 pgbench
|
||||
|
||||
结果目录 `tests/load/collaboration/results/pgbench-20261012-131948`。隔离实例 `u7bench`,scale 100,每档 60 秒,`-M prepared`。`max_connections=100`,`superuser_reserved_connections=3`,100 客户端封顶为 95。六档失败事务均为 0。
|
||||
|
||||
| 模式 | 客户端 | tps | P50 | P95 | P99 |
|
||||
|---|---|---|---|---|---|
|
||||
| select-only | 10 | 535646 | 0.018 ms | 0.024 ms | 0.030 ms |
|
||||
| TPC-B 类 | 10 | 18798 | 0.339 ms | 0.673 ms | 5.560 ms |
|
||||
| select-only | 30 | 952115 | 0.026 ms | 0.057 ms | 0.078 ms |
|
||||
| TPC-B 类 | 30 | 52224 | 0.493 ms | 1.002 ms | 1.777 ms |
|
||||
| select-only | 95 | 904708 | 0.087 ms | 0.180 ms | 0.417 ms |
|
||||
| TPC-B 类 | 95 | 50607 | 1.041 ms | 3.361 ms | 18.106 ms |
|
||||
|
||||
主机不空闲。这是数据库参考基线,没有业务阈值,也不替代容量窗口。
|
||||
|
||||
## 3. C4 断连
|
||||
|
||||
结果目录 `tests/ops/results/fault-20261012-142734`。PG 18991,应用 18990/18992,Redis 18993。
|
||||
|
||||
| 判据 | pg-stop | pg-kill |
|
||||
|---|---|---|
|
||||
| F1 有界失败、进程仍在 | 过 | 过 |
|
||||
| F2 不回落 SQLite,新进程拒绝就绪 | 过 | 过 |
|
||||
| F3 恢复后两侧各 5 次写入 | 过,RTO 不到 1 秒,未重启应用 | 同左 |
|
||||
| F4 失败 requestId 重放恰好一条 | 过 | 过 |
|
||||
| F5 dup_seq=0、seq 无洞、无非终态 run | 过 | 过 |
|
||||
|
||||
Redis 限额 20 次/分钟,两实例各突发 40 个读:
|
||||
|
||||
| 判据 | 结果 |
|
||||
|---|---|
|
||||
| G1 共享限额 | 放行 20、429 为 60、其他错误 0 |
|
||||
| G2 断连 | 放行 40、429 为 40、其他错误 0;已确认写入仍在 |
|
||||
| G3 只拉起 Redis | 放行回到 20;`rl:*` 均有过期时间 |
|
||||
| G4 | 发现:日志看不到降级计数 |
|
||||
| G5 | 发现:Redis 不通时新进程拒绝启动 |
|
||||
|
||||
`runtime.redisAddr` 没有调用者可写的产品入口。演练用 SQL 写入默认 owner `local` 的 `user` 设置,并保留 mock。
|
||||
|
||||
## 4. C5 备份与恢复
|
||||
|
||||
结果目录 `tests/ops/results/backup-20261012-153441`。源 PG 18994,恢复目标 18997。合同数据量 seed 约 12 秒。
|
||||
|
||||
| 判据 | 结果 |
|
||||
|---|---|
|
||||
| K1 备份有效 | 过。`failed_count=0`,`archived_count=80`,`pg_verifybackup` 与 `pg_restore --list` 退出码 0 |
|
||||
| K2 RPO≤5 分钟 | 过。64 秒 |
|
||||
| K3 RTO≤60 分钟 | 过。4 秒。恢复后登录、列项目、读会话均为 200 |
|
||||
| K4 工件与权限 | **FAIL**。五次上传都没有拿到工件编号 |
|
||||
| K5 不变量 | 过。dup_seq=0,seq 无洞;恢复后消息/事件/知识/run 计数与故障前一致(消息 1 000 120);非终态 run 为 0 |
|
||||
| K6 逻辑恢复 | 过。`pg_restore` 退出码 0,约 4 秒;计数等于 dump 时快照(消息 1 000 000,知识 100 000) |
|
||||
| K7 权限与泄密 | 过。备份目录 700、文件 600;结果文本里没有连接串。静态加密与凭据演练记 N/A。归档和数据在同一块盘,没有模拟存储全毁 |
|
||||
|
||||
恢复后的计数与故障前一致,说明已提交的标记都在。64 秒是最后一条成功标记的确认时间到故障时刻的间隔;窗口末尾有的写入因为会话仍被 mock run 占用而没有落库。
|
||||
|
||||
K4 的原因在源应用日志:未设置 `BLOBSTORE_S3_ENDPOINT` 时,`NewS3FromEnv` 返回空的 `*S3`。这个空指针被放进 `blobstore.Store` 接口后不再等于 nil,`finishOpen` 不会回落本地目录,上传在 `blobstore.(*S3).Put` 空指针 panic。产品代码未改。因此工件 sha256 和跨用户拒绝没有测成。代码里本地后端的 `content_path` 是绝对路径;这次没有成功上传,所以没有用恢复后的下载来核验。
|
||||
|
||||
同日另一次恢复(`backup-20261012-150713`)在数据目录复制之后起不来,因为 socket 路径超过 107 字节。正式这次把 socket 放到 `/tmp/u7bk-18997`。
|
||||
|
||||
## 5. 放行(2026-10-12 当时)
|
||||
|
||||
B6、C4 为 SELF 通过。C5 的库恢复为 SELF 通过,工件恢复失败。第二实例写流量仍不放行。
|
||||
|
||||
当时还没做、该任务不启动的三项:
|
||||
|
||||
- 独立 REPLAY,或把 C4/C5 的快速档接进 CI 成为 GATE(需要平台准入)。
|
||||
- C3 双主机。
|
||||
- 上传在未配置对象存储时 panic,需要单独的产品修复后才能重测 K4。
|
||||
|
||||
## 6. 2026-10-13 K4 重测
|
||||
|
||||
上传 panic 已在 store 边界修复:带类型的空对象存储(未设置 `BLOBSTORE_S3_ENDPOINT` 时的 `(*S3)(nil)`)视为未配置,回落本地工件目录。已构造的对象存储保持不变。Backend 提交 `46073d30`,Dev 被测头 `a83588dd`,backend gitlink 同为 `46073d30`。
|
||||
|
||||
重跑入口仍是 `tests/ops/run_backup_drill.sh`。结果目录 `tests/ops/results/backup-20261013-013354`(SELF)。原始结果另存于仓外 `/home/weichen/projects/u7-k4-retest-preserved-20261013`。
|
||||
|
||||
| 判据 | 结果 |
|
||||
|---|---|
|
||||
| K1–K3、K5–K7 | 过。RPO 65 秒,RTO 3 秒。`pg_verifybackup` 与 `pg_restore --list` 退出码 0,逻辑恢复约 5 秒,恢复后计数与故障前一致 |
|
||||
| K4 工件与权限 | **过**。5 个工件 `checked=5`、`missing=0`、`mismatch=0`。跨用户访问项目和工件均为 404 |
|
||||
|
||||
`content_path` 仍是绝对路径,快照继续还原到原目录。静态加密、凭据演练和整盘损坏仍是 N/A。
|
||||
|
||||
第二实例写流量仍不放行。剩下的门槛是独立 REPLAY 或经平台准入后的 C4/C5 CI 快速档,以及 C3 双主机。
|
||||
@@ -0,0 +1,51 @@
|
||||
# 合入调度首轮受控试行(2026-10-14)
|
||||
|
||||
状态:三个真实任务已由智能体依次合入;本报告记录 **manual** 模式的实际观察。是否扩大试行、调整预算或建设自动领取,仍待用户评审。依据为[已批准的实施计划](../proposals/2026-10-13-merge-queue-implementation-plan.md) U5–U6、[Dev 项目规则](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/src/branch/main/policy/merge-queue.md)和[唯一调度记录 #518](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/issues/518)。本报告不代表发布、部署或运行服务验收。
|
||||
|
||||
## 范围与证据口径
|
||||
|
||||
用户授权由当前智能体接管已有的 Dev #489、#488、#486,确认三者没有其他活动写者;所有实际 PR 合入由智能体执行。Dev `refs/heads/main` 的仓库 ID=29,协调者和窗口在 #518 登记。原任务 R0 各自不同,未伪称共同启动 SHA。组件先按自身目标交付,再固定 Dev 父仓组合;等待的 Dev 源分支没有随前一个正常合入反复同步、推最终候选或跑最终 CI。
|
||||
|
||||
证据分层:本机 `make evidence`、API 读取及隔离夹具输出是 **SELF**;`/root/merge_queue_review` 或 `/root/docs_delivery_review` 对固定对象的独立重放另记 **REPLAY**;Gitea Actions 的实际运行链接、作业身份和精确 SHA 才作为 **GATE**。原始 SELF 收据保存在各任务卡、#518 所指 `/tmp/mq-*` 路径及本轮私人状态目录;本文件只列对象、结论和索引,不转写命令输出。未执行的负例继续标 `NOT_RUN`。
|
||||
|
||||
平台前置使用用户亲手设置的私有夹具仓库 repoID38 `main` 保护规则。用户修正字段后,Root 只读回读六字段;隔离实测缺检查、失败检查、陈旧绿色候选、匿名请求及已认证绿色候选直推拒绝,合法固定候选由智能体合入。原始 SELF 收据和独立 REPLAY 索引在 #518。该夹具证明所测入口的拒绝/合法路径,不证明 Dev 所有角色、全部写者的机器隔离或旧执行者 fencing。Dev 三项业务检查仍须逐候选运行。
|
||||
|
||||
## 三个真实条目
|
||||
|
||||
| 顺序 | 原任务 R0 | 先行组件 | Dev 最终 base → head | 独立 Review 与当前 HEAD GATE | 实际合入 main |
|
||||
|---|---|---|---|---|---|
|
||||
| [#489](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/489) | `cd61bbb112eea6a210a64e84f2cef00b0d64bfc1` | [Documents #89](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/89) → `7bd4e17827d4c7c88647bf3c9199c495b60cb107` | `add097d06137c4912a4ed9279e98ca353e4e4cf1` → `5e6bf4aa0546d68fb3f872158f22b2791c301a60` | `/root/docs_delivery_review` PASS;[run 3038](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3038) 三作业成功 | `f00165e8d71e4dc8ba0ceb7dc50c1a8a3deb6d60` |
|
||||
| [#488](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/488) | `99048dda1f48bccb3d5d798050d7beeea2907177` | [Frontend #73](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/73) → `5313cfad4e633d0909ed40dcdfa28a11bc1902c0`;[RDM #301](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/301) → `ef5100a020abdd8ba8712c3d15c04c28bcac6e84` | `f00165e8d71e4dc8ba0ceb7dc50c1a8a3deb6d60` → `a70de2c54a74e175ad12c8d52ac29d0bafce9491` | `/root/merge_queue_review` PASS、隔离浏览器 7/7;[run 3050](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3050) 三作业成功 | `d852c159b6b3387a2f418a42ab6d3696ac873d01` |
|
||||
| [#486](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/486) | `4d362537d0e8755a03b1757b5bad92779a064b33` | [Backend #185](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/185) → `8e80e2618eb7471dd12d5f172ff3cd23622b7d2f` | `d852c159b6b3387a2f418a42ab6d3696ac873d01` → `d805cc1697ae7f49d371a56a6a55191f00897b8c` | `/root/merge_queue_review` PASS;[run 3067](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3067) 三作业成功 | `05b997b84db26c517604c48d12676f0eb2b86e18` |
|
||||
|
||||
三个 Dev 合入都用固定 `head_commit_id`、`force_merge=false`,合入后从远端重新读取 PR/main 并核对完整 tree 与已审候选一致;组件 gitlink 没有回退。#489 首个合入响应后的本地指针统计出错,Root 先从 PR/main 重新对账再释放窗口,未重发合入请求。#488 的独立浏览器验收使用临时二进制/私有环境,未操作 live 服务。#486 的 U7 安全审阅先发现 B1–B7,Backend 在推最终源 HEAD 前修复并以隔离 PostgreSQL 真实交叠、跨进程、SIGTERM/SIGKILL 重放;Dev 最终组合继续通过本地 `make test`、隔离 PostgreSQL/Redis `make test-backend-pg` 和 `make build` 的 SELF 检查,GATE 另见表内 run 3067。
|
||||
|
||||
## 同步、CI、等待与恢复
|
||||
|
||||
每条 Dev 任务对其本轮最新目标仅发生一次真实纳入;固定后同基线 `task-sync` 核验不生成提交。#489 为纠正旧启动状态,在正式窗口前完成源码/组件整改与目标纳入;这与理想的“领取窗口后才第一次纳入”不同,不能抹去。#488、#486 都在领取最终窗口后才执行 `changed=1`,随后成功的固定 HEAD 检查为 `changed=0`。#486 一次无变更检查被嵌套 Git 的短暂 `index.lock` 拒绝,未删锁;持锁操作结束后原对象复核通过。原始失败和成功收据都在 #518。
|
||||
|
||||
| Dev PR | 目标纳入次数 | 固定后成功的无变更核验 | 本轮最终 PR CI | 作业运行时长(test / test-pg / svc-realcombo) | runner 等待 |
|
||||
|---|---:|---:|---|---|---|
|
||||
| #489 | 1(启动整改期) | 至少 3 次,均未改 HEAD | [3038](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3038):1 次、3/3 成功 | 5:10 / 7:22 / 1:46 | 每作业 3 秒 |
|
||||
| #488 | 1(最终窗口) | 2 次,均未改 HEAD | [3050](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3050):1 次、3/3 成功 | 5:12 / 8:42 / 1:54 | 每作业 3 秒 |
|
||||
| #486 | 1(最终窗口) | 1 次成功;另 1 次锁拒绝未推进 | [3067](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3067):1 次、3/3 成功 | 5:01 / 7:19 / 1:54 | 每作业 3 秒 |
|
||||
|
||||
三次最终 PR CI 共 3 个 run、9 个必需作业,**因本轮正常排队任务移动 main 而废弃的最终 run 为 0**;没有拿旧绿色检查放行新 HEAD。合入后 main push CI 单列:[run 3040](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3040) 对 #489 合入树、[run 3053](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3053) 对 #488 合入树、[run 3068](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3068) 对 #486 合入树,各自另有 3/3 作业成功;共 3 个 push run、9 个作业,不能省略这部分实际 CI 成本。3068 在 04:43:55Z 完成,精确对象为 `05b997b84db26c517604c48d12676f0eb2b86e18`。组件仓的 GATE/N/A 与 RDM #301 任务卡闭合 [PR #364](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/364) 的 CI 不计入上述 Dev 目标 run。
|
||||
|
||||
自 2026-10-12 起查询到三个 PR 另有 13 次**试行前开发** Actions run(#489 2、#488 7、#486 4;6 成功、7 失败),其对象与本轮最终候选不同;原始只读清单 `/tmp/mq-trial-ci-history-20261014.json`。这些运行既不能当本轮最终准入,也不能归因于本轮 main 移动。runner 作业等待时间以各 GATE job 的 `created_at`→`started_at` 计算;人的准备/依赖等待没有统一的入队就绪时间戳,本轮不填造净等待时长。仅可复核首次最终同步到合入的可观测下界:#489 19:49、#488 24:20、#486 18:46;它们含测试、Review 和平台等待,不等同完整窗口耗时。三条目均未重新领取最终目标窗口;启动整改、#488 的 E2E 夹具失败、#486 的一次锁拒绝分别保留,不计成 CI 废弃或窗口接管成功。
|
||||
|
||||
## 验收与下一步边界
|
||||
|
||||
| 验收 | 本轮结论 | 依据及限制 |
|
||||
|---|---|---|
|
||||
| MQ1 | 部分满足 | 三任务顺序合入且后继未提前最终同步;最终 CI 0 次因正常排队合入废弃。#489 的目标纳入发生在启动整改期,严格“领取后首同步”未由该例满足。 |
|
||||
| MQ2 | manual 已登记;原子互斥 `NOT_RUN` | 单协调者与目标窗口记录有效;重复领取的执行端拒绝及旧代次 fencing 未实现/未测。 |
|
||||
| MQ3 | 本轮通过 | 三个固定对象有同基线无变更核验;#486 短暂锁失败被拒绝且重验不改 HEAD。 |
|
||||
| MQ4 | 本轮通过 | 三个最终 HEAD 各跑实际新 CI;隔离夹具的陈旧绿色候选被拒。没有把组件/旧分支检查当父仓 GATE。 |
|
||||
| MQ5 | 部分满足 | #486 活动锁阻断并自行恢复,#489/#488 源码和夹具问题在固定前整改;人工超时释放及无依赖任务并行负例 `NOT_RUN`。 |
|
||||
| MQ6 | 部分满足 | 组件先合入,后继父仓保留其他能力;紧急插队导致候选失效的真实路径 `NOT_RUN`。 |
|
||||
| MQ7 | 部分满足 | #489 合入后本地异常先对账,未重复 POST;未知请求结果与旧执行者失联接管 `NOT_RUN`。 |
|
||||
| MQ8 | manual 范围通过 | 私有夹具正负例、Dev 精确 GATE 和合法智能体合入均有对象证据;全部角色/自动 fencing `NOT_RUN`。 |
|
||||
| MQ9 | 待文档 PR Review | 权威规范、Dev 采纳、调度记录、实际 PR/运行互相链接;本报告的最终交叉检查需随文档 PR 完成。 |
|
||||
|
||||
建议维持单协调者的 **manual** 模式,按目标串行领取,把组件准备与父仓最终 CI 分开。首次试行证明“等待分支不因正常合入反复重跑最终 CI”在这三项中成立;没有可比历史基线,**不报告节省百分比**。自动模式须另行建设并验证原子持久领取、执行端旧代次拒绝、角色覆盖和异常接管,不能从本轮人工遵约推导已具备。扩大试行与预算调整留待用户阶段评审决定;本报告不替代该决定。
|
||||
Reference in New Issue
Block a user