Skip to content

Add OpenSpec workflow and open-pr skill (LS-3223) - #53

Open
brandonmarshal wants to merge 3 commits into
developfrom
feature/ls-3223-aiops-openspec-plan-new-skills
Open

Add OpenSpec workflow and open-pr skill (LS-3223)#53
brandonmarshal wants to merge 3 commits into
developfrom
feature/ls-3223-aiops-openspec-plan-new-skills

Conversation

@brandonmarshal

Copy link
Copy Markdown
Collaborator

Summary

New skills were being planned ad hoc, with no shared process and no version-controlled record of why a given skill was built the way it was. This adds OpenSpec as the repo's spec-driven planning workflow for new skills, and uses it end-to-end to build the first real skill under that process: open-pr, replacing a personal, machine-local PR-creation command with a proper repo-committed agent skill.

OpenSpec setup

  • Initialize OpenSpec for Claude Code (openspec init --tools claude), adding the /opsx:propose, /opsx:apply, /opsx:archive, /opsx:explore, /opsx:sync commands and their corresponding skills under .claude/.
  • Add openspec/specs/ and openspec/changes/archive/ scaffolding.

open-pr skill — planned and built through OpenSpec

  • openspec/changes/open-pr-skill/proposal.md, design.md, specs/pr-creation/spec.md, tasks.md — the full planning trail: why the personal command is being replaced, the key design decisions (skill location, dual invocation with a confirmation guard, content carryover), and testable WHEN/THEN requirements.
  • .claude/skills/open-pr/SKILL.md — the implemented skill. Gathers PR context from the branch's own commits/diff rather than assumed conversation context, runs pre-flight checks (existing PR, real label set, base branch, changelog requirement), and applies labels and assignee in the same gh pr create/gh pr edit call rather than as a separate step that can be skipped. Adds a CHANGELOG.md entry only after the PR exists, linking back to it. Works via the explicit /open-pr command and via natural-language requests (e.g. "create the PR for me"), with a guard requiring branch/base confirmation before acting on an implicit trigger.
  • The skill deliberately lives at .claude/skills/ rather than this repo's usual .agents/skills/ portable-skill location, since it needs native Claude Code slash-command registration and natural-language auto-invocation, which Claude Code does not provide for .agents/skills/. Documented inline in the skill file and in design.md (Decision 1) so it isn't mistaken for an oversight of AGENTS.md rule 11.

Housekeeping

  • Gitignore .claude/settings.local.json (personal, machine-local Claude Code permission grants) — this file is not meant to be shared and was about to be committed by accident.

Investigated, not changed

  • Considered placing the open-pr skill under .agents/skills/ for consistency with this repo's stated portable-skill convention. Rejected: Claude Code only auto-discovers and slash-command-registers skills from .claude/skills/, and this skill has no near-term need for cross-tool portability (it's a gh-CLI-specific workflow, not a shared WordPress convention). Full rationale in openspec/changes/open-pr-skill/design.md.

Test plan

  • openspec validate open-pr-skillChange 'open-pr-skill' is valid
  • Cross-checked all 6 requirements in specs/pr-creation/spec.md against the shipped SKILL.md body — all represented
  • Confirmed .claude/settings.local.json is excluded via git check-ignore -v
  • This PR was itself created using the new /open-pr-equivalent skill (natural-language invocation, branch/base confirmed per the implicit-trigger guard) — a live, real-world test of task 4.1/4.2 in tasks.md
  • Verify natural-language re-invocation on an existing PR (the gh pr edit --add-label/--add-assignee path) — not yet exercised, since this PR didn't previously exist
  • Archive openspec/changes/open-pr-skill/ via /opsx:archive after this PR is reviewed

LS-3223

Closes LS-3223.

OpenSpec integration
- Initialize OpenSpec for Claude Code (openspec init --tools claude)
- Add opsx:propose/apply/archive/explore/sync commands and skills

Planning artifacts
- Add proposal.md: why open-pr is moving from a personal command to a repo-committed skill
- Add design.md: skill location, dual-invocation guard, content-carryover decisions
- Add specs/pr-creation/spec.md: testable requirements for context-gathering, pre-flight checks, labels/assignee-in-same-command, changelog-after-PR
- Add tasks.md: implementation checklist for building the open-pr skill

