Alignment dialogues now use custom `alignment-expert` subagents with max_turns: 10, tool restrictions (Read/Grep/Glob), and hard 400-word output limits. Judge protocol injects as prose via RFC 0023. Moved Blue voice patterns from CLAUDE.md to MCP server instructions field for cross-repo portability. Includes RFCs 0017-0026, spikes, and alignment dialogues from 2026-01-25/26 sessions. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
206 lines
5.8 KiB
Markdown
206 lines
5.8 KiB
Markdown
# RFC 0017: Plan File Authority
|
|
|
|
| | |
|
|
|---|---|
|
|
| **Status** | Superseded |
|
|
| **Superseded By** | [RFC 0022: Filesystem Authority](./0022-filesystem-authority.md) |
|
|
| **Date** | 2026-01-26 |
|
|
| **Dialogue** | [0001: Plan Files And Dialogue Separation](../dialogues/2026-01-25-plan-files-and-dialogue-separation.dialogue.md) |
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
RFC task tracking currently requires loading entire RFC documents to check status. This creates token inefficiency and couples operational state with design documentation. By introducing `.plan.md` companion files as the authoritative source for task state (with SQLite as a derived index rebuilt on read), we achieve: 60-80% token reduction for status operations, cleaner git diffs, surgical commits, and separation of ephemeral operational state from permanent documentation.
|
|
|
|
## Problem
|
|
|
|
1. **Token Waste**: Loading a 2000-line RFC to check task status wastes tokens
|
|
2. **Coupled Concerns**: Operational state (tasks) mixed with design documentation (RFC content)
|
|
3. **Noisy Diffs**: Task status changes pollute RFC git history
|
|
4. **Cross-Repo Limitation**: When using Blue from another repo, no plan file support exists
|
|
5. **Header Format Drift**: RFC headers have drifted between table and inline formats
|
|
|
|
### Header Format Drift
|
|
|
|
The canonical RFC header uses a metadata table:
|
|
|
|
```markdown
|
|
# RFC 0058: Remove Training Infrastructure
|
|
|
|
| | |
|
|
|---|---|
|
|
| **Status** | Accepted |
|
|
| **Created** | 2026-01-24 |
|
|
| **Dialogue** | [0058-remove-training...](./0058-remove-training...) |
|
|
```
|
|
|
|
But some RFCs use inline format:
|
|
|
|
```markdown
|
|
# RFC 0075: Spot Capacity Providers
|
|
|
|
**Status**: Draft
|
|
**Created**: 2026-01-25
|
|
**Author**: Claude
|
|
```
|
|
|
|
The table format is canonical. Blue's `to_markdown()` generates it correctly, but manually-created or external RFCs may drift.
|
|
|
|
## Architecture
|
|
|
|
### Authority Inversion
|
|
|
|
The key insight: make `.plan.md` **authoritative**, not derived.
|
|
|
|
```
|
|
CURRENT (problematic):
|
|
RFC.md (source) → SQLite (derived) → .plan.md (derived)
|
|
Drift accumulates at each derivation step.
|
|
|
|
PROPOSED:
|
|
.plan.md (authoritative) → SQLite (derived index, rebuild-on-read)
|
|
Single source of truth. SQLite is ephemeral cache.
|
|
```
|
|
|
|
### File Structure
|
|
|
|
```
|
|
.blue/docs/rfcs/
|
|
├── 0017-plan-file-authority.md # Design documentation (permanent)
|
|
├── 0017-plan-file-authority.plan.md # Task state (ephemeral scaffolding)
|
|
└── ...
|
|
```
|
|
|
|
### Plan File Format
|
|
|
|
```markdown
|
|
# Plan: 0017-plan-file-authority
|
|
|
|
| | |
|
|
|---|---|
|
|
| **RFC** | 0017-plan-file-authority |
|
|
| **Status** | in-progress |
|
|
| **Updated** | 2026-01-26T10:30:00Z |
|
|
|
|
## Tasks
|
|
|
|
- [x] Define architecture
|
|
- [x] Run alignment dialogue
|
|
- [ ] Implement plan file parsing
|
|
- [ ] Add rebuild-on-read to SQLite
|
|
- [ ] Update blue_rfc_plan tool
|
|
- [ ] Update blue_rfc_task_complete tool
|
|
- [ ] Write tests
|
|
```
|
|
|
|
### Atomic Update Sequence
|
|
|
|
To prevent drift during writes:
|
|
|
|
```
|
|
1. Set RFC status: "updating-plan"
|
|
2. Write .plan.md file
|
|
3. Clear RFC status flag
|
|
4. SQLite rebuilds on next read
|
|
```
|
|
|
|
If interrupted between steps 1-3, the status flag indicates recovery needed.
|
|
|
|
### SQLite as Derived Index
|
|
|
|
```rust
|
|
// On any plan query:
|
|
fn get_plan_tasks(rfc_id: &str) -> Vec<Task> {
|
|
let plan_file = format!("{}.plan.md", rfc_id);
|
|
|
|
if plan_file.exists() && plan_file.mtime() > cache.mtime() {
|
|
// Rebuild cache from authoritative source
|
|
let tasks = parse_plan_markdown(&plan_file);
|
|
cache.rebuild(rfc_id, &tasks);
|
|
}
|
|
|
|
cache.get_tasks(rfc_id)
|
|
}
|
|
```
|
|
|
|
### API Unchanged
|
|
|
|
Existing tools work identically:
|
|
|
|
- `blue_rfc_plan` - Creates/updates `.plan.md` (now authoritative)
|
|
- `blue_rfc_task_complete` - Marks task done in `.plan.md`
|
|
|
|
Callers don't know or care about the authority change.
|
|
|
|
## Guardrails
|
|
|
|
From Git Workflow Expert (converged dialogue):
|
|
|
|
1. **Status Gating**: Plans only for `accepted` or `in-progress` RFCs
|
|
2. **File Limit**: Maximum 3 companion files per RFC (plan, test-plan, architecture notes)
|
|
3. **Single Responsibility**: Each companion file serves exactly one purpose
|
|
|
|
### Header Format Validation
|
|
|
|
Add `blue_lint` validation for RFC header format:
|
|
|
|
```rust
|
|
fn validate_rfc_header(content: &str) -> Result<(), LintError> {
|
|
// Must have table format, not inline
|
|
if content.contains("**Status**:") {
|
|
return Err(LintError::HeaderFormat {
|
|
expected: "| **Status** | value |",
|
|
found: "**Status**: value",
|
|
});
|
|
}
|
|
|
|
// Must have table structure
|
|
if !content.contains("| | |\n|---|---|") {
|
|
return Err(LintError::MissingMetadataTable);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
The `blue_lint` tool should:
|
|
- Detect inline format (`**Status**: value`)
|
|
- Offer auto-fix to convert to table format
|
|
- Run on `blue_rfc_create` to catch manual edits
|
|
|
|
## Key Insight
|
|
|
|
> "Plans are like scaffolding - essential during construction, removed after completion."
|
|
|
|
The `.plan.md` file is **operational state**, not **documentation**. It exists to track work, then can be deleted or archived when the RFC completes. This "ephemeral framing" resolved documentation cohesion objections in the alignment dialogue.
|
|
|
|
## References
|
|
|
|
- **ADR 0005**: Single Source of Truth
|
|
- **ADR 0006**: Relationships (file co-location)
|
|
- **Dialogue 0001**: 12-expert alignment achieved 100% convergence on this architecture
|
|
|
|
## Test Plan
|
|
|
|
### Plan Files
|
|
- [ ] Create plan file for existing RFC
|
|
- [ ] Verify SQLite rebuilds from plan on read
|
|
- [ ] Verify atomic update sequence handles interruption
|
|
- [ ] Verify blue_rfc_plan creates companion file
|
|
- [ ] Verify blue_rfc_task_complete updates companion file
|
|
- [ ] Test cross-repo usage (Blue in external project)
|
|
- [ ] Verify status gating (no plans for draft RFCs)
|
|
|
|
### Header Format Validation
|
|
- [ ] Detect inline format (`**Status**: Draft`)
|
|
- [ ] Auto-fix inline to table format
|
|
- [ ] Validate table structure exists
|
|
- [ ] blue_lint reports header format errors
|
|
- [ ] blue_lint --fix converts inline to table
|
|
|
|
---
|
|
|
|
*"Right then. Let's get to it."*
|
|
|
|
— Blue
|