Compare pin trees offline and archive finished task cards
ci / test (pull_request) Failing after 1m0s

Why: Merge commits share a tree with the pinned feature commit, the import ratchet downloaded modules during CI, and task sync wrote the checkpoint onto the wrong card.
Evidence: check-pins accepts 6c0f1e8 (same tree as Backend squad 8e987bf) and rejects empty-tree 8db069d; both objects stayed local. An empty GOMODCACHE run of lint-boundaries matches the cached go list, 14 pairs. bash -n scripts/task.sh.
Impact: make pin no longer checks out Backend nested core or agent-command, and a failing pin check does not fail the target. task sync writes the branch card or warns. precheck reports completed-but-unarchived cards and card-close branches older than 24 hours.
Refs: feature/agent-stack-r0-r1
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-03 10:19:06 +00:00
co-authored by Cursor
parent 0f8660bf40
commit 88d5787f29
6 changed files with 173 additions and 11 deletions
+48 -5
View File
@@ -42,6 +42,23 @@ cmd_precheck() {
fi
done
[ -n "$open_cards" ] && echo "[cards] 已合入未闭合任务卡:$(echo $open_cards)——make task-close 回填归档(主检出运行)"
local done_open="" stale="" now ts ref
for pc in .task/*.md; do
[ -f "$pc" ] || continue
case "$(card_status "$pc")" in
已完成*) done_open="${done_open} ${pc##*/}" ;;
esac
done
[ -n "$done_open" ] && echo "[cards] 已完成但未归档:$(echo $done_open)"
now=$(date +%s)
while read -r ref ts; do
[ -n "$ref" ] || continue
git merge-base --is-ancestor "$ref" "origin/${TARGET_BRANCH}" 2>/dev/null && continue
if [ $((now - ts)) -gt 86400 ]; then
stale="${stale} ${ref#origin/}"
fi
done < <(git for-each-ref --format='%(refname:short) %(committerdate:unix)' "refs/remotes/origin/feature/card-close-*")
[ -n "$stale" ] && echo "[cards] 闭合分支超过 24 小时未合入:$(echo $stale)"
echo "[required-reading] core/baseline.md, workflows/delivery.md §1$([ "$dirty" -gt 0 ] && echo ", standards/collaboration.md(树脏=他人或未收尾现场,不得写入)")"
echo "[R0] $(echo "$rmain" | cut -c1-10)(完整:$rmain)"
if [ "$dirty" -gt 0 ] || [ "${sub_drift:-0}" -gt 0 ]; then
@@ -119,13 +136,27 @@ cmd_sync() {
[ "$(git status --porcelain | grep -v '^.. \.zcode/' | wc -l)" -eq 0 ] || die "dirty tree — 先显式提交;不隐式 stash(collaboration.md:11)"
git merge --no-edit "origin/${TARGET_BRANCH}"
git merge-base --is-ancestor "origin/${TARGET_BRANCH}" HEAD || die "sync incomplete"
local base head card
local base head card branch slug pc
base=$(git rev-parse "origin/${TARGET_BRANCH}"); head=$(git rev-parse HEAD)
card=$(ls .task/*.md 2>/dev/null | head -1 || true)
if [ -n "$card" ]; then
branch=$(git rev-parse --abbrev-ref HEAD)
slug=$(echo "$branch" | tr '/' '-')
card=".task/${slug}.md"
if [ ! -f "$card" ]; then
card=""
for pc in .task/*.md; do
[ -f "$pc" ] || continue
if [ "$(card_of_branch "$pc")" = "$branch" ]; then
card=$pc
break
fi
done
fi
if [ -n "$card" ] && [ -f "$card" ]; then
printf '| 同步前验收 | %s | %s | %s |\n' "$base" "$head" "$(date -u +%FT%TZ)" >> "$card"
git add "$card"
git commit -q -m "Record the sync checkpoint" || true
else
echo "[warn] 找不到分支 ${branch} 的任务卡,同步记录未写入" >&2
fi
echo "[synced] sync_base=$(echo "$base" | cut -c1-10) tested_head=$(echo "$head" | cut -c1-10) checked_at=$(date -u +%FT%TZ)"
echo "[next] 跑正式验收(make test 等),证据写入任务卡"
@@ -189,13 +220,18 @@ cmd_close() {
for c in .task/*.md; do
[ -f "$c" ] || continue
b=$(card_of_branch "$c"); [ -n "$b" ] || continue
st=$(card_status "$c"); case "$st" in 已完成*) continue ;; esac
st=$(card_status "$c")
done_unarchived=0
case "$st" in 已完成*) done_unarchived=1 ;; esac
if card_pending "${c##*/}"; then
echo "[close] ${c##*/} 已有待合入的闭合分支,跳过(等其 PR 合入)"
continue
fi
m=$(card_merge "$b") || m=""
[ -n "$m" ] || continue
if [ -z "$m" ]; then
[ "$done_unarchived" = 1 ] || continue
m="ARCHIVE"
fi
cards="$cards
$c|$b|$m"
done
@@ -213,6 +249,13 @@ $c|$b|$m"
local n=0 sha subject pr closed_list=""
while IFS='|' read -r c b m; do
[ -n "$c" ] || continue
if [ "$m" = "ARCHIVE" ]; then
mkdir -p .task/archive
git mv "$c" ".task/archive/${c##*/}"
closed_list="$closed_list ${c##*/}(already-complete)"
n=$((n+1))
continue
fi
sha="${m%%|*}"; subject="${m#*|}"
pr=$(printf '%s' "$subject" | sed -n 's/.*(#\([0-9]\+\)) from.*/\1/p')
[ -n "$pr" ] || pr=unknown