Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/config/rules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ rules:
BDD-02: { tier: BLOCK }

# -------- PATTERNS --------
PY-PT-01: { tier: BLOCK, predicates: { module_shape: client } }
JV-PT-01: { tier: BLOCK, predicates: { module_shape: client } }
PY-PT-01: { tier: FLAG, predicates: { module_shape: client } }
JV-PT-01: { tier: FLAG, predicates: { module_shape: client } }
PY-PT-03: { tier: FLAG }
PY-PT-04: { tier: FLAG }
PY-PT-08: { tier: FLAG }
Expand Down
26 changes: 19 additions & 7 deletions .claude/scripts/check-bdd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,28 @@ while IFS= read -r mod; do
[ -z "$mod" ] && continue

# Path for THIS repo's feature file
# FP-C-01: BDD-01 must accept ANY .feature file under the module's integration
# dir, not just `<module>.feature`.
if [ "$LANGUAGE" = "python" ]; then
feature_path="$REPO_ROOT/tests/$mod/integration/$mod.feature"
feature_dir="$REPO_ROOT/tests/$mod/integration"
feature_path="$feature_dir/$mod.feature" # kept for BDD-02 sibling comparison
mod_dir="$REPO_ROOT/src/sap_cloud_sdk/$mod"
else
feature_path="$REPO_ROOT/src/test/resources/com/sap/applicationfoundation/$mod/integration/$mod.feature"
feature_dir="$REPO_ROOT/src/test/resources/com/sap/applicationfoundation/$mod/integration"
feature_path="$feature_dir/$mod.feature" # kept for BDD-02 sibling comparison
mod_dir="$REPO_ROOT/src/main/java/com/sap/cloud/sdk/$mod"
fi

# BDD-01: feature file exists (only fire if module has any source files)
if [ ! -f "$feature_path" ] && [ -d "$mod_dir" ]; then
# BDD-01: at least one .feature file exists in the module's integration dir
# (only fire if module has any source files and PR creates the module).
has_any_feature=false
if [ -d "$feature_dir" ]; then
if compgen -G "$feature_dir/*.feature" > /dev/null 2>&1; then
has_any_feature=true
fi
fi

if [ "$has_any_feature" = "false" ] && [ -d "$mod_dir" ]; then
# Detect if this PR creates any new file INSIDE the module.
# `new file mode` is on its own line before the `+++ b/<path>` header,
# so we scan block-by-block to link them.
Expand All @@ -89,9 +101,9 @@ while IFS= read -r mod; do
}
')
if [ "$is_new_module" = "true" ]; then
emit_finding "BDD-01" "BLOCK" "tests/$mod/integration/$mod.feature" 1 \
"New module '$mod' has no BDD feature file" \
"Create $feature_path with cross-language-consistent scenarios" >> "$findings"
emit_finding "BDD-01" "BLOCK" "tests/$mod/integration/" 1 \
"New module '$mod' has no .feature files under integration/" \
"Create at least one $feature_dir/*.feature with cross-language-consistent scenarios" >> "$findings"
fi
fi

Expand Down
3 changes: 2 additions & 1 deletion .claude/scripts/check-concurrency.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/json-emit.sh"
source "$SCRIPT_DIR/lib/hunk-filter.sh"
source "$SCRIPT_DIR/lib/skill-self-skip.sh"

LANGUAGE="${LANGUAGE:-python}"
Expand All @@ -27,7 +28,7 @@ echo "$diff_content" | awk '
if echo "$content" | grep -qE 'asyncio\.Queue\('; then
# Check if same file has a Lock or set() nearby
if [ -f "$REPO_ROOT/$file" ] && ! grep -qE 'asyncio\.Lock|set\(\)' "$REPO_ROOT/$file" 2>/dev/null; then
emit_finding "CC-01" "FLAG" "$file" "$line_num" \
emit_finding_if_touched "CC-01" "FLAG" "$file" "$line_num" \
"asyncio.Queue without dedup — if items must be unique, add a set() + asyncio.Lock" "" >> "$findings"
fi
fi
Expand Down
15 changes: 14 additions & 1 deletion .claude/scripts/check-constants.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/json-emit.sh"
source "$SCRIPT_DIR/lib/hunk-filter.sh"
source "$SCRIPT_DIR/lib/skill-self-skip.sh"

