@ericrisco/rsc 0.1.57 → 0.1.59
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.
- package/manifest.json +16 -16
- package/package.json +1 -1
- package/skills/gamedev-physics/SKILL.md +1 -1
- package/skills/git-workflow/SKILL.md +1 -1
- package/skills/google-workspace/SKILL.md +25 -66
- package/skills/htmx/SKILL.md +1 -1
- package/skills/huggingface/SKILL.md +1 -1
- package/skills/inventory/SKILL.md +1 -1
- package/skills/investor-materials/SKILL.md +1 -1
- package/skills/ip-trademark/SKILL.md +1 -1
- package/skills/java/SKILL.md +1 -1
- package/skills/kotlin-android/SKILL.md +1 -1
- package/skills/kpi-framework/SKILL.md +1 -1
- package/skills/level-design/SKILL.md +25 -57
- package/skills/spring-boot/SKILL.md +34 -59
- package/skills/spring-boot/evals/cases.yaml +2 -2
- package/skills/together-fireworks/SKILL.md +2 -7
- package/skills/youtube-api/SKILL.md +11 -30
package/manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.1.
|
|
2
|
+
"version": "0.1.59",
|
|
3
3
|
"counts": {
|
|
4
4
|
"skills": 258
|
|
5
5
|
},
|
|
@@ -1930,7 +1930,7 @@
|
|
|
1930
1930
|
},
|
|
1931
1931
|
{
|
|
1932
1932
|
"id": "gamedev-physics",
|
|
1933
|
-
"description": "Use when working with a game engine's physics — rigid bodies, colliders, collision layers
|
|
1933
|
+
"description": "Use when working with a game engine's physics — rigid bodies, colliders, collision layers and masks, character controllers, joints, forces versus impulses, raycasts and shapecasts, or when a simulation is unstable (tunnelling, jitter, missed overlaps). Covers the Godot, Unity and Unreal equivalents. NOT rendering or shader-driven visual jitter (that is `gamedev-shaders`), NOT navigation, pathfinding or navmesh (that is `gamedev-pathing`).",
|
|
1934
1934
|
"tags": [
|
|
1935
1935
|
"physics",
|
|
1936
1936
|
"collision",
|
|
@@ -2047,7 +2047,7 @@
|
|
|
2047
2047
|
},
|
|
2048
2048
|
{
|
|
2049
2049
|
"id": "git-workflow",
|
|
2050
|
-
"description": "Use when naming or scoping a branch, writing or fixing a commit message, untangling history (rebase
|
|
2050
|
+
"description": "Use when naming or scoping a branch, writing or fixing a commit message, untangling history (rebase versus merge versus squash), or cutting a versioned release — the portable git-convention layer for any repo. Covers Conventional Commits, SemVer tags, branch hygiene, force-push safety and gh pr/release mechanics. NOT the land-it decision and pre-ship checklist (that is `ship`), NOT an isolated checkout before coding (that is `worktrees`), NOT CI/CD release automation (that is `deployment`).",
|
|
2051
2051
|
"tags": [
|
|
2052
2052
|
"git",
|
|
2053
2053
|
"version-control",
|
|
@@ -2126,7 +2126,7 @@
|
|
|
2126
2126
|
},
|
|
2127
2127
|
{
|
|
2128
2128
|
"id": "google-workspace",
|
|
2129
|
-
"description": "Use when
|
|
2129
|
+
"description": "Use when server-side code reads or writes Gmail, Drive, Calendar, or Sheets with a GCP service account and no human in the OAuth loop: picking the auth mode (app-owned vs domain-wide delegation vs keyless), scoping to least privilege, building the authed Node/Python client, staying under per-user quota, and debugging unauthorized_client / 403 / 429. NOT SMTP providers or deliverability (that is `email-connector`), NOT slot-finding and booking UX (that is `calendar-scheduling`).",
|
|
2130
2130
|
"tags": [
|
|
2131
2131
|
"google-workspace",
|
|
2132
2132
|
"gmail-api",
|
|
@@ -2235,7 +2235,7 @@
|
|
|
2235
2235
|
},
|
|
2236
2236
|
{
|
|
2237
2237
|
"id": "htmx",
|
|
2238
|
-
"description": "Use when adding interactivity to a server-rendered app (FastAPI/Jinja, Django, Rails, Laravel, Go templates, Express) without adopting a JS framework
|
|
2238
|
+
"description": "Use when adding interactivity to a server-rendered app (FastAPI/Jinja, Django, Rails, Laravel, Go templates, Express) without adopting a JS framework — hx-get/post/put/delete with hx-target, hx-swap and hx-trigger, returning HTML fragments instead of JSON, out-of-band swaps, active search, infinite scroll, inline edit and polling. NOT a client-state SPA with routing and a store (that is `react` or `nextjs`).",
|
|
2239
2239
|
"tags": [
|
|
2240
2240
|
"htmx",
|
|
2241
2241
|
"hypermedia",
|
|
@@ -2253,7 +2253,7 @@
|
|
|
2253
2253
|
},
|
|
2254
2254
|
{
|
|
2255
2255
|
"id": "huggingface",
|
|
2256
|
-
"description": "Use when running open models or working on the Hugging Face platform
|
|
2256
|
+
"description": "Use when running open models or working on the Hugging Face platform — the Inference Providers router or InferenceClient, Hub repos via the hf CLI, a dedicated Inference Endpoint with scale-to-zero, a Gradio Space with ZeroGPU, picking an open model by task/license/size, or loading one locally with transformers. NOT serving locally on your own machine (that is `ollama`), NOT renting your own GPU box (that is `runpod`), NOT hosted creative image APIs (that is `replicate-images`), NOT fine-tuning with trl/peft (that is `finetuning`).",
|
|
2257
2257
|
"tags": [
|
|
2258
2258
|
"huggingface",
|
|
2259
2259
|
"inference-providers",
|
|
@@ -2335,7 +2335,7 @@
|
|
|
2335
2335
|
},
|
|
2336
2336
|
{
|
|
2337
2337
|
"id": "inventory",
|
|
2338
|
-
"description": "Use when deciding how much stock to hold and when to reorder it — classifying SKUs, sizing safety stock, setting reorder points and order quantities, and tracking
|
|
2338
|
+
"description": "Use when deciding how much stock to hold and when to reorder it — classifying SKUs, sizing safety stock, setting reorder points and order quantities, and tracking the KPIs that keep a business from either stocking out or sitting on dead stock. NOT raising or negotiating the purchase order itself (that is `procurement`).",
|
|
2339
2339
|
"tags": [
|
|
2340
2340
|
"reorder-point",
|
|
2341
2341
|
"safety-stock",
|
|
@@ -2358,7 +2358,7 @@
|
|
|
2358
2358
|
},
|
|
2359
2359
|
{
|
|
2360
2360
|
"id": "investor-materials",
|
|
2361
|
-
"description": "Use when packaging
|
|
2361
|
+
"description": "Use when packaging or circulating the documents an investor reads outside the meeting — setting up or cleaning a data room, writing the one-pager or teaser that earns the first meeting, or drafting the recurring monthly investor update. NOT the slide narrative (that is `pitch-deck`), NOT the projection spreadsheet (that is `financial-model`), NOT round strategy and the investor pipeline (that is `fundraising`).",
|
|
2362
2362
|
"tags": [
|
|
2363
2363
|
"fundraising",
|
|
2364
2364
|
"data-room",
|
|
@@ -2404,7 +2404,7 @@
|
|
|
2404
2404
|
},
|
|
2405
2405
|
{
|
|
2406
2406
|
"id": "ip-trademark",
|
|
2407
|
-
"description": "Use when a non-lawyer operator needs to protect a brand or creative work — clearing and choosing a name
|
|
2407
|
+
"description": "Use when a non-lawyer operator needs to protect a brand or creative work — clearing and choosing a name or logo, deciding whether and where to register a trademark, using the trademark and registered symbols correctly, knowing what copyright is automatic, or checking whether they own work a freelancer was paid for. NOT drafting the IP-assignment clause itself (that is `contracts`).",
|
|
2408
2408
|
"tags": [
|
|
2409
2409
|
"intellectual-property",
|
|
2410
2410
|
"trademark",
|
|
@@ -2422,7 +2422,7 @@
|
|
|
2422
2422
|
},
|
|
2423
2423
|
{
|
|
2424
2424
|
"id": "java",
|
|
2425
|
-
"description": "Use when writing, reviewing
|
|
2425
|
+
"description": "Use when writing, reviewing or refactoring modern Java (21+, 25 LTS) — records and sealed interfaces as algebraic data types, exhaustive pattern-matching switch over instanceof ladders, virtual-thread concurrency, structured concurrency and ScopedValue replacing ThreadLocal, Stream and Optional pipelines, compact-constructor validation, parametrized JDBC, and the Maven/Gradle build surface. NOT Spring framework wiring (that is `spring-boot`).",
|
|
2426
2426
|
"tags": [
|
|
2427
2427
|
"java",
|
|
2428
2428
|
"jvm",
|
|
@@ -2462,7 +2462,7 @@
|
|
|
2462
2462
|
},
|
|
2463
2463
|
{
|
|
2464
2464
|
"id": "kotlin-android",
|
|
2465
|
-
"description": "Use when building or fixing a native Android app in Kotlin
|
|
2465
|
+
"description": "Use when building or fixing a native Android app in Kotlin and Jetpack Compose on the UDF layered architecture — ViewModel/StateFlow, Hilt, Room, Retrofit, coroutines, type-safe Navigation, and the Gradle/AGP surface. NOT shared Android and iOS UI from one Kotlin codebase (that is `compose-multiplatform`).",
|
|
2466
2466
|
"tags": [
|
|
2467
2467
|
"kotlin",
|
|
2468
2468
|
"android",
|
|
@@ -2484,7 +2484,7 @@
|
|
|
2484
2484
|
},
|
|
2485
2485
|
{
|
|
2486
2486
|
"id": "kpi-framework",
|
|
2487
|
-
"description": "Use when a team must decide what to measure before building anything — picking one north-star metric, separating leading input drivers from lagging outputs, adding guardrails so a number
|
|
2487
|
+
"description": "Use when a team must decide what to measure before building anything — picking one north-star metric, separating leading input drivers from lagging outputs, adding guardrails so a number cannot be gamed, and setting a target that is not arbitrary. NOT the live dashboard that displays them (that is `dashboard`), NOT instrumenting the events (that is `analytics`), NOT the recurring board report (that is `reporting`).",
|
|
2488
2488
|
"tags": [
|
|
2489
2489
|
"north-star-metric",
|
|
2490
2490
|
"leading-vs-lagging",
|
|
@@ -2570,7 +2570,7 @@
|
|
|
2570
2570
|
},
|
|
2571
2571
|
{
|
|
2572
2572
|
"id": "level-design",
|
|
2573
|
-
"description": "Use when designing a game level
|
|
2573
|
+
"description": "Use when designing a game level's space — blockout/greybox layout, pacing that drags or spikes, guiding lost players without waypoints, encounter and arena progression, or secret placement. NOT mechanics or economy (that is `game-design`), NOT story beats (that is `game-storytelling`), NOT engine tooling like nav meshes or lightmaps (that is `godot`/`unity`/`unreal`).",
|
|
2574
2574
|
"tags": [
|
|
2575
2575
|
"level-design",
|
|
2576
2576
|
"blockout",
|
|
@@ -4466,7 +4466,7 @@
|
|
|
4466
4466
|
},
|
|
4467
4467
|
{
|
|
4468
4468
|
"id": "spring-boot",
|
|
4469
|
-
"description": "Use when building, reviewing, testing, securing
|
|
4469
|
+
"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`).",
|
|
4470
4470
|
"tags": [
|
|
4471
4471
|
"java",
|
|
4472
4472
|
"spring",
|
|
@@ -4823,7 +4823,7 @@
|
|
|
4823
4823
|
},
|
|
4824
4824
|
{
|
|
4825
4825
|
"id": "together-fireworks",
|
|
4826
|
-
"description": "Use when calling
|
|
4826
|
+
"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`).",
|
|
4827
4827
|
"tags": [
|
|
4828
4828
|
"llm",
|
|
4829
4829
|
"inference",
|
|
@@ -5240,7 +5240,7 @@
|
|
|
5240
5240
|
},
|
|
5241
5241
|
{
|
|
5242
5242
|
"id": "youtube-api",
|
|
5243
|
-
"description": "Use when
|
|
5243
|
+
"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).",
|
|
5244
5244
|
"tags": [
|
|
5245
5245
|
"youtube",
|
|
5246
5246
|
"youtube-data-api",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gamedev-physics
|
|
3
|
-
description: "Use when working with a game engine's physics — rigid bodies, colliders, collision layers
|
|
3
|
+
description: "Use when working with a game engine's physics — rigid bodies, colliders, collision layers and masks, character controllers, joints, forces versus impulses, raycasts and shapecasts, or when a simulation is unstable (tunnelling, jitter, missed overlaps). Covers the Godot, Unity and Unreal equivalents. NOT rendering or shader-driven visual jitter (that is `gamedev-shaders`), NOT navigation, pathfinding or navmesh (that is `gamedev-pathing`)."
|
|
4
4
|
tags: [physics, collision, rigidbody, character-controller, colliders]
|
|
5
5
|
recommends: [godot, unity, unreal, gamedev-pathing]
|
|
6
6
|
profiles: [full]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: git-workflow
|
|
3
|
-
description: "Use when naming or scoping a branch, writing or fixing a commit message, untangling history (rebase
|
|
3
|
+
description: "Use when naming or scoping a branch, writing or fixing a commit message, untangling history (rebase versus merge versus squash), or cutting a versioned release — the portable git-convention layer for any repo. Covers Conventional Commits, SemVer tags, branch hygiene, force-push safety and gh pr/release mechanics. NOT the land-it decision and pre-ship checklist (that is `ship`), NOT an isolated checkout before coding (that is `worktrees`), NOT CI/CD release automation (that is `deployment`)."
|
|
4
4
|
tags: [git, version-control, conventional-commits, semver, pull-request]
|
|
5
5
|
recommends: [ship, worktrees, deployment, github-actions]
|
|
6
6
|
origin: risco
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: google-workspace
|
|
3
|
-
description: "Use when
|
|
3
|
+
description: "Use when server-side code reads or writes Gmail, Drive, Calendar, or Sheets with a GCP service account and no human in the OAuth loop: picking the auth mode (app-owned vs domain-wide delegation vs keyless), scoping to least privilege, building the authed Node/Python client, staying under per-user quota, and debugging unauthorized_client / 403 / 429. NOT SMTP providers or deliverability (that is `email-connector`), NOT slot-finding and booking UX (that is `calendar-scheduling`)."
|
|
4
4
|
tags: [google-workspace, gmail-api, drive-api, calendar-api, sheets-api, service-account, domain-wide-delegation, oauth-scopes]
|
|
5
5
|
recommends: [email-connector, calendar-scheduling, spreadsheet-ops, document-processing, automation-flows, secure-coding, webhooks]
|
|
6
6
|
origin: risco
|
|
@@ -9,52 +9,22 @@ origin: risco
|
|
|
9
9
|
# Google Workspace — auth + calling Gmail/Drive/Calendar/Sheets
|
|
10
10
|
|
|
11
11
|
This skill owns one layer: **authenticating to and calling the four Google
|
|
12
|
-
Workspace REST APIs from server-side code.**
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
downloaded JSON key. A leaked key is the single most common Workspace
|
|
29
|
-
credential compromise.
|
|
30
|
-
- **Quota is a real constraint, not a footnote.** The per-user limits are tight
|
|
31
|
-
(6k units/min Gmail, 60 req/min Sheets). Build backoff in from line one.
|
|
32
|
-
|
|
33
|
-
## When to use / When NOT to use
|
|
34
|
-
|
|
35
|
-
**Use when:** a cron, webhook handler, or agent tool reads/writes Gmail, Drive,
|
|
36
|
-
Calendar, or Sheets without an interactive login; you must decide between
|
|
37
|
-
app-owned resources and impersonating each Workspace user; you hit
|
|
38
|
-
`403 insufficient permissions`, `403 rateLimitExceeded`, `429`, or
|
|
39
|
-
`unauthorized_client` and need the scope/delegation/quota fix; you are wiring
|
|
40
|
-
`googleapis` (Node) or `google-api-python-client` + `google-auth` (Python);
|
|
41
|
-
you are migrating off downloaded JSON keys toward keyless auth.
|
|
42
|
-
|
|
43
|
-
**Do NOT use for:**
|
|
44
|
-
|
|
45
|
-
- **Generic transactional/marketing email, SMTP, providers, deliverability,
|
|
46
|
-
SPF/DKIM** → `email-connector` and `email-deliverability`. This skill covers
|
|
47
|
-
Gmail-the-API inside a Workspace mailbox, not provider choice or inbox
|
|
48
|
-
placement.
|
|
49
|
-
- **Scheduling logic, availability, booking-link UX, timezone-as-a-feature** →
|
|
50
|
-
`calendar-scheduling`. This skill covers the raw Calendar event CRUD it sits
|
|
51
|
-
on top of.
|
|
52
|
-
- **Spreadsheet data modeling, formulas, pivots, transforms as the deliverable**
|
|
53
|
-
→ `spreadsheet-ops`. This skill covers the Sheets API read/write transport.
|
|
54
|
-
- **Doc/PDF parsing, extraction, OCR** → `document-processing`. Drive here is
|
|
55
|
-
storage transport (upload/download/move/permissions), not content extraction.
|
|
56
|
-
- **Multi-step orchestration across connectors** → `automation-flows`. **Notion**
|
|
57
|
-
→ `notion-connector`. **Generic REST wrapping** → `api-connector-builder`.
|
|
12
|
+
Workspace REST APIs from server-side code.** Everything here is service-account
|
|
13
|
+
/ machine auth — if a real user must click "Allow", that is interactive OAuth and
|
|
14
|
+
out of scope.
|
|
15
|
+
|
|
16
|
+
Where the neighbouring layers live:
|
|
17
|
+
|
|
18
|
+
| Not this skill | Goes to | This skill's slice |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| SMTP/provider choice, transactional/marketing sends | `email-connector` | Gmail-the-API inside a Workspace mailbox |
|
|
21
|
+
| SPF/DKIM, inbox placement | `email-deliverability` | — |
|
|
22
|
+
| Availability search, booking-link UX, timezone-as-a-feature | `calendar-scheduling` | Raw Calendar event CRUD underneath |
|
|
23
|
+
| Sheet data modeling, formulas, pivots | `spreadsheet-ops` | Sheets API read/write transport |
|
|
24
|
+
| Doc/PDF parsing, extraction, OCR | `document-processing` | Drive as storage transport (upload/download/move/permissions) |
|
|
25
|
+
| Chaining several connectors into one flow | `automation-flows` | The individual Google calls |
|
|
26
|
+
| Notion as the backend / generic REST wrapping | `notion-connector`, `api-connector-builder` | — |
|
|
27
|
+
| Receiving Gmail/Drive push notifications | `webhooks` | — |
|
|
58
28
|
|
|
59
29
|
## Pick your auth mode
|
|
60
30
|
|
|
@@ -72,7 +42,9 @@ large blast radius. Use it only when you genuinely must act as the user.
|
|
|
72
42
|
|
|
73
43
|
## Setup checklist
|
|
74
44
|
|
|
75
|
-
Do these in order.
|
|
45
|
+
Do these in order. `references/auth-setup.md` has the full Cloud + Admin
|
|
46
|
+
click-path, the scope catalog, DWD authorization, keyless WIF/ADC, and a longer
|
|
47
|
+
troubleshooting matrix.
|
|
76
48
|
|
|
77
49
|
1. **Enable the APIs** you will call in the Cloud console (Gmail, Drive,
|
|
78
50
|
Calendar, Sheets) for the project. A disabled API returns `403` regardless of
|
|
@@ -242,8 +214,9 @@ def with_backoff(call, max_retries=6, max_backoff=64):
|
|
|
242
214
|
- **Never commit the SA key JSON.** It is a long-lived bearer credential — a
|
|
243
215
|
committed `service_account.json` is game over. Add `*.json` SA patterns to
|
|
244
216
|
`.gitignore`; the `verify.sh` here flags tracked keys.
|
|
245
|
-
- **Prefer keyless.**
|
|
246
|
-
|
|
217
|
+
- **Prefer keyless.** A leaked key is the single most common Workspace credential
|
|
218
|
+
compromise. On GCP/CI use ADC or Workload Identity Federation so there is no
|
|
219
|
+
file to leak. If you must use a key, store it in a secret manager
|
|
247
220
|
(env-injected, not a file beside the code) and rotate it.
|
|
248
221
|
- **Least scope.** A leaked `drive.file` key sees app files; a leaked full
|
|
249
222
|
`drive` key sees everything. The scope IS the blast radius.
|
|
@@ -268,20 +241,6 @@ def with_backoff(call, max_retries=6, max_backoff=64):
|
|
|
268
241
|
| Reading whole resources without `fields` | Bigger payloads, higher quota cost, slower | Request only the fields you use (`fields: 'id'`) |
|
|
269
242
|
| Hardcoding the private key inline in source | Can't rotate, leaks via logs/screenshots/history | Inject from env/secret manager; `\n`-unescape at load |
|
|
270
243
|
| Pasting raw text into Gmail `raw` | API needs base64url RFC 822, not plain text → 400 | Build a MIME message, `base64url`-encode it |
|
|
271
|
-
| Setting `subject` but skipping the Admin DWD step | `unauthorized_client` — the SA was never allowed to impersonate | Authorize client ID + exact scopes in Manage DWD first |
|
|
272
|
-
|
|
273
|
-
## See also
|
|
274
|
-
|
|
275
|
-
- `../secure-coding/SKILL.md` — secret handling, key rotation, and the security
|
|
276
|
-
pass before this connector ships.
|
|
277
|
-
|
|
278
|
-
Recommended companions (siblings; create/link when present): `email-connector`
|
|
279
|
-
for SMTP/provider/deliverability email, `calendar-scheduling` for slot-finding
|
|
280
|
-
and booking UX, `spreadsheet-ops` for sheet data modeling and formulas,
|
|
281
|
-
`document-processing` for parsing files you pull from Drive, `automation-flows`
|
|
282
|
-
for chaining this across multiple connectors, and `webhooks` for receiving
|
|
283
|
-
Gmail/Drive push notifications.
|
|
284
244
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
`references/api-recipes.md` (extended Node + Python recipes).
|
|
245
|
+
Before this connector ships, run the secret-handling and key-rotation pass in
|
|
246
|
+
`../secure-coding/SKILL.md`.
|
package/skills/htmx/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: htmx
|
|
3
|
-
description: "Use when adding interactivity to a server-rendered app (FastAPI/Jinja, Django, Rails, Laravel, Go templates, Express) without adopting a JS framework
|
|
3
|
+
description: "Use when adding interactivity to a server-rendered app (FastAPI/Jinja, Django, Rails, Laravel, Go templates, Express) without adopting a JS framework — hx-get/post/put/delete with hx-target, hx-swap and hx-trigger, returning HTML fragments instead of JSON, out-of-band swaps, active search, infinite scroll, inline edit and polling. NOT a client-state SPA with routing and a store (that is `react` or `nextjs`)."
|
|
4
4
|
tags: [htmx, hypermedia, frontend, server-rendered, html]
|
|
5
5
|
recommends: [fastapi, django, secure-coding, accessibility]
|
|
6
6
|
origin: risco
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: huggingface
|
|
3
|
-
description: "Use when running open models or working on the Hugging Face platform
|
|
3
|
+
description: "Use when running open models or working on the Hugging Face platform — the Inference Providers router or InferenceClient, Hub repos via the hf CLI, a dedicated Inference Endpoint with scale-to-zero, a Gradio Space with ZeroGPU, picking an open model by task/license/size, or loading one locally with transformers. NOT serving locally on your own machine (that is `ollama`), NOT renting your own GPU box (that is `runpod`), NOT hosted creative image APIs (that is `replicate-images`), NOT fine-tuning with trl/peft (that is `finetuning`)."
|
|
4
4
|
tags: [huggingface, inference-providers, transformers, model-hub, inference-endpoints, spaces, ai-infra]
|
|
5
5
|
recommends: [ollama, runpod, modal, replicate, together-fireworks, fal, rag, embeddings-search, prompt-engineering, llm-pipeline, ai-media]
|
|
6
6
|
origin: risco
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: inventory
|
|
3
|
-
description: "Use when deciding how much stock to hold and when to reorder it — classifying SKUs, sizing safety stock, setting reorder points and order quantities, and tracking
|
|
3
|
+
description: "Use when deciding how much stock to hold and when to reorder it — classifying SKUs, sizing safety stock, setting reorder points and order quantities, and tracking the KPIs that keep a business from either stocking out or sitting on dead stock. NOT raising or negotiating the purchase order itself (that is `procurement`)."
|
|
4
4
|
tags: [reorder-point, safety-stock, eoq, abc-xyz, replenishment, inventory-kpis, ddmrp, min-max]
|
|
5
5
|
recommends: [procurement, logistics-ops, forecasting, dashboard, reporting, spreadsheet-ops]
|
|
6
6
|
origin: risco
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: investor-materials
|
|
3
|
-
description: "Use when packaging
|
|
3
|
+
description: "Use when packaging or circulating the documents an investor reads outside the meeting — setting up or cleaning a data room, writing the one-pager or teaser that earns the first meeting, or drafting the recurring monthly investor update. NOT the slide narrative (that is `pitch-deck`), NOT the projection spreadsheet (that is `financial-model`), NOT round strategy and the investor pipeline (that is `fundraising`)."
|
|
4
4
|
tags: [fundraising, data-room, investor-update, one-pager, investor-relations, due-diligence]
|
|
5
5
|
recommends: [pitch-deck, financial-model, fundraising, cold-outreach, unit-economics, grants]
|
|
6
6
|
origin: risco
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ip-trademark
|
|
3
|
-
description: "Use when a non-lawyer operator needs to protect a brand or creative work — clearing and choosing a name
|
|
3
|
+
description: "Use when a non-lawyer operator needs to protect a brand or creative work — clearing and choosing a name or logo, deciding whether and where to register a trademark, using the trademark and registered symbols correctly, knowing what copyright is automatic, or checking whether they own work a freelancer was paid for. NOT drafting the IP-assignment clause itself (that is `contracts`)."
|
|
4
4
|
tags: [intellectual-property, trademark, copyright, licensing, legal-compliance]
|
|
5
5
|
recommends: [contracts, brand-identity, compliance, terms-conditions]
|
|
6
6
|
origin: risco
|
package/skills/java/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: java
|
|
3
|
-
description: "Use when writing, reviewing
|
|
3
|
+
description: "Use when writing, reviewing or refactoring modern Java (21+, 25 LTS) — records and sealed interfaces as algebraic data types, exhaustive pattern-matching switch over instanceof ladders, virtual-thread concurrency, structured concurrency and ScopedValue replacing ThreadLocal, Stream and Optional pipelines, compact-constructor validation, parametrized JDBC, and the Maven/Gradle build surface. NOT Spring framework wiring (that is `spring-boot`)."
|
|
4
4
|
tags: [java, jvm, records, virtual-threads, sealed-types]
|
|
5
5
|
recommends: [spring-boot, secure-coding, deployment]
|
|
6
6
|
origin: risco
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: kotlin-android
|
|
3
|
-
description: "Use when building or fixing a native Android app in Kotlin
|
|
3
|
+
description: "Use when building or fixing a native Android app in Kotlin and Jetpack Compose on the UDF layered architecture — ViewModel/StateFlow, Hilt, Room, Retrofit, coroutines, type-safe Navigation, and the Gradle/AGP surface. NOT shared Android and iOS UI from one Kotlin codebase (that is `compose-multiplatform`)."
|
|
4
4
|
tags: [kotlin, android, jetpack-compose, hilt, room, coroutines, mvvm, clean-architecture]
|
|
5
5
|
recommends: [compose-multiplatform, spring-boot, java, testing-web, github-actions]
|
|
6
6
|
origin: risco
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: kpi-framework
|
|
3
|
-
description: "Use when a team must decide what to measure before building anything — picking one north-star metric, separating leading input drivers from lagging outputs, adding guardrails so a number
|
|
3
|
+
description: "Use when a team must decide what to measure before building anything — picking one north-star metric, separating leading input drivers from lagging outputs, adding guardrails so a number cannot be gamed, and setting a target that is not arbitrary. NOT the live dashboard that displays them (that is `dashboard`), NOT instrumenting the events (that is `analytics`), NOT the recurring board report (that is `reporting`)."
|
|
4
4
|
tags: [north-star-metric, leading-vs-lagging, input-metrics, guardrail-metrics, target-setting, vanity-metrics, kpi-tree]
|
|
5
5
|
recommends: [analytics, dashboard, reporting, ab-testing, forecasting, business-intelligence, unit-economics, project-ops]
|
|
6
6
|
origin: risco
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: level-design
|
|
3
|
-
description: "Use when designing a game level
|
|
3
|
+
description: "Use when designing a game level's space — blockout/greybox layout, pacing that drags or spikes, guiding lost players without waypoints, encounter and arena progression, or secret placement. NOT mechanics or economy (that is `game-design`), NOT story beats (that is `game-storytelling`), NOT engine tooling like nav meshes or lightmaps (that is `godot`/`unity`/`unreal`)."
|
|
4
4
|
tags: [level-design, blockout, pacing, encounter, playtest]
|
|
5
5
|
recommends: [game-design, godot, unity, unreal]
|
|
6
6
|
profiles: [full]
|
|
@@ -11,29 +11,12 @@ origin: risco
|
|
|
11
11
|
|
|
12
12
|
*Shape the space, the rhythm, and the encounters so the player always knows where to go, never gets bored, and feels smart for exploring. Prove it in grey boxes; add art last.*
|
|
13
13
|
|
|
14
|
-
This skill owns the **craft of physical space and its play**: how a level is laid out, how it reads, how its intensity rises and falls, how encounters teach, and where reward hides. It is **engine-agnostic** — every technique here is validated in a blockout, then handed to an engine skill for the actual tooling
|
|
15
|
-
|
|
16
|
-
## When to use / When NOT to use
|
|
17
|
-
|
|
18
|
-
**Use when:** blocking out a new level/map/arena; a level playtests as boring, confusing, or too hard/easy; players get lost or stuck; you need to pace a level, space encounters, or add breathers; you're guiding players without arrows/waypoints; placing secrets, rewards, or shortcuts; teaching a mechanic through the space itself.
|
|
19
|
-
|
|
20
|
-
**Do NOT use for:**
|
|
21
|
-
|
|
22
|
-
- **Systemic / mechanic design** — the verbs, rules, economy, and numbers the player brings *into* the level (jump height as a rule, weapon balance, loot tables, progression systems). That's `game-design`. This skill *exercises* those verbs in space; it doesn't invent or tune them.
|
|
23
|
-
- **Narrative, quests, dialogue, environmental story beats** — what the space *says*. That's `game-storytelling`. Level design places the beat; storytelling writes it.
|
|
24
|
-
- **Engine-specific level tooling** — nav-mesh baking, occlusion culling, terrain/tilemap/ProBuilder editors, lightmap/GI bakes, streaming volumes, collision setup. Defer to `godot` / `unity` / `unreal`. This skill decides *what* the space must do; the engine skill implements *how*.
|
|
25
|
-
|
|
26
|
-
## The craft laws (non-negotiable)
|
|
27
|
-
|
|
28
|
-
1. **Art last.** Never model or texture a space you haven't proven fun in blockout. Art-first means reworking expensive assets when the layout inevitably changes.
|
|
29
|
-
2. **Metrics before geometry.** Lock the player's dimensions (height, jump, reach, cover) first; build everything as multiples of them. → `references/blockout-to-art.md`
|
|
30
|
-
3. **The player always knows where to go, never how it ends.** Guide the critical path; leave exploration to earn its own reward. Lostness is a readability bug, not player error.
|
|
31
|
-
4. **Watch, don't tell.** A level is only as good as it plays for someone you didn't coach. Every claim ("this is obvious", "the fight is fun") is a hypothesis until a fresh player validates it.
|
|
32
|
-
5. **Rhythm, not a flat line.** Intensity must rise and fall. Sustained peak = fatigue; sustained calm = boredom. Design the graph, not just the rooms.
|
|
33
|
-
6. **Teach through space, not text.** Introduce a threat where it's safe to learn it, before it can kill.
|
|
14
|
+
This skill owns the **craft of physical space and its play**: how a level is laid out, how it reads, how its intensity rises and falls, how encounters teach, and where reward hides. It is **engine-agnostic** — every technique here is validated in a blockout, then handed to an engine skill for the actual tooling.
|
|
34
15
|
|
|
35
16
|
## The pipeline: blockout -> greybox -> playtest -> art (never art-first)
|
|
36
17
|
|
|
18
|
+
**Lock the player's metrics first** — height, jump, reach, cover, door/corridor widths — and build all geometry as multiples of them. Guessing widths breaks traversal after the space is full of dependent geometry, which is why this comes before the first box. → `references/blockout-to-art.md`
|
|
19
|
+
|
|
37
20
|
| Stage | You build | You answer | Gate to next |
|
|
38
21
|
|---|---|---|---|
|
|
39
22
|
| **Blockout** | Primitive geometry only (boxes/planes at true metrics). No materials, no props. | Does the space flow? Are timings/distances right? Can I find my way? | Layout & traversal feel right. |
|
|
@@ -41,7 +24,7 @@ This skill owns the **craft of physical space and its play**: how a level is lai
|
|
|
41
24
|
| **Playtest** | Nothing — you watch fresh players. | Where do they hesitate, get lost, die, skip? | Fixes are cheap because it's still grey. |
|
|
42
25
|
| **Art pass** | Meshes, materials, VFX, final lighting, audio — *serving* the proven layout. | Does art reinforce the guidance the greybox already established? | Ship. |
|
|
43
26
|
|
|
44
|
-
Iterate blockout↔playtest many times before art
|
|
27
|
+
Iterate blockout↔playtest many times before art: changing a grey box is minutes, changing a finished art set-piece is days — so never model or texture a space you have not already proven fun. Full stage detail, the metrics block, and the art-pass handoff checklist → `references/blockout-to-art.md`.
|
|
45
28
|
|
|
46
29
|
## Spatial composition — leading the eye
|
|
47
30
|
|
|
@@ -49,13 +32,13 @@ Iterate blockout↔playtest many times before art. Changing a grey box is minute
|
|
|
49
32
|
- **Landmarks (the "weenie").** One large, distinct, distant silhouette per area that the player orients toward (tower, spire, mountain) — Disney's term for the visual magnet that pulls you forward. Self-locating beats a minimap.
|
|
50
33
|
- **Lead the eye** with converging lines (rails, beams), framing (foreground arches), contrast (a bright end to a dark corridor), and motion. The eye goes to the brightest, highest-contrast, most-different thing — put that on the path you want taken.
|
|
51
34
|
- **Silhouette readability.** Enemies, interactables, and hazards must read by shape alone at a glance. Two things sharing a silhouette is an unintended trap.
|
|
52
|
-
- **Golden path vs exploration.** The **critical path** is the always-legible guaranteed route to the objective; **exploration** is optional branches and loops off it. Prefer loops that return the player forward (avoid dead-end backtracking); breadcrumb side routes with a visible reward.
|
|
35
|
+
- **Golden path vs exploration.** The **critical path** is the always-legible guaranteed route to the objective; **exploration** is optional branches and loops off it. The player must always know where to go and never how it ends. Prefer loops that return the player forward (avoid dead-end backtracking); breadcrumb side routes with a visible reward.
|
|
53
36
|
|
|
54
37
|
Framing, contrast, and layout topologies (loops, hubs, gates) → `references/guidance-and-readability.md`.
|
|
55
38
|
|
|
56
39
|
## Pacing & rhythm — tension and release
|
|
57
40
|
|
|
58
|
-
Design the **intensity graph** for the whole level, not room by room. A good level is a sawtooth trending upward: each peak (combat, platforming gauntlet, chase) followed by a valley — a **safe room / breather** with no threat, low stimulus, often a save/restock.
|
|
41
|
+
Design the **intensity graph** for the whole level, not room by room. Intensity must rise and fall — sustained peak is fatigue, sustained calm is boredom. A good level is a sawtooth trending upward: each peak (combat, platforming gauntlet, chase) followed by a valley — a **safe room / breather** with no threat, low stimulus, often a save/restock.
|
|
59
42
|
|
|
60
43
|
- **Space encounters in time and distance, and *vary* both** — three identical-length fights back to back feel like one long slog.
|
|
61
44
|
- **Breathers earn the next peak.** The calm between (Halo's cadence is often described as "thirty seconds of fun" on repeat) is what makes the fun read as fun. Use it to let adrenaline drop, reward observation, and telegraph the next escalation.
|
|
@@ -66,7 +49,7 @@ Intensity-graph template, breather patterns, and difficulty-curve worked example
|
|
|
66
49
|
|
|
67
50
|
## Encounter design — introduce, develop, twist, combine
|
|
68
51
|
|
|
69
|
-
|
|
52
|
+
Teach through space, not text: the four-beat progression (the pattern behind Portal, Half-Life 2, and Mario level craft) introduces a threat where it is safe to learn, before it can kill.
|
|
70
53
|
|
|
71
54
|
1. **Introduce** — meet the new element somewhere it *can't* hurt you. A single turret across a safe gap; one platform of the new hazard. Learn it risk-free.
|
|
72
55
|
2. **Develop** — use it for real, low stakes. The turret now guards a corridor you must cross.
|
|
@@ -84,7 +67,7 @@ Encounter template, arena patterns, and a full introduce→develop→twist→com
|
|
|
84
67
|
|
|
85
68
|
## Guidance & readability — direct without hand-holding
|
|
86
69
|
|
|
87
|
-
Guide with the environment so you never need a floating arrow:
|
|
70
|
+
Guide with the environment so you never need a floating arrow. When a player is lost, that is a readability bug in the level, not player error:
|
|
88
71
|
|
|
89
72
|
- **Light leads.** Players move toward light (the moth effect) and higher value-contrast. Light the path, objective, and exit; keep dead-ends dim. Placeholder lighting is a greybox *design* tool, not a final-art afterthought.
|
|
90
73
|
- **Reserve one accent color for "you can interact / go here"** (Mirror's Edge runner red, Dishonored's usable glint) and **never** use it decoratively. Consistency is the whole point; break it once and you've lied to the player.
|
|
@@ -96,7 +79,7 @@ Full catalog — lighting/color/composition, the affordance language, the "criti
|
|
|
96
79
|
|
|
97
80
|
## Metrics & playtesting — where players get lost and stuck
|
|
98
81
|
|
|
99
|
-
You cannot see your own level fresh. **Observe, don't coach:**
|
|
82
|
+
You cannot see your own level fresh, so every claim ("this is obvious", "the fight is fun") is a hypothesis until a fresh player validates it. **Observe, don't coach:**
|
|
100
83
|
|
|
101
84
|
- **Watch a first-timer play, silent.** Note every hesitation (readability gap), wrong turn (navigation gap), repeated death (telegraph/difficulty gap), and skipped content (reward-placement gap). Do **not** answer "where do I go?" — that question *is* the finding.
|
|
102
85
|
- **Traversal telemetry** turns anecdote into pattern: **position heatmaps** (cold zones players never enter = wasted level), **death heatmaps** (clusters = unfair/unreadable threats), **path traces** (golden path or lost?), **dwell time** at forks (long dwell = unclear guidance), and **look/aim heatmaps** (did they even see the landmark?).
|
|
@@ -114,41 +97,26 @@ Playtest protocol, question scripts, and turning heatmaps into fixes → `refere
|
|
|
114
97
|
|
|
115
98
|
Reward taxonomy, secret-signposting, and risk/reward tuning → `references/guidance-and-readability.md`.
|
|
116
99
|
|
|
117
|
-
## Anti-patterns
|
|
100
|
+
## Anti-patterns
|
|
118
101
|
|
|
119
|
-
|
|
|
102
|
+
| Anti-pattern | Do instead |
|
|
120
103
|
|---|---|
|
|
121
|
-
|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
|
|
131
|
-
## Quick reference
|
|
132
|
-
|
|
133
|
-
| Lever | Default | Where |
|
|
134
|
-
|---|---|---|
|
|
135
|
-
| Build order | blockout → greybox → playtest → art (art last) | `references/blockout-to-art.md` |
|
|
136
|
-
| Metrics block | lock player height/jump/reach/cover first; build to multiples | `references/blockout-to-art.md` |
|
|
137
|
-
| Navigation | one dominant landmark per area; legible critical path + breadcrumbed loops | `references/guidance-and-readability.md` |
|
|
138
|
-
| Pacing | sawtooth: peak → breather (safe room) → higher peak | `references/pacing-and-encounters.md` |
|
|
139
|
-
| Encounter teaching | introduce → develop → twist → combine | `references/pacing-and-encounters.md` |
|
|
140
|
-
| Arena shape | sightline length matched to threat range; flanks + verticality | `references/pacing-and-encounters.md` |
|
|
141
|
-
| Guidance | light leads; one reserved interact color; consistent affordances | `references/guidance-and-readability.md` |
|
|
142
|
-
| Playtest | watch silent; log hesitation/lost/death/skip; read heatmaps | `references/guidance-and-readability.md` |
|
|
143
|
-
| Secrets / risk | breadcrumb them; best optional reward behind biggest optional risk | `references/guidance-and-readability.md` |
|
|
104
|
+
| Making it look good first, then tuning the layout. | Art-first burns days reworking assets when the layout changes. Blockout, playtest, *then* art. |
|
|
105
|
+
| Trusting that it's "obvious where to go". | Obvious to *you*, the author. Fresh players get lost. Watch one before you believe it. |
|
|
106
|
+
| Patching confusion with a waypoint arrow or big text prompt. | That's a patch over a readability failure. Fix it with light, framing, and a landmark first. |
|
|
107
|
+
| Keeping the whole level intense because intensity is exciting. | Sustained peak = fatigue and it all flattens into noise. Add breathers so the peaks read. |
|
|
108
|
+
| Reusing the space by sending the player back the way they came. | Repeated dead-end backtracking reads as padding. Use loops that return the player forward. |
|
|
109
|
+
| Dropping a new mechanic in and expecting players to figure it out. | Not while it's killing them. Introduce it where it's safe, then develop/twist/combine. |
|
|
110
|
+
| Yellow paint everywhere so they see the ledges. | Only if yellow means *exactly* climbable and appears nowhere else. Inconsistent affordances lie. |
|
|
111
|
+
| Hiding a secret so well nobody finds it. | A secret with no breadcrumb is just frustration. Show the thread; reward the curious eye. |
|
|
112
|
+
| Eyeballing gap, cover, and door widths because they feel about right. | Guessing metrics breaks traversal later. Set the metrics block first; build to multiples. |
|
|
144
113
|
|
|
145
114
|
## Related skills
|
|
146
115
|
|
|
147
|
-
-
|
|
148
|
-
-
|
|
149
|
-
-
|
|
150
|
-
-
|
|
151
|
-
- **References:** `references/blockout-to-art.md` (pipeline, metrics block, art handoff, playtesting the blockout); `references/pacing-and-encounters.md` (intensity graph, encounter template, arena patterns, difficulty curve); `references/guidance-and-readability.md` (light/color/composition, affordances, playtest protocol, telemetry, reward & secrets).
|
|
116
|
+
- `game-design` — the systemic layer: mechanics, verbs, economy, progression, difficulty *systems*. Level design exercises those verbs in space; if the request is about the rules themselves, route there.
|
|
117
|
+
- `game-storytelling` — narrative, quests, dialogue, and the meaning of environmental beats. Level design places the beat; storytelling authors it.
|
|
118
|
+
- `godot` / `unity` / `unreal` — the engine tooling that *implements* a proven layout: nav meshes, occlusion, terrain/tilemap editors, lightmap/GI bakes, streaming, collision. Hand off here after the blockout plays well.
|
|
119
|
+
- `harness` — the `02-DOCS` Karpathy-wiki this skill records level conventions into.
|
|
152
120
|
|
|
153
121
|
## Checklist
|
|
154
122
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spring-boot
|
|
3
|
-
description: "Use when building, reviewing, testing, securing
|
|
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
|
-
##
|
|
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 ->
|
|
43
|
-
- Async Python FastAPI ->
|
|
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
|
-
|
|
46
|
-
- Language-agnostic injection/authz/secret theory ->
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
|
|
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, `
|
|
88
|
-
|
|
89
|
-
`
|
|
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.
|
|
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
|
|
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
|
|
306
|
+
## Anti-patterns
|
|
328
307
|
|
|
329
|
-
|
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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
|
-
|
|
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 |
|
|
35
|
-
| Video ideas, hooks, a topic backlog |
|
|
36
|
-
| Title + thumbnail packaging, CTR copy, A/B framing |
|
|
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 |
|
|
41
|
-
| Chain upload → Notion row → Slack across tools |
|
|
42
|
-
| Service-account auth to Gmail/Drive/Sheets |
|
|
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
|
-
|
|
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
|
|
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.
|