From 217bab42275c6b1148492c44113799d5e7de4245 Mon Sep 17 00:00:00 2001 From: weichen Date: Wed, 30 Sep 2026 16:41:35 +0000 Subject: [PATCH 1/3] Record the task card for fix-close-pr-retry --- .task/fix-close-pr-retry.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .task/fix-close-pr-retry.md diff --git a/.task/fix-close-pr-retry.md b/.task/fix-close-pr-retry.md new file mode 100644 index 00000000..5f29671b --- /dev/null +++ b/.task/fix-close-pr-retry.md @@ -0,0 +1,25 @@ +# fix/close-pr-retry 任务卡 + +任务主记录:;状态:进行中;owner:weichen + +## 基线与授权 + +- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 0b0540e2d251ed6bee77e63fb1ed174dda3ddd41 +- 工作区:/home/weichen/projects/Agent-System-Dev-wt-fix-close-pr-retry(worktree);分支:fix/close-pr-retry +- 授权与交付终点:<本次允许的动作与终点;未授权事项写明> + +## 目标与非目标 + +<预期结果、受影响入口/模块/契约;明确不做什么。> + +## 同步记录 + +| 节点 | sync_base_sha | tested_head_sha | checked_at | +|---|---|---|---| +| 启动 | 0b0540e2d251ed6bee77e63fb1ed174dda3ddd41 | 0b0540e2d251ed6bee77e63fb1ed174dda3ddd41 | 2026-09-30T16:41:35Z | + +## 结果与验证(完成后填写) + +- 结果: +- 验证: +- 影响与剩余项: From 888aa9471c0a6f6917eef1d4801e87b5c411cf6a Mon Sep 17 00:00:00 2001 From: weichen Date: Wed, 30 Sep 2026 16:47:53 +0000 Subject: [PATCH 2/3] Retry card-close PR creation instead of failing silently Why: cmd_close posted the PR with a single curl wrapped in 2>/dev/null || true, so any transient TLS/timeout on the git-home HTTPS surface left the card-close branch pushed with no PR and no diagnostics; this hit three times on 2026-09-30 and each needed a manual API call to recover. Evidence: bash -n clean; stub-server harness running the block verbatim (sed-extracted from this file, executed inside the worktree branch context): ok mode recovers the PR URL on first POST; exists mode (POST always 500) retries 4x with visible stderr then recovers the pre-existing open PR via GET ?state=open matching head ref; fail mode against the retired git-panel host shows four visible retry notices and falls through to the existing [next] hint. Impact: scripts/task.sh cmd_close only; precheck/start/sync/finish untouched; card-close merge authority unchanged (owner merges). post-merge hook and task-finish auto-close inherit the fix through the same function. Refs: task card fix-close-pr-retry --- .task/fix-close-pr-retry.md | 11 ++++++----- scripts/task.sh | 25 ++++++++++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/.task/fix-close-pr-retry.md b/.task/fix-close-pr-retry.md index 5f29671b..ef115512 100644 --- a/.task/fix-close-pr-retry.md +++ b/.task/fix-close-pr-retry.md @@ -6,11 +6,12 @@ - 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 0b0540e2d251ed6bee77e63fb1ed174dda3ddd41 - 工作区:/home/weichen/projects/Agent-System-Dev-wt-fix-close-pr-retry(worktree);分支:fix/close-pr-retry -- 授权与交付终点:<本次允许的动作与终点;未授权事项写明> +- 授权与交付终点:用户 2026-09-30 授权修复 task.sh close 建 PR 静默失败问题(此前观察项)。终点:PR 合入 main。未授权:改 task.sh 其它命令、改 post-merge 钩子、改兄弟仓脚本。 ## 目标与非目标 -<预期结果、受影响入口/模块/契约;明确不做什么。> +- 目标:`cmd_close` 的 PR 创建从单发 curl(`2>/dev/null || true` 静默吞错)改为:退避重试 4 次(间隔 3/6/9s)、每次失败信息可见(stderr)、终局失败时按 head 分支 GET open PR 兜底查回(覆盖 post-merge 钩子与手动 close 并发导致 PR 已存在的场景)、全部落空时保留既有 `[next]` 人工提示。 +- 非目标:不改 precheck/start/sync/finish 的行为;不改卡片闭合的合入权归属(仍所有者);不给 close 加自动合入。 ## 同步记录 @@ -20,6 +21,6 @@ ## 结果与验证(完成后填写) -- 结果: -- 验证: -- 影响与剩余项: +- 结果:cmd_close PR 创建重试化:4 次退避重试 + stderr 可见 + 终局按 head 查回已存在 PR + 既有 [next] 提示兜底。post-merge 钩子与 task-finish 自动闭合同路径受益(同一函数)。 +- 验证:`bash -n` 通过;行为验证用桩服务器三模式(代码块由 sed 从真实文件逐字提取、在 worktree 分支上下文运行)——①ok:POST 201 → 首发即回收 `http://stub/pr/1`;②exists:POST 恒 500 模拟"PR 已存在"竞态 → 4 次重试后 GET `?state=open` 按 head 查回 `http://stub/pr/9`;③fail:真实 git-panel(TLS 失效主机)→ 4 次重试均可见 `建 PR 第 N 次未成功` → pr_url 空 → 走 [next] 人工提示分支。三轮合计行为与设计一致。 +- 影响与剩余项:本次未产生真实卡片可作端到端样本(无已合入未闭合卡),闭环等下次真实 card-close 时由钩子自然验证。剩余项:无。 diff --git a/scripts/task.sh b/scripts/task.sh index 0c7c85f6..02cd67c6 100755 --- a/scripts/task.sh +++ b/scripts/task.sh @@ -231,11 +231,26 @@ EOF local headbr pr_url="" headbr=$(git rev-parse --abbrev-ref HEAD) if [ -n "${GITEA_TOKEN:-}" ]; then - local resp - resp=$(curl -sS -X POST -H "Authorization: token ${GITEA_TOKEN}" -H 'Content-Type: application/json' \ - "${web_base}/api/v1/repos/${owner}/${repo}/pulls" \ - -d "{\"head\":\"${headbr}\",\"base\":\"${TARGET_BRANCH}\",\"title\":\"Close merged task cards (${headbr})\",\"body\":\"Auto-generated by task.sh close; see commit message for evidence.\"}" 2>/dev/null || true) - pr_url=$(printf '%s' "$resp" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("html_url",""))' 2>/dev/null || true) + # HTTPS 面偶发 broken pipe / 超时(AGENTS.md 访问事实节),单发 curl 会让 PR 静默 + # 缺失(闭合分支推了、PR 没建,2026-09-30 三次踩中):退避重试 + 失败可见 + 终局 + # 按 head 查回可能已存在的 PR(post-merge 钩子与手动 close 并发时 PR 会重复请求)。 + local resp attempt api="${web_base}/api/v1/repos/${owner}/${repo}/pulls" + for attempt in 1 2 3 4; do + resp=$(curl -sS -m 25 -X POST -H "Authorization: token ${GITEA_TOKEN}" -H 'Content-Type: application/json' \ + "$api" \ + -d "{\"head\":\"${headbr}\",\"base\":\"${TARGET_BRANCH}\",\"title\":\"Close merged task cards (${headbr})\",\"body\":\"Auto-generated by task.sh close; see commit message for evidence.\"}" 2>&1) || resp="" + pr_url=$(printf '%s' "$resp" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d.get("html_url","") if isinstance(d,dict) else "")' 2>/dev/null || true) + [ -n "$pr_url" ] && break + echo "[close] 建 PR 第 ${attempt} 次未成功${resp:+($(printf '%s' "$resp" | head -c 120))},退避重试" >&2 + [ "$attempt" = 4 ] || sleep $((attempt * 3)) + done + if [ -z "$pr_url" ]; then + resp=$(curl -sS -m 25 -H "Authorization: token ${GITEA_TOKEN}" "$api?state=open" 2>/dev/null || true) + pr_url=$(printf '%s' "$resp" | python3 -c 'import json,sys +for p in json.load(sys.stdin): + if p["head"]["ref"] == sys.argv[1]: + print(p["html_url"]); break' "$headbr" 2>/dev/null || true) + fi fi if [ -n "$newbranch" ]; then git checkout -q "${TARGET_BRANCH}"; fi if [ -n "$pr_url" ]; then From 4601e5b40795080be858d909b0de429c1e78cd15 Mon Sep 17 00:00:00 2001 From: weichen Date: Wed, 30 Sep 2026 16:47:54 +0000 Subject: [PATCH 3/3] Record the sync checkpoint --- .task/feature-duplication-lesson-records.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.task/feature-duplication-lesson-records.md b/.task/feature-duplication-lesson-records.md index 43cf820c..837c1432 100644 --- a/.task/feature-duplication-lesson-records.md +++ b/.task/feature-duplication-lesson-records.md @@ -48,3 +48,4 @@ | 同步前验收 | 03dc518eec70eccdc88a1c4f0e525e29bbd2a556 | a552939497cf7f5d8e0b2a9b19a2e9d110000bbd | 2026-09-30T16:03:44Z | | 同步前验收 | ab3cae07b5854ee71c9dd36b226cabd0f778d48d | c5ed9444a6f6b3ae9be9336c360a1d09204d9491 | 2026-09-30T16:06:01Z | | 同步前验收 | a612361b98879f4679cab503035e2111c593bf9b | 290b9bbd26077ae4320783d3b24b6cef0c2e6e05 | 2026-09-30T16:38:22Z | +| 同步前验收 | 0b0540e2d251ed6bee77e63fb1ed174dda3ddd41 | 888aa9471c0a6f6917eef1d4801e87b5c411cf6a | 2026-09-30T16:47:54Z |