LANGUAGE="${LANGUAGE:-python}"
Expand All @@ -25,8 +26,20 @@ if [ "$LANGUAGE" = "python" ]; then
filtered="$filtered $f"
done <<< "$changed"
if [ -n "$filtered" ]; then
raw_con=$(mktemp); trap 'rm -f "$raw_con"' EXIT
# shellcheck disable=SC2086
python3 "$SCRIPT_DIR/lib/ast_python_checks.py" con-01 $filtered 2>/dev/null >> "$findings" || true
python3 "$SCRIPT_DIR/lib/ast_python_checks.py" con-01 $filtered 2>/dev/null > "$raw_con" || true
# FP-A-01: filter to touched lines only
while IFS= read -r finding; do
[ -z "$finding" ] && continue
f=$(echo "$finding" | python3 -c "import json,sys;o=json.loads(sys.stdin.read());print(o.get('file',''))")
ln=$(echo "$finding" | python3 -c "import json,sys;o=json.loads(sys.stdin.read());print(o.get('line',0))")
[ -z "$f" ] && continue
if is_line_touched "$f" "$ln"; then
echo "$finding" >> "$findings"
fi
done < "$raw_con"
rm -f "$raw_con"
fi
fi

Expand Down
4 changes: 4 additions & 0 deletions .claude/scripts/check-deletion-hygiene.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/json-emit.sh"
# DEL-01 uses synthetic path "src/:1" — hunk-filter is sourced for
# emit_finding_if_touched (via is_meta_finding, which treats non-file paths
# as metadata and passes them through). No filtering applied here.
source "$SCRIPT_DIR/lib/hunk-filter.sh"

LANGUAGE="${LANGUAGE:-python}"
DIFF_FILE="${DIFF_FILE:-/dev/stdin}"
Expand Down
8 changes: 5 additions & 3 deletions .claude/scripts/check-disclosure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib/json-emit.sh
source "$SCRIPT_DIR/lib/json-emit.sh"
# shellcheck source=lib/hunk-filter.sh
source "$SCRIPT_DIR/lib/hunk-filter.sh"
# shellcheck source=lib/skill-self-skip.sh
source "$SCRIPT_DIR/lib/skill-self-skip.sh"

Expand Down Expand Up @@ -39,16 +41,16 @@ echo "$diff_content" | awk '
# DIS-02: Internal Jira URL (checked first — more specific)
dis02_fired=false
if echo "$content" | grep -qEi 'jira\.tools\.sap|jira\.wdf\.sap\.corp'; then
emit_finding "DIS-02" "$(sev_public)" "$file" "$line_num" "Internal Jira URL — remove or move to internal-only docs" "" >> "$findings"
emit_finding_if_touched "DIS-02" "$(sev_public)" "$file" "$line_num" "Internal Jira URL — remove or move to internal-only docs" "" >> "$findings"
dis02_fired=true
fi
# DIS-01: SAP-internal hostnames (skip if DIS-02 already covers the same line)
if [ "$dis02_fired" = "false" ] && echo "$content" | grep -qEi '(int\.repositories\.cloud\.sap|\.tools\.sap|\.wdf\.sap\.corp|\.mo\.sap\.corp)'; then
emit_finding "DIS-01" "$(sev_public)" "$file" "$line_num" "SAP-internal hostname detected in code" "" >> "$findings"
emit_finding_if_touched "DIS-01" "$(sev_public)" "$file" "$line_num" "SAP-internal hostname detected in code" "" >> "$findings"
fi
# DIS-06: Internal artifactory index-url
if echo "$content" | grep -qEi '\-\-index-url[[:space:]]+https?://int\.repositories\.cloud\.sap'; then
emit_finding "DIS-06" "BLOCK" "$file" "$line_num" "Internal artifactory --index-url — must not appear in public/shared configs" "" >> "$findings"
emit_finding_if_touched "DIS-06" "BLOCK" "$file" "$line_num" "Internal artifactory --index-url — must not appear in public/shared configs" "" >> "$findings"
fi
done

