RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Diff/arturogarrido-claudinho-cursor-rules-surface-parity ↔ arturogarrido-claudinho-claude

Comparison

A · Cursor rules · arturogarrido/claudinhoB · CLAUDE.md · arturogarrido/claudinho
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections0420%
Commands0040%
Section tags22140%

What each file covers

Sections

0 shared · 4 only in A · 2 only in B
  • − Surface parity (CLI / MCP / share)
  • − Knockout surfaces live-resolve — never read the skeleton (the #1 recurring bug)
  • − Format opts invariant
  • − Regression tests
  • + CLAUDE.md
  • + Claude Code specifics

Commands

0 shared · 0 only in A · 4 only in B
  • + pnpm -F @claudinho/mcp build
  • + pnpm -r typecheck
  • + pnpm lint
  • + gh run watch <id> --exit-status

Section tags

2 shared · 2 only in A · 1 only in B
  • − testing-strategy
  • − do-not
  • + agent-behaviour
  •   lint-format
  •   performance

Line diff

+14 added−56 removed5 unchanged8.2% identical
arturogarrido/claudinho · .cursor/rules/surface-parity.mdc
@@ −1 @@
1---
2description: CLI, MCP, and share must pass the same format opts (tz, locale, flags)
3globs: packages/{cli,mcp,core}/**/*
4alwaysApply: false
5---
6 
7# Surface parity (CLI / MCP / share)
8 
9Any user-visible formatter change must land on **all three surfaces** before merge:
10 
11| Surface | Verify |
12|---------|--------|
13| CLI | `packages/cli` command + `packages/cli/test/` |
14| MCP | `toolGet*` in `packages/mcp/src/tools.ts` + `packages/mcp/test/tools.test.ts` |
15| Share | `formatShare*` + `packages/mcp/test/share.test.ts` |
16 
17`scripts/release-qa.sh` exercises CLI + share rendering across locales and timezones; MCP arg threading is **not** rendered there — guard it with unit tests.
18 
19## Knockout surfaces live-resolve — never read the skeleton (the #1 recurring bug)
20 
21The bundled schedule's knockout slots are **resultless placeholders** (codes like `2A`/`2B`, flag `🏳️`). So a team-facing surface that reads the static bundle is **silently** blind to a confirmed knockout tie — no crash, no wrong data, just a stale placeholder. **Knockout live-resolve regressions** shipped repeatedly in different surfaces (root cause: skeleton reads, cache gaps, or both):
22 
23- v0.8.2 — R32 pre-draw seeds rendered static, didn't live-resolve.
24- v0.8.6 — bracket third-place slots never read the merged live `match.home/away`.
25- v0.8.7 — `next` / `share next` / MCP next-fixture resolvers read only the static bundle.
26- v0.8.8 — statusline next-match countdown read the static bundle (`🏳️ vs 🏳️` / `⚽ —` in knockouts).
27- v0.8.9 — empty fixtures cache stamped the full 15min TTL at phase boundaries; stale-cache `live · syncing…` still read the skeleton.
28 
29**Rule:** every team-facing surface must reach the live overlay (`getBracket` / `getNextFixtureForTeam` — the same `fetchWindow` the bracket uses), fail closed on outage, and attribute the provider only when the overlay served the chosen fixture. **Exception — statusline:** hot path cannot fetch; the cold-path refresher calls `getKnockoutFixtures` and caches to `CacheState.fixtures`; `renderPrompt` merges that slice over the bundle (countdown **and** `live · syncing…`), never leaking 🏳️. **Exception — MCP `fixtures://{date}` resource:** deliberately static ("Static fixture list"; a resource URI carries no tz and gets no live overlay) — do not "fix" it to live-resolve without a maintainer decision; agents use `get_today`/`get_bracket` for resolved pairings.
30 
31| Surface | Entry point | Must |
32|---------|-------------|------|
33| CLI `bracket` / `next` | `cmdBracket` / `cmdNext` | call `getBracket` / `getNextFixtureForTeam` |
34| CLI `share bracket` / `share next` | `cmdShare` | same |
35| MCP `get_bracket` / `get_next_fixture` | `toolGetBracket` / `toolGetNextFixture` | same |
36| MCP `get_share_snippet{bracket,next}` | `toolGetShareSnippet` | same |
37| **statusline** | `renderPrompt` + `runRefresh` | hot path, NO network — indirect: refresher caches `getKnockoutFixtures` → `CacheState.fixtures`; `renderPrompt` merges them, **failing closed to `⚽ —`** when the cache lacks the pairing; unresolved placeholders dropped in syncing (never 🏳️). Empty successful fetch uses a **short TTL** (~60s); provider errors keep prior cache. **`cmdPrompt` and `cmdHook`** both spawn fixtures refresh in knockout phase. |
38 
39**Executable guard:** `packages/{cli,mcp}/test/knockout-surface-coverage.test.ts` pins one fake resolved tie (Mexico vs Ecuador) and asserts every surface renders the real nations, not `🏳️` (statusline from a seeded cache). **`statusline.test.ts` / `refresh.test.ts`** cover syncing + empty-cache TTL. **Adding a team-facing surface? Add it to that test and this table.**
40 
41## Format opts invariant
42 
43If a core formatter accepts `tz`, `locale`, `flags`, or `date`, **every wrapper** passes them from `CliConfig` / `CommonOpts`.
44 
45```typescript
46// ❌ BAD — locale only; tz silently drops to server local
47formatBracketList(view, { footer: false, locale: args.lang });
48 
49// ✅ GOOD
50formatBracketList(view, { footer: false, locale: args.lang, tz: args.tz });
51// or reuse fmtOpts(args) where shapes align
52```
53 
54## Regression tests
55 
56When adding a format option (e.g. `date: true` on `formatKickoff`):
57 
58- Add a **core** unit test for the option.
59- Add an **MCP tool test** proving `tz` changes output (e.g. UTC vs `America/Mexico_City` on a cross-midnight kickoff).
60- Update share tests if `formatShareBracket` / compact lines are affected.
61 
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: CLI, MCP, and share must pass the same format opts (tz, locale, flags)
3−globs: packages/{cli,mcp,core}/**/*
4−alwaysApply: false
5−---
1+# CLAUDE.md
62  
7−# Surface parity (CLI / MCP / share)
3+This project uses **AGENTS.md** as the primary agent guide. Read it first:
84  
9−Any user-visible formatter change must land on **all three surfaces** before merge:
5+@AGENTS.md
106  
11−| Surface | Verify |
12−|---------|--------|
13−| CLI | `packages/cli` command + `packages/cli/test/` |
14−| MCP | `toolGet*` in `packages/mcp/src/tools.ts` + `packages/mcp/test/tools.test.ts` |
15−| Share | `formatShare*` + `packages/mcp/test/share.test.ts` |
7+## Claude Code specifics
168  
17−`scripts/release-qa.sh` exercises CLI + share rendering across locales and timezones; MCP arg threading is **not** rendered there — guard it with unit tests.
18− 
19−## Knockout surfaces live-resolve — never read the skeleton (the #1 recurring bug)
20− 
21−The bundled schedule's knockout slots are **resultless placeholders** (codes like `2A`/`2B`, flag `🏳️`). So a team-facing surface that reads the static bundle is **silently** blind to a confirmed knockout tie — no crash, no wrong data, just a stale placeholder. **Knockout live-resolve regressions** shipped repeatedly in different surfaces (root cause: skeleton reads, cache gaps, or both):
22− 
23−- v0.8.2 — R32 pre-draw seeds rendered static, didn't live-resolve.
24−- v0.8.6 — bracket third-place slots never read the merged live `match.home/away`.
25−- v0.8.7 — `next` / `share next` / MCP next-fixture resolvers read only the static bundle.
26−- v0.8.8 — statusline next-match countdown read the static bundle (`🏳️ vs 🏳️` / `⚽ —` in knockouts).
27−- v0.8.9 — empty fixtures cache stamped the full 15min TTL at phase boundaries; stale-cache `live · syncing…` still read the skeleton.
28− 
29−**Rule:** every team-facing surface must reach the live overlay (`getBracket` / `getNextFixtureForTeam` — the same `fetchWindow` the bracket uses), fail closed on outage, and attribute the provider only when the overlay served the chosen fixture. **Exception — statusline:** hot path cannot fetch; the cold-path refresher calls `getKnockoutFixtures` and caches to `CacheState.fixtures`; `renderPrompt` merges that slice over the bundle (countdown **and** `live · syncing…`), never leaking 🏳️. **Exception — MCP `fixtures://{date}` resource:** deliberately static ("Static fixture list"; a resource URI carries no tz and gets no live overlay) — do not "fix" it to live-resolve without a maintainer decision; agents use `get_today`/`get_bracket` for resolved pairings.
30− 
31−| Surface | Entry point | Must |
32−|---------|-------------|------|
33−| CLI `bracket` / `next` | `cmdBracket` / `cmdNext` | call `getBracket` / `getNextFixtureForTeam` |
34−| CLI `share bracket` / `share next` | `cmdShare` | same |
35−| MCP `get_bracket` / `get_next_fixture` | `toolGetBracket` / `toolGetNextFixture` | same |
36−| MCP `get_share_snippet{bracket,next}` | `toolGetShareSnippet` | same |
37−| **statusline** | `renderPrompt` + `runRefresh` | hot path, NO network — indirect: refresher caches `getKnockoutFixtures` → `CacheState.fixtures`; `renderPrompt` merges them, **failing closed to `⚽ —`** when the cache lacks the pairing; unresolved placeholders dropped in syncing (never 🏳️). Empty successful fetch uses a **short TTL** (~60s); provider errors keep prior cache. **`cmdPrompt` and `cmdHook`** both spawn fixtures refresh in knockout phase. |
38− 
39−**Executable guard:** `packages/{cli,mcp}/test/knockout-surface-coverage.test.ts` pins one fake resolved tie (Mexico vs Ecuador) and asserts every surface renders the real nations, not `🏳️` (statusline from a seeded cache). **`statusline.test.ts` / `refresh.test.ts`** cover syncing + empty-cache TTL. **Adding a team-facing surface? Add it to that test and this table.**
40− 
41−## Format opts invariant
42− 
43−If a core formatter accepts `tz`, `locale`, `flags`, or `date`, **every wrapper** passes them from `CliConfig` / `CommonOpts`.
44− 
45−```typescript
46−// ❌ BAD — locale only; tz silently drops to server local
47−formatBracketList(view, { footer: false, locale: args.lang });
48− 
49−// ✅ GOOD
50−formatBracketList(view, { footer: false, locale: args.lang, tz: args.tz });
51−// or reuse fmtOpts(args) where shapes align
52−```
53− 
54−## Regression tests
55− 
56−When adding a format option (e.g. `date: true` on `formatKickoff`):
57− 
58−- Add a **core** unit test for the option.
59−- Add an **MCP tool test** proving `tz` changes output (e.g. UTC vs `America/Mexico_City` on a cross-midnight kickoff).
60−- Update share tests if `formatShareBracket` / compact lines are affected.
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.
6119  
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack