Add evidence gates: facts registry, evidence tooling, and precheck checks

Why: declarations were passing as capability; hand-transcribed outputs flowed
through cards and PR bodies as if they were execution evidence, and stale
external facts (e.g. the dead git-panel host) kept being trusted until burned.

Evidence: guidelines draft.10 (PR Development-Guidelines#4, merged af199ee)
pinned here; policy/facts.md F1-F4 each re-verified on 2026-10-05 before
registration (endpoint version, token HTTP 200 via header only, SSH ls-remote,
dead-host negative probe); scripts syntax-checked (bash -n); tool self-tests
and make test recorded in the task card via the new make evidence.

Impact: new AGENTS.md section (SELF/REPLAY/GATE, tool-written evidence,
replay-on-review, zero-trust facts, honest-empty); make evidence/facts-verify;
precheck gains [hooks]/[facts], task-sync gains stale-evidence-HEAD warning;
task-start cards now embed the evidence table; gitlink advances to draft.10.

Refs: task card .task/feature-evidence-driven-gates.md; guidelines CHANGELOG
0.1.0-draft.10.
This commit is contained in:
2026-10-05 10:47:27 +00:00
parent fb99968922
commit ba83a17c11
8 changed files with 211 additions and 8 deletions
+43 -1
View File
@@ -59,6 +59,34 @@ cmd_precheck() {
fi
done < <(git for-each-ref --format='%(refname:short) %(committerdate:unix)' "refs/remotes/origin/feature/card-close-*")
[ -n "$stale" ] && echo "[cards] 闭合分支超过 24 小时未合入:$(echo $stale)"
# [hooks] 声明≠能力:core.hooksPath 未指向 scripts/hooks 时,"钩子已启用"只是声明。
local hp; hp=$(git config core.hooksPath 2>/dev/null || true)
if [ "$hp" = "scripts/hooks" ] && [ -x scripts/hooks/pre-commit ]; then
echo "[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)"
else
echo "[hooks] WARN core.hooksPath='${hp:-未设置}'——本地钩子未生效,先 make setup;本检出提交将绕过本地闸(远端准入仍在)"
fi
# [facts] 外部事实登记表过期项(policy/facts.md;引用前先跑其验证命令,AGENTS.md 证据与验证门禁)。
if [ -f policy/facts.md ]; then
local fid lv ttl expired="" ftotal=0
while IFS='|' read -r _ fid _ _ lv ttl _; do
fid=$(echo "${fid:-}" | tr -d ' '); case "$fid" in F[0-9]*) ;; *) continue ;; esac
ftotal=$((ftotal+1))
lv=$(echo "$lv" | tr -d ' '); ttl=$(echo "$ttl" | tr -d ' ')
case "$lv" in [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) ;; *) expired="$expired ${fid}(日期格式)"; continue ;; esac
case "$ttl" in ''|*[!0-9]*) ttl=30 ;; esac
if [ $(( $(date +%s) - $(date -d "$lv" +%s) )) -gt $(( ttl*86400 )) ]; then
expired="$expired ${fid}(last=${lv},ttl=${ttl}d)"
fi
done < <(grep -E '^\| *F[0-9]+ ' policy/facts.md || true)
if [ -n "$expired" ]; then
echo "[facts] WARN 过期事实:$(echo $expired)——引用前先 make facts-verify 重验并更新登记表"
else
echo "[facts] policy/facts.md ${ftotal} 条事实均在有效期内"
fi
else
echo "[facts] WARN policy/facts.md 不存在——外部事实登记表缺失(AGENTS.md 证据与验证门禁)"
fi
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
@@ -120,10 +148,16 @@ cmd_start() {
|---|---|---|---|
| 启动 | ${rmain} | $(git -C "$wt" rev-parse HEAD) | $(date -u +%FT%TZ) |
## 证据(Evidence)
<!-- make evidence CMD="…" 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证(完成后填写)
- 结果:
- 验证:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
EOF
git -C "$wt" add .task && git -C "$wt" commit -q -m "Record the task card for ${slug}" && echo "[card] $card(已随分支提交)"
@@ -155,6 +189,14 @@ cmd_sync() {
printf '| 同步前验收 | %s | %s | %s |\n' "$base" "$head" "$(date -u +%FT%TZ)" >> "$card"
git add "$card"
git commit -q -m "Record the sync checkpoint" || true
# [evidence] 同步改变了被测对象:卡片证据表中旧 HEAD 的行自动失效,关键检查须重跑。
local eh stale_ev="" short_head
short_head=$(echo "$head" | cut -c1-10)
while IFS='|' read -r _ _ _ eh _ _ _; do
eh=$(echo "$eh" | tr -d ' `')
[ -n "$eh" ] && [ "$eh" != "$short_head" ] && stale_ev="$stale_ev $eh"
done < <(grep -E '^\| [0-9]{4}-[0-9]{2}-[0-9]{2}T[^|]*\|' "$card" 2>/dev/null || true)
[ -n "$stale_ev" ] && echo "[evidence] WARN 证据表含旧被测 HEAD:$(echo $stale_ev | tr ' ' '\n' | sort -u | tr '\n' ' ')(≠ 当前 $short_head)——同步后关键检查须重跑并以 make evidence 重新写入"
else
echo "[warn] 找不到分支 ${branch} 的任务卡,同步记录未写入" >&2
fi