Expand Down
19 changes: 16 additions & 3 deletions .claude/scripts/check-errors-logging.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/json-emit.sh"
source "$SCRIPT_DIR/lib/hunk-filter.sh"
source "$SCRIPT_DIR/lib/skill-self-skip.sh"

LANGUAGE="${LANGUAGE:-python}"
Expand All @@ -19,10 +20,22 @@ if [ "$LANGUAGE" = "python" ]; then
changed=$(echo "$diff_content" | grep -oE '^\+\+\+ b/src/.*\.py' | sed 's|^+++ b/||' | sort -u)
if [ -n "$changed" ]; then
# AST-based chaining / swallow — only reports FLAGs when body ends non-Raise
# FP-A-01: filter AST hits through hunk attribution
raw_el=$(mktemp); trap 'rm -f "$raw_el"' EXIT
# shellcheck disable=SC2086
python3 "$SCRIPT_DIR/lib/ast_python_checks.py" el-01 $changed 2>/dev/null >> "$findings" || true
python3 "$SCRIPT_DIR/lib/ast_python_checks.py" el-01 $changed 2>/dev/null > "$raw_el" || true
# shellcheck disable=SC2086
python3 "$SCRIPT_DIR/lib/ast_python_checks.py" el-02 $changed 2>/dev/null >> "$findings" || true
python3 "$SCRIPT_DIR/lib/ast_python_checks.py" el-02 $changed 2>/dev/null >> "$raw_el" || true
while IFS= read -r finding; do
[ -z "$finding" ] && continue
f=$(echo "$finding" | python3 -c "import json,sys;o=json.loads(sys.stdin.read());print(o.get('file',''))")
ln=$(echo "$finding" | python3 -c "import json,sys;o=json.loads(sys.stdin.read());print(o.get('line',0))")
[ -z "$f" ] && continue
if is_line_touched "$f" "$ln"; then
echo "$finding" >> "$findings"
fi
done < "$raw_el"
rm -f "$raw_el"
fi

# EL-04: secret-like variable name in raise args (grep-based, added lines only)
Expand All @@ -37,7 +50,7 @@ if [ "$LANGUAGE" = "python" ]; then
if [ "$(is_skill_file "$file")" = "true" ]; then continue; fi
# match raise ...({...token|secret|password|api_key|client_secret...})
if echo "$content" | grep -qE 'raise[[:space:]].*[fF]?"[^"]*\{[^}]*(token|secret|password|api_key|client_secret)[^}]*\}'; then
emit_finding "EL-04" "BLOCK" "$file" "$line_num" \
emit_finding_if_touched "EL-04" "BLOCK" "$file" "$line_num" \
"Exception message includes secret-like variable — leaks sensitive data" "" >> "$findings"
fi
done
Expand Down
23 changes: 16 additions & 7 deletions .claude/scripts/check-hardcode.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib/json-emit.sh
source "$SCRIPT_DIR/lib/json-emit.sh"
# shellcheck source=lib/hunk-filter.sh
source "$SCRIPT_DIR/lib/hunk-filter.sh"
# shellcheck source=lib/skill-self-skip.sh
source "$SCRIPT_DIR/lib/skill-self-skip.sh"

Expand All @@ -18,10 +20,12 @@ trap 'rm -f "$findings"' EXIT
diff_content=$(cat "$DIFF_FILE" 2>/dev/null || echo "")

