You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
How to keep specs consistent and up-to-date with spec-kit? #620
With spec-kit, each feature defines its own spec. This works well at first, but over time and with the multiplication of features, some descriptions become outdated or are enriched by new features.
Example
Feature 001 – User Login defines that a user can log in with email + password.
A few months later, feature 009 – Two-Factor Authentication enhances the login by adding an extra step (OTP code).
In this case, the original spec of feature 001 becomes partially outdated or needs to be complemented by feature 009.
Discussion
Is there a recommended approach to consolidate specs over time?
Should the original feature be modified, or is it better to keep the historical record and add links to subsequent evolutions?
Are there patterns used by the community to manage the evolution and consistency of specs as new features are added?
Idea: Would it be useful to introduce a /close command (or equivalent) to mark a feature as deprecated and automatically update a centralized project documentation?
I think the up-to-date centralized documentation could be considered an integral part of the spec constitution, not just a supporting tool.
This would ensure that as features evolve, the “official” documentation reflects the current state and remains consistent with the history of specs.
I have a similar concern. I think it's essential that specs are maintained/curated/refactored to maintain a single, logically organized source of truth that both humans and AI can refer to. An implementation path could be to do a git commit on the spec update(s), and then use that commit to kick-off planning of a migration plan to implement the spec change.
Doing that, your example might be extended as:
Spec 001 - Initial, Minimal Product is implemented, which amongst other things defines email + password login
A few months later, Spec 009 - Authentication is implemented, which more thoroughly considers authentication requirements and states that both email + password and OAuth login should be supported. The mention of email + password is removed from 001 in the same commit that adds 009. A migration plan + implementation is kicked off.
A few months later, Spec 009 - Authentication is amended, to incorporate the new two-factor auth feature. A migration plan + implementation is kicked off.
What if SpecKit could compact multiple implemented features into a single “milestone” spec — kind of like how LLMs summarize long conversations?
After several /specify → /plan → /tasks → implement cycles, we could run /speckit.compact to:
Synthesize all completed specs into a concise milestone summary
Capture shared patterns, architecture, and lessons
Detect drift between intent and implementation
Optionally trigger a light refactor phase to align the codebase with the consolidated spec
Basically: milestones not as planning containers, but as post-implementation compaction points — compressing implementation history into reusable context and keeping both specs and code coherent as the system evolves.
Reacted by Josh Perfetto, Gideon Catz, Mbertu, deoncg, Viet Vu, 𖤬𝔫𝔡𝔶, Lestan, dhc-bianyunpeng, Ernest, Liron Cohen and 7 more
This is indeed a key point!
It is important to have an up-to-date, consolidated specification describing the overall project.
So I'm joining the question :-)
I also ran into this very early in my testing of this tool. The generated output after the spec is implmented quickly becomes out of date due the the fine tuning changes applied to get the feature ready for actual use. In a perfect world there would be some background job that can detect when feature deviate from the original spec and suggests changes to bring it up to date. I envision this could also be used to create specs for existing features that are missing specs within your project.
I once considered not merging the specs directory into the main branch each time a branch is merged, so as to ensure that the development branch retains its own archival information from the development process.
This issue has been automatically marked as stale because it has not had any activity for 150 days. It will be closed in 30 days if no further activity occurs.
The 001-login / 009-2FA example is exactly the case I hit, and I ended up splitting it into two problems that turned out to need different tools.
"What did we already decide?" — context from earlier specs never reaching the current one. I published spec-kit-memory for that (community catalog id memory): it hooks before_specify / before_plan and recalls prior specs and decisions from a configurable memory backend before you write the new spec.
"Which earlier promise did this new spec just invalidate?" — the sharper half of your question, and the one that actually bit me. A merged spec in my project made a closed per-intent allowlist its central safety control. A later spec made that intent set page-derived and unbounded. The first spec was not wrong — an assumption underneath it moved, and nobody wrote the amendment. Both merged separately, each passing its own gate. /speckit-analyze could not see it, because it reads one feature directory: spec.md, plan.md, tasks.md, constitution. The hole survived three review rounds before a concrete behavioural question walked straight into it.
So I wrote spec-kit-coherence. It hooks after_analyze and diffs the feature against its merged siblings — where "merged" is read from git ls-tree <base-ref>, so a spec that only exists in your working tree is a peer under construction, not a promise already made.
Two halves on purpose:
A deterministic script enumerates siblings from declared links only — spec numbers cited in the prose, # Implements: headers in files the branch changed, contracts declaring themselves a delta over another spec. Never "specs that feel related", which is how this degenerates into a second architecture review. It also flags the two defects that need no judgment: a cited spec with no directory, and a delta contract with no base contract to be a delta of.
A judgment pass then classifies each sibling invariant HOLDS / SILENTLY BROKEN / AMENDED — where AMENDED requires the amendment to actually live in the sibling, not merely in the new spec's prose. An amendment written only in the changing document has not been made.
On your example it would surface 001's "log in with email + password" as a closed-world promise sitting against 009's added step, and say plainly that the artefact to amend is 001 — and that this is a governance change to 001's promises, not a code edit.
Answering @dan-s-github's June question directly: this is that extension, such as it is. Fair warning that it is new — source is public, but no release is cut yet and it is not in the community catalog, so it is a specify extension add --dev <path> install for now.
This issue has been automatically marked as stale because it has had no activity for 60 days. It will be closed in 30 days unless there is a substantive update. If the problem still applies, please provide updated context such as whether it is still reproducible, the affected version or environment, its current impact, and any new reproduction details. A comment that only states that the issue is "still relevant" does not give maintainers enough information to reconsider it.
Activity
elebescond commentedon Sep 27, 2025
Following up on my own question:
I think the up-to-date centralized documentation could be considered an integral part of the spec constitution, not just a supporting tool.
This would ensure that as features evolve, the “official” documentation reflects the current state and remains consistent with the history of specs.
jperfetto commentedon Sep 29, 2025
I have a similar concern. I think it's essential that specs are maintained/curated/refactored to maintain a single, logically organized source of truth that both humans and AI can refer to. An implementation path could be to do a git commit on the spec update(s), and then use that commit to kick-off planning of a migration plan to implement the spec change.
Doing that, your example might be extended as:
michelegirini commentedon Oct 18, 2025
What if SpecKit could compact multiple implemented features into a single “milestone” spec — kind of like how LLMs summarize long conversations?
After several /specify → /plan → /tasks → implement cycles, we could run /speckit.compact to:
Synthesize all completed specs into a concise milestone summary
Capture shared patterns, architecture, and lessons
Detect drift between intent and implementation
Optionally trigger a light refactor phase to align the codebase with the consolidated spec
Basically: milestones not as planning containers, but as post-implementation compaction points — compressing implementation history into reusable context and keeping both specs and code coherent as the system evolves.
gideoncatz commentedon Oct 20, 2025
This is indeed a key point!
It is important to have an up-to-date, consolidated specification describing the overall project.
So I'm joining the question :-)
timgaunt commentedon Nov 5, 2025
I agree, it would be great if there was a centralised/consolidated spec that keeps track of the entire current definition
amerzad commentedon Nov 11, 2025
That is exactly the killer feature of Openspec.
tjohnson4 commentedon Nov 15, 2025
I also ran into this very early in my testing of this tool. The generated output after the spec is implmented quickly becomes out of date due the the fine tuning changes applied to get the feature ready for actual use. In a perfect world there would be some background job that can detect when feature deviate from the original spec and suggests changes to bring it up to date. I envision this could also be used to create specs for existing features that are missing specs within your project.
gwallan commentedon Dec 30, 2025
I once considered not merging the specs directory into the main branch each time a branch is merged, so as to ensure that the development branch retains its own archival information from the development process.
github-actions commentedon May 30, 2026
This issue has been automatically marked as stale because it has not had any activity for 150 days. It will be closed in 30 days if no further activity occurs.
dan-s-github commentedon Jun 1, 2026
just came across this FR while investigating the same problems, wonder if there is an extension available that would solve this
dmarcelino commentedon Jun 30, 2026
I have the same concern. There's also a discussion about this here: #152
zaytsevand commentedon Aug 12, 2026
The 001-login / 009-2FA example is exactly the case I hit, and I ended up splitting it into two problems that turned out to need different tools.
"What did we already decide?" — context from earlier specs never reaching the current one. I published spec-kit-memory for that (community catalog id
memory): it hooksbefore_specify/before_planand recalls prior specs and decisions from a configurable memory backend before you write the new spec."Which earlier promise did this new spec just invalidate?" — the sharper half of your question, and the one that actually bit me. A merged spec in my project made a closed per-intent allowlist its central safety control. A later spec made that intent set page-derived and unbounded. The first spec was not wrong — an assumption underneath it moved, and nobody wrote the amendment. Both merged separately, each passing its own gate.
/speckit-analyzecould not see it, because it reads one feature directory:spec.md,plan.md,tasks.md, constitution. The hole survived three review rounds before a concrete behavioural question walked straight into it.So I wrote spec-kit-coherence. It hooks
after_analyzeand diffs the feature against its merged siblings — where "merged" is read fromgit ls-tree <base-ref>, so a spec that only exists in your working tree is a peer under construction, not a promise already made.Two halves on purpose:
# Implements:headers in files the branch changed, contracts declaring themselves a delta over another spec. Never "specs that feel related", which is how this degenerates into a second architecture review. It also flags the two defects that need no judgment: a cited spec with no directory, and a delta contract with no base contract to be a delta of.HOLDS/SILENTLY BROKEN/AMENDED— whereAMENDEDrequires the amendment to actually live in the sibling, not merely in the new spec's prose. An amendment written only in the changing document has not been made.On your example it would surface 001's "log in with email + password" as a closed-world promise sitting against 009's added step, and say plainly that the artefact to amend is 001 — and that this is a governance change to 001's promises, not a code edit.
Answering @dan-s-github's June question directly: this is that extension, such as it is. Fair warning that it is new — source is public, but no release is cut yet and it is not in the community catalog, so it is a
specify extension add --dev <path>install for now.mnriem commentedon Aug 12, 2026
As indicated above you can deliver an extension and/or preset to deliver this above and beyond the core SDD process
github-actions commentedon Oct 13, 2026
This issue has been automatically marked as stale because it has had no activity for 60 days. It will be closed in 30 days unless there is a substantive update. If the problem still applies, please provide updated context such as whether it is still reproducible, the affected version or environment, its current impact, and any new reproduction details. A comment that only states that the issue is "still relevant" does not give maintainers enough information to reconsider it.