Merge pull request 'Report the real identity marker in svc adopt and the deploy gate' (#681) from fix/genui-prod-upgrade-followups into main
This commit was merged in pull request #681.
This commit is contained in:
@@ -0,0 +1,133 @@
|
|||||||
|
# fix/genui-prod-upgrade-followups 任务卡
|
||||||
|
|
||||||
|
任务主记录:PR #681 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/681;状态:已完成(合入前闭合);owner:weichen
|
||||||
|
|
||||||
|
- 权威仓:ssh://git@192.168.3.2:2222/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= ccb6dfaa9cdf7e69eb15d7df024dee55f37b8df1
|
||||||
|
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-fix-genui-prod-upgrade-followups(worktree);分支:fix/genui-prod-upgrade-followups
|
||||||
|
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
|
||||||
|
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=88169f094e22b9e6549ea7e86f2f211beb1eba9acb9db9ff9cc51a3af5f13c60;triage_receipt=/tmp/genui-followups-20261021/triage.json;receipt_sha256=659253527394185c956e8005f246d7599118d2d5a6c9f15d6093c4bf3b70b148
|
||||||
|
|
||||||
|
- 授权与交付终点:用户 2026-10-21「把剩下的 3件事做了」(GenUI prod 升级遗留:GenUI 功能验收 NOT_RUN、`svc.sh adopt` 误报 established、部署门禁处理不了 v27 前旧库);终点为 svc.sh 修复与 Documents 验收记录经 PR 合入并回收。未授权:prod 业务角色配置(`admin` 建项目权限)、自动迁移、高后果 git 操作
|
||||||
|
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
|
||||||
|
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
|
||||||
|
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
|
||||||
|
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
|
||||||
|
|
||||||
|
## 目标与非目标
|
||||||
|
|
||||||
|
- 目标 1(prod 运维,仓外):在 `dev@5360884` 的 prod 上按 2026-10-12 清单重放 GenUI API 验收。结果 PASS(11 项),不调用模型、无费用。`superadmin` 无 `project.create`(新版本该权限只来自角色),因此用 `superadmin` 建临时角色 `genui-accept`(仅 `project.create`)与同名临时账户执行;首登改密后跑完,账户与角色均已停用,`superadmin` 的 GenUI 启用恢复为关闭;prod 日志无 panic。工作文件 `/tmp/genui-prod-accept-20261021/`(accept.sh、accept.txt,不含凭据)。
|
||||||
|
- 目标 2(`scripts/svc.sh`):`adopt` 读回真实 `db_marker`,未建立时警告而非宣称 established;部署身份门禁遇 `identity table missing` 时提示 pre-v27 库的备份→stop→`migrate --data`→再部署指引(DSN 只经 `AGENT_SYSTEM_DSN`),仍在停旧服务前拒绝、不自动迁移。`tests/test_svc_identity.py` 新增两条回归。
|
||||||
|
- 目标 3(Documents):收口文档 `部署与运行验收` 要点把 NOT_RUN 换成 10-21 验收结果与角色发现(Documents #120),Dev 跟进 gitlink。
|
||||||
|
- 非目标:为 prod 建业务角色/给 `admin` 分配建项目权限(业务配置,需用户决定);svc 自动迁移;svc 持久化超级管理员凭据。
|
||||||
|
|
||||||
|
## Agent 实施收据
|
||||||
|
|
||||||
|
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
|
||||||
|
|
||||||
|
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|
||||||
|
|---|---|---|---|---|---|---|---|---|---|---|
|
||||||
|
| dev-svc-identity-adopt-gate-messages | scripts/svc.sh、tests/test_svc_identity.py | AGENT-EXECUTION.md | implementation | cursor→agy→pi | 1(fresh_session) | cursor | success | refs/agent-exec/…,apply 快进 | 未用 | /tmp/genui-followups-20261021/dev-run.json |
|
||||||
|
| documents-genui-prod-acceptance-20261021 | Documents docs/proposals/2026-10-12-generative-ui-usage-and-evaluation.md | AGENT-EXECUTION.md | implementation | cursor→agy→pi | 1(fresh_session) | cursor | success | refs/agent-exec/d70e53e1…/bbe777052627,apply 快进 | 未用 | /tmp/genui-followups-20261021/docs-run.json |
|
||||||
|
|
||||||
|
## 同步记录
|
||||||
|
|
||||||
|
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 启动 | ccb6dfaa9cdf7e69eb15d7df024dee55f37b8df1 | ccb6dfaa9cdf7e69eb15d7df024dee55f37b8df1 | 2026-10-21T13:32:20Z |
|
||||||
|
|
||||||
|
## 证据(Evidence)
|
||||||
|
|
||||||
|
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
|
||||||
|
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
|
||||||
|
## 结果与验证
|
||||||
|
|
||||||
|
- 结果:三项完成。prod GenUI API 验收 PASS(仓外运维,见目标 1);`svc.sh` adopt/部署门禁提示修复并加回归;Documents #120(合入 75e43e1)记录验收结果与角色发现,本分支跟进 gitlink。
|
||||||
|
- 验证:prod 验收 PASS(SELF,`/tmp/genui-prod-accept-20261021/accept.txt` VERDICT PASS,11/11);`python3 -m unittest tests.test_svc_identity` 31 项 OK(1 跳过为真实 PG 专项,SELF,见证据表);`bash -n scripts/svc.sh` 通过;Documents #120 CI success(GATE,f5417fb);本 PR 当前 HEAD 的 CI 为合入依据。
|
||||||
|
- 影响与剩余项:svc.sh 只改 adopt 与门禁失败提示,成功路径不变。剩余(非目标,需用户决定):prod 无业务角色,`admin` 不能新建项目;svc 不持久化超级管理员凭据。观察:`POST /api/surfaces` 对空 `conversationId` 也返回 201(验收首轮误用触发,非阻塞,未处理)。
|
||||||
|
|
||||||
|
## 合入与清理
|
||||||
|
|
||||||
|
- Review 记录:当前主模型(host,非实施会话)审阅 base ccb6dfa..0e6180c 实际 diff:svc.sh 35 行、测试 45 行、gitlink 1 行、Documents 单要点;结论通过,无阻塞项;重放依据为上方测试证据与 bash -n。
|
||||||
|
- 冲突记录: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-21T13:31:41.603289+00:00",
|
||||||
|
"command": "make precheck",
|
||||||
|
"exit_code": 0,
|
||||||
|
"cwd": "/home/weichen/projects/Agent-System-Dev",
|
||||||
|
"before_head": "ccb6dfaa9cdf7e69eb15d7df024dee55f37b8df1",
|
||||||
|
"after_head": "ccb6dfaa9cdf7e69eb15d7df024dee55f37b8df1",
|
||||||
|
"branch": "main",
|
||||||
|
"target_branch": "main",
|
||||||
|
"target_head": "ccb6dfaa9cdf7e69eb15d7df024dee55f37b8df1",
|
||||||
|
"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=ccb6dfaa9c",
|
||||||
|
"[remote] origin/main=ccb6dfaa9c ahead=0 behind=0",
|
||||||
|
"[tree] clean submodules_drift=0 uninit=0",
|
||||||
|
"[worktrees] linked=4",
|
||||||
|
"[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] ccb6dfaa9c(完整:ccb6dfaa9cdf7e69eb15d7df024dee55f37b8df1)",
|
||||||
|
"[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": "09b9e9691664020d0e7e0d54d516f261c432989878fe18cd76fdf9d5483b4a69",
|
||||||
|
"receipt_sha256": "9aaf14e57c338c29c559dfe23ca5e66fa8c9d2d776803f3bcbc65f474cfd294b",
|
||||||
|
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/9aaf14e57c338c29c559dfe23ca5e66fa8c9d2d776803f3bcbc65f474cfd294b.json"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"summary_schema": 1,
|
||||||
|
"source": "SELF",
|
||||||
|
"timestamp": "2026-10-21T13:38:36.782459+00:00",
|
||||||
|
"command": "PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_svc_identity",
|
||||||
|
"exit_code": 0,
|
||||||
|
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-fix-genui-prod-upgrade-followups",
|
||||||
|
"before_head": "0e6180cbd53b68da9b5810c28506225d6d59085e",
|
||||||
|
"after_head": "0e6180cbd53b68da9b5810c28506225d6d59085e",
|
||||||
|
"branch": "fix/genui-prod-upgrade-followups",
|
||||||
|
"target_branch": "main",
|
||||||
|
"target_head": "a736d5a420370cff052bd946f6d6397d4c354547",
|
||||||
|
"root_target": "main",
|
||||||
|
"immediate_target": "main",
|
||||||
|
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||||
|
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||||
|
"output_tail": [
|
||||||
|
"..................s............",
|
||||||
|
"----------------------------------------------------------------------",
|
||||||
|
"Ran 31 tests in 36.292s",
|
||||||
|
"",
|
||||||
|
"OK (skipped=1)"
|
||||||
|
],
|
||||||
|
"output_sha256": "5db0f58ef46fff16da8a9e48cbf54b5efe5cb93514ecb06def22ba430d7af68e",
|
||||||
|
"receipt_sha256": "c4f367c2b1590a823f0e3cfb6868126788932ec74fcae2c13d5b93cc9b243ce3",
|
||||||
|
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/c4f367c2b1590a823f0e3cfb6868126788932ec74fcae2c13d5b93cc9b243ce3.json"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 闭合记录(合入前折叠)
|
||||||
|
|
||||||
|
- 本卡在 PR #681(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/681)合入前闭合并归档,随该 PR 一同合入。
|
||||||
|
- 该 PR 的合并提交即本任务的落地记录。
|
||||||
|
- 合入后无需回填,也无需单独的闭合 PR。
|
||||||
|
| 同步(记录前对象) | a736d5a420370cff052bd946f6d6397d4c354547 | 62ba1a225fcf1938ee97af2e08e1dbeca142fe97 | 2026-10-21T13:40:41Z |
|
||||||
+1
-1
Submodule modules/documents updated: 2e9c3bc1d8...75e43e1adf
+32
-3
@@ -1355,6 +1355,8 @@ svc_identity_run() {
|
|||||||
svc_db_identity_ensure() {
|
svc_db_identity_ensure() {
|
||||||
# 仅 fresh/pending 或显式 adopt 调用。established 缺行不得走这里自动补。
|
# 仅 fresh/pending 或显式 adopt 调用。established 缺行不得走这里自动补。
|
||||||
# 非 agent 或无能力:跳过。可选参数 BIN:部署候选。
|
# 非 agent 或无能力:跳过。可选参数 BIN:部署候选。
|
||||||
|
# SVC_IDENTITY_LAST_OUT:最近一次 identity CLI 输出,供候选门禁区分失败原因。
|
||||||
|
SVC_IDENTITY_LAST_OUT=""
|
||||||
local bin="${1:-${ENV_BIN:-}}"
|
local bin="${1:-${ENV_BIN:-}}"
|
||||||
manifest_ok || return 0
|
manifest_ok || return 0
|
||||||
local kind; kind="$(svc_get kind)"
|
local kind; kind="$(svc_get kind)"
|
||||||
@@ -1365,6 +1367,7 @@ svc_db_identity_ensure() {
|
|||||||
IFS=$'\t' read -r iid dbref data <<<"$line"
|
IFS=$'\t' read -r iid dbref data <<<"$line"
|
||||||
local out rc=0
|
local out rc=0
|
||||||
out="$(svc_identity_run "$bin" ensure "$iid" "$dbref" "$data" 2>&1)" || rc=$?
|
out="$(svc_identity_run "$bin" ensure "$iid" "$dbref" "$data" 2>&1)" || rc=$?
|
||||||
|
SVC_IDENTITY_LAST_OUT="$out"
|
||||||
if [ "$rc" -ne 0 ]; then
|
if [ "$rc" -ne 0 ]; then
|
||||||
c_err "[$ENV_NAME] DB 身份 ensure 失败:$out"
|
c_err "[$ENV_NAME] DB 身份 ensure 失败:$out"
|
||||||
return 1
|
return 1
|
||||||
@@ -1374,6 +1377,7 @@ svc_db_identity_ensure() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
svc_db_identity_verify() {
|
svc_db_identity_verify() {
|
||||||
|
SVC_IDENTITY_LAST_OUT=""
|
||||||
manifest_ok || return 0
|
manifest_ok || return 0
|
||||||
local kind; kind="$(svc_get kind)"
|
local kind; kind="$(svc_get kind)"
|
||||||
[ "$kind" = agent ] || return 0
|
[ "$kind" = agent ] || return 0
|
||||||
@@ -1384,6 +1388,7 @@ svc_db_identity_verify() {
|
|||||||
IFS=$'\t' read -r iid dbref data <<<"$line"
|
IFS=$'\t' read -r iid dbref data <<<"$line"
|
||||||
local out rc=0
|
local out rc=0
|
||||||
out="$(svc_identity_run "$bin" verify "$iid" "$dbref" "$data" 2>&1)" || rc=$?
|
out="$(svc_identity_run "$bin" verify "$iid" "$dbref" "$data" 2>&1)" || rc=$?
|
||||||
|
SVC_IDENTITY_LAST_OUT="$out"
|
||||||
if [ "$rc" -ne 0 ]; then
|
if [ "$rc" -ne 0 ]; then
|
||||||
c_err "[$ENV_NAME] DB 身份校验失败,拒绝启动:$out"
|
c_err "[$ENV_NAME] DB 身份校验失败,拒绝启动:$out"
|
||||||
c_err " 先调查库文件与身份行;确认归属后 scripts/svc.sh $ENV_NAME adopt --confirm $iid"
|
c_err " 先调查库文件与身份行;确认归属后 scripts/svc.sh $ENV_NAME adopt --confirm $iid"
|
||||||
@@ -1395,6 +1400,22 @@ svc_db_identity_verify() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# svc_identity_schema_missing SRCBIN:最近一次 identity CLI 报身份表缺失(库 schema
|
||||||
|
# 早于 v27)时打印迁移指引并返回 0;否则返回 1,调用方沿用原失败提示。不自动迁移。
|
||||||
|
svc_identity_schema_missing() {
|
||||||
|
case "${SVC_IDENTITY_LAST_OUT:-}" in
|
||||||
|
*"identity table missing"*) ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
local data_root
|
||||||
|
data_root="$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["identity"]["data_root"])' "$ENV_DIR/manifest.json" 2>/dev/null)" \
|
||||||
|
|| data_root="<data_root>"
|
||||||
|
c_err "[$ENV_NAME] 数据库 schema 早于身份表(pre-v27,identity table missing):候选无法补齐/验证 DB 身份;旧服务/旧制品/登记保持不变"
|
||||||
|
c_err " 处理:先备份数据库 → scripts/svc.sh $ENV_NAME stop → 用候选制品执行 $1 migrate --data $data_root(PostgreSQL:DSN 只经环境变量 AGENT_SYSTEM_DSN 传入,不进 argv)→ 再次部署"
|
||||||
|
c_err " svc 不会自动迁移;本次暂存的候选在拒绝后清理,迁移请使用同一版本的制品"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
# svc_deploy_identity_gate SRCBIN:部署候选的身份门禁——在停旧服务、覆盖制品之前
|
# svc_deploy_identity_gate SRCBIN:部署候选的身份门禁——在停旧服务、覆盖制品之前
|
||||||
# 执行(2026-10-12 rdm1/rdmcand 事故:停服→覆盖→启动即被身份门禁拒绝,只剩
|
# 执行(2026-10-12 rdm1/rdmcand 事故:停服→覆盖→启动即被身份门禁拒绝,只剩
|
||||||
# 「登记版本≠磁盘制品」的混合状态且无恢复路径)。规则:
|
# 「登记版本≠磁盘制品」的混合状态且无恢复路径)。规则:
|
||||||
@@ -1425,7 +1446,8 @@ svc_deploy_identity_gate() {
|
|||||||
data_root="$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["identity"]["data_root"])' "$ENV_DIR/manifest.json")"
|
data_root="$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["identity"]["data_root"])' "$ENV_DIR/manifest.json")"
|
||||||
if [ -f "$data_root/agent-system.db" ] || { [ "${DB_MODE:-}" = pg ] && [ -n "${DB_DSN:-}" ]; }; then
|
if [ -f "$data_root/agent-system.db" ] || { [ "${DB_MODE:-}" = pg ] && [ -n "${DB_DSN:-}" ]; }; then
|
||||||
svc_db_identity_ensure "$srcbin" || {
|
svc_db_identity_ensure "$srcbin" || {
|
||||||
c_err "[$ENV_NAME] 候选补齐 DB 身份失败(外宾行/不一致 fail-closed);旧服务/旧制品/登记保持不变"
|
svc_identity_schema_missing "$srcbin" \
|
||||||
|
|| c_err "[$ENV_NAME] 候选补齐 DB 身份失败(外宾行/不一致 fail-closed);旧服务/旧制品/登记保持不变"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
@@ -1433,7 +1455,8 @@ svc_deploy_identity_gate() {
|
|||||||
*)
|
*)
|
||||||
# established:只验证,不补行。缺行或不匹配在停旧服务前拒绝。
|
# established:只验证,不补行。缺行或不匹配在停旧服务前拒绝。
|
||||||
svc_db_identity_verify "$srcbin" || {
|
svc_db_identity_verify "$srcbin" || {
|
||||||
c_err "[$ENV_NAME] 候选无法验证已建立的 DB 身份;旧服务/旧制品/登记保持不变"
|
svc_identity_schema_missing "$srcbin" \
|
||||||
|
|| c_err "[$ENV_NAME] 候选无法验证已建立的 DB 身份;旧服务/旧制品/登记保持不变"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
;;
|
;;
|
||||||
@@ -6507,7 +6530,13 @@ finally:
|
|||||||
PY
|
PY
|
||||||
svc_db_marker_set pending || exit 1
|
svc_db_marker_set pending || exit 1
|
||||||
svc_db_identity_ensure || { c_err "[$ENV_NAME] adopt ensure 失败"; exit 1; }
|
svc_db_identity_ensure || { c_err "[$ENV_NAME] adopt ensure 失败"; exit 1; }
|
||||||
c_ok "[$ENV_NAME] adopt 完成,db_marker=established" ;;
|
local adopt_marker; adopt_marker="$(svc_db_marker)"
|
||||||
|
if [ "$adopt_marker" = established ]; then
|
||||||
|
c_ok "[$ENV_NAME] adopt 完成,db_marker=established"
|
||||||
|
else
|
||||||
|
c_warn "[$ENV_NAME] adopt 未建立 DB 身份:db_marker=$adopt_marker(当前已装制品不具备 identity 能力,无法建立身份)"
|
||||||
|
c_warn " 部署具备 identity ensure/verify 的制品后,由候选身份门禁补齐"
|
||||||
|
fi ;;
|
||||||
status) env_status_detail ;;
|
status) env_status_detail ;;
|
||||||
logs) [ -f "$ENV_LOG" ] && tail -n "${CLI_LOGS_N:-50}" -f "$ENV_LOG" || c_warn "[$ENV_NAME] 暂无日志" ;;
|
logs) [ -f "$ENV_LOG" ] && tail -n "${CLI_LOGS_N:-50}" -f "$ENV_LOG" || c_warn "[$ENV_NAME] 暂无日志" ;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -413,6 +413,51 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
|||||||
hang.chmod(0o755)
|
hang.chmod(0o755)
|
||||||
self.assertIn("rc=1", probe(hang), "探测挂死须有界返回无能力")
|
self.assertIn("rc=1", probe(hang), "探测挂死须有界返回无能力")
|
||||||
|
|
||||||
|
def test_U1_adopt_identityless_artifact_reports_pending(self):
|
||||||
|
"""已装制品无 identity 能力:adopt 的 ensure 静默跳过,marker 留在 pending——
|
||||||
|
输出必须如实报 pending,不得宣称 db_marker=established。"""
|
||||||
|
self.seed_agent("adx", 9454)
|
||||||
|
self.start_ok("adx")
|
||||||
|
iid = self.manifest("adx")["instance_id"]
|
||||||
|
self.svc("adx", "stop")
|
||||||
|
self.install_noid_bin("adx")
|
||||||
|
result = self.svc("adx", "adopt", "--confirm", iid)
|
||||||
|
self.assertNotIn("db_marker=established", result.stdout)
|
||||||
|
self.assertIn("db_marker=pending", result.stdout)
|
||||||
|
self.assertEqual(self.manifest("adx")["identity"]["db_marker"], "pending")
|
||||||
|
|
||||||
|
def test_U1_update_pre_v27_schema_refused_with_migrate_guidance(self):
|
||||||
|
"""候选有 identity 能力但库 schema 早于身份表:停服前拒绝,给出
|
||||||
|
备份→stop→migrate→再部署的指引,而非「外宾行」误导;不自动迁移。"""
|
||||||
|
cand = self.root / "stub-agent-system-noschema"
|
||||||
|
cand.write_text(
|
||||||
|
'#!/usr/bin/env bash\ncase "${1:-}" in identity) '
|
||||||
|
'echo "identity ${2:-ensure}: identity table missing" >&2; exit 1 ;; '
|
||||||
|
'*) exec "%s" "$@" ;; esac\n' % self.stub)
|
||||||
|
cand.chmod(0o755)
|
||||||
|
remote, old_sha, _ = self._make_track_repo(cand, "agent-system")
|
||||||
|
self.git_ok(self.root, "clone", str(remote), str(self.root / "srccache"))
|
||||||
|
self.seed_agent("scx", 9455)
|
||||||
|
self.start_ok("scx")
|
||||||
|
self.set_kv("scx", "source", "dev@%s" % old_sha)
|
||||||
|
mpath = self.runtime("scx") / "manifest.json"
|
||||||
|
m = json.loads(mpath.read_text(encoding="utf-8"))
|
||||||
|
m["identity"]["db_marker"] = "pending"
|
||||||
|
mpath.write_text(json.dumps(m, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||||
|
pid = self.pid_of("scx")
|
||||||
|
bin_before = (self.runtime("scx") / "bin" / "agent-system").read_bytes()
|
||||||
|
|
||||||
|
result = self.svc("update", "scx", check=False)
|
||||||
|
self.assertNotEqual(result.returncode, 0, result.stdout)
|
||||||
|
self.assertIn("migrate --data", result.stdout)
|
||||||
|
self.assertIn("AGENT_SYSTEM_DSN", result.stdout)
|
||||||
|
self.assertNotIn("外宾行", result.stdout)
|
||||||
|
self.assertTrue(self.running("scx"), "拒绝必须发生在停旧服务之前")
|
||||||
|
self.assertEqual(self.pid_of("scx"), pid)
|
||||||
|
self.assertEqual((self.runtime("scx") / "bin" / "agent-system").read_bytes(),
|
||||||
|
bin_before, "旧制品不得被覆盖")
|
||||||
|
self.svc("scx", "stop")
|
||||||
|
|
||||||
def test_I3_start_ensures_sqlite_identity(self):
|
def test_I3_start_ensures_sqlite_identity(self):
|
||||||
self.seed_agent("idb1", 9441)
|
self.seed_agent("idb1", 9441)
|
||||||
self.start_ok("idb1")
|
self.start_ok("idb1")
|
||||||
|
|||||||
Reference in New Issue
Block a user