@ericrisco/rsc 0.1.43 → 0.1.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +1 -1
  2. package/manifest.json +110 -86
  3. package/package.json +1 -1
  4. package/scripts/lib/domains.js +1 -1
  5. package/scripts/skill-migration-brief.md +104 -0
  6. package/skills/ab-testing/SKILL.md +9 -41
  7. package/skills/accessibility/SKILL.md +5 -7
  8. package/skills/ads/SKILL.md +9 -24
  9. package/skills/agent-eval/SKILL.md +7 -33
  10. package/skills/agent-safety/SKILL.md +7 -14
  11. package/skills/ai-media/SKILL.md +4 -20
  12. package/skills/analytics/SKILL.md +8 -30
  13. package/skills/analyze/SKILL.md +24 -59
  14. package/skills/angular/SKILL.md +12 -25
  15. package/skills/api-connector-builder/SKILL.md +10 -27
  16. package/skills/api-design/SKILL.md +7 -14
  17. package/skills/article-writing/SKILL.md +1 -18
  18. package/skills/astro/SKILL.md +36 -54
  19. package/skills/author-skill/SKILL.md +41 -74
  20. package/skills/author-skill/evals/README.md +5 -5
  21. package/skills/author-skill/evals/cases.yaml +8 -8
  22. package/skills/author-skill/references/description-recipe.md +25 -26
  23. package/skills/author-skill/references/eval-authoring.md +1 -1
  24. package/skills/author-skill/references/rsc-conventions.md +1 -1
  25. package/skills/automation-flows/SKILL.md +6 -16
  26. package/skills/automation-strategy/SKILL.md +1 -9
  27. package/skills/aws-essentials/SKILL.md +6 -23
  28. package/skills/backups/SKILL.md +1 -7
  29. package/skills/bash-scripting/SKILL.md +5 -9
  30. package/skills/bookkeeping/SKILL.md +2 -10
  31. package/skills/brand-identity/SKILL.md +18 -44
  32. package/skills/brand-voice/SKILL.md +4 -31
  33. package/skills/building-agents/SKILL.md +20 -103
  34. package/skills/business-intelligence/SKILL.md +9 -23
  35. package/skills/calendar-scheduling/SKILL.md +11 -27
  36. package/skills/case-studies/SKILL.md +3 -8
  37. package/skills/chatbot/SKILL.md +6 -23
  38. package/skills/chrome-extension/SKILL.md +2 -2
  39. package/skills/clarify/SKILL.md +31 -72
  40. package/skills/clickhouse-analytics/SKILL.md +2 -8
  41. package/skills/client-onboarding/SKILL.md +17 -19
  42. package/skills/cloudflare/SKILL.md +3 -8
  43. package/skills/code-review/SKILL.md +10 -23
  44. package/skills/codebase-onboarding/SKILL.md +2 -7
  45. package/skills/cold-outreach/SKILL.md +9 -30
  46. package/skills/community/SKILL.md +4 -31
  47. package/skills/competitor-watch/SKILL.md +20 -35
  48. package/skills/compliance/SKILL.md +10 -37
  49. package/skills/compose-multiplatform/SKILL.md +1 -1
  50. package/skills/constitution/SKILL.md +8 -35
  51. package/skills/content-engine/SKILL.md +4 -16
  52. package/skills/context-budget/SKILL.md +3 -21
  53. package/skills/continuous-learning/SKILL.md +10 -40
  54. package/skills/contracts/SKILL.md +6 -17
  55. package/skills/coolify/SKILL.md +8 -14
  56. package/skills/cost-tracking/SKILL.md +3 -11
  57. package/skills/course-builder/SKILL.md +17 -45
  58. package/skills/course-storytelling/SKILL.md +26 -94
  59. package/skills/cpp/SKILL.md +26 -71
  60. package/skills/csharp-dotnet/SKILL.md +19 -38
  61. package/skills/customer-support/SKILL.md +14 -37
  62. package/skills/dashboard/SKILL.md +6 -26
  63. package/skills/data-cleaning/SKILL.md +37 -63
  64. package/skills/data-policy/SKILL.md +8 -21
  65. package/skills/data-scraper/SKILL.md +1 -7
  66. package/skills/debug/SKILL.md +10 -49
  67. package/skills/deployment/SKILL.md +38 -101
  68. package/skills/design/SKILL.md +34 -116
  69. package/skills/fable-operator/SKILL.md +1 -4
  70. package/skills/fastapi/SKILL.md +50 -82
  71. package/skills/flutter/SKILL.md +41 -89
  72. package/skills/go/SKILL.md +57 -105
  73. package/skills/harness/SKILL.md +52 -68
  74. package/skills/implement/SKILL.md +1 -1
  75. package/skills/init/SKILL.md +152 -168
  76. package/skills/marketing/SKILL.md +30 -80
  77. package/skills/nextjs/SKILL.md +42 -116
  78. package/skills/orient/SKILL.md +25 -20
  79. package/skills/parallel/SKILL.md +9 -75
  80. package/skills/plan/SKILL.md +92 -165
  81. package/skills/postgresdb/SKILL.md +52 -72
  82. package/skills/presentations/SKILL.md +49 -87
  83. package/skills/python/SKILL.md +23 -72
  84. package/skills/react/SKILL.md +19 -67
  85. package/skills/review/SKILL.md +22 -52
  86. package/skills/rust/SKILL.md +40 -115
  87. package/skills/sdd-init/SKILL.md +9 -14
  88. package/skills/secure-coding/SKILL.md +80 -109
  89. package/skills/ship/SKILL.md +25 -55
  90. package/skills/tasks/SKILL.md +37 -61
  91. package/skills/typescript/SKILL.md +22 -55
  92. package/skills/verify/SKILL.md +8 -32
  93. package/skills/viral-score/SKILL.md +122 -0
  94. package/skills/viral-score/evals/README.md +16 -0
  95. package/skills/viral-score/evals/cases.yaml +50 -0
  96. package/skills/vue-nuxt/SKILL.md +45 -106
  97. package/skills/worktrees/SKILL.md +24 -69
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: analyze
3
- description: "Use when the spec, plan and task list are written and you want a last consistency check BEFORE any code is touched — the pre-implementation GATE of the rsc-sdd chain. It cross-reads constitution vs spec vs plan vs tasks and reports gaps, contradictions, duplication, ambiguity and scope drift, mapping every artifact to the requirements it claims to satisfy. Report-only: it never edits artifacts and never writes code; the user decides each resolution. Triggers: 'analyze', 'analiza la spec antes de implementar', 'cross-check constitution spec plan tasks', 'consistency gate', 'are spec and plan aligned', 'did we miss any requirement', 'scope drift check', 'gap analysis before coding', 'is the plan complete', 'sanity-check before implement', 'coverage of requirements'. NOT clarifying a single spec (that is `clarify`), NOT writing the plan or tasks, NOT running tests/lint (that is `verify`), NOT root-causing a bug (that is `debug`)."
3
+ description: "Use when constitution, spec, plan and tasks all exist and you want them cross-read against each other before any code is written — the rsc-sdd pre-implementation gate. Reports coverage gaps, contradictions, duplication, ambiguity and scope drift; edits nothing. NOT the task breakdown (that is `tasks`), NOT the coding (that is `implement`), NOT the post-code test gate (that is `verify`), NOT resolving ambiguity (that is `clarify`)."
4
4
  tags: [sdd, analyze, consistency]
