@ericrisco/rsc 0.1.43 → 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.
- package/README.md +1 -1
- package/manifest.json +110 -86
- package/package.json +1 -1
- package/scripts/lib/domains.js +1 -1
- package/scripts/skill-migration-brief.md +104 -0
- package/skills/ab-testing/SKILL.md +9 -41
- package/skills/accessibility/SKILL.md +5 -7
- package/skills/ads/SKILL.md +9 -24
- package/skills/agent-eval/SKILL.md +7 -33
- package/skills/agent-safety/SKILL.md +7 -14
- package/skills/ai-media/SKILL.md +4 -20
- package/skills/analytics/SKILL.md +8 -30
- package/skills/analyze/SKILL.md +24 -59
- package/skills/angular/SKILL.md +12 -25
- package/skills/api-connector-builder/SKILL.md +10 -27
- package/skills/api-design/SKILL.md +7 -14
- package/skills/article-writing/SKILL.md +1 -18
- package/skills/astro/SKILL.md +36 -54
- package/skills/author-skill/SKILL.md +41 -74
- package/skills/author-skill/evals/README.md +5 -5
- package/skills/author-skill/evals/cases.yaml +8 -8
- package/skills/author-skill/references/description-recipe.md +25 -26
- package/skills/author-skill/references/eval-authoring.md +1 -1
- package/skills/author-skill/references/rsc-conventions.md +1 -1
- package/skills/automation-flows/SKILL.md +6 -16
- package/skills/automation-strategy/SKILL.md +1 -9
- package/skills/aws-essentials/SKILL.md +6 -23
- package/skills/backups/SKILL.md +1 -7
- package/skills/bash-scripting/SKILL.md +5 -9
- package/skills/bookkeeping/SKILL.md +2 -10
- package/skills/brand-identity/SKILL.md +18 -44
- package/skills/brand-voice/SKILL.md +4 -31
- package/skills/building-agents/SKILL.md +20 -103
- package/skills/business-intelligence/SKILL.md +9 -23
- package/skills/calendar-scheduling/SKILL.md +11 -27
- package/skills/case-studies/SKILL.md +3 -8
- package/skills/chatbot/SKILL.md +6 -23
- package/skills/chrome-extension/SKILL.md +2 -2
- package/skills/clarify/SKILL.md +31 -72
- package/skills/clickhouse-analytics/SKILL.md +2 -8
- package/skills/client-onboarding/SKILL.md +17 -19
- package/skills/cloudflare/SKILL.md +3 -8
- package/skills/code-review/SKILL.md +10 -23
- package/skills/codebase-onboarding/SKILL.md +2 -7
- package/skills/cold-outreach/SKILL.md +9 -30
- package/skills/community/SKILL.md +4 -31
- package/skills/competitor-watch/SKILL.md +20 -35
- package/skills/compliance/SKILL.md +10 -37
- package/skills/compose-multiplatform/SKILL.md +1 -1
- package/skills/constitution/SKILL.md +8 -35
- package/skills/content-engine/SKILL.md +4 -16
- package/skills/context-budget/SKILL.md +3 -21
- package/skills/continuous-learning/SKILL.md +10 -40
- package/skills/contracts/SKILL.md +6 -17
- package/skills/coolify/SKILL.md +8 -14
- package/skills/cost-tracking/SKILL.md +3 -11
- package/skills/course-builder/SKILL.md +17 -45
- package/skills/course-storytelling/SKILL.md +26 -94
- package/skills/cpp/SKILL.md +26 -71
- package/skills/csharp-dotnet/SKILL.md +19 -38
- package/skills/customer-support/SKILL.md +14 -37
- package/skills/dashboard/SKILL.md +6 -26
- package/skills/data-cleaning/SKILL.md +37 -63
- package/skills/data-policy/SKILL.md +8 -21
- package/skills/data-scraper/SKILL.md +1 -7
- package/skills/debug/SKILL.md +10 -49
- package/skills/deployment/SKILL.md +38 -101
- package/skills/design/SKILL.md +34 -116
- package/skills/fable-operator/SKILL.md +1 -4
- package/skills/fastapi/SKILL.md +50 -82
- package/skills/flutter/SKILL.md +41 -89
- package/skills/go/SKILL.md +57 -105
- package/skills/harness/SKILL.md +52 -68
- package/skills/implement/SKILL.md +1 -1
- package/skills/init/SKILL.md +152 -168
- package/skills/marketing/SKILL.md +30 -80
- package/skills/nextjs/SKILL.md +42 -116
- package/skills/orient/SKILL.md +25 -20
- package/skills/parallel/SKILL.md +9 -75
- package/skills/plan/SKILL.md +92 -165
- package/skills/postgresdb/SKILL.md +52 -72
- package/skills/presentations/SKILL.md +49 -87
- package/skills/python/SKILL.md +23 -72
- package/skills/react/SKILL.md +19 -67
- package/skills/review/SKILL.md +22 -52
- package/skills/rust/SKILL.md +40 -115
- package/skills/sdd-init/SKILL.md +9 -14
- package/skills/secure-coding/SKILL.md +80 -109
- package/skills/ship/SKILL.md +25 -55
- package/skills/tasks/SKILL.md +37 -61
- package/skills/typescript/SKILL.md +22 -55
- package/skills/verify/SKILL.md +8 -32
- package/skills/viral-score/SKILL.md +122 -0
- package/skills/viral-score/evals/README.md +16 -0
- package/skills/viral-score/evals/cases.yaml +50 -0
- package/skills/vue-nuxt/SKILL.md +45 -106
- package/skills/worktrees/SKILL.md +24 -69
package/skills/tasks/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tasks
|
|
3
|
-
description: "Use when
|
|
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
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
-
|
|
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
|
-
|
|
159
|
-
`02-DOCS/wiki/sdd/plans/<slug>.md
|
|
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.
|
|
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
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
|
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**
|
|
52
|
-
|
|
53
|
-
|
|
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. **`
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
137
|
-
|
|
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 =
|
package/skills/verify/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: verify
|
|
3
|
-
description: "Use when implementation is finished and
|
|
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
|
-
|
|
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
|
|
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
|
|
136
|
+
## Anti-patterns
|
|
155
137
|
|
|
156
|
-
|
|
|
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:
|
|
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"
|