@ericrisco/rsc 0.1.56 → 0.1.58

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: spring-boot
3
- description: "Use when building, reviewing, testing, securing, or configuring a Spring Boot 4 / Spring Framework 7 backend — controllers, services, Spring Data JPA, application.yml, SecurityFilterChain, slice tests. Triggers: 'add a REST endpoint', 'wire up @Service and @Repository', 'my @Transactional isn't rolling back', 'LazyInitializationException after the session closed', 'N+1 select on a lazy collection', '@WebMvcTest + mock the service', 'migrate WebSecurityConfigurerAdapter', 'monta la seguridad con SecurityFilterChain', 'per què surt LazyInitializationException', a file importing org.springframework.boot.*, a pom.xml with spring-boot-starter-web, or an application.yml. NOT plain modern-Java language work like records/streams/virtual threads (that is java); NOT engine-level SQL schema/index/EXPLAIN (that is postgresdb); NOT container/CI mechanics (that is deployment)."
3
+ description: "Use when building, reviewing, testing, securing or configuring a Spring Boot 4 / Framework 7 backend — controllers, services, Spring Data JPA, application.yml, SecurityFilterChain, slice tests. NOT plain modern-Java language work like records or virtual threads (that is `java`); NOT engine-level SQL schema/index/EXPLAIN (that is `postgresdb`)."
4
4
  tags: [java, spring, jpa, security, backend]
5
5
  recommends: [java, postgresdb, secure-coding, deployment]
6
6
  origin: risco