# Determine ignore patterns per language
# FP-B-01: HC-01 must not fire on XML/YAML/POM files where URL-like strings
# are namespace declarations (http://maven.apache.org/POM/4.0.0 etc.).
if [ "$LANGUAGE" = "python" ]; then
ignore_files='^(tests?/|mocks?/|docs?/|.*/spec/|.*/constants\.py|.*/user-guide\.md|README\.md)'
ignore_files='^(tests?/|mocks?/|docs?/|.*/spec/|.*/constants\.py|.*/user-guide\.md|README\.md|.*\.md$|.*\.ya?ml$|.*\.xml$|.*\.properties$|.*pom\.xml$)'
else
ignore_files='^(src/test/|mocks?/|docs?/|.*Constants\.java|.*/constants/|.*/user-guide\.md|README\.md)'
ignore_files='^(src/test/|mocks?/|docs?/|.*Constants\.java|.*/constants/|.*/user-guide\.md|README\.md|.*\.md$|.*\.ya?ml$|.*\.xml$|.*\.properties$|.*pom\.xml$)'
fi

echo "$diff_content" | awk '
Expand All @@ -43,30 +47,35 @@ echo "$diff_content" | awk '
[ -z "$url" ] && continue
# allow-list: only IANA-reserved test/example TLDs and localhost
# `.example` must be the terminal label (RFC 2606) — anchor at path/port/end.
# FP-B-01: also allowlist standard XML/POM/W3C namespace URLs which appear
# as identifiers in build files, not as network endpoints.
if echo "$url" | grep -qE '^https?://(localhost|127\.0\.0\.1|example\.(com|org|net)|[^/]+\.example(/|:|$)|reserved\.)'; then
continue
fi
emit_finding "HC-01" "BLOCK" "$file" "$line_num" "Hardcoded URL '$url' in implementation — externalize to config" "" >> "$findings"
if echo "$url" | grep -qE '^https?://(maven\.apache\.org/POM/|www\.w3\.org/[0-9]+/XMLSchema|schemas\.xmlsoap\.org/)'; then
continue
fi
emit_finding_if_touched "HC-01" "BLOCK" "$file" "$line_num" "Hardcoded URL '$url' in implementation — externalize to config" "" >> "$findings"
break # only one finding per line to avoid duplicate reports
done < <(echo "$content" | grep -oE 'https?://[A-Za-z0-9][A-Za-z0-9._~:/?#@!$&*+,;=%-]*' || true)
# HC-02: Authorization Bearer
if echo "$content" | grep -qE 'Authorization[[:space:]]*:[[:space:]]*Bearer[[:space:]]+[A-Za-z0-9]'; then
emit_finding "HC-02" "BLOCK" "$file" "$line_num" "Hardcoded Authorization header value" "" >> "$findings"
emit_finding_if_touched "HC-02" "BLOCK" "$file" "$line_num" "Hardcoded Authorization header value" "" >> "$findings"
fi
# HC-04: direct os.environ / System.getenv
if [ "$LANGUAGE" = "python" ]; then
if echo "$content" | grep -qE 'os\.environ\["[A-Z]'; then
emit_finding "HC-04" "FLAG" "$file" "$line_num" "Direct os.environ access — prefer secret_resolver / config layer" "" >> "$findings"
emit_finding_if_touched "HC-04" "FLAG" "$file" "$line_num" "Direct os.environ access — prefer secret_resolver / config layer" "" >> "$findings"
fi
else
if echo "$content" | grep -qE 'System\.getenv\('; then
emit_finding "HC-04" "FLAG" "$file" "$line_num" "Direct System.getenv() — prefer SecretResolver" "" >> "$findings"
emit_finding_if_touched "HC-04" "FLAG" "$file" "$line_num" "Direct System.getenv() — prefer SecretResolver" "" >> "$findings"
fi
fi
# HC-06: hardcoded timeout numeric literal
# Use word boundary via (^|[^A-Za-z0-9_]) so 'default_timeout' or 'my_timeout' don't match
if echo "$content" | grep -qiE '(^|[^A-Za-z0-9_])(timeout|retries|max_retries)[[:space:]]*=[[:space:]]*[0-9]+'; then
emit_finding "HC-06" "FLAG" "$file" "$line_num" "Hardcoded timeout/retry number — externalize to config" "" >> "$findings"
emit_finding_if_touched "HC-06" "FLAG" "$file" "$line_num" "Hardcoded timeout/retry number — externalize to config" "" >> "$findings"
fi
done

