mirror of
https://github.com/Fission-AI/OpenSpec.git
synced 2026-10-03 22:13:19 +08:00
Compare commits
517
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79a45ac043 | ||
|
|
80f61a5550 | ||
|
|
f529b25968 | ||
|
|
93f7b797cf | ||
|
|
7d07101363 | ||
|
|
c0f29044f9 | ||
|
|
7fe45ca330 | ||
|
|
c8e2072e3a | ||
|
|
cd5e49346f | ||
|
|
a18d992fa1 | ||
|
|
4df6a4889b | ||
|
|
9b5007dbc3 | ||
|
|
cce787ec40 | ||
|
|
94d651de8c | ||
|
|
040e382d64 | ||
|
|
caafd7c9bf | ||
|
|
144528257d | ||
|
|
af0b3418d0 | ||
|
|
7fd5417ed0 | ||
|
|
5ac1e12b83 | ||
|
|
fd7ad273c7 | ||
|
|
ea6f380fea | ||
|
|
765df47ad3 | ||
|
|
64d476f8b9 | ||
|
|
afdca0d5da | ||
|
|
61eb999f7c | ||
|
|
3d3bf96061 | ||
|
|
d199dfa407 | ||
|
|
d7d186088e | ||
|
|
6a3a1263fe | ||
|
|
1e94443a35 | ||
|
|
a0608d0bab | ||
|
|
e4c32dbe07 | ||
|
|
2d4c98e196 | ||
|
|
be6659cd39 | ||
|
|
4ba26902df | ||
|
|
5fd8e9d66c | ||
|
|
4108563731 | ||
|
|
fbef555041 | ||
|
|
92731e2263 | ||
|
|
c574e7992d | ||
|
|
62d4391268 | ||
|
|
4573c28048 | ||
|
|
0541f93ddd | ||
|
|
be51bcbc6a | ||
|
|
1d34e72f10 | ||
|
|
36fbc898da | ||
|
|
afb73cf9ec | ||
|
|
697738bc9b | ||
|
|
37686944a9 | ||
|
|
53081fb2a2 | ||
|
|
5e2e02c090 | ||
|
|
a3cee3c2f2 | ||
|
|
f27e5e809a | ||
|
|
6b545f6ebb | ||
|
|
661059b54f | ||
|
|
ddbfa529f4 | ||
|
|
d3c3d66e67 | ||
|
|
277be194ef | ||
|
|
f45ba73a5f | ||
|
|
41305753b4 | ||
|
|
86d2e04cae | ||
|
|
f6b415cb9b | ||
|
|
e91568deb9 | ||
|
|
fc0d798f93 | ||
|
|
d155126235 | ||
|
|
943e0d4102 | ||
|
|
12a7224dc6 | ||
|
|
c773ef6feb | ||
|
|
0bfe1d4426 | ||
|
|
0e6f42c81c | ||
|
|
0cc9d9025a | ||
|
|
3261ccf6dc | ||
|
|
26ed336a16 | ||
|
|
847aa81c0f | ||
|
|
39bebefcc4 | ||
|
|
cf8b6212c8 | ||
|
|
c157483685 | ||
|
|
f90c7c3354 | ||
|
|
9381bd3b24 | ||
|
|
ae83b4e16d | ||
|
|
d48528134b | ||
|
|
54bd3f1ccd | ||
|
|
675e870bf1 | ||
|
|
07eaf7b691 | ||
|
|
153721d14a | ||
|
|
70c2e17525 | ||
|
|
e2c333e493 | ||
|
|
e137dd3981 | ||
|
|
2beb8e77e8 | ||
|
|
3b16b13613 | ||
|
|
c4cfdc7c49 | ||
|
|
e0736807b4 | ||
|
|
fdb05a723e | ||
|
|
8332a09811 | ||
|
|
d61a49f6d5 | ||
|
|
7d1237f00d | ||
|
|
33466b1e2a | ||
|
|
6c8c778043 | ||
|
|
43b01ad374 | ||
|
|
3cdcdfca8e | ||
|
|
32fc19a60d | ||
|
|
84f372517f | ||
|
|
adda63e17a | ||
|
|
90d05b7115 | ||
|
|
20714c1c28 | ||
|
|
2e51ae26d3 | ||
|
|
dbd4ed7bfb | ||
|
|
473093f885 | ||
|
|
b5a884748b | ||
|
|
690c75225c | ||
|
|
dd53fb7736 | ||
|
|
2a441c472d | ||
|
|
ed4d965208 | ||
|
|
c86985d6ec | ||
|
|
bf4bc2426f | ||
|
|
c57e421cc2 | ||
|
|
ed2e832066 | ||
|
|
9db74aa5ac | ||
|
|
b5b7248610 | ||
|
|
322bfd455a | ||
|
|
08c349369a | ||
|
|
40afee643e | ||
|
|
05023dab43 | ||
|
|
d7a928b4e9 | ||
|
|
07dd634986 | ||
|
|
36078b1947 | ||
|
|
d0e1b076c2 | ||
|
|
2fbda520de | ||
|
|
5633556b6d | ||
|
|
2bb0ed36c5 | ||
|
|
06097f9cb7 | ||
|
|
8f5a526396 | ||
|
|
eb152eb2ca | ||
|
|
e987a5a327 | ||
|
|
4971cda812 | ||
|
|
4715138927 | ||
|
|
940898c1c5 | ||
|
|
d49a88c3bb | ||
|
|
bb9f6ce0ea | ||
|
|
ae85a7229d | ||
|
|
504c93bdf1 | ||
|
|
c4a54a8d54 | ||
|
|
38d2356836 | ||
|
|
3f67debf65 | ||
|
|
533cb0fa87 | ||
|
|
8dfd824477 | ||
|
|
3ed1270316 | ||
|
|
eb15cdb983 | ||
|
|
cd172a4427 | ||
|
|
b7f5a429de | ||
|
|
a5c10ed5e7 | ||
|
|
1bc849554c | ||
|
|
d73705736f | ||
|
|
ed924ffcff | ||
|
|
1786684af6 | ||
|
|
51fb10db5e | ||
|
|
cac54042ce | ||
|
|
c47cdaafe2 | ||
|
|
ea5aa0e562 | ||
|
|
48b5ed9657 | ||
|
|
fb7ff527a6 | ||
|
|
11e195575f | ||
|
|
ab47cc6b00 | ||
|
|
8dcd1707ee | ||
|
|
4f4af5708d | ||
|
|
9822576770 | ||
|
|
af273b8e0b | ||
|
|
3ceef2db72 | ||
|
|
2c2599b1f0 | ||
|
|
c08a53cb21 | ||
|
|
455c65f3c4 | ||
|
|
9ac6330430 | ||
|
|
fb264bcbcd | ||
|
|
a2757e7856 | ||
|
|
6d84924c18 | ||
|
|
6de04f3b2b | ||
|
|
c2a1a4c807 | ||
|
|
2e71835d23 | ||
|
|
971f8ca4a3 | ||
|
|
68e0a7e68e | ||
|
|
f39cc5c1fb | ||
|
|
5129a8cf96 | ||
|
|
4ff893048d | ||
|
|
cefb4719aa | ||
|
|
5e1cef3b3b | ||
|
|
1adf3cea88 | ||
|
|
6d3cfe0443 | ||
|
|
17d1e5db3f | ||
|
|
3f5a66d3e4 | ||
|
|
c08fbc1ba0 | ||
|
|
938d03be9a | ||
|
|
19ccaabfc7 | ||
|
|
2e382b9898 | ||
|
|
b5a7d096f0 | ||
|
|
c54079a0cd | ||
|
|
1050e57ae4 | ||
|
|
17d7e59343 | ||
|
|
4758c5c68d | ||
|
|
c4b0826da7 | ||
|
|
537e6078b7 | ||
|
|
5439ab0833 | ||
|
|
9b6a763eb8 | ||
|
|
d32e50fe36 | ||
|
|
8386b91a71 | ||
|
|
8f9c3c7d0b | ||
|
|
9cdb0743f2 | ||
|
|
4e93d7a881 | ||
|
|
c4b6be41c1 | ||
|
|
a66580735c | ||
|
|
fb1d37e56e | ||
|
|
cf0de5e569 | ||
|
|
92b45462c6 | ||
|
|
5ab438f5fd | ||
|
|
5855fa2353 | ||
|
|
668a125d4d | ||
|
|
fef961f6e3 | ||
|
|
3677e0175f | ||
|
|
3ddf2586b4 | ||
|
|
ece61a6d68 | ||
|
|
ecddffc22e | ||
|
|
822464ec44 | ||
|
|
67ab683105 | ||
|
|
f82e243551 | ||
|
|
88b260d51f | ||
|
|
ce7422209f | ||
|
|
63b8a3e9f9 | ||
|
|
4cf7bf863d | ||
|
|
b30882b579 | ||
|
|
082abb4795 | ||
|
|
b81fa1e6cc | ||
|
|
4a863285b0 | ||
|
|
fe83be5d61 | ||
|
|
345f9dbb45 | ||
|
|
cc9d5402ff | ||
|
|
108bcd66d8 | ||
|
|
a50105e03c | ||
|
|
312e1d6d7c | ||
|
|
56d57da119 | ||
|
|
f56189a8f7 | ||
|
|
d7e0ce85e5 | ||
|
|
eb0d50c094 | ||
|
|
c482f1b47a | ||
|
|
2ae0484ac7 | ||
|
|
8c65b47abe | ||
|
|
9c9e57daa1 | ||
|
|
c7ca76cb4f | ||
|
|
06bd3999bf | ||
|
|
821097079a | ||
|
|
42e3118b0c | ||
|
|
a785c2a99a | ||
|
|
af513191eb | ||
|
|
efbbf3b9f1 | ||
|
|
6105211163 | ||
|
|
b3d31d224d | ||
|
|
9ae6141eb1 | ||
|
|
d84069a3ae | ||
|
|
8c974f8a80 | ||
|
|
25289b510d | ||
|
|
d070d08aa8 | ||
|
|
6539ceb54a | ||
|
|
c29b06da42 | ||
|
|
4a2b23942c | ||
|
|
807b9d32a6 | ||
|
|
b3d05d2f78 | ||
|
|
9848242587 | ||
|
|
5e0d21d1ed | ||
|
|
31d85d0e8b | ||
|
|
bc3666d702 | ||
|
|
970b9f6e2d | ||
|
|
5cb84a775e | ||
|
|
adc63069a9 | ||
|
|
f8eca37796 | ||
|
|
a908dc5a05 | ||
|
|
b46f99b9bc | ||
|
|
6f7cc2abd2 | ||
|
|
4867bfade5 | ||
|
|
7359b4846a | ||
|
|
88526e6b93 | ||
|
|
367aa12892 | ||
|
|
dcfb6afe0c | ||
|
|
86925b2b2d | ||
|
|
604ecb8bd1 | ||
|
|
5a4837c37d | ||
|
|
9d9539aaa2 | ||
|
|
c3fecf0619 | ||
|
|
6469593495 | ||
|
|
157936cf68 | ||
|
|
fef33df753 | ||
|
|
78b61e8466 | ||
|
|
5fa0fa68a7 | ||
|
|
fe9eb44ec2 | ||
|
|
ee78f21b08 | ||
|
|
e3ae2ceaf0 | ||
|
|
20b2fee749 | ||
|
|
e7fff31df2 | ||
|
|
fdf9a30f0b | ||
|
|
161aa41cb3 | ||
|
|
9e092a185b | ||
|
|
38454bb2a6 | ||
|
|
b04f1cc923 | ||
|
|
ae86e9be9e | ||
|
|
f955e87fd9 | ||
|
|
55efd19953 | ||
|
|
dab5d93b85 | ||
|
|
7b0f494754 | ||
|
|
dd7ba71fe5 | ||
|
|
66ad5658f9 | ||
|
|
21a0e74b74 | ||
|
|
485ef07ec7 | ||
|
|
ce5ceadbe7 | ||
|
|
9a173b917c | ||
|
|
79baabbed1 | ||
|
|
818a5922ce | ||
|
|
d8d2930182 | ||
|
|
6af6e0ccb6 | ||
|
|
50e6660018 | ||
|
|
4bbb52dda4 | ||
|
|
4a0ae49b6e | ||
|
|
5b2049aedf | ||
|
|
332020ac6b | ||
|
|
646c516b0d | ||
|
|
8c1b580f03 | ||
|
|
17e6f7166b | ||
|
|
931d10477e | ||
|
|
e4548bcc58 | ||
|
|
68fc049955 | ||
|
|
4874a16495 | ||
|
|
3caabf86cf | ||
|
|
d4593e4a54 | ||
|
|
0144ec2b1b | ||
|
|
98d90cc00d | ||
|
|
ccaa5ad0b0 | ||
|
|
8eb7ebd7cd | ||
|
|
be395d9d74 | ||
|
|
a09b87e391 | ||
|
|
9d7b44b722 | ||
|
|
44c06cc40e | ||
|
|
b33f435812 | ||
|
|
b62b57caf3 | ||
|
|
758d91613d | ||
|
|
47180e5120 | ||
|
|
8dde1d55fc | ||
|
|
3cef6f0925 | ||
|
|
82ba1f504e | ||
|
|
d54fcc97f2 | ||
|
|
ebff738860 | ||
|
|
1bdaeef4da | ||
|
|
2921676e93 | ||
|
|
792129bfe3 | ||
|
|
715ff513e3 | ||
|
|
f6913b7661 | ||
|
|
730bbc00af | ||
|
|
adfcc65b9f | ||
|
|
590541277d | ||
|
|
14e2cc628a | ||
|
|
299171c5cb | ||
|
|
bb6aae0205 | ||
|
|
23c0ab6358 | ||
|
|
02fe5b3547 | ||
|
|
57216a7824 | ||
|
|
6e210cf084 | ||
|
|
5c6ae8e407 | ||
|
|
5376030421 | ||
|
|
7d735eb2d8 | ||
|
|
4d55e9ac6d | ||
|
|
9d674b22a3 | ||
|
|
96458ced1f | ||
|
|
3d8f2a5974 | ||
|
|
006676c973 | ||
|
|
63f45c0fcf | ||
|
|
522126a6ee | ||
|
|
23b8030494 | ||
|
|
f70df96656 | ||
|
|
df12368f11 | ||
|
|
acd1ca28f3 | ||
|
|
aedf4a34af | ||
|
|
f0c52ac7e8 | ||
|
|
f933e9b144 | ||
|
|
24b4866426 | ||
|
|
b7899602b4 | ||
|
|
b66d914198 | ||
|
|
9926103505 | ||
|
|
873e45a996 | ||
|
|
573afa0c65 | ||
|
|
665d740adb | ||
|
|
c35dd38567 | ||
|
|
aa9e49612b | ||
|
|
36eb0bbbf5 | ||
|
|
d549cec121 | ||
|
|
1a3bfae784 | ||
|
|
fae08072a9 | ||
|
|
07df6c97c9 | ||
|
|
7b13a2de03 | ||
|
|
41fc14d360 | ||
|
|
7c0face31b | ||
|
|
332816cc35 | ||
|
|
7ced2a8791 | ||
|
|
a79b8b5c03 | ||
|
|
52d620e40e | ||
|
|
22082338fd | ||
|
|
6458b6ed39 | ||
|
|
01a2f5d600 | ||
|
|
95d855d641 | ||
|
|
562530dfa8 | ||
|
|
1e17cfdd0b | ||
|
|
5d185ba3a8 | ||
|
|
08b41c7bea | ||
|
|
8ac50289f0 | ||
|
|
1f295cec52 | ||
|
|
ad8e213cf9 | ||
|
|
a6c1a90165 | ||
|
|
21b5a3e680 | ||
|
|
1bda5be96c | ||
|
|
0faf44807e | ||
|
|
f9c1d07edb | ||
|
|
2bd1a4417c | ||
|
|
1db19ac3d8 | ||
|
|
25018786e4 | ||
|
|
5fd9173ad9 | ||
|
|
0a611747bc | ||
|
|
49e422724f | ||
|
|
c22d6bce1c | ||
|
|
1c0dc09dc9 | ||
|
|
f0b1e00c65 | ||
|
|
5fe72ddc5d | ||
|
|
c18f3b2b2e | ||
|
|
33344727a8 | ||
|
|
828e5ba316 | ||
|
|
31c57f5c0f | ||
|
|
767a0053e8 | ||
|
|
fd65b99c91 | ||
|
|
e170df9f41 | ||
|
|
b91040e8c2 | ||
|
|
8824bd2a42 | ||
|
|
1d3c292d94 | ||
|
|
cfe6da96ac | ||
|
|
c3c78551d0 | ||
|
|
f1fabc5f18 | ||
|
|
166b960428 | ||
|
|
ef1a6c0f0b | ||
|
|
9b3944bd09 | ||
|
|
7917d08a50 | ||
|
|
4a8e5986f0 | ||
|
|
103838f371 | ||
|
|
0a26c686f9 | ||
|
|
efcf766193 | ||
|
|
151eddb759 | ||
|
|
cb0d6f3189 | ||
|
|
a897c697a5 | ||
|
|
3bedf6b23e | ||
|
|
9ff0e85693 | ||
|
|
1ca407fa2f | ||
|
|
46c927af06 | ||
|
|
87cb206e88 | ||
|
|
6806a2fc5a | ||
|
|
4ab65d75dd | ||
|
|
2a3294dbfb | ||
|
|
8334006f2b | ||
|
|
8a559e0d00 | ||
|
|
a3924f17b2 | ||
|
|
b11e862b0f | ||
|
|
099585afcb | ||
|
|
f023fc317e | ||
|
|
38a1463af0 | ||
|
|
f2399d3280 | ||
|
|
f699e10778 | ||
|
|
c824d8927f | ||
|
|
5821b24ab3 | ||
|
|
e812eb9e78 | ||
|
|
abfe13c5a7 | ||
|
|
0d5a75d3a0 | ||
|
|
b30c0ad27e | ||
|
|
1cada18186 | ||
|
|
fa50b07938 | ||
|
|
b6cad1631c | ||
|
|
2497e81e4d | ||
|
|
d8cba03840 | ||
|
|
0b1be19302 | ||
|
|
d7ebee4555 | ||
|
|
8f45a6f6ee | ||
|
|
6da77f01ce | ||
|
|
d90eccf959 | ||
|
|
f192a97aeb | ||
|
|
7781bbadd3 | ||
|
|
aeaa1d50cc | ||
|
|
fa5df9a329 | ||
|
|
f94f396c99 | ||
|
|
1f670f71d4 | ||
|
|
32b2901d13 | ||
|
|
2ad0b1d306 | ||
|
|
279d327899 | ||
|
|
5d848cf005 | ||
|
|
5607fd3ccb | ||
|
|
6a0d862258 | ||
|
|
1fe5f84fbc | ||
|
|
80e78ecd1e | ||
|
|
564135a530 | ||
|
|
b9e80641a0 | ||
|
|
0755994eaa | ||
|
|
dcabd6de31 | ||
|
|
aef6ce01ff | ||
|
|
441f9f444b | ||
|
|
b322829091 | ||
|
|
5167e65a5c | ||
|
|
5c6b4113a7 | ||
|
|
a8b76c3e69 | ||
|
|
d3237cac7b | ||
|
|
e395eb4eeb | ||
|
|
76e1ec2a1f | ||
|
|
27eaccc024 | ||
|
|
b288f2fc88 | ||
|
|
22134a603b | ||
|
|
3b5fd11cb9 | ||
|
|
e9417fc147 | ||
|
|
8bcf2c6905 | ||
|
|
9a03ba1853 |
@@ -0,0 +1,95 @@
|
||||
# Changesets
|
||||
|
||||
This directory is managed by [Changesets](https://github.com/changesets/changesets).
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
pnpm changeset
|
||||
```
|
||||
|
||||
Follow the prompts to select version bump type and describe your changes.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. **Add a changeset** — Run `pnpm changeset` locally before or after your PR
|
||||
2. **Version PR** — CI opens/updates a "Version Packages" PR when changesets merge to main
|
||||
3. **Release** — Merging the Version PR triggers npm publish and GitHub Release
|
||||
|
||||
> **Note:** Contributors only need to run `pnpm changeset`. Versioning (`changeset version`) and publishing happen automatically in CI.
|
||||
|
||||
## Template
|
||||
|
||||
Use this structure for your changeset content:
|
||||
|
||||
```markdown
|
||||
---
|
||||
"@fission-ai/openspec": patch
|
||||
---
|
||||
|
||||
### New Features
|
||||
|
||||
- **Feature name** — What users can now do
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fixed issue where X happened when Y
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- `oldMethod()` has been removed, use `newMethod()` instead
|
||||
|
||||
### Deprecations
|
||||
|
||||
- `legacyOption` is deprecated and will be removed in v2.0
|
||||
|
||||
### Other
|
||||
|
||||
- Internal refactoring of X for better performance
|
||||
```
|
||||
|
||||
Include only the sections relevant to your change.
|
||||
|
||||
## Version Bump Guide
|
||||
|
||||
| Type | When to use | Example |
|
||||
|------|-------------|---------|
|
||||
| `patch` | Bug fixes, small improvements | Fixed crash when config missing |
|
||||
| `minor` | New features, non-breaking additions | Added `--verbose` flag |
|
||||
| `major` | Breaking changes, removed features | Renamed `init` to `setup` |
|
||||
|
||||
## When to Create a Changeset
|
||||
|
||||
**Create one for:**
|
||||
- New features or commands
|
||||
- Bug fixes that affect users
|
||||
- Breaking changes or deprecations
|
||||
- Performance improvements users would notice
|
||||
|
||||
**Skip for:**
|
||||
- Documentation-only changes
|
||||
- Test additions/fixes
|
||||
- Internal refactoring with no user impact
|
||||
- CI/tooling changes
|
||||
|
||||
## Writing Good Descriptions
|
||||
|
||||
**Do:** Write for users, not developers
|
||||
```markdown
|
||||
- **Shell completions** — Tab completion now available for Bash, Fish, and PowerShell
|
||||
```
|
||||
|
||||
**Don't:** Write implementation details
|
||||
```markdown
|
||||
- Added ShellCompletionGenerator class with Bash/Fish/PowerShell subclasses
|
||||
```
|
||||
|
||||
**Do:** Explain the impact
|
||||
```markdown
|
||||
- Fixed config loading to respect `XDG_CONFIG_HOME` on Linux
|
||||
```
|
||||
|
||||
**Don't:** Just reference the fix
|
||||
```markdown
|
||||
- Fixed #123
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://unpkg.com/@changesets/config/schema.json",
|
||||
"changelog": [
|
||||
"@changesets/changelog-github",
|
||||
{ "repo": "Fission-AI/OpenSpec" }
|
||||
],
|
||||
"commit": false,
|
||||
"fixed": [],
|
||||
"linked": [],
|
||||
"access": "public",
|
||||
"baseBranch": "main",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": []
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
|
||||
# Minimal configuration for getting started
|
||||
language: "en-US"
|
||||
reviews:
|
||||
profile: "chill"
|
||||
high_level_summary: true
|
||||
auto_review:
|
||||
enabled: true
|
||||
drafts: false
|
||||
base_branches:
|
||||
- ".*"
|
||||
@@ -0,0 +1,92 @@
|
||||
# Dev Container Setup
|
||||
|
||||
This directory contains the VS Code dev container configuration for OpenSpec development.
|
||||
|
||||
## What's Included
|
||||
|
||||
- **Node.js 20 LTS** (>=20.19.0) - TypeScript/JavaScript runtime
|
||||
- **pnpm** - Fast, disk space efficient package manager
|
||||
- **Git + GitHub CLI** - Version control tools
|
||||
- **VS Code Extensions**:
|
||||
- ESLint & Prettier for code quality
|
||||
- Vitest Explorer for running tests
|
||||
- GitLens for enhanced git integration
|
||||
- Error Lens for inline error highlighting
|
||||
- Code Spell Checker
|
||||
- Path IntelliSense
|
||||
|
||||
## How to Use
|
||||
|
||||
### First Time Setup
|
||||
|
||||
1. **Install Prerequisites** (on your local machine):
|
||||
- [VS Code](https://code.visualstudio.com/)
|
||||
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
|
||||
- [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
|
||||
|
||||
2. **Open in Container**:
|
||||
- Open this project in VS Code
|
||||
- You'll see a notification: "Folder contains a Dev Container configuration file"
|
||||
- Click "Reopen in Container"
|
||||
|
||||
OR
|
||||
|
||||
- Open Command Palette (`Cmd/Ctrl+Shift+P`)
|
||||
- Type "Dev Containers: Reopen in Container"
|
||||
- Press Enter
|
||||
|
||||
3. **Wait for Setup**:
|
||||
- The container will build (first time takes a few minutes)
|
||||
- `pnpm install` runs automatically via `postCreateCommand`
|
||||
- All extensions install automatically
|
||||
|
||||
### Daily Development
|
||||
|
||||
Once set up, the container preserves your development environment:
|
||||
|
||||
```bash
|
||||
# Run development build
|
||||
pnpm run dev
|
||||
|
||||
# Run CLI in development
|
||||
pnpm run dev:cli
|
||||
|
||||
# Run tests
|
||||
pnpm test
|
||||
|
||||
# Run tests in watch mode
|
||||
pnpm test:watch
|
||||
|
||||
# Build the project
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
### SSH Keys
|
||||
|
||||
Your SSH keys are mounted read-only from `~/.ssh`, so git operations work seamlessly with GitHub/GitLab.
|
||||
|
||||
### Rebuilding the Container
|
||||
|
||||
If you modify `.devcontainer/devcontainer.json`:
|
||||
- Command Palette → "Dev Containers: Rebuild Container"
|
||||
|
||||
## Benefits
|
||||
|
||||
- No need to install Node.js or pnpm on your local machine
|
||||
- Consistent development environment across team members
|
||||
- Isolated from other Node.js projects on your machine
|
||||
- All dependencies and tools containerized
|
||||
- Easy onboarding for new developers
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Container won't build:**
|
||||
- Ensure Docker Desktop is running
|
||||
- Check Docker has enough memory allocated (recommend 4GB+)
|
||||
|
||||
**Extensions not appearing:**
|
||||
- Rebuild the container: "Dev Containers: Rebuild Container"
|
||||
|
||||
**Permission issues:**
|
||||
- The container runs as the `node` user (non-root)
|
||||
- Files created in the container are owned by this user
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "OpenSpec Development",
|
||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bookworm",
|
||||
|
||||
// Additional tools and features
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/git:1": {
|
||||
"version": "latest",
|
||||
"ppa": true
|
||||
},
|
||||
"ghcr.io/devcontainers/features/github-cli:1": {
|
||||
"version": "latest"
|
||||
}
|
||||
},
|
||||
|
||||
// Configure tool-specific properties
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
// Set default container specific settings
|
||||
"settings": {
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": "explicit"
|
||||
},
|
||||
"files.eol": "\n",
|
||||
"terminal.integrated.defaultProfile.linux": "bash"
|
||||
},
|
||||
|
||||
// Add extensions you want installed when the container is created
|
||||
"extensions": [
|
||||
// TypeScript/JavaScript essentials
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
|
||||
// Testing
|
||||
"vitest.explorer",
|
||||
|
||||
// Git
|
||||
"eamodio.gitlens",
|
||||
|
||||
// Utilities
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"usernamehw.errorlens",
|
||||
"christian-kohler.path-intellisense"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created
|
||||
"postCreateCommand": "corepack enable && corepack prepare pnpm@latest --activate && pnpm install",
|
||||
|
||||
// Configure mounts to preserve SSH keys for git operations
|
||||
"mounts": [
|
||||
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/node/.ssh,readonly,type=bind,consistency=cached"
|
||||
],
|
||||
|
||||
// Set the default user to 'node' (non-root user)
|
||||
"remoteUser": "node",
|
||||
|
||||
// Ensure git is properly configured
|
||||
"initializeCommand": "echo 'Initializing dev container...'"
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
# Default code ownership
|
||||
* @TabishB
|
||||
@@ -0,0 +1,20 @@
|
||||
# Github Workflows
|
||||
|
||||
## Testing CI Locally
|
||||
|
||||
Test GitHub Actions workflows locally using [act](https://nektosact.com/):
|
||||
|
||||
```bash
|
||||
# Test all PR checks
|
||||
act pull_request
|
||||
|
||||
# Test specific job
|
||||
act pull_request -j nix-flake-validate
|
||||
|
||||
# Dry run to see what would execute
|
||||
act pull_request --dryrun
|
||||
```
|
||||
|
||||
The `.actrc` file configures act to use the appropriate Docker image.
|
||||
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
merge_group:
|
||||
branches: [main]
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# Detect which files changed to enable path-based filtering
|
||||
changes:
|
||||
name: Detect changes
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
nix: ${{ steps.filter.outputs.nix }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check for Nix-related changes
|
||||
uses: dorny/paths-filter@v3
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
nix:
|
||||
- 'flake.nix'
|
||||
- 'flake.lock'
|
||||
- 'package.json'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'scripts/update-flake.sh'
|
||||
- '.github/workflows/ci.yml'
|
||||
|
||||
test_pr:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build project
|
||||
run: pnpm run build
|
||||
|
||||
- name: Run tests
|
||||
run: pnpm test
|
||||
|
||||
- name: Upload test coverage
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-report-pr
|
||||
path: coverage/
|
||||
retention-days: 7
|
||||
|
||||
test_matrix:
|
||||
name: Test (${{ matrix.label }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 15
|
||||
if: github.event_name == 'push'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
shell: bash
|
||||
label: linux-bash
|
||||
- os: macos-latest
|
||||
shell: bash
|
||||
label: macos-bash
|
||||
- os: windows-latest
|
||||
shell: pwsh
|
||||
label: windows-pwsh
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.shell }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Print environment diagnostics
|
||||
run: |
|
||||
node -p "JSON.stringify({ platform: process.platform, arch: process.arch, shell: process.env.SHELL || process.env.ComSpec || '' })"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build project
|
||||
run: pnpm run build
|
||||
|
||||
- name: Run tests
|
||||
run: pnpm test
|
||||
|
||||
- name: Upload test coverage
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-report-main
|
||||
path: coverage/
|
||||
retention-days: 7
|
||||
|
||||
lint:
|
||||
name: Lint & Type Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build project
|
||||
run: pnpm run build
|
||||
|
||||
- name: Type check
|
||||
run: pnpm exec tsc --noEmit
|
||||
|
||||
- name: Lint
|
||||
run: pnpm lint
|
||||
|
||||
- name: Check for build artifacts
|
||||
run: |
|
||||
if [ ! -d "dist" ]; then
|
||||
echo "Error: dist directory not found after build"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "dist/cli/index.js" ]; then
|
||||
echo "Error: CLI entry point not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
nix-flake-validate:
|
||||
name: Nix Flake Validation
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
needs: changes
|
||||
if: needs.changes.outputs.nix == 'true'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@v21
|
||||
|
||||
- name: Setup Nix cache
|
||||
uses: DeterminateSystems/magic-nix-cache-action@v13
|
||||
|
||||
- name: Build with Nix
|
||||
run: nix build
|
||||
|
||||
- name: Verify build output
|
||||
run: |
|
||||
if [ ! -e "result" ]; then
|
||||
echo "Error: Nix build output 'result' symlink not found"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "result/bin/openspec" ]; then
|
||||
echo "Error: openspec binary not found in build output"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Build output verified"
|
||||
|
||||
- name: Test binary execution
|
||||
run: |
|
||||
VERSION=$(nix run . -- --version)
|
||||
echo "OpenSpec version: $VERSION"
|
||||
if [ -z "$VERSION" ]; then
|
||||
echo "Error: Version command returned empty output"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Binary execution successful"
|
||||
|
||||
- name: Validate update script
|
||||
run: |
|
||||
echo "Testing update-flake.sh script..."
|
||||
bash scripts/update-flake.sh
|
||||
echo "✅ Update script executed successfully"
|
||||
|
||||
- name: Check flake.nix modifications
|
||||
run: |
|
||||
if git diff --quiet flake.nix; then
|
||||
echo "ℹ️ flake.nix unchanged (hash already up-to-date)"
|
||||
else
|
||||
echo "✅ flake.nix was updated by script"
|
||||
git diff flake.nix
|
||||
fi
|
||||
|
||||
- name: Restore flake.nix
|
||||
if: always()
|
||||
run: git checkout -- flake.nix || true
|
||||
|
||||
validate-changesets:
|
||||
name: Validate Changesets
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Validate changesets
|
||||
run: |
|
||||
if command -v changeset &> /dev/null; then
|
||||
pnpm exec changeset status --since=origin/main
|
||||
else
|
||||
echo "Changesets not configured, skipping validation"
|
||||
fi
|
||||
|
||||
required-checks-pr:
|
||||
name: All checks passed
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test_pr, lint, nix-flake-validate]
|
||||
if: always() && (github.event_name == 'pull_request' || github.event_name == 'merge_group')
|
||||
steps:
|
||||
- name: Verify all checks passed
|
||||
run: |
|
||||
if [[ "${{ needs.test_pr.result }}" != "success" ]]; then
|
||||
echo "Test job failed"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${{ needs.lint.result }}" != "success" ]]; then
|
||||
echo "Lint job failed"
|
||||
exit 1
|
||||
fi
|
||||
# Nix validation may be skipped if no Nix-related files changed
|
||||
if [[ "${{ needs.nix-flake-validate.result }}" != "success" && "${{ needs.nix-flake-validate.result }}" != "skipped" ]]; then
|
||||
echo "Nix flake validation job failed"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${{ needs.nix-flake-validate.result }}" == "skipped" ]]; then
|
||||
echo "Nix flake validation skipped (no Nix-related changes)"
|
||||
fi
|
||||
echo "All required checks passed!"
|
||||
|
||||
required-checks-main:
|
||||
name: All checks passed
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test_matrix, lint, nix-flake-validate]
|
||||
if: always() && github.event_name == 'push'
|
||||
steps:
|
||||
- name: Verify all checks passed
|
||||
run: |
|
||||
if [[ "${{ needs.test_matrix.result }}" != "success" ]]; then
|
||||
echo "Matrix test job failed"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${{ needs.lint.result }}" != "success" ]]; then
|
||||
echo "Lint job failed"
|
||||
exit 1
|
||||
fi
|
||||
# Nix validation may be skipped if no Nix-related files changed
|
||||
if [[ "${{ needs.nix-flake-validate.result }}" != "success" && "${{ needs.nix-flake-validate.result }}" != "skipped" ]]; then
|
||||
echo "Nix flake validation job failed"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${{ needs.nix-flake-validate.result }}" == "skipped" ]]; then
|
||||
echo "Nix flake validation skipped (no Nix-related changes)"
|
||||
fi
|
||||
echo "All required checks passed!"
|
||||
@@ -0,0 +1,60 @@
|
||||
name: Release (prepare)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
id-token: write # Required for npm OIDC trusted publishing
|
||||
|
||||
concurrency:
|
||||
group: release-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
if: github.repository == 'Fission-AI/OpenSpec'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Generate GitHub App token first - used for checkout and changesets
|
||||
# This allows git operations to trigger CI workflows on the version PR
|
||||
# (GITHUB_TOKEN cannot trigger workflows by design)
|
||||
- name: Generate GitHub App Token
|
||||
id: app-token
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
app-id: ${{ vars.APP_ID }}
|
||||
private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24' # Node 24 includes npm 11.5.1+ required for OIDC
|
||||
cache: 'pnpm'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
|
||||
# Opens/updates the Version Packages PR; publishes when the Version PR merges
|
||||
- name: Create/Update Version PR
|
||||
id: changesets
|
||||
uses: changesets/action@v1
|
||||
with:
|
||||
title: 'chore(release): version packages'
|
||||
createGithubReleases: true
|
||||
# Use CI-specific release script: relies on version PR having been merged
|
||||
# so package.json already contains the bumped version.
|
||||
publish: pnpm run release:ci
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
# npm authentication handled via OIDC trusted publishing (no token needed)
|
||||
+16
-3
@@ -140,9 +140,22 @@ dist/
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
|
||||
# Internal Docs
|
||||
docs/
|
||||
|
||||
# Claude
|
||||
.claude/
|
||||
CLAUDE.md
|
||||
CLAUDE.md
|
||||
.DS_Store
|
||||
|
||||
# Pnpm
|
||||
.pnpm-store/
|
||||
result
|
||||
|
||||
# OpenCode
|
||||
.opencode/
|
||||
opencode.json
|
||||
|
||||
# Codex
|
||||
.codex/
|
||||
|
||||
# Bob
|
||||
.bob/
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
## Product Thinking
|
||||
|
||||
When discussing workflows, documentation, onboarding, or product behavior, start from the user's goal and lived interaction. Do not translate the problem into CLI commands, config flags, file formats, or internal implementation steps as the primary answer unless the user explicitly asks for that level.
|
||||
|
||||
Default framing:
|
||||
|
||||
- What is the user trying to accomplish?
|
||||
- Where are they starting from?
|
||||
- What should they say or do in the product experience?
|
||||
- What should the agent/system do on their behalf?
|
||||
- What outcome should they see?
|
||||
|
||||
Only after that, mention commands, files, APIs, or implementation mechanics as supporting detail. Treat these as backing mechanisms, not the user journey.
|
||||
|
||||
Bad pattern:
|
||||
|
||||
```text
|
||||
Run command X, then command Y, then command Z.
|
||||
```
|
||||
|
||||
Better pattern:
|
||||
|
||||
```text
|
||||
Open the relevant experience and tell the agent what outcome you want. The system should guide the workflow and may use command X/Y/Z internally.
|
||||
```
|
||||
|
||||
If the user is critiquing UX, docs, or workflow design, do not answer with a bare CLI recipe. First restate the intended human workflow, then identify where the current product forces implementation details onto the user.
|
||||
+541
@@ -0,0 +1,541 @@
|
||||
# @fission-ai/openspec
|
||||
|
||||
## 1.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#952](https://github.com/Fission-AI/OpenSpec/pull/952) [`cce787e`](https://github.com/Fission-AI/OpenSpec/commit/cce787ec4083da2b27781f6786f5ce0002909a7b) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
|
||||
|
||||
- **Junie support** — Added tool and command generation for JetBrains Junie
|
||||
- **Lingma IDE support** — Added configuration support for Lingma IDE
|
||||
- **ForgeCode support** — Added tool support for ForgeCode
|
||||
- **IBM Bob support** — Added support for IBM Bob coding assistant
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **Shell completions opt-in** — Completion install is now opt-in, fixing PowerShell encoding corruption
|
||||
- **Copilot auto-detection** — Prevented false GitHub Copilot detection from a bare `.github/` directory
|
||||
- **pi.dev command generation** — Fixed command reference transforms and template argument passing
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#760](https://github.com/Fission-AI/OpenSpec/pull/760) [`61eb999`](https://github.com/Fission-AI/OpenSpec/commit/61eb999f7c6c0fc98d2e7f3678756fce6a3f4378) Thanks [@fsilvaortiz](https://github.com/fsilvaortiz)! - fix: OpenCode adapter now uses `.opencode/commands/` (plural) to match OpenCode's official directory convention. Fixes #748.
|
||||
|
||||
- [#759](https://github.com/Fission-AI/OpenSpec/pull/759) [`afdca0d`](https://github.com/Fission-AI/OpenSpec/commit/afdca0d5dab1aa109cfd8848b2512333ccad60c3) Thanks [@fsilvaortiz](https://github.com/fsilvaortiz)! - fix: `openspec status` now exits gracefully when no changes exist instead of throwing a fatal error. Fixes #714.
|
||||
|
||||
## 1.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#747](https://github.com/Fission-AI/OpenSpec/pull/747) [`1e94443`](https://github.com/Fission-AI/OpenSpec/commit/1e94443a3551b228eecbc89e95d96d3b9600a192) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
|
||||
|
||||
- **Profile system** — Choose between `core` (4 essential workflows) and `custom` (pick any subset) profiles to control which skills get installed. Manage profiles with the new `openspec config profile` command
|
||||
- **Propose workflow** — New one-step workflow creates a complete change proposal with design, specs, and tasks from a single request — no need to run `new` then `ff` separately
|
||||
- **AI tool auto-detection** — `openspec init` now scans your project for existing tool directories (`.claude/`, `.cursor/`, etc.) and pre-selects detected tools
|
||||
- **Pi (pi.dev) support** — Pi coding agent is now a supported tool with prompt and skill generation
|
||||
- **Kiro support** — AWS Kiro IDE is now a supported tool with prompt and skill generation
|
||||
- **Sync prunes deselected workflows** — `openspec update` now removes command files and skill directories for workflows you've deselected, keeping your project clean
|
||||
- **Config drift warning** — `openspec config list` warns when global config is out of sync with the current project
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fixed onboard preflight giving a false "not initialized" error on freshly initialized projects
|
||||
- Fixed archive workflow stopping mid-way when syncing — it now properly resumes after sync completes
|
||||
- Added Windows PowerShell alternatives for onboard shell commands
|
||||
|
||||
## 1.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#627](https://github.com/Fission-AI/OpenSpec/pull/627) [`afb73cf`](https://github.com/Fission-AI/OpenSpec/commit/afb73cf9ec59c6f8b26d0c538c0218c203ba3c56) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
|
||||
|
||||
- **OpenCode command references** — Command references in generated files now use the correct `/opsx-` hyphen format instead of `/opsx:` colon format, ensuring commands work properly in OpenCode
|
||||
|
||||
## 1.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#625](https://github.com/Fission-AI/OpenSpec/pull/625) [`53081fb`](https://github.com/Fission-AI/OpenSpec/commit/53081fb2a26ec66d2950ae0474b9a56cbc5b5a76) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
|
||||
|
||||
- **Codex global path support** — Codex adapter now resolves global paths correctly, fixing workflow file generation when run outside the project directory (#622)
|
||||
- **Archive operations on cross-device or restricted paths** — Archive now falls back to copy+remove when rename fails with EPERM or EXDEV errors, fixing failures on networked/external drives (#605)
|
||||
- **Slash command hints in workflow messages** — Workflow completion messages now display helpful slash command hints for next steps (#603)
|
||||
- **Windsurf workflow file path** — Updated Windsurf adapter to use the correct `workflows` directory instead of the legacy `commands` path (#610)
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#550](https://github.com/Fission-AI/OpenSpec/pull/550) [`86d2e04`](https://github.com/Fission-AI/OpenSpec/commit/86d2e04cae76a999dbd1b4571f52fa720036be0c) Thanks [@jerome-benoit](https://github.com/jerome-benoit)! - ### Improvements
|
||||
|
||||
- **Nix flake maintenance** — Version now read dynamically from package.json, reducing manual sync issues
|
||||
- **Nix build optimization** — Source filtering excludes node_modules and artifacts, improving build times
|
||||
- **update-flake.sh script** — Detects when hash is already correct, skipping unnecessary rebuilds
|
||||
|
||||
### Other
|
||||
|
||||
- Updated Nix CI actions to latest versions (nix-installer v21, magic-nix-cache v13)
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#596](https://github.com/Fission-AI/OpenSpec/pull/596) [`e91568d`](https://github.com/Fission-AI/OpenSpec/commit/e91568deb948073f3e9d9bb2d2ab5bf8080d6cf4) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
|
||||
|
||||
- Clarified spec naming convention — Specs should be named after capabilities (`specs/<capability>/spec.md`), not changes
|
||||
- Fixed task checkbox format guidance — Tasks now clearly require `- [ ]` checkbox format for apply phase tracking
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#587](https://github.com/Fission-AI/OpenSpec/pull/587) [`943e0d4`](https://github.com/Fission-AI/OpenSpec/commit/943e0d41026d034de66b9442d1276c01b293eb2b) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
|
||||
|
||||
- Fixed incorrect archive path in onboarding documentation — the template now shows the correct path `openspec/changes/archive/YYYY-MM-DD-<name>/` instead of the incorrect `openspec/archive/YYYY-MM-DD--<name>/`
|
||||
|
||||
## 1.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#578](https://github.com/Fission-AI/OpenSpec/pull/578) [`0cc9d90`](https://github.com/Fission-AI/OpenSpec/commit/0cc9d9025af367faa1688a7b2606a2549053cd3f) Thanks [@TabishB](https://github.com/TabishB)! - ## OpenSpec 1.0 — The OPSX Release
|
||||
|
||||
The workflow has been rebuilt from the ground up. OPSX replaces the old phase-locked `/openspec:*` commands with an action-based system where AI understands what artifacts exist, what's ready to create, and what each action unlocks.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- **Old commands removed** — `/openspec:proposal`, `/openspec:apply`, and `/openspec:archive` no longer exist
|
||||
- **Config files removed** — Tool-specific instruction files (`CLAUDE.md`, `.cursorrules`, `AGENTS.md`, `project.md`) are no longer generated
|
||||
- **Migration** — Run `openspec init` to upgrade. Legacy artifacts are detected and cleaned up with confirmation.
|
||||
|
||||
### From Static Prompts to Dynamic Instructions
|
||||
|
||||
**Before:** AI received the same static instructions every time, regardless of project state.
|
||||
|
||||
**Now:** Instructions are dynamically assembled from three layers:
|
||||
|
||||
1. **Context** — Project background from `config.yaml` (tech stack, conventions)
|
||||
2. **Rules** — Artifact-specific constraints (e.g., "propose spike tasks for unknowns")
|
||||
3. **Template** — The actual structure for the output file
|
||||
|
||||
AI queries the CLI for real-time state: which artifacts exist, what's ready to create, what dependencies are satisfied, and what each action unlocks.
|
||||
|
||||
### From Phase-Locked to Action-Based
|
||||
|
||||
**Before:** Linear workflow — proposal → apply → archive. Couldn't easily go back or iterate.
|
||||
|
||||
**Now:** Flexible actions on a change. Edit any artifact anytime. The artifact graph tracks state automatically.
|
||||
|
||||
| Command | What it does |
|
||||
| -------------------- | ---------------------------------------------------- |
|
||||
| `/opsx:explore` | Think through ideas before committing to a change |
|
||||
| `/opsx:new` | Start a new change |
|
||||
| `/opsx:continue` | Create one artifact at a time (step-through) |
|
||||
| `/opsx:ff` | Create all planning artifacts at once (fast-forward) |
|
||||
| `/opsx:apply` | Implement tasks |
|
||||
| `/opsx:verify` | Validate implementation matches artifacts |
|
||||
| `/opsx:sync` | Sync delta specs to main specs |
|
||||
| `/opsx:archive` | Archive completed change |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes with conflict detection |
|
||||
| `/opsx:onboard` | Guided 15-minute walkthrough of complete workflow |
|
||||
|
||||
### From Text Merging to Semantic Spec Syncing
|
||||
|
||||
**Before:** Spec updates required manual merging or wholesale file replacement.
|
||||
|
||||
**Now:** Delta specs use semantic markers that AI understands:
|
||||
|
||||
- `## ADDED Requirements` — New requirements to add
|
||||
- `## MODIFIED Requirements` — Partial updates (add scenario without copying existing ones)
|
||||
- `## REMOVED Requirements` — Delete with reason and migration notes
|
||||
- `## RENAMED Requirements` — Rename preserving content
|
||||
|
||||
Archive parses these at the requirement level, not brittle header matching.
|
||||
|
||||
### From Scattered Files to Agent Skills
|
||||
|
||||
**Before:** 8+ config files at project root + slash commands scattered across 21 tool-specific locations with different formats.
|
||||
|
||||
**Now:** Single `.claude/skills/` directory with YAML-fronted markdown files. Auto-detected by Claude Code, Cursor, Windsurf. Cross-editor compatible.
|
||||
|
||||
### New Features
|
||||
|
||||
- **Onboarding skill** — `/opsx:onboard` walks new users through their first complete change with codebase-aware task suggestions and step-by-step narration (11 phases, ~15 minutes)
|
||||
|
||||
- **21 AI tools supported** — Claude Code, Cursor, Windsurf, Continue, Gemini CLI, GitHub Copilot, Amazon Q, Cline, RooCode, Kilo Code, Auggie, CodeBuddy, Qoder, Qwen, CoStrict, Crush, Factory, OpenCode, Antigravity, iFlow, and Codex
|
||||
|
||||
- **Interactive setup** — `openspec init` shows animated welcome screen and searchable multi-select for choosing tools. Pre-selects already-configured tools for easy refresh.
|
||||
|
||||
- **Customizable schemas** — Define custom artifact workflows in `openspec/schemas/` without touching package code. Teams can share workflows via version control.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fixed Claude Code YAML parsing failure when command names contained colons
|
||||
- Fixed task file parsing to handle trailing whitespace on checkbox lines
|
||||
- Fixed JSON instruction output to separate context/rules from template — AI was copying constraint blocks into artifact files
|
||||
|
||||
### Documentation
|
||||
|
||||
- New getting-started guide, CLI reference, concepts documentation
|
||||
- Removed misleading "edit mid-flight and continue" claims that weren't implemented
|
||||
- Added migration guide for upgrading from pre-OPSX versions
|
||||
|
||||
## 0.23.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#540](https://github.com/Fission-AI/OpenSpec/pull/540) [`c4cfdc7`](https://github.com/Fission-AI/OpenSpec/commit/c4cfdc7c499daef30d8a218f5f59b8d9e5adb754) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
|
||||
|
||||
- **Bulk archive skill** — Archive multiple completed changes in a single operation with `/opsx:bulk-archive`. Includes batch validation, spec conflict detection, and consolidated confirmation
|
||||
|
||||
### Other
|
||||
|
||||
- **Simplified setup** — Config creation now uses sensible defaults with helpful comments instead of interactive prompts
|
||||
|
||||
## 0.22.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#530](https://github.com/Fission-AI/OpenSpec/pull/530) [`33466b1`](https://github.com/Fission-AI/OpenSpec/commit/33466b1e2a6798bdd6d0e19149173585b0612e6f) Thanks [@TabishB](https://github.com/TabishB)! - Add project-level configuration, project-local schemas, and schema management commands
|
||||
|
||||
**New Features**
|
||||
|
||||
- **Project-level configuration** — Configure OpenSpec behavior per-project via `openspec/config.yaml`, including custom rules injection, context files, and schema resolution settings
|
||||
- **Project-local schemas** — Define custom artifact schemas within your project's `openspec/schemas/` directory for project-specific workflows
|
||||
- **Schema management commands** — New `openspec schema` commands (`list`, `show`, `export`, `validate`) for inspecting and managing artifact schemas (experimental)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fixed config loading to handle null `rules` field in project configuration
|
||||
|
||||
## 0.21.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#516](https://github.com/Fission-AI/OpenSpec/pull/516) [`b5a8847`](https://github.com/Fission-AI/OpenSpec/commit/b5a884748be6156a7bb140b4941cfec4f20a9fc8) Thanks [@TabishB](https://github.com/TabishB)! - Add feedback command and Nix flake support
|
||||
|
||||
**New Features**
|
||||
|
||||
- **Feedback command** — Submit feedback directly from the CLI with `openspec feedback`, which creates GitHub Issues with automatic metadata inclusion and graceful fallback for manual submission
|
||||
- **Nix flake support** — Install and develop openspec using Nix with the new `flake.nix`, including automated flake maintenance and CI validation
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- **Explore mode guardrails** — Explore mode now explicitly prevents implementation, keeping the focus on thinking and discovery while still allowing artifact creation
|
||||
|
||||
**Other**
|
||||
|
||||
- Improved change inference in `opsx apply` — automatically detects the target change from conversation context or prompts when ambiguous
|
||||
- Streamlined archive sync assessment with clearer delta spec location guidance
|
||||
|
||||
## 0.20.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#502](https://github.com/Fission-AI/OpenSpec/pull/502) [`9db74aa`](https://github.com/Fission-AI/OpenSpec/commit/9db74aa5ac6547efadaed795217cfa17444f2004) Thanks [@TabishB](https://github.com/TabishB)! - Add `/opsx:verify` command and fix vitest process storms
|
||||
|
||||
**New Features**
|
||||
|
||||
- **`/opsx:verify` command** — Validate that change implementations match their specifications
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fixed vitest process storms by capping worker parallelism
|
||||
- Fixed agent workflows to use non-interactive mode for validation commands
|
||||
- Fixed PowerShell completions generator to remove trailing commas
|
||||
|
||||
## 0.19.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- eb152eb: Add Continue IDE support, shell completions, and `/opsx:explore` command
|
||||
|
||||
**New Features**
|
||||
|
||||
- **Continue IDE support** – OpenSpec now generates slash commands for [Continue](https://continue.dev/), expanding editor integration options alongside Cursor, Windsurf, Claude Code, and others
|
||||
- **Shell completions for Bash, Fish, and PowerShell** – Run `openspec completion install` to set up tab completion in your preferred shell
|
||||
- **`/opsx:explore` command** – A new thinking partner mode for exploring ideas and investigating problems before committing to changes
|
||||
- **Codebuddy slash command improvements** – Updated frontmatter format for better compatibility
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Shell completions now correctly offer parent-level flags (like `--help`) when a command has subcommands
|
||||
- Fixed Windows compatibility issues in tests
|
||||
|
||||
**Other**
|
||||
|
||||
- Added optional anonymous usage statistics to help understand how OpenSpec is used. This is **opt-out** by default – set `OPENSPEC_TELEMETRY=0` or `DO_NOT_TRACK=1` to disable. Only command names and version are collected; no arguments, file paths, or content. Automatically disabled in CI environments.
|
||||
|
||||
## 0.18.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 8dfd824: Add OPSX experimental workflow commands and enhanced artifact system
|
||||
|
||||
**New Commands:**
|
||||
|
||||
- `/opsx:ff` - Fast-forward through artifact creation, generating all needed artifacts in one go
|
||||
- `/opsx:sync` - Sync delta specs from a change to main specs
|
||||
- `/opsx:archive` - Archive completed changes with smart sync check
|
||||
|
||||
**Artifact Workflow Enhancements:**
|
||||
|
||||
- Schema-aware apply instructions with inline guidance and XML output
|
||||
- Agent schema selection for experimental artifact workflow
|
||||
- Per-change schema metadata via `.openspec.yaml` files
|
||||
- Agent Skills for experimental artifact workflow
|
||||
- Instruction loader for template loading and change context
|
||||
- Restructured schemas as directories with templates
|
||||
|
||||
**Improvements:**
|
||||
|
||||
- Enhanced list command with last modified timestamps and sorting
|
||||
- Change creation utilities for better workflow support
|
||||
|
||||
**Fixes:**
|
||||
|
||||
- Normalize paths for cross-platform glob compatibility
|
||||
- Allow REMOVED requirements when creating new spec files
|
||||
|
||||
## 0.17.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 455c65f: Fix `--no-interactive` flag in validate command to properly disable spinner, preventing hangs in pre-commit hooks and CI environments
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a2757e7: Fix pre-commit hook hang issue in config command by using dynamic import for @inquirer/prompts
|
||||
|
||||
The config command was causing pre-commit hooks to hang indefinitely due to stdin event listeners being registered at module load time. This fix converts the static import to a dynamic import that only loads inquirer when the `config reset` command is actually used interactively.
|
||||
|
||||
Also adds ESLint with a rule to prevent static @inquirer imports, avoiding future regressions.
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 2e71835: Add `openspec config` command and Oh-my-zsh completions
|
||||
|
||||
**New Features**
|
||||
|
||||
- Add `openspec config` command for managing global configuration settings
|
||||
- Implement global config directory with XDG Base Directory specification support
|
||||
- Add Oh-my-zsh shell completions support for enhanced CLI experience
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix hang in pre-commit hooks by using dynamic imports
|
||||
- Respect XDG_CONFIG_HOME environment variable on all platforms
|
||||
- Resolve Windows compatibility issues in zsh-installer tests
|
||||
- Align cli-completion spec with implementation
|
||||
- Remove hardcoded agent field from slash commands
|
||||
|
||||
**Documentation**
|
||||
|
||||
- Alphabetize AI tools list in README and make it collapsible
|
||||
|
||||
## 0.16.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- c08fbc1: Add new AI tool integrations and enhancements:
|
||||
|
||||
- **feat(iflow-cli)**: Add iFlow-cli integration with slash command support and documentation
|
||||
- **feat(init)**: Add IDE restart instruction after init to inform users about slash command availability
|
||||
**feat(antigravity)**: Add Antigravity slash command support
|
||||
- **fix**: Generate TOML commands for Qwen Code (fixes #293)
|
||||
- Clarify scaffold proposal documentation and enhance proposal guidelines
|
||||
- Update proposal guidelines to emphasize design-first approach before implementation
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add Continue slash command support so `openspec init` can generate `.continue/prompts/openspec-*.prompt` files with MARKDOWN frontmatter and `$ARGUMENTS` placeholder, and refresh them on `openspec update`.
|
||||
|
||||
- Add Antigravity slash command support so `openspec init` can generate `.agent/workflows/openspec-*.md` files with description-only frontmatter and `openspec update` refreshes existing workflows alongside Windsurf.
|
||||
|
||||
## 0.15.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 4758c5c: Add support for new AI tools with native slash command integration
|
||||
|
||||
- **Gemini CLI**: Add native TOML-based slash command support for Gemini CLI with `.gemini/commands/openspec/` integration
|
||||
- **RooCode**: Add RooCode integration with configurator, slash commands, and templates
|
||||
- **Cline**: Fix Cline to use workflows instead of rules for slash commands (`.clinerules/workflows/` paths)
|
||||
- **Documentation**: Update documentation to reflect new integrations and workflow changes
|
||||
|
||||
## 0.14.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 8386b91: Add support for new AI assistants and configuration improvements
|
||||
|
||||
- feat: add Qwen Code support with slash command integration
|
||||
- feat: add $ARGUMENTS support to apply slash command for dynamic variable passing
|
||||
- feat: add Qoder CLI support to configuration and documentation
|
||||
- feat: add CoStrict AI assistant support
|
||||
- fix: recreate missing openspec template files in extend mode
|
||||
- fix: prevent false 'already configured' detection for tools
|
||||
- fix: use change-id as fallback title instead of "Untitled Change"
|
||||
- docs: add guidance for populating project-level context
|
||||
- docs: add Crush to supported AI tools in README
|
||||
|
||||
## 0.13.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 668a125: Add support for multiple AI assistants and improve validation
|
||||
|
||||
This release adds support for several new AI coding assistants:
|
||||
|
||||
- CodeBuddy Code - AI-powered coding assistant
|
||||
- CodeRabbit - AI code review assistant
|
||||
- Cline - Claude-powered CLI assistant
|
||||
- Crush AI - AI assistant platform
|
||||
- Auggie (Augment CLI) - Code augmentation tool
|
||||
|
||||
New features:
|
||||
|
||||
- Archive slash command now supports arguments for more flexible workflows
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Delta spec validation now handles case-insensitive headers and properly detects empty sections
|
||||
- Archive validation now correctly honors --no-validate flag and ignores metadata
|
||||
|
||||
Documentation improvements:
|
||||
|
||||
- Added VS Code dev container configuration for easier development setup
|
||||
- Updated AGENTS.md with explicit change-id notation
|
||||
- Enhanced slash commands documentation with restart notes
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 082abb4: Add factory function support for slash commands and non-interactive init options
|
||||
|
||||
This release includes two new features:
|
||||
|
||||
- **Factory function support for slash commands**: Slash commands can now be defined as functions that return command objects, enabling dynamic command configuration
|
||||
- **Non-interactive init options**: Added `--tools`, `--all-tools`, and `--skip-tools` CLI flags to `openspec init` for automated initialization in CI/CD pipelines while maintaining backward compatibility with interactive mode
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 312e1d6: Add Amazon Q Developer CLI integration. OpenSpec now supports Amazon Q Developer with automatic prompt generation in `.amazonq/prompts/` directory, allowing you to use OpenSpec slash commands with Amazon Q's @-syntax.
|
||||
|
||||
## 0.10.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- d7e0ce8: Improve init wizard Enter key behavior to allow proceeding through prompts more naturally
|
||||
|
||||
## 0.9.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2ae0484: Fix cross-platform path handling issues. This release includes fixes for joinPath behavior and slash command path resolution to ensure OpenSpec works correctly across all platforms.
|
||||
|
||||
## 0.9.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 8210970: Fix OpenSpec not working on Windows when Codex integration is selected. This release includes fixes for cross-platform path handling and normalization to ensure OpenSpec works correctly on Windows systems.
|
||||
|
||||
## 0.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- efbbf3b: Add support for Codex and GitHub Copilot slash commands with YAML frontmatter and $ARGUMENTS
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add GitHub Copilot slash command support. OpenSpec now writes prompts to `.github/prompts/openspec-{proposal,apply,archive}.prompt.md` with YAML frontmatter and `$ARGUMENTS` placeholder, and refreshes them on `openspec update`.
|
||||
|
||||
## 0.8.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- d070d08: Fix CLI version mismatch and add a release guard that validates the packed tarball prints the same version as package.json via `openspec --version`.
|
||||
|
||||
## 0.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- c29b06d: Add Windsurf support.
|
||||
- Add Codex slash command support. OpenSpec now writes prompts directly to Codex's global directory (`~/.codex/prompts` or `$CODEX_HOME/prompts`) and refreshes them on `openspec update`.
|
||||
|
||||
## 0.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add native Kilo Code workflow integration so `openspec init` and `openspec update` manage `.kilocode/workflows/openspec-*.md` files.
|
||||
- Always scaffold the managed root `AGENTS.md` hand-off stub and regroup the AI tool prompts during init/update to keep instructions consistent.
|
||||
|
||||
## 0.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Slim the generated root agent instructions down to a managed hand-off stub and update the init/update flows to refresh it safely.
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- feat: implement Phase 1 E2E testing with cross-platform CI matrix
|
||||
|
||||
- Add shared runCLI helper in test/helpers/run-cli.ts for spawn testing
|
||||
- Create test/cli-e2e/basic.test.ts covering help, version, validate flows
|
||||
- Migrate existing CLI exec tests to use runCLI helper
|
||||
- Extend CI matrix to bash (Linux/macOS) and pwsh (Windows)
|
||||
- Split PR and main workflows for optimized feedback
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Make apply instructions more specific
|
||||
|
||||
Improve agent templates and slash command templates with more specific and actionable apply instructions.
|
||||
|
||||
- docs: improve documentation and cleanup
|
||||
|
||||
- Document non-interactive flag for archive command
|
||||
- Replace discord badge in README
|
||||
- Archive completed changes for better organization
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add OpenSpec change proposals for CLI improvements and enhanced user experience
|
||||
- Add Opencode slash commands support for AI-driven development workflows
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Add documentation improvements including --yes flag for archive command template and Discord badge
|
||||
- Fix normalize line endings in markdown parser to handle CRLF files properly
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Enhance `openspec init` with extend mode, multi-tool selection, and an interactive `AGENTS.md` configurator.
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- ce5cead: - Add an `openspec view` dashboard that rolls up spec counts and change progress at a glance
|
||||
- Generate and update AI slash commands alongside the renamed `openspec/AGENTS.md` instructions file
|
||||
- Remove the deprecated `openspec diff` command and direct users to `openspec show`
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 24b4866: Initial release
|
||||
@@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 OpenSpec Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# Maintainers
|
||||
|
||||
People who maintain and guide OpenSpec.
|
||||
|
||||
## Core Maintainers
|
||||
|
||||
| Name | GitHub | Role |
|
||||
|------|--------|------|
|
||||
| Tabish Bidiwale | [@TabishB](https://github.com/TabishB) | Lead maintainer |
|
||||
|
||||
## Advisors
|
||||
|
||||
Advisors help shape technical direction and provide guidance to the project.
|
||||
|
||||
| Name | GitHub | Focus |
|
||||
|------|--------|-------|
|
||||
| Hari Krishnan | [@harikrishnan83](https://github.com/harikrishnan83) | Technical direction |
|
||||
@@ -0,0 +1,201 @@
|
||||
<p align="center">
|
||||
<a href="https://github.com/Fission-AI/OpenSpec">
|
||||
<picture>
|
||||
<source srcset="assets/openspec_bg.png">
|
||||
<img src="assets/openspec_bg.png" alt="OpenSpec logo">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml/badge.svg" /></a>
|
||||
<a href="https://www.npmjs.com/package/@fission-ai/openspec"><img alt="npm version" src="https://img.shields.io/npm/v/@fission-ai/openspec?style=flat-square" /></a>
|
||||
<a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" /></a>
|
||||
<a href="https://discord.gg/YctCnvvshC"><img alt="Discord" src="https://img.shields.io/discord/1411657095639601154?style=flat-square&logo=discord&logoColor=white&label=Discord&suffix=%20online" /></a>
|
||||
</p>
|
||||
|
||||
<details>
|
||||
<summary><strong>The most loved spec framework.</strong></summary>
|
||||
|
||||
[](https://github.com/Fission-AI/OpenSpec/stargazers)
|
||||
[](https://www.npmjs.com/package/@fission-ai/openspec)
|
||||
[](https://github.com/Fission-AI/OpenSpec/graphs/contributors)
|
||||
|
||||
</details>
|
||||
<p></p>
|
||||
Our philosophy:
|
||||
|
||||
```text
|
||||
→ fluid not rigid
|
||||
→ iterative not waterfall
|
||||
→ easy not complex
|
||||
→ built for brownfield not just greenfield
|
||||
→ scalable from personal projects to enterprises
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> **New workflow now available!** We've rebuilt OpenSpec with a new artifact-guided workflow.
|
||||
>
|
||||
> Run `/opsx:propose "your idea"` to get started. → [Learn more here](docs/opsx.md)
|
||||
|
||||
<p align="center">
|
||||
Follow <a href="https://x.com/0xTab">@0xTab on X</a> for updates · Join the <a href="https://discord.gg/YctCnvvshC">OpenSpec Discord</a> for help and questions.
|
||||
</p>
|
||||
|
||||
<!-- TODO: Add GIF demo of /opsx:propose → /opsx:archive workflow -->
|
||||
|
||||
## See it in action
|
||||
|
||||
```text
|
||||
You: /opsx:propose add-dark-mode
|
||||
AI: Created openspec/changes/add-dark-mode/
|
||||
✓ proposal.md — why we're doing this, what's changing
|
||||
✓ specs/ — requirements and scenarios
|
||||
✓ design.md — technical approach
|
||||
✓ tasks.md — implementation checklist
|
||||
Ready for implementation!
|
||||
|
||||
You: /opsx:apply
|
||||
AI: Implementing tasks...
|
||||
✓ 1.1 Add theme context provider
|
||||
✓ 1.2 Create toggle component
|
||||
✓ 2.1 Add CSS variables
|
||||
✓ 2.2 Wire up localStorage
|
||||
All tasks complete!
|
||||
|
||||
You: /opsx:archive
|
||||
AI: Archived to openspec/changes/archive/2025-01-23-add-dark-mode/
|
||||
Specs updated. Ready for the next feature.
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><strong>OpenSpec Dashboard</strong></summary>
|
||||
|
||||
<p align="center">
|
||||
<img src="assets/openspec_dashboard.png" alt="OpenSpec dashboard preview" width="90%">
|
||||
</p>
|
||||
|
||||
</details>
|
||||
|
||||
## Quick Start
|
||||
|
||||
**Requires Node.js 20.19.0 or higher.**
|
||||
|
||||
Install OpenSpec globally:
|
||||
|
||||
```bash
|
||||
npm install -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
Then navigate to your project directory and initialize:
|
||||
|
||||
```bash
|
||||
cd your-project
|
||||
openspec init
|
||||
```
|
||||
|
||||
Now tell your AI: `/opsx:propose <what-you-want-to-build>`
|
||||
|
||||
If you want the expanded workflow (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:sync`, `/opsx:bulk-archive`, `/opsx:onboard`), select it with `openspec config profile` and apply with `openspec update`.
|
||||
|
||||
> [!NOTE]
|
||||
> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 25+ tools and growing.
|
||||
>
|
||||
> Also works with pnpm, yarn, bun, and nix. [See installation options](docs/installation.md).
|
||||
|
||||
## Docs
|
||||
|
||||
→ **[Getting Started](docs/getting-started.md)**: first steps<br>
|
||||
→ **[Workflows](docs/workflows.md)**: combos and patterns<br>
|
||||
→ **[Commands](docs/commands.md)**: slash commands & skills<br>
|
||||
→ **[CLI](docs/cli.md)**: terminal reference<br>
|
||||
→ **[Workspace Mode](docs/workspace.md)**: when to use cross-repo workspaces, starting with `openspec workspace setup`<br>
|
||||
→ **[Workspace Demo](docs/workspace-demo.md)**: a real-user workspace tutorial you can run against your actual local repos<br>
|
||||
→ **[Supported Tools](docs/supported-tools.md)**: tool integrations & install paths<br>
|
||||
→ **[Concepts](docs/concepts.md)**: how it all fits<br>
|
||||
→ **[Multi-Language](docs/multi-language.md)**: multi-language support<br>
|
||||
→ **[Customization](docs/customization.md)**: make it yours
|
||||
|
||||
|
||||
## Why OpenSpec?
|
||||
|
||||
AI coding assistants are powerful but unpredictable when requirements live only in chat history. OpenSpec adds a lightweight spec layer so you agree on what to build before any code is written.
|
||||
|
||||
- **Agree before you build** — human and AI align on specs before code gets written
|
||||
- **Stay organized** — each change gets its own folder with proposal, specs, design, and tasks
|
||||
- **Work fluidly** — update any artifact anytime, no rigid phase gates
|
||||
- **Use your tools** — works with 20+ AI assistants via slash commands
|
||||
|
||||
### How we compare
|
||||
|
||||
**vs. [Spec Kit](https://github.com/github/spec-kit)** (GitHub) — Thorough but heavyweight. Rigid phase gates, lots of Markdown, Python setup. OpenSpec is lighter and lets you iterate freely.
|
||||
|
||||
**vs. [Kiro](https://kiro.dev)** (AWS) — Powerful but you're locked into their IDE and limited to Claude models. OpenSpec works with the tools you already use.
|
||||
|
||||
**vs. nothing** — AI coding without specs means vague prompts and unpredictable results. OpenSpec brings predictability without the ceremony.
|
||||
|
||||
## Updating OpenSpec
|
||||
|
||||
**Upgrade the package**
|
||||
|
||||
```bash
|
||||
npm install -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
**Refresh agent instructions**
|
||||
|
||||
Run this inside each project to regenerate AI guidance and ensure the latest slash commands are active:
|
||||
|
||||
```bash
|
||||
openspec update
|
||||
```
|
||||
|
||||
## Usage Notes
|
||||
|
||||
**Model selection**: OpenSpec works best with high-reasoning models. We recommend Opus 4.5 and GPT 5.2 for both planning and implementation.
|
||||
|
||||
**Context hygiene**: OpenSpec benefits from a clean context window. Clear your context before starting implementation and maintain good context hygiene throughout your session.
|
||||
|
||||
## Contributing
|
||||
|
||||
**Small fixes** — Bug fixes, typo corrections, and minor improvements can be submitted directly as PRs.
|
||||
|
||||
**Larger changes** — For new features, significant refactors, or architectural changes, please submit an OpenSpec change proposal first so we can align on intent and goals before implementation begins.
|
||||
|
||||
When writing proposals, keep the OpenSpec philosophy in mind: we serve a wide variety of users across different coding agents, models, and use cases. Changes should work well for everyone.
|
||||
|
||||
**AI-generated code is welcome** — as long as it's been tested and verified. PRs containing AI-generated code should mention the coding agent and model used (e.g., "Generated with Claude Code using claude-opus-4-5-20251101").
|
||||
|
||||
### Development
|
||||
|
||||
- Install dependencies: `pnpm install`
|
||||
- Build: `pnpm run build`
|
||||
- Test: `pnpm test`
|
||||
- Develop CLI locally: `pnpm run dev` or `pnpm run dev:cli`
|
||||
- Conventional commits (one-line): `type(scope): subject`
|
||||
|
||||
## Other
|
||||
|
||||
<details>
|
||||
<summary><strong>Telemetry</strong></summary>
|
||||
|
||||
OpenSpec collects anonymous usage stats.
|
||||
|
||||
We collect only command names and version to understand usage patterns. No arguments, paths, content, or PII. Automatically disabled in CI.
|
||||
|
||||
**Opt-out:** `export OPENSPEC_TELEMETRY=0` or `export DO_NOT_TRACK=1`
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Maintainers & Advisors</strong></summary>
|
||||
|
||||
See [MAINTAINERS.md](MAINTAINERS.md) for the list of core maintainers and advisors who help guide the project.
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
+475
@@ -0,0 +1,475 @@
|
||||
<p align="center">
|
||||
<a href="https://github.com/Fission-AI/OpenSpec">
|
||||
<picture>
|
||||
<source srcset="assets/openspec_pixel_dark.svg" media="(prefers-color-scheme: dark)">
|
||||
<source srcset="assets/openspec_pixel_light.svg" media="(prefers-color-scheme: light)">
|
||||
<img src="assets/openspec_pixel_light.svg" alt="OpenSpec logo" height="64">
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
</p>
|
||||
<p align="center">Spec-driven development for AI coding assistants.</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml/badge.svg" /></a>
|
||||
<a href="https://www.npmjs.com/package/@fission-ai/openspec"><img alt="npm version" src="https://img.shields.io/npm/v/@fission-ai/openspec?style=flat-square" /></a>
|
||||
<a href="https://nodejs.org/"><img alt="node version" src="https://img.shields.io/node/v/@fission-ai/openspec?style=flat-square" /></a>
|
||||
<a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" /></a>
|
||||
<a href="https://conventionalcommits.org"><img alt="Conventional Commits" src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg?style=flat-square" /></a>
|
||||
<a href="https://discord.gg/YctCnvvshC"><img alt="Discord" src="https://img.shields.io/badge/Discord-Join%20the%20community-5865F2?logo=discord&logoColor=white&style=flat-square" /></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="assets/openspec_dashboard.png" alt="OpenSpec dashboard preview" width="90%">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Follow <a href="https://x.com/0xTab">@0xTab on X</a> for updates · Join the <a href="https://discord.gg/YctCnvvshC">OpenSpec Discord</a> for help and questions.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<sub>🧪 <strong>New:</strong> <a href="docs/opsx.md">OPSX Workflow</a> — schema-driven, hackable, fluid. Iterate on workflows without code changes.</sub>
|
||||
</p>
|
||||
|
||||
# OpenSpec
|
||||
|
||||
OpenSpec aligns humans and AI coding assistants with spec-driven development so you agree on what to build before any code is written. **No API keys required.**
|
||||
|
||||
## Why OpenSpec?
|
||||
|
||||
AI coding assistants are powerful but unpredictable when requirements live in chat history. OpenSpec adds a lightweight specification workflow that locks intent before implementation, giving you deterministic, reviewable outputs.
|
||||
|
||||
Key outcomes:
|
||||
- Human and AI stakeholders agree on specs before work begins.
|
||||
- Structured change folders (proposals, tasks, and spec updates) keep scope explicit and auditable.
|
||||
- Shared visibility into what's proposed, active, or archived.
|
||||
- Works with the AI tools you already use: custom slash commands where supported, context rules everywhere else.
|
||||
|
||||
## How OpenSpec compares (at a glance)
|
||||
|
||||
- **Lightweight**: simple workflow, no API keys, minimal setup.
|
||||
- **Brownfield-first**: works great beyond 0→1. OpenSpec separates the source of truth from proposals: `openspec/specs/` (current truth) and `openspec/changes/` (proposed updates). This keeps diffs explicit and manageable across features.
|
||||
- **Change tracking**: proposals, tasks, and spec deltas live together; archiving merges the approved updates back into specs.
|
||||
- **Compared to spec-kit & Kiro**: those shine for brand-new features (0→1). OpenSpec also excels when modifying existing behavior (1→n), especially when updates span multiple specs.
|
||||
|
||||
See the full comparison in [How OpenSpec Compares](#how-openspec-compares).
|
||||
|
||||
## How It Works
|
||||
|
||||
```
|
||||
┌────────────────────┐
|
||||
│ Draft Change │
|
||||
│ Proposal │
|
||||
└────────┬───────────┘
|
||||
│ share intent with your AI
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ Review & Align │
|
||||
│ (edit specs/tasks) │◀──── feedback loop ──────┐
|
||||
└────────┬───────────┘ │
|
||||
│ approved plan │
|
||||
▼ │
|
||||
┌────────────────────┐ │
|
||||
│ Implement Tasks │──────────────────────────┘
|
||||
│ (AI writes code) │
|
||||
└────────┬───────────┘
|
||||
│ ship the change
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ Archive & Update │
|
||||
│ Specs (source) │
|
||||
└────────────────────┘
|
||||
|
||||
1. Draft a change proposal that captures the spec updates you want.
|
||||
2. Review the proposal with your AI assistant until everyone agrees.
|
||||
3. Implement tasks that reference the agreed specs.
|
||||
4. Archive the change to merge the approved updates back into the source-of-truth specs.
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Supported AI Tools
|
||||
|
||||
<details>
|
||||
<summary><strong>Native Slash Commands</strong> (click to expand)</summary>
|
||||
|
||||
These tools have built-in OpenSpec commands. Select the OpenSpec integration when prompted.
|
||||
|
||||
| Tool | Commands |
|
||||
|------|----------|
|
||||
| **Amazon Q Developer** | `@openspec-proposal`, `@openspec-apply`, `@openspec-archive` (`.amazonq/prompts/`) |
|
||||
| **Antigravity** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.agent/workflows/`) |
|
||||
| **Auggie (Augment CLI)** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.augment/commands/`) |
|
||||
| **Claude Code** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` |
|
||||
| **Cline** | Workflows in `.clinerules/workflows/` directory (`.clinerules/workflows/openspec-*.md`) |
|
||||
| **CodeBuddy Code (CLI)** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.codebuddy/commands/`) — see [docs](https://www.codebuddy.ai/cli) |
|
||||
| **Codex** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (global: `~/.codex/prompts`, auto-installed) |
|
||||
| **Continue** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.continue/prompts/`) |
|
||||
| **CoStrict** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.cospec/openspec/commands/`) — see [docs](https://costrict.ai)|
|
||||
| **Crush** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.crush/commands/openspec/`) |
|
||||
| **Cursor** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
|
||||
| **Factory Droid** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.factory/commands/`) |
|
||||
| **Gemini CLI** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.gemini/commands/openspec/`) |
|
||||
| **GitHub Copilot** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.github/prompts/`) |
|
||||
| **iFlow (iflow-cli)** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.iflow/commands/`) |
|
||||
| **Kilo Code** | `/openspec-proposal.md`, `/openspec-apply.md`, `/openspec-archive.md` (`.kilocode/workflows/`) |
|
||||
| **OpenCode** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
|
||||
| **Qoder** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.qoder/commands/openspec/`) — see [docs](https://qoder.com) |
|
||||
| **Qwen Code** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.qwen/commands/`) |
|
||||
| **RooCode** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.roo/commands/`) |
|
||||
| **Windsurf** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.windsurf/workflows/`) |
|
||||
|
||||
Kilo Code discovers team workflows automatically. Save the generated files under `.kilocode/workflows/` and trigger them from the command palette with `/openspec-proposal.md`, `/openspec-apply.md`, or `/openspec-archive.md`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>AGENTS.md Compatible</strong> (click to expand)</summary>
|
||||
|
||||
These tools automatically read workflow instructions from `openspec/AGENTS.md`. Ask them to follow the OpenSpec workflow if they need a reminder. Learn more about the [AGENTS.md convention](https://agents.md/).
|
||||
|
||||
| Tools |
|
||||
|-------|
|
||||
| Amp • Jules • Others |
|
||||
|
||||
</details>
|
||||
|
||||
### Install & Initialize
|
||||
|
||||
#### Prerequisites
|
||||
- **Node.js >= 20.19.0** - Check your version with `node --version`
|
||||
|
||||
#### Step 1: Install the CLI globally
|
||||
|
||||
**Option A: Using npm**
|
||||
|
||||
```bash
|
||||
npm install -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
Verify installation:
|
||||
```bash
|
||||
openspec --version
|
||||
```
|
||||
|
||||
**Option B: Using Nix (NixOS and Nix package manager)**
|
||||
|
||||
Run OpenSpec directly without installation:
|
||||
```bash
|
||||
nix run github:Fission-AI/OpenSpec -- init
|
||||
```
|
||||
|
||||
Or install to your profile:
|
||||
```bash
|
||||
nix profile install github:Fission-AI/OpenSpec
|
||||
```
|
||||
|
||||
Or add to your development environment in `flake.nix`:
|
||||
```nix
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
openspec.url = "github:Fission-AI/OpenSpec";
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, openspec, ... }: {
|
||||
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
|
||||
buildInputs = [ openspec.packages.x86_64-linux.default ];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Verify installation:
|
||||
```bash
|
||||
openspec --version
|
||||
```
|
||||
|
||||
#### Step 2: Initialize OpenSpec in your project
|
||||
|
||||
Navigate to your project directory:
|
||||
```bash
|
||||
cd my-project
|
||||
```
|
||||
|
||||
Run the initialization:
|
||||
```bash
|
||||
openspec init
|
||||
```
|
||||
|
||||
**What happens during initialization:**
|
||||
- You'll be prompted to pick any natively supported AI tools (Claude Code, CodeBuddy, Cursor, OpenCode, Qoder,etc.); other assistants always rely on the shared `AGENTS.md` stub
|
||||
- OpenSpec automatically configures slash commands for the tools you choose and always writes a managed `AGENTS.md` hand-off at the project root
|
||||
- A new `openspec/` directory structure is created in your project
|
||||
|
||||
**After setup:**
|
||||
- Primary AI tools can trigger `/openspec` workflows without additional configuration
|
||||
- Run `openspec list` to verify the setup and view any active changes
|
||||
- If your coding assistant doesn't surface the new slash commands right away, restart it. Slash commands are loaded at startup,
|
||||
so a fresh launch ensures they appear
|
||||
|
||||
### Optional: Populate Project Context
|
||||
|
||||
After `openspec init` completes, you'll receive a suggested prompt to help populate your project context:
|
||||
|
||||
```text
|
||||
Populate your project context:
|
||||
"Please read openspec/project.md and help me fill it out with details about my project, tech stack, and conventions"
|
||||
```
|
||||
|
||||
Use `openspec/project.md` to define project-level conventions, standards, architectural patterns, and other guidelines that should be followed across all changes.
|
||||
|
||||
### Create Your First Change
|
||||
|
||||
Here's a real example showing the complete OpenSpec workflow. This works with any AI tool. Those with native slash commands will recognize the shortcuts automatically.
|
||||
|
||||
#### 1. Draft the Proposal
|
||||
Start by asking your AI to create a change proposal:
|
||||
|
||||
```text
|
||||
You: Create an OpenSpec change proposal for adding profile search filters by role and team
|
||||
(Shortcut for tools with slash commands: /openspec:proposal Add profile search filters)
|
||||
|
||||
AI: I'll create an OpenSpec change proposal for profile filters.
|
||||
*Scaffolds openspec/changes/add-profile-filters/ with proposal.md, tasks.md, spec deltas.*
|
||||
```
|
||||
|
||||
#### 2. Verify & Review
|
||||
Check that the change was created correctly and review the proposal:
|
||||
|
||||
```bash
|
||||
$ openspec list # Confirm the change folder exists
|
||||
$ openspec validate add-profile-filters # Validate spec formatting
|
||||
$ openspec show add-profile-filters # Review proposal, tasks, and spec delta
|
||||
```
|
||||
|
||||
#### 3. Refine the Specs
|
||||
Iterate on the specifications until they match your needs:
|
||||
|
||||
```text
|
||||
You: Can you add acceptance criteria for the role and team filters?
|
||||
|
||||
AI: I'll update the spec delta with scenarios for role and team filters.
|
||||
*Edits openspec/changes/add-profile-filters/specs/profile/spec.md and tasks.md.*
|
||||
```
|
||||
|
||||
#### 4. Implement the Change
|
||||
Once specs look good, start implementation:
|
||||
|
||||
```text
|
||||
You: The specs look good. Let's implement this change.
|
||||
(Shortcut for tools with slash commands: /openspec:apply add-profile-filters)
|
||||
|
||||
AI: I'll work through the tasks in the add-profile-filters change.
|
||||
*Implements tasks from openspec/changes/add-profile-filters/tasks.md*
|
||||
*Marks tasks complete: Task 1.1 ✓, Task 1.2 ✓, Task 2.1 ✓...*
|
||||
```
|
||||
|
||||
#### 5. Archive the Completed Change
|
||||
After implementation is complete, archive the change:
|
||||
|
||||
```text
|
||||
AI: All tasks are complete. The implementation is ready.
|
||||
|
||||
You: Please archive the change
|
||||
(Shortcut for tools with slash commands: /openspec:archive add-profile-filters)
|
||||
|
||||
AI: I'll archive the add-profile-filters change.
|
||||
*Runs: openspec archive add-profile-filters --yes*
|
||||
✓ Change archived successfully. Specs updated. Ready for the next feature!
|
||||
```
|
||||
|
||||
Or run the command yourself in terminal:
|
||||
```bash
|
||||
$ openspec archive add-profile-filters --yes # Archive the completed change without prompts
|
||||
```
|
||||
|
||||
**Note:** Tools with native slash commands (Claude Code, CodeBuddy, Cursor, Codex, Qoder, RooCode) can use the shortcuts shown. All other tools work with natural language requests to "create an OpenSpec proposal", "apply the OpenSpec change", or "archive the change".
|
||||
|
||||
## Command Reference
|
||||
|
||||
```bash
|
||||
openspec list # View active change folders
|
||||
openspec view # Interactive dashboard of specs and changes
|
||||
openspec show <change> # Display change details (proposal, tasks, spec updates)
|
||||
openspec validate <change> # Check spec formatting and structure
|
||||
openspec archive <change> [--yes|-y] # Move a completed change into archive/ (non-interactive with --yes)
|
||||
```
|
||||
|
||||
## Example: How AI Creates OpenSpec Files
|
||||
|
||||
When you ask your AI assistant to "add two-factor authentication", it creates:
|
||||
|
||||
```
|
||||
openspec/
|
||||
├── specs/
|
||||
│ └── auth/
|
||||
│ └── spec.md # Current auth spec (if exists)
|
||||
└── changes/
|
||||
└── add-2fa/ # AI creates this entire structure
|
||||
├── proposal.md # Why and what changes
|
||||
├── tasks.md # Implementation checklist
|
||||
├── design.md # Technical decisions (optional)
|
||||
└── specs/
|
||||
└── auth/
|
||||
└── spec.md # Delta showing additions
|
||||
```
|
||||
|
||||
### AI-Generated Spec (created in `openspec/specs/auth/spec.md`):
|
||||
|
||||
```markdown
|
||||
# Auth Specification
|
||||
|
||||
## Purpose
|
||||
Authentication and session management.
|
||||
|
||||
## Requirements
|
||||
### Requirement: User Authentication
|
||||
The system SHALL issue a JWT on successful login.
|
||||
|
||||
#### Scenario: Valid credentials
|
||||
- WHEN a user submits valid credentials
|
||||
- THEN a JWT is returned
|
||||
```
|
||||
|
||||
### AI-Generated Change Delta (created in `openspec/changes/add-2fa/specs/auth/spec.md`):
|
||||
|
||||
```markdown
|
||||
# Delta for Auth
|
||||
|
||||
## ADDED Requirements
|
||||
### Requirement: Two-Factor Authentication
|
||||
The system MUST require a second factor during login.
|
||||
|
||||
#### Scenario: OTP required
|
||||
- WHEN a user submits valid credentials
|
||||
- THEN an OTP challenge is required
|
||||
```
|
||||
|
||||
### AI-Generated Tasks (created in `openspec/changes/add-2fa/tasks.md`):
|
||||
|
||||
```markdown
|
||||
## 1. Database Setup
|
||||
- [ ] 1.1 Add OTP secret column to users table
|
||||
- [ ] 1.2 Create OTP verification logs table
|
||||
|
||||
## 2. Backend Implementation
|
||||
- [ ] 2.1 Add OTP generation endpoint
|
||||
- [ ] 2.2 Modify login flow to require OTP
|
||||
- [ ] 2.3 Add OTP verification endpoint
|
||||
|
||||
## 3. Frontend Updates
|
||||
- [ ] 3.1 Create OTP input component
|
||||
- [ ] 3.2 Update login flow UI
|
||||
```
|
||||
|
||||
**Important:** You don't create these files manually. Your AI assistant generates them based on your requirements and the existing codebase.
|
||||
|
||||
## Understanding OpenSpec Files
|
||||
|
||||
### Delta Format
|
||||
|
||||
Deltas are "patches" that show how specs change:
|
||||
|
||||
- **`## ADDED Requirements`** - New capabilities
|
||||
- **`## MODIFIED Requirements`** - Changed behavior (include complete updated text)
|
||||
- **`## REMOVED Requirements`** - Deprecated features
|
||||
|
||||
**Format requirements:**
|
||||
- Use `### Requirement: <name>` for headers
|
||||
- Every requirement needs at least one `#### Scenario:` block
|
||||
- Use SHALL/MUST in requirement text
|
||||
|
||||
## How OpenSpec Compares
|
||||
|
||||
### vs. spec-kit
|
||||
OpenSpec’s two-folder model (`openspec/specs/` for the current truth, `openspec/changes/` for proposed updates) keeps state and diffs separate. This scales when you modify existing features or touch multiple specs. spec-kit is strong for greenfield/0→1 but provides less structure for cross-spec updates and evolving features.
|
||||
|
||||
### vs. Kiro.dev
|
||||
OpenSpec groups every change for a feature in one folder (`openspec/changes/feature-name/`), making it easy to track related specs, tasks, and designs together. Kiro spreads updates across multiple spec folders, which can make feature tracking harder.
|
||||
|
||||
### vs. No Specs
|
||||
Without specs, AI coding assistants generate code from vague prompts, often missing requirements or adding unwanted features. OpenSpec brings predictability by agreeing on the desired behavior before any code is written.
|
||||
|
||||
## Team Adoption
|
||||
|
||||
1. **Initialize OpenSpec** – Run `openspec init` in your repo.
|
||||
2. **Start with new features** – Ask your AI to capture upcoming work as change proposals.
|
||||
3. **Grow incrementally** – Each change archives into living specs that document your system.
|
||||
4. **Stay flexible** – Different teammates can use Claude Code, CodeBuddy, Cursor, or any AGENTS.md-compatible tool while sharing the same specs.
|
||||
|
||||
Run `openspec update` whenever someone switches tools so your agents pick up the latest instructions and slash-command bindings.
|
||||
|
||||
## Updating OpenSpec
|
||||
|
||||
1. **Upgrade the package**
|
||||
```bash
|
||||
npm install -g @fission-ai/openspec@latest
|
||||
```
|
||||
2. **Refresh agent instructions**
|
||||
- Run `openspec update` inside each project to regenerate AI guidance and ensure the latest slash commands are active.
|
||||
|
||||
## Experimental Features
|
||||
|
||||
<details>
|
||||
<summary><strong>🧪 OPSX: Fluid, Iterative Workflow</strong> (Claude Code only)</summary>
|
||||
|
||||
**Why this exists:**
|
||||
- Standard workflow is locked down — you can't tweak instructions or customize
|
||||
- When AI output is bad, you can't improve the prompts yourself
|
||||
- Same workflow for everyone, no way to match how your team works
|
||||
|
||||
**What's different:**
|
||||
- **Hackable** — edit templates and schemas yourself, test immediately, no rebuild
|
||||
- **Granular** — each artifact has its own instructions, test and tweak individually
|
||||
- **Customizable** — define your own workflows, artifacts, and dependencies
|
||||
- **Fluid** — no phase gates, update any artifact anytime
|
||||
|
||||
```
|
||||
You can always go back:
|
||||
|
||||
proposal ──→ specs ──→ design ──→ tasks ──→ implement
|
||||
▲ ▲ ▲ │
|
||||
└───────────┴──────────┴────────────────────┘
|
||||
```
|
||||
|
||||
| Command | What it does |
|
||||
|---------|--------------|
|
||||
| `/opsx:new` | Start a new change |
|
||||
| `/opsx:continue` | Create the next artifact (based on what's ready) |
|
||||
| `/opsx:ff` | Fast-forward (all planning artifacts at once) |
|
||||
| `/opsx:apply` | Implement tasks, updating artifacts as needed |
|
||||
| `/opsx:archive` | Archive when done |
|
||||
|
||||
**Setup:** `openspec experimental`
|
||||
|
||||
[Full documentation →](docs/opsx.md)
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Telemetry</strong> – OpenSpec collects anonymous usage stats (opt-out: <code>OPENSPEC_TELEMETRY=0</code>)</summary>
|
||||
|
||||
We collect only command names and version to understand usage patterns. No arguments, paths, content, or PII. Automatically disabled in CI.
|
||||
|
||||
**Opt-out:** `export OPENSPEC_TELEMETRY=0` or `export DO_NOT_TRACK=1`
|
||||
|
||||
</details>
|
||||
|
||||
## Contributing
|
||||
|
||||
- Install dependencies: `pnpm install`
|
||||
- Build: `pnpm run build`
|
||||
- Test: `pnpm test`
|
||||
- Develop CLI locally: `pnpm run dev` or `pnpm run dev:cli`
|
||||
- Conventional commits (one-line): `type(scope): subject`
|
||||
|
||||
<details>
|
||||
<summary><strong>Maintainers & Advisors</strong></summary>
|
||||
|
||||
See [MAINTAINERS.md](MAINTAINERS.md) for the list of core maintainers and advisors who help guide the project.
|
||||
|
||||
</details>
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
+846
@@ -0,0 +1,846 @@
|
||||
# Workspace POC Roadmap
|
||||
|
||||
## Goal
|
||||
|
||||
Deliver a lean but real Workspace POC that follows the intended user flow:
|
||||
|
||||
`workspace create` -> `workspace add-repo` -> `new change --targets` -> `workspace open --change` -> `apply --change --repo` -> workspace-aware `status` -> explicit workspace completion/archive.
|
||||
|
||||
The roadmap is deliberately execution-ordered. Early phases establish the entrypoint and filesystem model first, then add repo registration, then cross-repo planning, then execution handoff, then roll-up and completion semantics.
|
||||
|
||||
## POC Guardrails
|
||||
|
||||
- Centralize planning in the workspace, not canonical truth.
|
||||
- Keep canonical specs in the owning repo.
|
||||
- Keep repo-local execution repo-local.
|
||||
- Reuse `change` as the primary user-facing primitive.
|
||||
- Keep workspace metadata under `.openspec/` at the workspace root.
|
||||
- Do not create an extra inner `openspec/` directory inside a dedicated workspace.
|
||||
- Store stable aliases in committed workspace metadata and absolute paths only in the local overlay.
|
||||
- Make repo attachment change-scoped, not workspace-wide.
|
||||
- Reuse the workspace change ID when materializing repo-local changes.
|
||||
- Start with create-only materialization unless a research phase explicitly chooses otherwise.
|
||||
- Keep mocks narrow. Prefer real temp directories, real file IO, and real CLI execution.
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
- Reuse the existing Vitest setup, `runCLI()` helper, and temp-directory pattern already used across the repo.
|
||||
- Add one reusable `workspaceSandbox()` helper instead of many bespoke test setups.
|
||||
- Add a small fixture set under `test/fixtures/workspace-poc/` and clone it into temp roots per test with `fs.cp` and `mkdtemp`.
|
||||
- Add shared assertions for the core invariants: no nested `openspec/` under the workspace root; no absolute repo paths in committed files; materialized repo-local change IDs match workspace change IDs; change-scoped attach only includes targeted repos.
|
||||
- Mock only prompt boundaries, telemetry, and agent-launch adapters. Do not mock filesystem behavior, path canonicalization, materialization logic, or status roll-up rules unless the test is specifically about an adapter boundary.
|
||||
- Keep three reusable filesystem shapes: empty workspace sandbox, happy-path workspace with three repos, and dirty workspace with stale aliases, partial materialization, and incomplete tasks.
|
||||
|
||||
## Output Convention
|
||||
|
||||
Every phase writes a `SUMMARY.md` to its phase directory.
|
||||
|
||||
- Build and test phases write to `notes/workspace-poc/phase-XX-<slug>/SUMMARY.md`, `notes/workspace-poc/phase-XX-<slug>/VERIFY.md`, and `notes/workspace-poc/phase-XX-<slug>/MANUAL_TEST.md`
|
||||
- Research phases write to `notes/workspace-poc/phase-XX-<slug>/SUMMARY.md`, `notes/workspace-poc/phase-XX-<slug>/DECISION.md`, `notes/workspace-poc/phase-XX-<slug>/VERIFY.md`, and `notes/workspace-poc/phase-XX-<slug>/MANUAL_TEST.md`
|
||||
- Task and acceptance-check checkboxes are phase-scoped and numbered sequentially, for example `01.1`, `01.2`, `01.3`.
|
||||
|
||||
The summary should capture:
|
||||
|
||||
- what was changed
|
||||
- what tests were run
|
||||
- what passed or failed
|
||||
- open issues for the next phase
|
||||
|
||||
The verification note should capture:
|
||||
|
||||
- what was independently checked in a fresh context
|
||||
- what issues were found
|
||||
- what fixes were applied
|
||||
- what residual risks remain, if any
|
||||
|
||||
The manual test note should capture:
|
||||
|
||||
- what user-visible or smoke scenarios were exercised in a fresh context
|
||||
- what passed or failed
|
||||
- what fixes were applied
|
||||
- what residual risks remain, if any
|
||||
|
||||
## Phase 00 - Testing Infrastructure Foundation
|
||||
|
||||
Type: Build
|
||||
|
||||
Usable outcome: A lean test harness exists for workspace work, so later phases can use real workspace and repo state without inventing new infrastructure each time.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-00-test-harness/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 00.1 Add `test/helpers/workspace-sandbox.ts` to create a temp managed workspace root plus attached repos.
|
||||
- [x] 00.2 Add fixture seeds under `test/fixtures/workspace-poc/` for `empty`, `happy-path`, and `dirty`.
|
||||
- [x] 00.3 Add shared assertion helpers for path leakage, workspace layout, target membership, and materialization invariants.
|
||||
- [x] 00.4 Reserve test suite locations for new coverage: `test/core/workspace/`, `test/commands/workspace/`, and `test/cli-e2e/workspace/`.
|
||||
- [x] 00.5 Keep the harness compatible with the current `runCLI()` helper and forked Vitest workers.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 00.6 `workspaceSandbox()` creates a workspace root with `.openspec/` and `changes/`, and no inner `openspec/`.
|
||||
- [x] 00.7 Cloned fixtures can be mutated independently without cross-test bleed.
|
||||
- [x] 00.8 Committed fixture files never contain absolute repo paths.
|
||||
- [x] 00.9 CLI tests can run against the sandbox and keep JSON output free of spinner noise.
|
||||
|
||||
## Phase 01 - Workspace Create Entrypoint
|
||||
|
||||
Type: Build
|
||||
|
||||
Usable outcome: A user can create a persistent workspace root through `openspec workspace create <name>`.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-01-workspace-create/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 01.1 Add the `workspace` command group and the `workspace create` entrypoint.
|
||||
- [x] 01.2 Reuse the current init/setup path rather than inventing a second bootstrap system.
|
||||
- [x] 01.3 Implement managed workspace root creation.
|
||||
- [x] 01.4 Create `.openspec/workspace.yaml`, `.openspec/local.yaml`, and top-level `changes/`.
|
||||
- [x] 01.5 Ensure `.openspec/local.yaml` is treated as local-only state.
|
||||
- [x] 01.6 Make the created layout clearly distinct from repo-local `openspec/` roots.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 01.7 Creating a workspace produces `.openspec/workspace.yaml`, `.openspec/local.yaml`, and `changes/`.
|
||||
- [x] 01.8 The workspace root does not contain `openspec/changes`.
|
||||
- [x] 01.9 Re-running against an existing workspace fails or behaves idempotently in one explicit, documented way.
|
||||
- [x] 01.10 Invalid or duplicate workspace names fail with actionable errors.
|
||||
|
||||
## Phase 02 - Validate Workspace Create
|
||||
|
||||
Type: Test
|
||||
|
||||
Usable outcome: `workspace create` is covered at unit, command, and CLI layers before other workspace behavior builds on it.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-02-test-workspace-create/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 02.1 Add unit tests for managed path resolution and workspace metadata initialization.
|
||||
- [x] 02.2 Add command-level tests for create behavior and failure modes.
|
||||
- [x] 02.3 Add CLI e2e coverage for `workspace create`, help text, exit codes, and layout assertions.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 02.4 Help output documents `workspace create`.
|
||||
- [x] 02.5 Successful CLI creation yields a usable workspace root on disk.
|
||||
- [x] 02.6 JSON output remains clean if a machine-readable mode is added.
|
||||
- [x] 02.7 Duplicate create attempts do not corrupt the workspace root.
|
||||
|
||||
## Phase 03 - Repo Registry and Doctor
|
||||
|
||||
Type: Build
|
||||
|
||||
Usable outcome: A workspace can register repo aliases and validate them with `workspace add-repo` and `workspace doctor`.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-03-repo-registry/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 03.1 Implement committed alias storage in `.openspec/workspace.yaml`.
|
||||
- [x] 03.2 Implement absolute path storage in `.openspec/local.yaml`.
|
||||
- [x] 03.3 Validate that registered paths exist and contain repo-local OpenSpec state.
|
||||
- [x] 03.4 Canonicalize stored local paths.
|
||||
- [x] 03.5 Implement `workspace doctor` to check alias resolution, missing repos, and overlay drift.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 03.6 `workspace add-repo <alias> <path>` stores the alias in committed metadata and the path only in local metadata.
|
||||
- [x] 03.7 Missing paths and duplicate aliases fail cleanly.
|
||||
- [x] 03.8 Paths are canonicalized before persistence.
|
||||
- [x] 03.9 `workspace doctor` reports stale or missing repos without mutating state.
|
||||
- [x] 03.10 No absolute path leaks into committed workspace files.
|
||||
|
||||
## Phase 04 - Validate Repo Registry and Doctor
|
||||
|
||||
Type: Test
|
||||
|
||||
Usable outcome: Repo registration becomes trustworthy enough for targeted changes and later agent attachment.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-04-test-repo-registry/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 04.1 Add pure tests for alias parsing, path canonicalization, committed-vs-local serialization, and doctor diagnostics.
|
||||
- [x] 04.2 Add command tests for add-repo and doctor using the workspace sandbox.
|
||||
- [x] 04.3 Add CLI e2e coverage for happy path and stale path scenarios.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 04.4 Doctor detects missing repo roots, missing `openspec/`, and alias/path drift.
|
||||
- [x] 04.5 Committed metadata remains stable across local path changes.
|
||||
- [x] 04.6 Repairing a stale path in `local.yaml` restores doctor success.
|
||||
- [x] 04.7 The registry remains readable after multiple repo additions in one workspace.
|
||||
|
||||
## Phase 05 - Target-Aware Workspace Change Creation
|
||||
|
||||
Type: Build
|
||||
|
||||
Usable outcome: A workspace can create a central cross-repo change with `openspec new change <id> --targets <a,b,c>`.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-05-targeted-change-create/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 05.1 Extend change creation to support workspace topology.
|
||||
- [x] 05.2 Record explicit targets in workspace change metadata.
|
||||
- [x] 05.3 Scaffold central planning artifacts in the workspace change: proposal, design, coordination tasks, and per-target draft task/spec partitions.
|
||||
- [x] 05.4 Hard-fail if a requested target alias is unknown.
|
||||
- [x] 05.5 Ensure no repo-local artifacts are created yet.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 05.6 Creating a targeted workspace change records the exact target set.
|
||||
- [x] 05.7 Per-target planning directories are created under the workspace change.
|
||||
- [x] 05.8 Unknown or duplicate targets fail with actionable errors.
|
||||
- [x] 05.9 Repo-local repos remain untouched until `apply`.
|
||||
- [x] 05.10 Duplicate change IDs still fail predictably.
|
||||
|
||||
## Phase 06 - Validate Target-Aware Change Creation
|
||||
|
||||
Type: Test
|
||||
|
||||
Usable outcome: The central planning object is stable before any agent-open or materialization work begins.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-06-test-targeted-change-create/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 06.1 Add unit tests for target parsing and workspace change metadata rules.
|
||||
- [x] 06.2 Add command tests for targeted change creation against a registered workspace.
|
||||
- [x] 06.3 Add CLI e2e coverage for successful creation, unknown aliases, and untouched repo-local roots.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 06.4 `new change --targets` rejects aliases not present in the workspace registry.
|
||||
- [x] 06.5 The workspace change layout matches the chosen topology.
|
||||
- [x] 06.6 The workspace change contains central planning artifacts and per-target partitions only.
|
||||
- [x] 06.7 Running status or doctor after creation still sees the workspace as healthy.
|
||||
|
||||
## Phase 07 - Research Minimum `workspace open` Contract
|
||||
|
||||
Type: Research
|
||||
|
||||
Usable outcome: The team decides the smallest honest v0 behavior for `workspace open --change` without overcommitting to multi-root agent support that may not be real.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-07-open-contract-research/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 07.1 Write the research note in `notes/workspace-poc/phase-07-open-contract-research/DECISION.md`.
|
||||
- [x] 07.2 Decide the minimum v0 behavior for planning-only mode, change-scoped attached mode, supported agent targets for the demo path, and failure behavior when one or more targeted repos are unresolved.
|
||||
- [x] 07.3 Choose whether non-primary agents are supported, partial, or explicitly out of scope in v0.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 07.4 The research note names one recommended contract and at least one rejected alternative.
|
||||
- [x] 07.5 The note defines exact user-visible behavior for `workspace open --change <id>` and `workspace open` with no change.
|
||||
- [x] 07.6 The note lists testable success and failure cases for the next phase.
|
||||
|
||||
## Phase 08 - Workspace Open
|
||||
|
||||
Type: Build
|
||||
|
||||
Usable outcome: A user can open the workspace in planning-only mode or open a specific change with only its target repos attached.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-08-workspace-open/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 08.1 Implement `workspace open --change <id> [--agent <tool>]`.
|
||||
- [x] 08.2 Implement planning-only mode when no change is supplied.
|
||||
- [x] 08.3 Ensure change-scoped open resolves only the change’s targeted repos.
|
||||
- [x] 08.4 Integrate with the existing command-generation/tooling path rather than inventing a new one.
|
||||
- [x] 08.5 Fail with actionable diagnostics when targeted repos are unresolved.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 08.6 `workspace open` without `--change` does not attach repo roots.
|
||||
- [x] 08.7 `workspace open --change <id>` attaches only targeted repos, not all registered repos.
|
||||
- [x] 08.8 Open fails clearly when a targeted repo path is stale or missing.
|
||||
- [x] 08.9 The chosen primary agent path produces a usable session launch or instruction surface.
|
||||
|
||||
## Phase 09 - Validate Workspace Open
|
||||
|
||||
Type: Test
|
||||
|
||||
Usable outcome: The open contract is pinned down with real fixture state before materialization depends on it.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-09-test-workspace-open/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 09.1 Add tests for planning-only vs change-scoped mode.
|
||||
- [x] 09.2 Add tests that verify only the expected repo aliases are attached.
|
||||
- [x] 09.3 Add tests for unresolved target paths and unsupported agent/tool combinations.
|
||||
- [x] 09.4 Add CLI e2e coverage for the selected primary demo path.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 09.5 Planning-only open never exposes attached repo roots.
|
||||
- [x] 09.6 Change-scoped open never attaches unrelated repos.
|
||||
- [x] 09.7 Open diagnostics point to `workspace doctor` or the alias that needs repair.
|
||||
- [x] 09.8 Test coverage does not depend on real multi-root writes.
|
||||
|
||||
## Phase 10 - Research Materialization Contract
|
||||
|
||||
Type: Research
|
||||
|
||||
Usable outcome: The materialization contract is explicit before `apply --change --repo` is implemented.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-10-materialization-contract-research/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 10.1 Write the research note in `notes/workspace-poc/phase-10-materialization-contract-research/DECISION.md`.
|
||||
- [x] 10.2 Decide the v0 rule for create-only vs refresh, overwrite behavior, rerun behavior, conflict handling, and the minimum metadata written during materialization.
|
||||
- [x] 10.3 Prefer the simplest honest contract for the POC, even if refresh is deferred.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 10.4 The research note chooses one v0 contract and names explicit non-goals.
|
||||
- [x] 10.5 The note defines what counts as a successful materialization.
|
||||
- [x] 10.6 The note defines the expected behavior for repeat `apply` calls.
|
||||
|
||||
## Phase 11 - Target Materialization via `apply`
|
||||
|
||||
Type: Build
|
||||
|
||||
Usable outcome: A selected target can be materialized into its repo with `openspec apply --change <id> --repo <alias>`.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-11-apply-materialization/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 11.1 Extend `apply` to understand workspace topology.
|
||||
- [x] 11.2 Materialize only the selected target slice into the target repo.
|
||||
- [x] 11.3 Reuse the same change ID in the target repo.
|
||||
- [x] 11.4 Keep workspace planning artifacts intact after materialization.
|
||||
- [x] 11.5 Make the authority handoff explicit: workspace draft before `apply`, repo-local execution after `apply`.
|
||||
- [x] 11.6 Write the minimum trace metadata needed for later status roll-up.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 11.7 Materialization creates a repo-local change with the same change ID.
|
||||
- [x] 11.8 Only the selected target repo is modified.
|
||||
- [x] 11.9 Untargeted aliases and unknown aliases fail clearly.
|
||||
- [x] 11.10 Repeating `apply` follows the v0 contract from Phase 10.
|
||||
- [x] 11.11 Workspace drafts remain intact after successful materialization.
|
||||
|
||||
## Phase 12 - Validate Materialization
|
||||
|
||||
Type: Test
|
||||
|
||||
Usable outcome: The execution handoff is proven against real repos before status and completion semantics are layered on top.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-12-test-apply-materialization/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 12.1 Add unit tests for materialization plan construction and target resolution.
|
||||
- [x] 12.2 Add command tests for apply success, apply failure, and repeat-apply behavior.
|
||||
- [x] 12.3 Add CLI e2e coverage for selective materialization into one repo out of many.
|
||||
- [x] 12.4 Add dirty-workspace coverage for stale aliases and pre-existing target change collisions.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 12.5 The repo-local change ID exactly matches the workspace change ID.
|
||||
- [x] 12.6 Apply never writes to repos outside the selected alias.
|
||||
- [x] 12.7 Apply surfaces collisions and stale-path failures without partial silent success.
|
||||
- [x] 12.8 The happy-path fixture supports `create -> add-repo -> new change -> apply`.
|
||||
|
||||
## Phase 13 - Research Status Roll-Up and Reverse Links
|
||||
|
||||
Type: Research
|
||||
|
||||
Usable outcome: Status semantics are concrete enough to implement without inventing misleading lifecycle labels.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-13-status-research/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 13.1 Write the research note in `notes/workspace-poc/phase-13-status-research/DECISION.md`.
|
||||
- [x] 13.2 Define the minimum v0 workspace states and their derivation rules: planned, materialized, in progress, blocked, complete, soft-done, and hard-done.
|
||||
- [x] 13.3 Decide whether repo-local changes need reverse links back to the workspace change in v0.
|
||||
- [x] 13.4 Define the minimum JSON status shape that tests can lock down.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 13.5 The research note gives one precise derivation rule per state.
|
||||
- [x] 13.6 The note defines which states rely on repo-local inspection and which rely on workspace state alone.
|
||||
- [x] 13.7 The note resolves whether reverse links are required, optional, or deferred.
|
||||
|
||||
## Phase 14 - Workspace Status Roll-Up
|
||||
|
||||
Type: Build
|
||||
|
||||
Usable outcome: Running status from the workspace tells the user what is planned, materialized, active, blocked, complete, soft-done, and hard-done.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-14-workspace-status/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 14.1 Extend status behavior to recognize workspace topology.
|
||||
- [x] 14.2 Roll up central coordination state plus per-target execution state.
|
||||
- [x] 14.3 Keep output honest and minimal.
|
||||
- [x] 14.4 Add stable JSON output for workspace status.
|
||||
- [x] 14.5 Do not infer more than the underlying workspace and repo-local state can actually support.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 14.6 Workspace status distinguishes planning-only targets from materialized targets.
|
||||
- [x] 14.7 Status can report blocked states for stale repo paths or missing materializations when appropriate.
|
||||
- [x] 14.8 Soft-done only appears when all known coordination and target work is complete.
|
||||
- [x] 14.9 Hard-done only appears after explicit workspace archive/completion in a later phase.
|
||||
- [x] 14.10 JSON status output is stable and free of spinner contamination.
|
||||
|
||||
## Phase 15 - Validate Workspace Status
|
||||
|
||||
Type: Test
|
||||
|
||||
Usable outcome: Roll-up semantics are verified with deterministic scenarios rather than manual interpretation.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-15-test-workspace-status/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 15.1 Add pure tests for state derivation logic.
|
||||
- [x] 15.2 Add command tests for workspace-aware status output.
|
||||
- [x] 15.3 Add CLI e2e coverage for mixed states across three repos.
|
||||
- [x] 15.4 Add regression tests for JSON shape and spinner-free output.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 15.5 Status correctly reports a mix of planned, materialized, archived, and blocked targets in one workspace.
|
||||
- [x] 15.6 Status remains readable when one repo is missing or stale.
|
||||
- [x] 15.7 JSON output can be parsed directly by an agent or automation.
|
||||
- [x] 15.8 The dirty fixture supports interruption and resume scenarios.
|
||||
|
||||
## Phase 16 - Workspace Completion and Archive Semantics
|
||||
|
||||
Type: Build
|
||||
|
||||
Usable outcome: The workspace has an explicit top-level completion/hard-done path while repo-local archive remains repo-local.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-16-workspace-archive/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 16.1 Decide the minimal command path for explicit workspace completion/archive using the existing archive surface where practical.
|
||||
- [x] 16.2 Preserve repo-local archive behavior and canonical spec ownership.
|
||||
- [x] 16.3 Ensure top-level hard-done is explicit and never implied by repo-local activity alone.
|
||||
- [x] 16.4 Record enough workspace-level completion state for status to report hard-done.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 16.5 Archiving a repo-local change does not automatically archive the workspace change.
|
||||
- [x] 16.6 Workspace hard-done requires explicit top-level user action.
|
||||
- [x] 16.7 Repo-local archive continues to operate against repo-local canonical specs.
|
||||
- [x] 16.8 Mixed repo cadences are allowed without invalidating workspace state.
|
||||
|
||||
## Phase 17 - Validate Workspace Completion and Archive
|
||||
|
||||
Type: Test
|
||||
|
||||
Usable outcome: Completion semantics are proven and do not collapse repo ownership boundaries.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-17-test-workspace-archive/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 17.1 Add command and CLI tests for workspace hard-done behavior.
|
||||
- [x] 17.2 Add tests for partial repo archive, staggered repo archive, and explicit workspace archive.
|
||||
- [x] 17.3 Add regression tests to ensure repo-local archive behavior is unchanged outside workspace flows.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 17.4 One repo can archive while another remains in progress without forcing top-level done.
|
||||
- [x] 17.5 Status shows soft-done before hard-done when the documented conditions are met.
|
||||
- [x] 17.6 Existing repo-local archive tests still pass without workspace regressions.
|
||||
|
||||
## Phase 18 - Deferred Research: Shared-Contract Promotion and Stable IDs
|
||||
|
||||
Type: Research
|
||||
|
||||
Usable outcome: Deferred questions are captured cleanly without bloating the POC implementation.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-18-deferred-research/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 18.1 Write the research note in `notes/workspace-poc/phase-18-deferred-research/DECISION.md`.
|
||||
- [x] 18.2 Capture the recommended next-step design for shared-contract promotion into canonical owner repos, migration from local alias/path overlays to stable project IDs, and whether any team-shared workspace semantics should exist after the POC.
|
||||
- [x] 18.3 Keep this phase explicitly non-blocking for the working POC.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 18.4 The research note separates deferred concerns from the shipped POC contract.
|
||||
- [x] 18.5 The note identifies which future changes would break current tests or fixture shape.
|
||||
- [x] 18.6 The note names at least one migration seam that preserves backward compatibility.
|
||||
|
||||
## Phase 19 - End-to-End POC Acceptance
|
||||
|
||||
Type: Test
|
||||
|
||||
Usable outcome: The whole POC is proven with a small number of realistic, repeatable scenarios.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-19-e2e-acceptance/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 19.1 Add one golden happy-path e2e scenario covering: create workspace, register three repos, create one targeted change, open the change, materialize one repo, inspect status, archive repo-local work, and explicitly complete/archive the workspace.
|
||||
- [x] 19.2 Add one interruption/re-entry scenario covering: an existing workspace, one materialized target, one stale target, and status/doctor output that points to the next action.
|
||||
- [x] 19.3 Add one failure-recovery scenario covering: duplicate aliases, unknown targets, repeat apply, stale repo paths, and partial completion.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 19.4 The happy-path scenario can run end-to-end with real filesystem state and no broad mocks.
|
||||
- [x] 19.5 The interruption scenario can be resumed without reconstructing context manually.
|
||||
- [x] 19.6 The failure-recovery scenario produces actionable errors and no silent corruption.
|
||||
- [x] 19.7 The final suite demonstrates the product promise: plan centrally, execute locally, preserve repo ownership.
|
||||
|
||||
## Phase 20 - PRD Satisfaction Audit
|
||||
|
||||
Type: Test
|
||||
|
||||
Usable outcome: The implementation is checked directly against `WORKSPACE_POC_PRD.md` rather than only against the roadmap or inferred intent.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-20-prd-audit/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 20.1 Compare the full implementation, docs, tests, and user-facing behavior against `WORKSPACE_POC_PRD.md`.
|
||||
- [x] 20.2 Identify every unmet, partially met, or ambiguous PRD requirement.
|
||||
- [x] 20.3 Validate that the implementation still respects the key guardrails from the PRD and decision record.
|
||||
- [x] 20.4 If any PRD gaps remain, insert concrete remediation phases immediately after this phase, each with acceptance tests and output directories, before allowing final signoff to proceed.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 20.5 Every meaningful PRD requirement is mapped to implemented behavior, explicit non-goal, or a documented gap.
|
||||
- [x] 20.6 Any remaining gaps result in newly inserted remediation phases, not a vague TODO list.
|
||||
- [x] 20.7 The audit output is concrete enough for a fresh agent session to act on immediately.
|
||||
|
||||
## Phase 21 - Workspace Guidance and Owner Visibility
|
||||
|
||||
Type: Build
|
||||
|
||||
Usable outcome: A fresh user can tell when workspace mode fits the job, capture owner or handoff information per repo, and see that information from the existing workspace surfaces.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-21-workspace-guidance-and-owners/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 21.1 Extend committed workspace repo metadata to capture optional owner or handoff information without storing machine-specific paths.
|
||||
- [x] 21.2 Add a backward-compatible CLI path to record or update owner or handoff information for a registered repo alias.
|
||||
- [x] 21.3 Surface owner or handoff information anywhere the workspace already shows affected repos and next actions, at minimum workspace-aware `status` and `workspace open`.
|
||||
- [x] 21.4 Add shipped user-facing guidance that explains when to use workspace mode versus stay repo-local, the supported end-to-end CLI flow, and how to re-enter or hand off an in-flight workspace change.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 21.5 Fresh users can discover from shipped docs or help when workspace mode is the right tool and what the supported CLI flow is.
|
||||
- [x] 21.6 When owner or handoff information is configured, workspace status and open surfaces expose it without leaking local paths into committed metadata.
|
||||
- [x] 21.7 Existing workspaces remain valid and readable when owner or handoff information is absent.
|
||||
|
||||
## Phase 22 - Validate Guidance and Owner Visibility
|
||||
|
||||
Type: Test
|
||||
|
||||
Usable outcome: Guidance and owner or handoff visibility are proven on real workspace state and remain backward-compatible with the shipped POC.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-22-test-workspace-guidance-and-owners/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 22.1 Add unit, command, and CLI coverage for owner or handoff metadata plus the updated docs or help surface.
|
||||
- [x] 22.2 Verify older workspace fixtures and workspaces without owner or handoff metadata still pass unchanged.
|
||||
- [x] 22.3 Run manual CLI checks for docs or help, `workspace open`, and workspace-aware `status` from a fresh workspace.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 22.4 Shipped docs or help no longer require the PRD or roadmap to explain when workspace mode is appropriate.
|
||||
- [x] 22.5 Workspace text and JSON surfaces show configured owner or handoff information consistently.
|
||||
- [x] 22.6 Existing ownerless workspaces and the Phase 19 acceptance flow continue to pass.
|
||||
|
||||
## Phase 23 - Workspace Target Set Adjustment
|
||||
|
||||
Type: Build
|
||||
|
||||
Usable outcome: Users can adjust the target set on a workspace change after creation without manual file edits or silent authority drift.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-23-workspace-target-set-adjustment/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 23.1 Add a minimal explicit command path to add or remove target aliases from an existing workspace change.
|
||||
- [x] 23.2 Keep workspace change metadata, per-target draft artifacts, and workspace registry validation coherent when targets are added or removed.
|
||||
- [x] 23.3 Define and implement safe guardrails for removing a target that has already been materialized or otherwise moved into repo-local execution.
|
||||
- [x] 23.4 Update workspace `open`, `apply`, and workspace-aware `status` to respect the adjusted target set.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 23.5 Adding a target updates the workspace change metadata and scaffolds the new per-target draft slice.
|
||||
- [x] 23.6 Removing an unmaterialized target updates the workspace cleanly without corrupting other targets.
|
||||
- [x] 23.7 Removing or mutating a materialized target fails or requires an explicit documented safety path instead of silently breaking authority handoff.
|
||||
|
||||
## Phase 24 - Validate Target Set Adjustment
|
||||
|
||||
Type: Test
|
||||
|
||||
Usable outcome: Target-set edits behave safely under real workspace conditions and do not regress the shipped POC flow.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-24-test-workspace-target-set-adjustment/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 24.1 Add unit, command, and CLI coverage for target-add and target-remove behavior, including materialized-target guardrails.
|
||||
- [x] 24.2 Run manual re-entry, `status`, `workspace open`, and `apply` checks after target-set edits in a fresh workspace.
|
||||
- [x] 24.3 Re-run the workspace acceptance slice to confirm target adjustment does not regress the existing happy path or interruption flow.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 24.4 Adjusted target sets are reflected consistently in workspace metadata, `workspace open`, `apply`, and workspace-aware `status`.
|
||||
- [x] 24.5 Guardrails prevent silent divergence for already materialized targets.
|
||||
- [x] 24.6 The existing Phase 19 acceptance scenario still passes after target-set support lands.
|
||||
|
||||
## Phase 25 - Final PRD Recheck and Signoff
|
||||
|
||||
Type: Test
|
||||
|
||||
Usable outcome: After any remediation phases have run, the codebase is rechecked against the PRD and the POC can be considered complete.
|
||||
|
||||
Output summary directory: `notes/workspace-poc/phase-25-prd-signoff/`
|
||||
|
||||
Completion checklist:
|
||||
|
||||
- [x] Tasks completed
|
||||
- [x] Acceptance tests satisfied
|
||||
- [x] Independent verification complete
|
||||
- [x] Manual testing complete
|
||||
- [x] Phase complete
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] 25.1 Re-run the PRD satisfaction check after all remediation phases are complete.
|
||||
- [x] 25.2 Confirm the final implementation, documentation, and tests satisfy the PRD.
|
||||
- [x] 25.3 Confirm the roadmap itself has no incomplete required phases left behind.
|
||||
- [x] 25.4 Produce a final signoff summary that states whether the POC is complete and what residual risks remain.
|
||||
|
||||
Acceptance tests:
|
||||
|
||||
- [x] 25.5 The final signoff references `WORKSPACE_POC_PRD.md` directly and confirms whether it is satisfied.
|
||||
- [x] 25.6 If the PRD is still not satisfied, the phase does not sign off and instead inserts further remediation phases before trying again.
|
||||
- [x] 25.7 The final signoff is explicit about any residual risks, but it does not leave known fixable PRD gaps unresolved.
|
||||
|
||||
## Recommended First Shipping Slice
|
||||
|
||||
If the POC needs the smallest credible milestone before full roll-up and completion semantics, ship through Phase 12:
|
||||
|
||||
- test harness
|
||||
- workspace create
|
||||
- repo registry + doctor
|
||||
- targeted workspace changes
|
||||
- minimum researched `workspace open`
|
||||
- create-only materialization through `apply`
|
||||
|
||||
That is the first point where the product is honest for real cross-repo work. Phases 13 through 25 then harden status, completion semantics, end-to-end resilience, PRD completeness, and final signoff.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,293 @@
|
||||
# Workspace POC PRD
|
||||
|
||||
- Status: Signed Off
|
||||
- Date: 2026-04-17
|
||||
- Audience: OpenSpec maintainers and future implementers
|
||||
- Derived from: [WORKSPACE_POC_DECISION_RECORD.md](/Users/tabishbidiwale/fission/repos/openspec/WORKSPACE_POC_DECISION_RECORD.md)
|
||||
|
||||
## Summary
|
||||
|
||||
The Workspace POC gives OpenSpec a lightweight way to coordinate work that spans multiple repositories without forcing planning into a single repo or introducing a separate planning primitive for users to learn.
|
||||
|
||||
A workspace is a persistent coordination home. Inside it, users create feature-scoped changes, plan the work once, and then materialize repo-specific execution artifacts into the affected repos when implementation is ready to begin.
|
||||
|
||||
The POC is intentionally opinionated:
|
||||
|
||||
- planning is centralized in the workspace
|
||||
- canonical specs remain in the owning repo
|
||||
- repo-local execution remains repo-local
|
||||
- the primary user-facing primitive stays `change`
|
||||
- the existing `spec-driven` methodology is reused rather than forked into a separate workspace schema
|
||||
|
||||
This document describes what we are building for the POC. It does not try to break the work into implementation phases yet.
|
||||
|
||||
## Problem
|
||||
|
||||
OpenSpec currently behaves like a single-root tool:
|
||||
|
||||
- commands assume one local root
|
||||
- changes are authored locally under one repo
|
||||
- specs and delta specs are resolved locally
|
||||
- `apply` and `archive` are repo-local lifecycle steps
|
||||
|
||||
That works for normal single-repo use, but it breaks down when one feature spans multiple services, clients, or owner repos.
|
||||
|
||||
Users need one place to:
|
||||
|
||||
- write a single proposal and design
|
||||
- see the full cross-repo change
|
||||
- assign and track repo-specific work
|
||||
- reason about shared behavior across repos
|
||||
|
||||
At the same time, repos still need to remain the source of truth for:
|
||||
|
||||
- canonical specs
|
||||
- implementation work
|
||||
- review and shipping
|
||||
- archive semantics
|
||||
|
||||
The product problem is to provide centralized planning without collapsing repo ownership.
|
||||
|
||||
## Who This Is For
|
||||
|
||||
The POC is aimed at users coordinating cross-boundary work, including:
|
||||
|
||||
- an engineer changing behavior across multiple repos
|
||||
- a lead or staff engineer coordinating a feature across teams
|
||||
- a team that needs one planning surface but still executes in separate repos
|
||||
|
||||
## When Users Reach For Workspace
|
||||
|
||||
Users should reach for a workspace when repo-local OpenSpec stops being an honest representation of the work.
|
||||
|
||||
Typical trigger situations:
|
||||
|
||||
- one feature spans two or more repos
|
||||
- the canonical spec owner is different from one or more implementation repos
|
||||
- different repos or teams need to move on different cadences
|
||||
- one person needs to coordinate work that will later be handed off to several repo owners
|
||||
- the user needs one place to pause and resume a cross-repo effort without reconstructing the full plan from scattered notes
|
||||
|
||||
## Jobs To Be Done
|
||||
|
||||
### Functional Jobs
|
||||
|
||||
Users hire the workspace POC to:
|
||||
|
||||
- start one cross-repo change from a neutral planning home
|
||||
- identify which repos are affected
|
||||
- author shared planning artifacts once
|
||||
- break the work into repo-specific slices for execution
|
||||
- materialize repo-local change artifacts when implementation should begin
|
||||
- track overall progress without losing repo ownership boundaries
|
||||
- resume a cross-repo change later and quickly understand what is planned, materialized, in progress, blocked, complete, or archived
|
||||
|
||||
### Social Jobs
|
||||
|
||||
Users also hire the workspace POC to:
|
||||
|
||||
- make the full cross-repo change legible to repo owners, reviewers, and leads
|
||||
- hand off the right slice of work to each repo owner without duplicating planning docs
|
||||
- show what is planned centrally versus what is already executing locally
|
||||
- reduce coordination overhead that would otherwise live in Slack threads, meetings, and ad hoc documents
|
||||
|
||||
### Emotional Jobs
|
||||
|
||||
The workspace POC should help users feel confident that:
|
||||
|
||||
- there is one clear planning home for the overall change
|
||||
- canonical repo ownership is preserved
|
||||
- materialization will not create confusing dual authority
|
||||
- they can tell what is authoritative at each step
|
||||
- they can recover safely from interruption, partial rollout, or divergence between workspace drafts and repo-local execution
|
||||
|
||||
### Adoption And Operations Jobs
|
||||
|
||||
For teams using this repeatedly, the workspace POC should also support:
|
||||
|
||||
- a repeatable way to start cross-repo work
|
||||
- a clear way to decide when to use workspace mode versus stay repo-local
|
||||
- onboarding another engineer into an in-flight cross-repo change
|
||||
- re-entering an existing workspace after time away
|
||||
- adjusting targets and continuing even when some repos are not ready at the same time
|
||||
|
||||
## Product Goals
|
||||
|
||||
The Workspace POC should:
|
||||
|
||||
1. Provide a credible cross-repo coordination experience for real work.
|
||||
2. Make the workspace a persistent coordination home rather than a disposable feature folder.
|
||||
3. Keep planning centralized while preserving canonical spec ownership in repos.
|
||||
4. Reuse the existing `change` primitive and `spec-driven` methodology.
|
||||
5. Minimize disruption to existing repo-local OpenSpec workflows.
|
||||
6. Support a simple, explicit CLI flow for creating workspaces, registering repos, opening a change, and materializing repo-local work.
|
||||
7. Avoid leaking machine-specific repo paths into committed workspace state.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
The POC does not attempt to solve the full long-term workspace model.
|
||||
|
||||
Out of scope:
|
||||
|
||||
- a fully multi-root-aware CLI across every command
|
||||
- a new top-level `initiative` primitive
|
||||
- a separate workspace-only methodology schema
|
||||
- stable remote repo identifiers or shared project IDs
|
||||
- automatic escalation from local work into a workspace
|
||||
- a full sync engine between workspace drafts and repo-local changes
|
||||
- final governance for shared-contract ownership
|
||||
- arbitrary user-chosen workspace locations as the default v0 behavior
|
||||
|
||||
## Product Shape
|
||||
|
||||
### Workspace
|
||||
|
||||
A workspace is a persistent coordination root used for cross-repo planning.
|
||||
|
||||
For the POC:
|
||||
|
||||
- it lives in a managed location by default
|
||||
- workspace metadata lives under `.openspec/`
|
||||
- the workspace does not add an extra inner `openspec/` directory
|
||||
- the workspace can contain many feature-scoped changes over time
|
||||
|
||||
### Workspace Change
|
||||
|
||||
A workspace change is the central planning object for one cross-repo feature or initiative-sized piece of work.
|
||||
|
||||
For the POC:
|
||||
|
||||
- users still think in terms of `change`
|
||||
- a workspace change records its target repos explicitly
|
||||
- proposal, design, coordination tasks, and per-target draft work live in the workspace until materialization
|
||||
|
||||
### Target Repos
|
||||
|
||||
Target repos are registered in the workspace by alias.
|
||||
|
||||
For the POC:
|
||||
|
||||
- stable repo aliases are stored in committed workspace metadata
|
||||
- machine-specific absolute paths are stored only in a gitignored local overlay
|
||||
- repo attachment should be change-scoped by default, not workspace-wide
|
||||
|
||||
### Repo-Local Changes
|
||||
|
||||
Repo-local changes are the execution artifacts created from a workspace change.
|
||||
|
||||
For the POC:
|
||||
|
||||
- a materialized repo-local change reuses the same change ID as the workspace change by default
|
||||
- repo-local execution remains local to that repo
|
||||
- repo-local archive remains local to that repo
|
||||
|
||||
## Core Principles
|
||||
|
||||
### Centralize The View, Not The Truth
|
||||
|
||||
The workspace is the shared planning surface. It is not the permanent home of canonical specs or repo execution state.
|
||||
|
||||
### Methodology And Topology Stay Separate
|
||||
|
||||
The POC reuses `spec-driven`. Workspace behavior is a topology concern, not a new methodology family.
|
||||
|
||||
### Planning First, Materialization Second
|
||||
|
||||
Users should be able to author the cross-repo plan in one place before copying the relevant slice into a repo for execution.
|
||||
|
||||
### Clear Authority Handoff
|
||||
|
||||
Before materialization, the workspace target slice is the planning truth for that repo.
|
||||
|
||||
After a successful `apply --change <id> --repo <alias>`, the repo-local change becomes the execution truth for that repo.
|
||||
|
||||
### Manual Completion At The Top Level
|
||||
|
||||
A workspace change becomes:
|
||||
|
||||
- soft-done when all known coordination work and tracked target work are complete
|
||||
- hard-done only when the user manually archives the workspace change
|
||||
|
||||
## User Experience
|
||||
|
||||
The intended POC flow is:
|
||||
|
||||
1. A user creates a workspace using the normal OpenSpec setup path.
|
||||
2. The user registers repo aliases against local repo paths.
|
||||
3. The user creates a workspace change with explicit targets.
|
||||
4. Planning happens centrally in the workspace:
|
||||
- proposal
|
||||
- design
|
||||
- coordination tasks
|
||||
- per-target draft tasks
|
||||
- per-target draft delta specs
|
||||
5. When execution should begin in a repo, the user runs `openspec apply --change <id> --repo <alias>`.
|
||||
6. OpenSpec materializes the selected repo’s local change using the same change ID.
|
||||
7. Repo-local implementation and archive proceed in that repo.
|
||||
8. The workspace continues to show overall coordination and completion state.
|
||||
|
||||
This is meant to feel like one change with multiple execution surfaces, not like separate unrelated changes stitched together manually.
|
||||
|
||||
## POC Command Surface
|
||||
|
||||
The minimum command shape for the POC is:
|
||||
|
||||
- `openspec workspace create <name>`
|
||||
- `openspec workspace add-repo <alias> <path>`
|
||||
- `openspec workspace doctor`
|
||||
- `openspec new change <id> --targets <a,b,c>`
|
||||
- `openspec workspace open --change <id> [--agent <tool>]`
|
||||
- `openspec apply --change <id> --repo <alias>`
|
||||
|
||||
These commands are enough to support:
|
||||
|
||||
- persistent workspace creation
|
||||
- repo registration and validation
|
||||
- explicit targeted change creation
|
||||
- change-scoped agent opening
|
||||
- deterministic materialization into a target repo
|
||||
|
||||
## Agent Story
|
||||
|
||||
The POC should optimize for the cleanest demo path rather than promise identical behavior across all tools.
|
||||
|
||||
Current expectation:
|
||||
|
||||
- Claude Code is the headline multi-root demo path
|
||||
- Codex is secondary if it remains straightforward
|
||||
- Copilot is partial or manual support, not the primary story
|
||||
|
||||
Because agent multi-root write behavior is uneven, `openspec apply --change --repo` is the safest POC default for moving from planning into repo execution.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
The POC is successful if users can:
|
||||
|
||||
- recognize when workspace mode is the right tool for the job
|
||||
- create one canonical plan for a cross-repo change without forcing it into a dishonest home repo
|
||||
- identify affected repos, owners, and next actions from one planning surface
|
||||
- hand off repo-specific work cleanly without duplicating the same plan across multiple repos or side documents
|
||||
- understand which work is planned, materialized, in progress, blocked, complete, and archived
|
||||
- resume an interrupted cross-repo change without reconstructing context from Slack, PRs, or notes
|
||||
- preserve canonical spec ownership in repos while still coordinating the overall effort centrally
|
||||
- trust what is authoritative at each stage of the workflow
|
||||
- avoid committing local absolute repo paths into shared state
|
||||
|
||||
## Open Questions
|
||||
|
||||
These are intentionally left open for roadmap and implementation planning:
|
||||
|
||||
- Should materialization be create-only at first, or support explicit refresh?
|
||||
- If re-materialization exists, what can be overwritten and what must be preserved?
|
||||
- How should workspace status roll up repo-local progress?
|
||||
- Should repo-local changes keep a reverse link back to the workspace change?
|
||||
- What is the minimum supported `workspace open --change` behavior in v0?
|
||||
- How should shared contract drafts be promoted into canonical owner repos?
|
||||
|
||||
## Appendix: Working Mental Model
|
||||
|
||||
The POC is built around one simple idea:
|
||||
|
||||
> Plan centrally, execute locally, preserve repo ownership.
|
||||
|
||||
That is the product promise the roadmap should now flesh out.
|
||||
@@ -0,0 +1,454 @@
|
||||
# Workspace Reimplementation Direction
|
||||
|
||||
Date: 2026-04-30
|
||||
|
||||
This document captures the intended direction for reimplementing OpenSpec workspace support from scratch, based on what we learned from the workspace POC.
|
||||
|
||||
The reimplementation should be ordered around the path a real user takes through OpenSpec:
|
||||
|
||||
```text
|
||||
create workspace
|
||||
-> add repos
|
||||
-> open workspace
|
||||
-> explore across repos
|
||||
-> create proposal
|
||||
-> apply one repo slice
|
||||
-> verify
|
||||
-> archive
|
||||
```
|
||||
|
||||
The goal is not to rebuild every POC mechanism. The goal is to get one user-facing capability working at a time, in the same order a user would naturally create, implement, verify, and archive a change.
|
||||
|
||||
## North Star
|
||||
|
||||
A user should think:
|
||||
|
||||
```text
|
||||
I have a multi-repo product goal.
|
||||
I create an OpenSpec workspace.
|
||||
I open it with my agent.
|
||||
The agent can see the registered repos.
|
||||
We explore until the scope is clear.
|
||||
Then we create a proposal.
|
||||
Then we implement one repo slice at a time.
|
||||
```
|
||||
|
||||
They should not think:
|
||||
|
||||
```text
|
||||
I need to create a change so repos become visible.
|
||||
I need to materialize repo-local artifacts.
|
||||
I need to understand workspace overlays.
|
||||
I need to manage target metadata separately from proposal files.
|
||||
```
|
||||
|
||||
The core product rule is:
|
||||
|
||||
```text
|
||||
Repository visibility is not change commitment.
|
||||
```
|
||||
|
||||
Registered repos are the workspace working set. Creating a change is a planning commitment. Applying a change is an implementation workflow.
|
||||
|
||||
## Build Order
|
||||
|
||||
### 1. Workspace Creation
|
||||
|
||||
First make workspace creation boring and solid.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Create a place where cross-repo planning lives.
|
||||
```
|
||||
|
||||
Expected surface:
|
||||
|
||||
```bash
|
||||
openspec workspace create my-workspace
|
||||
openspec workspace add-repo openspec /path/to/openspec
|
||||
openspec workspace add-repo landing /path/to/openspec-landing
|
||||
```
|
||||
|
||||
Expected outcome:
|
||||
|
||||
```text
|
||||
workspace/
|
||||
AGENTS.md
|
||||
changes/
|
||||
.openspec-workspace/
|
||||
```
|
||||
|
||||
Product decisions:
|
||||
|
||||
- Use `.openspec-workspace/`, not `.openspec/`, for workspace metadata.
|
||||
- Keep `changes/` visible at the workspace root.
|
||||
- Treat registered repos as the workspace working set.
|
||||
- Make `doctor` show human-readable repo names and resolved paths.
|
||||
|
||||
Defer:
|
||||
|
||||
- Branches.
|
||||
- Worktrees.
|
||||
- Apply.
|
||||
- Archive.
|
||||
- Complex target lifecycle.
|
||||
|
||||
Done when a user can create a workspace, register repos, and run `doctor` to see exactly what OpenSpec knows.
|
||||
|
||||
### 2. Workspace Open
|
||||
|
||||
Next make the workspace openable in the way users expect.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Open this multi-repo working set with my coding agent.
|
||||
```
|
||||
|
||||
Expected surface:
|
||||
|
||||
```bash
|
||||
openspec workspace open
|
||||
openspec workspace open --agent codex
|
||||
openspec workspace open --agent github-copilot
|
||||
```
|
||||
|
||||
Product behavior:
|
||||
|
||||
- `workspace open` opens the coordination workspace plus registered repos.
|
||||
- Repo visibility is default.
|
||||
- Change selection is optional focus, not the mechanism for repo access.
|
||||
- `--agent` should be a one-session override by default. Persisting the preferred agent should require an explicit preference-setting action.
|
||||
|
||||
For GitHub Copilot, generate or open a `.code-workspace` file with:
|
||||
|
||||
```text
|
||||
workspace root
|
||||
registered repo A
|
||||
registered repo B
|
||||
```
|
||||
|
||||
For Claude and Codex, attach the registered repo directories through the agent's supported mechanism.
|
||||
|
||||
Defer:
|
||||
|
||||
- `workspace open --change`.
|
||||
- In-session upgrade flows.
|
||||
- Per-change attachment restrictions.
|
||||
|
||||
Done when opening a workspace gives the agent visibility into the coordination root and all registered repos.
|
||||
|
||||
### 3. Agent Guidance And Explore
|
||||
|
||||
Then make exploration work.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Tell the agent a rough product goal and have it inspect the repos before creating a proposal.
|
||||
```
|
||||
|
||||
Expected user prompt:
|
||||
|
||||
```text
|
||||
Explore how we should make the OpenSpec docs available on the landing page.
|
||||
Look across the registered repos, but do not implement yet.
|
||||
```
|
||||
|
||||
Agent behavior:
|
||||
|
||||
- Understand it is in workspace mode.
|
||||
- Inspect registered repos.
|
||||
- Explain likely affected repos.
|
||||
- Ask for clarification only when needed.
|
||||
- Avoid implementation edits during explore.
|
||||
|
||||
Build:
|
||||
|
||||
- Workspace-level `AGENTS.md` guidance.
|
||||
- Normal OpenSpec skills and commands in workspace sessions.
|
||||
- Workspace-specific guidance layered on top of normal `/explore`, not replacing it.
|
||||
|
||||
Defer:
|
||||
|
||||
- Proposal artifact generation.
|
||||
- Target confirmation commands.
|
||||
- Apply context providers.
|
||||
|
||||
Done when a user can open a workspace and run a useful cross-repo exploration without creating a dummy change.
|
||||
|
||||
### 4. Proposal Creation
|
||||
|
||||
Only after explore works, build proposal creation.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Now that we understand the scope, capture the plan.
|
||||
```
|
||||
|
||||
Expected user prompt:
|
||||
|
||||
```text
|
||||
Create a proposal for this change.
|
||||
Target the repos that are actually affected.
|
||||
```
|
||||
|
||||
Preferred artifact shape:
|
||||
|
||||
```text
|
||||
changes/integrate-docs/
|
||||
proposal.md
|
||||
design.md
|
||||
tasks.md
|
||||
specs/
|
||||
openspec/
|
||||
docs-conventions/spec.md
|
||||
landing/
|
||||
docs-routing/spec.md
|
||||
```
|
||||
|
||||
Key workflow rule:
|
||||
|
||||
```text
|
||||
/explore may leave targets unknown.
|
||||
/propose may discover targets.
|
||||
/propose must confirm targets before saying ready for apply.
|
||||
```
|
||||
|
||||
Targets should be represented by the proposal artifacts themselves where possible. If there is `specs/landing/...`, then `landing` is in scope. Avoid a separate required `targets: [...]` metadata list as the active source of truth.
|
||||
|
||||
Defer:
|
||||
|
||||
- Repo-local materialization.
|
||||
- Worktree selection.
|
||||
- Multi-repo implementation.
|
||||
- Archive.
|
||||
|
||||
Done when a user can explore, then create a workspace proposal with repo-scoped specs and tasks.
|
||||
|
||||
### 5. Status
|
||||
|
||||
Before implementation, make status excellent.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Where are we, what repos are involved, and is this ready to implement?
|
||||
```
|
||||
|
||||
Expected surface:
|
||||
|
||||
```bash
|
||||
openspec status
|
||||
openspec status --change integrate-docs
|
||||
```
|
||||
|
||||
Human output should answer:
|
||||
|
||||
```text
|
||||
Change: integrate-docs
|
||||
Scope: openspec, landing
|
||||
Proposal: present
|
||||
Design: present
|
||||
Tasks: present
|
||||
Ready for apply: yes/no
|
||||
```
|
||||
|
||||
Status should also catch structural mistakes:
|
||||
|
||||
- Unknown repo folder under `specs/`.
|
||||
- Missing tasks.
|
||||
- No confirmed affected repo.
|
||||
- Registered repo path missing.
|
||||
|
||||
Done when the agent and user can trust status before applying.
|
||||
|
||||
### 6. Apply One Repo Slice
|
||||
|
||||
Only now build `/apply`.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Implement the planned slice for one repo.
|
||||
```
|
||||
|
||||
Expected user prompt:
|
||||
|
||||
```text
|
||||
/apply integrate-docs for landing
|
||||
```
|
||||
|
||||
Product contract:
|
||||
|
||||
```text
|
||||
/apply means implement.
|
||||
```
|
||||
|
||||
It does not mean:
|
||||
|
||||
```text
|
||||
copy planning files
|
||||
materialize repo-local OpenSpec state
|
||||
create the proposal files for the first time
|
||||
```
|
||||
|
||||
Agent behavior:
|
||||
|
||||
1. Ask OpenSpec for apply context.
|
||||
2. Read proposal, design, tasks, and relevant specs.
|
||||
3. Confirm the target repo checkout.
|
||||
4. Edit only that repo.
|
||||
5. Update workspace tasks.
|
||||
6. Run relevant checks.
|
||||
|
||||
This likely wants a normalized context command internally, but that is supporting machinery:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "workspace",
|
||||
"change": "integrate-docs",
|
||||
"target": "landing",
|
||||
"implementationRoot": "/repos/openspec-landing",
|
||||
"contextFiles": [
|
||||
"changes/integrate-docs/proposal.md",
|
||||
"changes/integrate-docs/design.md",
|
||||
"changes/integrate-docs/tasks.md",
|
||||
"changes/integrate-docs/specs/landing/docs-routing/spec.md"
|
||||
],
|
||||
"allowedEditRoots": [
|
||||
"/repos/openspec-landing"
|
||||
],
|
||||
"tasksFile": "changes/integrate-docs/tasks.md"
|
||||
}
|
||||
```
|
||||
|
||||
Defer:
|
||||
|
||||
- Applying multiple repos at once.
|
||||
- Automatic branch creation.
|
||||
- Worktree management.
|
||||
- Repo-local OpenSpec mirroring.
|
||||
|
||||
Done when one repo slice can be implemented from the central workspace plan.
|
||||
|
||||
### 7. Verify
|
||||
|
||||
Then build verification.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Check whether the implemented repo slice satisfies the plan.
|
||||
```
|
||||
|
||||
Expected prompt:
|
||||
|
||||
```text
|
||||
/verify integrate-docs for landing
|
||||
```
|
||||
|
||||
Behavior:
|
||||
|
||||
- Read the same normalized context as `/apply`.
|
||||
- Inspect the implementation checkout.
|
||||
- Check tasks and specs for that repo.
|
||||
- Run repo validation.
|
||||
- Report gaps clearly.
|
||||
|
||||
Default behavior should verify one repo slice. Whole-workspace verification can come later.
|
||||
|
||||
Done when a user can verify one implemented repo slice against the central workspace plan.
|
||||
|
||||
### 8. Archive
|
||||
|
||||
Archive comes last in the first complete loop.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
The change is done. Move it out of active planning.
|
||||
```
|
||||
|
||||
Expected prompt:
|
||||
|
||||
```text
|
||||
/archive integrate-docs
|
||||
```
|
||||
|
||||
Behavior:
|
||||
|
||||
- Require all targeted repo slices to be complete or explicitly accepted.
|
||||
- Archive the workspace change.
|
||||
- Do not require repo-local planning copies unless OpenSpec later decides that repo-local archival matters.
|
||||
|
||||
Done when a user can complete the full lifecycle:
|
||||
|
||||
```text
|
||||
workspace create
|
||||
-> open
|
||||
-> explore
|
||||
-> propose
|
||||
-> apply repo A
|
||||
-> apply repo B
|
||||
-> verify
|
||||
-> archive
|
||||
```
|
||||
|
||||
## Implementation Discipline
|
||||
|
||||
Build only the next user-visible step.
|
||||
|
||||
The sequence should stay grounded in these questions:
|
||||
|
||||
```text
|
||||
1. Can I create the workspace?
|
||||
2. Can I see my repos?
|
||||
3. Can my agent explore them?
|
||||
4. Can we capture a proposal?
|
||||
5. Can status tell us if it is ready?
|
||||
6. Can the agent implement one repo slice?
|
||||
7. Can we verify it?
|
||||
8. Can we archive it?
|
||||
```
|
||||
|
||||
Avoid starting with internal abstractions unless they are required for the next user-visible capability.
|
||||
|
||||
Do not start with:
|
||||
|
||||
- Target metadata machinery.
|
||||
- Materialization.
|
||||
- Adapter abstractions.
|
||||
- Branch orchestration.
|
||||
- Worktree orchestration.
|
||||
- Multi-repo apply.
|
||||
|
||||
Those may matter later, but they should not define the first reimplementation path.
|
||||
|
||||
## Product Shape
|
||||
|
||||
The workspace should feel like OpenSpec's normal workflow stretched across multiple repos, not a second product with its own lifecycle.
|
||||
|
||||
The durable product model is:
|
||||
|
||||
```text
|
||||
workspace = central planning source of truth
|
||||
registered repos = visible working set
|
||||
proposal = scoped planning commitment
|
||||
repo target = one affected repo in the plan
|
||||
branch/worktree = implementation checkout
|
||||
/apply = implement one selected repo slice
|
||||
```
|
||||
|
||||
Keep the user journey simple:
|
||||
|
||||
```text
|
||||
Open the workspace.
|
||||
Ask the agent to explore.
|
||||
Create the proposal when scope is clear.
|
||||
Implement one repo slice at a time.
|
||||
Verify.
|
||||
Archive.
|
||||
```
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 450 KiB |
@@ -0,0 +1,89 @@
|
||||
<svg width="640" height="80" viewBox="0 0 640 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M32 0H16V16H32V0Z" fill="white"/>
|
||||
<path d="M48 0H32V16H48V0Z" fill="white"/>
|
||||
<path d="M16 16H0V32H16V16Z" fill="white"/>
|
||||
<path d="M64 16H48V32H64V16Z" fill="white"/>
|
||||
<path d="M16 32H0V48H16V32Z" fill="white"/>
|
||||
<path d="M64 32H48V48H64V32Z" fill="white"/>
|
||||
<path d="M16 48H0V64H16V48Z" fill="white"/>
|
||||
<path d="M64 48H48V64H64V48Z" fill="white"/>
|
||||
<path d="M32 64H16V80H32V64Z" fill="white"/>
|
||||
<path d="M48 64H32V80H48V64Z" fill="white"/>
|
||||
<path d="M96 0H80V16H96V0Z" fill="white"/>
|
||||
<path d="M112 0H96V16H112V0Z" fill="white"/>
|
||||
<path d="M128 0H112V16H128V0Z" fill="white"/>
|
||||
<path d="M96 16H80V32H96V16Z" fill="white"/>
|
||||
<path d="M144 16H128V32H144V16Z" fill="white"/>
|
||||
<path d="M96 32H80V48H96V32Z" fill="white"/>
|
||||
<path d="M112 32H96V48H112V32Z" fill="white"/>
|
||||
<path d="M128 32H112V48H128V32Z" fill="white"/>
|
||||
<path d="M144 32H128V48H144V32Z" fill="white"/>
|
||||
<path d="M96 48H80V64H96V48Z" fill="white"/>
|
||||
<path d="M96 64H80V80H96V64Z" fill="white"/>
|
||||
<path d="M176 0H160V16H176V0Z" fill="white"/>
|
||||
<path d="M192 0H176V16H192V0Z" fill="white"/>
|
||||
<path d="M208 0H192V16H208V0Z" fill="white"/>
|
||||
<path d="M224 0H208V16H224V0Z" fill="white"/>
|
||||
<path d="M176 16H160V32H176V16Z" fill="white"/>
|
||||
<path d="M176 32H160V48H176V32Z" fill="white"/>
|
||||
<path d="M192 32H176V48H192V32Z" fill="white"/>
|
||||
<path d="M208 32H192V48H208V32Z" fill="white"/>
|
||||
<path d="M176 48H160V64H176V48Z" fill="white"/>
|
||||
<path d="M176 64H160V80H176V64Z" fill="white"/>
|
||||
<path d="M192 64H176V80H192V64Z" fill="white"/>
|
||||
<path d="M208 64H192V80H208V64Z" fill="white"/>
|
||||
<path d="M224 64H208V80H224V64Z" fill="white"/>
|
||||
<path d="M256 0H240V16H256V0Z" fill="white"/>
|
||||
<path d="M304 0H288V16H304V0Z" fill="white"/>
|
||||
<path d="M256 16H240V32H256V16Z" fill="white"/>
|
||||
<path d="M272 16H256V32H272V16Z" fill="white"/>
|
||||
<path d="M304 16H288V32H304V16Z" fill="white"/>
|
||||
<path d="M256 32H240V48H256V32Z" fill="white"/>
|
||||
<path d="M288 32H272V48H288V32Z" fill="white"/>
|
||||
<path d="M304 32H288V48H304V32Z" fill="white"/>
|
||||
<path d="M256 48H240V64H256V48Z" fill="white"/>
|
||||
<path d="M304 48H288V64H304V48Z" fill="white"/>
|
||||
<path d="M256 64H240V80H256V64Z" fill="white"/>
|
||||
<path d="M304 64H288V80H304V64Z" fill="white"/>
|
||||
<path d="M352 0H336V16H352V0Z" fill="white"/>
|
||||
<path d="M368 0H352V16H368V0Z" fill="white"/>
|
||||
<path d="M384 0H368V16H384V0Z" fill="white"/>
|
||||
<path d="M336 16H320V32H336V16Z" fill="white"/>
|
||||
<path d="M352 32H336V48H352V32Z" fill="white"/>
|
||||
<path d="M368 32H352V48H368V32Z" fill="white"/>
|
||||
<path d="M384 48H368V64H384V48Z" fill="white"/>
|
||||
<path d="M336 64H320V80H336V64Z" fill="white"/>
|
||||
<path d="M352 64H336V80H352V64Z" fill="white"/>
|
||||
<path d="M368 64H352V80H368V64Z" fill="white"/>
|
||||
<path d="M416 0H400V16H416V0Z" fill="white"/>
|
||||
<path d="M432 0H416V16H432V0Z" fill="white"/>
|
||||
<path d="M448 0H432V16H448V0Z" fill="white"/>
|
||||
<path d="M416 16H400V32H416V16Z" fill="white"/>
|
||||
<path d="M464 16H448V32H464V16Z" fill="white"/>
|
||||
<path d="M416 32H400V48H416V32Z" fill="white"/>
|
||||
<path d="M432 32H416V48H432V32Z" fill="white"/>
|
||||
<path d="M448 32H432V48H448V32Z" fill="white"/>
|
||||
<path d="M464 32H448V48H464V32Z" fill="white"/>
|
||||
<path d="M416 48H400V64H416V48Z" fill="white"/>
|
||||
<path d="M416 64H400V80H416V64Z" fill="white"/>
|
||||
<path d="M496 0H480V16H496V0Z" fill="white"/>
|
||||
<path d="M512 0H496V16H512V0Z" fill="white"/>
|
||||
<path d="M528 0H512V16H528V0Z" fill="white"/>
|
||||
<path d="M544 0H528V16H544V0Z" fill="white"/>
|
||||
<path d="M496 16H480V32H496V16Z" fill="white"/>
|
||||
<path d="M496 32H480V48H496V32Z" fill="white"/>
|
||||
<path d="M512 32H496V48H512V32Z" fill="white"/>
|
||||
<path d="M528 32H512V48H528V32Z" fill="white"/>
|
||||
<path d="M496 48H480V64H496V48Z" fill="white"/>
|
||||
<path d="M496 64H480V80H496V64Z" fill="white"/>
|
||||
<path d="M512 64H496V80H512V64Z" fill="white"/>
|
||||
<path d="M528 64H512V80H528V64Z" fill="white"/>
|
||||
<path d="M544 64H528V80H544V64Z" fill="white"/>
|
||||
<path d="M592 0H576V16H592V0Z" fill="white"/>
|
||||
<path d="M608 0H592V16H608V0Z" fill="white"/>
|
||||
<path d="M576 16H560V32H576V16Z" fill="white"/>
|
||||
<path d="M576 32H560V48H576V32Z" fill="white"/>
|
||||
<path d="M576 48H560V64H576V48Z" fill="white"/>
|
||||
<path d="M592 64H576V80H592V64Z" fill="white"/>
|
||||
<path d="M608 64H592V80H608V64Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
@@ -0,0 +1,89 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="80" viewBox="0 0 640 80">
|
||||
<rect x="16" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="32" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="0" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="48" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="0" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="48" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="0" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="48" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="16" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="32" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="80" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="96" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="112" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="80" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="128" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="80" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="96" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="112" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="128" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="80" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="80" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="160" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="176" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="192" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="208" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="160" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="160" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="176" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="192" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="160" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="160" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="176" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="192" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="208" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="240" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="288" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="240" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="256" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="288" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="240" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="272" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="288" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="240" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="288" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="240" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="288" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="336" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="352" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="368" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="320" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="336" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="352" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="368" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="320" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="336" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="352" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="400" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="416" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="432" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="400" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="448" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="400" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="416" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="432" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="448" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="400" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="400" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="480" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="496" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="512" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="528" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="480" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="480" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="496" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="512" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="480" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="480" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="496" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="512" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="528" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="576" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="592" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="560" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="560" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="560" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="576" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="592" y="64" width="16" height="16" fill="black" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.1 KiB |
@@ -1,7 +1,15 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { execSync } from 'child_process';
|
||||
import { execFileSync } from 'child_process';
|
||||
import { existsSync, rmSync } from 'fs';
|
||||
import { createRequire } from 'module';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
const runTsc = (args = []) => {
|
||||
const tscPath = require.resolve('typescript/bin/tsc');
|
||||
execFileSync(process.execPath, [tscPath, ...args], { stdio: 'inherit' });
|
||||
};
|
||||
|
||||
console.log('🔨 Building OpenSpec...\n');
|
||||
|
||||
@@ -11,12 +19,13 @@ if (existsSync('dist')) {
|
||||
rmSync('dist', { recursive: true, force: true });
|
||||
}
|
||||
|
||||
// Run TypeScript compiler
|
||||
// Run TypeScript compiler (use local version explicitly)
|
||||
console.log('Compiling TypeScript...');
|
||||
try {
|
||||
execSync('tsc', { stdio: 'inherit' });
|
||||
runTsc(['--version']);
|
||||
runTsc();
|
||||
console.log('\n✅ Build completed successfully!');
|
||||
} catch (error) {
|
||||
console.error('\n❌ Build failed!');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,316 @@
|
||||
|
||||
---
|
||||
|
||||
## Request `request_79caa9a0-bb0e-4cb4-bf91-4ce6456ad26a`
|
||||
|
||||
**Timestamp:** 2026-04-28 11:59:49 AEST
|
||||
|
||||
**Agent:** GitHubCopilot
|
||||
|
||||
### User
|
||||
|
||||
Follow instructions in [SKILL.md](file:///Users/tabishbidiwale/.local/share/openspec/workspaces/poc-workspace/.agents/skills/openspec-explore/SKILL.md).
|
||||
How could we get the docs from openspec repo to show up in the landing page
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Request `request_79caa9a0-bb0e-4cb4-bf91-4ce6456ad26a`
|
||||
|
||||
**Timestamp:** 2026-04-28 11:59:49 AEST
|
||||
|
||||
**Agent:** GitHubCopilot
|
||||
|
||||
### User
|
||||
|
||||
Follow instructions in [SKILL.md](file:///Users/tabishbidiwale/.local/share/openspec/workspaces/poc-workspace/.agents/skills/openspec-explore/SKILL.md).
|
||||
How could we get the docs from openspec repo to show up in the landing page
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
I'm in explore mode. Let me think through this with you.
|
||||
|
||||
First, let me understand what you're working with:
|
||||
|
||||
**The setup:**
|
||||
- You have
|
||||
|
||||
---
|
||||
|
||||
## Request `request_79caa9a0-bb0e-4cb4-bf91-4ce6456ad26a`
|
||||
|
||||
**Timestamp:** 2026-04-28 11:59:49 AEST
|
||||
|
||||
**Agent:** GitHubCopilot
|
||||
|
||||
### User
|
||||
|
||||
Follow instructions in [SKILL.md](file:///Users/tabishbidiwale/.local/share/openspec/workspaces/poc-workspace/.agents/skills/openspec-explore/SKILL.md).
|
||||
How could we get the docs from openspec repo to show up in the landing page
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Request `request_79caa9a0-bb0e-4cb4-bf91-4ce6456ad26a`
|
||||
|
||||
**Timestamp:** 2026-04-28 11:59:49 AEST
|
||||
|
||||
**Agent:** GitHubCopilot
|
||||
|
||||
### User
|
||||
|
||||
Follow instructions in [SKILL.md](file:///Users/tabishbidiwale/.local/share/openspec/workspaces/poc-workspace/.agents/skills/openspec-explore/SKILL.md).
|
||||
How could we get the docs from openspec repo to show up in the landing page
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
repo (the core product/system)
|
||||
- You have `/openspec-landing` (the landing page)
|
||||
- You want docs from openspec to appear on the landing page
|
||||
|
||||
**Before I dig into the code, some clarifying questions:**
|
||||
|
||||
1. **What docs are we talking about?** Are these:
|
||||
- API documentation (auto-generated from code)?
|
||||
- Guides and tutorials (hand-written markdown)?
|
||||
- Specs and architecture docs?
|
||||
- All of the above?
|
||||
|
||||
2. **How should they appear on the landing page?**
|
||||
- Embedded directly (copy/sync)?
|
||||
- Linked to (openspec repo becomes the source of truth)?
|
||||
- A combination (some docs embedded, some linked)?
|
||||
|
||||
3. **Single source of truth?** Should the landing page reflect the *current* state of docs in openspec automatically, or is it okay if they drift?
|
||||
|
||||
4. **User experience angle**: When someone lands on the landing page, what should they see/do? Is the landing page meant to be:
|
||||
- An entry point that says "here's what this is" + links to full docs elsewhere?
|
||||
- Self-contained docs that happen to be synced from the repo?
|
||||
- Something else?
|
||||
|
||||
Let me also check what's actually in these repos right now - that'll ground the thinking:
|
||||
|
||||
```bash
|
||||
# What docs exist in openspec?
|
||||
find /Users/tabishbidiwale/fission/repos/openspec -name "*.md" -type f | head -20
|
||||
|
||||
# What's the landing page structure?
|
||||
ls -la /Users/tabishbidiwale/fission/repos/openspec-landing/
|
||||
```
|
||||
|
||||
Once I see the actual structure and understand your intent, the solution becomes clearer. Could be anything from a static build step that copies markdown, to a dynamic system that fetches docs at runtime, to a link-and-let-them-navigate approach.
|
||||
|
||||
What resonates most with how you're thinking about this?
|
||||
|
||||
---
|
||||
|
||||
## Request `request_b6e88cd6-d531-43eb-904b-6225c3981934`
|
||||
|
||||
**Timestamp:** 2026-04-28 12:00:32 AEST
|
||||
|
||||
**Agent:** agent
|
||||
|
||||
### User
|
||||
|
||||
go search and ground before asking questions
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Request `request_b6e88cd6-d531-43eb-904b-6225c3981934`
|
||||
|
||||
**Timestamp:** 2026-04-28 12:00:32 AEST
|
||||
|
||||
**Agent:** agent
|
||||
|
||||
### User
|
||||
|
||||
go search and ground before asking questions
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
|
||||
**Visible Thinking**
|
||||
|
||||
The user is right - I should explore the codebase first before asking clarifying questions. They're in explore mode and I should ground my thinking in what actually exists. Let me search and read the actual structure of both repos.
|
||||
|
||||
Let me:
|
||||
1. Look at the docs in the openspec repo
|
||||
2. Look at the structure of openspec-landing
|
||||
3. See if there's any existing mechanism for sharing docs
|
||||
4. Then come back with grounded thinking
|
||||
|
||||
I should use tools to explore the codebase first.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Request `request_b6e88cd6-d531-43eb-904b-6225c3981934`
|
||||
|
||||
**Timestamp:** 2026-04-28 12:00:32 AEST
|
||||
|
||||
**Agent:** agent
|
||||
|
||||
### User
|
||||
|
||||
go search and ground before asking questions
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
|
||||
**Tool Call** `run_in_terminal`
|
||||
|
||||
```bash
|
||||
find /Users/tabishbidiwale/fission/repos/openspec/docs -type f -name "*.md" | head -20
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Request `request_d515673c-cd78-483d-b0c7-139dfbe0f4b7`
|
||||
|
||||
**Timestamp:** 2026-04-28 12:09:16 AEST
|
||||
|
||||
**Agent:** agent
|
||||
|
||||
### User
|
||||
|
||||
choose best defaults and create a change proposal
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Request `request_c020834d-3218-4ba4-b3ac-0fe8d8a292db`
|
||||
|
||||
**Timestamp:** 2026-04-28 12:32:26 AEST
|
||||
|
||||
**Agent:** agent
|
||||
|
||||
### User
|
||||
|
||||
what was this session id?
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Request `request_c020834d-3218-4ba4-b3ac-0fe8d8a292db`
|
||||
|
||||
**Timestamp:** 2026-04-28 12:32:26 AEST
|
||||
|
||||
**Agent:** agent
|
||||
|
||||
### User
|
||||
|
||||
what was this session id?
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
|
||||
**Visible Thinking**
|
||||
|
||||
The user is asking about the session ID. I need to check what session ID was used or assigned during this exploration/proposal creation. Let me look back at what happened.
|
||||
|
||||
Looking at the context, I don't see a specific session ID mentioned anywhere. The user might be asking about:
|
||||
1. The OpenSpec change ID (which is "integrate-docs")
|
||||
2. Some kind of terminal session ID
|
||||
3. Some other identifier
|
||||
|
||||
The change we created is called "integrate-docs" and it's located at:
|
||||
`/Users/tabishbidiwale/.local/share/openspec/workspaces/poc-workspace/changes/integrate-docs/`
|
||||
|
||||
I should clarify what they're asking about. The most likely answer is the change name/ID, which is "integrate-docs".
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Request `request_c020834d-3218-4ba4-b3ac-0fe8d8a292db`
|
||||
|
||||
**Timestamp:** 2026-04-28 12:32:26 AEST
|
||||
|
||||
**Agent:** agent
|
||||
|
||||
### User
|
||||
|
||||
what was this session id?
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
The change ID is **`integrate-docs`**.
|
||||
|
||||
It's located at:
|
||||
```
|
||||
/Users/tabishbidiwale/.local/share/openspec/workspaces/poc-workspace/changes/integrate-docs/
|
||||
```
|
||||
|
||||
You can reference it in commands with `--change integrate-docs`.
|
||||
|
||||
---
|
||||
|
||||
## Request `request_632f186b-58f8-4301-8b64-a29b5005d8bf`
|
||||
|
||||
**Timestamp:** 2026-04-28 12:32:41 AEST
|
||||
|
||||
**Agent:** agent
|
||||
|
||||
### User
|
||||
|
||||
nah chat session ID
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Request `request_632f186b-58f8-4301-8b64-a29b5005d8bf`
|
||||
|
||||
**Timestamp:** 2026-04-28 12:32:41 AEST
|
||||
|
||||
**Agent:** agent
|
||||
|
||||
### User
|
||||
|
||||
nah chat session ID
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
|
||||
**Visible Thinking**
|
||||
|
||||
The user is asking for the chat session ID - not the OpenSpec change ID. They want to know the session ID for this conversation.
|
||||
|
||||
However, I don't have a built-in way to retrieve the chat session ID from the context provided to me. The context includes information about the workspace, files, and environment, but not the chat session ID.
|
||||
|
||||
I should be honest that I don't have access to that information.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Request `request_632f186b-58f8-4301-8b64-a29b5005d8bf`
|
||||
|
||||
**Timestamp:** 2026-04-28 12:32:41 AEST
|
||||
|
||||
**Agent:** agent
|
||||
|
||||
### User
|
||||
|
||||
nah chat session ID
|
||||
|
||||
### Assistant / Events
|
||||
|
||||
I don't have access to the chat session ID from my context. That information isn't available to me in the tools and context I can see. You might be able to find it in your chat client's UI or logs.
|
||||
File diff suppressed because it is too large
Load Diff
+978
@@ -0,0 +1,978 @@
|
||||
# CLI Reference
|
||||
|
||||
The OpenSpec CLI (`openspec`) provides terminal commands for project setup, validation, status inspection, and management. These commands complement the AI slash commands (like `/opsx:propose`) documented in [Commands](commands.md).
|
||||
|
||||
## Summary
|
||||
|
||||
| Category | Commands | Purpose |
|
||||
|----------|----------|---------|
|
||||
| **Setup** | `init`, `update` | Initialize and update OpenSpec in your project |
|
||||
| **Browsing** | `list`, `view`, `show` | Explore changes and specs |
|
||||
| **Validation** | `validate` | Check changes and specs for issues |
|
||||
| **Lifecycle** | `archive` | Finalize completed changes |
|
||||
| **Workflow** | `status`, `instructions`, `templates`, `schemas` | Artifact-driven workflow support |
|
||||
| **Workspace** | `workspace setup`, `workspace list`, `workspace create`, `workspace add-repo`, `workspace update-repo`, `workspace targets`, `workspace doctor`, `workspace open` | Coordinate cross-repo planning without collapsing repo ownership |
|
||||
| **Schemas** | `schema init`, `schema fork`, `schema validate`, `schema which` | Create and manage custom workflows |
|
||||
| **Config** | `config` | View and modify settings |
|
||||
| **Utility** | `feedback`, `completion` | Feedback and shell integration |
|
||||
|
||||
---
|
||||
|
||||
## Human vs Agent Commands
|
||||
|
||||
Most CLI commands are designed for **human use** in a terminal. Some commands also support **agent/script use** via JSON output.
|
||||
|
||||
### Human-Only Commands
|
||||
|
||||
These commands are interactive and designed for terminal use:
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `openspec init` | Initialize project (interactive prompts) |
|
||||
| `openspec view` | Interactive dashboard |
|
||||
| `openspec config edit` | Open config in editor |
|
||||
| `openspec feedback` | Submit feedback via GitHub |
|
||||
| `openspec completion install` | Install shell completions |
|
||||
|
||||
### Agent-Compatible Commands
|
||||
|
||||
These commands support `--json` output for programmatic use by AI agents and scripts:
|
||||
|
||||
| Command | Human Use | Agent Use |
|
||||
|---------|-----------|-----------|
|
||||
| `openspec list` | Browse changes/specs | `--json` for structured data |
|
||||
| `openspec show <item>` | Read content | `--json` for parsing |
|
||||
| `openspec validate` | Check for issues | `--all --json` for bulk validation |
|
||||
| `openspec status` | See artifact progress | `--json` for structured status |
|
||||
| `openspec instructions` | Get next steps | `--json` for agent instructions |
|
||||
| `openspec templates` | Find template paths | `--json` for path resolution |
|
||||
| `openspec schemas` | List available schemas | `--json` for schema discovery |
|
||||
|
||||
---
|
||||
|
||||
## Global Options
|
||||
|
||||
These options work with all commands:
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--version`, `-V` | Show version number |
|
||||
| `--no-color` | Disable color output |
|
||||
| `--help`, `-h` | Display help for command |
|
||||
|
||||
---
|
||||
|
||||
## Setup Commands
|
||||
|
||||
### `openspec init`
|
||||
|
||||
Initialize OpenSpec in your project. Creates the folder structure and configures AI tool integrations.
|
||||
|
||||
Default behavior uses global config defaults: profile `core`, delivery `both`, workflows `propose, explore, apply, archive`.
|
||||
|
||||
```
|
||||
openspec init [path] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `path` | No | Target directory (default: current directory) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--tools <list>` | Configure AI tools non-interactively. Use `all`, `none`, or comma-separated list |
|
||||
| `--force` | Auto-cleanup legacy files without prompting |
|
||||
| `--profile <profile>` | Override global profile for this init run (`core` or `custom`) |
|
||||
|
||||
`--profile custom` uses whatever workflows are currently selected in global config (`openspec config profile`).
|
||||
|
||||
**Supported tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Interactive initialization
|
||||
openspec init
|
||||
|
||||
# Initialize in a specific directory
|
||||
openspec init ./my-project
|
||||
|
||||
# Non-interactive: configure for Claude and Cursor
|
||||
openspec init --tools claude,cursor
|
||||
|
||||
# Configure for all supported tools
|
||||
openspec init --tools all
|
||||
|
||||
# Override profile for this run
|
||||
openspec init --profile core
|
||||
|
||||
# Skip prompts and auto-cleanup legacy files
|
||||
openspec init --force
|
||||
```
|
||||
|
||||
**What it creates:**
|
||||
|
||||
```
|
||||
openspec/
|
||||
├── specs/ # Your specifications (source of truth)
|
||||
├── changes/ # Proposed changes
|
||||
└── config.yaml # Project configuration
|
||||
|
||||
.claude/skills/ # Claude Code skills (if claude selected)
|
||||
.cursor/skills/ # Cursor skills (if cursor selected)
|
||||
.cursor/commands/ # Cursor OPSX commands (if delivery includes commands)
|
||||
... (other tool configs)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec update`
|
||||
|
||||
Update OpenSpec instruction files after upgrading the CLI. Re-generates AI tool configuration files using your current global profile, selected workflows, and delivery mode.
|
||||
|
||||
```
|
||||
openspec update [path] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `path` | No | Target directory (default: current directory) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--force` | Force update even when files are up to date |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
# Update instruction files after npm upgrade
|
||||
npm update @fission-ai/openspec
|
||||
openspec update
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Browsing Commands
|
||||
|
||||
### `openspec list`
|
||||
|
||||
List changes or specs in your project.
|
||||
|
||||
```
|
||||
openspec list [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--specs` | List specs instead of changes |
|
||||
| `--changes` | List changes (default) |
|
||||
| `--sort <order>` | Sort by `recent` (default) or `name` |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# List all active changes
|
||||
openspec list
|
||||
|
||||
# List all specs
|
||||
openspec list --specs
|
||||
|
||||
# JSON output for scripts
|
||||
openspec list --json
|
||||
```
|
||||
|
||||
**Output (text):**
|
||||
|
||||
```
|
||||
Active changes:
|
||||
add-dark-mode UI theme switching support
|
||||
fix-login-bug Session timeout handling
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec view`
|
||||
|
||||
Display an interactive dashboard for exploring specs and changes.
|
||||
|
||||
```
|
||||
openspec view
|
||||
```
|
||||
|
||||
Opens a terminal-based interface for navigating your project's specifications and changes.
|
||||
|
||||
---
|
||||
|
||||
### `openspec show`
|
||||
|
||||
Display details of a change or spec.
|
||||
|
||||
```
|
||||
openspec show [item-name] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `item-name` | No | Name of change or spec (prompts if omitted) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--type <type>` | Specify type: `change` or `spec` (auto-detected if unambiguous) |
|
||||
| `--json` | Output as JSON |
|
||||
| `--no-interactive` | Disable prompts |
|
||||
|
||||
**Change-specific options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--deltas-only` | Show only delta specs (JSON mode) |
|
||||
|
||||
**Spec-specific options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--requirements` | Show only requirements, exclude scenarios (JSON mode) |
|
||||
| `--no-scenarios` | Exclude scenario content (JSON mode) |
|
||||
| `-r, --requirement <id>` | Show specific requirement by 1-based index (JSON mode) |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Interactive selection
|
||||
openspec show
|
||||
|
||||
# Show a specific change
|
||||
openspec show add-dark-mode
|
||||
|
||||
# Show a specific spec
|
||||
openspec show auth --type spec
|
||||
|
||||
# JSON output for parsing
|
||||
openspec show add-dark-mode --json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validation Commands
|
||||
|
||||
### `openspec validate`
|
||||
|
||||
Validate changes and specs for structural issues.
|
||||
|
||||
```
|
||||
openspec validate [item-name] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `item-name` | No | Specific item to validate (prompts if omitted) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--all` | Validate all changes and specs |
|
||||
| `--changes` | Validate all changes |
|
||||
| `--specs` | Validate all specs |
|
||||
| `--type <type>` | Specify type when name is ambiguous: `change` or `spec` |
|
||||
| `--strict` | Enable strict validation mode |
|
||||
| `--json` | Output as JSON |
|
||||
| `--concurrency <n>` | Max parallel validations (default: 6, or `OPENSPEC_CONCURRENCY` env) |
|
||||
| `--no-interactive` | Disable prompts |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Interactive validation
|
||||
openspec validate
|
||||
|
||||
# Validate a specific change
|
||||
openspec validate add-dark-mode
|
||||
|
||||
# Validate all changes
|
||||
openspec validate --changes
|
||||
|
||||
# Validate everything with JSON output (for CI/scripts)
|
||||
openspec validate --all --json
|
||||
|
||||
# Strict validation with increased parallelism
|
||||
openspec validate --all --strict --concurrency 12
|
||||
```
|
||||
|
||||
**Output (text):**
|
||||
|
||||
```
|
||||
Validating add-dark-mode...
|
||||
✓ proposal.md valid
|
||||
✓ specs/ui/spec.md valid
|
||||
⚠ design.md: missing "Technical Approach" section
|
||||
|
||||
1 warning found
|
||||
```
|
||||
|
||||
**Output (JSON):**
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"results": {
|
||||
"changes": [
|
||||
{
|
||||
"name": "add-dark-mode",
|
||||
"valid": true,
|
||||
"warnings": ["design.md: missing 'Technical Approach' section"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"total": 1,
|
||||
"valid": 1,
|
||||
"invalid": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Lifecycle Commands
|
||||
|
||||
### `openspec archive`
|
||||
|
||||
Archive a completed change and merge delta specs into main specs.
|
||||
|
||||
```
|
||||
openspec archive [change-name] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Change to archive (prompts if omitted) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `-y, --yes` | Skip confirmation prompts |
|
||||
| `--skip-specs` | Skip spec updates (for infrastructure/tooling/doc-only changes) |
|
||||
| `--no-validate` | Skip validation (requires confirmation) |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Interactive archive
|
||||
openspec archive
|
||||
|
||||
# Archive specific change
|
||||
openspec archive add-dark-mode
|
||||
|
||||
# Archive without prompts (CI/scripts)
|
||||
openspec archive add-dark-mode --yes
|
||||
|
||||
# Archive a tooling change that doesn't affect specs
|
||||
openspec archive update-ci-config --skip-specs
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
|
||||
1. Validates the change (unless `--no-validate`)
|
||||
2. Prompts for confirmation (unless `--yes`)
|
||||
3. Merges delta specs into `openspec/specs/`
|
||||
4. Moves change folder to `openspec/changes/archive/YYYY-MM-DD-<name>/`
|
||||
|
||||
---
|
||||
|
||||
## Workflow Commands
|
||||
|
||||
These commands support the artifact-driven OPSX workflow. They're useful for both humans checking progress and agents determining next steps.
|
||||
|
||||
### `openspec status`
|
||||
|
||||
Display artifact completion status for a change.
|
||||
|
||||
```
|
||||
openspec status [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--change <id>` | Change name (prompts if omitted) |
|
||||
| `--schema <name>` | Schema override (auto-detected from change's config) |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Interactive status check
|
||||
openspec status
|
||||
|
||||
# Status for specific change
|
||||
openspec status --change add-dark-mode
|
||||
|
||||
# JSON for agent use
|
||||
openspec status --change add-dark-mode --json
|
||||
```
|
||||
|
||||
**Output (text):**
|
||||
|
||||
```
|
||||
Change: add-dark-mode
|
||||
Schema: spec-driven
|
||||
Progress: 2/4 artifacts complete
|
||||
|
||||
[x] proposal
|
||||
[ ] design
|
||||
[x] specs
|
||||
[-] tasks (blocked by: design)
|
||||
```
|
||||
|
||||
**Output (JSON):**
|
||||
|
||||
```json
|
||||
{
|
||||
"changeName": "add-dark-mode",
|
||||
"schemaName": "spec-driven",
|
||||
"isComplete": false,
|
||||
"applyRequires": ["tasks"],
|
||||
"artifacts": [
|
||||
{"id": "proposal", "outputPath": "proposal.md", "status": "done"},
|
||||
{"id": "design", "outputPath": "design.md", "status": "ready"},
|
||||
{"id": "specs", "outputPath": "specs/**/*.md", "status": "done"},
|
||||
{"id": "tasks", "outputPath": "tasks.md", "status": "blocked", "missingDeps": ["design"]}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec instructions`
|
||||
|
||||
Get enriched instructions for creating an artifact or applying tasks. Used by AI agents to understand what to create next.
|
||||
|
||||
```
|
||||
openspec instructions [artifact] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `artifact` | No | Artifact ID: `proposal`, `specs`, `design`, `tasks`, or `apply` |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--change <id>` | Change name (required in non-interactive mode) |
|
||||
| `--schema <name>` | Schema override |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Special case:** Use `apply` as the artifact to get task implementation instructions.
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Get instructions for next artifact
|
||||
openspec instructions --change add-dark-mode
|
||||
|
||||
# Get specific artifact instructions
|
||||
openspec instructions design --change add-dark-mode
|
||||
|
||||
# Get apply/implementation instructions
|
||||
openspec instructions apply --change add-dark-mode
|
||||
|
||||
# JSON for agent consumption
|
||||
openspec instructions design --change add-dark-mode --json
|
||||
```
|
||||
|
||||
**Output includes:**
|
||||
|
||||
- Template content for the artifact
|
||||
- Project context from config
|
||||
- Content from dependency artifacts
|
||||
- Per-artifact rules from config
|
||||
|
||||
---
|
||||
|
||||
### `openspec templates`
|
||||
|
||||
Show resolved template paths for all artifacts in a schema.
|
||||
|
||||
```
|
||||
openspec templates [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--schema <name>` | Schema to inspect (default: `spec-driven`) |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Show template paths for default schema
|
||||
openspec templates
|
||||
|
||||
# Show templates for custom schema
|
||||
openspec templates --schema my-workflow
|
||||
|
||||
# JSON for programmatic use
|
||||
openspec templates --json
|
||||
```
|
||||
|
||||
**Output (text):**
|
||||
|
||||
```
|
||||
Schema: spec-driven
|
||||
|
||||
Templates:
|
||||
proposal → ~/.openspec/schemas/spec-driven/templates/proposal.md
|
||||
specs → ~/.openspec/schemas/spec-driven/templates/specs.md
|
||||
design → ~/.openspec/schemas/spec-driven/templates/design.md
|
||||
tasks → ~/.openspec/schemas/spec-driven/templates/tasks.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec schemas`
|
||||
|
||||
List available workflow schemas with their descriptions and artifact flows.
|
||||
|
||||
```
|
||||
openspec schemas [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
openspec schemas
|
||||
```
|
||||
|
||||
**Output:**
|
||||
|
||||
```
|
||||
Available schemas:
|
||||
|
||||
spec-driven (package)
|
||||
The default spec-driven development workflow
|
||||
Flow: proposal → specs → design → tasks
|
||||
|
||||
my-custom (project)
|
||||
Custom workflow for this project
|
||||
Flow: research → proposal → tasks
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workspace Commands
|
||||
|
||||
Use workspace mode when one change spans multiple repos or you need a neutral planning home for cross-repo coordination. Stay repo-local when one repo owns the full change end to end.
|
||||
|
||||
For the supported v0 flow, re-entry path, and owner or handoff guidance, see [Workspace Mode](workspace.md).
|
||||
|
||||
Start with the guided setup path unless you already know the exact workspace shape you want:
|
||||
|
||||
- `openspec workspace setup`
|
||||
|
||||
The setup wizard is interactive and asks for:
|
||||
|
||||
- workspace name
|
||||
- repo paths
|
||||
- repo aliases
|
||||
- optional owner or handoff notes
|
||||
- whether to open the planning surface immediately
|
||||
|
||||
The current workspace command group includes:
|
||||
|
||||
- `openspec workspace setup`
|
||||
- `openspec workspace list`
|
||||
- `openspec workspace create <name>`
|
||||
- `openspec workspace add-repo <alias> <path> [--owner ...] [--handoff ...]`
|
||||
- `openspec workspace update-repo <alias> [--owner ...] [--handoff ...]`
|
||||
- `openspec workspace targets <id> [--add <a,b,c>] [--remove <x,y,z>]`
|
||||
- `openspec workspace doctor`
|
||||
- `openspec workspace open [--change <id>] [--name <workspace>] [--agent <claude|codex|github-copilot>] [--prepare-only]`
|
||||
|
||||
`openspec workspace targets` only mutates workspace-owned planning state. If the same change ID already exists or was already archived in a target repo, the command fails instead of silently rewriting the target set around repo-local authority handoff.
|
||||
|
||||
Workspace planning still uses the normal workflow commands around that command group:
|
||||
|
||||
- `openspec new change <id> --targets <a,b,c>`
|
||||
- `openspec apply --change <id> --repo <alias>`
|
||||
- `openspec status --change <id>`
|
||||
- `openspec archive <id> --workspace`
|
||||
|
||||
---
|
||||
|
||||
## Schema Commands
|
||||
|
||||
Commands for creating and managing custom workflow schemas.
|
||||
|
||||
### `openspec schema init`
|
||||
|
||||
Create a new project-local schema.
|
||||
|
||||
```
|
||||
openspec schema init <name> [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `name` | Yes | Schema name (kebab-case) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--description <text>` | Schema description |
|
||||
| `--artifacts <list>` | Comma-separated artifact IDs (default: `proposal,specs,design,tasks`) |
|
||||
| `--default` | Set as project default schema |
|
||||
| `--no-default` | Don't prompt to set as default |
|
||||
| `--force` | Overwrite existing schema |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Interactive schema creation
|
||||
openspec schema init research-first
|
||||
|
||||
# Non-interactive with specific artifacts
|
||||
openspec schema init rapid \
|
||||
--description "Rapid iteration workflow" \
|
||||
--artifacts "proposal,tasks" \
|
||||
--default
|
||||
```
|
||||
|
||||
**What it creates:**
|
||||
|
||||
```
|
||||
openspec/schemas/<name>/
|
||||
├── schema.yaml # Schema definition
|
||||
└── templates/
|
||||
├── proposal.md # Template for each artifact
|
||||
├── specs.md
|
||||
├── design.md
|
||||
└── tasks.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec schema fork`
|
||||
|
||||
Copy an existing schema to your project for customization.
|
||||
|
||||
```
|
||||
openspec schema fork <source> [name] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `source` | Yes | Schema to copy |
|
||||
| `name` | No | New schema name (default: `<source>-custom`) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--force` | Overwrite existing destination |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
# Fork the built-in spec-driven schema
|
||||
openspec schema fork spec-driven my-workflow
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec schema validate`
|
||||
|
||||
Validate a schema's structure and templates.
|
||||
|
||||
```
|
||||
openspec schema validate [name] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `name` | No | Schema to validate (validates all if omitted) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--verbose` | Show detailed validation steps |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
# Validate a specific schema
|
||||
openspec schema validate my-workflow
|
||||
|
||||
# Validate all schemas
|
||||
openspec schema validate
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec schema which`
|
||||
|
||||
Show where a schema resolves from (useful for debugging precedence).
|
||||
|
||||
```
|
||||
openspec schema which [name] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `name` | No | Schema name |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--all` | List all schemas with their sources |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
# Check where a schema comes from
|
||||
openspec schema which spec-driven
|
||||
```
|
||||
|
||||
**Output:**
|
||||
|
||||
```
|
||||
spec-driven resolves from: package
|
||||
Source: /usr/local/lib/node_modules/@fission-ai/openspec/schemas/spec-driven
|
||||
```
|
||||
|
||||
**Schema precedence:**
|
||||
|
||||
1. Project: `openspec/schemas/<name>/`
|
||||
2. User: `~/.local/share/openspec/schemas/<name>/`
|
||||
3. Package: Built-in schemas
|
||||
|
||||
---
|
||||
|
||||
## Configuration Commands
|
||||
|
||||
### `openspec config`
|
||||
|
||||
View and modify global OpenSpec configuration.
|
||||
|
||||
```
|
||||
openspec config <subcommand> [options]
|
||||
```
|
||||
|
||||
**Subcommands:**
|
||||
|
||||
| Subcommand | Description |
|
||||
|------------|-------------|
|
||||
| `path` | Show config file location |
|
||||
| `list` | Show all current settings |
|
||||
| `get <key>` | Get a specific value |
|
||||
| `set <key> <value>` | Set a value |
|
||||
| `unset <key>` | Remove a key |
|
||||
| `reset` | Reset to defaults |
|
||||
| `edit` | Open in `$EDITOR` |
|
||||
| `profile [preset]` | Configure workflow profile interactively or via preset |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Show config file path
|
||||
openspec config path
|
||||
|
||||
# List all settings
|
||||
openspec config list
|
||||
|
||||
# Get a specific value
|
||||
openspec config get telemetry.enabled
|
||||
|
||||
# Set a value
|
||||
openspec config set telemetry.enabled false
|
||||
|
||||
# Set a string value explicitly
|
||||
openspec config set user.name "My Name" --string
|
||||
|
||||
# Remove a custom setting
|
||||
openspec config unset user.name
|
||||
|
||||
# Reset all configuration
|
||||
openspec config reset --all --yes
|
||||
|
||||
# Edit config in your editor
|
||||
openspec config edit
|
||||
|
||||
# Configure profile with action-based wizard
|
||||
openspec config profile
|
||||
|
||||
# Fast preset: switch workflows to core (keeps delivery mode)
|
||||
openspec config profile core
|
||||
```
|
||||
|
||||
`openspec config profile` starts with a current-state summary, then lets you choose:
|
||||
- Change delivery + workflows
|
||||
- Change delivery only
|
||||
- Change workflows only
|
||||
- Keep current settings (exit)
|
||||
|
||||
If you keep current settings, no changes are written and no update prompt is shown.
|
||||
If there are no config changes but the current project files are out of sync with your global profile/delivery, OpenSpec will show a warning and suggest running `openspec update`.
|
||||
Pressing `Ctrl+C` also cancels the flow cleanly (no stack trace) and exits with code `130`.
|
||||
In the workflow checklist, `[x]` means the workflow is selected in global config. To apply those selections to project files, run `openspec update` (or choose `Apply changes to this project now?` when prompted inside a project).
|
||||
|
||||
**Interactive examples:**
|
||||
|
||||
```bash
|
||||
# Delivery-only update
|
||||
openspec config profile
|
||||
# choose: Change delivery only
|
||||
# choose delivery: Skills only
|
||||
|
||||
# Workflows-only update
|
||||
openspec config profile
|
||||
# choose: Change workflows only
|
||||
# toggle workflows in the checklist, then confirm
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Utility Commands
|
||||
|
||||
### `openspec feedback`
|
||||
|
||||
Submit feedback about OpenSpec. Creates a GitHub issue.
|
||||
|
||||
```
|
||||
openspec feedback <message> [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `message` | Yes | Feedback message |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--body <text>` | Detailed description |
|
||||
|
||||
**Requirements:** GitHub CLI (`gh`) must be installed and authenticated.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
openspec feedback "Add support for custom artifact types" \
|
||||
--body "I'd like to define my own artifact types beyond the built-in ones."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec completion`
|
||||
|
||||
Manage shell completions for the OpenSpec CLI.
|
||||
|
||||
```
|
||||
openspec completion <subcommand> [shell]
|
||||
```
|
||||
|
||||
**Subcommands:**
|
||||
|
||||
| Subcommand | Description |
|
||||
|------------|-------------|
|
||||
| `generate [shell]` | Output completion script to stdout |
|
||||
| `install [shell]` | Install completion for your shell |
|
||||
| `uninstall [shell]` | Remove installed completions |
|
||||
|
||||
**Supported shells:** `bash`, `zsh`, `fish`, `powershell`
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Install completions (auto-detects shell)
|
||||
openspec completion install
|
||||
|
||||
# Install for specific shell
|
||||
openspec completion install zsh
|
||||
|
||||
# Generate script for manual installation
|
||||
openspec completion generate bash > ~/.bash_completion.d/openspec
|
||||
|
||||
# Uninstall
|
||||
openspec completion uninstall
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Exit Codes
|
||||
|
||||
| Code | Meaning |
|
||||
|------|---------|
|
||||
| `0` | Success |
|
||||
| `1` | Error (validation failure, missing files, etc.) |
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `OPENSPEC_TELEMETRY` | Set to `0` to disable telemetry |
|
||||
| `DO_NOT_TRACK` | Set to `1` to disable telemetry (standard DNT signal) |
|
||||
| `OPENSPEC_CONCURRENCY` | Default concurrency for bulk validation (default: 6) |
|
||||
| `EDITOR` or `VISUAL` | Editor for `openspec config edit` |
|
||||
| `NO_COLOR` | Disable color output when set |
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Commands](commands.md) - AI slash commands (`/opsx:propose`, `/opsx:apply`, etc.)
|
||||
- [Workflows](workflows.md) - Common patterns and when to use each command
|
||||
- [Workspace Mode](workspace.md) - When to use cross-repo workspaces and the supported CLI flow
|
||||
- [Customization](customization.md) - Create custom schemas and templates
|
||||
- [Getting Started](getting-started.md) - First-time setup guide
|
||||
@@ -0,0 +1,704 @@
|
||||
# Commands
|
||||
|
||||
This is the reference for OpenSpec's slash commands. These commands are invoked in your AI coding assistant's chat interface (e.g., Claude Code, Cursor, Windsurf).
|
||||
|
||||
For workflow patterns and when to use each command, see [Workflows](workflows.md). For CLI commands, see [CLI](cli.md).
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Default Quick Path (`core` profile)
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/opsx:propose` | Create a change and generate planning artifacts in one step |
|
||||
| `/opsx:explore` | Think through ideas before committing to a change |
|
||||
| `/opsx:apply` | Implement tasks from the change |
|
||||
| `/opsx:archive` | Archive a completed change |
|
||||
|
||||
### Expanded Workflow Commands (custom workflow selection)
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/opsx:new` | Start a new change scaffold |
|
||||
| `/opsx:continue` | Create the next artifact based on dependencies |
|
||||
| `/opsx:ff` | Fast-forward: create all planning artifacts at once |
|
||||
| `/opsx:verify` | Validate implementation matches artifacts |
|
||||
| `/opsx:sync` | Merge delta specs into main specs |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes at once |
|
||||
| `/opsx:onboard` | Guided tutorial through the complete workflow |
|
||||
|
||||
The default global profile is `core`. To enable expanded workflow commands, run `openspec config profile`, select workflows, then run `openspec update` in your project.
|
||||
|
||||
---
|
||||
|
||||
## Command Reference
|
||||
|
||||
### `/opsx:propose`
|
||||
|
||||
Create a new change and generate planning artifacts in one step. This is the default start command in the `core` profile.
|
||||
|
||||
**Syntax:**
|
||||
```text
|
||||
/opsx:propose [change-name-or-description]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name-or-description` | No | Kebab-case name or plain-language change description |
|
||||
|
||||
**What it does:**
|
||||
- Creates `openspec/changes/<change-name>/`
|
||||
- Generates artifacts needed before implementation (for `spec-driven`: proposal, specs, design, tasks)
|
||||
- Stops when the change is ready for `/opsx:apply`
|
||||
|
||||
**Example:**
|
||||
```text
|
||||
You: /opsx:propose add-dark-mode
|
||||
|
||||
AI: Created openspec/changes/add-dark-mode/
|
||||
✓ proposal.md
|
||||
✓ specs/ui/spec.md
|
||||
✓ design.md
|
||||
✓ tasks.md
|
||||
Ready for implementation. Run /opsx:apply.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Use this for the fastest end-to-end path
|
||||
- If you want step-by-step artifact control, enable expanded workflows and use `/opsx:new` + `/opsx:continue`
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:explore`
|
||||
|
||||
Think through ideas, investigate problems, and clarify requirements before committing to a change.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:explore [topic]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `topic` | No | What you want to explore or investigate |
|
||||
|
||||
**What it does:**
|
||||
- Opens an exploratory conversation with no structure required
|
||||
- Investigates the codebase to answer questions
|
||||
- Compares options and approaches
|
||||
- Creates visual diagrams to clarify thinking
|
||||
- Can transition to `/opsx:propose` (default) or `/opsx:new` (expanded workflow) when insights crystallize
|
||||
|
||||
**Example:**
|
||||
```text
|
||||
You: /opsx:explore
|
||||
|
||||
AI: What would you like to explore?
|
||||
|
||||
You: How should we handle authentication for the mobile app?
|
||||
|
||||
AI: Let me investigate your current auth setup...
|
||||
[Analyzes codebase]
|
||||
|
||||
I see you're using session-based auth for the web app.
|
||||
For mobile, we have three main options:
|
||||
|
||||
1. JWT tokens (stateless, works offline)
|
||||
2. OAuth2 (if you need third-party login)
|
||||
3. Extend current sessions (simpler, but requires connectivity)
|
||||
|
||||
Your API already has CORS configured. Which direction interests you?
|
||||
|
||||
You: Let's go with JWT. Can we start a change for that?
|
||||
|
||||
AI: Ready when you are. Run /opsx:propose add-jwt-auth to begin.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Use when requirements are unclear or you need to investigate
|
||||
- No artifacts are created during exploration
|
||||
- Good for comparing multiple approaches before deciding
|
||||
- Can read files and search the codebase
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:new`
|
||||
|
||||
Start a new change scaffold. Creates the change folder and waits for you to generate artifacts with `/opsx:continue` or `/opsx:ff`.
|
||||
|
||||
This command is part of the expanded workflow set (not included in the default `core` profile).
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:new [change-name] [--schema <schema-name>]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Name for the change folder (prompted if not provided) |
|
||||
| `--schema` | No | Workflow schema to use (default: from config or `spec-driven`) |
|
||||
|
||||
**What it does:**
|
||||
- Creates `openspec/changes/<change-name>/` directory
|
||||
- Creates `.openspec.yaml` metadata file in the change folder
|
||||
- Shows the first artifact template ready for creation
|
||||
- Prompts for change name and schema if not provided
|
||||
|
||||
**What it creates:**
|
||||
```
|
||||
openspec/changes/<change-name>/
|
||||
└── .openspec.yaml # Change metadata (schema, created date)
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:new add-dark-mode
|
||||
|
||||
AI: Created openspec/changes/add-dark-mode/
|
||||
Schema: spec-driven
|
||||
|
||||
Ready to create: proposal
|
||||
Use /opsx:continue to create it, or /opsx:ff to create all artifacts.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Use descriptive names: `add-feature`, `fix-bug`, `refactor-module`
|
||||
- Avoid generic names like `update`, `changes`, `wip`
|
||||
- Schema can also be set in project config (`openspec/config.yaml`)
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:continue`
|
||||
|
||||
Create the next artifact in the dependency chain. Creates one artifact at a time for incremental progress.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:continue [change-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Which change to continue (inferred from context if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Queries the artifact dependency graph
|
||||
- Shows which artifacts are ready vs blocked
|
||||
- Creates the first ready artifact
|
||||
- Reads dependency files for context
|
||||
- Shows what becomes available after creation
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:continue
|
||||
|
||||
AI: Change: add-dark-mode
|
||||
|
||||
Artifact status:
|
||||
✓ proposal (done)
|
||||
◆ specs (ready)
|
||||
◆ design (ready)
|
||||
○ tasks (blocked - needs: specs)
|
||||
|
||||
Creating specs...
|
||||
|
||||
[Reads proposal.md, creates specs based on requirements]
|
||||
|
||||
✓ Created openspec/changes/add-dark-mode/specs/ui/spec.md
|
||||
|
||||
Now available: tasks
|
||||
Run /opsx:continue to create the next artifact.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Use when you want to review each artifact before proceeding
|
||||
- Good for complex changes where you want control
|
||||
- Multiple artifacts may become ready simultaneously
|
||||
- You can edit created artifacts before continuing
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:ff`
|
||||
|
||||
Fast-forward through artifact creation. Creates all planning artifacts at once.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:ff [change-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Which change to fast-forward (inferred from context if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Creates all artifacts in dependency order
|
||||
- Tracks progress via todo list
|
||||
- Stops when all `apply-required` artifacts are complete
|
||||
- Reads each dependency before creating the next artifact
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:ff add-dark-mode
|
||||
|
||||
AI: Fast-forwarding add-dark-mode...
|
||||
|
||||
✓ Creating proposal.md
|
||||
✓ Creating specs/ui/spec.md
|
||||
✓ Creating design.md
|
||||
✓ Creating tasks.md
|
||||
|
||||
All planning artifacts complete!
|
||||
Ready for implementation. Run /opsx:apply to begin.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Use when you have a clear picture of what you're building
|
||||
- Faster than `/opsx:continue` for straightforward changes
|
||||
- You can still edit artifacts afterward
|
||||
- Good for small to medium features
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:apply`
|
||||
|
||||
Implement tasks from the change. Works through the task list, writing code and checking off items.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:apply [change-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Which change to implement (inferred from context if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Reads `tasks.md` and identifies incomplete tasks
|
||||
- Works through tasks one by one
|
||||
- Writes code, creates files, runs tests as needed
|
||||
- Marks tasks complete with checkboxes `[x]`
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:apply
|
||||
|
||||
AI: Implementing add-dark-mode...
|
||||
|
||||
Reading tasks.md:
|
||||
- [ ] 1.1 Create ThemeContext
|
||||
- [ ] 1.2 Add CSS custom properties
|
||||
- [ ] 1.3 Implement localStorage persistence
|
||||
|
||||
Working on 1.1: Create ThemeContext...
|
||||
[Creates src/context/ThemeContext.tsx]
|
||||
|
||||
✓ 1.1 Complete
|
||||
|
||||
Working on 1.2: Add CSS custom properties...
|
||||
[Updates src/styles/globals.css]
|
||||
|
||||
✓ 1.2 Complete
|
||||
...
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Can resume where you left off if interrupted
|
||||
- Use for parallel changes by specifying the change name
|
||||
- Completion state is tracked in `tasks.md` checkboxes
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:verify`
|
||||
|
||||
Validate that implementation matches your change artifacts. Checks completeness, correctness, and coherence.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:verify [change-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Which change to verify (inferred from context if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Checks three dimensions of implementation quality
|
||||
- Searches codebase for implementation evidence
|
||||
- Reports issues categorized as CRITICAL, WARNING, or SUGGESTION
|
||||
- Does not block archive, but surfaces issues
|
||||
|
||||
**Verification dimensions:**
|
||||
|
||||
| Dimension | What it validates |
|
||||
|-----------|-------------------|
|
||||
| **Completeness** | All tasks done, all requirements implemented, scenarios covered |
|
||||
| **Correctness** | Implementation matches spec intent, edge cases handled |
|
||||
| **Coherence** | Design decisions reflected in code, patterns consistent |
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:verify
|
||||
|
||||
AI: Verifying add-dark-mode...
|
||||
|
||||
COMPLETENESS
|
||||
✓ All 8 tasks in tasks.md are checked
|
||||
✓ All requirements in specs have corresponding code
|
||||
⚠ Scenario "System preference detection" has no test coverage
|
||||
|
||||
CORRECTNESS
|
||||
✓ Implementation matches spec intent
|
||||
✓ Edge cases from scenarios are handled
|
||||
✓ Error states match spec definitions
|
||||
|
||||
COHERENCE
|
||||
✓ Design decisions reflected in code structure
|
||||
✓ Naming conventions consistent with design.md
|
||||
⚠ Design mentions "CSS variables" but implementation uses Tailwind classes
|
||||
|
||||
SUMMARY
|
||||
─────────────────────────────
|
||||
Critical issues: 0
|
||||
Warnings: 2
|
||||
Ready to archive: Yes (with warnings)
|
||||
|
||||
Recommendations:
|
||||
1. Add test for system preference detection
|
||||
2. Update design.md to reflect Tailwind usage, or refactor to use CSS variables
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Run before archiving to catch mismatches early
|
||||
- Warnings don't block archive but indicate potential issues
|
||||
- Good for reviewing AI's work before committing
|
||||
- Can reveal drift between artifacts and implementation
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:sync`
|
||||
|
||||
**Optional command.** Merge delta specs from a change into main specs. Archive will prompt to sync if needed, so you typically don't need to run this manually.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:sync [change-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Which change to sync (inferred from context if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Reads delta specs from change folder
|
||||
- Parses ADDED/MODIFIED/REMOVED/RENAMED sections
|
||||
- Merges changes into main `openspec/specs/` directory
|
||||
- Preserves existing content not mentioned in delta
|
||||
- Does not archive the change (remains active)
|
||||
|
||||
**Example:**
|
||||
```text
|
||||
You: /opsx:sync
|
||||
|
||||
AI: Syncing add-dark-mode delta specs...
|
||||
|
||||
Reading: openspec/changes/add-dark-mode/specs/ui/spec.md
|
||||
Target: openspec/specs/ui/spec.md
|
||||
|
||||
Changes to apply:
|
||||
✓ ADDED: Theme Selection requirement (2 scenarios)
|
||||
✓ ADDED: Accessibility requirement (1 scenario)
|
||||
|
||||
Merging...
|
||||
✓ openspec/specs/ui/spec.md updated
|
||||
|
||||
Change remains active. Run /opsx:archive when ready to complete.
|
||||
```
|
||||
|
||||
**When to use manually:**
|
||||
|
||||
| Scenario | Use sync? |
|
||||
|----------|-----------|
|
||||
| Long-running change, want specs in main before archiving | Yes |
|
||||
| Multiple parallel changes need the updated base specs | Yes |
|
||||
| Want to preview/review the merge separately | Yes |
|
||||
| Quick change, going straight to archive | No (archive handles it) |
|
||||
|
||||
**Tips:**
|
||||
- Sync is intelligent, not copy-paste
|
||||
- Can add scenarios to existing requirements without duplicating
|
||||
- Change stays active after sync (not archived)
|
||||
- Most users will never need to call this directly—archive prompts if needed
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:archive`
|
||||
|
||||
Archive a completed change. Finalizes the change and moves it to the archive folder.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:archive [change-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Which change to archive (inferred from context if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Checks artifact completion status
|
||||
- Checks task completion (warns if incomplete)
|
||||
- Offers to sync delta specs if not already synced
|
||||
- Moves change folder to `openspec/changes/archive/YYYY-MM-DD-<name>/`
|
||||
- Preserves all artifacts for audit trail
|
||||
|
||||
**Example:**
|
||||
```text
|
||||
You: /opsx:archive
|
||||
|
||||
AI: Archiving add-dark-mode...
|
||||
|
||||
Artifact status:
|
||||
✓ proposal.md exists
|
||||
✓ specs/ exists
|
||||
✓ design.md exists
|
||||
✓ tasks.md exists (8/8 tasks complete)
|
||||
|
||||
Delta specs: Not yet synced
|
||||
→ Sync now? (recommended)
|
||||
|
||||
You: Yes
|
||||
|
||||
AI: ✓ Synced specs to openspec/specs/ui/spec.md
|
||||
✓ Moved to openspec/changes/archive/2025-01-24-add-dark-mode/
|
||||
|
||||
Change archived successfully.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Archive won't block on incomplete tasks, but will warn
|
||||
- Delta specs can be synced during archive or beforehand
|
||||
- Archived changes are preserved for history
|
||||
- Use `/opsx:verify` first to catch issues
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:bulk-archive`
|
||||
|
||||
Archive multiple completed changes at once. Handles spec conflicts between changes.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:bulk-archive [change-names...]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-names` | No | Specific changes to archive (prompts to select if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Lists all completed changes
|
||||
- Validates each change before archiving
|
||||
- Detects spec conflicts across changes
|
||||
- Resolves conflicts by checking what's actually implemented
|
||||
- Archives in chronological order
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:bulk-archive
|
||||
|
||||
AI: Found 3 completed changes:
|
||||
- add-dark-mode (8/8 tasks complete)
|
||||
- fix-login-bug (3/3 tasks complete)
|
||||
- update-footer (2/2 tasks complete)
|
||||
|
||||
Checking for spec conflicts...
|
||||
⚠ add-dark-mode and update-footer both touch specs/ui/
|
||||
|
||||
Inspecting codebase to resolve...
|
||||
Both changes are implemented. Will merge in chronological order:
|
||||
1. add-dark-mode (created Jan 20)
|
||||
2. update-footer (created Jan 22)
|
||||
|
||||
Archive all 3 changes?
|
||||
|
||||
You: Yes
|
||||
|
||||
AI: ✓ Archived add-dark-mode
|
||||
✓ Archived fix-login-bug
|
||||
✓ Archived update-footer
|
||||
Specs merged: add-dark-mode → update-footer
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Good for parallel work streams
|
||||
- Conflict resolution is agentic (checks codebase)
|
||||
- Changes are archived in order of creation
|
||||
- Prompts before overwriting spec content
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:onboard`
|
||||
|
||||
Guided onboarding through the complete OpenSpec workflow. An interactive tutorial using your actual codebase.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:onboard
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
- Walks through a complete workflow cycle with narration
|
||||
- Scans your codebase for real improvement opportunities
|
||||
- Creates an actual change with real artifacts
|
||||
- Implements actual work (small, safe changes)
|
||||
- Archives the completed change
|
||||
- Explains each step as it happens
|
||||
|
||||
**Phases:**
|
||||
1. Welcome and codebase analysis
|
||||
2. Finding an improvement opportunity
|
||||
3. Creating a change (`/opsx:new`)
|
||||
4. Writing the proposal
|
||||
5. Creating specs
|
||||
6. Writing the design
|
||||
7. Creating tasks
|
||||
8. Implementing tasks (`/opsx:apply`)
|
||||
9. Verifying implementation
|
||||
10. Archiving the change
|
||||
11. Summary and next steps
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:onboard
|
||||
|
||||
AI: Welcome to OpenSpec!
|
||||
|
||||
I'll walk you through the complete workflow using your actual codebase.
|
||||
We'll find something small to improve, create a proper change for it,
|
||||
implement it, and archive it.
|
||||
|
||||
Let me scan your codebase for opportunities...
|
||||
|
||||
[Analyzes codebase]
|
||||
|
||||
I found a few things we could work on:
|
||||
1. Add input validation to the contact form
|
||||
2. Improve error messages in the auth flow
|
||||
3. Add loading states to async buttons
|
||||
|
||||
Which interests you? (or suggest something else)
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Best for new users learning the workflow
|
||||
- Uses real code, not toy examples
|
||||
- Creates a real change you can keep or discard
|
||||
- Takes 15-30 minutes to complete
|
||||
|
||||
---
|
||||
|
||||
## Command Syntax by AI Tool
|
||||
|
||||
Different AI tools use slightly different command syntax. Use the format that matches your tool:
|
||||
|
||||
| Tool | Syntax Example |
|
||||
|------|----------------|
|
||||
| Claude Code | `/opsx:propose`, `/opsx:apply` |
|
||||
| Cursor | `/opsx-propose`, `/opsx-apply` |
|
||||
| Windsurf | `/opsx-propose`, `/opsx-apply` |
|
||||
| Copilot (IDE) | `/opsx-propose`, `/opsx-apply` |
|
||||
| Trae | Skill-based invocations such as `/openspec-propose`, `/openspec-apply-change` (no generated `opsx-*` command files) |
|
||||
|
||||
The intent is the same across tools, but how commands are surfaced can differ by integration.
|
||||
|
||||
> **Note:** GitHub Copilot commands (`.github/prompts/*.prompt.md`) are only available in IDE extensions (VS Code, JetBrains, Visual Studio). GitHub Copilot CLI does not currently support custom prompt files — see [Supported Tools](supported-tools.md) for details and workarounds.
|
||||
|
||||
---
|
||||
|
||||
## Legacy Commands
|
||||
|
||||
These commands use the older "all-at-once" workflow. They still work but OPSX commands are recommended.
|
||||
|
||||
| Command | What it does |
|
||||
|---------|--------------|
|
||||
| `/openspec:proposal` | Create all artifacts at once (proposal, specs, design, tasks) |
|
||||
| `/openspec:apply` | Implement the change |
|
||||
| `/openspec:archive` | Archive the change |
|
||||
|
||||
**When to use legacy commands:**
|
||||
- Existing projects using the old workflow
|
||||
- Simple changes where you don't need incremental artifact creation
|
||||
- Preference for the all-or-nothing approach
|
||||
|
||||
**Migrating to OPSX:**
|
||||
Legacy changes can be continued with OPSX commands. The artifact structure is compatible.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Change not found"
|
||||
|
||||
The command couldn't identify which change to work on.
|
||||
|
||||
**Solutions:**
|
||||
- Specify the change name explicitly: `/opsx:apply add-dark-mode`
|
||||
- Check that the change folder exists: `openspec list`
|
||||
- Verify you're in the right project directory
|
||||
|
||||
### "No artifacts ready"
|
||||
|
||||
All artifacts are either complete or blocked by missing dependencies.
|
||||
|
||||
**Solutions:**
|
||||
- Run `openspec status --change <name>` to see what's blocking
|
||||
- Check if required artifacts exist
|
||||
- Create missing dependency artifacts first
|
||||
|
||||
### "Schema not found"
|
||||
|
||||
The specified schema doesn't exist.
|
||||
|
||||
**Solutions:**
|
||||
- List available schemas: `openspec schemas`
|
||||
- Check spelling of schema name
|
||||
- Create the schema if it's custom: `openspec schema init <name>`
|
||||
|
||||
### Commands not recognized
|
||||
|
||||
The AI tool doesn't recognize OpenSpec commands.
|
||||
|
||||
**Solutions:**
|
||||
- Ensure OpenSpec is initialized: `openspec init`
|
||||
- Regenerate skills: `openspec update`
|
||||
- Check that `.claude/skills/` directory exists (for Claude Code)
|
||||
- Restart your AI tool to pick up new skills
|
||||
|
||||
### Artifacts not generating properly
|
||||
|
||||
The AI creates incomplete or incorrect artifacts.
|
||||
|
||||
**Solutions:**
|
||||
- Add project context in `openspec/config.yaml`
|
||||
- Add per-artifact rules for specific guidance
|
||||
- Provide more detail in your change description
|
||||
- Use `/opsx:continue` instead of `/opsx:ff` for more control
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Workflows](workflows.md) - Common patterns and when to use each command
|
||||
- [CLI](cli.md) - Terminal commands for management and validation
|
||||
- [Customization](customization.md) - Create custom schemas and workflows
|
||||
@@ -0,0 +1,628 @@
|
||||
# Concepts
|
||||
|
||||
This guide explains the core ideas behind OpenSpec and how they fit together. For practical usage, see [Getting Started](getting-started.md) and [Workflows](workflows.md).
|
||||
|
||||
## Philosophy
|
||||
|
||||
OpenSpec is built around four principles:
|
||||
|
||||
```
|
||||
fluid not rigid — no phase gates, work on what makes sense
|
||||
iterative not waterfall — learn as you build, refine as you go
|
||||
easy not complex — lightweight setup, minimal ceremony
|
||||
brownfield-first — works with existing codebases, not just greenfield
|
||||
```
|
||||
|
||||
### Why These Principles Matter
|
||||
|
||||
**Fluid not rigid.** Traditional spec systems lock you into phases: first you plan, then you implement, then you're done. OpenSpec is more flexible — you can create artifacts in any order that makes sense for your work.
|
||||
|
||||
**Iterative not waterfall.** Requirements change. Understanding deepens. What seemed like a good approach at the start might not hold up after you see the codebase. OpenSpec embraces this reality.
|
||||
|
||||
**Easy not complex.** Some spec frameworks require extensive setup, rigid formats, or heavyweight processes. OpenSpec stays out of your way. Initialize in seconds, start working immediately, customize only if you need to.
|
||||
|
||||
**Brownfield-first.** Most software work isn't building from scratch — it's modifying existing systems. OpenSpec's delta-based approach makes it easy to specify changes to existing behavior, not just describe new systems.
|
||||
|
||||
## The Big Picture
|
||||
|
||||
OpenSpec organizes your work into two main areas:
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────────┐
|
||||
│ openspec/ │
|
||||
│ │
|
||||
│ ┌─────────────────────┐ ┌───────────────────────────────┐ │
|
||||
│ │ specs/ │ │ changes/ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ Source of truth │◄─────│ Proposed modifications │ │
|
||||
│ │ How your system │ merge│ Each change = one folder │ │
|
||||
│ │ currently works │ │ Contains artifacts + deltas │ │
|
||||
│ │ │ │ │ │
|
||||
│ └─────────────────────┘ └───────────────────────────────┘ │
|
||||
│ │
|
||||
└────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Specs** are the source of truth — they describe how your system currently behaves.
|
||||
|
||||
**Changes** are proposed modifications — they live in separate folders until you're ready to merge them.
|
||||
|
||||
This separation is key. You can work on multiple changes in parallel without conflicts. You can review a change before it affects the main specs. And when you archive a change, its deltas merge cleanly into the source of truth.
|
||||
|
||||
## Specs
|
||||
|
||||
Specs describe your system's behavior using structured requirements and scenarios.
|
||||
|
||||
### Structure
|
||||
|
||||
```
|
||||
openspec/specs/
|
||||
├── auth/
|
||||
│ └── spec.md # Authentication behavior
|
||||
├── payments/
|
||||
│ └── spec.md # Payment processing
|
||||
├── notifications/
|
||||
│ └── spec.md # Notification system
|
||||
└── ui/
|
||||
└── spec.md # UI behavior and themes
|
||||
```
|
||||
|
||||
Organize specs by domain — logical groupings that make sense for your system. Common patterns:
|
||||
|
||||
- **By feature area**: `auth/`, `payments/`, `search/`
|
||||
- **By component**: `api/`, `frontend/`, `workers/`
|
||||
- **By bounded context**: `ordering/`, `fulfillment/`, `inventory/`
|
||||
|
||||
### Spec Format
|
||||
|
||||
A spec contains requirements, and each requirement has scenarios:
|
||||
|
||||
```markdown
|
||||
# Auth Specification
|
||||
|
||||
## Purpose
|
||||
Authentication and session management for the application.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: User Authentication
|
||||
The system SHALL issue a JWT token upon successful login.
|
||||
|
||||
#### Scenario: Valid credentials
|
||||
- GIVEN a user with valid credentials
|
||||
- WHEN the user submits login form
|
||||
- THEN a JWT token is returned
|
||||
- AND the user is redirected to dashboard
|
||||
|
||||
#### Scenario: Invalid credentials
|
||||
- GIVEN invalid credentials
|
||||
- WHEN the user submits login form
|
||||
- THEN an error message is displayed
|
||||
- AND no token is issued
|
||||
|
||||
### Requirement: Session Expiration
|
||||
The system MUST expire sessions after 30 minutes of inactivity.
|
||||
|
||||
#### Scenario: Idle timeout
|
||||
- GIVEN an authenticated session
|
||||
- WHEN 30 minutes pass without activity
|
||||
- THEN the session is invalidated
|
||||
- AND the user must re-authenticate
|
||||
```
|
||||
|
||||
**Key elements:**
|
||||
|
||||
| Element | Purpose |
|
||||
|---------|---------|
|
||||
| `## Purpose` | High-level description of this spec's domain |
|
||||
| `### Requirement:` | A specific behavior the system must have |
|
||||
| `#### Scenario:` | A concrete example of the requirement in action |
|
||||
| SHALL/MUST/SHOULD | RFC 2119 keywords indicating requirement strength |
|
||||
|
||||
### Why Structure Specs This Way
|
||||
|
||||
**Requirements are the "what"** — they state what the system should do without specifying implementation.
|
||||
|
||||
**Scenarios are the "when"** — they provide concrete examples that can be verified. Good scenarios:
|
||||
- Are testable (you could write an automated test for them)
|
||||
- Cover both happy path and edge cases
|
||||
- Use Given/When/Then or similar structured format
|
||||
|
||||
**RFC 2119 keywords** (SHALL, MUST, SHOULD, MAY) communicate intent:
|
||||
- **MUST/SHALL** — absolute requirement
|
||||
- **SHOULD** — recommended, but exceptions exist
|
||||
- **MAY** — optional
|
||||
|
||||
### What a Spec Is (and Is Not)
|
||||
|
||||
A spec is a **behavior contract**, not an implementation plan.
|
||||
|
||||
Good spec content:
|
||||
- Observable behavior users or downstream systems rely on
|
||||
- Inputs, outputs, and error conditions
|
||||
- External constraints (security, privacy, reliability, compatibility)
|
||||
- Scenarios that can be tested or explicitly validated
|
||||
|
||||
Avoid in specs:
|
||||
- Internal class/function names
|
||||
- Library or framework choices
|
||||
- Step-by-step implementation details
|
||||
- Detailed execution plans (those belong in `design.md` or `tasks.md`)
|
||||
|
||||
Quick test:
|
||||
- If implementation can change without changing externally visible behavior, it likely does not belong in the spec.
|
||||
|
||||
### Keep It Lightweight: Progressive Rigor
|
||||
|
||||
OpenSpec aims to avoid bureaucracy. Use the lightest level that still makes the change verifiable.
|
||||
|
||||
**Lite spec (default):**
|
||||
- Short behavior-first requirements
|
||||
- Clear scope and non-goals
|
||||
- A few concrete acceptance checks
|
||||
|
||||
**Full spec (for higher risk):**
|
||||
- Cross-team or cross-repo changes
|
||||
- API/contract changes, migrations, security/privacy concerns
|
||||
- Changes where ambiguity is likely to cause expensive rework
|
||||
|
||||
Most changes should stay in Lite mode.
|
||||
|
||||
### Human + Agent Collaboration
|
||||
|
||||
In many teams, humans explore and agents draft artifacts. The intended loop is:
|
||||
|
||||
1. Human provides intent, context, and constraints.
|
||||
2. Agent converts this into behavior-first requirements and scenarios.
|
||||
3. Agent keeps implementation detail in `design.md` and `tasks.md`, not `spec.md`.
|
||||
4. Validation confirms structure and clarity before implementation.
|
||||
|
||||
This keeps specs readable for humans and consistent for agents.
|
||||
|
||||
## Changes
|
||||
|
||||
A change is a proposed modification to your system, packaged as a folder with everything needed to understand and implement it.
|
||||
|
||||
### Change Structure
|
||||
|
||||
```
|
||||
openspec/changes/add-dark-mode/
|
||||
├── proposal.md # Why and what
|
||||
├── design.md # How (technical approach)
|
||||
├── tasks.md # Implementation checklist
|
||||
├── .openspec.yaml # Change metadata (optional)
|
||||
└── specs/ # Delta specs
|
||||
└── ui/
|
||||
└── spec.md # What's changing in ui/spec.md
|
||||
```
|
||||
|
||||
Each change is self-contained. It has:
|
||||
- **Artifacts** — documents that capture intent, design, and tasks
|
||||
- **Delta specs** — specifications for what's being added, modified, or removed
|
||||
- **Metadata** — optional configuration for this specific change
|
||||
|
||||
### Why Changes Are Folders
|
||||
|
||||
Packaging a change as a folder has several benefits:
|
||||
|
||||
1. **Everything together.** Proposal, design, tasks, and specs live in one place. No hunting through different locations.
|
||||
|
||||
2. **Parallel work.** Multiple changes can exist simultaneously without conflicting. Work on `add-dark-mode` while `fix-auth-bug` is also in progress.
|
||||
|
||||
3. **Clean history.** When archived, changes move to `changes/archive/` with their full context preserved. You can look back and understand not just what changed, but why.
|
||||
|
||||
4. **Review-friendly.** A change folder is easy to review — open it, read the proposal, check the design, see the spec deltas.
|
||||
|
||||
## Artifacts
|
||||
|
||||
Artifacts are the documents within a change that guide the work.
|
||||
|
||||
### The Artifact Flow
|
||||
|
||||
```
|
||||
proposal ──────► specs ──────► design ──────► tasks ──────► implement
|
||||
│ │ │ │
|
||||
why what how steps
|
||||
+ scope changes approach to take
|
||||
```
|
||||
|
||||
Artifacts build on each other. Each artifact provides context for the next.
|
||||
|
||||
### Artifact Types
|
||||
|
||||
#### Proposal (`proposal.md`)
|
||||
|
||||
The proposal captures **intent**, **scope**, and **approach** at a high level.
|
||||
|
||||
```markdown
|
||||
# Proposal: Add Dark Mode
|
||||
|
||||
## Intent
|
||||
Users have requested a dark mode option to reduce eye strain
|
||||
during nighttime usage and match system preferences.
|
||||
|
||||
## Scope
|
||||
In scope:
|
||||
- Theme toggle in settings
|
||||
- System preference detection
|
||||
- Persist preference in localStorage
|
||||
|
||||
Out of scope:
|
||||
- Custom color themes (future work)
|
||||
- Per-page theme overrides
|
||||
|
||||
## Approach
|
||||
Use CSS custom properties for theming with a React context
|
||||
for state management. Detect system preference on first load,
|
||||
allow manual override.
|
||||
```
|
||||
|
||||
**When to update the proposal:**
|
||||
- Scope changes (narrowing or expanding)
|
||||
- Intent clarifies (better understanding of the problem)
|
||||
- Approach fundamentally shifts
|
||||
|
||||
#### Specs (delta specs in `specs/`)
|
||||
|
||||
Delta specs describe **what's changing** relative to the current specs. See [Delta Specs](#delta-specs) below.
|
||||
|
||||
#### Design (`design.md`)
|
||||
|
||||
The design captures **technical approach** and **architecture decisions**.
|
||||
|
||||
````markdown
|
||||
# Design: Add Dark Mode
|
||||
|
||||
## Technical Approach
|
||||
Theme state managed via React Context to avoid prop drilling.
|
||||
CSS custom properties enable runtime switching without class toggling.
|
||||
|
||||
## Architecture Decisions
|
||||
|
||||
### Decision: Context over Redux
|
||||
Using React Context for theme state because:
|
||||
- Simple binary state (light/dark)
|
||||
- No complex state transitions
|
||||
- Avoids adding Redux dependency
|
||||
|
||||
### Decision: CSS Custom Properties
|
||||
Using CSS variables instead of CSS-in-JS because:
|
||||
- Works with existing stylesheet
|
||||
- No runtime overhead
|
||||
- Browser-native solution
|
||||
|
||||
## Data Flow
|
||||
```
|
||||
ThemeProvider (context)
|
||||
│
|
||||
▼
|
||||
ThemeToggle ◄──► localStorage
|
||||
│
|
||||
▼
|
||||
CSS Variables (applied to :root)
|
||||
```
|
||||
|
||||
## File Changes
|
||||
- `src/contexts/ThemeContext.tsx` (new)
|
||||
- `src/components/ThemeToggle.tsx` (new)
|
||||
- `src/styles/globals.css` (modified)
|
||||
````
|
||||
|
||||
**When to update the design:**
|
||||
- Implementation reveals the approach won't work
|
||||
- Better solution discovered
|
||||
- Dependencies or constraints change
|
||||
|
||||
#### Tasks (`tasks.md`)
|
||||
|
||||
Tasks are the **implementation checklist** — concrete steps with checkboxes.
|
||||
|
||||
```markdown
|
||||
# Tasks
|
||||
|
||||
## 1. Theme Infrastructure
|
||||
- [ ] 1.1 Create ThemeContext with light/dark state
|
||||
- [ ] 1.2 Add CSS custom properties for colors
|
||||
- [ ] 1.3 Implement localStorage persistence
|
||||
- [ ] 1.4 Add system preference detection
|
||||
|
||||
## 2. UI Components
|
||||
- [ ] 2.1 Create ThemeToggle component
|
||||
- [ ] 2.2 Add toggle to settings page
|
||||
- [ ] 2.3 Update Header to include quick toggle
|
||||
|
||||
## 3. Styling
|
||||
- [ ] 3.1 Define dark theme color palette
|
||||
- [ ] 3.2 Update components to use CSS variables
|
||||
- [ ] 3.3 Test contrast ratios for accessibility
|
||||
```
|
||||
|
||||
**Task best practices:**
|
||||
- Group related tasks under headings
|
||||
- Use hierarchical numbering (1.1, 1.2, etc.)
|
||||
- Keep tasks small enough to complete in one session
|
||||
- Check tasks off as you complete them
|
||||
|
||||
## Delta Specs
|
||||
|
||||
Delta specs are the key concept that makes OpenSpec work for brownfield development. They describe **what's changing** rather than restating the entire spec.
|
||||
|
||||
### The Format
|
||||
|
||||
```markdown
|
||||
# Delta for Auth
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Two-Factor Authentication
|
||||
The system MUST support TOTP-based two-factor authentication.
|
||||
|
||||
#### Scenario: 2FA enrollment
|
||||
- GIVEN a user without 2FA enabled
|
||||
- WHEN the user enables 2FA in settings
|
||||
- THEN a QR code is displayed for authenticator app setup
|
||||
- AND the user must verify with a code before activation
|
||||
|
||||
#### Scenario: 2FA login
|
||||
- GIVEN a user with 2FA enabled
|
||||
- WHEN the user submits valid credentials
|
||||
- THEN an OTP challenge is presented
|
||||
- AND login completes only after valid OTP
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Session Expiration
|
||||
The system MUST expire sessions after 15 minutes of inactivity.
|
||||
(Previously: 30 minutes)
|
||||
|
||||
#### Scenario: Idle timeout
|
||||
- GIVEN an authenticated session
|
||||
- WHEN 15 minutes pass without activity
|
||||
- THEN the session is invalidated
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: Remember Me
|
||||
(Deprecated in favor of 2FA. Users should re-authenticate each session.)
|
||||
```
|
||||
|
||||
### Delta Sections
|
||||
|
||||
| Section | Meaning | What Happens on Archive |
|
||||
|---------|---------|------------------------|
|
||||
| `## ADDED Requirements` | New behavior | Appended to main spec |
|
||||
| `## MODIFIED Requirements` | Changed behavior | Replaces existing requirement |
|
||||
| `## REMOVED Requirements` | Deprecated behavior | Deleted from main spec |
|
||||
|
||||
### Why Deltas Instead of Full Specs
|
||||
|
||||
**Clarity.** A delta shows exactly what's changing. Reading a full spec, you'd have to diff it mentally against the current version.
|
||||
|
||||
**Conflict avoidance.** Two changes can touch the same spec file without conflicting, as long as they modify different requirements.
|
||||
|
||||
**Review efficiency.** Reviewers see the change, not the unchanged context. Focus on what matters.
|
||||
|
||||
**Brownfield fit.** Most work modifies existing behavior. Deltas make modifications first-class, not an afterthought.
|
||||
|
||||
## Schemas
|
||||
|
||||
Schemas define the artifact types and their dependencies for a workflow.
|
||||
|
||||
### How Schemas Work
|
||||
|
||||
```yaml
|
||||
# openspec/schemas/spec-driven/schema.yaml
|
||||
name: spec-driven
|
||||
artifacts:
|
||||
- id: proposal
|
||||
generates: proposal.md
|
||||
requires: [] # No dependencies, can create first
|
||||
|
||||
- id: specs
|
||||
generates: specs/**/*.md
|
||||
requires: [proposal] # Needs proposal before creating
|
||||
|
||||
- id: design
|
||||
generates: design.md
|
||||
requires: [proposal] # Can create in parallel with specs
|
||||
|
||||
- id: tasks
|
||||
generates: tasks.md
|
||||
requires: [specs, design] # Needs both specs and design first
|
||||
```
|
||||
|
||||
**Artifacts form a dependency graph:**
|
||||
|
||||
```
|
||||
proposal
|
||||
(root node)
|
||||
│
|
||||
┌─────────────┴─────────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
specs design
|
||||
(requires: (requires:
|
||||
proposal) proposal)
|
||||
│ │
|
||||
└─────────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
tasks
|
||||
(requires:
|
||||
specs, design)
|
||||
```
|
||||
|
||||
**Dependencies are enablers, not gates.** They show what's possible to create, not what you must create next. You can skip design if you don't need it. You can create specs before or after design — both depend only on proposal.
|
||||
|
||||
### Built-in Schemas
|
||||
|
||||
**spec-driven** (default)
|
||||
|
||||
The standard workflow for spec-driven development:
|
||||
|
||||
```
|
||||
proposal → specs → design → tasks → implement
|
||||
```
|
||||
|
||||
Best for: Most feature work where you want to agree on specs before implementation.
|
||||
|
||||
### Custom Schemas
|
||||
|
||||
Create custom schemas for your team's workflow:
|
||||
|
||||
```bash
|
||||
# Create from scratch
|
||||
openspec schema init research-first
|
||||
|
||||
# Or fork an existing one
|
||||
openspec schema fork spec-driven research-first
|
||||
```
|
||||
|
||||
**Example custom schema:**
|
||||
|
||||
```yaml
|
||||
# openspec/schemas/research-first/schema.yaml
|
||||
name: research-first
|
||||
artifacts:
|
||||
- id: research
|
||||
generates: research.md
|
||||
requires: [] # Do research first
|
||||
|
||||
- id: proposal
|
||||
generates: proposal.md
|
||||
requires: [research] # Proposal informed by research
|
||||
|
||||
- id: tasks
|
||||
generates: tasks.md
|
||||
requires: [proposal] # Skip specs/design, go straight to tasks
|
||||
```
|
||||
|
||||
See [Customization](customization.md) for full details on creating and using custom schemas.
|
||||
|
||||
## Archive
|
||||
|
||||
Archiving completes a change by merging its delta specs into the main specs and preserving the change for history.
|
||||
|
||||
### What Happens When You Archive
|
||||
|
||||
```
|
||||
Before archive:
|
||||
|
||||
openspec/
|
||||
├── specs/
|
||||
│ └── auth/
|
||||
│ └── spec.md ◄────────────────┐
|
||||
└── changes/ │
|
||||
└── add-2fa/ │
|
||||
├── proposal.md │
|
||||
├── design.md │ merge
|
||||
├── tasks.md │
|
||||
└── specs/ │
|
||||
└── auth/ │
|
||||
└── spec.md ─────────┘
|
||||
|
||||
|
||||
After archive:
|
||||
|
||||
openspec/
|
||||
├── specs/
|
||||
│ └── auth/
|
||||
│ └── spec.md # Now includes 2FA requirements
|
||||
└── changes/
|
||||
└── archive/
|
||||
└── 2025-01-24-add-2fa/ # Preserved for history
|
||||
├── proposal.md
|
||||
├── design.md
|
||||
├── tasks.md
|
||||
└── specs/
|
||||
└── auth/
|
||||
└── spec.md
|
||||
```
|
||||
|
||||
### The Archive Process
|
||||
|
||||
1. **Merge deltas.** Each delta spec section (ADDED/MODIFIED/REMOVED) is applied to the corresponding main spec.
|
||||
|
||||
2. **Move to archive.** The change folder moves to `changes/archive/` with a date prefix for chronological ordering.
|
||||
|
||||
3. **Preserve context.** All artifacts remain intact in the archive. You can always look back to understand why a change was made.
|
||||
|
||||
### Why Archive Matters
|
||||
|
||||
**Clean state.** Active changes (`changes/`) shows only work in progress. Completed work moves out of the way.
|
||||
|
||||
**Audit trail.** The archive preserves the full context of every change — not just what changed, but the proposal explaining why, the design explaining how, and the tasks showing the work done.
|
||||
|
||||
**Spec evolution.** Specs grow organically as changes are archived. Each archive merges its deltas, building up a comprehensive specification over time.
|
||||
|
||||
## How It All Fits Together
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────────────────┐
|
||||
│ OPENSPEC FLOW │
|
||||
│ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ 1. START │ /opsx:propose (core) or /opsx:new (expanded) │
|
||||
│ │ CHANGE │ │
|
||||
│ └───────┬────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ 2. CREATE │ /opsx:ff or /opsx:continue (expanded workflow) │
|
||||
│ │ ARTIFACTS │ Creates proposal → specs → design → tasks │
|
||||
│ │ │ (based on schema dependencies) │
|
||||
│ └───────┬────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ 3. IMPLEMENT │ /opsx:apply │
|
||||
│ │ TASKS │ Work through tasks, checking them off │
|
||||
│ │ │◄──── Update artifacts as you learn │
|
||||
│ └───────┬────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ 4. VERIFY │ /opsx:verify (optional) │
|
||||
│ │ WORK │ Check implementation matches specs │
|
||||
│ └───────┬────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ ┌──────────────────────────────────────────────┐ │
|
||||
│ │ 5. ARCHIVE │────►│ Delta specs merge into main specs │ │
|
||||
│ │ CHANGE │ │ Change folder moves to archive/ │ │
|
||||
│ └────────────────┘ │ Specs are now the updated source of truth │ │
|
||||
│ └──────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**The virtuous cycle:**
|
||||
|
||||
1. Specs describe current behavior
|
||||
2. Changes propose modifications (as deltas)
|
||||
3. Implementation makes the changes real
|
||||
4. Archive merges deltas into specs
|
||||
5. Specs now describe the new behavior
|
||||
6. Next change builds on updated specs
|
||||
|
||||
## Glossary
|
||||
|
||||
| Term | Definition |
|
||||
|------|------------|
|
||||
| **Artifact** | A document within a change (proposal, design, tasks, or delta specs) |
|
||||
| **Archive** | The process of completing a change and merging its deltas into main specs |
|
||||
| **Change** | A proposed modification to the system, packaged as a folder with artifacts |
|
||||
| **Delta spec** | A spec that describes changes (ADDED/MODIFIED/REMOVED) relative to current specs |
|
||||
| **Domain** | A logical grouping for specs (e.g., `auth/`, `payments/`) |
|
||||
| **Requirement** | A specific behavior the system must have |
|
||||
| **Scenario** | A concrete example of a requirement, typically in Given/When/Then format |
|
||||
| **Schema** | A definition of artifact types and their dependencies |
|
||||
| **Spec** | A specification describing system behavior, containing requirements and scenarios |
|
||||
| **Source of truth** | The `openspec/specs/` directory, containing the current agreed-upon behavior |
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Getting Started](getting-started.md) - Practical first steps
|
||||
- [Workflows](workflows.md) - Common patterns and when to use each
|
||||
- [Commands](commands.md) - Full command reference
|
||||
- [Customization](customization.md) - Create custom schemas and configure your project
|
||||
@@ -0,0 +1,342 @@
|
||||
# Customization
|
||||
|
||||
OpenSpec provides three levels of customization:
|
||||
|
||||
| Level | What it does | Best for |
|
||||
|-------|--------------|----------|
|
||||
| **Project Config** | Set defaults, inject context/rules | Most teams |
|
||||
| **Custom Schemas** | Define your own workflow artifacts | Teams with unique processes |
|
||||
| **Global Overrides** | Share schemas across all projects | Power users |
|
||||
|
||||
---
|
||||
|
||||
## Project Configuration
|
||||
|
||||
The `openspec/config.yaml` file is the easiest way to customize OpenSpec for your team. It lets you:
|
||||
|
||||
- **Set a default schema** - Skip `--schema` on every command
|
||||
- **Inject project context** - AI sees your tech stack, conventions, etc.
|
||||
- **Add per-artifact rules** - Custom rules for specific artifacts
|
||||
|
||||
### Quick Setup
|
||||
|
||||
```bash
|
||||
openspec init
|
||||
```
|
||||
|
||||
This walks you through creating a config interactively. Or create one manually:
|
||||
|
||||
```yaml
|
||||
# openspec/config.yaml
|
||||
schema: spec-driven
|
||||
|
||||
context: |
|
||||
Tech stack: TypeScript, React, Node.js, PostgreSQL
|
||||
API style: RESTful, documented in docs/api.md
|
||||
Testing: Jest + React Testing Library
|
||||
We value backwards compatibility for all public APIs
|
||||
|
||||
rules:
|
||||
proposal:
|
||||
- Include rollback plan
|
||||
- Identify affected teams
|
||||
specs:
|
||||
- Use Given/When/Then format
|
||||
- Reference existing patterns before inventing new ones
|
||||
```
|
||||
|
||||
### How It Works
|
||||
|
||||
**Default schema:**
|
||||
|
||||
```bash
|
||||
# Without config
|
||||
openspec new change my-feature --schema spec-driven
|
||||
|
||||
# With config - schema is automatic
|
||||
openspec new change my-feature
|
||||
```
|
||||
|
||||
**Context and rules injection:**
|
||||
|
||||
When generating any artifact, your context and rules are injected into the AI prompt:
|
||||
|
||||
```xml
|
||||
<context>
|
||||
Tech stack: TypeScript, React, Node.js, PostgreSQL
|
||||
...
|
||||
</context>
|
||||
|
||||
<rules>
|
||||
- Include rollback plan
|
||||
- Identify affected teams
|
||||
</rules>
|
||||
|
||||
<template>
|
||||
[Schema's built-in template]
|
||||
</template>
|
||||
```
|
||||
|
||||
- **Context** appears in ALL artifacts
|
||||
- **Rules** ONLY appear for the matching artifact
|
||||
|
||||
### Schema Resolution Order
|
||||
|
||||
When OpenSpec needs a schema, it checks in this order:
|
||||
|
||||
1. CLI flag: `--schema <name>`
|
||||
2. Change metadata (`.openspec.yaml` in the change folder)
|
||||
3. Project config (`openspec/config.yaml`)
|
||||
4. Default (`spec-driven`)
|
||||
|
||||
---
|
||||
|
||||
## Custom Schemas
|
||||
|
||||
When project config isn't enough, create your own schema with a completely custom workflow. Custom schemas live in your project's `openspec/schemas/` directory and are version-controlled with your code.
|
||||
|
||||
```text
|
||||
your-project/
|
||||
├── openspec/
|
||||
│ ├── config.yaml # Project config
|
||||
│ ├── schemas/ # Custom schemas live here
|
||||
│ │ └── my-workflow/
|
||||
│ │ ├── schema.yaml
|
||||
│ │ └── templates/
|
||||
│ └── changes/ # Your changes
|
||||
└── src/
|
||||
```
|
||||
|
||||
### Fork an Existing Schema
|
||||
|
||||
The fastest way to customize is to fork a built-in schema:
|
||||
|
||||
```bash
|
||||
openspec schema fork spec-driven my-workflow
|
||||
```
|
||||
|
||||
This copies the entire `spec-driven` schema to `openspec/schemas/my-workflow/` where you can edit it freely.
|
||||
|
||||
**What you get:**
|
||||
|
||||
```text
|
||||
openspec/schemas/my-workflow/
|
||||
├── schema.yaml # Workflow definition
|
||||
└── templates/
|
||||
├── proposal.md # Template for proposal artifact
|
||||
├── spec.md # Template for specs
|
||||
├── design.md # Template for design
|
||||
└── tasks.md # Template for tasks
|
||||
```
|
||||
|
||||
Now edit `schema.yaml` to change the workflow, or edit templates to change what AI generates.
|
||||
|
||||
### Create a Schema from Scratch
|
||||
|
||||
For a completely fresh workflow:
|
||||
|
||||
```bash
|
||||
# Interactive
|
||||
openspec schema init research-first
|
||||
|
||||
# Non-interactive
|
||||
openspec schema init rapid \
|
||||
--description "Rapid iteration workflow" \
|
||||
--artifacts "proposal,tasks" \
|
||||
--default
|
||||
```
|
||||
|
||||
### Schema Structure
|
||||
|
||||
A schema defines the artifacts in your workflow and how they depend on each other:
|
||||
|
||||
```yaml
|
||||
# openspec/schemas/my-workflow/schema.yaml
|
||||
name: my-workflow
|
||||
version: 1
|
||||
description: My team's custom workflow
|
||||
|
||||
artifacts:
|
||||
- id: proposal
|
||||
generates: proposal.md
|
||||
description: Initial proposal document
|
||||
template: proposal.md
|
||||
instruction: |
|
||||
Create a proposal that explains WHY this change is needed.
|
||||
Focus on the problem, not the solution.
|
||||
requires: []
|
||||
|
||||
- id: design
|
||||
generates: design.md
|
||||
description: Technical design
|
||||
template: design.md
|
||||
instruction: |
|
||||
Create a design document explaining HOW to implement.
|
||||
requires:
|
||||
- proposal # Can't create design until proposal exists
|
||||
|
||||
- id: tasks
|
||||
generates: tasks.md
|
||||
description: Implementation checklist
|
||||
template: tasks.md
|
||||
requires:
|
||||
- design
|
||||
|
||||
apply:
|
||||
requires: [tasks]
|
||||
tracks: tasks.md
|
||||
```
|
||||
|
||||
**Key fields:**
|
||||
|
||||
| Field | Purpose |
|
||||
|-------|---------|
|
||||
| `id` | Unique identifier, used in commands and rules |
|
||||
| `generates` | Output filename (supports globs like `specs/**/*.md`) |
|
||||
| `template` | Template file in `templates/` directory |
|
||||
| `instruction` | AI instructions for creating this artifact |
|
||||
| `requires` | Dependencies - which artifacts must exist first |
|
||||
|
||||
### Templates
|
||||
|
||||
Templates are markdown files that guide the AI. They're injected into the prompt when creating that artifact.
|
||||
|
||||
```markdown
|
||||
<!-- templates/proposal.md -->
|
||||
## Why
|
||||
|
||||
<!-- Explain the motivation for this change. What problem does this solve? -->
|
||||
|
||||
## What Changes
|
||||
|
||||
<!-- Describe what will change. Be specific about new capabilities or modifications. -->
|
||||
|
||||
## Impact
|
||||
|
||||
<!-- Affected code, APIs, dependencies, systems -->
|
||||
```
|
||||
|
||||
Templates can include:
|
||||
- Section headers the AI should fill in
|
||||
- HTML comments with guidance for the AI
|
||||
- Example formats showing expected structure
|
||||
|
||||
### Validate Your Schema
|
||||
|
||||
Before using a custom schema, validate it:
|
||||
|
||||
```bash
|
||||
openspec schema validate my-workflow
|
||||
```
|
||||
|
||||
This checks:
|
||||
- `schema.yaml` syntax is correct
|
||||
- All referenced templates exist
|
||||
- No circular dependencies
|
||||
- Artifact IDs are valid
|
||||
|
||||
### Use Your Custom Schema
|
||||
|
||||
Once created, use your schema with:
|
||||
|
||||
```bash
|
||||
# Specify on command
|
||||
openspec new change feature --schema my-workflow
|
||||
|
||||
# Or set as default in config.yaml
|
||||
schema: my-workflow
|
||||
```
|
||||
|
||||
### Debug Schema Resolution
|
||||
|
||||
Not sure which schema is being used? Check with:
|
||||
|
||||
```bash
|
||||
# See where a specific schema resolves from
|
||||
openspec schema which my-workflow
|
||||
|
||||
# List all available schemas
|
||||
openspec schema which --all
|
||||
```
|
||||
|
||||
Output shows whether it's from your project, user directory, or the package:
|
||||
|
||||
```text
|
||||
Schema: my-workflow
|
||||
Source: project
|
||||
Path: /path/to/project/openspec/schemas/my-workflow
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **Note:** OpenSpec also supports user-level schemas at `~/.local/share/openspec/schemas/` for sharing across projects, but project-level schemas in `openspec/schemas/` are recommended since they're version-controlled with your code.
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### Rapid Iteration Workflow
|
||||
|
||||
A minimal workflow for quick iterations:
|
||||
|
||||
```yaml
|
||||
# openspec/schemas/rapid/schema.yaml
|
||||
name: rapid
|
||||
version: 1
|
||||
description: Fast iteration with minimal overhead
|
||||
|
||||
artifacts:
|
||||
- id: proposal
|
||||
generates: proposal.md
|
||||
description: Quick proposal
|
||||
template: proposal.md
|
||||
instruction: |
|
||||
Create a brief proposal for this change.
|
||||
Focus on what and why, skip detailed specs.
|
||||
requires: []
|
||||
|
||||
- id: tasks
|
||||
generates: tasks.md
|
||||
description: Implementation checklist
|
||||
template: tasks.md
|
||||
requires: [proposal]
|
||||
|
||||
apply:
|
||||
requires: [tasks]
|
||||
tracks: tasks.md
|
||||
```
|
||||
|
||||
### Adding a Review Artifact
|
||||
|
||||
Fork the default and add a review step:
|
||||
|
||||
```bash
|
||||
openspec schema fork spec-driven with-review
|
||||
```
|
||||
|
||||
Then edit `schema.yaml` to add:
|
||||
|
||||
```yaml
|
||||
- id: review
|
||||
generates: review.md
|
||||
description: Pre-implementation review checklist
|
||||
template: review.md
|
||||
instruction: |
|
||||
Create a review checklist based on the design.
|
||||
Include security, performance, and testing considerations.
|
||||
requires:
|
||||
- design
|
||||
|
||||
- id: tasks
|
||||
# ... existing tasks config ...
|
||||
requires:
|
||||
- specs
|
||||
- design
|
||||
- review # Now tasks require review too
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [CLI Reference: Schema Commands](cli.md#schema-commands) - Full command documentation
|
||||
@@ -0,0 +1,253 @@
|
||||
# Getting Started
|
||||
|
||||
This guide explains how OpenSpec works after you've installed and initialized it. For installation instructions, see the [main README](../README.md#quick-start).
|
||||
|
||||
## How It Works
|
||||
|
||||
OpenSpec helps you and your AI coding assistant agree on what to build before any code is written.
|
||||
|
||||
**Default quick path (core profile):**
|
||||
|
||||
```text
|
||||
/opsx:propose ──► /opsx:apply ──► /opsx:archive
|
||||
```
|
||||
|
||||
**Expanded path (custom workflow selection):**
|
||||
|
||||
```text
|
||||
/opsx:new ──► /opsx:ff or /opsx:continue ──► /opsx:apply ──► /opsx:verify ──► /opsx:archive
|
||||
```
|
||||
|
||||
The default global profile is `core`, which includes `propose`, `explore`, `apply`, and `archive`. You can enable the expanded workflow commands with `openspec config profile` and then `openspec update`.
|
||||
|
||||
## What OpenSpec Creates
|
||||
|
||||
After running `openspec init`, your project has this structure:
|
||||
|
||||
```
|
||||
openspec/
|
||||
├── specs/ # Source of truth (your system's behavior)
|
||||
│ └── <domain>/
|
||||
│ └── spec.md
|
||||
├── changes/ # Proposed updates (one folder per change)
|
||||
│ └── <change-name>/
|
||||
│ ├── proposal.md
|
||||
│ ├── design.md
|
||||
│ ├── tasks.md
|
||||
│ └── specs/ # Delta specs (what's changing)
|
||||
│ └── <domain>/
|
||||
│ └── spec.md
|
||||
└── config.yaml # Project configuration (optional)
|
||||
```
|
||||
|
||||
**Two key directories:**
|
||||
|
||||
- **`specs/`** - The source of truth. These specs describe how your system currently behaves. Organized by domain (e.g., `specs/auth/`, `specs/payments/`).
|
||||
|
||||
- **`changes/`** - Proposed modifications. Each change gets its own folder with all related artifacts. When a change is complete, its specs merge into the main `specs/` directory.
|
||||
|
||||
## Understanding Artifacts
|
||||
|
||||
Each change folder contains artifacts that guide the work:
|
||||
|
||||
| Artifact | Purpose |
|
||||
|----------|---------|
|
||||
| `proposal.md` | The "why" and "what" - captures intent, scope, and approach |
|
||||
| `specs/` | Delta specs showing ADDED/MODIFIED/REMOVED requirements |
|
||||
| `design.md` | The "how" - technical approach and architecture decisions |
|
||||
| `tasks.md` | Implementation checklist with checkboxes |
|
||||
|
||||
**Artifacts build on each other:**
|
||||
|
||||
```
|
||||
proposal ──► specs ──► design ──► tasks ──► implement
|
||||
▲ ▲ ▲ │
|
||||
└───────────┴──────────┴────────────────────┘
|
||||
update as you learn
|
||||
```
|
||||
|
||||
You can always go back and refine earlier artifacts as you learn more during implementation.
|
||||
|
||||
## How Delta Specs Work
|
||||
|
||||
Delta specs are the key concept in OpenSpec. They show what's changing relative to your current specs.
|
||||
|
||||
### The Format
|
||||
|
||||
Delta specs use sections to indicate the type of change:
|
||||
|
||||
```markdown
|
||||
# Delta for Auth
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Two-Factor Authentication
|
||||
The system MUST require a second factor during login.
|
||||
|
||||
#### Scenario: OTP required
|
||||
- GIVEN a user with 2FA enabled
|
||||
- WHEN the user submits valid credentials
|
||||
- THEN an OTP challenge is presented
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Session Timeout
|
||||
The system SHALL expire sessions after 30 minutes of inactivity.
|
||||
(Previously: 60 minutes)
|
||||
|
||||
#### Scenario: Idle timeout
|
||||
- GIVEN an authenticated session
|
||||
- WHEN 30 minutes pass without activity
|
||||
- THEN the session is invalidated
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: Remember Me
|
||||
(Deprecated in favor of 2FA)
|
||||
```
|
||||
|
||||
### What Happens on Archive
|
||||
|
||||
When you archive a change:
|
||||
|
||||
1. **ADDED** requirements are appended to the main spec
|
||||
2. **MODIFIED** requirements replace the existing version
|
||||
3. **REMOVED** requirements are deleted from the main spec
|
||||
|
||||
The change folder moves to `openspec/changes/archive/` for audit history.
|
||||
|
||||
## Example: Your First Change
|
||||
|
||||
Let's walk through adding dark mode to an application.
|
||||
|
||||
### 1. Start the Change (Default)
|
||||
|
||||
```text
|
||||
You: /opsx:propose add-dark-mode
|
||||
|
||||
AI: Created openspec/changes/add-dark-mode/
|
||||
✓ proposal.md — why we're doing this, what's changing
|
||||
✓ specs/ — requirements and scenarios
|
||||
✓ design.md — technical approach
|
||||
✓ tasks.md — implementation checklist
|
||||
Ready for implementation!
|
||||
```
|
||||
|
||||
If you've enabled the expanded workflow profile, you can also do this as two steps: `/opsx:new` then `/opsx:ff` (or `/opsx:continue` incrementally).
|
||||
|
||||
### 2. What Gets Created
|
||||
|
||||
**proposal.md** - Captures the intent:
|
||||
|
||||
```markdown
|
||||
# Proposal: Add Dark Mode
|
||||
|
||||
## Intent
|
||||
Users have requested a dark mode option to reduce eye strain
|
||||
during nighttime usage.
|
||||
|
||||
## Scope
|
||||
- Add theme toggle in settings
|
||||
- Support system preference detection
|
||||
- Persist preference in localStorage
|
||||
|
||||
## Approach
|
||||
Use CSS custom properties for theming with a React context
|
||||
for state management.
|
||||
```
|
||||
|
||||
**specs/ui/spec.md** - Delta showing new requirements:
|
||||
|
||||
```markdown
|
||||
# Delta for UI
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Theme Selection
|
||||
The system SHALL allow users to choose between light and dark themes.
|
||||
|
||||
#### Scenario: Manual toggle
|
||||
- GIVEN a user on any page
|
||||
- WHEN the user clicks the theme toggle
|
||||
- THEN the theme switches immediately
|
||||
- AND the preference persists across sessions
|
||||
|
||||
#### Scenario: System preference
|
||||
- GIVEN a user with no saved preference
|
||||
- WHEN the application loads
|
||||
- THEN the system's preferred color scheme is used
|
||||
```
|
||||
|
||||
**tasks.md** - Implementation checklist:
|
||||
|
||||
```markdown
|
||||
# Tasks
|
||||
|
||||
## 1. Theme Infrastructure
|
||||
- [ ] 1.1 Create ThemeContext with light/dark state
|
||||
- [ ] 1.2 Add CSS custom properties for colors
|
||||
- [ ] 1.3 Implement localStorage persistence
|
||||
|
||||
## 2. UI Components
|
||||
- [ ] 2.1 Create ThemeToggle component
|
||||
- [ ] 2.2 Add toggle to settings page
|
||||
- [ ] 2.3 Update Header to include quick toggle
|
||||
|
||||
## 3. Styling
|
||||
- [ ] 3.1 Define dark theme color palette
|
||||
- [ ] 3.2 Update components to use CSS variables
|
||||
```
|
||||
|
||||
### 3. Implement
|
||||
|
||||
```
|
||||
You: /opsx:apply
|
||||
|
||||
AI: Working through tasks...
|
||||
✓ 1.1 Created ThemeContext with light/dark state
|
||||
✓ 1.2 Added CSS custom properties to globals.css
|
||||
✓ 1.3 Implemented localStorage persistence
|
||||
✓ 2.1 Created ThemeToggle component
|
||||
...
|
||||
All tasks complete!
|
||||
```
|
||||
|
||||
During implementation, if you discover the design needs adjustment, just update the artifact and continue.
|
||||
|
||||
### 4. Archive
|
||||
|
||||
```
|
||||
You: /opsx:archive
|
||||
|
||||
AI: Archiving add-dark-mode...
|
||||
✓ Merged specs into openspec/specs/ui/spec.md
|
||||
✓ Moved to openspec/changes/archive/2025-01-24-add-dark-mode/
|
||||
Done! Ready for the next feature.
|
||||
```
|
||||
|
||||
Your delta specs are now part of the main specs, documenting how your system works.
|
||||
|
||||
## Verifying and Reviewing
|
||||
|
||||
Use the CLI to check on your changes:
|
||||
|
||||
```bash
|
||||
# List active changes
|
||||
openspec list
|
||||
|
||||
# View change details
|
||||
openspec show add-dark-mode
|
||||
|
||||
# Validate spec formatting
|
||||
openspec validate add-dark-mode
|
||||
|
||||
# Interactive dashboard
|
||||
openspec view
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Workflows](workflows.md) - Common patterns and when to use each command
|
||||
- [Commands](commands.md) - Full reference for all slash commands
|
||||
- [Concepts](concepts.md) - Deeper understanding of specs, changes, and schemas
|
||||
- [Customization](customization.md) - Make OpenSpec work your way
|
||||
@@ -0,0 +1,79 @@
|
||||
# Installation
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Node.js 20.19.0 or higher** — Check your version: `node --version`
|
||||
|
||||
## Package Managers
|
||||
|
||||
### npm
|
||||
|
||||
```bash
|
||||
npm install -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
### pnpm
|
||||
|
||||
```bash
|
||||
pnpm add -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
### yarn
|
||||
|
||||
```bash
|
||||
yarn global add @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
### bun
|
||||
|
||||
```bash
|
||||
bun add -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
## Nix
|
||||
|
||||
Run OpenSpec directly without installation:
|
||||
|
||||
```bash
|
||||
nix run github:Fission-AI/OpenSpec -- init
|
||||
```
|
||||
|
||||
Or install to your profile:
|
||||
|
||||
```bash
|
||||
nix profile install github:Fission-AI/OpenSpec
|
||||
```
|
||||
|
||||
Or add to your development environment in `flake.nix`:
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
openspec.url = "github:Fission-AI/OpenSpec";
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, openspec, ... }: {
|
||||
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
|
||||
buildInputs = [ openspec.packages.x86_64-linux.default ];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Verify Installation
|
||||
|
||||
```bash
|
||||
openspec --version
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
After installing, initialize OpenSpec in your project:
|
||||
|
||||
```bash
|
||||
cd your-project
|
||||
openspec init
|
||||
```
|
||||
|
||||
See [Getting Started](getting-started.md) for a full walkthrough.
|
||||
@@ -0,0 +1,595 @@
|
||||
# Migrating to OPSX
|
||||
|
||||
This guide helps you transition from the legacy OpenSpec workflow to OPSX. The migration is designed to be smooth—your existing work is preserved, and the new system offers more flexibility.
|
||||
|
||||
## What's Changing?
|
||||
|
||||
OPSX replaces the old phase-locked workflow with a fluid, action-based approach. Here's the key shift:
|
||||
|
||||
| Aspect | Legacy | OPSX |
|
||||
|--------|--------|------|
|
||||
| **Commands** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` | Default: `/opsx:propose`, `/opsx:apply`, `/opsx:archive` (expanded workflow commands optional) |
|
||||
| **Workflow** | Create all artifacts at once | Create incrementally or all at once—your choice |
|
||||
| **Going back** | Awkward phase gates | Natural—update any artifact anytime |
|
||||
| **Customization** | Fixed structure | Schema-driven, fully hackable |
|
||||
| **Configuration** | `CLAUDE.md` with markers + `project.md` | Clean config in `openspec/config.yaml` |
|
||||
|
||||
**The philosophy change:** Work isn't linear. OPSX stops pretending it is.
|
||||
|
||||
---
|
||||
|
||||
## Before You Begin
|
||||
|
||||
### Your Existing Work Is Safe
|
||||
|
||||
The migration process is designed with preservation in mind:
|
||||
|
||||
- **Active changes in `openspec/changes/`** — Completely preserved. You can continue them with OPSX commands.
|
||||
- **Archived changes** — Untouched. Your history remains intact.
|
||||
- **Main specs in `openspec/specs/`** — Untouched. These are your source of truth.
|
||||
- **Your content in CLAUDE.md, AGENTS.md, etc.** — Preserved. Only the OpenSpec marker blocks are removed; everything you wrote stays.
|
||||
|
||||
### What Gets Removed
|
||||
|
||||
Only OpenSpec-managed files that are being replaced:
|
||||
|
||||
| What | Why |
|
||||
|------|-----|
|
||||
| Legacy slash command directories/files | Replaced by the new skills system |
|
||||
| `openspec/AGENTS.md` | Obsolete workflow trigger |
|
||||
| OpenSpec markers in `CLAUDE.md`, `AGENTS.md`, etc. | No longer needed |
|
||||
|
||||
**Legacy command locations by tool** (examples—your tool may vary):
|
||||
|
||||
- Claude Code: `.claude/commands/openspec/`
|
||||
- Cursor: `.cursor/commands/openspec-*.md`
|
||||
- Windsurf: `.windsurf/workflows/openspec-*.md`
|
||||
- Cline: `.clinerules/workflows/openspec-*.md`
|
||||
- Roo: `.roo/commands/openspec-*.md`
|
||||
- GitHub Copilot: `.github/prompts/openspec-*.prompt.md` (IDE extensions only; not supported in Copilot CLI)
|
||||
- And others (Augment, Continue, Amazon Q, etc.)
|
||||
|
||||
The migration detects whichever tools you have configured and cleans up their legacy files.
|
||||
|
||||
The removal list may seem long, but these are all files that OpenSpec originally created. Your own content is never deleted.
|
||||
|
||||
### What Needs Your Attention
|
||||
|
||||
One file requires manual migration:
|
||||
|
||||
**`openspec/project.md`** — This file isn't deleted automatically because it may contain project context you've written. You'll need to:
|
||||
|
||||
1. Review its contents
|
||||
2. Move useful context to `openspec/config.yaml` (see guidance below)
|
||||
3. Delete the file when ready
|
||||
|
||||
**Why we made this change:**
|
||||
|
||||
The old `project.md` was passive—agents might read it, might not, might forget what they read. We found reliability was inconsistent.
|
||||
|
||||
The new `config.yaml` context is **actively injected into every OpenSpec planning request**. This means your project conventions, tech stack, and rules are always present when the AI is creating artifacts. Higher reliability.
|
||||
|
||||
**The tradeoff:**
|
||||
|
||||
Because context is injected into every request, you'll want to be concise. Focus on what really matters:
|
||||
- Tech stack and key conventions
|
||||
- Non-obvious constraints the AI needs to know
|
||||
- Rules that frequently got ignored before
|
||||
|
||||
Don't worry about getting it perfect. We're still learning what works best here, and we'll be improving how context injection works as we experiment.
|
||||
|
||||
---
|
||||
|
||||
## Running the Migration
|
||||
|
||||
Both `openspec init` and `openspec update` detect legacy files and guide you through the same cleanup process. Use whichever fits your situation:
|
||||
|
||||
- New installs default to profile `core` (`propose`, `explore`, `apply`, `archive`).
|
||||
- Migrated installs preserve your previously installed workflows by writing a `custom` profile when needed.
|
||||
|
||||
### Using `openspec init`
|
||||
|
||||
Run this if you want to add new tools or reconfigure which tools are set up:
|
||||
|
||||
```bash
|
||||
openspec init
|
||||
```
|
||||
|
||||
The init command detects legacy files and guides you through cleanup:
|
||||
|
||||
```
|
||||
Upgrading to the new OpenSpec
|
||||
|
||||
OpenSpec now uses agent skills, the emerging standard across coding
|
||||
agents. This simplifies your setup while keeping everything working
|
||||
as before.
|
||||
|
||||
Files to remove
|
||||
No user content to preserve:
|
||||
• .claude/commands/openspec/
|
||||
• openspec/AGENTS.md
|
||||
|
||||
Files to update
|
||||
OpenSpec markers will be removed, your content preserved:
|
||||
• CLAUDE.md
|
||||
• AGENTS.md
|
||||
|
||||
Needs your attention
|
||||
• openspec/project.md
|
||||
We won't delete this file. It may contain useful project context.
|
||||
|
||||
The new openspec/config.yaml has a "context:" section for planning
|
||||
context. This is included in every OpenSpec request and works more
|
||||
reliably than the old project.md approach.
|
||||
|
||||
Review project.md, move any useful content to config.yaml's context
|
||||
section, then delete the file when ready.
|
||||
|
||||
? Upgrade and clean up legacy files? (Y/n)
|
||||
```
|
||||
|
||||
**What happens when you say yes:**
|
||||
|
||||
1. Legacy slash command directories are removed
|
||||
2. OpenSpec markers are stripped from `CLAUDE.md`, `AGENTS.md`, etc. (your content stays)
|
||||
3. `openspec/AGENTS.md` is deleted
|
||||
4. New skills are installed in `.claude/skills/`
|
||||
5. `openspec/config.yaml` is created with a default schema
|
||||
|
||||
### Using `openspec update`
|
||||
|
||||
Run this if you just want to migrate and refresh your existing tools to the latest version:
|
||||
|
||||
```bash
|
||||
openspec update
|
||||
```
|
||||
|
||||
The update command also detects and cleans up legacy artifacts, then refreshes generated skills/commands to match your current profile and delivery settings.
|
||||
|
||||
### Non-Interactive / CI Environments
|
||||
|
||||
For scripted migrations:
|
||||
|
||||
```bash
|
||||
openspec init --force --tools claude
|
||||
```
|
||||
|
||||
The `--force` flag skips prompts and auto-accepts cleanup.
|
||||
|
||||
---
|
||||
|
||||
## Migrating project.md to config.yaml
|
||||
|
||||
The old `openspec/project.md` was a freeform markdown file for project context. The new `openspec/config.yaml` is structured and—critically—**injected into every planning request** so your conventions are always present when the AI works.
|
||||
|
||||
### Before (project.md)
|
||||
|
||||
```markdown
|
||||
# Project Context
|
||||
|
||||
This is a TypeScript monorepo using React and Node.js.
|
||||
We use Jest for testing and follow strict ESLint rules.
|
||||
Our API is RESTful and documented in docs/api.md.
|
||||
|
||||
## Conventions
|
||||
|
||||
- All public APIs must maintain backwards compatibility
|
||||
- New features should include tests
|
||||
- Use Given/When/Then format for specifications
|
||||
```
|
||||
|
||||
### After (config.yaml)
|
||||
|
||||
```yaml
|
||||
schema: spec-driven
|
||||
|
||||
context: |
|
||||
Tech stack: TypeScript, React, Node.js
|
||||
Testing: Jest with React Testing Library
|
||||
API: RESTful, documented in docs/api.md
|
||||
We maintain backwards compatibility for all public APIs
|
||||
|
||||
rules:
|
||||
proposal:
|
||||
- Include rollback plan for risky changes
|
||||
specs:
|
||||
- Use Given/When/Then format for scenarios
|
||||
- Reference existing patterns before inventing new ones
|
||||
design:
|
||||
- Include sequence diagrams for complex flows
|
||||
```
|
||||
|
||||
### Key Differences
|
||||
|
||||
| project.md | config.yaml |
|
||||
|------------|-------------|
|
||||
| Freeform markdown | Structured YAML |
|
||||
| One blob of text | Separate context and per-artifact rules |
|
||||
| Unclear when it's used | Context appears in ALL artifacts; rules appear in matching artifacts only |
|
||||
| No schema selection | Explicit `schema:` field sets default workflow |
|
||||
|
||||
### What to Keep, What to Drop
|
||||
|
||||
When migrating, be selective. Ask yourself: "Does the AI need this for *every* planning request?"
|
||||
|
||||
**Good candidates for `context:`**
|
||||
- Tech stack (languages, frameworks, databases)
|
||||
- Key architectural patterns (monorepo, microservices, etc.)
|
||||
- Non-obvious constraints ("we can't use library X because...")
|
||||
- Critical conventions that often get ignored
|
||||
|
||||
**Move to `rules:` instead**
|
||||
- Artifact-specific formatting ("use Given/When/Then in specs")
|
||||
- Review criteria ("proposals must include rollback plans")
|
||||
- These only appear for the matching artifact, keeping other requests lighter
|
||||
|
||||
**Leave out entirely**
|
||||
- General best practices the AI already knows
|
||||
- Verbose explanations that could be summarized
|
||||
- Historical context that doesn't affect current work
|
||||
|
||||
### Migration Steps
|
||||
|
||||
1. **Create config.yaml** (if not already created by init):
|
||||
```yaml
|
||||
schema: spec-driven
|
||||
```
|
||||
|
||||
2. **Add your context** (be concise—this goes into every request):
|
||||
```yaml
|
||||
context: |
|
||||
Your project background goes here.
|
||||
Focus on what the AI genuinely needs to know.
|
||||
```
|
||||
|
||||
3. **Add per-artifact rules** (optional):
|
||||
```yaml
|
||||
rules:
|
||||
proposal:
|
||||
- Your proposal-specific guidance
|
||||
specs:
|
||||
- Your spec-writing rules
|
||||
```
|
||||
|
||||
4. **Delete project.md** once you've moved everything useful.
|
||||
|
||||
**Don't overthink it.** Start with the essentials and iterate. If you notice the AI missing something important, add it. If context feels bloated, trim it. This is a living document.
|
||||
|
||||
### Need Help? Use This Prompt
|
||||
|
||||
If you're unsure how to distill your project.md, ask your AI assistant:
|
||||
|
||||
```
|
||||
I'm migrating from OpenSpec's old project.md to the new config.yaml format.
|
||||
|
||||
Here's my current project.md:
|
||||
[paste your project.md content]
|
||||
|
||||
Please help me create a config.yaml with:
|
||||
1. A concise `context:` section (this gets injected into every planning request, so keep it tight—focus on tech stack, key constraints, and conventions that often get ignored)
|
||||
2. `rules:` for specific artifacts if any content is artifact-specific (e.g., "use Given/When/Then" belongs in specs rules, not global context)
|
||||
|
||||
Leave out anything generic that AI models already know. Be ruthless about brevity.
|
||||
```
|
||||
|
||||
The AI will help you identify what's essential vs. what can be trimmed.
|
||||
|
||||
---
|
||||
|
||||
## The New Commands
|
||||
|
||||
Command availability is profile-dependent:
|
||||
|
||||
**Default (`core` profile):**
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/opsx:propose` | Create a change and generate planning artifacts in one step |
|
||||
| `/opsx:explore` | Think through ideas with no structure |
|
||||
| `/opsx:apply` | Implement tasks from tasks.md |
|
||||
| `/opsx:archive` | Finalize and archive the change |
|
||||
|
||||
**Expanded workflow (custom selection):**
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/opsx:new` | Start a new change scaffold |
|
||||
| `/opsx:continue` | Create the next artifact (one at a time) |
|
||||
| `/opsx:ff` | Fast-forward—create planning artifacts at once |
|
||||
| `/opsx:verify` | Validate implementation matches specs |
|
||||
| `/opsx:sync` | Preview/spec-merge without archiving |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes at once |
|
||||
| `/opsx:onboard` | Guided end-to-end onboarding workflow |
|
||||
|
||||
Enable expanded commands with `openspec config profile`, then run `openspec update`.
|
||||
|
||||
### Command Mapping from Legacy
|
||||
|
||||
| Legacy | OPSX Equivalent |
|
||||
|--------|-----------------|
|
||||
| `/openspec:proposal` | `/opsx:propose` (default) or `/opsx:new` then `/opsx:ff` (expanded) |
|
||||
| `/openspec:apply` | `/opsx:apply` |
|
||||
| `/openspec:archive` | `/opsx:archive` |
|
||||
|
||||
### New Capabilities
|
||||
|
||||
These capabilities are part of the expanded workflow command set.
|
||||
|
||||
**Granular artifact creation:**
|
||||
```
|
||||
/opsx:continue
|
||||
```
|
||||
Creates one artifact at a time based on dependencies. Use this when you want to review each step.
|
||||
|
||||
**Exploration mode:**
|
||||
```
|
||||
/opsx:explore
|
||||
```
|
||||
Think through ideas with a partner before committing to a change.
|
||||
|
||||
---
|
||||
|
||||
## Understanding the New Architecture
|
||||
|
||||
### From Phase-Locked to Fluid
|
||||
|
||||
The legacy workflow forced linear progression:
|
||||
|
||||
```
|
||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ PLANNING │ ───► │ IMPLEMENTING │ ───► │ ARCHIVING │
|
||||
│ PHASE │ │ PHASE │ │ PHASE │
|
||||
└──────────────┘ └──────────────┘ └──────────────┘
|
||||
|
||||
If you're in implementation and realize the design is wrong?
|
||||
Too bad. Phase gates don't let you go back easily.
|
||||
```
|
||||
|
||||
OPSX uses actions, not phases:
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────┐
|
||||
│ ACTIONS (not phases) │
|
||||
│ │
|
||||
│ new ◄──► continue ◄──► apply ◄──► archive │
|
||||
│ │ │ │ │ │
|
||||
│ └──────────┴───────────┴─────────────┘ │
|
||||
│ any order │
|
||||
└───────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Dependency Graph
|
||||
|
||||
Artifacts form a directed graph. Dependencies are enablers, not gates:
|
||||
|
||||
```
|
||||
proposal
|
||||
(root node)
|
||||
│
|
||||
┌─────────────┴─────────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
specs design
|
||||
(requires: (requires:
|
||||
proposal) proposal)
|
||||
│ │
|
||||
└─────────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
tasks
|
||||
(requires:
|
||||
specs, design)
|
||||
```
|
||||
|
||||
When you run `/opsx:continue`, it checks what's ready and offers the next artifact. You can also create multiple ready artifacts in any order.
|
||||
|
||||
### Skills vs Commands
|
||||
|
||||
The legacy system used tool-specific command files:
|
||||
|
||||
```
|
||||
.claude/commands/openspec/
|
||||
├── proposal.md
|
||||
├── apply.md
|
||||
└── archive.md
|
||||
```
|
||||
|
||||
OPSX uses the emerging **skills** standard:
|
||||
|
||||
```
|
||||
.claude/skills/
|
||||
├── openspec-explore/SKILL.md
|
||||
├── openspec-new-change/SKILL.md
|
||||
├── openspec-continue-change/SKILL.md
|
||||
├── openspec-apply-change/SKILL.md
|
||||
└── ...
|
||||
```
|
||||
|
||||
Skills are recognized across multiple AI coding tools and provide richer metadata.
|
||||
|
||||
---
|
||||
|
||||
## Continuing Existing Changes
|
||||
|
||||
Your in-progress changes work seamlessly with OPSX commands.
|
||||
|
||||
**Have an active change from the legacy workflow?**
|
||||
|
||||
```
|
||||
/opsx:apply add-my-feature
|
||||
```
|
||||
|
||||
OPSX reads the existing artifacts and continues from where you left off.
|
||||
|
||||
**Want to add more artifacts to an existing change?**
|
||||
|
||||
```
|
||||
/opsx:continue add-my-feature
|
||||
```
|
||||
|
||||
Shows what's ready to create based on what already exists.
|
||||
|
||||
**Need to see status?**
|
||||
|
||||
```bash
|
||||
openspec status --change add-my-feature
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## The New Config System
|
||||
|
||||
### config.yaml Structure
|
||||
|
||||
```yaml
|
||||
# Required: Default schema for new changes
|
||||
schema: spec-driven
|
||||
|
||||
# Optional: Project context (max 50KB)
|
||||
# Injected into ALL artifact instructions
|
||||
context: |
|
||||
Your project background, tech stack,
|
||||
conventions, and constraints.
|
||||
|
||||
# Optional: Per-artifact rules
|
||||
# Only injected into matching artifacts
|
||||
rules:
|
||||
proposal:
|
||||
- Include rollback plan
|
||||
specs:
|
||||
- Use Given/When/Then format
|
||||
design:
|
||||
- Document fallback strategies
|
||||
tasks:
|
||||
- Break into 2-hour maximum chunks
|
||||
```
|
||||
|
||||
### Schema Resolution
|
||||
|
||||
When determining which schema to use, OPSX checks in order:
|
||||
|
||||
1. **CLI flag**: `--schema <name>` (highest priority)
|
||||
2. **Change metadata**: `.openspec.yaml` in the change directory
|
||||
3. **Project config**: `openspec/config.yaml`
|
||||
4. **Default**: `spec-driven`
|
||||
|
||||
### Available Schemas
|
||||
|
||||
| Schema | Artifacts | Best For |
|
||||
|--------|-----------|----------|
|
||||
| `spec-driven` | proposal → specs → design → tasks | Most projects |
|
||||
|
||||
List all available schemas:
|
||||
|
||||
```bash
|
||||
openspec schemas
|
||||
```
|
||||
|
||||
### Custom Schemas
|
||||
|
||||
Create your own workflow:
|
||||
|
||||
```bash
|
||||
openspec schema init my-workflow
|
||||
```
|
||||
|
||||
Or fork an existing one:
|
||||
|
||||
```bash
|
||||
openspec schema fork spec-driven my-workflow
|
||||
```
|
||||
|
||||
See [Customization](customization.md) for details.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Legacy files detected in non-interactive mode"
|
||||
|
||||
You're running in a CI or non-interactive environment. Use:
|
||||
|
||||
```bash
|
||||
openspec init --force
|
||||
```
|
||||
|
||||
### Commands not appearing after migration
|
||||
|
||||
Restart your IDE. Skills are detected at startup.
|
||||
|
||||
### "Unknown artifact ID in rules"
|
||||
|
||||
Check that your `rules:` keys match your schema's artifact IDs:
|
||||
|
||||
- **spec-driven**: `proposal`, `specs`, `design`, `tasks`
|
||||
|
||||
Run this to see valid artifact IDs:
|
||||
|
||||
```bash
|
||||
openspec schemas --json
|
||||
```
|
||||
|
||||
### Config not being applied
|
||||
|
||||
1. Ensure the file is at `openspec/config.yaml` (not `.yml`)
|
||||
2. Validate YAML syntax
|
||||
3. Config changes take effect immediately—no restart needed
|
||||
|
||||
### project.md not migrated
|
||||
|
||||
The system intentionally preserves `project.md` because it may contain your custom content. Review it manually, move useful parts to `config.yaml`, then delete it.
|
||||
|
||||
### Want to see what would be cleaned up?
|
||||
|
||||
Run init and decline the cleanup prompt—you'll see the full detection summary without any changes being made.
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Files After Migration
|
||||
|
||||
```
|
||||
project/
|
||||
├── openspec/
|
||||
│ ├── specs/ # Unchanged
|
||||
│ ├── changes/ # Unchanged
|
||||
│ │ └── archive/ # Unchanged
|
||||
│ └── config.yaml # NEW: Project configuration
|
||||
├── .claude/
|
||||
│ └── skills/ # NEW: OPSX skills
|
||||
│ ├── openspec-propose/ # default core profile
|
||||
│ ├── openspec-explore/
|
||||
│ ├── openspec-apply-change/
|
||||
│ └── ... # expanded profile adds new/continue/ff/etc.
|
||||
├── CLAUDE.md # OpenSpec markers removed, your content preserved
|
||||
└── AGENTS.md # OpenSpec markers removed, your content preserved
|
||||
```
|
||||
|
||||
### What's Gone
|
||||
|
||||
- `.claude/commands/openspec/` — replaced by `.claude/skills/`
|
||||
- `openspec/AGENTS.md` — obsolete
|
||||
- `openspec/project.md` — migrate to `config.yaml`, then delete
|
||||
- OpenSpec marker blocks in `CLAUDE.md`, `AGENTS.md`, etc.
|
||||
|
||||
### Command Cheatsheet
|
||||
|
||||
```text
|
||||
/opsx:propose Start quickly (default core profile)
|
||||
/opsx:apply Implement tasks
|
||||
/opsx:archive Finish and archive
|
||||
|
||||
# Expanded workflow (if enabled):
|
||||
/opsx:new Scaffold a change
|
||||
/opsx:continue Create next artifact
|
||||
/opsx:ff Create planning artifacts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
- **Discord**: [discord.gg/YctCnvvshC](https://discord.gg/YctCnvvshC)
|
||||
- **GitHub Issues**: [github.com/Fission-AI/OpenSpec/issues](https://github.com/Fission-AI/OpenSpec/issues)
|
||||
- **Documentation**: [docs/opsx.md](opsx.md) for the full OPSX reference
|
||||
@@ -0,0 +1,115 @@
|
||||
# Multi-Language Guide
|
||||
|
||||
Configure OpenSpec to generate artifacts in languages other than English.
|
||||
|
||||
## Quick Setup
|
||||
|
||||
Add a language instruction to your `openspec/config.yaml`:
|
||||
|
||||
```yaml
|
||||
schema: spec-driven
|
||||
|
||||
context: |
|
||||
Language: Portuguese (pt-BR)
|
||||
All artifacts must be written in Brazilian Portuguese.
|
||||
|
||||
# Your other project context below...
|
||||
Tech stack: TypeScript, React, Node.js
|
||||
```
|
||||
|
||||
That's it. All generated artifacts will now be in Portuguese.
|
||||
|
||||
## Language Examples
|
||||
|
||||
### Portuguese (Brazil)
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
Language: Portuguese (pt-BR)
|
||||
All artifacts must be written in Brazilian Portuguese.
|
||||
```
|
||||
|
||||
### Spanish
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
Idioma: Español
|
||||
Todos los artefactos deben escribirse en español.
|
||||
```
|
||||
|
||||
### Chinese (Simplified)
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
语言:中文(简体)
|
||||
所有产出物必须用简体中文撰写。
|
||||
```
|
||||
|
||||
### Japanese
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
言語:日本語
|
||||
すべての成果物は日本語で作成してください。
|
||||
```
|
||||
|
||||
### French
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
Langue : Français
|
||||
Tous les artefacts doivent être rédigés en français.
|
||||
```
|
||||
|
||||
### German
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
Sprache: Deutsch
|
||||
Alle Artefakte müssen auf Deutsch verfasst werden.
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
### Handle Technical Terms
|
||||
|
||||
Decide how to handle technical terminology:
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
Language: Japanese
|
||||
Write in Japanese, but:
|
||||
- Keep technical terms like "API", "REST", "GraphQL" in English
|
||||
- Code examples and file paths remain in English
|
||||
```
|
||||
|
||||
### Combine with Other Context
|
||||
|
||||
Language settings work alongside your other project context:
|
||||
|
||||
```yaml
|
||||
schema: spec-driven
|
||||
|
||||
context: |
|
||||
Language: Portuguese (pt-BR)
|
||||
All artifacts must be written in Brazilian Portuguese.
|
||||
|
||||
Tech stack: TypeScript, React 18, Node.js 20
|
||||
Database: PostgreSQL with Prisma ORM
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
To verify your language config is working:
|
||||
|
||||
```bash
|
||||
# Check the instructions - should show your language context
|
||||
openspec instructions proposal --change my-change
|
||||
|
||||
# Output will include your language context
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Customization Guide](./customization.md) - Project configuration options
|
||||
- [Workflows Guide](./workflows.md) - Full workflow documentation
|
||||
+659
@@ -0,0 +1,659 @@
|
||||
# OPSX Workflow
|
||||
|
||||
> Feedback welcome on [Discord](https://discord.gg/YctCnvvshC).
|
||||
|
||||
## What Is It?
|
||||
|
||||
OPSX is now the standard workflow for OpenSpec.
|
||||
|
||||
It's a **fluid, iterative workflow** for OpenSpec changes. No more rigid phases — just actions you can take anytime.
|
||||
|
||||
## Why This Exists
|
||||
|
||||
The legacy OpenSpec workflow works, but it's **locked down**:
|
||||
|
||||
- **Instructions are hardcoded** — buried in TypeScript, you can't change them
|
||||
- **All-or-nothing** — one big command creates everything, can't test individual pieces
|
||||
- **Fixed structure** — same workflow for everyone, no customization
|
||||
- **Black box** — when AI output is bad, you can't tweak the prompts
|
||||
|
||||
**OPSX opens it up.** Now anyone can:
|
||||
|
||||
1. **Experiment with instructions** — edit a template, see if the AI does better
|
||||
2. **Test granularly** — validate each artifact's instructions independently
|
||||
3. **Customize workflows** — define your own artifacts and dependencies
|
||||
4. **Iterate quickly** — change a template, test immediately, no rebuild
|
||||
|
||||
```
|
||||
Legacy workflow: OPSX:
|
||||
┌────────────────────────┐ ┌────────────────────────┐
|
||||
│ Hardcoded in package │ │ schema.yaml │◄── You edit this
|
||||
│ (can't change) │ │ templates/*.md │◄── Or this
|
||||
│ ↓ │ │ ↓ │
|
||||
│ Wait for new release │ │ Instant effect │
|
||||
│ ↓ │ │ ↓ │
|
||||
│ Hope it's better │ │ Test it yourself │
|
||||
└────────────────────────┘ └────────────────────────┘
|
||||
```
|
||||
|
||||
**This is for everyone:**
|
||||
- **Teams** — create workflows that match how you actually work
|
||||
- **Power users** — tweak prompts to get better AI outputs for your codebase
|
||||
- **OpenSpec contributors** — experiment with new approaches without releases
|
||||
|
||||
We're all still learning what works best. OPSX lets us learn together.
|
||||
|
||||
## The User Experience
|
||||
|
||||
**The problem with linear workflows:**
|
||||
You're "in planning phase", then "in implementation phase", then "done". But real work doesn't work that way. You implement something, realize your design was wrong, need to update specs, continue implementing. Linear phases fight against how work actually happens.
|
||||
|
||||
**OPSX approach:**
|
||||
- **Actions, not phases** — create, implement, update, archive — do any of them anytime
|
||||
- **Dependencies are enablers** — they show what's possible, not what's required next
|
||||
|
||||
```
|
||||
proposal ──→ specs ──→ design ──→ tasks ──→ implement
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
# Make sure you have openspec installed — skills are automatically generated
|
||||
openspec init
|
||||
```
|
||||
|
||||
This creates skills in `.claude/skills/` (or equivalent) that AI coding assistants auto-detect.
|
||||
|
||||
By default, OpenSpec uses the `core` workflow profile (`propose`, `explore`, `apply`, `archive`). If you want the expanded workflow commands (`new`, `continue`, `ff`, `verify`, `sync`, `bulk-archive`, `onboard`), configure them with `openspec config profile` and apply with `openspec update`.
|
||||
|
||||
During setup, you'll be prompted to create a **project config** (`openspec/config.yaml`). This is optional but recommended.
|
||||
|
||||
## Project Configuration
|
||||
|
||||
Project config lets you set defaults and inject project-specific context into all artifacts.
|
||||
|
||||
### Creating Config
|
||||
|
||||
Config is created during `openspec init`, or manually:
|
||||
|
||||
```yaml
|
||||
# openspec/config.yaml
|
||||
schema: spec-driven
|
||||
|
||||
context: |
|
||||
Tech stack: TypeScript, React, Node.js
|
||||
API conventions: RESTful, JSON responses
|
||||
Testing: Vitest for unit tests, Playwright for e2e
|
||||
Style: ESLint with Prettier, strict TypeScript
|
||||
|
||||
rules:
|
||||
proposal:
|
||||
- Include rollback plan
|
||||
- Identify affected teams
|
||||
specs:
|
||||
- Use Given/When/Then format for scenarios
|
||||
design:
|
||||
- Include sequence diagrams for complex flows
|
||||
```
|
||||
|
||||
### Config Fields
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `schema` | string | Default schema for new changes (e.g., `spec-driven`) |
|
||||
| `context` | string | Project context injected into all artifact instructions |
|
||||
| `rules` | object | Per-artifact rules, keyed by artifact ID |
|
||||
|
||||
### How It Works
|
||||
|
||||
**Schema precedence** (highest to lowest):
|
||||
1. CLI flag (`--schema <name>`)
|
||||
2. Change metadata (`.openspec.yaml` in change directory)
|
||||
3. Project config (`openspec/config.yaml`)
|
||||
4. Default (`spec-driven`)
|
||||
|
||||
**Context injection:**
|
||||
- Context is prepended to every artifact's instructions
|
||||
- Wrapped in `<context>...</context>` tags
|
||||
- Helps AI understand your project's conventions
|
||||
|
||||
**Rules injection:**
|
||||
- Rules are only injected for matching artifacts
|
||||
- Wrapped in `<rules>...</rules>` tags
|
||||
- Appear after context, before the template
|
||||
|
||||
### Artifact IDs by Schema
|
||||
|
||||
**spec-driven** (default):
|
||||
- `proposal` — Change proposal
|
||||
- `specs` — Specifications
|
||||
- `design` — Technical design
|
||||
- `tasks` — Implementation tasks
|
||||
|
||||
### Config Validation
|
||||
|
||||
- Unknown artifact IDs in `rules` generate warnings
|
||||
- Schema names are validated against available schemas
|
||||
- Context has a 50KB size limit
|
||||
- Invalid YAML is reported with line numbers
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
**"Unknown artifact ID in rules: X"**
|
||||
- Check artifact IDs match your schema (see list above)
|
||||
- Run `openspec schemas --json` to see artifact IDs for each schema
|
||||
|
||||
**Config not being applied:**
|
||||
- Ensure file is at `openspec/config.yaml` (not `.yml`)
|
||||
- Check YAML syntax with a validator
|
||||
- Config changes take effect immediately (no restart needed)
|
||||
|
||||
**Context too large:**
|
||||
- Context is limited to 50KB
|
||||
- Summarize or link to external docs instead
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | What it does |
|
||||
|---------|--------------|
|
||||
| `/opsx:propose` | Create a change and generate planning artifacts in one step (default quick path) |
|
||||
| `/opsx:explore` | Think through ideas, investigate problems, clarify requirements |
|
||||
| `/opsx:new` | Start a new change scaffold (expanded workflow) |
|
||||
| `/opsx:continue` | Create the next artifact (expanded workflow) |
|
||||
| `/opsx:ff` | Fast-forward planning artifacts (expanded workflow) |
|
||||
| `/opsx:apply` | Implement tasks, updating artifacts as needed |
|
||||
| `/opsx:verify` | Validate implementation against artifacts (expanded workflow) |
|
||||
| `/opsx:sync` | Sync delta specs to main (expanded workflow, optional) |
|
||||
| `/opsx:archive` | Archive when done |
|
||||
| `/opsx:bulk-archive` | Archive multiple completed changes (expanded workflow) |
|
||||
| `/opsx:onboard` | Guided walkthrough of an end-to-end change (expanded workflow) |
|
||||
|
||||
## Usage
|
||||
|
||||
### Explore an idea
|
||||
```
|
||||
/opsx:explore
|
||||
```
|
||||
Think through ideas, investigate problems, compare options. No structure required - just a thinking partner. When insights crystallize, transition to `/opsx:propose` (default) or `/opsx:new`/`/opsx:ff` (expanded).
|
||||
|
||||
### Start a new change
|
||||
```
|
||||
/opsx:propose
|
||||
```
|
||||
Creates the change and generates planning artifacts needed before implementation.
|
||||
|
||||
If you've enabled expanded workflows, you can instead use:
|
||||
|
||||
```text
|
||||
/opsx:new # scaffold only
|
||||
/opsx:continue # create one artifact at a time
|
||||
/opsx:ff # create all planning artifacts at once
|
||||
```
|
||||
|
||||
### Create artifacts
|
||||
```
|
||||
/opsx:continue
|
||||
```
|
||||
Shows what's ready to create based on dependencies, then creates one artifact. Use repeatedly to build up your change incrementally.
|
||||
|
||||
```
|
||||
/opsx:ff add-dark-mode
|
||||
```
|
||||
Creates all planning artifacts at once. Use when you have a clear picture of what you're building.
|
||||
|
||||
### Implement (the fluid part)
|
||||
```
|
||||
/opsx:apply
|
||||
```
|
||||
Works through tasks, checking them off as you go. If you're juggling multiple changes, you can run `/opsx:apply <name>`; otherwise it should infer from the conversation and prompt you to choose if it can't tell.
|
||||
|
||||
### Finish up
|
||||
```
|
||||
/opsx:archive # Move to archive when done (prompts to sync specs if needed)
|
||||
```
|
||||
|
||||
## When to Update vs. Start Fresh
|
||||
|
||||
You can always edit your proposal or specs before implementation. But when does refining become "this is different work"?
|
||||
|
||||
### What a Proposal Captures
|
||||
|
||||
A proposal defines three things:
|
||||
1. **Intent** — What problem are you solving?
|
||||
2. **Scope** — What's in/out of bounds?
|
||||
3. **Approach** — How will you solve it?
|
||||
|
||||
The question is: which changed, and by how much?
|
||||
|
||||
### Update the Existing Change When:
|
||||
|
||||
**Same intent, refined execution**
|
||||
- You discover edge cases you didn't consider
|
||||
- The approach needs tweaking but the goal is unchanged
|
||||
- Implementation reveals the design was slightly off
|
||||
|
||||
**Scope narrows**
|
||||
- You realize full scope is too big, want to ship MVP first
|
||||
- "Add dark mode" → "Add dark mode toggle (system preference in v2)"
|
||||
|
||||
**Learning-driven corrections**
|
||||
- Codebase isn't structured how you thought
|
||||
- A dependency doesn't work as expected
|
||||
- "Use CSS variables" → "Use Tailwind's dark: prefix instead"
|
||||
|
||||
### Start a New Change When:
|
||||
|
||||
**Intent fundamentally changed**
|
||||
- The problem itself is different now
|
||||
- "Add dark mode" → "Add comprehensive theme system with custom colors, fonts, spacing"
|
||||
|
||||
**Scope exploded**
|
||||
- Change grew so much it's essentially different work
|
||||
- Original proposal would be unrecognizable after updates
|
||||
- "Fix login bug" → "Rewrite auth system"
|
||||
|
||||
**Original is completable**
|
||||
- The original change can be marked "done"
|
||||
- New work stands alone, not a refinement
|
||||
- Complete "Add dark mode MVP" → Archive → New change "Enhance dark mode"
|
||||
|
||||
### The Heuristics
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Is this the same work? │
|
||||
└──────────────┬──────────────────────┘
|
||||
│
|
||||
┌──────────────────┼──────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
Same intent? >50% overlap? Can original
|
||||
Same problem? Same scope? be "done" without
|
||||
│ │ these changes?
|
||||
│ │ │
|
||||
┌────────┴────────┐ ┌──────┴──────┐ ┌───────┴───────┐
|
||||
│ │ │ │ │ │
|
||||
YES NO YES NO NO YES
|
||||
│ │ │ │ │ │
|
||||
▼ ▼ ▼ ▼ ▼ ▼
|
||||
UPDATE NEW UPDATE NEW UPDATE NEW
|
||||
```
|
||||
|
||||
| Test | Update | New Change |
|
||||
|------|--------|------------|
|
||||
| **Identity** | "Same thing, refined" | "Different work" |
|
||||
| **Scope overlap** | >50% overlaps | <50% overlaps |
|
||||
| **Completion** | Can't be "done" without changes | Can finish original, new work stands alone |
|
||||
| **Story** | Update chain tells coherent story | Patches would confuse more than clarify |
|
||||
|
||||
### The Principle
|
||||
|
||||
> **Update preserves context. New change provides clarity.**
|
||||
>
|
||||
> Choose update when the history of your thinking is valuable.
|
||||
> Choose new when starting fresh would be clearer than patching.
|
||||
|
||||
Think of it like git branches:
|
||||
- Keep committing while working on the same feature
|
||||
- Start a new branch when it's genuinely new work
|
||||
- Sometimes merge a partial feature and start fresh for phase 2
|
||||
|
||||
## What's Different?
|
||||
|
||||
| | Legacy (`/openspec:proposal`) | OPSX (`/opsx:*`) |
|
||||
|---|---|---|
|
||||
| **Structure** | One big proposal document | Discrete artifacts with dependencies |
|
||||
| **Workflow** | Linear phases: plan → implement → archive | Fluid actions — do anything anytime |
|
||||
| **Iteration** | Awkward to go back | Update artifacts as you learn |
|
||||
| **Customization** | Fixed structure | Schema-driven (define your own artifacts) |
|
||||
|
||||
**The key insight:** work isn't linear. OPSX stops pretending it is.
|
||||
|
||||
## Architecture Deep Dive
|
||||
|
||||
This section explains how OPSX works under the hood and how it compares to the legacy workflow.
|
||||
Examples in this section use the expanded command set (`new`, `continue`, etc.); default `core` users can map the same flow to `propose → apply → archive`.
|
||||
|
||||
### Philosophy: Phases vs Actions
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ LEGACY WORKFLOW │
|
||||
│ (Phase-Locked, All-or-Nothing) │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ PLANNING │ ───► │ IMPLEMENTING │ ───► │ ARCHIVING │ │
|
||||
│ │ PHASE │ │ PHASE │ │ PHASE │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ /openspec:proposal /openspec:apply /openspec:archive │
|
||||
│ │
|
||||
│ • Creates ALL artifacts at once │
|
||||
│ • Can't go back to update specs during implementation │
|
||||
│ • Phase gates enforce linear progression │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ OPSX WORKFLOW │
|
||||
│ (Fluid Actions, Iterative) │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────┐ │
|
||||
│ │ ACTIONS (not phases) │ │
|
||||
│ │ │ │
|
||||
│ │ new ◄──► continue ◄──► apply ◄──► archive │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ └──────────┴───────────┴───────────┘ │ │
|
||||
│ │ any order │ │
|
||||
│ └────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ • Create artifacts one at a time OR fast-forward │
|
||||
│ • Update specs/design/tasks during implementation │
|
||||
│ • Dependencies enable progress, phases don't exist │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Component Architecture
|
||||
|
||||
**Legacy workflow** uses hardcoded templates in TypeScript:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ LEGACY WORKFLOW COMPONENTS │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Hardcoded Templates (TypeScript strings) │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Tool-specific configurators/adapters │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Generated Command Files (.claude/commands/openspec/*.md) │
|
||||
│ │
|
||||
│ • Fixed structure, no artifact awareness │
|
||||
│ • Change requires code modification + rebuild │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**OPSX** uses external schemas and a dependency graph engine:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ OPSX COMPONENTS │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Schema Definitions (YAML) │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ name: spec-driven │ │
|
||||
│ │ artifacts: │ │
|
||||
│ │ - id: proposal │ │
|
||||
│ │ generates: proposal.md │ │
|
||||
│ │ requires: [] ◄── Dependencies │ │
|
||||
│ │ - id: specs │ │
|
||||
│ │ generates: specs/**/*.md ◄── Glob patterns │ │
|
||||
│ │ requires: [proposal] ◄── Enables after proposal │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Artifact Graph Engine │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ • Topological sort (dependency ordering) │ │
|
||||
│ │ • State detection (filesystem existence) │ │
|
||||
│ │ • Rich instruction generation (templates + context) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Skill Files (.claude/skills/openspec-*/SKILL.md) │
|
||||
│ │
|
||||
│ • Cross-editor compatible (Claude Code, Cursor, Windsurf) │
|
||||
│ • Skills query CLI for structured data │
|
||||
│ • Fully customizable via schema files │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Dependency Graph Model
|
||||
|
||||
Artifacts form a directed acyclic graph (DAG). Dependencies are **enablers**, not gates:
|
||||
|
||||
```
|
||||
proposal
|
||||
(root node)
|
||||
│
|
||||
┌─────────────┴─────────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
specs design
|
||||
(requires: (requires:
|
||||
proposal) proposal)
|
||||
│ │
|
||||
└─────────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
tasks
|
||||
(requires:
|
||||
specs, design)
|
||||
│
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ APPLY PHASE │
|
||||
│ (requires: │
|
||||
│ tasks) │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
**State transitions:**
|
||||
|
||||
```
|
||||
BLOCKED ────────────────► READY ────────────────► DONE
|
||||
│ │ │
|
||||
Missing All deps File exists
|
||||
dependencies are DONE on filesystem
|
||||
```
|
||||
|
||||
### Information Flow
|
||||
|
||||
**Legacy workflow** — agent receives static instructions:
|
||||
|
||||
```
|
||||
User: "/openspec:proposal"
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Static instructions: │
|
||||
│ • Create proposal.md │
|
||||
│ • Create tasks.md │
|
||||
│ • Create design.md │
|
||||
│ • Create specs/<capability>/spec.md │
|
||||
│ │
|
||||
│ No awareness of what exists or │
|
||||
│ dependencies between artifacts │
|
||||
└─────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
Agent creates ALL artifacts in one go
|
||||
```
|
||||
|
||||
**OPSX** — agent queries for rich context:
|
||||
|
||||
```
|
||||
User: "/opsx:continue"
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────────────────┐
|
||||
│ Step 1: Query current state │
|
||||
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ $ openspec status --change "add-auth" --json │ │
|
||||
│ │ │ │
|
||||
│ │ { │ │
|
||||
│ │ "artifacts": [ │ │
|
||||
│ │ {"id": "proposal", "status": "done"}, │ │
|
||||
│ │ {"id": "specs", "status": "ready"}, ◄── First ready │ │
|
||||
│ │ {"id": "design", "status": "ready"}, │ │
|
||||
│ │ {"id": "tasks", "status": "blocked", "missingDeps": ["specs"]}│ │
|
||||
│ │ ] │ │
|
||||
│ │ } │ │
|
||||
│ └────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Step 2: Get rich instructions for ready artifact │
|
||||
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ $ openspec instructions specs --change "add-auth" --json │ │
|
||||
│ │ │ │
|
||||
│ │ { │ │
|
||||
│ │ "template": "# Specification\n\n## ADDED Requirements...", │ │
|
||||
│ │ "dependencies": [{"id": "proposal", "path": "...", "done": true}│ │
|
||||
│ │ "unlocks": ["tasks"] │ │
|
||||
│ │ } │ │
|
||||
│ └────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Step 3: Read dependencies → Create ONE artifact → Show what's unlocked │
|
||||
└──────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Iteration Model
|
||||
|
||||
**Legacy workflow** — awkward to iterate:
|
||||
|
||||
```
|
||||
┌─────────┐ ┌─────────┐ ┌─────────┐
|
||||
│/proposal│ ──► │ /apply │ ──► │/archive │
|
||||
└─────────┘ └─────────┘ └─────────┘
|
||||
│ │
|
||||
│ ├── "Wait, the design is wrong"
|
||||
│ │
|
||||
│ ├── Options:
|
||||
│ │ • Edit files manually (breaks context)
|
||||
│ │ • Abandon and start over
|
||||
│ │ • Push through and fix later
|
||||
│ │
|
||||
│ └── No official "go back" mechanism
|
||||
│
|
||||
└── Creates ALL artifacts at once
|
||||
```
|
||||
|
||||
**OPSX** — natural iteration:
|
||||
|
||||
```
|
||||
/opsx:new ───► /opsx:continue ───► /opsx:apply ───► /opsx:archive
|
||||
│ │ │
|
||||
│ │ ├── "The design is wrong"
|
||||
│ │ │
|
||||
│ │ ▼
|
||||
│ │ Just edit design.md
|
||||
│ │ and continue!
|
||||
│ │ │
|
||||
│ │ ▼
|
||||
│ │ /opsx:apply picks up
|
||||
│ │ where you left off
|
||||
│ │
|
||||
│ └── Creates ONE artifact, shows what's unlocked
|
||||
│
|
||||
└── Scaffolds change, waits for direction
|
||||
```
|
||||
|
||||
### Custom Schemas
|
||||
|
||||
Create custom workflows using the schema management commands:
|
||||
|
||||
```bash
|
||||
# Create a new schema from scratch (interactive)
|
||||
openspec schema init my-workflow
|
||||
|
||||
# Or fork an existing schema as a starting point
|
||||
openspec schema fork spec-driven my-workflow
|
||||
|
||||
# Validate your schema structure
|
||||
openspec schema validate my-workflow
|
||||
|
||||
# See where a schema resolves from (useful for debugging)
|
||||
openspec schema which my-workflow
|
||||
```
|
||||
|
||||
Schemas are stored in `openspec/schemas/` (project-local, version controlled) or `~/.local/share/openspec/schemas/` (user global).
|
||||
|
||||
**Schema structure:**
|
||||
```
|
||||
openspec/schemas/research-first/
|
||||
├── schema.yaml
|
||||
└── templates/
|
||||
├── research.md
|
||||
├── proposal.md
|
||||
└── tasks.md
|
||||
```
|
||||
|
||||
**Example schema.yaml:**
|
||||
```yaml
|
||||
name: research-first
|
||||
artifacts:
|
||||
- id: research # Added before proposal
|
||||
generates: research.md
|
||||
requires: []
|
||||
|
||||
- id: proposal
|
||||
generates: proposal.md
|
||||
requires: [research] # Now depends on research
|
||||
|
||||
- id: tasks
|
||||
generates: tasks.md
|
||||
requires: [proposal]
|
||||
```
|
||||
|
||||
**Dependency Graph:**
|
||||
```
|
||||
research ──► proposal ──► tasks
|
||||
```
|
||||
|
||||
### Summary
|
||||
|
||||
| Aspect | Legacy | OPSX |
|
||||
|--------|----------|------|
|
||||
| **Templates** | Hardcoded TypeScript | External YAML + Markdown |
|
||||
| **Dependencies** | None (all at once) | DAG with topological sort |
|
||||
| **State** | Phase-based mental model | Filesystem existence |
|
||||
| **Customization** | Edit source, rebuild | Create schema.yaml |
|
||||
| **Iteration** | Phase-locked | Fluid, edit anything |
|
||||
| **Editor Support** | Tool-specific configurator/adapters | Single skills directory |
|
||||
|
||||
## Schemas
|
||||
|
||||
Schemas define what artifacts exist and their dependencies. Currently available:
|
||||
|
||||
- **spec-driven** (default): proposal → specs → design → tasks
|
||||
|
||||
```bash
|
||||
# List available schemas
|
||||
openspec schemas
|
||||
|
||||
# See all schemas with their resolution sources
|
||||
openspec schema which --all
|
||||
|
||||
# Create a new schema interactively
|
||||
openspec schema init my-workflow
|
||||
|
||||
# Fork an existing schema for customization
|
||||
openspec schema fork spec-driven my-workflow
|
||||
|
||||
# Validate schema structure before use
|
||||
openspec schema validate my-workflow
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- Use `/opsx:explore` to think through an idea before committing to a change
|
||||
- `/opsx:ff` when you know what you want, `/opsx:continue` when exploring
|
||||
- During `/opsx:apply`, if something's wrong — fix the artifact, then continue
|
||||
- Tasks track progress via checkboxes in `tasks.md`
|
||||
- Check status anytime: `openspec status --change "name"`
|
||||
|
||||
## Feedback
|
||||
|
||||
This is rough. That's intentional — we're learning what works.
|
||||
|
||||
Found a bug? Have ideas? Join us on [Discord](https://discord.gg/YctCnvvshC) or open an issue on [GitHub](https://github.com/Fission-AI/openspec/issues).
|
||||
@@ -0,0 +1,108 @@
|
||||
# Supported Tools
|
||||
|
||||
OpenSpec works with many AI coding assistants. When you run `openspec init`, OpenSpec configures selected tools using your active profile/workflow selection and delivery mode.
|
||||
|
||||
## How It Works
|
||||
|
||||
For each selected tool, OpenSpec can install:
|
||||
|
||||
1. **Skills** (if delivery includes skills): `.../skills/openspec-*/SKILL.md`
|
||||
2. **Commands** (if delivery includes commands): tool-specific `opsx-*` command files
|
||||
|
||||
By default, OpenSpec uses the `core` profile, which includes:
|
||||
- `propose`
|
||||
- `explore`
|
||||
- `apply`
|
||||
- `archive`
|
||||
|
||||
You can enable expanded workflows (`new`, `continue`, `ff`, `verify`, `sync`, `bulk-archive`, `onboard`) via `openspec config profile`, then run `openspec update`.
|
||||
|
||||
## Tool Directory Reference
|
||||
|
||||
| Tool (ID) | Skills path pattern | Command path pattern |
|
||||
|-----------|---------------------|----------------------|
|
||||
| Amazon Q Developer (`amazon-q`) | `.amazonq/skills/openspec-*/SKILL.md` | `.amazonq/prompts/opsx-<id>.md` |
|
||||
| Antigravity (`antigravity`) | `.agent/skills/openspec-*/SKILL.md` | `.agent/workflows/opsx-<id>.md` |
|
||||
| Auggie (`auggie`) | `.augment/skills/openspec-*/SKILL.md` | `.augment/commands/opsx-<id>.md` |
|
||||
| IBM Bob Shell (`bob`) | `.bob/skills/openspec-*/SKILL.md` | `.bob/commands/opsx-<id>.md` |
|
||||
| Claude Code (`claude`) | `.claude/skills/openspec-*/SKILL.md` | `.claude/commands/opsx/<id>.md` |
|
||||
| Cline (`cline`) | `.cline/skills/openspec-*/SKILL.md` | `.clinerules/workflows/opsx-<id>.md` |
|
||||
| CodeBuddy (`codebuddy`) | `.codebuddy/skills/openspec-*/SKILL.md` | `.codebuddy/commands/opsx/<id>.md` |
|
||||
| Codex (`codex`) | `.codex/skills/openspec-*/SKILL.md` | `$CODEX_HOME/prompts/opsx-<id>.md`\* |
|
||||
| ForgeCode (`forgecode`) | `.forge/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/openspec-*` invocations) |
|
||||
| Continue (`continue`) | `.continue/skills/openspec-*/SKILL.md` | `.continue/prompts/opsx-<id>.prompt` |
|
||||
| CoStrict (`costrict`) | `.cospec/skills/openspec-*/SKILL.md` | `.cospec/openspec/commands/opsx-<id>.md` |
|
||||
| Crush (`crush`) | `.crush/skills/openspec-*/SKILL.md` | `.crush/commands/opsx/<id>.md` |
|
||||
| Cursor (`cursor`) | `.cursor/skills/openspec-*/SKILL.md` | `.cursor/commands/opsx-<id>.md` |
|
||||
| Factory Droid (`factory`) | `.factory/skills/openspec-*/SKILL.md` | `.factory/commands/opsx-<id>.md` |
|
||||
| Gemini CLI (`gemini`) | `.gemini/skills/openspec-*/SKILL.md` | `.gemini/commands/opsx/<id>.toml` |
|
||||
| GitHub Copilot (`github-copilot`) | `.github/skills/openspec-*/SKILL.md` | `.github/prompts/opsx-<id>.prompt.md`\*\* |
|
||||
| iFlow (`iflow`) | `.iflow/skills/openspec-*/SKILL.md` | `.iflow/commands/opsx-<id>.md` |
|
||||
| Junie (`junie`) | `.junie/skills/openspec-*/SKILL.md` | `.junie/commands/opsx-<id>.md` |
|
||||
| Kilo Code (`kilocode`) | `.kilocode/skills/openspec-*/SKILL.md` | `.kilocode/workflows/opsx-<id>.md` |
|
||||
| Kiro (`kiro`) | `.kiro/skills/openspec-*/SKILL.md` | `.kiro/prompts/opsx-<id>.prompt.md` |
|
||||
| OpenCode (`opencode`) | `.opencode/skills/openspec-*/SKILL.md` | `.opencode/commands/opsx-<id>.md` |
|
||||
| Pi (`pi`) | `.pi/skills/openspec-*/SKILL.md` | `.pi/prompts/opsx-<id>.md` |
|
||||
| Qoder (`qoder`) | `.qoder/skills/openspec-*/SKILL.md` | `.qoder/commands/opsx/<id>.md` |
|
||||
| Qwen Code (`qwen`) | `.qwen/skills/openspec-*/SKILL.md` | `.qwen/commands/opsx-<id>.toml` |
|
||||
| RooCode (`roocode`) | `.roo/skills/openspec-*/SKILL.md` | `.roo/commands/opsx-<id>.md` |
|
||||
| Trae (`trae`) | `.trae/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/openspec-*` invocations) |
|
||||
| Windsurf (`windsurf`) | `.windsurf/skills/openspec-*/SKILL.md` | `.windsurf/workflows/opsx-<id>.md` |
|
||||
|
||||
\* Codex commands are installed in the global Codex home (`$CODEX_HOME/prompts/` if set, otherwise `~/.codex/prompts/`), not your project directory.
|
||||
|
||||
\*\* GitHub Copilot prompt files are recognized as custom slash commands in IDE extensions (VS Code, JetBrains, Visual Studio). `openspec workspace open --agent github-copilot` targets VS Code Copilot and emits a managed `.code-workspace` file under `.openspec/workspace-open/github-copilot/`. Copilot CLI does not currently consume `.github/prompts/*.prompt.md` directly.
|
||||
|
||||
## Non-Interactive Setup
|
||||
|
||||
For CI/CD or scripted setup, use `--tools` (and optionally `--profile`):
|
||||
|
||||
```bash
|
||||
# Configure specific tools
|
||||
openspec init --tools claude,cursor
|
||||
|
||||
# Configure all supported tools
|
||||
openspec init --tools all
|
||||
|
||||
# Skip tool configuration
|
||||
openspec init --tools none
|
||||
|
||||
# Override profile for this init run
|
||||
openspec init --profile core
|
||||
```
|
||||
|
||||
**Available tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `forgecode`, `gemini`, `github-copilot`, `iflow`, `junie`, `kilocode`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`
|
||||
|
||||
## Workflow-Dependent Installation
|
||||
|
||||
OpenSpec installs workflow artifacts based on selected workflows:
|
||||
|
||||
- **Core profile (default):** `propose`, `explore`, `apply`, `archive`
|
||||
- **Custom selection:** any subset of all workflow IDs:
|
||||
`propose`, `explore`, `new`, `continue`, `apply`, `ff`, `sync`, `archive`, `bulk-archive`, `verify`, `onboard`
|
||||
|
||||
In other words, skill/command counts are profile-dependent and delivery-dependent, not fixed.
|
||||
|
||||
## Generated Skill Names
|
||||
|
||||
When selected by profile/workflow config, OpenSpec generates these skills:
|
||||
|
||||
- `openspec-propose`
|
||||
- `openspec-explore`
|
||||
- `openspec-new-change`
|
||||
- `openspec-continue-change`
|
||||
- `openspec-apply-change`
|
||||
- `openspec-ff-change`
|
||||
- `openspec-sync-specs`
|
||||
- `openspec-archive-change`
|
||||
- `openspec-bulk-archive-change`
|
||||
- `openspec-verify-change`
|
||||
- `openspec-onboard`
|
||||
|
||||
See [Commands](commands.md) for command behavior and [CLI](cli.md) for `init`/`update` options.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI Reference](cli.md) — Terminal commands
|
||||
- [Commands](commands.md) — Slash commands and skills
|
||||
- [Getting Started](getting-started.md) — First-time setup
|
||||
@@ -0,0 +1,451 @@
|
||||
# Workflows
|
||||
|
||||
This guide covers common workflow patterns for OpenSpec and when to use each one. For basic setup, see [Getting Started](getting-started.md). For command reference, see [Commands](commands.md).
|
||||
|
||||
## Philosophy: Actions, Not Phases
|
||||
|
||||
Traditional workflows force you through phases: planning, then implementation, then done. But real work doesn't fit neatly into boxes.
|
||||
|
||||
OPSX takes a different approach:
|
||||
|
||||
```text
|
||||
Traditional (phase-locked):
|
||||
|
||||
PLANNING ────────► IMPLEMENTING ────────► DONE
|
||||
│ │
|
||||
│ "Can't go back" │
|
||||
└────────────────────┘
|
||||
|
||||
OPSX (fluid actions):
|
||||
|
||||
proposal ──► specs ──► design ──► tasks ──► implement
|
||||
```
|
||||
|
||||
**Key principles:**
|
||||
|
||||
- **Actions, not phases** - Commands are things you can do, not stages you're stuck in
|
||||
- **Dependencies are enablers** - They show what's possible, not what's required next
|
||||
|
||||
> **Customization:** OPSX workflows are driven by schemas that define artifact sequences. See [Customization](customization.md) for details on creating custom schemas.
|
||||
|
||||
## Two Modes
|
||||
|
||||
### Default Quick Path (`core` profile)
|
||||
|
||||
New installs default to `core`, which provides:
|
||||
- `/opsx:propose`
|
||||
- `/opsx:explore`
|
||||
- `/opsx:apply`
|
||||
- `/opsx:archive`
|
||||
|
||||
Typical flow:
|
||||
|
||||
```text
|
||||
/opsx:propose ──► /opsx:apply ──► /opsx:archive
|
||||
```
|
||||
|
||||
### Expanded/Full Workflow (custom selection)
|
||||
|
||||
If you want explicit scaffold-and-build commands (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:sync`, `/opsx:bulk-archive`, `/opsx:onboard`), enable them with:
|
||||
|
||||
```bash
|
||||
openspec config profile
|
||||
openspec update
|
||||
```
|
||||
|
||||
## Workflow Patterns (Expanded Mode)
|
||||
|
||||
### Quick Feature
|
||||
|
||||
When you know what you want to build and just need to execute:
|
||||
|
||||
```text
|
||||
/opsx:new ──► /opsx:ff ──► /opsx:apply ──► /opsx:verify ──► /opsx:archive
|
||||
```
|
||||
|
||||
**Example conversation:**
|
||||
|
||||
```text
|
||||
You: /opsx:new add-logout-button
|
||||
|
||||
AI: Created openspec/changes/add-logout-button/
|
||||
Ready to create: proposal
|
||||
|
||||
You: /opsx:ff
|
||||
|
||||
AI: Creating all planning artifacts...
|
||||
✓ proposal.md
|
||||
✓ specs/
|
||||
✓ design.md
|
||||
✓ tasks.md
|
||||
Ready for implementation!
|
||||
|
||||
You: /opsx:apply
|
||||
|
||||
AI: Working through tasks...
|
||||
✓ Added logout button to header
|
||||
✓ Implemented session clearing
|
||||
✓ Added confirmation dialog
|
||||
All tasks complete!
|
||||
|
||||
You: /opsx:archive
|
||||
|
||||
AI: ✓ Merged specs
|
||||
✓ Archived change
|
||||
```
|
||||
|
||||
**Best for:** Small to medium features, bug fixes, straightforward changes.
|
||||
|
||||
### Exploratory
|
||||
|
||||
When requirements are unclear or you need to investigate first:
|
||||
|
||||
```text
|
||||
/opsx:explore ──► /opsx:new ──► /opsx:continue ──► ... ──► /opsx:apply
|
||||
```
|
||||
|
||||
**Example conversation:**
|
||||
|
||||
```text
|
||||
You: /opsx:explore
|
||||
|
||||
AI: What would you like to explore?
|
||||
|
||||
You: I want to improve page load performance but I'm not sure
|
||||
where the bottlenecks are.
|
||||
|
||||
AI: Let me help investigate...
|
||||
[Analyzes bundle sizes, identifies slow queries, reviews
|
||||
component render patterns]
|
||||
|
||||
I found three main bottlenecks:
|
||||
1. Large unoptimized images
|
||||
2. Synchronous data fetching in ProductList
|
||||
3. Re-renders from context changes
|
||||
|
||||
Which would you like to address first?
|
||||
|
||||
You: Let's tackle the data fetching issue.
|
||||
|
||||
You: /opsx:new optimize-product-list-fetching
|
||||
|
||||
AI: Created change. Ready to create: proposal
|
||||
|
||||
You: /opsx:continue
|
||||
|
||||
AI: Creating proposal based on our exploration...
|
||||
[Writes proposal incorporating investigation insights]
|
||||
|
||||
Ready to create: specs, design
|
||||
Which would you like next?
|
||||
|
||||
You: /opsx:continue
|
||||
|
||||
AI: Creating specs...
|
||||
```
|
||||
|
||||
**Best for:** Performance optimization, debugging, architectural decisions, unclear requirements.
|
||||
|
||||
### Parallel Changes
|
||||
|
||||
Work on multiple changes at once:
|
||||
|
||||
```text
|
||||
Change A: /opsx:new ──► /opsx:ff ──► /opsx:apply (in progress)
|
||||
│
|
||||
context switch
|
||||
│
|
||||
Change B: /opsx:new ──► /opsx:ff ──────► /opsx:apply
|
||||
```
|
||||
|
||||
**Example conversation:**
|
||||
|
||||
```text
|
||||
You: I'm working on add-dark-mode but got pulled into a bug fix
|
||||
|
||||
You: /opsx:new fix-login-redirect
|
||||
|
||||
AI: Created openspec/changes/fix-login-redirect/
|
||||
|
||||
You: /opsx:ff
|
||||
|
||||
AI: ✓ Created planning artifacts
|
||||
|
||||
You: /opsx:apply
|
||||
|
||||
AI: Working on fix-login-redirect...
|
||||
[Implements the fix]
|
||||
All tasks complete!
|
||||
|
||||
You: /opsx:archive
|
||||
|
||||
AI: ✓ Archived fix-login-redirect
|
||||
|
||||
You: Let's get back to dark mode
|
||||
|
||||
You: /opsx:apply add-dark-mode
|
||||
|
||||
AI: Resuming add-dark-mode...
|
||||
Picking up at task 2.3: Update Header...
|
||||
```
|
||||
|
||||
**Best for:** Parallel work streams, urgent interrupts, team collaboration.
|
||||
|
||||
When you have multiple completed changes, use `/opsx:bulk-archive`:
|
||||
|
||||
```text
|
||||
You: /opsx:bulk-archive
|
||||
|
||||
AI: Found 3 completed changes:
|
||||
- add-dark-mode (all tasks done)
|
||||
- fix-login-redirect (all tasks done)
|
||||
- update-footer (all tasks done)
|
||||
|
||||
Checking for spec conflicts...
|
||||
⚠ add-dark-mode and update-footer both touch specs/ui/
|
||||
|
||||
Inspecting codebase to resolve...
|
||||
Both changes are implemented. Will apply in chronological order.
|
||||
|
||||
Archive all 3 changes?
|
||||
|
||||
You: Yes
|
||||
|
||||
AI: ✓ Archived add-dark-mode
|
||||
✓ Archived fix-login-redirect
|
||||
✓ Archived update-footer
|
||||
Specs merged in order: add-dark-mode → update-footer
|
||||
```
|
||||
|
||||
Bulk archive detects when multiple changes touch the same specs and resolves conflicts by checking what's actually implemented.
|
||||
|
||||
### Completing a Change
|
||||
|
||||
The recommended completion flow:
|
||||
|
||||
```text
|
||||
/opsx:apply ──► /opsx:verify ──► /opsx:archive
|
||||
│ │
|
||||
validates prompts to sync
|
||||
implementation if needed
|
||||
```
|
||||
|
||||
#### Verify: Check Your Work
|
||||
|
||||
`/opsx:verify` validates implementation against your artifacts across three dimensions:
|
||||
|
||||
```text
|
||||
You: /opsx:verify
|
||||
|
||||
AI: Verifying add-auth...
|
||||
|
||||
COMPLETENESS
|
||||
✓ All 12 tasks in tasks.md are checked
|
||||
✓ All requirements in specs have corresponding code
|
||||
⚠ Scenario "Session timeout after inactivity" not tested
|
||||
|
||||
CORRECTNESS
|
||||
✓ Implementation matches spec intent
|
||||
✓ Edge cases from scenarios are handled
|
||||
✓ Error states match spec definitions
|
||||
|
||||
COHERENCE
|
||||
✓ Design decisions reflected in code structure
|
||||
✓ Naming conventions consistent with design.md
|
||||
⚠ Design mentions "event-driven" but implementation uses polling
|
||||
|
||||
SUMMARY
|
||||
─────────────────────────────
|
||||
Critical issues: 0
|
||||
Warnings: 2
|
||||
Ready to archive: Yes (with warnings)
|
||||
|
||||
Recommendations:
|
||||
1. Add test for session timeout scenario
|
||||
2. Consider refactoring to event-driven as designed, or update design.md
|
||||
```
|
||||
|
||||
**What verify checks:**
|
||||
|
||||
| Dimension | What it validates |
|
||||
|-----------|------------------|
|
||||
| Completeness | All tasks done, all requirements implemented, scenarios covered |
|
||||
| Correctness | Implementation matches spec intent, edge cases handled |
|
||||
| Coherence | Design decisions reflected in code, patterns consistent |
|
||||
|
||||
Verify won't block archive, but it surfaces issues you might want to address first.
|
||||
|
||||
#### Archive: Finalize the Change
|
||||
|
||||
`/opsx:archive` completes the change and moves it to the archive:
|
||||
|
||||
```text
|
||||
You: /opsx:archive
|
||||
|
||||
AI: Archiving add-auth...
|
||||
|
||||
Artifact status:
|
||||
✓ proposal.md exists
|
||||
✓ specs/ exists
|
||||
✓ design.md exists
|
||||
✓ tasks.md exists (12/12 tasks complete)
|
||||
|
||||
Delta specs: Not yet synced to main
|
||||
→ Would you like to sync now?
|
||||
|
||||
You: Yes
|
||||
|
||||
AI: ✓ Synced specs to openspec/specs/auth/spec.md
|
||||
✓ Moved to openspec/changes/archive/2025-01-24-add-auth/
|
||||
|
||||
Change archived successfully.
|
||||
```
|
||||
|
||||
Archive will prompt if specs aren't synced. It won't block on incomplete tasks, but it will warn you.
|
||||
|
||||
## When to Use What
|
||||
|
||||
### `/opsx:ff` vs `/opsx:continue`
|
||||
|
||||
| Situation | Use |
|
||||
|-----------|-----|
|
||||
| Clear requirements, ready to build | `/opsx:ff` |
|
||||
| Exploring, want to review each step | `/opsx:continue` |
|
||||
| Want to iterate on proposal before specs | `/opsx:continue` |
|
||||
| Time pressure, need to move fast | `/opsx:ff` |
|
||||
| Complex change, want control | `/opsx:continue` |
|
||||
|
||||
**Rule of thumb:** If you can describe the full scope upfront, use `/opsx:ff`. If you're figuring it out as you go, use `/opsx:continue`.
|
||||
|
||||
### When to Update vs Start Fresh
|
||||
|
||||
A common question: when is updating an existing change okay, and when should you start a new one?
|
||||
|
||||
**Update the existing change when:**
|
||||
|
||||
- Same intent, refined execution
|
||||
- Scope narrows (MVP first, rest later)
|
||||
- Learning-driven corrections (codebase isn't what you expected)
|
||||
- Design tweaks based on implementation discoveries
|
||||
|
||||
**Start a new change when:**
|
||||
|
||||
- Intent fundamentally changed
|
||||
- Scope exploded to different work entirely
|
||||
- Original change can be marked "done" standalone
|
||||
- Patches would confuse more than clarify
|
||||
|
||||
```text
|
||||
┌─────────────────────────────────────┐
|
||||
│ Is this the same work? │
|
||||
└──────────────┬──────────────────────┘
|
||||
│
|
||||
┌──────────────────┼──────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
Same intent? >50% overlap? Can original
|
||||
Same problem? Same scope? be "done" without
|
||||
│ │ these changes?
|
||||
│ │ │
|
||||
┌────────┴────────┐ ┌──────┴──────┐ ┌───────┴───────┐
|
||||
│ │ │ │ │ │
|
||||
YES NO YES NO NO YES
|
||||
│ │ │ │ │ │
|
||||
▼ ▼ ▼ ▼ ▼ ▼
|
||||
UPDATE NEW UPDATE NEW UPDATE NEW
|
||||
```
|
||||
|
||||
**Example: "Add dark mode"**
|
||||
|
||||
- "Need to also support custom themes" → New change (scope exploded)
|
||||
- "System preference detection is harder than expected" → Update (same intent)
|
||||
- "Let's ship toggle first, add preferences later" → Update then archive, then new change
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Keep Changes Focused
|
||||
|
||||
One logical unit of work per change. If you're doing "add feature X and also refactor Y", consider two separate changes.
|
||||
|
||||
**Why it matters:**
|
||||
- Easier to review and understand
|
||||
- Cleaner archive history
|
||||
- Can ship independently
|
||||
- Simpler rollback if needed
|
||||
|
||||
### Use `/opsx:explore` for Unclear Requirements
|
||||
|
||||
Before committing to a change, explore the problem space:
|
||||
|
||||
```text
|
||||
You: /opsx:explore
|
||||
|
||||
AI: What would you like to explore?
|
||||
|
||||
You: How should we handle rate limiting for our API?
|
||||
|
||||
AI: Let me investigate your current setup and options...
|
||||
[Researches codebase, considers patterns]
|
||||
|
||||
I see three approaches we could take:
|
||||
1. Middleware-based (simple, per-endpoint)
|
||||
2. Redis-backed (scalable, shared state)
|
||||
3. Token bucket per user (fair, complex)
|
||||
|
||||
Your current stack suggests #1 or #2. What's your scale?
|
||||
```
|
||||
|
||||
Exploration clarifies thinking before you create artifacts.
|
||||
|
||||
### Verify Before Archiving
|
||||
|
||||
Use `/opsx:verify` to check implementation matches artifacts:
|
||||
|
||||
```text
|
||||
You: /opsx:verify
|
||||
|
||||
AI: Verifying add-dark-mode...
|
||||
|
||||
✓ All tasks in tasks.md are checked
|
||||
✓ Requirements in specs have corresponding code
|
||||
✓ Design decisions are reflected in implementation
|
||||
|
||||
Ready to archive!
|
||||
```
|
||||
|
||||
Catches mismatches before you close out the change.
|
||||
|
||||
### Name Changes Clearly
|
||||
|
||||
Good names make `openspec list` useful:
|
||||
|
||||
```text
|
||||
Good: Avoid:
|
||||
add-dark-mode feature-1
|
||||
fix-login-redirect update
|
||||
optimize-product-query changes
|
||||
implement-2fa wip
|
||||
```
|
||||
|
||||
## Command Quick Reference
|
||||
|
||||
For full command details and options, see [Commands](commands.md).
|
||||
|
||||
| Command | Purpose | When to Use |
|
||||
|---------|---------|-------------|
|
||||
| `/opsx:propose` | Create change + planning artifacts | Fast default path (`core` profile) |
|
||||
| `/opsx:explore` | Think through ideas | Unclear requirements, investigation |
|
||||
| `/opsx:new` | Start a change scaffold | Expanded mode, explicit artifact control |
|
||||
| `/opsx:continue` | Create next artifact | Expanded mode, step-by-step artifact creation |
|
||||
| `/opsx:ff` | Create all planning artifacts | Expanded mode, clear scope |
|
||||
| `/opsx:apply` | Implement tasks | Ready to write code |
|
||||
| `/opsx:verify` | Validate implementation | Expanded mode, before archiving |
|
||||
| `/opsx:sync` | Merge delta specs | Expanded mode, optional |
|
||||
| `/opsx:archive` | Complete the change | All work finished |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes | Expanded mode, parallel work |
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Commands](commands.md) - Full command reference with options
|
||||
- [Concepts](concepts.md) - Deep dive into specs, artifacts, and schemas
|
||||
- [Customization](customization.md) - Create custom workflows
|
||||
@@ -0,0 +1,494 @@
|
||||
# Workspace Demo
|
||||
|
||||
This guide is for using workspace mode with **real repos on your machine**.
|
||||
|
||||
It is written as a dogfood tutorial:
|
||||
|
||||
- use the actual `openspec` repo checkout you already have
|
||||
- optionally add one or two more real repos if you want to exercise the multi-repo parts more fully
|
||||
- create a real managed workspace
|
||||
- try the commands in the order a real user would
|
||||
|
||||
If you only have the `openspec` repo available right now, you can still run the core flow. If you also have a second or third repo handy, the guide points out the extra things worth trying.
|
||||
|
||||
## What you will exercise
|
||||
|
||||
- creating a managed workspace
|
||||
- registering real repos with stable aliases
|
||||
- using `workspace doctor`
|
||||
- creating a workspace change with explicit targets
|
||||
- workspace-root and change-scoped `workspace open`
|
||||
- Codex and GitHub Copilot workspace-open flows
|
||||
- `status` as the coordination view
|
||||
- `apply` as the handoff into repo-local execution
|
||||
- optional target mutation before apply
|
||||
- optional guardrails after apply
|
||||
- optional workspace archive at the end
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- `openspec` is installed and available on your `PATH`
|
||||
- Node.js `20.19.0+`
|
||||
- `git` is available
|
||||
- optional: VS Code with GitHub Copilot if you want to try the Copilot path
|
||||
|
||||
If you are running from this repo checkout instead of a global install, replace `openspec` below with:
|
||||
|
||||
```bash
|
||||
node /absolute/path/to/openspec/bin/openspec.js
|
||||
```
|
||||
|
||||
## 1. Pick the real repos you want to coordinate
|
||||
|
||||
Start in the root of the real `openspec` repo you want to use:
|
||||
|
||||
```bash
|
||||
cd /path/to/your/openspec/repo
|
||||
pwd
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- this repo path is the one repo this guide assumes you definitely have
|
||||
- additional repos are optional, but they make workspace mode much more interesting
|
||||
- You can use any real repos here, not just repos related to OpenSpec.
|
||||
|
||||
## 2. Make sure each repo has repo-local OpenSpec state
|
||||
|
||||
`workspace add-repo` only accepts repos that already contain repo-local OpenSpec state, which means the repo has an `openspec/` directory.
|
||||
|
||||
Check the `openspec` repo:
|
||||
|
||||
```bash
|
||||
test -d /path/to/your/openspec/repo/openspec && echo "openspec repo is ready"
|
||||
```
|
||||
|
||||
If you are adding other repos, initialize them if needed:
|
||||
|
||||
```bash
|
||||
openspec init /absolute/path/to/another/repo --tools none --force
|
||||
```
|
||||
|
||||
Only run that command for repos that do not already have `openspec/`.
|
||||
|
||||
## 3. Use the setup wizard the way a real user would
|
||||
|
||||
The recommended onboarding path is:
|
||||
|
||||
```bash
|
||||
openspec workspace setup
|
||||
```
|
||||
|
||||
Use these answers when prompted:
|
||||
|
||||
```text
|
||||
Workspace name: openspec-dogfood
|
||||
Repo path: /absolute/path/to/your/openspec/repo
|
||||
Repo alias: openspec
|
||||
Owner (optional): OpenSpec Core
|
||||
Handoff note (optional): Apply when the shared plan is ready
|
||||
Add another repo? n
|
||||
Open the workspace now? y
|
||||
Which agent should OpenSpec prepare for? codex
|
||||
```
|
||||
|
||||
If you also want to register more repos, answer `y` to `Add another repo?` and keep going until the wizard reaches the summary.
|
||||
|
||||
At the end of the wizard, `cd` into the created workspace. If you used the workspace name above, the default path is:
|
||||
|
||||
```bash
|
||||
cd "$HOME/.local/share/openspec/workspaces/openspec-dogfood"
|
||||
pwd
|
||||
```
|
||||
|
||||
What to check:
|
||||
|
||||
- you are now inside the managed workspace root
|
||||
- these files exist:
|
||||
- `.openspec/workspace.yaml`
|
||||
- `.openspec/local.yaml`
|
||||
- `changes/`
|
||||
|
||||
Quick inspection:
|
||||
|
||||
```bash
|
||||
find . -maxdepth 2 -type f | sort
|
||||
sed -n '1,200p' .gitignore
|
||||
```
|
||||
|
||||
What to notice:
|
||||
|
||||
- the workspace is separate from any one repo
|
||||
- `.openspec/local.yaml` is machine-local state
|
||||
- `/.openspec/workspace-open/` is ignored because workspace-open may generate local artifacts there
|
||||
|
||||
If you want to understand the lower-level equivalent, it is:
|
||||
|
||||
```bash
|
||||
openspec workspace create openspec-dogfood
|
||||
openspec workspace add-repo openspec /absolute/path/to/your/openspec/repo --owner "OpenSpec Core" --handoff "Apply when the shared plan is ready"
|
||||
cd "$HOME/.local/share/openspec/workspaces/openspec-dogfood"
|
||||
```
|
||||
|
||||
## 4. Register additional real repos if you want a broader test
|
||||
|
||||
If you only want to test the single-repo flow, you can skip this section because the wizard already registered `openspec`.
|
||||
|
||||
If you have more repos, register them now:
|
||||
|
||||
```bash
|
||||
openspec workspace add-repo consumer /absolute/path/to/another/repo --owner "Consumer Team" --handoff "Pick up once the core contract is stable"
|
||||
openspec workspace add-repo docs /absolute/path/to/a/docs-repo --owner "Docs Team" --handoff "Document the rollout after implementation lands"
|
||||
```
|
||||
|
||||
Now validate the workspace registry:
|
||||
|
||||
```bash
|
||||
openspec workspace doctor
|
||||
sed -n '1,200p' .openspec/workspace.yaml
|
||||
sed -n '1,200p' .openspec/local.yaml
|
||||
```
|
||||
|
||||
What to notice:
|
||||
|
||||
- `workspace.yaml` holds alias metadata you could share or commit
|
||||
- `local.yaml` holds machine-local repo paths
|
||||
- `workspace doctor` is the first thing to run if the registry feels wrong later
|
||||
|
||||
## 5. Create a real workspace change
|
||||
|
||||
Choose one of these commands based on the aliases you actually want to coordinate.
|
||||
|
||||
Single-repo flow:
|
||||
|
||||
```bash
|
||||
openspec new change workspace-dogfood --targets openspec
|
||||
```
|
||||
|
||||
Two-repo flow:
|
||||
|
||||
```bash
|
||||
openspec new change workspace-dogfood --targets openspec,consumer
|
||||
```
|
||||
|
||||
Three-repo flow:
|
||||
|
||||
```bash
|
||||
openspec new change workspace-dogfood --targets openspec,consumer,docs
|
||||
```
|
||||
|
||||
Inspect what was created:
|
||||
|
||||
```bash
|
||||
find changes/workspace-dogfood -maxdepth 3 -type f | sort
|
||||
sed -n '1,200p' changes/workspace-dogfood/proposal.md
|
||||
sed -n '1,200p' changes/workspace-dogfood/design.md
|
||||
sed -n '1,200p' changes/workspace-dogfood/tasks/coordination.md
|
||||
```
|
||||
|
||||
If you targeted more than one repo, also inspect the draft slices:
|
||||
|
||||
```bash
|
||||
find changes/workspace-dogfood/targets -maxdepth 2 -type f | sort
|
||||
```
|
||||
|
||||
What to notice:
|
||||
|
||||
- the workspace owns the shared planning artifacts
|
||||
- the target repo drafts live under `targets/<alias>/`
|
||||
- no repo-local change exists yet in any repo
|
||||
|
||||
Confirm that for the `openspec` repo:
|
||||
|
||||
```bash
|
||||
test ! -e /path/to/your/openspec/repo/openspec/changes/workspace-dogfood && echo "openspec repo not materialized yet"
|
||||
```
|
||||
|
||||
## 6. Try `workspace open` in the order a real user would
|
||||
|
||||
### 6a. Root coordination open
|
||||
|
||||
```bash
|
||||
openspec workspace open
|
||||
```
|
||||
|
||||
What to look for:
|
||||
|
||||
- your preferred agent should launch
|
||||
- the session should open in workspace-root mode
|
||||
- `Attached repos:` should list the registered repos with valid local paths
|
||||
- the agent should have the registered repos, repo inventory, and active workspace changes available for coordination
|
||||
|
||||
If you want to inspect the prepared surface without launching the agent:
|
||||
|
||||
```bash
|
||||
openspec workspace open --prepare-only
|
||||
```
|
||||
|
||||
### 6b. Change-scoped open for the default agent
|
||||
|
||||
```bash
|
||||
openspec workspace open --change workspace-dogfood
|
||||
```
|
||||
|
||||
What to look for:
|
||||
|
||||
- your preferred agent should launch again, now change-scoped
|
||||
- only the targeted aliases should appear
|
||||
- owner and handoff notes should appear
|
||||
- non-targeted repos should not appear
|
||||
|
||||
If you want to inspect the prepared surface without launching the agent:
|
||||
|
||||
```bash
|
||||
openspec workspace open --change workspace-dogfood --prepare-only
|
||||
```
|
||||
|
||||
### 6c. Change-scoped open for Codex
|
||||
|
||||
```bash
|
||||
openspec workspace open --change workspace-dogfood --agent codex
|
||||
```
|
||||
|
||||
What to look for:
|
||||
|
||||
- Codex should launch with the workspace root plus only the targeted repos attached
|
||||
- the session should stay scoped to the targeted repos
|
||||
|
||||
If you want to inspect the generated prompt surface without launching Codex:
|
||||
|
||||
```bash
|
||||
openspec workspace open --change workspace-dogfood --agent codex --prepare-only
|
||||
```
|
||||
|
||||
### 6d. Change-scoped open for GitHub Copilot in VS Code
|
||||
|
||||
```bash
|
||||
openspec workspace open --change workspace-dogfood --agent github-copilot
|
||||
```
|
||||
|
||||
Inspect the generated artifacts:
|
||||
|
||||
```bash
|
||||
sed -n '1,200p' .github/prompts/opsx-workspace-open.prompt.md
|
||||
sed -n '1,200p' .openspec/workspace-open/github-copilot/workspace-dogfood.code-workspace
|
||||
```
|
||||
|
||||
What to notice:
|
||||
|
||||
- the prompt file lives under `.github/prompts/`
|
||||
- the VS Code workspace file lives under `.openspec/workspace-open/github-copilot/`
|
||||
- the `.code-workspace` file includes:
|
||||
- the workspace root
|
||||
- only the targeted repos
|
||||
|
||||
If you have VS Code installed, open the generated workspace:
|
||||
|
||||
```bash
|
||||
code .openspec/workspace-open/github-copilot/workspace-dogfood.code-workspace
|
||||
```
|
||||
|
||||
This is the real Copilot path: open the generated VS Code workspace and use Copilot there.
|
||||
|
||||
## 7. Use `status` as your control plane
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
openspec status --change workspace-dogfood
|
||||
openspec status --change workspace-dogfood --json
|
||||
```
|
||||
|
||||
What to look for:
|
||||
|
||||
- overall change state
|
||||
- target-by-target progress
|
||||
- owner and handoff notes
|
||||
- the next recommended step
|
||||
|
||||
This is the main command to re-enter an in-flight cross-repo change later.
|
||||
|
||||
## 8. Optional: try target-set changes before apply
|
||||
|
||||
This section is only interesting if you registered at least one repo that is **not** already in the change target list.
|
||||
|
||||
For example, if you registered `docs` but did not target it yet:
|
||||
|
||||
```bash
|
||||
openspec workspace targets workspace-dogfood --add docs
|
||||
find changes/workspace-dogfood/targets -maxdepth 2 -type f | sort
|
||||
openspec status --change workspace-dogfood
|
||||
```
|
||||
|
||||
What to notice:
|
||||
|
||||
- the `docs` target draft gets scaffolded
|
||||
- `status` now includes `docs`
|
||||
|
||||
Now remove it again before any apply:
|
||||
|
||||
```bash
|
||||
openspec workspace targets workspace-dogfood --remove docs
|
||||
find changes/workspace-dogfood/targets -maxdepth 2 -type f | sort
|
||||
openspec status --change workspace-dogfood
|
||||
```
|
||||
|
||||
What to notice:
|
||||
|
||||
- removing an unmaterialized target is allowed
|
||||
- the remaining targets stay intact
|
||||
|
||||
## 9. Materialize one real repo
|
||||
|
||||
Now hand execution off into the `openspec` repo:
|
||||
|
||||
```bash
|
||||
openspec apply --change workspace-dogfood --repo openspec
|
||||
openspec status --change workspace-dogfood
|
||||
find /path/to/your/openspec/repo/openspec/changes/workspace-dogfood -maxdepth 3 -type f | sort
|
||||
sed -n '1,200p' /path/to/your/openspec/repo/openspec/changes/workspace-dogfood/tasks.md
|
||||
```
|
||||
|
||||
What to notice:
|
||||
|
||||
- the workspace change still exists
|
||||
- the `openspec` repo now has a repo-local change
|
||||
- the source of truth for execution of that slice has moved into the repo
|
||||
|
||||
This is the core handoff:
|
||||
|
||||
- plan centrally
|
||||
- execute locally
|
||||
|
||||
## 10. Optional: trigger a guardrail after apply
|
||||
|
||||
Once a repo has crossed into repo-local execution, try to remove it from the target set:
|
||||
|
||||
```bash
|
||||
openspec workspace targets workspace-dogfood --remove openspec
|
||||
```
|
||||
|
||||
This should fail.
|
||||
|
||||
What to learn:
|
||||
|
||||
- workspace target mutation is allowed only while the alias is still workspace-owned
|
||||
- after apply, the workspace refuses to silently rewrite the target set around a repo-local slice
|
||||
|
||||
## 11. Continue from inside the real repo
|
||||
|
||||
Now switch into the `openspec` repo and look at the repo-local change directly:
|
||||
|
||||
```bash
|
||||
cd /path/to/your/openspec/repo
|
||||
find openspec/changes/workspace-dogfood -maxdepth 3 -type f | sort
|
||||
sed -n '1,200p' openspec/changes/workspace-dogfood/tasks.md
|
||||
```
|
||||
|
||||
This is where you would now do real implementation work.
|
||||
|
||||
When you want the workspace view again:
|
||||
|
||||
```bash
|
||||
cd "$HOME/.local/share/openspec/workspaces/openspec-dogfood"
|
||||
openspec status --change workspace-dogfood
|
||||
```
|
||||
|
||||
## 12. Optional: test `workspace doctor` on a real broken path
|
||||
|
||||
If you want to see the repair flow, temporarily break one alias in `.openspec/local.yaml`.
|
||||
|
||||
The simplest safe way is:
|
||||
|
||||
1. open `.openspec/local.yaml`
|
||||
2. replace one repo path with a missing path like `/tmp/does-not-exist`
|
||||
3. run:
|
||||
|
||||
```bash
|
||||
openspec workspace doctor
|
||||
openspec status --change workspace-dogfood
|
||||
```
|
||||
|
||||
Then repair the path in `.openspec/local.yaml` and run:
|
||||
|
||||
```bash
|
||||
openspec workspace doctor
|
||||
```
|
||||
|
||||
What to learn:
|
||||
|
||||
- broken local paths are a **doctor** problem
|
||||
- the fix belongs in `local.yaml`, not in the shared workspace metadata
|
||||
|
||||
## 13. Optional: complete and archive the full flow
|
||||
|
||||
If you want to exercise the whole lifecycle, finish the tasks and archive the repo-local change.
|
||||
|
||||
In the `openspec` repo:
|
||||
|
||||
```bash
|
||||
cd /path/to/your/openspec/repo
|
||||
perl -0pi -e 's/- \[ \]/- [x]/g' openspec/changes/workspace-dogfood/tasks.md
|
||||
openspec archive workspace-dogfood --yes --skip-specs --no-validate
|
||||
```
|
||||
|
||||
Back in the workspace:
|
||||
|
||||
```bash
|
||||
cd "$HOME/.local/share/openspec/workspaces/openspec-dogfood"
|
||||
perl -0pi -e 's/- \[ \]/- [x]/g' changes/workspace-dogfood/tasks/coordination.md
|
||||
openspec status --change workspace-dogfood
|
||||
openspec archive workspace-dogfood --workspace
|
||||
openspec status --change workspace-dogfood
|
||||
```
|
||||
|
||||
What to notice:
|
||||
|
||||
- repo-local archive and workspace archive are distinct
|
||||
- the workspace archive is the explicit “this cross-repo change is done” step
|
||||
|
||||
## 14. The re-entry flow you will actually use later
|
||||
|
||||
Once you have a real workspace in use, this is the normal re-entry sequence:
|
||||
|
||||
```bash
|
||||
cd "$HOME/.local/share/openspec/workspaces/openspec-dogfood"
|
||||
openspec status --change workspace-dogfood
|
||||
openspec workspace open --change workspace-dogfood
|
||||
openspec workspace open --change workspace-dogfood --agent codex
|
||||
openspec workspace open --change workspace-dogfood --agent github-copilot
|
||||
```
|
||||
|
||||
Use:
|
||||
|
||||
- `status` to understand current state and next action
|
||||
- `workspace open` to relaunch the root or change-scoped session
|
||||
- `workspace doctor` if aliases or paths look stale
|
||||
- `apply` only when you are ready to hand execution off into a repo
|
||||
|
||||
## If you want to remove the workspace later
|
||||
|
||||
The workspace is just a managed directory under:
|
||||
|
||||
```bash
|
||||
$HOME/.local/share/openspec/workspaces/
|
||||
```
|
||||
|
||||
So if you want to discard this dogfood workspace after testing:
|
||||
|
||||
```bash
|
||||
rm -rf "$HOME/.local/share/openspec/workspaces/openspec-dogfood"
|
||||
```
|
||||
|
||||
That does **not** delete your registered repos. It only deletes the coordination root.
|
||||
|
||||
## Optional convenience shortcuts
|
||||
|
||||
If you end up using the same repos repeatedly, you can set shell variables to avoid retyping long paths:
|
||||
|
||||
```bash
|
||||
export OPENSPEC_REPO="/path/to/your/openspec/repo"
|
||||
export WORKSPACE_ROOT="$HOME/.local/share/openspec/workspaces/openspec-dogfood"
|
||||
```
|
||||
|
||||
Those shortcuts are optional. They are not required for the walkthrough above.
|
||||
@@ -0,0 +1,130 @@
|
||||
# Workspace Mode
|
||||
|
||||
Workspace mode is the cross-repo coordination path for OpenSpec. It gives you one planning home for a change that spans multiple repositories, while keeping canonical specs and execution owned by the real repos.
|
||||
|
||||
## When To Use Workspace Mode
|
||||
|
||||
Use workspace mode when repo-local OpenSpec is no longer an honest representation of the work.
|
||||
|
||||
Typical signals:
|
||||
|
||||
- one change spans two or more repos
|
||||
- the canonical contract owner is different from one or more implementation repos
|
||||
- repos or teams need to move at different cadences
|
||||
- you need one place to pause, resume, or hand off a cross-repo change
|
||||
|
||||
Stay repo-local when:
|
||||
|
||||
- the work fits in one repo
|
||||
- the same repo owns planning, implementation, and archive
|
||||
- you do not need a separate coordination surface
|
||||
|
||||
Rule of thumb:
|
||||
|
||||
> Plan centrally, execute locally, preserve repo ownership.
|
||||
|
||||
Need a runnable walkthrough instead of a reference page? See [Workspace Demo](workspace-demo.md).
|
||||
|
||||
## Recommended First Run
|
||||
|
||||
Most people should start with the guided setup wizard:
|
||||
|
||||
```bash
|
||||
openspec workspace setup
|
||||
```
|
||||
|
||||
That flow:
|
||||
|
||||
1. creates the managed workspace root
|
||||
2. prompts for one or more repo paths and aliases
|
||||
3. stores optional owner and handoff notes
|
||||
4. runs `openspec workspace doctor`
|
||||
5. stores a preferred workspace-open agent in `.openspec/local.yaml`
|
||||
6. offers to open the workspace immediately using that preferred agent
|
||||
|
||||
Use the lower-level commands directly when you already know the exact workspace shape you want or when you are scripting against the workspace model.
|
||||
|
||||
## Supported CLI Flow
|
||||
|
||||
The current supported v0 flow is:
|
||||
|
||||
```bash
|
||||
openspec workspace setup
|
||||
openspec workspace list
|
||||
openspec new change <id> --targets <alias-a,alias-b>
|
||||
openspec workspace targets <id> --add <alias-c> --remove <alias-d>
|
||||
openspec workspace open [--change <id>] [--name <workspace>] [--agent claude|codex|github-copilot] [--prepare-only]
|
||||
openspec apply --change <id> --repo <alias>
|
||||
openspec status --change <id>
|
||||
```
|
||||
|
||||
The equivalent manual setup path is:
|
||||
|
||||
```bash
|
||||
openspec workspace create <name>
|
||||
openspec workspace add-repo <alias> <path> [--owner "<team or person>"] [--handoff "<next step>"]
|
||||
```
|
||||
|
||||
What each step does:
|
||||
|
||||
1. `workspace setup` is the onboarding path. It creates the workspace, registers repos, validates the registry, stores a preferred workspace-open agent, and can optionally launch the workspace immediately.
|
||||
2. `workspace list` shows the locally managed workspaces OpenSpec knows about.
|
||||
3. `workspace create` and `workspace add-repo` remain the manual setup path. `workspace create` creates a managed coordination root with `.openspec/` metadata and top-level `changes/`. `workspace add-repo` registers stable repo aliases. Repo paths stay local in `.openspec/local.yaml`. Optional owner and handoff notes are committed in `.openspec/workspace.yaml`.
|
||||
4. `new change --targets` creates one workspace change with shared planning artifacts plus per-target draft slices.
|
||||
5. `workspace targets <id>` adjusts the target set without manual file edits. It scaffolds added draft slices, removes unmaterialized draft slices, and refuses add or remove mutations once the same change ID already has repo-local execution or archive state for that alias.
|
||||
6. `workspace open` launches a workspace-root coordination session. If you are already inside a workspace root, it uses that workspace. If you are outside a workspace and only one managed workspace exists, it uses that automatically. If multiple managed workspaces exist, it prompts interactively or you can pass `--name <workspace>`. When you omit `--agent`, OpenSpec uses the preferred agent stored during setup, or prompts once and persists it for older workspaces with no stored preference.
|
||||
7. Workspace-root mode opens the workspace working set: the coordination root plus registered repos with valid local paths. It also gives the agent the registered repo inventory, owner or handoff notes, and active workspace changes so it can explore before proposal creation.
|
||||
8. `workspace open --change <id>` adds focused change context for an existing workspace change. Use `--agent codex` when you want Codex launched with the workspace working set attached, or `--agent github-copilot` when you want VS Code opened on a generated `.code-workspace` file.
|
||||
9. `workspace open --prepare-only` or `workspace open --json` prepares the surfaces without launching an external tool. Use that when you want to inspect or script the generated state.
|
||||
10. `apply --change <id> --repo <alias>` materializes one repo-local execution surface. After that point, repo-local execution remains local to that repo.
|
||||
11. `status --change <id>` from the workspace root rolls up coordination state, repo progress, blockers, owner or handoff notes, and the next action.
|
||||
|
||||
## Re-Enter An Existing Workspace
|
||||
|
||||
When you return to an in-flight cross-repo change:
|
||||
|
||||
1. Run `openspec status --change <id>` to see the overall state, affected repos, owner or handoff notes, and the next step.
|
||||
2. Run `openspec workspace open` when you want the root coordination session. You can run this from anywhere if OpenSpec can uniquely resolve the workspace. Add `--name <workspace>` when more than one managed workspace exists.
|
||||
3. Run `openspec workspace open --change <id>` when you want the current planning context reopened with just the targeted repos in view.
|
||||
4. Run `openspec workspace targets <id> --add <alias>` or `--remove <alias>` if the repo scope changed and that alias has not already crossed into repo-local execution for the same change ID.
|
||||
5. Run `openspec workspace doctor` if `status` reports a stale or missing repo alias.
|
||||
|
||||
If you need to explore or plan across the workspace, `openspec workspace open` without `--change` launches the workspace-root session with registered repo roots attached. The supported workspace-open agents are `claude`, `codex`, and `github-copilot`. The default agent comes from the workspace-local preferred agent stored in `.openspec/local.yaml`.
|
||||
|
||||
If you create a targeted workspace change from a launched root session, stop after the change is created. OpenSpec records that scope upgrade and reopens the next session change-scoped. Today that automatic upgrade is implemented as a relaunch or continue flow for Claude and Codex, not a live directory attach inside the existing TUI.
|
||||
|
||||
For GitHub Copilot, `workspace open` targets VS Code rather than Copilot CLI:
|
||||
|
||||
- it writes the scoped prompt file to `.github/prompts/opsx-workspace-open.prompt.md`
|
||||
- it writes a managed `.code-workspace` file under `.openspec/workspace-open/github-copilot/`
|
||||
- in workspace-root mode that workspace file includes the coordination root plus registered repos with valid local paths
|
||||
- in change-scoped mode it includes the coordination root plus only the targeted repos
|
||||
|
||||
## Hand Off Work To Another Repo Owner
|
||||
|
||||
Owner and handoff metadata are lightweight coordination notes for the workspace registry:
|
||||
|
||||
- `--owner` is the repo owner, primary contact, or team that should own the repo-local slice.
|
||||
- `--handoff` is the short next-step note another engineer should follow when they pick up that repo.
|
||||
|
||||
You can add or update those notes later without changing local repo paths:
|
||||
|
||||
```bash
|
||||
openspec workspace update-repo <alias> --owner "<team or person>" --handoff "<next step>"
|
||||
```
|
||||
|
||||
You can also adjust the target set later without editing `.openspec.yaml` by hand:
|
||||
|
||||
```bash
|
||||
openspec workspace targets <id> --add <alias-a,alias-b>
|
||||
openspec workspace targets <id> --remove <alias-c>
|
||||
```
|
||||
|
||||
That command keeps authority handoff explicit. If the same change ID already exists or was already archived in a target repo, `workspace targets` fails instead of silently mutating the workspace target set around repo-local execution.
|
||||
|
||||
The committed workspace metadata stays machine-safe:
|
||||
|
||||
- `.openspec/workspace.yaml` stores aliases plus optional owner or handoff notes
|
||||
- `.openspec/local.yaml` stores machine-specific repo paths
|
||||
|
||||
That split keeps shared workspace state portable while still letting each machine resolve local repo roots.
|
||||
@@ -0,0 +1,42 @@
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
export default tseslint.config(
|
||||
{
|
||||
files: ['src/**/*.ts'],
|
||||
extends: [...tseslint.configs.recommended],
|
||||
rules: {
|
||||
// Prevent static imports of @inquirer modules to avoid pre-commit hook hangs.
|
||||
// These modules have side effects that can keep the Node.js event loop alive
|
||||
// when stdin is piped. Use dynamic import() instead.
|
||||
// See: https://github.com/Fission-AI/OpenSpec/issues/367
|
||||
'no-restricted-imports': [
|
||||
'error',
|
||||
{
|
||||
patterns: [
|
||||
{
|
||||
group: ['@inquirer/*'],
|
||||
message:
|
||||
'Use dynamic import() for @inquirer modules to prevent pre-commit hook hangs. See #367.',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
// Disable rules that need broader cleanup - focus on critical issues only
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'no-empty': 'off',
|
||||
'prefer-const': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
// init.ts is dynamically imported from cli/index.ts, so static @inquirer
|
||||
// imports there are safe - they won't be loaded at CLI startup
|
||||
files: ['src/core/init.ts'],
|
||||
rules: {
|
||||
'no-restricted-imports': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
ignores: ['dist/**', 'node_modules/**', '*.js', '*.mjs'],
|
||||
}
|
||||
);
|
||||
Generated
+27
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1767640445,
|
||||
"narHash": "sha256-UWYqmD7JFBEDBHWYcqE6s6c77pWdcU/i+bwD6XxMb8A=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9f0c42f8bc7151b8e7e5840fb3bd454ad850d8c5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
{
|
||||
description = "OpenSpec - AI-native system for spec-driven development";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
};
|
||||
|
||||
outputs =
|
||||
{ self, nixpkgs }:
|
||||
let
|
||||
supportedSystems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
"x86_64-darwin"
|
||||
"aarch64-darwin"
|
||||
];
|
||||
|
||||
forAllSystems = f: nixpkgs.lib.genAttrs supportedSystems (system: f system);
|
||||
in
|
||||
{
|
||||
packages = forAllSystems (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
inherit (pkgs) lib;
|
||||
in
|
||||
{
|
||||
default = pkgs.stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "openspec";
|
||||
version = (builtins.fromJSON (builtins.readFile ./package.json)).version;
|
||||
|
||||
src = lib.fileset.toSource {
|
||||
root = ./.;
|
||||
fileset = lib.fileset.unions [
|
||||
./src
|
||||
./bin
|
||||
./schemas
|
||||
./scripts
|
||||
./test
|
||||
./package.json
|
||||
./pnpm-lock.yaml
|
||||
./tsconfig.json
|
||||
./build.js
|
||||
./vitest.config.ts
|
||||
./vitest.setup.ts
|
||||
./eslint.config.js
|
||||
];
|
||||
};
|
||||
|
||||
pnpmDeps = pkgs.fetchPnpmDeps {
|
||||
inherit (finalAttrs) pname version src;
|
||||
pnpm = pkgs.pnpm_9;
|
||||
fetcherVersion = 3;
|
||||
hash = "sha256-9s2kdvd7svK4hofnD66HkDc86WTQeayfF5y7L2dmjNg=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
nodejs_20
|
||||
npmHooks.npmInstallHook
|
||||
pnpmConfigHook
|
||||
pnpm_9
|
||||
];
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
pnpm run build
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
dontNpmPrune = true;
|
||||
|
||||
meta = with pkgs.lib; {
|
||||
description = "AI-native system for spec-driven development";
|
||||
homepage = "https://github.com/Fission-AI/OpenSpec";
|
||||
license = licenses.mit;
|
||||
maintainers = [ ];
|
||||
mainProgram = "openspec";
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
apps = forAllSystems (system: {
|
||||
default = {
|
||||
type = "app";
|
||||
program = "${self.packages.${system}.default}/bin/openspec";
|
||||
};
|
||||
});
|
||||
|
||||
devShells = forAllSystems (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in
|
||||
{
|
||||
default = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
nodejs_20
|
||||
pnpm_9
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
echo "OpenSpec development environment"
|
||||
echo "Node version: $(node --version)"
|
||||
echo "pnpm version: $(pnpm --version)"
|
||||
echo "Run 'pnpm install' to install dependencies"
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
# Decision Space Navigation — Research Session
|
||||
**Date:** 2026-04-07
|
||||
|
||||
## Context
|
||||
|
||||
Exploring whether OpenSpec's linear assembly-line workflow (requirements → design → tasks) can be replaced with a more iterative, non-linear system where users work on any component in any order with continuous feedback.
|
||||
|
||||
---
|
||||
|
||||
## 1. The Starting Point: Assembly Line vs Iterative
|
||||
|
||||
**Current model:** OpenSpec enforces ordering via an ArtifactGraph DAG. Artifacts have hard gates — tasks are blocked until both specs and design are "done."
|
||||
|
||||
**Desired model:** User can work on any part in any order. System provides feedback on what's incomplete/inconsistent, but never blocks.
|
||||
|
||||
### Patterns explored:
|
||||
- **Blackboard Architecture** (1970s, Hearsay-II) — multiple specialists read/write shared state, controller suggests what to work on
|
||||
- **Stigmergy** — agents coordinate by modifying the environment (workspace is the pheromone trail)
|
||||
- **Tuple Spaces / Linda** — decoupled communication through shared memory
|
||||
- **ECS (Entity Component System)** — game engine pattern where systems process entities matching their component signature
|
||||
- **Society of Mind** (Minsky) — intelligence from many simple agents each handling a narrow concern
|
||||
|
||||
### Key design:
|
||||
- **Workspace** — shared state, items with maturity levels (sketch/draft/solid/complete)
|
||||
- **Concerns** — pluggable perspectives defined as YAML prompt files (security, PM, QA, etc.)
|
||||
- **The Loop** — classify → capture → dispatch concerns → surface findings
|
||||
|
||||
---
|
||||
|
||||
## 2. The IDE Analogy — Tested and Found Wanting
|
||||
|
||||
### Hypothesis
|
||||
Background LLM agents act as "language servers" that continuously analyze a shared workspace, like how IDEs surface type errors and lint warnings.
|
||||
|
||||
### Agent debate results (4 agents ran in parallel):
|
||||
|
||||
**The analogy breaks down on the properties that matter most:**
|
||||
|
||||
| IDE Property | Transfers to Specs? | Why |
|
||||
|---|---|---|
|
||||
| Formal grammar | NO | Specs are natural language, no AST |
|
||||
| Objective correctness | PARTIALLY | Some checks are objective (dangling refs), high-value ones are subjective |
|
||||
| Low false positive rate | NO | LLMs hallucinate. >67% false positive rate = users stop looking (IBM SOC research) |
|
||||
| Deterministic trust | NO | Same input → different output. Users can't trust it like a type checker |
|
||||
| Speed (<100ms) | NO | LLM calls are 5-30s. Not ambient, just slow consultation |
|
||||
| Incrementality | PARTIALLY | Specs are small enough for brute-force re-analysis |
|
||||
| Actionability | PARTIALLY | "Add return type here" vs "this section may conflict with section 3" |
|
||||
| Progressive disclosure | YES | Pure UX pattern, transfers cleanly |
|
||||
| Composability | NO | Multiple LLM concerns will contradict each other |
|
||||
|
||||
**Market research confirmed:** No one has shipped a true "IDE for specs" that stuck for general product work. QVscribe works in aerospace/medical (bad requirements kill people). ChatPRD works because it's on-demand, not ambient.
|
||||
|
||||
### What survived the critique:
|
||||
The shift from **review-time to authoring-time** feedback is genuinely valuable. Finding contradictions while writing — not days later in review — is better. The question is delivery mechanism.
|
||||
|
||||
---
|
||||
|
||||
## 3. Ambient Suggestions — The Graveyard and Survivors
|
||||
|
||||
### What died:
|
||||
- **Clippy (1997-2003)** — interruption without intelligence, high dismissal cost, couldn't learn
|
||||
- **Cortana proactive suggestions** — 10% usage, generic, required dedicated pane
|
||||
- **Google Now cards** — ambient card deck abandoned within 4 years
|
||||
- **Apple Siri Suggestions** — 73% of users say "little to no value"
|
||||
|
||||
### What survived:
|
||||
- **Grammarly** — 40M+ users. Inline underlines, zero cost to ignore, passive/contextual
|
||||
- **Gmail Smart Compose** — 70% adoption. Ghost text, Tab to accept, zero dismissal cost
|
||||
- **GitHub Copilot** — 21-30% acceptance rate. Same inline ghost text pattern. BUT sentiment dropping (70% → 60%)
|
||||
- **Nest thermostat** — Gold standard: invisible when correct. You see outcomes, not suggestions
|
||||
|
||||
### The fundamental law:
|
||||
**The cost of ignoring a suggestion must be lower than the cost of evaluating it, or users disable the system.**
|
||||
|
||||
### The pattern:
|
||||
| Factor | Survives | Dies |
|
||||
|---|---|---|
|
||||
| Where | Inline, in workflow | Separate pane, pop-up |
|
||||
| Ignore cost | Zero | Must actively dismiss |
|
||||
| Accuracy | High precision | High recall, many false positives |
|
||||
| Learning | Adapts over time | Same for everyone |
|
||||
| Agency | User chooses | System interrupts |
|
||||
|
||||
---
|
||||
|
||||
## 4. The Reframe: Decision Space Navigation
|
||||
|
||||
### Key insight
|
||||
Specs aren't about **construction** (like code). They're about **deciding** — navigating a problem space with many open dimensions. Gaps aren't errors to fix; they're unmade decisions.
|
||||
|
||||
The right question isn't "how do we show inline errors" — it's "how do we help someone navigate a large decision space efficiently?"
|
||||
|
||||
### The good collaborator model
|
||||
A good PM doesn't present a list of 12 open questions. They follow your thread and pull you toward the adjacent unexplored area:
|
||||
|
||||
> "Solid. What happens when they deny the permission?"
|
||||
|
||||
Gaps are the agent's **internal state, not a UI element.** Surface ONE thing at a time, the most relevant to the user's current train of thought.
|
||||
|
||||
### Two types of gaps:
|
||||
- **Decision gaps** — only the user can resolve ("should we support multiple providers?"). Surface as questions.
|
||||
- **Research gaps** — system can explore autonomously ("what OAuth libraries does the project use?"). Run in background.
|
||||
|
||||
### The model: Research team, not IDE
|
||||
- **Lead agent** (foreground) — follows your thread, asks the next relevant question
|
||||
- **Research agents** (background) — explore research gaps, report findings
|
||||
- **Internal state** (never shown raw) — full map of all gaps, dependencies, priorities
|
||||
|
||||
---
|
||||
|
||||
## 5. UX: Spatial vs Temporal
|
||||
|
||||
### The fundamental tension
|
||||
Chat is temporal (sequential). Decision spaces are spatial (multi-dimensional). Can't represent a map in a line.
|
||||
|
||||
### Three models explored:
|
||||
|
||||
**Model 1: Workspace file as passive map**
|
||||
Agent maintains a markdown file open in user's editor. Chat is focused work, file is the map. Works today, zero infrastructure.
|
||||
|
||||
**Model 2: Named focus areas**
|
||||
`/focus auth` — switch between dimensions. Agent gives a briefing on entry ("here's where we are, what changed since last time"). Still a single chat thread.
|
||||
|
||||
**Model 3: Parallel conversations**
|
||||
Each dimension is its own persistent agent conversation. Map view shows the landscape. Cross-impacts propagate automatically. Requires new runtime model.
|
||||
|
||||
### Core structure all models share:
|
||||
```
|
||||
MAP (spatial, always available, shows whole landscape)
|
||||
├── DIMENSION (focused workspace, deep conversation)
|
||||
├── DIMENSION
|
||||
├── DIMENSION
|
||||
CROSS-CUTS (propagation layer, how decisions ripple)
|
||||
```
|
||||
|
||||
### What's genuinely new:
|
||||
**Decision propagation.** When you make a decision in one dimension, the system understands implications for other dimensions, updates their state, and briefs you when you arrive. No existing tool does this well.
|
||||
|
||||
---
|
||||
|
||||
## 6. Desktop App — Not Worth It
|
||||
|
||||
### Agent debate results (4 agents):
|
||||
|
||||
**Market evidence on spatial tools:**
|
||||
| Tool | Approach | Outcome |
|
||||
|---|---|---|
|
||||
| Muse (Ink & Switch) | Spatial-first | Dead ($120K ARR peak) |
|
||||
| Roam Research | Graph-first | Collapsed from $200M hype |
|
||||
| Scapple, TheBrain, Kinopio | Spatial/graph | Permanent niche |
|
||||
| Obsidian Canvas | Canvas as feature | "Half-baked," minimal sustained use |
|
||||
| Miro | Spatial whiteboard | $665M ARR but only for brainstorming |
|
||||
| Linear | Structured-first | Won |
|
||||
| Notion | Structured-first | Won |
|
||||
| Claude Code, Cursor | Text/chat-first | Won |
|
||||
|
||||
**Cognitive Fit Theory (Vessey, 1991):** Spatial helps with spatial tasks (seeing relationships). Hurts analytical tasks (prioritizing, sequencing). Planning requires both. Answer: **structured-first with spatial views as a lens.**
|
||||
|
||||
**The Muse lesson:** Spatial was great for ideation but users couldn't bridge to execution. Exactly the transition our product needs.
|
||||
|
||||
**Engineering cost:** 70% of effort goes to UI, 30% to AI. Inverted from where value lives.
|
||||
|
||||
### Recommendation:
|
||||
1. **Weeks 1-4:** Build the AI. Ship as Claude Code skill. Markdown workspace as map.
|
||||
2. **Months 2-3:** Add lightweight web viz (ReactFlow). Browser tab alongside terminal.
|
||||
3. **Months 4-6:** Invest in whatever surface drives retention.
|
||||
4. **Probably never:** Desktop app. Moat is in AI judgment, not renderer.
|
||||
|
||||
---
|
||||
|
||||
## 7. Where's the Moat? (The Uncomfortable Truth)
|
||||
|
||||
### What the "judgment layer" actually is:
|
||||
|
||||
| Component | What it really is |
|
||||
|---|---|
|
||||
| Detect cross-impacts | A prompt |
|
||||
| Rank gaps by importance | A prompt |
|
||||
| Decide when to speak | A prompt with rules |
|
||||
| Propagate decisions | A prompt |
|
||||
| Choose which concern to consult | A few lines of routing code |
|
||||
| Classify user input | A prompt |
|
||||
|
||||
**Day one, it's prompts and files. No moat.** Someone with Claude and a markdown file gets 80% of the value.
|
||||
|
||||
### Where real brain could emerge over time:
|
||||
|
||||
| Timeline | Component | Moat type |
|
||||
|---|---|---|
|
||||
| Day 1 | Prompts + files | None |
|
||||
| Month 3 | Formal decision graph with deterministic constraint propagation | Structural — code enforces what LLM guesses |
|
||||
| Month 6 | Learned silence model from usage patterns | Data — when to speak, trained on real sessions |
|
||||
| Month 12 | Temporal provenance + decision decay | Product — tracking how decisions evolve over weeks |
|
||||
|
||||
### The honest framing:
|
||||
The moat isn't in technology on day one. It's in **product design** — getting the conversation rhythm right. When to ask, how to bridge dimensions, how to surface cross-impacts. Design moats are real (Linear, Figma) but defended by taste and iteration speed, not patents.
|
||||
|
||||
---
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. Is the "good collaborator" conversational model enough, or do users actually need to see the decision map?
|
||||
2. Does the formal decision graph (month 3 milestone) actually improve over LLM reasoning, or is it unnecessary engineering?
|
||||
3. How many dimensions does a typical feature planning session actually have? If it's 4-6, markdown is fine. If it's 15, we need something more.
|
||||
4. Can the "silence problem" (when to speak vs stay quiet) be solved with heuristics, or does it genuinely require learned models?
|
||||
5. Is this a product or a feature? Could this be a mode within an existing tool (Claude Code, Linear, Notion) rather than standalone?
|
||||
@@ -0,0 +1,27 @@
|
||||
# Phase 00 Manual Test
|
||||
|
||||
## Scenarios Run
|
||||
|
||||
- Copied the committed `happy-path` fixture into two fresh temp roots by cloning both `workspace/` and `repos/` outside Vitest.
|
||||
- Confirmed one copied workspace root contains `.openspec/` and `changes/`, and does not contain a repo-local `openspec/` directory.
|
||||
- Ran `node "$OPENSPEC_REPO/dist/cli/index.js" list --json` from the copied `repos/app` root, with `OPENSPEC_REPO` set to the current OpenSpec checkout, and parsed stdout as JSON.
|
||||
- Mutated `repos/app/README.md` in the first temp root and confirmed the same file in the second temp root remained unchanged.
|
||||
- Ran `rg -n -F "$OPENSPEC_REPO" test/fixtures/workspace-poc` to confirm the current checkout path is not committed into the workspace fixtures.
|
||||
|
||||
## Results
|
||||
|
||||
- All manual smoke scenarios passed.
|
||||
- The workspace copy preserved the expected Phase 00 layout: `.openspec/` and `changes/` exist at the workspace root, and no nested repo-local `openspec/` directory exists there.
|
||||
- The direct CLI invocation exited `0`, produced empty `stderr`, and returned parseable JSON from the attached repo fixture. The current payload shape is an object with a `changes` array containing the fixture-backed `app-ui-polish` change.
|
||||
- Mutating one fresh fixture copy did not affect the second copy, which confirms the Phase 00 isolation property outside the automated test harness.
|
||||
- The committed fixture seeds do not contain the current checkout path.
|
||||
|
||||
## Fixes Applied
|
||||
|
||||
- No product-code fixes were needed from this manual pass.
|
||||
- Corrected the first smoke attempt to use the attached repo as the real process working directory; `openspec list` does not expose a `--cwd` flag.
|
||||
|
||||
## Residual Risks
|
||||
|
||||
- No residual risks were found within the implemented Phase 00 scope.
|
||||
- This manual smoke still validates attached-repo execution rather than future workspace command entrypoints, because workspace commands land in later phases.
|
||||
@@ -0,0 +1,24 @@
|
||||
# Phase 00 Summary
|
||||
|
||||
## Changes Made
|
||||
|
||||
- Added `test/helpers/workspace-sandbox.ts` to clone workspace fixtures into unique temp roots, split managed workspace state from attached repos, and rewrite `.openspec/local.yaml` repo paths to canonical absolute paths at runtime.
|
||||
- Added `test/helpers/workspace-assertions.ts` with reusable checks for workspace layout, committed absolute-path leakage, target membership, and materialization invariants.
|
||||
- Added workspace fixture seeds under `test/fixtures/workspace-poc/` for `empty`, `happy-path`, and `dirty`.
|
||||
- Reserved workspace test suite locations with new coverage in `test/core/workspace/`, `test/commands/workspace/`, and `test/cli-e2e/workspace/`.
|
||||
- Added focused Phase 00 tests in `test/core/workspace/workspace-sandbox.test.ts` and `test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`.
|
||||
|
||||
## Tests Performed
|
||||
|
||||
- `pnpm vitest run test/core/workspace/workspace-sandbox.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`
|
||||
|
||||
## Results
|
||||
|
||||
- All 6 Phase 00 tests passed under the current forked Vitest worker configuration.
|
||||
- The harness creates `.openspec/` plus `changes/` at the workspace root and does not create an inner repo-local `openspec/`.
|
||||
- Fixture clones mutate independently, committed fixture seeds stay free of absolute repo paths, and `runCLI()` can execute JSON commands inside sandbox repos without spinner noise in stderr.
|
||||
|
||||
## Blockers And Next-Step Notes
|
||||
|
||||
- No blockers in this phase.
|
||||
- The harness is ready for Phase 01 and later workspace command coverage to reuse the same `workspaceSandbox()` helper and fixture seeds.
|
||||
@@ -0,0 +1,25 @@
|
||||
# Phase 00 Verification
|
||||
|
||||
## Checks Performed
|
||||
|
||||
- Re-read the Phase 00 block in `ROADMAP.md` plus the current `SUMMARY.md`, `VERIFY.md`, and `MANUAL_TEST.md` artifacts in fresh context.
|
||||
- Inspected the Phase 00 implementation in `test/helpers/workspace-sandbox.ts`, `test/helpers/workspace-assertions.ts`, `test/core/workspace/workspace-sandbox.test.ts`, `test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`, and the committed fixtures under `test/fixtures/workspace-poc/`.
|
||||
- Re-ran the focused Phase 00 suite with `pnpm vitest run test/core/workspace/workspace-sandbox.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`.
|
||||
- Reproduced the manual smoke by copying the committed `happy-path` fixture into a fresh temp root, confirming the workspace layout, running `node "$OPENSPEC_REPO/dist/cli/index.js" list --json` from `repos/app`, and parsing the JSON output.
|
||||
- Ran `rg -n -F "$(pwd)" test/fixtures/workspace-poc || true` to confirm the committed fixture seeds do not embed the current checkout path.
|
||||
- Ran `git diff --check -- test/helpers/workspace-sandbox.ts test/helpers/workspace-assertions.ts test/core/workspace/workspace-sandbox.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts test/fixtures/workspace-poc notes/workspace-poc/phase-00-test-harness ROADMAP.md` after the note updates to confirm the phase files remain whitespace-clean.
|
||||
|
||||
## Issues Found
|
||||
|
||||
- Documentation quality issue: `MANUAL_TEST.md` recorded a workstation-specific absolute CLI path, which made the smoke instructions less portable than the rest of the phase artifacts.
|
||||
- No harness, fixture, or acceptance-test defects were found during the verification pass.
|
||||
|
||||
## Fixes Applied
|
||||
|
||||
- Updated `MANUAL_TEST.md` to describe the CLI smoke with `OPENSPEC_REPO` instead of a machine-specific absolute path.
|
||||
- Updated this verification note to reflect the fresh-context checks that were actually rerun for Phase 00.
|
||||
|
||||
## Residual Risks
|
||||
|
||||
- No residual risks were found within the implemented Phase 00 scope.
|
||||
- `test/commands/workspace/` remains intentionally reserved until later phases add workspace commands, so the current CLI compatibility proof is limited to attached repo roots.
|
||||
@@ -0,0 +1,33 @@
|
||||
# Phase 01 Manual Test
|
||||
|
||||
## Scenarios Run
|
||||
|
||||
- Rebuilt the CLI with `pnpm run build` so the manual pass used the current source tree.
|
||||
- Ran `node bin/openspec.js --no-color workspace --help` in a fresh temp XDG config/data root with telemetry disabled.
|
||||
- Ran `node bin/openspec.js --no-color workspace create alpha-team-binmanual` in that same fresh context.
|
||||
- Inspected the created workspace root on disk, including `.openspec/workspace.yaml`, `.openspec/local.yaml`, `changes/`, and `.gitignore`.
|
||||
- Re-ran `node bin/openspec.js --no-color workspace create alpha-team-binmanual` to confirm duplicate handling.
|
||||
- Ran `node bin/openspec.js --no-color workspace create "Alpha Team"` to confirm invalid-name handling.
|
||||
|
||||
## Results
|
||||
|
||||
- `workspace --help` exposed the `create <name>` entrypoint as expected.
|
||||
- Successful create produced a managed workspace root under the temporary XDG data directory with:
|
||||
- `.openspec/workspace.yaml`
|
||||
- `.openspec/local.yaml`
|
||||
- `changes/`
|
||||
- `.gitignore` containing `/.openspec/local.yaml`
|
||||
- The created workspace root did not contain `openspec/changes` or any inner `openspec/` repo-local layout.
|
||||
- `workspace.yaml` stored the workspace name and empty repo registry as expected for a new workspace.
|
||||
- `local.yaml` stored the local overlay version and an empty `repoPaths` map.
|
||||
- Re-running `workspace create` with the same name failed cleanly with an actionable duplicate-workspace error and did not mutate the existing workspace.
|
||||
- Creating a workspace with `Alpha Team` failed cleanly with the expected kebab-case validation error.
|
||||
|
||||
## Fixes Applied
|
||||
|
||||
- None.
|
||||
|
||||
## Residual Risks
|
||||
|
||||
- None found within the Phase 01 scope.
|
||||
- Broader automated command and CLI coverage for `workspace create` still belongs to Phase 02.
|
||||
@@ -0,0 +1,37 @@
|
||||
# Phase 01 Summary
|
||||
|
||||
## Changes Made
|
||||
|
||||
- Added `src/commands/workspace.ts` and registered a new `openspec workspace` command group with a `workspace create <name>` entrypoint.
|
||||
- Added `src/core/workspace/create.ts` to create managed workspace roots under the global OpenSpec data directory at `workspaces/<name>`.
|
||||
- Added `src/core/setup/bootstrap.ts` and reused it from both `workspace create` and the existing `InitCommand` so writable-target checks and directory bootstrapping stay on one shared setup path.
|
||||
- `workspace create` now creates a dedicated workspace layout with `.openspec/workspace.yaml`, `.openspec/local.yaml`, and top-level `changes/`, without creating a repo-local `openspec/` tree.
|
||||
- `workspace create` now writes `/.openspec/local.yaml` into the workspace root `.gitignore` so the local overlay is treated as local-only state.
|
||||
- Duplicate and invalid workspace names now fail with explicit, actionable errors.
|
||||
|
||||
## Tests Performed
|
||||
|
||||
- `pnpm run build`
|
||||
- `pnpm vitest run test/core/init.test.ts test/core/workspace/workspace-sandbox.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`
|
||||
- Fresh CLI smoke in temp XDG config/data roots:
|
||||
- `node dist/cli/index.js --no-color workspace create alpha-team-2`
|
||||
- repeated create for duplicate handling
|
||||
- invalid create with `Alpha Team`
|
||||
|
||||
## Results
|
||||
|
||||
- Build passed.
|
||||
- 48 focused Vitest checks passed, including existing init coverage and workspace harness compatibility coverage.
|
||||
- Fresh CLI smoke created a managed workspace at `XDG_DATA_HOME/openspec/workspaces/alpha-team-2` with:
|
||||
- `.openspec/workspace.yaml`
|
||||
- `.openspec/local.yaml`
|
||||
- `changes/`
|
||||
- `.gitignore` containing `/.openspec/local.yaml`
|
||||
- The created workspace root did not contain `openspec/changes`.
|
||||
- Re-running against the same name failed explicitly without mutating the workspace.
|
||||
- Invalid names failed with a workspace-specific kebab-case error.
|
||||
|
||||
## Blockers And Next-Step Notes
|
||||
|
||||
- No blockers in Phase 01.
|
||||
- Automated command/unit/e2e coverage for `workspace create` is still intentionally thin and should be expanded in Phase 02.
|
||||
@@ -0,0 +1,38 @@
|
||||
# Phase 01 Verification
|
||||
|
||||
## Checks Performed
|
||||
|
||||
- Read the Phase 01 block in `ROADMAP.md` plus the current `SUMMARY.md` and `MANUAL_TEST.md` artifacts.
|
||||
- Reviewed the implementation boundary for this phase in:
|
||||
- `src/cli/index.ts`
|
||||
- `src/commands/workspace.ts`
|
||||
- `src/core/workspace/create.ts`
|
||||
- `src/core/setup/bootstrap.ts`
|
||||
- `src/core/init.ts`
|
||||
- Rebuilt the CLI with `pnpm run build`.
|
||||
- Ran focused regression coverage:
|
||||
- `pnpm vitest run test/core/init.test.ts test/core/workspace/workspace-sandbox.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`
|
||||
- Ran fresh CLI verification in temporary XDG config/data roots with telemetry disabled:
|
||||
- `node dist/cli/index.js --no-color workspace --help`
|
||||
- `node dist/cli/index.js --no-color workspace create alpha-team-verify`
|
||||
- repeated create for duplicate handling
|
||||
- `node dist/cli/index.js --no-color workspace create "Alpha Team"` for invalid-name handling
|
||||
- Inspected the generated workspace root on disk and confirmed:
|
||||
- `.openspec/workspace.yaml` exists
|
||||
- `.openspec/local.yaml` exists
|
||||
- top-level `changes/` exists
|
||||
- `.gitignore` contains `/.openspec/local.yaml`
|
||||
- no nested `openspec/` or `openspec/changes` was created
|
||||
|
||||
## Issues Found
|
||||
|
||||
- None.
|
||||
|
||||
## Fixes Applied
|
||||
|
||||
- None.
|
||||
|
||||
## Residual Risks
|
||||
|
||||
- No blocking issues were found within the Phase 01 scope.
|
||||
- Dedicated automated command/e2e coverage for `workspace create` is still intentionally deferred to Phase 02, so create-specific confidence still comes from this fresh CLI smoke plus the shared regression suites.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Phase 02 Manual Test
|
||||
|
||||
Manual pass date: 2026-04-17
|
||||
Phase cycle: 1
|
||||
Stage: `manual-test`
|
||||
|
||||
## Scenarios Run
|
||||
|
||||
- Rebuilt the CLI with `pnpm run build` so the manual pass used the current source tree.
|
||||
- In a fresh `mktemp` root with isolated `XDG_CONFIG_HOME` and `XDG_DATA_HOME`, and `OPEN_SPEC_TELEMETRY_DISABLED=1`, ran `node bin/openspec.js --no-color workspace --help`.
|
||||
- Ran `node bin/openspec.js --no-color workspace create alpha-manual`.
|
||||
- Inspected the created `alpha-manual` workspace root for `.openspec/workspace.yaml`, `.openspec/local.yaml`, `changes/`, `.gitignore`, and absence of any nested repo-local `openspec/` directory.
|
||||
- Ran `node bin/openspec.js --no-color workspace create beta-json --json` and parsed stdout as JSON.
|
||||
- Re-ran `node bin/openspec.js --no-color workspace create alpha-manual` and compared file hashes for `.gitignore`, `.openspec/workspace.yaml`, and `.openspec/local.yaml` before and after the duplicate attempt.
|
||||
|
||||
## Results
|
||||
|
||||
- `workspace --help` exposed `create [options] <name>` under the `workspace` command.
|
||||
- `workspace create alpha-manual` exited `0`, produced no stderr output, and created a managed workspace root under the isolated XDG data directory.
|
||||
- The created workspace contained `.openspec/workspace.yaml`, `.openspec/local.yaml`, `changes/`, and `.gitignore` with `/.openspec/local.yaml`.
|
||||
- `workspace.yaml` contained `version: 1`, `name: alpha-manual`, and `repos: {}`.
|
||||
- `local.yaml` contained `version: 1` and `repoPaths: {}`.
|
||||
- The workspace root did not contain any nested repo-local `openspec/` directory.
|
||||
- `workspace create beta-json --json` exited `0`, emitted parseable JSON on stdout only, and returned the expected absolute paths plus `gitignoreStatus: "created"`.
|
||||
- Re-running `workspace create alpha-manual` exited `1`, emitted the expected blank line on stdout plus an actionable error on stderr, and left the existing workspace files unchanged.
|
||||
|
||||
## Fixes Applied
|
||||
|
||||
- None. No product or test changes were required from this manual pass.
|
||||
- Refreshed this artifact so the manual-test record matches the fresh cycle-1 run.
|
||||
|
||||
## Residual Risks
|
||||
|
||||
- None found within the Phase 02 scope.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Phase 02 Summary
|
||||
|
||||
## Changes Made
|
||||
|
||||
- Added focused core coverage in `test/core/workspace/workspace-create.test.ts` for managed workspace path resolution plus metadata and overlay initialization.
|
||||
- Added command-layer coverage in `test/commands/workspace/create.test.ts` for the `workspace create` action, including happy path, duplicate handling, invalid names, and machine-readable output.
|
||||
- Added CLI e2e coverage in `test/cli-e2e/workspace/workspace-create-cli.test.ts` for help output, JSON cleanliness, exit codes, on-disk layout, and duplicate-create safety.
|
||||
- Added a minimal `--json` success and error path to `src/commands/workspace.ts` so acceptance 02.6 is concrete and testable instead of hypothetical.
|
||||
- Updated `test/commands/workspace/README.md` now that the reserved command-layer directory contains real coverage.
|
||||
|
||||
## Tests Performed
|
||||
|
||||
- `pnpm run build`
|
||||
- `pnpm vitest run test/core/workspace/workspace-create.test.ts test/core/workspace/workspace-sandbox.test.ts test/commands/workspace/create.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`
|
||||
- Fresh CLI verification and manual smoke in isolated XDG config/data roots with telemetry disabled:
|
||||
- `node bin/openspec.js --no-color workspace --help`
|
||||
- `node bin/openspec.js --no-color workspace create alpha-manual`
|
||||
- `node bin/openspec.js --no-color workspace create beta-json --json`
|
||||
- repeated `workspace create alpha-manual` for duplicate handling
|
||||
- `git diff --check -- src/commands/workspace.ts test/core/workspace/workspace-create.test.ts test/commands/workspace/create.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/commands/workspace/README.md`
|
||||
|
||||
## Results
|
||||
|
||||
- Build passed.
|
||||
- The focused workspace suite passed with 15/15 tests.
|
||||
- `workspace --help` now documents `create [options] <name>`.
|
||||
- Successful create still produces a usable managed workspace root with `.openspec/workspace.yaml`, `.openspec/local.yaml`, top-level `changes/`, and no nested repo-local `openspec/`.
|
||||
- `workspace create --json` now emits clean parseable JSON with no stderr noise on success.
|
||||
- Duplicate create attempts still exit `1`, surface an actionable error, and leave the existing workspace files unchanged.
|
||||
|
||||
## Blockers And Next-Step Notes
|
||||
|
||||
- No blockers in Phase 02.
|
||||
- No new roadmap phases were required from this pass.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Phase 02 Verification
|
||||
|
||||
## Checks Performed
|
||||
|
||||
- Read the Phase 02 block in `ROADMAP.md` plus the current `SUMMARY.md`, `VERIFY.md`, and `MANUAL_TEST.md` for this phase before running checks.
|
||||
- Reviewed the current Phase 02 implementation boundary in:
|
||||
- `src/commands/workspace.ts`
|
||||
- `src/core/workspace/create.ts`
|
||||
- `src/cli/index.ts`
|
||||
- `test/core/workspace/workspace-create.test.ts`
|
||||
- `test/commands/workspace/create.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-create-cli.test.ts`
|
||||
- `test/helpers/workspace-assertions.ts`
|
||||
- `test/helpers/run-cli.ts`
|
||||
- `test/commands/workspace/README.md`
|
||||
- Rebuilt the CLI with `pnpm run build`.
|
||||
- Ran the focused regression suite:
|
||||
- `pnpm vitest run test/core/workspace/workspace-create.test.ts test/core/workspace/workspace-sandbox.test.ts test/commands/workspace/create.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`
|
||||
- Re-ran fresh CLI verification in isolated XDG roots with telemetry disabled:
|
||||
- `node bin/openspec.js --no-color workspace --help`
|
||||
- `node bin/openspec.js --no-color workspace create alpha-manual`
|
||||
- inspected `.openspec/workspace.yaml`, `.openspec/local.yaml`, `.gitignore`, and the top-level `changes/` directory
|
||||
- confirmed there is no nested repo-local `openspec/` directory
|
||||
- `node bin/openspec.js --no-color workspace create beta-json --json`
|
||||
- repeated `workspace create alpha-manual` to verify duplicate handling, exit code `1`, and unchanged workspace files
|
||||
- Ran `git diff --check` on the Phase 02 source, test, and helper files.
|
||||
- Validated documentation quality against the live command surface by comparing the current help text and test assertions with the phase notes.
|
||||
|
||||
## Issues Found
|
||||
|
||||
- No product or test failures were found in the current Phase 02 scope.
|
||||
- The existing `VERIFY.md` reflected the earlier implementation pass rather than this independent verification pass, so the phase notes were stale.
|
||||
|
||||
## Fixes Applied
|
||||
|
||||
- Refreshed this verification note so it documents the current independent verification run, the checks actually performed, and the current status of the phase.
|
||||
- Refreshed `MANUAL_TEST.md` to match the current manual pass and to keep the phase documentation aligned with the live CLI behavior.
|
||||
|
||||
## Residual Risks
|
||||
|
||||
- No blocking issues remain within the Phase 02 scope.
|
||||
- Phase 02 still stays within its intended boundary: managed workspace creation, metadata initialization, and validation coverage only. Later workspace behaviors remain outside this phase.
|
||||
- `--json` discipline is currently proven for `workspace create`; future workspace commands should follow the same stdout/stderr contract when they add machine-readable output.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Phase 03 Manual Test
|
||||
|
||||
Manual test stage re-run in fresh isolated XDG state on 2026-04-17 for ROADMAP Phase 03, cycle 1.
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Built the current CLI with `pnpm run build`.
|
||||
- Created a managed workspace with `openspec workspace create phase03-manual --json`.
|
||||
- Registered a repo with `openspec workspace add-repo app <symlink-path> --json`.
|
||||
- Confirmed the persisted split:
|
||||
- `.openspec/workspace.yaml` stored only the committed alias entry `app: {}`
|
||||
- `.openspec/local.yaml` stored only the canonical absolute repo path
|
||||
- no absolute repo path leaked into `.openspec/workspace.yaml`
|
||||
- Exercised `workspace add-repo` failure cases from the real CLI:
|
||||
- duplicate alias registration
|
||||
- missing repo path
|
||||
- repo path without repo-local `openspec/`
|
||||
- Ran `openspec workspace doctor --json` on a healthy workspace and confirmed a clean pass.
|
||||
- Corrupted fresh workspace metadata to simulate doctor-only recovery scenarios, then ran `openspec workspace doctor --json` and confirmed:
|
||||
- `missing-local-path` for a committed alias missing from `.openspec/local.yaml`
|
||||
- `non-canonical-path` for a symlinked local overlay path
|
||||
- `extra-local-alias` for a local-only alias not present in committed metadata
|
||||
- non-zero exit and no mutation of `.openspec/workspace.yaml` or `.openspec/local.yaml`
|
||||
- Removed a previously registered repo directory, reran `openspec workspace doctor --json`, and confirmed `missing-repo-path` with no overlay mutation.
|
||||
- Removed `openspec/` from a previously registered repo, reran `openspec workspace doctor --json`, and confirmed `missing-openspec-state`.
|
||||
|
||||
## Results
|
||||
|
||||
- All manual smoke scenarios passed against the current built CLI.
|
||||
- `workspace add-repo` still persists committed alias metadata separately from local absolute paths.
|
||||
- Canonicalization still resolves symlink inputs before persistence.
|
||||
- `workspace doctor` reports healthy state correctly, reports stale or broken registry state with the expected issue codes, exits non-zero on problems, and does not rewrite workspace files during diagnostics.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product fixes were required from this manual-test pass.
|
||||
- Updated this manual-test note to reflect the fresh-context run and expanded doctor scenarios.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No residual Phase 03 functional issues were found during manual testing.
|
||||
- Dedicated automated regression coverage for these flows is still expected in Phase 04.
|
||||
@@ -0,0 +1,48 @@
|
||||
# Phase 03 Summary
|
||||
|
||||
## Changes made
|
||||
|
||||
- Added shared workspace metadata helpers in `src/core/workspace/metadata.ts` so committed workspace state and local overlay state are read and written consistently.
|
||||
- Added repo registry and doctor logic in `src/core/workspace/registry.ts`.
|
||||
- Extended `src/commands/workspace.ts` with:
|
||||
- `openspec workspace add-repo <alias> <path>`
|
||||
- `openspec workspace doctor`
|
||||
- Kept committed alias registration in `.openspec/workspace.yaml`.
|
||||
- Kept canonical absolute repo paths in `.openspec/local.yaml`.
|
||||
- Validated repo registration inputs for:
|
||||
- kebab-case alias shape
|
||||
- existing directory paths
|
||||
- repo-local OpenSpec state via `openspec/`
|
||||
- Implemented doctor diagnostics for:
|
||||
- missing local alias mappings
|
||||
- missing repo paths
|
||||
- non-canonical local overlay paths
|
||||
- extra local-only aliases
|
||||
- missing repo-local OpenSpec state
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- `pnpm run build`
|
||||
- `pnpm vitest run test/core/workspace/workspace-create.test.ts test/core/workspace/workspace-sandbox.test.ts test/commands/workspace/create.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`
|
||||
- Fresh CLI smoke in temporary XDG roots covering:
|
||||
- `workspace create`
|
||||
- `workspace add-repo` success with a symlinked repo path
|
||||
- duplicate alias failure
|
||||
- missing path failure
|
||||
- missing `openspec/` failure
|
||||
- `workspace doctor` success on a healthy workspace
|
||||
- `workspace doctor --json` failure reporting stale path and local-overlay drift without mutating files
|
||||
|
||||
## Results
|
||||
|
||||
- Build passed.
|
||||
- Existing workspace regression tests passed: 15/15.
|
||||
- `workspace add-repo` writes only the alias to `.openspec/workspace.yaml` and only the canonical absolute path to `.openspec/local.yaml`.
|
||||
- Canonicalization resolved a symlinked repo input to the real absolute path before persistence.
|
||||
- `workspace doctor` reports missing repos and overlay drift and exits non-zero without rewriting workspace files.
|
||||
- No absolute repo path leaked into committed workspace metadata during the fresh acceptance run.
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers in Phase 03.
|
||||
- Phase 04 should add permanent automated coverage for the new registry and doctor behaviors across core, command, and CLI layers.
|
||||
@@ -0,0 +1,35 @@
|
||||
# Phase 03 Verification
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 03 block in `ROADMAP.md` and the current phase artifacts in `notes/workspace-poc/phase-03-repo-registry/`.
|
||||
- Inspected the Phase 03 implementation boundaries in:
|
||||
- `src/core/workspace/metadata.ts`
|
||||
- `src/core/workspace/registry.ts`
|
||||
- `src/commands/workspace.ts`
|
||||
- `src/cli/index.ts`
|
||||
- `src/utils/file-system.ts`
|
||||
- Rebuilt from the current workspace with `pnpm run build`.
|
||||
- Re-ran the current workspace-focused automated coverage with `pnpm vitest run test/core/workspace test/commands/workspace test/cli-e2e/workspace`.
|
||||
- Verified the acceptance cases in a fresh temporary XDG workspace using the built CLI:
|
||||
- `workspace create phase03-verify`
|
||||
- `workspace add-repo app <symlink-path>`
|
||||
- confirmed `.openspec/workspace.yaml` stored only the committed alias entry
|
||||
- confirmed `.openspec/local.yaml` stored only the canonical absolute repo path
|
||||
- confirmed duplicate alias, missing path, and missing `openspec/` failures
|
||||
- confirmed `workspace doctor` passes on healthy state
|
||||
- corrupted `.openspec/local.yaml` and confirmed `workspace doctor --json` reports stale state with a non-zero exit and no YAML mutation
|
||||
- Reviewed `openspec workspace --help` to confirm the new subcommands are discoverable from the CLI surface.
|
||||
|
||||
## Issues found
|
||||
|
||||
- No implementation, boundary, or documentation defects were found during this verification pass.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- Updated this verification note to reflect the fresh-context verification run.
|
||||
- No code changes were required.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- Direct automated coverage for `workspace add-repo` and `workspace doctor` is still deferred to Phase 04, so this phase currently relies on manual verification plus adjacent workspace regression tests.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Phase 04 Manual Test
|
||||
|
||||
Manual smoke re-run with the built CLI in fresh isolated XDG state on 2026-04-17 for ROADMAP Phase 04, cycle 1.
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Built the current CLI with `pnpm run build`.
|
||||
- Created a managed workspace with `openspec workspace create phase04-manual-cycle1 --json`.
|
||||
- Created three real repo fixtures with repo-local `openspec/changes` state: `app`, `api`, and `docs`.
|
||||
- Registered all three repos through the real CLI with:
|
||||
- `openspec workspace add-repo app <path> --json`
|
||||
- `openspec workspace add-repo api <path> --json`
|
||||
- `openspec workspace add-repo docs <path> --json`
|
||||
- Ran `openspec workspace doctor --json` and confirmed a clean pass with:
|
||||
- `registeredAliasCount: 3`
|
||||
- `localAliasCount: 3`
|
||||
- `issues: []`
|
||||
- `status: "ok"`
|
||||
- Edited `.openspec/local.yaml` to replace the `api` path with a relative non-canonical path and reran `openspec workspace doctor --json`.
|
||||
- Confirmed the drift run returned exit code `1` with a `non-canonical-path` issue for alias `api`.
|
||||
- Removed `docs/openspec/` from a registered repo and reran `openspec workspace doctor --json`.
|
||||
- Confirmed the doctor run returned exit code `1` with a `missing-openspec-state` issue for alias `docs`.
|
||||
- Edited `.openspec/local.yaml` to replace the `app` path with a missing repo root and reran `openspec workspace doctor --json`.
|
||||
- Confirmed the stale run returned exit code `1` with a `missing-repo-path` issue for alias `app`.
|
||||
- Repaired `.openspec/local.yaml` by restoring the canonical absolute repo path and restored `docs/openspec/`, then reran `openspec workspace doctor --json`.
|
||||
- Compared `.openspec/workspace.yaml` before and after the local overlay edits to confirm committed metadata stayed unchanged.
|
||||
|
||||
## Results
|
||||
|
||||
- All manual smoke scenarios passed.
|
||||
- Multiple repo additions remained readable and doctor-clean in one workspace.
|
||||
- Doctor detected alias/path drift, missing repo-local `openspec/`, and missing repo roots with the expected non-zero exit behavior.
|
||||
- Repairing the stale `local.yaml` entry restored doctor success.
|
||||
- `.openspec/workspace.yaml` remained unchanged across local path mutations, so committed metadata stayed stable while only the local overlay changed.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No additional product fixes were required during this manual smoke pass.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No user-visible Phase 04 issues were found in this manual smoke run.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Phase 04 Summary
|
||||
|
||||
## Changes made
|
||||
|
||||
- Added core registry coverage in `test/core/workspace/registry.test.ts` for:
|
||||
- alias trimming and invalid alias rejection
|
||||
- canonical repo-path persistence
|
||||
- committed metadata stability when `local.yaml` changes
|
||||
- doctor diagnostics for missing local mappings, missing repo roots, missing `openspec/`, alias/path drift, and extra local aliases
|
||||
- Added command-surface coverage in `test/commands/workspace/registry.test.ts` for:
|
||||
- `workspace add-repo`
|
||||
- healthy `workspace doctor`
|
||||
- stale `workspace doctor`
|
||||
- Added CLI e2e coverage in `test/cli-e2e/workspace/workspace-registry-cli.test.ts` for:
|
||||
- multiple repo additions in one workspace
|
||||
- healthy doctor JSON output
|
||||
- stale-path detection and repair via `.openspec/local.yaml`
|
||||
- Fixed two issues exposed by the new coverage in `src/commands/workspace.ts`:
|
||||
- corrected pluralized doctor status text for `aliases` and `entries`
|
||||
- changed doctor issue exits to set `process.exitCode = 1` after printing results instead of calling `process.exit(1)` inside the action body
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- `pnpm vitest run test/core/workspace test/commands/workspace test/cli-e2e/workspace`
|
||||
- `pnpm run build`
|
||||
- `pnpm vitest run test/core/workspace/registry.test.ts test/commands/workspace/registry.test.ts test/cli-e2e/workspace/workspace-registry-cli.test.ts`
|
||||
- Fresh built-CLI smoke on 2026-04-17 covering:
|
||||
- `workspace create phase04-manual --json`
|
||||
- two successful `workspace add-repo ... --json` registrations
|
||||
- healthy `workspace doctor --json`
|
||||
- forced stale `local.yaml` repo path
|
||||
- successful doctor recovery after repairing the stale local path
|
||||
|
||||
## Results
|
||||
|
||||
- All targeted workspace tests passed: 23/23 in the full workspace slice and 8/8 in the Phase 04-focused verification slice.
|
||||
- Build passed.
|
||||
- Doctor now reports clean human-readable pluralization in healthy output.
|
||||
- Doctor still exits non-zero when issues are present, while keeping the command-surface control flow stable enough for interception and tests.
|
||||
- The registry stayed readable after multiple repo additions, committed metadata remained path-free and stable, and stale local overlay repair restored doctor success.
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 04.
|
||||
- No new roadmap phases were required from this test pass.
|
||||
- Phase 05 can build on the now-covered repo registry and doctor behavior.
|
||||
@@ -0,0 +1,38 @@
|
||||
# Phase 04 Verification
|
||||
|
||||
Verification re-run in a fresh shell context on 2026-04-17 for ROADMAP Phase 04, cycle 1.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 04 block in `ROADMAP.md`.
|
||||
- Reviewed the current phase artifacts for scope and documentation quality:
|
||||
- `notes/workspace-poc/phase-04-test-repo-registry/SUMMARY.md`
|
||||
- `notes/workspace-poc/phase-04-test-repo-registry/MANUAL_TEST.md`
|
||||
- Reviewed the implementation and test coverage for this phase:
|
||||
- `src/core/workspace/registry.ts`
|
||||
- `src/commands/workspace.ts`
|
||||
- `test/core/workspace/registry.test.ts`
|
||||
- `test/commands/workspace/registry.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-registry-cli.test.ts`
|
||||
- Verified that the implementation boundaries still match the phase intent:
|
||||
- committed repo aliases live in `.openspec/workspace.yaml`
|
||||
- local absolute repo paths live only in `.openspec/local.yaml`
|
||||
- doctor reports missing local mappings, missing repo roots, missing `openspec/`, non-canonical path drift, and extra local aliases
|
||||
- Rebuilt the CLI with `pnpm run build`.
|
||||
- Re-ran the Phase 04-focused automated slice with:
|
||||
- `pnpm vitest run test/core/workspace/registry.test.ts test/commands/workspace/registry.test.ts test/cli-e2e/workspace/workspace-registry-cli.test.ts`
|
||||
- Re-ran the broader workspace regression slice with:
|
||||
- `pnpm vitest run test/core/workspace test/commands/workspace test/cli-e2e/workspace`
|
||||
|
||||
## Issues found
|
||||
|
||||
- None.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- None required.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- None found for Phase 04 in this verification pass.
|
||||
- The phase artifacts remain consistent with the implemented scope, and the acceptance coverage is in place across core, command, and CLI layers.
|
||||
@@ -0,0 +1,64 @@
|
||||
# Phase 05 Manual Test
|
||||
|
||||
Manual smoke re-run in a fresh temp/XDG context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 05, cycle 1.
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Rebuilt the current CLI with `pnpm run build`.
|
||||
- Checked `node dist/cli/index.js new change --help` and confirmed the Phase 05 surface still documents:
|
||||
- `--description <text>` as seeding the initial change artifact
|
||||
- `--targets <aliases>` for workspace-targeted change creation
|
||||
- Created a brand-new isolated CLI environment with:
|
||||
- `OPENSPEC_TELEMETRY=0`
|
||||
- fresh `XDG_CONFIG_HOME`
|
||||
- fresh `XDG_DATA_HOME`
|
||||
- Created three real repo roots under the temp sandbox:
|
||||
- `app`
|
||||
- `api`
|
||||
- `docs`
|
||||
- Seeded each repo root with repo-local OpenSpec state via `openspec/changes/` so the real `workspace add-repo` path validation would accept them.
|
||||
- Ran `node dist/cli/index.js workspace create phase05-manual-cycle1 --json`.
|
||||
- Ran the real repo registration flow from inside that managed workspace:
|
||||
- `node dist/cli/index.js workspace add-repo app <path> --json`
|
||||
- `node dist/cli/index.js workspace add-repo api <path> --json`
|
||||
- `node dist/cli/index.js workspace add-repo docs <path> --json`
|
||||
- Ran the target-aware create flow:
|
||||
- `node dist/cli/index.js new change shared-auth --targets app,api --description "Cross-repo auth rollout"`
|
||||
- Inspected the created workspace change and confirmed:
|
||||
- `changes/shared-auth/.openspec.yaml` exists
|
||||
- metadata recorded `schema: spec-driven`
|
||||
- metadata recorded `targets: [app, api]`
|
||||
- `proposal.md`, `design.md`, and `tasks/coordination.md` exist
|
||||
- `targets/app/tasks.md` and `targets/api/tasks.md` exist
|
||||
- `targets/app/specs/` and `targets/api/specs/` exist
|
||||
- Verified the untargeted and targeted repos all remained free of repo-local materialization:
|
||||
- `<app>/openspec/changes/shared-auth` does not exist
|
||||
- `<api>/openspec/changes/shared-auth` does not exist
|
||||
- `<docs>/openspec/changes/shared-auth` does not exist
|
||||
- Exercised the negative CLI cases in the same fresh workspace:
|
||||
- `node dist/cli/index.js new change dup-targets --targets app,app`
|
||||
- `node dist/cli/index.js new change unknown-target --targets app,missing`
|
||||
- reran `node dist/cli/index.js new change shared-auth --targets app,api`
|
||||
- Re-ran `node dist/cli/index.js workspace doctor --json` after targeted creation.
|
||||
|
||||
## Results
|
||||
|
||||
- All manual smoke scenarios passed.
|
||||
- The real targeted-create flow produced the expected central workspace scaffold under `changes/shared-auth/`.
|
||||
- The workspace change metadata recorded the exact requested target set: `app`, `api`.
|
||||
- Duplicate target aliases failed with a non-zero exit and the expected actionable message: `Duplicate target alias 'app' in --targets. Remove duplicates and retry.`
|
||||
- Unknown target aliases failed with a non-zero exit and the expected actionable message naming the missing alias and registered aliases.
|
||||
- Reusing the same workspace change ID failed predictably with the existing duplicate-change error.
|
||||
- No repo-local change directories were created in any registered repo during `new change`.
|
||||
- `workspace doctor --json` still returned `status: "ok"` after targeted creation, so the registry remained healthy.
|
||||
- The generated metadata still stored `created: 2026-04-16` during this 2026-04-17 Australia/Sydney run because the shared date path remains UTC-based.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product fixes were required during this manual-test pass.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No Phase 05 user-visible regressions were found in this manual smoke cycle.
|
||||
- The shared metadata `created` field still reflects UTC day boundaries rather than local date boundaries. That was observed again here, but it is existing shared behavior rather than a Phase 05-specific regression.
|
||||
- Permanent automated coverage for this flow is still expected in Phase 06.
|
||||
@@ -0,0 +1,52 @@
|
||||
# Phase 05 Summary
|
||||
|
||||
## Changes made
|
||||
|
||||
- Added workspace-aware change creation in [src/commands/workflow/new-change.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workflow/new-change.ts) so `openspec new change <id> --targets <a,b,c>` now detects managed workspaces, requires explicit targets there, and still preserves the existing repo-local path outside a workspace.
|
||||
- Added [src/core/workspace/change-create.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/change-create.ts) to:
|
||||
- parse and validate `--targets`
|
||||
- reject duplicate or unknown aliases before writing anything
|
||||
- create workspace changes under `changes/<id>/`
|
||||
- scaffold `proposal.md`, `design.md`, `tasks/coordination.md`, and per-target `targets/<alias>/tasks.md` plus `targets/<alias>/specs/`
|
||||
- Extended change metadata in [src/core/artifact-graph/types.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/artifact-graph/types.ts) and reused the shared metadata writer so workspace changes persist explicit `targets` in `.openspec.yaml`.
|
||||
- Added `findWorkspaceRoot()` in [src/core/workspace/registry.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/registry.ts) so the command can detect workspace topology without disturbing the existing registry and doctor flows.
|
||||
- Extracted schema resolution into [src/utils/change-utils.ts](/Users/tabishbidiwale/fission/repos/openspec/src/utils/change-utils.ts) so repo-local and workspace change creation both resolve schemas through the same path.
|
||||
- Updated [src/cli/index.ts](/Users/tabishbidiwale/fission/repos/openspec/src/cli/index.ts) to expose `--targets` on `openspec new change`.
|
||||
- Clarified the `openspec new change --help` text in [src/cli/index.ts](/Users/tabishbidiwale/fission/repos/openspec/src/cli/index.ts) so `--description` no longer incorrectly promises a `README.md` write for workspace-targeted changes.
|
||||
- Expanded [test/utils/change-metadata.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/utils/change-metadata.test.ts) so shared metadata coverage now includes persisted target aliases and duplicate-target rejection.
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- `pnpm run build`
|
||||
- `pnpm vitest run test/utils/change-metadata.test.ts test/utils/change-utils.test.ts test/core/workspace/registry.test.ts`
|
||||
- `node dist/cli/index.js new change --help`
|
||||
- Fresh isolated CLI smoke on 2026-04-17 (Australia/Sydney) with telemetry disabled:
|
||||
- `openspec workspace create phase05-manual`
|
||||
- `openspec workspace add-repo app <path>`
|
||||
- `openspec workspace add-repo api <path>`
|
||||
- `openspec workspace add-repo docs <path>`
|
||||
- `openspec new change shared-auth --targets app,api --description "Cross-repo auth rollout"`
|
||||
- verified `changes/shared-auth/.openspec.yaml`
|
||||
- verified `proposal.md`, `design.md`, `tasks/coordination.md`, and `targets/{app,api}/{tasks.md,specs/}`
|
||||
- verified no `openspec/changes/shared-auth` directory was created in any registered repo
|
||||
- verified duplicate-target, unknown-target, and duplicate-change-ID failures
|
||||
- Fresh isolated post-create health check:
|
||||
- `openspec workspace doctor --json` after targeted creation
|
||||
|
||||
## Results
|
||||
|
||||
- Build passed.
|
||||
- Focused regression coverage passed: 51/51 tests.
|
||||
- Targeted workspace changes now record the exact target list in `.openspec.yaml`.
|
||||
- The workspace change layout now includes the central planning scaffold plus per-target task/spec partitions under `changes/<id>/targets/`.
|
||||
- Unknown targets and duplicate targets fail before any workspace artifacts are written, with actionable error messages.
|
||||
- Repo-local repos remained untouched during creation; no target repo received a materialized `openspec/changes/<id>` directory.
|
||||
- Duplicate workspace change IDs still fail predictably at the workspace change path.
|
||||
- `workspace doctor --json` still reported `status: "ok"` after targeted change creation, so the new flow does not corrupt workspace registry state.
|
||||
- The CLI help output now describes `--description` generically enough to match both repo-local and workspace-targeted change creation.
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 05.
|
||||
- No new roadmap phases were required from this implementation pass.
|
||||
- Phase 06 should add dedicated permanent unit, command, and CLI coverage for the new workspace-targeted change path instead of relying on the focused shared regressions and CLI smoke used here.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Phase 05 Verification
|
||||
|
||||
Independent verification re-run in a fresh context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 05, cycle 1.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 05 block in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md) and the current phase artifacts in [SUMMARY.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-05-targeted-change-create/SUMMARY.md) and [MANUAL_TEST.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-05-targeted-change-create/MANUAL_TEST.md).
|
||||
- Reviewed the implementation boundary in:
|
||||
- [src/commands/workflow/new-change.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workflow/new-change.ts)
|
||||
- [src/core/workspace/change-create.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/change-create.ts)
|
||||
- [src/core/workspace/registry.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/registry.ts)
|
||||
- [src/utils/change-utils.ts](/Users/tabishbidiwale/fission/repos/openspec/src/utils/change-utils.ts)
|
||||
- [src/core/artifact-graph/types.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/artifact-graph/types.ts)
|
||||
- [src/cli/index.ts](/Users/tabishbidiwale/fission/repos/openspec/src/cli/index.ts)
|
||||
- [test/utils/change-metadata.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/utils/change-metadata.test.ts)
|
||||
- Confirmed `openspec new change --help` documents both `--targets` and the updated generic `--description` behavior.
|
||||
- Rebuilt the current tree with `pnpm run build`.
|
||||
- Re-ran focused regressions with `pnpm vitest run test/utils/change-metadata.test.ts test/utils/change-utils.test.ts test/core/workspace/registry.test.ts`.
|
||||
- Ran a fresh isolated CLI verification with the built CLI and telemetry disabled:
|
||||
- created a managed workspace
|
||||
- registered `app`, `api`, and `docs`
|
||||
- created `shared-auth` with `--targets app,api`
|
||||
- inspected `changes/shared-auth/.openspec.yaml`
|
||||
- confirmed `proposal.md`, `design.md`, `tasks/coordination.md`, and per-target `tasks.md` plus `specs/` directories
|
||||
- confirmed no repo-local `openspec/changes/shared-auth` directory was created in any registered repo
|
||||
- confirmed duplicate-target, unknown-target, and duplicate-change-ID failures returned non-zero exits with actionable messages
|
||||
- confirmed `openspec workspace doctor --json` returned `status: "ok"` after targeted creation
|
||||
- Observed that the generated metadata stored `created: 2026-04-16` during this 2026-04-17 Australia/Sydney verification run because the shared date path still uses UTC `toISOString()`.
|
||||
|
||||
## Issues found
|
||||
|
||||
- `openspec new change --help` still said `--description` adds text to `README.md`, which was inaccurate for workspace-targeted changes that seed `proposal.md` instead.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- Updated [src/cli/index.ts](/Users/tabishbidiwale/fission/repos/openspec/src/cli/index.ts) so `--description` is described as seeding the initial change artifact rather than specifically writing `README.md`.
|
||||
- Rebuilt the CLI and rechecked both `openspec new change --help` and the fresh targeted-create smoke flow after that text change.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No Phase 05 correctness blockers remain after verification.
|
||||
- Dedicated permanent automated coverage for workspace-targeted change creation is still intentionally deferred to Phase 06.
|
||||
- The shared metadata `created` date remains UTC-based. On 2026-04-17 in Australia/Sydney, the generated file stored `2026-04-16`. This is existing shared behavior rather than a Phase 05-specific regression.
|
||||
@@ -0,0 +1,47 @@
|
||||
# Phase 06 Manual Test
|
||||
|
||||
Manual pass date: 2026-04-17
|
||||
Phase cycle: 1
|
||||
Stage: `manual-test`
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Reused the current built CLI from `pnpm run build`.
|
||||
- Created a fresh isolated workspace by copying the `happy-path` workspace fixture and repo fixtures into a temporary directory.
|
||||
- Rewrote `.openspec/local.yaml` in the copied workspace so `app`, `api`, and `docs` pointed to canonical absolute repo paths inside the temporary fixture root.
|
||||
On this macOS host, that canonicalization resolved the temp repo roots under `/private/var/...`.
|
||||
- Created repo-local `openspec/changes/` directories in all three attached repos so `workspace doctor` exercised a healthy registered workspace.
|
||||
- Ran `OPEN_SPEC_TELEMETRY_DISABLED=1 node bin/openspec.js --no-color new change phase06-manual --targets app,api` from the workspace root.
|
||||
- Ran `OPEN_SPEC_TELEMETRY_DISABLED=1 node bin/openspec.js --no-color status --change phase06-manual --json`.
|
||||
- Ran `OPEN_SPEC_TELEMETRY_DISABLED=1 node bin/openspec.js --no-color workspace doctor --json`.
|
||||
- Ran `OPEN_SPEC_TELEMETRY_DISABLED=1 node bin/openspec.js --no-color new change phase06-bad --targets app,missing`.
|
||||
- Checked that no repo-local `openspec/changes/phase06-manual` or `openspec/changes/phase06-bad` directories existed in `app`, `api`, or `docs`.
|
||||
|
||||
## Results
|
||||
|
||||
- `new change phase06-manual --targets app,api` exited `0` and created `changes/phase06-manual/` in the workspace root.
|
||||
- The resulting workspace change kept the expected central planning topology:
|
||||
- `.openspec.yaml`
|
||||
- `proposal.md`
|
||||
- `design.md`
|
||||
- `tasks/coordination.md`
|
||||
- `targets/app/{tasks.md,specs/}`
|
||||
- `targets/api/{tasks.md,specs/}`
|
||||
- `status --change phase06-manual --json` exited `0` and returned parseable JSON for the workspace change.
|
||||
- The status JSON reported:
|
||||
- `proposal: done`
|
||||
- `design: done`
|
||||
- `specs: ready`
|
||||
- `tasks: blocked` by `specs`
|
||||
- `workspace doctor --json` exited `0` and returned `status: "ok"` with `issues: []`.
|
||||
- `new change phase06-bad --targets app,missing` exited `1` with `Unknown target alias: missing. Registered aliases: api, app, docs`.
|
||||
- No repo-local change directories were created in any attached repo for either the successful or rejected create attempt.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product fixes were required during this manual-test pass.
|
||||
- The temporary workspace overlay was canonicalized before running `workspace doctor --json` so the copied fixture matched the CLI's expected path form on this macOS host.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- None found within the Phase 06 scope.
|
||||
@@ -0,0 +1,57 @@
|
||||
# Phase 06 Summary
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
|
||||
## Changes made
|
||||
|
||||
- Added workspace-aware change-container helpers in `src/core/workspace/metadata.ts` and reused them from:
|
||||
- `src/commands/workflow/shared.ts`
|
||||
- `src/core/artifact-graph/instruction-loader.ts`
|
||||
- Fixed the workflow path mismatch exposed by the new coverage so `status --change <name>` can read workspace-created changes from top-level `changes/` instead of only repo-local `openspec/changes/`.
|
||||
- Added an exact workspace-change topology assertion to `test/helpers/workspace-assertions.ts`.
|
||||
- Added focused core coverage in `test/core/workspace/change-create.test.ts` for:
|
||||
- `parseWorkspaceTargets()`
|
||||
- workspace change metadata
|
||||
- layout-only central planning scaffolds
|
||||
- unknown alias rejection
|
||||
- Added command-surface coverage in `test/commands/workflow/new-change.workspace.test.ts` for targeted change creation inside a registered workspace.
|
||||
- Added CLI e2e coverage in `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts` for:
|
||||
- successful targeted creation
|
||||
- unknown alias rejection
|
||||
- untouched repo-local roots
|
||||
- healthy `status` and `workspace doctor` after creation
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- `pnpm run build`
|
||||
- `pnpm vitest --run test/core/workspace/change-create.test.ts test/commands/workflow/new-change.workspace.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- `pnpm vitest --run test/core/artifact-graph/instruction-loader.test.ts test/commands/artifact-workflow.test.ts test/cli-e2e/workspace/workspace-registry-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- `git diff --check -- src/core/workspace/metadata.ts src/commands/workflow/shared.ts src/core/artifact-graph/instruction-loader.ts test/helpers/workspace-assertions.ts test/core/workspace/change-create.test.ts test/commands/workflow/new-change.workspace.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Fresh built-CLI smoke in an isolated copied workspace fixture with telemetry disabled:
|
||||
- `node bin/openspec.js --no-color new change phase06-manual --targets app,api`
|
||||
- `node bin/openspec.js --no-color status --change phase06-manual --json`
|
||||
- `node bin/openspec.js --no-color workspace doctor --json`
|
||||
- `node bin/openspec.js --no-color new change phase06-bad --targets app,missing`
|
||||
- explicit repo-root checks that no `openspec/changes/phase06-manual` or `openspec/changes/phase06-bad` directories were created under `app`, `api`, or `docs`
|
||||
|
||||
## Results
|
||||
|
||||
- Build passed.
|
||||
- The focused Phase 06 slice passed: 9/9 tests.
|
||||
- The broader regression slice that touches workflow loading and workspace registry behavior passed: 98/98 tests.
|
||||
- `new change --targets` now has direct coverage for rejecting aliases outside the workspace registry.
|
||||
- Workspace change creation is now proven to produce only:
|
||||
- central planning artifacts at the workspace change root
|
||||
- per-target partitions under `targets/<alias>/`
|
||||
- Successful targeted creation leaves repo-local `openspec/changes/` roots untouched before any materialization step.
|
||||
- `status --change` now succeeds for workspace-created changes and reports the expected incomplete planning state:
|
||||
- `proposal` and `design` are `done`
|
||||
- `specs` is `ready`
|
||||
- `tasks` is `blocked` by missing `specs`
|
||||
- `workspace doctor --json` still reports a healthy workspace after targeted change creation.
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 06.
|
||||
- No new bounded follow-up phases were required from this implementation pass.
|
||||
@@ -0,0 +1,48 @@
|
||||
# Phase 06 Verification
|
||||
|
||||
Verification re-run in a fresh shell context on 2026-04-17 for ROADMAP Phase 06, cycle 1.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 06 block in `ROADMAP.md`.
|
||||
- Reviewed the current phase artifacts for scope and note quality:
|
||||
- `notes/workspace-poc/phase-06-test-targeted-change-create/SUMMARY.md`
|
||||
- `notes/workspace-poc/phase-06-test-targeted-change-create/MANUAL_TEST.md`
|
||||
- Reviewed the implementation and tests touched by this phase:
|
||||
- `src/commands/workflow/new-change.ts`
|
||||
- `src/core/workspace/change-create.ts`
|
||||
- `src/core/workspace/metadata.ts`
|
||||
- `src/commands/workflow/shared.ts`
|
||||
- `src/core/artifact-graph/instruction-loader.ts`
|
||||
- `test/helpers/workspace-assertions.ts`
|
||||
- `test/core/workspace/change-create.test.ts`
|
||||
- `test/commands/workflow/new-change.workspace.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Rebuilt the CLI with `pnpm run build`.
|
||||
- Re-ran the focused Phase 06 automated slice:
|
||||
- `pnpm vitest --run test/core/workspace/change-create.test.ts test/commands/workflow/new-change.workspace.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Re-ran the closest regression slice for shared workflow path resolution and workspace health:
|
||||
- `pnpm vitest --run test/core/artifact-graph/instruction-loader.test.ts test/commands/artifact-workflow.test.ts test/cli-e2e/workspace/workspace-registry-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Ran `git diff --check` on the Phase 06 source, helper, and test files.
|
||||
- Re-executed the manual smoke against a freshly copied `happy-path` workspace fixture with telemetry disabled:
|
||||
- `node bin/openspec.js --no-color new change phase06-manual --targets app,api`
|
||||
- `node bin/openspec.js --no-color status --change phase06-manual --json`
|
||||
- `node bin/openspec.js --no-color workspace doctor --json`
|
||||
- `node bin/openspec.js --no-color new change phase06-bad --targets app,missing`
|
||||
- explicit repo-root checks that no `openspec/changes/phase06-manual` or `openspec/changes/phase06-bad` directories were created under `app`, `api`, or `docs`
|
||||
|
||||
## Issues found
|
||||
|
||||
- No remaining product or test failures were found in the current Phase 06 scope.
|
||||
- During the first manual smoke setup, the temporary workspace overlay used raw `/var/...` paths; on this macOS host `workspace doctor --json` correctly flagged them as `non-canonical-path` drift because the canonical repo roots resolve under `/private/var/...`.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No additional fixes were required during this verification pass.
|
||||
- Corrected the manual verification setup to rewrite `.openspec/local.yaml` with canonicalized repo paths before the final `workspace doctor --json` check.
|
||||
- Refreshed this verification artifact so it reflects the current post-fix validation run instead of an empty placeholder.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No blocking risks remain within the Phase 06 scope.
|
||||
- This phase stays bounded to targeted workspace change creation and its pre-materialization stability checks; later workspace-open and materialization behavior remains outside this phase.
|
||||
@@ -0,0 +1,189 @@
|
||||
# Phase 07 Decision
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
## Recommended contract
|
||||
|
||||
The minimum honest v0 contract for `workspace open` is:
|
||||
|
||||
- `openspec workspace open` is a planning-only session-prep command.
|
||||
- `openspec workspace open --change <id>` is a change-scoped attached-roots session-prep command.
|
||||
- v0 produces a usable instruction surface for one supported agent path instead of promising generic external process launch.
|
||||
- v0 officially supports only `--agent claude`. Omitting `--agent` defaults to `claude`.
|
||||
- `workspace open --change <id>` resolves only that change's targeted repos and hard-fails if any target repo is unresolved.
|
||||
- `workspace open` never materializes repo-local changes and never replaces `openspec apply --change <id> --repo <alias>`.
|
||||
|
||||
This is the smallest contract that is still real:
|
||||
|
||||
- planning-only mode is useful even when no repos are ready
|
||||
- attached mode is honest only when every targeted repo is actually readable
|
||||
- the CLI stays responsible for materialization, not the agent
|
||||
- the POC avoids claiming multi-agent parity that the current code and tool landscape do not prove
|
||||
|
||||
## Why this contract
|
||||
|
||||
Evidence reviewed for this phase:
|
||||
|
||||
- `src/commands/workspace.ts` currently implements only `create`, `add-repo`, and `doctor`; there is no `open` entrypoint yet.
|
||||
- `src/core/workspace/registry.ts` already defines the concrete repo-resolution failure states the new command can build on.
|
||||
- `src/core/workspace/change-create.ts` already makes target aliases explicit in workspace change metadata.
|
||||
- `src/core/command-generation/adapters/claude.ts`, `codex.ts`, and `github-copilot.ts` show that command formatting exists, but not a stable cross-tool attach-at-launch contract.
|
||||
- `docs/supported-tools.md` already documents that Copilot custom prompts are IDE-only and that Codex commands are global prompts, which is weaker than a clean repo-scoped attach story.
|
||||
- `WORKSPACE_POC_PRD.md` and `WORKSPACE_POC_DECISION_RECORD.md` both point toward planning-only vs attached-roots mode and a single primary demo path.
|
||||
|
||||
The practical conclusion is:
|
||||
|
||||
- planning-only mode should exist independently of repo resolution
|
||||
- change-scoped attached mode should be all-targets-or-fail
|
||||
- the first shipped path should optimize for one tool, not theoretical parity
|
||||
|
||||
## Exact user-visible behavior
|
||||
|
||||
### `openspec workspace open`
|
||||
|
||||
`workspace open` with no `--change` enters planning-only mode.
|
||||
|
||||
Behavior:
|
||||
|
||||
- Must be run inside a managed workspace created with `openspec workspace create`.
|
||||
- Defaults to `--agent claude` when `--agent` is omitted.
|
||||
- Does not resolve repo aliases and does not attach any repo roots.
|
||||
- Exits successfully with a planning-only instruction surface rooted at the workspace.
|
||||
- The surface must state:
|
||||
- mode: `planning-only`
|
||||
- workspace root path
|
||||
- agent target
|
||||
- attached repos: `none`
|
||||
- next step: use the workspace for central planning, then run `workspace open --change <id>` when target repos need to be in view
|
||||
- Does not create or update repo-local change artifacts.
|
||||
- Does not mutate workspace metadata.
|
||||
|
||||
### `openspec workspace open --change <id>`
|
||||
|
||||
`workspace open --change <id>` enters change-scoped attached-roots mode.
|
||||
|
||||
Behavior:
|
||||
|
||||
- Must be run inside a managed workspace created with `openspec workspace create`.
|
||||
- Defaults to `--agent claude` when `--agent` is omitted.
|
||||
- Validates that `changes/<id>/` exists in the workspace.
|
||||
- Reads the workspace change metadata and requires a non-empty `targets` list.
|
||||
- Resolves only the aliases named in that change's `targets`.
|
||||
- Treats a target as resolved only when:
|
||||
- the alias is registered in workspace metadata
|
||||
- the alias has a local overlay path
|
||||
- the resolved path exists and is a directory
|
||||
- the resolved path contains repo-local OpenSpec state at `openspec/`
|
||||
- On success, exits with a change-scoped instruction surface that states:
|
||||
- mode: `change-scoped`
|
||||
- workspace root path
|
||||
- change ID and change path
|
||||
- agent target
|
||||
- attached repos: only the targeted aliases with their resolved absolute paths
|
||||
- a reminder that `openspec apply --change <id> --repo <alias>` is still the supported materialization step
|
||||
- Does not attach every registered repo.
|
||||
- Does not create or update repo-local change artifacts.
|
||||
|
||||
### Failure behavior for targeted repos
|
||||
|
||||
`workspace open --change <id>` fails the entire command if one or more targeted repos are unresolved.
|
||||
|
||||
Behavior:
|
||||
|
||||
- Exit code is non-zero.
|
||||
- No partial success surface is emitted.
|
||||
- The error names every failing alias and why it failed.
|
||||
- The error points the user to `openspec workspace doctor` or the exact alias that needs repair.
|
||||
|
||||
Fatal failure reasons:
|
||||
|
||||
- change does not exist
|
||||
- change metadata has no `targets`
|
||||
- target alias is missing from the workspace registry
|
||||
- target alias is missing from `.openspec/local.yaml`
|
||||
- target repo path is missing
|
||||
- target repo path is not a directory
|
||||
- target repo path exists but lacks `openspec/`
|
||||
|
||||
Non-fatal nuance:
|
||||
|
||||
- A non-canonical but still valid stored path may be normalized for use and surfaced as drift, but it is not by itself an unresolved-target failure.
|
||||
|
||||
## Supported agent targets in v0
|
||||
|
||||
Decision:
|
||||
|
||||
- `claude` is the only officially supported `workspace open` agent target in v0.
|
||||
- Omitting `--agent` is equivalent to `--agent claude`.
|
||||
- Non-primary agents are explicitly out of scope for Phase 08 v0 behavior.
|
||||
|
||||
Rationale:
|
||||
|
||||
- Phase 08 only needs one primary agent path to produce a real demoable outcome.
|
||||
- The current codebase has command-format adapters for many tools, but that is not the same as proving stable multi-root session-open behavior.
|
||||
- Claude is already the clearest documented primary path in the workspace POC docs.
|
||||
- Supporting more tools now would expand the test matrix faster than the current workspace implementation surface justifies.
|
||||
|
||||
Follow-up note:
|
||||
|
||||
- Codex is the first revisit candidate after Phase 08 and Phase 09 if the primary path lands cleanly.
|
||||
- Copilot remains out of scope for v0 because the repo's current support is prompt-file oriented and not a credible one-shot multi-root CLI attach story.
|
||||
|
||||
## Rejected alternatives
|
||||
|
||||
### Rejected: attach every registered repo
|
||||
|
||||
Why rejected:
|
||||
|
||||
- it violates the roadmap principle that attachment should be change-scoped, not workspace-wide
|
||||
- it scales poorly as workspaces grow
|
||||
- it makes agent context noisy and hides the actual execution set
|
||||
|
||||
### Rejected: partial open when some targeted repos are unresolved
|
||||
|
||||
Why rejected:
|
||||
|
||||
- attached mode is only honest if the agent can see the full targeted working set
|
||||
- partial success creates a false sense that cross-repo planning is complete
|
||||
- planning-only mode already covers the "not all repos are ready yet" use case
|
||||
|
||||
### Rejected: promise multi-agent parity in v0
|
||||
|
||||
Why rejected:
|
||||
|
||||
- the repo currently proves command generation, not equal attach semantics across tools
|
||||
- it would force Phase 08 to solve tool-specific behavior instead of landing one real path
|
||||
- the roadmap only needs one primary agent path for the POC
|
||||
|
||||
### Rejected: auto-launch and manage external agent processes in v0
|
||||
|
||||
Why rejected:
|
||||
|
||||
- it adds tool-specific process and environment complexity that is not required to prove the contract
|
||||
- a deterministic instruction surface is enough for the next phase acceptance target
|
||||
|
||||
## Testable success and failure cases for Phase 08
|
||||
|
||||
### Success cases
|
||||
|
||||
- `openspec workspace open` inside a healthy workspace exits `0` and reports `planning-only` with `attached repos: none`.
|
||||
- `openspec workspace open --change shared-auth` for a change targeting `app,api` exits `0` and lists only `app` and `api`, not other registered aliases like `docs`.
|
||||
- `openspec workspace open --change shared-auth` reports the workspace root, the change path, and the exact resolved absolute repo paths for the targeted aliases.
|
||||
- `openspec workspace open --change shared-auth` leaves repo-local `openspec/changes/shared-auth` absent in all targeted repos.
|
||||
- `openspec workspace open --change shared-auth --agent claude` produces the same usable instruction surface as the default no-flag path.
|
||||
|
||||
### Failure cases
|
||||
|
||||
- `openspec workspace open` outside a managed workspace exits non-zero with an actionable workspace-root error.
|
||||
- `openspec workspace open --change missing-change` exits non-zero and names the missing change.
|
||||
- `openspec workspace open --change planning-only-draft` exits non-zero if the change exists but has no `targets` metadata.
|
||||
- `openspec workspace open --change shared-auth` exits non-zero when any targeted alias is missing from `.openspec/local.yaml`.
|
||||
- `openspec workspace open --change shared-auth` exits non-zero when any targeted path is stale, missing, or no longer contains `openspec/`.
|
||||
- `openspec workspace open --change shared-auth --agent codex` exits non-zero with an unsupported-agent error in v0.
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No new roadmap phase is required from this decision.
|
||||
- Phase 08 should implement only the recommended contract above and should not broaden agent scope during the build unless a new bounded phase is added first.
|
||||
@@ -0,0 +1,40 @@
|
||||
# Phase 07 Manual Test
|
||||
|
||||
Manual test stage re-run in a fresh isolated XDG context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 07, cycle 1.
|
||||
|
||||
This phase is research-only, so the manual pass combined a real CLI smoke for the current workspace/change workflow boundary with a tabletop review of the proposed `workspace open` contract. `workspace open` is not implemented yet, so the command itself was validated only up to its current user-visible absence (`error: unknown command 'open'`).
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Created isolated `XDG_DATA_HOME` and `XDG_CONFIG_HOME` roots under `/tmp` with `OPENSPEC_TELEMETRY=0` so the smoke could exercise the built CLI without writing to the real home directory.
|
||||
- Ran `node bin/openspec.js --no-color workspace create phase07-manual --json`.
|
||||
- Created three disposable repo roots with repo-local `openspec/` directories and registered them sequentially:
|
||||
- `workspace add-repo app ../../../../repos/app --json`
|
||||
- `workspace add-repo api ../../../../repos/api --json`
|
||||
- `workspace add-repo docs ../../../../repos/docs --json`
|
||||
- Ran `workspace doctor --json` to confirm the healthy registry state.
|
||||
- Ran `node bin/openspec.js --no-color new change shared-auth --targets app,api` inside the managed workspace.
|
||||
- Inspected `changes/shared-auth/.openspec.yaml` and the generated planning layout under `changes/shared-auth/targets/{app,api}`.
|
||||
- Ran `node bin/openspec.js --no-color workspace open` and `node bin/openspec.js --no-color workspace open --change shared-auth` to confirm the current CLI surface still rejects `open` as unimplemented.
|
||||
- Removed `repos/api/openspec`, reran `workspace doctor --json`, restored the directory, and reran `workspace doctor --json` to confirm the existing unresolved-repo diagnostics that Phase 07 relies on.
|
||||
|
||||
## Results
|
||||
|
||||
- `workspace create`, sequential `workspace add-repo`, `workspace doctor`, and `new change --targets` all worked in the fresh isolated context.
|
||||
- The created change wrote explicit target metadata to `changes/shared-auth/.openspec.yaml`:
|
||||
- `schema: spec-driven`
|
||||
- `targets: app, api`
|
||||
- The generated planning layout was change-scoped: `changes/shared-auth/targets/app/` and `changes/shared-auth/targets/api/` were created, and no `changes/shared-auth/targets/docs/` directory was created.
|
||||
- `workspace doctor` reported `status: ok` before the failure injection and then reported a precise `missing-openspec-state` issue for alias `api` after the repo-local `openspec/` directory was removed.
|
||||
- The current CLI still exposes no `workspace open` subcommand. Both `workspace open` and `workspace open --change shared-auth` failed with `error: unknown command 'open'`.
|
||||
- Given that runtime boundary, the remaining validation for Phase 07 stayed at the artifact/tabletop level: [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md) still matches the current implementation surface and does not overclaim behavior that exists today.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- Rewrote this manual-test artifact from the prior authoring-time tabletop note into a fresh-context record with real CLI evidence.
|
||||
- No product code or roadmap changes were required for Phase 07. The recommended contract in [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md) remained valid after the smoke and failure-injection pass.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- `workspace open` still has no runtime implementation, so this manual pass can only prove the surrounding workflow boundary and the honesty of the proposed contract, not the eventual UX.
|
||||
- Phase 08 still needs to implement the command exactly as documented, and Phase 09 still needs fixture-backed automated coverage for the success and failure cases listed in [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md).
|
||||
@@ -0,0 +1,49 @@
|
||||
# Phase 07 Summary
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
|
||||
## Changes made
|
||||
|
||||
- Added [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md) with a concrete v0 contract for `workspace open`.
|
||||
- Chose the minimum supported behavior for:
|
||||
- planning-only mode with `openspec workspace open`
|
||||
- change-scoped attached mode with `openspec workspace open --change <id>`
|
||||
- hard-fail behavior when one or more targeted repos are unresolved
|
||||
- official v0 agent support limited to `claude`, with non-primary agents explicitly out of scope
|
||||
- Added [VERIFY.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/VERIFY.md) and [MANUAL_TEST.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/MANUAL_TEST.md) to record the research checks and tabletop/manual review for this phase.
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- Re-read the Phase 07 block in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md) and confirmed the phase started with no on-disk artifacts.
|
||||
- Reviewed the current workspace implementation surface in:
|
||||
- [src/commands/workspace.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workspace.ts)
|
||||
- [src/core/workspace/registry.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/registry.ts)
|
||||
- [src/core/workspace/metadata.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/metadata.ts)
|
||||
- [src/core/workspace/change-create.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/change-create.ts)
|
||||
- Reviewed the existing tool-command surface in:
|
||||
- [src/core/command-generation/adapters/claude.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/command-generation/adapters/claude.ts)
|
||||
- [src/core/command-generation/adapters/codex.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/command-generation/adapters/codex.ts)
|
||||
- [src/core/command-generation/adapters/github-copilot.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/command-generation/adapters/github-copilot.ts)
|
||||
- [docs/supported-tools.md](/Users/tabishbidiwale/fission/repos/openspec/docs/supported-tools.md)
|
||||
- Reviewed the higher-level workspace direction in:
|
||||
- [WORKSPACE_POC_PRD.md](/Users/tabishbidiwale/fission/repos/openspec/WORKSPACE_POC_PRD.md)
|
||||
- [WORKSPACE_POC_DECISION_RECORD.md](/Users/tabishbidiwale/fission/repos/openspec/WORKSPACE_POC_DECISION_RECORD.md)
|
||||
- Ran focused research verification after drafting:
|
||||
- content checks against `DECISION.md` for recommended contract, rejected alternatives, exact command behavior, and next-phase success/failure cases
|
||||
- `git diff --check` on the touched Phase 07 files and `ROADMAP.md`
|
||||
|
||||
## Results
|
||||
|
||||
- The note now defines one recommended v0 contract instead of leaving `workspace open` underspecified.
|
||||
- The contract distinguishes planning-only mode from attached-roots mode and keeps repo attachment change-scoped.
|
||||
- The contract defines exact failure semantics: attached mode is all-targets-or-fail, with actionable diagnostics per failing alias.
|
||||
- The note explicitly chooses `claude` as the only official v0 agent target and keeps non-primary agents out of scope.
|
||||
- The note records multiple rejected alternatives so Phase 08 does not accidentally broaden scope.
|
||||
- The note lists concrete success and failure cases that are directly usable for Phase 08 implementation and Phase 09 test planning.
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 07.
|
||||
- No new bounded follow-up phase was required from this research pass.
|
||||
- Phase 08 should implement only the contract in `DECISION.md` and avoid adding multi-agent or partial-open behavior without a new explicit roadmap phase.
|
||||
@@ -0,0 +1,54 @@
|
||||
# Phase 07 Verification
|
||||
|
||||
Independent verification completed in a fresh context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 07, cycle 1.
|
||||
|
||||
This phase is research-only. `workspace open` is not implemented yet, so verification here checks the Phase 07 contract against the current codebase, roadmap, and workspace POC docs rather than executing a new CLI command.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 07 block in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md) and verified the completion checklist and acceptance targets for this phase.
|
||||
- Re-read [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md) and validated the documentation quality for the research output:
|
||||
- one recommended contract is named
|
||||
- rejected alternatives are listed
|
||||
- exact user-visible behavior is defined for both `openspec workspace open` and `openspec workspace open --change <id>`
|
||||
- concrete success and failure cases are listed for the next build and test phases
|
||||
- Reviewed the current workspace implementation boundary in:
|
||||
- [src/commands/workspace.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workspace.ts)
|
||||
- [src/core/workspace/registry.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/registry.ts)
|
||||
- [src/core/workspace/metadata.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/metadata.ts)
|
||||
- [src/core/workspace/change-create.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/change-create.ts)
|
||||
- [src/utils/change-metadata.ts](/Users/tabishbidiwale/fission/repos/openspec/src/utils/change-metadata.ts)
|
||||
- Confirmed the decision note stays inside the real implementation boundary:
|
||||
- there is no `workspace open` subcommand yet
|
||||
- workspace changes already record explicit `targets`
|
||||
- repo resolution and failure states already exist through workspace registry and doctor behavior
|
||||
- the note keeps `workspace open` read-only and does not blur into `openspec apply --change <id> --repo <alias>`
|
||||
- Reviewed the current agent/tool surface in:
|
||||
- [src/core/command-generation/adapters/claude.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/command-generation/adapters/claude.ts)
|
||||
- [src/core/command-generation/adapters/codex.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/command-generation/adapters/codex.ts)
|
||||
- [src/core/command-generation/adapters/github-copilot.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/command-generation/adapters/github-copilot.ts)
|
||||
- [docs/supported-tools.md](/Users/tabishbidiwale/fission/repos/openspec/docs/supported-tools.md)
|
||||
- Confirmed the agent-scope choice in the decision note matches the broader workspace POC direction in:
|
||||
- [WORKSPACE_POC_PRD.md](/Users/tabishbidiwale/fission/repos/openspec/WORKSPACE_POC_PRD.md)
|
||||
- [WORKSPACE_POC_DECISION_RECORD.md](/Users/tabishbidiwale/fission/repos/openspec/WORKSPACE_POC_DECISION_RECORD.md)
|
||||
- Ran `git diff --check -- ROADMAP.md notes/workspace-poc/phase-07-open-contract-research/DECISION.md notes/workspace-poc/phase-07-open-contract-research/SUMMARY.md notes/workspace-poc/phase-07-open-contract-research/VERIFY.md notes/workspace-poc/phase-07-open-contract-research/MANUAL_TEST.md`.
|
||||
- Ran `rg -n "[[:blank:]]$" ROADMAP.md notes/workspace-poc/phase-07-open-contract-research/DECISION.md notes/workspace-poc/phase-07-open-contract-research/SUMMARY.md notes/workspace-poc/phase-07-open-contract-research/VERIFY.md notes/workspace-poc/phase-07-open-contract-research/MANUAL_TEST.md` and confirmed there is no trailing whitespace in the Phase 07 files.
|
||||
|
||||
## Issues found
|
||||
|
||||
- The existing `VERIFY.md` was not a clean independent verification artifact. It included stale implementation-stage claims such as "confirmed the phase started with no on-disk artifacts" and authoring-time statements about changes made "during authoring," which do not belong in a fresh verification pass.
|
||||
- No contract gaps were found in [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md). The acceptance tests for this research phase are satisfied.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- Rewrote [VERIFY.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/VERIFY.md) to reflect only this fresh-context verification pass.
|
||||
- Removed stale claims about the prior artifact state and removed authoring-stage commentary that did not belong in independent verification.
|
||||
- Recorded a direct file-content whitespace check in addition to `git diff --check`, because the Phase 07 files are currently untracked in this worktree.
|
||||
- No changes were required to [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md), [MANUAL_TEST.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/MANUAL_TEST.md), or the Phase 07 checklist in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md).
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No residual research-note gaps were found for Phase 07 itself.
|
||||
- Runtime proof still belongs to later phases:
|
||||
- Phase 08 must implement the contract without broadening scope.
|
||||
- Phase 09 must validate the resulting behavior with fixture-backed tests.
|
||||
@@ -0,0 +1,50 @@
|
||||
# Phase 08 Manual Test
|
||||
|
||||
Manual smoke re-run in a fresh temp context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 08, cycle 1.
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Rebuilt the current CLI with `pnpm run build`.
|
||||
- Checked `node dist/cli/index.js workspace open --help`.
|
||||
- Created a brand-new temp sandbox by copying the real fixture state into sibling `workspace/` and `repos/` directories under one temp root, because `.openspec/local.yaml` resolves repo overlays through `../repos/*`:
|
||||
- `test/fixtures/workspace-poc/dirty/workspace`
|
||||
- `test/fixtures/workspace-poc/dirty/repos`
|
||||
- Ran the planning-only flow from inside the copied workspace:
|
||||
- `node dist/cli/index.js workspace open --json`
|
||||
- Created a healthy change-scoped case:
|
||||
- `node dist/cli/index.js new change shared-refresh --targets app,api`
|
||||
- `node dist/cli/index.js workspace open --change shared-refresh --json`
|
||||
- Verified the success case output reported:
|
||||
- `mode: "change-scoped"`
|
||||
- `change.id: "shared-refresh"`
|
||||
- attached repos for `app` and `api` only
|
||||
- no `docs` attachment
|
||||
- instruction surface path `.claude/commands/opsx/workspace-open.md`
|
||||
- Verified `workspace open` did not materialize repo-local execution state:
|
||||
- `repos/app/openspec/changes/shared-refresh` remained absent
|
||||
- `repos/api/openspec/changes/shared-refresh` remained absent
|
||||
- `repos/docs/openspec/changes/shared-refresh` remained absent
|
||||
- Created a stale-target failure case:
|
||||
- `node dist/cli/index.js new change shared-broken --targets app,docs`
|
||||
- `node dist/cli/index.js workspace open --change shared-broken`
|
||||
- Exercised the unsupported-agent path:
|
||||
- `node dist/cli/index.js workspace open --agent codex`
|
||||
|
||||
## Results
|
||||
|
||||
- All manual smoke scenarios passed.
|
||||
- Planning-only open succeeded even though the copied fixture still had a stale `docs` path in `.openspec/local.yaml`, confirming that the no-change path does not attach repo roots.
|
||||
- Change-scoped open for `shared-refresh` attached only `app` and `api`, not all registered repos.
|
||||
- Change-scoped open for `shared-broken` failed with a non-zero exit and the expected actionable message naming `docs` plus the `workspace doctor` repair path.
|
||||
- The unsupported-agent path failed cleanly with `Unsupported agent 'codex' for workspace open in v0. Supported agent: claude.`
|
||||
- `workspace open` left repo-local `openspec/changes/shared-refresh` directories absent in all copied repos after the smoke run.
|
||||
- The help surface still exposes the Phase 08 contract cleanly: `--change <id>`, `--agent <tool>` with `claude` as the v0 default, and `--json`.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product fixes were required during this manual-test pass.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No Phase 08 user-visible regressions or residual risks were identified in this manual smoke cycle.
|
||||
- Phase 09 can still widen the permanent validation matrix, but the shipped Phase 08 user path behaved as intended end to end.
|
||||
@@ -0,0 +1,56 @@
|
||||
# Phase 08 Summary
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
## Changes made
|
||||
|
||||
- Added [src/core/workspace/open.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/open.ts) so `openspec workspace open` now supports:
|
||||
- planning-only mode when no `--change` is supplied
|
||||
- change-scoped mode for `--change <id>`
|
||||
- defaulting `--agent` to `claude`
|
||||
- generating a usable Claude instruction surface through the existing command adapter/generator path instead of inventing a separate formatter
|
||||
- validating that workspace changes exist and have non-empty `targets`
|
||||
- resolving only the targeted repos for the selected change
|
||||
- hard-failing with aggregated actionable diagnostics when one or more targeted repos are unresolved
|
||||
- Extended [src/core/workspace/registry.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/registry.ts) with target-specific repo resolution helpers so `workspace open` can reuse the existing registry model while resolving only the change’s requested aliases.
|
||||
- Extended [src/commands/workspace.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workspace.ts) with `openspec workspace open`, including both human-readable and `--json` output.
|
||||
- Added focused Phase 08 coverage in:
|
||||
- [test/core/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/core/workspace/open.test.ts)
|
||||
- [test/commands/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/commands/workspace/open.test.ts)
|
||||
- [test/cli-e2e/workspace/workspace-open-cli.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/cli-e2e/workspace/workspace-open-cli.test.ts)
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- `pnpm run build`
|
||||
- `pnpm vitest run test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
|
||||
- `pnpm vitest run test/core/workspace/*.test.ts test/commands/workspace/*.test.ts test/cli-e2e/workspace/*.test.ts`
|
||||
- `node dist/cli/index.js workspace open --help`
|
||||
- Fresh copied-fixture CLI smoke on 2026-04-17 (Australia/Sydney):
|
||||
- copied `test/fixtures/workspace-poc/dirty/{workspace,repos}` into a fresh temp root
|
||||
- `node dist/cli/index.js workspace open --json`
|
||||
- `node dist/cli/index.js new change shared-refresh --targets app,api`
|
||||
- `node dist/cli/index.js workspace open --change shared-refresh --json`
|
||||
- verified only `app` and `api` were attached
|
||||
- verified `repos/{app,api,docs}/openspec/changes/shared-refresh` remained absent after `workspace open`
|
||||
- `node dist/cli/index.js new change shared-broken --targets app,docs`
|
||||
- `node dist/cli/index.js workspace open --change shared-broken`
|
||||
- `node dist/cli/index.js workspace open --agent codex`
|
||||
|
||||
## Results
|
||||
|
||||
- Build passed.
|
||||
- Focused Phase 08 tests passed: 7/7.
|
||||
- Broader workspace regression coverage passed: 37/37.
|
||||
- `workspace open` without `--change` now succeeds in planning-only mode and reports `attachedRepos: []` / `Attached repos: none`.
|
||||
- `workspace open --change <id>` now attaches only the change’s targeted repos and does not pull in unrelated registered aliases.
|
||||
- Change-scoped open now fails clearly when a targeted repo path is stale or missing, and the error names the broken alias plus the `workspace doctor` repair path.
|
||||
- The primary v0 agent path now produces a usable Claude instruction surface at `.claude/commands/opsx/workspace-open.md`.
|
||||
- `workspace open` does not materialize repo-local changes during the session-prep flow.
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 08.
|
||||
- No new roadmap phases were required from this implementation pass.
|
||||
- Phase 09 can expand the validation matrix further, but the Phase 08 contract is now implemented, exercised, and manually smoke-tested.
|
||||
@@ -0,0 +1,41 @@
|
||||
# Phase 08 Verification
|
||||
|
||||
Independent verification re-run in a fresh context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 08, cycle 1.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 08 block in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md) and the current phase artifacts in [SUMMARY.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-08-workspace-open/SUMMARY.md) and [MANUAL_TEST.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-08-workspace-open/MANUAL_TEST.md).
|
||||
- Reviewed the implementation boundary in:
|
||||
- [src/core/workspace/open.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/open.ts)
|
||||
- [src/core/workspace/registry.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/registry.ts)
|
||||
- [src/commands/workspace.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workspace.ts)
|
||||
- [test/core/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/core/workspace/open.test.ts)
|
||||
- [test/commands/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/commands/workspace/open.test.ts)
|
||||
- [test/cli-e2e/workspace/workspace-open-cli.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/cli-e2e/workspace/workspace-open-cli.test.ts)
|
||||
- Confirmed `node dist/cli/index.js workspace open --help` documents:
|
||||
- `--change <id>`
|
||||
- `--agent <tool>` with `claude` as the default
|
||||
- `--json`
|
||||
- Rebuilt the current tree with `pnpm run build`.
|
||||
- Re-ran the focused Phase 08 suites with `pnpm vitest run test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`.
|
||||
- Re-ran the broader workspace regression slice with `pnpm vitest run test/core/workspace/*.test.ts test/commands/workspace/*.test.ts test/cli-e2e/workspace/*.test.ts`.
|
||||
- Rechecked the copied-fixture CLI smoke outcomes in a fresh temp root while preserving the expected sibling `workspace/` and `repos/` fixture layout from `.openspec/local.yaml`:
|
||||
- planning-only open attached no repos even with a stale non-targeted `docs` overlay entry
|
||||
- change-scoped open for a change targeting `app,api` attached only those repos
|
||||
- change-scoped open for a change targeting `app,docs` failed non-zero with an aggregated alias-specific diagnostic
|
||||
- unsupported-agent open failed cleanly with the documented v0 `claude`-only error
|
||||
|
||||
## Issues found
|
||||
|
||||
- No Phase 08 product correctness issues were found during the independent verification pass.
|
||||
- The manual test notes were slightly underspecified about fixture layout. Copying the dirty workspace fixture into an arbitrary directory name breaks the smoke harness because the checked-in local overlay uses relative `../repos/*` paths.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product code changes were required during verification.
|
||||
- Clarified [MANUAL_TEST.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-08-workspace-open/MANUAL_TEST.md) so the copied-fixture smoke explicitly preserves sibling `workspace/` and `repos/` directories.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- `workspace open` intentionally supports only `claude` in v0. That is the chosen Phase 08 contract, not an accidental gap.
|
||||
- Phase 09 can still widen and harden the validation matrix, especially around unsupported-agent coverage and extra edge cases, but no Phase 08 blocker remains.
|
||||
@@ -0,0 +1,49 @@
|
||||
# Phase 09 Manual Test
|
||||
|
||||
Manual smoke re-run in a fresh temp context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 09, cycle 1.
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Rebuilt the current CLI with `pnpm run build`.
|
||||
- Created a brand-new temp sandbox by copying the real dirty fixture into sibling `workspace/` and `repos/` directories under one temp root:
|
||||
- `test/fixtures/workspace-poc/dirty/workspace`
|
||||
- `test/fixtures/workspace-poc/dirty/repos`
|
||||
- Canonicalized the temp root with `pwd -P` before making path assertions so the smoke matched the CLI's real canonical path output on macOS.
|
||||
- Confirmed the copied dirty fixture preserved the stale `docs` alias pointing at a missing `repos/docs-missing` path before exercising the failure case.
|
||||
- Ran the planning-only flow:
|
||||
- `node dist/cli/index.js workspace open --json`
|
||||
- Created a healthy change-scoped case:
|
||||
- `node dist/cli/index.js new change shared-refresh --targets app,api`
|
||||
- `node dist/cli/index.js workspace open --change shared-refresh --agent claude`
|
||||
- Verified the success case output reported:
|
||||
- `Prepared change-scoped workspace open surface for claude.`
|
||||
- instruction surface path `.claude/commands/opsx/workspace-open.md`
|
||||
- attached repos for `app` and `api` only
|
||||
- no `docs` attachment
|
||||
- the `openspec apply --change shared-refresh --repo <alias>` reminder
|
||||
- Verified the session-prep contract stayed intact:
|
||||
- `workspace/.claude/commands/opsx/workspace-open.md` was still absent on disk after the command
|
||||
- `repos/app/openspec/changes/shared-refresh` was absent
|
||||
- `repos/api/openspec/changes/shared-refresh` was absent
|
||||
- Created a stale-target failure case:
|
||||
- `node dist/cli/index.js new change shared-broken --targets app,docs`
|
||||
- `node dist/cli/index.js workspace open --change shared-broken`
|
||||
- Exercised the unsupported-agent path:
|
||||
- `node dist/cli/index.js workspace open --agent codex`
|
||||
|
||||
## Results
|
||||
|
||||
- All manual smoke scenarios passed.
|
||||
- Planning-only open succeeded without exposing attached repo roots, even with the copied fixture still carrying the stale `docs -> repos/docs-missing` alias.
|
||||
- Change-scoped open for `shared-refresh` attached only `app` and `api`, not all registered repos.
|
||||
- The Claude demo path remained instruction-surface only; it did not write a `.claude` command file and did not materialize repo-local execution state.
|
||||
- Change-scoped open for `shared-broken` failed with a non-zero exit and the expected actionable message naming `docs`, the missing `repos/docs-missing` path, and the `workspace doctor` repair path.
|
||||
- The unsupported-agent path failed cleanly with `Unsupported agent 'codex' for workspace open in v0. Supported agent: claude.`
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product fixes were required during this manual-test pass.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No new user-visible residual risks were identified within the Phase 09 validation scope.
|
||||
@@ -0,0 +1,49 @@
|
||||
# Phase 09 Summary
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
## Changes made
|
||||
|
||||
- Added stronger Phase 09 validation coverage for `workspace open` in:
|
||||
- [test/core/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/core/workspace/open.test.ts)
|
||||
- [test/commands/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/commands/workspace/open.test.ts)
|
||||
- [test/cli-e2e/workspace/workspace-open-cli.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/cli-e2e/workspace/workspace-open-cli.test.ts)
|
||||
- Strengthened the planning-only assertions so Phase 09 now proves the surface does not leak attached repo roots, including stale overlay paths from the dirty fixture.
|
||||
- Added command and CLI coverage that proves change-scoped open lists only targeted aliases and excludes unrelated registered repos.
|
||||
- Added unsupported-agent coverage for the documented v0 contract (`claude` only), using `codex` as the explicit negative case even though that tool has a command adapter elsewhere in the repo.
|
||||
- Added non-JSON CLI e2e coverage for the primary Claude demo path and asserted that `workspace open` stays session-prep only:
|
||||
- no `.claude/commands/opsx/workspace-open.md` file is written to disk
|
||||
- no repo-local `openspec/changes/<id>` materialization is created in attached repos
|
||||
- Updated the Phase 09 checklist in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md).
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- `pnpm run build`
|
||||
- `pnpm vitest run test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
|
||||
- `pnpm vitest run test/core/workspace/*.test.ts test/commands/workspace/*.test.ts test/cli-e2e/workspace/*.test.ts`
|
||||
- Fresh copied-fixture CLI smoke on 2026-04-17 (Australia/Sydney):
|
||||
- copied `test/fixtures/workspace-poc/dirty/{workspace,repos}` into a fresh temp root while preserving sibling `workspace/` and `repos/`
|
||||
- canonicalized the temp root with `pwd -P` so the smoke assertions matched the CLI's real path normalization on macOS
|
||||
- ran `node dist/cli/index.js workspace open --json`
|
||||
- ran `node dist/cli/index.js new change shared-refresh --targets app,api`
|
||||
- ran `node dist/cli/index.js workspace open --change shared-refresh --agent claude`
|
||||
- ran `node dist/cli/index.js new change shared-broken --targets app,docs`
|
||||
- ran `node dist/cli/index.js workspace open --change shared-broken`
|
||||
- ran `node dist/cli/index.js workspace open --agent codex`
|
||||
|
||||
## Results
|
||||
|
||||
- Build passed.
|
||||
- Focused Phase 09 workspace-open validation passed: 12/12 tests.
|
||||
- Broader workspace regression coverage passed: 42/42 tests.
|
||||
- Planning-only open now has permanent coverage proving it exposes no attached repo roots in either JSON output or the generated instruction surface.
|
||||
- Change-scoped open now has permanent coverage proving it attaches only the targeted aliases and excludes unrelated registered repos.
|
||||
- Failure coverage now proves unresolved target diagnostics include both the failing alias and the `workspace doctor` repair path.
|
||||
- The primary Claude demo path is covered end to end in CLI e2e without relying on real multi-root writes or repo-local materialization.
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 09.
|
||||
- No new roadmap phases were required from this validation pass.
|
||||
@@ -0,0 +1,47 @@
|
||||
# Phase 09 Verification
|
||||
|
||||
Independent verification re-run in a fresh context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 09, cycle 1.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 09 block in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md) and the current implementation summary in [notes/workspace-poc/phase-09-test-workspace-open/SUMMARY.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-09-test-workspace-open/SUMMARY.md).
|
||||
- Reviewed the implementation boundary in:
|
||||
- [src/core/workspace/open.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/open.ts)
|
||||
- [src/commands/workspace.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workspace.ts)
|
||||
- [test/core/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/core/workspace/open.test.ts)
|
||||
- [test/commands/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/commands/workspace/open.test.ts)
|
||||
- [test/cli-e2e/workspace/workspace-open-cli.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/cli-e2e/workspace/workspace-open-cli.test.ts)
|
||||
- Rebuilt the current tree with `pnpm run build`.
|
||||
- Re-ran the focused Phase 09 suites with `pnpm vitest run test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`.
|
||||
- Result: 3 files passed, 12/12 tests passed.
|
||||
- Re-ran the broader workspace regression slice with `pnpm vitest run test/core/workspace/*.test.ts test/commands/workspace/*.test.ts test/cli-e2e/workspace/*.test.ts`.
|
||||
- Result: 13 files passed, 42/42 tests passed.
|
||||
- Re-ran a fresh copied-fixture CLI smoke against sibling `workspace/` and `repos/` directories under a new temp root, canonicalized with `pwd -P`, then exercised:
|
||||
- `node dist/cli/index.js workspace open --json`
|
||||
- `node dist/cli/index.js new change shared-refresh --targets app,api`
|
||||
- `node dist/cli/index.js workspace open --change shared-refresh --agent claude`
|
||||
- `node dist/cli/index.js new change shared-broken --targets app,docs`
|
||||
- `node dist/cli/index.js workspace open --change shared-broken`
|
||||
- `node dist/cli/index.js workspace open --agent codex`
|
||||
- Validated the documented contract and notes quality for this phase:
|
||||
- planning-only open exposes no attached repo roots
|
||||
- change-scoped open lists only targeted aliases
|
||||
- stale-target diagnostics name the failing alias and `workspace doctor`
|
||||
- the Claude demo path stays session-prep only and does not write a real multi-root command file or repo-local materialization
|
||||
- [notes/workspace-poc/phase-09-test-workspace-open/MANUAL_TEST.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-09-test-workspace-open/MANUAL_TEST.md) still matches the real CLI behavior exercised in this pass
|
||||
|
||||
## Issues found
|
||||
|
||||
- No product correctness issues were found.
|
||||
- No acceptance-test coverage gaps were found for the Phase 09 scope.
|
||||
- No documentation-quality issues were found in the current summary or manual-test notes.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product or test changes were required during this verification pass.
|
||||
- Updated this verification artifact to reflect the fresh-context checks and outcomes above.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No residual risks were identified within the Phase 09 verification scope.
|
||||
- The `claude`-only agent constraint remains an intentional v0 boundary and is explicitly covered by negative tests.
|
||||
@@ -0,0 +1,185 @@
|
||||
# Phase 10 Decision
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
## Recommended v0 contract
|
||||
|
||||
The v0 materialization contract for `openspec apply --change <id> --repo <alias>` is:
|
||||
|
||||
- create-only at the selected target repo
|
||||
- zero overwrite behavior
|
||||
- no refresh or re-materialize path in v0
|
||||
- reuse the workspace change ID as the repo-local change ID
|
||||
- keep the repo-local bundle self-contained enough to execute without going back to the workspace
|
||||
- keep workspace planning artifacts intact after apply
|
||||
|
||||
In concrete terms, a successful v0 apply writes exactly one repo-local change at:
|
||||
|
||||
`<resolved-repo>/openspec/changes/<change-id>/`
|
||||
|
||||
The repo-local bundle should contain:
|
||||
|
||||
- `.openspec.yaml` with the workspace change schema and a repo-local `created` date
|
||||
- `proposal.md` copied from the workspace change root
|
||||
- `design.md` copied from the workspace change root
|
||||
- `tasks.md` copied from `targets/<alias>/tasks.md`
|
||||
- `specs/` copied from `targets/<alias>/specs/`
|
||||
- `.openspec.materialization.yaml` as the minimum trace sidecar
|
||||
|
||||
The trace sidecar should be the smallest machine-readable link needed for later roll-up without redesigning core change metadata:
|
||||
|
||||
```yaml
|
||||
source: workspace
|
||||
workspaceName: <workspace metadata name>
|
||||
targetAlias: <alias>
|
||||
materializedAt: <ISO-8601 timestamp>
|
||||
```
|
||||
|
||||
This file intentionally does not store absolute paths.
|
||||
|
||||
What stays in the workspace only:
|
||||
|
||||
- `tasks/coordination.md`
|
||||
- any other workspace-only planning notes outside the selected target slice
|
||||
- the original `targets/` tree
|
||||
|
||||
## Why this contract
|
||||
|
||||
Evidence reviewed for this phase:
|
||||
|
||||
- `src/core/workspace/open.ts` explicitly keeps `workspace open` read-only and tells the user that repo-local materialization happens later with `openspec apply --change <id> --repo <alias>`.
|
||||
- `src/core/workspace/change-create.ts` already stores the shared planning truth centrally: schema, created date, and explicit target aliases in the workspace change.
|
||||
- `src/utils/change-metadata.ts` and `src/core/artifact-graph/types.ts` currently model normal change metadata as `schema`, `created`, and optional `targets`; adding traceability through a sidecar is less invasive than expanding `.openspec.yaml` first.
|
||||
- `schemas/spec-driven/schema.yaml` expects repo-local execution artifacts in their normal locations, especially root-level `tasks.md` and `specs/`.
|
||||
- The current CLI surface has schema-aware apply instructions, but no repo-aware `apply --repo` materialization implementation yet, so Phase 11 should land a narrow write contract instead of a refresh engine.
|
||||
|
||||
The practical conclusion is:
|
||||
|
||||
- create-only is the smallest honest contract for the POC
|
||||
- repo-local execution should not depend on the workspace remaining mounted in context
|
||||
- traceability should be explicit, but minimal
|
||||
|
||||
## Exact v0 behavior
|
||||
|
||||
### Preconditions
|
||||
|
||||
`openspec apply --change <id> --repo <alias>` should hard-fail unless all of the following are true:
|
||||
|
||||
- the command is run from a managed workspace root
|
||||
- `changes/<id>/` exists in that workspace
|
||||
- the workspace change metadata contains `targets`
|
||||
- `<alias>` is one of those targets
|
||||
- `<alias>` resolves through workspace metadata and local overlay to a live repo containing `openspec/`
|
||||
- the workspace change has the source files needed for a repo-local execution bundle:
|
||||
- `proposal.md`
|
||||
- `design.md`
|
||||
- `targets/<alias>/tasks.md`
|
||||
- `targets/<alias>/specs/` (may be empty, but the directory must exist)
|
||||
- the destination repo does not already contain `openspec/changes/<id>/`
|
||||
|
||||
### Successful materialization
|
||||
|
||||
A materialization counts as successful only when:
|
||||
|
||||
- the command exits `0`
|
||||
- only the selected target repo is modified
|
||||
- the destination repo now contains one complete repo-local change at `openspec/changes/<id>/`
|
||||
- that repo-local change includes the exact files listed in the recommended contract above
|
||||
- the workspace change remains intact and unchanged after the write
|
||||
|
||||
At the selected-repo scope, success is all-or-nothing:
|
||||
|
||||
- validate every source and destination condition before writing
|
||||
- stage the repo-local bundle in a fresh temp directory
|
||||
- move it into place only after the bundle is complete
|
||||
- if staging fails, clean up the temp directory and leave the final destination absent
|
||||
|
||||
### Repeat `apply` behavior
|
||||
|
||||
The repeat-call behavior in v0 is:
|
||||
|
||||
- first successful apply for a target repo creates that repo-local change and transfers execution authority for that target
|
||||
- repeating apply for the same `<change-id>` and the same `<alias>` fails clearly because v0 is create-only
|
||||
- repeating apply for a different targeted alias is allowed if that other target repo does not already have `openspec/changes/<id>/`
|
||||
- editing workspace planning artifacts after one repo has already been materialized does not refresh that repo on a repeat apply; divergence is expected until a future refresh contract exists
|
||||
|
||||
The user-facing rule is simple:
|
||||
|
||||
- if the repo-local change already exists, OpenSpec protects it and refuses to overwrite it
|
||||
|
||||
### Conflict handling
|
||||
|
||||
These cases should fail non-zero with no partial success:
|
||||
|
||||
- unknown repo alias
|
||||
- alias registered in the workspace but not targeted by the selected workspace change
|
||||
- stale or missing target repo path
|
||||
- target repo missing `openspec/`
|
||||
- missing workspace source files for the selected target slice
|
||||
- pre-existing destination change directory or destination file collision
|
||||
|
||||
The error should say whether the failure is:
|
||||
|
||||
- a target-selection problem
|
||||
- a repo-resolution problem
|
||||
- a source-artifact problem
|
||||
- or a create-only collision
|
||||
|
||||
## Explicit non-goals
|
||||
|
||||
The v0 contract explicitly does not include:
|
||||
|
||||
- refresh or re-materialize behavior
|
||||
- selective overwrite of existing repo-local files
|
||||
- sync-back from repo-local execution into workspace drafts
|
||||
- automatic workspace status updates during apply
|
||||
- automatic promotion of shared drafts into a canonical owner repo
|
||||
- copying workspace coordination tasks into repo-local execution bundles
|
||||
- expanding `.openspec.yaml` with richer workspace-link metadata in this phase
|
||||
|
||||
## Rejected alternatives
|
||||
|
||||
### Rejected: support refresh in v0
|
||||
|
||||
Why rejected:
|
||||
|
||||
- refresh immediately forces overwrite rules, merge semantics, and conflict resolution policy
|
||||
- the roadmap already leans toward create-only unless this phase proved otherwise
|
||||
- the POC does not need refresh to prove the planning-to-execution handoff
|
||||
|
||||
### Rejected: overwrite an existing repo-local change on repeat apply
|
||||
|
||||
Why rejected:
|
||||
|
||||
- it risks destroying real repo-local execution state
|
||||
- it hides authority transfer instead of making it explicit
|
||||
- it makes repeat behavior harder to explain and harder to test honestly
|
||||
|
||||
### Rejected: copy coordination tasks into the repo-local change
|
||||
|
||||
Why rejected:
|
||||
|
||||
- coordination remains a workspace concern
|
||||
- copying it into one repo would blur local execution with cross-repo planning
|
||||
- the target repo should receive only the shared context plus its own execution slice
|
||||
|
||||
### Rejected: store trace metadata by expanding `.openspec.yaml` first
|
||||
|
||||
Why rejected:
|
||||
|
||||
- current change metadata support is intentionally small
|
||||
- a sidecar is enough for Phase 11 and Phase 13 follow-on work
|
||||
- it avoids coupling the workspace POC to a broader metadata-schema change
|
||||
|
||||
## Phase 11 implications
|
||||
|
||||
Phase 11 should implement only this contract:
|
||||
|
||||
- one selected repo per apply call
|
||||
- create-only destination semantics
|
||||
- normal repo-local change layout
|
||||
- explicit minimal sidecar trace metadata
|
||||
|
||||
No new roadmap phase is required from this decision.
|
||||
@@ -0,0 +1,45 @@
|
||||
# Phase 10 Manual Test
|
||||
|
||||
Manual smoke re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 10, cycle 1.
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Built the current CLI with `pnpm run build`.
|
||||
- Created a fresh temp root and copied:
|
||||
- `test/fixtures/workspace-poc/happy-path/workspace` to `<tmp>/workspace`
|
||||
- `test/fixtures/workspace-poc/happy-path/repos` to `<tmp>/repos`
|
||||
- Ran the real CLI from the copied workspace with telemetry disabled:
|
||||
|
||||
```bash
|
||||
cd <tmp>/workspace
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change shared-refresh --targets app,api
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js workspace open --change shared-refresh --agent claude
|
||||
test ! -e <tmp>/repos/app/openspec/changes/shared-refresh
|
||||
test ! -e <tmp>/repos/api/openspec/changes/shared-refresh
|
||||
test ! -e <tmp>/repos/docs/openspec/changes/shared-refresh
|
||||
```
|
||||
|
||||
- Inspected the `workspace open` output to confirm:
|
||||
- only targeted repos were attached
|
||||
- the instruction surface still said `Do not materialize repo-local changes from this session.`
|
||||
- the instruction surface still said `openspec apply --change shared-refresh --repo <alias>`
|
||||
- Checked that the reported `.claude/commands/opsx/workspace-open.md` path was not actually written during the command.
|
||||
|
||||
## Results
|
||||
|
||||
- `pnpm run build` passed.
|
||||
- `new change shared-refresh --targets app,api` succeeded and created the workspace change.
|
||||
- `workspace open --change shared-refresh --agent claude` succeeded and attached exactly `app` and `api`.
|
||||
- No repo-local change was materialized in `app`, `api`, or `docs`.
|
||||
- The instruction surface remained advisory only; the reported `.claude/commands/opsx/workspace-open.md` path was not written to disk.
|
||||
- The current product boundary still matches `DECISION.md`: planning and session prep happen in the workspace, while repo-local execution remains an explicit later step.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product or test code fixes were required from this manual pass.
|
||||
- Rewrote this manual-test note to reflect the fresh smoke run and the required stage structure.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- None found within the scope of Phase 10.
|
||||
- Phase 11 still needs to implement the create-only materialization contract defined in `DECISION.md`; that is a forward implementation dependency, not a Phase 10 manual-test gap.
|
||||
@@ -0,0 +1,66 @@
|
||||
# Phase 10 Summary
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
## Changes made
|
||||
|
||||
- Added the Phase 10 research decision in `notes/workspace-poc/phase-10-materialization-contract-research/DECISION.md`.
|
||||
- Added Phase 10 verification and manual-test artifacts:
|
||||
- `notes/workspace-poc/phase-10-materialization-contract-research/VERIFY.md`
|
||||
- `notes/workspace-poc/phase-10-materialization-contract-research/MANUAL_TEST.md`
|
||||
- Chose one concrete v0 materialization contract for `openspec apply --change <id> --repo <alias>`:
|
||||
- create-only
|
||||
- no overwrite
|
||||
- no refresh path
|
||||
- explicit repeat-apply failure for the same target repo
|
||||
- minimal sidecar trace metadata in `.openspec.materialization.yaml`
|
||||
- Defined the repo-local bundle shape as:
|
||||
- shared context copied from workspace root: `proposal.md`, `design.md`
|
||||
- target slice copied from `targets/<alias>/`: `tasks.md`, `specs/`
|
||||
- no workspace coordination artifacts copied into the repo-local change
|
||||
- Updated the Phase 10 checklist in `ROADMAP.md`.
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- Re-read the Phase 10 and Phase 11 blocks in `ROADMAP.md`.
|
||||
- Reviewed the current workspace and apply-adjacent implementation surface in:
|
||||
- `src/core/workspace/open.ts`
|
||||
- `src/core/workspace/change-create.ts`
|
||||
- `src/utils/change-metadata.ts`
|
||||
- `src/core/artifact-graph/types.ts`
|
||||
- `schemas/spec-driven/schema.yaml`
|
||||
- `src/cli/index.ts`
|
||||
- Re-read prior workspace POC notes and design anchors in:
|
||||
- `notes/workspace-poc/phase-07-open-contract-research/DECISION.md`
|
||||
- `notes/workspace-poc/phase-09-test-workspace-open/{SUMMARY.md,VERIFY.md}`
|
||||
- `WORKSPACE_POC_PRD.md`
|
||||
- `WORKSPACE_POC_DECISION_RECORD.md`
|
||||
- Ran focused workspace regression coverage:
|
||||
- `pnpm vitest run test/core/workspace/change-create.test.ts test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
|
||||
- Ran a fresh copied-fixture CLI smoke against `test/fixtures/workspace-poc/happy-path` using the built CLI:
|
||||
- `node dist/cli/index.js new change shared-refresh --targets app,api`
|
||||
- `node dist/cli/index.js workspace open --change shared-refresh --agent claude`
|
||||
- verified `repos/{app,api,docs}/openspec/changes/shared-refresh` remained absent
|
||||
- Corrected one invalid manual harness attempt during this run:
|
||||
- an initial smoke used `pnpm exec` from the copied temp workspace, which is not a package
|
||||
- reran successfully with `node dist/cli/index.js` from the repository build output
|
||||
|
||||
## Results
|
||||
|
||||
- Focused workspace tests passed: 5 files, 19/19 tests passed.
|
||||
- The current implementation boundary still holds:
|
||||
- workspace changes centralize planning and target metadata
|
||||
- `workspace open` remains read-only
|
||||
- the user-facing handoff to `apply --change --repo` is already explicit in the open surface
|
||||
- The chosen v0 contract is consistent with both the roadmap guardrails and the current implementation surface:
|
||||
- create-only avoids inventing refresh semantics before they are tested
|
||||
- copying shared context plus one target slice produces a usable repo-local execution bundle
|
||||
- a sidecar trace file is enough for later roll-up without broadening core change metadata now
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 10.
|
||||
- No new roadmap phases were required from this research pass.
|
||||
- Phase 11 should implement exactly the create-only contract captured in `DECISION.md` and should not add refresh or overwrite behavior unless the roadmap is expanded first.
|
||||
@@ -0,0 +1,57 @@
|
||||
# Phase 10 Verification
|
||||
|
||||
Independent verification re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 10, cycle 1.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 10 roadmap block in `ROADMAP.md`.
|
||||
- Re-read the phase artifacts under `notes/workspace-poc/phase-10-materialization-contract-research/`, with primary focus on:
|
||||
- `SUMMARY.md`
|
||||
- `DECISION.md`
|
||||
- Re-checked the implementation boundary that Phase 10 depends on:
|
||||
- `src/core/workspace/open.ts`
|
||||
- `src/core/workspace/change-create.ts`
|
||||
- `src/utils/change-metadata.ts`
|
||||
- `src/core/artifact-graph/types.ts`
|
||||
- `schemas/spec-driven/schema.yaml`
|
||||
- `src/commands/workspace.ts`
|
||||
- Confirmed the decision still matches the current product surface:
|
||||
- workspace changes record explicit `targets`
|
||||
- `workspace open` remains session-prep only
|
||||
- `workspace open` still points repo-local execution to `openspec apply --change <id> --repo <alias>`
|
||||
- change metadata remains narrow enough that a sidecar trace file is the least invasive Phase 11 follow-on
|
||||
- Rebuilt the CLI used by the documented smoke path:
|
||||
- `pnpm run build`
|
||||
- Result: passed
|
||||
- Re-ran the focused workspace regression slice:
|
||||
- `pnpm vitest run test/core/workspace/change-create.test.ts test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
|
||||
- Result: 5 files passed, 19/19 tests passed
|
||||
- Re-ran a fresh copied-fixture smoke using `test/fixtures/workspace-poc/happy-path`:
|
||||
- created `shared-refresh` with `new change --targets app,api`
|
||||
- opened it with `workspace open --change shared-refresh --agent claude`
|
||||
- confirmed only `app` and `api` were attached
|
||||
- confirmed the instruction surface still says `Do not materialize repo-local changes from this session.`
|
||||
- confirmed the instruction surface still says `openspec apply --change shared-refresh --repo <alias>`
|
||||
- confirmed no repo-local `openspec/changes/shared-refresh` directory was created in `app`, `api`, or `docs`
|
||||
- confirmed the reported `.claude/commands/opsx/workspace-open.md` instruction-surface path is not actually written during this flow
|
||||
- Re-validated the Phase 10 acceptance criteria against `DECISION.md`:
|
||||
- 10.4 one v0 contract is chosen and explicit non-goals are named
|
||||
- 10.5 successful materialization is defined concretely
|
||||
- 10.6 repeat `apply` behavior is defined explicitly
|
||||
|
||||
## Issues found
|
||||
|
||||
- No product correctness issues were found in the reviewed boundary.
|
||||
- No acceptance-test gaps were found in `DECISION.md`.
|
||||
- No documentation corrections were required in `SUMMARY.md`, `DECISION.md`, or `MANUAL_TEST.md`.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- Rewrote this verification note to reflect the fresh verification pass and the exact checks rerun here.
|
||||
- No product or test code changes were required.
|
||||
- No ROADMAP checkbox corrections were needed because the Phase 10 checklist was already accurate.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No residual risk remains within the scope of this research phase itself.
|
||||
- Phase 11 still needs to implement the create-only, all-or-nothing materialization behavior described here; that is a forward implementation dependency, not a Phase 10 verification gap.
|
||||
@@ -0,0 +1,56 @@
|
||||
# Phase 11 Manual Test
|
||||
|
||||
Manual smoke re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 11, cycle 1.
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Rebuilt the CLI with `pnpm run build`.
|
||||
- Re-ran the focused Phase 11 regression slice to confirm the current tree before the manual smoke:
|
||||
- `pnpm vitest run test/core/workspace/apply.test.ts test/core/workspace/change-create.test.ts test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-apply-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
|
||||
- Created a fresh temp root and copied:
|
||||
- `test/fixtures/workspace-poc/happy-path/workspace` to `<tmp>/workspace`
|
||||
- `test/fixtures/workspace-poc/happy-path/repos` to `<tmp>/repos`
|
||||
- Ran the real CLI from the copied workspace with telemetry disabled:
|
||||
|
||||
```bash
|
||||
cd <tmp>/workspace
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change shared-refresh --targets app,api
|
||||
# seed proposal.md, design.md, and targets/{app,api}/{tasks.md,specs/**}
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change shared-refresh --repo app
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change shared-refresh --repo app
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change shared-refresh --repo docs
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change shared-refresh --repo missing
|
||||
```
|
||||
|
||||
- Inspected the copied temp workspace and repos after the run to confirm:
|
||||
- `repos/app/openspec/changes/shared-refresh/` was created
|
||||
- `repos/api/openspec/changes/shared-refresh/` remained absent
|
||||
- `repos/docs/openspec/changes/shared-refresh/` remained absent
|
||||
- `repos/app/openspec/changes/shared-refresh/` contained `.openspec.yaml`, `proposal.md`, `design.md`, `tasks.md`, `specs/`, and `.openspec.materialization.yaml`
|
||||
- `workspace/changes/shared-refresh/targets/app/tasks.md` remained present after apply
|
||||
- Inspected the CLI output to confirm:
|
||||
- the success path printed the repo-local destination and explicit authority handoff
|
||||
- the repeat run failed with a create-only collision
|
||||
- `docs` failed as an untargeted alias
|
||||
- `missing` failed as an unknown alias
|
||||
|
||||
## Results
|
||||
|
||||
- `pnpm run build` passed.
|
||||
- The focused Phase 11 regression slice passed: 7 files, 23/23 tests passed.
|
||||
- `apply --change shared-refresh --repo app` succeeded and created the repo-local change only in `app`.
|
||||
- The success output explicitly showed the handoff from workspace planning to repo-local execution.
|
||||
- The same-alias repeat run failed with the expected create-only collision message.
|
||||
- The untargeted `docs` run failed with the expected targeted-alias error.
|
||||
- The unknown `missing` run failed with the expected unregistered-alias error.
|
||||
- The workspace draft files remained in place after the successful materialization.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product fixes were required from this manual smoke pass.
|
||||
- Updated this manual-test note to reflect the exact commands, inspections, and results from the fresh-context run.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No residual risks were found within the Phase 11 scope during this pass.
|
||||
- Broader materialization matrix coverage remains Phase 12 follow-on work rather than a Phase 11 defect.
|
||||
@@ -0,0 +1,68 @@
|
||||
# Phase 11 Summary
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
## Changes made
|
||||
|
||||
- Added a real top-level `openspec apply` command that materializes one targeted workspace change into one selected repo with `--change <id> --repo <alias>`.
|
||||
- Added shared workspace-change resolution in `src/core/workspace/change.ts` so `workspace open` and `apply` use the same change lookup and target metadata rules.
|
||||
- Added the Phase 11 materialization engine in `src/core/workspace/apply.ts`:
|
||||
- resolves the workspace root and selected repo alias
|
||||
- validates unknown vs untargeted aliases distinctly
|
||||
- validates required workspace source artifacts for the selected target slice
|
||||
- stages a repo-local bundle under `openspec/changes/` and atomically renames it into place
|
||||
- reuses the workspace change ID in the target repo
|
||||
- writes `.openspec.materialization.yaml` with the minimum trace metadata from Phase 10
|
||||
- keeps workspace planning artifacts untouched
|
||||
- Made the authority handoff explicit in the CLI success output: workspace target slice before `apply`, repo-local execution surface after `apply`.
|
||||
- Added focused Phase 11 coverage in:
|
||||
- `test/core/workspace/apply.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-apply-cli.test.ts`
|
||||
- Updated the Phase 11 checklist in `ROADMAP.md`.
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- Re-read the Phase 11 block in `ROADMAP.md`.
|
||||
- Re-read the Phase 10 contract in `notes/workspace-poc/phase-10-materialization-contract-research/DECISION.md`.
|
||||
- Reviewed the current workspace implementation boundary in:
|
||||
- `src/core/workspace/open.ts`
|
||||
- `src/core/workspace/registry.ts`
|
||||
- `src/core/workspace/change-create.ts`
|
||||
- `src/utils/change-metadata.ts`
|
||||
- Built the CLI:
|
||||
- `pnpm run build`
|
||||
- Ran the focused Phase 11 regression slice:
|
||||
- `pnpm vitest run test/core/workspace/apply.test.ts test/core/workspace/change-create.test.ts test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-apply-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
|
||||
- Ran a fresh copied-fixture CLI smoke using `test/fixtures/workspace-poc/happy-path`:
|
||||
- created `shared-refresh` with `new change --targets app,api`
|
||||
- seeded the target slice files
|
||||
- ran `apply --change shared-refresh --repo app`
|
||||
- re-ran `apply` for the same alias to confirm create-only collision behavior
|
||||
- ran `apply` for `docs` and `missing` to confirm untargeted and unknown alias failures
|
||||
|
||||
## Results
|
||||
|
||||
- `pnpm run build` passed.
|
||||
- The focused workspace regression slice passed: 7 files, 23/23 tests passed.
|
||||
- The new `apply` flow now satisfies the Phase 11 contract:
|
||||
- repo-local materialization uses the same change ID as the workspace change
|
||||
- only the selected target repo is modified
|
||||
- unknown and untargeted aliases fail with distinct target-selection errors
|
||||
- repeating `apply` for the same target repo fails with a create-only collision
|
||||
- applying the same change to a different targeted alias still works
|
||||
- workspace drafts remain intact after successful materialization
|
||||
- The repo-local bundle shape matches the Phase 10 decision:
|
||||
- `.openspec.yaml`
|
||||
- `proposal.md`
|
||||
- `design.md`
|
||||
- `tasks.md`
|
||||
- `specs/`
|
||||
- `.openspec.materialization.yaml`
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 11.
|
||||
- No new roadmap phases were required from this implementation pass.
|
||||
- Phase 12 can now focus on expanding the materialization test matrix rather than defining or changing the contract.
|
||||
@@ -0,0 +1,55 @@
|
||||
# Phase 11 Verification
|
||||
|
||||
Independent verification re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 11, cycle 1.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 11 roadmap block in `ROADMAP.md`.
|
||||
- Re-read the current phase artifacts:
|
||||
- `notes/workspace-poc/phase-11-apply-materialization/SUMMARY.md`
|
||||
- `notes/workspace-poc/phase-11-apply-materialization/MANUAL_TEST.md`
|
||||
- Re-read the Phase 10 materialization contract in `notes/workspace-poc/phase-10-materialization-contract-research/DECISION.md`.
|
||||
- Re-checked the implementation surface added for this phase:
|
||||
- `src/core/workspace/change.ts`
|
||||
- `src/core/workspace/apply.ts`
|
||||
- `src/commands/workflow/apply.ts`
|
||||
- `src/cli/index.ts`
|
||||
- `src/core/workspace/open.ts`
|
||||
- `src/core/workspace/registry.ts`
|
||||
- Rebuilt the CLI used by the verification and manual smoke path:
|
||||
- `pnpm run build`
|
||||
- Result: passed
|
||||
- Re-ran the focused workspace regression slice:
|
||||
- `pnpm vitest run test/core/workspace/apply.test.ts test/core/workspace/change-create.test.ts test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-apply-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
|
||||
- Result: 7 files passed, 23/23 tests passed
|
||||
- Ran a fresh copied-fixture CLI smoke outside the test harness:
|
||||
- copied `test/fixtures/workspace-poc/happy-path/workspace` and `test/fixtures/workspace-poc/happy-path/repos` into a temp root
|
||||
- ran `node dist/cli/index.js new change shared-refresh --targets app,api`
|
||||
- seeded `proposal.md`, `design.md`, and the per-target `tasks.md` and `specs/` files
|
||||
- ran `node dist/cli/index.js apply --change shared-refresh --repo app`
|
||||
- re-ran the same command for `app` to confirm create-only collision behavior
|
||||
- ran `apply` for `docs` and `missing` to confirm untargeted and unknown alias failures
|
||||
- Verified the acceptance criteria through the focused suites and the fresh CLI smoke:
|
||||
- repo-local materialization reuses the workspace change ID
|
||||
- only the selected target repo gets the materialized change
|
||||
- unknown and untargeted aliases fail distinctly
|
||||
- same-alias repeat `apply` fails with a create-only collision while another targeted alias can still materialize
|
||||
- workspace drafts remain unchanged after successful materialization
|
||||
- the repo-local bundle contains `.openspec.yaml`, `proposal.md`, `design.md`, `tasks.md`, `specs/`, and `.openspec.materialization.yaml`
|
||||
- the success output makes the workspace-to-repo authority handoff explicit
|
||||
|
||||
## Issues found
|
||||
|
||||
- No product correctness issues were found in the implemented materialization flow.
|
||||
- No acceptance-test gaps remained after the focused verification run.
|
||||
- Documentation-quality issue: the previous verification note mixed implementation work into the "Fixes applied" section instead of keeping that section scoped to verification-stage changes.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product code changes were required during this verification pass.
|
||||
- Updated this verification note so it records the checks run in this pass and keeps the issues and fixes sections scoped to verification work.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No known residual risk remains inside the Phase 11 scope.
|
||||
- Phase 12 still needs to broaden coverage around the materialization matrix, but that is follow-on validation work rather than a correctness gap in the implemented Phase 11 contract.
|
||||
@@ -0,0 +1,53 @@
|
||||
# Phase 12 Manual Test
|
||||
|
||||
Manual smoke re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 12, cycle 1, stage `manual-test`.
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Rebuilt the CLI with `pnpm run build`.
|
||||
- Re-ran the focused Phase 12 regression slice before the manual smoke:
|
||||
- `pnpm vitest run test/core/workspace/apply.test.ts test/commands/workflow/apply.test.ts test/cli-e2e/workspace/workspace-apply-cli.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Scenario 1: happy-path selective materialization into one repo out of many using copied fixture repos and isolated XDG roots.
|
||||
- Ran `workspace create phase-12-manual --json`.
|
||||
- Registered `app`, `api`, and `docs` with `workspace add-repo ... --json`.
|
||||
- Ran `new change shared-refresh --targets app,api,docs`.
|
||||
- Ran `apply --change shared-refresh --repo app --json`.
|
||||
- Re-ran `apply --change shared-refresh --repo app` to confirm repeat-apply collision behavior.
|
||||
- Inspected the temp repo trees and the JSON payload after apply.
|
||||
- Scenario 2: dirty-workspace stale alias failure using the committed dirty fixture plus a rewritten temp `local.yaml` overlay with `docs` still pointing at a missing path.
|
||||
- Copied `test/fixtures/workspace-poc/dirty/workspace` and `test/fixtures/workspace-poc/dirty/repos` into a temp root.
|
||||
- Rewrote `.openspec/local.yaml` to absolute temp paths for `app` and `api`, while leaving `docs` pointed at `<tmp>/repos/docs-missing`.
|
||||
- Ran `new change docs-repair --targets docs`.
|
||||
- Ran `apply --change docs-repair --repo docs`.
|
||||
- Inspected the temp repo trees to confirm no new repo-local change was created in the healthy repos.
|
||||
|
||||
## Results
|
||||
|
||||
- `pnpm run build` passed.
|
||||
- The focused Phase 12 regression slice passed: 5 files, 17/17 tests passed.
|
||||
- Scenario 1 passed end to end:
|
||||
- workspace creation and repo registration succeeded
|
||||
- `new change shared-refresh --targets app,api,docs` succeeded
|
||||
- `apply --change shared-refresh --repo app --json` succeeded
|
||||
- the JSON payload reported `change.id = shared-refresh`
|
||||
- `target.changePath` ended in `/shared-refresh`, so the repo-local change ID exactly matched the workspace change ID
|
||||
- only `app` received `openspec/changes/shared-refresh/`
|
||||
- `api` and `docs` kept only their pre-existing fixture changes and did not receive `shared-refresh`
|
||||
- the materialized app change contained `.openspec.yaml`, `proposal.md`, `design.md`, `tasks.md`, `specs/`, and `.openspec.materialization.yaml`
|
||||
- the repeat `app` apply exited with code `1` and surfaced the explicit create-only collision
|
||||
- Scenario 2 passed for the failure path:
|
||||
- `new change docs-repair --targets docs` succeeded inside the copied dirty workspace
|
||||
- `apply --change docs-repair --repo docs` exited with code `1`
|
||||
- the error reported `Target alias 'docs' points to a missing repo path: <tmp>/repos/docs-missing`
|
||||
- the error also told the user to run `openspec workspace doctor` and repair the failing alias before retrying
|
||||
- no `docs-repair` repo-local materialization appeared in `app` or `api`, so the stale-path failure did not produce silent partial success
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product fixes were required from this manual smoke pass.
|
||||
- Updated this manual-test note to capture the exact fresh-context scenarios, outputs, and repo-tree inspections from the current run.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No residual risks were found within the Phase 12 scope during this pass.
|
||||
- Status roll-up and completion semantics remain future work for Phase 13 onward.
|
||||
@@ -0,0 +1,62 @@
|
||||
# Phase 12 Summary
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
## Changes made
|
||||
|
||||
- Expanded `test/core/workspace/apply.test.ts` to cover:
|
||||
- missing target-slice source artifacts during materialization plan construction
|
||||
- stale dirty-workspace alias resolution failures
|
||||
- pre-existing target change collisions without overwrite
|
||||
- Added `test/commands/workflow/apply.test.ts` to cover the direct command surface for:
|
||||
- apply success output
|
||||
- apply failure on stale repo resolution
|
||||
- repeat-apply create-only behavior
|
||||
- Expanded `test/cli-e2e/workspace/workspace-apply-cli.test.ts` to cover:
|
||||
- dirty-workspace stale-alias failure through the built CLI
|
||||
- a fresh `workspace create -> add-repo -> new change -> apply` flow using copied `happy-path` fixture repos
|
||||
- selective materialization into only one repo out of many
|
||||
- Updated the Phase 12 checklist in `ROADMAP.md`.
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- Re-read the Phase 12 roadmap block in `ROADMAP.md`.
|
||||
- Reviewed the current materialization implementation and existing tests in:
|
||||
- `src/core/workspace/apply.ts`
|
||||
- `src/commands/workflow/apply.ts`
|
||||
- `test/core/workspace/apply.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-apply-cli.test.ts`
|
||||
- `test/helpers/workspace-sandbox.ts`
|
||||
- Built the CLI:
|
||||
- `pnpm run build`
|
||||
- Ran the focused Phase 12 verification slice:
|
||||
- `pnpm vitest run test/core/workspace/apply.test.ts test/commands/workflow/apply.test.ts test/cli-e2e/workspace/workspace-apply-cli.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Ran a fresh manual CLI smoke in an isolated temp root with telemetry disabled:
|
||||
- `workspace create phase-12-manual --json`
|
||||
- `workspace add-repo app <tmp>/repos/app --json`
|
||||
- `workspace add-repo api <tmp>/repos/api --json`
|
||||
- `new change shared-refresh --targets app,api`
|
||||
- `apply --change shared-refresh --repo app --json`
|
||||
- repeated `apply --change shared-refresh --repo app` to confirm collision behavior
|
||||
|
||||
## Results
|
||||
|
||||
- `pnpm run build` passed.
|
||||
- The focused Phase 12 verification slice passed: 5 files, 17/17 tests passed.
|
||||
- The expanded coverage now proves the Phase 12 acceptance surface:
|
||||
- the repo-local change directory name matches the workspace change ID
|
||||
- apply writes only to the selected alias
|
||||
- stale-path and collision failures are explicit and do not produce silent partial success
|
||||
- the `happy-path` fixture repos support the fresh create/add-repo/new-change/apply flow through the built CLI
|
||||
- The manual smoke matched the automated results:
|
||||
- `shared-refresh` materialized only into `app`
|
||||
- `api` remained untouched
|
||||
- the repeat `app` apply failed with the expected create-only collision
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 12.
|
||||
- No new roadmap phases were required from this pass.
|
||||
- Phase 13 can build status semantics on top of a materially better-tested handoff surface.
|
||||
@@ -0,0 +1,57 @@
|
||||
# Phase 12 Verification
|
||||
|
||||
Independent verification re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 12, cycle 1, stage `verification`.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 12 roadmap block in `ROADMAP.md`.
|
||||
- Re-read the current phase artifacts to verify scope coverage and documentation quality:
|
||||
- `notes/workspace-poc/phase-12-test-apply-materialization/SUMMARY.md`
|
||||
- `notes/workspace-poc/phase-12-test-apply-materialization/MANUAL_TEST.md`
|
||||
- Re-checked the Phase 12 implementation boundaries in:
|
||||
- `src/core/workspace/apply.ts`
|
||||
- `src/commands/workflow/apply.ts`
|
||||
- `src/core/workspace/change-create.ts`
|
||||
- `src/core/workspace/registry.ts`
|
||||
- `test/helpers/workspace-assertions.ts`
|
||||
- Re-checked the automated Phase 12 coverage in:
|
||||
- `test/core/workspace/apply.test.ts`
|
||||
- `test/commands/workflow/apply.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-apply-cli.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-create-cli.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Rebuilt the CLI used by the e2e and direct CLI paths:
|
||||
- `pnpm run build`
|
||||
- Result: passed
|
||||
- Re-ran the focused Phase 12 regression slice:
|
||||
- `pnpm vitest run test/core/workspace/apply.test.ts test/commands/workflow/apply.test.ts test/cli-e2e/workspace/workspace-apply-cli.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Result: 5 files passed, 17/17 tests passed
|
||||
- Ran an isolated real-CLI smoke in a temp XDG root using copied `happy-path` fixture repos:
|
||||
- `workspace create phase-12-verify --json`
|
||||
- `workspace add-repo app <tmp>/repos/app --json`
|
||||
- `workspace add-repo api <tmp>/repos/api --json`
|
||||
- `new change shared-refresh --targets app,api`
|
||||
- `apply --change shared-refresh --repo app --json`
|
||||
- repeated `apply --change shared-refresh --repo app`
|
||||
- Confirmed:
|
||||
- `apply` returned `change.id = shared-refresh`
|
||||
- the repo-local change directory basename was `shared-refresh`
|
||||
- only `app` received `openspec/changes/shared-refresh/`
|
||||
- `api` remained untouched
|
||||
- repeat apply exited with code `1` and surfaced the explicit create-only collision
|
||||
|
||||
## Issues found
|
||||
|
||||
- No product correctness issues were found during this verification pass.
|
||||
- No acceptance-test gaps were found in the current Phase 12 implementation or coverage.
|
||||
- No documentation-quality issues were found in the phase summary or manual-test notes; both matched the current implementation and rerun results.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product code changes were required during this verification pass.
|
||||
- Updated this verification note to capture the exact rerun scope, implementation-boundary review, and direct CLI smoke evidence.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No known residual risks remain inside the Phase 12 scope.
|
||||
- Phase 13 remains the next boundary: status and completion semantics still need their own contract and implementation work.
|
||||
@@ -0,0 +1,275 @@
|
||||
# Phase 13 Decision
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
## Recommended v0 status model
|
||||
|
||||
Phase 14 should implement workspace-aware roll-up instead of reusing raw artifact-graph status for workspace changes.
|
||||
|
||||
The minimum honest v0 model is:
|
||||
|
||||
- overall workspace-change state: `planned`, `in-progress`, `blocked`, `soft-done`, `hard-done`
|
||||
- per-target state: `planned`, `materialized`, `in-progress`, `blocked`, `complete`
|
||||
- coordination state: `planned`, `in-progress`, `blocked`, `complete`
|
||||
|
||||
This split is necessary because the current generic `status --change` command assumes repo-local topology:
|
||||
|
||||
- root-level `tasks.md`
|
||||
- root-level `specs/`
|
||||
- artifact completion by file existence
|
||||
|
||||
A workspace change does not have that layout. The direct manual probe for this phase showed that running `status --change shared-refresh --json` from a workspace root reports `proposal` and `design` as done, `specs` as ready, and `tasks` as blocked because it is looking for repo-local root artifacts that do not exist in workspace topology. That output is valid for the existing command, but it is not an honest workspace roll-up.
|
||||
|
||||
The current implementation surface already gives the right raw signals for a custom roll-up:
|
||||
|
||||
- `src/core/workspace/change-create.ts` creates workspace coordination tasks at `tasks/coordination.md` and per-target draft tasks at `targets/<alias>/tasks.md`
|
||||
- `src/core/workspace/apply.ts` reuses the workspace change ID in the target repo and writes `.openspec.materialization.yaml`
|
||||
- `src/utils/task-progress.ts` and `src/core/list.ts` already define tracked progress in terms of checkbox counts inside `tasks.md`
|
||||
|
||||
The practical conclusion is:
|
||||
|
||||
- use task-progress counts for progress and completion
|
||||
- use repo-local materialization plus trace metadata for execution provenance
|
||||
- do not infer archive from repo-local task completion
|
||||
|
||||
## One precise derivation rule per state
|
||||
|
||||
### `planned`
|
||||
|
||||
Rule:
|
||||
|
||||
- A target is `planned` when it is declared in the workspace change metadata, the target repo alias resolves cleanly, and no valid repo-local materialization exists at `<resolved-repo>/openspec/changes/<change-id>/`.
|
||||
- The overall workspace change is `planned` only when coordination is `planned` and every target is `planned`.
|
||||
|
||||
Why:
|
||||
|
||||
- an unmaterialized target is still using the workspace draft as its current authority
|
||||
- absence of repo-local execution state is not by itself a failure
|
||||
|
||||
### `materialized`
|
||||
|
||||
Rule:
|
||||
|
||||
- A target is `materialized` when a valid repo-local materialization exists and its repo-local task progress is either `0/<n>` or `0/0`.
|
||||
|
||||
Why:
|
||||
|
||||
- the current repo-local `list --json` surface collapses `0/<n>` into `in-progress`
|
||||
- the workspace roll-up needs one extra state to distinguish "execution surface exists" from "tracked work has started"
|
||||
|
||||
### `in-progress`
|
||||
|
||||
Rule:
|
||||
|
||||
- A coordination slice or target is `in-progress` when its tracked task progress is `0 < completed < total`.
|
||||
- The overall workspace change is `in-progress` when it is not `blocked`, `soft-done`, or `hard-done`, and at least one target is `materialized`, `in-progress`, or `complete`, or coordination is `in-progress` or `complete`.
|
||||
|
||||
Why:
|
||||
|
||||
- task progress is the only current product signal that distinguishes "some execution happened" from "nothing started"
|
||||
|
||||
### `blocked`
|
||||
|
||||
Rule:
|
||||
|
||||
- A coordination slice or target is `blocked` when status cannot classify it honestly because a required workspace or repo-local inspection surface is missing or inconsistent.
|
||||
- The overall workspace change is `blocked` when coordination is `blocked` or any target is `blocked`.
|
||||
|
||||
For v0, target-blocked conditions are:
|
||||
|
||||
- the target alias is declared on the workspace change but is missing from workspace repo metadata
|
||||
- the target alias is missing from `.openspec/local.yaml`
|
||||
- the resolved repo path is missing, not a directory, or no longer contains `openspec/`
|
||||
- a same-ID repo-local change exists, but `.openspec.materialization.yaml` is missing, malformed, or does not match this workspace and target alias
|
||||
- a traced repo-local change exists, but `tasks.md` cannot be read for progress derivation
|
||||
|
||||
For v0, coordination-blocked conditions are:
|
||||
|
||||
- `tasks/coordination.md` is missing or unreadable
|
||||
|
||||
Why:
|
||||
|
||||
- `blocked` should mean "the status command cannot tell the truth from the current state"
|
||||
- v0 should not invent softer warning labels when the underlying surface is actually broken
|
||||
|
||||
### `complete`
|
||||
|
||||
Rule:
|
||||
|
||||
- A coordination slice or target is `complete` when its tracked task progress is `n/n` with `n > 0`.
|
||||
|
||||
Why:
|
||||
|
||||
- `complete` is task-complete, not archive-complete
|
||||
- this keeps completion aligned with the current repo-local `list` semantics
|
||||
|
||||
### `soft-done`
|
||||
|
||||
Rule:
|
||||
|
||||
- The overall workspace change is `soft-done` when coordination is `complete` and every target is `complete`.
|
||||
|
||||
Why:
|
||||
|
||||
- this matches the PRD and decision-record definition of "all known coordination work and tracked target work are complete"
|
||||
- it still leaves explicit top-level archive for the final lifecycle step
|
||||
|
||||
### `hard-done`
|
||||
|
||||
Rule:
|
||||
|
||||
- The overall workspace change is `hard-done` only when an explicit workspace-level archive/completion marker exists for that workspace change.
|
||||
|
||||
Why:
|
||||
|
||||
- repo-local archive remains repo-local
|
||||
- repo-local task completion or repo-local archive alone must never imply top-level finality
|
||||
|
||||
## Workspace-only versus repo-local inspection
|
||||
|
||||
The minimum source split for v0 is:
|
||||
|
||||
### Uses workspace state alone
|
||||
|
||||
- workspace metadata and target membership
|
||||
- coordination task progress from `changes/<id>/tasks/coordination.md`
|
||||
- pre-materialization draft task progress from `changes/<id>/targets/<alias>/tasks.md`
|
||||
- overall `hard-done` once Phase 16 adds explicit workspace archive state
|
||||
|
||||
### Requires repo-local inspection
|
||||
|
||||
- whether a target has been materialized at all
|
||||
- whether the materialized change belongs to this workspace target rather than just sharing the same change ID
|
||||
- repo-local execution progress and completion from `<repo>/openspec/changes/<id>/tasks.md`
|
||||
- blocked states caused by stale repo paths, missing `openspec/`, or malformed materialization traces
|
||||
|
||||
### Mixed roll-up states
|
||||
|
||||
- overall `planned` depends on workspace coordination plus every target still being `planned`
|
||||
- overall `in-progress` depends on both workspace coordination and any materialized target state
|
||||
- overall `blocked` depends on any blocked coordination or target slice
|
||||
- overall `soft-done` depends on coordination plus every target reaching `complete`
|
||||
|
||||
## Reverse-link decision
|
||||
|
||||
Decision:
|
||||
|
||||
- reverse links are required in v0, but the minimum required reverse link is the existing `.openspec.materialization.yaml` sidecar
|
||||
|
||||
What is required:
|
||||
|
||||
- keep reusing the workspace change ID as the repo-local change ID
|
||||
- keep writing `.openspec.materialization.yaml`
|
||||
- Phase 14 status should validate:
|
||||
- `source: workspace`
|
||||
- `workspaceName` matches the current workspace
|
||||
- `targetAlias` matches the target being inspected
|
||||
|
||||
What is not required:
|
||||
|
||||
- no new backlink fields in `.openspec.yaml`
|
||||
- no absolute workspace paths
|
||||
- no extra workspace change ID field beyond the repo-local directory name, because Phase 11 already made the directory name match the workspace change ID
|
||||
|
||||
Why this is the minimum honest choice:
|
||||
|
||||
- without the sidecar, a same-ID repo-local change could be mistaken for a materialized workspace target even if it did not originate from this workspace flow
|
||||
- with the sidecar, Phase 14 can distinguish "materialized from this workspace" from "same change name exists locally for some other reason"
|
||||
|
||||
## Minimum JSON shape to lock down in Phase 14
|
||||
|
||||
Phase 14 should keep the JSON contract small and stable:
|
||||
|
||||
```json
|
||||
{
|
||||
"change": {
|
||||
"id": "shared-refresh",
|
||||
"state": "planned"
|
||||
},
|
||||
"coordination": {
|
||||
"state": "planned",
|
||||
"tasks": {
|
||||
"completed": 0,
|
||||
"total": 2
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"alias": "api",
|
||||
"state": "planned",
|
||||
"source": "workspace",
|
||||
"tasks": {
|
||||
"completed": 0,
|
||||
"total": 2
|
||||
},
|
||||
"problems": []
|
||||
},
|
||||
{
|
||||
"alias": "app",
|
||||
"state": "materialized",
|
||||
"source": "repo",
|
||||
"tasks": {
|
||||
"completed": 0,
|
||||
"total": 2
|
||||
},
|
||||
"problems": []
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Contract notes:
|
||||
|
||||
- `change.id` is the workspace change ID
|
||||
- `change.state` is only `planned`, `in-progress`, `blocked`, `soft-done`, or `hard-done`
|
||||
- `coordination.state` is only `planned`, `in-progress`, `blocked`, or `complete`
|
||||
- target `state` is only `planned`, `materialized`, `in-progress`, `blocked`, or `complete`
|
||||
- `targets` are sorted by alias for deterministic tests
|
||||
- `source` is `workspace` before materialization and `repo` after materialization
|
||||
- `tasks` always reflects the authority for the current `source`
|
||||
- `problems` is empty unless the slice is `blocked`
|
||||
- the JSON should not include spinner text, ANSI codes, or absolute repo paths
|
||||
|
||||
## Rejected alternatives
|
||||
|
||||
### Rejected: reuse raw artifact-graph `status --change` for workspace roll-up
|
||||
|
||||
Why rejected:
|
||||
|
||||
- the current command is correct for repo-local change topology, not workspace topology
|
||||
- it looks for root `specs/` and root `tasks.md`, which the workspace change intentionally does not have
|
||||
- it would misreport workspace state instead of clarifying it
|
||||
|
||||
### Rejected: treat `0/<n>` repo-local task progress as `in-progress` in workspace roll-up
|
||||
|
||||
Why rejected:
|
||||
|
||||
- that loses the important distinction between "materialized, but untouched" and "work has actually started"
|
||||
- the roadmap explicitly wants both `materialized` and `in progress`
|
||||
|
||||
### Rejected: trust any same-ID repo-local change without a workspace trace sidecar
|
||||
|
||||
Why rejected:
|
||||
|
||||
- same-name repo-local changes are not strong enough provenance
|
||||
- status would risk claiming a workspace target was materialized when it was not
|
||||
|
||||
### Rejected: infer `hard-done` from repo-local archive or repo-local task completion
|
||||
|
||||
Why rejected:
|
||||
|
||||
- the PRD and roadmap keep workspace archive as an explicit top-level action
|
||||
- different repos can finish or archive at different times without closing the whole workspace change
|
||||
|
||||
## Phase 14 implications
|
||||
|
||||
Phase 14 should implement only this contract:
|
||||
|
||||
- custom workspace-aware roll-up logic
|
||||
- checkbox-based task progress for coordination and target completion
|
||||
- materialization provenance validated through `.openspec.materialization.yaml`
|
||||
- target states distinct from overall workspace states
|
||||
|
||||
No new roadmap phase is required from this decision.
|
||||
@@ -0,0 +1,75 @@
|
||||
# Phase 13 Manual Test
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `manual-test`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
Manual smoke run in a fresh local context for ROADMAP Phase 13 only.
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Built the current CLI with `pnpm run build`.
|
||||
- Created a fresh temp root and copied:
|
||||
- `test/fixtures/workspace-poc/happy-path/workspace` to `<tmp>/workspace`
|
||||
- `test/fixtures/workspace-poc/happy-path/repos` to `<tmp>/repos`
|
||||
- Ran the real CLI from the copied workspace and repo roots with telemetry disabled:
|
||||
|
||||
```bash
|
||||
cd <tmp>/workspace
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change shared-refresh --targets app,api
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change shared-refresh --json
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change shared-refresh --repo app --json
|
||||
|
||||
cd <tmp>/repos/app
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js list --json
|
||||
|
||||
# edit tasks to simulate partial execution
|
||||
printf '%s\n' '## App Tasks' '- [x] Finish API wiring' '- [ ] Land UI follow-up' > openspec/changes/shared-refresh/tasks.md
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js list --json
|
||||
|
||||
# edit tasks to simulate completion
|
||||
printf '%s\n' '## App Tasks' '- [x] Finish API wiring' '- [x] Land UI follow-up' > openspec/changes/shared-refresh/tasks.md
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js list --json
|
||||
|
||||
cat openspec/changes/shared-refresh/.openspec.materialization.yaml
|
||||
```
|
||||
|
||||
- Inspected the raw workspace-root `status --change` JSON before apply.
|
||||
- Inspected repo-local `list --json` immediately after apply, after a partial task update, and after a full task update.
|
||||
- Inspected the materialization sidecar contents.
|
||||
|
||||
## Results
|
||||
|
||||
- `pnpm run build` passed.
|
||||
- `new change shared-refresh --targets app,api` succeeded and created the workspace change.
|
||||
- The raw workspace-root `status --change shared-refresh --json` output still reported:
|
||||
- `proposal: done`
|
||||
- `design: done`
|
||||
- `specs: ready`
|
||||
- `tasks: blocked`
|
||||
- That confirmed the current generic status command is still interpreting workspace changes as if they had repo-local root `specs/` and `tasks.md`.
|
||||
- `apply --change shared-refresh --repo app --json` succeeded and wrote one repo-local change under `repos/app/openspec/changes/shared-refresh`.
|
||||
- Repo-local `list --json` reported `shared-refresh` as:
|
||||
- `in-progress` at `0/2` immediately after apply
|
||||
- `in-progress` at `1/2` after one checked task
|
||||
- `complete` at `2/2` after both tasks were checked
|
||||
- The fixture also still contained the unrelated baseline entry `app-ui-polish` with `status: no-tasks`; it did not affect the `shared-refresh` probe.
|
||||
- The materialization sidecar contained:
|
||||
- `source: workspace`
|
||||
- `workspaceName: happy-path`
|
||||
- `targetAlias: app`
|
||||
- `materializedAt: 2026-04-17T00:44:12.632Z`
|
||||
- The current product surface therefore supports the Phase 13 decision:
|
||||
- task checkboxes are the real progress signal
|
||||
- raw artifact-graph status is not workspace-aware
|
||||
- the sidecar is the minimum reverse link needed for honest roll-up
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product or test code fixes were required from this manual pass.
|
||||
- Updated this manual-test note to reflect the fresh smoke run and explicit `manual-test` stage metadata.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- None found within the scope of Phase 13.
|
||||
- Phase 14 still needs to implement the actual workspace roll-up behavior defined in `DECISION.md`; that is a forward implementation dependency, not a manual-test gap.
|
||||
@@ -0,0 +1,68 @@
|
||||
# Phase 13 Summary
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
## Changes made
|
||||
|
||||
- Added the Phase 13 research decision in `notes/workspace-poc/phase-13-status-research/DECISION.md`.
|
||||
- Added Phase 13 verification and manual-test artifacts:
|
||||
- `notes/workspace-poc/phase-13-status-research/VERIFY.md`
|
||||
- `notes/workspace-poc/phase-13-status-research/MANUAL_TEST.md`
|
||||
- Chose one concrete v0 status roll-up model for the workspace POC:
|
||||
- overall workspace states: `planned`, `in-progress`, `blocked`, `soft-done`, `hard-done`
|
||||
- per-target states: `planned`, `materialized`, `in-progress`, `blocked`, `complete`
|
||||
- coordination states: `planned`, `in-progress`, `blocked`, `complete`
|
||||
- Decided that Phase 14 must derive progress from task checkboxes plus materialization provenance instead of reusing raw artifact-graph status for workspace changes.
|
||||
- Decided that reverse links are required in v0, but the existing `.openspec.materialization.yaml` sidecar is the only required backlink.
|
||||
- Defined the minimum JSON status shape for Phase 14 tests to lock down.
|
||||
- Updated the Phase 13 checklist in `ROADMAP.md`.
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- Re-read the Phase 13, 14, 15, and 16 roadmap blocks in `ROADMAP.md`.
|
||||
- Reviewed the current implementation surfaces that define the available status signals:
|
||||
- `src/commands/workflow/status.ts`
|
||||
- `src/core/artifact-graph/instruction-loader.ts`
|
||||
- `src/core/view.ts`
|
||||
- `src/core/list.ts`
|
||||
- `src/utils/task-progress.ts`
|
||||
- `src/core/workspace/change-create.ts`
|
||||
- `src/core/workspace/apply.ts`
|
||||
- `src/utils/change-metadata.ts`
|
||||
- `src/core/workspace/metadata.ts`
|
||||
- Re-read the prior workspace POC anchors:
|
||||
- `WORKSPACE_POC_PRD.md`
|
||||
- `WORKSPACE_POC_DECISION_RECORD.md`
|
||||
- `notes/workspace-poc/phase-07-open-contract-research/DECISION.md`
|
||||
- `notes/workspace-poc/phase-10-materialization-contract-research/DECISION.md`
|
||||
- Ran focused automated validation:
|
||||
- `pnpm run build`
|
||||
- `pnpm vitest run test/core/workspace/apply.test.ts test/commands/artifact-workflow.test.ts test/core/artifact-graph/instruction-loader.test.ts`
|
||||
- Ran a fresh copied-fixture manual probe against `test/fixtures/workspace-poc/happy-path` with the built CLI:
|
||||
- created `shared-refresh` in the copied workspace
|
||||
- ran `status --change shared-refresh --json` from the workspace root before apply
|
||||
- ran `apply --change shared-refresh --repo app --json`
|
||||
- ran `list --json` in the copied `app` repo immediately after apply, after `1/2` tasks, and after `2/2` tasks
|
||||
- inspected `.openspec.materialization.yaml`
|
||||
|
||||
## Results
|
||||
|
||||
- The generic artifact-graph `status --change` command is not an honest workspace-status implementation because it inspects repo-local root artifact paths that workspace changes do not have.
|
||||
- The current codebase already exposes the minimum signals needed for Phase 14:
|
||||
- workspace coordination progress through `tasks/coordination.md`
|
||||
- target draft progress through `targets/<alias>/tasks.md`
|
||||
- repo-local execution progress through `openspec/changes/<id>/tasks.md`
|
||||
- materialization provenance through `.openspec.materialization.yaml`
|
||||
- The manual probe confirmed the key semantic gap Phase 14 must close:
|
||||
- immediately after `apply`, repo-local `list --json` reports `shared-refresh` as `in-progress` at `0/2`
|
||||
- Phase 14 therefore needs a distinct workspace-level `materialized` state for `0/<n>` or `0/0` repo-local task progress
|
||||
- The existing materialization sidecar is sufficient to act as the required v0 reverse link without expanding `.openspec.yaml`.
|
||||
- The note now defines one precise derivation rule per requested state, clearly separates workspace-only versus repo-local inspection, and resolves the reverse-link question.
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 13.
|
||||
- No new bounded follow-up phase was required from this research pass.
|
||||
- Phase 14 should implement only the custom roll-up and JSON shape described in `DECISION.md`.
|
||||
@@ -0,0 +1,55 @@
|
||||
# Phase 13 Verification
|
||||
|
||||
Independent verification re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 13, cycle 1.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 13 roadmap block in `ROADMAP.md`.
|
||||
- Re-read the phase artifacts under `notes/workspace-poc/phase-13-status-research/`, with focus on `SUMMARY.md` and `DECISION.md`.
|
||||
- Re-checked the implementation boundary the research note depends on:
|
||||
- `src/commands/workflow/status.ts`
|
||||
- `src/core/artifact-graph/instruction-loader.ts`
|
||||
- `src/core/list.ts`
|
||||
- `src/utils/task-progress.ts`
|
||||
- `src/core/workspace/change-create.ts`
|
||||
- `src/core/workspace/apply.ts`
|
||||
- Confirmed the note still matches the current product surface:
|
||||
- workspace changes still scaffold coordination work at `tasks/coordination.md`
|
||||
- workspace changes still scaffold per-target draft work at `targets/<alias>/tasks.md`
|
||||
- `apply` still reuses the workspace change ID and writes `.openspec.materialization.yaml`
|
||||
- repo-local progress is still derived from `tasks.md` checkbox counts
|
||||
- generic `status --change` is still artifact-graph status, not a workspace-aware roll-up
|
||||
- Rebuilt the CLI:
|
||||
- `pnpm run build`
|
||||
- Result: passed
|
||||
- Re-ran the focused regression slice for the signals this phase depends on:
|
||||
- `pnpm vitest run test/core/workspace/apply.test.ts test/commands/artifact-workflow.test.ts test/core/artifact-graph/instruction-loader.test.ts`
|
||||
- Result: 3 files passed, 100/100 tests passed
|
||||
- Re-ran one fresh temp-fixture CLI probe using `test/fixtures/workspace-poc/happy-path`:
|
||||
- created `shared-refresh` in the copied workspace
|
||||
- confirmed workspace-root `status --change shared-refresh --json` still reported `proposal: done`, `design: done`, `specs: ready`, and `tasks: blocked`
|
||||
- materialized `shared-refresh` into the copied `app` repo with `apply --change shared-refresh --repo app --json`
|
||||
- confirmed repo-local `list --json` reported `shared-refresh` as `in-progress` at `0/2`, `in-progress` at `1/2`, and `complete` at `2/2`
|
||||
- confirmed `.openspec.materialization.yaml` still carried `source: workspace`, `workspaceName: happy-path`, and `targetAlias: app`
|
||||
- Re-validated the Phase 13 acceptance criteria against `DECISION.md`:
|
||||
- 13.5 one precise derivation rule is present for `planned`, `materialized`, `in-progress`, `blocked`, `complete`, `soft-done`, and `hard-done`
|
||||
- 13.6 the note explicitly separates workspace-only inspection from repo-local inspection
|
||||
- 13.7 the note resolves reverse links as required in v0, using the existing sidecar as the minimum backlink
|
||||
- Confirmed the Phase 13 checklist in `ROADMAP.md` already matched the verified state, so no checkbox changes were required in this pass.
|
||||
|
||||
## Issues found
|
||||
|
||||
- No product correctness issues were found in the reviewed boundary.
|
||||
- No acceptance-test gaps were found in `DECISION.md`.
|
||||
- No documentation-quality issues were found in the phase artifacts.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- Updated this verification note to reflect the exact fresh-context checks run in this pass.
|
||||
- No product, roadmap, or test changes were required.
|
||||
- No additional roadmap phases were needed.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No residual risks were found within the scope of this research phase.
|
||||
- Phase 14 still needs to implement the custom roll-up described here; that is a forward implementation dependency, not a Phase 13 verification gap.
|
||||
@@ -0,0 +1,63 @@
|
||||
# Phase 14 Manual Test
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `manual-test`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
Manual smoke re-run in a fresh local context for ROADMAP Phase 14 using copied workspace fixtures and the built CLI.
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Rebuilt the CLI with `pnpm run build`.
|
||||
- Copied `test/fixtures/workspace-poc/happy-path/workspace` and `test/fixtures/workspace-poc/happy-path/repos` into a fresh temp root and created repo-local `openspec/changes/` roots for `app`, `api`, and `docs`.
|
||||
- Ran the real CLI from the copied happy-path workspace with telemetry disabled:
|
||||
|
||||
```bash
|
||||
cd <tmp>/workspace
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change manual-status --targets app,api
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-status --json
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-status --repo app --json
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-status --json
|
||||
# mark workspace coordination tasks complete
|
||||
# mark repos/app/openspec/changes/manual-status/tasks.md complete
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-status --repo api --json
|
||||
# mark repos/api/openspec/changes/manual-status/tasks.md complete
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-status --json
|
||||
```
|
||||
|
||||
- Validated each raw `status --change <id> --json` output parsed cleanly and contained no ANSI escapes or spinner glyphs.
|
||||
- Copied `test/fixtures/workspace-poc/dirty/workspace` and `test/fixtures/workspace-poc/dirty/repos` into a second fresh temp root and created repo-local `openspec/changes/` roots for `app` and `api`.
|
||||
- Ran the real CLI from the copied dirty workspace:
|
||||
|
||||
```bash
|
||||
cd <dirty-tmp>/workspace
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change docs-repair --targets docs
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change docs-repair --json
|
||||
```
|
||||
|
||||
- Validated the dirty-fixture raw `status --change docs-repair --json` output parsed cleanly and contained no ANSI escapes or spinner glyphs.
|
||||
|
||||
## Results
|
||||
|
||||
- `pnpm run build` passed.
|
||||
- In the happy-path smoke:
|
||||
- the first status output showed `change.state: "planned"` with both `api` and `app` as `planned` via `workspace`
|
||||
- after `apply --repo app`, status showed `change.state: "in-progress"` with `app: materialized via repo` and `api: planned via workspace`
|
||||
- after completing coordination plus both repo-local task files, status showed `change.state: "soft-done"` with both targets `complete via repo`
|
||||
- `hard-done` never appeared during the run
|
||||
- In the dirty-workspace smoke:
|
||||
- status showed `change.state: "blocked"`
|
||||
- the `docs` target reported `blocked via workspace`
|
||||
- the problem text was `repo alias 'docs' points to a missing repo path`
|
||||
- All status outputs were valid JSON with no spinner contamination.
|
||||
- No Phase 14 behavior drift was found between the implementation summary, verification notes, and this manual smoke re-run.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product fixes were required from this manual smoke pass.
|
||||
- No manual-test-only fixes were needed beyond updating this artifact with the exact scenarios and observed assertions from the fresh run.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No additional Phase 14 residual risks were found in this manual smoke pass.
|
||||
- Explicit workspace archive and `hard-done` remain deferred to Phase 16 by design.
|
||||
@@ -0,0 +1,68 @@
|
||||
# Phase 14 Summary
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
## Changes made
|
||||
|
||||
- Added workspace-aware status roll-up in `src/core/workspace/status.ts`.
|
||||
- Extended `src/commands/workflow/status.ts` so `openspec status --change <id>` detects targeted workspace changes and uses the workspace roll-up instead of the repo-local artifact graph.
|
||||
- Implemented the Phase 14 state model:
|
||||
- overall workspace change: `planned`, `in-progress`, `blocked`, `soft-done`, `hard-done`
|
||||
- coordination: `planned`, `in-progress`, `blocked`, `complete`
|
||||
- targets: `planned`, `materialized`, `in-progress`, `blocked`, `complete`
|
||||
- Rolled coordination state from `tasks/coordination.md`.
|
||||
- Rolled target state from workspace draft tasks before materialization and from repo-local `tasks.md` after validating `.openspec.materialization.yaml`.
|
||||
- Kept JSON output small and stable:
|
||||
- `change.id`
|
||||
- `change.state`
|
||||
- `coordination.state`
|
||||
- `coordination.tasks`
|
||||
- `coordination.problems`
|
||||
- sorted `targets[]` with `alias`, `state`, `source`, `tasks`, and `problems`
|
||||
- Kept blocked output honest by reporting missing local overlay entries, stale repo paths, missing repo-local OpenSpec state, invalid materialization traces, and unreadable task files instead of inferring progress.
|
||||
- Added focused Phase 14 coverage in:
|
||||
- `test/core/workspace/status.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Updated the Phase 14 checklist in `ROADMAP.md`.
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- Re-read the Phase 14 roadmap block in `ROADMAP.md`.
|
||||
- Re-read the Phase 13 decision in `notes/workspace-poc/phase-13-status-research/DECISION.md`.
|
||||
- Re-reviewed the current workspace implementation surface:
|
||||
- `src/core/workspace/change-create.ts`
|
||||
- `src/core/workspace/apply.ts`
|
||||
- `src/core/workspace/registry.ts`
|
||||
- `src/utils/task-progress.ts`
|
||||
- Built the CLI:
|
||||
- `pnpm run build`
|
||||
- Ran the repository test suite after the implementation landed:
|
||||
- `pnpm test -- test/core/workspace/status.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Result: Vitest ran the full suite; 87 files passed, 1453/1453 tests passed
|
||||
- Ran the focused Phase 14 verification slice in a fresh process:
|
||||
- `pnpm exec vitest run test/core/workspace/status.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Ran a fresh copied-fixture CLI smoke outside Vitest:
|
||||
- happy-path fixture: created `manual-status`, checked `planned`, materialized `app`, then completed coordination plus both repo-local task files to confirm `soft-done`
|
||||
- dirty fixture: created `docs-repair` and confirmed blocked status for the stale `docs` repo path
|
||||
|
||||
## Results
|
||||
|
||||
- `pnpm run build` passed.
|
||||
- The full Vitest suite passed: 87 files, 1453/1453 tests.
|
||||
- The focused Phase 14 verification slice passed: 2 files, 6/6 tests.
|
||||
- The workspace status contract now behaves as intended:
|
||||
- planning-only targets stay `planned` with `source: "workspace"`
|
||||
- valid repo-local materializations show `materialized` at `0/n` or `0/0`
|
||||
- partial repo-local progress shows `in-progress`
|
||||
- stale repo paths and invalid materialization traces show `blocked`
|
||||
- `soft-done` appears only after coordination and every target are task-complete
|
||||
- `hard-done` is not inferred and remained absent in the manual smoke
|
||||
- The JSON output stayed machine-readable with no spinner contamination or ANSI escape sequences.
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 14.
|
||||
- No new roadmap phases were required from this implementation pass.
|
||||
- Phase 15 can expand the status validation matrix, but the Phase 14 build contract is now implemented and passing.
|
||||
@@ -0,0 +1,49 @@
|
||||
# Phase 14 Verification
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `verification`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
Independent verification re-run in a fresh local context for ROADMAP Phase 14.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 14 roadmap block in `ROADMAP.md`.
|
||||
- Re-read the current implementation summary in `notes/workspace-poc/phase-14-workspace-status/SUMMARY.md`.
|
||||
- Re-read the Phase 13 status decision in `notes/workspace-poc/phase-13-status-research/DECISION.md`.
|
||||
- Re-inspected the Phase 14 implementation surface:
|
||||
- `src/core/workspace/status.ts`
|
||||
- `src/commands/workflow/status.ts`
|
||||
- `src/core/workspace/apply.ts`
|
||||
- `src/core/workspace/metadata.ts`
|
||||
- `src/utils/task-progress.ts`
|
||||
- Re-inspected the focused Phase 14 automated coverage:
|
||||
- `test/core/workspace/status.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Rebuilt the CLI:
|
||||
- `pnpm run build`
|
||||
- Result: passed
|
||||
- Re-ran the focused Phase 14 regression slice in a fresh process:
|
||||
- `pnpm exec vitest run test/core/workspace/status.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Result: 2 files passed, 6/6 tests passed
|
||||
- Re-ran a direct CLI smoke on copied happy-path and dirty workspace fixtures outside Vitest:
|
||||
- created `manual-status`, confirmed initial `planned`
|
||||
- materialized `app`, confirmed mixed `in-progress` with `app: materialized` and `api: planned`
|
||||
- completed coordination plus both repo-local task files, confirmed `soft-done`
|
||||
- created `docs-repair` in the dirty fixture, confirmed overall `blocked` plus `repo alias 'docs' points to a missing repo path`
|
||||
- confirmed every `status --change <id> --json` response stayed parseable and wrote no spinner text or ANSI escapes
|
||||
- Re-reviewed `SUMMARY.md` and `MANUAL_TEST.md` for consistency with the implementation and the re-run checks.
|
||||
|
||||
## Issues found
|
||||
|
||||
- No Phase 14 product correctness issues were found.
|
||||
- No acceptance-test failures or documentation contradictions were found.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product code changes were required during this verification pass.
|
||||
- Updated this verification record to reflect the fresh-context checks completed in this stage.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No additional Phase 14 residual risks were found beyond the intentional deferral of explicit workspace archive and `hard-done` behavior to Phase 16.
|
||||
@@ -0,0 +1,63 @@
|
||||
# Phase 15 Manual Test
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `manual-test`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
Fresh manual smoke run in a copied local fixture context for ROADMAP Phase 15 using the built CLI.
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Rebuilt the CLI with `pnpm run build`.
|
||||
- Copied `test/fixtures/workspace-poc/happy-path/workspace` and `test/fixtures/workspace-poc/happy-path/repos` into a fresh temp root, added an `ops` repo, and updated `.openspec/workspace.yaml` plus `.openspec/local.yaml` so `ops` participated as a fourth target.
|
||||
- Ran the real CLI from the copied happy-path workspace:
|
||||
|
||||
```bash
|
||||
cd <tmp>/happy-workspace
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change manual-phase15 --targets app,api,docs,ops
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-phase15 --repo app
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-phase15 --repo api
|
||||
cd <tmp>/happy-repos/app
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js archive manual-phase15 --yes --skip-specs --no-validate
|
||||
rm -rf <tmp>/happy-repos/docs
|
||||
cd <tmp>/happy-workspace
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-phase15 --json
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-phase15
|
||||
```
|
||||
|
||||
- Copied `test/fixtures/workspace-poc/dirty/workspace` and `test/fixtures/workspace-poc/dirty/repos` into a second fresh temp root, keeping the fixture’s stale `docs` path, and ran:
|
||||
|
||||
```bash
|
||||
cd <tmp>/dirty-workspace
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change manual-resume --targets app,api,docs
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-resume --repo app
|
||||
# mark repos/app/openspec/changes/manual-resume/tasks.md as 1/2 complete
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-resume --json
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-resume
|
||||
```
|
||||
|
||||
- Validated each raw `status --change <id> --json` output parsed cleanly and contained no ANSI escapes, spinner glyphs, or `Loading change status...`.
|
||||
|
||||
## Results
|
||||
|
||||
- `pnpm run build` passed.
|
||||
- In the happy-path smoke:
|
||||
- text and JSON status both showed `api: materialized`, `app: archived`, `docs: blocked`, and `ops: planned`
|
||||
- the text output rendered the archived target as `- app: archived via repo (0/2 tasks)`, which matches the current command and e2e expectations
|
||||
- the text output remained readable and listed the stale `docs` problem inline
|
||||
- the JSON output remained machine-parseable
|
||||
- In the dirty-fixture smoke:
|
||||
- text and JSON status both showed `app: in-progress`, `api: planned`, and `docs: blocked`
|
||||
- overall change state remained `blocked`, which is the honest roll-up while the stale repo path is unresolved
|
||||
- the JSON output remained machine-parseable
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- This manual smoke reconfirmed the Phase 15 product fix: archived repo-local targets are surfaced as `archived` instead of being misreported as `planned`.
|
||||
- No product code changes were required during this manual-test pass.
|
||||
- Refreshed this note to record the currently observed archived text rendering and the fresh-context smoke coverage completed in this pass.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No additional Phase 15 residual risks were found in this manual smoke pass.
|
||||
- Explicit workspace archive/completion and `hard-done` remain deferred to Phase 16 by design.
|
||||
@@ -0,0 +1,57 @@
|
||||
# Phase 15 Summary
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
## Changes made
|
||||
|
||||
- Fixed `src/core/workspace/status.ts` so a repo-local change archived under `openspec/changes/archive/` is reported as `archived` instead of silently falling back to `planned`.
|
||||
- Exported the pure state-derivation helpers from `src/core/workspace/status.ts` and tightened the `soft-done` roll-up so archived targets only count once their archived task file is actually complete.
|
||||
- Added Phase 15 coverage in:
|
||||
- `test/core/workspace/status.test.ts`
|
||||
- `test/commands/workflow/status.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-status-cli.test.ts`
|
||||
- Kept `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts` in the focused slice to preserve the existing planned-only workspace status contract.
|
||||
- Created the missing Phase 15 notes and updated the Phase 15 checklist in `ROADMAP.md`.
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- Re-read the Phase 15 roadmap block in `ROADMAP.md`.
|
||||
- Confirmed the Phase 15 notes were missing on disk before implementation.
|
||||
- Re-inspected the current workspace status implementation and existing coverage:
|
||||
- `src/core/workspace/status.ts`
|
||||
- `src/commands/workflow/status.ts`
|
||||
- `test/core/workspace/status.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Built the CLI:
|
||||
- `pnpm run build`
|
||||
- Ran the focused Phase 15 automated slice:
|
||||
- `pnpm exec vitest run test/core/workspace/status.test.ts test/commands/workflow/status.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-status-cli.test.ts`
|
||||
- Re-ran the same focused slice in a fresh process after the first pass.
|
||||
- Ran `git diff --check`.
|
||||
- Ran a direct built-CLI smoke on copied fixtures outside Vitest:
|
||||
- happy-path workspace plus an added `ops` repo to validate `planned`, `materialized`, `archived`, and `blocked` targets in one workspace
|
||||
- dirty fixture to validate interruption/resume with `app: in-progress`, `api: planned`, and `docs: blocked`
|
||||
|
||||
## Results
|
||||
|
||||
- `pnpm run build` passed.
|
||||
- The focused Phase 15 slice passed twice in fresh Vitest processes: 4 files, 13/13 tests.
|
||||
- `git diff --check` passed.
|
||||
- The happy-path CLI smoke showed the intended mixed state matrix:
|
||||
- `api: materialized`
|
||||
- `app: archived`
|
||||
- `docs: blocked`
|
||||
- `ops: planned`
|
||||
- The dirty-fixture CLI smoke showed the intended interruption/resume state:
|
||||
- `app: in-progress`
|
||||
- `api: planned`
|
||||
- `docs: blocked`
|
||||
- All `status --change <id> --json` outputs stayed parseable and free of ANSI/spinner contamination.
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 15.
|
||||
- No new roadmap phases were required from this implementation pass.
|
||||
- Phase 16 can build explicit workspace completion and `hard-done` behavior on top of the now-tested `planned/materialized/in-progress/archived/blocked/complete` target surface.
|
||||
@@ -0,0 +1,66 @@
|
||||
# Phase 15 Verification
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `verification`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
Independent verification re-run in a fresh local context for ROADMAP Phase 15.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 15 roadmap block in `ROADMAP.md`.
|
||||
- Re-read the implementation summary in `notes/workspace-poc/phase-15-test-workspace-status/SUMMARY.md`.
|
||||
- Re-read the current manual smoke record in `notes/workspace-poc/phase-15-test-workspace-status/MANUAL_TEST.md`.
|
||||
- Re-inspected the implementation boundary for Phase 15:
|
||||
- `src/core/workspace/status.ts`
|
||||
- `src/commands/workflow/status.ts`
|
||||
- `test/core/workspace/status.test.ts`
|
||||
- `test/commands/workflow/status.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-status-cli.test.ts`
|
||||
- `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
|
||||
- Confirmed the boundary stays within Phase 15 scope:
|
||||
- workspace status derivation and rendering live under the workspace status surface
|
||||
- no explicit workspace completion or archive state was introduced ahead of Phase 16
|
||||
- `hasExplicitWorkspaceCompletion()` remains a deliberate Phase 16 stub returning `false`
|
||||
- Rebuilt the CLI:
|
||||
- `pnpm run build`
|
||||
- Result: passed
|
||||
- Re-ran the focused Phase 15 regression slice in a fresh process:
|
||||
- `pnpm exec vitest run test/core/workspace/status.test.ts test/commands/workflow/status.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-status-cli.test.ts`
|
||||
- Result: 4 files passed, 13/13 tests passed
|
||||
- Ran `git diff --check`.
|
||||
- Result: passed
|
||||
- Reproduced the mixed-state scenario with the built CLI on copied fixtures outside Vitest:
|
||||
- added an `ops` repo to the happy-path workspace
|
||||
- created and materialized `manual-phase15`
|
||||
- archived the repo-local `app` change
|
||||
- removed the `docs` repo root to force a stale alias
|
||||
- verified status reported `api: materialized`, `app: archived`, `docs: blocked`, and `ops: planned`
|
||||
- Reproduced the interruption/resume scenario with the built CLI on copied dirty fixtures outside Vitest:
|
||||
- created and materialized `manual-resume` for `app`
|
||||
- marked the repo-local app tasks as 1/2 complete
|
||||
- verified status reported `app: in-progress`, `api: planned`, and `docs: blocked`
|
||||
- Performed a raw JSON cleanliness check outside Vitest for both scenarios:
|
||||
- captured `status --change <id> --json` output directly from the built CLI
|
||||
- parsed the raw output with `JSON.parse(...)`
|
||||
- checked that the raw output contained no ANSI escapes, spinner glyphs, or `Loading change status...`
|
||||
- Reviewed Phase 15 documentation quality:
|
||||
- `SUMMARY.md`, `VERIFY.md`, and `MANUAL_TEST.md` all match the observed behavior
|
||||
- the notes clearly distinguish automated coverage from direct CLI smoke coverage
|
||||
- the notes do not claim Phase 16 completion semantics are already implemented
|
||||
|
||||
## Issues found
|
||||
|
||||
- No Phase 15 product correctness issues were found.
|
||||
- No acceptance-test gap was found in the current Phase 15 test slice and direct CLI smoke.
|
||||
- No documentation mismatch was found between the phase artifacts and the current implementation.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product code changes were required during this verification pass.
|
||||
- Refreshed this verification note to record the fresh-context checks completed in this pass, including implementation-boundary review and raw JSON cleanliness checks.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No additional Phase 15 residual risks were found.
|
||||
- Explicit workspace completion/archive semantics and `hard-done` remain intentionally deferred to Phase 16.
|
||||
@@ -0,0 +1,71 @@
|
||||
# Phase 16 Manual Test
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `manual-test`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
Fresh manual smoke run in copied local fixture contexts for ROADMAP Phase 16 using the built CLI.
|
||||
|
||||
## Scenarios run
|
||||
|
||||
- Rebuilt the CLI with `pnpm run build`.
|
||||
- Scenario 1: early top-level workspace archive rejection in a fresh copied fixture:
|
||||
|
||||
```bash
|
||||
cd <tmp-1>/workspace
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change manual-phase16-early --targets app,api
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-phase16-early --repo app
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js archive manual-phase16-early --workspace
|
||||
```
|
||||
|
||||
- Scenario 2: repo-local archive first, then explicit workspace archive, in a second fresh copied fixture:
|
||||
|
||||
```bash
|
||||
cd <tmp-2>/workspace
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change manual-phase16 --targets app,api
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-phase16 --repo app
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-phase16 --repo api
|
||||
# mark workspace coordination plus both repo-local task files as 2/2 complete
|
||||
cd <tmp-2>/repos/app
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js archive manual-phase16 --yes --skip-specs --no-validate
|
||||
cd <tmp-2>/workspace
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-phase16 --json
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-phase16
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js archive manual-phase16 --workspace
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-phase16 --json
|
||||
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-phase16
|
||||
```
|
||||
|
||||
- Parsed the raw JSON status output before and after the explicit workspace archive.
|
||||
- Inspected the copied workspace metadata and repo-local archive directories on disk after Scenario 2.
|
||||
|
||||
## Results
|
||||
|
||||
- `pnpm run build` passed.
|
||||
- Scenario 1 behaved as required for `16.6`:
|
||||
- `openspec archive manual-phase16-early --workspace` exited non-zero
|
||||
- the CLI reported `Workspace change 'manual-phase16-early' is 'in-progress'. Reach 'soft-done' before running 'openspec archive manual-phase16-early --workspace'.`
|
||||
- workspace hard-done was not implied or backfilled
|
||||
- Scenario 2 behaved as required for `16.5`, `16.7`, and `16.8`:
|
||||
- before the explicit workspace archive, JSON status parsed cleanly and overall state was `soft-done`
|
||||
- before the explicit workspace archive, targets rendered as `api: complete` and `app: archived`
|
||||
- before the explicit workspace archive, `workspace/changes/manual-phase16/.openspec.yaml` did not contain `workspaceArchivedAt`
|
||||
- after `openspec archive manual-phase16 --workspace`, JSON status parsed cleanly and overall state became `hard-done`
|
||||
- after the explicit workspace archive, target states stayed `api: complete` and `app: archived`
|
||||
- after the explicit workspace archive, `workspace/changes/manual-phase16/.openspec.yaml` contained `workspaceArchivedAt`
|
||||
- The filesystem boundaries stayed correct in Scenario 2:
|
||||
- the workspace change still existed under `workspace/changes/manual-phase16/`
|
||||
- the repo-local active `app` change no longer existed under `repos/app/openspec/changes/manual-phase16/`
|
||||
- the repo-local archived copy existed under `repos/app/openspec/changes/archive/2026-04-17-manual-phase16/`
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No product code changes were required during this manual-test pass.
|
||||
- Refreshed this note to capture both observed manual paths:
|
||||
- early `--workspace` archive rejection
|
||||
- repo-local archive first, explicit workspace archive second
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No additional Phase 16 residual risks were found in this manual smoke.
|
||||
- The broader command and CLI coverage expansion remains Phase 17 work.
|
||||
@@ -0,0 +1,66 @@
|
||||
# Phase 16 Summary
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `implementation`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
## Changes made
|
||||
|
||||
- Added the lean explicit workspace completion path on the existing archive surface: `openspec archive <id> --workspace`.
|
||||
- Implemented workspace archive handling in `src/core/workspace/archive.ts` and routed `src/core/archive.ts` to it only when `--workspace` is present, leaving repo-local archive behavior unchanged by default.
|
||||
- Recorded explicit workspace-level hard-done state in workspace change metadata via a new optional `workspaceArchivedAt` field on `.openspec.yaml`.
|
||||
- Updated `src/core/workspace/status.ts` so `hard-done` is derived only from that explicit workspace archive marker.
|
||||
- Kept repo-local archive semantics repo-local:
|
||||
- repo-local archive still moves only the repo-local change under `openspec/changes/archive/`
|
||||
- workspace archive does not move repo-local changes or touch canonical repo-local specs
|
||||
- Added focused Phase 16 coverage in `test/core/workspace/archive.test.ts`.
|
||||
- Extended `test/utils/change-metadata.test.ts` so the new workspace archive marker is parsed and persisted correctly.
|
||||
- Re-ran the existing repo-local archive and workspace status regression coverage to prove the new path did not collapse the repo/local boundary.
|
||||
- Created the missing Phase 16 notes and updated the Phase 16 checklist in `ROADMAP.md`.
|
||||
|
||||
## Tests or research performed
|
||||
|
||||
- Re-read the Phase 16 roadmap block in `ROADMAP.md`.
|
||||
- Confirmed the Phase 16 phase artifacts were missing on disk before implementation.
|
||||
- Re-read the Phase 13 decision and the Phase 15 status/archive notes to preserve the documented `soft-done` versus explicit `hard-done` boundary.
|
||||
- Re-inspected the touched implementation boundary:
|
||||
- `src/core/archive.ts`
|
||||
- `src/core/workspace/status.ts`
|
||||
- `src/utils/change-metadata.ts`
|
||||
- `src/core/artifact-graph/types.ts`
|
||||
- Built the CLI:
|
||||
- `pnpm run build`
|
||||
- Ran the focused Phase 16 automated slice:
|
||||
- `pnpm exec vitest run test/core/archive.test.ts test/core/workspace/status.test.ts test/core/workspace/archive.test.ts test/utils/change-metadata.test.ts`
|
||||
- Ran `git diff --check`.
|
||||
- Ran a direct built-CLI smoke on copied `happy-path` fixtures outside Vitest:
|
||||
- created `manual-phase16` for `app,api`
|
||||
- materialized both targets
|
||||
- completed coordination plus both repo-local task files
|
||||
- archived the repo-local `app` change
|
||||
- confirmed workspace status was still `soft-done`
|
||||
- ran `openspec archive manual-phase16 --workspace`
|
||||
- confirmed workspace status became `hard-done` and `.openspec.yaml` gained `workspaceArchivedAt`
|
||||
|
||||
## Results
|
||||
|
||||
- `pnpm run build` passed.
|
||||
- The focused Phase 16 automated slice passed: 4 files, 57/57 tests.
|
||||
- `git diff --check` passed.
|
||||
- Repo-local archive no longer risks implying workspace completion:
|
||||
- before the explicit workspace archive, status reported `soft-done`
|
||||
- after `archive --workspace`, status reported `hard-done`
|
||||
- The direct CLI smoke confirmed the intended separation of concerns:
|
||||
- `app` remained archived only in `repos/app/openspec/changes/archive/...`
|
||||
- the workspace change remained present at `workspace/changes/manual-phase16/`
|
||||
- the workspace metadata, not repo-local archive activity, became the source of truth for `hard-done`
|
||||
- Mixed repo cadences remained valid:
|
||||
- `api` stayed `complete`
|
||||
- `app` stayed `archived`
|
||||
- the overall workspace still transitioned cleanly from `soft-done` to `hard-done`
|
||||
|
||||
## Blockers and next-step notes
|
||||
|
||||
- No blockers remain for Phase 16.
|
||||
- No new roadmap phases were required from this implementation pass.
|
||||
- Phase 17 can now expand the command/CLI regression matrix around this shipped `--workspace` hard-done path.
|
||||
@@ -0,0 +1,65 @@
|
||||
# Phase 16 Verification
|
||||
|
||||
Phase cycle: 1
|
||||
Stage: `verification`
|
||||
Date: 2026-04-17 (Australia/Sydney)
|
||||
|
||||
Fresh verification pass for ROADMAP Phase 16 in a clean context after the implementation landed.
|
||||
|
||||
## Checks performed
|
||||
|
||||
- Re-read the Phase 16 roadmap block in `ROADMAP.md`.
|
||||
- Re-read the current Phase 16 implementation summary in `notes/workspace-poc/phase-16-workspace-archive/SUMMARY.md`.
|
||||
- Re-read `notes/workspace-poc/phase-16-workspace-archive/MANUAL_TEST.md` and checked that its documented user path still matches the implementation and current observed behavior.
|
||||
- Re-inspected the implementation boundary:
|
||||
- `src/core/archive.ts`
|
||||
- `src/core/workspace/archive.ts`
|
||||
- `src/core/workspace/status.ts`
|
||||
- `src/core/artifact-graph/types.ts`
|
||||
- `test/core/archive.test.ts`
|
||||
- `test/core/workspace/archive.test.ts`
|
||||
- `test/core/workspace/status.test.ts`
|
||||
- `test/utils/change-metadata.test.ts`
|
||||
- Confirmed the Phase 16 boundary stays lean:
|
||||
- the existing top-level `archive` surface is reused
|
||||
- repo-local archive behavior still runs unless `--workspace` is passed
|
||||
- workspace hard-done is represented only by workspace metadata
|
||||
- repo-local canonical spec/archive ownership is untouched
|
||||
- Rebuilt the CLI:
|
||||
- `pnpm run build`
|
||||
- Result: passed
|
||||
- Re-ran the focused verification slice:
|
||||
- `pnpm exec vitest run test/core/archive.test.ts test/core/workspace/status.test.ts test/core/workspace/archive.test.ts test/utils/change-metadata.test.ts`
|
||||
- Result: 4 files passed, 57/57 tests passed
|
||||
- Ran `git diff --check`.
|
||||
- Result: passed
|
||||
- Reproduced the full user-visible Phase 16 path with the built CLI on copied happy-path fixtures in a fresh temp root:
|
||||
- created and materialized `manual-phase16` for `app,api`
|
||||
- completed coordination and both repo-local task files
|
||||
- archived only the repo-local `app` change
|
||||
- confirmed `status --change manual-phase16 --json` still parsed and reported `soft-done`
|
||||
- ran `archive manual-phase16 --workspace`
|
||||
- confirmed `status --change manual-phase16 --json` then parsed and reported `hard-done`
|
||||
- confirmed the workspace change directory remained active while the repo-local archive stayed under `repos/app/openspec/changes/archive/`
|
||||
- Mapped the acceptance tests back to the implementation and checks above:
|
||||
- `16.5` verified by `test/core/workspace/archive.test.ts` and the fresh CLI smoke showing repo-local archive leaves the workspace change active
|
||||
- `16.6` verified by `test/core/workspace/archive.test.ts` rejecting early workspace archive and by the CLI smoke requiring explicit `--workspace`
|
||||
- `16.7` verified by `test/core/archive.test.ts`, `src/core/archive.ts`, and the CLI smoke showing repo-local archive still operates inside repo-local `openspec/changes/archive/`
|
||||
- `16.8` verified by `test/core/workspace/status.test.ts` and the CLI smoke showing `api: complete` plus `app: archived` still rolls up cleanly from `soft-done` to `hard-done`
|
||||
|
||||
## Issues found
|
||||
|
||||
- No Phase 16 product correctness issues were found.
|
||||
- No regression was found in repo-local archive behavior.
|
||||
- No acceptance-test gap was found in the focused automated slice plus the direct CLI smoke.
|
||||
- No documentation drift was found between `SUMMARY.md`, `MANUAL_TEST.md`, and the verified implementation behavior.
|
||||
|
||||
## Fixes applied
|
||||
|
||||
- No additional product code changes were required during this verification pass.
|
||||
- Refreshed this verification note to capture the completed fresh checks, including the direct CLI confirmation of `soft-done` before explicit workspace archive and `hard-done` after it.
|
||||
|
||||
## Residual risks
|
||||
|
||||
- No additional Phase 16 residual risks were found.
|
||||
- Broader command and CLI matrix expansion remains Phase 17 work, but the shipped Phase 16 build contract is implemented and behaving as intended.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user