## Summary - Introduce C0/C1/C2 change classification based on the Mikado method, where documentation cards serve as persistent context for agents across sessions - Add `docs-mikado` mise task to visualize active Mikado dependency chains from `status: active` and `requires` frontmatter fields - Rename `zk-docs` task to `ai-docs` ## Changes - **New:** `docs/how-to/agent-change-process.md` — methodology card - **New:** `mise-tasks/docs-mikado` — Python uv script for dependency graph visualization - **Renamed:** `mise-tasks/zk-docs` → `mise-tasks/ai-docs` - **Updated:** `CLAUDE.md` — added Change Classification section, updated references - **Updated:** `ai-assistance-guide.md`, `exploring-the-docs.md`, `how-to.md` — updated references and index ## Verification - [x] `mise run ai-docs` works - [x] `mise run docs-mikado` runs (no active chains yet, as expected) - [x] `docs-check-links` — all valid - [x] `docs-check-index` — all indexed - [x] `docs-check-frontmatter` — all valid - [x] All pre-commit hooks pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/225
5.4 KiB
CLAUDE.md
Guidance for Claude Code working in this repository. See also ai-assistance-guide.
Overview
blumeops is Erich Blume's GitOps repository for personal infrastructure, orchestrated via tailnet tail8d86e.ts.net.
CRITICAL: Public repo at github.com/eblume/blumeops - never commit secrets!
Shell: The user's shell is fish. Use $status not $? for exit codes. Use fish syntax in interactive examples.
Rules
- Always run
mise run ai-docs -- --style=header --color=never --decorations=alwaysat session start This will refresh your context with important information you will be assumed to know and follow. - Always use
--context=minikube-indriwith kubectl (or--context=k3s-ringtailfor ringtail services) - work contexts must never be touched - Feature branches only - checkout main, pull, create branch, commit often
- Create PRs via
tea pr create- user reviews before deploy, merges after - Check PR comments with
mise run pr-comments <pr_number>before proceeding - Add changelog fragments -
docs/changelog.d/<branch>.<type>.mdTypes:feature,bugfix,infra,doc,ai,misc - Test before applying - dry runs (
--check --diff), syntax checks,ssh indri '...' - Wait for user review before deploying
- Never merge PRs or push to main without explicit request
- Verify deployments -
mise run services-check
Change Classification
Before starting work, classify the change:
| Class | Scope | Process |
|---|---|---|
| C0 | Quick fix, single-file, obvious | Read ai-docs, implement directly |
| C1 | Moderate, potential hidden complexity | Mikado method, single session, single PR |
| C2 | Complex, multi-session | Mikado method, documentation-driven, single PR |
See agent-change-process for the full methodology.
Project Structure
./docs/ # documentation (Diataxis, Quartz)
./docs/changelog.d/ # towncrier fragments
./.dagger/ # dagger pipelines
./.forgejo/ # forgejo-runner actions and workflows
./mise-tasks/ # scripts via `mise run`
./ansible/playbooks/ # ansible (indri.yml primary)
./ansible/roles/ # indri service roles
./argocd/apps/ # ArgoCD Application definitions
./argocd/manifests/ # k8s manifests per service
./fly/ # fly.io proxy for public routing
./pulumi/ # Pulumi IaC (tailnet ACLs, dns, cloud)
~/.config/{nvim,fish} # user's shell config, managed by chezmoi
~/code/personal/ # user's projects
~/code/personal/zk # user's Obsidian-sync managed zettelkasten. Potential source for reference data.
~/code/3rd/ # mirrored external projects
~/code/work # FORBIDDEN
Other code paths will be listed via ai-docs, this is just an overview. When you
encounter wiki-links ([[like-this]]) it is referring to docs/ cards.
Service Deployment
Kubernetes (ArgoCD)
Most services run in minikube on indri via ArgoCD (app-of-apps, manual sync). GPU workloads (Frigate, Mosquitto, ntfy) run on ringtail's k3s cluster, also managed by ArgoCD.
PR workflow:
- Create branch, modify
argocd/manifests/<service>/ - Push. Sync 'apps' app if service definition changed (set --revision to branch).
- Test on branch:
argocd app set <service> --revision <branch> && argocd app sync <service> - After merge:
argocd app set <service> --revision main && argocd app sync <service>
Commands: argocd app list|get|diff|sync <app>
Login: argocd login argocd.ops.eblu.me --username admin --password "$(op read 'op://vg6xf6vvfmoh5hqjjhlhbeoaie/srogeebssulhtb6tnqd7ls6qey/password')"
Indri (Ansible)
Native services: Forgejo, Zot, Caddy, Borgmatic, Alloy
mise run provision-indri # full
mise run provision-indri -- --tags <role> # specific
mise run provision-indri -- --check --diff # dry run
Routing
| Domain | Mechanism | Reachable from |
|---|---|---|
*.eblu.me |
Fly.io proxy (Tailscale tunnel) | public internet |
*.ops.eblu.me |
Caddy on indri | k8s pods, containers, tailnet |
*.tail8d86e.ts.net |
Tailscale MagicDNS | tailnet clients only |
Check tailscale serve: ssh indri 'tailscale serve status --json'
Container Releases
mise run container-list # show images/tags
mise run container-release <name> <version> # tag and build
The goal is to eventually use only locally built containers in all cases, with full supply chain control via forge.ops.eblu.me repositories, mirroring source from upstream.
Third-Party Projects
Ask user to mirror on forge first, then clone to ~/code/3rd/<project>/.
Task Discovery
mise run blumeops-tasks # fetch from Todoist, sorted by priority
Most tasks are stored in ./mise-tasks/. For scripts with any logic or
complexity, use uv run --script 's with explicit dependencies. Complex
workflows with artifacts should become dagger pipelines. Mise tasks are for
development processes and operations - tools for the user or the agent.
Credentials
Root store is 1Password. Never grab directly - use existing patterns (ansible
pre_tasks, external-secrets, scripts with op CLI). It's ok to use op item get without --reveal to explore what secrets are available, however.
Prefer op read "op://vault/item/field" over op item get --fields to avoid
quoting issues with multi-line values.