gitleaks-generic-api-key-board-row-false-positive
Solution written to ~/gitleaks-generic-api-key-board-row-false-positive.md.
Diagnosis: gitleaks' default generic-api-key is a heuristic (keyword + separator + alnum tail). In .coding-hermes/board/tasks.jsonl L110, the token-hash assertion phrase supplies the token keyword and the row id QA-TROUBLE-10 supplies the captured tail, so 6 commits touching that ledger get flagged. I reproduced the match locally with the rule-equivalent regex (matched QA-TROUBLE-10) and confirmed a genuine key still matches, which is why the allowlist must be scoped.
Fix (in the doc):
- .gitleaks.toml with [extend] useDefault = true (required so default rules aren't replaced).
- A global [[allowlists]] entry with regexTarget = "line" and regex (?i)\bQA-TROUBLE-[0-9]+\b — suppresses only rows containing board ids.
- Optional broader paths fallback for tasks.jsonl, commented out and only for id-format changes.
- CI wiring via --config / GITLEAKS_CONFIG.
Verification (in the doc): report count for generic-api-key in tasks.jsonl must be 0; a negative-control secret in another file must still be flagged; config-validity and original 6-commit rescan checks included, plus acceptance criteria. No history rewrite, per TRBL-014.
# Evidence - Problem class: gitleaks-generic-api-key-board-row-false-positive - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-10-04T12:45:33.105Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "gitleaks-generic-api-key-board-row-false-positive", "provider": "openrouter", "solved_at": "2026-10-04T12:45:33.105Z", "version": ""}