@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: dashboard
3
- description: "Use when building or fixing a KPI dashboard that decision-makers will actually open and act on within one screen — arranging which metrics earn a tile, framing each tile so it answers a decision at a glance, and picking the right chart per metric. Triggers: 'build a KPI dashboard for leadership', 'exec dashboard on one screen', 'nobody opens the dashboard we built', '20 tiles and I still can't tell if the business is healthy', 'which chart for each of these metrics', 'munta un dashboard de KPIs per a direcció amb el north-star a dalt', 'el dashboard tiene demasiados gráficos y nadie lo mira'. NOT defining the metrics or their targets (that is kpi-framework), wiring the data (that is analytics), or writing a narrative status report (that is reporting)."
3
+ description: "Use when building or fixing a KPI dashboard decision-makers must read in one screen: which metrics earn a tile, how each tile is framed to answer a decision, and which chart fits it. NOT defining the metrics or their targets (that is kpi-framework), wiring the data (that is analytics), or writing a narrative status report (that is reporting)."
4
4
  tags: [kpi-dashboard, data-visualization, executive-dashboard, chart-selection, dashboard-design, at-a-glance]
5
5
  recommends: [kpi-framework, analytics, reporting, forecasting, business-intelligence, ab-testing, design, spreadsheet-ops]
6
6
  origin: risco
@@ -15,19 +15,11 @@ A dashboard is read in **5 seconds by someone who will not scroll**. If a busy r
15
15
 
16
16
  You do **not** decide which metrics matter (that is [kpi-framework](../kpi-framework/SKILL.md)) and you do **not** wire the data source (that is [analytics](../analytics/SKILL.md)). You take a metric set that already exists and make it readable at a glance.
17
17
 
18
- Run `scripts/verify.sh dashboard.yaml` before you hand off. It checks shape and discipline (tile budget, one north-star, required keys, banned charts) — never whether the numbers are correct.
19
-
20
- ## The one rule: the 5-second read
21
-
22
- A dashboard is a **glance, not a report**. The reader looks at the top-left, gets the headline, and decides whether anything needs their attention. Everything you do serves that.
23
-
24
- - One north-star tile, read first, top-left. Why: a screen with no clear entry point forces the reader to hunt, and they won't.
25
- - If a tile does not change a decision, it is decoration. Cut it (Decision Test below).
26
- - A bare number is not actionable. Every number carries a comparison.
18
+ Run `scripts/verify.sh dashboard.yaml` before you hand off. It checks shape and discipline — tile count 1-9, exactly one `north_star: true`, the required keys on every tile, no banned charts — never whether the numbers are correct.
27
19
 
28
20
  ## The Decision Test gate
29
21
 
30
- No tile exists until its metric names the **action it drives**. Ask: *what does someone do differently based on this number?* If the answer is vague ("good to know", "shows we're growing"), the metric is vanity — cut it or convert it.
22
+ No tile exists until its metric names the **action it drives**. Ask: *what does someone do differently based on this number?* If the answer is vague ("good to know", "shows we're growing"), the metric is vanity — cut it or convert it. A tile that changes no decision is decoration.
31
23
 
32
24
  | Vanity metric (Bad) | Actionable conversion (Good) | Decision it drives |
33
25
  | --- | --- | --- |
@@ -94,12 +86,7 @@ Choose the chart from the **shape of the question**, not from what looks impress
94
86
  | Correlation | Scatter | Shows relationship between two measures |
95
87
  | Distribution | Histogram | Shape of spread, not just average |
96
88
 
97
- Kill-list (verify.sh enforces the first two):
98
-
99
- - No `pie` beyond 5 categories — slices become unreadable. Use a sorted bar.
100
- - No `gauge` / `dial` — they waste space and resist comparison. Use a **bullet chart**.
101
- - No dual-axis trickery — two y-axes invent correlations that aren't there.
102
- - No 3D, no donut-with-center-number gimmicks.
89
+ Kill-list: no `pie` beyond 5 categories (sorted bar instead) and no `gauge` / `dial` (bullet chart instead) — verify.sh rejects both; no dual-axis, which invents correlations that aren't there; no 3D and no donut-with-center-number gimmicks.
103
90
 
104
91
  ## Layout & data-ink
105
92
 
@@ -177,7 +164,7 @@ layout:
177
164
  groups: [growth, revenue, health]
178
165
  ```
179
166
 
180
- verify.sh parses this, counts tiles (must be 1-9), checks exactly one `north_star: true`, requires `metric/chart/comparison/owner/refresh/decision` on every tile, and rejects banned charts.
167
+ The keys verify.sh requires on every tile: `metric`, `chart`, `comparison`, `owner`, `refresh`, `decision`.
181
168
 
182
169
  ## Anti-patterns
183
170
 
@@ -195,11 +182,4 @@ verify.sh parses this, counts tiles (must be 1-9), checks exactly one `north_sta
195
182
 
196
183
  ## Handoff
197
184
 
198
- - Metrics undefined? Define the north-star, metric tree, targets and owners first → [kpi-framework](../kpi-framework/SKILL.md).
199
- - No data behind the tiles? Instrument events, funnels, attribution → [analytics](../analytics/SKILL.md).
200
- - Need a written status with commentary on *why* a number moved → [reporting](../reporting/SKILL.md).
201
- - Projecting a metric forward under scenarios → [forecasting](../forecasting/SKILL.md).
202
- - Self-serve slice-and-dice / semantic layer → [business-intelligence](../business-intelligence/SKILL.md).
203
- - Reading out an experiment / variant significance → [ab-testing](../ab-testing/SKILL.md).
204
- - Visual polish, spacing, type scale of the rendered screen → [design](../design/SKILL.md).
205
- - Pulling/joining the underlying numbers in a sheet → [spreadsheet-ops](../spreadsheet-ops/SKILL.md).
185
+ Beyond the routes named above: reading out an experiment or variant significance → [ab-testing](../ab-testing/SKILL.md); visual polish, spacing and type scale of the rendered screen → [design](../design/SKILL.md); pulling or joining the underlying numbers in a sheet → [spreadsheet-ops](../spreadsheet-ops/SKILL.md).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: data-cleaning
3
- description: "Use when a raw dataset is too dirty to trust — nulls and sentinels (-1, 999, \"N/A\"), duplicate rows, inconsistent categories (USA / U.S. / United States), mixed types in one column, junk whitespace/encoding, out-of-range numbers or malformed dates — and you need it cleaned the same way every time, with a schema that fails loud on bad input. Triggers: 'clean and dedupe this CSV', 'normalize these messy categories', 'why did my integer column turn into floats', 'build a repeatable cleaning pipeline', 'add a validation gate before this feeds my model', 'quarantine the bad rows instead of dropping them', 'limpiar y deduplicar este dataset', 'normalitzar dades brutes abans d''analitzar', 'mis fechas se parsean mal y unas filas se duplican'. NOT producing or repairing a spreadsheet/formula/.xlsx (that is spreadsheet-ops), NOT scraping rows off a website (that is data-scraper), NOT parsing fields out of PDFs/HTML (that is structured-extraction)."
3
+ description: "Use when a raw table is too dirty to trust — nulls, sentinels, duplicate rows, category sprawl, mixed types, bad dates — and you need a re-runnable clean() plus a schema gate that fails loud. NOT emitting .xlsx (that is spreadsheet-ops), NOT acquiring rows (that is data-scraper), NOT parsing PDF/HTML into rows (that is structured-extraction)."
4
4
  tags: [data-cleaning, data-quality, pandas, pandera, validation, deduplication, reproducibility, polars]
5
5
  recommends: [duckdb, spreadsheet-ops, structured-extraction, data-scraper, analytics, business-intelligence, forecasting, python]
6
6
  profiles: []
@@ -16,28 +16,17 @@ the same input always yields the same output: versions pinned, sorts determinist
16
16
  a seed. If you can't re-run it tomorrow and get the identical result, you haven't cleaned the data — you've
17
17
  edited a snapshot.
18
18
 
19
- Current stack (verified 2026-06-02): **pandas 3.0.x** (3.0.0 shipped 2026-01-21). Two 3.0 facts shape how you
20
- read and assert: the default `str` dtype is **PyArrow-backed when PyArrow is installed, NumPy-object-backed
21
- otherwise** (PDEP-14 deliberately kept the object fallback to avoid a hard PyArrow dependency — PyArrow is
22
- *recommended, not required*), and the new string dtype uses **`NaN` missing-value semantics** like every other
23
- default dtype, so test for null with `pd.isna()`, not by comparing against a specific token. Install PyArrow
24
- to get the faster backed path. **pandera 0.31.1** (supports pandas ≥ 3) for in-pipeline schema validation.
25
- **Polars** and **DuckDB** when pandas runs out of RAM. Pin them: `pandas==3.0.3`, `pandera==0.31.1`.
19
+ Cleaning **starts** once you hold tabular rows and **ends** at a validated table/DataFrame/Parquet. Before
20
+ that boundary the job is acquisition ([`data-scraper`](../data-scraper/SKILL.md),
21
+ [`structured-extraction`](../structured-extraction/SKILL.md)); after it, consumption
22
+ ([`spreadsheet-ops`](../spreadsheet-ops/SKILL.md), [`analytics`](../analytics/SKILL.md),
23
+ [`business-intelligence`](../business-intelligence/SKILL.md),
24
+ [`forecasting`](../forecasting/SKILL.md)). Multi-GB analytical SQL is an engine choice, not a cleaning one
25
+ — [`duckdb`](../duckdb/SKILL.md).
26
26
 
