Skip to content

Add plan-lifecycle rule: Plan → ADR lifecycle for non-trivial features #154

Description

@markcallen

Summary

Add .claude/rules/common/plan-lifecycle.md to codify the Plan → ADR lifecycle so Ballast can install it in any project via ballast init, the same way linting, testing, and git-hook rules are distributed.

Problem

The plan/ADR lifecycle currently lives in plans/plan-lifecycle.md in this repo only. It is not distributed to other projects via Ballast. Agents working in other repos have no guidance on how to create plans, maintain them during implementation, or graduate them to ADRs at merge time.

Goal

Make the plan → ADR lifecycle a first-class Ballast rule available to all projects.

Relationship to existing rules

Rule Concern
tasks-todo.md The TODO scratchpad file and PR triage gate
tasks-task-system.md Durable issue tracker (GitHub/Jira/Linear) and MCP setup
plan-lifecycle.md (new) Plan → ADR lifecycle for non-trivial features

The new rule should defer to tasks-todo.md as authoritative for tasks/todo.md behavior (the parking lot for discovered out-of-scope work) rather than re-specifying it. The graduation gate — all open TODO items resolved before merge — reinforces what tasks-todo.md already defines.

Deliverables

1. Create .claude/rules/common/plan-lifecycle.md

This rule is language-agnostic and belongs in common/ only — no per-language duplicates needed.

The rule must cover:

When to create a plan

Create a plan when:

  • The change touches more than 2 files
  • You are unsure of the approach
  • The feature takes more than one session to complete
  • The work involves architectural decisions

Skip a plan when:

  • Single-file fix (typo, log line, rename)
  • The entire change fits in one sentence

Directory structure

<project-root>/
├── plans/
│   ├── README.md
│   └── plan-<feature-name>.md
├── tasks/
│   └── todo.md                   ← discovered out-of-scope work, cleared at graduation
└── adr/
    ├── README.md
    └── NNN-<decision-title>.md

Plan template

File: plans/plan-<feature-name>.md (kebab-case, specific: plan-oauth-google.md not plan-auth.md)

# Plan: <Feature Name>

**Status:** In Progress
**Branch:** <branch-name>
**Created:** YYYY-MM-DD
**Related ADRs:** _(link any relevant existing ADRs)_

## Problem

What are we solving and why does it matter now?

## Approach

The chosen solution in plain language. What will change and how.

## Files Affected

- `src/...` — reason
- `tests/...` — reason

## Phases

- [ ] Phase 1: Explore and confirm approach
- [ ] Phase 2: Core implementation
- [ ] Phase 3: Tests and edge cases
- [ ] Phase 4: Documentation and cleanup

## Verification

How will we know this works? Commands, tests, or checks to run.

## Alternatives Rejected

| Option | Why rejected |
|--------|-------------|
| ...    | ...         |

## Open Questions

Things still to resolve. Remove entries as they are answered.

## Change Log

| Date | Change |
|------|--------|
| YYYY-MM-DD | Plan created |

After creating the plan, commit it and update plans/README.md.

Maintaining the plan during implementation

  • Check off phases as they complete
  • If approach changes, update Approach and note it in Change Log
  • Commit plan updates alongside code changes — not as a separate commit at the end
  • At the start of each session, read the plan to restore context
  • When you discover work that is real but out of scope for this feature, add it to tasks/todo.md (see tasks-todo.md rule) rather than expanding the plan

Graduation: graduating the plan to an ADR

When the feature is ready to merge, use the trigger phrase:

"Graduate plans/plan-<feature-name>.md to an ADR"

Graduation steps:

  1. Check tasks/todo.md for any incomplete items (- [ ]) added during this feature
  2. For each incomplete item: create a task system work item, then update the line to - [x] TASK-NNN: <description>
  3. Determine the next ADR number from adr/README.md
  4. Create adr/NNN-<decision-title>.md from the plan content
  5. Update adr/README.md with the new row
  6. Remove plans/plan-<feature-name>.md
  7. Update plans/README.md to remove the entry
  8. Commit: docs: graduate plan-<feature-name> to ADR-NNN

Graduation is blocked until all items in tasks/todo.md for this feature are either checked off or have a task system reference.

ADR template

# ADR-NNN: <Decision Title>

**Status:** Accepted
**Date:** YYYY-MM-DD
**Branch:** <branch-name>
**PR:** #<number>
**Supersedes:** _(ADR-NNN if replacing an earlier decision)_
**Superseded by:** _(leave blank)_

## Context

Why did this decision need to be made?

## Decision

What was chosen and why.

## Alternatives Considered

| Option | Reason not chosen |
|--------|------------------|
| ...    | ...              |

## Consequences

### Positive
- What becomes easier

### Negative or trade-offs
- What becomes harder or what we gave up

## Implementation Notes

Key details future readers should know.

## Verification

How the decision was validated.

## Lessons Learned

What would you do differently? What worked better than expected?

ADR management rules

Rule Detail
Never delete Mark superseded, create a new ADR
Sequential numbering Zero-padded three digits: 001, 002, 003
One decision per ADR Don't bundle unrelated decisions
Status values Accepted · Deprecated · Superseded

Quick reference

Situation Action
Starting a feature Create plans/plan-<name>.md, commit it
New session on existing feature "Continue implementing plans/plan-<name>.md"
Approach changed Update plan + Change Log, commit with code
Phase complete Check off in plan, commit
Discovered out-of-scope work Add to tasks/todo.md, commit alongside current change
Ready to merge "Graduate plans/plan-<name>.md to an ADR"
Graduation finds open todo items Create task system issues, add references to tasks/todo.md, then proceed
Decision reversed later Mark ADR Superseded, create new ADR
Small single-file fix Skip the plan entirely

2. Wire into Ballast installation

Ensure ballast init can distribute this rule to target repos.

3. Update CLAUDE.md installed rules list

Add the rule entry alongside the existing tasks rules:

- `.claude/rules/common/plan-lifecycle.md` — Rules for common/plan-lifecycle

Acceptance criteria

  • .claude/rules/common/plan-lifecycle.md exists and covers: when to create a plan, the plan template, how to maintain it during implementation, the graduation ceremony (plan → ADR), the ADR template, ADR management rules, and the quick reference table
  • The rule defers to tasks-todo.md for tasks/todo.md behaviour rather than duplicating it
  • Task system references are generic (not Jira-specific)
  • The rule is installable via Ballast and listed in CLAUDE.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions