Add best-practices library, knowledge distillation pipeline settings, and first session log
- best-practices/: 11 topic files + INDEX.md extracted from cluster-bootstrap and custom-claude-skills (validation, k8s, helm, ansible, secrets, debugging, etc.) - settings.yaml: pipeline config (log retention, tracked projects, max logs per run) - CLAUDE.md: updated with best-practices loading and pipeline documentation - memory/log/: first session log demonstrating the format Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
25
CLAUDE.md
25
CLAUDE.md
@@ -15,9 +15,9 @@
|
||||
Scan the directories at runtime so the list is always current. Include a brief description if the project has a CLAUDE.md or README.md you can glean one from.
|
||||
|
||||
2. Based on the user's choice:
|
||||
- **Existing project**: `cd` into the directory, read all `.md` files, and read `~/dev/claude/secrets/` (read-only reference — review every file to refresh context). Ask clarifying questions if anything is unclear or incomplete, and note context in MEMORY.md.
|
||||
- **Existing project**: `cd` into the directory, read all `.md` files, and read `~/dev/claude/secrets/` (read-only reference — review every file to refresh context). Then read the [Best Practices Index](best-practices/INDEX.md) and load any topic files relevant to the selected project's technology stack. Ask clarifying questions if anything is unclear or incomplete, and note context in MEMORY.md.
|
||||
- **No project right now**: Do nothing further — just respond normally.
|
||||
- **New project!**: Follow the "New Projects" section below. Also read `~/dev/claude/secrets/` as above.
|
||||
- **New project!**: Follow the "New Projects" section below. Also read `~/dev/claude/secrets/` as above. Read the [Best Practices Index](best-practices/INDEX.md) and load topic files relevant to the new project's technology stack.
|
||||
|
||||
## Secrets (`~/dev/claude/secrets/`)
|
||||
|
||||
@@ -110,6 +110,27 @@ Human-readable project documentation:
|
||||
- Milestone table with status
|
||||
- Scripts section listing every script with purpose and usage
|
||||
|
||||
## Knowledge Distillation Pipeline
|
||||
|
||||
Three skills form a continuous learning pipeline across projects:
|
||||
|
||||
1. **`/log`** — Run at end of session. Captures decisions, gotchas, open questions to `memory/log/YYYY-MM-DD.<HHMMSS>.md` in the current project. Also prunes old reflected logs.
|
||||
2. **`/reflect-logs`** — Run periodically. Processes unprocessed session logs into topic memory files (`memory/gotchas-*.md`, `memory/process-lessons.md`, etc.). Flags stale entries. Tracks state in `.reflection-state.json`.
|
||||
3. **`/distill-best-practices`** — Run from any project. Reads changed memory files across all tracked projects and proposes updates to `claude-foundations/best-practices/`. Tracks state in `best-practices/.distill-state.json`.
|
||||
|
||||
### State Files
|
||||
- **`.reflection-state.json`** — Per-project, tracks which logs have been reflected on (md5 hashes of log file content)
|
||||
- **`best-practices/.distill-state.json`** — In claude-foundations, tracks git SHAs per project at time of last distillation
|
||||
- **`settings.yaml`** — In claude-foundations, configures log retention (default 7 days), max logs per reflection run, and tracked project list
|
||||
|
||||
### Log Format
|
||||
Session logs use structured markdown with parseable section headers: Summary, Decisions, Gotchas Discovered (tagged with `[topic]` for routing), Open Questions, Key Context, Process Notes. Empty sections are omitted.
|
||||
|
||||
### Pruning
|
||||
- Reflected logs older than `log.retention_days` (default: 7) are automatically deleted by `/log`
|
||||
- Unreflected logs older than `log.warn_unreflected_days` (default: 14) trigger a warning instead of deletion
|
||||
- `/reflect-logs` flags stale memory entries (version-specific bugs that have been fixed, manual processes that have been automated)
|
||||
|
||||
## Milestones
|
||||
|
||||
Break projects into numbered milestones (M1, M2, ...). Every milestone completion MUST include:
|
||||
|
||||
17
best-practices/INDEX.md
Normal file
17
best-practices/INDEX.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Best Practices Index
|
||||
|
||||
Generalised best practices extracted from real project work. Each topic file is self-contained — read only the files relevant to the current project.
|
||||
|
||||
## Topics
|
||||
|
||||
- [Validation & Deployment](validation.md) — Validate locally, deploy once; full-chain testing; pre-flight checks
|
||||
- [Secrets Management](secrets-management.md) — SOPS + age, credential handling, file naming, encryption gotchas
|
||||
- [Git & Source Control](git-source-control.md) — Commit practices, GitOps workflows, remote conventions
|
||||
- [Kubernetes Patterns](kubernetes.md) — Volume mounts, deployment strategies, naming, bootstrap ordering
|
||||
- [Helm Charts](helm.md) — Schema validation, version verification, values structure
|
||||
- [Ansible](ansible.md) — Inventory, templates, idempotency, credential safety
|
||||
- [Scripting](scripting.md) — Shell conventions, verification scripts, idempotency, colour output
|
||||
- [Documentation Standards](documentation.md) — CLAUDE.md, MEMORY.md, FUTURE.md, README.md structure and tiered memory
|
||||
- [Milestones & Reflections](milestones.md) — Milestone workflow, verification, reflection process
|
||||
- [Debugging Methodology](debugging.md) — Systematic diagnosis, full-chain testing, common pitfalls
|
||||
- [Claude Code Skills](skills-development.md) — Skill authoring, context injection, tool restrictions
|
||||
36
best-practices/ansible.md
Normal file
36
best-practices/ansible.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Ansible
|
||||
|
||||
## Inventory and Execution
|
||||
|
||||
- Always pass `-i inventory.yml` explicitly or run from the directory containing `ansible.cfg`
|
||||
- Playbooks that can't find inventory skip silently with no error — a common source of "it ran but nothing happened" confusion
|
||||
- Variables that need customisation go in `inventory.yml` files, not scattered across role defaults
|
||||
|
||||
## Role Structure
|
||||
|
||||
- Roles follow standard structure: `tasks/main.yml`, `templates/*.j2`, `handlers/main.yml`
|
||||
- Jinja2 templates have `.j2` extension and include a "managed by Ansible" header comment
|
||||
|
||||
## Template Safety
|
||||
|
||||
- **Never use placeholder values with `-e` for vars that template config files.** Using `-e "var=dummy"` will overwrite live configs with garbage. Either read real values, use `--skip-tags` to skip templating tasks, or restructure roles so sensitive templates are in a separate tag.
|
||||
|
||||
## Credential Safety
|
||||
|
||||
- Pass secrets via `@file` not `-e` on the command line — `-e "key=value"` exposes secrets in `ps` output
|
||||
- Use temp files with `trap rm` cleanup: `-e "@${tmpfile}"`
|
||||
|
||||
## Module Gotchas
|
||||
|
||||
- `docker_compose_v2` doesn't support `state: restarted` — use `recreate: always` instead
|
||||
- `ansible.builtin.unarchive` with `remote_src` and `extra_opts: --strip-components` is unreliable — use `get_url` + `command: tar` separately
|
||||
- `get_url` won't re-download when the URL changes but the destination filename stays the same — use a version marker file to detect changes
|
||||
|
||||
## Service Restarts
|
||||
|
||||
- Some services (dnsmasq, etc.) need container restarts for config changes to take effect
|
||||
- Ansible handlers handle this, but always verify the change took effect (e.g., `dig @<ip> <record> +short`)
|
||||
|
||||
## Docker Compose
|
||||
|
||||
- `network_mode: host` ignores `ports:` mappings — remove `ports:` to avoid warnings
|
||||
41
best-practices/debugging.md
Normal file
41
best-practices/debugging.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Debugging Methodology
|
||||
|
||||
## Check Before You Act
|
||||
|
||||
- Before writing firewall/network rules, check actual routing (`ip route get <dest>`)
|
||||
- Before running config management with variables, ensure values are real, not placeholders
|
||||
- Before assuming a container has a shell, `docker inspect` it
|
||||
- Before creating API tokens, research all required scopes upfront — iterating one scope at a time costs a push-debug cycle each
|
||||
|
||||
## Routing and Networking
|
||||
|
||||
- Always run `ip route get <dest>` on the forwarding host first
|
||||
- macvlan, Docker bridge, and other virtual interfaces mean the "obvious" physical interface is often wrong
|
||||
- Test from both in-cluster and external perspectives
|
||||
|
||||
## Full-Chain Testing
|
||||
|
||||
After wiring up any new service:
|
||||
1. Test direct to backend (bypass all proxies)
|
||||
2. Test through reverse proxy (bypass DNS)
|
||||
3. Test end-to-end as a user would
|
||||
|
||||
Use `curl --resolve` to test specific paths without depending on DNS propagation.
|
||||
|
||||
## When Something Doesn't Sync/Apply
|
||||
|
||||
- Check resource exclusions in the GitOps controller immediately
|
||||
- Check if the resource type requires special permissions or labels
|
||||
- Check if ServerSideApply conflicts are preventing field changes
|
||||
- Don't try workarounds before understanding the root cause
|
||||
|
||||
## OIDC Integration Checklist
|
||||
|
||||
Before starting any OIDC integration, research:
|
||||
1. What format is the `sub` claim (UUID? username?)
|
||||
2. Which claims are in the ID token vs userinfo endpoint
|
||||
3. How the consumer matches RBAC identities (groups? email? username?)
|
||||
|
||||
## Grep Your Own Docs
|
||||
|
||||
Known issues documented in CLAUDE.md or MEMORY.md but not applied to new scripts/configs waste debugging time. Search your own documentation before writing automation that touches areas with known gotchas.
|
||||
50
best-practices/documentation.md
Normal file
50
best-practices/documentation.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Documentation Standards
|
||||
|
||||
Every project maintains four core markdown files.
|
||||
|
||||
## CLAUDE.md
|
||||
|
||||
The primary reference for Claude sessions. Should contain:
|
||||
- Project overview and architecture
|
||||
- Repository structure (keep updated as the project evolves)
|
||||
- Key design decisions with rationale
|
||||
- Conventions and coding standards
|
||||
- Environment details (IPs, URLs, credential references — never actual values)
|
||||
- Common operations / how-to recipes
|
||||
- Put critical rules at the top — Claude reads sequentially and earlier content has more influence
|
||||
|
||||
## MEMORY.md (Tiered Memory System)
|
||||
|
||||
Long-running projects accumulate significant context. Use a **tiered memory** structure:
|
||||
|
||||
**MEMORY.md** is a **thin index only** — one-line descriptions with links to topic files in `memory/`. No content lives in MEMORY.md itself. Keep it under ~50 lines.
|
||||
|
||||
**memory/** contains the actual content, split by topic:
|
||||
- `memory/project-status.md` — Current milestone, what's next, blockers
|
||||
- `memory/gotchas-<topic>.md` — Gotchas grouped by technology
|
||||
- `memory/process-lessons.md` — How-to-work-with-this-repo lessons
|
||||
- `memory/m<N>-reflection.md` — One file per milestone reflection
|
||||
- `memory/decisions.md` — Architecture and design decisions
|
||||
|
||||
**Principles:**
|
||||
- Split by topic, not by time
|
||||
- Index descriptions matter — they're used to decide what to read
|
||||
- Prune aggressively — stale memory is worse than no memory
|
||||
- Each file should be self-contained and greppable
|
||||
- Deduplicate with CLAUDE.md — stable conventions go in CLAUDE.md, learnings and gotchas go in memory
|
||||
|
||||
## FUTURE.md
|
||||
|
||||
Backlog of improvement ideas, each with:
|
||||
- **Problem:** What's painful or manual today
|
||||
- **Idea:** What the improvement looks like
|
||||
- **Open questions:** Unknowns to research before starting
|
||||
- **Depends on:** Other items or milestones that should come first
|
||||
|
||||
## README.md
|
||||
|
||||
Human-readable project documentation:
|
||||
- Architecture summary
|
||||
- Quick start / setup instructions
|
||||
- Milestone table with status
|
||||
- Scripts section listing every script with purpose and usage
|
||||
34
best-practices/git-source-control.md
Normal file
34
best-practices/git-source-control.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Git & Source Control
|
||||
|
||||
## Commit Practices
|
||||
|
||||
- Use meaningful commit messages; prefer small, focused commits over large batches
|
||||
- Never commit secrets in plaintext — use SOPS + age or equivalent encryption
|
||||
- Enable pre-commit hooks where appropriate (secret detection, linting, formatting)
|
||||
|
||||
## Pre-Commit Hooks
|
||||
|
||||
- Block `local_secrets/` and similar directories from being committed
|
||||
- Auto-encrypt files matching `.sops.yaml` rules that aren't yet encrypted
|
||||
- Enable with `git config core.hooksPath .githooks`
|
||||
- Consider secret detection, linting, and formatting hooks
|
||||
|
||||
## GitOps Workflow
|
||||
|
||||
- All infrastructure changes should be tracked in Git
|
||||
- No manual changes without corresponding GitOps manifests — anything applied manually (e.g., `kubectl apply`, `helm install`) should immediately get a corresponding tracked manifest
|
||||
- For ArgoCD-managed clusters: edit in Git, push, sync — never edit live resources directly
|
||||
|
||||
## Remote Conventions
|
||||
|
||||
- SSH workflows preferred over HTTPS for Git remotes
|
||||
- Use SSH config host aliases for multi-user setups (e.g., `gitea.example.com-<user>`)
|
||||
- Remote URL format: `git@<host-alias>:<org>/<repo>.git`
|
||||
- Optionally push-mirror to GitHub for public visibility
|
||||
|
||||
## Version Management
|
||||
|
||||
- Use the latest stable version of dependencies unless pinned for a reason
|
||||
- Verify versions from live sources (`helm search repo`, upstream docs, package registries) — don't rely on memory
|
||||
- Document the reason in a comment if a version is intentionally pinned below latest
|
||||
- Check compatibility matrices before upgrading (e.g., Talos ↔ Kubernetes, framework ↔ runtime)
|
||||
25
best-practices/helm.md
Normal file
25
best-practices/helm.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Helm Charts
|
||||
|
||||
## Schema Validation
|
||||
|
||||
- **Always validate values against the chart schema before committing.** Run `helm show values <repo>/<chart> --version <ver>` to check the actual structure.
|
||||
- Helm chart schemas change between versions — field names and nesting can differ from documentation or online examples.
|
||||
- A quick `helm template` test locally catches schema errors before deployment.
|
||||
- `additionalProperties: false` in chart schemas means any extra keys at the wrong nesting level cause a hard failure.
|
||||
|
||||
## Version Verification
|
||||
|
||||
- Run `helm search repo` or check upstream docs to confirm latest stable versions
|
||||
- Don't rely on memory for chart versions — they go stale quickly
|
||||
- Check compatibility matrices between chart version, app version, and other cluster components
|
||||
|
||||
## Multi-Source Applications
|
||||
|
||||
- ArgoCD multi-source Applications use `$ref` syntax to combine external Helm charts with Git-stored values files
|
||||
- Keep values files in Git alongside the ArgoCD Application manifest
|
||||
|
||||
## Timeout Handling
|
||||
|
||||
- Under cluster pressure (many events, etcd busy), default Helm timeouts may not be enough
|
||||
- Increase timeout for initial installs (e.g., 10m instead of 5m)
|
||||
- `helm upgrade --install` is idempotent — retries are safe
|
||||
36
best-practices/kubernetes.md
Normal file
36
best-practices/kubernetes.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Kubernetes Patterns
|
||||
|
||||
## Volume Mounts
|
||||
|
||||
- **Avoid `subPath` volume mounts** for Secrets and ConfigMaps. The kubelet does not auto-update `subPath` mounts when the source changes — the pod must be restarted. Use directory mounts instead and adjust the application's config path.
|
||||
- **Secret volume propagation is async.** After updating a Secret, the kubelet takes seconds to sync mounted volumes. A `rollout restart` issued immediately after may start pods with stale data. Add a short delay (5s) before restarting.
|
||||
|
||||
## Deployment Strategies
|
||||
|
||||
- **RWO PVC + RollingUpdate = Deadlock.** New pod can't attach the volume while the old pod holds it. Use `strategy: Recreate` for single-replica deployments with RWO PVCs.
|
||||
- **SSA + strategy change conflict.** Switching from RollingUpdate to Recreate via ServerSideApply fails because SSA won't remove the old `rollingUpdate` field. Must patch the live resource first.
|
||||
|
||||
## Naming
|
||||
|
||||
- `metadata.name` must be DNS-1035 compliant — no dots allowed. Replace dots with dashes (e.g., `oreillyit-nz` not `oreillyit.nz`). Label values CAN contain dots.
|
||||
|
||||
## Bootstrap Ordering
|
||||
|
||||
Some components have chicken-and-egg dependencies:
|
||||
1. CNI (e.g., Cilium) must be installed before anything else — nodes are NotReady without it
|
||||
2. GitOps controller (e.g., ArgoCD) installed second
|
||||
3. Root app applied last — the GitOps controller then "adopts" CLI-installed releases
|
||||
|
||||
Manual bootstrap secrets (encryption keys, OIDC client secrets) must be documented as explicit steps.
|
||||
|
||||
## Network Policies
|
||||
|
||||
- DNS egress for `toFQDNs` rules must use `toEndpoints` targeting kube-dns pods with `rules.dns` — this triggers the DNS proxy. Using `toCIDRSet` for DNS bypasses the proxy and FQDN rules never populate.
|
||||
- Cross-namespace policies need explicit namespace matching (e.g., `matchExpressions` on namespace label).
|
||||
- Always test from the actual consumer namespace, not same-namespace test pods.
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
- `enableServiceLinks: false` may be needed when K8s-injected service env vars conflict with app config (e.g., Authelia interprets `AUTHELIA_*` service vars as configuration).
|
||||
- Proxmox VM names must match K8s node hostnames for cloud controller manager integration.
|
||||
- Metrics-server on Talos needs `--kubelet-insecure-tls` (self-signed kubelet certs).
|
||||
42
best-practices/milestones.md
Normal file
42
best-practices/milestones.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Milestones & Reflections
|
||||
|
||||
## Milestone Structure
|
||||
|
||||
Break projects into numbered milestones (M1, M2, ...). This provides clear checkpoints, measurable progress, and natural reflection points.
|
||||
|
||||
## Milestone Completion Checklist
|
||||
|
||||
Every milestone MUST include:
|
||||
|
||||
### 1. Verification Script
|
||||
|
||||
`scripts/verify-m<N>.sh` — automated checks confirming all milestone outcomes.
|
||||
- Idempotent, non-destructive, returns non-zero on failure
|
||||
- Colour output (green/red) for pass/fail
|
||||
- Environment-resilient (no sudo, test from accessible side)
|
||||
- Check for default/insecure credentials
|
||||
|
||||
### 2. Milestone Reflection
|
||||
|
||||
Write `memory/m<N>-reflection.md` by reviewing the **entire conversation** from milestone start. Cover:
|
||||
|
||||
- **Process improvements:** What slowed us down? Wrong assumptions? Where did we go in circles? What would make this faster if redone from scratch?
|
||||
- **Key knowledge for reproduction:** Critical facts, gotchas, non-obvious config details, version-specific quirks, debugging detours
|
||||
- **Scripts and automation:** Existing tools that proved valuable, new scripts to build, patterns to extract into reusable automation
|
||||
- **Future improvements:** Ideas that surfaced but don't belong in current scope — add to FUTURE.md
|
||||
|
||||
### 3. Updated README.md
|
||||
|
||||
Ensure the scripts section, milestone table, and setup steps are current.
|
||||
|
||||
### 4. Updated CLAUDE.md
|
||||
|
||||
Reflect new repo structure, conventions, and patterns discovered during the milestone.
|
||||
|
||||
## Reflection Quality
|
||||
|
||||
Good reflections capture:
|
||||
- Commit stats (total commits, fix percentage) to measure validation discipline
|
||||
- Longest detour and root cause
|
||||
- Most avoidable waste and what would have prevented it
|
||||
- Concrete checklist items for future similar work
|
||||
29
best-practices/scripting.md
Normal file
29
best-practices/scripting.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Scripting Conventions
|
||||
|
||||
## Structure
|
||||
|
||||
- All scripts live in `scripts/` and run from the repository root
|
||||
- Scripts should be idempotent and safe to re-run
|
||||
- Exit non-zero on failure so `&&` chains work naturally
|
||||
|
||||
## Verification Scripts
|
||||
|
||||
- Automated checks confirming milestone or feature outcomes
|
||||
- Use colour output (green/red) for pass/fail indicators
|
||||
- Should be non-destructive and environment-resilient
|
||||
- Avoid needing sudo — test from the accessible side of a connection instead
|
||||
- Check for default/insecure credentials and print remediation instructions on failure
|
||||
- Use `curl --resolve` to bypass DNS/proxy layers when testing direct connectivity
|
||||
|
||||
## Automation Triggers
|
||||
|
||||
If you run the same 3+ commands in sequence more than once, it should become a script. Look for:
|
||||
- Repeated command sequences in conversation history
|
||||
- Steps requiring careful ordering
|
||||
- Multi-step manual processes that are error-prone
|
||||
|
||||
## Shell Gotchas
|
||||
|
||||
- `((PASS++))` fails under `set -e` when PASS=0 — the expression evaluates to 0 (false), triggering errexit. Use `PASS=$((PASS + 1))` instead.
|
||||
- Always quote variables in conditionals and file paths
|
||||
- Use `trap` for cleanup of temp files and credentials
|
||||
41
best-practices/secrets-management.md
Normal file
41
best-practices/secrets-management.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Secrets Management
|
||||
|
||||
## SOPS + age
|
||||
|
||||
SOPS with age encryption is the standard across all projects. A single `.sops.yaml` at the repo root defines path-based encryption rules.
|
||||
|
||||
### File Naming
|
||||
|
||||
- `.sops.yaml` path-based rules match specific filename patterns (e.g., `**/*secret*.yaml`)
|
||||
- Non-secret files must NOT contain `secret` in their name, or the pre-commit hook will encrypt them
|
||||
- KSOPS generator files should be named `ksops-generator.yaml`, not `secret-generator.yaml`
|
||||
|
||||
### encrypted_regex Gotcha
|
||||
|
||||
When using `encrypted_regex` for selective field encryption (e.g., Ansible group_vars), variable names must contain a keyword that matches the regex (e.g., `password|private_key|api_key|secret|token`). Arbitrary key names are silently left unencrypted.
|
||||
|
||||
### SOPS Vars Plugin
|
||||
|
||||
Each Ansible project needs `vars_plugins_enabled = host_group_vars,community.sops.sops` in `ansible.cfg`. Files in `group_vars/` must be named after a group (e.g., `all.sops.yaml`), not arbitrary names.
|
||||
|
||||
### Interactive Editor Pitfalls
|
||||
|
||||
- `sops <file>` opens an interactive editor — fails in non-interactive sessions
|
||||
- `sops -e /tmp/file` fails when the temp path doesn't match `.sops.yaml` rules
|
||||
- Multiple `sops --set` calls can corrupt files — use the interactive editor for multi-field edits
|
||||
|
||||
## Credential Handling
|
||||
|
||||
- **Never pass secrets via command-line arguments** — visible in `ps` output
|
||||
- Use `@file` references, environment variables sourced at runtime, or stdin
|
||||
- For Ansible, use temp files with `trap rm` cleanup: `-e "@${tmpfile}"`
|
||||
- Read secrets at execution time and use them ephemerally — never cache or persist values
|
||||
- Reference the **existence** of a secret file in docs, never its contents
|
||||
|
||||
## Bootstrap Secrets
|
||||
|
||||
Some secrets are chicken-and-egg (e.g., the age decryption key for ArgoCD's KSOPS). These must be created manually as a bootstrap step and documented clearly.
|
||||
|
||||
## Backup Considerations
|
||||
|
||||
Backup plans must include encryption keys (age private keys, etc.) so that encrypted data in Git repos remains recoverable.
|
||||
24
best-practices/skills-development.md
Normal file
24
best-practices/skills-development.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Claude Code Skills
|
||||
|
||||
## Skill Structure
|
||||
|
||||
- Each skill lives in `skills/<skill-name>/SKILL.md`
|
||||
- Skills should be project-agnostic where possible — use dynamic context injection to adapt
|
||||
- After adding a new skill, run the install script to register it
|
||||
- Skills only useful for one project should live in that project's `.claude/skills/` instead
|
||||
|
||||
## Authoring Guidelines
|
||||
|
||||
- **Inline by default** — only use `context: fork` if the skill genuinely doesn't need conversation history
|
||||
- **Pre-fetch context** with `!`command`` injection to reduce tool calls during execution
|
||||
- **Restrict tools** with `allowed-tools` to the minimum needed — reduces permission prompts
|
||||
- **Use $ARGUMENTS** for user input, `$0`, `$1` etc. for positional args
|
||||
- Dynamic commands in `!`command`` run at skill load time, not during Claude's execution
|
||||
|
||||
## `!`command`` Gotchas
|
||||
|
||||
- **No `$()` command substitution** — the permission checker rejects commands containing `$()`
|
||||
- **No complex shell pipelines relying on subshells** — keep commands simple and self-contained
|
||||
- **`allowed-tools` patterns must match the command binary** — each binary used in `!`command`` blocks needs its own pattern
|
||||
- **Prefer specific tool patterns over broad ones** — `Bash(git log *)` is safer than `Bash(git *)`
|
||||
- **Fallback to tool instructions for dynamic paths** — if a command needs `$ARGUMENTS` to compute a path, use a plain-text instruction telling Claude to use the Read tool instead
|
||||
35
best-practices/validation.md
Normal file
35
best-practices/validation.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Validation & Deployment
|
||||
|
||||
## Validate Locally, Deploy Once
|
||||
|
||||
The single biggest time sink across projects is "deploy first, validate later." Real-world stats from a 9-milestone infrastructure project showed 50-60% of commits were fixes that could have been caught locally.
|
||||
|
||||
**Always validate before pushing:**
|
||||
- `helm template` for Helm chart values
|
||||
- `kustomize build` (or `kubectl kustomize`) for Kustomize apps
|
||||
- `kubectl apply --dry-run=server` for K8s naming/schema issues
|
||||
- `docker run <app> validate-configuration` for apps that support it (Authelia, Homepage, etc.)
|
||||
- `docker inspect` for unfamiliar container images before writing init containers
|
||||
- Lint/typecheck/test for application code
|
||||
|
||||
**Batch fixes locally, push once.** Each push-sync-crash-fix cycle wastes minutes and clutters Git history.
|
||||
|
||||
## Test the Full Chain Immediately
|
||||
|
||||
After wiring up any new service or endpoint, test end-to-end from the user's perspective right away. Don't assume intermediate steps working means the whole chain works.
|
||||
|
||||
- `curl --resolve domain:443:<ip> https://domain` to test bypassing DNS/proxy layers
|
||||
- Test from the actual consumer (not same-namespace test pods for network policies)
|
||||
- Test DNS resolution after deploying FQDN-based policies
|
||||
|
||||
## Pre-Flight Checks
|
||||
|
||||
Before starting a deploy or automation phase:
|
||||
- Verify SSH keys are loaded (`ssh -T git@<host>`)
|
||||
- Confirm environment variables and credentials are available
|
||||
- Check that the target environment is in the expected state
|
||||
- Verify DNS records resolve as expected
|
||||
|
||||
## Scripts That Change Config Must Self-Verify
|
||||
|
||||
After updating and restarting a service, the script should test that the change actually took effect (e.g., curl an API endpoint, check a config value). A "success" message without verification hides failures.
|
||||
25
memory/log/2026-03-12.233744.md
Normal file
25
memory/log/2026-03-12.233744.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Session Log — 2026-03-12
|
||||
|
||||
## Summary
|
||||
Created the claude-foundations repo on Gitea (skynet org), built a best-practices folder with 11 topic files extracted from cluster-bootstrap and custom-claude-skills, then designed and implemented a three-tier knowledge distillation pipeline (/log, /reflect-logs, /distill-best-practices).
|
||||
|
||||
## Decisions
|
||||
- Decision: Separate `/reflect-logs` from existing `/reflect` — Rationale: different purpose (continuous vs milestone), different cadence, avoids overcomplicating the existing skill
|
||||
- Decision: Use MD5 hashes for reflection state, git SHAs for distill state — Rationale: log files may not be committed when reflected; distill explicitly works across committed repos
|
||||
- Decision: Timestamp-based session IDs (HHMMSS) — Rationale: human-readable, naturally sorted, no external dependencies
|
||||
- Decision: Pruning happens in `/log` not `/reflect-logs` — Rationale: runs most frequently, keeps log dir clean as side effect of the most common operation
|
||||
- Decision: `/distill-best-practices` is interactive (proposals before changes) — Rationale: cross-project conventions need human judgment
|
||||
|
||||
## Gotchas Discovered
|
||||
- **[skills]** Symptom: install.sh failed with exit 1 on broken symlink — Fix: old reflect symlink pointed to pre-move path (`~/dev/claude/custom-claude-skills/` instead of `~/dev/claude/projects/custom-claude-skills/`). `readlink -f` on a broken symlink returns empty string, causing comparison failure under `set -e`. Fixed by removing stale symlink and re-running.
|
||||
- **[skills]** Symptom: skills created mid-session not available as slash commands — Fix: skills are discovered at session start, not dynamically. New skills require a new session to become available.
|
||||
|
||||
## Key Context
|
||||
- Best practices files are in claude-foundations/best-practices/ with INDEX.md as the card catalog
|
||||
- Settings for the pipeline live in claude-foundations/settings.yaml
|
||||
- State files: `.reflection-state.json` (per-project), `best-practices/.distill-state.json` (in claude-foundations)
|
||||
- SSH key for ai_enablement is password-protected — needs ssh-agent loaded before git push
|
||||
|
||||
## Process Notes
|
||||
- The plan mode workflow worked well for this — explored existing patterns, designed the architecture, got approval, then executed cleanly
|
||||
- Creating all 11 best-practices files in parallel (single Write batch) was efficient
|
||||
14
settings.yaml
Normal file
14
settings.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
# Knowledge distillation pipeline settings
|
||||
|
||||
log:
|
||||
retention_days: 7 # Prune reflected logs older than this
|
||||
warn_unreflected_days: 14 # Warn (don't delete) unreflected logs older than this
|
||||
|
||||
reflect:
|
||||
max_logs_per_run: 10 # Process at most N logs per invocation
|
||||
|
||||
distill:
|
||||
projects_dir: ~/dev/claude/projects
|
||||
projects: # Projects to scan for memory changes
|
||||
- cluster-bootstrap
|
||||
- custom-claude-skills
|
||||
Reference in New Issue
Block a user