5
5
  recommends: [implement]
6
6
  profiles: [core, full]
@@ -9,51 +9,26 @@ origin: risco
9
9
 
10
10
  # Analyze — the pre-implementation consistency gate
11
11
 
12
- You have a **constitution**, a **spec**, a **plan** and a **task list**. Four artifacts written at four different moments, by a mind that drifted a little each time. `analyze` is the last checkpoint before the first line of code: it reads all four *against each other* and surfaces where they disagree. It is the cheapest place in the whole chain to catch a problem — a contradiction found here costs a sentence; the same contradiction found mid-implement costs a rewrite.
12
+ You have a **constitution**, a **spec**, a **plan** and a **task list**. Four artifacts written at four different moments, by a mind that drifted a little each time. `analyze` reads all four *against each other* and surfaces where they disagree. It is the cheapest place in the whole chain to catch a problem — a contradiction found here costs a sentence; the same contradiction found mid-implement costs a rewrite.
13
13
 
14
- This is the **sixth phase** of the rsc-sdd chain (`constitution → specify → clarify → plan → tasks → analyze → implement`). It is a **gate, not a worker**: it produces a report and stops. It does not patch the spec, does not reorder tasks, does not touch code. The user reads the findings and decides what to fix, and which phase to send each fix back to.
14
+ Sixth phase of the rsc-sdd chain (`constitution → specify → clarify → plan → tasks → analyze → implement`); the method itself lives in `../sdd/SKILL.md`. It is a **gate, not a worker**: it produces a report and stops. The user reads the findings and decides what to fix, and which phase to send each fix back to.
15
15
 
16
- ## The one rule that defines this skill
16
+ **Report only. Resolve nothing.** Never edit the constitution, spec, plan or tasks; never open a code file to "just fix it"; never silently reconcile a contradiction by picking a side. This one is absolute because a gate that quietly fixes things stops being a gate: the user never learns the spec was wrong, the plan built on the old assumption stays stale, and the "consistency check" has manufactured a new inconsistency. Name the conflict, show both sides with locations, propose where it should be resolved, hand the decision back.
17
17
 
18
- **Report only. Resolve nothing.** `analyze` never edits the constitution, spec, plan or tasks, never opens a code file to "just fix it", never silently reconciles a contradiction by picking a side. It names the conflict, shows both artifacts with their locations, proposes where it should be resolved, and hands the decision back. The moment you feel the urge to edit an artifact, you have left this skill — stop and route the fix to the phase that owns it.
18
+ **Model tier: `heavy`** (adversarial cross-reading). Resolve and apply it per `../sdd/references/model-routing.md`; routing is off unless `models.enabled: true` in `02-DOCS/wiki/sdd/config.yaml`.
19
19
 
20
- Why so strict? Because a gate that quietly fixes things stops being a gate. If `analyze` patches the spec on its own, the user never learns the spec was wrong, the plan built on the old assumption stays stale, and the "consistency check" has manufactured a new inconsistency. The value is the *honest report*, not the patch.
20
+ **Accompaniment dial.** Read `02-DOCS/wiki/harness/user-profile.md` before reporting — default to **L2** and say the harness has not gauged the user yet if there is no profile. The dial flexes how the report reads, never what gets checked; the six analyses always run in full.
21
21
 
22
- ## When to use / when NOT to use
23
-
24
- Use when:
25
-
26
- - The plan and tasks exist and you are about to start implementing — run this first, every time.
27
- - A spec or plan changed after the others were written and you want to re-check alignment.
28
- - Implementation stalled because the artifacts seem to contradict each other.
29
- - You want a requirements-coverage map: which task satisfies which spec requirement, and what is orphaned.
30
-
31
- Do NOT use when (route elsewhere):
32
-
33
- - A single spec is fuzzy and you need to ask the user questions and bake answers in → `clarify` (analyze reports the ambiguity; clarify resolves it).
34
- - The plan or tasks don't exist yet → write them first (`plan`, then `tasks`).
35
- - You want to run lint/types/tests/acceptance after coding → `verify` (post-implementation gate; analyze is pre-implementation).
36
- - A test is failing or behavior is wrong → `debug`.
37
- - You intend to fix what you find right now → that is `implement`/`clarify`/`plan`/`tasks` work, not analyze. Analyze only reports.
38
-
39
- ## Model tier — `heavy` (opt-in routing)
40
-
41
- This phase's default model tier is **`heavy`** — it is the adversarial consistency gate across constitution ↔ spec ↔ plan ↔ tasks. Routing is **off** unless `models.enabled: true` in `02-DOCS/wiki/sdd/config.yaml`. When on: resolve this phase's tier (`models.overrides` wins over `models.phases`), map it to a model via `models.tiers`, and apply per `../sdd/references/model-routing.md` — announce the switch per the accompaniment dial when it differs from the session model, and dispatch any `Task`/`parallel` subagents on that model. Routing off or no profile → honor the session model silently. Never fake a switch a tool can't make; skip routing on a one-line change.
42
-
43
- ## Read the accompaniment dial first
44
-
45
- Before reporting, read `02-DOCS/wiki/harness/user-profile.md` for the technical + accompaniment level (the harness dial, L0..L3). It shapes how the report reads — not what gets checked. The six analyses always run in full; verbosity flexes:
46
-
47
- - **L0** — the finding table only: severity, the two artifacts, the conflict in one line. No prose.
48
- - **L1** — the table plus a one-line *why it matters* per CRITICAL/HIGH finding.
49
- - **L2** — the table plus, per finding, the recommended resolution phase and the trade-off of leaving it.
50
- - **L3** — full walk-through: for each finding, quote both sides, explain the consequence at implement time in plain language, and lay out the options so a non-technical user can choose.
51
-
52
- If no profile exists, default to L2 and note that the harness has not gauged the user yet.
22
+ | Dial | The report renders as |
23
+ | --- | --- |
24
+ | L0 | Finding table only: severity, the two artifacts, the conflict in one line. No prose. |
25
+ | L1 | + a one-line *why it matters* per CRITICAL/HIGH finding. |
26
+ | L2 | + per finding, the recommended resolution phase and the trade-off of leaving it. |
27
+ | L3 | + full walk-through: quote both sides, explain the consequence at implement time in plain language, lay out the options so a non-technical user can choose. |
53
28
 
