---
description: Release batching, gitignore policy, and pre-tag checks
alwaysApply: true
---

# Release discipline

## One feature, one release

- **One user-facing feature → one minor.** Stack review fixes (tz, dates, guards) into the **same PR** before merge when they belong to the same feature.
- Do **not** tag npm until CI is green **and** `pnpm release:qa` passes (tripwires at the end must be 0 failed).
- Before tagging: `git diff main` must not include accidental private paths (`docs/`, `CLAUDE.local.md`, `.env`).

## Commit attribution

Every commit produced with an AI agent: follow **`AGENTS.md` § Commit attribution** — trailer names the agent **and** model in use (e.g. `Co-Authored-By: Cursor (Composer 2.5) <cursoragent@cursor.com>`).

## Public vs private docs

**Tracked (public engineering guides):** `AGENTS.md`, `CLAUDE.md`, `.cursor/rules/`, README, MCP tool descriptions.

**Gitignored (maintainer-local):** `docs/` (e.g. `docs/AGENTS.internal.md` notebook), `CLAUDE.local.md`.

- Engineering process → update the **public** guides above.
- Candid history, strategy, or release post-mortems → `docs/` notebook only.
- **Never** add `!docs/…` exceptions to `.gitignore` without explicit maintainer approval.

## Bracket / live-formatting ship checklist

Before merge **or** release of bracket or kickoff-formatting work:

1. Adversarial tests: 0 games, mid-tournament (2/3 played), degraded standings.
2. **Surface parity:** CLI `bracket` + MCP `get_bracket` + `share bracket` all pass `tz` and show calendar dates on multi-week knockouts.
3. **Statusline knockouts (if touched):** indirect-resolve via cached `getKnockoutFixtures` — hot path fail-closed (no 🏳️ on countdown or `live · syncing…`); empty-cache short TTL; `knockout-surface-coverage.test.ts` + `statusline.test.ts` / `refresh.test.ts` green. See `.cursor/rules/surface-parity.mdc`.
4. After `pnpm -r build`, run **`pnpm release:qa`** and eyeball the rendered sections; keep `packages/mcp/test/tools.test.ts` green for MCP arg threading.