Housekeeping
- Gitignore .claude/settings.local.json (personal, machine-local permission grants)
Skill implementation
- Add .claude/skills/open-pr/SKILL.md implementing the pr-creation spec
- Port validated PR-creation instructions: context gathering, pre-flight checks, PR structure
- Apply labels and assignee in the same gh pr create/edit call, not a follow-up step
- Add CHANGELOG entry step that runs only after the PR exists and links back to it
- Add branch/base confirmation guard for natural-language (non-/open-pr) invocation
- Document the deliberate .claude/skills/ vs .agents/skills/ location choice inline

Planning
- Check off tasks.md sections 1-3 (scaffolding, instruction porting, dual invocation)
@brandonmarshal brandonmarshal added ai-ops:tools Tool/plugin manifests lang:md Markdown content/docs priority:normal Default priority for most issues. status:needs-review Awaiting code review labels Sep 10, 2026
@linear-code

linear-code Bot commented Sep 10, 2026

Copy link
Copy Markdown

LS-3223

@brandonmarshal brandonmarshal self-assigned this Sep 10, 2026
- Link the entry to PR #53, per this repo's per-PR changelog convention

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved moderate workflow and safety issues remain in the OpenSpec commands and open-pr skill.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds a version-controlled OpenSpec workflow and Claude Code open-pr skill for consistent, spec-driven PR creation.

Changes:

  • Adds /opsx:* commands and corresponding workflow skills.
  • Adds OpenSpec planning artefacts for open-pr.
  • Adds PR creation/update guidance, changelog integration, and local settings exclusions.
File summaries
File Description
openspec/changes/open-pr-skill/tasks.md Implementation and verification checklist
openspec/changes/open-pr-skill/specs/pr-creation/spec.md PR creation requirements
openspec/changes/open-pr-skill/proposal.md Change rationale and scope
openspec/changes/open-pr-skill/design.md Architectural decisions and trade-offs
openspec/changes/open-pr-skill/.openspec.yaml OpenSpec metadata
CHANGELOG.md Documents the new workflow and skill
.gitignore Excludes local Claude settings
.claude/skills/openspec-sync-specs/SKILL.md Specification synchronisation workflow
.claude/skills/openspec-propose/SKILL.md Proposal workflow
.claude/skills/openspec-explore/SKILL.md Exploration workflow
.claude/skills/openspec-archive-change/SKILL.md Archive workflow
.claude/skills/openspec-apply-change/SKILL.md Implementation workflow
.claude/skills/open-pr/SKILL.md PR creation and update workflow
.claude/commands/opsx/sync.md Sync command
.claude/commands/opsx/propose.md Propose command
.claude/commands/opsx/explore.md Explore command
.claude/commands/opsx/archive.md Archive command
.claude/commands/opsx/apply.md Apply command
Review details

Suppressed comments (9)

.claude/commands/opsx/archive.md:65

  • The prompt includes Cancel as an option when specs are already synced, but this sentence says to proceed to archive regardless of the choice. A user who cancels can therefore still have the change moved into the archive. Handle Cancel as a stop and only continue for the two archive choices.
   If user chooses sync, use Task tool (subagent_type: "general-purpose", prompt: "Use Skill tool to invoke openspec-sync-specs for change '<name>'. Delta spec analysis: <include the analyzed delta spec summary>"). Proceed to archive regardless of choice.

.claude/commands/opsx/propose.md:19

  • This input contract accepts a free-form description, but the command then passes <name> straight to openspec new change without deriving a kebab-case name. A request such as add user authentication can therefore be rejected or create an invalid change name; add the derivation/ambiguity check here before step 2, as the paired skill already describes.
**Input**: The argument after `/opsx:propose` is the change name (kebab-case), OR a description of what the user wants to build.

.claude/skills/open-pr/SKILL.md:61

  • This condition checks only whether the repository requires a changelog, not whether this branch already contains the required PR-linked entry. Re-running the skill for an existing PR after the first invocation will append and push a duplicate entry; gate this step on the current branch lacking that entry.
If Step 2.6 found this repo requires a changelog entry, add it now — only after the PR exists, never before:

.claude/skills/open-pr/SKILL.md:63

  • On the existing-PR path, no gh pr create output exists, so this step cannot provide the URL/number needed for a required changelog link. Use the existing PR returned by gh pr list or gh pr view when updating instead.
1. Take the PR URL and/or number from the `gh pr create` output in the previous step.

