- 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>
106 lines
7.2 KiB
Markdown
106 lines
7.2 KiB
Markdown
# Architecture & Design Decisions
|
|
|
|
## Knowledge Pipeline: Separate /reflect-logs from /reflect
|
|
|
|
`/reflect-logs` handles continuous log processing; `/reflect` handles milestone reflections. Different purpose, different cadence — combining them would overcomplicate the milestone skill.
|
|
|
|
## Knowledge Pipeline: MD5 for reflection state, git SHAs for distill state
|
|
|
|
Log files may not be committed when reflected on, so MD5 of file content is the right identity. `/distill-best-practices` works across committed repos, so git SHAs are appropriate there.
|
|
|
|
## Knowledge Pipeline: Pruning happens in /log, not /reflect-logs
|
|
|
|
`/log` runs most frequently (every session end), so it naturally keeps the log directory clean as a side effect.
|
|
|
|
## Knowledge Pipeline: /distill-best-practices is interactive
|
|
|
|
Cross-project convention changes need human judgment. The skill proposes updates and waits for approval before writing.
|
|
|
|
## Session Logs: Timestamp-based IDs (HHMMSS)
|
|
|
|
Human-readable, naturally sorted, no external dependencies. Format: `YYYY-MM-DD.HHMMSS.md`.
|
|
|
|
## Linting: Formatter exit codes vs hook exit codes
|
|
|
|
Formatter scripts exit 1 on lint errors. The dispatcher hook decides the final exit code (exit 2 for PostToolUse feedback). This separates formatter logic from hook semantics — same scripts work for both PostToolUse and pre-commit.
|
|
|
|
## Linting: Checkpoint via git hash-object with .pre-lint sidecar
|
|
|
|
Fast (~1ms), no commits or stash needed, orphan blobs auto-GC'd. Falls back to `cp` outside git repos.
|
|
|
|
## Linting: Project opt-in via formatter symlinks
|
|
|
|
Projects opt in by having a `formatters/` directory with symlinks back to canonical scripts. Zero-config, visible in `ls`, no parsing needed. The hook walks up the directory tree to find `formatters/`.
|
|
|
|
## Skills: Use CLAUDE_PROJECT_ROOT for cross-project path resolution
|
|
|
|
Skills that reference files outside their own project (e.g., `/distill-best-practices` reading settings.yaml) use `CLAUDE_PROJECT_ROOT` env var instead of hardcoded `~/dev/claude/` or relative `../` paths. Makes skills portable across users. Env var exported in `~/.bashrc`, with runtime fallback (walk up directory tree to find highest CLAUDE.md).
|
|
|
|
## Skills: settings.yaml paths relative to project root
|
|
|
|
`settings.yaml` uses relative paths (`projects_dir: projects`) rather than absolute paths. Combined with `CLAUDE_PROJECT_ROOT`, this keeps config portable. The `extra_projects` section handles projects outside the standard `projects_dir` (e.g., `small-scripts` at root level).
|
|
|
|
## CLAUDE.md: Remove technology-specific sections from root
|
|
|
|
Ansible and Helm sections removed from root CLAUDE.md — already covered with more detail in `best-practices/ansible.md` and `best-practices/helm.md`. Technology-specific practices belong in best-practices, not root guidelines.
|
|
|
|
## context-load: Walk upward collecting context files
|
|
|
|
Walks from cwd upward collecting CLAUDE.md, CONTEXT.md, MEMORY.md, BESTPRACTICES.md at each level. Gives hierarchical context inheritance — highest ancestor provides global guidelines, project dir provides specifics.
|
|
|
|
## context-load: Dedup via readlink -f
|
|
|
|
Root CLAUDE.md is a symlink to claude-foundations. Without dedup it would load twice. `readlink -f` resolves all symlinks before comparison.
|
|
|
|
## context-load: Tree depth 3
|
|
|
|
Deep enough to show project structure without overwhelming output. Applied at every CLAUDE.md location.
|
|
|
|
## CONTEXT.md follows MEMORY.md pattern
|
|
|
|
Thin index + `context/` folder. Consistency with MEMORY.md. CONTEXT.md focuses on active work for agent orientation; MEMORY.md on accumulated learnings.
|
|
|
|
## Status line: Per-session topic files keyed by session ID
|
|
|
|
Topic files at `~/.claude/status/<session-id>/claude-topic.txt`. Session ID uniquely identifies each session, allowing multiple concurrent sessions to have independent topics without collisions.
|
|
|
|
## Status line: Bridge session ID via /tmp file
|
|
|
|
Claude has no direct access to its own session ID. The status line script writes it to `/tmp/claude-session-id-<md5 of cwd>`, which `set-topic.sh` reads to find the correct per-session topic directory.
|
|
|
|
## Status line: Pending-topic queue for bootstrap race condition
|
|
|
|
`set-topic.sh` is called on the first message, before `statusline.sh` has written the session ID file. Instead of erroring, it writes to `/tmp/claude-pending-topic-<hash>`. `statusline.sh` picks this up on its next run via `mv` (atomic, no double-application). Simple and self-healing — statusline already runs after every response.
|
|
|
|
## Status line: Config must exist in every profile settings file
|
|
|
|
Each profile (`~/.claude`, `~/.claude-octopus`, `~/.claude-oreillyit`) has its own `settings.json` with no inheritance. The `statusLine` entry and `Bash(~/.claude/status/set-topic.sh:*)` permission must be added to each independently.
|
|
|
|
## Best practices: One file per topic, not combined mega-documents
|
|
|
|
api-design.md and llm-code-security.md are separate files despite both being "security-adjacent". API design covers versioning, pagination, idempotency — not just security. Self-contained topic files are independently referenceable and can be loaded selectively by skills and agents.
|
|
|
|
## 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.
|