@ericrisco/rsc 0.1.44 → 0.1.45

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.
Files changed (97) hide show
  1. package/README.md +1 -1
  2. package/manifest.json +110 -86
  3. package/package.json +1 -1
  4. package/scripts/lib/domains.js +1 -1
  5. package/scripts/skill-migration-brief.md +104 -0
  6. package/skills/ab-testing/SKILL.md +9 -41
  7. package/skills/accessibility/SKILL.md +5 -7
  8. package/skills/ads/SKILL.md +9 -24
  9. package/skills/agent-eval/SKILL.md +7 -33
  10. package/skills/agent-safety/SKILL.md +7 -14
  11. package/skills/ai-media/SKILL.md +4 -20
  12. package/skills/analytics/SKILL.md +8 -30
  13. package/skills/analyze/SKILL.md +24 -59
  14. package/skills/angular/SKILL.md +12 -25
  15. package/skills/api-connector-builder/SKILL.md +10 -27
  16. package/skills/api-design/SKILL.md +7 -14
  17. package/skills/article-writing/SKILL.md +1 -18
  18. package/skills/astro/SKILL.md +36 -54
  19. package/skills/author-skill/SKILL.md +41 -74
  20. package/skills/author-skill/evals/README.md +5 -5
  21. package/skills/author-skill/evals/cases.yaml +8 -8
  22. package/skills/author-skill/references/description-recipe.md +25 -26
  23. package/skills/author-skill/references/eval-authoring.md +1 -1
  24. package/skills/author-skill/references/rsc-conventions.md +1 -1
  25. package/skills/automation-flows/SKILL.md +6 -16
  26. package/skills/automation-strategy/SKILL.md +1 -9
  27. package/skills/aws-essentials/SKILL.md +6 -23
  28. package/skills/backups/SKILL.md +1 -7
  29. package/skills/bash-scripting/SKILL.md +5 -9
  30. package/skills/bookkeeping/SKILL.md +2 -10
  31. package/skills/brand-identity/SKILL.md +18 -44
  32. package/skills/brand-voice/SKILL.md +4 -31
  33. package/skills/building-agents/SKILL.md +20 -103
  34. package/skills/business-intelligence/SKILL.md +9 -23
  35. package/skills/calendar-scheduling/SKILL.md +11 -27
  36. package/skills/case-studies/SKILL.md +3 -8
  37. package/skills/chatbot/SKILL.md +6 -23
  38. package/skills/chrome-extension/SKILL.md +2 -2
  39. package/skills/clarify/SKILL.md +31 -72
  40. package/skills/clickhouse-analytics/SKILL.md +2 -8
  41. package/skills/client-onboarding/SKILL.md +17 -19
  42. package/skills/cloudflare/SKILL.md +3 -8
  43. package/skills/code-review/SKILL.md +10 -23
  44. package/skills/codebase-onboarding/SKILL.md +2 -7
  45. package/skills/cold-outreach/SKILL.md +9 -30
  46. package/skills/community/SKILL.md +4 -31
  47. package/skills/competitor-watch/SKILL.md +20 -35
  48. package/skills/compliance/SKILL.md +10 -37
  49. package/skills/compose-multiplatform/SKILL.md +1 -1
  50. package/skills/constitution/SKILL.md +8 -35
  51. package/skills/content-engine/SKILL.md +4 -16
  52. package/skills/context-budget/SKILL.md +3 -21
  53. package/skills/continuous-learning/SKILL.md +10 -40
  54. package/skills/contracts/SKILL.md +6 -17
  55. package/skills/coolify/SKILL.md +8 -14
  56. package/skills/cost-tracking/SKILL.md +3 -11
  57. package/skills/course-builder/SKILL.md +17 -45
  58. package/skills/course-storytelling/SKILL.md +26 -94
  59. package/skills/cpp/SKILL.md +26 -71
  60. package/skills/csharp-dotnet/SKILL.md +19 -38
  61. package/skills/customer-support/SKILL.md +14 -37
  62. package/skills/dashboard/SKILL.md +6 -26
  63. package/skills/data-cleaning/SKILL.md +37 -63
  64. package/skills/data-policy/SKILL.md +8 -21
  65. package/skills/data-scraper/SKILL.md +1 -7
  66. package/skills/debug/SKILL.md +10 -49
  67. package/skills/deployment/SKILL.md +38 -101
  68. package/skills/design/SKILL.md +34 -116
  69. package/skills/fable-operator/SKILL.md +1 -4
  70. package/skills/fastapi/SKILL.md +50 -82
  71. package/skills/flutter/SKILL.md +41 -89
  72. package/skills/go/SKILL.md +57 -105
  73. package/skills/harness/SKILL.md +52 -68
  74. package/skills/implement/SKILL.md +1 -1
  75. package/skills/init/SKILL.md +152 -168
  76. package/skills/marketing/SKILL.md +30 -80
  77. package/skills/nextjs/SKILL.md +42 -116
  78. package/skills/orient/SKILL.md +25 -20
  79. package/skills/parallel/SKILL.md +9 -75
  80. package/skills/plan/SKILL.md +92 -165
  81. package/skills/postgresdb/SKILL.md +52 -72
  82. package/skills/presentations/SKILL.md +49 -87
  83. package/skills/python/SKILL.md +23 -72
  84. package/skills/react/SKILL.md +19 -67
  85. package/skills/review/SKILL.md +22 -52
  86. package/skills/rust/SKILL.md +40 -115
  87. package/skills/sdd-init/SKILL.md +9 -14
  88. package/skills/secure-coding/SKILL.md +80 -109
  89. package/skills/ship/SKILL.md +25 -55
  90. package/skills/tasks/SKILL.md +37 -61
  91. package/skills/typescript/SKILL.md +22 -55
  92. package/skills/verify/SKILL.md +8 -32
  93. package/skills/viral-score/SKILL.md +122 -0
  94. package/skills/viral-score/evals/README.md +16 -0
  95. package/skills/viral-score/evals/cases.yaml +50 -0
  96. package/skills/vue-nuxt/SKILL.md +45 -106
  97. package/skills/worktrees/SKILL.md +24 -69
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: tasks
3
- description: "Use when you have an approved implementation plan and need to break it into an ordered, independently-verifiable task list before any code is written — the SDD `tasks` phase (GitHub Spec Kit lineage: constitution → specify → clarify → plan → tasks → analyze → implement). Turns a plan into numbered tasks, each with an explicit done-check (the literal command or observation that proves it complete), dependencies, and a parallel-safe marker. Triggers: 'break the plan into tasks', 'make a task list', 'task breakdown', 'descompón el plan en tareas', 'lista de tareas', 'what are the steps to build this', 'turn the plan into a checklist', 'sequence the work', 'which tasks can run in parallel', 'give each task a done-check'. Appends the task list into the plan artifact under 02-DOCS/wiki/sdd/plans/<slug>.md. NOT writing the plan itself (that is `plan`), NOT the consistency gate over the artifacts (that is `analyze`), NOT executing the tasks (that is `implement`)."
3
+ description: "Use when an approved plan needs slicing into an ordered task list before any code — the SDD `tasks` phase. Each row carries a literal done-check, dependencies, a parallel-safe marker and a spec trace, appended to the plan artifact. NOT writing the plan (that is `plan`), NOT the consistency gate (that is `analyze`), NOT executing the tasks (that is `implement`)."
4
4
  tags: [sdd, tasks, breakdown]