54
29
  ## Inputs — locate the four artifacts
55
30
 
56
- Read all four before analyzing. The rsc-sdd artifacts live under `02-DOCS/wiki/sdd/` (the harness Karpathy-wiki convention), indexed from `02-DOCS/wiki/index.md` (the Knowledge map; root `CLAUDE.md` keeps only a short pointer to it):
31
+ Read all four before analyzing. The rsc-sdd artifacts live under `02-DOCS/wiki/sdd/`, indexed from `02-DOCS/wiki/index.md` (the Knowledge map; root `CLAUDE.md` keeps only a short pointer to it):
57
32
 
58
33
  | Artifact | Canonical location | Role in the check |
59
34
  | --- | --- | --- |
@@ -110,32 +85,22 @@ Produce a single consistency report:
110
85
  1. **Verdict line** — `GATE: PASS` (zero CRITICAL/HIGH) or `GATE: BLOCKED` (one or more CRITICAL/HIGH), with the counts.
111
86
  2. **Coverage map** — the table above.
112
87
  3. **Findings table** — `# | Severity | Type | Artifact A (loc) | Artifact B (loc) | Conflict | Resolve in (phase)`.
113
- 4. **Recommended routing** — group fixes by the phase that owns them (`clarify` for spec ambiguity, `plan` for missing architecture, `tasks` for a missing done-check, `constitution` if a principle itself is wrong).
88
+ 4. **Recommended routing** — group fixes by the phase that owns them (`clarify` for spec ambiguity, `plan` for missing architecture, `tasks` for a missing done-check, `constitution` if a principle itself is wrong). If findings pour in across all six checks, the artifacts diverged badly — recommend re-running `clarify`/`plan` before a line-by-line analyze is even useful.
114
89
 
115
- Write the report to `02-DOCS/wiki/sdd/analysis/<slug>.md` (create the dir if absent) and index it in `02-DOCS/wiki/index.md` (the Knowledge map; root `CLAUDE.md` keeps only a short pointer) under the `sdd/` topic, so the next phase and the harness can find it. It is an OKF v0.1 wiki article: open it with YAML frontmatter carrying a non-empty `type:` (use `type: analysis`), a `timestamp` in ISO 8601, and standard markdown links — never wikilinks. The report is the artifact analyze owns — it is the *only* thing analyze writes. Per-run point-in-time; overwrite on re-run, the wiki keeps history.
90
+ Write the report to `02-DOCS/wiki/sdd/analysis/<slug>.md` (create the dir if absent) and index it in `02-DOCS/wiki/index.md` under the `sdd/` topic, so the next phase and the harness can find it. It is an OKF v0.1 wiki article: open it with YAML frontmatter carrying a non-empty `type:` (use `type: analysis`), a `timestamp` in ISO 8601, and standard markdown links — never wikilinks. The report is the artifact analyze owns — it is the *only* thing analyze writes. Per-run point-in-time; overwrite on re-run, the wiki keeps history.
116
91
 
117
- Adapt the rendered verbosity to the dial (L0 = table only; L3 = full walk-through). Do not log a decision to `decisions.md` — analyze decides nothing; the phase that resolves the finding logs its own decision.
92
+ Render it at the dial's verbosity. Do not log a decision to `decisions.md` — analyze decides nothing; the phase that resolves the finding logs its own decision.
118
93
 
119
- ## Anti-patterns → STOP
94
+ ## Anti-patterns
120
95
 
121
- | Rationalization | Reality / Fix |
96
+ | Anti-pattern | Why it breaks the gate / do instead |
122
97
  | --- | --- |
123
- | "This contradiction is trivial, I'll just fix the spec myself" | Then you are `clarify`/`plan`, not `analyze`. Report it; the user resolves. A gate that edits stops being a gate. |
124
- | "No CRITICAL findings, so I'll start coding from here" | Analyze never transitions to code. Pass the verdict to `implement`; that phase starts the work. |
125
- | "The plan adds caching the spec didn't mention — obviously a good idea, I'll allow it" | That is DRIFT. Flag it. Good ideas still need the spec amended (user's call), or they are silent scope creep. |
126
- | "I'll only check coverage; contradictions are rare" | Run all six analyses every time. The one you skip is the one that bites at implement time. |
127
- | "The spec is vague but I can guess what they meant" | Guessing defeats the gate. Mark AMBIGUOUS and route to `clarify`; do not encode your guess. |
128
- | "I'll fold the findings straight into the task list to save a step" | No. Editing tasks is the `tasks` phase. Report, route, hand back. |
129
- | "Constitution says Postgres but plan picked Mongo for good reasons — I'll side with the plan" | The constitution wins by definition. Flag CRITICAL. If the principle is wrong, that is a `constitution` change the user makes, not a quiet override here. |
130
- | "I read the spec and tasks; the constitution is boilerplate, skip it" | The constitution is analysis #1 and the highest severity. Never skip it. |
131
-
132
- ## Red flags — stop and report instead of analyzing
133
-
134
- - An artifact is missing (no plan, no tasks) → say which, name the phase, do not fabricate it.
135
- - Multiple specs match the slug → ask which feature; don't analyze the wrong one.
136
- - You catch yourself opening a source file → you have left the gate; close it.
137
- - Findings are pouring in across all six checks → the artifacts diverged badly; recommend the user re-runs `clarify`/`plan` before a line-by-line analyze is even useful.
98
+ | Fixing a "trivial" contradiction in the spec yourself | Then you are `clarify`/`plan`/`tasks`, not `analyze`. Report it; the user resolves. |
99
+ | Starting to code because nothing CRITICAL turned up | Analyze never transitions to code. Hand the verdict to `implement`; that phase starts the work. |
100
+ | Waving through plan work the spec never asked for because it's obviously a good idea | That is DRIFT. Flag it. Good ideas still need the spec amended (user's call), or they are silent scope creep. |
101
+ | Siding with the plan when it contradicts the constitution | The constitution wins by definition — flag CRITICAL. If the principle itself is wrong, that is a `constitution` change the user makes, not a quiet override here. |
102
+ | Guessing what a vague requirement meant | Guessing defeats the gate. Mark AMBIGUOUS and route to `clarify`; do not encode your guess. |
138
103
 
139
104
  ## Next in the chain
140
105
 
