@ericrisco/rsc 0.1.56 → 0.1.58

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: market-research
3
- description: "Use when you need a defensible picture of a MARKET as a whole — sizing it with TAM/SAM/SOM, cutting it into reachable segments, and proving demand is real and moving — with a dated source behind every number. Triggers: 'how big is the market for X', 'size this market', 'what's our TAM', 'is there real demand for this', 'who are the segments', 'where's the beachhead', 'sanity-check this TAM before the raise', 'top-down or bottom-up', '¿qué tamaño tiene el mercado de X', 'calcula el TAM', 'hay demanda real para esto', 'quina mida té aquest mercat'. NOT profiling specific named rivals and their moves (that is competitor-watch), NOT building a named list of accounts to sell to (that is lead-gen)."
3
+ 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`)."
4
4
  tags: [market-research, tam-sam-som, market-sizing, segmentation, demand-signals, jtbd, opportunity]
5
5
  recommends: [competitor-watch, lead-gen, pitch-deck, financial-model, pricing, forecasting, content-engine]
6
6
  origin: risco
@@ -14,22 +14,19 @@ The test of this work is not the number. It is **whether someone else can audit
14
14
 
15
15
  ## The hard stop: no named entities
16
16
 
17
- This skill produces understanding of a market **as a whole** — never a named buyer you can call today, never a named competitor dossier. The moment the ask turns into "who specifically," stop and route:
18
-
19
- - "Give me 200 fintech accounts with the VP Eng contact" → that is a sales list → `../lead-gen/SKILL.md`.
20
- - "Profile Competitor X — their tiers, gaps, recent launches" → that is a rival dossier → `../competitor-watch/SKILL.md`.
17
+ This skill produces understanding of a market **as a whole** — never a named buyer you can call today, never a named competitor dossier. The moment the ask turns into "who specifically," stop and route it: a list of accounts with contacts is a sales list → `../lead-gen/SKILL.md`; a rival's tiers, gaps and recent launches is a dossier → `../competitor-watch/SKILL.md`.
21
18
 
22
19
  Competition is **only a force that shrinks SOM** in this memo, never a per-company teardown. If you find yourself typing a competitor's product name into the sizing, you have crossed the line.
23
20
 
24
21
  ## The three jobs
25
22
 
26
- | Job | One governing rule | Failure if skipped |
27
- | --- | --- | --- |
28
- | **Size it** | Never ship a number without a second, independent method | A lone figure is unfalsifiable; readers discount it |
29
- | **Segment it** | Cut by the *job buyers hire you for*, then prove the slice is reachable AND distinct | A market with no beachhead is a market you can't enter |
30
- | **Read demand** | Secondary to form the hypothesis, primary to decide it | You confirm your own bias with stale reports |
23
+ | Job | One governing rule |
24
+ | --- | --- |
25
+ | **Size it** | Never ship a number without a second, independent method |
26
+ | **Segment it** | Cut by the *job buyers hire you for*, then prove the slice is reachable AND distinct |
27
+ | **Read demand** | Secondary to form the hypothesis, primary to decide it |
31
28
 
32
- Do them in order — sizing tells you what to segment, segments tell you where to read demand. The artifact at the end ties all three together with a sources table. That memo is what `scripts/verify.sh` lints.
29
+ Do them in order — sizing tells you what to segment, segments tell you where to read demand. The artifact at the end ties all three together with a sources table.
33
30
 
34
31
  ## Job 1 — Size it (triangulate or it's a guess)
35
32
 
@@ -39,7 +36,6 @@ Two instruments, two different errors. Run **both** and force them to agree.
39
36
  | --- | --- | --- | --- | --- |
40
37
  | **Top-down** | A published industry figure (Gartner/IDC/Statista, e.g. "$70B CRM market") | `industry size × your segment share %` | Fast, anchors to a named source | Inherits and amplifies the report's error; easy to hand-wave the share % |
41
38
  | **Bottom-up** | Your customers + price | `ACV × number of ICP-fitting accounts` | Grounded in your own pricing; survives investor scrutiny | Slow; needs a real ICP and a real account count |
42
- | **Triangulation** | BOTH of the above | Run both, force them to agree | The actual credibility signal | Skipping it — a lone number is a guess |
43
39
 
44
40
  ### The triangulation gate
45
41
 
@@ -58,7 +54,7 @@ Good Bottom-up: 960 ICP accounts × $50K ACV = $48M
58
54
  - **SAM** — the slice your business model + geography can actually serve.
59
55
  - **SOM** — the slice you can realistically capture near-term, given competition and sales capacity.
60
56
 
61
- The funnel `SAM ≈ 20% of TAM`, `SOM ≈ 10% of SAM` is an **illustrative example to defend, not a constant to assume.** Derive SAM from your real reach (model, geography, language) and SOM from the competitive pressure and your sales capacity — then state why. Worked top-down and bottom-up calculations, the convergence math, and the full memo template live in `references/sizing-playbook.md`.
57
+ The funnel `SAM ≈ 20% of TAM`, `SOM ≈ 10% of SAM` is an **illustrative example to defend, not a constant to assume.** Derive SAM from your real reach (model, geography, language) and SOM from the competitive pressure and your sales capacity — then state why. Worked top-down and bottom-up calculations, the convergence math, the SAM-then-SOM derivation logic, and the full memo template with its sources/provenance schema live in `references/sizing-playbook.md`.
62
58
 
63
59
  ## Job 2 — Segment it (reachable AND distinct, with a named beachhead)
64
60
 
@@ -108,15 +104,15 @@ This is exactly what `scripts/verify.sh` checks. Keep it Markdown so the linter
108
104
  | "$50B market" with no source or year | Cite the report + access date for every figure | Undated/unsourced = a guess; markets move fast |
109
105
  | Top-down and bottom-up are 4× apart, pick the bigger | Re-check inputs until they converge ≤~20% | 3–5× divergence means broken assumptions, not a choice |
110
106
  | Convert a Google Trends curve into a market size | Pair with absolute-volume tools before sizing | Trends is RELATIVE interest, never absolute volume |
111
- | Segment by demographics alone | Add JTBD/behavioral; name a reachable beachhead | Demographics miss *why* people actually buy |
107
+ | Segment by demographics alone | Add JTBD/behavioral; name a reachable beachhead | Demographics miss *why* people buy, and a market with no beachhead is one you can't enter |
112
108
  | Treat SAM/SOM as fixed 20%/10% of TAM | Derive SAM from reach, SOM from competition + capacity | Those ratios are illustrative, not constants |
113
109
  | Name specific competitor products in the memo | Treat competition as a SOM-shrinking force | A dossier is scope creep — hand to competitor-watch |
114
110
  | List named target accounts as "the market" | Hand the segment to lead-gen to build the list | That is a sales list, not market understanding |
115
- | All secondary data, no primary check on the decisive question | Use interviews/survey to fill the gap that decides | Stale or misaligned reports mislead the call |
111
+ | All secondary data, no primary check on the decisive question | Use interviews/survey to fill the gap that decides | Stale or misaligned reports mislead the call — you just confirm your own bias |
116
112
 
117
113
  ## Verify
118
114
 
119
- The memo is a checkable artifact, so `scripts/verify.sh` lints a produced memo file (read-only — it never edits) for the three things that keep "market sizing" honest:
115
+ The memo is a checkable artifact, so `scripts/verify.sh` lints a produced memo file (read-only — it never edits) for the three things above that keep "market sizing" honest: the numeric `SOM ≤ SAM ≤ TAM` nesting, **both** methods plus a stated convergence/divergence note (one method alone fails), and a citation **and** date on every load-bearing figure.
120
116
 
121
117
  ```bash
122
118
  ./scripts/verify.sh # scan ./ for *memo*/*market*.md
@@ -125,7 +121,7 @@ The memo is a checkable artifact, so `scripts/verify.sh` lints a produced memo f
125
121
  ./scripts/verify.sh --strict # treat warnings as failures (CI gate)
126
122
  ```
127
123
 
128
- It asserts: (a) **TAM, SAM, SOM** all present with parseable numeric values and the nesting `SOM ≤ SAM ≤ TAM` holds; (b) evidence of **both** a top-down and a bottom-up figure plus a stated **convergence/divergence** note — fails if only one method is present; (c) a **sources** section where each load-bearing figure carries a citation/URL AND a date. It exits `0` on a clean or empty target — a missing memo is a skip, never a false failure. The memo schema it enforces is documented in `references/sizing-playbook.md`.
124
+ It exits `0` on a clean or empty target — a missing memo is a skip, never a false failure.
129
125
 
130
126
  ## Hand-offs
131
127
 
@@ -138,8 +134,3 @@ The memo is the start of a chain. When it is done, route:
138
134
  - Set the ACV the bottom-up math depends on → `../pricing/SKILL.md`.
139
135
  - Project the demand series forward from history → `../forecasting/SKILL.md`.
140
136
  - Act on the keyword/topic demand signals → `../content-engine/SKILL.md`.
141
-
142
- ## references/
143
-
144
- - `references/sizing-playbook.md` — worked top-down and bottom-up calculations side by side, the triangulation convergence math (≤~15–20% credible, 3–5× broken), the SAM-then-SOM derivation logic, and the full market-memo template including the mandatory sources/provenance table schema.
145
- - `references/demand-signals.md` — the signal-source catalog (Google Trends + its relative-volume caveat, Exploding Topics, Statista, government/industry data, primary survey/interview design) and a source-grading rubric for vetting secondary data by recency and credibility.
@@ -2,7 +2,7 @@ skill: market-research
2
2
 
3
3
  should_trigger:
4
4
  - prompt: "How big is the market for AI legal-research tools in Spain?"
5
- why: Core sizing request — "how big is the market for X" is the central trigger.
5
+ why: Core sizing request for a whole market — Job 1, the central case for this skill.
6
6
  - prompt: "Sanity-check this TAM before our seed raise — does $2B hold up?"
7
7
  why: Non-obvious; cross-checking an existing number IS the triangulation core, not deck design or modeling.
8
8
  - prompt: "Cut our addressable market into segments and tell me which one to attack first."
@@ -12,9 +12,9 @@ should_trigger:
12
12
  - prompt: "Should we size this top-down from the industry report or bottom-up from our customers?"
13
13
  why: Non-obvious; the top-down-vs-bottom-up choice and triangulation gate are this skill's method, not a generic data pull.
14
14
  - prompt: "¿Qué tamaño tiene el mercado de software de reservas para restaurantes y cuál es el TAM/SAM/SOM?"
15
- why: Spanish trigger for the full sizing job — TAM/SAM/SOM explicitly requested.
15
+ why: Spanish-language ask for the full sizing job — TAM/SAM/SOM explicitly requested.
16
16
  - prompt: "Quina mida té el mercat d'apps de reserves i hi ha demanda real?"
17
- why: Catalan trigger combining market size and demand validation — both core jobs.
17
+ why: Catalan-language ask combining market size and demand validation — both core jobs.
18
18
 
19
19
  should_not_trigger:
20
20
  - prompt: "Profile Competitor X — their pricing tiers, feature gaps, and recent product launches."
@@ -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: 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: 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: 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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: shortform-ideation
3
- description: "Use when an account that already posts (or is about to start posting) Reels/TikTok/Shorts needs a ranked batch of next video ideas grounded in its own performance log plus live trending sounds/formats/hashtags, and a ledger that ties each idea-bet to its measured outcome. Use to fold this week's trending audio into ideas, to decide which 3 of 12 ideas to shoot first, or to review why the bets you made flopped. Triggers: 'give me 10 Reels ideas for next week', 'which of these ideas do we make first', 'fold this week's trending TikTok sounds into our idea list', 'why did the ones we bet on last month flop', 'idea backlog for our TikTok', 'idéame Reels para esta semana basándote en lo que ya nos funcionó', 'prioritza idees de vídeo curt per aquesta setmana'. NOT writing the shot-by-shot script or edit decision sheet for a chosen idea (that is video-shorts), NOT setting cadence/pillars/positioning (that is shortform-strategy), NOT captions/covers/hashtag-sets for a finished cut (that is shortform-packaging)."
3
+ 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`)."
4
4
  tags: [shortform, reels, tiktok, ideation, content-ideas, trend-jacking, experiment-log]
5
5
  recommends: [video-shorts, shortform-strategy, shortform-packaging, analytics, content-engine]
6
6
  origin: risco
@@ -8,27 +8,27 @@ origin: risco
8
8
 
9
9
  # Shortform Ideation — The Idea Engine and the Bet Ledger
10
10
 
11
- *You run the closed loop for a Reels/TikTok/Shorts account: hypothesis → bet → measured outcome → a better next batch.* You own the idea list, the priority score, and the experiment ledger. You do not write the spoken lines, you do not pick the cadence, and you do not finalize the caption.
11
+ *You run the closed loop for a Reels/TikTok/Shorts account: hypothesis → bet → measured outcome → a better next batch.* You own the idea list, the priority score, and the experiment ledger.
12
12
 
13
- **Your output stops at a ranked, evidenced idea carrying a chosen trend hook and a written hypothesis.** The moment you start writing spoken lines or beat timecodes, you have crossed into `video-shorts`. Hand off; do not squat.
13
+ **Your output stops at a ranked, evidenced idea carrying a chosen trend hook and a written hypothesis.** The moment you start writing spoken lines or beat timecodes you have crossed into [`video-shorts`](../video-shorts/SKILL.md) — hand off, do not squat.
14
14
 
15
15
  An idea you cannot defend with (a) this account's own performance log and (b) a dated trend signal is a brainstorm, not a bet. This skill refuses to emit a brainstorm dump.
16
16
 
17
17
  ## Decision gate — are you even in ideation?
18
18
 
19
- Read the ask against this table before you generate anything. *Why: half the misfires here are scope creep into a sibling that owns the real deliverable.*
19
+ Read the ask against this table before you generate anything, and hand off by the same table when a request lands outside your column. *Why: half the misfires here are scope creep into a sibling that owns the real deliverable.*
20
20
 
