Files
Agent-System-Dev/.task/archive/fix-pal-component-delivery-pins.md
T
weichen 6db7d37888
ci / svc-realcombo (pull_request) Successful in 2m26s
ci / test (pull_request) Successful in 8m9s
ci / test-pg (pull_request) Successful in 11m8s
Close 1 merged task card(s) and archive them
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)
2026-10-22 01:28:59 +00:00

17 KiB
Raw Blame History

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 pin c6304224(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 推进范围内,且我未继续深挖。

我的两处失误(均已修正)

  1. 选 prev_sha 时未核对 pins 布局一致性,把 4-pin 的旧 sha 当成 prev(已改为 6-pin 区间内最老的提交)。
  2. 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。