@ericrisco/rsc 0.1.50 → 0.1.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: harness
3
- description: "Use to control, govern or maintain a workspace's harness — software or non-code (a company, an ops desk, a knowledge vault). The harness is the control plane: the `01-TOOLS/` tooling layer, the `02-DOCS/` chaos→knowledge wiki, and the root Knowledge map. It audits, migrates legacy `XX-*` folders, scaffolds provider tooling, sweeps the inbox, and generates root CLAUDE.md/AGENTS.md. Brownfield-first. NOT the bootstrap front door (that is `init`, which hands off here)."
3
+ description: "Use when governing a workspace's control plane, code or not — the `01-TOOLS/` tooling layer, the `02-DOCS/` chaos→knowledge wiki, the root Knowledge map. Audits it, migrates legacy `XX-*` folders, scaffolds provider tooling, sweeps the inbox, writes root CLAUDE.md/AGENTS.md. NOT the bootstrap front door (that is `init`, which hands off here)."
4
4
  tags: [harness, company, ops, docs, wiki, connect, tools, knowledge]
5
5
  recommends: [init]
6
6
  profiles: [minimal, core, full]
@@ -18,8 +18,9 @@ The **harness** is the control plane of a workspace. A workspace need not be cod
18
18
 
19
19
  Two on-ramps feed it. **Ingest**: the user drops any file in any format into `inbox/`, and the
20
20
  Auto-Ingest Sweep extracts, classifies, cross-links and compiles it — then goes for a walk,
21
- discovering un-ingested documents anywhere in the workspace, bounded by `.rscignore` and
22
- de-duplicated through the `wiki/.ingested.json` ledger. **Worklog**: every meaningful session of
21
+ discovering un-ingested documents anywhere in the workspace, bounded by `.rscignore` (baseline:
22
+ `references/ingest-ignore-defaults.md`) and de-duplicated through the `wiki/.ingested.json`
23
+ ledger. **Worklog**: every meaningful session of
23
24
  work is itself a raw source in `raw/worklog/`, captured on `PreCompact`/`SessionEnd`, at a commit
24
25
  milestone, or by the daily curation pass.
25
26
 
@@ -35,7 +36,8 @@ The **harness** is the control plane of a workspace. A workspace need not be cod
35
36
 
36
37
  It compounds on its own: every Ingest, Sweep and Query triggers a Maintenance Pass (lint, score
37
38
  recomputation, gap detection, Related sweep), a Micro-Improve runs every N interactions, and Deep
38
- Improve runs on request or on the daily schedule. Protocol → `references/wiki-protocol.md`;
39
+ Improve runs on request or on the daily schedule (`references/daily-curation-automation.md` — on
40
+ Claude Code, wire it via the `schedule` skill). Protocol → `references/wiki-protocol.md`;
39
41
  formats → `references/ingest-formats.md`; capture → `references/wiki-worklog-template.md`;
40
42
  vault → `references/obsidian-scaffolding.md`.
41
43
  - **The Knowledge map** — the `## Knowledge map` section of the root `CLAUDE.md` that indexes the wiki (including the `harness/` topic) and is read by every other skill before it works in its area.
@@ -78,45 +80,7 @@ for harness-level choices, but defer concrete deploy mechanics to `deployment`,
78
80
 
79
81
  The skill proposes, the user confirms, the skill executes. Every destructive operation (deleting a legacy folder, merging into an existing `CLAUDE.md`) requires explicit consent quoted back from the user, not inferred.
80
82
 
81
- ## When to use
82
-
83
- - A workspace has grown organically and needs the canonical `01-TOOLS` / `02-DOCS` structure.
84
- - Old numbered folders (`00-TOOLS`, `03-NOTES`, `04-LEGACY`…) exist and need to be consolidated.
85
- - A new project is being kicked off and needs the harness from day one.
86
- - Provider integrations exist in code but there's no operational tooling for them.
87
-
88
- **Do NOT use when:**
89
- - The user only wants to add a single tool — they can `cp -r 01-TOOLS/_TEMPLATE 01-TOOLS/<X>` manually.
90
- - The user wants to refactor runtime code — this skill is operational tooling only, never runtime.
91
-
92
- ## Architecture
93
-
94
- ```
95
- harness/
96
- ├── SKILL.md ← this file (the protocol)
97
- ├── references/
98
- │ ├── providers.yaml ← detector catalog with full file bodies per provider
99
- │ ├── claude-md-template.md ← root CLAUDE.md template
100
- │ ├── agents-md-template.md ← root AGENTS.md template
101
- │ ├── tools-readme-template.md ← 01-TOOLS/README.md catalog template
102
- │ ├── audit-report-template.md ← exact format of the audit report shown to user
103
- │ ├── wiki-protocol.md ← embedded wiki protocol + Inbox/Worklog Sweep + Continuous Improvement
104
- │ ├── ingest-formats.md ← multiformat Fetch (PDF, image, CSV, JSON, html…)
105
- │ ├── ingest-ignore-defaults.md ← what the sweep skips by default (the .rscignore baseline)
106
- │ ├── inbox-readme-template.md ← the inbox/README.md drop-zone contract
107
- │ ├── wiki-raw-template.md ← format for raw/<topic>/*.md
108
- │ ├── wiki-worklog-template.md ← format for raw/worklog/*.md (work-driven capture)
109
- │ ├── wiki-article-template.md ← format for wiki/<topic>/*.md (OKF frontmatter + markdown links)
110
- │ ├── wiki-index-template.md ← format for wiki/index.md (machine catalog; .base = human nav)
111
- │ ├── obsidian-scaffolding.md ← .base views, .gitignore, attachments, .obsidian config
112
- │ ├── daily-curation-automation.md ← portable scheduled compounding pass (the third trigger)
113
- │ ├── wiki-archive-template.md ← format for archived query answers
114
- │ └── wiki-gaps-template.md ← format for wiki/gaps.md (Knowledge Gaps log)
115
- ├── assets/
116
- │ └── _TEMPLATE/ ← per-tool boilerplate (cp -r seed)
117
- └── examples/
118
- └── audit-example.md ← walked-through audit on a synthetic project
119
- ```
83
+ **Out of scope:** adding a single tool — the user does `cp -r 01-TOOLS/_TEMPLATE 01-TOOLS/<X>` manually, no need for the full protocol; and refactoring runtime code — this skill is operational tooling only, never runtime.
120
84
 
121
85
  ## Protocol — five phases
122
86
 
@@ -148,7 +112,7 @@ Walk the workspace root and gather:
148
112
 
149
113
  Render **two artifacts**:
150
114
 
151
- 1. **A compact text summary in the conversation** — 1–3 sentences per section, the full destructive-ops list, the consent prompt. This keeps the terminal flow fast.
115
+ 1. **A compact text summary in the conversation** — 1–3 sentences per section, the full destructive-ops list, the consent prompt, in the format of `references/audit-report-template.md`. This keeps the terminal flow fast. A full walked-through audit on a synthetic project: `examples/audit-example.md`.
152
116
  2. **A full HTML report at `<workspace_root>/02-DOCS/audits/audit-YYYY-MM-DD-HHMM.html`** using `references/audit-report-template.html`. Self-contained (inline CSS, no CDN). Includes color-coded action tables, collapsible legacy-folder sections, highlighted destructive ops, and the consent prompt. **Gitignored** (per-run artifact).
153
117
 
154
118
  If `02-DOCS/audits/` does not exist, create it (with `.gitkeep`) before writing — even on first run, before Phase 4 builds the rest of `02-DOCS/`. Same for `02-DOCS/` itself: the audits subdirectory is the only piece allowed to materialize during Phase 2; the rest waits until APPLY. Never write the audit HTML at the workspace root.
@@ -184,7 +148,7 @@ Execute in this exact order. Each step writes to disk; abort and report on first
184
148
  1. **Root files.**
185
149
  - If `CLAUDE.md` does not exist: render `references/claude-md-template.md` with the scan data and write it.
186
150
  - If `CLAUDE.md` exists: read it, compute a section-level diff against the template, and apply ONLY additive merges. Never delete user content. Never overwrite a section the user has customized. Append missing sections at the end with an `<!-- added by harness YYYY-MM-DD -->` marker.
187
- - Same logic for `AGENTS.md`.
151
+ - Same logic for `AGENTS.md`, rendered from `references/agents-md-template.md`.
188
152
  2. **Create `01-TOOLS/` skeleton.**
189
153
  - Create `01-TOOLS/` directory.
190
154
  - Copy `assets/_TEMPLATE/` to `01-TOOLS/_TEMPLATE/`. This template is **generic boilerplate with placeholders (`<NOMBRE_TOOL>`, `<TOOL>_API_KEY`)**. The user copies it manually when adding a tool NOT in the catalog. The skill itself does NOT use `_TEMPLATE/` to generate the detected tools — those come from `providers.yaml`.
@@ -198,7 +162,7 @@ Execute in this exact order. Each step writes to disk; abort and report on first
198
162
  4. **Migrate legacy `XX-*` folders.**
199
163
  - For each TOOLING file: move to its mapped destination in `01-TOOLS/<X>/`. If the destination file already exists from step 3, the legacy file goes to `01-TOOLS/<X>/migrated/<original-name>` so nothing is overwritten. The user resolves manually.
200
164
  - For each DOCS file: move to `02-DOCS/raw/migrated/<original-folder>/<path>`.
201
- - For each AMBIGUOUS file: leave in place. Record in the verification report.
165
+ - For each AMBIGUOUS file: leave in place. Record in the verification report. Never force-classify — a file moved to the wrong place is harder to recover than one left where the user put it.
202
166
  5. **Verify migration.**
203
167
  - Count files moved vs files originally present. They must match (moved + ambiguous-remaining = original).
204
168
  - If counts don't match, abort and report. Don't proceed to deletion.
@@ -216,7 +180,14 @@ Execute in this exact order. Each step writes to disk; abort and report on first
216
180
  - Each `01-TOOLS/<TOOL>/README.md` and `CREDENTIALS.md`.
217
181
  - Every file under `02-DOCS/raw/migrated/` (from legacy `XX-*` migration in step 4).
218
182
  - Root `CLAUDE.md` and `AGENTS.md`.
219
- - Use the templates in `references/wiki-*.md` verbatim. Do NOT invent a different format.
183
+ - Use these templates verbatim; `wiki-protocol.md` is the source of truth for `02-DOCS`, so do NOT invent a different structure or format:
184
+ - `references/wiki-raw-template.md` — `raw/<topic>/*.md`.
185
+ - `references/wiki-article-template.md` — `wiki/<topic>/*.md` (OKF v0.1 frontmatter + relative markdown links + `## Related`).
186
+ - `references/wiki-index-template.md` — `wiki/index.md` (machine catalog; the `.base` views are the human navigation).
187
+ - `references/wiki-gaps-template.md` — `wiki/gaps.md` (Knowledge Gaps log).
188
+ - `references/wiki-dashboard-template.html` — the live wiki dashboard, regenerated by Maintenance Pass.
189
+ - `references/wiki-archive-template.html` — archived query answers (point-in-time, never edited).
190
+ - `references/wiki-deep-improve-report-template.html` — Deep Improve run reports.
220
191
 
221
192
  ### Phase 5 — VERIFY
222
193
 
@@ -304,20 +275,13 @@ Opt out of the size nudge with `.rsc/.no-claudemd-check`.
304
275
 
305
276
  ## Invariants
306
277
 
307
- These are not style preferences you can weigh against convenience — each one exists because
308
- breaking it destroys something the user cannot get back. Violating any aborts the run.
309
-
310
- 1. **Audit before action.** Nothing is written before the AUDIT is rendered and CONSENT is given.
311
- 2. **Explicit consent only.** Silence, ambiguity, "ok" all mean NO. Only the exact-form strings count as yes.
312
- 3. **No `.env` real, ever.** The skill writes `.env.example` only. Real credentials are the user's responsibility.
313
- 4. **No speculative tools.** A tool is created if and only if the detector found evidence in the user's code. No "we should probably have a Sentry tool too".
314
- 5. **No overwrite without merge.** Existing `CLAUDE.md`, `AGENTS.md`, or tool files are merged additively. The skill never deletes user content.
315
- 6. **Destructive ops require a second consent quoting the path.** "Yes, delete `00-TOOLS`" is different from a generic "yes, proceed".
316
- 7. **Ambiguous files preserve the legacy folder.** Don't force-classify. If you can't classify with confidence, leave it.
317
- 8. **Idempotent.** Running the skill twice produces no extra side effects. Re-scanning a project already canonical detects "nothing to do".
318
- 9. **Out-of-scope dirs are invisible.** `node_modules/`, `.venv/`, `.next/`, `__pycache__/`, `.git/`, `dist/`, `build/`, `.dart_tool/` are never read for detection and never touched.
319
- 10. **`references/wiki-protocol.md` is the source of truth for `02-DOCS`.** Do not invent a different wiki structure.
320
- 11. **Subproject internals are out of scope.** `.env.example`, `requirements.txt`, `package.json`, source files inside subprojects are READ for detection only. They are NEVER moved, renamed, modified, or deleted. The skill operates exclusively on workspace-root artifacts (`CLAUDE.md`, `AGENTS.md`, `01-TOOLS/`, `02-DOCS/`, and `XX-*` legacy folders at the root level).
278
+ The consent, merge and `.env` rules live with the phases that enforce them above. These four are
279
+ scope rules that no single phase owns, and breaking one destroys something the user cannot get back:
280
+
281
+ 1. **No speculative tools.** A tool is created if and only if the detector found evidence in the user's code. No "we should probably have a Sentry tool too".
282
+ 2. **Idempotent.** Running the skill twice produces no extra side effects. Re-scanning a project already canonical detects "nothing to do".
283
+ 3. **Out-of-scope dirs are invisible.** `node_modules/`, `.venv/`, `.next/`, `__pycache__/`, `.git/`, `dist/`, `build/`, `.dart_tool/` are never read for detection and never touched.
284
+ 4. **Subproject internals are out of scope.** `.env.example`, `requirements.txt`, `package.json`, source files inside subprojects are READ for detection only. They are NEVER moved, renamed, modified, or deleted. The skill operates exclusively on workspace-root artifacts (`CLAUDE.md`, `AGENTS.md`, `01-TOOLS/`, `02-DOCS/`, and `XX-*` legacy folders at the root level).
321
285
 
322
286
  ## Red flags — abort and re-plan
323
287
 
@@ -327,30 +291,7 @@ If any of these occur, stop and report:
327
291
  - The AUDIT shows zero detected tools AND zero legacy folders AND `CLAUDE.md`/`AGENTS.md` already exist → there's nothing for the skill to do. Tell the user.
328
292
  - The user types anything ambiguous after AUDIT → do not infer consent.
329
293
  - Migration verification (step 5 of APPLY) shows file count mismatch → abort, don't delete anything.
330
- - The catalog has no entry for a provider obviously present in code → tell the user, suggest adding a catalog entry, don't fake one.
331
-
332
- ## References
333
-
334
- - `references/providers.yaml` — full provider catalog with detectors and per-file content. Edit this to add a new provider; don't edit `SKILL.md`.
335
- - `references/claude-md-template.md` — root `CLAUDE.md` template.
336
- - `references/agents-md-template.md` — root `AGENTS.md` template.
337
- - `references/tools-readme-template.md` — `01-TOOLS/README.md` catalog template.
338
- - `references/audit-report-template.md` — text summary format for the in-conversation audit summary.
339
- - `references/audit-report-template.html` — HTML format for the full per-run audit artifact written to `02-DOCS/audits/`.
340
- - `references/wiki-protocol.md` — embedded protocol for the `02-DOCS/` chaos→knowledge layer (initialization, **Inbox Sweep**, **Worklog Sweep**, ingest, query, lint, **Continuous Improvement**: Maintenance Pass, Micro-Improve, Deep Improve; Obsidian-native conventions).
341
- - `references/ingest-formats.md` — multiformat Fetch: how any input (PDF, image, CSV/Excel, JSON/API, html, docx, email, unknown binary) becomes `raw/` markdown with the original preserved in `_originals/`.
342
- - `references/inbox-readme-template.md` — the `inbox/README.md` drop-zone contract shown to the user.
343
- - `references/wiki-raw-template.md` — format for `02-DOCS/raw/<topic>/*.md`.
344
- - `references/wiki-worklog-template.md` — format for `02-DOCS/raw/worklog/*.md` (the work-driven capture; the session as a raw source).
345
- - `references/wiki-article-template.md` — format for `02-DOCS/wiki/<topic>/*.md` (OKF v0.1 frontmatter + relative markdown links + `## Related`).
346
- - `references/wiki-index-template.md` — format for `02-DOCS/wiki/index.md` (machine catalog; the `.base` views are the human navigation).
347
- - `references/obsidian-scaffolding.md` — the vault scaffolding: `.base` views, `.gitignore`, `attachments/`, `.obsidian` config (no vector DB / RAG).
348
- - `references/daily-curation-automation.md` — portable scheduled compounding pass; on Claude Code wired via the `schedule` skill.
349
- - `references/wiki-archive-template.html` — HTML format for archived query answers (point-in-time, never edited).
350
- - `references/wiki-dashboard-template.html` — HTML format for the live wiki dashboard, regenerated by Maintenance Pass.
351
- - `references/wiki-deep-improve-report-template.html` — HTML format for Deep Improve run reports.
352
- - `references/wiki-gaps-template.md` — format for `02-DOCS/wiki/gaps.md` (Knowledge Gaps log).
353
- - `assets/_TEMPLATE/` — the boilerplate copied into every new tool.
294
+ - The catalog has no entry for a provider obviously present in code → tell the user, suggest adding an entry to `references/providers.yaml` (that file, never `SKILL.md`, is where providers are added), don't fake one.
354
295
 
