Formalize C0/C1/C2 change classification process
Redefine the three change classes with clearer boundaries: - C0: direct-to-main commits for low-risk, fix-forward-safe changes - C1: feature branch + PR with docs-first workflow and branch deployment - C2: Mikado Branch Invariant enforcing strict commit ordering (card commits first, code progress, card closures) with branch resets on new prerequisite discovery Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f05e5cccdf
commit
9e39087a0a
6 changed files with 127 additions and 64 deletions
24
CLAUDE.md
24
CLAUDE.md
|
|
@ -15,25 +15,31 @@ blumeops is Erich Blume's GitOps repository for personal infrastructure, orchest
|
|||
1. **Always run `mise run ai-docs -- --style=header --color=never --decorations=always` at session start**
|
||||
This will refresh your context with important information you will be assumed to know and follow.
|
||||
2. **Always use `--context=minikube-indri` with kubectl** (or `--context=k3s-ringtail` for ringtail services) - work contexts must never be touched
|
||||
3. **Feature branches only** - checkout main, pull, create branch, commit often
|
||||
4. **Create PRs via `tea pr create`** - user reviews before deploy, merges after
|
||||
3. **Classify the change as C0/C1/C2 before starting** (see below) — this determines branching and PR requirements
|
||||
4. **Feature branches + PRs for C1/C2** - checkout main, pull, create branch, open PR via `tea pr create`. C0 goes direct to main.
|
||||
5. **Check PR comments with `mise run pr-comments <pr_number>`** before proceeding
|
||||
6. **Add changelog fragments** - `docs/changelog.d/<branch>.<type>.md`
|
||||
Types: `feature`, `bugfix`, `infra`, `doc`, `ai`, `misc`
|
||||
7. **Test before applying** - dry runs (`--check --diff`), syntax checks, `ssh indri '...'`
|
||||
8. **Wait for user review before deploying**
|
||||
9. **Never merge PRs or push to main without explicit request**
|
||||
8. **Wait for user review before deploying** (C1/C2)
|
||||
9. **Never merge PRs or push to main without explicit request** (C0 commits to main are fine)
|
||||
10. **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 |
|
||||
| Class | Name | When to use | Key trait |
|
||||
|-------|------|-------------|-----------|
|
||||
| **C0** | Quick Fix | Small, low-risk, fix-forward safe | Direct to main, no PR |
|
||||
| **C1** | Human Review | Moderate complexity or risk | Feature branch + PR, docs-first |
|
||||
| **C2** | Mikado Chain | Multi-phase, multi-session, high complexity | Mikado Branch Invariant |
|
||||
|
||||
**C0** — commit directly to main. No branch or PR needed. Fix forward if problems arise.
|
||||
|
||||
**C1** — feature branch with early PR. Search related docs first, write documentation changes before code, deploy from the unmerged branch (ArgoCD `--revision`, Ansible from checkout). Upgrade to C2 if complexity spirals.
|
||||
|
||||
**C2** — feature branch governed by the Mikado Branch Invariant: all Mikado card commits come first, then code progress commits, then card-closing commits. Reset the branch when new prerequisites are discovered.
|
||||
|
||||
See [[agent-change-process]] for the full methodology.
|
||||
|
||||
|
|
|
|||
1
docs/changelog.d/formalize-change-classification.doc.md
Normal file
1
docs/changelog.d/formalize-change-classification.doc.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Formalize C0/C1/C2 change classification: C0 allows direct-to-main commits, C1 adds docs-first workflow with branch deployment, C2 introduces the Mikado Branch Invariant for strict commit ordering on multi-phase changes.
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Agent Change Process
|
||||
modified: 2026-02-20
|
||||
last-reviewed: 2026-02-22
|
||||
modified: 2026-02-23
|
||||
last-reviewed: 2026-02-23
|
||||
tags:
|
||||
- how-to
|
||||
- ai
|
||||
|
|
@ -15,71 +15,125 @@ How to classify and execute infrastructure changes, especially when working with
|
|||
|
||||
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 |
|
||||
| Class | Name | When to use | Key trait |
|
||||
|-------|------|-------------|-----------|
|
||||
| **C0** | Quick Fix | Small, low-risk, fix-forward safe | Direct to main, no PR |
|
||||
| **C1** | Human Review | Moderate complexity or risk | Feature branch + PR, docs-first |
|
||||
| **C2** | Mikado Chain | Multi-phase, multi-session, high complexity | Mikado Branch Invariant |
|
||||
|
||||
When in doubt, start at C1. Upgrade to C2 if complexity spirals or the user requests it.
|
||||
|
||||
## C0 — Quick Fix
|
||||
|
||||
1. Run `mise run ai-docs` to load context
|
||||
2. Implement the change directly
|
||||
3. Commit, push, create PR
|
||||
|
||||
Examples: fix a typo, bump a version, add a simple config value.
|
||||
|
||||
## C1 — Guided Change (Single Session)
|
||||
|
||||
Use the [Mikado method](https://mikadomethod.info/) within a single session:
|
||||
A change where the risk is low enough that problems can be quickly fixed forward.
|
||||
|
||||
1. Run `mise run ai-docs` to load context
|
||||
2. Attempt the change on a feature branch, amending a single commit as you iterate
|
||||
3. **If it works:** push and create PR
|
||||
4. **If it fails:** revert the broken change (`git revert`), then:
|
||||
- Amend or add a commit with documentation updates noting what prerequisite was discovered
|
||||
- Update frontmatter: add `requires: [prerequisite-card]` to the goal card
|
||||
- Work the leaf nodes (prerequisites with no further dependencies) first
|
||||
- Repeat until the goal succeeds
|
||||
2. Implement the change directly on main
|
||||
3. Commit and push
|
||||
|
||||
Single feature branch, squash-merge when complete. GitOps may require pushing to test — if a pushed commit breaks, revert it promptly.
|
||||
No feature branch or PR required. If something goes wrong, fix forward with another commit.
|
||||
|
||||
## C2 — Documented Change (Multi-Session)
|
||||
Examples: fix a typo, bump a version, add a simple config value, update a doc.
|
||||
|
||||
Like C1 but designed to survive agent context loss across sessions:
|
||||
## C1 — Human Review
|
||||
|
||||
A change with enough complexity or risk that a human should review it, but not so much that a formal multi-phase approach is needed.
|
||||
|
||||
### Process
|
||||
|
||||
1. Run `mise run ai-docs` to load context
|
||||
2. **Search related docs** — read existing documentation, reference cards, and prior Mikado chains related to the change area
|
||||
3. **Create a feature branch** and open a PR early (draft is fine)
|
||||
4. **Documentation first** — commit doc changes reflecting the desired end state before writing code. This helps the reviewer understand intent and catches design issues early
|
||||
5. **Implement** — commit code changes, pushing as you go. The PR gets updated along the way and the user can review and comment at any point
|
||||
6. **Deploy from the branch** — do not wait for merge:
|
||||
- **ArgoCD:** `argocd app set <service> --revision <branch> && argocd app sync <service>`
|
||||
- **Ansible:** run playbooks directly from the branch checkout
|
||||
- **Workflows:** point workflow triggers at the branch if needed
|
||||
7. After user review and successful deployment, the user merges the PR
|
||||
8. **After merge:** reset ArgoCD revisions back to main, re-sync
|
||||
|
||||
### Upgrading to C2
|
||||
|
||||
Upgrade to C2 if any of these happen during a C1 change:
|
||||
|
||||
- You discover the change requires multiple prerequisite changes that must be sequenced
|
||||
- The change is spiraling in complexity beyond a single session
|
||||
- The user requests it
|
||||
- During planning you realize this is a multi-phase project
|
||||
|
||||
## C2 — Mikado Chain
|
||||
|
||||
A complex, multi-session change managed through the [Mikado method](https://mikadomethod.info/) with a strict branch discipline called the **Mikado Branch Invariant**.
|
||||
|
||||
### The Mikado Branch Invariant
|
||||
|
||||
The invariant governs how commits are ordered on a C2 feature branch. The branch must always have this structure:
|
||||
|
||||
```
|
||||
main ← [Mikado card commits] ← [code commits] ← [card-closing commits]
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Planning layer Implementation Resolution
|
||||
(cards only) (code only) (close leaf nodes)
|
||||
```
|
||||
|
||||
**Rules:**
|
||||
|
||||
1. The first N commits on the branch (after diverging from main) must ALL be commits that **only introduce or modify Mikado cards** — no code changes
|
||||
2. After the card commits, a series of commits (preferably just one) make **code progress toward closing a leaf node** — these commits must NOT introduce or change Mikado cards
|
||||
3. The code commits must be followed by one or more commits that **close Mikado leaf nodes** based on the work done
|
||||
4. This pattern (code → close) repeats until the chain is complete
|
||||
|
||||
**What is NOT allowed:**
|
||||
|
||||
- Introducing a Mikado card in a commit that comes after code progress commits
|
||||
- Closing a Mikado card before all cards it depends on have been introduced
|
||||
|
||||
**The length-zero case:** It is valid for the "planning layer" to have zero commits on the branch — this happens when all Mikado cards were introduced in earlier sessions and are already in main's history. The invariant is satisfied.
|
||||
|
||||
### Process
|
||||
|
||||
1. **Goal card:** Create a how-to doc in `docs/how-to/` describing the desired end state
|
||||
- Add `status: active` to frontmatter
|
||||
2. **Attempt the change** — GitOps may require pushing code to test (e.g., ArgoCD sync). When the attempt fails:
|
||||
- **First**, reset the failed code changes (the branch should not carry broken code forward)
|
||||
- **Then**, create/update prerequisite cards as how-to docs with `status: active`
|
||||
- Add `requires: [prerequisite-stem, ...]` to the goal card's frontmatter
|
||||
- Commit only the doc updates (the documentation IS the Mikado graph)
|
||||
3. **Work leaf nodes first** — cards with `status: active` and no unmet `requires`
|
||||
4. **Re-attempt the goal** after leaf nodes are resolved — code from the attempt comes back here
|
||||
- Create prerequisite cards discovered during planning, each with `status: active`
|
||||
- Commit all cards together (or in a sequence of card-only commits)
|
||||
2. **Open a PR** after the first card commits so the user can review the Mikado graph
|
||||
3. **Work leaf nodes** — pick a leaf (a card with `status: active` and no unmet `requires`):
|
||||
- Commit code changes that progress toward closing it
|
||||
- Commit the card closure (remove `status: active`)
|
||||
- Push to origin — this is the save point
|
||||
4. **Repeat** until the chain is complete
|
||||
5. **New agent sessions** pick up state by running `mise run docs-mikado`
|
||||
6. When a card's change succeeds, remove `status: active` (or the entire field) from its frontmatter
|
||||
|
||||
Documentation IS the Mikado graph. Each card captures what was learned from failed attempts, so the next agent session doesn't repeat mistakes.
|
||||
### Discovering new prerequisites
|
||||
|
||||
### Handling failed attempts
|
||||
When you discover a new prerequisite during code work, you must restore the Mikado Branch Invariant:
|
||||
|
||||
When an attempt fails and you discover prerequisites, the branch must be cleaned up before documenting what you learned:
|
||||
1. **Reset the branch** back to the top of the Mikado commit stack — the point where all card-introducing commits end and code commits begin
|
||||
2. **Add a new commit** introducing the new prerequisite card (and updating `requires` on existing cards if needed)
|
||||
3. **Replay the Mikado process** from the new state of the card stack
|
||||
|
||||
1. Reset to before the code attempt (`git reset --hard`)
|
||||
2. Commit the new prerequisite cards and frontmatter updates
|
||||
3. If you already committed docs mixed with code, cherry-pick the doc commits onto a clean base rather than reverting (avoids noisy add/revert history)
|
||||
**Saving work across resets:** It is acceptable to cherry-pick or rebase code commits from before the reset back onto the branch after adding the new card. This is a pragmatic exception — use it only when you are confident the saved work is still valid given the new prerequisite. When in doubt, redo the work from scratch.
|
||||
|
||||
The branch between attempts should contain only documentation. Code returns when prerequisites are satisfied and the next attempt succeeds.
|
||||
### Completing a chain
|
||||
|
||||
When the final leaf node is closed and no `status: active` cards remain:
|
||||
|
||||
1. **Rewrite all Mikado cards** to reflect their nature as historical documentation:
|
||||
- Remove transient technical details (specific version numbers, temporary workarounds) that won't matter in the future
|
||||
- Frame the content as "what to do if someone wanted to repeat this process"
|
||||
- Add appropriate context about what was learned
|
||||
2. **Add changelog information** in `docs/changelog.d/`
|
||||
3. The user reviews and merges the PR
|
||||
|
||||
### Build artifacts
|
||||
|
||||
Mikado resets apply to branch code, not build artifacts. Container images in the registry are independent of branch lifecycle:
|
||||
|
||||
- **Registry images** are build outputs cached in zot — tagged with commit SHAs, so each build is unique and traceable.
|
||||
- **Automatic builds** trigger when container changes merge to main. Use `mise run container-build-and-release` for manual dispatch.
|
||||
- **If a build succeeds but deployment fails**, the image is fine; the problem is elsewhere. Document what you learned and try again.
|
||||
- **If a build fails in CI**, no image is pushed. Fix the nix/dockerfile and re-merge or re-dispatch.
|
||||
- **Registry images** are build outputs cached in zot — tagged with commit SHAs, so each build is unique and traceable
|
||||
- **Automatic builds** trigger when container changes merge to main. Use `mise run container-build-and-release` for manual dispatch
|
||||
- **If a build succeeds but deployment fails**, the image is fine; the problem is elsewhere. Document what you learned and try again
|
||||
- **If a build fails in CI**, no image is pushed. Fix the nix/dockerfile and re-merge or re-dispatch
|
||||
|
||||
## Card Conventions
|
||||
|
||||
|
|
@ -111,12 +165,11 @@ tags:
|
|||
|
||||
### Git Discipline
|
||||
|
||||
- Single feature branch per C1/C2 change
|
||||
- **Create a PR early** — open a draft PR after the first doc commit so the user can review the Mikado graph as it evolves between iterations.
|
||||
- **Push after every iteration** — after completing a leaf node or documenting a failed attempt, push to origin. This is the save point for multi-session work.
|
||||
- Amend a single working commit as you iterate; keep the branch history clean
|
||||
- **C0:** Commit directly to main
|
||||
- **C1:** Single feature branch, PR early, push often
|
||||
- **C2:** Single feature branch, Mikado Branch Invariant enforced, PR early, push after every leaf-node closure
|
||||
- **Deploy from branches** — C1 and C2 changes deploy from the unmerged branch (ArgoCD `--revision`, Ansible from checkout, etc.). Reset to main after merge.
|
||||
- GitOps requires pushing to test — if a pushed commit breaks, revert it promptly
|
||||
- Commit doc updates noting what was learned from failures
|
||||
|
||||
## Tools
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ Task-oriented instructions for common BlumeOps operations. These guides assume y
|
|||
|-------|-------------|
|
||||
| [[review-documentation]] | Periodically review and maintain documentation |
|
||||
| [[review-services]] | Periodically review services for version freshness |
|
||||
| [[agent-change-process]] | C0/C1/C2 change classification and Mikado method for agents |
|
||||
| [[agent-change-process]] | C0/C1/C2 change classification and Mikado Branch Invariant |
|
||||
|
||||
## Operations
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: AI Assistance Guide
|
||||
modified: 2026-02-09
|
||||
modified: 2026-02-23
|
||||
tags:
|
||||
- tutorials
|
||||
- ai
|
||||
|
|
@ -22,13 +22,16 @@ These are non-negotiable for AI agents working in this repo:
|
|||
4. **Wait for user review before deploying** - Create PRs, don't auto-deploy
|
||||
5. **Never merge PRs without explicit request** - The user merges after review
|
||||
|
||||
Full rules are in the repo's `CLAUDE.md`. See [[agent-change-process]] for the C0/C1/C2 change classification methodology.
|
||||
Full rules are in the repo's `CLAUDE.md`. See [[agent-change-process]] for the C0/C1/C2 change classification methodology — C0 (direct to main), C1 (feature branch + PR), C2 (Mikado Branch Invariant).
|
||||
|
||||
## Workflow Conventions
|
||||
|
||||
### Feature Branches
|
||||
### Branching
|
||||
|
||||
All work happens on feature branches:
|
||||
Branching depends on change classification (see [[agent-change-process]]):
|
||||
|
||||
- **C0 (Quick Fix):** Commit directly to main — no branch or PR needed
|
||||
- **C1/C2:** Feature branch required:
|
||||
```bash
|
||||
git checkout main && git pull
|
||||
git checkout -b feature/descriptive-name
|
||||
|
|
@ -85,7 +88,7 @@ BlumeOps operations are driven by mise tasks. Run `mise tasks` to list all avail
|
|||
| Task | When to Use |
|
||||
|------|-------------|
|
||||
| `ai-docs` | At session start - review infrastructure documentation |
|
||||
| `docs-mikado` | View active Mikado dependency chains for C1/C2 changes |
|
||||
| `docs-mikado` | View active Mikado dependency chains for C2 changes |
|
||||
| `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 |
|
||||
|
|
@ -131,5 +134,5 @@ Credentials live in 1Password. Never retrieve them directly - use existing patte
|
|||
| 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 |
|
||||
| Committing to main without classifying | Classify as C0/C1/C2 first — only C0 goes to main |
|
||||
| Guessing at credentials | Ask user or check 1Password patterns |
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
# requires-python = ">=3.12"
|
||||
# dependencies = ["pyyaml>=6.0", "rich>=13.0.0", "typer>=0.15.0"]
|
||||
# ///
|
||||
#MISE description="View active Mikado dependency chains for C1/C2 changes"
|
||||
#MISE description="View active Mikado dependency chains for C2 changes"
|
||||
#USAGE arg "[card]" help="Card stem to show chain for"
|
||||
#USAGE flag "--all" help="Show all cards in full, including complete ones"
|
||||
"""View active Mikado dependency chains for C1/C2 changes.
|
||||
"""View active Mikado dependency chains for C2 changes.
|
||||
|
||||
Scans all markdown files in docs/ for YAML frontmatter with ``status: active``
|
||||
and ``requires`` fields, then builds and displays the Mikado dependency graph.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue