fix(ci): skip the OpenSpec archive gate on draft PRs - #84
Conversation
A spec-only proposal is its own tip until its implementation is stacked on top, so the gate demanded it archive a change nobody had built yet. #70, #71, and #72 have failed this check on every run since July 28 for exactly that reason — weeks of red on PRs that were never merge-eligible, which is how a team learns to stop reading red. A draft cannot merge, so skipping it costs nothing: no unarchived change can reach `main` either way. `ready_for_review` is added to the trigger types because the default set (opened/synchronize/reopened) does not include it — without that, a draft could be marked ready and merged on a green that was never re-evaluated. That event is what preserves the guarantee. The tip rule is unchanged for PRs that are ready for review.
There was a problem hiding this comment.
Pull request overview
Adjusts the OpenSpec archive gate workflow so draft PRs don’t get stuck in a permanently failing “tip must be archived” state before any implementation exists, while still ensuring the gate re-evaluates when a PR becomes ready for review.
Changes:
- Skip the
stack: openspec-archivedjob whenpull_request.draft == true. - Add
ready_for_reviewto the workflow’spull_requestevent types so the gate re-runs when a draft is marked ready. - Document the draft-skip behavior in the iterate-pr skill guidance.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| .github/workflows/pr-check-openspec.yml | Skips the archive gate job on drafts and adds ready_for_review to the trigger types. |
| .agents/skills/iterate-pr/SKILL.md | Updates operator guidance to explain the archive check’s draft behavior. |
The archive job's condition depends on draft state, so both draft transitions have to be trigger events. `ready_for_review` was already there because it protects the guarantee. `converted_to_draft` is the other half: without it a PR that failed the gate while ready keeps that failure after being converted back to draft, until some unrelated push re-runs it — a stale red on a PR that is no longer merge-eligible, which is the state this workflow change exists to remove. Found in review by Copilot on #84.
The one finding was right and is fixed: All three legs are verified against real runs on this PR:
— AI Coding Agent |
The archive gate demands that the tip of a stack archive its OpenSpec change. A spec-only proposal PR is its own tip — nothing is stacked on it until its implementation exists — so the gate asked it to archive a change nobody had built yet.
That is why #70, #71, and #72 have failed this check on every run since July 28. None of them was ever merge-eligible; the red was permanent, unactionable, and exactly the kind that teaches people to stop reading check status.
The stack mechanism itself is fine and needs no change: once an implementation PR is stacked on a proposal, the proposal has a child, the gate skips it, and the tip archives.
partition-rules-by-enginedid precisely that. The gap is only the window before the implementation exists.Drafts are now skipped. A draft cannot merge, so the guarantee — no unarchived change reaches
main— is untouched.The load-bearing detail is the trigger.
on: pull_requestwith notypes:defaults toopened,synchronize,reopened, and notready_for_review. Skipping drafts without adding that event would let a draft be marked ready and merged on a green that was never re-evaluated, which would convert a noisy check into a silently wrong one.ready_for_reviewis added for that reason.Net effect: a proposal PR stays green while it is a draft, and the moment it is marked ready the full tip rule applies — mark it ready once its implementation is stacked beneath it.