Add question-reframing guidance to CLAUDE.md; commit accumulated project files

- CLAUDE.md: add "Question the question" and "One clarifying question" rules
  to Tone and Interaction — XY problem detection, false premise checks, and
  explicit reframe pattern before answering
- Add claude/ detail-file directory (topic docs referenced from CLAUDE.md)
- Add ABOUT.md, FUTURE.md
- Update memory/, scripts/, settings.yaml with accumulated session changes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Paul O'Reilly
2026-05-25 09:37:28 +12:00
parent 6dfa20c47c
commit f41c22d0ac
29 changed files with 689 additions and 352 deletions

View File

@@ -0,0 +1,7 @@
{
"version": 1,
"last_run": "2026-04-19T09:51:20Z",
"processed": {
"log/2026-04-13.140716.md": "a2e7bfbbe892117df48526fb236ea367"
}
}

View File

@@ -83,3 +83,23 @@ api-design.md and llm-code-security.md are separate files despite both being "se
## Review skills: Read-only output, not auto-edit
/review-plan and /review-spec are read-only (allowed-tools: Read, Glob, Grep). Review output informs the human rather than auto-editing plans/specs. This avoids unintended changes and reduces permission prompts. Both skills load all 5 design/security best practice files upfront — better to over-load context than miss a relevant check.
## Transcript backups: Sonnet (not Haiku) for /log transcript-analysis subagent
Gotcha detection requires judgment about backtracking and failed attempts mid-session. Haiku tends to see only the final outcome and miss the failure mode that led to it. Sonnet in its own fresh context window produces usable transcript companion logs; Haiku did not.
## Transcript backups: /log pre-gathers metadata only, subagent reads content
`/log` calls `list-transcripts-here.sh` to pull compact JSON metadata (backup names, session IDs, paths) — no transcript content. Full JSONL content is read only by the Sonnet subagent in its own context window via `extract-transcripts.py --extract`. Keeps the parent skill's context small while still giving the subagent everything it needs.
## Transcript backups: Tracking file is JSON at `~/.claude/transcript-backups/tracking.json`
Machine-readable JSON (not a markdown table) because both the pre-compact hook (bash) and the /log skill / subagent (python) need to update it. JSON parses trivially from both; markdown tables do not.
## Skill-helper scripts: Live in claude-foundations, symlinked to `~/.claude/scripts/`
`~/.claude/` always resolves to the default profile directory regardless of `CLAUDE_CONFIG_DIR`, making `~/.claude/scripts/` a stable location accessible from all profiles. Scripts live canonically in `claude-foundations/scripts/` and `install-hooks.sh` symlinks them in. Same pattern as hooks.
## install-hooks: Curated `SKILL_HELPERS` array, not blanket symlink
Not every script in `claude-foundations/scripts/` belongs in `~/.claude/scripts/` — only those referenced by skills. `install-hooks.sh` keeps an explicit `SKILL_HELPERS` array as the authoritative list of which scripts to symlink. Regular scripts (statusline.sh, set-topic.sh, etc.) are accessed via their full repo path.

13
memory/gotchas-hooks.md Normal file
View File

@@ -0,0 +1,13 @@
# Hooks Gotchas
## PreCompact hook no longer receives `transcript_path` in JSON input
**Symptom:** `pre-compact-backup.sh` silently skipped every run — no backup file produced, no error.
**Cause:** Claude Code's PreCompact hook JSON input no longer includes `transcript_path` (changed from older versions). The hook was reading an empty value and short-circuiting.
**Fix:** Derive the transcript path from `session_id` and `cwd` instead: `~/.claude/projects/$(echo "$cwd" | tr '/' '-')/<session_id>.jsonl`. Both fields are still present in the hook input JSON.
## Hooks fail silently under `set -e` when an input field is missing
**Symptom:** Hook appears to run (exit 0) but produces no output or side effects.
**Cause:** A missing jq-extracted field returns empty, then subsequent commands operate on the empty string and either no-op or skip conditional branches without error.
**Fix:** Always validate required inputs early in the hook: `if [ -z "$session_id" ] || [ -z "$cwd" ]; then echo "missing input" >&2; exit 1; fi`. Log failures to stderr so they surface in Claude Code hook diagnostics.

7
memory/gotchas-python.md Normal file
View File

