Two CI-layer fixes found during the v3.25.0 review. Same layer, both small, so
they land together (Iron Rule 11).
#198 — alignment.yml did not run on a models.json-only PR.
The `paths:` filter listed server.mjs / setup.mjs / scripts / lib / ocp /
ocp-connect, but not models.json. That made CLAUDE.md hard-requirement #2 ("CI
blacklist pass") vacuous for exactly the PRs that change model routing:
confirmed on #192, where only gitleaks and test-features ran.
models.json is not inert data. It drives MODEL_MAP and VALID_MODELS, the
default request model, and — since ADR 0009 — the global MAX_PROMPT_CHARS
truncation budget. A models.json-only PR can therefore change server.mjs's
runtime behavior with the guardrail never running. models.schema.json is
included for the same reason one level up: loosening the schema is what would
let a malformed models.json through.
Adding paths only widens coverage; the blacklist grep still scans server.mjs,
so this costs nothing and closes the gap. Per CLAUDE.md this is a PR amendment
to alignment.yml, which is the sanctioned way to change it (removing entries
would need an ALIGNMENT.md amendment; nothing is removed here).
#202 — release.yml's no-CHANGELOG fallback would have failed the release job.
The branch wrote an output named `notes` and exited WITHOUT creating
/tmp/release-notes.md, while the create step hard-codes
`--notes-file /tmp/release-notes.md`. So the one path that exists to "degrade
to minimal notes" instead produced a failed release.
Verified both directions by extracting the step's actual script from the YAML
and running it, rather than reading it:
PRE-FIX, no CHANGELOG -> exit 0, GITHUB_OUTPUT="notes=Release v3.25.0",
/tmp/release-notes.md MISSING
-> gh release create --notes-file WOULD FAIL
POST-FIX, no CHANGELOG -> exit 0, notes_file set, file present ("Release v3.25.0")
POST-FIX, with CHANGELOG -> file present, first line "## v3.25.0 — 2026-07-27"
Fixed by writing the file in that branch, and by removing the hard-coded-path
coupling entirely: both branches now set `notes_file` and the create step
consumes `steps.notes.outputs.notes_file`. That output existed already and was
never read — the two only agreed by accident.
Also added `set -euo pipefail` (the step previously ran unset-tolerant) and an
echo of the resolved notes before creating the release, so a wrong-looking body
is visible in the job log instead of only on the published release.
NOT changed: the empty-extraction guard. My issue text suggested adding one,
but `if [ ! -s "$NOTES" ]` was already there and already handles a heading
mismatch. Correcting that claim on #202 rather than taking credit for it.
Both workflows re-validated as YAML.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017gbqUZ8HfBZpjjbzQ85oH8
Implements cc-rules v1.4's 第五律 5.5 project overlay requirement.
- CLAUDE.md: declare release_kit: YAML block (version_source,
changelog, release_channel, docs_source, resource_lists,
new_feature_doc_expectations, bootstrap_quirk_policy)
- .github/PULL_REQUEST_TEMPLATE.md: add 5.3 user-visible-change
self-check section with reviewer gate instruction
- .github/workflows/release.yml (NEW): auto-create GitHub Release
from CHANGELOG.md section on v* tag push. Idempotent (checks if
release already exists). Closes the gap that caused v3.9.0 /
v3.10.0 / v3.11.0 to each miss their GH Release.
Governance-only change. No code, no user-visible behavior change
(the workflow only fires on future tags). No README update needed.
Co-authored-by: Tao Deng <dtzp555@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>