Skip to content

fix(templates): make archive sync guidance profile-agnostic when sync skill is uninstalled (#913) - #1443

Open
hsusul wants to merge 3 commits into
Fission-AI:mainfrom
hsusul:fix/profile-agnostic-archive-sync-guidance
Open

fix(templates): make archive sync guidance profile-agnostic when sync skill is uninstalled (#913)#1443
hsusul wants to merge 3 commits into
Fission-AI:mainfrom
hsusul:fix/profile-agnostic-archive-sync-guidance

Conversation

@hsusul

@hsusul hsusul commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Linked Issue

Fixes #913

Observed Failure

Under the default core profile (propose, explore, apply, archive), openspec-sync-specs is not installed on user projects. However, the archive and bulk-archive workflow instructions unconditionally directed the agent to run openspec-sync-specs when syncing delta specs during archiving. When an agent attempted to execute openspec-sync-specs on the core profile, execution failed with a missing-skill error.

Root Cause

archive-change.ts and bulk-archive-change.ts templates contained hardcoded instructions pointing at openspec-sync-specs without providing a fallback when the sync skill/workflow is not installed on the active profile.

Implementation

  • Updated src/core/templates/workflows/archive-change.ts and src/core/templates/workflows/bulk-archive-change.ts to provide profile-agnostic guidance: when openspec-sync-specs is not installed, the agent is instructed to perform the spec sync directly by merging delta specs into main specs under openspec/specs/.
  • Regenerated committed skills (pnpm run generate:skills) and updated parity hashes (pnpm run regen:parity-hashes).

Regression Coverage & Validation

  • Ran pnpm test -> 112 test files passed (2253 tests), including all skill template parity tests.
  • Ran pnpm build -> Build completed cleanly.
  • Verified git diff --check -> Passed with 0 whitespace issues.

AI Assistance Disclosure

This pull request was prepared with AI pair-programming assistance (Antigravity). All template edits, generated skills updates, and parity test validations were verified locally before submission.

Limitations or Untested Platforms

None.

Unrelated Changes

No unrelated changes were included.

Summary by CodeRabbit

  • Improvements
    • Archiving workflows now support direct specification synchronization when the sync workflow isn’t available.
    • Delegated sync must complete before archiving proceeds, preventing sync-in-progress archives.
    • Bulk and single archiving add stronger verification to ensure main specs match expected added/modified/removed/renamed outcomes before moving forward.
    • Generated examples and guidance now use fully qualified, store-root aware main spec paths.
  • Tests
    • Updated golden baselines and added assertions covering the revised main-spec path handling and sync/verification behavior.

@hsusul
hsusul requested a review from TabishB as a code owner July 26, 2026 01:02
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Archive and bulk-archive instructions now support direct delta-spec merging when the sync workflow is unavailable, require completed synchronization and main-spec verification before archiving, and update parity tests for the changed templates and generated skills.

Changes

Archive spec synchronization

Layer / File(s) Summary
Archive skill guidance
skills/openspec-archive-change/SKILL.md, skills/openspec-bulk-archive-change/SKILL.md
Archive workflows document direct delta-spec merging, store-root-aware main-spec verification, sync-in-flight guards, and verification failure outcomes.
Embedded workflow templates
src/core/templates/workflows/archive-change.ts, src/core/templates/workflows/bulk-archive-change.ts
Generated archive instructions support inline or direct synchronization, require synchronous delegated completion, and gate moving changeRoot on verified main specs.
Template parity validation
test/core/templates/skill-templates-parity.test.ts
Expected hashes and archive gating assertions are updated for the modified templates and generated skills.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

  • Issue 919 — Addresses archive workflows referencing an unavailable openspec-sync-specs workflow.
  • Issue 1264 — Relates to archive prompt updates and delta-spec synchronization handling.
  • Issue 963 — Concerns the missing optional sync workflow in archive flows.

Possibly related PRs

Suggested reviewers: tabishb, clay-good, alfred-openspec

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the archive sync guidance fix for the core profile.
Linked Issues check ✅ Passed The changes address #913 by removing the hard dependency on openspec-sync-specs and providing a valid sync path when it is unavailable.
Out of Scope Changes check ✅ Passed The added bulk-archive updates and test hash refreshes are directly tied to the same archive sync guidance change.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@skills/openspec-archive-change/SKILL.md`:
- Line 75: Update the direct spec-sync instruction in
skills/openspec-archive-change/SKILL.md to use the store-aware
<planningHome.root>/openspec/specs/ path instead of the literal openspec/specs/
path. Apply the same change in the archive-change template at
src/core/templates/workflows/archive-change.ts, then regenerate the installed
skill from the updated template.

In `@skills/openspec-bulk-archive-change/SKILL.md`:
- Line 133: Bulk synchronization must execute, complete, and verify inline
before archiving. Update skills/openspec-bulk-archive-change/SKILL.md:133 to
require synchronous execution rather than merely invoking the
openspec-sync-specs approach; apply the same requirement in
getBulkArchiveChangeSkillTemplate() at
src/core/templates/workflows/bulk-archive-change.ts:135 and
getOpsxBulkArchiveCommandTemplate() at
src/core/templates/workflows/bulk-archive-change.ts:395, ensuring each workflow
waits for completion and verification before archive.

In `@src/core/templates/workflows/archive-change.ts`:
- Line 132: Update getOpsxArchiveCommandTemplate() so its instructions for
syncing specs match getArchiveChangeSkillTemplate(): run openspec-sync-specs
inline when available, otherwise perform the spec sync directly, and wait
synchronously for completion before continuing. Apply this consistently to both
existing sync guidance locations in the template.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9e3427b8-1bf9-494c-9728-d5d2507f5b99

📥 Commits

Reviewing files that changed from the base of the PR and between 19d4171 and f0221c5.

📒 Files selected for processing (5)
  • skills/openspec-archive-change/SKILL.md
  • skills/openspec-bulk-archive-change/SKILL.md
  • src/core/templates/workflows/archive-change.ts
  • src/core/templates/workflows/bulk-archive-change.ts
  • test/core/templates/skill-templates-parity.test.ts

- Anything else — ask again rather than archiving

To sync, run the `openspec-sync-specs` workflow inline (agent-driven intelligent merge) for change '<name>', passing the delta spec analysis from above, and wait for it to finish. Do not delegate it to a background task — step 5 would move `changeRoot` out from under a sync that is still reading it, leaving the change archived and the main specs never updated. If your agent can only run it by delegation, delegate synchronously and wait for the result.
To sync, run the `openspec-sync-specs` workflow inline (agent-driven intelligent merge) for change '<name>' (if `openspec-sync-specs` is not installed, perform the spec sync directly by merging delta specs into main specs under `openspec/specs/`), passing the delta spec analysis from above, and wait for it to finish. Do not delegate it to a background task — step 5 would move `changeRoot` out from under a sync that is still reading it, leaving the change archived and the main specs never updated. If your agent can only run it by delegation, delegate synchronously and wait for the result.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use the store-aware main-spec root for direct sync.

  • skills/openspec-archive-change/SKILL.md#L75-L75: replace literal openspec/specs/ with the <planningHome.root>/openspec/specs/ location established earlier.
  • src/core/templates/workflows/archive-change.ts#L77-L77: update the source template accordingly, then regenerate the installed skill.
📍 Affects 2 files
  • skills/openspec-archive-change/SKILL.md#L75-L75 (this comment)
  • src/core/templates/workflows/archive-change.ts#L77-L77
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/openspec-archive-change/SKILL.md` at line 75, Update the direct
spec-sync instruction in skills/openspec-archive-change/SKILL.md to use the
store-aware <planningHome.root>/openspec/specs/ path instead of the literal
openspec/specs/ path. Apply the same change in the archive-change template at
src/core/templates/workflows/archive-change.ts, then regenerate the installed
skill from the updated template.

Comment thread skills/openspec-bulk-archive-change/SKILL.md Outdated
Comment thread src/core/templates/workflows/archive-change.ts
@clay-good
clay-good requested a review from a team as a code owner July 27, 2026 17:30
@clay-good

Copy link
Copy Markdown
Collaborator

Code review — verdict: needs rework before this can be considered

The mechanics of this PR are clean. My concern is the approach itself, and I think it introduces more risk than the bug it fixes. Details below.

1. Real need — the issue is real, but it's deliberately parked

#913 describes a genuine failure: core profile ships propose/explore/apply/archive, openspec-sync-specs is not installed, and the archive template tells the agent to run it anyway.

However, on that issue @alfred-openspec wrote:

Thanks for calling this out. I agree this is part of a broader skills-packaging decision, so I've kept this at P1 in backlog and will use it as the acceptance test case as we roll that out.

So this is intentionally held pending a packaging decision, and #913 is earmarked as the acceptance test for it. A stopgap landing now pre-empts that, and worse, it would make #913 look resolved while the packaging gap remains. I'd want maintainer sign-off on the approach before any version of this merges.

2. Does the solution work — this is where I have a substantive objection

The fallback is a single parenthetical:

(if openspec-sync-specs is not installed, perform the spec sync directly by merging delta specs into main specs under openspec/specs/)

That instruction is standing in for skills/openspec-sync-specs/SKILL.md, which is 182 lines, roughly 140 of which are load-bearing merge semantics the agent now has to reconstruct unaided:

  • "Main specs must never contain delta operation headers (## ADDED/MODIFIED/REMOVED/RENAMED Requirements)" — the entire Main Spec Format Reference section.
  • Purpose handling — "The main spec already has one and it is authoritative — leave it alone"; and on a new spec, "copy the delta's ## Purpose body verbatim."
  • MODIFIED is a partial update — "Preserve scenarios/content not mentioned in the delta"; "Never copy a delta file into a main spec as-is."
  • RENAMED FROM:/TO: semantics, and the idempotency guardrail.

Two of those rules exist because they were shipped bug fixes:

Rule Originally broke as
No delta headers in main specs #1120 — agents left delta headers in main specs, view then reported 0 requirements
Purpose carried over, not stomped #1413 / #369 — archive stamped TBD over an authored ## Purpose

Telling a core-profile agent to "merge delta specs into main specs" with none of that context is a direct invitation to reproduce both. And because core is the default profile, the blast radius is every default install — which runs against the "must not break a user of OpenSpec" bar for this review.

There's also a mechanical gap: the instruction never says how the agent should determine whether openspec-sync-specs is installed. There's no CLI for that, so the agent is left to guess or probe the filesystem. In practice I'd expect it to attempt the skill, fail, and then improvise — which is close to today's behaviour.

3. A deterministic path already exists and isn't used

openspec archive already merges specs deterministically — findSpecUpdates() at src/core/archive.ts:433 and buildUpdatedSpec() at :469, with --skip-specs / --yes / --json flags available:

$ openspec archive --help
Archive a completed change and update main specs
  -y, --yes      Skip confirmation prompts
  --skip-specs   Skip spec update operations ...

This is Option B in the issue's own triage notes ("recommended"), and it's the option that cannot regress the format rules above, because the merge is code rather than prose. Routing the no-sync-skill case at the deterministic CLI would be both smaller and safer than asking an LLM to hand-merge.

4. Scope — fine

Guidance-only, no architecture expanded. No complaint here.

Mechanics — verified clean

Credit where due, the regeneration discipline is correct, which is the usual failure mode for template PRs:

  • pnpm build && pnpm generate:skills produces no diff against the committed skills/*/SKILL.md — the golden files genuinely match their source.
  • Full suite: 112 files / 2253 tests, all passing, identical to the base-main count. No test was weakened, only the four parity hashes moved, and they moved honestly.

What I'd suggest instead

  1. Check with @alfred-openspec first, since /opsx-archive can offer 'Sync now' even when openspec-sync-specs is not installed (core profile) #913 is explicitly reserved for the packaging rollout.
  2. If a stopgap is wanted in the meantime, point the fallback at the deterministic CLI (openspec archive '<name>') rather than at freehand merging. One clear sentence, no format contract to re-derive, no regression surface.
  3. If freehand merging really is the desired fallback, it needs to carry the format contract with it — at minimum the Main Spec Format Reference block and the Purpose rule — not a parenthetical. That's a much bigger edit, and it duplicates content that already lives in the sync skill, which is an argument for (2).

Happy to re-review whichever direction you take. To be clear, the underlying report is worth fixing — it's the "let the agent merge it by hand" mechanism I can't sign off on.

@alfred-openspec alfred-openspec left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core-profile archive command path still invokes the missing sync skill, the direct fallback hardcodes repo-local openspec/specs, and bulk archive still lacks inline completion plus verification before moving each change. Please make the command and bulk paths root-aware and synchronous, with semantic regressions for those generated surfaces.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/templates/workflows/bulk-archive-change.ts`:
- Around line 135-146: Define a complete, idempotent direct-merge contract
covering preservation of main-spec purpose, partial MODIFIED updates, RENAMED
FROM/TO handling, delta-header removal, and all ADDED/MODIFIED/REMOVED
semantics, then apply the same contract at
src/core/templates/workflows/bulk-archive-change.ts lines 135-146 and 406-417
and src/core/templates/workflows/archive-change.ts line 77. Regenerate
skills/openspec-bulk-archive-change/SKILL.md lines 133-144 from the updated
guidance, and extend test/core/templates/skill-templates-parity.test.ts lines
227-277 to assert these fallback semantics for every variant.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 74211531-b167-4f00-b1a2-42d5ea2cb4dd

📥 Commits

Reviewing files that changed from the base of the PR and between f0221c5 and 8c632a8.

📒 Files selected for processing (4)
  • skills/openspec-bulk-archive-change/SKILL.md
  • src/core/templates/workflows/archive-change.ts
  • src/core/templates/workflows/bulk-archive-change.ts
  • test/core/templates/skill-templates-parity.test.ts

Comment on lines +135 to +146
- Run the \`openspec-sync-specs\` workflow inline (agent-driven intelligent merge, or merge delta specs directly into main specs at \`<planningHome.root>/openspec/specs/<capability>/spec.md\` if sync workflow is not installed) for each change, passing the delta spec analysis, and wait for it to finish.
- For conflicts, apply in resolved order.
- Do not delegate to a background task — step 8c would move \`changeRoot\` out from under a sync that is still reading it.

b. **Perform the archive**:
b. **Verify main specs before moving changeRoot**:
- Re-run the comparison against every capability that has a delta spec in \`artifactPaths.specs.existingOutputPaths\` against main spec at \`<planningHome.root>/openspec/specs/<capability>/spec.md\` (use the store-aware \`planningHome.root\` from step 3 status JSON, not a hardcoded repo path).
- Verify that main specs are updated:
- ADDED requirements present
- MODIFIED requirements carrying scenario and description changes named in the delta, with their other scenarios intact
- REMOVED requirements gone
- RENAMED requirements present under the new name and absent under the old one
- If sync failed or any capability does not match verification, report what differs and fail/skip moving that change's \`changeRoot\` — do not archive that change. \`changeRoot\` remains intact.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Define the complete direct-merge contract before using it as the fallback.

“Merge delta specs directly” omits preservation of main-spec purpose, partial MODIFIED application, RENAMED FROM/TO processing, delta-header removal, and idempotency. Verification covers only part of this, so a malformed main spec can be archived permanently.

  • src/core/templates/workflows/bulk-archive-change.ts#L135-L146: specify the complete merge semantics.
  • src/core/templates/workflows/archive-change.ts#L77-L77: apply the same contract to single archive fallback.
  • src/core/templates/workflows/bulk-archive-change.ts#L406-L417: apply it to the OPSX bulk fallback.
  • skills/openspec-bulk-archive-change/SKILL.md#L133-L144: regenerate after updating source guidance.
  • test/core/templates/skill-templates-parity.test.ts#L227-L277: assert the required fallback semantics for every variant.
📍 Affects 4 files
  • src/core/templates/workflows/bulk-archive-change.ts#L135-L146 (this comment)
  • src/core/templates/workflows/archive-change.ts#L77-L77
  • src/core/templates/workflows/bulk-archive-change.ts#L406-L417
  • skills/openspec-bulk-archive-change/SKILL.md#L133-L144
  • test/core/templates/skill-templates-parity.test.ts#L227-L277
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/templates/workflows/bulk-archive-change.ts` around lines 135 - 146,
Define a complete, idempotent direct-merge contract covering preservation of
main-spec purpose, partial MODIFIED updates, RENAMED FROM/TO handling,
delta-header removal, and all ADDED/MODIFIED/REMOVED semantics, then apply the
same contract at src/core/templates/workflows/bulk-archive-change.ts lines
135-146 and 406-417 and src/core/templates/workflows/archive-change.ts line 77.
Regenerate skills/openspec-bulk-archive-change/SKILL.md lines 133-144 from the
updated guidance, and extend test/core/templates/skill-templates-parity.test.ts
lines 227-277 to assert these fallback semantics for every variant.

@alfred-openspec

Copy link
Copy Markdown
Collaborator

Thanks for the follow-up. Maintainer call: let's not add either a freehand or CLI fallback here; #913's exact core failure was fixed by #1030 and shipped in v1.4.0 (current v1.6.0 core installs sync), while preserved custom profiles are intentionally user-owned and get an update warning, so we should close this PR and #913 as superseded/fixed and keep #919 for the broader packaging invariant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/opsx-archive can offer 'Sync now' even when openspec-sync-specs is not installed (core profile)

3 participants