5
5
  recommends: [analyze, implement]
6
6
  profiles: [core, full]
@@ -20,29 +20,25 @@ task list says "T004: implement `POST /login`; done when `pytest
20
20
  tests/auth/test_login.py` is green AND a 401 is returned for a bad password —
21
21
  depends on T002, T003; parallel-safe with T005." The difference is that the
22
22
  second one can be **handed to a subagent, executed, and verified** with no
23
- further questions.
24
-
25
- This is a process skill. It writes no runtime code. It produces one artifact: an
26
- ordered, checkable task list appended to the plan it was built from.
23
+ further questions. This phase writes zero runtime code; it produces one artifact,
24
+ appended to the plan it was built from.
27
25
 
28
26
  ## Model tier — `balanced` (opt-in routing)
29
27
 
30
- This phase's default model tier is **`balanced`** — it decomposes an approved plan into verifiable tasks: structured work, not architecture. Routing is **off** unless `models.enabled: true` in `02-DOCS/wiki/sdd/config.yaml`. When on: resolve this phase's tier (`models.overrides` wins over `models.phases`), map it to a model via `models.tiers`, and apply per `../sdd/references/model-routing.md` — announce the switch per the accompaniment dial when it differs from the session model, and dispatch any `Task`/`parallel` subagents on that model. Routing off or no profile → honor the session model silently. Never fake a switch a tool can't make; skip routing on a one-line change.
28
+ This phase's default tier is **`balanced`**: decomposing an approved plan is
29
+ structured work, not architecture. Routing is off unless `models.enabled: true`
30
+ in `02-DOCS/wiki/sdd/config.yaml`; when on, resolve the tier and apply it per
31
+ `../sdd/references/model-routing.md`, which owns the resolution order and the
32
+ announcement rules. Routing off or no profile → honor the session model silently.
31
33
 
32
34
  ## Read the harness profile first
33
35
 
34
- Before producing anything, read `02-DOCS/wiki/harness/user-profile.md` for the
35
- technical level and the **accompaniment dial**, and adapt:
36
-
37
- - **L0 (cavernícola)** — emit the task table, nothing else. No commentary.
38
- - **L1 (breve)** — one line of *why this slicing* above the table.
39
- - **L2 (explica decisiones)** — justify the ordering and the parallel markers as
40
- you go; flag the risky tasks.
41
- - **L3 (acompañamiento total)** — explain the slicing method, walk each
42
- dependency, and confirm the done-checks make sense to the user before writing.
43
-
44
- If no profile exists, assume non-technical + ask the two gauging questions the
45
- harness defines before slicing. Never invent a level.
36
+ Read `02-DOCS/wiki/harness/user-profile.md` before producing anything and match
37
+ the accompaniment dial: **L0** emit the task table and nothing else; **L1** add
38
+ one line of *why this slicing* above it; **L2** justify the ordering and the
39
+ parallel markers as you go, flagging the risky tasks; **L3** walk each dependency
40
+ and confirm the done-checks make sense to the user before writing. No profile →
41
+ assume non-technical and let `init` gauge the level; never invent one.
46
42
 
47
43
  ## Inputs (refuse to start without them)
48
44
 
@@ -154,10 +150,10 @@ The task list is **not** a new document. Append it to the existing plan under a
154
150
  ```
155
151
 
156
152
  Then ensure the plan is indexed in `02-DOCS/wiki/index.md` (the Knowledge map;
157
- root `CLAUDE.md` keeps only a short pointer) under
158
- the `sdd/` topic (the `plan` phase usually added the row; confirm it points at
159
- `02-DOCS/wiki/sdd/plans/<slug>.md`, add it if missing — additive only, never
160
- delete a user's map entry).
153
+ root `CLAUDE.md` keeps only a short pointer) under the `sdd/` topic — the `plan`
154
+ phase usually added the row, so confirm it points at
155
+ `02-DOCS/wiki/sdd/plans/<slug>.md` and add it if missing. Additive only: never
156
+ delete a user's map entry.
161
157
 
162
158
  ### The table format
163
159
 
@@ -181,8 +177,8 @@ delete a user's map entry).
181
177
  subagent) that see *only their own task* — not the whole plan. Such a worker can't infer a
182
178
  neighbor's function signature, payload shape, or column name from a one-line row. For any task
183
179
  whose correctness depends on a contract it doesn't own, attach an **Interfaces block** right under
