Skip to content

fix(explore): name the propose workflow at every handoff - #1788

Open
clay-good wants to merge 3 commits into
mainfrom
claude/openspec-issue-triage-pr-8d7357
Open

fix(explore): name the propose workflow at every handoff#1788
clay-good wants to merge 3 commits into
mainfrom
claude/openspec-issue-triage-pr-8d7357

Conversation

@clay-good

@clay-good clay-good commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Status

Ready for review. Two commits. Full suite: 4,429 passing; the only 2 failures (artifact-workflow Cursor-skills, config-profile interactive apply) reproduce on unmodified main with this branch's files reverted.

What was wrong

Explore mode refuses to implement. It never said what to do instead.

The docs already promise the handoff. docs/explore.md opens with "When the picture is clear, it hands off to /opsx:propose", diagrams explore ──► propose ──► apply ──► archive, and docs/commands.md shows a worked example ending in "Run /opsx:propose add-jwt-auth to begin." The template implemented none of it. Every place the skill and command pointed past themselves was prose:

Where Before
Implement refusal "remind them to exit explore mode first and create a change proposal"
Ending Discovery "Ready to start? I can create a change proposal."
Closing summary "- Create a change proposal"
Guardrails "Don't implement — Never write code…" (no alternative named)
Seamless capture scaffolds the change, writes artifacts, then stops mid-air

Every other workflow template names its handoff — propose/opsx:apply, new/opsx:continue, ff/opsx:apply. Explore was the one workflow that said "stop" without saying "go here", so /opsx:explore had no exit an agent could take. Two reporters in #869 hit the predictable result through GitHub Copilot: the agent ran discovery, answered the questions, then went straight to implementing, skipping change creation entirely.

The capture path is the sharper half. Explore can scaffold a change and write artifacts in a confirmed scope, and then the guidance simply ended. An agent holding a fresh proposal, still inside explore mode, with nothing named next, has one obvious wrong move — the one the issue reported.

How it was fixed

Five handoff points now name the workflow:

  • Refusal: "point them at /opsx:propose, which turns the discussion into a change. The work happens from that change, never from explore mode."
  • Ending Discovery: "Ready to start? Run /opsx:propose and this becomes a change."
  • Closing summary: "- Turn this into a change: /opsx:propose"
  • Guardrail: "When the user is ready to build, name the handoff rather than starting: /opsx:propose turns the discussion into a change, and the work happens there."
  • Seamless capture ending: "When the requested capture is done, stop there and name where the work continues: /opsx:propose writes the remaining planning artifacts, and /opsx:apply implements the change once tasks exist. Capturing artifacts is never permission to implement them."

Both references are written in the canonical /opsx:<id> form, so the existing per-tool transformers render the invocation each tool actually registers. No new mechanism: propose and apply are both CORE_WORKFLOWS members, and this is the same cross-workflow reference pattern onboard, propose, ff, and new already use (68 existing instances).

Skill and command bodies are patched together (both carry the text), the skills/ mirror is regenerated with npm run generate:skills, and parity hashes are refreshed with scripts/regen-parity-hashes.mjs.

Proof it works

Eight new tests in test/core/templates/explore.test.ts, each asserted against both delivery surfaces. All 8 fail on unmodified main (8 failed | 25 passed) and pass here.

Content assertions cover each of the five handoff points and assert the old prose is gone.