@@ -0,0 +1,7 @@
# Python Gotchas
## `sys.exit()` inside bare `except: pass` is swallowed
**Symptom:** A loop that should terminate on first match with `sys.exit(0)` kept iterating and printing multiple lines.
**Cause:** `sys.exit()` raises `SystemExit`, which is a `BaseException`. A bare `except:` (or `except Exception:`) inside the loop body catches it and continues iteration.
**Fix:** Use `break` instead of `sys.exit()` when the exit is inside an exception handler, or narrow the except clause to the specific exception you care about (e.g., `except (KeyError, ValueError):`). Never use bare `except:` — it masks `SystemExit`, `KeyboardInterrupt`, and real bugs.

View File

@@ -16,7 +16,7 @@
**Symptom:** Bang-command like `git log --since="$(git log ...)"` fails even though `Bash(git *)` is in allowed-tools.
**Cause:** The permission checker rejects any command containing `$()` subshells regardless of the outer pattern match.
**Fix:** Keep bang-commands simple. If complex logic is needed, have the skill instructions tell Claude to run it via tool calls instead.
**Fix:** Keep bang-commands simple. If complex logic is needed, either (a) have the skill instructions tell Claude to run it via tool calls instead, or (b) create a thin wrapper shell script that runs the `$()` substitution internally and call the wrapper from the bang-command (see `list-transcripts-here.sh` for the wrapper pattern).
## Relative paths in bang-commands resolve differently based on CWD

View File

@@ -0,0 +1,11 @@
# Statusline Gotchas
## set-topic.sh errors "No session ID found" on first message
Symptom: `set-topic.sh` always fails on the first assistant message because `/tmp/claude-session-id-<hash>` doesn't exist yet — `statusline.sh` hasn't run to create it.
Fix: Implemented pending-topic queue. `set-topic.sh` writes to `/tmp/claude-pending-topic-<hash>` when session ID is missing. `statusline.sh` picks it up on next run.
## md5sum hash inconsistency between scripts
Symptom: Hash mismatch between `statusline.sh` and `set-topic.sh` when computing the cwd-based filename.
Fix: Both scripts must use `echo -n "$CWD" | md5sum` — the `-n` flag (no trailing newline) is critical for consistent hashes.

View File

@@ -51,3 +51,11 @@ The Edit tool fails if `old_string` matches multiple locations. When editing fil
## Best-practices repo is separate from claude-foundations
Best practices live in skynet/best-practices (cloned at ~/dev/claude/projects/best-practices/). ~/dev/claude/BESTPRACTICES.md is a symlink to its index. context-load doesn't show the best-practices directory in the tree — remember it exists when working on best practices topics.
## Keep skill and script symlinks in sync across all profiles
Every profile (`~/.claude`, `~/.claude-octopus`, `~/.claude-oreillyit`) is independent — missing a symlink in one profile breaks that profile's slash commands without affecting others. When adding or renaming a skill or skill-helper script, verify symlinks exist in every active profile. Example that bit: `~/.claude-octopus/skills/switch-mode` symlink was missing while `~/.claude/skills/switch-mode` worked. Audit with `ls -la ~/.claude*/skills/` when touching skill layout.
## Verify subagent output paths use the project's absolute path
When `/log` (or any skill that spawns a subagent) writes files on the project's behalf, always verify the first real run that the subagent wrote to the project's **absolute** `memory/log/` path, not a relative path resolved from an unexpected cwd. A relative path silently lands in the wrong directory and the log looks missing.

View File