141
- When the verdict is `GATE: PASS` (or the user has consciously accepted the remaining MEDIUM/LOW findings), proceed to **`implement`** — execute the tasks with TDD discipline, delegating concrete test tooling to the relevant stack skill (`fastapi`, `nextjs`, `go`, `flutter`, `postgresdb`). If the verdict is `GATE: BLOCKED`, route each CRITICAL/HIGH finding to its owning phase (`clarify`, `plan`, `tasks`, or `constitution`), let the user resolve, then re-run `analyze`. The gate only opens once.
106
+ On `GATE: PASS` (or once the user consciously accepts the remaining MEDIUM/LOW findings), proceed to **`implement`** — execute the tasks with TDD discipline, delegating concrete test tooling to the relevant stack skill (`fastapi`, `nextjs`, `go`, `flutter`, `postgresdb`). On `GATE: BLOCKED`, route each CRITICAL/HIGH finding to its owning phase (`clarify`, `plan`, `tasks`, or `constitution`), let the user resolve, then re-run `analyze`. The gate only opens once.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: angular
3
- description: "Use when building, refactoring, reviewing, or debugging an Angular app (Angular 20/21+: standalone components, signals, zoneless change detection, the @if/@for/@defer built-in control flow, inject() DI, resource()/httpResource(), RxJS interop, NgRx SignalStore, the ng CLI). Triggers: 'why isn't my view updating', migrating NgModules to standalone, replacing *ngFor with @for, decorator inputs vs input() signals, 'monta una app Angular', 'componente standalone con signals', 'com passo a zoneless', going zoneless / removing Zone.js, app.config.ts providers, toSignal/toObservable interop, ng generate/ng update. NOT React (that is react), NOT Next.js (that is nextjs), NOT a plain TypeScript language question (that is typescript)."
3
+ description: "Use when building, refactoring, or debugging Angular (v20/21+): standalone components, signals, zoneless change detection, @if/@for/@defer control flow, inject() DI, resource()/httpResource(), RxJS interop, NgRx SignalStore, ng CLI. NOT React (that is react), NOT Next.js (that is nextjs), NOT a TypeScript language question (that is typescript)."
4
4
  tags: [angular, frontend, web, signals, typescript, spa]
5
5
  recommends: [typescript, testing-web, secure-coding]
6
6
  origin: risco
@@ -10,31 +10,23 @@ origin: risco
10
10
 
11
11
  > Build Angular the way it ships in 2026: standalone components, signals as the reactivity model, zoneless change detection, built-in control flow, and `inject()` DI. Treat NgModules, `*ngFor`, and `@Input()` decorators as legacy you only touch to migrate.
12
12
 
13
- ## When to use
13
+ ## Not this skill
14
14
 
15
- - Creating or editing Angular components, directives, services, guards, resolvers, interceptors, or routes.
16
- - Anything touching `angular.json`, the `ng` CLI, `main.ts` bootstrap, `app.config.ts`, or `provide*()` providers.
17
- - Deciding signals vs RxJS, or migrating decorators/NgModules to standalone + signals.
18
- - Wiring data fetching with `httpResource()`/`resource()` or `HttpClient` + RxJS.
19
- - Debugging zoneless change detection, `OnPush`, or "view not updating" bugs.
20
- - State with NgRx SignalStore or plain signal services; reactive/typed forms; route-bound signal inputs.
21
-
22
- ## When NOT to use
23
-
24
- - **AngularJS (1.x)** — out of scope entirely. This skill is Angular 2+ only; the APIs do not map.
25
- - **React** → that is the `react` skill. NOT React (that is react).
26
- - **Next.js App Router** → `../nextjs/SKILL.md`.
27
- - **Vue/Nuxt, Svelte, SolidJS, Astro** → `vue-nuxt`, `svelte`, `solid-js`, `../astro/SKILL.md`.
28
- - **Pure TypeScript language question** (generics, narrowing, tsconfig) with no Angular dimension → `../typescript/SKILL.md`.
29
- - **A standalone NestJS API** → `../nestjs/SKILL.md`. A generic Node service → `nodejs`. Angular Universal SSR itself stays here.
30
- - **Cross-framework Playwright e2e strategy** → `testing-web` / `e2e-testing`. Angular's own `ng test` (Vitest) setup stays here.
15
+ **AngularJS (1.x)** is out of scope entirely — this skill is Angular 2+ only and the APIs do not map.
16
+ Route elsewhere for **React** → `../react/SKILL.md`; **Next.js App Router** → `../nextjs/SKILL.md`;
17
+ **Vue/Nuxt, Svelte, SolidJS, Astro** → `../vue-nuxt/SKILL.md`, `../svelte/SKILL.md`,
18
+ `../solid-js/SKILL.md`, `../astro/SKILL.md`; a **pure TypeScript language question** (generics,
19
+ narrowing, tsconfig) with no Angular dimension → `../typescript/SKILL.md`; a **standalone NestJS
20
+ API** → `../nestjs/SKILL.md`; a generic Node service → `../nodejs/SKILL.md`; **cross-framework
21
+ Playwright e2e strategy** → `../testing-web/SKILL.md` / `../e2e-testing/SKILL.md`. Angular Universal
22
+ SSR and Angular's own `ng test` (Vitest) setup stay here.
31
23
 
32
24
  ## Decide first
33
25
 
34
26
  | Situation | Do this | Why |
35
27
  |-----------|---------|-----|
36
28
  | Greenfield app / new feature | Zoneless + signals + standalone by default. `ng new` (Angular 21) already excludes Zone.js. | The defaults shipped stable in v20-v21; fight them and you write more code that the framework now does for you. |
37
- | Brownfield NgModule + decorator app | Migrate incrementally with schematics; do not rewrite. Keep Zone.js until you flip it on purpose. | A working app that uses `*ngIf` is not a bug. Churn introduces risk for no user value. |
29
+ | Brownfield NgModule + decorator app | Migrate incrementally with the schematics in `references/migration.md` (NgModule→standalone, control flow, decorator→signal inputs, Zone.js→zoneless, Karma→Vitest); do not rewrite. Keep Zone.js until you flip it on purpose. | A working app that uses `*ngIf` is not a bug. Churn introduces risk for no user value. |
38
30
  | "View not updating" complaint | Jump to the change-detection section: signal not read in template, `OnPush` without a signal, or stale Zone.js assumption. | Zoneless means a mutation that no signal observes will never repaint — the fix is structural, not a `detectChanges()` call. |
39
31
 
40
32
  ## The modern baseline