Expand Down
9 changes: 6 additions & 3 deletions .claude/scripts/check-http-hygiene.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/json-emit.sh"
source "$SCRIPT_DIR/lib/hunk-filter.sh"
source "$SCRIPT_DIR/lib/skill-self-skip.sh"

LANGUAGE="${LANGUAGE:-python}"
Expand All @@ -24,10 +25,12 @@ echo "$diff_content" | awk '
' | while IFS=$'\t' read -r file line_num content; do
[ -z "$file" ] && continue
if [ "$(is_skill_file "$file")" = "true" ]; then continue; fi
# only for impl files (not tests/mocks)
if echo "$file" | grep -qE '^(tests?/|mocks?/)'; then continue; fi
# only for impl files (not tests/mocks/docs/examples/markdown)
# FP-B-02: HTTP-01 must not fire on markdown code fences.
if echo "$file" | grep -qE '^(tests?/|mocks?/|docs?/|examples?/)'; then continue; fi
if echo "$file" | grep -qiE '\.(md|rst|txt)$'; then continue; fi
if echo "$content" | grep -qE '(requests|httpx)\.(Session|AsyncClient)\(\)'; then
emit_finding "HTTP-01" "FLAG" "$file" "$line_num" \
emit_finding_if_touched "HTTP-01" "FLAG" "$file" "$line_num" \
"HTTP session created per invocation — prefer single instance in __init__" "" >> "$findings"
fi
done
Expand Down
61 changes: 47 additions & 14 deletions .claude/scripts/check-patterns.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/json-emit.sh"
source "$SCRIPT_DIR/lib/predicates.sh"
source "$SCRIPT_DIR/lib/hunk-filter.sh"
source "$SCRIPT_DIR/lib/baseline.sh"
source "$SCRIPT_DIR/lib/peer-consistency.sh"

LANGUAGE="${LANGUAGE:-python}"
REPO_ROOT="${REPO_ROOT:-.}"
Expand Down Expand Up @@ -33,20 +36,31 @@ while IFS= read -r mod; do

[ -d "$mod_dir" ] || continue

# PY-PT-01 / JV-PT-01: factory exists — only fire on client modules
# PY-PT-01 / JV-PT-01: peer-consistency check (FP-G-01).
# Previously: BLOCK if client module missing create_client()/ClientFactory.
# Empirically wrong — only `destination` follows that shape. Now: FLAG only
# when the module diverges from an element that ≥80% of peers adopt.
# Tier: FLAG (never BLOCK).
shape=$(module_shape "$mod_dir")
if [ "$shape" = "client" ]; then
if [ "$LANGUAGE" = "python" ]; then
if ! grep -rqE '^def create_[a-z_]*client\(' "$mod_dir" 2>/dev/null; then
emit_finding "PY-PT-01" "BLOCK" "src/sap_cloud_sdk/$mod/" 1 \
"Client module '$mod' missing create_client() factory function" "" >> "$findings"
for element in factory client config user-guide.md exceptions py.typed; do
# py.typed only applies to Python
if [ "$element" = "py.typed" ] && [ "$LANGUAGE" != "python" ]; then continue; fi
# exceptions is checked separately below with AST for accuracy
if [ "$element" = "exceptions" ]; then continue; fi
if should_flag_peer_divergence "$mod_dir" "$element" "$LANGUAGE" "0.80"; then
if [ "$LANGUAGE" = "python" ]; then
rule_id="PY-PT-01"
rel="src/sap_cloud_sdk/$mod/"
else
rule_id="JV-PT-01"
rel="src/main/java/com/sap/cloud/sdk/$mod/"
fi
emit_finding "$rule_id" "FLAG" "$rel" 1 \
"Module '$mod' diverges from peer convention: missing '$element' (≥80% of peer modules have it)" \
"Consider adding $element for consistency with sibling modules" >> "$findings"
fi
else
if ! grep -rqE 'class [A-Z][A-Za-z]*ClientFactory' "$mod_dir" 2>/dev/null; then
emit_finding "JV-PT-01" "BLOCK" "src/main/java/com/sap/cloud/sdk/$mod/" 1 \
"Client module '$mod' missing ClientFactory class" "" >> "$findings"
fi
fi
done
fi

