@ericrisco/rsc 0.1.55 → 0.1.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: nestjs
3
- description: "Use when building or structuring a NestJS backend — feature modules, providers, controllers, DI wiring, and the cross-cutting layer (guards, interceptors, pipes, exception filters) — including binding-scope and request-lifecycle decisions and Nest-specific testing. Triggers: 'create a NestJS module', 'wire a custom provider with useFactory', 'APP_GUARD vs @UseGuards on the controller', 'my request-scoped provider is undefined in a guard', 'A circular dependency has been detected at bootstrap', 'mock a repository provider with overrideProvider', 'monta un módulo de Nest', 'guard de autenticación JWT en NestJS'. NOT a bare Express/Node service with no DI (that is nodejs)."
3
+ 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`)."
4
4
  tags: [nestjs, nodejs, backend, dependency-injection, guards, pipes, testing, typescript]
5
5
  recommends: [nodejs, typescript, api-design, prisma-orm, testing-web]
6
6
  origin: risco
@@ -10,15 +10,7 @@ origin: risco
10
10
 
11
11
  Build server-side Node apps the way NestJS intends: feature modules, providers wired through the DI container, controllers, and a cross-cutting layer bound at a deliberate scope. This skill is about Nest-specific mechanics — how DI scopes resolve, what order the request lifecycle runs in, where to bind guards/pipes/interceptors/filters, and how to test it with `Test.createTestingModule`.
12
12
 
13
- ## Use this when
14
-
15
- - Scaffolding or extending a Nest app: new module, controller, provider, resolver.
16
- - Wiring DI: `useClass` / `useValue` / `useFactory` / `useExisting`, injection tokens, `forwardRef`, dynamic modules (`forRoot` / `forRootAsync`).
17
- - Adding cross-cutting behavior and deciding global vs controller vs route binding.
18
- - "Why is my request-scoped provider undefined" / "circular dependency detected at bootstrap".
19
- - Unit tests with mock providers and e2e tests with Supertest against the real Nest app.
20
-
21
- ## Not this when
13
+ ## Not this — route instead
22
14
 
23
15
  - Bare Express/Fastify/`http` service, no `@Module`/`@Injectable` → `../nodejs/SKILL.md`. Nest starts the moment the DI container appears.
24
16
  - REST resource modeling, versioning, status codes, idempotency (framework-agnostic) → `../api-design/SKILL.md`. Nest is where you *implement* those decisions.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: nodejs
3
- description: "Use when building or structuring a plain Node.js / Express backend service — project layout, async correctness, central error handling, config validation, and graceful shutdown — the runtime and HTTP service, not a DI framework. Triggers: 'set up an Express 5 service', 'my async route error returns 200 with an empty body', 'where do controllers vs services go', 'centralize error handling middleware', 'shut down cleanly on SIGTERM without dropping requests', 'why does one unhandled promise rejection crash my server', 'monta un backend con Express y manejo de errores', 'apaga el servidor sin perder peticiones en vuelo'. NOT NestJS DI/modules/guards (that is nestjs); NOT the TS type system/tsconfig (that is typescript); NOT REST contract/versioning (that is api-design)."
3
+ 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`)."
4
4
  tags: [nodejs, express, backend, async, error-handling]
5
5
  recommends: [nestjs, typescript, api-design, error-handling, postgresdb]
6
6
  origin: risco
@@ -8,24 +8,15 @@ origin: risco
8
8
 
9
9
  # Node.js backend services
10
10
 
11
- Stand up a plain Node.js HTTP/JSON service — `node:http` or Express 5 — that a person can read, test, and operate without a DI framework. This skill is about the runtime and the request lifecycle: how to lay out the code, how to keep async correct, how errors become status codes, how config fails fast, and how the process dies cleanly. The contract shape, the type system, and the data layer live elsewhere (see the boundaries below).
11
+ Stand up a plain Node.js HTTP/JSON service — `node:http` or Express 5 — that a person can read, test, and operate without a DI framework. This skill is about the runtime and the request lifecycle: how to lay out the code, how to keep async correct, how errors become status codes, how config fails fast, and how the process dies cleanly. The contract shape, the type system, and the data layer live elsewhere (see the boundary below).
12
12
 
13
- ## Use this when
13
+ ## Boundary
14
14
 
15
- - Standing up a new HTTP/JSON service on Node with Express 5 (or bare `node:http`).
16
- - Structuring routes / controllers / services / repositories in a non-DI app.
17
- - Fixing async bugs: floating promises, swallowed errors, callbacks not awaited.
18
- - Centralizing error handling and the 404/500 contract in one place.
19
- - Graceful shutdown on SIGTERM, env validation at boot, the request lifecycle.
20
- - Choosing CommonJS vs ESM and pinning a runtime.
21
-
22
- ## Not this when
23
-
24
- - The app is built around `@Module` / `@Injectable` / DI providers, guards, interceptors, pipes, exception filters → `../nestjs/SKILL.md`. Nest starts the moment the DI container appears; route away then, do not half-build it here.
25
- - Pure TypeScript type system, generics, `tsconfig` → `../typescript/SKILL.md`. This skill uses TS but does not teach types.
26
- - REST resource modeling, versioning, pagination, status-code semantics (framework-agnostic) → api-design. This skill *wires* the handlers; api-design decides the contract.
27
- - Schema, queries, connection pool, migrations → `../postgresdb/SKILL.md` / prisma-orm / drizzle-orm. *Calling* a repository stays here; designing the table does not.
28
- - Containerizing / shipping → docker / deployment. Choosing the logging/metrics/tracing stack → observability. This skill emits structured logs and a shutdown hook; it does not own the pipeline.
15
+ - The app is built around `@Module` / `@Injectable` / DI providers, guards, interceptors, pipes, exception filters → [`nestjs`](../nestjs/SKILL.md). Nest starts the moment the DI container appears; route away then, do not half-build it here.
16
+ - Pure TypeScript type system, generics, `tsconfig` → [`typescript`](../typescript/SKILL.md). This skill uses TS but does not teach types.
17
+ - REST resource modeling, versioning, pagination, status-code semantics (framework-agnostic) → [`api-design`](../api-design/SKILL.md). This skill *wires* the handlers; api-design decides the contract. Cross-cutting error taxonomy → [`error-handling`](../error-handling/SKILL.md).
18
+ - Schema, queries, connection pool, migrations → [`postgresdb`](../postgresdb/SKILL.md) / [`prisma-orm`](../prisma-orm/SKILL.md) / [`drizzle-orm`](../drizzle-orm/SKILL.md). *Calling* a repository stays here; designing the table does not.
19
+ - Containerizing / shipping → [`docker`](../docker/SKILL.md) / [`deployment`](../deployment/SKILL.md). Choosing the logging/metrics/tracing stack → [`observability`](../observability/SKILL.md). This skill emits structured logs and a shutdown hook; it does not own the pipeline.
29
20
 
30
21
  ## Decide first
31
22
 
@@ -33,7 +24,7 @@ Pick the runtime shape before writing code — the wrong choice is expensive to
33
24
 
34
25
  | Situation | Choice | Why |
35
26
  | --- | --- | --- |
36
- | Needs DI/modules, large team, heavy cross-cutting | route to `../nestjs/SKILL.md` | Don't reinvent a DI container by hand |
27
+ | Needs DI/modules, large team, heavy cross-cutting | route to [`nestjs`](../nestjs/SKILL.md) | Don't reinvent a DI container by hand |
37
28
  | Small/medium JSON API, want middleware + routing | Express 5 | Mature, async errors auto-forward (v5) |
38
29
  | One tiny endpoint, zero deps, a healthcheck | `node:http` | No dependency surface to maintain |
39
30
  | A library, not a server | not this skill | No request lifecycle to manage |
@@ -158,7 +149,7 @@ app.get("/users/:id", async (req, res) => {
158
149
  });
159
150
  ```
160
151
 
161
- The error handler placed before the route never sees the throw, so the response is whatever was half-written. Put it last. See `references/express5-migration.md` for the full v4→5 breaking-change checklist and the legacy v4 `asyncHandler` wrapper.
152
+ The error handler placed before the route never sees the throw, so the response is whatever was half-written. Put it last. See [`references/express5-migration.md`](references/express5-migration.md) for the full v4→5 breaking-change checklist, the middleware-order diagram, and the legacy v4 `asyncHandler` wrapper.
162
153
 
163
154
  ## Config & secrets
164
155
 
@@ -185,7 +176,7 @@ On SIGTERM the orchestrator gives you a brief window to finish. Drop nothing.
185
176
  4. Close the DB pool and other resources.
186
177
  5. `process.exit(0)`, with a force-exit timer as a backstop if drain stalls.
187
178
 
188
- Expose `/healthz` (liveness — is the process up) separately from `/readyz` (readiness — should it receive traffic). They answer different questions; conflating them causes both false restarts and dropped requests during deploys. The full copy-pasteable `server.ts` lives in `references/graceful-shutdown.md`.
179
+ Expose `/healthz` (liveness — is the process up) separately from `/readyz` (readiness — should it receive traffic). They answer different questions; conflating them causes both false restarts and dropped requests during deploys. The complete copy-pasteable `server.ts` — signal handlers, `AbortController`, readiness gate, force-exit backstop — lives in [`references/graceful-shutdown.md`](references/graceful-shutdown.md).
189
180
 
190
181
  ```ts
191
182
  // server.ts (sketch — full version in references/)
