type: learnings_registry entry_prefix: LRN schema: id: LRN-XXX date: YYYY-MM-DD pattern: string (what was observed, abstracted) context: string (where/when it happened - concrete) future_application: string (when to recall this) rules:
| ID | Date | Pattern | Applies to |
|---|---|---|---|
| LRN-001 | 2026-04-22 | rtk shape-compression breaks pipes |
any pipeline chaining rtk curl/cat/read into jq, python -c, awk |
| LRN-002 | 2026-04-23 | Moving report-file paths requires grepping bash READS, not just WRITES | any refactor that moves a generated file used by a dispatcher |
| LRN-003 | 2026-04-27 | Claude Code disable* settings use sentinel string "disable", not boolean |
any change to permissions.defaultMode or related blocker keys |
rtk shape-compression silently breaks downstream parsersrtk) intercepts stdout and returns a schematized/compressed representation instead of the raw payload, every downstream parser breaks silently — because the user (or the LLM) never sees rtk's output, only the parser error.rtk curl replaces raw JSON output with a tokenized version, regardless of TTY vs pipe. Claude Code hooks auto-rewrite curl → rtk curl, so the behavior is impossible to anticipate without knowing the hook.exclude_commands=["curl"] in ~/.config/rtk/config.toml, or rtk proxy. See BLK-001.test -s X.md, grep ... X.md, wc -l X.md — these refs are invisible if you only grep for "write" or "output path"..claude/audits/ refactor (commit 5c5e82c). First pass: I updated write paths across 5 skills (seo/geo/harden/validate/code-clean) and 3 agents. The user asked for a verify-gate. They re-grepped and found 10+ bare bash refs (e.g. test -s HARDEN.md, grep -oE ... VALIDATE.md) I had missed — the dispatchers were broken (looking at project root while the agent was writing to .claude/audits/). Fixed in commit 5c5e82c (bundled with the same commit).grep -rn "HARDEN\.md") in addition to the full path — to catch bare bash usages.test, grep, wc, cat, head), search for those verbs explicitly.disable* settings use the sentinel string "disable", not a booleandisableAutoMode, disableBypassPermissionsMode) use the literal string "disable" as a sentinel. The key being absent means the feature is available; the value "disable" is what turns the blocker on. Any other value (including false, true, null) has no effect — the doc explicitly states this.permissions.defaultMode to "auto" while disableAutoMode: "disable" was still present would have failed at startup ("auto mode unavailable"). The naming disable<Foo>: "disable" reads ambiguously — easy to assume it's a boolean toggle and leave the key in place.defaultMode, audit the matching disable* key in the same permissions block. If present with value "disable", remove it.bypassPermissions mode and disableBypassPermissionsMode.1421578, doc https://code.claude.com/docs/en/settings.