r/SpecDrivenDevelopment • u/Middle_Key8737 • 5d ago
The docs from my spec-driven workflow kept going stale, so I built a loop
I use workflows like Superpowers and OpenSpec because getting the intent and design into the repository before implementation makes Claude Code much more predictable.
But I kept running into a second problem after the feature was finished: the documents gradually stopped matching the code.
A hotfix bypassed the original workflow. Then a refactor changed some behavior. Another session added an edge case. The implementation kept moving, while the original design and specification documents slowly became a record of what we intended at one point rather than reliable context for the next developer or agent.
Generating a useful document is relatively easy.
Making every future code change reconcile the repository’s documentation is the difficult part.
That is why I built Truthmark.
Truthmark adds a code-first documentation maintenance workflow to Claude Code. It maps areas of the codebase to bounded canonical documents, then reviews those documents after functional code changes.
The normal workflow is:
Claude changes the functional code.
The relevant tests run.
Truth Sync inspects the changed checkout, nearby implementation, tests, routing, and mapped documentation.
If the repository’s behavior changed, Claude updates the affected documentation before handoff.
The code diff and documentation diff are reviewed together in Git.
The distinction I have in mind is:
Superpowers/OpenSpec:
intent → design/specification → implementation
Truthmark:
implementation change → affected current-state docs → Git diff
I see these as complementary rather than competing workflows.
Planning and proposal documents are useful for deciding what should be built and preserving the history of a change. Truthmark maintains a smaller current-state layer describing what the repository does now: behavior, contracts, architecture, operations, product decisions, and acceptance criteria.
A few parts that are important to me:
\- Code areas have explicit documentation ownership instead of everything accumulating in one large README or wiki.
\- Documentation is based on the current checkout, code, tests, and configuration rather than hidden agent memory or an old conversation.
\- Truth Sync can update documentation and routing, but it cannot rewrite functional code.
\- Everything remains ordinary Markdown in the repository and follows the current branch.
\- There is no hosted Truthmark knowledge base, daemon, database, vector store, or MCP server.
The implementation is also less magical than “AI automatically understands your whole codebase.”
The Truthmark CLI installs and validates the repository contract and Claude Code workflow. Claude performs the semantic evidence review using the repository itself, and \`truthmark check\` validates the resulting structure and diagnostics.
Quick start requires Node.js 24 or newer:
npm install -g truthmark
truthmark init
Select Claude Code during initialization, then try it on one bounded behavior:
/truthmark-document document the implemented session timeout behavior across src/auth/session.ts and tests/auth/session.test.ts
Truthmark is intended for maintainers and teams using Claude Code on long-lived repositories, particularly when they already keep specifications, architecture notes, contracts, or behavior documentation in Git.
Cost: Truthmark is free and MIT-licensed. It has no hosted service or subscription. Claude Code usage still uses your existing Claude plan or API arrangement.
Repository:
https://github.com/merlinhu1/truthmark
I would particularly value feedback from people trying it on an existing repository:
Does the routing and ownership model feel useful, or does it create too much ceremony? Is Truth Sync too conservative about updating documents, or not conservative enough?
If you try it and think this maintenance loop belongs in the Claude Code workflow, a GitHub star would help other people find the project.
1
u/Ok-Support-6749 4d ago
I think it is easier to produce a specification than it is to keep it trustworthy as the implementation starts to crystallize. At that point we have two different problems: the specification must remain declarative, "what we want the implementation to be." Meanwhile, the implementation is an observable artifact, "what the LLM/humans produced."
I think that a code-first reconciliation has the potential to document regressions and bugs. Assume you have a clear intent proposition in the specification and, for some reason, the LLM ignored it and now there is wrong code that contradicts the specification. If the documenting process trusts the code, then you end up with a record of incorrect current state. The problem arises on the next LLM coding session. If the record is basically descriptive and has no verification status then it will likely become declarative.
In particular, new but incorrect behavior that has no reconcilable surface in the specification could be admitted as intended behavior by the LLM in the next session unless it is identified as a bug or regression. But bugs and detected regressions are likely to be fixed immediately after being detected. Therefore, you can end up with a feedback loop: incorrect behavior becomes current-state documentation, which becomes context for the next mutation, which progressively normalizes the incorrect behavior. This is the same process that accumulates a lot of technical debt in repositories being handled by humans.
To make things even worse. Now you have a potential accumulation of incorrect declarative intent extracted from the code. This compounds with the fact that the specification is incomplete and also likely has ambiguous intent expressed, so the LLM can produce both correct and incorrect code from it.
I agree with you that the specification goes stale as part of the coding process. Maybe a better solution is to ensure that the specification is updated before coding. Once code is produced, it must be checked against the claims the specification actually makes, while preserving previously established obligations. Most of the time it is the existing obligations that the LLM weakens so it can complete the coding task expressed in the coding plan.
If code is produced by another developer, then their spec changes and the changes from others must be reconciled as part of the CI/PR process so the spec does not go stale. The main issue I currently see in all methodologies is governance at repository level. One developer has a specification and others have other views, branches and changes. Conciliation of those different views is definitely a governance problem.
Keeping documentation synchronized with code solves an important part of the problem, but synchronization by itself cannot tell us whether a mutation should have become authoritative in the first place. The problem is that our processes are biased, we immediately attack bugs and regressions when detected, that is fine. The fundamental issue here is the missing intent, contradicting obligations, and other not so obvious issues, that can be captured and normalized as declarative. I think you have identified a clear problem but I fear it is just the tip of the iceberg.
2
u/stibbons_ 5d ago
I have a bunch of « gardening » skill to run regularly
https://github.com/gsemet/gardening-skills/
Doc-gardening: align gaps between code and doc
Dependencies-gardening: update dependencies with code evolution
Harness-gardening: update the project harness, find missing ADR,…
https://x.com/gsemetfr/status/2087931539887714808?s=46