@@ -230,13 +221,9 @@ test("404 returns the error contract", async () => {
230
221
  | `catch (e) {}` then continue | Swallows the failure, masks the bug | Re-throw, or map to an `AppError` |
231
222
  | `process.exit()` without draining | Drops in-flight requests on deploy | SIGTERM → `server.close()` → abort → exit |
232
223
  | Global `unhandledRejection` as control flow | Hides bugs, leaves process in a bad state | Log + exit there; fix the floating promise |
233
- | Assuming Express 4 defaults | v5: `urlencoded` `extended:false`, `static` `dotfiles:"ignore"` | Read `references/express5-migration.md` |
224
+ | Assuming Express 4 defaults | v5: `urlencoded` `extended:false`, `static` `dotfiles:"ignore"` | Read [`references/express5-migration.md`](references/express5-migration.md) |
234
225
  | Leaking stack/message in prod | Information disclosure | Stack only when `NODE_ENV !== "production"` |
235
226
 
236
- ## References & siblings
237
-
238
- - `references/express5-migration.md` — full Express 4→5 breaking changes, middleware-order diagram, the legacy v4 `asyncHandler` wrapper.
239
- - `references/graceful-shutdown.md` — complete `server.ts`: signal handlers, `AbortController`, readiness gate, force-exit backstop.
240
- - DI/modules/guards → `../nestjs/SKILL.md`. Type system/tsconfig → `../typescript/SKILL.md`. Data layer → `../postgresdb/SKILL.md`. Contract design → api-design. Cross-cutting error taxonomy → error-handling.
227
+ ## Verify
241
228
 
242
229
  `scripts/verify.sh` statically lints a produced repo for these rules (4-arg error handler last, no `listen()` in `app.ts`, `engines.node` supported, floating-promise heuristic). Advisory; hard-fails only on `listen()` in `app.ts` or a missing error handler.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: power-automate
3
- description: "Use when operating Microsoft Power Automate cloud flows programmatically — creating, enabling, updating, listing or deleting flows through the Dataverse Web API (the workflow table, category 5) with Entra ID / OAuth2 auth, or reading action-level run history via the third-party FlowStudio MCP. Triggers: 'create a Power Automate cloud flow with the Dataverse API', 'enable my flow by code / set statecode to 1', 'why can't I create or edit a My Flow programmatically', 'PATCH the workflow clientdata', 'automatizar el despliegue de un flujo de Power Automate desde código'. NOT designing the flow or authoring its definition (automation-flows), NOT choosing a platform by billing model (automation-strategy), NOT a generic typed REST client with auth/pagination/backoff (api-connector-builder), NOT the endpoint receiving an HTTP-trigger POST in your app (webhooks), NOT scripting Microsoft 365 / Graph mail & calendar directly (no first-party skill — api-connector-builder, or google-workspace)."
3
+ description: "Use when operating Microsoft Power Automate cloud flows from code — create, enable, update, list or delete via the Dataverse Web API (`workflow` table, category 5) with Entra ID OAuth2, plus run-history debugging. NOT designing the flow definition (that is `automation-flows`), NOT picking a platform by billing model (that is `automation-strategy`)."
4
4
  tags: [power-automate, dataverse, microsoft, flows, entra, oauth, mcp, m365, automation]
5
5
  recommends: [automation-flows, automation-strategy, api-connector-builder, webhooks]
6
6
  profiles: [full]
@@ -80,7 +80,7 @@ Two load-bearing parts:
80
80
  - **`definition`** — a Logic Apps workflow definition: `triggers` (exactly one) then `actions`. This is the *design* artifact. Do not invent it from scratch here — get the trigger→actions→branch→error shape from `../automation-flows/SKILL.md`, then drop it into `definition`. Fastest reliable way to get a real one: build the flow once in the maker portal, export the solution, and copy its `clientdata`.
81
81
  - **`connectionReferences`** — the map from the definition's connectors to actual connections. **A flow whose connection references are not authorized will not turn on.** In a solution these are connection-reference records the target environment must resolve; unresolved references are the #1 reason a `PATCH statecode=1` "succeeds" but the flow never runs.
82
82
 
83
- **The trap:** `clientdata` must be *escaped into a string* before it goes in the request body — a nested object is rejected. In a script, `JSON.stringify(clientDataObject)` and assign the result; do not paste the object raw. Full annotated example in `references/dataverse-web-api.md`.
83
+ **The trap:** `clientdata` must be *escaped into a string* before it goes in the request body — a nested object is rejected. In a script, `JSON.stringify(clientDataObject)` and assign the result; do not paste the object raw. Full annotated example — plus the endpoint cheat-sheet (token, list/filter, create, enable, update, delete, ExportSolution, share), OData headers and error handling — in `references/dataverse-web-api.md`.
84
84
 
85
85
  ## Dynamic lifecycle — token → create → validate → enable → manage → delete
86
86
 
@@ -128,13 +128,17 @@ curl -s -X DELETE "$PA_DATAVERSE_URL/api/data/v9.2/workflows(<workflowid>)" \
128
128
 
129
129
  **Debug a run** — Dataverse's `flowrun` table lists run records but not per-action I/O. To see *which action failed and with what payload*, use FlowStudio MCP: `list_live_flows` → `get_live_flow_runs` → `get_live_flow_run_action_outputs`. See `references/flowstudio-mcp-and-limits.md`.
130
130
 
131
- ## Microsoft 365 ecosystem fit
131
+ ## Boundaries — when it is not a flow you operate here
132
132
 
133
- Power Automate is Microsoft's iPaaS across M365 and Dynamics; flows live in **Dataverse** and glue Outlook, Teams, SharePoint, Dynamics, and hundreds of connectors. That means the boundary is sharp: if the ask is *"send this email / read this calendar via Microsoft Graph from my own backend code,"* that is not a flow at all — build a typed Graph client with `../api-connector-builder/SKILL.md` (there is no first-party MS-Graph skill). If the equivalent is on Google, that is `../google-workspace/SKILL.md`. This skill is for when the automation genuinely *is* a Power Automate flow you must operate by code.
133
+ Power Automate is Microsoft's iPaaS across M365 and Dynamics; flows live in **Dataverse** and glue Outlook, Teams, SharePoint, Dynamics, and hundreds of connectors. This skill is for when the automation genuinely *is* a Power Automate flow you must operate by code. When it isn't:
134
134
 
135
- ## Honesty / gotchas
135
+ - *"Send this email / read this calendar via Microsoft Graph from my own backend code"* — not a flow at all; build a typed Graph client with `../api-connector-builder/SKILL.md` (there is no first-party MS-Graph skill), or `../google-workspace/SKILL.md` for the Google equivalent. Same route for a general typed client with auth/pagination/backoff — this skill uses the Dataverse endpoints surgically, it does not build a client.
136
+ - *"Power Automate or n8n/Make/Zapier?"* — billing model and constraints decide that: `../automation-strategy/SKILL.md`, before you commit to operating here.
137
+ - *"Receive my flow's HTTP-trigger POST in my app"* — that inbound endpoint is `../webhooks/SKILL.md`; this skill triggers and operates flows, it does not build the receiver.
136
138
 
137
- | Trap | Why it bites | Do instead |
139
+ ## Anti-patterns
140
+
141
+ | Anti-pattern | Why it bites | Do instead |
138
142
  |---|---|---|
139
143
  | Trying to CRUD a **My Flow** by code | Unsupported — silently impossible, not a bug you can fix | Move it into a Dataverse solution, or drive it by hand |
140
144
  | `clientdata` sent as a nested object | Request rejected; the column expects an escaped **string** | Serialize (`JSON.stringify`) the definition+connectionReferences before sending |
@@ -144,13 +148,6 @@ Power Automate is Microsoft's iPaaS across M365 and Dynamics; flows live in **Da
144
148
  | Hardcoding the Dataverse URL / secret | Env-specific, leaks in source | `.env`: `PA_DATAVERSE_URL`, `PA_TENANT_ID`, `PA_CLIENT_ID`, `PA_CLIENT_SECRET` |
145
149
  | Assuming the Dataverse path is permanent | Power Platform API is superseding surfaces piecemeal | Re-check `api.powerplatform.com` coverage at author time; the split is fast-moving |
146
150
 
147
- ## Related skills
148
-
149
- - **`../automation-flows/SKILL.md`** — design side: what the trigger→actions→branch→error should be, the importable definition. This skill *consumes* that shape as `clientdata.definition`. Design there, operate here.
150
- - **`../automation-strategy/SKILL.md`** — choosing Power Automate vs n8n/Make/Zapier by billing and constraints. Decide there before you commit to operating here.
151
- - **`../api-connector-builder/SKILL.md`** — a generic typed REST client with auth/pagination/backoff (including a Dataverse or MS Graph client). This skill uses the Dataverse API surgically; it does not build a general client.
152
- - **`../webhooks/SKILL.md`** — building the inbound endpoint in *your* app that receives a flow's HTTP-trigger POST. This skill triggers/operates flows; it does not build the receiver.
153
-
154
151
  ## Checklist
155
152
 
156
153
  - [ ] `.env` set: `PA_DATAVERSE_URL` (no trailing slash), `PA_TENANT_ID`, `PA_CLIENT_ID`, `PA_CLIENT_SECRET`.
@@ -161,9 +158,3 @@ Power Automate is Microsoft's iPaaS across M365 and Dynamics; flows live in **Da
161
158
  - [ ] Flow enabled via `PATCH statecode=1` and verified on read-back.
162
159
  - [ ] Solution **exported** before any `DELETE`.
163
160
  - [ ] No secrets or org URLs hardcoded; FlowStudio MCP (if used) flagged as third-party.
164
-
165
- ## References
166
-
167
- - `references/dataverse-web-api.md` — endpoint cheat-sheet (token, list/filter, create, enable, update, delete, ExportSolution, share), the full annotated `clientdata`, OData headers, and error handling.
168
- - `references/entra-auth-setup.md` — app registration, service principal vs delegated user, the Dataverse application user + security role, `.default` vs `user_impersonation`, and common 401/403 causes.
169
- - `references/flowstudio-mcp-and-limits.md` — FlowStudio MCP tools and auth (third-party), what it exposes that Dataverse doesn't, and the platform limits (My Flows, `api.flow.microsoft.com`, Power Platform API evolution).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: prisma-orm
3
- description: "Use when modeling data or writing type-safe queries with Prisma ORM in TypeScript and hitting its classic problems: N+1 on relations, over-fetching with fat include, an unbounded findMany scanning the whole table, the v7 'requires either adapter or accelerateUrl' error, or a Prisma 6 to 7 upgrade. Owns schema.prisma, the prisma-client generator, prisma.config.ts, the Prisma Client query API, and Prisma Migrate. Triggers: 'PrismaClient requires either adapter or accelerateUrl', 'client is not in node_modules anymore', 'relationLoadStrategy join vs query', 'migrate dev vs migrate deploy in CI', 'findMany returns the whole table', 'modela el esquema de usuarios y pedidos con Prisma', 'migració de Prisma a la versió 7'. NOT the schema-as-TS SQL-builder ORM (that is drizzle-orm), NOT cross-cutting zero-downtime migration strategy (that is db-migrations), NOT Postgres server tuning and EXPLAIN (that is postgresdb)."
3
+ 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`)."
4
4
  tags:
5
5
  - prisma
6
6
  - prisma-orm
@@ -286,8 +286,8 @@ Rules with teeth:
286
286
 
287
287
  Failed-migration recovery, baselining an existing database, and the full Prisma 6 to 7
288
288
  upgrade are in `references/migrations-and-v7-upgrade.md`. For ORM-independent evolution
289
- strategy (expand/contract, dual-write, zero-downtime backfills) that is the `db-migrations`
290
- skill.
289
+ strategy (expand/contract, dual-write, zero-downtime backfills) that is
290
+ `../db-migrations/SKILL.md`.
291
291
 
292
292
  ## Anti-patterns
293
293
 
@@ -311,10 +311,3 @@ Run `scripts/verify.sh <path>` to statically check emitted artifacts: it confirm
311
311
  `prisma-client` generator + `output`, an adapter on the constructor, and flags
312
312
  `$queryRawUnsafe` injection, `binaryTargets`, unbounded `findMany`, and wrong-ORM
313
313
  contamination. Read-only; no database connection.
314
-
315
- ## References
316
-
317
- - `references/queries-and-performance.md` — query cookbook, `relationLoadStrategy` matrix,
318
- transactions, generated types, the perf checklist, and the raw-SQL safety matrix.
319
- - `references/migrations-and-v7-upgrade.md` — migrate workflow detail, failed-migration
320
- recovery, baselining, and the full Prisma 6 to 7 upgrade.
@@ -21,8 +21,8 @@ should_trigger:
21
21
  why: Non-obvious v7 change — generated output path replaces the node_modules import.
22
22
  - prompt: "Necessito fer la migració de Prisma a la versió 7, què he de canviar a schema.prisma i al client?"
23
23
  why: >
24
- Catalan phrasing matching the description's stated coverage — the v6 to 7 upgrade
25
- (generator rename, output, adapter, prisma.config.ts) is explicitly owned here.
24
+ Catalan phrasing of the v6 to 7 upgrade (generator rename, output, adapter,
25
+ prisma.config.ts), which this skill owns.
26
26
 
27
27
  should_not_trigger:
28
28
  - prompt: "Set up the same schema using Drizzle's pgTable and drizzle-kit"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: procurement
3
- description: "Use when a small operator must decide what to buy and from whom — pick a supplier/vendor, write an RFI/RFQ/RFP that gets comparable bids back, compare quotes on total cost not sticker price, negotiate price and payment terms, judge single-source risk, or build a vendor scorecard for quarterly review. Triggers: 'help me pick a supplier for X', 'write an RFQ for 5,000 units', 'which of these quotes is actually cheapest over three years', 'should I take the 2/10 net 30 early-payment discount', 'we buy a critical part from one supplier — how risky is that', 'build a supplier scorecard', 'compara estos proveedores / negociar condiciones de pago', 'compara aquests proveïdors / negociar condicions amb el proveïdor'. NOT signing the binding purchase agreement or redlining liability/IP clauses (that is contracts), NOT the price you charge your own customers (that is pricing), NOT counting or reordering the stock once it arrives (that is inventory)."
3
+ 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`)."
4
4
  tags: [procurement, sourcing, suppliers, rfq, negotiation, vendor-management]
5
5
  recommends: [contracts, pricing, inventory, logistics-ops, invoicing, cost-tracking]
6
6
  origin: risco
@@ -172,8 +172,3 @@ You own the decision and the deal. The moment it becomes something else, route:
172
172
  - Tracking ongoing SaaS/subscription spend after a renewal decision → `../cost-tracking/SKILL.md`.
173
173
 
174
174
  > Note on AI: generative tools can compress supplier *discovery* by up to ~90% — finding candidates fast. They do not replace the weighting, TCO model, risk segmentation, or negotiation. Use AI to widen the shortlist; keep the judgment human and on paper.
175
-
176
- ## references/
177
-
178
- - `references/sourcing-requests.md` — copy-ready RFI/RFQ/RFP skeletons with the mandatory comparable-bid sections, plus invite and award/regret email templates.
179
- - `references/scorecard-and-tco.md` — weighted-scorecard template, worked TCO comparison layout, supplier performance scorecard, SRM-cadence-by-quadrant table, and re-source trigger thresholds.
@@ -12,9 +12,9 @@ should_trigger:
12
12
  - prompt: "We buy a critical component from only one supplier — how worried should I be?"
13
13
  why: Single/sole-source concentration risk and the backup-plan requirement.
14
14
  - prompt: "Negociar mejores condiciones de pago con nuestro proveedor."
15
- why: Spanish trigger — payment-terms negotiation, trading a concession for extended terms.
15
+ why: Asked in Spanish — payment-terms negotiation, trading a concession for extended terms.
16
16
  - prompt: "Compara aquests proveïdors i munta una scorecard ponderada per decidir."
17
- why: Catalan trigger — weighted-scorecard supplier comparison.
17
+ why: Asked in Catalan — weighted-scorecard supplier comparison.
18
18
 
19
19
  should_not_trigger:
20
20
  - prompt: "Draft and redline the purchase agreement so we can sign it."
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: react-native
3
- description: "Use when writing the JS/TS code inside a React Native or Expo app — screens, navigation, lists, animation, platform-conditional UI, data/offline state, and native-module authoring — and when killing runtime jank or render bugs. Triggers: 'scaffold an Expo Router app', 'FlashList vs FlatList', 'auth-gated route groups', 'gesture reattaches every render', 're-render storm on every keystroke', 'deep link lands on the wrong screen', 'write an Expo Module wrapping a native SDK', 'la llista pateix lag quan faig scroll', 'mi app va fluida en iOS pero a tirones en Android'. NOT eas build/submit/OTA update/prebuild/config-plugin (that is expo), NOT a Dart app (that is flutter), NOT web React/DOM (that is react or nextjs)."
3
+ description: "Use when writing the JS/TS inside a React Native or Expo app — screens, Expo Router navigation, lists, Reanimated gestures, platform forks, offline state, native modules — or killing jank and render storms. NOT eas build/submit/OTA/config-plugin (that is `expo`), NOT a Dart app (that is `flutter`), NOT web React/DOM (that is `react` or `nextjs`)."
4
4
  tags: [react-native, expo, mobile, ios, android, navigation, performance]
5
5
  recommends: [expo, react, flutter, design, debug, performance]
6
6
  origin: risco
@@ -8,11 +8,7 @@ origin: risco
8
8
 
9
9
  # React Native (app code)
10
10
 
11
- You write the code that runs *inside* the app: render, navigate, animate, list, persist, and author native modules. The pipeline around it — building, signing, OTA, native config — is not yours.
12
-
13
- ## What this skill owns
14
-
15
- Mobile is split across two skills by **verb**. Run the verb test before doing anything:
11
+ You write the code that runs *inside* the app: render, navigate, animate, list, persist, and author native modules. Mobile is split across two skills by **verb** — run the verb test before doing anything:
16
12
 
17
13
  | Verb in the request | Skill |
18
14
  |---|---|
@@ -149,7 +145,7 @@ Use Reanimated 4 CSS animations for simple declarative cases (fades, simple tran
149
145
 
150
146
  - Small forks: `Platform.select({ ios: 12, android: 8 })` or `Platform.OS === 'ios'`.
151
147
  - Whole-component forks: `Button.ios.tsx` / `Button.android.tsx` — the bundler picks the right one; import `./Button` with no extension.
152
- - Safe area: use `react-native-safe-area-context` insets, not hardcoded notch padding. Why: insets differ per device and orientation.
148
+ - Safe area: use `react-native-safe-area-context` insets, not hardcoded notch padding. Why: insets differ per device and orientation. Palette, type scale and layout intent are not decided here → `../design/SKILL.md`.
153
149
  - `KeyboardAvoidingView` behaves differently per platform — `padding` on iOS, often `height` or nothing on Android; test both, don't assume the iOS behavior ports.
154
150
  - Set the status bar style explicitly per screen via `expo-status-bar`.
155
151
 
@@ -196,6 +192,7 @@ Full Expo Module (Swift + Kotlin + view), the Turbo Module codegen-spec walkthro
196
192
  - Read **Hermes** stack traces from the bottom up; the JS frame that matters is usually above the native bridge frames.
197
193
  - "Works on iOS, breaks on Android" (or vice versa) → run the platform-divergence checklist in `references/performance-debugging.md` before guessing.
198
194
  - A red screen citing the interop layer is usually an old-architecture lib running under Fabric — update the lib or find a New-Arch-ready replacement; do **not** disable New Arch.
195
+ - A fault that resists all of the above needs systematic isolation, not more guesses → `../debug/SKILL.md`.
199
196
 
200
197
  ## Anti-patterns
201
198
 
@@ -211,10 +208,3 @@ Full Expo Module (Swift + Kotlin + view), the Turbo Module codegen-spec walkthro
211
208
  | Index as list key | Breaks recycling, reorders rows on insert | Stable domain id |
212
209
  | Doing native config / `eas.json` / OTA here | Wrong skill; this is app code | `../expo/SKILL.md` |
213
210
  | Hardcoded notch/safe-area padding | Wrong on other devices/orientations | `react-native-safe-area-context` insets |
214
-
215
- ## Cross-references
216
-
217
- - Building, signing, OTA, native config → `../expo/SKILL.md`
218
- - Dart cross-platform alternative → `../flutter/SKILL.md`
219
- - Layout/visual design decisions → `../design/SKILL.md`
220
- - Systematic runtime fault isolation → `../debug/SKILL.md`
@@ -42,6 +42,7 @@ flag() { # message + matching lines
42
42
  findings=1
43
43
  printf '%s[finding]%s %s\n' "$YELLOW" "$RESET" "$1"
44
44
  [ -n "${2:-}" ] && printf '%s\n' "$2" | sed 's/^/ /'
45
+ return 0 # never let a message-only finding trip set -e and skip the remaining checks
45
46
  }
46
47
 
47
48
  md_files() { # SKILL.md + every references/*.md
@@ -86,11 +87,13 @@ if [ -n "$bare" ]; then
86
87
  done < "$SKILL"
87
88
  fi
88
89
 
89
- # 4) Description must carry the Triggers: label and a NOT-boundary.
90
+ # 4) Description shape: a "Use when/to" lead, a NOT-boundary, and no keyword trigger list
91
+ # (the model matches by meaning; a phrase list is per-turn cost for every install).
90
92
  desc="$(grep -m1 -E '^description:' "$SKILL" 2>/dev/null || true)"
91
93
  if [ -n "$desc" ]; then
92
- printf '%s' "$desc" | grep -q 'Triggers:' || flag "description missing 'Triggers:' label"
94
+ printf '%s' "$desc" | grep -qE 'Use (when|to) ' || flag "description does not open with 'Use when/to'"
93
95
  printf '%s' "$desc" | grep -qE 'NOT ' || flag "description missing a 'NOT <x> (that is <sibling>)' boundary"
96
+ printf '%s' "$desc" | grep -q 'Triggers:' && flag "description carries a 'Triggers:' keyword list -> delete it, the model matches by meaning" ""
94
97
  fi
95
98
 
96
99
  # 5) No cross-ref to a sibling that does not exist on disk next to this skill.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: reporting
3
- description: "Use when you need a recurring report that ships to stakeholders on a cadence — a weekly team digest, monthly exec pack, quarterly board summary, or recurring client performance report — and it must go out reliably without a human in the loop. Symptoms: a standing metrics email keeps breaking or shows stale numbers, the Monday digest is hand-assembled every week, leadership asks for 'the same report but every month', or a client expects a PDF on a schedule. Triggers: 'set up a weekly automated report emailed to the exec team', 'build a monthly PDF report for our biggest client on a schedule', 'send the board a quarterly summary every quarter', 'our Monday metrics email keeps going out with last week's numbers — make it reliable', 'automatiza un informe mensual para dirección', 'munta un informe setmanal automàtic per al comitè'. NOT a live screen people open to slice metrics (that is dashboard), NOT deciding which KPIs to track (that is kpi-framework), NOT a one-off investigation (that is analytics)."
3
+ 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`)."
4
4
  tags: [reporting, automated-reports, recurring, stakeholder-reporting, scheduled-delivery, data-analytics]
5
5
  recommends: [dashboard, kpi-framework, analytics, automation-flows, email-connector, spreadsheet-ops, google-workspace, notion-connector, github-actions]
6
6
  origin: risco
@@ -10,9 +10,10 @@ origin: risco
10
10
 
11
11
  A report is a **push** artifact: a fixed snapshot that lands in someone's inbox or shared drive on a
12
12
  cadence, the same shape every period, with no human assembling it. That is the whole job. If a human
13
- opens a live view to slice numbers themselves, that is **pull** — a dashboard, not a report. Hold that
14
- line; almost every failed "reporting" project is a dashboard wearing a report's name, or a report
15
- nobody can trust because the numbers went stale and no one noticed.
13
+ opens a live view to slice numbers themselves, that is **pull** — a
14
+ [`dashboard`](../dashboard/SKILL.md), not a report. Hold that line; almost every failed "reporting"
15
+ project is a dashboard wearing a report's name, or a report nobody can trust because the numbers went
16
+ stale and no one noticed.
16
17
 
17
18
  Your deliverable is a **runnable pipeline**, not advice: a template, a generation script, a schedule,
18
19
  and a delivery step, with a freshness gate so it fails loud instead of shipping yesterday's numbers.
@@ -32,24 +33,23 @@ is a number no one can defend.
32
33
  | **Owner** | Who gets paged when it breaks | a named person, not "the team" |
33
34
 
34
35
  Rule: you **consume** an agreed metric set — you do not adjudicate which KPIs matter. If the ask is
35
- "which metrics should we even track?", that is kpi-framework, not this skill. The contract names the
36
- source and its owner so a wrong number has an address.
36
+ "which metrics should we even track?", that is [`kpi-framework`](../kpi-framework/SKILL.md), not this
37
+ skill. The contract names the source and its owner so a wrong number has an address.
37
38
 
38
39
  ## Decide: push report vs live dashboard (this branches — settle it first)
39
40
 
40
- Audiences want a consistent, citable snapshot for the period far more often than a live feed; that is
41
- why scheduled push beats a dashboard for exec summaries, weekly reviews, and finance close packs.
41
+ Audiences want a citable snapshot for the period more often than a live feed — that is why push wins
42
+ for exec summaries, weekly reviews, and finance close packs.
42
43
 
43
44
  | Signal in the ask | Route |
44
45
  | --- | --- |
45
46
  | "Same summary, every week/month/quarter" | **reporting** (here) |
46
47
  | "Consistent snapshot the board can cite in a meeting" | **reporting** (here) |
47
48
  | "It must arrive even if no one logs in" | **reporting** (here) |
48
- | "A screen people open to filter/drill live" | **dashboard** |
49
- | "Self-serve, slice by region/date on demand" | **dashboard** |
49
+ | "A screen people open to filter/drill live" | [`dashboard`](../dashboard/SKILL.md) |
50
+ | "Self-serve, slice by region/date on demand" | [`dashboard`](../dashboard/SKILL.md) |
50
51
 
51
- When both are wanted, build the report; let it link to the dashboard as a "go deeper" footer. Do not
52
- email a dashboard link and call it a report — see the anti-patterns table.
52
+ When both are wanted, build the report and let it link to the dashboard as a "go deeper" footer.
53
53
 
54
54
  ## Pick the artifact format
55
55
 
@@ -120,7 +120,7 @@ Bad → Good, the difference that decides whether the report is useful:
120
120
  - **Bad:** a table row `Revenue | 248,300 | 201,400`. The reader must do the math and guess if it matters.
121
121
  - **Good:** "Revenue up 23.3% WoW (€248,300 from €201,400) — investigate: driven by the enterprise renewal that won't recur next week."
122
122
 
123
- Never ship a raw metric dump with no narrative. The numbers are the evidence; the sentence is the report.
123
+ The numbers are the evidence; the sentence is the report.
124
124
 
125
125
  ## Schedule + reliability gate (where reports actually die)
126
126
 
@@ -145,7 +145,8 @@ does not teach scheduling in general. The actual transport (SMTP/Gmail send) bel
145
145
 
146
146
  - [ ] **Freshness gate before send** — assert the source is newer than the last period; if stale, do
147
147
  NOT send, raise instead. A report that consumes dirty data is not this skill's job to clean —
148
- that is data-cleaning; this gate only refuses to ship known-stale numbers.
148
+ that is [`data-cleaning`](../data-cleaning/SKILL.md); this gate only refuses to ship
149
+ known-stale numbers.
149
150
  - [ ] **Fail loud** — on any error, alert the owner (the report not arriving is itself a silent failure).
150
151
  - [ ] **Idempotent run** — re-running for the same period produces the same artifact, no duplicate send.
151
152
  - [ ] **Dead-report cleanup** — if no one opened the last N editions, kill the schedule. Unread reports
@@ -161,18 +162,15 @@ does not teach scheduling in general. The actual transport (SMTP/Gmail send) bel
161
162
  | Raw metric dump, no narrative | Reader does the math, misses what changed, stops opening it | Exec summary + 3 takeaways + a "so what" per section |
162
163
  | Schedule with no failure alert | A broken job is invisible for weeks; the report just stops | Fail loud to the named owner on any error |
163
164
  | A template forked per recipient | Layout change must be made N times; they drift | Single template scoped by `params` |
164
- | Redefining KPIs inside the report | The report quietly becomes the metric authority, numbers diverge | Consume an agreed set; defer definition to kpi-framework |
165
+ | Redefining KPIs inside the report | The report quietly becomes the metric authority, numbers diverge | Consume an agreed set; defer definition to [`kpi-framework`](../kpi-framework/SKILL.md) |
165
166
  | Unpinned WeasyPrint / render lib | A minor bump reflows the board pack with no warning | Pin (WeasyPrint 68.1) and re-check PyPI before changing |
166
167
  | Hand-assembling the digest weekly | It breaks the week the owner is on leave | Automate the pipeline end to end; a human only reads it |
167
168
 
168
169
  ## Verify
169
170
 
170
171
  Run `scripts/verify.sh` (read-only; pass a path to a generated pipeline directory, or run in it). It
171
- confirms a Jinja2 template exists and renders against a sample context without error, that the
172
- generation script produces a non-empty PDF/HTML artifact, that a schedule definition exists (a crontab
173
- line or a `.github/workflows/*.yml` with a `schedule:` block), and that a delivery step is wired. It
174
- soft-warns if no freshness/failure gate is detected. On an empty/clean target it exits 0 — nothing to
175
- check is not a failure.
176
-
177
- References: [`pipeline.md`](references/pipeline.md) — full template, chart embed, per-recipient loop,
178
- GitHub Actions `schedule:` YAML, freshness gate, and failure alert.
172
+ confirms a Jinja2 template renders against a sample context without error, the generation script
173
+ produces a non-empty PDF/HTML artifact, a schedule definition exists (a crontab line or a
174
+ `.github/workflows/*.yml` with a `schedule:` block), and a delivery step is wired. It soft-warns if no
175
+ freshness/failure gate is detected, and exits 0 on an empty/clean target — nothing to check is not a
176
+ failure.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: roast-me
3
- description: "Use when you want honest, comedic feedback on how you prompt — analyzing your own past sessions to score prompt quality and compute efficiency, surface your worst habits, and generate a model-selection cheat sheet. Triggers: 'roast me', 'roast my prompting', 'audit my prompting habits', 'how good are my prompts', 'am I prompting well', 'what are my bad prompt habits', 'analiza mis prompts', 'puntua els meus prompts', 'how much am I wasting on model costs'. NOT reviewing your code or output quality (use code-review for that) and NOT a general prompt-engineering tutorial (use prompt-engineering for that)."
3
+ description: "Use when someone wants an honest, comedic audit of their own prompting — reads their past agent transcripts, scores prompt quality and compute efficiency, names their worst habits, builds a model-selection cheat sheet. NOT reviewing code an agent produced (that is `code-review`), NOT prompting technique in general (that is `prompt-engineering`)."
4
4
  tags: [prompting, self-audit, compute-efficiency, ai-hygiene, learning]
5
5
  recommends: [prompt-engineering, code-review, context-budget]
6
6
  profiles: [full]
@@ -9,7 +9,7 @@ origin: risco
9
9
 
10
10
  # roast-me — audit your prompting, score yourself, stop burning money
11
11
 
12
- You are the **prompt auditor**. Your target is not the user's code — it is their *prompting behaviour*. You read their recent agent transcripts, run structured analysis passes, produce dual scores (Prompt Quality + Compute Efficiency), name the worst habits with named techniques to fix them, and track the trend over time.
12
+ You are the **prompt auditor**. Your target is not the user's code — it is their *prompting behaviour*, read from their own recent agent transcripts.
13
13
 
14
14
  Every run follows five phases. Execute them in order.
15
15
 
@@ -115,9 +115,7 @@ Score History:
115
115
  2026-06-08 73/100 (C) +5↑ 35/100 (F) The 3W Rule
116
116
  ```
117
117
 
118
- Output the roast report as formatted markdown. If history exists, append the trend line.
119
-
120
- Done.
118
+ Output the roast report as formatted markdown.
121
119
 
122
120
  ## Orientación (siempre)
123
121
 
@@ -9,7 +9,7 @@ skill: roast-me
9
9
 
10
10
  should_trigger:
11
11
  - prompt: "Roast me."
12
- why: "Canonical verbatim invocation — the skill's own trigger phrase. Must fire immediately and run the five-phase pipeline."
12
+ why: "Canonical invocation — the shortest possible ask for exactly this skill's job. Must fire immediately and run the five-phase pipeline."
13
13
 
14
14
  - prompt: "Audit my prompting habits over the last two weeks."
15
15
  why: "Situation-first phrasing with a custom time window — roast-me owns both the 'audit prompting' job and the --days N parameter."
@@ -18,10 +18,10 @@ should_trigger:
18
18
  why: "Dual concern (prompt quality + cost) phrased as a question — maps directly to the two scores roast-me produces. No mention of 'roast' keyword."
19
19
 
20
20
  - prompt: "Analiza mis prompts de la última semana y dime dónde soy malo."
21
- why: "Spanish-language trigger — rsc users write Spanish; the description must fire on non-English phrasings. Tests the non-English trigger."
21
+ why: "Spanish-language request — rsc users write Spanish; routing must survive translation on meaning alone."
22
22
 
23
23
  - prompt: "Puntua els meus prompts i digue'm quins hàbits hauria de canviar."
24
- why: "Catalan-language trigger — a non-obvious language variant. The description lists this phrasing explicitly."
24
+ why: "Catalan-language request — a non-obvious language variant that must route on meaning, with no keyword resembling the skill id."
25
25
 
26
26
  - prompt: "How much am I burning on model costs? Show me where I overspend."
27
27
  why: "Compute-efficiency angle only, no prompting-quality framing — roast-me's compute score and cheat sheet are the direct answer."
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ruby
3
- description: "Use when writing idiomatic Ruby outside Rails — plain scripts, CLIs, gems, libraries — or refactoring imperative loops into Enumerable chains, designing module mixins, packaging with Bundler, deciding whether metaprogramming is worth it, or setting up Minitest/RSpec. Triggers: 'write this in Ruby', 'refactor this loop with map/reduce', 'build a gem', 'gemspec / Gemfile.lock', 'method_missing or define_method?', 'Minitest vs RSpec', 'FrozenError after Ruby 3.4 upgrade', 'mixin vs inheritance', 'escribir una gema en Ruby', 'refactoritzar amb blocs'. NOT Rails/ActiveRecord/controllers (that is rails)."
3
+ 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`)."
4
4
  tags: [ruby, gems, bundler, metaprogramming, rspec, minitest, enumerable]
5
5
  recommends: [rails, testing-web, secure-coding]
6
6
  profiles: []
@@ -14,31 +14,18 @@ leaning on `Enumerable` and `Comparable` instead of hand-rolled loops, with
14
14
  `frozen_string_literal` hygiene and a real `Gemfile`/`.gemspec` when you package.
15
15
 
16
16
  This is **Ruby the language and its non-Rails ecosystem** — blocks, modules, gems,
17
- metaprogramming, Minitest/RSpec. The moment code loads the Rails framework or reaches
18
- for ActiveRecord/ActiveSupport idioms, it is no longer this skill — that is `rails`.
17
+ metaprogramming, Minitest/RSpec. Delegate: Rails apps, ActiveRecord models, controllers,
18
+ migrations, views, Hotwire — anything that loads Rails or uses ActiveSupport/ActiveRecord
19
+ idioms — to [`rails`](../rails/SKILL.md); the same task in another language to
20
+ [`python`](../python/SKILL.md), [`go`](../go/SKILL.md), [`rust`](../rust/SKILL.md),
21
+ [`elixir`](../elixir/SKILL.md), [`php`](../php/SKILL.md) or
22
+ [`typescript`](../typescript/SKILL.md); the CI pipeline that runs your Ruby tests to
23
+ [`github-actions`](../github-actions/SKILL.md) — this skill writes the tests, not the workflow.
19
24
 
20
25
  Targets **Ruby 4.0** (released 2025-12-25) on **3.4** semantics: Prism is the default
21
26
  parser, string literals warn on mutation without a magic comment, `it` is an implicit
22
27
  block param, and `Set` is now a core class.
23
28
 
24
- ## When to use / When NOT to use
25
-
26
- **Use when:**
27
-
28
- - Authoring or refactoring any plain-Ruby `.rb` file, CLI, script, gem, or library.
29
- - Turning imperative loops into `Enumerable` chains (`map`/`select`/`reduce`/`each_with_object`/`group_by`).
30
- - Designing module mixins, `Comparable`/`Enumerable` inclusion, refinements, or value objects (`Struct`/`Data`).
31
- - Setting up a gem: `bundle gem`, `.gemspec`, SemVer, version constraints, publishing to RubyGems.
32
- - Deciding whether metaprogramming (`method_missing`, `define_method`, `instance_eval`, DSLs) earns its keep.
33
- - Writing tests with Minitest or RSpec, wiring RuboCop/Standard, or adding RBS/Sorbet typing.
34
-
35
- **When NOT to use (delegate):**
36
-
37
- - Rails apps, ActiveRecord models, controllers, migrations, views, Hotwire -> `rails`.
38
- The hard line: anything that loads Rails or uses ActiveSupport/ActiveRecord idioms.
39
- - The same task in another language -> `python`, `go`, `rust`, `elixir`, `php`, `typescript`.
40
- - A CI pipeline that runs your Ruby tests -> `github-actions` (this skill writes the tests, not the workflow).
41
-
42
29
  ## Mental model
43
30
 
44
31
  Internalize these before writing a line:
@@ -291,7 +278,8 @@ examples with `let`/`subject`/`context` are in
291
278
  - **Types:** two coexisting systems — **RBS** (official signatures in separate `.rbs`
292
279
  files, checked by Steep) and **Sorbet** (inline `sig` blocks, with experimental
293
280
  inline-RBS-comment support). Add types only on a library's public surface or a hot,
294
- bug-prone core — not on throwaway scripts.
281
+ bug-prone core — not on throwaway scripts. RuboCop vs Standard config sits in
282
+ [references/gems-and-testing.md](references/gems-and-testing.md).
295
283
 
296
284
  ## Anti-patterns
297
285
 
@@ -305,12 +293,3 @@ examples with `let`/`subject`/`context` are in
305
293
  | Not committing `Gemfile.lock` for an app | Non-reproducible installs across machines | Commit it for apps; omit only for library gems |
306
294
  | `eval` of user-derived input | Remote code execution | Parse explicitly; never `eval` untrusted data |
307
295
  | Over-DSLing config a Hash would serve | Hidden control flow, slow `method_missing` | A plain Hash or `Data` object |
308
-
309
- ## References
310
-
311
- - [references/metaprogramming.md](references/metaprogramming.md) — `define_method`,
312
- `method_missing` + `respond_to_missing?`, `instance_eval`/`class_eval`, building a DSL,
313
- refinements vs monkey-patching, `prepend` wrapping.
314
- - [references/gems-and-testing.md](references/gems-and-testing.md) — full `bundle gem`
315
- tree and `.gemspec`, SemVer + `~>`, publishing, Rakefile, full Minitest + RSpec files,
316
- RuboCop vs Standard config.