21
21
  | The ask | Owner | Why it is not you |
22
22
  |---|---|---|
23
23
  | "Give me N ranked ideas / which do we shoot first" | **you** | generating + scoring + ranking is the core loop |
24
24
  | "Fold this week's trending sounds into ideas" | **you** | trend-grounded ideation is the signature move |
25
25
  | "Why did the bets we made flop?" | **you** | the outcome ledger ties bet → result; that is yours |
26
- | "Write the shot-by-shot script / edit sheet for this idea" | `video-shorts` | you stop at the idea + hook angle + chosen sound |
27
- | "What should our pillars / cadence / positioning be?" | `shortform-strategy` | you consume pillars as input, you do not set them |
28
- | "Write the caption + hashtags + cover for this finished cut" | `shortform-packaging` | you may *suggest* a hashtag as a trend signal, not finalize one |
29
- | "YouTube ideas with thumbnail-first packaging" | `youtube-ideation` | that pipeline is packaging-led and decays slower |
30
- | "Run the cross-channel calendar across blog/email/social" | `content-engine` | you feed ranked ideas *into* a calendar, you don't run it |
31
- | "Build me a metrics dashboard" | `analytics` | you *read* the perf log to score ideas, you don't build reporting |
26
+ | "Write the shot-by-shot script / edit sheet for this idea" | [`video-shorts`](../video-shorts/SKILL.md) | you stop at the idea + hook angle + chosen sound |
27
+ | "What should our pillars / cadence / positioning be?" | [`shortform-strategy`](../shortform-strategy/SKILL.md) | you consume pillars as input, you do not set them |
28
+ | "Write the caption + hashtags + cover for this finished cut" | [`shortform-packaging`](../shortform-packaging/SKILL.md) | you may *suggest* a hashtag as a trend signal, not finalize one |
29
+ | "YouTube ideas with thumbnail-first packaging" | [`youtube-ideation`](../youtube-ideation/SKILL.md) | that pipeline is packaging-led and decays slower |
30
+ | "Run the cross-channel calendar across blog/email/social" | [`content-engine`](../content-engine/SKILL.md) | you feed ranked ideas *into* a calendar, you don't run it |
31
+ | "Build me a metrics dashboard" | [`analytics`](../analytics/SKILL.md) | you *read* the perf log to score ideas, you don't build reporting |
32
32
 
33
33
  ## The loop — four phases, in order
34
34
 
@@ -118,6 +118,8 @@ The hypothesis is one falsifiable sentence:
118
118
 
119
119
  Then leave the **result fields pending** — `result: pending | 3s-hold: __ | hook-rate: __ | shares: __ | saves: __ | verdict: __` — to be filled after the video runs. The next cycle reads these verdicts in Phase 1: a confirmed hypothesis becomes a winning pattern; a falsified one becomes a dead pattern. *Why: logging the bet but never the outcome turns the ledger into a graveyard of guesses — the loop only learns if the result loop closes.*
120
120
 
121
+ To structurally lint an emitted backlog or experiment file, point `scripts/verify.sh` at it (read-only): `bash scripts/verify.sh 02-DOCS/shortform/`.
122
+
121
123
  ## Metrics that matter
122
124
 
123
125
  Score and judge on these, not on raw views. *Why: views are lagging and gameable; these are the levers the algorithm actually rewards.*
@@ -141,13 +143,3 @@ Score and judge on these, not on raw views. *Why: views are lagging and gameable
141
143
  | Logging the bet but never the outcome | the loop never learns; next batch re-guesses | leave result fields and fill them; Phase 1 reads the verdicts |
142
144
  | Writing the full script/timecodes here | crosses into `video-shorts`; muddies the idea ledger | stop at hook line + chosen sound; hand off |
143
145
  | Capturing a trend signal with no date | freshness is unscorable; you may brief a dead sound | every signal carries a first-seen date or it doesn't enter Phase 3 |
144
-
145
- ## Hand-off
146
-
147
- - Chosen an idea and need the shot-by-shot script + edit decision sheet? → [`../video-shorts/SKILL.md`](../video-shorts/SKILL.md).
148
- - Missing the pillars/cadence/positioning the ideas should fit inside? → `shortform-strategy` (it owns strategy; you consume it).
149
- - The cut exists and needs caption/cover/hashtag-set? → `shortform-packaging`.
150
- - Feeding the ranked backlog into a multi-channel calendar? → [`../content-engine/SKILL.md`](../content-engine/SKILL.md).
151
- - Long-form/YouTube idea pipeline instead? → [`../youtube-ideation/SKILL.md`](../youtube-ideation/SKILL.md).
152
-
153
- To structurally lint an emitted backlog or experiment file, point `scripts/verify.sh` at it (read-only): `bash scripts/verify.sh 02-DOCS/shortform/`.