Every document filename now mirrors its lifecycle state with a status suffix (e.g., .draft.md, .wip.md, .accepted.md). No more bare .md for tracked document types. Also renamed all from_str methods to parse to avoid FromStr trait confusion, introduced StagingDeploymentParams struct, and fixed all 19 clippy warnings across the codebase. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
152 lines
5.7 KiB
Markdown
152 lines
5.7 KiB
Markdown
# Spike: Document Lifecycle Filenames
|
|
|
|
| | |
|
|
|---|---|
|
|
| **Status** | Complete |
|
|
| **Date** | 2026-01-26 |
|
|
| **Time Box** | 30 minutes |
|
|
|
|
---
|
|
|
|
## Question
|
|
|
|
How should Blue encode document lifecycle status in filenames so that browsing a directory reveals document state at a glance? What format works across all 9 document types, preserves lexicographic sorting, remains filesystem-safe, and integrates with the ISO 8601 timestamp work from RFC 0030?
|
|
|
|
---
|
|
|
|
## Investigation
|
|
|
|
### Current State
|
|
|
|
9 document types. Status stored in SQLite + markdown frontmatter. **Zero status information in filenames.**
|
|
|
|
| Type | Filename Pattern | Statuses | Browse Problem |
|
|
|---|---|---|---|
|
|
| RFC | `0030-slug.md` | draft, accepted, in-progress, implemented, superseded | Can't tell if draft or shipped |
|
|
| Spike | `2026-01-26-slug.md` | in-progress, complete (+outcome) | Can't tell if resolved |
|
|
| ADR | `0004-slug.md` | accepted, in-progress, implemented | Can't tell if active |
|
|
| Decision | `2026-01-26-slug.md` | recorded | Always same (no problem) |
|
|
| PRD | `0001-slug.md` | draft, approved, implemented | Can't tell if approved |
|
|
| Postmortem | `2026-01-26-slug.md` | open, closed | Can't tell if resolved |
|
|
| Runbook | `slug.md` | active, archived | Can't tell if current |
|
|
| Dialogue | `2026-01-26-slug.dialogue.md` | draft, published | Can't tell if final |
|
|
| Audit | `2026-01-26-slug.md` | in-progress, complete | Can't tell if done |
|
|
|
|
### Key Constraint: No Code Parses Filenames
|
|
|
|
From RFC 0030 investigation: `store.rs:2232` regex only extracts numbered doc prefixes. Document lookups use SQLite by title. **Renaming files does not break internal lookups** — only `file_path` in the documents table needs updating.
|
|
|
|
### Design Options
|
|
|
|
#### Option A: Status suffix before `.md`
|
|
|
|
```
|
|
0030-iso-8601-timestamps.draft.md → 0030-iso-8601-timestamps.impl.md
|
|
2026-01-26T0856Z-kanban-apps.wip.md → 2026-01-26T0856Z-kanban-apps.done.md
|
|
```
|
|
|
|
**Pros:** Clear at a glance, sorts by number/date first, status is visual suffix
|
|
**Cons:** Renaming on status change breaks git history, external links
|
|
|
|
#### Option B: Status prefix after number/date
|
|
|
|
```
|
|
0030-DRAFT-iso-8601-timestamps.md → 0030-IMPL-iso-8601-timestamps.md
|
|
2026-01-26T0856Z-WIP-kanban-apps.md → 2026-01-26T0856Z-DONE-kanban-apps.md
|
|
```
|
|
|
|
**Pros:** Status visible early in filename
|
|
**Cons:** Disrupts slug, ALL_CAPS is noisy, breaks cross-references
|
|
|
|
#### Option C: Status subdirectories
|
|
|
|
```
|
|
rfcs/draft/0030-iso-8601-timestamps.md → rfcs/implemented/0030-iso-8601-timestamps.md
|
|
spikes/active/2026-01-26T0856Z-kanban.md → spikes/complete/2026-01-26T0856Z-kanban.md
|
|
```
|
|
|
|
**Pros:** Clean filenames, easy browsing by status, familiar (like git branches)
|
|
**Cons:** Moving files between directories, deeper path nesting, complex for tools
|
|
|
|
#### Option D: Status dot-notation (minimal)
|
|
|
|
```
|
|
0030-iso-8601-timestamps.d.md → 0030-iso-8601-timestamps.i.md
|
|
```
|
|
|
|
**Pros:** Minimal visual noise
|
|
**Cons:** Single letter is cryptic, easy to miss
|
|
|
|
#### Option E: Combination — timestamp + status suffix
|
|
|
|
```
|
|
2026-01-26T0856Z-kanban-apps.spike.wip.md
|
|
2026-01-26T0856Z-kanban-apps.spike.done-rfc.md
|
|
0030-iso-8601-timestamps.rfc.draft.md
|
|
0030-iso-8601-timestamps.rfc.impl.md
|
|
```
|
|
|
|
**Pros:** Self-documenting (type + status), works across all doc types
|
|
**Cons:** Long filenames, multiple dots
|
|
|
|
### The Rename Problem
|
|
|
|
All status-in-filename approaches require renaming files when status changes. This has consequences:
|
|
|
|
1. **Git history**: `git log --follow` tracks renames, but `git blame` shows only current name
|
|
2. **Cross-references**: Markdown links like `[RFC 0030](../rfcs/0030-slug.md)` break on rename
|
|
3. **External bookmarks**: Browser bookmarks, shell aliases break
|
|
4. **SQLite file_path**: Must update `documents.file_path` on every rename
|
|
|
|
**Mitigation strategies:**
|
|
- Update `file_path` in store on every status change (already touches store + markdown)
|
|
- Cross-references use title-based lookups, not filename — most survive
|
|
- `git mv` preserves history tracking
|
|
- Accept that external bookmarks break (they already break on file deletion)
|
|
|
|
### Spike-Specific Requirements
|
|
|
|
The user specifically wants to see spike outcomes from filenames:
|
|
|
|
| Outcome | Meaning | Proposed Suffix |
|
|
|---|---|---|
|
|
| in-progress | Active investigation | `.wip` or no suffix |
|
|
| complete: no-action | Dead end | `.done` |
|
|
| complete: decision-made | Resolved with decision | `.done` |
|
|
| complete: recommends-implementation | Needs RFC | `.rfc` or `.done-rfc` |
|
|
|
|
### RFC-Specific Requirements
|
|
|
|
| Status | Proposed Suffix |
|
|
|---|---|
|
|
| draft | `.draft` or no suffix |
|
|
| accepted | `.accepted` |
|
|
| in-progress | `.wip` |
|
|
| implemented | `.impl` |
|
|
| superseded | `.super` |
|
|
|
|
### Status Abbreviation Vocabulary
|
|
|
|
A consistent set of short status tags across all document types:
|
|
|
|
| Tag | Meaning | Used By |
|
|
|---|---|---|
|
|
| (none) | Active/in-progress/draft (default) | All types |
|
|
| `.done` | Complete/closed/recorded | Spike, Audit, Postmortem |
|
|
| `.impl` | Implemented | RFC, ADR, PRD |
|
|
| `.super` | Superseded | RFC |
|
|
| `.archived` | Archived/inactive | Runbook |
|
|
|
|
## Findings
|
|
|
|
| Question | Answer |
|
|
|---------|--------|
|
|
| Can status live in filenames? | Yes — no internal code parses filenames for status |
|
|
| Best approach? | Option A (status suffix) or Option C (subdirectories) — needs alignment dialogue |
|
|
| Does this integrate with RFC 0030? | Yes — timestamp + status suffix: `2026-01-26T0856Z-slug.done.md` |
|
|
| What about the rename problem? | Manageable — `git mv` + store update + title-based lookups survive |
|
|
| Biggest risk? | Cross-reference breakage in markdown files |
|
|
|
|
## Outcome
|
|
|
|
Recommends implementation. This should supersede RFC 0030 by incorporating both ISO 8601 timestamps AND status-in-filename into a unified "Document Lifecycle Filenames" RFC.
|