Files
OpenSpec/test/core
Clay GoodandClaude Opus 4.8 b474f81cb4 fix(templates): don't archive a change before its spec sync finishes (#1394)
* fix(templates): wait for the spec sync before archiving a change

The generated openspec-archive-change skill dispatched the spec sync to a
subagent via the Task tool and then moved changeRoot in the very next step,
with nothing requiring it to wait. Where subagents run asynchronously, the
archive relocates the delta specs out from under the running sync, so the
change is archived while openspec/specs/ is never updated — and the success
summary still reports "Specs: ✓ Synced".

Step 4 now requires waiting for the dispatched sync to return, verifying the
synced requirements are present in the main spec, and stopping without
archiving if either check fails. Adds a matching guardrail bullet and a
parity assertion so the gate cannot silently disappear again.

Fixes #1393

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(templates): run the spec sync inline and verify it before archiving

Addresses review on #1394. The first pass asked the agent to "wait" for a
dispatched subagent, but subagents run in the background by default and the
wait is not reliably expressible in prose — the race survived. It also gated
the archive on the synced requirements being *present*, which a correct
REMOVED-only or RENAMED-only sync does not satisfy, turning a successful sync
into a hard block.

The sync now runs inline via the Skill tool, with a synchronous-subagent
fallback for harnesses that need one. Verification follows delta semantics:
ADDED/MODIFIED present, REMOVED gone, RENAMED under the new name, checked
across every capability the sync touched.

Also resolves the opsx command variant's contradiction with its own guardrail,
stops the summary reporting a checkmark that step 4 never verified, and updates
openspec/specs/opsx-archive-skill/spec.md, which still said the skill proceeds
with the archive regardless of the sync choice.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(specs): encode delta verification semantics in the archive skill spec

The scenario said the agent verifies each capability "matches its delta",
which is ambiguous about what a match means — and a REMOVED-only sync
correctly leaves requirements absent. Spell out the predicate the template
implements, and separate an explicit "Archive without syncing" choice from a
requested sync that failed or could not be verified: only the former may skip
verification, the latter must stop.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(templates): close verification holes and drop Claude-only tool names

Second review pass on #1394.

The gate was weaker than it looked. "MODIFIED requirements present" is
vacuous — a MODIFIED requirement exists in the main spec before the sync runs,
so a no-op sync passed the check for the most common delta shape, which is the
exact symptom #1393 reports. "RENAMED under their new name" passed a sync that
copied rather than renamed, leaving both names behind. And scoping the re-check
to "every capability it touched" derived the verification set from the artifact
being verified, so a silently skipped capability escaped it.

Verification is now bound to the delta specs in artifactPaths.specs, covers the
changes each MODIFIED delta names, and requires RENAMED requirements to be gone
from the old name.

Separately, the previous pass named the Claude Code "Skill tool" and
run_in_background in a template that is also the slash-command source for ~28
other tools, where skills are removed entirely for commands-only delivery. Both
variants now use the runtime-neutral phrasing bulk-archive-change already uses.

Also: route the prompt options explicitly instead of defaulting unknown answers
to archive, tell the user a stopped archive is recoverable, and mark the summary
line as a conditional rather than literal text to copy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(templates): verify the sync by re-running step 4's own comparison

The verification predicate restated delta semantics in its own words, which
could drift from what openspec-sync-specs actually does. Anchor it instead to
the comparison step 4 already performs before prompting: a successful sync
leaves nothing to apply, so every capability must read as already synced. The
explicit ADDED/MODIFIED/REMOVED/RENAMED bullets stay as the definition of what
"nothing left to apply" means.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 18:59:51 +00:00
..