@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.
- package/manifest.json +15 -15
- package/package.json +1 -1
- package/skills/github-actions/SKILL.md +15 -27
- package/skills/google-workspace/SKILL.md +25 -66
- package/skills/level-design/SKILL.md +25 -57
- package/skills/market-research/SKILL.md +13 -22
- package/skills/market-research/evals/cases.yaml +3 -3
- package/skills/nestjs/SKILL.md +2 -10
- package/skills/nodejs/SKILL.md +13 -26
- package/skills/prisma-orm/SKILL.md +3 -10
- package/skills/prisma-orm/evals/cases.yaml +2 -2
- package/skills/procurement/SKILL.md +1 -6
- package/skills/procurement/evals/cases.yaml +2 -2
- package/skills/reporting/SKILL.md +21 -23
- package/skills/ruby/SKILL.md +10 -31
- package/skills/shortform-ideation/SKILL.md +12 -20
- 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.58",
|
|
3
3
|
"counts": {
|
|
4
4
|
"skills": 258
|
|
5
5
|
},
|
|
@@ -2065,7 +2065,7 @@
|
|
|
2065
2065
|
},
|
|
2066
2066
|
{
|
|
2067
2067
|
"id": "github-actions",
|
|
2068
|
-
"description": "Use when authoring or fixing GitHub Actions CI/CD — workflows under .github/workflows,
|
|
2068
|
+
"description": "Use when authoring or fixing GitHub Actions CI/CD — workflows under .github/workflows, triggers, job matrix, caching, token permissions, OIDC cloud deploys, environment gates, reusable workflows. NOT the Dockerfile or image build strategy (that is `docker`), NOT the branching model (that is `git-workflow`), NOT release readiness (that is `ship`).",
|
|
2069
2069
|
"tags": [
|
|
2070
2070
|
"github-actions",
|
|
2071
2071
|
"ci-cd",
|
|
@@ -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",
|
|
@@ -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",
|
|
@@ -2789,7 +2789,7 @@
|
|
|
2789
2789
|
},
|
|
2790
2790
|
{
|
|
2791
2791
|
"id": "market-research",
|
|
2792
|
-
"description": "Use when
|
|
2792
|
+
"description": "Use when a MARKET as a whole needs a defensible picture — TAM/SAM/SOM sized top-down AND bottom-up until the two converge, cut into reachable segments with one named beachhead, demand proven real, and a dated source behind every figure. NOT profiling named rivals and their moves (that is `competitor-watch`), NOT building a list of accounts to sell to (that is `lead-gen`).",
|
|
2793
2793
|
"tags": [
|
|
2794
2794
|
"market-research",
|
|
2795
2795
|
"tam-sam-som",
|
|
@@ -3033,7 +3033,7 @@
|
|
|
3033
3033
|
},
|
|
3034
3034
|
{
|
|
3035
3035
|
"id": "nestjs",
|
|
3036
|
-
"description": "Use when building or structuring a NestJS backend — feature modules, providers
|
|
3036
|
+
"description": "Use when building or structuring a NestJS backend — feature modules, providers and DI wiring, provider scopes and request-lifecycle order, where to bind guards/pipes/interceptors/filters, and testing with Test.createTestingModule. NOT a bare Express/Fastify service with no DI (that is `nodejs`), NOT framework-agnostic REST design (that is `api-design`).",
|
|
3037
3037
|
"tags": [
|
|
3038
3038
|
"nestjs",
|
|
3039
3039
|
"nodejs",
|
|
@@ -3158,7 +3158,7 @@
|
|
|
3158
3158
|
},
|
|
3159
3159
|
{
|
|
3160
3160
|
"id": "nodejs",
|
|
3161
|
-
"description": "Use when building or
|
|
3161
|
+
"description": "Use when building or operating a plain Node.js / Express 5 backend service: project layout, async correctness, central error middleware, fail-fast config, graceful shutdown on SIGTERM. NOT DI modules/providers/guards (that is `nestjs`), NOT the type system or tsconfig (that is `typescript`), NOT REST contract design (that is `api-design`).",
|
|
3162
3162
|
"tags": [
|
|
3163
3163
|
"nodejs",
|
|
3164
3164
|
"express",
|
|
@@ -3546,7 +3546,7 @@
|
|
|
3546
3546
|
},
|
|
3547
3547
|
{
|
|
3548
3548
|
"id": "prisma-orm",
|
|
3549
|
-
"description": "Use when modeling data or writing type-safe queries with Prisma ORM in TypeScript
|
|
3549
|
+
"description": "Use when modeling data or writing type-safe queries with Prisma ORM in TypeScript — `schema.prisma`, `prisma.config.ts`, the generated Prisma Client, and Prisma Migrate, including the v6 to v7 upgrade. NOT schema-as-TS with a SQL builder (that is `drizzle-orm`), NOT ORM-agnostic zero-downtime migration (that is `db-migrations`), NOT Postgres engine tuning (that is `postgresdb`).",
|
|
3550
3550
|
"tags": [
|
|
3551
3551
|
"prisma",
|
|
3552
3552
|
"prisma-orm",
|
|
@@ -3571,7 +3571,7 @@
|
|
|
3571
3571
|
},
|
|
3572
3572
|
{
|
|
3573
3573
|
"id": "procurement",
|
|
3574
|
-
"description": "Use when a small operator must
|
|
3574
|
+
"description": "Use when a small operator must choose what to buy and from whom: pick a supplier, write an RFI/RFQ/RFP that returns comparable bids, score quotes on total cost of ownership, negotiate price and payment terms, or judge single-source risk. NOT redlining the purchase agreement (that is `contracts`), NOT the price you charge customers (that is `pricing`), NOT stock once it lands (that is `inventory`).",
|
|
3575
3575
|
"tags": [
|
|
3576
3576
|
"procurement",
|
|
3577
3577
|
"sourcing",
|
|
@@ -3884,7 +3884,7 @@
|
|
|
3884
3884
|
},
|
|
3885
3885
|
{
|
|
3886
3886
|
"id": "reporting",
|
|
3887
|
-
"description": "Use when
|
|
3887
|
+
"description": "Use when a recurring report must ship itself on a cadence — weekly digest, monthly exec pack, board pack — via a fetch→narrate→render→deliver pipeline with a schedule and a freshness gate. NOT a live view people slice (that is `dashboard`), NOT picking which KPIs to track (that is `kpi-framework`), NOT a one-off investigation (that is `analytics`).",
|
|
3888
3888
|
"tags": [
|
|
3889
3889
|
"reporting",
|
|
3890
3890
|
"automated-reports",
|
|
@@ -4013,7 +4013,7 @@
|
|
|
4013
4013
|
},
|
|
4014
4014
|
{
|
|
4015
4015
|
"id": "ruby",
|
|
4016
|
-
"description": "Use when writing
|
|
4016
|
+
"description": "Use when writing or refactoring plain Ruby outside Rails — scripts, CLIs, gems, libraries: Enumerable chains and blocks, module mixins and value objects, Bundler/gemspec packaging, whether metaprogramming earns its keep, Minitest or RSpec, Ruby 3.4/4.0 frozen-string hygiene. NOT Rails, ActiveRecord, or ActiveSupport idioms (that is `rails`).",
|
|
4017
4017
|
"tags": [
|
|
4018
4018
|
"ruby",
|
|
4019
4019
|
"gems",
|
|
@@ -4273,7 +4273,7 @@
|
|
|
4273
4273
|
},
|
|
4274
4274
|
{
|
|
4275
4275
|
"id": "shortform-ideation",
|
|
4276
|
-
"description": "Use when
|
|
4276
|
+
"description": "Use when a Reels/TikTok/Shorts account needs its next video ideas scored into a ranked backlog, grounded in its own performance log plus dated trending sounds, each bet logged so its outcome feeds the next batch. NOT scripting a chosen idea (that is `video-shorts`), NOT pillars or cadence (that is `shortform-strategy`), NOT packaging a finished cut (that is `shortform-packaging`).",
|
|
4277
4277
|
"tags": [
|
|
4278
4278
|
"shortform",
|
|
4279
4279
|
"reels",
|
|
@@ -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: github-actions
|
|
3
|
-
description: "Use when authoring or fixing GitHub Actions CI/CD — workflows under .github/workflows,
|
|
3
|
+
description: "Use when authoring or fixing GitHub Actions CI/CD — workflows under .github/workflows, triggers, job matrix, caching, token permissions, OIDC cloud deploys, environment gates, reusable workflows. NOT the Dockerfile or image build strategy (that is `docker`), NOT the branching model (that is `git-workflow`), NOT release readiness (that is `ship`)."
|
|
4
4
|
tags: [github-actions, ci-cd, workflows, oidc, caching]
|
|
5
5
|
recommends: [docker, git-workflow, ship, deployment, secure-coding, aws-essentials, vercel]
|
|
6
6
|
origin: risco
|
|
@@ -10,26 +10,16 @@ origin: risco
|
|
|
10
10
|
|
|
11
11
|
A workflow is config that runs on an event. Before you write a single step, decide three things: **which events** fire the workflow, **what permissions** the token needs, and **where credentials come from**. Get those wrong and you have a fast pipeline that leaks secrets or a secure one nobody can trigger. Everything after that — checkout, install, test, build — is just steps.
|
|
12
12
|
|
|
13
|
-
This skill owns the workflow layer
|
|
13
|
+
This skill owns the workflow layer — the `.github/workflows/*.yml` files, their triggers, jobs, matrix, caching, secret/OIDC handling, environments and deploy gates. Route the rest out:
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
- Killing redundant runs with `concurrency`; SHA-pinning actions for supply-chain safety.
|
|
24
|
-
|
|
25
|
-
## Not this when
|
|
26
|
-
|
|
27
|
-
- Authoring the `Dockerfile` or deciding the image build strategy → docker. The workflow may *call* `docker build`; designing the image is not this skill.
|
|
28
|
-
- Branching model, PR hygiene, merge vs rebase, commit conventions → git-workflow.
|
|
29
|
-
- Release readiness checklist, changelog, the shipping decision → `../ship/SKILL.md`.
|
|
30
|
-
- Blue/green, canary, rollback *theory* → `../deployment/SKILL.md`. Actions triggers the deploy; the strategy is deployment's.
|
|
31
|
-
- Choosing the host and its deploy primitives → `../vercel/SKILL.md` / `../aws-essentials/SKILL.md` / the host skill. Actions *triggers* the deploy; the host owns the target.
|
|
32
|
-
- Triaging SAST/CVE findings or threat-modeling → `../secure-coding/SKILL.md`. This skill runs a scanner *as a job*; it does not interpret the report.
|
|
15
|
+
| Not this skill | Goes to | Because |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| The `Dockerfile`, image build strategy | `../docker/SKILL.md` | The workflow may *call* `docker build`; designing the image is not this skill. |
|
|
18
|
+
| Branching model, PR hygiene, merge vs rebase, commit conventions | `../git-workflow/SKILL.md` | That is the source-control model, not the CI config layer. |
|
|
19
|
+
| Release readiness checklist, changelog, the shipping decision | `../ship/SKILL.md` | Whether to release is a decision; this skill only automates the mechanics. |
|
|
20
|
+
| Blue/green, canary, rollback *theory* | `../deployment/SKILL.md` | Actions triggers the deploy; the strategy is deployment's. |
|
|
21
|
+
| Choosing the host and its deploy primitives | `../vercel/SKILL.md`, `../aws-essentials/SKILL.md` | Actions *triggers* the deploy; the host owns the target. |
|
|
22
|
+
| Triaging SAST/CVE findings, threat modeling | `../secure-coding/SKILL.md` | This skill runs a scanner *as a job*; it does not interpret the report. |
|
|
33
23
|
|
|
34
24
|
## Decide the trigger first
|
|
35
25
|
|
|
@@ -74,16 +64,15 @@ jobs:
|
|
|
74
64
|
with:
|
|
75
65
|
node-version: 22
|
|
76
66
|
cache: npm # built-in lockfile-keyed cache
|
|
77
|
-
- run: npm ci #
|
|
67
|
+
- run: npm ci # not install — fails on a stale lockfile, reproducible
|
|
78
68
|
- run: npm run lint
|
|
79
69
|
- run: npm test
|
|
80
70
|
```
|
|
81
71
|
|
|
82
|
-
|
|
83
|
-
- `permissions: contents: read` at the top — **default token permissions may be write
|
|
84
|
-
- `concurrency` + `cancel-in-progress: true` — without it
|
|
85
|
-
- `
|
|
86
|
-
- `actions/checkout@v6`, `setup-node@v6` — current majors (checkout v6.0.2, setup-node v6.4.0). Old majors run on Node 20, removed from runners in **September 2026**; JS actions are forced onto **Node 24** by default since June 2026. Upgrade to silence deprecation warnings and stay supported.
|
|
72
|
+
Why those three lines are not optional:
|
|
73
|
+
- `permissions: contents: read` at the top — **default token permissions may be write**, and a leaked write token can push tags or publish packages. Widen per job and only to what that job needs (`packages: write` to publish, `id-token: write` for OIDC), never at the top.
|
|
74
|
+
- `concurrency` + `cancel-in-progress: true` — without it every push to an open PR leaves the old run finishing and billing. One group per ref keeps at most one running + one pending.
|
|
75
|
+
- `actions/checkout@v6`, `setup-node@v6` are the current majors (checkout v6.0.2, setup-node v6.4.0). Old majors run on Node 20, removed from runners in **September 2026**; JS actions are forced onto **Node 24** by default since June 2026.
|
|
87
76
|
|
|
88
77
|
## Caching
|
|
89
78
|
|
|
@@ -183,7 +172,6 @@ Per-cloud trust setup (AWS role, GCP Workload Identity Federation, Azure federat
|
|
|
183
172
|
```
|
|
184
173
|
|
|
185
174
|
First-party `actions/*` and `github/*` may stay on a major tag (GitHub controls them), but pinning everything is the stronger posture.
|
|
186
|
-
- **Keep `GITHUB_TOKEN` read-only by default**, widen per job. Set `permissions: contents: read` at the top, then grant exactly what a job needs (`packages: write` to publish, `id-token: write` for OIDC).
|
|
187
175
|
- **`pull_request_target` + checking out the PR head = remote code execution with your secrets.** That trigger runs in the *base* repo's trusted context. If you then `checkout` `github.event.pull_request.head.sha`, you execute a fork's code with full secret access. Never combine them.
|
|
188
176
|
|
|
189
177
|
## Reuse: workflow vs composite action
|
|
@@ -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`.
|
|
@@ -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
|
|