Compare commits

...
Author SHA1 Message Date
Tabish Bidiwale 7ae14d5858 simplify status command proposal to minimal scope 2025-08-06 21:17:53 +10:00
Tabish Bidiwale e08f1a2e60 feat: add change proposal for status command 2025-08-06 18:09:08 +10:00
Tabish Bidiwale d00d66a89d Merge pull request #4 from Fission-AI/adopt-future-state-storage
feat: adopt future state storage for OpenSpec changes
2025-08-06 17:35:05 +10:00
Tabish Bidiwale cb5ac65d03 feat: adopt future state storage for OpenSpec changes 2025-08-06 16:50:00 +10:00
Tabish Bidiwale 4564229a60 Merge pull request #3 from Fission-AI/update-spec-change-format
feat: Update spec change format
2025-08-06 15:52:48 +10:00
Tabish Bidiwale 79c4fa3122 Merge pull request #2 from Fission-AI/add-project-init-change
feat: add change proposal for openspec init command
2025-08-06 15:52:00 +10:00
Tabish Bidiwale 6b8845b10a remove any updates to the proposal format 2025-08-06 15:42:19 +10:00
Tabish Bidiwale b5be00bfe5 Add change for updating spec storage format 2025-08-06 14:26:19 +10:00
Tabish Bidiwale f479e15075 Revert test changes 2025-08-06 14:06:05 +10:00
Tabish Bidiwale c111c18043 improve diff format readability with unified diff headers and preview file 2025-08-05 23:29:19 +10:00
Tabish Bidiwale 6b09fa6efe feat: add change proposal for openspec init command 2025-08-05 23:15:13 +10:00
Tabish Bidiwale 79972cf9b1 docs: clarify patch requirements for new capabilities 2025-08-05 23:11:17 +10:00
Tabish Bidiwale 1bb8f10a3f docs: update OpenSpec workflow to use two-PR approach 2025-08-05 22:56:04 +10:00
Tabish Bidiwale ed04971e14 Merge pull request #1 from Fission-AI/project-setup
feat: initialize typescript project
2025-08-05 22:49:35 +10:00
12 changed files with 689 additions and 19 deletions
+77 -19
View File
@@ -26,9 +26,9 @@ openspec/
│ │ ├── proposal.md # Why, what, impact (consolidated)
│ │ ├── tasks.md # Implementation checklist
│ │ ├── design.md # Technical decisions (optional, for complex changes)
│ │ └── patches/ # Spec intent changes
│ │ └── specs/ # Future state of affected specs
│ │ └── [capability]/
│ │ └── spec.md.diff
│ │ └── spec.md # Clean markdown (no diff syntax)
│ └── archive/ # Completed changes (dated)
```
@@ -91,10 +91,13 @@ openspec/changes/[descriptive-name]/
- Affected specs: [list capabilities that will change]
- Affected code: [list key files/systems]
# 3. Create patches showing spec changes
patches/
# 3. Create future state specs for ALL affected capabilities
# - Store complete spec files as they will exist after the change
# - Use clean markdown without diff syntax (+/- prefixes)
# - Include all formatting and structure of the final intended state
specs/
└── [capability]/
└── spec.md.diff
└── spec.md
# 4. Create tasks.md with implementation steps
## 1. [Task Group]
@@ -109,7 +112,7 @@ patches/
1. **Propose** → Create change directory with all documentation
2. **Review** → User reviews and approves the proposal
3. **Implement** → Follow the approved tasks.md
3. **Implement** → Follow the approved tasks.md (can be multiple PRs)
4. **Deploy** → User confirms deployment
5. **Update Specs** → Sync specs/ with new reality (IF the change affects system capabilities)
6. **Archive** → Move to `changes/archive/YYYY-MM-DD-[name]/`
@@ -118,15 +121,25 @@ patches/
When implementing an approved change:
1. Follow the tasks.md checklist exactly
2. Ensure code matches the proposed behavior
3. Update any affected tests
2. **Mark completed tasks** in tasks.md as you finish them (e.g., `- [x] 1.1 Task completed`)
3. Ensure code matches the proposed behavior
4. Update any affected tests
5. **Keep change in `changes/` directory** - do NOT archive in implementation PR
### 6. Updating Specs After Deployment
**Multiple Implementation PRs:**
- Changes can be implemented across multiple PRs
- Each PR should update tasks.md to mark what was completed
- Different developers can work on different task groups
- Example: PR #1 completes tasks 1.1-1.3, PR #2 completes tasks 2.1-2.4
Once a change is deployed:
1. Update relevant files in `specs/` to reflect new reality
2. If design.md exists, move proven patterns to `specs/[capability]/design.md`
3. Archive the change directory with date prefix
### 6. Updating Specs and Archiving After Deployment
**Create a separate PR after deployment** that:
1. Moves change to `changes/archive/YYYY-MM-DD-[name]/`
2. Updates relevant files in `specs/` to reflect new reality (if needed)
3. If design.md exists, incorporates proven patterns into `specs/[capability]/design.md`
This ensures changes are only archived when truly complete and deployed.
### 7. Types of Changes That Don't Require Specs
@@ -201,9 +214,10 @@ User: "Initialize TypeScript project"
You should:
1. Create change proposal for TypeScript setup
2. Implement configuration files
3. Mark tasks complete
4. Archive (no specs needed - this is tooling, not a capability)
2. Implement configuration files (PR #1)
3. Mark tasks complete in tasks.md
4. After deployment, create separate PR to archive
(no specs update needed - this is tooling, not a capability)
```
## Summary Workflow
@@ -212,9 +226,53 @@ You should:
2. **Read current state** → Check specs and pending changes
3. **Create proposal** → Generate complete change documentation
4. **Get approval** → User reviews the proposal
5. **Implement** → Follow approved tasks
6. **Update specs** → Sync with deployed reality
7. **Archive** → Move completed changes to archive
5. **Implement** → Follow approved tasks, mark completed items in tasks.md
6. **Deploy** → User deploys the implementation
7. **Archive PR** → Create separate PR to:
- Move change to archive
- Update specs if needed
- Mark change as complete
## PR Workflow Examples
### Single Developer, Simple Change
```
PR #1: Implementation
- Implement all tasks
- Update tasks.md marking items complete
- Get merged and deployed
PR #2: Archive (after deployment)
- Move changes/feature-x/ → changes/archive/2025-01-15-feature-x/
- Update specs if needed
```
### Multiple Developers, Complex Change
```
PR #1: Alice implements auth components
- Complete tasks 1.1, 1.2, 1.3
- Update tasks.md marking these complete
PR #2: Bob implements UI components
- Complete tasks 2.1, 2.2
- Update tasks.md marking these complete
PR #3: Alice fixes integration issues
- Complete remaining task 1.4
- Update tasks.md
[Deploy all changes]
PR #4: Archive
- Move to archive with deployment date
- Update specs to reflect new auth flow
```
### Key Rules
- **Never archive in implementation PRs** - changes aren't done until deployed
- **Always update tasks.md** - shows accurate progress
- **One archive PR per change** - clear completion boundary
- **Archive PR includes spec updates** - keeps specs current
## Capability Organization Best Practices
+104
View File
@@ -0,0 +1,104 @@
# Technical Design for Init Command
## Architecture Overview
The init command follows a modular architecture with clear separation of concerns:
```
CLI Layer (src/cli/index.ts)
↓
Core Logic (src/core/init.ts)
↓
Templates (src/core/templates/)
↓
File System Utils (src/utils/file-system.ts)
```
## Key Design Decisions
### 1. Template Management
**Decision**: Store templates as TypeScript modules rather than separate files
**Rationale**:
- Ensures templates are bundled with the compiled code
- Allows for dynamic content insertion
- Type-safe template handling
- No need for complex file path resolution
### 2. Interactive vs Non-Interactive Mode
**Decision**: Support both interactive (default) and non-interactive modes
**Rationale**:
- Interactive mode for developer experience
- Non-interactive for CI/CD and automation
- Flags: `--yes` to accept defaults, `--no-input` for full automation
### 3. Directory Structure Creation
**Decision**: Create all directories upfront, then populate files
**Rationale**:
- Fail fast if permissions issues
- Clear transaction boundary
- Easier to clean up on failure
### 4. Error Handling Strategy
**Decision**: Implement rollback on failure
**Rationale**:
- Prevent partial installations
- Clear error states
- Better user experience
## Implementation Details
### File System Operations
```typescript
// Atomic directory creation with rollback
interface InitTransaction {
createdPaths: string[];
rollback(): Promise<void>;
commit(): Promise<void>;
}
```
### Template System
```typescript
interface Template {
path: string;
content: string | ((context: ProjectContext) => string);
}
interface ProjectContext {
projectName: string;
description: string;
techStack: string[];
conventions: string;
}
```
### CLI Command Structure
```bash
openspec init [path] # Initialize in specified path (default: current directory)
--yes # Accept all defaults
--no-input # Skip all prompts
--force # Overwrite existing OpenSpec directory
--dry-run # Show what would be created
```
## Security Considerations
1. **Path Traversal**: Sanitize all user-provided paths
2. **File Permissions**: Check write permissions before starting
3. **Existing Files**: Never overwrite without explicit --force flag
4. **Template Injection**: Sanitize user inputs in templates
## Future Extensibility
The design supports future enhancements:
- Custom template sources
- Project type presets (API, web app, library)
- Migration from other documentation systems
- Integration with version control systems
@@ -0,0 +1,25 @@
# Add Init Command for OpenSpec
## Why
Projects need a simple way to adopt OpenSpec conventions. Currently, users must manually create the directory structure and understand all the conventions, which creates friction for adoption. An init command would enable instant OpenSpec setup with proper structure and guidance.
## What Changes
- Add `openspec init` CLI command that creates the complete OpenSpec directory structure
- Generate template files (README.md with AI instructions, project.md template)
- Interactive prompts to gather project-specific information
- Validation to prevent overwriting existing OpenSpec structures
- Clear success/error messages to guide users
### Breaking Changes
- None - this is a new feature
## Impact
- Affected specs: None (new feature)
- Affected code:
- src/cli/index.ts (add init command)
- src/core/init.ts (new - initialization logic)
- src/core/templates/ (new - template files)
- src/utils/file-system.ts (new - file operations)
@@ -0,0 +1,66 @@
# CLI Init Specification
## Purpose
The `openspec init` command SHALL create a complete OpenSpec directory structure in any project, enabling immediate adoption of OpenSpec conventions.
## Behavior
### Directory Creation
WHEN `openspec init` is executed
THEN create the following directory structure:
```
openspec/
├── project.md
├── README.md
├── specs/
└── changes/
└── archive/
```
### File Generation
The command SHALL generate:
- `README.md` containing complete OpenSpec instructions for AI assistants
- `project.md` with customizable project context template
### Interactive Mode (Default)
WHEN run without flags
THEN prompt user for:
- Project name
- Project description
- Technology stack
- Key conventions
### Non-Interactive Mode
WHEN run with `--yes` flag
THEN use sensible defaults for all prompts
WHEN run with `--no-input` flag
THEN skip all prompts and use minimal defaults
### Safety Checks
WHEN `openspec/` directory already exists
THEN exit with error unless `--force` flag is provided
WHEN `--force` flag is provided
THEN backup existing directory before overwriting
### Exit Codes
- 0: Success
- 1: OpenSpec directory already exists
- 2: Insufficient permissions
- 3: User cancelled operation
## Why
Manual creation of OpenSpec structure is error-prone and creates adoption friction. A standardized init command ensures:
- Consistent structure across all projects
- Proper AI instruction files are always included
- Quick onboarding for new projects
- Clear conventions from the start
@@ -0,0 +1,30 @@
# Implementation Tasks for Init Command
## 1. Core Infrastructure
- [ ] 1.1 Create src/utils/file-system.ts with directory/file creation utilities
- [ ] 1.2 Create src/core/templates/index.ts for template management
- [ ] 1.3 Create src/core/init.ts with main initialization logic
## 2. Template Files
- [ ] 2.1 Create src/core/templates/readme-template.ts with OpenSpec README content
- [ ] 2.2 Create src/core/templates/project-template.ts with customizable project.md
- [ ] 2.3 Create src/core/templates/gitignore-template.ts for OpenSpec-specific ignores
## 3. Init Command Implementation
- [ ] 3.1 Add init command to src/cli/index.ts using Commander
- [ ] 3.2 Implement interactive prompts for project information
- [ ] 3.3 Add validation for existing OpenSpec directories
- [ ] 3.4 Implement directory structure creation logic
- [ ] 3.5 Implement file generation with templates
## 4. User Experience
- [ ] 4.1 Add colorful console output for better UX
- [ ] 4.2 Implement progress indicators during creation
- [ ] 4.3 Add success message with next steps
- [ ] 4.4 Add error handling with helpful messages
## 5. Testing and Documentation
- [ ] 5.1 Add unit tests for file system utilities
- [ ] 5.2 Add integration tests for init command
- [ ] 5.3 Update package.json with proper bin configuration
- [ ] 5.4 Test the built CLI command end-to-end
@@ -0,0 +1,19 @@
# Add Status Command to OpenSpec CLI
## Why
Developers need to know which changes have all tasks completed and are ready to archive.
## What Changes
- Add `openspec status` command that scans the changes/ directory
- Parse each tasks.md file to count `[x]` (complete) and `[ ]` (incomplete) tasks
- Display each change with its completion status (e.g., "auth-feature: 5/5" or "auth-feature: ✓")
- Skip the archive/ subdirectory
## Impact
- Affected specs: New capability `cli-status` will be added
- Affected code:
- `src/cli/index.ts` - Add status command
- `src/core/status.ts` - New file with simple scanning and parsing logic (~50 lines)
@@ -0,0 +1,58 @@
# CLI Status Command Specification
## Purpose
The status command shows which OpenSpec changes are ready to archive by displaying task completion status for each change.
## Command Interface
```bash
# Show status of all changes
openspec status
```
## Behavior
WHEN the status command runs:
1. Scan the `openspec/changes/` directory
2. Skip the `archive/` subdirectory
3. For each change directory with a `tasks.md` file:
- Count tasks marked with `[x]` (case-insensitive)
- Count tasks marked with `[ ]`
- Display the change name and completion status
## Output Format
```
add-auth-feature: 15/15
fix-payment-bug: 8/8
refactor-api: 3/10
update-docs: 0/5
```
Or with checkmark for fully complete:
```
add-auth-feature: ✓
fix-payment-bug: ✓
refactor-api: 3/10
update-docs: 0/5
```
## Task Detection
The command recognizes these patterns as tasks:
- `- [ ]` Incomplete task
- `- [x]` Complete task (lowercase)
- `- [X]` Complete task (uppercase)
## Error Handling
- If no `tasks.md` exists, skip that change
- If `tasks.md` is empty or has no tasks, skip that change
- Continue scanning even if individual files have errors
## Exit Codes
- `0`: Success - status displayed
- `1`: Error - unable to scan changes directory
@@ -0,0 +1,8 @@
# Implementation Tasks for Status Command
## Core Implementation
- [ ] Add status command to `src/cli/index.ts`
- [ ] Create `src/core/status.ts` with directory scanning logic
- [ ] Parse tasks.md files to count `[x]` and `[ ]` patterns
- [ ] Display each change with completion status (name: complete/total)
- [ ] Skip the archive/ subdirectory when scanning
@@ -0,0 +1,24 @@
# Adopt Future State Storage for OpenSpec Changes
## Why
The current approach of storing spec changes as diff files (`.spec.md.diff`) creates friction for both humans and AI. Diff syntax with `+` and `-` prefixes makes specs hard to read, AI tools struggle with the format when understanding future state, and GitHub can't show nice comparisons between current and proposed specs in different folders.
## What Changes
- Change from storing diffs (`patches/[capability]/spec.md.diff`) to storing complete future state (`specs/[capability]/spec.md`)
- Update all documentation to reflect new storage format
- Migrate existing `add-init-command` change to new format
- Add new `openspec-conventions` capability to document these conventions
## Impact
- Affected specs: New `openspec-conventions` capability
- Affected code:
- openspec/README.md (lines 85-108)
- docs/PRD.md (lines 376-382, 778-783)
- docs/openspec-walkthrough.md (lines 58-62, 112-126)
- openspec/changes/add-init-command/ (migration needed)
@@ -0,0 +1,120 @@
# OpenSpec Conventions Specification
## Purpose
OpenSpec conventions SHALL define how system capabilities are documented, how changes are proposed and tracked, and how specifications evolve over time. This meta-specification serves as the source of truth for OpenSpec's own conventions.
## Core Principles
The system SHALL follow these principles:
- Specs reflect what IS currently built and deployed
- Changes contain proposals for what SHOULD be changed
- AI drives the documentation process
- Specs are living documentation kept in sync with deployed code
## Directory Structure
WHEN an OpenSpec project is initialized
THEN it SHALL have this structure:
```
openspec/
├── project.md # Project-specific context
├── README.md # AI assistant instructions
├── specs/ # Current deployed capabilities
│ └── [capability]/ # Single, focused capability
│ ├── spec.md # WHAT and WHY
│ └── design.md # HOW (optional, for established patterns)
└── changes/ # Proposed changes
├── [change-name]/ # Descriptive change identifier
│ ├── proposal.md # Why, what, and impact
│ ├── tasks.md # Implementation checklist
│ ├── design.md # Technical decisions (optional)
│ └── specs/ # Complete future state
│ └── [capability]/
│ └── spec.md # Clean markdown (no diff syntax)
└── archive/ # Completed changes
└── YYYY-MM-DD-[name]/
```
## Change Storage Convention
### Future State Storage
WHEN creating a change proposal
THEN store the complete future state of affected specs
AND use clean markdown without diff syntax
The `changes/[name]/specs/` directory SHALL contain:
- Complete spec files as they will exist after the change
- Clean markdown without `+` or `-` prefixes
- All formatting and structure of the final intended state
### Proposal Format
WHEN documenting what changes
THEN the proposal SHALL explicitly describe each change:
```markdown
**[Section or Behavior Name]**
- From: [current state/requirement]
- To: [future state/requirement]
- Reason: [why this change is needed]
- Impact: [breaking/non-breaking, who's affected]
```
This explicit format compensates for not having inline diffs and ensures reviewers understand exactly what will change.
## Change Lifecycle
The change process SHALL follow these states:
1. **Propose**: AI creates change with future state specs and explicit proposal
2. **Review**: Humans review proposal and future state
3. **Approve**: Change is approved for implementation
4. **Implement**: Follow tasks.md checklist (can span multiple PRs)
5. **Deploy**: Changes are deployed to production
6. **Update**: Specs in `specs/` are updated to match deployed reality
7. **Archive**: Change is moved to `archive/YYYY-MM-DD-[name]/`
## Viewing Changes
WHEN reviewing proposed changes
THEN reviewers can compare using:
- GitHub PR diff view when changes are committed
- Command line: `diff -u specs/[capability]/spec.md changes/[name]/specs/[capability]/spec.md`
- Any visual diff tool comparing current vs future state
The system relies on tools to generate diffs rather than storing them.
## Capability Naming
Capabilities SHALL use:
- Verb-noun patterns (e.g., `user-auth`, `payment-capture`)
- Hyphenated lowercase names
- Singular focus (one responsibility per capability)
- No nesting (flat structure under `specs/`)
## When Changes Require Proposals
A proposal SHALL be created for:
- New features or capabilities
- Breaking changes to existing behavior
- Architecture or pattern changes
- Performance optimizations that change behavior
- Security updates affecting access patterns
A proposal is NOT required for:
- Bug fixes restoring intended behavior
- Typos or formatting fixes
- Non-breaking dependency updates
- Adding tests for existing behavior
- Documentation clarifications
## Why This Approach
Clean future state storage provides:
- **Readability**: No diff syntax pollution
- **AI-compatibility**: Standard markdown that AI tools understand
- **Simplicity**: No special parsing or processing needed
- **Tool-agnostic**: Any diff tool can show changes
- **Clear intent**: Explicit proposals document reasoning
@@ -0,0 +1,38 @@
# Implementation Tasks
## 1. Update Core Documentation
- [x] 1.1 Update openspec/README.md section on "Creating a Change Proposal"
- [x] Replace `patches/` with `specs/` in directory structure
- [x] Update step 3 to show storing complete future state
- [x] Remove diff syntax instructions (+/- prefixes)
## 2. Migrate Existing Change
- [x] 2.1 Convert add-init-command change to new format
- [x] Create `specs/cli-init/spec.md` with clean content (no diff markers)
- [x] Delete old `patches/` directory
- [x] 2.2 Test that the migrated change is clear and reviewable
## 3. Update Documentation Examples
- [x] 3.1 Update docs/PRD.md
- [x] Fix directory structure examples (lines 376-382)
- [x] Update archive examples (lines 778-783)
- [x] Ensure consistency throughout
- [x] 3.2 Update docs/openspec-walkthrough.md
- [x] Replace diff examples with future state examples
- [x] Ensure the walkthrough reflects new approach
## 4. Create New Spec
- [x] 4.1 Finalize openspec-conventions spec in main specs/ directory
- [x] Document the future state storage approach
- [x] Include examples of good proposals
- [x] Make it the source of truth for conventions
## 5. Validation
- [x] 5.1 Verify all documentation is consistent
- [x] 5.2 Test creating a new change with the new approach
- [x] 5.3 Ensure GitHub PR view shows diffs clearly
## 6. Deployment
- [ ] 6.1 Get approval for this change
- [ ] 6.2 Implement all tasks above
- [ ] 6.3 After deployment, archive this change with completion date
+120
View File
@@ -0,0 +1,120 @@
# OpenSpec Conventions Specification
## Purpose
OpenSpec conventions SHALL define how system capabilities are documented, how changes are proposed and tracked, and how specifications evolve over time. This meta-specification serves as the source of truth for OpenSpec's own conventions.
## Core Principles
The system SHALL follow these principles:
- Specs reflect what IS currently built and deployed
- Changes contain proposals for what SHOULD be changed
- AI drives the documentation process
- Specs are living documentation kept in sync with deployed code
## Directory Structure
WHEN an OpenSpec project is initialized
THEN it SHALL have this structure:
```
openspec/
├── project.md # Project-specific context
├── README.md # AI assistant instructions
├── specs/ # Current deployed capabilities
│ └── [capability]/ # Single, focused capability
│ ├── spec.md # WHAT and WHY
│ └── design.md # HOW (optional, for established patterns)
└── changes/ # Proposed changes
├── [change-name]/ # Descriptive change identifier
│ ├── proposal.md # Why, what, and impact
│ ├── tasks.md # Implementation checklist
│ ├── design.md # Technical decisions (optional)
│ └── specs/ # Complete future state
│ └── [capability]/
│ └── spec.md # Clean markdown (no diff syntax)
└── archive/ # Completed changes
└── YYYY-MM-DD-[name]/
```
## Change Storage Convention
### Future State Storage
WHEN creating a change proposal
THEN store the complete future state of affected specs
AND use clean markdown without diff syntax
The `changes/[name]/specs/` directory SHALL contain:
- Complete spec files as they will exist after the change
- Clean markdown without `+` or `-` prefixes
- All formatting and structure of the final intended state
### Proposal Format
WHEN documenting what changes
THEN the proposal SHALL explicitly describe each change:
```markdown
**[Section or Behavior Name]**
- From: [current state/requirement]
- To: [future state/requirement]
- Reason: [why this change is needed]
- Impact: [breaking/non-breaking, who's affected]
```
This explicit format compensates for not having inline diffs and ensures reviewers understand exactly what will change.
## Change Lifecycle
The change process SHALL follow these states:
1. **Propose**: AI creates change with future state specs and explicit proposal
2. **Review**: Humans review proposal and future state
3. **Approve**: Change is approved for implementation
4. **Implement**: Follow tasks.md checklist (can span multiple PRs)
5. **Deploy**: Changes are deployed to production
6. **Update**: Specs in `specs/` are updated to match deployed reality
7. **Archive**: Change is moved to `archive/YYYY-MM-DD-[name]/`
## Viewing Changes
WHEN reviewing proposed changes
THEN reviewers can compare using:
- GitHub PR diff view when changes are committed
- Command line: `diff -u specs/[capability]/spec.md changes/[name]/specs/[capability]/spec.md`
- Any visual diff tool comparing current vs future state
The system relies on tools to generate diffs rather than storing them.
## Capability Naming
Capabilities SHALL use:
- Verb-noun patterns (e.g., `user-auth`, `payment-capture`)
- Hyphenated lowercase names
- Singular focus (one responsibility per capability)
- No nesting (flat structure under `specs/`)
## When Changes Require Proposals
A proposal SHALL be created for:
- New features or capabilities
- Breaking changes to existing behavior
- Architecture or pattern changes
- Performance optimizations that change behavior
- Security updates affecting access patterns
A proposal is NOT required for:
- Bug fixes restoring intended behavior
- Typos or formatting fixes
- Non-breaking dependency updates
- Adding tests for existing behavior
- Documentation clarifications
## Why This Approach
Clean future state storage provides:
- **Readability**: No diff syntax pollution
- **AI-compatibility**: Standard markdown that AI tools understand
- **Simplicity**: No special parsing or processing needed
- **Tool-agnostic**: Any diff tool can show changes
- **Clear intent**: Explicit proposals document reasoning