agent-exec transport 7bc7519fb1dc6e9f12e152359a795c89/731d7f5ba3a5

This commit is contained in:
agent-exec-transport
2026-10-18 15:46:44 +00:00
parent bc304111a4
commit 471948c59c
+44 -7
View File
@@ -18,10 +18,30 @@ fetch_target() {
git rev-parse --verify "refs/remotes/origin/${TARGET_BRANCH}^{commit}" >/dev/null \
|| { echo "[verdict] REMOTE_UNVERIFIED — target commit missing" >&2; return 6; }
}
target_history() { # $1=可选基线(无缓存目标时代替比较,如任务 R0)→ 输出 ok(远端不可查询/通告提交为基线后代)、rewound(回退或分叉)或 uncomparable(远端可查询但目标 ref 缺失、无基线、通告提交本地缺失或无法比较)
origin_transport_unavailable() { # $1=失败的远端命令 stderr → 仅明确的传输失败(DNS/连接超时/拒绝/重置/无路由,或本地缺失仓库路径)返回 0;认证/授权/权限与未知错误返回 1
local err=$1 url path
if printf '%s\n' "$err" | grep -qiE 'authentication failed|permission denied|unauthori[sz]ed|forbidden|HTTP[^0-9]*40[13]|\b40[13]\b|could not read (username|password)|terminal prompts disabled|invalid credentials|access denied|host key verification failed'; then
return 1
fi
if printf '%s\n' "$err" | grep -qiE 'could not resolve (host|hostname|proxy)|name or service not known|temporary failure in name resolution|nodename nor servname|connection timed out|operation timed out|timed out after|connection refused|connection reset|no route to host|network is unreachable|couldn.t connect to server'; then
return 0
fi
printf '%s\n' "$err" | grep -qF 'does not appear to be a git repository' || return 1
url=$(git remote get-url origin 2>/dev/null) || return 1
case "$url" in
file://*) path=${url#file://} ;;
/*|./*|../*) path=$url ;;
*) return 1 ;;
esac
[ ! -e "$path" ]
}
target_history() { # $1=可选基线(无缓存目标时代替比较,如任务 R0)→ 输出 ok(远端传输不可达/通告提交为基线后代)、rewound(回退或分叉)或 uncomparable(认证/授权/未知错误、目标 ref 缺失、无基线、通告提交本地缺失或无法比较)
local cached listing advertised rc=0
cached=$(git rev-parse -q --verify "refs/remotes/origin/${TARGET_BRANCH}^{commit}" 2>/dev/null) || cached=${1:-}
listing=$(git ls-remote origin "refs/heads/${TARGET_BRANCH}" 2>/dev/null) || { echo ok; return 0; }
if ! listing=$(git ls-remote origin "refs/heads/${TARGET_BRANCH}" 2>&1); then
if origin_transport_unavailable "$listing"; then echo ok; else echo uncomparable; fi
return 0
fi
advertised=$(printf '%s\n' "$listing" \
| awk -v ref="refs/heads/${TARGET_BRANCH}" '$2 == ref && !seen { print $1; seen = 1 }')
[ -n "$advertised" ] && [ -n "$cached" ] || { echo uncomparable; return 0; }
@@ -70,7 +90,10 @@ cmd_precheck() {
echo "[tree] $([ "$dirty" -eq 0 ] && echo clean || echo "dirty(${dirty})") submodules_drift=${sub_drift} uninit=${sub_uninit}"
local wt merged
wt=$(git worktree list | tail -n +2 | wc -l)
merged=$(git branch --merged "origin/${TARGET_BRANCH}" 2>/dev/null | { grep -vE 'main|master|\*' || true; } | tr -d ' +')
merged=""
if git rev-parse -q --verify "refs/remotes/origin/${TARGET_BRANCH}^{commit}" >/dev/null 2>&1; then
merged=$(git branch --merged "origin/${TARGET_BRANCH}" 2>/dev/null | { grep -vE 'main|master|\*' || true; } | tr -d ' +')
fi
[ "${sub_uninit:-0}" -gt 0 ] && echo "[warn] ${sub_uninit} 个子模块未初始化——构建/测试前需物化(不阻断写入)"
echo "[worktrees] linked=${wt}"
[ -n "$merged" ] && echo "[recycle] merged un-recycled branches: $(echo $merged)"
@@ -518,8 +541,18 @@ cmd_resume() {
fi
fi
if [ "$immediate" != "${TARGET_BRANCH}" ]; then
observed=$(resolve_parent_ref "$immediate") || die "immediate target ${immediate} unavailable; receipt not imported"
recorded=$(card_field "$card" parent_head_sha)
if [ "$mode" = local ]; then
# local 续作只以登记的父头为比较基准:缺失、非完整 SHA 或本地无此提交时不得回落到本地父分支。
local sha_len=40
[ "$(git rev-parse --show-object-format 2>/dev/null)" = sha256 ] && sha_len=64
if ! [[ "$recorded" =~ ^[0-9a-f]+$ ]] || [ "${#recorded}" -ne "$sha_len" ] \
|| ! git cat-file -e "${recorded}^{commit}" 2>/dev/null; then
echo "[verdict] REMOTE_UNVERIFIED — registered parent_head_sha for ${immediate} is missing, malformed or not available locally; preserve local work, receipt not imported" >&2
return 6
fi
fi
observed=$(resolve_parent_ref "$immediate") || die "immediate target ${immediate} unavailable; receipt not imported"
if [ -n "$recorded" ] && ! git merge-base --is-ancestor "$recorded" "$observed"; then
die "immediate target ${immediate} no longer contains recorded parent head ${recorded}; receipt not imported"
fi
@@ -676,8 +709,8 @@ resolve_parent_ref() { # $1=父 initiative 分支 → 打印用于同步/核验
printf '%s\n' "$remote_head"
return 0
fi
local remote="" local_ref="" rc=0
git ls-remote --exit-code --heads origin "refs/heads/$1" >/dev/null 2>&1 || rc=$?
local remote="" local_ref="" rc=0 ls_err
ls_err=$(git ls-remote --exit-code --heads origin "refs/heads/$1" 2>&1 >/dev/null) || rc=$?
if [ "$rc" -eq 0 ]; then
if ! git fetch -q origin "refs/heads/$1:refs/remotes/origin/$1"; then
echo "[verdict] REMOTE_UNVERIFIED — cannot refresh origin/$1; preserve local work and retry" >&2
@@ -688,8 +721,12 @@ resolve_parent_ref() { # $1=父 initiative 分支 → 打印用于同步/核验
# 远端可达而登记的父分支缺失:权威侧已不认该父分支,本地同名分支不得替代。
echo "[verdict] REMOTE_UNVERIFIED — origin is reachable but $1 is missing; preserve local work and reconcile the parent initiative" >&2
return 6
elif ! origin_transport_unavailable "$ls_err"; then
# 认证/授权/权限或未知错误不等于远端不可达:权威侧状态未知,不得以本地父分支替代。
echo "[verdict] REMOTE_UNVERIFIED — cannot verify origin/$1 (non-transport remote error); preserve local work and retry" >&2
return 6
else
# 远端不可查询时只把已登记的本地父分支作为局部续作参考;不声称其为最新或可交付,调用方仍核验 parent_head_sha。
# 远端传输不可达时只把已登记的本地父分支作为局部续作参考;不声称其为最新或可交付,调用方仍核验 parent_head_sha。
local_ref=$(git rev-parse -q --verify "refs/heads/$1^{commit}" 2>/dev/null || true)
if [ -z "$local_ref" ]; then
echo "[verdict] REMOTE_UNVERIFIED — cannot query origin/$1 and no local $1 exists; preserve local work and retry" >&2