Merge authoritative main into the task branch

Why: include the current integration baseline before verification.

Evidence: fetched origin/main=1850d03563875fd848664ab9b348f6858d0fa590.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
This commit is contained in:
2026-10-20 16:36:07 +00:00
11 changed files with 1306 additions and 27 deletions
@@ -0,0 +1,244 @@
# feature/project-access-lifecycle-u1-role-project-access 任务卡
任务主记录:PR #637 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/637;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 3e70d76a20a6caf6f2edfd738a86f501c31064b6
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u1-role-project-access(worktree);分支:feature/project-access-lifecycle-u1-role-project-access
- 分支类型:child;initiative_id:feature-project-access-lifecycle;root_target:main;immediate_target:feature/project-access-lifecycle;accepting_requirements:false;parent_branch:feature/project-access-lifecycle;parent_head_sha:a8557f27ed8a1708f814539d7161364daea15dd5;parent_pr:无;parent_source:origin
- 需求分流:免(父 initiative 子任务登记已列出 feature/project-access-lifecycle-u1-role-project-access;parent_head_sha=a8557f27ed8a1708f814539d7161364daea15dd5)
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
| pal-u1a Backend | 角色权限收窄为项目访问布尔 + R13 门禁拆分 + 管理员去旁路 + 归一化 | AGENT-EXECUTION digest(见各收据) | implementation | cursor→agy→pi | 4 次运行:scope-expansion(测试文件未授权)、scope-expansion(仓内 scratch)、failed-unknown(cursor 网络中断)、success | cursor(success 次为 cursor,session not-observable) | success | 已应用 cf9c35a(c8b1b7e→cf9c35a) | never | /tmp/pal-u1a-run.json、run2、run3、run4.json |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 3e70d76a20a6caf6f2edfd738a86f501c31064b6 | a8557f27ed8a1708f814539d7161364daea15dd5 | 2026-10-19T14:59:41Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
| pal-u1b Frontend | 角色编辑收窄为单项目访问布尔 + R13 门禁(roles.manage)+ 旧模型测试重写 | AGENT-EXECUTION digest | implementation | cursor→agy→pi | 1 | cursor(session not-observable) | success | 已应用 2c19439(dab1605→2c19439) | never | /tmp/pal-u1b-run.json |
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 合入与清理
- Review 记录:独立审查(全新 cursor 会话,无 resume,未参与实现;输出存 /tmp/pal-u1-review-output.txt)结论 BLOCKED(1 项):缺计划 U1 第 9 条测试(provider 缺失/不兼容拒绝创建项目);五项重点全部成立。阻塞项已由 repair 修复(transport 03646b5,测试 internal/server/role_authorization_test.go 新增场景并 PASS),闭环依据:修复后过滤套件 ok + make test-affected PASS(/tmp/pal-u1-affected3.json)。另:agent-exec review 路由两次 pi 尝试均未产出报告文件(failed-unknown,收据 /tmp/pal-u1-review-run.json、review2-run.json,工作区已清理),改用上述全新会话方式。(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:task-sync 于合入前执行;组合 pin 期间发生一次误配(pins2 将前端回退 dab1605),已由 pins3 纠正为 backend 03646b5 + frontend 2c19439(7519672),组合门禁以终态对象通过。(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T14:58:45.588024+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle",
"before_head": "a8557f27ed8a1708f814539d7161364daea15dd5",
"after_head": "a8557f27ed8a1708f814539d7161364daea15dd5",
"branch": "feature/project-access-lifecycle",
"target_branch": "main",
"target_head": "3e70d76a20a6caf6f2edfd738a86f501c31064b6",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle'",
"[repo] branch=feature/project-access-lifecycle head=a8557f27ed",
"[remote] origin/main=3e70d76a20 ahead=3 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=5",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 3e70d76a20(完整:3e70d76a20a6caf6f2edfd738a86f501c31064b6)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle'"
],
"output_sha256": "4dbe19daf89259d609baf4cb3df0a993029edc91d8b1f0889987bd6d74a59761",
"receipt_sha256": "7e8ed3a646ae25996e75763ca1d199723ce86193f84ebea48ed622f7e036d0ee",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/7e8ed3a646ae25996e75763ca1d199723ce86193f84ebea48ed622f7e036d0ee.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T15:41:10.347615+00:00",
"command": "sh -c 'cd modules/backend && GOWORK=off go build ./... && GOWORK=off go test ./internal/authz/... ./internal/store ./internal/server -run \"Role|Policy|Catalog|Access|Super\" -count=1 && GOWORK=off go vet ./internal/authz/... ./internal/store ./internal/server && git status --porcelain | wc -l'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u1-role-project-access",
"before_head": "a455919908d8949988aafc7b984c8eb870dcba6d",
"after_head": "a455919908d8949988aafc7b984c8eb870dcba6d",
"branch": "feature/project-access-lifecycle-u1-role-project-access",
"target_branch": "main",
"target_head": "2b7fdc39a1f44163f4766701429d61ffd6926f1a",
"root_target": "main",
"immediate_target": "feature/project-access-lifecycle",
"before_tracked_diff_sha256": "59bad28b181e892816c6c432ef14deb2e178ab05190f808e8dd292fabc33e74f",
"after_tracked_diff_sha256": "59bad28b181e892816c6c432ef14deb2e178ab05190f808e8dd292fabc33e74f",
"output_tail": [
"? \tagent-system-backend/internal/authz\t[no test files]",
"ok \tagent-system-backend/internal/authz/catalog\t0.002s",
"ok \tagent-system-backend/internal/store\t4.029s",
"ok \tagent-system-backend/internal/server\t3.266s",
"0"
],
"output_sha256": "3546e0a0a2c49bf4b92853a0b97e746823398a5f19c3f4f028d0ff8f015a4c4d",
"receipt_sha256": "80c009bd4f0750a8be9fc3e6bcf71ed3631645e88f0b7b8210c70a35dff62e81",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/80c009bd4f0750a8be9fc3e6bcf71ed3631645e88f0b7b8210c70a35dff62e81.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T15:48:12.454853+00:00",
"command": "sh -c 'cd modules/frontend && npx vitest run test/role-permissions.test.ts test/role-permissions-ui.test.ts test/account-users-panel.test.ts test/design-guard.test.ts 2>&1 | tail -3 && npx tsc -b && echo TSC_OK'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u1-role-project-access",
"before_head": "d2e78d53be5d7a9eb549ee87180685feed385fa9",
"after_head": "d2e78d53be5d7a9eb549ee87180685feed385fa9",
"branch": "feature/project-access-lifecycle-u1-role-project-access",
"target_branch": "main",
"target_head": "2b7fdc39a1f44163f4766701429d61ffd6926f1a",
"root_target": "main",
"immediate_target": "feature/project-access-lifecycle",
"before_tracked_diff_sha256": "79fc127e44f0bcb60eca463a19384c65e9f3a70c781dc2ff72d3395affe9dfae",
"after_tracked_diff_sha256": "79fc127e44f0bcb60eca463a19384c65e9f3a70c781dc2ff72d3395affe9dfae",
"output_tail": [
" Start at 15:48:12",
" Duration 385ms (transform 439ms, setup 0ms, import 634ms, tests 27ms, environment 0ms)",
"",
"TSC_OK"
],
"output_sha256": "9241d526c3f2dac26fbd1d7745047cacdf505c4ddd9f525884f1e5f7aca5d8a9",
"receipt_sha256": "998b331751b5e987ae229d179674ae99af97ac850ed87a496bdc011b8f175495",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/998b331751b5e987ae229d179674ae99af97ac850ed87a496bdc011b8f175495.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T15:49:58.382245+00:00",
"command": "sh -c 'umask 0022 && make test-affected'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u1-role-project-access",
"before_head": "ef8d142a8a56984d3d674edf3465e6165152961f",
"after_head": "ef8d142a8a56984d3d674edf3465e6165152961f",
"branch": "feature/project-access-lifecycle-u1-role-project-access",
"target_branch": "main",
"target_head": "2b7fdc39a1f44163f4766701429d61ffd6926f1a",
"root_target": "main",
"immediate_target": "feature/project-access-lifecycle",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"(node:4185712) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.",
"(Use `node --trace-warnings ...` to show where the warning was created)",
"(node:4185778) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.",
"(Use `node --trace-warnings ...` to show where the warning was created)",
"(node:4185713) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.",
"(Use `node --trace-warnings ...` to show where the warning was created)",
"",
" Test Files 49 passed (49)",
" Tests 588 passed (588)",
" Start at 15:50:33",
" Duration 797ms (transform 6.87s, setup 0ms, import 11.31s, tests 1.10s, environment 3ms)",
"",
"knip unused exports 57 <= 58",
"make[2]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u1-role-project-access'",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u1-role-project-access'"
],
"output_sha256": "a8a060112b3e15dd817d7b66314a5ca89ce0ef1f5cc17edba7a939f1278d79fb",
"receipt_sha256": "e60210ccc7eda17e55ca0c72d4ab7b635e1f45650b5d7eb80ffcaea0e1e3a24f",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/e60210ccc7eda17e55ca0c72d4ab7b635e1f45650b5d7eb80ffcaea0e1e3a24f.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T16:08:30.705187+00:00",
"command": "sh -c 'umask 0022 && make test-affected'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u1-role-project-access",
"before_head": "75196728eb462b1e18579e4657ffab84ac54dde2",
"after_head": "75196728eb462b1e18579e4657ffab84ac54dde2",
"branch": "feature/project-access-lifecycle-u1-role-project-access",
"target_branch": "main",
"target_head": "2b7fdc39a1f44163f4766701429d61ffd6926f1a",
"root_target": "main",
"immediate_target": "feature/project-access-lifecycle",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"(node:414845) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.",
"(Use `node --trace-warnings ...` to show where the warning was created)",
"(node:414911) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.",
"(Use `node --trace-warnings ...` to show where the warning was created)",
"(node:414846) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.",
"(Use `node --trace-warnings ...` to show where the warning was created)",
"",
" Test Files 49 passed (49)",
" Tests 588 passed (588)",
" Start at 16:09:04",
" Duration 806ms (transform 7.07s, setup 0ms, import 11.27s, tests 1.17s, environment 4ms)",
"",
"knip unused exports 57 <= 58",
"make[2]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u1-role-project-access'",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u1-role-project-access'"
],
"output_sha256": "6575ab5b5ba1b87a87736b5dec8f2be390bee0f9a6fe499825332e5d2027c53b",
"receipt_sha256": "43973a45aae37e8b5aec60342ac1ddc013b8e292f9044a413272f8d983972ae1",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/43973a45aae37e8b5aec60342ac1ddc013b8e292f9044a413272f8d983972ae1.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #637(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/637)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,132 @@
# feature/project-access-lifecycle-u2-creator-management 任务卡
任务主记录:PR #640 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/640;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 2b7fdc39a1f44163f4766701429d61ffd6926f1a
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u2-creator-management(worktree);分支:feature/project-access-lifecycle-u2-creator-management
- 分支类型:child;initiative_id:feature-project-access-lifecycle;root_target:main;immediate_target:feature/project-access-lifecycle;accepting_requirements:false;parent_branch:feature/project-access-lifecycle;parent_head_sha:a32e2227b0d4f77c15581fdc475a22edc4d10823;parent_pr:无;parent_source:origin
- 需求分流:免(父 initiative 子任务登记已列出 feature/project-access-lifecycle-u2-creator-management;parent_head_sha=a32e2227b0d4f77c15581fdc475a22edc4d10823)
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 2b7fdc39a1f44163f4766701429d61ffd6926f1a | a32e2227b0d4f77c15581fdc475a22edc4d10823 | 2026-10-19T16:34:33Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
| pal-u2 RDM | creator 管理权威收敛(有效项目访问+精确 createdBy;override 不增不减)+ 旧语义测试重写 | AGENT-EXECUTION digest | implementation | cursor→agy→pi | 16 次运行:2 次 cursor 网络 TLS 失败、2 次合理 scope-expansion(perms_api.go/测试文件)、2 次 local_config(worker 跑 submodule update 触发监管)、2 次 blocked(pins 嵌套依赖缺失)、1 次终态记录失足、其余为逐轮修正重派;末次 success | cursor(R10 配方:-modfile 覆盖 + pin 自愈;session not-observable) | success | 已应用 853121d(5a27d78→853121d,RDM 仓分支 feature/project-access-lifecycle-u2-creator-management 已推送) | never | /tmp/pal-u2-run*.json(run16 为成功收据) |
| pal-u2 Review 修复 | fail-open 旁路修复(legacy 模式 fail-closed)+ 13 个 Skip 回归测试恢复 | AGENT-EXECUTION digest | repair | cursor→agy→pi | 2 次运行(首次终态记录失足,第二次 success) | cursor(session not-observable) | success | 已应用 aa1a7d2(853121d→aa1a7d2) | never | /tmp/pal-u2-fix2-run.json、fix2b-run.json |
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 合入与清理
- Review 记录:独立审查(全新 cursor 会话,未参与实现;输出 /tmp/pal-u2-review-output.txt)结论 BLOCKED(2):①legacy readiness 模式管理判定 fail-open;②13 个 host_projection 回归测试被 Skip。两项已由 repair(aa1a7d2)修复:fail-closed 语义 + 全部恢复并按新语义通过;rdmapp 全量 3 包 ok、Skip=0。非阻塞建议 3 条(canManageProject 死参数收敛、成员入口重复调用清理、场景映射注释)留后续增量。(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T16:33:45.887202+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle",
"before_head": "5eb8591957a89a269326d52d53a982fbc157dba1",
"after_head": "5eb8591957a89a269326d52d53a982fbc157dba1",
"branch": "feature/project-access-lifecycle",
"target_branch": "main",
"target_head": "2b7fdc39a1f44163f4766701429d61ffd6926f1a",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle'",
"[repo] branch=feature/project-access-lifecycle head=5eb8591957",
"[remote] origin/main=2b7fdc39a1 ahead=5 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=6",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 2b7fdc39a1(完整:2b7fdc39a1f44163f4766701429d61ffd6926f1a)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle'"
],
"output_sha256": "f4c03343235843eaf5f99905576d9e5c3133939f633b4fcaf227aeb70fdadbdb",
"receipt_sha256": "2bfa8f889300bce9ad9f556e8abb6e23b5730a252a76d286f02f4a103a7f13ca",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/2bfa8f889300bce9ad9f556e8abb6e23b5730a252a76d286f02f4a103a7f13ca.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T20:33:08.272772+00:00",
"command": "sh -c 'cd /home/weichen/projects/Agent-System-RDM-wt-pal-u2 && GOWORK=off go build ./internal/projects/... ./internal/rdmapp/... ./internal/perms/... ./internal/members/... && GOWORK=off go test ./internal/perms/... ./internal/members/... ./internal/projects/... -count=1 2>&1 | tail -1 && GOWORK=off go test ./internal/rdmapp/... -count=1 2>&1 | grep -cE \"^ok\" && GOWORK=off go vet ./internal/perms ./internal/members ./internal/rdmapp && echo VET_OK && git status --porcelain | wc -l'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u2-creator-management",
"before_head": "4e3d5240e759ab80f2a481c0f4d6465119ee0c37",
"after_head": "4e3d5240e759ab80f2a481c0f4d6465119ee0c37",
"branch": "feature/project-access-lifecycle-u2-creator-management",
"target_branch": "main",
"target_head": "f07a53d86aa10d35be0d3519fcf3c493b3391fec",
"root_target": "main",
"immediate_target": "feature/project-access-lifecycle",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"ok \tagent-system-rdm/internal/projects\t0.145s",
"3",
"VET_OK",
"0"
],
"output_sha256": "f2e306cfce2ea88f542f0bbb1671e5d70931120990c6936b3a9b80bc82db49cd",
"receipt_sha256": "8d6760af9d8f734b5c7212ea1f18d25835e46864a8603e0ce1aaba4ae5be7a91",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/8d6760af9d8f734b5c7212ea1f18d25835e46864a8603e0ce1aaba4ae5be7a91.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #640(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/640)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,131 @@
# feature/project-access-lifecycle-u3-member-history 任务卡
任务主记录:PR #646 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/646;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= f07a53d86aa10d35be0d3519fcf3c493b3391fec
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u3-member-history(worktree);分支:feature/project-access-lifecycle-u3-member-history
- 分支类型:child;initiative_id:feature-project-access-lifecycle;root_target:main;immediate_target:feature/project-access-lifecycle;accepting_requirements:false;parent_branch:feature/project-access-lifecycle;parent_head_sha:c9ca59b195c17abfbcb29ed7a7b958bc69fb22ab;parent_pr:无;parent_source:origin
- 需求分流:免(父 initiative 子任务登记已列出 feature/project-access-lifecycle-u3-member-history;parent_head_sha=c9ca59b195c17abfbcb29ed7a7b958bc69fb22ab)
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | f07a53d86aa10d35be0d3519fcf3c493b3391fec | c9ca59b195c17abfbcb29ed7a7b958bc69fb22ab | 2026-10-20T01:17:12Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
| pal-u3a RDM(部分交付) | 成员状态机(active/removed/absent + removed_at + 迁移回填);Remove 保留行;re-add 恢复 active;IsMember 只认 active;被移除成员共享域只读放行(doc.read 前置解耦);写全拒与隐私负控 | AGENT-EXECUTION digest | implementation | cursor→agy→pi | 3 次运行(2 次网络/中断、1 次 blocked 未用 -modfile 配方)后 success | cursor(session not-observable) | success | 已应用 62c77ec(aa1a7d2→62c77ec,RDM 仓分支已推送) | never | /tmp/pal-u3a-run3.json |
| pal-u3b Backend | 被移除成员本人会话只读路径(经唯一资源授权面)+ 写门全拒负控 | AGENT-EXECUTION digest | implementation | cursor(配额禁用)→antigravity(端点禁用)→pi | 6 次运行(详见下);末次 pi success | pi(session not-observable) | success | 已应用 d3380de(03646b5→d3380de,Backend 仓分支已推送) | never | /tmp/pal-u3b-run*.json(run12 为成功收据) |
## 结果与验证
- 结果:U3a(RDM 侧)+ U3b(Backend 侧)均已交付;U3 整体待独立 Review 与合入。
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 合入与清理
- Review 记录:U3a 待独立 Review(RDM 分支 62c77ec)。U3b:host 主模型 Review(实现由 pi 完成,三个 CLI 候选当前不可用:cursor 配额禁用、agy 端点 EOF×3 禁用、pi 为本单元实现者)——结论 PASS:读决策唯一化(projectRead 经域内资源授权面,removed+共享域放行)、写全走 projectWork、无授权器时行为不变、fail-closed;依据 server.go:876/1063/1459/1558/1618/1647 与新增 250 行测试。临时路由变更记录:Backend AGENT-EXECUTION.md 于 001ba38(cursor 配额禁用)、5543a44(agy 端点禁用),随本 PR 可审计,配额/端点恢复后应改回。(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-20T01:16:15.775522+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle",
"before_head": "c9ca59b195c17abfbcb29ed7a7b958bc69fb22ab",
"after_head": "c9ca59b195c17abfbcb29ed7a7b958bc69fb22ab",
"branch": "feature/project-access-lifecycle",
"target_branch": "main",
"target_head": "f07a53d86aa10d35be0d3519fcf3c493b3391fec",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle'",
"[repo] branch=feature/project-access-lifecycle head=c9ca59b195",
"[remote] origin/main=f07a53d86a ahead=23 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=6",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] f07a53d86a(完整:f07a53d86aa10d35be0d3519fcf3c493b3391fec)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle'"
],
"output_sha256": "584a369ff09522a79ecca05db2987a558d00d82789b6055b44b7f6beb6a4a33a",
"receipt_sha256": "87a4a678d7471e64c1497f0e9b584e8b3114296fe3a935fe61376209923e3ffe",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/87a4a678d7471e64c1497f0e9b584e8b3114296fe3a935fe61376209923e3ffe.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-20T05:00:39.146940+00:00",
"command": "sh -c 'cd modules/backend && GOWORK=off go build ./internal/... 2>/dev/null; GOWORK=off go test ./internal/server -run \"Project|Conversation|Message|Member\" -count=1 2>&1 | tail -1 && GOWORK=off go test ./internal/authz/... -count=1 2>&1 | tail -1 && GOWORK=off go vet ./internal/server ./internal/authz && echo VET_OK && git status --porcelain | wc -l'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u3-member-history",
"before_head": "bd7ae9a892c32f158fb60cbd705c0fd781c5fa94",
"after_head": "bd7ae9a892c32f158fb60cbd705c0fd781c5fa94",
"branch": "feature/project-access-lifecycle-u3-member-history",
"target_branch": "main",
"target_head": "d2035c76dc1cb15e01d2c184af5155d9d773cd9f",
"root_target": "main",
"immediate_target": "feature/project-access-lifecycle",
"before_tracked_diff_sha256": "d16db70897f470c2a2d69a393757ded896703b26562be1c19e29c63d2da49b1d",
"after_tracked_diff_sha256": "d16db70897f470c2a2d69a393757ded896703b26562be1c19e29c63d2da49b1d",
"output_tail": [
"ok \tagent-system-backend/internal/server\t12.943s",
"ok \tagent-system-backend/internal/authz/catalog\t0.001s",
"VET_OK",
"0"
],
"output_sha256": "606658b1f5cbf647603a229c72d25dd53ca7f5dcf84ff1dafdf2fd0eb822e069",
"receipt_sha256": "1a1f139555b65e7b82dd9ccbf5a827510d89651f2d5abb87484eb71d930257b1",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/1a1f139555b65e7b82dd9ccbf5a827510d89651f2d5abb87484eb71d930257b1.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #646(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/646)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,129 @@
# feature/project-access-lifecycle-u4-work-states 任务卡
任务主记录:PR #654 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/654;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= d2035c76dc1cb15e01d2c184af5155d9d773cd9f
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u4-work-states(worktree);分支:feature/project-access-lifecycle-u4-work-states
- 分支类型:child;initiative_id:feature-project-access-lifecycle;root_target:main;immediate_target:feature/project-access-lifecycle;accepting_requirements:false;parent_branch:feature/project-access-lifecycle;parent_head_sha:028c36d13fb67d62c9884306ecb94135d26a8d1b;parent_pr:无;parent_source:origin
- 需求分流:免(父 initiative 子任务登记已列出 feature/project-access-lifecycle-u4-work-states;parent_head_sha=028c36d13fb67d62c9884306ecb94135d26a8d1b)
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | d2035c76dc1cb15e01d2c184af5155d9d773cd9f | 028c36d13fb67d62c9884306ecb94135d26a8d1b | 2026-10-20T05:50:13Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
| pal-u4 RDM | 项目/成员工作状态机(work_state、suspended)+ 工作判定 + 管理命令入口 + 审计 + removed/suspended 只读边界的可见性修复 | AGENT-EXECUTION digest | implementation | cursor(配额误报禁用后恢复)→agy(区域/EOF 禁用)→pi(限流)→cursor(--model auto 修复后) | 多轮(详见收据) | cursor(--model auto)+pi | success×2(f54c769 状态机、7f43da6 review 修复) | 已应用 f54c769、7f43da6 | never | /tmp/pal-u4-run2.json、/tmp/pal-u4-fix3b-run.json |
## 结果与验证
- 结果:U4 已交付(RDM 分支 feature/project-access-lifecycle-u4-work-states @ 7f43da6,已推送):work_state/suspended 状态机与迁移、工作判定落点、creator 的 close/reopen/suspend/reactivate 命令入口与审计、时间比较与 doc-read 检查并行的只读边界(修掉 Review 指出的“新增可见性”缺陷)。
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 合入与清理
- Review 记录:独立审查(全新 cursor 会话,--model auto 修复后可用)结论 BLOCKED(2):①removed/suspended 共享读取跳过 doc.read 三查且无时间比较(新增可见性,源自 U3a 基线、U4 扩大);②状态转换缺命令入口与审计。两项已由 repair(7f43da6)修复并有新增负控测试(TestFormerMemberSliceReadExcludesLaterPublication 等),rdmapp 全量绿、Skip=0。报告 /tmp/pal-u4-review-output.txt。(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-20T05:49:21.114317+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle",
"before_head": "028c36d13fb67d62c9884306ecb94135d26a8d1b",
"after_head": "028c36d13fb67d62c9884306ecb94135d26a8d1b",
"branch": "feature/project-access-lifecycle",
"target_branch": "main",
"target_head": "d2035c76dc1cb15e01d2c184af5155d9d773cd9f",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle'",
"[repo] branch=feature/project-access-lifecycle head=028c36d13f",
"[remote] origin/main=d2035c76dc ahead=30 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=6",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] d2035c76dc(完整:d2035c76dc1cb15e01d2c184af5155d9d773cd9f)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle'"
],
"output_sha256": "056f1cc21e09910b01081fae0ec088394c2f522d8e4de15620c6f687876c76d0",
"receipt_sha256": "8dd3dfce03454527c8f4f5c127f50a70bbcefd1ec1cfa912bee25a1a1fed7bb3",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/8dd3dfce03454527c8f4f5c127f50a70bbcefd1ec1cfa912bee25a1a1fed7bb3.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-20T06:27:50.962524+00:00",
"command": "sh -c 'cd /home/weichen/projects/Agent-System-RDM-wt-pal-u2 && GOWORK=off GOFLAGS=-modfile=/tmp/pal-u3.mod go test ./internal/members/... ./internal/projects/... ./internal/perms/... -count=1 2>&1 | tail -1 && GOWORK=off GOFLAGS=-modfile=/tmp/pal-u3.mod go test ./internal/rdmapp/... -count=1 2>&1 | grep -cE \"^ok\" && GOWORK=off go vet ./internal/members ./internal/projects ./internal/rdmapp && echo VET_OK && git status --porcelain | wc -l'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle-u4-work-states",
"before_head": "607c3c209fd68903086adb868580d175dcbec0d0",
"after_head": "607c3c209fd68903086adb868580d175dcbec0d0",
"branch": "feature/project-access-lifecycle-u4-work-states",
"target_branch": "main",
"target_head": "65e4aa39592ed8f11b5385d6665aab6a883ae345",
"root_target": "main",
"immediate_target": "feature/project-access-lifecycle",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"ok \tagent-system-rdm/internal/perms\t0.019s",
"3",
"VET_OK",
"0"
],
"output_sha256": "0ea9c6e9427f885022bfb5c62cdb746ac8a178a81febea8da3931b995ff9cc58",
"receipt_sha256": "28d77a6df794aecb5cb43d8bb8c62195af3d54feb6b8c58f98cf8fea0f9cdb2d",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/28d77a6df794aecb5cb43d8bb8c62195af3d54feb6b8c58f98cf8fea0f9cdb2d.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #654(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/654)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
+1 -1
View File
@@ -1,6 +1,6 @@
# fix/account-chain-ui 任务卡
任务主记录:<PR 链接,交付前填写>;状态:进行中;owner:weichen
任务主记录:PR #586 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/586(merge eb2bdd6a8);状态:已完成(回填);owner:weichen
## 基线与授权
+225
View File
@@ -0,0 +1,225 @@
# feature/project-access-lifecycle 任务卡
任务主记录:<PR 链接,交付前填写>;状态:进行中;owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 3e70d76a20a6caf6f2edfd738a86f501c31064b6
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle(worktree);分支:feature/project-access-lifecycle
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=72ce129300a749b532d1d2806e247cdcd412bb19e927a50d5b16be827b398f5e;triage_receipt=/tmp/access-lifecycle-triage.json;receipt_sha256=399267dd5f0e1d3e1ba1bf1ccf52532b386535fef618d03985b46d36e8f6c800
- 授权与交付终点:按计划 docs/superpowers/plans/2026-10-19-1440-feat-project-access-lifecycle-plan.md 实施 U1–U6:角色权限收窄为单一项目访问布尔(含 R13 门禁修正与旧数据兼容归一)、creator 管理权威、成员历史与只读移除、项目/成员工作状态、固定模板库、界面呈现。终点:L1 分支经组合验证与 CI 后合入 main;不含部署、生产数据迁移、发布/打标与线上权限改写(计划 Verification Contract 明确排除)。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:U3 实施前须确认「移除成员后的历史可见范围」(计划 Deferred Planning Questions,当前按 KTD6 保守默认);其余按既有边界
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:需求拆解;当前增量:I1(待定义)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 章程(charter)
**用途与目标**:按计划实现「项目访问与生命周期管理」——角色配置收窄为单一「项目访问」布尔(旧 allowed/capAllowed 按原有效结果 allowed&&capAllowed 兼容归一,写时双写两列);角色管理者凭 system.roles.manage 即可配置该权限(R13,系统授权与平台上限仍由 system.permissions.manage 保护);系统管理员不再默认绕过项目创建检查;项目管理 = 有效项目访问 + 精确 creator 身份;成员/项目工作状态(active/suspended/removed、active/closed)可逆且在每个执行边界重验;固定模板库全量入册、按需实例化;不含文档职责分配。
**接纳范围**:计划 R1–R13;单元 U1–U6(U1 角色收窄+门禁修正;U2 creator 管理权威;U3 成员历史与只读移除;U4 工作状态;U5 模板库;U6 界面呈现);AE1–AE11。
**非目标**:文档职责分配的新增/接线;归档/恢复行为变更;项目转移创建者;项目删除;全局同名唯一性变更;部署、生产迁移、发布/打标、线上权限改写;私人内容对系统管理员开放。
**分级测试策略**:单元→L2:worker 自检 + host 最小直接检查(make test-affected)+ 全新会话独立 Review;轻量 CI。L1→main:task-sync + 完整组合验证 + 完整 CI(test/test-pg/svc-realcombo)+ 三段证据 + 独立 Review。
**验收条件**:计划 Success Criteria 全部成立;AE1–AE11 在真实组合通过;Definition of Done 逐项满足(不含部署项)。
**追加领域规则**:
- 角色授权判定只消费规范化后的项目访问布尔;旧 system/user 行对角色授权无效且不得出现在角色能力中。
- system.grants 与平台上限写入门禁保持 system.permissions.manage,不得因 R13 放宽。
- 创建者身份只能来自服务端认证与不可变 createdBy;任何 owner 标签、调用方字段、RDM 域管理员、系统管理员都不得绕过。
- 成员移除/停用与项目关闭在每个副作用边界重验;移除历史保留且可审计。
**生命周期**:建立即开本 PR(base main,[WIP])作分流发现;子任务按登记推进;最终一次性合入 main 后归档回收。
**关联方向与规划**:主记录 docs/superpowers/plans/2026-10-19-1440-feat-project-access-lifecycle-plan.md(本分支提交);关联 #628(其角色模型由本计划取代,衔接由 L1 owner 处理)。
## 子任务登记
| 子任务分支 | 必需 | 状态 | PR | 单元 | 范围摘要 |
|---|---|---|---|---|---|
| feature/project-access-lifecycle-u1-role-project-access | 是 | 已登记,待派发 | — | U1 | Backend catalog/service/role_policy/migrate/roles.go + Frontend rolePermissions.ts/RolePermissionsPanel.tsx:单一项目访问布尔、R13 门禁拆分、旧数据归一;R1/R2/R9/R11/R13 |
| feature/project-access-lifecycle-u2-creator-management | 是 | 待启动(依赖 U1) | — | U2 | RDM projects_api/system_projects/perms:有效项目访问+精确 creator 的管理权威 |
| feature/project-access-lifecycle-u3-member-history | 是 | 待启动(依赖 U2;实施前须确认历史可见范围) | — | U3 | RDM members/projects_api/system_projects/private_doc_views + Backend server.go:移除/停用即时停工、只读历史 |
| feature/project-access-lifecycle-u4-work-states | 是 | 待启动(依赖 U2/U3) | — | U4 | 项目 active/closed 与成员 active/suspended 状态、迁移与全边界重验 |
| feature/project-access-lifecycle-u5-template-catalog | 是 | 已交付待合入(RDM 分支 @ 0f97deb 已推送:inventory.json 414 文件全量盘点、130 项差距诚实列出、catalog 44 条已核验覆盖、项目选用接线测试;rdmapp 全量绿) | — | U5 | RDM 模板清单刷新(44 项 DHF+)、目录连接项目浏览/选择、来源/版本溯源 |
| feature/project-access-lifecycle-u6-ui-presentation | 是 | 待启动(依赖 U1–U5 合同) | — | U6 | Frontend 角色/成员/项目/模板界面呈现与只读态 |
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
| pal-u6 Frontend | 项目工作状态控制(close/reopen/suspend/reactivate 命令消费)+ 模板浏览(rdm.docs.templates/instantiate)+ 状态只读呈现 | AGENT-EXECUTION digest | implementation | cursor(--model auto 经 Dev dm)→… | 1 | cursor(session not-observable) | success | Frontend 分支 581b25d(已推送) | never | /tmp/pal-u6-run.json |
## 关联方向与规划
- 适用状态:待核对(无适用规划时说明原因)
- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文)
- 对应里程碑:待核对
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 待填写 | 待评估 | 待定 | 待定义 | 待确认 | 待评审 |
## 方案与计划
- 方案引用:待填写(含对象版本)
- 实施计划引用:待填写(含增量与需求 ID)
- 测试计划引用:待填写(含需求 ID 与验收条件)
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 待定 | 待执行 | — | — | — |
| 需求评估 | 待定 | 待执行 | — | — | — |
| 需求表确认 | 待定 | 待执行 | — | — | — |
| 方案设计 | 待定 | 待执行 | — | — | — |
| 实施计划 | 待定 | 待执行 | — | — | — |
| 实施与自检 | 待定 | 待执行 | — | — | — |
| 正式测试与验收 | 待定 | 待执行 | — | — | — |
| 代码 Review | 待定 | 待执行 | — | — | — |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 3e70d76a20a6caf6f2edfd738a86f501c31064b6 | 3e70d76a20a6caf6f2edfd738a86f501c31064b6 | 2026-10-19T14:56:17Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 组合合并事项(L1 集成期)
- Backend 组合:本 L1 的 backend pin d3380de(基于 03646b5 线)与 Backend main 3f4b34a(#219 关联+解释)已分叉——L1 最终交付前需在 Backend 仓做一次组合合并(3f4b34a + d3380de 线),解决 U1 角色收窄与关联/解释工作的叠加,并以组合验证收口。
- 前端组合:本 L1 frontend pin 2c19439 包含 main(dab1605)与 U1 前端,无分叉。
- RDM:交付组合经 svc(RDM 分支 feature/project-access-lifecycle-u3-member-history @ 62c77ec,含 U2/U3a),后续 U4/U5 继续在其上堆叠。
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证(完成后填写)
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 规划进展与下一步
- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划)
- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务)
- 推荐依据:待填写
- 前置条件/待确认:待核对
- 预期产物/验收条件:待定义
- 重复任务核对:待核对(已有/在途任务、PR 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T14:55:22.278761+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "3e70d76a20a6caf6f2edfd738a86f501c31064b6",
"after_head": "3e70d76a20a6caf6f2edfd738a86f501c31064b6",
"branch": "main",
"target_branch": "main",
"target_head": "3e70d76a20a6caf6f2edfd738a86f501c31064b6",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=3e70d76a20",
"[remote] origin/main=3e70d76a20 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=4",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 3e70d76a20(完整:3e70d76a20a6caf6f2edfd738a86f501c31064b6)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "d2baa6708f27afe1ed29f31d2f69bf866829477011cf2e0e12ebc4721dfa0ca4",
"receipt_sha256": "8172707bdb0edab18ee7d04aefb24cceedfbf32480538e5cde7f78aa647c3aa0",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/8172707bdb0edab18ee7d04aefb24cceedfbf32480538e5cde7f78aa647c3aa0.json"
}
```
| 同步(记录前对象) | 2b7fdc39a1f44163f4766701429d61ffd6926f1a | 7fe701c379180d20691078236457874643835ec1 | 2026-10-19T16:33:44Z |
| 同步(记录前对象) | f07a53d86aa10d35be0d3519fcf3c493b3391fec | d25b2f3287c6b875d03a8286a710454b37f5afb0 | 2026-10-20T01:16:00Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-20T11:56:47.221717+00:00",
"command": "sh -c 'cd modules/frontend && npx vitest run test/pal-u6-ui.test.ts test/rdm-management.test.ts test/design-guard.test.ts test/role-permissions-ui.test.ts 2>&1 | tail -1 && npx tsc -b && echo TSC_OK'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-project-access-lifecycle",
"before_head": "93482789110f80b7bdfd587a7f88dc5fc09d923f",
"after_head": "93482789110f80b7bdfd587a7f88dc5fc09d923f",
"branch": "feature/project-access-lifecycle",
"target_branch": "main",
"target_head": "aa9f98d2e5b8ce36724f881752b0a95a353df987",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "50c6322bb37ebbfb2900beb621fb17f0059076485f8e82c8b21590a40e562b10",
"after_tracked_diff_sha256": "50c6322bb37ebbfb2900beb621fb17f0059076485f8e82c8b21590a40e562b10",
"output_tail": [
"",
"TSC_OK"
],
"output_sha256": "80606ea8f083ab10f6c81f1a2dceced6ba7715c4b1e06d3990489d1041c91463",
"receipt_sha256": "60009b5124f35d49a8a256a8ff1c57e0452cf4029dbc49cee71e55171e5e3876",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/60009b5124f35d49a8a256a8ff1c57e0452cf4029dbc49cee71e55171e5e3876.json"
}
```
@@ -0,0 +1,409 @@
---
title: feat: Clarify project access and lifecycle management
date: 2026-10-19
type: feat
artifact_contract: ce-unified-plan/v1
product_contract_source: ce-brainstorm
execution: code
---
## Goal Capsule
- **Objective:** Make project access understandable and enforceable: administrator authority stays outside job roles; the sole role permission is project access, which permits project creation; project creators with that permission manage their own project; members and project states determine whether work can continue; all fixed company templates are available to projects.
- **Means:** Keep Backend authoritative for authenticated identity and job-role permission, and RDM authoritative for canonical project ownership, membership, project state, and template catalog. Recheck authorization at every read/write and asynchronous execution boundary.
- **Authority:** The user's request in this conversation. Preserve the existing distinction between system administrator and RDM domain administrator. Product rules below govern when existing implementation or older proposals differ.
- **Execution profile:** Split implementation into bounded Backend, RDM, and Frontend units, with host-owned integration, verification, review, and delivery under the repository's agent-per-unit rules.
- **Stop conditions:** Stop when role permissions show only project access, project creator and state gates work for synchronous and in-flight operations, the complete fixed-template catalog is available, and focused verification passes. Do not implement document-duty assignment, production data changes, deployment, or unrelated permission redesign.
- **Delivery owner:** Host owns cross-repository planning, scope review, authoritative verification, review, PR/CI, merge scheduling, and safe closure. Component work begins only after fresh source and branch checks.
## Product Contract
### Summary
The system's role editor exposes job-level system settings and user-management actions alongside project access, which makes role permission sound broader than the intended project boundary. In this product, administrator and super-administrator authority governs system settings, accounts, roles, and platform permissions. A job role has one product permission: project access. Users with effective project access may create projects, and only the creator with effective project access may administer a project. Project membership and project/member state separately govern conversation work. Projects expose the complete fixed company-template library; assignment of document authors, reviewers, and approvers is outside this increment.
### Problem Frame
Current code has a broader action catalog, Backend role-permission records, RDM membership rows, creator/owner checks, project archive/close fields, and a 44-item published DHF catalog. These mechanisms do not yet express one product rule: system administration is distinct from role permission; member removal is currently represented by deleting membership; project-wide and per-member work suspension are not the same as archival; and a complete template catalog is not the same as project-level template access. The result is confusing role configuration and inconsistent expectations about who can create or continue work.
### Actors
- **Super-administrator:** Holds the highest protected system authority according to the existing super-administrator contract.
- **System administrator:** Manages the system actions explicitly assigned by the existing administrator contract. System administrator status alone does not grant project content access or project management.
- **Project creator:** The immutable `createdBy` identity for one canonical RDM project. It can manage that project only while its effective project-access permission and account are valid.
- **Active project member:** Can discover the project and create/use personal conversations while both project and member states permit work.
- **Read-only former or suspended member:** Can read the historical material allowed by the applicable read boundary, but cannot create or continue work.
### Requirements
- **R1. Separate system authority from job roles.** Role configuration must not expose or grant system settings, account/user management, role administration, administrator appointment, or platform-permission management. Those actions remain in protected administrator/super-administrator authorization paths. Preserve the existing distinction between administrator levels; do not infer authority from an RDM domain administrator, project creator, or project member.
- **R2. Reduce role permissions to project access.** Each role has one boolean project-access setting, whose meaning is permission to create a project. Unknown, disabled, unassigned, or denied roles cannot create projects. System administrator status by itself does not substitute for project access.
- **R3. Enforce creator-scoped project management.** Project management requires a valid account, effective project access, and the exact authenticated actor matching the canonical project's immutable creator. These two project conditions are sufficient for the in-scope management actions: project settings, membership, and project/member work states. Existing per-action member/project overrides must not separately grant these management actions to another actor or block the eligible creator. A member with role `owner`, a system administrator, a caller-supplied owner field, or a host-project owner does not bypass the gate.
- **R4. Preserve active-member work.** An active project member can see the project and create personal conversations. Existing conversations remain private according to the read boundary; membership does not itself publish another user's private uploads or drafts.
- **R5. Make removal revoke work but retain allowed history.** Removing a member revokes project work immediately. The former member cannot create conversations, send messages, resume/retry work, approve an execution that would continue work, upload or mutate project data, or continue an existing conversation. The former member retains read-only access to historical material within the agreed historical visibility boundary. Preserve the revocation record so history remains auditable and re-adding does not erase prior removal.
- **R6. Add project-wide work state.** An active project permits work only for members whose member state is active. A closed project permits no member to create or continue conversation work; existing readable conversations and documents remain available. The creator can still use project-management actions needed to reopen or administer the project.
- **R7. Add per-member work state.** The creator can suspend or reactivate an individual member without removing membership. A suspended member remains discoverable/read-only within the same historical boundary but cannot create or continue conversation work. Project-wide closed state overrides an individually active state.
- **R8. Enforce gates at every execution boundary.** Authorization must be rechecked before writes and before queued, resumed, confirmed, or delayed work causes side effects. A permission or state change that wins the race prevents the later operation. Read-only access must not accidentally resume a stream, run, or HITL action.
- **R9. Integrate the complete fixed-template library.** Inventory and expose every fixed company template used in R&D and business phases, including the existing 44-item DHF source batch and any additional fixed-template source found during inventory. Preserve source identity, version/hash, phase, applicability, and format. A template can be selected and instantiated into a project where generation is supported; a project is not prepopulated with every template automatically.
- **R10. Defer document-duty assignment.** Do not add, connect, or change assignment of document author/reviewer/approver duties for these templates in this increment. Do not alter existing duty history or make a template unavailable solely because new duty UI is deferred. Keep any existing behavior outside the changed paths intact.
- **R11. Migrate without privilege expansion.** Existing administrator grants remain protected administrator authority. Existing role assignments that grant system/user actions cease to be effective through roles; they must not silently promote users to administrators. Existing valid project-access assignments are preserved. Any ambiguous legacy owner, membership, or history visibility remains explicit and fails closed rather than being guessed.
- **R12. Keep project data and lifecycle history.** Closing a project or suspending a member is reversible and does not delete projects, conversations, documents, or membership history. Removal is not archive or account deletion.
- **R13. Let authorized role managers configure a new role's project permission.** An actor allowed to manage roles can edit the role's single project-access permission immediately after creation. The role editor must not require the separate `system.permissions.manage` authority to set that one job-role permission. Actors without role-management authority remain read-only, and direct API writes remain protected. System grants and administrator-owned platform limits continue to require `system.permissions.manage`.
### Scope Boundaries
**In scope:** role editor and server role validation; system/admin action sources; project creation and creator authorization; creator-only project settings, membership, and work-state management; project membership active/suspended/removed states; project active/closed state; historical read-only boundary after suspension/removal; all fixed-template inventory and project availability; API, UI, migrations, audit, and tests required for these behaviors.
**Out of scope:** implementing or newly integrating document-duty assignment; redesigning document author/review/approval workflow; exposing private content to system administrators; changing archive/restore behavior; project transfer to another creator; project deletion; automatic creation of every template instance; changing global project-name uniqueness; production migration, release/tag publication, deployment, and live-data repair.
**Deferred to Follow-Up Work:** assigning author/reviewer/approver responsibilities per fixed template; transfer of project creator ownership; richer per-member project action matrices beyond active/suspended work state; template fidelity remediation beyond current supported generation contracts.
### Key Flows
- **F1. Create a project:** An enabled user with effective project access creates a canonical project. The server records the authenticated creator; the client cannot choose or replace the creator.
- **F2. Manage a project:** The creator with effective project access changes settings, membership, or state. A non-creator, a creator whose project access has been removed, or an administrator without project access is denied.
- **F3. Add a member:** The creator adds an enabled account. The member sees the project and can create personal conversations only when the project and member are active.
- **F4. Suspend a member:** The creator suspends the member. Reads remain within the historical boundary; every new or continued work action is denied. Re-activation restores the active-member path without erasing history.
- **F5. Remove a member:** The creator removes the member. The work gate closes and removal is retained as history; the former member can only read permitted historical material.
- **F6. Close or reopen a project:** The creator closes the project; all members become read-only for project work. Reopening restores work to members whose own state is active.
- **F7. Use a fixed template:** A project member browses the complete company-template catalog, selects a template, and creates an instance only through supported generation. Duty assignment is not part of this flow.
### Acceptance Examples
- **AE1.** A normal user without project access receives a denial when creating a project; a user with project access succeeds and is recorded as creator.
- **AE2.** A user with system-admin rights but without project access cannot create or administer a project. The same user can perform only the system actions allowed by the administrator contract.
- **AE3.** A member with project access but who did not create project A cannot manage A or project B. Project A's creator cannot manage B.
- **AE4.** An active member sees the shared project and creates a personal conversation. Other members do not gain access to that conversation merely through membership.
- **AE5.** After removal or suspension, a member can read allowed existing history but every new or continued work action is rejected, including retry, resume, queued continuation, and confirmation that would cause execution.
- **AE6.** Closing project A blocks work for all members and preserves read access; reopening A restores work only for active members.
- **AE7.** Suspending one member blocks only that member's work; other active members continue while the project is active. Closing the project blocks all members regardless of individual state.
- **AE8.** The project catalog accounts for every fixed company template from the approved source inventory, including all 44 DHF assets. Duplicate bytes with distinct source identities remain distinct catalog entries. No project is silently seeded with 44 document instances.
- **AE9.** Role configuration cannot set a system setting, user-management, administrator, or platform-permission action. These actions remain available only through their protected admin paths.
- **AE10.** SQLite and PostgreSQL produce equivalent authorization, concurrency, and migration outcomes; cross-project and post-revocation negatives remain denied.
- **AE11.** An authorized role manager creates a role and can immediately enable or disable its single project-access permission. A role manager who lacks `system.permissions.manage` still succeeds; an actor without `system.roles.manage` cannot edit the permission through the UI or API. System-grant and platform-limit writes remain denied without `system.permissions.manage`.
### Success Criteria
- Role configuration has one understandable project-access choice and no configurable system/user actions.
- A role manager can create a role and configure its project-access choice without a separate platform-permission-management grant.
- Project creation and management follow the exact effective-project-access plus creator rule.
- Project/member state transitions have predictable, reversible read-only behavior, including for in-flight and queued work.
- Every fixed company template is discoverable with traceable source/version/phase metadata; supported selection creates a project instance without introducing duty assignment.
- Existing private-content, project-isolation, system-admin, and super-admin boundaries remain intact.
## Planning Contract
### Key Technical Decisions
- **KTD1. Keep admin authority outside roles.** Keep super-administrator and system-administrator checks in the existing trusted system-authority path. Role permission APIs and UI expose only the project-access capability. Reuse current administrator-level distinctions rather than creating role-based substitutes.
- **KTD2. Define one effective project-access capability.** A single role boolean determines whether an enabled account with an enabled assigned role can create projects. The legacy `allowed`/`capAllowed` pair is only a storage compatibility shape for this action: normalize old records from their prior effective result (`allowed && capAllowed`), and write both fields from the new single boolean. Do not show or authorize an independent role cap for project creation. Administrator status alone is not an implicit project grant. The same effective capability and exact creator identity are the complete authorization rule for in-scope project management; existing per-action project overrides cannot add another manager or impose a second management gate. Preserve explicit deny/fail-closed behavior when role/provider data is missing or stale.
- **KTD3. Separate project membership, member work state, and project work state.** Retain canonical RDM ownership/membership as domain authority. Represent `active`, `suspended`, and `removed` member history separately from `active`/`closed` project work state. Effective work requires an enabled account, active membership, active member state, and active project state.
- **KTD4. Preserve read and work authorization as different checks.** Membership revocation/suspension and project closure block all work paths immediately while leaving only the explicitly allowed read paths. Recheck current state at execution/side-effect boundaries rather than relying on a UI state or a conversation's creation-time authorization.
- **KTD5. Use the published company-template catalog as the source of truth.** Include all inventoried fixed company templates in the project catalog. Keep source assets and template instances distinct. Instantiate on explicit selection, not by bulk-seeding every project. Preserve unsupported fidelity/generation states as visible limitations; catalog presence alone does not claim full-fidelity rendering.
- **KTD6. Use conservative historical visibility.** Unless the user chooses a broader boundary during this planning conversation, retain only the history the member could already read before suspension/removal; do not make another member's private conversation or upload newly visible. Capture the chosen boundary in the final plan and tests.
- **KTD7. Keep this increment reversible and local.** No deletion or destructive data migration is needed. Preserve audit/history, run local verification, and keep deployment and production data repair outside this plan.
### High-Level Technical Design
```mermaid
flowchart LR
A[Authenticated actor] --> B[Backend admin authority]
A --> C[Backend job role: project access]
C -->|create permitted| D[RDM canonical project]
C -->|plus exact createdBy| E[Project management]
D --> F[Member state: active / suspended / removed]
D --> G[Project state: active / closed]
F --> H{Work gate}
G --> H
H -->|allowed| I[Create or continue conversation work]
H -->|denied| J[Historical read-only projection]
D --> K[Complete fixed-template catalog]
K -->|explicit selection| L[Supported project document instance]
```
Project-management authorization and project-work authorization are separate decisions. A closed project may still be administered by its eligible creator, while its members remain read-only. A suspended or removed member never gains creator-management capability through historical read access. Archival remains a separate existing lifecycle and is not changed by this plan.
### Implementation Notes
- Backend owns authenticated actor identity, role assignment, administrator actions, and effective project-access resolution. RDM owns canonical project creator, membership history, project/member work states, and template catalog consumption. Frontend is a projection, not an authorization source.
- Existing project and conversation data may live in different stores. Any write gate crossing Backend and RDM must use the established public extension contracts and preserve account-write fencing; do not assume one transaction spans both stores.
- RDM currently stores `rdm_members` rows by `(project_id, owner)` and removal deletes the row. It has creator checks, owner/member roles, archive/closed fields, and project action caps. The new contract must not mistake project owner role, archived state, or RDM domain-admin state for the requested rule.
- The RDM checkout inspected for this plan is 15 commits behind its remote-tracking `main`; the Backend RDM pin and fixed-template inventory must be refreshed before implementation. Current local source is planning evidence, not a delivery candidate.
### Sources & Research
- `modules/backend/internal/authz/catalog/catalog.go`, `modules/backend/internal/authz/service.go`, and `modules/backend/internal/server/server.go`: current catalog separates protected system actions from the special `project.create` role decision; authenticated system administrators currently bypass that decision, which this plan changes.
- `modules/backend/internal/store/role_policy.go` and `modules/frontend/src/components/RolePermissionsPanel.tsx`: current role policy storage and role-permission editor to be narrowed to project access.
- `modules/backend/internal/server/roles.go` and `modules/frontend/src/components/RolePermissionsPanel.tsx`: role creation/listing use `system.roles.manage` / `system.roles.view`, but role permission catalog and writes plus checkbox enablement currently require `system.permissions.view` and `system.permissions.manage`. This lets a delegated role manager create a role while leaving every permission checkbox disabled. This source path grounds R13; live account grants were not inspected.
- `modules/documents/docs/proposals/2026-10-13-system-project-membership.md`: prior approved boundary for RDM project identity, Backend projections, member-created private conversations, and project/resource privacy. Its privacy rules remain unless the user explicitly changes the historical scope in this plan.
- `modules/documents/docs/proposals/2026-10-15-iam-focused-role-permission-spec.md`: current administrator, role, and project permission contracts; the present role model is broader than the user's requested product model.
- `modules/documents/docs/records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-requirements-r1.md` and `modules/documents/docs/proposals/2026-10-14-rdm-two-trees-latest-templates.md`: 44-source DHF inventory and current known distinction between catalog coverage and rendering fidelity.
- `/home/weichen/projects/Agent-System-RDM/internal/members/members.go`, `internal/rdmapp/projects_api.go`, `internal/rdmapp/system_projects.go`, and `internal/rdmapp/templates/dhf/catalog.json`: inspected RDM membership deletion, creator management, active work checks, and template catalog. This checkout is behind remote `main` and must be refreshed before implementation.
- No external research was used; existing Backend and RDM authorization and template contracts provide direct local patterns.
### Alternatives Considered
- **Keep all existing system actions in the role matrix but lock them:** Rejected because it preserves the misleading product model and makes role configuration look capable of controlling admin authority.
- **Use project membership alone as management authority:** Rejected because a member or delegated project-owner role must not acquire the creator's project-management right.
- **Delete membership and infer history from conversation ownership:** Rejected because it loses explicit revocation history and cannot represent per-member suspension cleanly.
- **Close a project by archiving it:** Rejected because closure must be reversible and read-only while preserving a distinct archival lifecycle.
- **Instantiate every template at project creation:** Rejected because it creates unused documents and duties/approval expectations the user explicitly deferred.
### Deferred Planning Questions
- The user's answer on removed-member historical visibility is pending. The plan currently assumes only pre-revocation visible history remains readable. If the user wants all project conversations/documents visible after removal, update the privacy requirements and acceptance tests before implementation.
- Exact fixed-template source inventory beyond the 44-item DHF batch must be verified against the current RDM source and company template directory when component baselines are refreshed. Missing, duplicate, unsupported, or unreviewed entries must be listed rather than silently omitted.
- Implementation must verify how active runs, delayed commands, streamed events, uploads, and HITL confirmations map onto the current Backend/RDM public contracts; the required outcome is specified, but exact handler names are implementation-time discovery.
## Implementation Units
### U1. Restrict role permissions to project access
**Goal:** Remove system settings, account/user, administrator, and platform-permission actions from role configuration while preserving protected administrator behavior.
**Requirements:** R1, R2, R9, R11, R13
**Dependencies:** None
**Files:**
- `Agent-System-Dev/modules/backend/internal/authz/catalog/catalog.go`
- `Agent-System-Dev/modules/backend/internal/authz/service.go`
- `Agent-System-Dev/modules/backend/internal/store/role_policy.go`
- `Agent-System-Dev/modules/backend/internal/store/migrate.go`
- `Agent-System-Dev/modules/backend/internal/server/roles.go`
- `Agent-System-Dev/modules/backend/internal/server/role_authorization_test.go`
- `Agent-System-Dev/modules/frontend/src/components/RolePermissionsPanel.tsx`
- `Agent-System-Dev/modules/frontend/src/rolePermissions.ts`
- Related Backend and Frontend permission tests
**Approach:**
1. Keep protected system actions in admin/super-admin authorization. Restrict job-role permission read/write/catalog views to one project-access boolean and label it by its actual meaning. The UI has one checkbox, not separate default and cap controls.
2. Authorize this role field using role-view/manage authority. Do not require `system.permissions.manage` to edit a job-role definition. Keep system-grant and platform-limit writes under `system.permissions.manage`.
3. Enforce the same split in the Backend API: role managers can read the project-access descriptor and replace that role value; handcrafted writes to protected system/user actions remain rejected. Map the boolean to both legacy storage columns and authorize from the canonical boolean result.
4. Ensure system administrator status does not bypass the effective project-access check for project creation. Keep role/provider errors, disabled role/account, and unknown actions denied.
5. Migrate old role permission rows so system/user actions are ignored for role authorization and not shown as role capabilities. Do not convert them into administrator grants. Preserve the prior effective project-access result when normalizing `allowed` and `capAllowed`; retain explicit administrator grants unchanged.
**Test scenarios:**
- A role containing old system settings/user action rows cannot authorize those actions and the role API/UI omits them.
- An administrator without project access cannot create a project; an eligible role can.
- A system setting/user action grant through a role-permission write is rejected atomically.
- A user with `system.roles.manage` but without `system.permissions.manage` creates a role, enables its project access, saves successfully, reloads the role, and sees the saved value.
- A user with `system.roles.view` but without `system.roles.manage` can read the project-access value but sees it read-only; direct role-permission writes are rejected.
- A user without `system.permissions.manage` still cannot change system grants or platform limits.
- A legacy role with protected rows migrates without promoting its members or losing valid project access.
- An existing project role with `allowed=true, capAllowed=false` remains effectively denied after normalization; one with both fields true remains allowed.
- A missing/incompatible role provider denies project creation.
**Verification:** Backend role-policy/catalog/authorization migration tests and Frontend role editor tests prove the separated role-management and platform-permission gates; current admin and super-admin tests pass.
### U2. Enforce project creator management authority
**Goal:** Require effective project access and exact canonical creator identity for every project-management action.
**Requirements:** R2, R3, R11
**Dependencies:** U1
**Files:**
- `Agent-System-RDM/internal/rdmapp/projects_api.go`
- `Agent-System-RDM/internal/rdmapp/system_projects.go`
- `Agent-System-RDM/internal/perms/role_provider.go`
- `Agent-System-RDM/internal/perms/perms.go`
- Related project creator and permission tests
**Approach:**
1. Centralize a management check using authenticated actor, canonical project ID, immutable `createdBy`, current account/role project access, and project existence.
2. Apply that complete check to project settings, member management, and project/member work-state management. Existing per-action overrides cannot grant management to non-creators or further restrict the eligible creator. Do not change archive/restore, which remains a separate lifecycle.
3. Preserve separate project-resource authorization for ordinary member reads and conversation work. Do not grant management because a member has an `owner` membership label or an action override.
4. Keep account disable and project-access revocation race-safe using existing write fences or equivalent transactional rechecks.
**Test scenarios:**
- The creator with project access manages their own project.
- The creator after losing project access is denied management.
- A non-creator member, project `owner` role holder, system administrator, and RDM domain administrator are each denied unless they independently meet the exact creator rule.
- The eligible creator can manage in-scope project settings, membership, and state even when a legacy per-action override denies them; a non-creator cannot manage when an override allows them.
- Cross-project IDs, host/RDM ID confusion, and caller-supplied owner substitutions are denied.
- Concurrent account disable or permission revocation prevents a later management write from committing.
**Verification:** Focused RDM project authorization tests pass on SQLite and PostgreSQL; existing project privacy and host-projection tests remain green.
### U3. Preserve membership history and read-only removal
**Goal:** Make member removal and suspension revoke all project work immediately while retaining only authorized historical reads.
**Requirements:** R4, R5, R8, R12
**Dependencies:** U2. The historical visibility scope is a blocking product decision before U3 implementation; the current plan records KTD6 as the conservative default.
**Files:**
- `Agent-System-RDM/internal/members/members.go`
- `Agent-System-RDM/internal/rdmapp/projects_api.go`
- `Agent-System-RDM/internal/rdmapp/system_projects.go`
- `Agent-System-RDM/internal/rdmapp/private_doc_views.go`
- `Agent-System-RDM/internal/rdmapp/iam_i1_privacy_test.go`
- `Agent-System-Dev/modules/backend/internal/server/server.go`
- Relevant conversation read/write, resource authorization, and async-work tests
**Approach:**
1. Replace hard deletion as the authorization source with retained membership/revocation state and timestamps while preserving current member-list semantics for active members.
2. Implement the settled historical read boundary independently from work authorization. Do not expose another user's private conversation/upload unless the user explicitly chooses that scope.
3. Recheck current membership state for conversation creation, message writes, run/retry/resume, upload/mutation, HITL continuation, queued work, and streamed side effects.
4. On removal or suspension, invalidate or stop pending operations where they would otherwise continue producing side effects; reads must remain non-mutating.
5. Re-adding a member creates a new active period or reactivates with an auditable transition; preserve previous removal history.
**Test scenarios:**
- Removed/suspended actor can read allowed historical items but cannot create a conversation or mutate a prior conversation.
- Removed/suspended actor cannot retry, resume, upload, send, approve-to-execute, or cause a queued run to continue.
- An operation authorized before revocation but attempting its side effect after revocation is rejected.
- Another active member's private conversation and original upload remain hidden under the conservative visibility choice.
- Re-adding restores active work without deleting or rewriting prior membership history.
**Verification:** Backend and RDM read/write boundary tests cover the exact revocation race and preserve private-content negatives.
### U4. Add project-wide and per-member work states
**Goal:** Support reversible project closure and per-member suspension with consistent read-only behavior.
**Requirements:** R3, R6, R7, R8, R12
**Dependencies:** U2, U3
**Files:**
- `Agent-System-RDM/internal/projects/projects.go`
- `Agent-System-RDM/internal/members/members.go`
- `Agent-System-RDM/internal/rdmapp/projects_api.go`
- `Agent-System-RDM/internal/rdmapp/system_projects.go`
- `Agent-System-RDM/internal/perms/perms.go`
- Related project/member migration and state-transition tests
- Related Backend conversation/async execution authorization tests
**Approach:**
1. Add explicit reversible project work state `active|closed` and member work state `active|suspended`, leaving archival and historical removal distinct.
2. Define the work predicate as enabled account AND active member AND active member state AND active project state. Historical read access is evaluated separately.
3. Permit the eligible creator to reopen/manage a closed project while denying all member work. Per-member suspension affects only that member; project closure overrides every member state.
4. Enforce current state before every work side effect and on in-flight/queued continuations. Persist version/audit data so stale UI requests and delayed responses cannot restore old state.
5. Keep transitions idempotent and reversible. Do not delete or rewrite conversations, project data, or membership history.
**Test scenarios:**
- Closing a project blocks new and existing conversation work for every member while preserving existing reads.
- Reopening restores work only for active members.
- Suspending one member blocks only that member; other active members continue normally.
- Closing a project blocks a member even when their individual state is active.
- State changes concurrent with message send, queued execution, retry, and confirmation prevent post-close side effects.
- Creator management remains available on a closed project but is denied when creator permission/account is invalid.
**Verification:** RDM state and migration tests pass on SQLite/PostgreSQL; Backend integration tests prove the canonical RDM state gates all conversation work paths.
### U5. Expose the complete fixed-template library to projects
**Goal:** Ensure every fixed company template across business and R&D phases is cataloged and available for explicit project use without adding document-duty assignment.
**Requirements:** R9, R10
**Dependencies:** None for inventory; project access read boundary from U3/U4 for project exposure
**Files:**
- `Agent-System-RDM/internal/domain/template_asset.go`
- `Agent-System-RDM/internal/rdmapp/dhf_catalog.go`
- `Agent-System-RDM/internal/rdmapp/templates/dhf/catalog.json`
- `Agent-System-RDM/internal/rdmapp/dhf_template_instance.go`
- `Agent-System-RDM/internal/rdmapp/dhf_catalog_test.go`
- `Agent-System-RDM/internal/rdmapp/dhf_template_instance_test.go`
- Source inventory and generated catalog tests
**Approach:**
1. Refresh source inventory and verify the fixed-template set from company sources; retain all 44 DHF source identities and include other fixed templates if present.
2. Reconcile source path/hash, template ID/version, business/R&D phase, applicability, format, publication/readiness, and supported generation status. Do not replace templates with the 69 legacy skeleton types or infer missing mappings from similar names.
3. Connect the complete catalog to project-level browse/select behavior. Instantiate only a selected template and preserve exact source/version provenance.
4. Surface blocked or unsupported fidelity/generation status honestly. Catalog inclusion does not claim that every `.doc` or render profile is fully faithful.
5. Do not add or invoke assignment of author/reviewer/approver duties, approval flows, or new lifecycle transitions.
**Test scenarios:**
- The catalog has one traceable entry for every inventoried source, including duplicate-byte files with distinct source identities.
- All fixed business and R&D phase templates appear in the project template browser with source/version/phase metadata.
- An explicitly selected supported template creates one instance with exact source/version provenance.
- Unsupported/blocked templates are visible with their real state and cannot be represented as successfully generated.
- No project creation path automatically creates all template instances or duty assignments.
**Verification:** Template source-inventory, catalog, supported-generation, and project integration tests prove completeness and provenance for the refreshed source snapshot.
### U6. Present role, member, and project-state controls
**Goal:** Make the permission and read-only states clear in the existing admin, role, project, and member interfaces.
**Requirements:** R1-R10, R13
**Dependencies:** U1-U5 API contracts
**Files:**
- `Agent-System-Dev/modules/frontend/src/components/RolePermissionsPanel.tsx`
- `Agent-System-Dev/modules/frontend/src/components/AccountUsersPanel.tsx`
- `Agent-System-Dev/modules/frontend/src/components/TaskSidebar.tsx`
- Existing project settings/member components
- `Agent-System-Dev/modules/frontend/test/role-permissions*.test.ts`
- Relevant project access and browser tests
- `Agent-System-Dev/DESIGN.md`
**Approach:**
1. Role UI shows one project-access checkbox to authorized role managers. A newly created role is selected with an editable project-access checkbox when the actor has `system.roles.manage`; unrelated `system.permissions.manage` state does not disable it. Read-only users receive a clear reason.
2. System/admin actions appear only in the protected system-administration area and reflect the current super-admin/admin contract.
3. Project management controls are visible and accepted only for the creator with project access. The UI uses service-provided state; server authorization remains authoritative.
4. Show project closed, member suspended, and removed/read-only states distinctly, with write controls disabled or absent while read access remains.
5. Surface the fixed-template catalog and explicit selection state. Do not add document-duty assignment UI.
6. Follow the existing UI design tokens, responsive behavior, accessibility, and async sequence ownership in `DESIGN.md`.
**Test scenarios:**
- Role users see only the project-access control; admins see only their authorized admin actions.
- A role manager without `system.permissions.manage` sees an editable project-access checkbox after creating a role and can save/reload its value; a read-only role viewer gets a clear explanation and cannot submit a direct write.
- The role editor does not grant the same actor access to system-grant or platform-limit changes.
- A non-creator cannot discover active project-management controls, and a direct API request remains denied.
- Active project/member affordances work; suspended/closed/removed states show read-only behavior with all work actions blocked.
- A late response cannot restore active controls after account switch, state transition, or membership revocation.
- Template browsing shows all catalog entries while no duty-assignment control is introduced.
**Verification:** Frontend typecheck/unit tests and focused Playwright flows pass at desktop and narrow viewport sizes; design guard remains green.
## System-Wide Impact
- **Users:** Role editing becomes smaller; project creation and management become predictable; removed/suspended members retain read-only history but cannot resume work.
- **Administrators:** System/user duties remain in protected admin surfaces, separate from job-role permissions. System administrators do not gain project contents by virtue of their status.
- **RDM:** Remains authoritative for canonical projects, membership/state, template catalog, and domain content. Member deletion, project closure, and creator management checks require coordinated domain/API updates.
- **Backend:** Continues to own identity and role authority and must fence conversation writes and continuations using current authorization, not UI claims.
- **Compatibility:** Existing role data, active membership, project archive/close fields, host-project projections, conversation privacy, and template identities require explicit migration/compatibility tests. Dev's RDM pin must be aligned only through the normal reviewed cross-repository process.
## Verification Contract
| Scope | Verification | Proves |
|---|---|---|
| Backend role authority | Focused `go test` for `internal/authz`, `internal/store`, and `internal/server` role/authz tests | Protected system actions remain admin-only; role project access gates creation; migrations do not elevate users |
| RDM authorization and state | Focused tests for `internal/perms`, `internal/members`, `internal/projects`, and `internal/rdmapp` | Creator identity, member/project states, removal history, privacy and execution gates |
| Database portability | Existing isolated PostgreSQL test harness for affected Backend/RDM migration and concurrency tests | SQLite/PostgreSQL parity, conflict handling, and transaction fencing |
| Template inventory | Catalog/source/hash checks plus supported generation tests | Complete fixed-template coverage with exact source provenance and honest fidelity state |
| Frontend | Focused Vitest/typecheck and browser tests for role, project, member, status, and template flows | Correct affordances and read-only behavior across real UI transitions |
| Integrated candidate | `make test-worktree`, `scripts/check-pins.sh`, and the applicable Dev composition suite once on the final fixed candidate | Exact cross-repository composition is buildable and matches reviewed component pins |
| Delivery | Independent review, exact-head required CI, PR base/target checks and task evidence under `policy/delivery.md` and `policy/governance.md` | Reviewed candidate is deliverable; local SELF results are not presented as CI or runtime acceptance |
No deployment, production database migration, live permission rewrite, or business-account acceptance is included. Runtime behavior remains `NOT_RUN` until separately authorized and validated against the exact deployed composition.
## Definition of Done
- Role permission API and UI offer only project access; system settings, user/account, role, and platform-permission actions remain admin/super-admin controlled.
- Project creation requires effective project access; project management additionally requires exact canonical creator identity and current enabled state.
- Active members can see projects and create personal conversations. Suspended/removed members and closed projects reject all new and continued work while preserving the agreed read-only history.
- Authorization is rechecked for synchronous, queued, resumed, retried, streamed, and confirmation-triggered side effects.
- Every fixed company template is inventoried and available to projects with traceable identity, phase, version, and supported-generation status; specific template instances are created only on selection.
- No document-duty assignment functionality is added or newly connected; existing private data and duty history remain unchanged.
- Focused Backend, RDM SQLite/PostgreSQL, Frontend/browser, and exact Dev composition checks pass for the final candidate; independent review and required exact-head CI pass before merge.
- No deployment, production data change, release/tag publication, or live-user permission adjustment is performed under this plan.
@@ -485,7 +485,7 @@ func (e *env) loginAlice(t *testing.T) *userClient {
}, nil)
apiKey := e.cliOut(t, "apikey", "create", "--dsn", e.dbDSN, "--owner", aliceOwner, "--name", "mi-acceptance")
// IAM U4 把建项目改为系统动作 project.create:由引导管理员经真实 API 授予 alice。
// 建项目需角色上的 project.create:由引导管理员经真实 API 建角色并绑定 alice。
e.grantAliceProjectCreate(t)
uc := &userClient{
api: &http.Client{Timeout: httpWait, Transport: bearerRT{key: apiKey}},
@@ -498,44 +498,53 @@ func (e *env) loginAlice(t *testing.T) *userClient {
return uc
}
// grantAliceProjectCreate 以 mi-root 身份经 admin API 为 alice 追加系统授权
// project.create(保留其已有授权;PUT 为整体替换,按 authorityEpoch 乐观并发)。
// mi-root 由 serve 启动时的 SUPER_ADMIN_* 建立,可直接为其发 API key。
// grantAliceProjectCreate 以 mi-root 身份经 admin API 为 alice 授予项目访问:
// project.create 只由已启用账号所绑定的已启用角色上的单一布尔决定,管理员
// 身份或系统授权都不再隐含它。故新建角色、写入 project.create
// (allowed=capAllowed=true,按 roleVersion 乐观并发),再按 alice 的
// stateVersion 绑定该角色。mi-root 由 serve 启动时的 SUPER_ADMIN_* 建立,
// 可直接为其发 API key。
func (e *env) grantAliceProjectCreate(t *testing.T) {
t.Helper()
rootKey := e.cliOut(t, "apikey", "create", "--dsn", e.dbDSN, "--owner", "mi-root", "--name", "mi-acceptance-root")
root := &http.Client{Timeout: httpWait, Transport: bearerRT{key: rootKey}}
var users []struct {
UserID string `json:"userId"`
Owner string `json:"owner"`
UserID string `json:"userId"`
Owner string `json:"owner"`
StateVersion int64 `json:"stateVersion"`
}
e.do(t, root, "GET", "/api/admin/users", nil, &users)
userID := ""
userID, stateVersion := "", int64(0)
for _, u := range users {
if u.Owner == aliceOwner {
userID = u.UserID
userID, stateVersion = u.UserID, u.StateVersion
}
}
if userID == "" {
t.Fatalf("user %s not found in /api/admin/users", aliceOwner)
}
var grants struct {
Actions []string `json:"actions"`
AuthorityEpoch int64 `json:"authorityEpoch"`
var role struct {
RoleID string `json:"roleId"`
RoleVersion int64 `json:"roleVersion"`
}
e.do(t, root, "GET", "/api/admin/users/"+userID+"/system-grants", nil, &grants)
actions := grants.Actions
has := false
for _, a := range actions {
has = has || a == "project.create"
e.do(t, root, "POST", "/api/admin/roles", map[string]any{
"name": "mi-project-access",
"description": "multi-instance acceptance: project.create",
}, &role)
if role.RoleID == "" {
t.Fatal("POST /api/admin/roles returned no roleId")
}
if !has {
actions = append(actions, "project.create")
}
e.do(t, root, "PUT", "/api/admin/users/"+userID+"/system-grants", map[string]any{
"expectedAuthorityEpoch": grants.AuthorityEpoch,
"idempotencyKey": "mi-alice-project-create",
"actions": actions,
e.do(t, root, "PUT", "/api/admin/roles/"+role.RoleID+"/permissions", map[string]any{
"expectedRoleVersion": role.RoleVersion,
"idempotencyKey": "mi-role-project-create",
"changes": []map[string]any{
{"actionId": "project.create", "allowed": true, "capAllowed": true},
},
}, nil)
e.do(t, root, "PUT", "/api/admin/users/"+userID+"/role", map[string]any{
"roleId": role.RoleID,
"expectedStateVersion": stateVersion,
"idempotencyKey": "mi-alice-project-access-role",
}, nil)
}