Bump frontend pin: gate audit entry on command availability

Why: the rdm-audit entry must hide on plain bases lacking rdm.inspect.*
commands (2026-10-12 diagnostic, increment 2), and the dev-repo e2e driver
needs a plain-base phase to prove it end to end.

Evidence: frontend e058adc carries the gating (vitest 23 files / 112 tests
incl. new contract matrix; tsc -b && vite build pass); full e2e rerun
follows this commit (RDM combo + plain base phases).

Impact: modules/frontend pin 360d640 -> e058adc; scripts/e2e.sh gains
phase 4 (same $DATA served by the base CLI, plain-base.playwright.ts);
task card records scope, authorization chain and stage table.

Refs: 2026-10-12 diagnostic report, increment 2.
This commit is contained in:
2026-10-12 02:59:46 +00:00
parent 032d96ba87
commit 6cf65f6357
3 changed files with 65 additions and 19 deletions
+41 -18
View File
@@ -7,44 +7,67 @@
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 475654363de3ec72df68d246ffab8217b1cfeab6
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-audit-capability-gate(worktree);分支:feature/rdm-audit-capability-gate
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:manual(逐阶段人工评审);明确授权后可记为 authorized-continuous
- 自动推进授权:无;授权范围:无;授权来源:无;授权终点:无;停止条件:无(未授权)
- 当前阶段:需求拆解;当前增量:I1(待定义)
- 授权与交付终点:实施 2026-10-12 诊断报告的增量 2(审计入口能力门控 + 错误四分类 + e2e 普通基座场景);
终点 = PR 就绪、证据齐备、请求人工评审(合入需另行授权)。未授权:增量 1(RDM 组合接入与部署切换)、
增量 3(改密表单语义,兄弟分支另卡)、任何部署/发布动作。
- 交付模式:manual(逐阶段人工评审)
- 自动推进授权:无;授权范围:增量 2 实施(可逆编辑、自检、建 PR);授权来源:用户 2026-10-12 会话
范围选型「增量 2+3 先行(推荐)」+其提供的 2026-10-12 诊断报告(含根因证据链、三增量方案与验收清单);
授权终点:PR 请求评审;停止条件:偏离诊断报告方案、触及部署或共享环境写入。
- 当前阶段:实施与自检;当前增量:I1(审计入口能力门控与错误分类)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
目标:普通基座(命令面无 rdm.inspect.*)不再展示「追溯审计」入口,消除「入口可达、进入即 400」;
RDM 组合下入口照常展示且四页签可读;审计页错误按「能力缺失 / 登录已失效 / 查询失败」分类呈现并保留原始回执。
受影响:modules/frontend(workspaces.ts、store.ts、api.ts、RdmAuditWorkspace.tsx、Workspaces.tsx、
TaskSidebar.tsx、styles.css、test/、e2e/)+ scripts/e2e.sh(新增第 4 阶段普通基座场景)。
契约变更:buildWorkspaceEntries(server, opts) 增加可选 rdmAudit 门控(默认关);workspaces.test.ts
的「无插件仍显示追溯审计」旧契约随之废止。
非目标:不接入/切换 RDM 组合与部署(增量 1);不改后端命令总线与 /api/commands 契约;
不修改密码表单(增量 3 另卡);不处理登录页 401 控制台噪音(属登录失败本身的正常回显)。
## 关联方向与规划
- 适用状态:待核对(无适用规划时说明原因)
- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文)
- 对应里程碑:待核对
- 适用状态:无适用规划文档——本任务源于 2026-10-12 会话诊断(普通基座审计入口 400),本卡即唯一主记录
- 主记录路径/版本:本卡(.task/feature-rdm-audit-capability-gate.md)
- 对应里程碑:无
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 待填写 | 待评估 | 待定 | 待定义 | 待确认 | 待评审 |
| R1 | 审计入口能力门控 | 符合——根因链(workspaces.ts 无条件 builtin + 普通基座无 rdm 命令)已由 2026-10-12 诊断复核(SELF) | 高 | 普通基座:入口不展示且无任何 rdm.* 请求;RDM 组合:入口展示、四页签可读 | GET /api/commands 已有 | 纳入本增量 |
| R2 | 审计页错误四分类 | 符合——原实现直出 e.message(400 回执 JSON) | 高 | 能力缺失/登录失效/无项目/查询失败各有明确文案;原始回执可展开查看 | R1 | 纳入本增量 |
| R3 | 能力撤销与过期入口 | 符合——探测与工作区清单同源刷新(store.refreshPlugins) | 中 | 命令停用后入口随下次刷新隐藏;页面内错误归类为「能力缺失」而非原文 400 | R1 | 纳入本增量 |
## 方案与计划
- 方案引用:待填写(含对象版本)
- 实施计划引用:待填写(含增量与需求 ID)
- 测试计划引用:待填写(含需求 ID 与验收条件)
- 方案引用:2026-10-12 诊断报告增量 2(授权来源节);实现为——
workspaces.ts 增 RDM_AUDIT_COMMANDS(七命令全集)+ rdmAuditReady()(id 匹配且 enabled===true)+
buildWorkspaceEntries(opts.rdmAudit) 门控(默认关);store.refreshPlugins 与 listWorkspaces 同源探测
GET /api/commands 写 rdmAuditAvailable;rdmErrors.ts classifyRdmError 三分类(401/403→登录失效,
unknown or disabled command / commands disabled→能力缺失,其余→查询失败);RdmAuditWorkspace 错误位
统一 RdmErrorState(EmptyState+Collapsible 原始回执,令牌驱动样式)。
- 实施计划引用:单增量 I1,文件级清单见「目标与非目标」;e2e.sh 第 4 阶段复用同 $DATA 换基座 CLI
(agent-system serve,与 RDM 二进制同源同 pin)跑 plain-base spec。
- 测试计划引用:R1/R3——vitest workspaces.test.ts 契约矩阵(无能力只有代理/能力开双内置/让位/溢出/
rdmAuditReady 四态)+ e2e 两段(rdm-audit.playwright.ts 正向锁「能力在→入口在」,新增
plain-base.playwright.ts 反向锁「无能力→入口隐、无 rdm 请求」);R2——rdm-errors.test.ts 五用例
(400 unknown/503 disabled/401/403/500+非 Error 输入)。design-guard 由 vitest 全量携带。
## 阶段评审
| 阶段 | 对象版本 | 结论 | 评审人 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 待定 | 未评审 | — | — | — |
| 需求评估 | 待定 | 未评审 | — | — | — |
| 需求表确认 | 待定 | 未评审 | — | — | — |
| 方案设计 | 待定 | 未评审 | — | — | — |
| 实施计划 | 待定 | 未评审 | — | — | — |
| 实施与自检 | 待定 | 未评审 | — | — | — |
| 需求拆解 | 诊断报告(2026-10-12) | 通过 | 用户(会话选型) | 2026-10-12 | 用户确认「增量 2+3 先行」,需求边界=报告增量 2 定义 |
| 需求评估 | 诊断报告(2026-10-12) | 通过 | 用户(会话选型) | 2026-10-12 | 报告含可行性/成本/风险与验收清单;优先级=报告建议顺序 |
| 需求表确认 | 本卡 R1–R3 | 通过 | 用户(会话选型) | 2026-10-12 | 范围=增量 2 全部验收点(R3 能力撤销由报告「处理能力撤销」派生) |
| 方案设计 | 本卡「方案与计划」 | 通过 | 用户(会话选型) | 2026-10-12 | 方案骨架=报告增量 2(GET /api/commands 复用、store 统一维护、错误分类) |
| 实施计划 | 本卡「方案与计划」 | 通过 | 用户(会话选型) | 2026-10-12 | 单增量 I1;测试=契约红绿+e2e 两段 |
| 实施与自检 | 待回填(实现 HEAD) | 未评审 | — | — | Agent 自检(vitest/tsc/build/e2e,SELF)已完成待人工复核 |
| 正式测试与验收 | 待定 | 未评审 | — | — | — |
| 代码 Review | 待定 | 未评审 | — | — | — |
| 合入 | 待定 | 未评审 | — | — | — |
+23
View File
@@ -78,6 +78,7 @@ cleanup() {
[ -n "${UI_PID:-}" ] && kill "$UI_PID" 2>/dev/null || true
pkill -f "vite preview --port $UI_PORT" 2>/dev/null || true
pkill -f "agent-system-rdm -data.*e2e" 2>/dev/null || true
pkill -f "agent-system serve .*$API_PORT" 2>/dev/null || true
}
trap cleanup EXIT
(cd "$RDM_WT" && go build -o "$OUT/agent-system-rdm" .) || die "rdm build failed"
@@ -220,4 +221,26 @@ set -e
cat "$OUT/playwright.log"
[ "$PW_EXIT" = 0 ] && log "PASS" || die "playwright exit=$PW_EXIT (log: $OUT/playwright.log, trace: $OUT/frontend/test-results/)"
# ── 4. 普通基座缺能力场景(增量 2 验收)──────────────────
# 同一 $DATA 换基座 CLI 服务(与 RDM 二进制同源同 pin,命令面无 rdm.inspect.*),
# preview 不动只换 /api 指向,跑 plain-base spec:审计入口隐藏、代理常驻、
# 全程无 rdm.* 命令请求——消除「入口可达、进入即 400」的原缺陷路径。
log "plain-base phase: serve base CLI (no RDM commands)"
stop_serve
"$OUT/agent-system" serve --data "$DATA" --addr "127.0.0.1:$API_PORT" --auth on \
>"$OUT/serve-plain.log" 2>&1 &
API_PID=$!
for i in $(seq 1 40); do
CODE=$(curl -s -o /dev/null -w '%{http_code}' "$API_BASE/api/me" || echo 000)
[ "$CODE" != "000" ] && break
sleep 0.25
[ "$i" = 40 ] && { tail -5 "$OUT/serve-plain.log"; die "plain api not ready"; }
done
set +e
npx playwright test e2e/plain-base.playwright.ts --reporter=list >"$OUT/playwright-plain.log" 2>&1
PW_PLAIN_EXIT=$?
set -e
cat "$OUT/playwright-plain.log"
[ "$PW_PLAIN_EXIT" = 0 ] && log "PASS (plain-base)" || die "plain-base playwright exit=$PW_PLAIN_EXIT (log: $OUT/playwright-plain.log)"
log "done; artifacts in $OUT"