Merge authoritative main into the task branch

Why: include the current integration baseline before verification.

Evidence: fetched origin/main=5575859b611239a3ee09a8a82b55911318c87187.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
This commit is contained in:
2026-10-16 08:56:08 +00:00
4 changed files with 726 additions and 21 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Executable → Regular
+26 -20
View File
@@ -5,8 +5,9 @@
# 1. 构建:RDM 二进制(RDM 仓 origin/main 临时 worktree,pins 物化)
# + 基座 CLI(本 worktree modules/backend,建号用)
# + frontend dist(本 worktree modules/frontend)
# 2. 种子:RDM -bootstrap-admin(域管理员)→ 基座 user create(登录账号)
# → serve(auth on)→ API rdm.project.create×2 + rdm.ingest(主项目)
# 2. 种子:RDM -bootstrap-admin(域管理员)→ serve 首启建基座存储 → identity ensure →
# 基座 user bootstrap-admin(login-key 激活契约;--password 已被拒绝)→
# redeem+设密 → API rdm.project.create×2 + rdm.ingest(主项目)
# 3. 验收:vite preview(dist+/api 代理)→ npx playwright test
# 4. 收尾:停 serve/preview,保存认证/失败工件到 $E2E_OUT
#
@@ -87,7 +88,7 @@ trap cleanup EXIT
(cd "$RDM_WT" && go build -o "$OUT/agent-system-rdm" .) || die "rdm build failed"
log "rdm binary: $OUT/agent-system-rdm (RDM@${RDM_SHA:0:12}, pins@${PIN_SHA_WANT:0:12})"
log "build base CLI (user create) from the same pinned backend as the RDM binary"
log "build base CLI (account bootstrap/activation) from the same pinned backend as the RDM binary"
# 版本一致性:建号 CLI 必须与被测 RDM 二进制共用同一基座 pin——用 Dev 顶层
# backend(main 最新)建号会把库迁到更高 schema,RDM pins(较旧)打不开。
(cd "$RDM_WT/pins/agent-system-backend" && go build -o "$OUT/agent-system" ./cmd/agent-system) \
@@ -104,11 +105,10 @@ RDM="$OUT/agent-system-rdm -data $DATA"
log "bootstrap: RDM domain admin = $OWNER"
$RDM -bootstrap-admin "$OWNER" >/dev/null
log "bootstrap: base account $OWNER (admin)"
"$OUT/agent-system" user create --data "$DATA" --owner "$OWNER" --name "E2E 审计员" \
--password "$PASSWORD" --admin >/dev/null
log "serve RDM at $API_BASE (auth on)"
# ── 凭据契约(2026-10-13 起):--password 建号被 RECOVERY_CONTRACT_REPLACED 拒绝,
# 改走 login-key 激活:serve 首启创建基座存储 → identity ensure → 基座首位账号
# bootstrap-admin(激活 Key 交付)→ API redeem → 设密(PASSWORD2 为登录密码)。
log "serve RDM at $API_BASE (auth on;首启创建基座存储)"
start_serve() {
"$OUT/agent-system-rdm" -data "$DATA" -addr "127.0.0.1:$API_PORT" -auth on \
>"$OUT/serve.log" 2>&1 &
@@ -136,16 +136,6 @@ login() {
done
die "login failed"
}
# CLI 建号留下 must_change_password。会话在改密前不能调用业务命令。
# 强制设密会作废当前会话,所以设密后用新密码再登录。
finish_password_gate() {
curl -sf -b "$JAR" -c "$JAR" -X POST "$API_BASE/api/auth/password" \
-H 'Content-Type: application/json' \
-d "{\"next\":\"$PASSWORD2\"}" >/dev/null || die "password setup failed"
PASSWORD=$PASSWORD2
login
}
cmd() { # cmd <id> <params-json> → payload(失败即死,种子步骤不容忍部分成功)
local id=$1 params=${2:-{\}}
curl -sf -b "$JAR" -X POST "$API_BASE/api/commands/$id" \
@@ -154,11 +144,27 @@ cmd() { # cmd <id> <params-json> → payload(失败即死,种子步骤不容
|| die "command $id rejected"
}
# 阶段①:建项目与需求台账(API;需 serve)。
# 阶段①:激活账号并建项目与需求台账(API;需 serve)。
start_serve
JAR="$OUT/cookies.txt"
log "seed: identity ensure + base first account (login-key 契约)"
ID_OK=0
for i in $(seq 1 15); do
if "$OUT/agent-system" identity ensure --data "$DATA" --instance-id "e2e-audit" >/dev/null 2>&1; then ID_OK=1; break; fi
sleep 1 # 服务端受控迁移(含 identity 表)可能晚于 HTTP 就绪
done
[ "$ID_OK" = 1 ] || { tail -5 "$OUT/serve.log"; die "identity ensure failed"; }
"$OUT/agent-system" user bootstrap-admin --data "$DATA" --owner "$OWNER" \
--name "E2E 审计员" --out-file "$OUT/$OWNER.bootstrap.key" >/dev/null \
|| die "base bootstrap-admin failed"
K=$(cat "$OUT/$OWNER.bootstrap.key")
curl -sf -c "$JAR" -X POST "$API_BASE/api/auth/login-key/redeem" \
-H 'Content-Type: application/json' -d "{\"key\":\"$K\"}" >/dev/null || die "login-key redeem failed"
# 激活会话仅能设密:设为 PASSWORD2(后续登录与规格消费一致)。
curl -sf -b "$JAR" -c "$JAR" -X POST "$API_BASE/api/auth/password" \
-H 'Content-Type: application/json' -d "{\"next\":\"$PASSWORD2\"}" >/dev/null || die "password setup failed"
PASSWORD=$PASSWORD2
login
finish_password_gate
log "seed: create projects"
PID_MAIN=$(cmd rdm.project.create "{\"name\":\"$PROJ_MAIN\"}" | python3 -c 'import json,sys; print(json.load(sys.stdin)["projectId"])')
PID_ISO=$(cmd rdm.project.create "{\"name\":\"$PROJ_ISO\"}" | python3 -c 'import json,sys; print(json.load(sys.stdin)["projectId"])')