# PY-PT-03: py.typed marker
Expand All @@ -58,10 +72,12 @@ while IFS= read -r mod; do
fi

# PY-PT-04 / JV-PT-05: module-specific exceptions
# FP-C-02: pass if module has ANY class subclassing Exception (or *Error/*Exception),
# regardless of whether it lives in exceptions.py or __init__.py or elsewhere.
if [ "$LANGUAGE" = "python" ]; then
if [ ! -f "$mod_dir/exceptions.py" ]; then
if ! python3 "$SCRIPT_DIR/lib/ast_python_checks.py" pt-04 "$mod_dir" 2>/dev/null; then
emit_finding "PY-PT-04" "FLAG" "src/sap_cloud_sdk/$mod/exceptions.py" 1 \
"Module lacks exceptions.py — module-specific exception hierarchy recommended" "" >> "$findings"
"Module lacks Exception subclasses — define a module-specific exception hierarchy (in exceptions.py or __init__.py)" "" >> "$findings"
fi
else
if [ ! -d "$mod_dir/exceptions" ]; then
Expand All @@ -73,11 +89,28 @@ while IFS= read -r mod; do
done <<< "$modules"

# PY-PT-08 via AST on changed Python files
# FP-A-01: filter by ADDED_LINES_FILE (only fire on functions declared on lines the PR touched)
# FP-E-01: consult line-level baseline for pre-existing PT-08 debt
if [ "$LANGUAGE" = "python" ]; then
changed_py=$(echo "$diff_content" | grep -oE '^\+\+\+ b/src/sap_cloud_sdk/.*\.py' | sed 's|^+++ b/||' | grep -v '__pycache__' | sort -u)
if [ -n "$changed_py" ]; then
raw_pt08=$(mktemp); trap 'rm -f "$raw_pt08"' EXIT
# shellcheck disable=SC2086
python3 "$SCRIPT_DIR/lib/ast_python_checks.py" pt-08 $changed_py 2>/dev/null >> "$findings" || true
python3 "$SCRIPT_DIR/lib/ast_python_checks.py" pt-08 $changed_py 2>/dev/null > "$raw_pt08" || true
# Filter: keep only findings on lines touched by this PR AND not in baseline
while IFS= read -r finding; do
[ -z "$finding" ] && continue
f=$(echo "$finding" | python3 -c "import json,sys;o=json.loads(sys.stdin.read());print(o.get('file',''))")
ln=$(echo "$finding" | python3 -c "import json,sys;o=json.loads(sys.stdin.read());print(o.get('line',0))")
[ -z "$f" ] && continue
# Baseline check first (bypasses hunk filter — always suppressed)
if is_in_line_baseline "PY-PT-08" "$f" "$ln"; then continue; fi
# Hunk filter
if is_line_touched "$f" "$ln"; then
echo "$finding" >> "$findings"
fi
done < "$raw_pt08"
rm -f "$raw_pt08"
fi
fi

Expand Down
2 changes: 2 additions & 0 deletions .claude/scripts/check-secrets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib/json-emit.sh
source "$SCRIPT_DIR/lib/json-emit.sh"
# shellcheck source=lib/hunk-filter.sh
source "$SCRIPT_DIR/lib/hunk-filter.sh"
# shellcheck source=lib/skill-self-skip.sh
source "$SCRIPT_DIR/lib/skill-self-skip.sh"

Expand Down
Loading
Loading