@@ -9,22 +9,27 @@ Gathers project context for a Claude Code session by walking from cwd upward, co
## What it loads (in order)
1. Every `CLAUDE.md` found walking up from cwd (top-down order) + directory tree (depth 3) from each
2. Every `CONTEXT.md` found walking up (top-down)
3. Every `MEMORY.md` found walking up (top-down)
4. Every `BESTPRACTICES.md` found walking up (top-down)
5. All `*.md` files in cwd (deduped against already-emitted files)
6. `git-status-report` output from the highest-level CLAUDE.md directory
1. **Paths** to every `CLAUDE.md` found walking up from cwd (not contents — Claude Code loads those natively via `claudeMd`), annotated with `description:` from sibling `ABOUT.md` if present
2. **Paths** to every project `CLAUDE.md` found under each CLAUDE.md directory (depth 2-4) — for project discovery, also annotated with ABOUT.md descriptions
3. Every `CONTEXT.md` found walking up (top-down) — full contents
4. Every `MEMORY.md` found walking up (top-down) — full contents
5. Every `BESTPRACTICES.md` found walking up (top-down) — full contents
## What it does NOT load
- CLAUDE.md contents (loaded natively by Claude Code)
- Directory trees (Claude can run `tree` on demand for fresh results)
- README.md files (human-oriented, read on demand)
- git-status-report (moved to `/housekeeping` skill)
## How it works
- Uses `discover_upward()` to walk from `$PWD` to `/`, collecting directories
- Resolves symlinks via `readlink -f` to deduplicate (e.g., `~/dev/claude/CLAUDE.md` symlink to `claude-foundations/CLAUDE.md`)
- Emits each file with a structured header (`=== FILE: ... ===`) for easy parsing
- Tree output uses `tree` with fallback to `find`
- ANSI codes are stripped from git-status-report output
- Uses `find` to discover project CLAUDE.md files under each hierarchy directory
## Gotchas
- Only walks **upward** from cwd — does not descend into subdirectories. Launch from within a project directory to get that project's context.
- Only walks **upward** from cwd for index files — but scans **downward** for project CLAUDE.md discovery. Launch from within a project directory to get that project's context.
- Index files (MEMORY.md, CONTEXT.md, BESTPRACTICES.md) should be thin indexes, not large documents, since they're injected into the system prompt.

View File

@@ -17,12 +17,12 @@ Run from any project directory. The skill will gather context from cwd upward, j
## How it works
- Uses `!`context-load`` to run the `scripts/context-load` script at skill load time
- The script output (CLAUDE.md files, trees, CONTEXT.md, MEMORY.md, BESTPRACTICES.md, git status) is injected directly into the skill prompt
- Uses `` !`context-load` `` to run the `scripts/context-load` script at skill load time
- The script output (CLAUDE.md paths, project listing, CONTEXT.md, MEMORY.md, BESTPRACTICES.md) is injected directly into the skill prompt
- Claude reads and internalizes the output, then confirms what it loaded
## Gotchas
- Depends on `context-load` being on `$PATH` (symlinked to `~/sbin/context-load`)
- Output size scales with the number of projects in the directory hierarchy — deep nesting or large index files may use significant tokens
- Output is lightweight (~50-200 lines) — CLAUDE.md contents are not included since Claude Code loads them natively
- Only loads index files, not topic files from `memory/` or `context/` — Claude must use Read tool for those if needed

View File

@@ -0,0 +1,33 @@
# skill: /end-session
**Location:** `custom-claude-skills/skills/end-session/SKILL.md`
## Purpose
End-of-session wrap-up that combines session logging, CONTEXT.md update, and project doc refresh into a single command. Replaces the manual workflow of running `/log` then separately updating CONTEXT.md and project docs.
## Usage
```
/end-session
```
No arguments. Reviews the full conversation history automatically.
## How it works
1. **Session log** (Phase 1): Creates `memory/log/YYYY-MM-DD.<HHMMSS>.md` with structured entries (Summary, Decisions, Gotchas, Open Questions, Key Context, Process Notes). Prunes old reflected logs per retention settings.
2. **Context update** (Phase 2): Assesses what's in progress, updates CONTEXT.md index and `context/<topic>.md` detail files so the next session can resume without conversation history.
3. **Doc refresh** (Phase 3): Updates FUTURE.md (new ideas), README.md (milestone table, scripts section), and CLAUDE.md (repo structure, conventions) -- only where this session actually changed something.
4. **Summary** (Phase 4): Prints what was logged, what the next session should pick up, and which docs were updated.
## Relationship to other skills
- Subsumes `/log` -- no need to run `/log` separately when using `/end-session`
- Does NOT include milestone reflection -- use `/reflect M<N>` separately when a milestone is complete
- CONTEXT.md updates follow the same thin-index pattern documented in CLAUDE.md
## Gotchas
- Pre-gathers git log, git status, MEMORY.md, CONTEXT.md, FUTURE.md at skill load time -- if you made changes after invoking the skill, the pre-gathered data may be stale (but the skill can re-read files via tool calls)
- `[topic]` tags on gotchas should match existing memory file topics for routing by `/reflect-logs`