@ericrisco/rsc 0.1.47 → 0.1.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/manifest.json +29 -29
- package/package.json +1 -1
- package/skills/db-migrations/SKILL.md +3 -20
- package/skills/decision-records/SKILL.md +3 -3
- package/skills/deep-learning/SKILL.md +12 -49
- package/skills/digitalocean/SKILL.md +10 -34
- package/skills/django/SKILL.md +2 -7
- package/skills/docker/SKILL.md +12 -44
- package/skills/document-processing/SKILL.md +5 -13
- package/skills/domains-dns/SKILL.md +2 -17
- package/skills/drizzle-orm/SKILL.md +1 -4
- package/skills/duckdb/SKILL.md +12 -18
- package/skills/dynamodb/SKILL.md +27 -40
- package/skills/e-signature/SKILL.md +9 -9
- package/skills/e2e-testing/SKILL.md +2 -12
- package/skills/electron/SKILL.md +12 -24
- package/skills/elixir/SKILL.md +6 -14
- package/skills/email-connector/SKILL.md +20 -37
- package/skills/email-deliverability/SKILL.md +9 -29
- package/skills/embeddings-search/SKILL.md +10 -19
- package/skills/error-handling/SKILL.md +10 -44
- package/skills/error-handling/scripts/verify.sh +0 -0
- package/skills/expo/SKILL.md +30 -45
- package/skills/fal/SKILL.md +2 -16
- package/skills/finance-ops/SKILL.md +5 -13
- package/skills/financial-model/SKILL.md +17 -35
- package/skills/finetuning/SKILL.md +7 -19
- package/skills/firebase/SKILL.md +19 -33
- package/skills/fly-io/SKILL.md +4 -13
- package/skills/fundraising/SKILL.md +5 -14
- package/skills/game-design/SKILL.md +9 -33
package/skills/elixir/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: elixir
|
|
3
|
-
description: "Use when writing or refactoring Elixir/OTP
|
|
3
|
+
description: "Use when writing or refactoring Elixir/OTP on the BEAM — GenServers, supervision trees and restart strategies, pattern matching, mix projects and releases — or when processes misbehave (restart loops, mailbox growth, call timeouts). NOT a Phoenix web app, LiveView, Ecto or channels (that is `phoenix`)."
|
|
4
4
|
tags: [elixir, otp, genserver, supervision, beam, mix, concurrency, functional]
|
|
5
5
|
recommends: [phoenix, postgresdb, docker]
|
|
6
6
|
origin: risco
|
|
@@ -14,7 +14,7 @@ Default to **pure functions**. Most of your code is data transformation and need
|
|
|
14
14
|
|
|
15
15
|
## Decision: do you even need a process?
|
|
16
16
|
|
|
17
|
-
A process is not "an object"
|
|
17
|
+
A process is not "an object": spawning one to hold a value you could pass as an argument is the most common beginner mistake, and it adds a serialization bottleneck and a failure mode for nothing.
|
|
18
18
|
|
|
19
19
|
| Situation | Use | Why |
|
|
20
20
|
|---|---|---|
|
|
@@ -28,8 +28,6 @@ Rule: if two pieces of code never run at the same time and share no mutable stat
|
|
|
28
28
|
|
|
29
29
|
## The functional core
|
|
30
30
|
|
|
31
|
-
Each rule below earns its place; the why is one line.
|
|
32
|
-
|
|
33
31
|
**Match in function heads, not with `if`** — branches become exhaustive and self-documenting, and a non-match crashes loudly instead of silently falling through.
|
|
34
32
|
|
|
35
33
|
```elixir
|
|
@@ -80,13 +78,11 @@ end
|
|
|
80
78
|
|
|
81
79
|
## Processes and message passing
|
|
82
80
|
|
|
83
|
-
Raw `spawn`/`send`/`receive` exists, but in production you almost always want an OTP behaviour (GenServer/Task/Agent) so you get `child_spec`, supervision, and shutdown handling for free.
|
|
81
|
+
Raw `spawn`/`send`/`receive` exists and is fine for a throwaway fire-and-forget where supervision genuinely does not matter, but in production you almost always want an OTP behaviour (GenServer/Task/Agent) so you get `child_spec`, supervision, and shutdown handling for free.
|
|
84
82
|
|
|
85
83
|
- **Link** (`spawn_link`) couples lifetimes: if one dies abnormally, the other gets an exit signal. This is how supervision works.
|
|
86
84
|
- **Monitor** (`Process.monitor/1`) is one-directional and non-fatal: you get a `{:DOWN, ...}` message but you do not die. Use it when you care *that* something died but should survive it.
|
|
87
85
|
|
|
88
|
-
Drop to raw processes only for a throwaway fire-and-forget where supervision genuinely does not matter; otherwise reach for OTP.
|
|
89
|
-
|
|
90
86
|
## GenServer
|
|
91
87
|
|
|
92
88
|
Split the **client API** (runs in the caller) from the **server callbacks** (run in the GenServer process). Callers never touch state directly.
|
|
@@ -124,11 +120,9 @@ defmodule Counter do
|
|
|
124
120
|
end
|
|
125
121
|
```
|
|
126
122
|
|
|
127
|
-
Rules, each with its why:
|
|
128
|
-
|
|
129
123
|
- **Never block in `init/1`.** `start_link` blocks until `init` returns, so a slow `init` stalls the whole supervision tree boot. Return `{:ok, state, {:continue, term}}` and do the work in `handle_continue/2`.
|
|
130
124
|
- **`use GenServer` auto-defines `child_spec/1`** — you rarely write one by hand; override only to change `:restart` or `:shutdown`.
|
|
131
|
-
- **`call` is synchronous (with a 5s default timeout), `cast` is fire-and-forget.** Use `call` when the caller needs the result or backpressure; `cast` when it does not. A flood of `cast`s with no backpressure is the classic mailbox-growth bug —
|
|
125
|
+
- **`call` is synchronous (with a 5s default timeout), `cast` is fire-and-forget.** Use `call` when the caller needs the result or backpressure; `cast` when it does not. A flood of `cast`s with no backpressure is the classic mailbox-growth bug — timeouts and backpressure recipes in `references/otp-patterns.md`.
|
|
132
126
|
- **Name via `Registry`, not a global atom**, when you have many dynamic instances — atoms are never garbage-collected (see anti-patterns).
|
|
133
127
|
|
|
134
128
|
## Supervision trees
|
|
@@ -164,7 +158,7 @@ end
|
|
|
164
158
|
|
|
165
159
|
**Let it crash**: do not wrap business logic in `try/rescue` to keep a process alive. Validate inputs at the boundary, then trust the happy path; if an invariant breaks, crashing and restarting from a known-good `init` state is the recovery mechanism. Reserve `rescue` for boundaries where you must convert an exception into a tagged tuple for a caller.
|
|
166
160
|
|
|
167
|
-
For runtime-spawned children (a worker per connection/job) use `DynamicSupervisor` + `Registry` for lookup. Full recipe in references/otp-patterns.md
|
|
161
|
+
For runtime-spawned children (a worker per connection/job) use `DynamicSupervisor` + `Registry` for lookup. Full recipe — plus `Task`, `Agent`, `:ets` and how to choose an OTP behaviour — in `references/otp-patterns.md`.
|
|
168
162
|
|
|
169
163
|
## mix project
|
|
170
164
|
|
|
@@ -189,7 +183,7 @@ MIX_ENV=prod mix release
|
|
|
189
183
|
_build/prod/rel/my_app/bin/my_app start
|
|
190
184
|
```
|
|
191
185
|
|
|
192
|
-
|
|
186
|
+
`mix.exs` anatomy, deps, environments, env vars, releases and the umbrella decision live in `references/mix-and-releases.md`.
|
|
193
187
|
|
|
194
188
|
## Types and modern stdlib
|
|
195
189
|
|
|
@@ -213,5 +207,3 @@ Deps anatomy, environments, env vars, and the umbrella decision live in referenc
|
|
|
213
207
|
## Verify
|
|
214
208
|
|
|
215
209
|
Run `scripts/verify.sh` from your mix project root (the directory containing `mix.exs`). It checks `mix format --check-formatted` and `mix compile --warnings-as-errors`, and skips cleanly with exit 0 when Elixir/mix is not installed so it never blocks a toolchain-free CI.
|
|
216
|
-
|
|
217
|
-
See references/otp-patterns.md (DynamicSupervisor+Registry, Task, Agent, ETS, timeouts/backpressure, choosing an OTP behaviour) and references/mix-and-releases.md (mix.exs anatomy, config vs runtime, releases, umbrellas).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: email-connector
|
|
3
|
-
description: "Use when wiring
|
|
3
|
+
description: "Use when wiring server code to send transactional or bulk email via Resend, SendGrid, or Postmark: a provider-agnostic sendEmail() seam, idempotent retries, 100-cap batches with partial failures, transactional-vs-broadcast streams, bounce webhooks feeding a suppression list. NOT SPF/DKIM/DMARC inbox reputation (that is `email-deliverability`)."
|
|
4
4
|
tags: [email, transactional-email, resend, sendgrid, postmark, webhooks, idempotency]
|
|
5
5
|
recommends: [email-deliverability, newsletter, webhooks, secure-coding, api-connector-builder, automation-flows]
|
|
6
6
|
origin: risco
|
|
@@ -13,30 +13,16 @@ digest — your job is the server code that hands it to a provider, makes it saf
|
|
|
13
13
|
to retry, and keeps the suppression list honest. You do **not** own the inbox
|
|
14
14
|
(SPF/DKIM/DMARC/reputation is `../email-deliverability/SKILL.md`) and you do
|
|
15
15
|
**not** own the words (subject lines and growth are `../newsletter/SKILL.md`,
|
|
16
|
-
launch copy is `../marketing/SKILL.md`).
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
launch copy is `../marketing/SKILL.md`). Generic typed clients for *any* REST API
|
|
17
|
+
are `../api-connector-builder/SKILL.md`; deciding *when* a multi-step sequence
|
|
18
|
+
fires is `../automation-flows/SKILL.md`.
|
|
19
19
|
|
|
20
20
|
Stack as of June 2026: `resend` 6.12.4, `@sendgrid/mail` 8.1.6, Postmark via its
|
|
21
21
|
HTTP API, React Email 5.0 (React 19.2 / Next.js 16, Tailwind 4), Node 20+ / TS.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
greps for the first three; the fourth is the design constraint behind them.
|
|
27
|
-
|
|
28
|
-
1. **API key from env, never a literal.** `process.env.RESEND_API_KEY`, not
|
|
29
|
-
`re_xxx` / `SG.xxx` / a server token in source. *Why:* a committed key is a
|
|
30
|
-
send-as-you credential — instant abuse and reputation burn.
|
|
31
|
-
2. **Idempotency key on every transactional send.** *Why:* queues retry,
|
|
32
|
-
serverless functions re-fire, users double-click. Without a stable key one
|
|
33
|
-
password reset becomes three.
|
|
34
|
-
3. **Send on the correct stream.** Transactional and broadcast traffic go on
|
|
35
|
-
distinct From + subdomain + stream. *Why:* a marketing reputation hit must
|
|
36
|
-
never push password resets to spam.
|
|
37
|
-
4. **Verify the inbound webhook signature against the raw body.** *Why:* the
|
|
38
|
-
bounce/complaint hook mutates your suppression list; an unverified hook lets
|
|
39
|
-
anyone suppress (or un-suppress) your users.
|
|
23
|
+
`scripts/verify.sh` is read-only and greps a target for the four invariants this
|
|
24
|
+
skill exists to hold: env-sourced key, idempotency, a single `sendEmail()` seam,
|
|
25
|
+
and a webhook signature checked on the raw body.
|
|
40
26
|
|
|
41
27
|
## Step 1 — pick a provider
|
|
42
28
|
|
|
@@ -47,14 +33,18 @@ greps for the first three; the fourth is the design constraint behind them.
|
|
|
47
33
|
| **Postmark** | Pure transactional, deliverability-first | No — self-dedupe via your key + webhooks | Postmark server templates | per-stream | Receipts/resets must never queue behind marketing |
|
|
48
34
|
|
|
49
35
|
Idempotency support changes your strategy, not just your config — see Step 4.
|
|
50
|
-
Full per-provider matrix (auth
|
|
51
|
-
|
|
36
|
+
Full per-provider matrix (auth header, SDK + version, single/batch signatures,
|
|
37
|
+
idempotency model, stream/subdomain model, dynamic-template syntax, webhook event
|
|
38
|
+
names, rate limits, when to pick each) plus a suppression-webhook handler skeleton
|
|
39
|
+
per provider is in `references/providers.md`.
|
|
52
40
|
|
|
53
41
|
## Step 2 — the `sendEmail()` seam
|
|
54
42
|
|
|
55
43
|
One provider-agnostic function. The rest of the app calls `sendEmail(...)` and
|
|
56
44
|
never imports a provider SDK. *Why:* swapping SendGrid→Postmark is then one file,
|
|
57
|
-
not a grep across every call site.
|
|
45
|
+
not a grep across every call site. That one file reads the key from
|
|
46
|
+
`process.env` — never a `re_…` / `SG.…` / server-token literal, because a
|
|
47
|
+
committed key is a send-as-you credential and burns your reputation with it.
|
|
58
48
|
|
|
59
49
|
```ts
|
|
60
50
|
// lib/email/index.ts — the only place a provider SDK is imported
|
|
@@ -174,7 +164,9 @@ const html = '<h1>Hi ' + req.body.name + '</h1>'; // XSS + broken layout risk
|
|
|
174
164
|
|
|
175
165
|
## Step 4 — idempotency & retries
|
|
176
166
|
|
|
177
|
-
|
|
167
|
+
Every transactional send carries a key, because queues retry, serverless
|
|
168
|
+
functions re-fire, and users double-click — without a stable key one password
|
|
169
|
+
reset becomes three. Derive it from the *event*, not the clock. Same event → same
|
|
178
170
|
key → provider (or your table) collapses the duplicate.
|
|
179
171
|
|
|
180
172
|
```ts
|
|
@@ -245,7 +237,9 @@ down with it. The DNS/auth setup for those subdomains is
|
|
|
245
237
|
|
|
246
238
|
The provider POSTs bounce and complaint events. Verify the signature on the
|
|
247
239
|
**raw** body (parse after verifying), then write the address to a suppression
|
|
248
|
-
list and check that list before every future send.
|
|
240
|
+
list and check that list before every future send. The verification is absolute
|
|
241
|
+
because this hook mutates the suppression list: unverified, anyone can suppress
|
|
242
|
+
— or un-suppress — your users.
|
|
249
243
|
|
|
250
244
|
```ts
|
|
251
245
|
// app/api/email/webhook/route.ts (Next.js 16) — verify BEFORE parsing
|
|
@@ -281,14 +275,3 @@ before I ever send) is `../lead-gen/SKILL.md` / `../email-deliverability/SKILL.m
|
|
|
281
275
|
| Trusting the webhook without signature check | Anyone can poison your suppression list | Verify signature on raw body, then parse |
|
|
282
276
|
| Sending to a bounced/complained address | Reputation damage, ISP penalties | Filter against suppression list before send |
|
|
283
277
|
| Calling the provider SDK at scattered call sites | Provider swap = grep across the app | One `sendEmail()` seam (Step 2) |
|
|
284
|
-
|
|
285
|
-
## Reference
|
|
286
|
-
|
|
287
|
-
`references/providers.md` — full side-by-side matrix (auth header, SDK +
|
|
288
|
-
version, single/batch signatures, idempotency model, stream/subdomain model,
|
|
289
|
-
dynamic-template syntax, webhook event names, rate limits, when to pick each)
|
|
290
|
-
plus a suppression-webhook handler skeleton per provider.
|
|
291
|
-
|
|
292
|
-
Generic typed HTTP-client wrappers for *any* REST API →
|
|
293
|
-
`../api-connector-builder/SKILL.md`. The orchestration that decides *when* to
|
|
294
|
-
fire a multi-step sequence → `../automation-flows/SKILL.md`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: email-deliverability
|
|
3
|
-
description: "Use when mail
|
|
3
|
+
description: "Use when mail already sent lands in spam, is rejected, or fails the Gmail/Yahoo bulk-sender checks and the fix is authentication and reputation, not the sending code: SPF/DKIM/DMARC alignment, domain warmup, spam-complaint rate, one-click unsubscribe, BIMI. NOT putting mail on the wire through a provider API (that is `email-connector`)."
|
|
4
4
|
tags: [email, deliverability, spf, dkim, dmarc, bimi, sender-reputation, bulk-sender]
|
|
5
5
|
recommends: [email-connector, newsletter, cold-outreach, gdpr-privacy, data-policy]
|
|
6
6
|
origin: risco
|
|
@@ -9,34 +9,26 @@ origin: risco
|
|
|
9
9
|
# email-deliverability — make mail authenticate and land in the inbox
|
|
10
10
|
|
|
11
11
|
This skill owns one layer: **why mail you already send gets filtered, deferred,
|
|
12
|
-
or rejected, and the DNS + reputation work that fixes it.** It
|
|
13
|
-
|
|
14
|
-
succeeds but the message never reaches the inbox.
|
|
12
|
+
or rejected, and the DNS + reputation work that fixes it.** It starts where the
|
|
13
|
+
send technically succeeds but the message never reaches the inbox.
|
|
15
14
|
|
|
16
15
|
The lever is almost never the sending code. It is three DNS records that must
|
|
17
16
|
*align*, a complaint rate you must hold down, and a reputation you build slowly
|
|
18
17
|
and lose fast. Treat this as ops on a domain, not a code change.
|
|
19
18
|
|
|
20
|
-
##
|
|
21
|
-
|
|
22
|
-
**Use when:** mail lands in spam or Promotions and you suspect auth/reputation,
|
|
23
|
-
not copy; a receiver returns `550 5.7.26` (unauthenticated), `421`/`451`
|
|
24
|
-
deferrals, or `dmarc=fail`; you must meet the Gmail/Yahoo bulk-sender rules
|
|
25
|
-
before a launch; you are standing up a brand-new sending domain and need a
|
|
26
|
-
warmup plan; Google Postmaster Tools shows a rising spam rate or "Bad" domain
|
|
27
|
-
reputation; you want the brand logo and a verified checkmark to show in Gmail
|
|
28
|
-
(BIMI + VMC/CMC).
|
|
29
|
-
|
|
30
|
-
**Do NOT use for:**
|
|
19
|
+
## Not this skill
|
|
31
20
|
|
|
32
21
|
- **Sending the mail at all** — provider SDK, `sendEmail()` seam, templates,
|
|
33
|
-
retries, batch caps, bounce/complaint webhooks →
|
|
34
|
-
feeds the suppression list; this one explains the reputation it
|
|
22
|
+
retries, batch caps, bounce/complaint webhooks → `../email-connector/SKILL.md`.
|
|
23
|
+
That skill feeds the suppression list; this one explains the reputation it
|
|
24
|
+
protects.
|
|
35
25
|
- **Subject lines, open/click optimization, list growth** → `newsletter`.
|
|
36
26
|
- **Outbound prospecting sequences, lead lists** → `cold-outreach` (deliverability
|
|
37
27
|
is a *constraint* on it, not the same job).
|
|
38
28
|
- **Consent, lawful basis, retention of the address list** → `gdpr-privacy` and
|
|
39
29
|
`data-policy`. Unsubscribe *mechanics* live here; consent *law* does not.
|
|
30
|
+
- **Handling the DKIM private key and provider API secrets** →
|
|
31
|
+
`../secure-coding/SKILL.md`.
|
|
40
32
|
|
|
41
33
|
## The three records that must align
|
|
42
34
|
|
|
@@ -154,15 +146,3 @@ low-complaint sending.
|
|
|
154
146
|
| Faking transactional headers to dodge Promotions | Violates bulk rules; risks rejection, not just foldering | Accept Promotions placement; earn Primary via engagement |
|
|
155
147
|
| Routing the unsubscribe to a form that takes a week | Breaks the 2-day one-click honor rule; raises complaints | Honor `List-Unsubscribe-Post` one-click within 2 days, automatically |
|
|
156
148
|
| Adding BIMI to fix spam-foldering | BIMI needs DMARC enforcement you do not have yet, and it changes logo display, not placement | Fix auth + reputation first; add BIMI last as a branding layer |
|
|
157
|
-
|
|
158
|
-
## See also
|
|
159
|
-
|
|
160
|
-
- `../email-connector/SKILL.md` — the provider/SDK send path, suppression list,
|
|
161
|
-
and bounce/complaint webhook that this skill's reputation rules sit on top of.
|
|
162
|
-
- `../secure-coding/SKILL.md` — handling the DKIM private key and provider API
|
|
163
|
-
secrets without leaking them.
|
|
164
|
-
|
|
165
|
-
Recommended companions (siblings): `email-connector` for the actual send,
|
|
166
|
-
`newsletter` for the copy/engagement side that drives complaint rate down,
|
|
167
|
-
`cold-outreach` (deliverability gates it), and `gdpr-privacy` / `data-policy`
|
|
168
|
-
for the consent and retention behind a clean list.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: embeddings-search
|
|
3
|
-
description: "Use when
|
|
3
|
+
description: "Use when choosing an embedding model, chunk size, or query form, when semantic search returns irrelevant results, when adding hybrid BM25+vector or a reranker, or when a retrieval change needs a number (recall@k, nDCG, MRR). NOT operating the store — index tuning, quantization (that is `vector-db`) — nor the retrieve-to-answer loop (that is `rag`)."
|
|
4
4
|
tags: [embeddings, semantic-search, chunking, hybrid-search, reranking, rrf, retrieval-eval, mteb, matryoshka]
|
|
5
5
|
recommends: [vector-db, rag, structured-extraction, prompt-engineering, postgresdb]
|
|
6
6
|
origin: risco
|
|
@@ -9,10 +9,9 @@ origin: risco
|
|
|
9
9
|
# embeddings-search — make and judge the vectors
|
|
10
10
|
|
|
11
11
|
You own the **embedding technique layer**: turn a corpus into searchable vectors, turn a
|
|
12
|
-
question into a good retrieval, and **measure whether that retrieval is any good**.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
back, measured by a number. You do not assemble a prompt or generate an answer.
|
|
12
|
+
question into a good retrieval, and **measure whether that retrieval is any good**. You stop the
|
|
13
|
+
moment the right chunks come back, measured by a number. You do not assemble a prompt or
|
|
14
|
+
generate an answer.
|
|
16
15
|
|
|
17
16
|
Route the adjacent surfaces away:
|
|
18
17
|
|
|
@@ -41,7 +40,9 @@ cost — where cost is set by **dimensions**, because dims set storage and memor
|
|
|
41
40
|
|
|
42
41
|
Quality anchor (mid-2026 MTEB English retrieval): Gemini ~68.3, Cohere `embed-v4` ~65.2,
|
|
43
42
|
OpenAI `3-large` ~64.6, `BGE-M3` ~63.0. MTEB is the standard comparison, not a verdict on
|
|
44
|
-
*your* domain
|
|
43
|
+
*your* domain — [`references/models.md`](references/models.md) carries the full model matrix
|
|
44
|
+
(dims, max tokens, price, `input_type` convention, Matryoshka support) and how to read MTEB
|
|
45
|
+
without over-trusting it.
|
|
45
46
|
|
|
46
47
|
Two hard rules — each is a **silent** failure, no error, just worse results:
|
|
47
48
|
|
|
@@ -153,7 +154,9 @@ This is the rigor of the skill. "Search is bad" is not actionable; "recall@10 is
|
|
|
153
154
|
|
|
154
155
|
1. **Build a golden query set** — 30–50+ labeled `query → relevant doc ids` pairs drawn from
|
|
155
156
|
real questions. This is the asset; everything else is reproducible from it.
|
|
156
|
-
2. **Pick metrics**
|
|
157
|
+
2. **Pick metrics** — definitions, a runnable Python eval skeleton, golden-set construction and
|
|
158
|
+
the A/B-one-change methodology are in
|
|
159
|
+
[`references/evaluation.md`](references/evaluation.md):
|
|
157
160
|
- **recall@k** — of the truly relevant docs, how many landed in the top-k. Catches "the
|
|
158
161
|
right chunk never came back."
|
|
159
162
|
- **nDCG@k** — rewards relevant docs ranked higher. Catches "right docs, wrong order."
|
|
@@ -179,15 +182,3 @@ flags hybrid/rerank artifacts that mention no recall/nDCG/MRR for exactly this r
|
|
|
179
182
|
| Over-large dims "for safety" | Doubles storage/RAM, little recall gain | Right-size; truncate via Matryoshka |
|
|
180
183
|
| Re-embedding the corpus to change dims | Wasteful when the model is Matryoshka-trained | Truncate dims, don't re-embed |
|
|
181
184
|
| Embedding raw HTML/boilerplate | Match signal drowns in markup | Embed clean text; keep the rest as metadata |
|
|
182
|
-
|
|
183
|
-
## References & siblings
|
|
184
|
-
|
|
185
|
-
- `references/models.md` — current model matrix (dims, max tokens, price, `input_type`
|
|
186
|
-
convention, Matryoshka support) and how to read MTEB without over-trusting it.
|
|
187
|
-
- `references/evaluation.md` — golden-set construction, recall@k / nDCG@k / MRR definitions, a
|
|
188
|
-
runnable Python eval skeleton, and the A/B-one-change methodology.
|
|
189
|
-
|
|
190
|
-
Siblings: store ops → [`../vector-db/SKILL.md`](../vector-db/SKILL.md) · full answer loop →
|
|
191
|
-
[`../rag/SKILL.md`](../rag/SKILL.md) · typed extraction →
|
|
192
|
-
[`../structured-extraction/SKILL.md`](../structured-extraction/SKILL.md) · prompt design →
|
|
193
|
-
[`../prompt-engineering/SKILL.md`](../prompt-engineering/SKILL.md).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: error-handling
|
|
3
|
-
description: "Use when designing
|
|
3
|
+
description: "Use when designing the reaction to a class of failures — typed error taxonomies, retry/backoff/timeout policy, circuit breakers, React/Next error boundaries, and the user-message vs operator-log split. NOT diagnosing one specific crash (that is debug), NOT logs/metrics/traces (that is observability), NOT the wire error envelope (that is api-design)."
|
|
4
4
|
tags: [error-handling, resilience, retry, circuit-breaker, error-boundary, typed-errors, fault-tolerance]
|
|
5
5
|
recommends: [debug, observability, monitoring, api-design, secure-coding, testing-web, nextjs]
|
|
6
6
|
origin: risco
|
|
@@ -9,23 +9,11 @@ origin: risco
|
|
|
9
9
|
# Error handling — classify, contain, surface
|
|
10
10
|
|
|
11
11
|
You are designing what happens *whenever anything in a class breaks*, not chasing
|
|
12
|
-
one crash (that is [`debug`](../debug/SKILL.md)).
|
|
13
|
-
|
|
12
|
+
one crash (that is [`debug`](../debug/SKILL.md)). Every failure gets classified,
|
|
13
|
+
contained, and surfaced — never swallowed. The deliverable, in that order: a typed
|
|
14
|
+
error taxonomy, a retry policy with caps and jitter, boundary placement, and a
|
|
14
15
|
two-audience message contract — never a pile of `try { … } catch {}`.
|
|
15
16
|
|
|
16
|
-
## The one rule
|
|
17
|
-
|
|
18
|
-
**Every failure gets classified, contained, and surfaced — never swallowed.**
|
|
19
|
-
|
|
20
|
-
- **Classify** — give the failure a type so the right code can react to the right
|
|
21
|
-
kind. An untyped `catch (e)` cannot decide anything.
|
|
22
|
-
- **Contain** — stop one failing dependency from taking the process (or the DB)
|
|
23
|
-
with it. No timeout, no cap = unbounded blast radius.
|
|
24
|
-
- **Surface** — emit two things: a human message that never leaks internals, and
|
|
25
|
-
an operator log with the full cause chain.
|
|
26
|
-
|
|
27
|
-
The five steps below are those three jobs in order. Do them in order.
|
|
28
|
-
|
|
29
17
|
## Step 1 — Model failure as a taxonomy
|
|
30
18
|
|
|
31
19
|
Bucket every failure into one of three kinds. The bucket dictates the reaction;
|
|
@@ -257,19 +245,6 @@ GOOD → 503 { "code": "upstream_unavailable", "correlationId": "a1b2c3" }
|
|
|
257
245
|
More before/after rewrites and the copy contract are in
|
|
258
246
|
[`references/boundaries-and-messaging.md`](references/boundaries-and-messaging.md).
|
|
259
247
|
|
|
260
|
-
## Decision table
|
|
261
|
-
|
|
262
|
-
| Situation | Reaction |
|
|
263
|
-
|---|---|
|
|
264
|
-
| Expected domain outcome the caller must handle | `Result<T,E>` |
|
|
265
|
-
| Programmer bug / invariant violation | `throw` → nearest boundary |
|
|
266
|
-
| Transient failure on an idempotent call | retry (capped + full jitter) |
|
|
267
|
-
| Transient failure on a mutation without a key | do **not** retry; require idempotency key first |
|
|
268
|
-
| Dependency failing repeatedly | circuit-break + fallback |
|
|
269
|
-
| Failure during React render | `error.tsx` boundary |
|
|
270
|
-
| Failure in an event handler / async callback | explicit `try/catch` + state |
|
|
271
|
-
| Unhandled at the top of the process | process handler → log + exit |
|
|
272
|
-
|
|
273
248
|
## Anti-patterns
|
|
274
249
|
|
|
275
250
|
| Anti-pattern | Why it bites | Fix |
|
|
@@ -289,19 +264,10 @@ More before/after rewrites and the copy contract are in
|
|
|
289
264
|
| One giant `try` around 200 lines | you cannot tell which call failed | scope `try` to the fallible call |
|
|
290
265
|
| Treat every error as a retryable transient | masks real bugs as "flaky" | classify first (Step 1), then react |
|
|
291
266
|
|
|
292
|
-
##
|
|
293
|
-
|
|
294
|
-
Before claiming the failure path is handled:
|
|
295
|
-
|
|
296
|
-
- [ ] Every failure maps to one of the three buckets (Step 1).
|
|
297
|
-
- [ ] No empty `catch {}` / `except: pass` / bare `except:`.
|
|
298
|
-
- [ ] Retries are capped, jittered, transient-only, and idempotent-only.
|
|
299
|
-
- [ ] Every outbound call has a per-attempt timeout.
|
|
300
|
-
- [ ] Repeatedly-failing dependencies have a circuit breaker + fallback.
|
|
301
|
-
- [ ] `error.tsx` / `global-error.tsx` placed correctly; render-only limits known.
|
|
302
|
-
- [ ] User message has no internals + carries a correlation id; the log has the cause chain.
|
|
303
|
-
- [ ] Cause is preserved on every wrap (no lost root error).
|
|
267
|
+
## The gate
|
|
304
268
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
269
|
+
Before claiming the failure path is handled, read your diff against the table
|
|
270
|
+
above — those rows *are* the checklist. `scripts/verify.sh <path>` scans the
|
|
271
|
+
working tree for the highest-signal ones. It is **advisory** (exit 0 with
|
|
272
|
+
warnings); pass `--strict` to make any hit fail. It is heuristic — it flags,
|
|
273
|
+
you judge.
|
|
File without changes
|
package/skills/expo/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: expo
|
|
3
|
-
description: "Use when
|
|
3
|
+
description: "Use when shipping a React Native app with Expo — EAS Build/Submit/Update, eas.json profiles and channels, config plugins, prebuild/CNG, runtime-version policy, OTA updates that never land, SDK upgrades, the New Architecture. NOT RN UI, navigation or native-module authoring (that is `react-native`), NOT a Dart app (that is `flutter`)."
|
|
4
4
|
tags: [expo, eas, react-native, mobile, ota-updates, app-store]
|
|
5
5
|
recommends: [react-native, github-actions, ship, deployment, secure-coding]
|
|
6
6
|
origin: risco
|
|
@@ -13,29 +13,19 @@ origin: risco
|
|
|
13
13
|
Expo is the toolchain and **EAS cloud platform** layered on React Native: cloud
|
|
14
14
|
builds, store submission, over-the-air JS updates, and **native configuration
|
|
15
15
|
declared in JavaScript** instead of hand-edited Xcode/Gradle projects. This skill
|
|
16
|
-
owns the *shipping pipeline* and *native-config-via-JS*.
|
|
17
|
-
navigation, animation, or native-module authoring — that is `react-native`.
|
|
16
|
+
owns the *shipping pipeline* and *native-config-via-JS*.
|
|
18
17
|
|
|
19
18
|
The verb rule of thumb: if the verb is **build / submit / update / prebuild /
|
|
20
19
|
plugin / EAS / channel / runtime-version**, you are in `expo`. If it is **render /
|
|
21
|
-
navigate / animate / bridge / write a native module**, route to react-native
|
|
22
|
-
|
|
20
|
+
navigate / animate / bridge / write a native module**, route to `react-native`.
|
|
21
|
+
Other exits: web React/hooks/state → `react`, a Dart app → `flutter`, native-only
|
|
22
|
+
Swift/Kotlin → `swift-ios`/`kotlin-android`, a desktop wrapper → `tauri`/`electron`,
|
|
23
|
+
CI unrelated to EAS → `github-actions`.
|
|
24
|
+
|
|
25
|
+
Current stable as of 2026-06-02: **Expo SDK 55** — React Native 0.83.1, React
|
|
23
26
|
19.2.0, shipped 2026-02-25. **SDK 56 is in beta** (beta opened 2026-05-06, ~2-week
|
|
24
27
|
window; RN 0.85.2, React 19.2.3) — upcoming, not yet shipped stable. Both run
|
|
25
|
-
exclusively on the New Architecture; the Legacy Architecture was removed in SDK 55.
|
|
26
|
-
|
|
27
|
-
## When to use / when NOT to use
|
|
28
|
-
|
|
29
|
-
**Use when:** wiring `eas.json` profiles or channels; cloud-building `.ipa`/`.aab`/
|
|
30
|
-
`.apk` and debugging EAS Build/credentials/queues; shipping EAS Update OTA JS
|
|
31
|
-
(runtime policy, branches, channels, rollouts/rollbacks); submitting with EAS
|
|
32
|
-
Submit; writing/debugging config plugins or `app.config.{js,ts}`/prebuild; building
|
|
33
|
-
a dev client; EAS Workflows YAML; migrating to the New Architecture or upgrading SDK.
|
|
34
|
-
|
|
35
|
-
**Do NOT use when** the work is pure RN code with no Expo/EAS angle (route to
|
|
36
|
-
react-native), web React/hooks/state (`react`), a Dart app (`flutter`), native-only
|
|
37
|
-
Swift/Kotlin (`swift-ios`/`kotlin-android`), a desktop wrapper (`tauri`/`electron`),
|
|
38
|
-
or generic CI unrelated to EAS (`github-actions`).
|
|
28
|
+
exclusively on the New Architecture; the Legacy Architecture was removed in SDK 55.
|
|
39
29
|
|
|
40
30
|
## Decision rules
|
|
41
31
|
|
|
@@ -91,6 +81,9 @@ stamped with a `channel`; a channel maps to a same-named EAS Update branch by de
|
|
|
91
81
|
}
|
|
92
82
|
```
|
|
93
83
|
|
|
84
|
+
Run `scripts/verify.sh` inside an Expo project to gate `eas.json`, the runtime
|
|
85
|
+
policy, committed secrets, and New-Arch readiness.
|
|
86
|
+
|
|
94
87
|
## EAS Update mental model
|
|
95
88
|
|
|
96
89
|
Runtime version is the **compatibility gate**. An update applies to a build only
|
|
@@ -220,34 +213,26 @@ $50/concurrency/month, up to 5 extra. If a user complains about build queue wait
|
|
|
220
213
|
the fix is usually the plan, not the config. (Pricing per expo.dev/pricing, verified
|
|
221
214
|
2026-06-02; re-check before quoting — Expo adjusts tiers and dollar figures.)
|
|
222
215
|
|
|
223
|
-
## Anti-patterns
|
|
216
|
+
## Anti-patterns
|
|
224
217
|
|
|
225
|
-
|
|
|
218
|
+
| Anti-pattern | Do instead |
|
|
226
219
|
|---|---|
|
|
227
|
-
|
|
|
228
|
-
|
|
|
229
|
-
|
|
|
230
|
-
| "
|
|
231
|
-
|
|
|
232
|
-
|
|
|
233
|
-
|
|
|
234
|
-
|
|
|
235
|
-
|
|
|
236
|
-
|
|
|
220
|
+
| Editing `ios/Info.plist` directly | `prebuild --clean` overwrites it; write a config plugin / `withInfoPlist`. |
|
|
221
|
+
| Hardcoding `runtimeVersion: '1.0.0'` because it is simpler | it drifts from the binary; updates silently stop matching. Use the `fingerprint` policy. |
|
|
222
|
+
| Expecting an OTA update to deliver a bumped native dep | EAS Update is JS-only; native changes need a new `eas build`. |
|
|
223
|
+
| Telling users to "just refresh" when a published update does not land | check the channel→branch and exact runtime match first — wrong channel = no delivery. |
|
|
224
|
+
| Testing a custom native module in Expo Go | Expo Go can't load arbitrary native code; build a dev client. |
|
|
225
|
+
| Upgrading the SDK and building straight to production | run `expo-doctor` + a preview build first; there is no Legacy-Arch fallback to catch a New-Arch-incompatible dep. |
|
|
226
|
+
| Setting `newArchEnabled: false` to dodge a broken native dep | the flag was removed in SDK 55 and the Legacy Architecture is gone; fix or replace the dep. |
|
|
227
|
+
| Committing the keystore so CI can sign | never; let EAS manage credentials or use EAS secrets. |
|
|
228
|
+
| Putting the API key in `app.config` extra | app config ships in the public bundle; use EAS env vars / a backend. |
|
|
229
|
+
| Reaching for GitHub Actions to call `eas build` | EAS Workflows is the native CI; only reach for github-actions if explicitly required. |
|
|
237
230
|
|
|
238
231
|
## Project grounding (02-DOCS + CLAUDE.md)
|
|
239
232
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
managed-vs-bare,
|
|
243
|
-
status —
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
gated* — never block the task on this.
|
|
247
|
-
|
|
248
|
-
## See also
|
|
249
|
-
|
|
250
|
-
- `references/eas-update.md` — runtime version policies, channel↔branch ops, rollouts/rollbacks, republish, "update not applying" debug flow.
|
|
251
|
-
- `references/config-plugins.md` — plugin anatomy, mods/dangerous-mods/ordering, common community plugins, prebuild troubleshooting, dynamic `app.config.ts`.
|
|
252
|
-
- `scripts/verify.sh` — run in your Expo project to gate `eas.json`, runtime policy, committed-secret, and New-Arch readiness.
|
|
253
|
-
- Sibling skills: `react-native` (RN UI/navigation/native modules — the other half of every Expo app), `secure-coding` (credential & secret handling), `ship`/`deployment` (release process), `github-actions` (only if you want non-Expo CI).
|
|
233
|
+
In a project with a `02-DOCS/` layer (the [`harness`](../harness/SKILL.md) wiki),
|
|
234
|
+
read `02-DOCS/wiki/stack/expo.md` first and record this app's shipping decisions
|
|
235
|
+
there — managed-vs-bare, runtime-version policy, channel/branch map, SDK/New-Arch
|
|
236
|
+
status — linked from the root `CLAUDE.md` `## Knowledge map`, bumping its `Updated`
|
|
237
|
+
date when a convention changes. No `02-DOCS/`? Skip silently. Conventions are
|
|
238
|
+
*recorded, not gated* — never block the task on this.
|
package/skills/fal/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: fal
|
|
3
|
-
description: "Use when calling a fal.ai
|
|
3
|
+
description: "Use when calling a fal.ai endpoint by id to generate image, audio, or video from JS/Python/curl: subscribe vs submit, queue states, ED25519 webhook signature verification, per-call cost, or migrating off @fal-ai/serverless-client. NOT which model or art direction (that is ai-media); NOT the same models on another platform (that is replicate)."
|
|
4
4
|
tags: [fal, fal-ai, inference, image-generation, video-generation, queue, webhooks, serverless]
|
|
5
5
|
recommends: [ai-media, replicate, replicate-images, modal, webhooks]
|
|
6
6
|
origin: risco
|
|
@@ -10,16 +10,7 @@ origin: risco
|
|
|
10
10
|
|
|
11
11
|
The wire to fal.ai's fast, pre-warmed media endpoints: call a model by id, control the queue, get the file back. fal is the **fast-media path** — latency-optimized image (FLUX, Seedream, SD), audio (TTS, music), and video (Veo, Wan, Kling, Hailuo) endpoints you invoke by id with `FAL_KEY`.
|
|
12
12
|
|
|
13
|
-
You own the *mechanics*: auth, call mode, queue states, webhook signatures, file I/O, per-call cost.
|
|
14
|
-
|
|
15
|
-
## When to use
|
|
16
|
-
|
|
17
|
-
- Generating media by calling a fal endpoint (`fal-ai/flux/dev`, `fal-ai/veo3`, `fal-ai/wan-2.5`) from JS, Python, or curl.
|
|
18
|
-
- Choosing the call mode: `subscribe` (block + auto-poll) vs `submit` (instant `request_id`) + queue polling or webhook.
|
|
19
|
-
- Receiving a result by webhook and verifying its ED25519 signature; handling retries and idempotency.
|
|
20
|
-
- Uploading local inputs (image-to-image, image-to-video, ref audio) and reading output URLs.
|
|
21
|
-
- Estimating and capping cost: per-image / per-second / per-megapixel / GPU-hour, plus the 50%-off batch path.
|
|
22
|
-
- Migrating off the deprecated `@fal-ai/serverless-client`.
|
|
13
|
+
You own the *mechanics*: auth, call mode, queue states, webhook signatures, file I/O, per-call cost.
|
|
23
14
|
|
|
24
15
|
## When NOT to use
|
|
25
16
|
|
|
@@ -203,8 +194,3 @@ The full model-family map and per-modality knob list live in [`references/models
|
|
|
203
194
|
| Ignoring the model's pricing unit | "$0.05" is per-second, not per-video — surprise bill | Read the pricing tab; pick the right knob |
|
|
204
195
|
| Tight `while` loop on `queue.status` | Hammers the API, gains nothing | Back off, or use a webhook |
|
|
205
196
|
| `@fal-ai/serverless-client` | Deprecated; missing fixes and APIs | `@fal-ai/client` (v1.10.1) |
|
|
206
|
-
|
|
207
|
-
## References
|
|
208
|
-
|
|
209
|
-
- [`references/queue-and-webhooks.md`](references/queue-and-webhooks.md) — full async lifecycle, complete ED25519 verification (Node + Python), JWKS caching, IP allowlist, idempotent handler, retry/timeout handling.
|
|
210
|
-
- [`references/models-and-cost.md`](references/models-and-cost.md) — model-family map, pricing-unit cheatsheet with 2026 examples, batch path, per-modality spend knobs, finding an endpoint id and its schema.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: finance-ops
|
|
3
|
-
description: "Use when running the money side of a small company on a cash basis
|
|
3
|
+
description: "Use when running the money side of a small company on a cash basis: a 13-week rolling cash-flow forecast and runway, bank-vs-books reconciliation, mapping spend to tax-return expense categories, or a month-end close. NOT posting journal entries, payroll or depreciation (that is `bookkeeping`); NOT multi-year projections (that is `financial-model`)."
|
|
4
4
|
tags: [cash-flow, reconciliation, month-close, expense-categories, runway, small-business-finance]
|
|
5
5
|
recommends: [bookkeeping, invoicing, financial-model, unit-economics, cost-tracking, forecasting, spreadsheet-ops]
|
|
6
6
|
origin: risco
|
|
@@ -10,13 +10,7 @@ origin: risco
|
|
|
10
10
|
|
|
11
11
|
You are the controller for a small company run on a **cash basis**. Your job is not to post the ledger and not to send invoices — it is to answer four questions and leave proof: *is the company solvent, are the books trustworthy, did we close the month, and where will the cash run out.*
|
|
12
12
|
|
|
13
|
-
Every engagement leaves behind one
|
|
14
|
-
|
|
15
|
-
1. A **13-week rolling cash-flow forecast** (CSV/sheet) — the runway answer.
|
|
16
|
-
2. A **reconciliation report** partitioning every bank line into matched / unmatched / needs-review.
|
|
17
|
-
3. A **month-close checklist** with every gate marked done or blocked.
|
|
18
|
-
|
|
19
|
-
`scripts/verify.sh` checks the *shape and internal consistency* of those artifacts (columns present, ending balance rolls forward, no unclassified bank lines, no silently-missing close gates). It does not judge whether the dollar figures are right — that is your job.
|
|
13
|
+
Every engagement leaves behind at least one checkable artifact — which one depends on the job you pick below. `scripts/verify.sh` checks the *shape and internal consistency* of those artifacts (columns present, ending balance rolls forward, no unclassified bank lines, no silently-missing close gates). It does not judge whether the dollar figures are right — that is your job.
|
|
20
14
|
|
|
21
15
|
## Pick the job first
|
|
22
16
|
|
|
@@ -24,10 +18,10 @@ The flow genuinely branches. Decide which of the four you are doing before touch
|
|
|
24
18
|
|
|
25
19
|
| If the ask is… | You are doing | Artifact you produce | Reference |
|
|
26
20
|
|---|---|---|---|
|
|
27
|
-
| "will we run out of cash", "what's our runway", "13-week forecast", "burn rate" | **Forecast** | 13-week rolling forecast CSV | `references/cash-flow-forecast.md` |
|
|
28
|
-
| "reconcile the bank", "these don't match", "what cleared" | **Reconcile** | matched/unmatched/needs-review
|
|
21
|
+
| "will we run out of cash", "what's our runway", "13-week forecast", "burn rate" | **Forecast** | 13-week rolling forecast CSV/sheet — the runway answer | `references/cash-flow-forecast.md` |
|
|
22
|
+
| "reconcile the bank", "these don't match", "what cleared" | **Reconcile** | report partitioning every bank line into matched / unmatched / needs-review | `references/reconciliation.md` |
|
|
29
23
|
| "set up categories", "everything's in Other", "how do I categorize this" | **Categorize** | tax-return-aligned category map | (inline below) |
|
|
30
|
-
| "close the books for May", "what's left before we close" | **Close** | 5-day gate
|
|
24
|
+
| "close the books for May", "what's left before we close" | **Close** | 5-day checklist, every gate done or blocked | `references/month-close.md` |
|
|
31
25
|
|
|
32
26
|
If the ask is actually about posting entries, sending invoices, or a multi-year model, stop and route — see **Hand-offs** at the bottom. Do not silently do another skill's job.
|
|
33
27
|
|
|
@@ -105,8 +99,6 @@ A line that is silently dropped is a hole in the books. `verify.sh` fails if any
|
|
|
105
99
|
- Business meals deductible at **50%** (book them at a rate that preserves the 50% haircut, e.g. category L24b).
|
|
106
100
|
- **1099-NEC required for any contractor paid ≥ $600/yr** — flag contractors crossing that line during categorization so nothing is missed at filing.
|
|
107
101
|
|
|
108
|
-
Categories are the one job here with no separate reference file — the rule (mirror the return, no junk drawer, confirm current-year numbers) is the whole skill.
|
|
109
|
-
|
|
110
102
|
## Month-close
|
|
111
103
|
|
|
112
104
|
Closing is a **sequenced 5-day checklist, not an event.** Target for a small business: books closed in **≤5 days**.
|