Why: branches merged into their immediate or root target had left their task cards open; backfill status and archive to prevent bookkeeping debt. Evidence: fix-pal-component-delivery-pins.md(PR#682 into main) — merges verified via git log --merges plus Gitea API squash lookup against each card's origin target. Impact: .task/*.md moved to .task/archive/ with status backfilled; no code or submodule change. Refs: task.sh close (card-autoclose-r1)
17 KiB
fix/pal-component-delivery-pins 任务卡
任务主记录:PR #682 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/682(merge f23f5bb01a);状态:已完成(回填);owner:weichen
-
权威仓:ssh://git@192.168.3.2:2222/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)=
a496ea0f02 -
工作区:/home/weichen/projects/Agent-System-Dev-wt-fix-pal-component-delivery-pins(worktree);分支:fix/pal-component-delivery-pins
-
分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
-
需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=5bd167003a0df76cc4ce5252be7b24ce28dbcc9614493a978e3e1b7a8e864dcc;triage_receipt=/tmp/pal-pins-triage.json;receipt_sha256=0f53fa4aab99a9d10ebac3f76c9be1308b4b84b1066a59230f1497bff05e917c
-
授权与交付终点:<本次允许的动作与终点;未授权事项写明>
-
交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
-
实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
-
合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
-
流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
目标与非目标
- 预期结果:把 PR #634 已合入 Dev main、但未进入交付件的组件内容补齐——Backend 与 RDM 各自合入 main,Dev 推进对应 pin,使 U1–U5 真正进入可部署制品。
- 已核实基线(2026-10-21 建任务时点):Dev main 钉
modules/backend=dfb31da(不含生命周期内容)、modules/frontend=113103f(即 U6 交付头,随 Dev 交付但未入 Frontend main)、RDM pinc6304224(2026-10-13,早于角色权威切到 Backend 的 #454)。上述取值均为时点快照,精确落后量不作依据。 - 非目标:不改 U1–U5 的规格语义;不部署(C16 另起,需 pin 就位后进行);不处理
feature/rdm-two-trees-followup(PR #635)的范围。
决策记录
- D1(role cap 是否受 R3 carve-out 约束)——用户裁决 2026-10-21,选 A1。 RDM 的
evalPerm有两层不同的覆盖:role cap(switch的RoleReasonCapDenied与 legacy 的!defined || !capAllowed)与项目覆盖层(末尾ps.OverrideFor)。计划 R3 原文只约束后者(原文用词为 per-action member/project overrides)。- 裁决内容:只让项目覆盖层不再撤销创建者权威本身授予的权限;role cap 维持现状、继续阻断创建者。覆盖层的「授予」方向也不变。平台上限、账号停用、职位停用、Linked.Conflicts、归档/结项状态守卫、对非创建者的拒绝全部不变。
- 实现:
internal/rdmapp/perms_api.go的evalPerm末尾,creatorGranted := base && relation == perms.RoleOwner && p.CreatedBy == actor && isManagementAction(act);if set && (override || !creatorGranted)。 - 该裁决曾以「Decision A1」写进
plugins/rdm/system_projects_test.go的注释,但当时未在任何仓内决策记录中留痕——这是本卡补记的原因。
- D2(archive/restore 授权门不得被 R3 收敛吞掉)——由计划原文直接决定,非新决策。 U2 第 219 行:「Do not change archive/restore, which remains a separate lifecycle.」故
canManageProject按 act 分流:ActProjectArchive沿用 main 的「创建者或显式授权」门,其余走 R3 的requireProjectManagement。 - D3(ArchivedAt 守卫必须还原,ClosedAt 不设)——由计划原文与 R6 共同决定。 归档属 Out of scope,main 的只读守卫必须恢复(含创建者);结项属 U4/R6,R6 明文「The creator can still use project-management actions needed to reopen or administer the project.」,故 ClosedAt 刻意不设守卫。
- D4(平台上限对创建者同样生效)——由领域规则与 SR-G9 决定。 「system.grants 与平台上限写入门禁保持 system.permissions.manage,不得因 R13 放宽」;
perms.SetCap注释「所有业务主体均受约束」;SR-G9 创建者「仍受有效角色与平台 cap」。故requireProjectManagement带 act 参数并恢复CapAllows。
Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| dev-advance-rdm-and-dm-pins | tests/integration/lifecycle/rdm.pin + deps/development-manager 指针 |
AGENT-EXECUTION digest ccceb3bf | implementation | cursor→agy→pi-glm→pi→codex | 1 | cursor(session not-observable) | success | b5a0abf(refs/agent-exec…),已 apply 快进入分支 | never | /tmp/dev-pin-run.json |
同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | a496ea0f02 |
a496ea0f02 |
2026-10-21T03:47:24Z |
证据(Evidence)
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|
组件交付结果(2026-10-21)
| 组件 | 状态 | 依据 |
|---|---|---|
| Backend | ✅ 已进 main(7158bea) |
生命周期工作已由 PR #234 合入;Dev 的 backend pin f084d10 已含该提交(他人推进,已核实祖先关系) |
| RDM | ✅ 已进 main(bc8db88) |
PR #460,五轮独立 Review 终判 PASS,CI 双作业绿 |
| Frontend | ✅ 随 Dev 交付 | pin 113103f 即 U6 交付头 |
交付前的状态
可核事实:Dev 的门禁从未消费交付分支。Makefile 的 test 目标只测各组件钉住的检出(test-backend 测 modules/backend 的 pin),rdm.pin 仅被 test-lifecycle / test-regulations-kb 消费,而真实生命周期门禁需要真实 PostgreSQL 与 RDM 源仓。因此「Dev 门禁全绿」与「交付分支本身有缺陷」可以同时成立。
SELF 观测(非本仓可复核,2026-10-21 时点):我在组件仓的临时 worktree 上检出交付分支顶端提交并运行其自带测试,观察到失败——
- Backend
bd640df:单跑TestConversationWorkErrorCategorization失败,同一用例在origin/main通过。 - RDM
301cf56:全量go test ./...有 4 个用例失败,同一运行中internal/rdmapp绿、plugins/rdm红。
这两个观测随后被下面的六项缺陷所印证与闭合。若需复核,请在对应组件仓按上述提交检出并运行其自带测试;本仓无法复现,故不得把本段当作 GATE 证据引用。
勘误:提交 537bf66 的信息中写有「red-at-tip finding」,该表述把上述 SELF 观测说成了既定发现;本条以本节为准。537bf66 另写的「差 27 文件/1379 行」「落后 RDM main 918 提交」为当时点的粗略量测,与任何自然口径都不精确对应,现予作废,不作为依据。
修复过程中发现并闭合的授权缺陷
| 编号 | 内容 | 性质 |
|---|---|---|
| B1 | canManageProject 被整体替换,archive/restore 授权门被吞;两个 main 测试被反向改写成「获授者也拒绝」并注释「新旧一致」 |
越界 + 伪装成延续 |
| B2 | 已归档项目只读守卫丢失,改名/成员增删/override 全放行 | 越界(计划禁止改 archive) |
| B3 | 平台上限失效:管理员 SetCap 关闭后创建者管理写入全部成功,而 member add 被拒、remove 放行 |
安全天花板被绕过 |
| F1 | 已结项项目上命令面 member-add 拒绝创建者,直接 API 却放行 | 自相矛盾(违反 R6) |
| F2 | role cap 只挡 add 不挡 remove/suspend/reactivate | 口径不一致 |
| F3 | render-profile 族允许非创建者凭 owner 标签或显式覆盖行使 project.settings |
违反 R3 |
结构根因:R3 把管理路径从 evalPerm 迁到 requireProjectManagement 时逐项丢门(先丢归档,再丢平台上限)。最终形态是两个独立维度——managementLifecycleDenial(归档拒绝、结项按 R6 不设)与 managementCeilingDenial(平台上限、role cap、联动冲突、停用、有效访问)。
顺带落地的治理修复
Development-Manager PR #32(2c2e372)为 admit 增加「权威基线内容认可」:暂存路径若与权威基线逐字节相同即免 transport。已实测生效——原本 65 个暂存路径全被拒,修复后仅 5 个需 transport,其余 60 个自动认可;最终以空合并提交记录祖先关系时 admit: ok,全程无 transport 妥协。
结果与验证
- 结果:RDM pin 与 dm pin 均已推进并推送(PR #682);CI
test-pg红,当前 blocked。
test-pg 失败(唯一阻塞)
svc-realcombo success、test 通过,test-pg 在「Clone Agent-System-RDM with nested pins」步骤失败:组合二进制编译报 missing go.sum entry for module providing package agent-document-renderer/{render,markdown,model,profile,profiles,word}。
已核实的成因:RDM bc8db88 的 go.mod 用本地路径 replace agent-document-renderer => pins/agent-document-renderer,因此其 go.sum 中没有任何 agent-document-renderer 条目(实测计数 0)。Dev 侧构建会把 RDM 的 backend replace 重写到 ../backend(即 Dev 的 modules/backend,当前 f084d10),而该 backend 直接 import document-renderer 的上述包,于是 RDM 的模块图无法提供对应条目。另注:RDM 自身钉的 backend 是 bd640df,与 Dev 的 f084d10 已分叉。
这正是「只有真实组合门禁才能发现」的那一类不兼容——make test 全绿(exit 0)也照样漏掉。
根因(已定位,非制品缺陷)
同一份 RDM 在本地跑 scripts/build-product.sh 成功(产物 9ea3fcc8cef0df8a),说明 RDM 制品无缺陷。报错只出现在 CI,原因是 RDM 的 pins 布局从 4 个变成 6 个(新增 pins/agent-document-renderer、pins/agent-system-kb-regulations):
| 提交 | pins 数量 |
|---|---|
legacy_sha 72bb1fec |
4 |
旧 prev_sha 3484ec2 |
4 |
旧 sha c6304224 |
4 |
新 sha bc8db88 |
6 |
| bc8db88 的第一父 59b3624 | 6 |
CI 步骤逐个检出并构建三个 pin,依赖三者布局一致。新 sha 是 6-pin,而 prev_sha/legacy_sha 仍是 4-pin,布局不再一致;本次 fail-loud 断言直接点名:rdm pin c6304224 的 pins/agent-system-frontend 未落地:缺少 go.mod。
我先前把 prev_sha 设成旧 sha(c6304224)是错的——它是 4-pin 布局,且我在单元包与注释里都未核对布局一致性,这是本次返工的直接原因。
进展(run 4714 / job 7830)
CI 物化修复已生效:三个 pin 全部通过 fail-loud 断言并各自构建成功,missing go.sum entry 不再出现。svc-realcombo 与 test 均绿。
失败因此推进到下一道门禁——真实组合门禁 make test-lifecycle,三个用例红:
| 用例 | 失败点 |
|---|---|
test_prev_and_current_pin_switch_and_back |
svc.sh 的 git fetch(独立 RDM 源仓:rdm) 退出 1 |
test_mixed_batch_updates_forward_and_deploy_reverses |
同上,更新检测失败 |
test_phase_interrupt_reconciles_on_real_artifacts |
同上,退出码 86 |
即:CI 里 rdm/ 是 --depth=1 克隆 + 对三个 pin 的 --depth=200 取,svc.sh 物化 RDM 提交时要对该源仓做 git fetch,在浅克隆/对象边界下失败。这属于 scripts/svc.sh 的 RDM 源仓取用方式与 CI 浅克隆之间的新问题,不在本 PR 的 pin 推进范围内,且我未继续深挖。
我的两处失误(均已修正)
- 选
prev_sha时未核对 pins 布局一致性,把 4-pin 的旧 sha 当成 prev(已改为 6-pin 区间内最老的提交)。 - CI 断言写成「每个 pin 必须有 go.mod」——pin 集合混有 Go 仓与非 Go 仓(前端仓根无 go.mod),产生假失败(已改为「HEAD 等于 gitlink 且工作树有已跟踪文件」)。
未决(需决策)
prev_sha应取 bc8db88 的第一父59b3624(6-pin、与新 sha 布局一致、紧邻交付);但这样prev_sha与sha仅隔一个合并,生命周期套件的「来回部署身份稳定性」覆盖力度下降。legacy_sha必须保持「无身份」语义,因而必然是老提交(4-pin)。构建循环是否应继续要求三个 pin 都可构建?若否,则该步骤对legacy_sha应放宽断言或单独处理——这属于 CI 步骤语义的设计取舍,不宜由实现侧默定。
其余验证
-
PASS|pin 取值自洽:
sha=bc8db88含交付内容(managementCeilingDenial、managementLifecycleDenial、txProjectManaged、MemberAddResolveFailure均在其树内);prev_sha为原 pin,供生命周期套件来回部署;legacy_sha未动。 -
PASS|
make test在98d794e上 exit 0、无 FAIL。 -
PASS|独立 Review 首轮判 FAIL(任务卡把会话内观测写成既定结论),已按其要求改写为可核表述 + SELF 观测 + 勘误,复审通过项见上文。
-
NOT_RUN|精确 HEAD 三作业 GATE(
test-pg红)。本地 SELF 不可替代,不得合入。 -
结果:
-
验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
-
影响与剩余项:
合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-21T03:46:26.935822+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "a496ea0f0249b2b412354677ef97612ccd692d25",
"after_head": "a496ea0f0249b2b412354677ef97612ccd692d25",
"branch": "main",
"target_branch": "main",
"target_head": "a496ea0f0249b2b412354677ef97612ccd692d25",
"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=a496ea0f02",
"[remote] origin/main=a496ea0f02 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=5",
"[cards] 已合入未闭合任务卡:feature-project-access-lifecycle.md——make task-close 回填归档(主检出运行)",
"[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] a496ea0f02(完整:a496ea0f0249b2b412354677ef97612ccd692d25)",
"[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": "d63eb6dfcf96743449b73edabd63a126308f731b7528b1e249ec5a7f4ce8aae4",
"receipt_sha256": "b659e67e444244c0f70ec7f71c89044666ba229581bab6ccca200bbf491cd24c",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/b659e67e444244c0f70ec7f71c89044666ba229581bab6ccca200bbf491cd24c.json"
}
| 同步(记录前对象) | ccb6dfaa9c | 2af80d6a24 | 2026-10-21T13:32:30Z |
| 同步(记录前对象) | a736d5a420 | e8dbbe001a | 2026-10-21T13:57:35Z |
闭合记录(card-autoclose 回填)
- 依据:merge f23f5bb01a8b96ab90686d3a1b07791d7f473de2(PR #682)已包含于 origin/main,分支成果已落盘;本段为合入后回填。
- 合并主题:Merge pull request 'Advance the RDM artifact pin so the delivered lifecycle work actually ships' (#682) from fix/pal-component-delivery-pins into main
- 归档:随闭合移入 .task/archive/;任务执行期的过程证据见原任务记录与 PR。