From ff482c2b96b24de3f0eac7714da3dea7b25478cb Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Mon, 23 Feb 2026 16:08:26 -0800 Subject: [PATCH] Add C2 conventions: commit naming, branch naming, cold-start, finalize exception - Commit convention: C2(): plan/impl/close/finalize - Branch convention: mikado/ - Goal card branch: frontmatter linking chain to branch - Planning/research phase documented as first step of C2 - Cold-start session guidance via docs-mikado --resume - Finalize as explicit exception to the one rule - Verification happens on impl commits before closing leaf nodes - Document planned tooling (docs-mikado --resume, mikado-branch-invariant-check) Co-Authored-By: Claude Opus 4.6 --- docs/how-to/agent-change-process.md | 112 ++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 13 deletions(-) diff --git a/docs/how-to/agent-change-process.md b/docs/how-to/agent-change-process.md index 60d5db0..e531237 100644 --- a/docs/how-to/agent-change-process.md +++ b/docs/how-to/agent-change-process.md @@ -66,15 +66,26 @@ Upgrade to C2 if any of these happen during a C1 change: A complex, multi-session change managed through the [Mikado method](https://mikadomethod.info/) with a strict branch discipline called the **Mikado Branch Invariant**. +### Planning and research + +Before writing any code, invest in understanding the problem: + +1. Run `mise run ai-docs` to load context +2. Search related docs, reference cards, and existing how-to guides for the change area +3. Think through the dependency graph — what prerequisites exist? What could go wrong? +4. Create Mikado cards for everything you can anticipate (you'll discover more later — that's the point of the method) + +This planning phase can span multiple sessions. Cards introduced during planning are merged to main and become the foundation for work cycles later. + ### The Mikado Branch Invariant The invariant governs how commits are ordered on a C2 feature branch. The branch must always have this structure: ``` -main ← [card commits] ← [code, close] ← [code, close] ← ... ← [finalize] - ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +main ← [plan commits] ← [impl, close] ← [impl, close] ← ... ← [finalize] + ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Planning layer Repeating work cycles - (cards only) (code then close, one leaf at a time) + (cards only) (impl then close, one leaf at a time) ``` **Rules:** @@ -88,26 +99,81 @@ main ← [card commits] ← [code, close] ← [code, close] ← ... ← [finaliz **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. +**Exception — finalize:** The terminal commit of a completed chain rewrites Mikado cards to historical documentation. This is a card modification after code commits, and is the only permitted violation of the one rule (see "Completing a chain" below). + +### Conventions + +#### Branch naming + +C2 branches must be named `mikado/`, where `` is the filename stem of the goal card. Example: goal card `deploy-authentik.md` → branch `mikado/deploy-authentik`. + +#### Goal card `branch:` frontmatter + +The goal card of a C2 chain must include a `branch:` field once work begins: + +```yaml +--- +title: Deploy Authentik +status: active +branch: mikado/deploy-authentik +requires: + - configure-postgres + - setup-redis +tags: + - how-to +--- +``` + +A goal card with `status: active` but no `branch:` field indicates a chain that has been planned but not yet started — the planning-phase cards exist but no implementation branch has been created. + +#### Commit message convention + +All commits on a `mikado/*` branch must use this format: + +``` +C2(): +``` + +Verbs and their meanings: + +| Verb | Phase | What it means | +|------|-------|---------------| +| `plan` | Planning layer | Introduces or modifies a Mikado card (no code changes) | +| `impl` | Work cycle | Code progress toward closing a leaf node (no card changes) | +| `close` | Work cycle | Closes a leaf node by removing `status: active` | +| `finalize` | Terminal | Rewrites cards to historical docs, adds changelog | + +Examples: +``` +C2(deploy-authentik): plan add postgres and redis prerequisite cards +C2(deploy-authentik): impl configure external-secrets for authentik +C2(deploy-authentik): close configure-postgres +C2(deploy-authentik): finalize rewrite cards as historical documentation +``` + +The `mikado-branch-invariant-check` pre-commit hook validates this convention and the invariant ordering. + ### Process 1. **Goal card:** Create a how-to doc in `docs/how-to/` describing the desired end state - - Add `status: active` to frontmatter + - Add `status: active` and `branch: mikado/` to frontmatter - Create prerequisite cards discovered during planning, each with `status: active` - - Commit all cards together (or in a sequence of card-only commits) + - Commit all cards together (or in a sequence of card-only commits) using `C2(): plan ...` messages 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`) + - Commit code changes (`C2(): impl ...`) that progress toward closing it + - **Verify the change works** (deploy from branch, run tests, etc.) before closing + - Commit the card closure (`C2(): close ...`) — 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` +5. **New agent sessions** pick up state by running `mise run docs-mikado --resume` ### Discovering new prerequisites When you discover a new prerequisite during code work, you must restore the Mikado Branch Invariant: -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) +1. **Reset the branch** back to the top of the Mikado commit stack — the last `C2(): plan` or `C2(): close` commit before your current `impl` commits +2. **Add a new commit** (`C2(): plan ...`) 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 **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. @@ -120,8 +186,22 @@ When the final leaf node is closed and no `status: active` cards remain: - 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 + - Remove `branch:` from the goal card frontmatter 2. **Add changelog information** in `docs/changelog.d/` -3. The user reviews and merges the PR +3. Commit as `C2(): finalize ...` — this is the one permitted exception to the invariant's "no card changes after code" rule +4. The user reviews and merges the PR + +### Cold-start: resuming a chain in a new session + +When starting a new session to continue C2 work: + +1. Run `mise run ai-docs` to load context +2. Run `mise run docs-mikado --resume` — this will: + - Detect the current branch and match it to an active chain + - Show the chain state, ready leaf nodes, and current position in the invariant + - If on main, list active chains and suggest which to resume +3. Check PR comments with `mise run pr-comments ` +4. Pick the next ready leaf node and continue with a work cycle ### Build artifacts @@ -140,6 +220,7 @@ Mikado resets apply to branch code, not build artifacts. Container images in the --- title: Deploy Authentik status: active # omit when complete +branch: mikado/deploy-authentik # goal cards only; omit when complete requires: # explicit dependencies - configure-postgres - setup-redis @@ -149,6 +230,7 @@ tags: ``` - `status: active` marks in-progress work; remove when done (this is the ONLY way a card is marked complete) +- `branch` is set on goal cards only, linking the card to its `mikado/` branch. A goal card with `status: active` but no `branch` indicates a chain that is planned but not yet started. Remove `branch` when the chain is finalized. - `requires` lists card stems (filenames without `.md`) that must be completed first. **Keep `requires` permanently** even after prerequisites are done — it documents the dependency graph history - `required-by` is NOT stored — it's computed by `docs-mikado` @@ -164,7 +246,7 @@ tags: - **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 +- **C2:** Branch named `mikado/`, Mikado Branch Invariant enforced, `C2()` commit convention, 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 @@ -172,9 +254,13 @@ tags: | Command | Purpose | |---------|---------| -| `mise run docs-mikado` | List all active Mikado chains | +| `mise run docs-mikado` | List all active Mikado chains with branch status | | `mise run docs-mikado ` | Show dependency chain for a goal card | | `mise run docs-mikado --all` | Include completed cards in full | +| `mise run docs-mikado --resume` | Resume a chain: detect branch, show state and next steps | +| `mise run docs-mikado --resume ` | Resume a specific chain with branch consistency check | + +The `mikado-branch-invariant-check` pre-commit hook runs automatically on `mikado/*` branches, validating commit message conventions and invariant ordering. ## Related