184
- its row. (Trivial, self-contained tasks don't need one — don't add ceremony where there's no
185
- cross-task contract.)
180
+ its row. Trivial, self-contained tasks don't need one — don't add ceremony where there's no
181
+ cross-task contract.
186
182
 
187
183
  ```markdown
188
184
  **T004 — Interfaces**
@@ -190,15 +186,13 @@ cross-task contract.)
190
186
  - Produces: `POST /login` → `200 {token}` | `401 {error}`; sets `Set-Cookie: sid=…; HttpOnly`
191
187
  ```
192
188
 
193
- Rules:
194
-
195
- - Quote **exact** signatures/shapes, not descriptions — the isolated worker copies them, it can't
196
- go look them up. "Returns the user" is invisible; `-> {id, email}` is usable.
197
- - `Consumes` names what the task reads from a neighbor or the environment; `Produces` names the
198
- contract later tasks (and the per-task reviewer) will hold it to.
199
- - The plan's **§0 Global Constraints** are inherited by every task implicitly — do **not** repeat
200
- them per task. Interfaces carry the *task-local* contract; Global Constraints carry the
201
- *project-wide* one. Together they are everything a blind implementer needs.
189
+ Quote **exact** signatures and shapes, not descriptions — the isolated worker copies them, it can't
190
+ go look them up. "Returns the user" is invisible; `-> {id, email}` is usable. `Consumes` names what
191
+ the task reads from a neighbor or the environment; `Produces` names the contract later tasks (and
192
+ the per-task reviewer) will hold it to. The plan's **§0 Global Constraints** are inherited by every
193
+ task implicitly — do **not** repeat them per task. Interfaces carry the *task-local* contract;
194
+ Global Constraints carry the *project-wide* one. Together they are everything a blind implementer
195
+ needs.
202
196
 
203
197
  ## Review workload + delivery strategy forecast
204
198
 
@@ -216,12 +210,11 @@ before a giant diff exists.
216
210
  | Suggested delivery | single-pr / ask-on-risk / autochain / exception | matched to config.review_budget |
217
211
  ```
218
212
 
219
- Rules:
220
-
221
- - If estimated changed lines exceed `config.sdd.review_budget.line_budget` (default 400), recommend splitting or `ask-on-risk`.
222
- - If many areas or cross-stack contracts are touched, recommend `autochain` or a feature-track branch.
223
- - If the change is tiny, recommend `single-pr`.
224
- - If a deadline or emergency justifies a large review, mark `exception` and require explicit user approval later.
213
+ Pick the delivery strategy from the forecast: tiny change → `single-pr`; estimated
214
+ lines over `config.sdd.review_budget.line_budget` (default 400) → recommend
215
+ splitting or `ask-on-risk`; many areas or cross-stack contracts touched →
216
+ `autochain` or a feature-track branch. A deadline or emergency that justifies a
217
+ large review is marked `exception` and requires explicit user approval later.
225
218
 
226
219
  ## Anti-patterns → STOP
227
220
 
@@ -236,19 +229,6 @@ Rules:
236
229
  | "I'll start coding the easy task while I list the rest" | This phase writes zero runtime code. Implementation is `implement`. |
237
230
  | "Renumber the IDs so they're contiguous" | Downstream phases cite IDs. They're stable once written. Append, don't renumber. |
238
231
 
239
- ## Done-of-done for this phase
240
-
241
- Before handing off, confirm:
242
-
243
- - [ ] Every plan deliverable maps to at least one task.
244
- - [ ] Every task has a runnable done-check (a command or a checkable observation).
245
- - [ ] Every task traces to a spec line; no orphan tasks.
246
- - [ ] Dependencies form a valid order (nothing precedes what it needs).
247
- - [ ] `[P]` markers only on file/state-disjoint tasks.
248
- - [ ] The list is appended under `## Tasks` in the plan artifact, indexed in the Knowledge map at `02-DOCS/wiki/index.md` (root `CLAUDE.md` keeps only a short pointer).
249
- - [ ] A final closer task gates on all done-checks + `verify.sh`.
250
- - [ ] Review workload forecast and suggested delivery strategy appended.
251
-
252
232
  ## Result envelope
253
233
 
254
234
  End with:
@@ -272,14 +252,11 @@ End with:
272
252
 
273
253
  ## Next in the SDD chain
274
254
 
275
- The task list is now the contract for the rest of the build. Hand off:
276
-
277
- - **→ `analyze`** — the consistency gate. Before any code, cross-check
278
- constitution ↔ spec ↔ plan ↔ **tasks** for gaps, contradictions, and scope
279
- drift. Orphan tasks and untraceable scope surface here. Report only; the user
280
- resolves.
281
- - then **→ `implement`** — execute the tasks in order, TDD-style (red → green →
282
- refactor), using `parallel` for the `[P]` tasks and `worktrees` for isolation.
255
+ The task list is now the contract for the rest of the build. Hand off to
256
+ **`analyze`** — the consistency gate that cross-checks constitution ↔ spec ↔ plan
257
+ ↔ **tasks** and surfaces orphan tasks and untraceable scope — and then to
258
+ **`implement`**, which executes the list TDD-style, using `parallel` for the `[P]`
259
+ tasks and `worktrees` for isolation.
283
260
 
284
261
  Do not jump straight to `implement`. The whole point of writing a checkable list
285
262
  was to let `analyze` audit it cheaply *before* code exists.
@@ -287,4 +264,3 @@ was to let `analyze` audit it cheaply *before* code exists.
287
264
  ## Orientación (siempre)
288
265
 
289
266
  Cierra cada turno con el **bloque-brújula** (📍 dónde estás · ✅ qué hiciste · 🧭 por qué · ➡️ siguiente, terminando en pregunta), calibrado al dial de `02-DOCS/wiki/harness/user-profile.md`. **Nunca termines en seco.** Protocolo completo: skill `orient` → `skills/orient/references/orientation-contract.md`. (Defiere a `suggest` el "¿instalo la skill que falta?".)