Rendering assertions walk the real registries rather than a hand-picked few, so a new adapter or a changed invocation shape cannot quietly leave explore advertising a command nobody answers to (the #727 / #1307 failure mode):

  • every adapter in CommandAdapterRegistry.getAll() (30 of them) must rewrite every canonical reference to that adapter's own spelling — counted, not substring-matched, so a partial rewrite fails
  • every entry in AI_TOOLS must do the same on the skills surface, with no /opsx: form of any kind surviving
  • the Codex-compatible shared .agents rendering is asserted separately

Verified against real installs, not just transformers. openspec init in a scratch repo produces, in the explore skill and command:

Tool Shape Rendered
Claude Code namespaced /opsx:propose
Cursor flat /opsx-propose
Amazon Q flat, @ prefix @opsx-propose (×4)
Kimi Code skills, /skill: /skill:openspec-propose (×5)
Rovo Dev natural language "the openspec-propose skill" (×5)
Codex shared .agents $openspec-propose (Codex) or /openspec-propose (other agents)

No residual opsx:propose in any generated file. test/core/templates/ and test/core/command-generation/ are green at 1,326/1,326; lint and tsc --noEmit clean.

Notes

  • Guidance fix, so it removes the ambiguity rather than making the behavior impossible — a model can still ignore an instruction. What changed is that explore now has a named exit instead of a dead end, and that exit matches what the docs have promised all along.
  • Only propose and apply are named, never ff or new. Both named workflows are in CORE_WORKFLOWS; ff and new are not installed on the core profile, so naming them would advertise workflows most projects do not have.
  • The "This feels solid enough to start a change. Want me to create a proposal?" offer is left as prose on purpose. That line opens explore's own confirmed-scope capture path, which scaffolds and writes in place; pointing at another workflow there would fight it. The handoff belongs where explore declines to act, and at the point where its own capture is finished.
  • There is no openspec/specs/ capability covering the explore skill (unlike opsx-onboard-skill, opsx-verify-skill, opsx-archive-skill), so no spec delta accompanies this. Worth filing separately if explore's contract should be specified.
  • fix(templates): stop generated skills naming workflows the profile omits #1775 (open) makes cross-workflow references profile-aware via optionalWorkflow(). It does not touch explore.ts today because explore had no cross-workflow references before this. Whichever of the two lands second should wrap these two new references so a custom profile that installs explore without propose or apply drops them.

Closes #869

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Explore guidance now clearly directs users to the proposal workflow after discovery or artifact capture.
    • Implementation requests from Explore mode now point to the appropriate proposal and apply workflows.
    • Guidance clarifies that capturing artifacts does not authorize implementation.
    • Workflow references are formatted according to each supported tool’s command conventions.
  • Tests
    • Added coverage to verify proposal and implementation handoffs across supported command and skills-based integrations.

Explore mode refuses to implement, but nowhere named the workflow that
turns the discussion into a change. The refusal, the "flow into a
proposal" ending, the closing summary, and the do-not-implement
guardrail all described the next step as prose. With no named exit,
agents answered the discovery questions and then started writing code
(#869).

All four handoff points now point at `/opsx:propose`, written in the
canonical `/opsx:<id>` form so each tool renders the invocation it
actually registers. Skill and command bodies are patched together, the
skills.sh mirror is regenerated, and parity hashes are refreshed.

Closes #869

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@clay-good
clay-good requested a review from a team as a code owner September 4, 2026 18:01
@clay-good
clay-good requested review from TabishB and removed request for a team September 4, 2026 18:01
@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 5b8b18a4-216c-4022-858d-2af3a1c54b54

📥 Commits

Reviewing files that changed from the base of the PR and between 7310533 and a3e4993.

📒 Files selected for processing (1)
  • .changeset/explore-names-the-propose-handoff.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/explore-names-the-propose-handoff.md

Included review availability: Your plan provides up to 10 included reviews per hour; 4 remain after this review.


📝 Walkthrough

Walkthrough

Explore guidance now names the proposal workflow at implementation and discovery handoff points. Templates, generated skill content, tests, parity hashes, and the patch changeset were updated.

Changes

Explore proposal handoff

Layer / File(s) Summary
Template handoff guidance
src/core/templates/workflows/explore.ts
Both explore templates direct implementation requests and discovery completion to /opsx:propose. The capture flow names /opsx:apply for implementation and states that capture does not authorize implementation.
Generated skill guidance
skills/openspec-explore/SKILL.md, .changeset/explore-names-the-propose-handoff.md
The packaged skill uses /openspec-propose for implementation handoffs. A patch changeset documents the update.
Handoff rendering and parity validation
test/core/templates/explore.test.ts, test/core/templates/skill-templates-parity.test.ts
Tests verify the handoff wording, removed phrases, rendered command references, capture guardrails, and updated template hashes.

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

Merge Risk: ⚪ Minimal · up to a3e49

The change updates Explore handoff guidance to direct users toward proposal creation before implementation. No concrete merge-blocking risk is currently identified.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 3 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: naming the propose workflow at each Explore handoff.
Linked Issues check ✅ Passed The changes address issue #869 by adding explicit /opsx:propose handoffs after exploration and artifact capture, while naming /opsx:apply for implementation after planning.
Out of Scope Changes check ✅ Passed The changes remain within scope. They update Explore guidance, generated template mirrors, related tests, and expected hashes required to implement and verify the handoff behavior.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 3 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/openspec-issue-triage-pr-8d7357

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.

@openspec-cloud

openspec-cloud Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

No PR-relevant drift confirmed.

AI-generated · A citation proves the line exists, not that it makes the case — verify before acting.
No issue was confirmed at 3a3113c; 2 requirements could not be verified.
This is not a full-repository clean result; see the check for coverage and any broader findings.
View results · Click Refresh, then Scan again in the check. Or comment /openspec-cloud.

clay-good and others added 2 commits September 4, 2026 13:18
The capture path let explore scaffold a change and write artifacts, then
said nothing about what came next. An agent holding a fresh proposal
inside explore mode has an obvious wrong next move, and it is the one
#869 reported. The capture now ends by naming `/opsx:propose` for the
remaining planning artifacts and `/opsx:apply` for implementation, and
says plainly that capturing artifacts is not permission to implement
them.

Widen the rendering guard to walk the real registries instead of a
hand-picked few: every registered command adapter and every entry in
AI_TOOLS must rewrite every canonical reference in both bodies, with no
`/opsx:` form surviving on any skills surface. A new adapter or a
changed invocation shape now fails here rather than shipping a command
nobody answers to.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

Claude Opus 4.6 will skip the opsx:ff and went ahead to implement

1 participant