Paul O'Reilly 25918bf028 Add database selection best practice: SQLite is not a production database
Hard rule: any service with a FQDN, multiple consumers, or concurrent
access MUST use PostgreSQL from day one. Documents the cost of "we'll
migrate later" based on the Gitea SQLite→PostgreSQL migration that cost
nearly a full day of productivity.

Extracted from cluster-bootstrap gitea-scaling session (2026-03-28).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 17:23:22 +13:00

claude-foundations

Shared infrastructure for Claude Code sessions: hooks, formatters, best practices, and the knowledge distillation pipeline.

Repository Structure

claude-foundations/
  formatters/              # Canonical formatter scripts (one per extension)
    py                     # ruff format + ruff check
    sh                     # shfmt + shellcheck
    ts                     # biome format + biome check
    js -> ts               # symlink (biome handles both)
    sql                    # sqlfluff fix + sqlfluff lint
    json                   # prettier
    yaml -> json           # symlink (prettier auto-detects)
    md -> json             # symlink
  hooks/
    post-edit-lint.sh      # PostToolUse: auto-format/lint on Edit/Write
    pre-commit-lint.sh     # Git pre-commit: lint staged files
    pre-compact-backup.sh  # PreCompact: backup transcript before compaction
    require-plan-file.sh   # PreToolUse/ExitPlanMode: enforce *-PLAN.md exists before leaving plan mode
  scripts/
    install-hooks.sh       # Symlink hooks into ~/.claude/hooks/
    setup-formatters.sh    # Set up formatters for a project
    statusline.sh          # Status line renderer (symlinked from ~/.claude/status/)
    set-topic.sh           # Set per-session topic for the status line
  best-practices/          # Generalised best practices (one file per topic) — also maintained in skynet/best-practices
  context/                 # Active work focus detail files
  memory/                  # Session logs and reflections
  settings.yaml            # Knowledge pipeline configuration
  BESTPRACTICES.md         # Best practices index (loaded by context-load)
  CLAUDE.md                # Global project guidelines (symlinked to ~/dev/claude/)
  CONTEXT.md               # Active work focus index (loaded by context-load)
  HOOKS.md                 # Hook documentation
  TODO.md                  # Improvement backlog

Quick Start

1. Install hooks (one-time)

cd ~/dev/claude/projects/claude-foundations
scripts/install-hooks.sh

This symlinks all hooks into ~/.claude/hooks/ and prints the settings.json config to add. The PostToolUse hook is what triggers auto-formatting on every Edit/Write.

2. Opt a project into auto-formatting

scripts/setup-formatters.sh ~/dev/claude/projects/<project-name> <ext> [<ext> ...]

For example, to enable Python and shell formatting for cluster-bootstrap:

scripts/setup-formatters.sh ~/dev/claude/projects/cluster-bootstrap py sh

This creates a formatters/ directory in the target project with symlinks back to the canonical formatter scripts here. It also installs a git pre-commit hook if one doesn't exist.

Available formatters: py, sh, ts, js, sql, json, yaml, md

Run with no arguments to see the full list:

scripts/setup-formatters.sh

3. Install required tools

Each formatter gracefully skips if its tool isn't installed, but for full functionality:

Formatter Tools needed Install
py ruff pip install ruff or pipx install ruff
sh shfmt, shellcheck sudo apt install shfmt shellcheck
ts/js biome npm i -g @biomejs/biome
sql sqlfluff pip install sqlfluff
json/yaml/md prettier npm i -g prettier

4. Add per-project config (optional)

Formatters respect project-level config files:

Formatter Config file Purpose
py pyproject.toml ruff rules, line length, target Python version
sh .editorconfig shfmt indent style, binary ops, switch cases
ts/js biome.json biome rules, formatting options
sql .sqlfluff SQL dialect, rules
json/yaml/md .prettierrc prettier options

Without config files, tools use their defaults.

5. Verify setup

Use the /linter skill inside a Claude Code session:

/linter

This scans the project, shows which formatters are active, which tools are installed, and suggests fixes for any gaps.

How It Works

PostToolUse hook (auto-format on edit)

When Claude edits or writes a file:

  1. The post-edit-lint.sh hook fires
  2. It walks up from the working directory to find formatters/
  3. If a formatter exists for the file's extension, it:
    • Creates a checkpoint (git blob hash stored in .pre-lint)
    • Runs the formatter (format in place + lint)
    • On clean pass: removes checkpoint, exits silently
    • On lint errors: keeps checkpoint, exits with errors shown to Claude

Pre-commit hook (lint on commit)

When you git commit, the pre-commit-lint.sh hook:

  1. Finds staged files with matching formatters
  2. Runs each formatter
  3. Re-stages formatted files
  4. Blocks the commit if lint errors remain

Reverting after lint

If you don't like what the formatter did:

git cat-file blob "$(cat <file>.pre-lint)" > <file>
rm <file>.pre-lint

Scripts

Script Purpose
scripts/install-hooks.sh Symlink all hooks to ~/.claude/hooks/ and print settings.json config
scripts/setup-formatters.sh Create formatter symlinks in a target project
scripts/statusline.sh Status line renderer — shows topic, model, context %. Symlinked from ~/.claude/status/
scripts/set-topic.sh Set the session topic: set-topic.sh <cwd> "topic text"
Description
Claude Code foundations - conventions, improvements research, and best practices
Readme 253 KiB
Languages
Shell 76.1%
Python 23.9%