Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,19 @@ jobs:
run: go run github.com/zricethezav/gitleaks/v8@v8.30.1 detect --source . --no-banner --redact --log-opts="HEAD"
- name: sanitization check (D-002, REQ-E7-S05-01)
run: bash hack/check-sanitization.sh
# REDMAIN-N1 / D-168 (REQ-REDMAIN-N1-02) — commit subjects must not lead with
# a LITERAL emoji: cliff.toml's parsers key on the ASCII gitmoji shortcode, so
# such a subject matches none of them and is published under "### Other" on the
# Release page (the REL-14/D-137 defect through another door). Deliberately NOT
# guarded off pull_request, unlike the changelog drift gate below (D-125/OQ-30):
# a PR is the LAST moment the subject can still be reworded, because hard rule 2
# forbids rewriting it once it is on main. Needs the full history the gitleaks
# comment above already requires (fetch-depth: 0); no argument — the argument
# form is the sandbox mode that skips the published-history exemption checks.
# Also runs locally in `task check` via hack/release/changelog_gate_test.sh §9,
# which is where both of its polarities are proved.
- name: commit subject gate (REDMAIN-N1 — no literal emoji, D-168)
run: bash hack/release/commit_subject_gate.sh
- run: go test -race ./...
# E7-S04 — determinism gate (P4-E1-S12): double-run named engine + conformance goldens.
# Keep this block distinct — E7-S05 adds sanitization steps below/after.
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ repository still gets a decision, never by following the link; no release carrie
- :memo: docs(backlog): track the D-154 guard-idiom S7688 residual as SONAR-SHELL-R01
- :memo: docs(decisions): correct SONAR-SHELL to 54 of 54 and withdraw two overstated figures (D-171)
- :memo: docs(decisions): repoint D-166 at the shifted E11 backlog lines (:594->:602, :613->:621)
- :memo: specs(redmain): the literal-emoji commit subject defect, both halves (REDMAIN-N1/N2)
- :memo: docs(decisions): D-168 records the REDMAIN-N1/N2 fix, its narrowness and its hand-off
- :memo: specs(redmain): N2-02 states the decoupled retire path; add N1-04 for the allowlist pin
- :memo: docs(decisions): D-168 (d) is corrected — one authority was the wrong instinct here
- :memo: specs(redmain): N2-02 stops claiming coverage the script does not have; file REDMAIN-N4
- :memo: docs(decisions): D-168 (f) records the unexercised paths and points at REDMAIN-N4

### Features
- :sparkles: feat(audit): measure REL-03/REL-07 by real mutation run, not by name
Expand All @@ -164,6 +170,7 @@ repository still gets a decision, never by following the link; no release carrie
- :bug: fix(lint): a redirection is not a version guard — require an adjacent comparison
- :bug: fix(lint): the include check missed 'source', one of its two spellings
- :bug: fix(lint): drop the reversed-form guard pattern — it opened a fresh fail-open
- :bug: fix(release): decouple the two exemption lists so REDMAIN-N3 has a green state (D-168)

### Other
- 👷 ci(docs): stop uploading the Pages artifact on pull requests
Expand Down Expand Up @@ -196,6 +203,7 @@ repository still gets a decision, never by following the link; no release carrie
- :white_check_mark: test(ci): grade the shared PR-reach helper itself, on fixtures (D-157)
- :white_check_mark: test(lint): pin all eleven detection patterns, not the four the tree happens to use
- :white_check_mark: test(lint): give the non-probe absence assertions an anti-vacuity partner
- :white_check_mark: test(release): reject literal-emoji commit subjects, and let §8 see them (D-168)
## [0.3.0] - 2026-08-18

### Chores
Expand Down
1 change: 1 addition & 0 deletions docs/decisions/decisions.md

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions hack/release/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,41 @@ template emits **categorized subject lines only — no commit SHAs** (D-101, oss
| `task changelog-verify` | Fail closed if `CHANGELOG.md` drifts from `cliff.toml` output (release gate) |
| `bash hack/release/verify-changelog.sh` | Same check as `task changelog-verify` (script entry point) |
| `task release-changelog-gate-test` | AUD-S02: proves the drift gate is wired and fires — in `task check` (REQ-AUD-S02-01/02) |
| `bash hack/release/commit_subject_gate.sh` | REDMAIN-N1 / D-168: rejects a commit subject that leads with a **literal emoji** instead of the ASCII gitmoji shortcode |

### Commit subjects must lead with the ASCII shortcode (REDMAIN-N1 / D-168)

`cliff.toml`'s `commit_parsers` key on the ASCII gitmoji **shortcode**
(`:construction_worker:`), which is also what `GUIDELINES.md` § Repository discipline mandates.
A subject that leads with the **literal emoji** (`👷 ci(docs): …`) matches none of them and falls
through the `.*` catch-all into `### Other` on the published GitHub Release page — the REL-14 /
D-137 defect reached through a different door. `dfdae69` is the commit where human attention
failed; `commit_subject_gate.sh` is the replacement for that attention.

- The rule is narrow on purpose: **the first character of the subject must be ASCII.** It is not
"the subject matches the whole convention" — Dependabot's `build(deps): bump …` and GitHub's
`Merge pull request #N from …` carry no shortcode and are legitimate.
- Published history is tolerated **by full commit SHA** (`LEGACY_ALLOW_SHAS`), never by shape, and
each exempt SHA must still *be* a detection — a stale exemption reds the gate. The list's exact
content is pinned from a second file (`LEGACY_EXPECTED`, `changelog_gate_test.sh` §9d), so it
cannot grow through an unremarked append: adding an exemption is a two-file change plus a row in
`docs/decisions/decisions.md`.
- Reachable two ways: a step of `verify.yaml`'s `verify:` job (**not** guarded off
`pull_request`, so a PR reds while the subject can still be reworded) and, locally, `task check`
through `changelog_gate_test.sh` §9. No 22nd `task check` stage was added — `CHECK_STAGES` in
`hack/audit/exitgate_test.sh` asserts the Taskfile's `check:` list is *equal* to it.
- Both polarities and the exemption's load-bearingness are proved in `changelog_gate_test.sh`
§9/§9a–§9d; the matching `### Other` detector fix is §8/§8b.

**Two exemption lists, and they are not interchangeable.** `LEGACY_ALLOW_SHAS`
(`commit_subject_gate.sh`) answers *"is this commit's SUBJECT still a literal emoji?"* — permanent,
because hard rule 2 forbids rewriting the subject. `OTHER_EXEMPT_SHAS` (`changelog_gate_test.sh`
§8) answers *"is this commit's RENDERED ENTRY still mis-filed under `### Other`?"* — temporary,
because REDMAIN-N3 will teach `cliff.toml` to file it correctly. Deriving one from the other left
**no green state** after N3 (keep the entry, §8 reds as stale; drop it, the commit-subject gate
reds on `dfdae69`), so they are separate, linked only by the one-way invariant
`OTHER_EXEMPT_SHAS ⊆ LEGACY_ALLOW_SHAS` — which the empty set satisfies. **When N3 lands, delete
the SHA from `OTHER_EXEMPT_SHAS` and nothing else**; §8's failure message says exactly this.

Long-lived notes for consumers of released artifacts (currently the **D-120 `pins.toolDigest`**
warning) live in `cliff.toml`'s `[changelog] header`, not in `CHANGELOG.md`: the file is
Expand Down
Loading