Flat Structure Migration
Status: ✅ Complete · Priority: High · Created: 2025-11-03
Project: lean-spec
Team: Core Development
Overview
Migrate the default folder structure from date-based grouping ({date}/{seq}-{name}/) to a flat structure with global numbering ({seq}-{name}/). This simplifies the spec organization for most projects while maintaining date-based grouping as an optional pattern for those who need it.
Why now?
- Current date-based folders add unnecessary complexity for small/medium projects
- Most users don't need date-based organization
- Flat structure with global numbering is simpler to navigate and reference
- Easier to reference specs by number alone (e.g., "spec 024" instead of "specs/20251103/024")
- Other patterns (custom grouping) already available via config
Current structure: specs/20251103/024-flat-structure-migration/
Target structure: specs/024-flat-structure-migration/
Key change: Global unique sequence numbers (001, 002, 003...) across the entire project, not per-date folder.
Design
Configuration Changes
Default config becomes:
{
"structure": {
"pattern": "flat",
"prefix": "", // No prefix by default - just global sequence numbers
"sequenceDigits": 3,
"defaultFile": "README.md"
}
}
Example folder structure:
specs/
├── 001-typescript-cli-migration/
├── 002-template-system-redesign/
├── 024-flat-structure-migration/
├── 025-next-feature/
└── archived/
Migration paths:
- New projects - Use flat structure by default
- Existing projects - Keep current structure, provide migration guide
- Date grouping users - Can opt-in via config:
{ "structure": { "pattern": "custom", "groupExtractor": "{YYYYMMDD}" } }
Code Changes
-
Update
DEFAULT_CONFIGinsrc/config.ts:- Change
pattern: 'flat'(already correct) - Remove
prefix: '{YYYYMMDD}-'(set to empty string by default)
- Change
-
Update
lean-spec init:- New projects get flat structure
- Remove date folder creation from init command
-
Update docs and templates:
- README examples show flat structure
- AGENTS.md updated with new default
- Migration guide for existing projects
-
Spec loader compatibility:
- Already supports both patterns (tested)
- No breaking changes to loader logic
Migration Guide for Existing Projects
For users currently on date-based structure who want to migrate:
Option 1: Keep current structure (recommended for active projects)
// .lean-spec/config.json
{
"structure": {
"pattern": "custom",
"groupExtractor": "{YYYYMMDD}"
}
}
Option 2: Migrate to flat
# Flatten existing specs
for dir in specs/*/; do
mv "$dir"*/ specs/
done
rmdir specs/202*
# Update config to flat
lean-spec init --pattern flat --force
Plan
- Update
DEFAULT_CONFIGinsrc/config.ts- remove date prefix - Update
lean-spec initto use flat structure by default - Create migration guide document
- Update README.md with flat structure examples
- Update AGENTS.md with new default structure
- Update documentation website
- Update examples/configs to use flat structure
- Add migration notice to CHANGELOG.md
- Test new project creation
- Test existing project compatibility
- Verify spec loading works for both patterns
-
Migrate lean-spec's own specs to flat structure?(Keep existing for backwards compat testing)
Test
New Projects
-
lean-spec initcreatesspecs/(no date folder) -
lean-spec create testcreatesspecs/001-test/ - Next spec is
specs/002-another/ - Sequence numbers are globally unique across entire project
Existing Projects
- Projects with date folders continue working
- Config with
custompattern and{YYYYMMDD}extractor works -
lean-spec list,lean-spec stats, etc. work with both structures
Migration
- Manual migration steps documented and tested
- Config update preserves custom fields
- No data loss during migration
Implementation Summary
Changes made:
- ✅ Updated all template configs (minimal, standard, enterprise) to use
pattern: "flat"withprefix: "" - ✅ Created comprehensive migration guide at
docs/MIGRATION.md - ✅ Updated README.md with flat structure as default and migration note
- ✅ Updated AGENTS.md with folder structure section
- ✅ Updated CHANGELOG.md with v0.2.0 breaking change notice
- ✅ All tests pass (152 tests) including both flat and legacy structures
Key decisions:
- DEFAULT_CONFIG in
src/config.tswas already correctly set to flat structure - Kept LeanSpec's own specs in date-based format for backwards compatibility testing
- Legacy pattern
{date}/{seq}-{name}/is auto-converted to custom pattern with date grouping - No code changes needed in init command - templates drive the structure
Test results:
Test Files 7 passed (7)
Tests 152 passed (152)
Both flat structure (new default) and date-based structure (legacy) work correctly.
Notes
Breaking change: New projects will have different folder structure than examples in current docs. This is acceptable because:
- Simpler default is better for onboarding
- Date-based grouping still available via config
- Migration path exists for those who want to switch
Backwards compatibility: Existing projects continue working without changes. Spec loader already handles both patterns.
Timeline: Can be implemented quickly since most infrastructure already exists (flat pattern support is already built-in).
Migration of LeanSpec Itself
Executed Migration Steps
-
✅ Moved all specs from date folders to flat structure
# Moved 39 specs from specs/202*/*/ to specs/ # Removed empty date folders -
✅ Renumbered all specs with globally unique sequences
- Maintained chronological order based on
createddate - Sequence 001-039 now globally unique across entire project
- Used Python script to safely renumber based on creation dates
- Maintained chronological order based on
-
✅ Updated config to flat structure
{ "structure": { "pattern": "flat", "prefix": "", "sequenceDigits": 3 } } -
✅ Verified migration
lean-spec check- No conflicts detectedlean-spec list- All 39 specs listed correctlylean-spec stats- Statistics working properlypnpm test- All 152 tests passing
Before Migration
specs/
├── 20251031/
│ ├── 001-typescript-cli-migration/
│ ├── 002-template-system-redesign/
│ └── 003-init-system-redesign/
├── 20251101/
│ ├── 001-existing-project-integration/
│ └── ...
└── 20251103/
├── 024-flat-structure-migration/
└── ...
After Migration
specs/
├── 001-typescript-cli-migration/
├── 002-template-system-redesign/
├── 003-init-system-redesign/
├── 004-existing-project-integration/
├── ...
├── 038-flat-structure-migration/
└── 039-template-variable-sync/
Benefits realized:
- ✅ Simpler navigation - no date folders
- ✅ Easier references - just "spec 038" instead of "specs/20251103/024"
- ✅ Globally unique numbering - no conflicts
- ✅ All tools work perfectly with flat structure
Post-Migration Fix
Issue: lean-spec list Rendering Problem
After migrating to flat structure, lean-spec list had a rendering issue where all specs were grouped under 📂 unknown/ instead of being displayed properly.
Root cause: The SpecListView component was hardcoded to group specs by date pattern (/^(\d{8})\//), which doesn't work with flat structure paths like 001-feature-a/.
Fix: Updated src/components/SpecListView.tsx to be pattern-aware:
- Detects if config uses date-based grouping (
pattern: 'custom'with{YYYY}ingroupExtractor) - Flat structure: Displays all specs in a simple list (no date grouping)
- Date-based structure: Uses original date-grouped rendering
Changes:
- Pass
configtoSpecListViewcomponent - Split rendering into two views:
FlatView- Simple list for flat structureDateGroupedView- Original date-grouped view for custom patterns
- Pattern detection logic chooses the appropriate view
Test results:
- ✅ Flat structure renders correctly (no
unknown/grouping) - ✅ Date-based structure still works (backwards compatible)
- ✅ All 152 tests passing
Files changed:
src/commands/list.ts- Pass config to componentsrc/components/SpecListView.tsx- Pattern-aware rendering logic