## Summary Migrates the docs build pipeline to Dagger (Phase 2 of the Dagger CI adoption plan). - **Backfill `date-modified` frontmatter** on all 80 docs — Dagger's `--src=.` excludes `.git`, so Quartz can't use git history for page dates. Frontmatter dates work with or without git. - **New `docs-check-frontmatter` mise task + pre-commit hook** — validates all docs have `title`, `tags`, and `date-modified` - **New Dagger functions** — `build_changelog` (towncrier in Python container) and `build_docs` (chains changelog → Quartz build in Node container, returns tarball) - **Simplified CI workflow** — the ~44-line inline Quartz build (clone, npm ci, build, tar, cleanup) is replaced by `dagger call build-docs`. Changelog step remains local on the runner since towncrier needs to modify the host working tree for the git commit. ### Design decisions - **Towncrier runs twice in CI**: once inside Dagger (for the docs tarball) and once on the runner (for the git commit). This is intentional — Dagger's directory export is additive and can't delete the consumed changelog fragments from the host. - **Artifact hosting stays on Forgejo Releases** (not migrated to Forgejo Packages as the plan doc originally suggested). That migration can happen independently. - **`date-modified` frontmatter** preserved even though `build_changelog` installs git — the git there is only for towncrier's `git add` call, not for history. The local iteration story (`dagger call build-docs --src=. --version=dev` with uncommitted changes) depends on frontmatter dates. ### Local iteration ```bash dagger call build-docs --src=. --version=dev export --path=./docs-dev.tar.gz tar tf docs-dev.tar.gz | head -20 ``` ## Deployment and Testing - [x] `dagger call build-docs --src=. --version=dev` produces valid 1.1MB tarball (149 HTML pages) - [x] Pre-commit hooks pass (including new `docs-check-frontmatter`) - [ ] Full `workflow_dispatch` run after merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/157
4.6 KiB
| title | date-modified | tags | ||
|---|---|---|---|---|
| AI Assistance Guide | 2026-02-09 |
|
AI Assistance Guide
Audiences: AI, Owner
This guide provides context for AI agents (like Claude Code) assisting with BlumeOps operations, and helps Erich understand how to work effectively with AI assistance.
Critical Rules
These are non-negotiable for AI agents working in this repo:
- Always use
--context=minikube-indriwith kubectl - Work contexts exist that must never be touched - Run
mise run zk-docsat session start - Review current infrastructure state - Never commit secrets - The repo is public at github.com/eblume/blumeops
- Wait for user review before deploying - Create PRs, don't auto-deploy
- Never merge PRs without explicit request - The user merges after review
Full rules are in the repo's CLAUDE.md.
Workflow Conventions
Feature Branches
All work happens on feature branches:
git checkout main && git pull
git checkout -b feature/descriptive-name
# ... make changes ...
git commit -m "Description"
Pull Requests
Use the forge's tea CLI:
tea pr create --title "Title" --description "$(cat <<'EOF'
## Summary
- Change 1
- Change 2
## Deployment and Testing
- [ ] Test step
EOF
)"
Changelog Fragments
Add a fragment for user-visible changes:
echo "Description" > docs/changelog.d/branch-name.feature.md
Types (file suffix): .feature, .bugfix, .infra, .doc, .ai, .misc
Wiki-Link Formatting
Use simple wiki-links without alternate text or extra spaces:
- Prefer
[[borgmatic]]over[[borgmatic|Borgmatic]] - Only use alternate text when grammatically warranted (e.g.,
[[cluster|Kubernetes]]reads better than[[cluster]]) - No spaces around the pipe:
[[path|Text]]not[[ path|Text ]]
When editing documentation, rewrite links to follow this convention as you encounter them.
Service Locations
Understanding where services run helps target changes correctly:
| Location | Services | Management |
|---|---|---|
| indri (native) | Forgejo, Zot, Jellyfin, Caddy | Ansible |
| [[cluster | Kubernetes]] | Everything else |
Mise Tasks
BlumeOps operations are driven by mise tasks. Run mise tasks to list all available tasks.
| Task | When to Use |
|---|---|
zk-docs |
At session start - review infrastructure documentation |
provision-indri |
Deploy changes to indri-hosted services via Ansible |
services-check |
After deployments - verify all services are healthy |
pr-comments |
Check unresolved PR comments during review |
blumeops-tasks |
Find pending tasks from Todoist |
container-list |
View available container images and tags |
container-tag-and-release |
Release a new container image version |
dns-preview |
Preview DNS changes before applying |
dns-up |
Apply DNS changes via Pulumi |
tailnet-preview |
Preview Tailscale ACL changes |
tailnet-up |
Apply Tailscale ACL changes via Pulumi |
docs-check-links |
Validate wiki-links in documentation (includes orphan detection) |
docs-check-index |
Check every doc is referenced in its category index |
docs-check-filenames |
Check for duplicate doc filenames |
docs-review-stale |
Report docs by last-modified date, highlight stale ones |
docs-review-tags |
Print frontmatter tag inventory across all docs |
docs-review |
Review the most stale doc by last-reviewed date |
indri-runner-logs |
View Forgejo workflow logs from local runner |
For ArgoCD operations, use the argocd CLI directly:
argocd app diff <service>- Preview changesargocd app sync <service>- Deploy changes
Reference Navigation
For AI agents building context:
- reference - Entry point for technical details
- hosts - What hardware exists
- apps - What's deployed in Kubernetes
- routing - How services are exposed
Credential Access
Credentials live in 1Password. Never retrieve them directly - use existing patterns:
- Ansible
pre_tasksgather secrets at playbook start - external-secrets syncs to Kubernetes
- Scripts use
opCLI with user biometric prompts
Common Pitfalls
| Pitfall | Correct Approach |
|---|---|
| Missing kubectl context | Always add --context=minikube-indri |
| Deploying without review | Create PR first, wait for user approval |
| Re-explaining reference material | Link to reference cards instead |
| Committing to main | Use feature branches |
| Guessing at credentials | Ask user or check 1Password patterns |