.claude/skills/open-pr/SKILL.md:81

  • This absolute prohibition conflicts with the spec's no-fit-label scenario: when gh label list has no accurate label, the skill must proceed without --label; requiring it here forces the agent either to invent a label or abort. Make the label flag conditional while keeping --assignee mandatory, and update the identical wording in the earlier creation section.
- Don't run `gh pr create` without `--label` and `--assignee` already in that same command.

.claude/skills/open-pr/SKILL.md:34

  • gh label list has a default result limit, so this does not guarantee the “full current label set” required by the next step; this repository currently has 91 labels, and a valid match can be omitted before the agent chooses labels. Use an explicit high --limit (or paginate) here.
4. Check `gh label list` for the full current label set — never invent a label that doesn't exist in the repo.

.claude/skills/openspec-archive-change/SKILL.md:69

  • The prompt includes Cancel as an option when specs are already synced, but this sentence says to proceed to archive regardless of the choice. A user who cancels can therefore still have the change moved into the archive. Handle Cancel as a stop and only continue for the two archive choices.
   If user chooses sync, use Task tool (subagent_type: "general-purpose", prompt: "Use Skill tool to invoke openspec-sync-specs for change '<name>'. Delta spec analysis: <include the analyzed delta spec summary>"). Proceed to archive regardless of choice.

openspec/changes/open-pr-skill/proposal.md:3

  • The proposal describes OpenSpec as the required planning process for new skills, but the repository's canonical guidance (AGENTS.md) is not updated to require or even point contributors to this workflow. Without that documentation, future agents can still follow the old ad-hoc process. Add the rule to the contributor/agent guidance or scope this claim explicitly.
PR creation currently relies on a personal, machine-local slash command (`~/.claude/commands/open-pr.md`) that isn't shared with the team, isn't discoverable by other agent tools, and has already shown a real failure mode: agents running it have skipped the labels/assignee step because it lived as trailing sections after the main "create the PR" action instead of being structurally part of it. LS-3223 also establishes OpenSpec as the required planning process for new skills going forward, and this is the first skill being planned through it — both problems are solved by converting `open-pr` into a proper, repo-committed agent skill with a spec-reviewed design instead of a hand-written command file.

openspec/changes/open-pr-skill/tasks.md:19

  • The PR description says this PR was created through the natural-language path with the branch/base confirmation, which exercises task 4.2, but the OpenSpec task remains unchecked. Mark 4.2 complete if that verification claim is accurate, while leaving 4.1 pending unless the literal /open-pr path was also exercised.
- [ ] 4.2 Trigger the skill with a natural-language prompt (e.g. "create the PR for me") and confirm the branch/base confirmation guard fires before any `gh pr create` call.
  • Files reviewed: 17/18 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

- Dynamic instruction based on current state

**Handle states:**
- If `state: "blocked"` (missing artifacts): show message, suggest using `/opsx:continue`

Create a pull request for the current branch, following this repo's established conventions exactly. This skill only creates/updates a PR — it does not create branches, commit changes, or push to `develop`. Assume the branch and its commits already exist.

**Invocation guard**: if this skill was triggered by a natural-language request (e.g. "create the PR for me") rather than the explicit `/open-pr` command, confirm the target branch and base with the user before running `gh pr create`. Skip this confirmation when invoked via the literal `/open-pr` command.
- Dynamic instruction based on current state

**Handle states:**
- If `state: "blocked"` (missing artifacts): show message, suggest using openspec-continue-change
- *Alternative considered*: `.agents/skills/open-pr/` for consistency with the repo's stated skill convention. Rejected because it would silently break native `/open-pr` slash-command registration and auto-invocation, the two explicit requirements driving this work.

**2. Auto-invocation: omit `disable-model-invocation`, but add an explicit confirmation guard for implicit triggers.**
The user wants both explicit (`/open-pr`) and natural-language invocation to work. Claude Code's own best practice recommends `disable-model-invocation: true` for side-effect operations, but that would block natural-language triggering entirely, which is a stated requirement here. Decision: leave auto-invocation enabled, and add an instruction in the skill body requiring the agent to confirm target branch and base with the user before running `gh pr create` when the skill was triggered implicitly (i.e., not via the literal `/open-pr` command) — for `gh pr edit` are more common on updates. This preserves today's "just run it" convenience for the explicit command while adding a safety check only for the ambiguous-trigger path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-ops:tools Tool/plugin manifests lang:md Markdown content/docs priority:normal Default priority for most issues. status:needs-review Awaiting code review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants