-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat: add hierarchical spec structure support #660
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
lsmonki
wants to merge
54
commits into
Fission-AI:main
Choose a base branch
from
lsmonki:feature/hierarchical-specs-support
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+6,191
−240
Open
Changes from 1 commit
Commits
Show all changes
54 commits
Select commit
Hold shift + click to select a range
9f80a43
feat: add hierarchical spec structure support
lsmonki 7d10cc2
fix: skip root-level spec.md in discovery and use recursive delta det…
lsmonki 098fef8
fix: use path.join for cross-platform path separators
lsmonki 70d74ba
refactor: remove duplicate SpecUpdate and rename Spec to DiscoveredSpec
lsmonki ab285b1
refactor: use isSpecStructureHierarchical utility and fix view.ts dis…
lsmonki 18e9111
fix: deep-merge specStructure in global config and deduplicate orphan…
lsmonki 8ea4d07
chore: remove unused imports and fix variable shadowing
lsmonki 7a0c4bf
docs: add language tags to fenced blocks and fix invalid JSON
lsmonki 36c3ed2
test: add findSpecUpdates tests, root-level edge case, and fix mislea…
lsmonki 509bb52
feat: add specStructure to project-level config
lsmonki ed71300
fix: enforce structure and allowMixed in spec structure validation
lsmonki 7b9a68f
chore: archive enforce-spec-structure-mode and sync delta specs
lsmonki 2db4fbf
refactor: remove redundant Partial type and cast in project config pa…
lsmonki dc408b0
refactor: remove misleading async from findSpecUpdates wrapper
lsmonki 1f14217
refactor: eliminate double findAllSpecs traversal in list and view
lsmonki 77bd0a4
refactor: eliminate double findAllSpecs traversal in bulk validation
lsmonki 8be039c
fix: validate specStructure sub-fields in global config
lsmonki a417a95
fix: move structure validation to separate field in bulk output
lsmonki c338e62
docs: remove unverified performance claim and update config scope in …
lsmonki d5e68ea
fix: use capability-path instead of capability-name in skill templates
lsmonki 4e3ff09
fix: normalize path separators in validate direct item lookup
lsmonki 6f95c63
fix: use update.capability instead of path.basename in delta error me…
lsmonki 7b3ae53
style: remove extra leading space in config-schema doc comment
lsmonki a007ebe
refactor: remove redundant ZodError cast after instanceof check
lsmonki 65b6508
fix: remove .gitignore from RESERVED_NAMES in spec structure validation
lsmonki 4c08439
docs: add language tags to fenced code blocks missing them
lsmonki 23780c5
refactor: reuse SpecStructureConfigSchema in global-config instead of…
lsmonki 5fe2fef
refactor: remove unnecessary async from getSpecCapabilities
lsmonki 6dc9b13
fix: handle empty path in Zod validation error messages
lsmonki e0aee8a
fix: align HARD_LIMIT_DEPTH with schema max of 10
lsmonki 50fe584
docs: add language tags to fenced code blocks in spec and design files
lsmonki a59f8f8
test: add upper boundary test for maxDepth rejection in project config
lsmonki 3f43394
refactor: sort directory entries in findAllSpecs for deterministic order
lsmonki 4fb0d3e
refactor: remove redundant sorts now that findAllSpecs returns sorted…
lsmonki 4fdc8c3
docs: fix incomplete sentence and vague phrasing in archived design doc
lsmonki 94e6e36
fix: reject Windows reserved device names in spec path validation
lsmonki a97d7b5
feat: add path length validation for Windows MAX_PATH and capability …
lsmonki c71be16
fix: warn on unreadable delta spec files during archive validation
lsmonki ba4d1bc
fix: use recursive capability-path in delta spec discovery instructions
lsmonki e94b23a
fix: correct test name from maxDepth 0 to maxDepth 1
lsmonki 38d0102
fix: relax view test ordering assertion for hierarchical specs
lsmonki a89684e
fix: correct view test description to match actual assertion
lsmonki 6803720
fix: use path.join in change-parser test assertions for cross-platfor…
lsmonki 1017e79
fix: use path.join for synthetic path fields in spec-discovery tests …
lsmonki 3399695
fix: align design.md snippet with actual findAllSpecs implementation
lsmonki f39f65b
docs: clarify naming convention regex applies per path segment
lsmonki a6b7abb
docs: clarify path separator conventions for code vs documentation
lsmonki 71fbbb1
fix: use path.sep instead of hardcoded / in reserved names test paths
lsmonki 76bcaa3
fix: strengthen mixed specs assertion to check both auth and testing
lsmonki ec3e486
docs: update design.md detection algorithm to match final implementation
lsmonki 0521eef
docs: align design.md depth limits, detection cost, and separator dec…
lsmonki d349790
docs: clarify separator strategy across layers in design.md
lsmonki 9b38608
Merge branch 'main' into feature/hierarchical-specs-support
lsmonki 611e650
docs: fix allowMixed non-goal inconsistency and resolve open question…
lsmonki File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -153,3 +153,6 @@ result | |
| # OpenCode | ||
| .opencode/ | ||
| opencode.json | ||
|
|
||
| # Codex | ||
| .codex/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,285 @@ | ||
| # Migration Guide: Flat to Hierarchical Specs | ||
|
|
||
| This guide helps you migrate an existing OpenSpec project from flat to hierarchical spec organization. | ||
|
|
||
| ## Should You Migrate? | ||
|
|
||
| **Consider migrating if:** | ||
| - You have 20+ specs that are hard to navigate | ||
| - Your specs naturally group by domain/subsystem | ||
| - Multiple teams own different spec areas | ||
| - You're working on a monorepo | ||
|
|
||
| **Stay flat if:** | ||
| - You have fewer than 20 specs | ||
| - Your project has a simple domain structure | ||
| - Your team prefers simplicity over organization | ||
|
|
||
| ## Pre-Migration Checklist | ||
|
|
||
| Before starting, ensure: | ||
|
|
||
| 1. ✓ All changes are archived (no active changes in `openspec/changes/`) | ||
| 2. ✓ All specs are validated (`openspec validate --specs`) | ||
| 3. ✓ You have a backup or version control | ||
| 4. ✓ Your team agrees on the new structure | ||
|
|
||
| ## Step 1: Plan Your Hierarchy | ||
|
|
||
| Design your new structure **before** moving files. Consider: | ||
|
|
||
| **Domain-based organization:** | ||
| ``` | ||
| _global/ # Cross-cutting concerns | ||
| frontend/ # Frontend-specific specs | ||
| backend/ # Backend-specific specs | ||
| infrastructure/ # Infrastructure specs | ||
| ``` | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| **Subsystem-based organization:** | ||
| ``` | ||
| platform/ | ||
| services/ | ||
| auth/ | ||
| api/ | ||
| database/ | ||
| core/ | ||
| business-logic/ | ||
| data-models/ | ||
| integrations/ | ||
| payments/ | ||
| notifications/ | ||
| ``` | ||
|
|
||
| **Tips:** | ||
| - Use `_global/` for specs that apply everywhere (testing, security, monitoring) | ||
| - Group by team ownership when possible | ||
| - Keep depth reasonable (3-4 levels max) | ||
| - Use descriptive directory names (lowercase, hyphens) | ||
|
|
||
| ## Step 2: Create Directory Structure | ||
|
|
||
| Create your new directory hierarchy: | ||
|
|
||
| ```bash | ||
| # Example: Create _global and platform domains | ||
| mkdir -p openspec/specs/_global/{testing,security,monitoring} | ||
| mkdir -p openspec/specs/platform/services/{api,auth,database} | ||
| mkdir -p openspec/specs/platform/infrastructure/{deployment,scaling} | ||
| mkdir -p openspec/specs/frontend/{components,state-management} | ||
| ``` | ||
|
|
||
| ## Step 3: Move Specs | ||
|
|
||
| Move each spec to its new location: | ||
|
|
||
| ```bash | ||
| # Example: Move testing spec to _global | ||
| git mv openspec/specs/testing openspec/specs/_global/testing | ||
|
|
||
| # Example: Move api spec to platform/services | ||
| git mv openspec/specs/api openspec/specs/platform/services/api | ||
|
|
||
| # Continue for all specs... | ||
| ``` | ||
|
|
||
| **Important:** Use `git mv` if you're using git to preserve history. | ||
|
|
||
| ## Step 4: Update References | ||
|
|
||
| ### Update Change Proposals | ||
|
|
||
| If you have archived changes that reference old flat capability names, update their `proposal.md` files: | ||
|
|
||
| ```markdown | ||
| <!-- Before --> | ||
| ## Capabilities | ||
| - api | ||
| - auth | ||
| - database | ||
|
|
||
| <!-- After --> | ||
| ## Capabilities | ||
| - platform/services/api | ||
| - platform/services/auth | ||
| - platform/services/database | ||
| ``` | ||
|
|
||
| ### Update Documentation | ||
|
|
||
| Update any project documentation that references spec paths: | ||
|
|
||
| ```markdown | ||
| <!-- Before --> | ||
| See specs/api/spec.md for API requirements | ||
|
|
||
| <!-- After --> | ||
| See specs/platform/services/api/spec.md for API requirements | ||
| ``` | ||
|
|
||
| ## Step 5: Verify Migration | ||
|
|
||
| Run validations to ensure everything still works: | ||
|
|
||
| ```bash | ||
| # Validate all specs | ||
| openspec validate --specs | ||
|
|
||
| # List all specs (verify new paths) | ||
| openspec list --specs | ||
|
|
||
| # View a hierarchical spec | ||
| openspec show _global/testing | ||
| openspec show platform/services/api | ||
| ``` | ||
|
|
||
| ## Step 6: Update Configuration (Optional) | ||
|
|
||
| Update your global config to enforce hierarchical structure: | ||
|
|
||
| **~/.config/openspec/config.json** (Linux/macOS) | ||
| ```json | ||
| { | ||
| "specStructure": { | ||
| "structure": "hierarchical", | ||
| "maxDepth": 4, | ||
| "allowMixed": false, | ||
| "validatePaths": true | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| **%APPDATA%/openspec/config.json** (Windows) | ||
|
|
||
| ## Step 7: Communicate to Team | ||
|
|
||
| Inform your team about the new structure: | ||
|
|
||
| 1. Share the new hierarchy diagram | ||
| 2. Update your project README | ||
| 3. Document naming conventions | ||
| 4. Show examples of new change workflows | ||
|
|
||
| ## Example Migration | ||
|
|
||
| ### Before (Flat) | ||
| ``` | ||
| openspec/specs/ | ||
| auth/spec.md | ||
| api/spec.md | ||
| database/spec.md | ||
| testing/spec.md | ||
| security/spec.md | ||
| monitoring/spec.md | ||
| deployment/spec.md | ||
| ``` | ||
|
|
||
| ### After (Hierarchical) | ||
| ``` | ||
| openspec/specs/ | ||
| _global/ | ||
| testing/spec.md | ||
| security/spec.md | ||
| monitoring/spec.md | ||
| platform/ | ||
| services/ | ||
| api/spec.md | ||
| auth/spec.md | ||
| database/spec.md | ||
| infrastructure/ | ||
| deployment/spec.md | ||
| ``` | ||
|
|
||
| ### Commands After Migration | ||
|
|
||
| ```bash | ||
| # Before | ||
| openspec show auth | ||
| openspec show testing | ||
|
|
||
| # After | ||
| openspec show platform/services/auth | ||
| openspec show _global/testing | ||
| ``` | ||
|
|
||
| ## Creating New Changes After Migration | ||
|
|
||
| When creating new changes, use the hierarchical path: | ||
|
|
||
| ```bash | ||
| # Before (flat) | ||
| /opsx:new add-oauth-support | ||
| # Creates: openspec/changes/add-oauth-support/specs/auth/spec.md | ||
|
|
||
| # After (hierarchical) | ||
| /opsx:new add-oauth-support | ||
| # Creates: openspec/changes/add-oauth-support/specs/platform/services/auth/spec.md | ||
| ``` | ||
|
|
||
| The change delta structure mirrors your main spec structure automatically. | ||
|
|
||
| ## Gradual Migration | ||
|
|
||
| You can migrate gradually by mixing flat and hierarchical: | ||
|
|
||
| 1. Start by moving specs to a few top-level domains | ||
| 2. Keep remaining specs flat | ||
| 3. Migrate more specs over time | ||
| 4. Eventually enforce pure hierarchical with config | ||
|
|
||
| Example gradual migration: | ||
| ``` | ||
| openspec/specs/ | ||
| auth/spec.md # Still flat | ||
| payments/spec.md # Still flat | ||
| _global/ | ||
| testing/spec.md # Migrated | ||
| security/spec.md # Migrated | ||
| platform/ | ||
| services/ | ||
| api/spec.md # Migrated | ||
| database/spec.md # Migrated | ||
| ``` | ||
|
|
||
| OpenSpec handles this mixed structure automatically. | ||
|
|
||
| ## Rollback | ||
|
|
||
| If you need to rollback: | ||
|
|
||
| ```bash | ||
| # Use git to revert the directory moves | ||
| git log --oneline # Find commit before migration | ||
| git reset --hard <commit-hash> | ||
|
|
||
| # Or manually move specs back | ||
| mv openspec/specs/_global/testing openspec/specs/testing | ||
| mv openspec/specs/platform/services/api openspec/specs/api | ||
| # Continue for all specs... | ||
| ``` | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Spec not found after migration | ||
| **Problem:** `openspec show auth` returns "not found" | ||
|
|
||
| **Solution:** Use the full hierarchical path: | ||
| ```bash | ||
| openspec show platform/services/auth | ||
| ``` | ||
|
|
||
| ### Changes can't find specs | ||
| **Problem:** Old change references flat capability names | ||
|
|
||
| **Solution:** Update the change's proposal.md with new hierarchical names, or archive the change before migrating. | ||
|
|
||
| ### Validation errors after migration | ||
| **Problem:** `openspec validate --specs` reports path errors | ||
|
|
||
| **Solution:** Ensure directory names follow conventions (lowercase, alphanumeric, hyphens/underscores only). | ||
|
|
||
| ## Need Help? | ||
|
|
||
| - **Discord:** [Join the OpenSpec Discord](https://discord.gg/YctCnvvshC) | ||
| - **Issues:** [GitHub Issues](https://github.com/Fission-AI/OpenSpec/issues) | ||
| - **Docs:** [Organizing Specs](./organizing-specs.md) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.