chore(ci): consolidate the workflow directory - #125
Merged
Conversation
Eight workflow files to six, dropping two OpenSpec checks that produced more false positives than signal and demoting the changeset gate that stacks made unsatisfiable. - ci.yml -> validate.yml, name: CI -> Validate. The job was already `Validate`, which is the required status check on main, so branch protection is unchanged. - openspec-rot.yml and pr-check-openspec.yml are deleted. An unarchived change directory is the normal state of a pull request, so a PR-time gate had to infer stack position, and a nightly sweep had to date directories from git history to guess at intent. Both are replaced by one step in validate.yml that runs on push to main only and fails while main carries an unarchived change. A forward-merging stack leaves main red until its final slice archives the change; that red blocks nothing, since branch protection reads each PR's own Validate. - require-changeset.yml -> changeset.yml, warning instead of failing. It now diffs origin/main...<head>, so a changeset on the bottom branch counts for every PR above it and the stack question answers itself. The base-ref guard and the branches: filter are gone with it. `skip-changeset` survives only to silence the warning, which is what it had degenerated into anyway. claude-code-review-on-demand.yml and vale-binaries.yml are untouched. Docs follow the code: the CLAUDE.md stacking section, the iterate-pr skill's two structural-failure sections, and the infrastructure spec, which gains requirements for the main-only archive check and for the changeset check being advisory. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Consolidates and simplifies GitHub Actions workflows by renaming the primary CI workflow to match the required check name, removing PR-time OpenSpec archive gating in favor of a main-only cleanliness check, and converting the changeset requirement into a stack-aware advisory warning. Documentation is updated to reflect the new workflow model and stacked-PR guidance.
Changes:
- Rename
ci.yml→validate.yml(workflow file/name alignment) and add a push-to-main-only step that fails ifopenspec/changes/contains unarchived directories. - Replace the failing
require-changesetgate with a newchangeset.ymlworkflow that warns (and is stack-aware by diffing againstmain). - Remove the previous OpenSpec PR archive check and the nightly rot sweep; update docs/specs/skill guidance accordingly.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
openspec/specs/infrastructure/spec.md |
Updates CI/changeset requirements and documents the new main-only OpenSpec archive check behavior. |
CLAUDE.md |
Refreshes stacked-PR guidance to match the new archive + advisory changeset behavior. |
.github/workflows/validate.yml |
New primary Validate workflow; adds main-only unarchived OpenSpec change detection step. |
.github/workflows/changeset.yml |
New advisory, stack-aware changeset warning workflow. |
.github/workflows/ci.yml |
Removed in favor of validate.yml. |
.github/workflows/require-changeset.yml |
Removed in favor of advisory changeset.yml. |
.github/workflows/pr-check-openspec.yml |
Removed (PR-time OpenSpec archive gate eliminated). |
.github/workflows/openspec-rot.yml |
Removed (nightly rot sweep eliminated). |
.agents/skills/iterate-pr/SKILL.md |
Updates iterate-pr operational guidance to reflect the new CI checks model. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+143
to
+150
| ### Requirement: Validation workflow exists | ||
|
|
||
| A GitHub Actions workflow file SHALL exist at `.github/workflows/ci.yml`. | ||
| A GitHub Actions workflow file SHALL exist at `.github/workflows/validate.yml`, and its job SHALL be named `Validate` to match the required status check configured on `main`. | ||
|
|
||
| #### Scenario: Workflow file is present | ||
|
|
||
| - **WHEN** inspecting the repository | ||
| - **THEN** `.github/workflows/ci.yml` SHALL exist and be valid YAML | ||
| - **THEN** `.github/workflows/validate.yml` SHALL exist and be valid YAML |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Eight workflow files become six. Two OpenSpec checks are deleted outright, the changeset gate stops failing, and
ci.ymlgets a name that matches the check it publishes.ci.yml→validate.yml. File and workflow name only. The job is stillValidate, which is the required status check onmain, so branch protection needs no change.Both OpenSpec checks are replaced by one step on
main.pr-check-openspec.ymlandopenspec-rot.ymlare gone. Neither could ask its question cleanly: an unarchived change directory is the normal state of a pull request, since a change is archived exactly once on the last slice of the work — so the PR gate had to infer stack position to avoid firing on work still in flight, and the nightly sweep had to date directories from git history to guess whether a stack was abandoned. Both guessed, and a check that is expected-red across most of a stack is one people learn to route around.validate.ymlnow carries a step, gated on push events tomain, that fails whilemainholds anything underopenspec/changes/other thanarchive/. Onmainthe question has an unambiguous answer: once the work has landed, what is left is debris.The tradeoff worth reviewing: a stack that merges forward lands its change directory on
mainand archives it only on the final slice, somainruns red for as long as that stack is draining. That red blocks nothing — branch protection reads each PR's ownValidaterun, notmain's — and the alternative is the staleness heuristic this replaces. A stack that merges down keepsmainclean throughout. If you would rathermainnever sit red, that is the knob to turn, and it belongs in this PR rather than after it.require-changeset.yml→changeset.yml, advisory. It emits a warning and a step summary instead of failing, and it looks for a changeset added or modified anywhere betweenmainand the PR head rather than in the PR's own diff. That range covers every branch below in a stack, so one changeset on the bottom branch satisfies every PR above it and the stack question answers itself — no base-ref guard, nobranches:filter.skip-changesetsurvives only to silence the warning, which is what it had degenerated into: a way to clear a red check rather than a record that a change ships no release note.claude-code-review-on-demand.ymlandvale-binaries.ymlare untouched.Docs move with the code — the CLAUDE.md stacking section, the
iterate-prskill's two structural-failure sections, andopenspec/specs/infrastructure/spec.md, which gains requirements for the main-only archive check and for the changeset check being advisory. Thebranches:filter lesson is kept and re-anchored; it was true independently of the guard it was documenting.This change ships no release note, so it adds no changeset. Under the new workflow that produces a warning rather than a failure, which is the first thing it demonstrates.