### Changelog entries and the conformance workflow's lists move into files a change adds

- **Changelog entries, one a file.** A change adds its entry as a file of `changes/`
  (`<yyyy-mm-dd>-<slug>.md`, holding the entry exactly as the changelog does) and leaves the
  head of the changelog alone. `scripts/changelog-assemble.py --write` puts the files at the
  head of `## Unreleased` for a release, newest date first and by name within a date, and
  removes them. `wai breaking` reads the lines a change adds to them as it reads the lines it
  adds to the changelog. The repository checks fail a pull request that changes anything
  under `wai/` and adds or edits no entry file directly in `changes/` (a release, which
  renders the files and removes them, passes), or one whose entry is malformed or in a
  subdirectory, and fail rather than pass when they cannot compare the change with its base.
  A pull request opened before the check reached main passes as it is; one opened since that
  adds its entry to the head of the changelog fails, saying to add the file. The check reads
  when it reached main from the base's first-parent history: the first commit there whose
  tree holds it, which is the merge that brought it in. The trailer line `Changelog: none`,
  exactly, in the trailer block of a commit message, says a change has nothing to record.
  `changes/README.md` states the form.
- **CI: the lists `wai-conformance.yml` kept by hand are derived when it runs.** Each step of
  the independent verifiers is a file of `.github/wai-conformance/verifiers/` (its body, and
  a header naming its features, binaries, paths and order), each cargo-class corpus a file of
  `.github/wai-conformance/corpora/`, and each test of the fast integer kernels' steps names
  them in its own file (`// wai-conformance: int-kernels`). `scripts/wai-conformance-lists.py`
  derives from them `WAI_FEATURES`, `WAI_PQ_FEATURES` and `WAI_RELEASE_FEATURES`, the
  binaries and tests the verifiers' job builds first and the steps it runs, the feature lists
  `features-alone` checks, the integer kernels' tests and features, and the corpora and their
  features. A new verifier, corpus or kernel test adds a file, or a line to its own file, and
  edits no line of the workflow, unless a step's `# paths:` names a file under none of the
  trigger's paths. Its features and `[[test]]` entries in `wai-rs/Cargo.toml` stay shared.
- **CI: every job runs what it ran.** `.github/wai-conformance/baseline.json` holds the hand
  lists the files replaced. `scripts/wai-conformance-lists.py selftest --exact` requires each
  derived list to equal its hand list, and each step's body and directory to be those of the
  hand list's step of its name, in the same order; the repository checks run `selftest`,
  which fails a change that drops an entry of them, and a self-test that takes a step, a
  feature, a tag and a corpus away in turn and requires each to fail. `dry-run` prints every
  list and step in a stable form, of the tree or of a commit (`--ref`), with the command
  lines of the integer kernels' steps, the corpus step, `int-kernels-amd` and the
  features-alone loop, so a review compares two of them by diff alone.
- **CI: the gate reads the steps' paths.** The workflow starts on any extension text
  (`wai/extensions/**`), and its `relevant` job runs the jobs only for the paths the workflow
  lists and the ones the steps' files name, which it reads through
  `scripts/pr-touches-paths.py --paths-from <dir> --wide <glob>`, so a new step brings the
  extension text it reads in its own file. For every file outside the two paths this adds to
  the gate (`.github/wai-conformance/**` and `scripts/wai-conformance-lists.py`), the gate
  answers as it did.
- `wai mcp`'s conformance tools read the verifier commands from the steps' files, and
  `scripts/check-tests-in-ci.py` counts a test as run when a step's file names it or a step
  takes a tag it carries.