355
296
  This skill is fully self-contained. No external sub-skill required.
356
297
 
@@ -28,7 +28,7 @@ should_trigger:
28
28
  should_not_trigger:
29
29
  - prompt: "I want to add a single Sentry tool folder to 01-TOOLS. Just copy the template and wire it up."
30
30
  route_to: "none"
31
- why: "SKILL.md 'Do NOT use' is explicit: adding a single tool is a manual `cp -r 01-TOOLS/_TEMPLATE 01-TOOLS/<X>` — the full SCAN/AUDIT/APPLY harness is overkill, no skill needed."
31
+ why: "SKILL.md 'Out of scope' is explicit: adding a single tool is a manual `cp -r 01-TOOLS/_TEMPLATE 01-TOOLS/<X>` — the full SCAN/AUDIT/APPLY harness is overkill, no skill needed."
32
32
 
33
33
  - prompt: "Refactor the runtime database layer in my FastAPI service to use async SQLAlchemy sessions."
34
34
  route_to: "fastapi"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: hiring
3
- description: "Use when there's an open role and you need to write the job post, screen inbound candidates, structure the interview loop, or build a scorecard to reach a fair hire decision; symptoms: gut-feel ratings, every interviewer asking the same question, a bloated requirements list, no consistent screen. Triggers: 'write a job description', 'screen these CVs', 'build an interview scorecard', 'structure the interview panel', 'redacta la oferta de empleo', 'necesito una scorecard', plus the non-obvious 'four people interviewed and we still can't decide' and 'is our AI résumé filter legal'. NOT managing the person after they're hired — onboarding, payroll, performance (that is people-ops)."
3
+ description: "Use when a role is open and you must write the job post, screen inbound candidates, structure the interview loop, or score them to a defensible Hire / On-Hold / No-Hire — including whether an AI résumé filter is legal. NOT after the offer is accepted — onboarding, payroll, performance (that is `people-ops`), NOT offer terms (that is `contracts`)."
4
4
  tags: [hiring, recruiting, job-description, interview-scorecard, candidate-screening, structured-interview]
5
5
  recommends: [people-ops, brand-voice, contracts, compliance, cold-outreach, calendar-scheduling]
6
6
  profiles: []
@@ -17,8 +17,7 @@ No-Hire with the reason written down.
17
17
 
18
18
  Hard boundary: the moment the offer is accepted, you are done. Onboarding,
19
19
  payroll, equipment, performance reviews, PTO — that is `../people-ops/SKILL.md`.
20
- Hiring gets the right person in the door; people-ops takes it from day one. Do
21
- not draft offer-letter terms here either; that is `../contracts/SKILL.md`.
20
+ Do not draft offer-letter terms here either; that is `../contracts/SKILL.md`.
22
21
 
23
22
  ## The funnel (the spine)
24
23
 
@@ -35,7 +34,7 @@ One rule per stage, with the why:
35
34
  named. Write the 3–6 competencies before the post, because they drive the
36
35
  post, the questions, and the scorecard.
37
36
  - **Write the post from the competencies.** A post is the competencies turned
38
- outward, not a wish list. See "Write the job post".
37
+ outward, not a wish list.
39
38
  - **Screen against one rubric.** Same criteria, same order, every candidate, or
40
39
  the comparison is meaningless.
41
40
  - **Run a structured loop.** Same questions, same rubric, every candidate —
@@ -45,18 +44,6 @@ One rule per stage, with the why:
45
44
  - **Score independently, then calibrate.** Each interviewer submits before the
46
45
  group talks. Debrief is calibration, not a re-vote.
47
46
 
48
- ### Screen decision table
49
-
50
- For each candidate at the screen stage:
51
-
52
- | Signal | Decision |
53
- |---|---|
54
- | Meets the must-haves on job-related evidence | Advance to loop |
55
- | Strong on most, one must-have unclear | Send a short work-sample / structured task to resolve it |
56
- | Misses a hard must-have (verified skill, legal eligibility) | Reject, with the job-related reason logged |
57
- | Borderline, more reqs open soon | Parking lot — note why, revisit, do not silently ghost |
58
- | Non-job factor (school name, age, gap, "vibe", name) | Ignore it — it is not in the rubric |
59
-
60
47
  ## Write the job post
61
48
 
62
49
  The job post is the top of the funnel and it leaks candidates if you write it
@@ -102,7 +89,8 @@ How to apply: send a short note + anything you've shipped.
102
89
  ## Screen the pile
103
90
 
104
91
  Score every applicant against the **same job-related rubric** you derived from
105
- the competencies. No bespoke criteria per candidate.
92
+ the competencies (template: `references/templates.md`). No bespoke criteria per
93
+ candidate.
106
94
 
107
95
  - **Blind to non-job factors.** School prestige, name, age, employment gaps,
108
96
  photo — none of it is in the rubric, so it does not enter the decision.
@@ -116,8 +104,15 @@ the competencies. No bespoke criteria per candidate.
116
104
  criminal-history box on the application form. (Candidate-data retention and
117
105
  consent: `../gdpr-privacy/SKILL.md`.)
118
106
 
119
- Use the screen decision table above for the advance / work-sample / reject /
120
- parking-lot call.
107
+ For each candidate, the call:
108
+
109
+ | Signal | Decision |
110
+ |---|---|
111
+ | Meets the must-haves on job-related evidence | Advance to loop |
112
+ | Strong on most, one must-have unclear | Send a short work-sample / structured task to resolve it |
113
+ | Misses a hard must-have (verified skill, legal eligibility) | Reject, with the job-related reason logged |
114
+ | Borderline, more reqs open soon | Parking lot — note why, revisit, do not silently ghost |
115
+ | Non-job factor (school name, age, gap, "vibe", name) | Ignore it — it is not in the rubric |
121
116
 
122
117
  ## Structure the interview loop
123
118
 