27
- ## Do you need this skill? (decide first)
28
-
29
- | Your situation | Reach for |
30
- | --- | --- |
31
- | Rows are dirty (nulls, dupes, mixed types, bad dates) and you want a re-runnable clean + a gate | **data-cleaning** (this skill) |
32
- | You need an `.xlsx` / formula / styled sheet / chart *out* | [`spreadsheet-ops`](../spreadsheet-ops/SKILL.md) |
33
- | The data is still on a website — you have to *acquire* it | [`data-scraper`](../data-scraper/SKILL.md) |
34
- | Fields are trapped in PDF/HTML/free text and must be *parsed into rows* | `structured-extraction` |
35
- | Multi-GB analytical SQL / heavy groupby-join is the actual bottleneck | [`duckdb`](../duckdb/SKILL.md) |
36
- | The table is already clean and you want charts / KPIs / a model | [`analytics`](../analytics/SKILL.md), `business-intelligence`, `forecasting` |
37
-
38
- Cleaning **starts** once you hold tabular rows and **ends** at a validated table/DataFrame/Parquet. The
39
- boundary with every consumer sibling is that validated table. (Some routed siblings may not be built in
40
- this collection yet; the routing decision still holds.)
27
+ Current stack (verified 2026-06-02): **pandas 3.0.x** (3.0.0 shipped 2026-01-21) and **pandera 0.31.1**
28
+ (supports pandas ≥ 3) for in-pipeline schema validation; **Polars** and **DuckDB** when pandas runs out of
29
+ RAM. Pin them: `pandas==3.0.3`, `pandera==0.31.1`.
41
30
 
42
31
  ## The pipeline shape
43
32
 
@@ -73,18 +62,19 @@ df = pd.read_csv("raw.csv")
73
62
  # GOOD — explicit, deterministic, real nullable types
74
63
  df = pd.read_csv(
75
64
  "raw.csv",
76
- dtype_backend="pyarrow", # real nullable ints/strings; no silent float-cast — REQUIRES pyarrow installed; use "numpy_nullable" if it isn't
65
+ dtype_backend="pyarrow", # real nullable ints/strings; no silent float-cast
77
66
  na_values=["", "N/A", "NA", "null", "-1", "999"], # YOUR sentinels become real NA
78
67
  keep_default_na=True, # keep pandas' default NA tokens too
79
68
  encoding="utf-8", # state it; don't let locale decide
80
69
  )
81
70
  ```
82
71
 
83
- pandas 3.0 notes that matter here: `dtype_backend="pyarrow"` only works if pyarrow is actually installed —
84
- it's recommended but *not* a hard pandas dependency, so install it (`pip install pyarrow`) or fall back to
85
- `dtype_backend="numpy_nullable"` when it's absent. The default `str` dtype is PyArrow-backed when pyarrow is
86
- present and NumPy-object-backed otherwise, but either way it uses `NaN` missing-value semantics — so assert
87
- nullability with `pd.isna()`, never by comparing against which null token appeared.
72
+ Two pandas 3.0 facts that read depends on. `dtype_backend="pyarrow"` only works if pyarrow is actually
73
+ installed — PDEP-14 deliberately kept a NumPy-object fallback so PyArrow stays *recommended, not required*
74
+ — so `pip install pyarrow` for the faster backed path, or pass `dtype_backend="numpy_nullable"` when it is
75
+ absent. And the default `str` dtype (PyArrow-backed when pyarrow is present, NumPy-object-backed otherwise)
76
+ uses **`NaN` missing-value semantics** like every other default dtype: test for null with `pd.isna()`, never
77
+ by comparing against whichever null token happened to appear.
88
78
 
89
79
  ## Profile before you fix
90
80
 
@@ -146,6 +136,10 @@ assert bad.sum() == 0, f"{bad.sum()} dates failed the expected format — inspec
146
136
  df["signup"] = parsed
147
137
  ```
148
138
 
139
+ Copy-paste versions of all of these — category mapping with unmapped→quarantine, a robust date parser,
140
+ unicode/encoding repair, a sentinel→NA table, numeric clip-vs-reject, plus Polars equivalents — are in
141
+ [references/normalization-recipes.md](references/normalization-recipes.md).
142
+
149
143
  ## Dedupe
150
144
 
151
145
  `drop_duplicates(keep="first")` is meaningless without a defined key and a stable sort — "first" of what
@@ -210,14 +204,16 @@ except pa.errors.SchemaErrors as e:
210
204
 
211
205
  `coerce=True` fixes types the contract expects; `nullable` states which columns may hold NA; field
212
206
  `Check`s (`ge`, `le`, `isin`, `unique`) are the allowed-value rules. `strict` catches columns that
213
- shouldn't be there. Together they are the data contract in code.
207
+ shouldn't be there. Together they are the data contract in code. Log the row-count diff on every run —
208
+ `in`, `out`, coerced, quarantined — so what the pipeline changed is an auditable record, not an assumption.
214
209
 
215
210
  When to escalate beyond pandera: reach for **GX Core 1.0** (Great Expectations' rebranded OSS — Data
216
211
  Context → Data Source → Expectation Suite → Validation Definition → Checkpoint) when you need a *shared
