| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 0 | 7 | 2 | 0% |
| Commands | 0 | 3 | 4 | 0% |
| Section tags | 1 | 4 | 2 | 14% |
What each file covers
Sections
0 shared · 7 only in A · 2 only in B- − Bundle & bracket PR readiness
- − Bundled schedule invariant
- − Knockout resolution
- − Topology indexing
- − Live hybrid paths
- − Pre-merge QA
- − Adversarial tests (add when touching bracket/schedule)
- + CLAUDE.md
- + Claude Code specifics
Commands
0 shared · 3 only in A · 4 only in B- − pnpm -r build && pnpm -r typecheck && pnpm -r test && pnpm lint
- − pnpm -r build
- − pnpm release:qa
- + pnpm -F @claudinho/mcp build
- + pnpm -r typecheck
- + pnpm lint
- + gh run watch <id> --exit-status
Section tags
1 shared · 4 only in A · 2 only in B- − build
- − test
- − testing-strategy
- − git-pr
- + lint-format
- + agent-behaviour
- performance
Line diff
arturogarrido/claudinho · .cursor/rules/bundle-bracket-pr.mdc
@@ −1 @@
1---
2description: Bundle, bracket, and live-data invariants before opening a PR
3globs: packages/core/**/*
4alwaysApply: false
5---
6
7# Bundle & bracket PR readiness
8
9Before marking a data-heavy feature merge-ready, run **`pnpm -r build && pnpm -r typecheck && pnpm -r test && pnpm lint`** (mirror CI — build first because cli/mcp import `@claudinho/core` from dist; `build` alone does not typecheck).
10
11## Bundled schedule invariant
12
13`schedule.*.json` is a **resultless skeleton**: no scores/status, no confirmed nations in knockout slots.
14
15- `sanitizeBundledFixture` must restore topology placeholders for KO home/away.
16- `gen:schedule` must **fail** if any knockout fixture carries a real nation flag.
17- Test degraded `getBracket()` on the bundle: seed/winner slots stay `tbd`, never `confirmed`.
18
19## Knockout resolution
20
21- Advance winners from **score OR `winnerCode`** (ESPN `competitor.winner` for penalties).
22- Always test FT draw + `winnerCode` — routine in knockouts.
23- Group slots project from live standings once **≥1 match played** (`hasGroupStarted`); **`confirmed`** when every team has played a full round-robin (`played >= n - 1` for `n` teams); **`(proj.)`** only mid-group. TBD at 0 games or when standings are degraded.
24
25## Topology indexing
26
27- Bracket node index must match ESPN winner refs (e.g. "Round of 32 3 Winner"), not kickoff sort order.
28- If live post-round data is unavailable, add a **guard test** against bundled `matchId` ↔ index and document the assumption.
29- **Spot-check when R32 starts (2026-06-28):** confirm ESPN's "Round of 32 N Winner" refs align with ascending event id.
30
31## Live hybrid paths
32
33- When knockout fetch fails but standings succeed: set `source` from standings provider.
34- Share/MCP: inner `formatBracketList({ footer: false })`, outer layer adds attribution/notices **once**.
35- CLI/MCP wrappers: option types must match the formatter (`ShareBracketOptions`, not `ShareSnippetOptions`).
36- **Surface parity:** see `.cursor/rules/surface-parity.mdc` — every bracket formatter path passes `tz` + `locale`; statusline knockouts indirect-resolve via cached `getKnockoutFixtures` (hot path fail-closed).
37
38## Pre-merge QA
39
40After `pnpm -r build`, run **`pnpm release:qa`** (`scripts/release-qa.sh`). Eyeball every section; tripwires at the end encode the 0.8.x bracket regressions (calendar month, tz threading, share disclaimer).
41
42## Adversarial tests (add when touching bracket/schedule)
43
44| Scenario | Assert |
45|----------|--------|
46| FT level + `winnerCode` | Winner advances |
47| `fetchWindow` throws, standings OK | Projected groups + `source` set |
48| Bundle-only bracket | No real flags in R32+ slots |
49| Group at 0 games played | Slots stay `tbd`, no `(proj.)` |
50| Group at 2/3 played, standings live | Leaders show flags + `(proj.)` |
51| Group fully played (round-robin complete) | Winner + runner-up `confirmed`, no `(proj.)` |
52| `toolGetBracket` `tz: UTC` vs `America/Mexico_City` | Calendar date/time differs on cross-midnight kickoff |
53| Knockout kickoffs span >1 week | Output includes month + day (not weekday-only) |
54| `formatShareBracket` social + compact | Same date format as CLI list |
55| `formatShareBracket` / `toolGetBracket` | Each disclaimer line once |
56| Statusline knockout countdown (cached fixtures) | Real nations or `⚽ —`; never `🏳️` |
57| Statusline stale cache during live KO | `live · syncing…` without `🏳️`; resolved pairing when cache has it |
58| Empty fixtures cache at phase boundary | Re-polls after short TTL (~60s), not 15min |
59
arturogarrido/claudinho · CLAUDE.md
@@ +1 @@
1# CLAUDE.md
2
3This project uses **AGENTS.md** as the primary agent guide. Read it first:
4
5@AGENTS.md
6
7## Claude Code specifics
8
9- The statusline command must return in **<150ms** and **never** hit the network on the hot path — read from the local micro-cache.
10- Local MCP dev loop:
11 ```bash
12 pnpm -F @claudinho/mcp build
13 claude mcp add claudinho-dev -- node packages/mcp/dist/index.js
14 ```
15- When changing shared types, update `@claudinho/core` and run `pnpm -r typecheck` before committing.
16- Run `pnpm lint` (Biome) before committing; CI gates on it. The setup is lint-only (no formatter) — keep style consistent with the surrounding code.
17- **Before declaring any change "done," run the "Pre-PR self-review" rubric in `AGENTS.md`** — verify external API shapes against a *real* response (fixtures included); apply the change to every surface (CLI text **and** `--json`, MCP `data` **and** text, READMEs); audit against the Hard Constraints (existing code too); do an adversarial failure-mode pass (fail-closed; never cache transient errors); and bound default-on latency. For money/legal/external-API changes, do an independent reviewer pass and self-classify findings **P1/P2/P3**.
18- **After any push to a branch with CI, always watch the run and confirm it's green** (`gh run watch <id> --exit-status`); report the per-job result. Don't consider a push "done" until CI passes.
19
@@ −1 +1 @@
1−---
2−description: Bundle, bracket, and live-data invariants before opening a PR
3−globs: packages/core/**/*
4−alwaysApply: false
5−---
1+# CLAUDE.md
62
7−# Bundle & bracket PR readiness
3+This project uses **AGENTS.md** as the primary agent guide. Read it first:
84
9−Before marking a data-heavy feature merge-ready, run **`pnpm -r build && pnpm -r typecheck && pnpm -r test && pnpm lint`** (mirror CI — build first because cli/mcp import `@claudinho/core` from dist; `build` alone does not typecheck).
5+@AGENTS.md
106
11−## Bundled schedule invariant
7+## Claude Code specifics
128
13−`schedule.*.json` is a **resultless skeleton**: no scores/status, no confirmed nations in knockout slots.
14−
15−- `sanitizeBundledFixture` must restore topology placeholders for KO home/away.
16−- `gen:schedule` must **fail** if any knockout fixture carries a real nation flag.
17−- Test degraded `getBracket()` on the bundle: seed/winner slots stay `tbd`, never `confirmed`.
18−
19−## Knockout resolution
20−
21−- Advance winners from **score OR `winnerCode`** (ESPN `competitor.winner` for penalties).
22−- Always test FT draw + `winnerCode` — routine in knockouts.
23−- Group slots project from live standings once **≥1 match played** (`hasGroupStarted`); **`confirmed`** when every team has played a full round-robin (`played >= n - 1` for `n` teams); **`(proj.)`** only mid-group. TBD at 0 games or when standings are degraded.
24−
25−## Topology indexing
26−
27−- Bracket node index must match ESPN winner refs (e.g. "Round of 32 3 Winner"), not kickoff sort order.
28−- If live post-round data is unavailable, add a **guard test** against bundled `matchId` ↔ index and document the assumption.
29−- **Spot-check when R32 starts (2026-06-28):** confirm ESPN's "Round of 32 N Winner" refs align with ascending event id.
30−
31−## Live hybrid paths
32−
33−- When knockout fetch fails but standings succeed: set `source` from standings provider.
34−- Share/MCP: inner `formatBracketList({ footer: false })`, outer layer adds attribution/notices **once**.
35−- CLI/MCP wrappers: option types must match the formatter (`ShareBracketOptions`, not `ShareSnippetOptions`).
36−- **Surface parity:** see `.cursor/rules/surface-parity.mdc` — every bracket formatter path passes `tz` + `locale`; statusline knockouts indirect-resolve via cached `getKnockoutFixtures` (hot path fail-closed).
37−
38−## Pre-merge QA
39−
40−After `pnpm -r build`, run **`pnpm release:qa`** (`scripts/release-qa.sh`). Eyeball every section; tripwires at the end encode the 0.8.x bracket regressions (calendar month, tz threading, share disclaimer).
41−
42−## Adversarial tests (add when touching bracket/schedule)
43−
44−| Scenario | Assert |
45−|----------|--------|
46−| FT level + `winnerCode` | Winner advances |
47−| `fetchWindow` throws, standings OK | Projected groups + `source` set |
48−| Bundle-only bracket | No real flags in R32+ slots |
49−| Group at 0 games played | Slots stay `tbd`, no `(proj.)` |
50−| Group at 2/3 played, standings live | Leaders show flags + `(proj.)` |
51−| Group fully played (round-robin complete) | Winner + runner-up `confirmed`, no `(proj.)` |
52−| `toolGetBracket` `tz: UTC` vs `America/Mexico_City` | Calendar date/time differs on cross-midnight kickoff |
53−| Knockout kickoffs span >1 week | Output includes month + day (not weekday-only) |
54−| `formatShareBracket` social + compact | Same date format as CLI list |
55−| `formatShareBracket` / `toolGetBracket` | Each disclaimer line once |
56−| Statusline knockout countdown (cached fixtures) | Real nations or `⚽ —`; never `🏳️` |
57−| Statusline stale cache during live KO | `live · syncing…` without `🏳️`; resolved pairing when cache has it |
58−| Empty fixtures cache at phase boundary | Re-polls after short TTL (~60s), not 15min |
9+- The statusline command must return in **<150ms** and **never** hit the network on the hot path — read from the local micro-cache.
10+- Local MCP dev loop:
11+ ```bash
12+ pnpm -F @claudinho/mcp build
13+ claude mcp add claudinho-dev -- node packages/mcp/dist/index.js
14+ ```
15+- When changing shared types, update `@claudinho/core` and run `pnpm -r typecheck` before committing.
16+- Run `pnpm lint` (Biome) before committing; CI gates on it. The setup is lint-only (no formatter) — keep style consistent with the surrounding code.
17+- **Before declaring any change "done," run the "Pre-PR self-review" rubric in `AGENTS.md`** — verify external API shapes against a *real* response (fixtures included); apply the change to every surface (CLI text **and** `--json`, MCP `data` **and** text, READMEs); audit against the Hard Constraints (existing code too); do an adversarial failure-mode pass (fail-closed; never cache transient errors); and bound default-on latency. For money/legal/external-API changes, do an independent reviewer pass and self-classify findings **P1/P2/P3**.
18+- **After any push to a branch with CI, always watch the run and confirm it's green** (`gh run watch <id> --exit-status`); report the per-job result. Don't consider a push "done" until CI passes.
5919