@@ -239,10 +234,3 @@ This skill *follows* the rules; it does not run the legal program — that is
239
234
  | Screening on school / name / gap | Non-job factor, not in the rubric | Blind to it; rubric only |
240
235
  | Deleting interview notes | Breaks EEOC retention; no defense | Retain ≥1 yr (2 yr for fed contractors) |
241
236
  | Drifting into onboarding/payroll | Out of scope, wrong skill | Stop at the decision → `../people-ops/SKILL.md` |
242
-
243
- ## References
244
-
245
- - `references/templates.md` — full anchored scorecard (one competency at all
246
- five levels), the structured question bank by competency, a fill-in job-post
247
- skeleton with the gender-coded word do/don't list, and a screening rubric
248
- template.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: instagram-api
3
- description: "Use when wiring an agent into Instagram's Graph API to publish a Reel from a video URL, pull per-media insights (reach, views, watch-time, saves, shares, total_interactions), check the 24-hour publish cap, or ingest Reel performance into 02-DOCS/wiki/shortform. Triggers: 'publish this Reel via the API', 'pull reach and average watch time for these media IDs', 'why does /insights?metric=plays return an error', 'my container is stuck IN_PROGRESS', 'how many posts left in the 24h publish window', 'publica este Reel por la API', 'ingesta el rendimiento dels Reels al wiki'. NOT TikTok publishing (that is tiktok-api), NOT a posting calendar/cadence (that is social-publisher), NOT YouTube uploads/stats (that is youtube-api)."
3
+ description: "Use when wiring an agent into Instagram's Graph API: publishing a Reel through the create/poll/publish container dance, reading per-media insights, checking the 24h publish cap, or ingesting Reel metrics into 02-DOCS/wiki/shortform. NOT TikTok (that is `tiktok-api`), NOT YouTube (that is `youtube-api`), NOT cross-platform cadence (that is `social-publisher`)."
4
4
  tags: [instagram, graph-api, content-publishing, reels, insights, shortform]
5
5
  recommends: [tiktok-api, youtube-api, social-publisher, shortform-strategy, api-connector-builder]
6
6
  origin: risco
@@ -12,15 +12,10 @@ The wire between an agent and Instagram's Graph API: publish Reels, pull the met
12
12
 
13
13
  All facts below are pinned to **Graph API v25.0** (current as of 2026-06-02). When you generate code, pin the version explicitly; Meta breaks metrics on version boundaries.
14
14
 
15
- ## When to use / when NOT
15
+ ## Route out
16
16
 
17
- | The ask | Route |
17
+ | The ask | Skill |
18
18
  |---|---|
19
- | Publish a Reel from a public `video_url` to an IG professional account | **here** |
20
- | Pull reach / views / watch-time / saves / shares for media IDs | **here** |
21
- | `/insights?metric=plays` (or `impressions`) suddenly errors | **here** (deprecation trap) |
22
- | Check the 24h publish cap before a batch | **here** |
23
- | Long-lived token exchange / refresh, scope wiring | **here** |
24
19
  | Post the same clip to **TikTok** | `tiktok-api` |
25
20
  | Upload to **YouTube** / pull YouTube stats | [`youtube-api`](../youtube-api/SKILL.md) |
26
21
  | Cadence, best-time, multi-platform calendar | [`social-publisher`](../social-publisher/SKILL.md) |
@@ -125,6 +120,8 @@ Bad: video_url behind auth or a 30s signed URL -> container stalls in ERROR.
125
120
  Good: a plain public MP4 that stays reachable for the full ~5 min window.