@@ -178,7 +170,7 @@ profile = resource({
178
170
  ```
179
171
 
180
172
  - Rule: `httpResource()`/`resource()` give you `value()`, `isLoading()`, `error()`, `reload()` for free — prefer them over a manual `subscribe` that you have to clean up. Why: less boilerplate, no leak, refetches automatically when its source signals change.
181
- - Rule: when you genuinely need a stream (websocket, debounced search, retry/switchMap), keep `HttpClient` + RxJS and bridge to a signal with `toSignal()`. Why: signals are not streams; do not fake backpressure with effects. See `references/signals-rxjs.md`.
173
+ - Rule: when you genuinely need a stream (websocket, debounced search, retry/switchMap), keep `HttpClient` + RxJS and bridge to a signal with `toSignal()`. Why: signals are not streams; do not fake backpressure with effects. `references/signals-rxjs.md` has the signals-vs-RxJS decision matrix, `toSignal`/`toObservable` interop recipes, `effect` pitfalls (infinite loops, untracked reads), and `takeUntilDestroyed`.
182
174
 
183
175
  ## DI & services
184
176
 
@@ -280,9 +272,4 @@ it('renders the user name', async () => {
280
272
  | Nested `subscribe()` inside `subscribe()` | Callback pyramid, lost cancellation | `switchMap`/`concatMap`, one subscription |
281
273
  | Constructor DI only (`constructor(private x: X)`) | Legacy ergonomic; can't compose into functions | `private x = inject(X)` |
282
274
 
283
- ## References
284
-
285
- - `references/signals-rxjs.md` — signals-vs-RxJS decision matrix, `toSignal`/`toObservable` interop recipes, `effect` pitfalls (infinite loops, untracked reads), `linkedSignal`/`resource()` patterns, `takeUntilDestroyed`.
286
- - `references/migration.md` — incremental migration checklist + schematics: NgModule→standalone, control-flow migration, decorator-input→signal-input, Zone.js→zoneless go-live, Karma/Jasmine→Vitest.
287
-
288
275
  `scripts/verify.sh` is a heuristic copy-banlist lint — it greps your Angular sources for the banned patterns above. It is a hint, not a compiler.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: api-connector-builder
3
- description: "Use when writing a client against a third-party REST or GraphQL API and the boring-but-critical parts keep biting — token refresh mid-run, only-the-first-page results, random 429s, banned keys. Covers auth flow selection (API key, Bearer, OAuth2 client-credentials, auth-code+PKCE, device), pagination to exhaustion (offset, cursor/keyset, Link header, Relay connections), retry-with-jitter on transient failures only, and rate-limit-aware throttling. Triggers: 'write a connector for the Linear/Shopify API', 'this API keeps 429-ing us', 'paginate through all results', 'token expires mid-run add refresh', 'wrap this REST API as a typed SDK', 'conector para una API que nos limita', 'recórreme totes les pàgines'. NOT receiving inbound callbacks (that is webhooks), NOT chaining many services into a flow (that is automation-flows), NOT designing your own API surface (that is api-design)."
3
+ description: "Use when writing a client for someone else's REST or GraphQL API: auth flow choice and token refresh, pagination to exhaustion, retry-with-jitter on transient failures only, rate-limit-aware throttling. NOT inbound callbacks (that is `webhooks`), NOT chaining services (that is `automation-flows`), NOT designing your own API (that is `api-design`)."
4
4
  tags: [api, rest, graphql, oauth, pagination, retries, rate-limiting, http-client, connector]
5
5
  recommends: [webhooks, automation-flows, api-design, data-scraper, secure-coding, error-handling, structured-extraction]
6
6
  origin: risco
@@ -12,31 +12,18 @@ You are writing a client for **someone else's** HTTP API. You do not own the
12
12
  contract; you obey it. The deliverable is one typed connector module per vendor
13
13
  that authenticates, walks the whole result set, retries only transient failures
14
14
  with backoff, and stays under the rate limit without getting the key banned.
15
+ One connector = one vendor: mixed clients tangle two auth schemes and two
16
+ rate-limit budgets into something no one can reason about.
15
17
 
16
18
  Four pillars, every time: **auth, pagination, retries, rate limits.** If your
17
19
  connector skips any one of them it works in the demo and breaks in production —
18
20
  on page 2, on token expiry, on the first 429, or on a flaky network.
19
21
 
20
- This skill goes **outbound** (you call them). Receiving their callbacks is the
21
- inverse and lives in `webhooks`.
22
-
23
- ## Operating posture
24
-
25
- - **Read the vendor docs before writing a line.** Invented endpoints and guessed
26
- field names 404 in prod. Find the real base URL, version, and error envelope.
27
- - **Secrets come from env or a secret store, never source.** Hardcoded keys leak
28
- through git history and screenshots and you cannot rotate them cleanly.
29
- - **One connector = one vendor.** Mixed clients tangle two auth schemes and two
30
- rate-limit budgets into one tangle no one can reason about.
31
- - **Every request gets a timeout.** A hung socket with no timeout stalls the
32
- whole run forever; the default in most clients is "wait indefinitely".
33
- - **Log request id + status + attempt, never the token.** Logs get shipped to
34
- third parties; a logged bearer token is a leaked credential.
35
-
36
22
  ## Step 0 — read the contract
37
23
 
38
- Before any code, extract these from the vendor's docs. Each one changes what you
39
- write, so missing one means a rewrite.
24
+ Read the vendor docs before writing a line — invented endpoints and guessed
25
+ field names 404 in prod. Extract these first; each one changes what you write,
26
+ so missing one means a rewrite.
40
27
 
41
28
  | Find in their docs | Why it changes your code |
42
29
  | ------------------------- | --------------------------------------------------------- |
@@ -202,8 +189,9 @@ def iter_records(client):
202
189
  return
203
190
  ```
204
191
 
205
- Full code for every style — offset, keyset, `Link`-header parsing, and GraphQL
206
- Relay connection walking, in Python and TS — is in `references/pagination.md`.
192
+ Full code for every style — offset, keyset, `Link`-header parsing, GraphQL Relay
193
+ connection walking, in Python and TS, plus dedup-on-overlap notes — is in
194
+ `references/pagination.md`.
207
195
 
208
196
  ## Putting it together
209
197
 
@@ -272,12 +260,7 @@ export async function request(path: string, init: RequestInit = {}, attempt = 0)
272
260
  | Token in query string | Token ends up in logs / referrers | Bearer in the `Authorization` header |
273
261
  | Implicit / password OAuth grant | Removed in OAuth 2.1; insecure | Auth-Code + PKCE, or Client Credentials |
274
262
 
275
- ## References & verify
276
-
277
- - `references/auth-flows.md` — per-flow walkthroughs, token storage + rotation,
278
- OAuth 2.1 deltas, RFC 9700 refresh rotation, DPoP note. Python + TS.
279
- - `references/pagination.md` — full code for offset, cursor/keyset, Link-header,
280
- and GraphQL Relay walking. Exhaustion-loop and dedup-on-overlap notes.
263
+ ## Verify
281
264
 
282
265
  Run `scripts/verify.sh` over the connector you write: it greps for hardcoded
283
266
  secrets, asserts a retry mechanism and a pagination loop and a request timeout
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: api-design
3
- description: "Use when designing the contract of a network API before/independent of implementation — modeling resources and URLs, choosing REST vs GraphQL, picking a versioning strategy, defining one consistent error envelope, and settling pagination/filtering/idempotency conventions. Triggers: 'design the REST API for X', 'what should the endpoints be', 'how do I version this without breaking clients', 'should this be REST or GraphQL', 'cursor vs offset pagination', 'standard error format for my API', 'RFC 9457 problem details', 'idempotency key on POST', '200 with error body', 'diseña la API REST de esto', 'cómo verziono la API sin romper clientes'. NOT implementing endpoints in a framework (that is fastapi/nestjs/go/nodejs), NOT security/auth hardening (that is secure-coding), NOT receiving inbound webhooks (that is webhooks), NOT building an outbound client to a third-party API (that is api-connector-builder)."
3
+ description: "Use when settling the contract of an API you expose, before implementation: resources/URLs, REST vs GraphQL, versioning, one RFC 9457 error envelope, pagination, idempotency — emitted as OpenAPI 3.1. NOT implementing the endpoints (that is `fastapi`/`nestjs`/`go`/`nodejs`), NOT auth hardening (that is `secure-coding`), NOT consuming a third-party API (that is `api-connector-builder`)."
4
4
  tags: [api-design, rest, graphql, openapi, versioning, pagination, http, rfc9457, contract-design]
5
5
  recommends: [fastapi, nestjs, go, nodejs, secure-coding, webhooks, api-connector-builder, code-review]
6
6
  origin: risco
@@ -24,7 +24,7 @@ Pick on traffic shape, not fashion. Decide once, write it down.
24
24
  | Many client shapes, deep nested graphs, mobile over-fetch is real | **GraphQL** | one round-trip, client picks fields; no N endpoints per screen |
25
25
  | Stable resource API + one rich read surface for a client app | **Hybrid** | REST for the system of record, a GraphQL read layer on top |
26
26
 
27
- Operational gotcha that decides monitoring: **GraphQL returns HTTP 200 even when a field errored** — failures live in an `errors[]` array next to partial `data`. Your dashboards cannot alert on 5xx; you must alert on the `errors[]` payload. REST signals failure with the HTTP status itself. If your ops team lives on status-code SLOs, that is a point for REST. Details in `references/graphql-design.md`.
27
+ Operational gotcha that decides monitoring: **GraphQL returns HTTP 200 even when a field errored** — failures live in an `errors[]` array next to partial `data`. Your dashboards cannot alert on 5xx; you must alert on the `errors[]` payload. REST signals failure with the HTTP status itself. If your ops team lives on status-code SLOs, that is a point for REST. Schema/nullability design, mutation and error-union conventions, and this error model in full: [`references/graphql-design.md`](references/graphql-design.md).
28
28
 
29
29
  ## Resource & URL modeling
30
30
 
@@ -44,7 +44,7 @@ Rules, each with its reason:
44
44
  | `GET /projects/active` | `GET /projects?status=active` | filter is a query param |
45
45
  | `POST /projects/{id}/delete` | `DELETE /projects/{id}` | method, not path segment |
46
46
 
47
- Full query grammar (filter operators, sparse fieldsets, sort syntax) is in `references/rest-conventions.md`.
47
+ Full query grammar (filter operators, sparse fieldsets, sort syntax), content negotiation, rate-limit headers and a HATEOAS note: [`references/rest-conventions.md`](references/rest-conventions.md).
48
48
 
49
49
  ## Status codes that matter
50
50
 
@@ -67,7 +67,7 @@ You need a small map, used consistently. Don't overload 200.
67
67
 
68
68
  Two distinctions agents get wrong:
69
69
  - **401 vs 403** — 401 means *unauthenticated* (no/invalid credentials); 403 means *authenticated but unauthorized*. Returning 401 on a permission failure leaks that re-auth might help when it won't.
70
- - **409 vs 422** — 409 is a *state* conflict (the request fights the current server state: dup key, stale version). 422 is a *content* problem (the body parses but fails business rules). Full table with when-each in `references/rest-conventions.md`.
70
+ - **409 vs 422** — 409 is a *state* conflict (the request fights the current server state: dup key, stale version). 422 is a *content* problem (the body parses but fails business rules). Full status-code table with when-each in [`references/rest-conventions.md`](references/rest-conventions.md).
71
71
 
72
72
  ## Error envelope: RFC 9457
73
73
 
@@ -116,7 +116,7 @@ REST cursor envelope — same keys on every list endpoint:
116
116
 
117
117
  The next page is `GET /projects?cursor=eyJpZCI6MTI4N30&limit=50`. The cursor is opaque — clients must not parse or construct it.
118
118
 
119
- GraphQL has its own de-facto standard: **Relay Connections** — `edges { node, cursor }`, `pageInfo { hasNextPage, endCursor }`, args `first` / `after`. Use it; don't invent a bespoke GraphQL pagination shape. See `references/graphql-design.md`.
119
+ GraphQL has its own de-facto standard: **Relay Connections** — `edges { node, cursor }`, `pageInfo { hasNextPage, endCursor }`, args `first` / `after`. Use it; don't invent a bespoke GraphQL pagination shape. See [`references/graphql-design.md`](references/graphql-design.md).
120
120
 
121
121
  ## Versioning & evolution
122
122
 
@@ -135,7 +135,7 @@ Sunset: Sat, 31 Oct 2026 23:59:59 GMT
135
135
  Link: <https://api.acme.com/v2/projects>; rel="successor-version"
136
136
  ```
137
137
 
138
- Full breaking-vs-non-breaking matrix and the deprecation workflow live in `references/versioning-and-evolution.md`.
138
+ Full breaking-vs-non-breaking matrix, the three versioning mechanisms and the deprecation/sunset workflow: [`references/versioning-and-evolution.md`](references/versioning-and-evolution.md).
139
139
 
140
140
  ## Idempotency & concurrency
141
141
 
@@ -167,7 +167,7 @@ Idempotency-Key: 9b1f7c2e-...
167
167
 
168
168
  ## Handoff
169
169
 
170
- The contract is the artifact. Emit it as an **OpenAPI 3.1** document (see `references/openapi-contract.md`) — that is the checkable deliverable a framework skill generates code from.
170
+ The contract is the artifact. Emit it as an **OpenAPI 3.1** document — the checkable deliverable a framework skill generates code from. How to shape it, and what `scripts/verify.sh` checks: [`references/openapi-contract.md`](references/openapi-contract.md).
171
171
 
172
172
  Hand off to the builder:
173
173
  - Python/async → [`../fastapi/SKILL.md`](../fastapi/SKILL.md)
@@ -180,10 +180,3 @@ Adjacent concerns you do **not** own:
180
180
  - Receiving inbound webhooks (HMAC verify, replay, dedupe) → [`../webhooks/SKILL.md`](../webhooks/SKILL.md)
181
181
  - Building an outbound client to a third-party API → [`../api-connector-builder/SKILL.md`](../api-connector-builder/SKILL.md)
182
182
  - Reviewing handler code (not the design) → [`../code-review/SKILL.md`](../code-review/SKILL.md)
183
-
184
- ## References
185
-
186
- - `references/rest-conventions.md` — full status-code table, filter/sort/sparse-fieldset grammar, content negotiation, rate-limit headers, HATEOAS note.
187
- - `references/versioning-and-evolution.md` — breaking-vs-non-breaking matrix, three versioning mechanisms, deprecation/sunset workflow.
188
- - `references/graphql-design.md` — schema/nullability design, Relay Connections, mutation + error-union conventions, the HTTP-200 error model and its monitoring impact.
189
- - `references/openapi-contract.md` — capture the contract as OpenAPI 3.1 so frameworks generate from it; what `scripts/verify.sh` checks.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: article-writing
3
- description: "Use when drafting a long-form blog post or article from a topic or target query and you need publishable prose plus the on-page surface that ships with it — an answer-first lede, a question-shaped H2/H3 hierarchy, title tag, meta description, slug, FAQ block, and Article/FAQPage JSON-LD. Use when an intro buries the answer, a draft rambles or reads padded with AI tells, or a piece needs depth matched to search intent for AI Overviews and featured snippets. Triggers: 'write a blog post about X', 'draft a 1500-word article', 'rewrite this intro so the answer comes first', 'add FAQ schema to this post', 'cut the fluff out of this draft', 'escriu un article de blog sobre teletreball optimitzat per SEO', 'redacta un artículo optimizado para SEO'. NOT keyword research or which topics to target (that is seo-geo), and NOT the editorial calendar or content pipeline (that is content-engine)."
3
+ description: "Use when writing one long-form article end to end — answer-first lede, question-shaped headings, plus its on-page surface (title, meta, slug, FAQ, Article/FAQPage JSON-LD) — or fixing a draft that buries the answer or reads AI-padded. NOT keyword research or topic selection (that is `seo-geo`), NOT the editorial calendar (that is `content-engine`)."
4
4
  tags: [article, blog, long-form, seo-writing, geo, on-page, eeat, copywriting]
5
5
  recommends: [seo-geo, content-engine, brand-voice, landing-copy, technical-writing, case-studies]
6
6
  origin: risco
@@ -12,15 +12,6 @@ Draft one long-form article end to end: the prose **and** the on-page surface th
12
12
 
13
13
  You own a single finished article. You do not pick the topic, build the calendar, or define the house voice — those are siblings below.
14
14
 
15
- ## When to use
16
-
17
- - Drafting a blog post or long-form article from a topic or a target query.
18
- - Turning a brief or outline into finished, publishable prose at the right depth.
19
- - Writing the answer-first lede — the first ~200 words that fully answer the primary query.
20
- - Restructuring a rambling draft into a question-shaped H2/H3 hierarchy.
21
- - Writing the on-page surface: title tag, meta description, H1, slug, FAQ section, and Article/FAQPage JSON-LD.
22
- - Cutting an AI-tell, fluff-padded draft down to the depth the query actually needs.
23
-
24
15
  ## When NOT to use
25
16
 
26
17
  | You want… | Go to |
@@ -109,14 +100,6 @@ Every article ships with these. Keep them in the file's front-matter or a clearl
109
100
  - **Slug**: short, lowercase, hyphenated, keyword-bearing, no stop-word noise — `/compost-in-apartment` not `/how-to-start-composting-in-your-apartment-today`.
110
101
  - **FAQ block**: 3–6 real questions from "People also ask", each answered in 2–4 sentences.
111
102
 
112
- Quick checklist:
113
-
114
- - [ ] Title 50–60 chars, keyword in first ~35
115
- - [ ] Meta 140–160 chars, value-first
116
- - [ ] Exactly one H1
117
- - [ ] Slug short + keyword-bearing
118
- - [ ] FAQ questions match visible page content
119
-
120
103
  Full pixel/char tables, slug rules, and copy-ready `Article`/`BlogPosting` + `FAQPage` JSON-LD (JSON-LD only — never microdata) live in [`references/on-page-seo.md`](references/on-page-seo.md). The JSON-LD must describe what is actually on the page; schema that does not match visible content is a quality flag, not a win.
121
104
 
122
105
  ## Internal links and topical authority
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: astro
3
- description: "Use when building a content-driven or marketing site with Astro 6 — static-first pages, islands, content collections, partial hydration, server islands, per-route on-demand rendering, and deploy adapters. Triggers: 'Astro blog with content collections', 'make this widget interactive only when it scrolls into view', 'server island to personalize a static page', 'migrate Astro 5 to 6', the non-obvious 'ship zero JS but keep one form interactive', and Catalan/Spanish 'web de marketing rápida con Astro' / 'una web de contingut amb Astro'. NOT app-router React or server actions (that is nextjs)."
3
+ description: "Use when building a content-driven or marketing site with Astro 6: static-first pages, islands and partial hydration, content collections, server islands, per-route on-demand rendering, deploy adapters, and Astro 5→6 migration. NOT app-router React with server actions and heavy client interactivity (that is `nextjs`)."
4
4
  tags: [astro, ssg, islands, content-collections, partial-hydration, marketing-site, frameworks]
5
5
  recommends: [landing-copy, seo-geo, vercel, cloudflare, netlify]
6
6
  origin: risco
@@ -8,41 +8,31 @@ origin: risco
8
8
 
9
9
  # Astro 6 — static-first sites, islands, content collections
10
10
 
11
- > Build fast content and marketing sites with Astro 6: ship zero client JS by default, hydrate the
12
- > smallest possible surface, model content with type-safe collections, deploy static or hybrid.
13
-
14
11
  ## The prime directive
15
12
 
16
13
  **Ship zero client JavaScript by default. Hydrate the smallest possible surface, as late as you can
17
- get away with.** Every island is a JS bundle the visitor downloads, parses, and executes — marketing
18
- and content sites win on TTFB/LCP and Lighthouse, not on React-everywhere. An `.astro` component
19
- renders to HTML at build time and ships *no* runtime. Only reach for an interactive island when a
20
- piece of UI genuinely needs client state, effects, or event handlers.
21
-
22
- If you find yourself adding `client:load` to make a page "work," stop — the page already works; you
23
- are adding interactivity, and interactivity is the expensive exception, not the default.
14
+ get away with.** An `.astro` component renders to HTML at build time and ships *no* runtime; every
15
+ island is a bundle the visitor downloads, parses, and executes. Content and marketing sites win on
16
+ TTFB/LCP and Lighthouse, not on React-everywhere. If you find yourself adding `client:load` to make
17
+ a page "work," stop — the page already works; you are adding interactivity, and interactivity is the
18
+ expensive exception, not the default.
24
19
 
25
20
  ## First: detect the project version
26
21
 
27
- Astro 6.0 is stable (released 2026-03-10); the Astro 5 line is still production-ready. Do not mix
28
- advice across majors. Every v6-only claim below is sourced to the official release post or the
29
- upgrade guide — cited inline so you can re-check before acting.
30
-
31
- 1. Read `package.json` → the `astro` version.
32
- 2. Astro 6 **requires Node `22.12.0` or higher** (Node 18 and 20 are dropped) — verbatim floor from
33
- the [upgrade-to-v6 guide](https://docs.astro.build/en/guides/upgrade-to/v6/). Check the runtime.
34
- 3. v6 content config lives at `src/content.config.ts`. The legacy `src/content/config.ts` path is
35
- **removed**, not merely discouraged: the v6 upgrade guide instructs you to "Rename and move this
36
- file to `src/content.config.ts`," and the old auto-detection (with the `legacy.collections` flag)
37
- is gone. A temporary `legacy.collectionsBackwardsCompat` escape hatch exists but is a migration
38
- crutch, not a supported layout.
39
- 4. v6 ships **Vite 7** (Vite v7.0), **Zod 4** for content schemas (imported from `astro/zod`, **not**
40
- `astro:content` — see Content collections below), and makes **Live Content Collections**, the
41
- **Fonts API**, and the **CSP API** stable. Sources: [Astro 6.0 release post,
42
- 2026-03-10](https://astro.build/blog/astro-6/) and the
43
- [upgrade-to-v6 guide](https://docs.astro.build/en/guides/upgrade-to/v6/). (v6 also ships an
44
- *experimental* Rust compiler succeeding the Go one — experimental, so do not rely on or configure
45
- it in production advice.)
22
+ Astro 6.0 is stable ([released 2026-03-10](https://astro.build/blog/astro-6/)); the Astro 5 line is
23
+ still production-ready. Do not mix advice across majors — read `package.json` → the `astro` version
24
+ before advising. What v6 changes, per the
25
+ [upgrade-to-v6 guide](https://docs.astro.build/en/guides/upgrade-to/v6/):
26
+
27
+ - **Node `22.12.0` or higher is required** (18 and 20 are dropped) — check the actual runtime.
28
+ - Content config lives at `src/content.config.ts`. The legacy `src/content/config.ts` path is
29
+ **removed**, not merely discouraged, and the old auto-detection (`legacy.collections`) is gone.
30
+ The `legacy.collectionsBackwardsCompat` escape hatch is a migration crutch, not a supported layout.
31
+ - **Vite 7** and **Zod 4** for content schemas — `z` is imported from `astro/zod`, **not**
32
+ `astro:content` (see Content collections below).
33
+ - **Live Content Collections**, the **Fonts API** and the **CSP API** are stable.
34
+ - The Rust compiler succeeding the Go one is *experimental* — do not rely on or configure it in
35
+ production advice.
46
36
 
47
37
  ## Decision table — what kind of thing is this?
48
38
 
@@ -160,8 +150,8 @@ const { Content } = await render(post);
160
150
  ```
161
151
 
162
152
  Built-in loaders are `glob()` (many files) and `file()` (one JSON/YAML array). Custom and CMS
163
- loaders, collection references, Live Content Collections (real-time data with no rebuild, stable in
164
- v6), and MDX details → `references/content-layer.md`.
153
+ loaders, Zod 4 schema patterns, collection references, Live Content Collections (real-time data with
154
+ no rebuild, stable in v6), querying and MDX details → `references/content-layer.md`.
165
155
 
166
156
  ## Server islands
167
157
 
@@ -202,14 +192,13 @@ npx astro add react mdx sitemap
202
192
 
203
193
  - **Tailwind 4** wires through the official **Vite plugin** (`@tailwindcss/vite`), not the legacy
204
194
  `@astrojs/tailwind` integration (that path was for Tailwind 3).
205
- - **Fonts API** (stable in v6 per the [Astro 6.0 release post,
206
- 2026-03-10](https://astro.build/blog/astro-6/)) self-hosts and optimizes fonts from
207
- `astro.config.mjs` — no manual `@font-face`.
208
- - **CSP API** (stable in v6, same release) emits a Content-Security-Policy with hashes for your
209
- inline scripts/styles.
195
+ - **Fonts API** (stable in v6) self-hosts and optimizes fonts from `astro.config.mjs` — no manual
196
+ `@font-face`.
197
+ - **CSP API** (stable in v6) emits a Content-Security-Policy with hashes for your inline
198
+ scripts/styles.
210
199
 
211
- Adapter recipes, env handling, and SSR endpoints (`src/pages/api/*.ts`) →
212
- `references/deploy-and-integrations.md`.
200
+ Adapter recipes per platform, hybrid rendering, env handling, SSR endpoints (`src/pages/api/*.ts`)
201
+ and the Fonts/CSP config → `references/deploy-and-integrations.md`.
213
202
 
214
203
  ## Performance rules
215
204
 
@@ -235,9 +224,9 @@ npx @astrojs/upgrade
235
224
  legacy path is removed, not just deprecated).
236
225
  - [ ] Full guide (dated 2026): `docs.astro.build/en/guides/upgrade-to/v6`.
237
226
 
238
- ## Anti-patterns → STOP
227
+ ## Anti-patterns
239
228
 
240
- | Rationalization | Reality / STOP |
229
+ | Anti-pattern | Reality |
241
230
  | -------------------------------------------------------- | --------------------------------------------------------------------------- |
242
231
  | "Add `client:load` so the page works" | An `.astro` page already works statically; you're shipping JS for nothing |
243
232
  | "`client:load` everywhere, simplest" | Pick `client:visible`/`idle`/`media`; first-paint JS is the LCP killer |
@@ -251,19 +240,12 @@ npx @astrojs/upgrade
251
240
 
252
241
  ## Verify
253
242
 
254
- Run `bash scripts/verify.sh` from the Astro project root. It is grep-based and needs no install: it
255
- **FAILS** if a v6 project still has `src/content/config.ts` instead of `src/content.config.ts`,
256
- **WARNS** on over-hydration smells (many `client:load`, or `client:only` with no framework string),
257
- **CHECKS** that content schemas import from `astro:content`, and — only if the `astro` binary
258
- resolves — optionally runs `npx astro check`. On an empty or clean tree it prints OK and exits 0;
259
- warnings are advisory and never fail the run.
260
-
261
- ## References
262
-
263
- - `references/content-layer.md` — loaders (`glob`/`file`/custom/CMS), Zod 4 schema patterns,
264
- collection references, Live Content Collections, querying & rendering, MDX.
265
- - `references/deploy-and-integrations.md` — adapter table per platform, hybrid rendering, SSR
266
- endpoints, env handling, `astro add` recipes, Fonts API & CSP API config.
243
+ `bash scripts/verify.sh` from the Astro project root — grep-based, needs no install. It **FAILS** if
244
+ a v6 project still has `src/content/config.ts` instead of `src/content.config.ts`, **WARNS** on
245
+ over-hydration smells (many `client:load`, or `client:only` with no framework string), **CHECKS**
246
+ that content schemas import from `astro:content`, and — only if the `astro` binary resolves —
247
+ optionally runs `npx astro check`. On an empty or clean tree it prints OK and exits 0; warnings are
248
+ advisory and never fail the run.
267
249
 
268
250
  ## See Also
269
251