@@ -23,47 +23,18 @@ If you are typing `WebSecurityConfigurerAdapter`, `@MockBean`, field `@Autowired
23
23
  `authorizeRequests`, or `javax.persistence` — **stop**. Those are the previous generation.
24
24
  The modern idioms below replace every one of them.
25
25
 
26
- ## When to use
27
-
28
- - Writing or reviewing any `@RestController`, `@Service`, `@Repository`, `@Component`,
29
- `@Configuration`, Spring Data JPA `@Entity`, or repository interface.
30
- - JPA persistence: entity mapping, `JpaRepository`, derived queries, `@Query`,
31
- `@Transactional` boundaries, fetch strategy / N+1, pagination.
32
- - Spring Security: `SecurityFilterChain`, method security, JWT resource server, OAuth2
33
- client, password encoding, CORS.
34
- - Configuration & profiles: `application.yml`, `@ConfigurationProperties`, `@Profile`,
35
- externalized secrets, `spring.config.import`.
36
- - Testing: `@SpringBootTest` vs slices (`@WebMvcTest`, `@DataJpaTest`), `@MockitoBean`,
37
- `MockMvc`, Testcontainers + `@ServiceConnection`.
38
-
39
- ## When NOT to use
26
+ ## Boundaries
40
27
 
41
28
  - Plain Java language work (records, sealed types, virtual threads, streams, pattern
42
- matching) with no Spring -> **`../java/SKILL.md`**.
43
- - Async Python FastAPI -> **`../fastapi/SKILL.md`**. NestJS/Node -> **`../nestjs/SKILL.md`**. Django -> `django`.
29
+ matching) with no Spring -> [`../java/SKILL.md`](../java/SKILL.md).
30
+ - Async Python FastAPI -> [`../fastapi/SKILL.md`](../fastapi/SKILL.md). NestJS/Node ->
31
+ [`../nestjs/SKILL.md`](../nestjs/SKILL.md). Django -> [`../django/SKILL.md`](../django/SKILL.md).
44
32
  - Engine-level SQL: schema/index design, `EXPLAIN`, partitioning, zero-downtime DDL ->
45
- **`../postgresdb/SKILL.md`** (this skill drives the JPA layer above it).
46
- - Language-agnostic injection/authz/secret theory -> **`../secure-coding/SKILL.md`**.
47
- - Dockerfile/Compose/CI/CD mechanics -> **`../deployment/SKILL.md`** (keep only a build note here).
48
-
49
- ## Decision rules
50
-
51
- 1. **Constructor injection only — final fields, no `@Autowired` on fields.** A class whose
52
- collaborators are constructor args is testable with `new` and fails fast on a missing bean.
53
- 2. **Controller stays thin: parse, validate, delegate, map.** Any branch with business
54
- meaning belongs in the service, where it is transactional and unit-testable without MVC.
55
- 3. **`@Transactional` lives on service methods, never on a controller or repository.** The
56
- transaction must wrap the unit of work, not the HTTP request or a single query.
57
- 4. **Expose DTO records in and out — never the `@Entity`.** Returning an entity leaks columns
58
- and triggers lazy loads inside the JSON serializer (the classic `LazyInitializationException`).
59
- 5. **Typed `@ConfigurationProperties` record over scattered `@Value`.** One validated binding
60
- beats string keys sprinkled across the codebase and gives you a fail-fast startup.
61
- 6. **Security is a `SecurityFilterChain` bean with the lambda DSL** — `authorizeHttpRequests`
62
- + `requestMatchers`. `WebSecurityConfigurerAdapter`, `authorizeRequests`, `antMatchers` are gone.
63
- 7. **Reach for the narrowest test slice first.** `@WebMvcTest` for a controller,
64
- `@DataJpaTest` for a repository; `@SpringBootTest` only when you genuinely need the full context.
65
- 8. **Validate at the edge with `@Valid` + Bean Validation (`jakarta.validation`).** Reject
66
- bad input before it reaches the service so business code assumes valid data.
33
+ [`../postgresdb/SKILL.md`](../postgresdb/SKILL.md) (this skill drives the JPA layer above it).
34
+ - Language-agnostic injection/authz/secret theory ->
35
+ [`../secure-coding/SKILL.md`](../secure-coding/SKILL.md).
36
+ - Dockerfile/Compose/CI/CD mechanics -> [`../deployment/SKILL.md`](../deployment/SKILL.md)
37
+ (keep only a build note here).
67
38
 
68
39
  ## Project layout
69
40
 
@@ -84,9 +55,12 @@ com.acme.shop
84
55
 
85
56
  ## Controllers
86
57
 
87
- `@RestController` + DTO records, `@Valid` on the body, `ResponseEntity` for 201/`Location`,
88
- a `@RestControllerAdvice` for one error envelope. Boot 4 adds first-class versioning via a
89
- `version` attribute on the mapping — one controller serves many versions, no path duplication.
58
+ `@RestController` + DTO records, `@Valid` on the body (Bean Validation, `jakarta.validation`)
59
+ so business code can assume valid data, `ResponseEntity` for 201/`Location`, a
60
+ `@RestControllerAdvice` for one error envelope. The controller parses, validates, delegates
61
+ and maps — any branch with business meaning belongs in the service, where it is transactional
62
+ and unit-testable without MVC. Boot 4 adds first-class versioning via a `version` attribute
63
+ on the mapping — one controller serves many versions, no path duplication.
90
64
 
91
65
  ```java
92
66
  @RestController