126
121
  ```
127
122
 
123
+ Full container field reference (reels / carousel / story), cover & thumb handling, error codes, retry/backoff, and batch publish with cap check → `references/publish-reel.md`.
124
+
128
125
  ## Status polling rules
129
126
 
130
127
  `status_code` is the only honest signal. Branch on it, do not guess from timing.
@@ -180,6 +177,8 @@ Requesting any retired metric does not return null — it **400s the entire insi
180
177
 
181
178
  If a previously-working call started erroring, this table is almost certainly why: a metric you used to request was retired on a version boundary. Swap to `views` and drop the dead names.
182
179
 
180
+ Complete current metric tables per media type, the full deprecated→replacement map with dates, version-gated 2025–2026 additions, and the `02-DOCS/wiki/shortform/` ingest schema spec → `references/insights-metrics.md`.
181
+
183
182
  ## Ingest into 02-DOCS/wiki/shortform/
184
183
 
185
184
  This is the checkable deliverable. One file per media id, idempotent overwrite (re-running a pull refreshes `pulled_at` and metrics, never duplicates).
@@ -222,14 +221,6 @@ current valid Reels set; no deprecated names requested.
222
221
 
223
222
  `type` is the only required OKF v0.1 field; `title`/`description`/`tags`/`timestamp` are the recommended OKF surface (`timestamp` mirrors the pull instant). The DOMAIN keys below are mandatory and stay byte-for-byte — `verify.sh` requires a pinned `graph_version` and greps the `metrics` block for deprecated names; `pulled_at` is the API-pull instant verify/diff rely on. Keep both `pulled_at` and `timestamp`. Why front-matter + media-id filename: the wiki is queried by key, and re-pulls must be diffable, not additive (the idempotent overwrite re-stamps `timestamp` and `pulled_at` together).
224
223
 
225
- ## Migration & gotchas
226
-
227
- - **Scopes:** replace `instagram_basic` → `instagram_business_basic`, `instagram_content_publish` → `instagram_business_content_publish`. Old names grant nothing post-2025-01-27.
228
- - **Host:** chosen by login path, not per call. Do not send a `graph.instagram.com` token to `graph.facebook.com`.
229
- - **Token:** refresh the 60-day long-lived token before expiry; expired tokens fail every call with an auth error, not a 404.
230
- - **Reel eligibility:** 9:16, 5–90s, H.264/HEVC. A non-conforming source surfaces as container `ERROR`, not a clean validation message.
231
- - **New 2025–2026 metrics** (Reels skip rate, repost counts, crossposted views): optional and version-gated. Confirm they exist on `GRAPH_VERSION` before requesting, or they trip the same 400 trap.
232
-
233
224
  ## Anti-patterns
234
225
 
235
226
  | Anti-pattern | Why it bites | Do instead |
@@ -239,10 +230,9 @@ current valid Reels set; no deprecated names requested.
239
230
  | Leaving `GRAPH_VERSION` blank / using default | Metric set silently shifts on Meta's rollout | Pin `v25.0` in every call |
240
231
  | Signed/auth-gated `video_url` | Container stalls in `ERROR` | Plain public MP4 for the full window |
241
232
  | Batch publishing without cap check | Hit #51 mid-run, half-published queue | `content_publishing_limit` before the loop |
242
- | Old scopes (`instagram_basic`) | Grant nothing since 2025-01-27 | `instagram_business_*` scopes |
233
+ | Old scopes (`instagram_basic`, `instagram_content_publish`) | Grant nothing since 2025-01-27 | `instagram_business_basic` / `instagram_business_content_publish` |
243
234
  | Storing the container id as "the post" | It's not the published media id | Persist the `media_publish` id |
244
-
245
- ## References
246
-
247
- - `references/publish-reel.md` — full container field reference (reels / carousel / story), cover & thumb handling, error codes, retry/backoff, batch publish with cap check.
248
- - `references/insights-metrics.md` — complete current metric tables per media type, the full deprecated→replacement map with dates, version-gated 2025–2026 additions, and the `02-DOCS/wiki/shortform/` ingest schema spec.
235
+ | Sending a `graph.instagram.com` token to `graph.facebook.com` | Host is fixed by the login path, not chosen per call | Pick the host with the auth path and stay on it |
236
+ | Letting the 60-day long-lived token lapse | Every call fails with an auth error, not a 404 | Refresh before expiry |
237
+ | A source video outside Reel eligibility | Surfaces as container `ERROR`, not a clean validation message | 9:16, 5–90s, H.264/HEVC |
238
+ | Requesting the 2025–2026 additions (Reels skip rate, repost counts, crossposted views) blind | Version-gated — trips the same 400 trap as a deprecated name | Confirm they exist on `GRAPH_VERSION` first |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: machine-learning
3
- description: "Use when the task is a classic/tabular machine-learning problem — predict a column from rows of features with trees and scikit-learn: fit a RandomForest / XGBoost / LightGBM classifier or regressor, build a leak-proof Pipeline + ColumnTransformer, choose a cross-validation scheme (stratified / k-fold / time-series / grouped), pick the right metric on imbalanced classes (precision/recall/F1/ROC-AUC/PR-AUC, not accuracy), or debug a model that aced CV then collapsed in production. Triggers: 'train a model to predict churn/fraud/price', 'my ROC-AUC is 0.99 — is that leakage', 'which metric for imbalanced classes', 'cross-validation without leaking', 'XGBoost vs LightGBM', 'add a DummyClassifier baseline', 'entrena un modelo de clasificación tabular con scikit-learn'. NOT neural-net / PyTorch training (that is deep-learning), NOT cleaning the raw dirty table first (that is data-cleaning), NOT BI dashboards or forecasting a dated series (that is analytics/forecasting), NOT text/token modeling (that is nlp)."
3
+ description: "Use when predicting a column from rows of tabular features with classic models — scikit-learn pipelines, RandomForest, XGBoost/LightGBM, leak-free cross-validation, metrics for imbalanced classes, or a model that aced CV then collapsed in production. NOT PyTorch neural nets (that is `deep-learning`), NOT cleaning the dirty table first (that is `data-cleaning`), NOT forecasting a dated series (that is `forecasting`), NOT text/token modeling (that is `nlp`)."
4
4
  tags: [machine-learning, scikit-learn, sklearn, xgboost, lightgbm, tabular, gbdt, cross-validation, data-leakage, classification, regression, pipeline]
5
5
  recommends: [deep-learning, data-cleaning, python, training-data]
6
6
  origin: risco
@@ -21,9 +21,9 @@ once isn't a result — it's a leak you haven't found yet.
21
21
  | Rows of features, predict a column, with trees / linear models / sklearn | **machine-learning** (this skill) |
22
22
  | Images, audio, long text, sequences, or you need a neural net / PyTorch | [`deep-learning`](../deep-learning/SKILL.md) |
23
23
  | The table is still dirty (nulls, dupes, mixed types, bad dates) | [`data-cleaning`](../data-cleaning/SKILL.md) **first** — it hands you a validated table |
24
- | Text/token classification, NER, tokenization, LLM-adjacent NLP metrics | [`nlp`](../nlp/SKILL.md) |
25
- | KPIs, dashboards, "explain the business" | `analytics` / `business-intelligence` |
26
- | Forecast a dated series forward (revenue next quarter) | `forecasting` |
24
+ | Text/token classification, NER, tokenization, LLM-adjacent NLP metrics | [`nlp`](../nlp/SKILL.md) (a TF-IDF + linear/GBDT baseline still lives happily in this skill's pipeline) |
25
+ | KPIs, dashboards, "explain the business" | [`analytics`](../analytics/SKILL.md) / [`business-intelligence`](../business-intelligence/SKILL.md) |
26
+ | Forecast a dated series forward (revenue next quarter) | [`forecasting`](../forecasting/SKILL.md) |
27
27
  | Building a training corpus of JSONL messages / preference pairs for an LLM | [`training-data`](../training-data/SKILL.md) |
28
28
 
29
29
  This skill **starts** at a clean, validated table (rows × features + a target) and **ends** at a fitted,
@@ -36,8 +36,9 @@ Verified 2026-07: **scikit-learn current major ~1.9** (1.9.0 shipped 2026-06-02,
36
36
  NOT pin from memory; check the current stable at scikit-learn.org, the 1.x line ships every few months.
37
37
  GBDTs: **XGBoost 3.x** and **LightGBM 4.x** (`xgboost` 3.3, `lightgbm` 4.6 current), plus sklearn's own
38
38
  **`HistGradientBoostingClassifier`/`...Regressor`** — a fast native GBDT that eats NaN and (with
39
- `categorical_features="from_dtype"`) categoricals with **no** preprocessing. Pin what you ship; state
40
- versions as "~X (verify)", never as frozen fact.
39
+ `categorical_features="from_dtype"`) categoricals with **no** preprocessing. Pin what you ship
40
+ ([`python`](../python/SKILL.md) owns the environment and the pinning); state versions as "~X (verify)",
41
+ never as frozen fact.
41
42
 
42
43
  ## The one rule everything else serves: fit on train only
43
44
 
@@ -107,7 +108,7 @@ functions**. Start with a GBDT; reach for `deep-learning` on tabular only with a
107
108
  All three expose the sklearn estimator API, so they drop into the pipeline and CV below unchanged. Don't
108
109
  agonize over XGBoost-vs-LightGBM before you have a baseline and a leak-free CV — split discipline dwarfs the
109
110
  library choice. Tuning knobs (`learning_rate`, `num_leaves`/`max_depth`, early stopping, `monotonic_cst`)
110
- → [references/gbdt-and-tuning.md](references/gbdt-and-tuning.md).
111
+ and importance/SHAP → [references/gbdt-and-tuning.md](references/gbdt-and-tuning.md).
111
112
 
112
113
  ## Leakage-safe feature engineering
113
114
 
@@ -174,19 +175,21 @@ The default 0.5 threshold is a *choice*: tune it on validation to hit your preci
174
175
  Regression uses `root_mean_squared_error` now (`mean_squared_error(squared=False)` is gone). Threshold
175
176
  tuning, calibration, `class_weight`/resampling → [references/metrics-and-imbalance.md](references/metrics-and-imbalance.md).
176
177
 
177
- ## Cardinal sins (the anti-pattern table)
178
+ ## Anti-patterns — the cardinal sins
178
179
 
179
- | Rationalization | Reality → STOP |
180
+ | Anti-pattern | Do instead |
180
181
  | --- | --- |
181
- | "I scaled/encoded/selected features, then split." | **Leakage (#1 sin).** Test statistics are now in train. Split first; put every learned transform *inside* the `Pipeline` so CV re-fits per fold. |
182
- | "This feature is amazingly predictive." | Suspect **target leakage** — a column derived from the label or unavailable at prediction time. Audit provenance before you celebrate. |
183
- | "99% accuracy!" (on 1% positives) | The **accuracy trap**. A constant predictor matches it. Report PR-AUC / precision / recall / F1 and a `confusion_matrix`. |
184
- | "The classes are imbalanced, so I `SMOTE`'d the whole dataset." | Resampling *before* the split, or on the test fold, leaks and evaluates on synthetic rows. Resample **inside CV, on the train fold only** (imblearn `Pipeline`), or just use `class_weight="balanced"`. |
185
- | "CV score is 0.95, ship it." | You never touched a **held-out test set**, or you peeked at it while tuning. One final, untouched test number — or the estimate is optimistic. |
186
- | "Random `KFold` on my time-series / multi-user data." | Future or same-group rows leak into train. Use `TimeSeriesSplit` / `GroupKFold`. |
187
- | "Big train/test gap? It'll generalize." | **Overfitting.** Regularize, reduce capacity (`max_depth`, `min_samples_leaf`), get more data, or use early stopping. Watch `return_train_score`. |
188
- | "Straight to XGBoost, no baseline." | Without a **`DummyClassifier(strategy="most_frequent")`** / `DummyRegressor` floor (and a simple linear model), you can't tell if the fancy model adds anything. |
189
- | "I'll grid-search 10k combos on all the data." | Tuning against the test set *is* fitting to it. Tune with CV on train, confirm once on test; consider nested CV. |
182
+ | Modeling straight off the raw, dirty table | This skill starts at a **clean, validated frame**. Run [`data-cleaning`](../data-cleaning/SKILL.md) first — nulls, dupes and mixed dtypes are its job, not a modeling problem. |
183
+ | Scaling / encoding / selecting features, *then* splitting | **Leakage (#1 sin).** Test statistics are now in train. Split first; put every learned transform *inside* the `Pipeline` so CV re-fits per fold. |
184
+ | Celebrating an amazingly predictive feature | Suspect **target leakage** — a column derived from the label or unavailable at prediction time. Audit provenance before you celebrate. |
185
+ | Reporting 99% accuracy on 1% positives | The **accuracy trap**. A constant predictor matches it. Report PR-AUC / precision / recall / F1 and a `confusion_matrix`. |
186
+ | `SMOTE`-ing the whole dataset because the classes are imbalanced | Resampling *before* the split, or on the test fold, leaks and evaluates on synthetic rows. Resample **inside CV, on the train fold only** (imblearn `Pipeline`), or just use `class_weight="balanced"`. |
187
+ | Shipping on the CV score alone | You never touched a **held-out test set**, or you peeked at it while tuning. One final, untouched test number — or the estimate is optimistic. |
188
+ | Random `KFold` on time-series / multi-user data | Future or same-group rows leak into train. Use `TimeSeriesSplit` / `GroupKFold`. |
189
+ | Waving off a big train/test gap | **Overfitting.** Regularize, reduce capacity (`max_depth`, `min_samples_leaf`), get more data, or use early stopping. Watch `return_train_score`. |
190
+ | Going straight to XGBoost with no baseline | Without a **`DummyClassifier(strategy="most_frequent")`** / `DummyRegressor` floor (and a simple linear model), you can't tell if the fancy model adds anything. |
191
+ | Grid-searching 10k combos over all the data | Tuning against the test set *is* fitting to it. Tune with CV on train, confirm once on test; consider nested CV. |
192
+ | Unset `random_state`, unpinned versions | Folds and fits stop being reproducible and re-trains stop being comparable. Set an integer `random_state` on splitters *and* estimators; pin the versions you ship. |
190
193
 
191
194
  ## Worked lifecycle (end to end)
192
195
 
@@ -216,41 +219,6 @@ print("TEST PR-AUC:", round(average_precision_score(y_test, proba), 3))
216
219
  print(classification_report(y_test, (proba >= 0.5).astype(int))) # threshold is a choice — tune it
217
220
  ```
