Last time I wrote about handing a monitoring script exactly one root command . This post is the same question ― what do you let unattended automation touch? ― aimed at a different target: the plumbing that carries audit reports and improvement plans written by Claude Code itself into my human-facing Obsidian wiki. The gate I ended up with takes 12 Markdown files as input, lets 4 through, and refuses to write anything at all if a single one of them contains something that looks like an API key. The problem: AI-written audit memos carry a different risk than chat logs ~/.claude/improvements/ accumulates audit reports and improvement plans that Claude Code writes during autonomous operation. Look inside and you find entries like this (excerpt from audit-2026-05-29.md ): | project | 状態 | 推奨アクション |
|---|---|---|
| seo-affiliate-site 🔴 | 63 files 未コミット(Like / コメント / AdSense 等のマネタイズ実装が宙吊り) | 機能単位で分割コミット |
| closet-os 🟢 | clean / 直近活発 | .env.production.local 1.9KB は gitignore 済だがバックアップ運用注意 | That's personal project names, implementation progress, and even the existence of .env files, all spelled out. Separate from the pipeline that turns conversation logs into long-term memory, there is a distinct risk here: documents the AI generates on its own can carry secrets and personal information . A fragment of an API key pasted during debugging ending up quoted in an audit memo is an entirely plausible accident. I needed something mechanical that would stop these memos before they got poured into the wiki. That's wiki-sync-improvements.sh . Design: narrow the targets, halt everything on a secret, default to dry The comment block at the top of the script summarizes the whole design. # wiki-sync-improvements.sh # ~/.claude/improvements/ の個別 plan/audit/curation docs を # ~/Documents/claude-obsidian/wiki/meta/improvements/ に同期する。 # # 対象: audit-.md / -plan-.md / -curation-.md # 除外: log.md (巨大), README.md, next-session-todo.md など # 秘密スキャン: sk- / ghp_* が含まれていれば sync 中止 # # 使い方: # wiki-sync-improvements.sh dry # 変更プレビューのみ # wiki-sync-improvements.sh apply # 実際に書き込む The reason log.md is excluded is visible in the numbers. On my machine it's 2,316 lines and roughly 228 KB ― a chronological log, not something that fits the wiki's one-note-per-file granularity. Target filtering is a shell case pattern. for f in " ( basename " base " in audit- * .md| * -plan- * .md| * -curation- * .md ) candidates+ =( " { candidates [@] } " ; do
if grep -E -q " f " ; then secret_hits+ =( " {# secret_hits [@] } -gt 0 ]] ; then echo "[abort] secrets detected — sync stopped" > &2 for h in " h " > &2 ; done exit 2 fi Note: This is deliberately not "drop only the files that contain a secret." A single hit halts every candidate. Allowing partial syncs would force the script to make the call "skip the one file with the secret, pass the rest through" ― and a mistake in that call is the scariest failure mode here. So the threshold has exactly one setting: stop everything. Writing defaults to dry. MODE="tmp " " tmp " skipped = DST / { base %.md } . ( ts_suffix ) .md" mv " stamped " Running it for real Running dry locally produced this: ls ~/Documents/claude-obsidian/wiki/meta/improvements/ ls: .../meta/improvements/: Interrupted system call
total 0 ls , find , and the Glob tool all kept returning the same Interrupted system call (EINTR) and could not enumerate the contents. The parent meta/ directory showed the same symptom. Meanwhile, existence checks on individual files went through. $ [ -e .../meta/improvements/audit-2026-05-29.md ] && echo exists exists But cat on that very same file hung with no response and timed out at 600 seconds. It behaves a lot like a directory under iCloud sync where only the file metadata exists and the actual content is stuck as an undownloaded placeholder. I can't say for certain, but the factual state is: "4 files are treated as existing, yet the path to read their contents doesn't work from this session." In other words, the secret scan and the halt-everything logic look sound on reading ― but the path for verifying afterwards that things "actually landed correctly in the wiki" is thin, and when it breaks, it's hard to notice. That's the reality that only showed up when I ran it. Writing a safety gate and being able to continuously verify that gate's output turned out to be two separate problems. Pitfalls I hit Including log.md (2,316 lines / ~228 KB) as-is would wreck the wiki's per-note granularity → explicitly excluded via filename pattern A single secret hit halts every candidate → the script is never asked to make a partial-sync decision The -plan-.md pattern doesn't match xxx-plan.md (no suffix) → improvement plans missing a date suffix drop out of scope with no warning Dry mode only checks "does a same-named file exist at the destination," not whether the contents differ → [dry] would write timestamped means "same-named file present or not," not "there is a diff" Verifying the destination directory's real contents gets stuck on EINTR because of iCloud sync → separately from the gate itself, you need an independent path (a hash ledger, for instance) to confirm output arrival Summary Audit and improvement memos the AI writes on its own can pick up secrets and personal information through a route entirely separate from conversation logs For secret scanning, "halt everything on a single hit" reduces judgment errors compared to "drop only the offending file" Target-file filtering that relies on shell patterns leaks silently. Inconsistent naming conventions are a breeding ground for accidents The safe-side design holds: default dry, hash-comparison skip on apply, and timestamped coexistence instead of overwrite when there's a diff But you still need a separate path to verify that what passed the gate actually arrived. This time, that path was still broken Next time I plan to cover verifying destination arrival from outside the gate using a hash ledger. If you're piping AI-generated notes into a knowledge base of your own, how do you confirm they actually landed ― or do you trust the exit code and move on? Written by **Lily * — I ship iOS apps and automate my content stack with Claude Code. Follow along: Portfolio · X · GitHub *

12 Files In, 4 Out: The Secret-Scanning Gate Between Claude Code's Audit Memos and My Obsidian Wiki
Lily

