将项目级的 Ratchet/约定检测方法论融入 req-test-gate 技能, 通过 /req 流程三个节点自动触发(dev 环境检测、cr 约定建议、test Gate 0B), 无需手动记忆执行。 新增文档:harness-engineering.md、ratchet-pattern.md、convention-flow.md、 project-bootstrap.md 及 4 个模板(ratchet/convention 脚本、GATES.md、pre-commit)。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.7 KiB
4.7 KiB
Convention Detection Script Template
泛化的约定检测脚本模板,基于 new-ai-proj check-modal-safety.sh 提取。用于检测代码中违反编码约定的模式。
使用方法
- 复制下方脚本到
scripts/check-{NAME}.sh - 替换所有
{PLACEHOLDER}为项目特定值 - 运行
chmod +x scripts/check-{NAME}.sh - 验证:
./scripts/check-{NAME}.sh输出 PASSED
脚本模板
#!/usr/bin/env bash
#
# {CONVENTION_NAME} Check — detects {WHAT_IT_DETECTS} in {TARGET_SCOPE}.
#
# {PROBLEM_DESCRIPTION}
#
# Usage:
# ./scripts/check-{NAME}.sh # Check and report
# ./scripts/check-{NAME}.sh --ci # Exit code 1 on violations
#
set -euo pipefail
TARGET_DIR="$(cd "$(dirname "$0")/../{TARGET_DIRECTORY}" && pwd)"
CI_MODE=false
[[ "${1:-}" == "--ci" ]] && CI_MODE=true
violations=0
# ── detection logic ─────────────────────────────────────────────────
# Strategy A: Simple grep pattern (file-level)
# Find files matching a bad pattern, optionally excluding false positives.
#
# while IFS= read -r file; do
# rel_path="${file#"$TARGET_DIR"/}"
# echo "WARNING: $rel_path — {VIOLATION_MESSAGE}"
# violations=$((violations + 1))
# done < <(grep -rl '{BAD_PATTERN}' "$TARGET_DIR" --include='{FILE_GLOB}' 2>/dev/null \
# | while read f; do grep -L '{FALSE_POSITIVE_PATTERN}' "$f" 2>/dev/null; done)
# Strategy B: Line-level with context (multi-condition)
# Find a primary pattern, check nearby lines for secondary pattern.
#
# while IFS= read -r file; do
# while IFS= read -r line_num; do
# # Check context around the match
# has_mitigation=$(sed -n "${line_num},$((line_num + {CONTEXT_LINES}))p" "$file" \
# | grep -c '{MITIGATION_PATTERN}' || true)
# if [[ "$has_mitigation" -eq 0 ]]; then
# # Additional condition: check if problematic follow-up exists
# after_end=$((line_num + {LOOKAHEAD_LINES}))
# has_problem=$(sed -n "$((line_num + 1)),${after_end}p" "$file" \
# | grep -cE '{FOLLOW_UP_BAD_PATTERN}' || true)
# if [[ "$has_problem" -gt 0 ]]; then
# rel_path="${file#"$TARGET_DIR"/}"
# echo "WARNING: $rel_path:$line_num — {VIOLATION_MESSAGE}"
# violations=$((violations + 1))
# fi
# fi
# done < <(grep -n '{PRIMARY_PATTERN}' "$file" | cut -d: -f1)
# done < <(grep -rl '{PRIMARY_PATTERN}' "$TARGET_DIR" --include='{FILE_GLOB}' 2>/dev/null)
# ── results ─────────────────────────────────────────────────────────
if [[ "$violations" -gt 0 ]]; then
echo ""
echo "Found $violations {CONVENTION_NAME} violation(s)."
echo "Fix: {FIX_GUIDANCE}"
echo "Docs: see CLAUDE.md '{CLAUDE_MD_SECTION}'"
$CI_MODE && exit 1
else
echo "{CONVENTION_NAME} check PASSED."
fi
Placeholder 说明
| Placeholder | 含义 | 示例 |
|---|---|---|
{NAME} |
脚本短名 | modal-safety, sql-injection |
{CONVENTION_NAME} |
约定显示名 | Modal safety, SQL injection prevention |
{WHAT_IT_DETECTS} |
检测内容 | potential modal overlap patterns |
{TARGET_SCOPE} |
目标范围描述 | frontend code, Go handlers |
{TARGET_DIRECTORY} |
扫描目录 | frontend/src, backend |
{PROBLEM_DESCRIPTION} |
问题描述 | Ant Design Modal.success is non-blocking... |
{FILE_GLOB} |
文件匹配 | *.tsx, *.go |
{PRIMARY_PATTERN} |
主匹配模式 | Modal\.\(success|info\) |
{MITIGATION_PATTERN} |
缓解模式(有则排除) | onOk |
{FOLLOW_UP_BAD_PATTERN} |
后续违规模式 | set\w*Open\(true\) |
{CONTEXT_LINES} |
上下文行数 | 25 |
{LOOKAHEAD_LINES} |
前瞻行数 | 20 |
{BAD_PATTERN} |
Strategy A 主匹配模式 | console\.log |
{FALSE_POSITIVE_PATTERN} |
Strategy A 排除模式(匹配到则非违规) | // eslint-disable |
{VIOLATION_MESSAGE} |
违规消息 | Modal without onOk followed by setState |
{FIX_GUIDANCE} |
修复指导 | add onOk callback to Modal |
{CLAUDE_MD_SECTION} |
CLAUDE.md 章节名 | Frontend: Modal 安全规则 |
两种检测策略
Strategy A: 文件级检测
适用于:整个文件不应出现某模式(或出现即违规)。
例子:
console.log在生产代码中TODO/FIXME计数- 缺少 license header
Strategy B: 行级 + 上下文检测
适用于:模式本身不违规,需要检查周围上下文。
例子:
Modal.success()不违规,但后面紧跟setState才违规db.Exec()不违规,但参数用字符串拼接才违规fmt.Println()不违规,但在 handler 中输出敏感数据才违规