217
212
  data-quality platform* across many datasets and teams with a results store and docs. Use **dbt model
218
213
  contracts** (enforced at build) plus **dbt tests** (post-materialization) when the cleaning lives in a
219
- SQL warehouse, not Python. Full pandera patterns, the GX checkpoint sketch, the dbt YAML, and the
220
- "which validator" chooser are in [references/validation-patterns.md](references/validation-patterns.md).
214
+ SQL warehouse, not Python. The full `DataFrameModel` (custom `@pa.check`, lazy `SchemaErrors` report,
215
+ valid/quarantine split helper), the GX checkpoint sketch, the dbt model-contract + `data_tests` YAML, and
216
+ the "which validator" chooser are in [references/validation-patterns.md](references/validation-patterns.md).
221
217
 
222
218
  ## Scale — when pandas hurts
223
219
 
@@ -226,28 +222,15 @@ that, or when a groupby/join dominates the runtime, switch the *mechanics* (not
226
222
 
227
223
  - **Polars** for clean-at-scale: `pl.scan_csv(...)` (lazy, parallel, Rust), then `.unique()`,
228
224
  `.drop_nulls()`, `.fill_null(...)`, `.str.*` — the same profile→normalize→dedupe→validate shape, faster.
229
- pandera validates Polars frames too.
225
+ pandera validates Polars frames too, and the
226
+ [recipes reference](references/normalization-recipes.md) has the Polars equivalent of every fix above.
230
227
  - **DuckDB** when the bottleneck is analytical SQL over multi-GB files — point heavy joins/aggregations
231
228
  there: [`duckdb`](../duckdb/SKILL.md). It is an *engine* choice; correctness/normalization is still this
232
229
  skill's job.
233
230
 
234
- Polars equivalents for every recipe above are in
235
- [references/normalization-recipes.md](references/normalization-recipes.md).
236
-
237
- ## Reproducibility checklist
238
-
239
- - [ ] Library versions pinned (`pandas==3.0.3`, `pandera==0.31.1`) — same input → same output.
240
- - [ ] Read with explicit `dtype_backend` + `na_values`; no silent int→float cast.
241
- - [ ] Dedupe has an explicit `subset` key AND a deterministic `sort_values(..., kind="stable")` before it.
242
- - [ ] No `random` / sampling without a fixed seed; stable tie-breaks everywhere.
243
- - [ ] Raw source untouched; output written to a NEW artifact.
244
- - [ ] Schema validated on output; `lazy=True` so all violations surface together.
245
- - [ ] Failing rows **quarantined**, not silently dropped.
246
- - [ ] Row-count diff logged (`in`, `out`, coerced, quarantined) — an auditable record of what changed.
247
-
248
231
  ## Anti-patterns
249
232
 
250
- | Rationalization | Reality → STOP |
233
+ | Anti-pattern | Why it breaks |
251
234
  | --- | --- |
252
235
  | "`fillna(0)` to get rid of the nulls" | Zero is a value; it distorts every mean/sum/model. Impute deliberately and add a `_was_missing` flag. |
253
236
  | "`drop_duplicates()` — done" | No `subset`, no sort → which row survives is nondeterministic. Define the key, `sort_values(kind="stable")`, set `keep`. |
@@ -259,27 +242,18 @@ Polars equivalents for every recipe above are in
259
242
  | "Validation passed, so we're good" | A gate that never fails is a no-op. Feed it a known-bad row and confirm it *rejects*. |
260
243
  | "It's slow, rewrite everything in Polars" | Switch the engine, not the discipline — profile→normalize→dedupe→validate still applies. |
261
244
 
262
- ## References
263
-
264
- - [references/validation-patterns.md](references/validation-patterns.md) — full pandera `DataFrameModel`
265
- (coerce, custom `@pa.check`, lazy `SchemaErrors` report, valid/quarantine split helper), GX Core 1.0
266
- checkpoint sketch, dbt model-contract + `data_tests` YAML, and the "which validator" chooser.
267
- - [references/normalization-recipes.md](references/normalization-recipes.md) — copy-paste recipes: category
268
- mapping with unmapped→quarantine, robust date parser, unicode/encoding repair, sentinel→NA table, numeric
269
- clip-vs-reject, and Polars equivalents (`unique`, `drop_nulls`, `fill_null`, `str.*`) for scale.
270
-
271
245
  ## Verify
272
246
 
273
- Run `scripts/verify.sh` from anywhere. It does static structure checks on this skill (frontmatter keys,
274
- references present) always, and — when pandas + pandera are installed — extracts the documented pattern,
275
- feeds it one clearly-good row and one clearly-bad row, and asserts the good row PASSES validation while the
276
- bad row is FLAGGED/quarantined, proving the gate is not a no-op. If pandas/pandera aren't installed it
277
- prints SKIP for the runtime check and still passes the static checks. No network.
247
+ `scripts/verify.sh` runs from anywhere, no network. It does static structure checks on this skill
248
+ (frontmatter keys, references present) always, and — when pandas + pandera are installed — extracts the
249
+ documented pattern, feeds it one clearly-good row and one clearly-bad row, and asserts the good row PASSES
250
+ validation while the bad row is FLAGGED/quarantined, proving the gate is not a no-op. Without
251
+ pandas/pandera it prints SKIP for the runtime check and still passes the static checks.
278
252
 
279
253
  ## Project grounding (02-DOCS + CLAUDE.md)
280
254
 
281
255
  In a project with a `02-DOCS/` layer (the [`harness`](../harness/SKILL.md) wiki), record this dataset's
282
256
  cleaning decisions — the schema/contract, the category mapping tables, the dedupe key, the quarantine
283
- location, version pins — in `02-DOCS/wiki/data/<dataset>.md` and link it from the root `CLAUDE.md`
284
- `## Knowledge map`. Read it first on every re-run so the contract stays consistent. No `02-DOCS/`? Skip
257
+ location, version pins — in `02-DOCS/wiki/data/<dataset>.md`, link it from the root `CLAUDE.md`
258
+ `## Knowledge map`, and read it first on every re-run so the contract stays consistent. No `02-DOCS/`? Skip
285
259
  silently. Conventions are recorded, never gated.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: data-policy
3
- description: "Use when an operator needs the internal data-governance machinery a business runs on — a retention schedule (how long each data category is kept and what happens at expiry), the lawful basis per activity, a Record of Processing Activities (ROPA), or a consent capture/withdrawal model; symptoms include 'how long can we keep this', a paper policy that never runs in systems, or data still in backups past its retention. Triggers: 'write our data retention policy', 'how long can we keep customer/HR/support/log data', 'set up a ROPA', 'lawful basis consent or legitimate interest', 'design our consent capture and withdrawal flow', 'auto-deletion with legal-hold exceptions', 'we delete from prod but backups still have it', 'política de conservación de datos', 'cuánto tiempo guardamos los datos'. NOT the public-facing privacy notice or DSAR handling (that is gdpr-privacy), NOT SOC 2 audit posture (that is compliance), and NOT the database TTL/partition-drop mechanics (that is db-migrations)."
3
+ description: "Use when building internal data-governance machinery: a retention schedule (period, lawful basis, expiry action, system where deletion runs), an Art. 6 lawful-basis register, an Art. 30 ROPA, or a consent capture/withdrawal model. NOT the public privacy notice or DSAR handling (that is `gdpr-privacy`), NOT SOC 2 posture (that is `compliance`)."
4
4
  tags: [data-governance, retention, gdpr, ropa, consent, lawful-basis, privacy, data-minimization]
5
5
  recommends: [gdpr-privacy, compliance, contracts, secure-coding, db-migrations, postgresdb]
6
6
  origin: risco
@@ -8,9 +8,7 @@ origin: risco
8
8
 
9
9
  # Data policy
10
10
 
11
- You build the **internal governance machinery** a business runs on: a retention schedule, a lawful-basis register, a Record of Processing Activities (ROPA), and a consent model. You produce structured artifacts that engineering and ops can implement — not the public-facing privacy notice users read (that is `../gdpr-privacy/SKILL.md`). You are not a DPO and you never claim to be one.
12
-
13
- One rule sits above everything else.
11
+ You produce the structured governance artifacts engineering and ops implement — a retention schedule, a lawful-basis register, a Record of Processing Activities (ROPA), a consent model — not the public-facing notice users read (that is `../gdpr-privacy/SKILL.md`). You are not a DPO and you never claim to be one.
14
12
 
15
13
  **A retention rule is only real when it has all four parts: a concrete period, the lawful basis, the expiry action, and the system where deletion actually runs.** A policy that names a period but never deletes anything is a paper policy — and a paper policy is precisely what regulators fine. Cumulative GDPR fines hit ~EUR 5.65B across ~2,245 actions by March 2025, and the two failures that recur are *no systematic data classification* and *no automated deletion capability* (Secure Privacy / CMS Enforcement Tracker, 2025). Every schedule you emit ends with the DPO/counsel sign-off boundary below.
16
14
 
@@ -26,7 +24,7 @@ Map the request to one artifact before writing anything. Each routes to a sectio
26
24
  | "Design consent capture / withdrawal" | Consent matrix | Consent model |
27
25
  | "Auto-delete but keep legal holds / backups still have data" | Deletion workflow | Make it real in systems |
28
26
 
29
- If the operator wants the public privacy notice, the DPA contract clauses, or SOC 2 readiness, stop and route them — see the boundary section. Those are different skills.
27
+ If they want the public privacy notice, DPA clauses, or SOC 2 readiness instead, stop and route them — see the boundary below.
30
28
 
31
29
  ## Build the retention schedule
32
30
 
@@ -88,7 +86,7 @@ Security: RBAC, encryption at rest, access logging
88
86
  Lawful basis: Art. 6(1)(b) contract ← log it even though Art. 30 doesn't demand it
89
87
  ```
90
88
 
91
- The full template with a second worked row is in `references/consent-and-ropa.md`.
89
+ The full ROPA template with a second worked row — plus the consent-matrix template and the withdrawal/refresh workflow — is in `references/consent-and-ropa.md`.
92
90
 
93
91
  ## Consent model
94
92
 
@@ -109,7 +107,7 @@ One note so you don't over-promise on cookies: the **ePrivacy Regulation was for
109
107
 
110
108
  ## Make it real in systems
111
109
 
112
- This is the section that earns the skill. The policy is worthless until deletion runs in the systems that actually hold the data — *including backups and archives*, which is exactly where regulators find data that should be gone.
110
+ The policy is worthless until deletion runs in the systems that actually hold the data — *including backups and archives*, which is exactly where regulators find data that should be gone.
113
111
 
114
112
  Checklist:
115
113
 
@@ -134,17 +132,11 @@ State explicitly in the policy whether production data may be reused for **AI/mo
134
132
 
135
133
  For cross-border transfers, name the mechanism in the ROPA row (e.g. SCCs) and point to `../gdpr-privacy/SKILL.md` for the SCC/notice depth — that is its territory, not yours.
136
134
 
137
- ## The boundary (non-negotiable)
138
-
139
- Retention periods are jurisdiction- and sector-specific. **You produce governance drafts, not legal sign-off.** Every policy you emit ends with a line stating a qualified DPO or privacy counsel must validate the schedule and lawful-basis register before adoption, and that this is not legal advice. You never assert a period is universally lawful.
135
+ ## The boundary
140
136
 
141
- Hand off the edges:
137
+ Retention periods are jurisdiction- and sector-specific, so a period you assert as final is legal advice you are not qualified to give — that is why this line has no exceptions. **You produce governance drafts, not legal sign-off.** Every policy you emit ends with a statement that a qualified DPO or privacy counsel must validate the schedule and lawful-basis register before adoption, and that this is not legal advice. You never assert a period is universally lawful.
142
138
 
143
- - Public-facing privacy notice + data-subject access/erasure (DSAR) handling -> `../gdpr-privacy/SKILL.md`.
144
- - Audit posture, SOC 2 / ISO 27001, control mapping -> `../compliance/SKILL.md`.
145
- - A negotiated DPA's contractual clauses or a two-party data contract -> `../contracts/SKILL.md`.
146
- - Encryption, access hardening, threat controls on the systems -> `../secure-coding/SKILL.md`.
147
- - The actual deletion mechanics in the database -> `../db-migrations/SKILL.md` / `../postgresdb/SKILL.md`.
139
+ Hand off the edges: public-facing privacy notice + data-subject access/erasure (DSAR) handling -> `../gdpr-privacy/SKILL.md`; audit posture, SOC 2 / ISO 27001, control mapping -> `../compliance/SKILL.md`; a negotiated DPA's contractual clauses or a two-party data contract -> `../contracts/SKILL.md`; encryption, access hardening, threat controls on the systems -> `../secure-coding/SKILL.md`; the actual deletion mechanics in the database -> `../db-migrations/SKILL.md` / `../postgresdb/SKILL.md`.
148
140
 
149
141
  ## Anti-patterns
150
142
 
@@ -156,8 +148,3 @@ Hand off the edges:
156
148
  | No legal-hold exception in the auto-deletion job | The job destroys data under litigation hold — spoliation | Flag held rows; skip them; document the hold basis |
157
149
  | Copy a generic retention template unchanged | Periods are jurisdiction/sector-specific; a copied period can be unlawful | Tag every period "validate vs local + sector law"; adjust |
158
150
  | Emit the policy as final / "compliant" | Crosses into legal advice you can't give | End with DPO/counsel sign-off + not-legal-advice line |
159
-
160
- ## References
161
-
162
- - `references/retention-schedule.md` — fillable schedule template (data category, purpose, lawful basis, period, expiry action, system of record, legal-hold flag, review date) + a populated example across HR, finance/tax, CRM, marketing, support, logs, with the delete-vs-anonymize-vs-archive note and the local + sector law validation checklist.
163
- - `references/consent-and-ropa.md` — consent matrix template + worked example, the Art. 30 ROPA template + worked rows, the legitimate-interest balancing-test worksheet, and the consent withdrawal/refresh workflow.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: data-scraper
3
- description: "Use when you need data that lives on a website with no usable API — listings, prices, public records, directories — and the scrape must stay legal and not get blocked. Triggers: 'scrape this site', 'extract data from a webpage', 'build a crawler', 'pull all the prices off this catalog', 'my scraper keeps getting 429s / IP-banned', 'the selectors break every time the site redesigns', 'is it legal to scrape this without getting sued', 'extreure dades d'una web', 'scrapear una página sin que me bloqueen'. NOT parsing HTML/PDF you already have into fields (that is structured-extraction), NOT a site that already exposes a documented API or key (that is api-connector-builder)."
3
+ description: "Use when data lives on a website with no usable API — listings, prices, public records — and the scrape must stay legal and not get blocked: legal gate, extraction path, durable selectors, pacing, resilience. NOT parsing bytes you already hold into fields (that is structured-extraction), NOT a documented API or key (that is api-connector-builder)."
4
4
  tags: [web-scraping, crawler, anti-bot, robots-txt, gdpr-compliance, playwright, rate-limiting]
5
5
  recommends: [api-connector-builder, structured-extraction, data-cleaning, gdpr-privacy, webhooks]
6
6
  origin: risco
@@ -125,10 +125,4 @@ A recurring crawler must survive crashes, redeploys, and the target's schema dri
125
125
  | Hardcoding one User-Agent forever | Stale UA is an easy bot tell | Current full header set; rotate when justified |
126
126
  | Retrying with no backoff | Lockstep retries self-DDoS the host | Exponential backoff + jitter; honor `Retry-After` |
127
127
 
128
- ## References
129
-
130
- - **`references/legal-compliance.md`** — robots.txt + ai.txt parsing, ToS red-flag list, GDPR lawful-basis decision flow, minimization/retention checklist, and the 2024-2025 case summaries (Meta v. Bright Data, hiQ v. LinkedIn, Reddit v. Perplexity).
131
- - **`references/anti-bot.md`** — `curl_cffi` impersonation profiles with an example, realistic header sets, Playwright launch/stealth config, the proxy taxonomy (datacenter / residential / mobile) and when each is justified, and the CAPTCHA line you do not cross.
132
- - **`references/frameworks.md`** — copy-paste resilient starters: Crawlee Python (`RequestQueue` + router + per-host concurrency), Playwright direct, Scrapy AUTOTHROTTLE, and an `httpx` + `selectolax` static template.
133
-
134
128
  When in doubt about whether a scrape is defensible, the answer is the gate. Run it, write down the outcome, and only then send a request.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: debug
3
- description: "Use when something is broken and the impulse is to start patching — a bug, a failing or flaky test, a crash, an exception, a wrong result, a regression, or behavior nobody can explain — and you want the root cause found BEFORE any fix is proposed. The on-demand rsc-sdd diagnosis discipline, callable from inside implement (or any phase) the moment a check fails for a reason you don't understand. Triggers: 'debug this', 'why is this failing', 'this test is flaky', 'find the root cause', 'it works locally but not in CI', 'this used to work', 'track down this bug', 'the fix didn't stick', 'figure out why', 'NullPointer/segfault/500 out of nowhere', 'intermittent failure'. Fixes the ONE confirmed cause, then hands back. NOT writing a planned feature (that is `implement`), NOT the lint/test gate (that is `verify`), NOT adversarial diff reading (that is `review`). Honors the harness accompaniment dial."
3
+ description: "Use when something is broken — a failing or flaky test, crash, wrong result or regression — and the root cause must be reproduced and proven before any fix. On-demand; callable mid-`implement`. NOT a feature to spec or build (that is `specify`/`implement`), NOT the lint/test gate (that is `verify`), NOT adversarial diff reading (that is `review`)."
4
4
  tags: [debug, bug, troubleshoot]
5
5
  recommends: []
6
6
  profiles: [core, full]
@@ -20,31 +20,9 @@ The one rule everything else serves: **no fix before a reproduced, isolated, con
20
20
  you cannot make the bug happen on demand, you cannot know you fixed it — you can only know the
21
21
  symptom stopped showing, which is not the same thing.
22
22
 
23
- This is a process skill. It does not own the test runner, the debugger, or the profiler — the
24
- **stack skills do** (`../fastapi/SKILL.md`, `../go/SKILL.md`, `../nextjs/SKILL.md`,
25
- `../flutter/SKILL.md`; data-layer issues `../postgresdb/SKILL.md`; security-shaped failures
26
- `../secure-coding/SKILL.md`). `debug` owns the *method*; it pulls the *mechanics* from whichever
27
- stack the failure lives in.
28
-
29
- ## When to use / when not to
30
-
31
- Use when:
32
-
33
- - A test fails (or flakes) for a reason you don't fully understand, mid-`implement` or after.
34
- - A crash, exception, 500, segfault, or wrong output appears and nobody can yet say why.
35
- - A regression shows up ("this used to work") and you need the commit/change that caused it.
36
- - A fix was applied and the symptom came back, or a "fix" didn't actually stick.
37
- - The behavior differs between environments ("works locally, fails in CI").
38
-
39
- Do NOT use when:
40
-
41
- - You're writing a *planned* feature task and its expected failing test — that's `implement`'s
42
- red→green→refactor; no mystery yet.
43
- - You're running the lint/type/test gate to confirm "done" — that's `verify` (it *reports* failures
44
- and hands them here; it doesn't diagnose).
45
- - You're reading a clean diff adversarially for smells a test can't catch — that's `review`.
46
- - The "bug" is actually an unclear requirement or contradictory spec — that's `clarify`/`analyze`,
47
- not a code defect.
23
+ This is a process skill: it owns the *method*, never the instruments. The test runner, debugger,
24
+ race detector and profiler belong to whichever stack the failure lives in — pull them from the
25
+ delegation table below.
48
26
 
49
27
  ## Model tier — `heavy` (opt-in routing)
50
28
 
@@ -53,7 +31,9 @@ This phase's default model tier is **`heavy`** — root-cause diagnosis is deep
53
31
  ## Read the room first (accompaniment dial)
54
32
 
55
33
  Before diagnosing, read `02-DOCS/wiki/harness/user-profile.md` for the technical + accompaniment
56
- level and match it. The *method* never changes with the dial — the volume does.
34
+ level and match it; with no profile yet, assume non-technical — narrate the reasoning plainly and
35
+ never apply a behavior-changing fix without a quick confirm. The *method* never changes with the
36
+ dial — the volume does.
57
37
 
58
38
  | Level | While diagnosing you show… | Questions you ask |
59
39
  | --- | --- | --- |
@@ -62,10 +42,7 @@ level and match it. The *method* never changes with the dial — the volume does
62
42
  | **L2** decisions | each step's finding (repro, the half that isolated it, the cause) | confirm before a fix that changes behavior beyond the bug |
63
43
  | **L3** full | narrate the whole loop, teach the binary-search reasoning aloud | ask to contextualize the environment, recent changes, expectations |
64
44
 
65
- No profile yet → assume non-technical, narrate the reasoning plainly, and never apply a
66
- behavior-changing fix without a quick confirm.
67
-
68
- ## The loop — five steps, in order
45
+ ## The loop — five steps, never skipped, never reordered
69
46
 
70
47
  ```text
71
48
  REPRODUCE → make the bug happen on demand. A reliable repro (or a quantified flake rate) is the
@@ -84,11 +61,6 @@ VERIFY → re-run the repro: symptom gone. Re-run the new test: green. Re-r
84
61
  dropped to zero. Only now is it fixed.
85
62
  ```
86
63
 
87
- Never skip a step and never reorder. **Reproduce before isolate** — you can't bisect a bug you can't
88
- trigger. **Hypothesize before fix** — an edit with no stated cause is a guess wearing a commit
89
- message. **Verify before "fixed"** — the word *fixed* is a claim about the repro no longer firing
90
- and the test being green, nothing less.
91
-
92
64
  ### Reproduce — the entry ticket
93
65
 
94
66
  A bug you cannot reproduce is not a bug you can fix; it's a rumor. Pin it down:
@@ -169,9 +141,9 @@ Why missed — what let it through, so the class of bug doesn't recur
169
141
 
170
142
  Skip the trivial ones (a typo'd variable). Log the cause a future debugger would pay to know.
171
143
 
172
- ## Anti-patterns → STOP
144
+ ## Anti-patterns
173
145
 
174
- | Rationalization | Reality |
146
+ | Anti-pattern | Why it fails |
175
147
  | --- | --- |
176
148
  | "I see the likely line — let me just change it and see." | That's guess-and-patch. Reproduce first; a fix to an untriggered bug proves nothing. |
177
149
  | "It's intermittent, you can't really reproduce it." | "Intermittent" is a rate to measure (k/N), not an excuse. Flakes have causes: state, order, races, time. |
@@ -185,8 +157,6 @@ Skip the trivial ones (a typo'd variable). Log the cause a future debugger would
185
157
 
186
158
  ## Red flags — stop and re-route
187
159
 
188
- - **You're editing code and you can't yet reproduce the bug** → stop; you're guessing. Get a repro
189
- (or a measured flake rate) first.
190
160
  - **The "bug" is a spec contradiction or unclear requirement**, not a defect → route to
191
161
  `clarify` / `analyze`; debugging won't fix an ambiguity.
192
162
  - **The fix grows past the cause** (you're refactoring "while you're here") → split it out; keep the
@@ -210,15 +180,6 @@ Skip the trivial ones (a typo'd variable). Log the cause a future debugger would
210
180
  - [ ] Handed the whole-gate re-run back to verify; resumed implement where the failure interrupted it
211
181
  ```
212
182
 
213
- ## What this skill is NOT
214
-
215
- - **Not the feature builder.** Once the cause is fixed and verified, planned work resumes in
216
- `implement` (its red→green→refactor for the *next* task, not this bug).
217
- - **Not the quality gate.** The lint/type/full-suite/audit run that licenses "done" is `verify`'s
218
- job; `debug` proves the one bug dead and hands the gate back.
219
- - **Not a refactor pass.** Keep the fix minimal; broader cleanups are `implement`/`review` territory,
220
- not smuggled into a bugfix.
221
-
222
183
  ## Where you are in the chain
223
184
 
224
185
  `debug` is **on-demand**, callable from any phase — most often pulled in mid-`implement` when a test