Repository navigation
Description
OpenSpec 1.12.0, upgrading generated artifacts from 1.11.0. openspec update printed:
Files to remove
No user content to preserve:
• openspec/AGENTS.md
⚠ Run with --force to auto-cleanup legacy files, or run interactively.
The file in that repo has 223 lines of hand-written, project-specific content. Measured before declining the cleanup:
| check | result |
|---|---|
| length | 223 lines |
| lines naming project-specific subjects (this repo's platforms, cache tables, contract governance) | 15 |
| git | tracked; last modified by a feature commit in July, not by openspec |
referenced by the project's own CLAUDE.md |
3 times, two of them by section number |
The two cited sections are both present and both hand-written: ## 1.5 Prerequisite — verify the API from the source BEFORE writing the spec at line 63, and ### 3.2 The final close-out task — the implementation-guide question (MANDATORY) at line 138. The project's CLAUDE.md calls the file "the canonical detailed local version" of its delivery workflow.
So the claim is not "this file is legacy and you may not need it" — it is the stronger and, here, false claim that there is no user content in it. Acting on that with --force deletes 223 lines of project doctrine that three other instruction files point at.
Why this is riskier than it first reads
The recommended path amplifies it. The message offers --force as the convenient option ("or run interactively"), and --force is the one an agent or a script reaches for, because interactive prompts are exactly what automation avoids. An agent that trusts the printed justification has been told there is nothing to lose — so the safe-looking action and the destructive one are the same action.
It is also silent afterwards. The file is tracked, so git status would show the deletion, but by then the reason to keep it has scrolled past, and the update's own output is on record saying it contained nothing.
What would fix it
The cleanup appears to decide by filename rather than by content or history. Anything that distinguishes a stock generated file from a modified one would be enough:
- compare against the digest of what OpenSpec itself last generated (if a
generatedBy-style stamp is written intoAGENTS.md, its absence or a content mismatch is the signal) - or, where the file is git-tracked, check whether its last-touching commit was an
openspecrun - or simply soften the wording to "no content OpenSpec recognizes" and have
--forcerefuse a file that differs from the generated baseline, requiring an explicit second flag
The last is the smallest change and still removes the trap: the sentence currently makes a claim about the user's file that the tool has not verified.
Related
#1689 covers the other half of the same deletion — that removing AGENTS.md takes the spec inventory's delivery mechanism with it, and no generated skill teaches openspec list --specs as a replacement. This issue is narrower and independent: whichever way that one is resolved, the cleanup should not tell people a modified file is empty.
Environment
OpenSpec CLI 1.12.0 (bun global install), artifacts previously generated by 1.11.0, Claude Code toolset. The update's regeneration half was clean — 8 files, +62/-6, new "Planning a Change" guidance plus generatedBy bumps — and was accepted. Only the cleanup half was declined.
Activity