290
-
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: typescript
3
- description: "Use when writing, reviewing, or fixing TypeScript type code (.ts/.tsx/.d.ts), modeling data with generics/unions/branded types, or configuring tsconfig and the build toolchain - the language and type system itself, not any runtime or framework. Triggers: \"make this generic preserve the literal type\", \"why won't this narrow / why won't TypeScript narrow this union\", \"type X is not assignable to type Y, fix the type not cast it\", \"set up a strict tsconfig with project references\", \"convert these magic strings into a discriminated union with exhaustiveness\", \"bundler vs nodenext moduleResolution\", \"configura el tsconfig en modo estricto y elimina los any\", \"por qué no estrecha el tipo\". NOT the Node runtime, fs/streams/http server (that is nodejs); NOT React/Next component wiring (that is react/nextjs); NOT ORM schema type-gen (that is drizzle-orm)."
3
+ description: "Use when writing or fixing TypeScript type code (.ts/.tsx/.d.ts), modeling data with generics/unions/branded types, diagnosing narrowing failures, or configuring tsconfig and the build toolchain. NOT runtime code, fs/streams/http (that is `nodejs`); NOT component/route typing (that is `react`/`nextjs`); NOT ORM type-gen (that is `drizzle-orm`)."
4
4
  tags: [typescript, types, generics, tsconfig, type-safety]
5
5
  recommends: [nodejs, secure-coding, drizzle-orm]
6
6
  origin: risco
