Let a pure-docs PR skip the draft, and stop [skip ci] stranding one #11

Merged
geusebio merged 1 commit from docs/pure-docs-prs-skip-draft into main 2026-08-07 10:37:50 +00:00
Owner

Two rules in VCS.md combined into a deadlock, and neither was wrong on its own:

  1. Skipping CI on docs-only commits — tag them [skip ci].
  2. Work in progress — a branch is WIP until CI is green on the pushed commit.

Together: a docs-only PR has no run, so it can never be green, so it can never leave draft.
Hit for real on someones.computer#350,
which is a 25-line docs/database.md change that cannot be marked ready under the rules as
they stand.

Untangled from both ends

[skip ci] is for a push with no PR open. On a PR, let CI run. Where the pipeline
classifies the diff and gates its expensive jobs on the verdict — which
someones.computer's ci.yml does, via a changes job every costly step reads — a
docs-only run has already collapsed to the Markdown lint. Skipping it saves seconds and buys
a PR nobody can merge, because pending checks are not passing ones.

A pull request whose diff is documentation and nothing else opens ready, not draft. Draft
exists to advertise that something is still unknown: a check that hasn't run, or ran red.
A docs change has nothing unknown about it — the entire gate is runnable locally before you
push, and CI's docs-only path runs that same lint and nothing else. A WIP: prefix there
means only "this is finished but the title says otherwise", and on a squash-merge repo it is
one forgotten edit away from becoming the permanent commit subject.

Opening ready costs no extra pipeline: docs_only gates the expensive jobs off already,
exactly as draft would have.

Also recorded

A submodule bump is code, however prose-only the change inside it is — the parent sees a
gitlink, not a *.md path, and a pointer can carry anything. So a change to these standards
lands as two PRs. This is the first of that pair; the consuming repo's pointer bump is the
second, and it correctly does not qualify for the exemption this PR adds.

On the shared-standard coupling

The docs-only classifier is introduced as this estate's implementation rather than as a
required path, and the rule (*.md, *.markdown, docs/**, everything else is code) is
stated so a repo without the script can still apply it — with false as the safe answer for
anything uncertain.

That is a deliberate departure from how the rest of VCS.md is written: it hardcodes
composer test:coverage, bin/coverage-gate.php, bin/lint-markdown.sh and the Symfony
console lints as though every consumer has them, which contradicts README.md's own
Requirements on the consuming project. Filed as #10 rather than fixed here, to keep this PR
to one change.

Verification

markdownlint clean on the changed file, apart from a pre-existing MD040 at line 82 (a
bare fence in the commit-message examples) that is present on main and untouched here.
Every anchor introduced or renamed was checked to resolve, and no other file in the estate
referenced the old #skipping-ci-on-docs-only-commits anchor.

This PR is itself pure docs and is therefore not a draft — which is the rule it adds.

Two rules in `VCS.md` combined into a deadlock, and neither was wrong on its own: 1. *Skipping CI on docs-only commits* — tag them `[skip ci]`. 2. *Work in progress* — a branch is WIP until CI is green **on the pushed commit**. Together: a docs-only PR has no run, so it can never be green, so it can never leave draft. Hit for real on [someones.computer#350](https://git.grey.ooo/Grey.ooo/Someones.Computer/pulls/350), which is a 25-line `docs/database.md` change that cannot be marked ready under the rules as they stand. ## Untangled from both ends **`[skip ci]` is for a push with no PR open.** On a PR, let CI run. Where the pipeline classifies the diff and gates its expensive jobs on the verdict — which `someones.computer`'s `ci.yml` does, via a `changes` job every costly step reads — a docs-only run has already collapsed to the Markdown lint. Skipping it saves seconds and buys a PR nobody can merge, because pending checks are not passing ones. **A pull request whose diff is documentation and nothing else opens ready, not draft.** Draft exists to advertise that something is still *unknown*: a check that hasn't run, or ran red. A docs change has nothing unknown about it — the entire gate is runnable locally before you push, and CI's docs-only path runs that same lint and nothing else. A `WIP:` prefix there means only "this is finished but the title says otherwise", and on a squash-merge repo it is one forgotten edit away from becoming the permanent commit subject. Opening ready costs no extra pipeline: `docs_only` gates the expensive jobs off already, exactly as `draft` would have. ## Also recorded **A submodule bump is code**, however prose-only the change inside it is — the parent sees a gitlink, not a `*.md` path, and a pointer can carry anything. So a change to these standards lands as two PRs. **This is the first of that pair**; the consuming repo's pointer bump is the second, and it correctly does *not* qualify for the exemption this PR adds. ## On the shared-standard coupling The docs-only classifier is introduced as *this estate's implementation* rather than as a required path, and the rule (`*.md`, `*.markdown`, `docs/**`, everything else is code) is stated so a repo without the script can still apply it — with `false` as the safe answer for anything uncertain. That is a deliberate departure from how the rest of `VCS.md` is written: it hardcodes `composer test:coverage`, `bin/coverage-gate.php`, `bin/lint-markdown.sh` and the Symfony console lints as though every consumer has them, which contradicts `README.md`'s own *Requirements on the consuming project*. Filed as #10 rather than fixed here, to keep this PR to one change. ## Verification `markdownlint` clean on the changed file, apart from a pre-existing `MD040` at line 82 (a bare fence in the commit-message examples) that is present on `main` and untouched here. Every anchor introduced or renamed was checked to resolve, and no other file in the estate referenced the old `#skipping-ci-on-docs-only-commits` anchor. **This PR is itself pure docs and is therefore not a draft** — which is the rule it adds.
Two rules here combined into a deadlock. "Tag docs-only commits [skip ci]" and
"a branch is WIP until CI is green on the pushed commit" are individually
sensible; together they mean a docs-only PR has no run, can never be green, and
can never leave draft. Hit for real on someones.computer#350.

Untangled from both ends:

- [skip ci] is for a push with no PR open. On a PR, let CI run — where a
  pipeline classifies the diff and gates its expensive jobs on the verdict, a
  docs-only run is already just the Markdown lint, so skipping saves seconds and
  costs a green check.
- A PR whose diff is documentation and nothing else opens ready, not draft.
  Draft advertises that something is unknown; for a docs change the whole gate is
  runnable locally before pushing, so there is nothing left to find out and
  nothing for a WIP: prefix to warn about.

Also records that a submodule bump is code however prose-only its contents, so a
change to these standards is two PRs — this one, and the pointer bump in the
consuming repo, which does not qualify.

The docs-only classifier is introduced as this estate's implementation rather
than as a required path, and the rule is stated so a repo without one can still
apply it. The rest of VCS.md still hardcodes commands that way; #10 tracks it.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Grey.ooo/agent-standards!11
No description provided.