218
221
 
219
- ## Related skills
220
-
221
- - [`deep-learning`](../deep-learning/SKILL.md) — PyTorch neural nets. Cross the boundary for images, audio,
222
- long text, sequences; on *tabular* data, stay here (Grinsztajn: trees win).
223
- - [`data-cleaning`](../data-cleaning/SKILL.md) — upstream; produces the validated table this skill trains
224
- on. Don't re-teach nulls/dupes/dtypes here.
225
- - [`nlp`](../nlp/SKILL.md) — text/token modeling, NER, tokenization, task metrics (a TF-IDF + linear/GBDT
226
- baseline still lives happily in this skill's pipeline).
227
- - [`python`](../python/SKILL.md) — environment, packaging, pinning the versions you ship.
228
- - [`training-data`](../training-data/SKILL.md) — if the goal is an LLM corpus (JSONL messages / preference
229
- pairs), not a tabular predictor. BI/forecasting products → `analytics` / `business-intelligence` / `forecasting`.
230
-
231
- ## Checklist
232
-
233
- - [ ] Input is a clean, validated table (from `data-cleaning`), not raw dirty rows.
234
- - [ ] A **test set** was held out **once, up front**, stratified, and left untouched until the final score.
235
- - [ ] Every learned transform (impute/scale/encode/select/target-encode) lives **inside** the `Pipeline`.
236
- - [ ] CV runs on the training portion only, via `cross_validate`/`GridSearchCV` over the *pipeline*.
237
- - [ ] Splitter matches the data: `StratifiedKFold` (imbalanced), `TimeSeriesSplit` (time), `GroupKFold` (clustered).
238
- - [ ] A `DummyClassifier`/`DummyRegressor` baseline (and a simple linear model) is beaten, not skipped.
239
- - [ ] Metric fits the task — **not accuracy on imbalanced data**; PR-AUC/precision/recall/F1 as appropriate.
240
- - [ ] Target-leakage audit done: no label-derived / future / not-at-prediction-time features.
241
- - [ ] `random_state` set on splitters and estimators; versions pinned for what ships.
242
- - [ ] Train-vs-test gap inspected; overfitting addressed before shipping.
243
-
244
- ## References
245
-
246
- - [references/pipelines-and-cv.md](references/pipelines-and-cv.md) — `Pipeline`/`ColumnTransformer` patterns,
247
- `FunctionTransformer`, `TargetEncoder` cross-fitting, `GridSearchCV`/`RandomizedSearchCV`/`HalvingRandomSearchCV`,
248
- nested CV, `TimeSeriesSplit`/`GroupKFold` recipes.
249
- - [references/metrics-and-imbalance.md](references/metrics-and-imbalance.md) — metric selection, threshold
250
- tuning, probability calibration, `class_weight`/`sample_weight`, leak-free resampling (imbalanced-learn `Pipeline`).
251
- - [references/gbdt-and-tuning.md](references/gbdt-and-tuning.md) — HistGBDT vs XGBoost vs LightGBM parameter
252
- maps, early stopping, native categoricals, monotonic constraints, permutation importance vs SHAP.
253
-
254
222
  ## Project grounding (02-DOCS + CLAUDE.md)
255
223
 
256
224
  In a project with a `02-DOCS/` layer (the [`harness`](../harness/SKILL.md) wiki), record the modeling
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: observability
3
- description: "Use when instrumenting a service from the inside so an incident can be explained from telemetry alone — wiring OpenTelemetry logs, metrics and traces, standing up a Collector, exporting via OTLP, and defining telemetry-driven alerts. Triggers: 'add OpenTelemetry to this service', 'we can't tell why requests are slow across services — add distributed tracing', 'replace our print/console.log with structured logs correlated to traces', 'stand up an OTel Collector and export to Grafana/Datadog/Honeycomb', 'instrument our LLM calls so each request is a span with token counts', 'define RED metrics and a burn-rate alert from the telemetry', 'instrumenta el servei amb OpenTelemetry i exporta a Grafana', 'añade trazas distribuidas y métricas'. NOT outside-in uptime probes, on-call rotation, or who-gets-paged (that is monitoring)."
3
+ description: "Use when instrumenting a service from the inside so an incident can be explained from telemetry alone — wiring OpenTelemetry logs, metrics and traces, standing up a Collector, exporting via OTLP, and defining telemetry-driven alerts. NOT outside-in uptime probes, on-call rotation, or who-gets-paged (that is `monitoring`)."
4
4
  tags: [observability, opentelemetry, tracing, metrics, structured-logging]
5
5
  recommends: [monitoring, error-handling, performance, cost-tracking, docker]
6
6
  origin: risco
@@ -8,9 +8,7 @@ origin: risco
8
8
 
9
9
  # Observability
10
10
 
11
- You are wiring the *inside* view of a service: when something breaks at 3am, an engineer must be able to answer "what happened, where, and why" from telemetry alone — without adding a `console.log` and redeploying into the fire. This skill emits a concrete artifact: SDK init code, instrumentation (spans/metrics/structured logs), a Collector config, and alert rules that the instrumentation makes possible.
12
-
13
- It is the inside-out half of running in production. The outside half — is it up, who gets paged, on-call rotation — is `../monitoring/SKILL.md`. The clean test: if the deliverable is *"a human gets paged,"* that is monitoring. If it is *"the data that explains the page exists and is queryable,"* that is here.
11
+ You are wiring the *inside* view of a service: when something breaks at 3am, an engineer must be able to answer "what happened, where, and why" from telemetry alone — without adding a `console.log` and redeploying into the fire. This skill emits a concrete artifact: SDK init code, instrumentation (spans/metrics/structured logs), a Collector config, and alert rules that the instrumentation makes possible. The outside-in half — is it up, who gets paged — is `../monitoring/SKILL.md`.
14
12
 
15
13
  ## The one rule
16
14