@@ -120,7 +94,7 @@ class ApiExceptionHandler {
120
94
  record ApiError(String code, String message, List<String> details) {}
121
95
  ```
122
96
 
123
- **Bad -> Good** — never return the entity:
97
+ **Bad -> Good** — never return the entity; it leaks columns and lazy-loads in the serializer:
124
98
 
125
99
  ```java
126
100
  // Bad: leaks columns; lazy fields blow up in the serializer after the tx closes.
@@ -132,7 +106,9 @@ record ApiError(String code, String message, List<String> details) {}
132
106
  ## Service + transactions
133
107
 
134
108
  Constructor-injected, `final` fields, `@Transactional` on the write path, `readOnly = true`
135
- on queries (lets Hibernate skip dirty checking).
109
+ on queries (lets Hibernate skip dirty checking). `@Transactional` belongs on service methods,
110
+ never on a controller or repository: the transaction must wrap the unit of work, not the HTTP
111
+ request or a single query.
136
112
 
137
113
  ```java
138
114
  @Service
@@ -233,11 +209,13 @@ record AppProperties(Duration inviteTtl, int maxOrdersPerDay) {} // typed, val
233
209
  ```
234
210
 
235
211
  **Bad -> Good** — scattered `@Value("${app.max-orders-per-day}")` strings vs one injected
236
- `AppProperties` record. Typed binding fails fast on a missing/mistyped key instead of NPE-ing later.
212
+ `AppProperties` record. One typed binding beats string keys sprinkled across the codebase and
213
+ fails fast on a missing/mistyped key instead of NPE-ing later.
237
214
 
238
215
  ## Security
239
216
 
240
- A single `SecurityFilterChain` bean, stateless for token APIs, JWT via the resource server.
217
+ A single `SecurityFilterChain` bean with the lambda DSL, stateless for token APIs, JWT via the
218
+ resource server.
241
219
 
242
220
  ```java
243
221
  @Configuration
@@ -264,11 +242,12 @@ Order `requestMatchers` from most specific to least — the first match wins, so
264
242
  `permitAll` placed early opens routes you meant to lock. Full JWT/OAuth2 client, method
265
243
  security, CORS, and CSRF posture (token vs cookie apps) live in
266
244
  [`references/security.md`](references/security.md). For the language-agnostic authz/secret
267
- principles behind these rules, see `../secure-coding/SKILL.md`.
245
+ principles behind these rules, see [`../secure-coding/SKILL.md`](../secure-coding/SKILL.md).
268
246
 
269
247
  ## Testing
270
248
 
271
- Pick the narrowest slice that exercises what you changed:
249
+ Pick the narrowest slice that exercises what you changed — `@SpringBootTest` only when you
250
+ genuinely need the full context:
272
251
 
273
252
  | Slice | Loads | Use for | Collaborators |
274
253
  |---|---|---|---|
@@ -324,14 +303,17 @@ interface BillingClient {
324
303
  `@Retryable` and `@ConcurrencyLimit` are core in Framework 7 — no extra Spring Retry
325
304
  dependency for the basics.
326
305
 
327
- ## Anti-patterns / rationalizations -> STOP
306
+ ## Anti-patterns
328
307
 
329
- | You are about to... | Why it's wrong | Do instead |
308
+ | Anti-pattern | Why it's wrong | Do instead |
330
309
  |---|---|---|
331
310
  | Extend `WebSecurityConfigurerAdapter` | Removed in Security 6/7 | `SecurityFilterChain` bean + lambda DSL |
332
311
  | `@Autowired` on a field | Untestable, hides missing beans till runtime | constructor injection, `final` fields |
333
312
  | `@Transactional` on a `@RestController` | Tx must wrap the unit of work, not the request | put it on the service method |
313
+ | Business branching in the controller | Not transactional, needs MVC to test | move the decision into the `@Service` |
334
314
  | Return the `@Entity` from a controller | Leaks columns, lazy-loads in serializer (LIE) | map to a DTO record inside the tx |
315
+ | Request body reaching the service unvalidated | Business code can no longer assume valid data | `@Valid` + `jakarta.validation` at the edge |
316
+ | Scattered `@Value("${...}")` config keys | String keys, no validation, fails late | one typed `@ConfigurationProperties` record |
335
317
  | Use `@MockBean` / `@SpyBean` | Replaced in Boot 4 | `@MockitoBean` / `@MockitoSpyBean` |
336
318
  | `import javax.persistence` / `javax.validation` | Jakarta EE 11 baseline | `jakarta.*` |
337
319
  | `authorizeRequests` / `antMatchers` | Gone in Security 6/7 | `authorizeHttpRequests` + `requestMatchers` |
@@ -341,6 +323,8 @@ dependency for the basics.
341
323
  | `catch (Exception e)` and echo `e.getMessage()` | Leaks internals, swallows bugs | `@RestControllerAdvice` + typed error envelope |
342
324
  | Serialize a lazy collection after the tx closes | `LazyInitializationException` / N+1 | fetch join or `@EntityGraph`, map in-tx |
343
325
 
326
+ `scripts/verify.sh` greps a project for the legacy idioms above (read-only, best effort).
327
+
344
328
  ## Quick reference
345
329
 
346
330
  | Task | Idiom |
@@ -364,12 +348,3 @@ If the repo has a `02-DOCS/` wiki, record stack decisions (Boot version, securit
364
348
  test strategy, migration tool) in `02-DOCS/wiki/stack/spring-boot.md` and link it from the
365
349
  `CLAUDE.md` Knowledge map. This is recorded, not gated — if there is no `02-DOCS/`, skip
366
350
  silently; you may suggest the project harness if the user wants persistent docs.
367
-
368
- ## See also
369
-
370
- - `../java/SKILL.md` — the language underneath (records, virtual threads, streams).
371
- - `../postgresdb/SKILL.md` — the engine under JPA (schema, indexes, `EXPLAIN`).
372
- - `../secure-coding/SKILL.md` — the authz/injection/secret principles behind the security rules.
373
- - `../deployment/SKILL.md` — packaging the jar, container, CI.
374
- - [`references/jpa.md`](references/jpa.md) · [`references/security.md`](references/security.md) · [`references/testing.md`](references/testing.md)
375
- - `scripts/verify.sh` — best-effort static reviewer for legacy Spring idioms.
@@ -4,7 +4,7 @@ should_trigger:
4
4
  - prompt: "Add a REST endpoint to create an order in our Spring Boot service."
5
5
  why: "Core controller/service work — the central job of the skill."
6
6
  - prompt: "My @Transactional method isn't rolling back when it throws, why?"
7
- why: "Non-obvious proxy self-invocation + checked-exception-no-rollback rule; a defining Spring trap."
7
+ why: "Non-obvious proxy self-invocation + checked-exception-no-rollback trap; documented in the service/transactions section."
8
8
  - prompt: "I get LazyInitializationException when the JSON serializer reads the response."
9
9
  why: "Classic JPA fetch/session-boundary symptom; the fix is map-to-DTO-in-tx, a core rule here."
10
10
  - prompt: "Migra esta config de seguridad, usa WebSecurityConfigurerAdapter y está deprecada."
@@ -12,7 +12,7 @@ should_trigger:
12
12
  - prompt: "Set up a @WebMvcTest for the controller and mock the service."
13
13
  why: "Slice testing + @MockitoBean — non-obvious that @MockBean is the wrong (removed) idiom."
14
14
  - prompt: "Configura @ConfigurationProperties con perfiles para esta app."
15
- why: "Catalan/Spanish; typed config + profiles is a named decision rule."
15
+ why: "Catalan/Spanish; typed @ConfigurationProperties + profiles is a documented config surface."
16
16
  - prompt: "We have N+1 selects on a lazy collection — how do I fetch-join it?"
17
17
  why: "JPA fetch strategy / @EntityGraph, a documented depth area."
18
18
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: together-fireworks
3
- description: "Use when calling hosted open-model inference on Together AI or Fireworks AI — pointing the OpenAI SDK at api.together.ai or api.fireworks.ai, picking an open model (Llama, DeepSeek, Qwen, GPT-OSS) and what it costs, or cutting the bill with batch inference. Triggers: 'call DeepSeek/Llama on Together', 'wire the OpenAI SDK to Fireworks', 'why is my model name 404ing', 'which open-source model and how much per million tokens', 'halve my LLM bill with batch', 'move off GPT-4 to a cheaper open-weights endpoint', 'serverless vs dedicated for sustained QPS', '¿qué modelo open source uso y cuánto cuesta?', 'abaratar la factura de inferència'. NOT renting raw GPUs to self-host weights (that is runpod), NOT running a model locally with zero marginal cost (that is ollama)."
3
+ description: "Use when calling open-weight LLMs on Together AI or Fireworks AI's OpenAI-compatible endpoints — `base_url` plus namespaced model id, the cheapest model that clears the bar, per-1M-token cost math, serverless vs batch vs dedicated. NOT renting GPUs to self-host weights (that is `runpod`), NOT running a model locally for free (that is `ollama`)."
4
4
  tags: [llm, inference, together-ai, fireworks-ai, openai-compatible, open-models, batch, cost]
5
5
  recommends: [runpod, modal, ollama, huggingface, fal, cost-tracking, llm-pipeline, prompt-engineering, embeddings-search]
6
6
  origin: risco
@@ -107,7 +107,7 @@ Fuller catalog and embedding/fine-tuning numbers: `references/models-and-pricing
107
107
 
108
108
  Decision: **real-time → serverless. Big offline job (eval, synthetic data, bulk classify) → batch. Sustained heavy traffic with an SLA → dedicated.**
109
109
 
110
- > **Gotcha — Together batch is NOT the OpenAI Batch endpoint.** Together's OpenAI-compat layer does **not** expose `/v1/batches`. Use Together's **native Batch API**: upload a JSONL file, default **24h** window, up to **50,000 requests/file**, up to **50% off**, separate rate-limit pool. Pointing the OpenAI Batch client at Together fails. Fireworks instead exposes Batch as a serving *path* through the one API (Serverless 2.0: Standard / Priority / Batch), batch = 50% of serverless. See `references/batch-and-tuning.md`.
110
+ > **Gotcha — Together batch is NOT the OpenAI Batch endpoint.** Together's OpenAI-compat layer does **not** expose `/v1/batches`. Use Together's **native Batch API**: upload a JSONL file, default **24h** window, up to **50,000 requests/file**, up to **50% off**, separate rate-limit pool. Pointing the OpenAI Batch client at Together fails. Fireworks instead exposes Batch as a serving *path* through the one API (Serverless 2.0: Standard / Priority / Batch), batch = 50% of serverless. JSONL shape, the upload/poll/download flow, limits, and dedicated-deployment notes: `references/batch-and-tuning.md`.
111
111
 
112
112
  Two more Fireworks multipliers worth knowing:
113
113
  - **Cached input tokens default to 50%** of input price (text/vision models) — repeated prefixes get cheaper automatically.
@@ -173,9 +173,4 @@ Keep the id mapping in config, not in `if provider == ...` branches scattered th
173
173
  | Treating these like free/local | They bill per token; ollama is the zero-marginal-cost path | If cost must be zero and weights run on your box → `../ollama/SKILL.md` |
174
174
  | Renting GPUs to "save money" then idling them | A serverless token endpoint has no idle cost | Self-host only at sustained scale → `../runpod/SKILL.md` |
175
175
 
176
- ## References
177
-
178
- - `references/models-and-pricing.md` — fuller per-provider model + pricing tables, embeddings, fine-tuning costs, with a re-check note.
179
- - `references/batch-and-tuning.md` — Together native Batch API JSONL shape + upload/poll/download flow and limits; Fireworks batch path; dedicated deployment notes.
180
-
181
176
  Validate any inference snippet/config with `scripts/verify.sh <file-or-dir>` — a static, no-network lint for the right base URLs, namespaced model ids, and env-var keys.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: youtube-api
3
- description: "Use when connecting a real YouTube channel to code via the Data API v3 (uploads, metadata) and Analytics API v2 (performance) — OAuth, resumable video upload, editing title/description/tags/privacy after publish, pulling views/watch time/averageViewPercentage/retention/traffic sources — and logging that performance into 02-DOCS/wiki/youtube/ as a dated feedback log. Triggers: 'upload a video to my channel via the API and set its tags', 'videos.insert returns 403 quotaExceeded / uploadLimitExceeded', 'my YouTube refresh token keeps dying after about 7 days', 'pull the audienceWatchRatio retention curve for video X', 'fetch this month's traffic sources and write them into the wiki', 'subir vídeos a YouTube por API y guardar las estadísticas del canal', 'treure les estadístiques del canal i guardar-les al wiki'. NOT what-to-publish or how-to-package it (that is youtube-strategy / youtube-packaging)."
3
+ description: "Use when wiring code to a real YouTube channel: user OAuth 2.0, resumable videos.insert uploads, editing metadata after publish, pulling views/watch time/retention/traffic from the Analytics API v2 into a dated 02-DOCS/wiki/youtube/ feedback log. NOT what to publish or how to title and thumbnail it (that is youtube-strategy / youtube-packaging)."
4
4
  tags: [youtube, youtube-data-api, youtube-analytics-api, oauth2, resumable-upload, video-metadata, audience-retention, channel-feedback-log]
5
5
  recommends: [social-publisher, api-connector-builder, automation-flows, knowledge-ops]
6
6
  origin: risco
@@ -17,31 +17,20 @@ YouTube has **two separate APIs** and you will touch both:
17
17
 
18
18
  Auth is **user OAuth 2.0, not a service account.** A human owns the channel; you act on their behalf with a refresh token. A service account cannot own a YouTube channel — if you reach for one, stop. (Service-account Google auth for Gmail/Drive/Sheets is `google-workspace`, a different model.)
19
19
 
20
- ## When to use / When NOT
21
-
22
- Use when:
23
-
24
- - Wiring a script or agent to upload to a channel (`videos.insert`), set metadata, schedule a publish, or set a custom thumbnail.
25
- - Editing an existing video's title/description/tags/privacy after publish (`videos.update`).
26
- - Pulling channel or per-video stats: views, `estimatedMinutesWatched`, `averageViewPercentage`, the audience-retention curve, the traffic-source breakdown.
27
- - Building the recurring "fetch performance → write to `02-DOCS/wiki/youtube/`" loop that turns API responses into a channel feedback log.
28
- - Debugging `403 quotaExceeded`, `uploadLimitExceeded` (429), `401 invalid_credentials`, scope errors, or a refresh token that dies after a week.
29
-
30
- Do NOT use when (route to the sibling that owns it):
20
+ Route elsewhere when the job is not transport:
31
21
 
32
22
  | You actually want | Go to |
33
23
  | --- | --- |
34
- | What videos to make / niche / cadence / growth plan | `youtube-strategy` *(catalog id)* |
35
- | Video ideas, hooks, a topic backlog | `youtube-ideation` *(catalog id)* |
36
- | Title + thumbnail packaging, CTR copy, A/B framing | `youtube-packaging` *(catalog id)* |
24
+ | What videos to make / niche / cadence / growth plan | `../youtube-strategy/SKILL.md` |
25
+ | Video ideas, hooks, a topic backlog | `../youtube-ideation/SKILL.md` |
26
+ | Title + thumbnail packaging, CTR copy, A/B framing | `../youtube-packaging/SKILL.md` |
37
27
  | The thumbnail image itself | `../youtube-thumbnails/SKILL.md` |
38
28
  | Render/produce the actual video file in code | `../remotion-video/SKILL.md` |
39
29
  | Post one asset across many networks at once | `../social-publisher/SKILL.md` |
40
- | Wrap an arbitrary REST provider with OAuth + retries | `api-connector-builder` *(catalog id)* |
41
- | Chain upload → Notion row → Slack across tools | `automation-flows` *(catalog id)* |
42
- | Service-account auth to Gmail/Drive/Sheets | `google-workspace` *(catalog id)* |
43
-
44
- One line: **this skill authenticates, calls, and ingests the two YouTube APIs into the wiki. What to publish and how to package it belong to the youtube-strategy / youtube-ideation / youtube-packaging siblings.**
30
+ | Wrap an arbitrary REST provider with OAuth + retries | `../api-connector-builder/SKILL.md` |
31
+ | Chain upload → Notion row → Slack across tools | `../automation-flows/SKILL.md` |
32
+ | Service-account auth to Gmail/Drive/Sheets | `../google-workspace/SKILL.md` |
33
+ | Generic wiki structure and conventions | `../knowledge-ops/SKILL.md` |
45
34
 
46
35
  ## 1. One-time setup (do this before any code)
47
36
 
@@ -151,7 +140,7 @@ video_id = resp["id"]
151
140
  data.thumbnails().set(videoId=video_id, media_body=MediaFileUpload("ep14.jpg")).execute()
152
141
  ```
153
142
 
154
- Two separate limits, not one — and uploads no longer come out of the 10k unit pool. As of the official quota docs (Last updated 2026-06-01 UTC, `https://developers.google.com/youtube/v3/getting-started`), a project's default allocation is *"100 search.list calls, 100 videos.insert calls, and 10,000 units per day combined for all other endpoints."* So `videos.insert` has its **own dedicated cap of ~100 uploads/day**, charged against that allocation rather than spending ~1,600 units of the 10k pool like the older model. That ~100/day call cap is exactly what trips `uploadLimitExceeded` (429) while your 10k unit pool still looks untouched. Throttle the upload **count** against the 100/day allocation, not just the unit spend — space automated uploads out and back off on 429.
143
+ Throttle the upload **count**, not the unit spend: `videos.insert` has its own cap of ~100 uploads/day, so `uploadLimitExceeded` (429) hits while the 10k unit pool still looks untouched. Space automated uploads out and back off on 429 — figures and citation in §7.
155
144
 
156
145
  ## 4. Edit metadata after publish
157
146
 
@@ -254,7 +243,7 @@ Rule: **append, never overwrite.** The feedback log *is* the value — overwriti
254
243
  | `*.list` read | 1–5 units (from the 10k pool) |
255
244
  | Analytics `reports.query` | (separate Analytics quota) |
256
245
 
257
- Per the official docs (Last updated 2026-06-01 UTC, `https://developers.google.com/youtube/v3/getting-started`; per-method costs at `https://developers.google.com/youtube/v3/determine_quota_cost`), a project's default allocation is **100 `search.list` calls + 100 `videos.insert` calls + 10,000 units/day combined for all other endpoints**. Uploads and search each draw on their *own* daily call cap; everything else (writes, reads) spends the shared 10k-unit pool. All quotas reset at midnight Pacific. This is a change from the older single-pool model where `videos.insert` cost ~1,600 units — confirm the live figure on the quota-cost page before relying on it, since Google notes the allocation "is subject to change."
246
+ Per the official docs (Last updated 2026-06-01 UTC, `https://developers.google.com/youtube/v3/getting-started`; per-method costs at `https://developers.google.com/youtube/v3/determine_quota_cost`), a project's default allocation is *"100 search.list calls, 100 videos.insert calls, and 10,000 units per day combined for all other endpoints."* All quotas reset at midnight Pacific. This is a change from the older single-pool model where `videos.insert` cost ~1,600 units — confirm the live figure on the quota-cost page before relying on it, since Google notes the allocation "is subject to change."
258
247
 
259
248
  On `403 quotaExceeded` / `rateLimitExceeded` or `429`: **exponential backoff with jitter**, then stop for the day on a hard quota cap — retrying a daily-quota 403 in a tight loop just burns the next day too.
260
249
 
@@ -281,11 +270,3 @@ Error → cause map:
281
270
  | Treat the 10k unit pool as the upload budget | Uploads use a separate ~100/day call cap, so `uploadLimitExceeded` 429 hits with the pool untouched | Throttle upload count against the ~100/day cap |
282
271
  | Overwrite yesterday's wiki snapshot | Destroys the trend the siblings read | Append a new dated entry every pull |
283
272
  | Leave the app in "Testing" | Token silently dies in 7 days | Publish to "In production" |
284
-
285
- ## Cross-references
286
-
287
- - `../youtube-thumbnails/SKILL.md` — the thumbnail image this skill only *sets*.
288
- - `../social-publisher/SKILL.md` — when the asset goes to many networks, not just YouTube.
289
- - `../remotion-video/SKILL.md` — produce the video file this skill uploads.
290
- - `youtube-strategy`, `youtube-ideation`, `youtube-packaging` *(catalog ids)* — what the numbers *mean* and what to do next.
291
- - `api-connector-builder`, `automation-flows`, `knowledge-ops` *(catalog ids)* — generic connector wrapping, cross-tool chaining, and wiki conventions.