@@ -18,42 +18,18 @@ compiler** (`tsgo`, the Go port) is in preview as `@typescript/native-preview` a
18
18
  type-checks roughly 10x faster (VS Code's 1.5M LOC: 89s -> 8.74s) — adopt it for fast
19
19
  local checks; stable 7.0 lands early 2026.
20
20
 
21
- This is a *language* skill: the type system plus the compiler config. It is the canonical
22
- authority for "how do I express this in TS and make `tsc` honor it", independent of any
23
- runtime or framework.
24
-
25
- ## When to use / When NOT to use
26
-
27
- **Use when:**
28
-
29
- - Authoring or fixing type code: generics, constraints, overloads, conditional/mapped/
30
- template-literal types, utility types, narrowing, `.d.ts` declarations.
31
- - Modeling data: discriminated unions, `satisfies`, branded/nominal types, exhaustiveness.
32
- - Setting up or hardening `tsconfig.json`: strict flags, `moduleResolution`, project
33
- references, path aliases, declaration emit, `isolatedModules`/`verbatimModuleSyntax`.
34
- - Diagnosing type errors: "why won't this narrow", "X is not assignable to Y", inference
35
- failures, `any`/`unknown` leakage, variance surprises.
36
- - Choosing the build toolchain: `tsc` vs `tsgo` (TS7), `tsx`, bundler vs nodenext resolution.
37
-
38
- **When NOT to use (delegate):**
39
-
40
- - Node runtime/server code — event loop, `fs`, streams, `http` server, `process`, env -> `nodejs`.
41
- - React/Next/Nest component or framework typing *in framework context* -> `react` / `nextjs` /
42
- `nestjs` (the type-level mechanics still come from here; the framework wiring does not).
43
- - ORM schema-to-type generation (Drizzle/Prisma) -> `drizzle-orm` / `prisma-orm`.
44
- - REST/contract shape design (status codes, resource naming) -> `api-design`.
45
- - Test runner / coverage / E2E setup -> `testing-web` / `e2e-testing`.
46
- - Language-agnostic injection/authz/threat review -> `secure-coding`.
47
- - Python typing -> `python`; Go -> `go`.
48
-
49
21
  ## Boundary: language vs runtime vs framework
50
22
 
51
- Three layers, three owners. **Language + compiler config lives here** (`tsconfig`, generics,
52
- narrowing). **Runtime behavior** (how a stream backpressures, how the event loop schedules)
53
- is `nodejs`. **Framework idioms** (component props, route maps, server-component typing) are
23
+ Three layers, three owners. **Language + compiler config lives here** — generics, narrowing,
24
+ `.d.ts`, `tsconfig`, and the build toolchain (`tsc` vs `tsgo`, `tsx`, resolution mode).
25
+ **Runtime behavior** (how a stream backpressures, how the event loop schedules) is `nodejs`.
26
+ **Framework idioms** (component props, route maps, server-component typing) are
54
27
  `react`/`nextjs`/`nestjs` — those *borrow* this skill's type mechanics but own their wiring.
55
28
  A `tsconfig` question is here; a "stream backpressure" question is `nodejs`; a "type my
56
- `useReducer` state" question is `react`.
29
+ `useReducer` state" question is `react`. Also delegate: ORM schema-to-type generation ->
30
+ `drizzle-orm` / `prisma-orm`; REST/contract shape design -> `api-design`; test runner and E2E
31
+ setup -> `testing-web` / `e2e-testing`; injection/authz review -> `secure-coding`; Python
32
+ typing -> `python`; Go -> `go`.
57
33
 
58
34
  ## Decision rules
59
35
 
@@ -62,28 +38,13 @@ Apply these on every TypeScript edit:
62
38
  1. **Prefer inference; annotate boundaries.** Let TS infer locals and returns; annotate
63
39
  function parameters, public APIs, and `.d.ts`. Why: redundant annotations drift from
64
40
  reality and suppress the better inferred type.
65
- 2. **`unknown`, never `any`.** `any` disables checking and leaks; `unknown` forces a narrow
66
- before use. Why: `any` silently poisons every downstream type it touches.
67
- 3. **`import type` for type-only imports**, with `verbatimModuleSyntax: true`. Why: it
41
+ 2. **`import type` for type-only imports**, with `verbatimModuleSyntax: true`. Why: it
68
42
  prevents emitting type-only imports as runtime `require`s and lets esbuild/swc transpile
69
43
  each file alone.
70
- 4. **Model state as discriminated unions, not optional-field bags.** A literal discriminant
71
- makes illegal states unrepresentable. Why: `{ data?: T; error?: E; loading?: bool }`
72
- permits `loading && error` — a union does not.
73
- 5. **`satisfies` for config objects, not a type annotation.** Why: annotation widens the
74
- value to the type (you lose literal keys); `satisfies` validates *without* widening, and
75
- catches discriminant typos at the construction site.
76
- 6. **Narrow, don't cast.** Reach for type guards, `in`, `typeof`, discriminant checks before
77
- `as`. Why: `as` asserts a claim the compiler cannot verify — it is a silenced error.
78
- 7. **`as` is a last resort, and only `as <narrower>` or `as unknown as T` at true I/O
79
- boundaries.** Why: `as` to a *wider* or unrelated type is almost always a real bug hidden.
80
- 8. **One `tsconfig` base, extended per package.** A shared `tsconfig.base.json` holds strict
81
- flags; each package `extends` it and sets only `outDir`/`rootDir`/references. Why: a single
82
- giant config can't express per-package module targets and breaks project references.
83
- 9. **Turn on `noUncheckedIndexedAccess`.** Why: `arr[i]` and `record[key]` are `T | undefined`
84
- in reality — without this flag TS lies and you get runtime `undefined`.
85
- 10. **Make unions exhaustive with a `never` guard.** A `default: const _: never = x` in
86
- every switch over a union turns "added a case, forgot a branch" into a compile error.
44
+ 3. **Narrow, don't cast.** Reach for type guards, `in`, `typeof`, discriminant checks before
45
+ `as`; when `as` is unavoidable, only `as <narrower>` or `as unknown as T` at a true I/O
46
+ boundary. Why: `as` asserts a claim the compiler cannot verify — it is a silenced error,
47
+ and `as` to a *wider* or unrelated type is almost always a real bug hidden.
87
48
 
88
49
  ## The type-system toolbox
89
50
 
@@ -105,6 +66,9 @@ const r = pick({ a: 1, b: "x" } as const, "b"); // r: "x", not string
105
66
 
106
67
  ### `unknown` over `any` at every boundary
107
68
 
69
+ `any` disables checking and silently poisons every downstream type it touches; `unknown`
70
+ forces a narrow before use.
71
+
108
72
  ```ts
109
73
  // Bad: any flows everywhere, no error ever fires downstream.
110
74
  function parse(json: string): any { return JSON.parse(json); }
@@ -133,8 +97,11 @@ routes.home.method; // "GET" (narrow), and "GE" would error right here
133
97
 
134
98
  ### Discriminated unions + exhaustive `never`
135
99
 
136
- The discriminant must be a **literal** type (not `string`), and you must check it **before**
137
- destructuring — destructuring first throws away the narrowing.
100
+ Model state as a discriminated union, not an optional-field bag:
101
+ `{ data?: T; error?: E; loading?: boolean }` permits `loading && error`; a literal discriminant
102
+ makes illegal states unrepresentable. That discriminant must be a **literal** type (not
103
+ `string`), and you must check it **before** destructuring — destructuring first throws away
104
+ the narrowing.
138
105
 
139
106
  ```ts
140
107
  type State =
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: verify
3
- description: "Use when implementation is finished and someone is about to say it's done, shipped, working, or ready to merge in the rsc-sdd flow — the post-implementation GATE that demands evidence before any 'done' claim. Triggers: 'verify this feature', 'is it done?', 'run the checks', 'lint/type/test before merge', 'did the acceptance criteria pass', 'confirm the tasks are complete', 'gate before review', 'audit the change', 'are we green', 'prove it works'. Runs the relevant stack skill's scripts/verify.sh (lint, type-check, tests, coverage, dependency/vuln audit), then walks every task done-check and every spec acceptance criterion, attaching the actual command output as evidence. Writes the verification record under 02-DOCS/wiki/sdd/ and points to the review phase. NOT writing tests or features (that is implement), NOT adversarial code reading (that is review), NOT root-cause diagnosis of a failing test (that is debug). Honors the harness accompaniment dial."
3
+ description: "Use when implementation is finished and about to be called done or merged — the rsc-sdd evidence gate: runs the stack's scripts/verify.sh (lint, type, test, audit), walks every task done-check and acceptance criterion, records a dated verdict. NOT judging the diff by eye (that is `review`, spec-less `code-review`), NOT diagnosis (that is `debug`)."
4
4
  tags: [sdd, verify, test]
5
5
  recommends: [review]
6
6
  profiles: [core, full]
@@ -15,21 +15,7 @@ The one rule everything else serves: **a claim of done is a claim about evidence
15
15
 
16
16
  This is a process skill. It does not own the lint/type/test tooling — the **stack skills do** (`../fastapi/SKILL.md`, `../go/SKILL.md`, `../nextjs/SKILL.md`, `../flutter/SKILL.md`, each shipping `scripts/verify.sh`; data-layer checks come from `../postgresdb/SKILL.md`, security from `../secure-coding/SKILL.md`). `verify` orchestrates them and judges the whole against the spec.
17
17
 
18
- ## When to use / when not to
19
-
20
- Use when:
21
-
22
- - Implementation of a task or feature is complete and you (or the user) are about to say so.
23
- - A fix has been applied and you need to confirm it actually resolves the issue, with the app's own checks.
24
- - You're at the gate before the `review` phase, or before a merge / PR.
25
- - Someone asks "is it done?", "are we green?", "did it pass?", "can I merge?".
26
-
27
- Do NOT use when:
28
-
29
- - You're still writing tests or production code → that's the `implement` phase (TDD lives there).
30
- - A check is failing and you need to find out *why* → that's `debug` (reproduce → isolate → fix). `verify` reports the failure and hands off; it does not diagnose.
31
- - You're reading the diff adversarially for design/correctness smells a test can't catch → that's `review`.
32
- - There is no spec or task list to verify against → you're earlier in the chain; go to `specify`/`plan`/`tasks` first.
18
+ Not this phase: still writing tests or production code → `../implement/SKILL.md` (TDD lives there); a check is failing and you need to know *why* → `../debug/SKILL.md` (`verify` reports the failure and hands off, it does not diagnose); reading the diff adversarially for design/correctness smells a test can't catch → `../review/SKILL.md`, or `../code-review/SKILL.md` when there is no spec/plan chain to key off; nothing to verify *against* → you're earlier in the chain, go to `../specify/SKILL.md` / `../plan/SKILL.md` / `../tasks/SKILL.md` first.
33
19
 
34
20
  ## Model tier — `balanced` (opt-in routing)
35
21
 
@@ -37,15 +23,13 @@ This phase's default model tier is **`balanced`** — it runs the checks and int
37
23
 
38
24
  ## Read the room first (accompaniment dial)
39
25
 
40
- Before running anything, read `02-DOCS/wiki/harness/user-profile.md` for the technical + accompaniment level and adapt:
26
+ Before running anything, read `02-DOCS/wiki/harness/user-profile.md` for the technical + accompaniment level; no profile yet → default to non-technical framing. The verdict itself (pass / fail per item) never changes with the dial — only how much you explain around it.
41
27
 
42
28
  - **L0** — run the gate, show pass/fail and the one-line failing summary. Minimal words.
43
29
  - **L1** — add one line of *why* per failing check.
44
30
  - **L2** — narrate each gate (what lint/type/test/audit checks and why it matters here).
45
31
  - **L3** — explain every result, what each acceptance criterion means in plain language, and what the user should decide next.
46
32
 
47
- If no profile exists yet, default to non-technical framing and keep the verdict legible. The verdict itself (pass / fail per item) never changes with the dial — only how much you explain around it.
48
-
49
33
  ## The gate (run in this order)
50
34
 
51
35
  ```text
@@ -105,12 +89,10 @@ Rules for RUN:
105
89
  The stack gate proves the code is *clean and tested*. It does **not** prove the feature does what the spec asked. Walk both lists explicitly:
106
90
 
107
91
  - **Task done-checks** — for each task in the plan, confirm its done-check is satisfiable from evidence (a passing test, a file that exists, an endpoint that returns the documented shape). Mark each ✅ with the evidence or ❌ with what's missing.
108
- - **Acceptance criteria** — for each criterion in the spec, point at the concrete evidence that satisfies it. A criterion with no test and no observable proof is **unverified** — treat it as a FAIL item, not a pass, until there is evidence.
92
+ - **Acceptance criteria** — for each criterion in the spec, point at the concrete evidence that satisfies it. A criterion with no test and no observable proof is **unverified** — treat it as a FAIL item, not a pass, until there is evidence. A criterion you "reviewed by reading the code" is not verified either: reading is `review`; verifying needs an observable result.
109
93
 
110
94
  Where a criterion needs runtime proof (a page renders, a command produces output), drive it through the relevant tool — defer browser/app runtime to the stack skill's own runtime guidance rather than inventing a check here.
111
95
 
112
- A criterion you "reviewed by reading the code" is not verified. Reading is `review`; verifying needs an observable result.
113
-
114
96
  ### 4 — RECORD
115
97
 
116
98
  Write a dated verification record to `02-DOCS/wiki/sdd/verifications/<slug>-YYYY-MM-DD.md` so the project's living knowledge carries the proof, then index it in `02-DOCS/wiki/index.md` (the Knowledge map; root `CLAUDE.md` keeps only a short pointer) under the `sdd/` topic. It is an OKF v0.1 wiki article: open it with YAML frontmatter carrying a non-empty `type:`. Keep it short and factual:
@@ -151,9 +133,9 @@ Append-only spirit: don't overwrite a prior run's record; a new run is a new dat
151
133
  - **FAIL** the moment any item lacks passing evidence. List the open items precisely (which check, which criterion, what's missing). Do not soften it. A single unverified acceptance criterion fails the whole gate.
152
134
  - Hand each failing kind to the right place: a failing test/type error → `debug`; a missing test for a criterion → back to `implement`; a spec ambiguity that surfaced → `clarify`.
153
135
 
154
- ## Anti-patterns → STOP
136
+ ## Anti-patterns
155
137
 
156
- | Rationalization | Reality |
138
+ | Anti-pattern | Why it fails / fix |
157
139
  | --- | --- |
158
140
  | "The tests passed last run, I'll trust that." | Re-run now. Code changed since; stale green is not green. Evidence is current, or it isn't evidence. |
159
141
  | "verify.sh printed SKIP for the tests — close enough." | A SKIP is *unverified*, not passing. The criterion it covers is still open until a real run passes. |
@@ -163,13 +145,7 @@ Append-only spirit: don't overwrite a prior run's record; a new run is a new dat
163
145
  | "One acceptance criterion is unproven; ship the rest." | The gate is all-or-nothing. One unverified criterion fails the whole verdict. |
164
146
  | "A test is failing — let me just fix it real quick." | That's `debug`, a different discipline. `verify` reports the failure and hands off; it does not patch mid-gate. |
165
147
  | "I'll write the verdict, then run the checks to confirm." | Backwards. RUN and WALK first; the verdict is the *consequence* of output you already read. |
166
-
167
- ## Red flags — abort the verdict
168
-
169
- - You're about to type "done"/"passing"/"works" and you cannot point to a specific line of command output that proves it. Stop; go run it.
170
- - The stack `verify.sh` for a touched stack doesn't exist or didn't run — the gate is incomplete; say so instead of declaring PASS.
171
- - An acceptance criterion has no test and no observable proof — it's unverified; the verdict is FAIL.
172
- - A failing check tempts you to fix it inline — that's scope drift into `debug`; record the failure and hand off.
148
+ | "The gate is mostly green, I'll call it done." | If you cannot point at the line of command output that proves a claim, you have no claim. Go run it. |
173
149
 
174
150
  ## Result envelope
175
151
 
@@ -194,7 +170,7 @@ End with:
194
170
 
195
171
  ## Next in the chain
196
172
 
197
- A **PASS** record is the entry ticket to the next phase: **`review`** (adversarial read of the diff for what the gate can't catch), then **`ship`** (PR/merge with Eric-only authorship). A **FAIL** routes back: failing checks to **`debug`**, missing coverage to **`implement`**, surfaced ambiguity to **`clarify`**. Either way the verification record under `02-DOCS/wiki/sdd/verifications/` travels with the work as its proof.
173
+ A **PASS** record is the entry ticket to the next phase: **`../review/SKILL.md`** (adversarial read of the diff for what the gate can't catch), then **`../ship/SKILL.md`** (PR/merge). A **FAIL** routes back per the VERDICT step. Either way the verification record under `02-DOCS/wiki/sdd/verifications/` travels with the work as its proof.
198
174
 
199
175
  ## Orientación (siempre)
200
176
 
@@ -0,0 +1,122 @@
1
+ ---
2
+ name: viral-score
3
+ description: "Use to judge whether a short-form clip is worth publishing — scores a reel, short or podcast excerpt 0-100 on ten weighted criteria with automatic penalties, then ranks a batch and says where the cut-off falls. Run it on transcript candidates before rendering. NOT writing the hook or caption (that is `shortform-packaging`), NOT inventing the idea (that is `shortform-ideation`), NOT executing the edit (that is `shortform-editing`)."
4
+ tags: [viral, score, rubric, shortform, reels, shorts, tiktok, ranking, evaluation, retention]
5
+ recommends: [shortform-packaging, shortform-ideation, shortform-editing, shortform-strategy, video-shorts]
6
+ profiles: []
7
+ origin: risco
8
+ ---
9
+
10
+ # viral-score — is this clip worth publishing?
11
+
12
+ A fixed rubric for scoring a vertical clip's chance of travelling. Its value is that it is
13
+ **fixed**: the same clip scores the same on Monday and Friday, and two clips are comparable
14
+ because they were measured with the same instrument.
15
+
16
+ So **do not substitute your own judgment for the rubric and do not adjust the weights.** If a clip
17
+ has a quality the rubric does not capture, say so in the reasons — but score it with this.
18
+
19
+ Score candidates **before rendering** whenever you can. Judging a transcript excerpt costs seconds;
20
+ editing a clip that gets discarded costs an afternoon.
21
+
22
+ ## The ten criteria
23
+
24
+ Each is scored **0-10**.
25
+
26
+ | # | Criterion | Weight | What earns the points |
27
+ |---|---|---|---|
28
+ | 1 | **Opening hook** | 20 % | Do the first 3 seconds stop the scroll? Curiosity, surprise, emotion, a strong claim, a striking open |
29
+ | 2 | **Expected retention** | 20 % | Is there a reason to reach the end? Sustained curiosity, pace, resolution, no dead air |
30
+ | 3 | **Emotional impact** | 15 % | Intensity: inspiration, awe, fear, anger, joy, nostalgia, humour, surprise. **Indifference scores very low** |
31
+ | 4 | **Shareability** | 10 % | Would someone send this to a friend? |
32
+ | 5 | **Comment-worthiness** | 10 % | Does it invite debate or a reply? |
33
+ | 6 | **Message clarity** | 5 % | Does the idea fit in one sentence? |
34
+ | 7 | **Value density** | 5 % | Does every second earn its place? |
35
+ | 8 | **Originality** | 5 % | Is it different or unexpected? |
36
+ | 9 | **Context independence** | 5 % | Does it land without having heard the rest of the episode? |
37
+ | 10 | **Storytelling** | 5 % | Is there a story, a lesson, or a transformation? |
38
+
39
+ ## The calculation
40
+
41
+ ```text
42
+ Viral Score = ( Hook×0.20 + Retention×0.20 + Emotion×0.15 + Shareability×0.10
43
+ + Comments×0.10 + Clarity×0.05 + Density×0.05
44
+ + Originality×0.05 + Context×0.05 + Storytelling×0.05 ) × 10
45
+ ```
46
+
47
+ ## Automatic penalties
48
+
49
+ Subtracted **after** the formula, and they stack.
50
+
51
+ | Penalty | Points |
52
+ |---|---|
53
+ | Weak hook | −10 |
54
+ | Slow intro | −8 |
55
+ | Needs too much context | −10 |
56
+ | Long pauses | −5 |
57
+ | Idea too generic | −8 |
58
+ | Provokes no emotion | −10 |
59
+ | Unsatisfying ending | −5 |
60
+
61
+ Clamp the final result to **[0, 100]**.
62
+
63
+ ## Reading the score
64
+
65
+ | Range | Verdict |
66
+ |---|---|
67
+ | 95-100 | Exceptional. Publish immediately |
68
+ | 90-94 | Very likely to perform |
69
+ | 80-89 | Good candidate. Worth editing and publishing |
70
+ | 70-79 | Acceptable, but there are better clips |
71
+ | 60-69 | Weak. Publish only if there is no alternative |
72
+ | 0-59 | Discard |
73
+
74
+ ## Required output, per clip
75
+
76
+ - **Start** and **end timestamp**
77
+ - **Viral Score** (0-100)
78
+ - A **table** with all ten criterion scores
79
+ - **Reasons** behind the scoring
80
+ - **Main strengths**
81
+ - **Main weaknesses**
82
+ - **Verdict**: Publish / Review / Discard
83
+
84
+ Scoring several clips adds two things: a **ranking from highest to lowest**, and **where the
85
+ cut-off falls** — the point below which publishing stops being worth it.
86
+
87
+ ## Applying it well
88
+
89
+ **Score the clip, not the topic.** A fascinating episode routinely yields a clip that scores 45.
90
+
91
+ **Judge the hook on the actual first three seconds**, not on the idea in the abstract. A clip that
92
+ opens with a filler word or halfway through a sentence has a weak hook: −10. That is also why the
93
+ excerpt should start on a sentence boundary — where you cut decides the hook.
94
+
95
+ **Be strict about context independence.** If the viewer needs to know who the guest is, or what the
96
+ previous question was, that is −10.
97
+
98
+ **Do not inflate the mean.** If twenty clips all come out above 80, the rubric is not being applied.
99
+ A healthy batch spreads widely, with few above 85.
100
+
101
+ **Justify every low score with what happens in the clip**, at a timestamp — not with a generality.
102
+
103
+ ## Anti-patterns
104
+
105
+ | Anti-pattern | Do instead |
106
+ |---|---|
107
+ | Scoring how interesting the subject is | Score this clip's execution; the topic is not the artifact |
108
+ | Grading the hook from the full idea | Read only the first three seconds as the viewer receives them |
109
+ | Compressing a batch into 78-85 | Use the range; a flat distribution means the instrument is not being used |
110
+ | "Weak hook" with no evidence | Quote the opening words and the timestamp |
111
+ | Adjusting weights for a clip you like | The weights are the instrument. Argue in the reasons, score with the rubric |
112
+ | Rendering first, scoring after | Score transcript candidates, then edit only what survives |
113
+ | Skipping the penalties because the total looks low | They are automatic and they stack; a 72 with three penalties is a 49 |
114
+
115
+ ## See Also
116
+
117
+ - `../shortform-packaging/SKILL.md` — the hook line, caption, hashtags and cover for a clip that
118
+ passed this bar.
119
+ - `../shortform-ideation/SKILL.md` — inventing the angle, upstream of anything scoreable.
120
+ - `../shortform-editing/SKILL.md` — executing the edit once a clip is chosen.
121
+ - `../shortform-strategy/SKILL.md` — what the channel should publish over time, which this feeds
122
+ with per-clip evidence.
@@ -0,0 +1,16 @@
1
+ # Evals — viral-score
2
+
3
+ These are routing and capability checks, not an automated harness. Run them by hand:
4
+ read each `should_trigger` prompt and confirm the skill fires on it — including the two
5
+ non-obvious ones ("this clip feels flat but I can't say why" and the retrospective "why
6
+ did this short underperform"), which carry no scoring keyword, and the Spanish prompt;
7
+ read each `should_not_trigger` prompt and confirm the description's NOT-boundary sends it
8
+ to the named `route_to` sibling instead. The neighbours are close together, so the
9
+ packaging / ideation / editing / strategy split is the part most worth checking.
10
+
11
+ For the `capability` cases, score the described clip for real and check the answer hits
12
+ every `must_include` line. The first case exists because penalties are the step most often
13
+ skipped: an opener mid-sentence, a 4s pause and an unresolved ending must each subtract,
14
+ and the total must be clamped after they do. The second checks that batch mode produces
15
+ what a single-clip run does not — a ranking and an explicit cut-off. No network, no
16
+ fixtures.
@@ -0,0 +1,50 @@
1
+ skill: viral-score
2
+
3
+ should_trigger:
4
+ - prompt: "Score this reel — is it worth publishing?"
5
+ why: Core ask — a single clip judged against the rubric, verdict required.
6
+ - prompt: "I cut 20 clips from yesterday's episode. Rank them and tell me which ones to post."
7
+ why: Batch mode — ranking plus the cut-off line, which only this skill produces.
8
+ - prompt: "Order these shorts from best to worst."
9
+ why: Comparison with no scoring keyword; ordering clips requires a shared instrument.
10
+ - prompt: "Here's the transcript of a 2h podcast. Which passages would make good shorts?"
11
+ why: The pre-render case the skill exists for — score candidates before anything is edited.
12
+ - prompt: "Valora este reel y dime si lo publico o lo descarto."
13
+ why: Spanish — same core ask, publish/discard verdict.
14
+ - prompt: "This clip feels flat to me but I can't say why. Is it me?"
15
+ why: Non-obvious — a vague quality doubt resolves into criterion scores and named weaknesses.
16
+ - prompt: "Why did this short underperform? It seemed strong when I made it."
17
+ why: Non-obvious — retrospective diagnosis against the same criteria, especially hook and context independence.
18
+
19
+ should_not_trigger:
20
+ - prompt: "Write the caption and hashtags for this Reel."
21
+ route_to: shortform-packaging
22
+ why: Upload-form copy for a clip already chosen, not the decision to choose it.
23
+ - prompt: "Give me ten ideas for shorts about discipline."
24
+ route_to: shortform-ideation
25
+ why: Inventing angles, upstream of anything that can be scored.
26
+ - prompt: "Burn in the subtitles and add B-roll to this clip."
27
+ route_to: shortform-editing
28
+ why: Executing the edit; scoring is what decides whether the edit is worth doing.
29
+ - prompt: "How often should I post on this channel, and at what times?"
30
+ route_to: shortform-strategy
31
+ why: Channel cadence over time, not the merit of one artifact.
32
+ - prompt: "Design a thumbnail for my YouTube video."
33
+ route_to: youtube-thumbnails
34
+ why: A different surface and a different artifact; this rubric scores the clip itself.
35
+
36
+ capability:
37
+ - prompt: "Score this 18s clip: it opens mid-sentence with 'o sea, entonces lo que pasa es que…', has a 4s pause in the middle, and ends without resolving the point."
38
+ must_include:
39
+ - "a score for all ten criteria"
40
+ - "the weak-hook penalty applied for opening mid-sentence"
41
+ - "the long-pause penalty"
42
+ - "the unsatisfying-ending penalty"
43
+ - "a final score clamped to 0-100 after penalties"
44
+ - "a Publish / Review / Discard verdict"
45
+ - prompt: "Here are 6 clips from one episode with their transcripts. Rank them."
46
+ must_include:
47
+ - "a Viral Score for every clip"
48
+ - "a ranking from highest to lowest"
49
+ - "an explicit cut-off point below which publishing is not worth it"
50
+ - "strengths and weaknesses per clip, tied to what happens in it"