Files
Agent-System-Dev/scripts/zcode/write-guard.sh
T
weichen ccddcc2b2b Add the zcode write-path guard instance with its adaptation matrix
Why: zcode lacks a rules feature (AGENTS.md is the resident layer) but
supports PreToolUse hooks that can block Edit/Write before the write lands,
upgrading A1/A3 from commit-time to write-time enforcement; the two block
shapes (integration branch, detached submodule) mirror the real incidents.
Evidence: script-level suite 8/8 (N1-N3 blocks with exit 2 and remediation
hints, P1-P5 allows incl. fail-open degradation paths); config JSON valid;
client-side live-fire interception marked pending-live in the matrix.
Impact: .zcode/config.json enables the hook runner for this workspace;
.zcode/plans/ ignored (client state); no product code change.
Refs: Development-Guidelines 0.1.0-draft.8; policy/tool-adaptation-zcode.md
2026-09-30 03:43:26 +00:00

39 lines
1.5 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# zcode PreToolUse 写路径守卫(Edit/Write/ApplyPatch)。
# 单一权威声明:本脚本是 Development-Guidelines standards/tool-adaptation.md
# 要求 A1/A3 在 zcode 客户端的机制实例;语义以库与项目入口为准,本文件不复制规则正文。
# 退出码:0 放行;2 阻断(PreToolUse 的 deny);其余非零为错误。
set -uo pipefail
input=$(cat)
file=$(printf '%s' "$input" | python3 -c '
import json, sys
try:
d = json.load(sys.stdin)
except Exception:
sys.exit(0)
ti = d.get("tool_input") if isinstance(d.get("tool_input"), dict) else {}
for src in (ti, d):
for k in ("file_path", "path", "filename"):
v = src.get(k)
if isinstance(v, str) and v:
print(v)
sys.exit(0)
' 2>/dev/null)
[ -n "$file" ] || exit 0
repo=$(git -C "$(dirname "$file")" rev-parse --show-toplevel 2>/dev/null) || exit 0
branch=$(git -C "$repo" rev-parse --abbrev-ref HEAD 2>/dev/null) || exit 0
deny() { echo "write-guard: 拒绝——${1}(目标 ${file},仓库 ${repo})" >&2; exit 2; }
case "$branch" in
main|master)
deny "集成分支 ${branch} 不得直接写入;先 make task-start NAME=feature|fix/<slug>(A1/A3)" ;;
HEAD)
deny "仓库处于 detached HEAD(常为他人现场或未建分支的子仓);先显式建任务分支(A1)" ;;
esac
echo "$branch" | grep -qE '^(feature|fix|hotfix|release)/[A-Za-z0-9._-]+$' \
|| deny "分支名 ${branch} 不符 feature|fix|hotfix|release/<slug>(A3)"
exit 0