Why: close the task card inside its own PR so landing it needs no post-merge backfill or separate close PR. Evidence: .task/fix-svc-static-deploy-test-port-flake.md -> .task/archive/fix-svc-static-deploy-test-port-flake.md; status 已完成(合入前闭合); PR #668 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/668. Impact: task metadata only; the card is archived within PR #668 and lands with its merge commit. Refs: task.sh close --self
17 KiB
fix/svc-static-deploy-test-port-flake 任务卡
任务主记录:PR #668 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/668;状态:已完成(合入前闭合);owner:weichen
-
权威仓:ssh://git@192.168.3.2:2222/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)=
a9566a6850 -
工作区:/home/weichen/projects/Agent-System-Dev-wt-fix-svc-static-deploy-test-port-flake(worktree);分支:fix/svc-static-deploy-test-port-flake
-
分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
-
需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=9dd8c0eec3933926486dbc7537df17ada16cbe48d6151410626f43be81914353;triage_receipt=/tmp/svc-flaky-triage.json;receipt_sha256=7e0e09ea9fd8067ba091a3b657f7930bac6d5eceb08da1a0a2c86c415a4c2c7a
-
授权与交付终点:修复
tests/test_svc.py中因硬编码端口导致的偶发失败用例,standalone 直达 main(PR + 完整 CI + 独立 Review)。不含scripts/svc.sh改动、不含其它用例的端口治理、不含发布/部署。 -
交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
-
实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
-
合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
-
流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
目标与非目标
- 预期结果:
tests/test_svc.py的SvcDbRecoveryTests.test_static_fresh_deploy_registers_pidcheck_and_starts不再因端口占用而偶发失败;该用例守护的语义(static 首启探活不得把http.server判成「进程即退」)保持不变。 - 根因(host 确定性复现,非推断):用例第 989 行硬编码
port = 18951。只要机器上任何进程占用该端口,scripts/svc.sh的check_port_free就会正确拒绝(「端口被占用(非本服务)」、退出 1),用例因此失败。host 实测:占用 18951 时该用例稳定失败(AssertionError: 1 != 0),不占用时 10/10 通过。 - 受影响面:仅
tests/test_svc.py(测试代码)。产品侧scripts/svc.sh不改——其拒绝占口的行为是正确的。 - 非目标:不改
scripts/svc.sh;不改tests/test_svc.py:753-754的register_pg("pg1", 18951, ...)夹具(只写svc.env文本、从不绑端口,与本问题无关);不重构测试类;不新增跨用例端口管理框架(TOCTOU 套件级解法属独立增量)。
Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| svc-static-deploy-test-port-flake | tests/test_svc.py 单文件:硬编码端口 → 内核分配空闲端口 |
AGENT-EXECUTION.md digest ccceb3bf | implementation | cursor→agy→pi-glm→pi→codex | 1 | cursor(cursor-agent-stable,model auto;session f4bd5b1f-6258-48f5-bcbd-442e1f8a66f2) |
success | d0b217d3(refs/agent-exec/850b1455f…/5ca3ade8a790),已 agent-exec apply 快进入分支 |
never | /tmp/svc-flake-run.json |
| review-svc-static-deploy-test-port-flake | 只读审查 | 同上 digest | review | pi-glm→pi→agy→cursor→codex | 1 | pi-glm(pi,zai-coding-cn/glm-5.3-flash,session not-observable) |
failed-unknown(worker exit 0 且只读无改动,控制器不建 transport) | 无 | never | /tmp/svc-flake-review-run.json |
第二次 Review 尝试以全新
piCLI 进程(非--continue/--resume,fresh session)单独执行,结论 PASS;原始输出/tmp/svc-flake-review-final.log。上表 failed-unknown 一行如实保留:按 policy/delivery.md,该终态不得计为门禁 Review。
同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | a9566a6850 |
a9566a6850 |
2026-10-21T02:38:22Z |
| 合入前同步 | a496ea0f02 |
4ebf9e1b47 |
2026-10-21T03:16:00Z |
证据(Evidence)
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|
结果与验证
- 结果:
tests/test_svc.py:989的硬编码port = 18951换成socket.bind(("127.0.0.1", 0))内核分配空闲端口(3 增 1 删,单文件单 hunk)。用例的 8 条断言一条未删未弱化。 - 验证:
- PASS|目标用例在干净主机通过(被测 HEAD 4ebf9e1,SELF,收据 7dfe7b09)
- PASS|目标用例在旧硬编码端口 18951 被外部进程占用时仍通过——这是修复的决定性一腿;同一场景在修复前确定性失败
- PASS|
tests.test_svc全模块 23 项 OK(被测 HEAD 4ebf9e1,SELF,收据 7dfe7b09) - PASS|
make test-affected BASE=main全量 518 项 OK(被测 HEAD d0b217d3,SELF;同步后非卡片变更触发 WARN,该收据按治理规则作废并以4ebf9e1重跑,见上) - NOT_RUN|交付信任所需的精确 HEAD CI(
test/test-pg/svc-realcombo)——合入前由make ci-wait取得 GATE
- 影响与剩余项:
- 未解决但非阻塞:释放保留端口到
svc.sh真正 bind 之间存在 TOCTOU 窗口。失效模式是响亮失败(check_port_free报错退出),不会静默假绿;且与本仓既有 5 处同类夹具(test_svc_recover.py:187、test_svc.py:366、test_task_pr_check.py:100、test_task_triage.py:230、test_svc_realcombo.py:128)风险同级。套件级解法属独立增量,不在本任务扩围。 - 本任务不解决「其它用例也硬编码端口」这一更大面上的同类脆弱性;仅记录,不在本任务处理。
- 未解决但非阻塞:释放保留端口到
合入与清理
- Review 记录:PASS。两次独立全新 CLI 会话:①
pi(zai-coding-cn/glm-5.3-flash),base=origin/main a496ea0f,head=0bd5a4b / 4ebf9e1;②pi-glm(zai-coding-cn/glm-5.3-flash),base=2fd11effd9ccb0ae35ae5a47caccefccbbb05a8e,head=c4528653b17665885a7b8f5b5b8f612a68081cef(Backend repin 之后基线)。两次均非 host 主模型、非实施会话、未使用--continue/--resume/既有 session id,session 身份 not-observable。核对项:动态取端口写法与仓内 5 处既有夹具惯例一致且socket已在:12导入;逐条核对 8 条断言未删未弱化;diff 仅tests/test_svc.py单 hunk,:753-754夹具未动;TOCTOU 与既有惯例同级、非阻塞;无回归面。第二次 Review 给出 4 项非阻塞建议:reservation TOCTOU 窗口在实践中可忽略、用法可观察性保留、register_pg 改不改的判定一致、其他用例硬编码端口的归属明确(已记入本卡)。重放依据:host 已在4ebf9e1与c4528653b独立重跑目标用例(含占端口一腿)与全模块(/tmp/svc-flake-finish-test-20261021.json、/tmp/svc-flake-svc-tests-20261021.json);首次审阅原始输出在仓外/tmp/svc-flake-review-final.log,二次复盘/tmp/svc-flake-review-r1-20261021.json。 - 冲突记录:无冲突。合入前同步
make task-sync纳入 origin/main a496ea0f(仅并入另一任务的归档卡与 spec,无代码变更、无组件 pin 变动);同步导致被测 HEAD 变化,关键检查已在4ebf9e1重跑。 - CI 记录:原 CI 失败(run 4592/4594,均为 npm registry
ECONNRESET/EIDLETIMEOUT与一次 RealCombo SQLite fixture 启动失败)已在本任务外解决:Backend 仓Manager.ResolveHITL写库顺序竞态修复(PR #237,mergef084d10)经 Dev 仓 gitlink 重钉(PR #674,merge2fd11eff)落地,CI 抖动在2fd11eff之后回归正常(参见2fd11eff之后的多次 Dev CI 全绿记录)。本任务在2fd11eff之后基线上重跑 PR #668 的 GATE:由make ci-wait在 fold-closed head 上单次取得(见合入核验)。 - 「与本改动无关」的依据:本次 diff 仅
tests/test_svc.py;三次失败分别发生在 npm registry 网络与真实 RDM 夹具启动,均不在该文件的影响面;同一窗口main@a496ea0f的 run 4587 三作业全绿,而 run 4585/4593(其它 PR)同样失败。 - 未完成:精确 HEAD 的三作业 GATE 结果。不得以本地 SELF 替代,不得合入。
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)——任务卡尚未闭合,worktree
Agent-System-Dev-wt-fix-svc-static-deploy-test-port-flake按规则保留现场,不得回收。
当前阻塞与下一动作
- 阻塞:精确 HEAD 的必需 CI 三作业连续 3 次因基础设施故障红(2× npm registry
ECONNRESET、1× 真实 RDM 夹具启动退出)。代码侧无待办:独立 Review PASS、本地关键检查在新 HEAD 全绿。 - 下一动作:平台 run 级重跑接口已耗尽;需以新提交(仅
.task/**)取得新 SHA 后make ci-wait,或由用户决定先处理 CI 基础设施稳定性。 - 遗留发现(不在本任务范围,未修):
tests/test_svc_realcombo.py仍有硬编码端口 9471/9473/9474(seed_real/http_ok/deploy --port),与本次修掉的tests/test_svc.py:989属同类脆弱性;本任务只授权了后者。
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-21T02:37:25.839631+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "a9566a68505ac97dead15ed3b5672954f15cea1c",
"after_head": "a9566a68505ac97dead15ed3b5672954f15cea1c",
"branch": "main",
"target_branch": "main",
"target_head": "a9566a68505ac97dead15ed3b5672954f15cea1c",
"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=a9566a6850",
"[remote] origin/main=a9566a6850 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=4",
"[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] a9566a6850(完整:a9566a68505ac97dead15ed3b5672954f15cea1c)",
"[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": "a43e43203f983403f6985ffa5d4fe7de220822e00febdc8b81cf0b86389db00b",
"receipt_sha256": "1247ce47e3885b17ccae7257ba8e6fdd8760f56ef681f89967a0e313ce8142ff",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/1247ce47e3885b17ccae7257ba8e6fdd8760f56ef681f89967a0e313ce8142ff.json"
}
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-21T03:04:28.871393+00:00",
"command": "sh -c 'set -e; echo \"[1] target test on a clean host:\"; PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_svc.SvcDbRecoveryTests.test_static_fresh_deploy_registers_pidcheck_and_starts 2>&1 | tail -3; echo; echo \"[2] same test while the legacy hard-coded port is held by a foreign process:\"; bash /tmp/occupy-port.sh 18951 env PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_svc.SvcDbRecoveryTests.test_static_fresh_deploy_registers_pidcheck_and_starts 2>&1 | tail -4; echo; echo \"[3] whole module tests.test_svc:\"; PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_svc 2>&1 | tail -3; echo; echo \"[4] legacy port released again:\"; (ss -ltn | grep -q \":18951 \" && echo LEAK) || echo released'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-fix-svc-static-deploy-test-port-flake",
"before_head": "d0b217d3a486d32db91d69539c39d07ed9dbdae0",
"after_head": "d0b217d3a486d32db91d69539c39d07ed9dbdae0",
"branch": "fix/svc-static-deploy-test-port-flake",
"target_branch": "main",
"target_head": "a496ea0f0249b2b412354677ef97612ccd692d25",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"OK",
"",
"[2] same test while the legacy hard-coded port is held by a foreign process:",
"----------------------------------------------------------------------",
"Ran 1 test in 0.599s",
"",
"OK",
"",
"[3] whole module tests.test_svc:",
"Ran 23 tests in 29.185s",
"",
"OK",
"",
"[4] legacy port released again:",
"released"
],
"output_sha256": "d8f352a6d39b09c2fca2e868a40723780fa8c7cf3ea4ab79600d894d2069db9f",
"receipt_sha256": "314db6279eec9bfc2666b2533347df850ada748e6e99c481bc1633f3faf34c4d",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/314db6279eec9bfc2666b2533347df850ada748e6e99c481bc1633f3faf34c4d.json"
}
| 同步(记录前对象) | a496ea0f02 | bbb9024e97 | 2026-10-21T03:16:00Z |
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-21T03:16:10.154890+00:00",
"command": "sh -c 'set -e; echo \"[1] target test, clean host:\"; PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_svc.SvcDbRecoveryTests.test_static_fresh_deploy_registers_pidcheck_and_starts 2>&1 | tail -3; echo; echo \"[2] target test while legacy hard-coded port is held:\"; bash /tmp/occupy-port.sh 18951 env PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_svc.SvcDbRecoveryTests.test_static_fresh_deploy_registers_pidcheck_and_starts 2>&1 | tail -3; echo; echo \"[3] whole module:\"; PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_svc 2>&1 | tail -3; echo; echo \"[4] port released:\"; (ss -ltn | grep -q \":18951 \" && echo LEAK) || echo released'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-fix-svc-static-deploy-test-port-flake",
"before_head": "4ebf9e1b47edb701541f57a72020b31d9e3fb323",
"after_head": "4ebf9e1b47edb701541f57a72020b31d9e3fb323",
"branch": "fix/svc-static-deploy-test-port-flake",
"target_branch": "main",
"target_head": "a496ea0f0249b2b412354677ef97612ccd692d25",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"",
"OK",
"",
"[2] target test while legacy hard-coded port is held:",
"Ran 1 test in 0.574s",
"",
"OK",
"",
"[3] whole module:",
"Ran 23 tests in 26.871s",
"",
"OK",
"",
"[4] port released:",
"released"
],
"output_sha256": "41ab6880e27c3f44906b392bbe76d342d1019ae1a2aad0690c2739d691330669",
"receipt_sha256": "7dfe7b09cfcb370d00c0e9a504a8857530b8637d18e1ab7bf2d4e434093bdb33",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/7dfe7b09cfcb370d00c0e9a504a8857530b8637d18e1ab7bf2d4e434093bdb33.json"
}
| 同步(记录前对象) | 2fd11effd9 | c766a81277 | 2026-10-21T09:48:46Z |
闭合记录(合入前折叠)
- 本卡在 PR #668(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/668)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。