@ericrisco/rsc 2.0.20 → 2.2.0

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 +63 -21
  2. package/manifest.json +18 -85
  3. package/package.json +5 -1
  4. package/scripts/consult.js +8 -8
  5. package/scripts/install-apply.js +48 -11
  6. package/scripts/lib/default-skill-floor.js +5 -4
  7. package/scripts/lib/divergence.js +7 -3
  8. package/scripts/lib/domains.js +2 -2
  9. package/scripts/lib/onboarding-apply.js +43 -26
  10. package/scripts/lib/onboarding.js +5 -5
  11. package/scripts/lib/recommend.js +1 -1
  12. package/scripts/lib/repair.js +4 -2
  13. package/scripts/lib/retired-skills.js +20 -0
  14. package/scripts/rsc.js +25 -19
  15. package/scripts/skill-behavior-rubric.md +1 -1
  16. package/scripts/skill-migration-brief.md +3 -3
  17. package/skills/analyze/SKILL.md +3 -8
  18. package/skills/analyze/evals/cases.yaml +1 -1
  19. package/skills/author-skill/SKILL.md +3 -3
  20. package/skills/author-skill/evals/cases.yaml +1 -1
  21. package/skills/author-skill/references/rsc-conventions.md +1 -1
  22. package/skills/clarify/SKILL.md +7 -14
  23. package/skills/clarify/evals/cases.yaml +2 -2
  24. package/skills/code-review/SKILL.md +1 -1
  25. package/skills/constitution/SKILL.md +10 -13
  26. package/skills/constitution/evals/cases.yaml +3 -3
  27. package/skills/continuous-learning/SKILL.md +1 -1
  28. package/skills/continuous-learning/evals/cases.yaml +1 -1
  29. package/skills/debug/SKILL.md +8 -12
  30. package/skills/debug/evals/cases.yaml +1 -1
  31. package/skills/decision-challenge/SKILL.md +1 -1
  32. package/skills/deprecation/SKILL.md +1 -1
  33. package/skills/ftd/SKILL.md +1 -3
  34. package/skills/ftd/evals/cases.yaml +1 -1
  35. package/skills/harness/SKILL.md +10 -9
  36. package/skills/harness/references/claude-md-template.md +1 -1
  37. package/skills/harness/references/wiki-protocol.md +5 -6
  38. package/skills/idea-refinement/SKILL.md +1 -1
  39. package/skills/implement/SKILL.md +14 -18
  40. package/skills/implement/evals/cases.yaml +1 -1
  41. package/skills/init/SKILL.md +36 -45
  42. package/skills/init/evals/README.md +3 -3
  43. package/skills/init/evals/cases.yaml +7 -7
  44. package/skills/init/references/accompaniment-and-profile.md +22 -40
  45. package/skills/init/references/discovery.md +2 -2
  46. package/skills/init/references/recommend-skills.md +5 -5
  47. package/skills/init/scripts/verify.sh +3 -7
  48. package/skills/knowledge-ops/SKILL.md +1 -1
  49. package/skills/orient/SKILL.md +52 -41
  50. package/skills/orient/evals/README.md +11 -9
  51. package/skills/orient/evals/cases.yaml +39 -29
  52. package/skills/orient/references/explain-ladder.md +93 -0
  53. package/skills/orient/references/orientation-contract.md +70 -18
  54. package/skills/parallel/SKILL.md +1 -1
  55. package/skills/parallel/evals/cases.yaml +2 -2
  56. package/skills/plan/SKILL.md +9 -13
  57. package/skills/review/SKILL.md +5 -8
  58. package/skills/roast-me/SKILL.md +1 -1
  59. package/skills/sdd/SKILL.md +10 -14
  60. package/skills/sdd/evals/README.md +2 -2
  61. package/skills/sdd/evals/cases.yaml +4 -4
  62. package/skills/sdd/references/model-routing.md +5 -12
  63. package/skills/sdd-init/SKILL.md +3 -3
  64. package/skills/ship/SKILL.md +6 -11
  65. package/skills/simplify-code/SKILL.md +1 -1
  66. package/skills/skill-scout/SKILL.md +1 -1
  67. package/skills/source-grounded-development/SKILL.md +1 -1
  68. package/skills/specify/SKILL.md +13 -14
  69. package/skills/specify/evals/cases.yaml +1 -1
  70. package/skills/specify/references/eliciting-requirements.md +5 -5
  71. package/skills/suggest/SKILL.md +3 -9
  72. package/skills/suggest/evals/cases.yaml +1 -1
  73. package/skills/tasks/SKILL.md +6 -7
  74. package/skills/tasks/evals/cases.yaml +1 -1
  75. package/skills/unslop/SKILL.md +39 -10
  76. package/skills/unslop/evals/README.md +7 -7
  77. package/skills/unslop/evals/cases.yaml +10 -9
  78. package/skills/verify/SKILL.md +5 -8
  79. package/skills/verify/evals/cases.yaml +1 -1
  80. package/skills/worktrees/SKILL.md +14 -18
  81. package/skills/worktrees/evals/cases.yaml +1 -1
  82. package/targets/_md-block.js +7 -1
  83. package/targets/auto-update.mjs +200 -0
  84. package/targets/claude.js +2 -0
  85. package/targets/clone-bootstrap.mjs +5 -2
  86. package/targets/opt-outs.js +1 -0
  87. package/targets/session-start.mjs +5 -78
  88. package/targets/update-wiring.js +153 -0
  89. package/skills/bro/SKILL.md +0 -76
  90. package/skills/bro/evals/README.md +0 -22
  91. package/skills/bro/evals/cases.yaml +0 -62
  92. package/skills/eli5/SKILL.md +0 -63
  93. package/skills/eli5/evals/README.md +0 -22
  94. package/skills/eli5/evals/cases.yaml +0 -54
  95. package/skills/show-me/SKILL.md +0 -140
  96. package/skills/show-me/evals/README.md +0 -23
  97. package/skills/show-me/evals/cases.yaml +0 -61
@@ -52,18 +52,17 @@ If you cannot state a requirement without naming the technology, that is a real
52
52
 
53
53
  ## Model tier — `balanced` (opt-in routing)
54
54
 
55
- This phase's default model tier is **`balanced`** — it drafts the what/why spec through dialogue, not architecture. Routing is **off** unless `models.enabled: true` in `02-DOCS/wiki/sdd/config.yaml`. When on: resolve this phase's tier (`models.overrides` wins over `models.phases`), map it to a model via `models.tiers`, and apply per `../sdd/references/model-routing.md` — announce the switch per the accompaniment dial when it differs from the session model, and dispatch any `Task`/`parallel` subagents on that model. Routing off or no profile → honor the session model silently. Never fake a switch a tool can't make; skip routing on a one-line change.
55
+ This phase's default model tier is **`balanced`** — it drafts the what/why spec through dialogue, not architecture. Routing is **off** unless `models.enabled: true` in `02-DOCS/wiki/sdd/config.yaml`. When on: resolve this phase's tier (`models.overrides` wins over `models.phases`), map it to a model via `models.tiers`, and apply per `../sdd/references/model-routing.md` — announce the switch in one line when it differs from the session model, and dispatch any `Task`/`parallel` subagents on that model. Routing off or no profile → honor the session model silently. Never fake a switch a tool can't make; skip routing on a one-line change.
56
56
 
57
- ## Read the room first (accompaniment dial)
57
+ ## Read the room first (register)
58
58
 
59
- Before asking anything, read `02-DOCS/wiki/harness/user-profile.md` for the technical level and accompaniment level, and adapt:
59
+ Before asking anything, read `technical_level` in `02-DOCS/wiki/harness/user-profile.md`. It picks the register — technical terms, or plain words with everyday analogies — and nothing else; the method is the same for every reader:
60
60
 
61
- - **L0 "cavernícola"** — infer aggressively from the intent and any existing wiki/constitution. Ask only the questions whose answer would change the contract. Draft, show, move on.
62
- - **L1 "breve"** — one line of *why* per question; ask the few that genuinely matter.
63
- - **L2 "explica decisiones"** — justify each requirement as you record it; surface the trade-offs you inferred.
64
- - **L3 "acompañamiento total"** — explain what a spec is and is not, walk every section, ask freely (still one round per frontier, never crossing a dependency), confirm each answer before recording it. Ideal for non-technical users.
61
+ - Infer aggressively from the intent and any existing wiki/constitution. Ask only the questions whose answer would change the contract — one round per frontier, never crossing a dependency.
62
+ - Give one line of *why* per question, in the `orient` voice; record each requirement with the trade-off you inferred.
63
+ - For a `non-technical` reader, say in one sentence what a spec is, and phrase each option as a concrete example to react to.
65
64
 
66
- If no profile exists, default to non-technical framing and keep questions plain. Never assume fluency.
65
+ If no profile exists, use analogies and keep questions plain. Never assume fluency.
67
66
 
68
67
  ## FRAME before you ask anything — from `idea-refinement`
69
68
 
@@ -171,7 +170,7 @@ Run these in order. It is a collaborative dialogue, not a form you fill in silen
171
170
  7. WRITE the spec → 02-DOCS/wiki/sdd/specs/<slug>.md (WHAT/WHY), index it in 02-DOCS/wiki/index.md
172
171
  (the Knowledge map; root CLAUDE.md keeps only a short pointer), commit if a repo
173
172
  8. SELF-REVIEW → run the EXIT GATE (below) until green; scan for contradictions, ambiguity,
174
- scope creep; fix inline. On L2/L3 or high risk, add a FRESH-EYES review
173
+ scope creep; fix inline. On a non-trivial or high-risk spec, add a FRESH-EYES review
175
174
  9. USER APPROVES → ask them to read the written spec and confirm; loop on changes until they approve
176
175
  10. HAND OFF → only now, result envelope → clarify/plan. NEVER to implement.
177
176
  ```
@@ -197,10 +196,10 @@ the section that failed and fix it before step 9.
197
196
  A gate that has never been seen fail is not known to work, so this one ships with the test that
198
197
  watches it fail and pass (`tests/spec-gate.test.js`).
199
198
 
200
- ### Fresh-eyes spec review (step 8, scaled to the dial)
199
+ ### Fresh-eyes spec review (step 8, scaled to the stakes)
201
200
 
202
201
  The author's own context is blind to its own gaps — the same mind that wrote the spec self-reviews it
203
- with the same blind spots. For an L2/L3 user or a **high-risk** spec (multi-subsystem, security/data,
202
+ with the same blind spots. For any spec beyond a small, low-risk one — and always for a **high-risk** spec (multi-subsystem, security/data,
204
203
  irreversible, or large scope), dispatch a **fresh-context subagent** to read the written spec cold,
205
204
  *before* the user-approval gate (step 9), and fold its findings in:
206
205
 
@@ -213,7 +212,7 @@ irreversible, or large scope), dispatch a **fresh-context subagent** to read the
213
212
  - **It returns** `Approved` or `Issues found` with a short list; you fix the real ones inline, then
214
213
  proceed to step 9.
215
214
 
216
- **Skip it** for L0/L1 on a small, low-risk spec — the self-review scan is enough there; don't spin up
215
+ **Skip it** on a small, low-risk spec — the self-review scan is enough there; don't spin up
217
216
  a subagent to vet a two-paragraph spec. Like the rest of the chain, ceremony scales to the stakes.
218
217
 
219
218
  ### Approval is its own exchange (step 9)
@@ -382,11 +381,11 @@ If `clarify` surfaces answers, they get baked back into this same spec file. Onl
382
381
  - `../constitution/SKILL.md` — the project principles this spec inherits as constraints.
383
382
  - `../clarify/SKILL.md` — the next phase: resolves the Points to clarify and de-risks the spec.
384
383
  - `../plan/SKILL.md` — turns the de-risked spec into a technical implementation plan (the HOW).
385
- - `../harness/SKILL.md` — the 02-DOCS wiki + accompaniment dial + decisions log this skill honors.
384
+ - `../harness/SKILL.md` — the 02-DOCS wiki + user profile + decisions log this skill honors.
386
385
  - `references/spec-template.md` — the exact section template written to `02-DOCS/wiki/sdd/specs/<slug>.md`.
387
386
  - `references/eliciting-requirements.md` — inference checklist + the frontier-round elicitation pattern.
388
387
 
389
388
  ## Orientación (siempre)
390
389
 
391
- Cierra cada turno con el **bloque-brújula** (📍 dónde estás · ✅ qué hiciste · 🧭 por qué · ➡️ siguiente, terminando en pregunta), calibrado al dial de `02-DOCS/wiki/harness/user-profile.md`. **Nunca termines en seco.** Protocolo completo: skill `orient` → `skills/orient/references/orientation-contract.md`. (Defiere a `suggest` el "¿instalo la skill que falta?".)
390
+ Habla con la voz de `orient`: frases cortas, una idea por frase, y cada respuesta se entiende sola. Registro técnico o con analogías según `technical_level` en `02-DOCS/wiki/harness/user-profile.md`. Cierra cada turno con el **bloque-brújula** (📍 dónde estás · ➡️ siguiente, terminando en pregunta; ✅ y 🧭 cuando hay algo hecho o decidido). **Nunca termines en seco.** Protocolo completo: skill `orient` → `skills/orient/references/orientation-contract.md`. (Defiere a `suggest` el "¿instalo la skill que falta?".)
392
391
 
@@ -63,7 +63,7 @@ should_not_trigger:
63
63
  capability:
64
64
  - scenario: "A user says: 'I want to add magic-link (passwordless) login.' There is a constitution at 02-DOCS/wiki/sdd/constitution.md but no spec yet. Produce the spec."
65
65
  must_include:
66
- - "Reads the accompaniment level from 02-DOCS/wiki/harness/user-profile.md and the constitution first, inferring everything it can before asking, then asks only contract-changing gaps — the whole FRONTIER in one numbered round, each with its recommendation, and nothing whose answer depends on another question open in that same round."
66
+ - "Reads technical_level from 02-DOCS/wiki/harness/user-profile.md and the constitution first, inferring everything it can before asking, then asks only contract-changing gaps — the whole FRONTIER in one numbered round, each with its recommendation, and nothing whose answer depends on another question open in that same round."
67
67
  - "Stays strictly WHAT/WHY: no framework, token format, database table, endpoint shape, email provider, library, or file path appears in the spec — implementation-laden answers are flagged as points to clarify instead of guessed."
68
68
  - "Produces the spec sections: Problem & why, Cost of not building it, The cheapest alternative, Goals, Non-goals / out of scope, Users & context, Behaviour (main + edge + error paths), Acceptance criteria, Points to clarify — and neither of the two doubt sections is left as a formality: 'Cost of not building it' names a concrete consequence, and 'The cheapest alternative' names something that would solve most of it without building this, plus why that is not enough."
69
69
  - "Writes testable acceptance criteria in Given/When/Then form that verify could later check (e.g. expired-link refusal, unknown-email revealing nothing)."
@@ -22,7 +22,7 @@ and the intent itself. Only what survives as unknown becomes a question or a
22
22
  - **Boundaries** — what's adjacent but deliberately excluded? Derive non-goals
23
23
  from the constitution's scope and quality bars.
24
24
  - **Happy path** — the common-case behaviour is usually inferable from the
25
- intent; write it, then test it with the user if L2/L3.
25
+ intent; write it, then test it with the user.
26
26
  - **Edges** — empty / none / one / many / max, concurrent, repeated, expired,
27
27
  unauthorized. Walk these mechanically; each is a candidate criterion.
28
28
  - **Errors** — what does the user see when it fails, and what must NOT be
@@ -77,15 +77,15 @@ moved is worse than no answer, because it looks settled.
77
77
 
78
78
  Phrase by register:
79
79
 
80
- - **Non-technical / L3** — plain language, one concept, offer a concrete
80
+ - **Non-technical** — plain language, one concept, offer a concrete
81
81
  example to react to rather than an open void:
82
82
  > "When someone's link has expired, should they be able to ask for a fresh
83
83
  > one right there, or is that a separate step?"
84
- - **Technical / L0-L1** — terse, decision-shaped:
84
+ - **Technical** — terse, decision-shaped:
85
85
  > "Expired-link recovery in scope, or defer?"
86
86
 
87
- Always: emit the round → wait → record each answer in its section → confirm at
88
- L2/L3 → recompute the frontier. The thing to avoid was never two questions in
87
+ Always: emit the round → wait → record each answer in its section → confirm it
88
+ → recompute the frontier. The thing to avoid was never two questions in
89
89
  one message; it was ten questions whose answers depend on each other, which is
90
90
  what crossing a dependency produces.
91
91
 
@@ -15,9 +15,6 @@ are the one piece guaranteed to be present before any other skill is matched. Tw
15
15
  1. **Classify every turn into one of three lanes** before anything is written.
16
16
  2. **Keep the session equipped** — spot the skill the task needs but the user does not have.
17
17
 
18
- Everything below is what only this layer can do. The method behind each rule lives in the skill that
19
- owns it; this is the pointer, not the manual.
20
-
21
18
  ---
22
19
 
23
20
  ## 1. The decisor: classify the turn before acting
@@ -110,8 +107,8 @@ Offer once per session. Never mention any of it when the harness is healthy.
110
107
  Before handling the first request of a session, check the workspace:
111
108
 
112
109
  - No `02-DOCS/wiki/harness/user-profile.md` **and** no `.rsc/.no-harness` → the harness has never
113
- been set up here. Invoke `init` first; it opens with the two gauging questions (technical level +
114
- accompaniment dial). Do not start the user's task before first contact is done.
110
+ been set up here. Invoke `init` first; it opens with one question: technical terms or analogies.
111
+ Do not start the user's task before first contact is done.
115
112
  - The user declines a harness here ("sin harness", "solo código") → create an empty
116
113
  `.rsc/.no-harness`, confirm in one line, and never auto-start `init` in this repo again.
117
114
  - Once the profile exists, this gate is inert. Never re-onboard.
@@ -122,7 +119,4 @@ Define a term at first use; never give a command, flag or path without saying wh
122
119
 
123
120
  ## Orientación (siempre)
124
121
 
125
- Cierra cada turno con el **bloque-brújula** (📍 dónde estás · ✅ qué hiciste · 🧭 por qué · ➡️ siguiente,
126
- terminando en pregunta), calibrado al dial de `02-DOCS/wiki/harness/user-profile.md`. Nunca termines
127
- en seco. Protocolo completo: skill `orient` → `skills/orient/references/orientation-contract.md`.
128
- (Defiere a este mismo cuerpo, §2, el "¿instalo la skill que falta?".)
122
+ Habla con la voz de `orient`: frases cortas, una idea por frase, al grano, y cada respuesta se entiende sola. Registro técnico o con analogías según `technical_level` en `02-DOCS/wiki/harness/user-profile.md`. Cierra cada turno con el **bloque-brújula** (📍 dónde estás · ➡️ siguiente, terminando en pregunta; ✅ y 🧭 cuando hay algo hecho o decidido). **Nunca termines en seco.** Protocolo completo: skill `orient` → `skills/orient/references/orientation-contract.md`. (Defiere a §2 el "¿instalo la skill que falta?".)
@@ -59,7 +59,7 @@ capability:
59
59
  - "Checks what is already installed (npx @ericrisco/rsc list) and never proposes a skill the user already has"
60
60
  - "Makes at most one suggestion and does not interrupt the flow for nice-to-haves"
61
61
 
62
- - scenario: "Mid-conversation, after base install, the user says 'quiero montar una pagina web para vender cursos online'. `init`, `harness`, `orient`, `suggest`, and `bro` are already installed; `nextjs` is not. Show how rsc-suggest behaves."
62
+ - scenario: "Mid-conversation, after base install, the user says 'quiero montar una pagina web para vender cursos online'. `init`, `harness`, `orient`, `suggest`, and `unslop` are already installed; `nextjs` is not. Show how rsc-suggest behaves."
63
63
  must_include:
64
64
  - "Treats the message as in-agent capability intent, not as a CLI-only consult task"
65
65
  - "Runs `npx @ericrisco/rsc catalog --available` to see the not-installed skills (already excludes installed `init`/`harness`)"
@@ -33,12 +33,11 @@ announcement rules. Routing off or no profile → honor the session model silent
33
33
 
34
34
  ## Read the harness profile first
35
35
 
36
- Read `02-DOCS/wiki/harness/user-profile.md` before producing anything and match
37
- the accompaniment dial: **L0** emit the task table and nothing else; **L1** add
38
- one line of *why this slicing* above it; **L2** justify the ordering and the
39
- parallel markers as you go, flagging the risky tasks; **L3** walk each dependency
40
- and confirm the done-checks make sense to the user before writing. No profile →
41
- assume non-technical and let `init` gauge the level; never invent one.
36
+ Read `02-DOCS/wiki/harness/user-profile.md` before producing anything: its
37
+ `technical_level` sets the register (technical terms, or plain words with
38
+ analogies). The task table is always complete. In chat, speak in the `orient`
39
+ voice: one line of *why this slicing*, then flag the risky tasks. No profile →
40
+ use analogies and ask once "technical or with analogies?"; never invent one.
42
41
 
43
42
  ## Inputs (refuse to start without them)
44
43
 
@@ -263,4 +262,4 @@ was to let `analyze` audit it cheaply *before* code exists.
263
262
 
264
263
  ## Orientación (siempre)
265
264
 
266
- Cierra cada turno con el **bloque-brújula** (📍 dónde estás · ✅ qué hiciste · 🧭 por qué · ➡️ siguiente, terminando en pregunta), calibrado al dial de `02-DOCS/wiki/harness/user-profile.md`. **Nunca termines en seco.** Protocolo completo: skill `orient` → `skills/orient/references/orientation-contract.md`. (Defiere a `suggest` el "¿instalo la skill que falta?".)
265
+ Habla con la voz de `orient`: frases cortas, una idea por frase, y cada respuesta se entiende sola. Registro técnico o con analogías según `technical_level` en `02-DOCS/wiki/harness/user-profile.md`. Cierra cada turno con el **bloque-brújula** (📍 dónde estás · ➡️ siguiente, terminando en pregunta; ✅ y 🧭 cuando hay algo hecho o decidido). **Nunca termines en seco.** Protocolo completo: skill `orient` → `skills/orient/references/orientation-contract.md`. (Defiere a `suggest` el "¿instalo la skill que falta?".)
@@ -65,7 +65,7 @@ capability:
65
65
  - scenario: "An approved plan exists at 02-DOCS/wiki/sdd/plans/auth.md (login + sessions + a users migration, pytest as the testing strategy) and a spec at specs/auth.md. Break it into a task list."
66
66
  must_include:
67
67
  - "Confirms the inputs first: plan, spec, AND constitution must exist; if the plan were missing it would STOP and route to `plan` rather than slice from intent."
68
- - "Reads 02-DOCS/wiki/harness/user-profile.md for the accompaniment level and adapts verbosity (L0 table-only … L3 explain the slicing/dependencies)."
68
+ - "Reads technical_level from 02-DOCS/wiki/harness/user-profile.md and picks the register; the table is complete either way, and the chat adds only one line of why-this-slicing plus the risky tasks."
69
69
  - "Emits sequential zero-padded stable IDs (T001, T002… — no hyphen, GitHub Spec Kit canon) with the six well-formed fields: ID, a separate [P] marker field after the ID, imperative title, done-check, depends-on, and a trace to a spec section."
70
70
  - "Every done-check is a LITERAL runnable command or checkable observation (e.g. `pytest tests/auth/test_login.py` green; `alembic upgrade head` applies; bad password → 401) — never 'login works'."
71
71
  - "Orders by dependency (migration/schema → data → service → API), so no task precedes what it depends on; marks `[P]` only on file/state-disjoint tasks and defaults to sequential when unsure."
@@ -1,17 +1,44 @@
1
1
  ---
2
2
  name: unslop
3
- description: "Use when a written text must be audited against a named catalogue of AI tells before it ships: puffery, `not just X but Y`, the rule of three, em dashes, filler, hedging, abstract metaphor nouns. Names each hit and fixes it. NOT the register rewrite in the user's own voice (that is `bro`), NOT a reusable voice guide (that is `brand-voice`)."
4
- tags: [unslop, ai-tells, editing, audit, slop, publish-check, revisar-texto]
5
- recommends: [bro, brand-voice, technical-writing]
3
+ description: "Use when a text that leaves the session (email, post, README, message, landing copy) must sound like a person and carry no AI tells: rewrites it in the user's language fitted to the channel and relationship, and audits it against a named catalogue of tells (puffery, `not just X but Y`, rule of three, em dashes, filler, hedging). Fires on 'bro', 'hazlo más humano', 'que no suene a IA', 'más natural', 'unslop this'. NOT how the harness talks to the user (that is `orient`), NOT a reusable voice guide (that is `brand-voice`)."
4
+ tags: [unslop, human-writing, humano, natural-language, plain-language, ai-tells, editing, rewrite, bro, revisar-texto]
5
+ recommends: [brand-voice, technical-writing]
6
6
  profiles: [minimal, core, full]
7
7
  origin: risco
8
8
  ---
9
9
 
10
- # unslop: the named-tell audit a text passes before it ships
10
+ # unslop: text that leaves the session sounds like a person
11
11
 
12
- `bro` decides how a text should *sound*. This decides whether a text still carries the marks of a
13
- machine, tell by named tell, on the words that are actually there. Run it on anything about to leave
14
- the session: a README, a post, an email, a landing page, a commit body.
12
+ Two passes over a text someone else will read: the **register** (sound like a person, in this
13
+ language, for this relationship and channel) and the **named-tell audit** (no marks of a machine,
14
+ tell by tell). Run it on anything about to leave the session: a README, a post, an email, a landing
15
+ page, a commit body. How the harness talks to the user is `orient`, not this.
16
+
17
+ ## Find the source without ceremony
18
+
19
+ A bare "bro", "unslop", "write like a human", "hazlo más natural" points to the assistant's last
20
+ answer. If the user pasted text, work on that. If they asked for new copy, draft it directly. Ask for
21
+ text only when no source exists.
22
+
23
+ ## The register pass
24
+
25
+ 1. **Preserve the payload.** Names, facts, numbers, links, commitments, constraints, uncertainty and
26
+ necessary warnings stay. Never invent evidence, opinions, anecdotes or certainty to make it flow.
27
+ 2. **Match the room.** The user's language, fitted to audience, relationship and channel. A natural
28
+ legal notice is still precise; a natural Slack message can be loose. Human is not always casual.
29
+ 3. **Cut the bot-shaped scaffolding.** Throat-clearing, needless summaries, repeated conclusions,
30
+ corporate filler, fake enthusiasm, headings or bullets that do not help the reader navigate.
31
+ 4. **Restore a real cadence.** Concrete verbs, direct sentences, natural contractions. The words a
32
+ person in this context would choose, without manufactured slang, typos or choppy fragments.
33
+
34
+ | Aim | The result |
35
+ | --- | --- |
36
+ | Plain, not simplistic | Easy to follow without losing the idea |
37
+ | Concise, not incomplete | No padding; every load-bearing fact remains |
38
+ | Warm, not performative | Appropriate care without canned empathy |
39
+ | Specific, not decorated | Concrete nouns and verbs instead of hype |
40
+
41
+ When a text needs both passes: audit first, register last.
15
42
 
16
43
  ## The pass
17
44
 
@@ -96,6 +123,9 @@ Voiceless writing is as obvious as slopped writing. After the cuts, put somethin
96
123
  | Strip a term because it sounds technical | Precision lost to style is a defect | Keep the term, explain it once |
97
124
  | Touch code, commands, URLs, quotes or regulated wording | Those are not prose | Leave them byte for byte |
98
125
  | Claim the result will pass an AI detector | Nobody can promise that | Promise named tells removed, nothing more |
126
+ | Add typos, slang or filler to seem human | It performs humanity and sounds less credible | Match the actual relationship and channel |
127
+ | Use the same casual voice for every audience | A client email, a README and a condolence need different registers | Infer the room before choosing the cadence |
128
+ | Announce and justify every edit | The preamble is the friction the user asked to remove | Lead with the finished words |
99
129
  | Flatten a voice the author chose on purpose | Some authors do write long, warm or formal | Match the intended tone, cut only the machine marks |
100
130
 
101
131
  ## Output boundary
@@ -106,9 +136,8 @@ email or a document by accident.
106
136
 
107
137
  ## Where this ends
108
138
 
109
- - **`bro`** owns the register pass: make it sound like a person, in the user's language, fitted to the
110
- channel and the relationship. A bare "bro" after an answer is always `bro`. This skill is the named
111
- audit of a text that already exists, before it goes out.
139
+ - **`orient`** owns how the harness talks to the user: STE-style, short, every answer stands alone.
140
+ This skill is for text the user sends to someone else.
112
141
  - **`brand-voice`** owns the standing voice system across writers and channels.
113
142
  - **`technical-writing`** owns structure: what belongs in a tutorial, a reference, a README.
114
143
  - **`landing-copy`** owns conversion architecture. Clean its words only after it has chosen them.
@@ -1,18 +1,18 @@
1
1
  # Evals — unslop
2
2
 
3
- The claim under test is the boundary as much as the capability. `bro` sits directly next to this
4
- skill in the base install, and a description that blurs them costs every user two owners for one
5
- turn. Half the negatives here exist to prove the split holds.
3
+ The claim under test is the boundary as much as the capability. `unslop` absorbed the retired `bro`,
4
+ so it owns both the register pass and the audit of text that leaves the session. Its neighbour is
5
+ `orient`, which owns how the harness talks to the user. The negatives prove that split holds.
6
6
 
7
7
  ## Triggering
8
8
 
9
9
  Load only `unslop` and run every prompt in 3–5 fresh sessions. A positive passes when `unslop` loads
10
10
  in a majority of trials; a negative passes when it stays quiet and the declared `route_to` skill is
11
- the real owner. Require at least 90% accuracy, and treat any failure on the two `bro` negatives as
12
- blocking rather than statistical: those are the cases the split was designed for.
11
+ the real owner. Require at least 90% accuracy, and treat any failure on the `orient` negative or on
12
+ the two former `bro` positives as blocking rather than statistical.
13
13
 
14
- Run the mirror direction too. `bro`'s own suite carries a negative that routes here; both must pass
15
- in the same round, or the boundary only exists on one side.
14
+ Run the mirror direction too. `orient`'s own suite carries a negative that routes here; both must
15
+ pass in the same round, or the boundary only exists on one side.
16
16
 
17
17
  ## Capability
18
18
 
@@ -1,9 +1,8 @@
1
1
  skill: unslop
2
2
 
3
- # `unslop` is the named-tell audit of a text that already exists, run before it
4
- # ships. `bro` is the register pass: sound like a person, in the user's language,
5
- # fitted to the channel. A bare "bro" is always `bro`; "check this for AI tells
6
- # before I publish it" is always this skill.
3
+ # `unslop` owns text that leaves the session: the register pass (sound like a person,
4
+ # in the user's language, fitted to the channel) and the named-tell audit before it
5
+ # ships. It absorbed the retired `bro`. How the harness talks to the user is `orient`.
7
6
  should_trigger:
8
7
  - prompt: "Revisa este README antes de publicarlo y quítale todo lo que huela a IA."
9
8
  why: "A pre-publication audit of an existing text is the exact contract, in the user's own words."
@@ -23,14 +22,16 @@ should_trigger:
23
22
  - prompt: "Before this goes to the client, strip the puffery and the hedging but keep every number exact."
24
23
  why: "A ship gate over existing prose with a preserve-the-facts constraint."
25
24
 
26
- should_not_trigger:
27
25
  - prompt: "Bro."
28
- route_to: "bro"
29
- why: "A bare bro after an answer is the register pass over the last message, not an audit of a supplied text."
26
+ why: "A bare bro after an answer is the register pass over the last message (the retired bro skill lives here now)."
30
27
 
31
28
  - prompt: "Haz que este correo suene más cercano y menos formal para un cliente de confianza."
32
- route_to: "bro"
33
- why: "Choosing a warmer register for a specific relationship is bro's job; no tell is being audited."
29
+ why: "Choosing a warmer register for a specific relationship and channel is the register pass."
30
+
31
+ should_not_trigger:
32
+ - prompt: "No entiendo lo que me acabas de explicar, hazlo más simple."
33
+ route_to: "orient"
34
+ why: "How the harness explains things to the user is orient's voice and ladder, not a text for others."
34
35
 
35
36
  - prompt: "Define how our company should sound across the blog, support replies and job ads."
36
37
  route_to: "brand-voice"
@@ -19,16 +19,13 @@ Not this phase: still writing tests or production code → `../implement/SKILL.m
19
19
 
20
20
  ## Model tier — `balanced` (opt-in routing)
21
21
 
22
- This phase's default model tier is **`balanced`** — it runs the checks and interprets failures with judgment. Routing is **off** unless `models.enabled: true` in `02-DOCS/wiki/sdd/config.yaml`. When on: resolve this phase's tier (`models.overrides` wins over `models.phases`), map it to a model via `models.tiers`, and apply per `../sdd/references/model-routing.md` — announce the switch per the accompaniment dial when it differs from the session model, and dispatch any `Task`/`parallel` subagents on that model. Routing off or no profile → honor the session model silently. Never fake a switch a tool can't make; skip routing on a one-line change.
22
+ This phase's default model tier is **`balanced`** — it runs the checks and interprets failures with judgment. Routing is **off** unless `models.enabled: true` in `02-DOCS/wiki/sdd/config.yaml`. When on: resolve this phase's tier (`models.overrides` wins over `models.phases`), map it to a model via `models.tiers`, and apply per `../sdd/references/model-routing.md` — announce the switch in one line when it differs from the session model, and dispatch any `Task`/`parallel` subagents on that model. Routing off or no profile → honor the session model silently. Never fake a switch a tool can't make; skip routing on a one-line change.
23
23
 
24
- ## Read the room first (accompaniment dial)
24
+ ## Read the room first (register)
25
25
 
26
- Before running anything, read `02-DOCS/wiki/harness/user-profile.md` for the technical + accompaniment level; no profile yet → default to non-technical framing. The verdict itself (pass / fail per item) never changes with the dial — only how much you explain around it.
26
+ Before running anything, read `technical_level` in `02-DOCS/wiki/harness/user-profile.md`; no profile yet → use analogies. The verdict itself (pass / fail per item) never changes with the register — only the words around it.
27
27
 
28
- - **L0** — run the gate, show pass/fail and the one-line failing summary. Minimal words.
29
- - **L1** — add one line of *why* per failing check.
30
- - **L2** — narrate each gate (what lint/type/test/audit checks and why it matters here).
31
- - **L3** — explain every result, what each acceptance criterion means in plain language, and what the user should decide next.
28
+ Report in the `orient` voice: pass/fail per gate, then one line of *why* per failing check, then what the user should decide next. For a `non-technical` reader, say what each failing check protects with an everyday analogy.
32
29
 
33
30
  ## The gate (run in this order)
34
31
 
@@ -229,5 +226,5 @@ A **PASS** record is the entry ticket to the next phase: **`../review/SKILL.md`*
229
226
 
230
227
  ## Orientación (siempre)
231
228
 
232
- Cierra cada turno con el **bloque-brújula** (📍 dónde estás · ✅ qué hiciste · 🧭 por qué · ➡️ siguiente, terminando en pregunta), calibrado al dial de `02-DOCS/wiki/harness/user-profile.md`. **Nunca termines en seco.** Protocolo completo: skill `orient` → `skills/orient/references/orientation-contract.md`. (Defiere a `suggest` el "¿instalo la skill que falta?".)
229
+ Habla con la voz de `orient`: frases cortas, una idea por frase, y cada respuesta se entiende sola. Registro técnico o con analogías según `technical_level` en `02-DOCS/wiki/harness/user-profile.md`. Cierra cada turno con el **bloque-brújula** (📍 dónde estás · ➡️ siguiente, terminando en pregunta; ✅ y 🧭 cuando hay algo hecho o decidido). **Nunca termines en seco.** Protocolo completo: skill `orient` → `skills/orient/references/orientation-contract.md`. (Defiere a `suggest` el "¿instalo la skill que falta?".)
233
230
 
@@ -88,7 +88,7 @@ capability:
88
88
  - "The retry loop can spin forever" was raised in review; the implementer replied
89
89
  "not a real problem".
90
90
  must_include:
91
- - "Reads the accompaniment level from 02-DOCS/wiki/harness/user-profile.md and adapts verbosity (verdict legibility unchanged by the dial)."
91
+ - "Reads technical_level from 02-DOCS/wiki/harness/user-profile.md and picks the register (verdict unchanged by it); reports short, with one line of why per failing check."
92
92
  - "LOCATES the three acceptance criteria and the three task done-checks from the material given, and maps each to what the implementer actually reports."
93
93
  - "Refuses to accept the implementer's summary as the gate: says the checks must be re-run and the output read, rather than trusting a reported '2 passed'."
94
94
  - "Treats the mypy SKIP as UNVERIFIED rather than a pass, and does not let 'everything else was green' stand in for the skipped layer."
@@ -53,10 +53,10 @@ extra directory. The rest of this skill assumes a worktree; the branch path is t
53
53
 
54
54
  Run this in order. Each check prevents a class of "lost work" you can't easily undo.
55
55
 
56
- 1. **Read the accompaniment dial** — `02-DOCS/wiki/harness/user-profile.md` gives the technical +
57
- accompaniment level (L0..L3); set your volume from the table below. No profile yet → assume
58
- non-technical, explain what a worktree is in one plain sentence before making one. No `02-DOCS/` at all (a worktree can be created in any git repo
59
- with no rsc harness present) → skip the dial, assume non-technical, and proceed.
56
+ 1. **Read the register** — `technical_level` in `02-DOCS/wiki/harness/user-profile.md` picks
57
+ technical terms or plain words with analogies (see "Talking about it" below). No profile yet, or
58
+ no `02-DOCS/` at all (a worktree can be created in any git repo with no rsc harness present) →
59
+ use analogies: explain what a worktree is in one plain sentence before making one, and proceed.
60
60
  2. **Confirm you're in a git repo.** `git rev-parse --is-inside-work-tree`. If not, there's nothing
61
61
  to isolate with git — tell the user; don't fabricate a worktree.
62
62
  3. **Check the current branch.** `git rev-parse --abbrev-ref HEAD`. On `main`/`master` with work
@@ -130,8 +130,8 @@ npx @ericrisco/rsc worktrees reap
130
130
  ```
131
131
 
132
132
  Either way, the contract is identical: **after this step, the cwd is an isolated branch off a clean
133
- base, and the default-branch checkout is exactly as it was.** Confirm that out loud (at the dial's
134
- level) before handing to `implement`.
133
+ base, and the default-branch checkout is exactly as it was.** Confirm that out loud, in
134
+ one line, before handing to `implement`.
135
135
 
136
136
  ### Cleanup is the default, and it is not yours to judge
137
137
 
@@ -169,21 +169,17 @@ a linked worktree (`git rev-parse --git-dir` ≠ `--git-common-dir`), rule out a
169
169
 
170
170
  ## Model tier — `light` (opt-in routing)
171
171
 
172
- This phase's default model tier is **`light`** — isolating the workspace is mechanical git work. Routing is **off** unless `models.enabled: true` in `02-DOCS/wiki/sdd/config.yaml`. When on: resolve this phase's tier (`models.overrides` wins over `models.phases`), map it to a model via `models.tiers`, and apply per `../sdd/references/model-routing.md` — announce the switch per the accompaniment dial when it differs from the session model, and dispatch any `Task`/`parallel` subagents on that model. Routing off or no profile → honor the session model silently. Never fake a switch a tool can't make; skip routing on a one-line change.
172
+ This phase's default model tier is **`light`** — isolating the workspace is mechanical git work. Routing is **off** unless `models.enabled: true` in `02-DOCS/wiki/sdd/config.yaml`. When on: resolve this phase's tier (`models.overrides` wins over `models.phases`), map it to a model via `models.tiers`, and apply per `../sdd/references/model-routing.md` — announce the switch in one line when it differs from the session model, and dispatch any `Task`/`parallel` subagents on that model. Routing off or no profile → honor the session model silently. Never fake a switch a tool can't make; skip routing on a one-line change.
173
173
 
174
- ## Adapting to the dial
174
+ ## Talking about it
175
175
 
176
- The isolation is identical at every level; only the talking changes.
176
+ The isolation is identical for every reader; only the words change. In the `orient` voice: state
177
+ the branch/dir in one line, add one line of *why* a worktree over a branch (or vice-versa) for this
178
+ case, and confirm the base ref. For a `non-technical` reader, say what a worktree is with an
179
+ everyday analogy (a second copy of the desk, so the first one stays as it was).
177
180
 
178
- | Level | How `worktrees` behaves |
179
- | --- | --- |
180
- | **L0** | Create the isolated workspace, state the branch/dir in one line, hand to `implement`. No explanation. |
181
- | **L1** | Same, plus one line of *why* a worktree over a branch (or vice-versa) for this case. |
182
- | **L2** | Justify the base-ref choice and the branch-vs-worktree call; surface the dirty-tree decision explicitly. |
183
- | **L3** | Explain in plain language what a worktree is and why isolation protects their work; ask before touching any uncommitted changes; confirm the base ref. |
184
-
185
- At every level, a **dirty tree with the user's uncommitted work is a hard stop for a confirmation** —
186
- the dial controls verbosity, never whether you check before risking someone's WIP.
181
+ A **dirty tree with the user's uncommitted work is always a hard stop for a confirmation** — no
182
+ wish for brevity removes the check before risking someone's WIP.
187
183
 
188
184
  ## Anti-patterns → STOP
189
185
 
@@ -37,7 +37,7 @@ capability:
37
37
  - scenario: "User says: 'I'm on main with a clean tree, the plan for the order-reservation feature (slug: order-reservation) is approved, and I'm about to implement it. My editor and a dev server are open against the current files. Set up isolation.' The agent has the worktrees skill loaded and a native worktree tool available."
38
38
  must_include:
39
39
  - "Runs the pre-flight gate: confirms it's a git repo, checks current branch (main), and checks `git status --short` for tree state before creating anything"
40
- - "Reads 02-DOCS/wiki/harness/user-profile.md for the accompaniment dial and matches narration to the level"
40
+ - "Reads technical_level from 02-DOCS/wiki/harness/user-profile.md and narrates briefly in that register (branch/dir in one line plus one line of why)"
41
41
  - "Chooses a WORKTREE over a plain branch and justifies it by the live dev server / open editor on the current files (a branch switch would yank files from the running process)"
42
42
  - "Prefers the native worktree tool (EnterWorktree-style) for creation and session-switch, naming it for the slug (feat/order-reservation); states the git `git worktree add -b feat/order-reservation … origin/<default>` fallback if no native tool exists"
43
43
  - "Branches from an up-to-date default base (fresh origin/<default>) rather than stale local HEAD, or asks which the user wants"
@@ -13,6 +13,12 @@ const MARK_END = '<!-- rsc-suggest:end -->';
13
13
  // The exact separator wireHook writes before an appended block, so unwireHook can take
14
14
  // back precisely what it gave and leave the rest of the file untouched.
15
15
  const SEAM = '\n\n';
16
+ // Most assistants that read a rules file have no session-start hook, so nothing checks for a new rsc
17
+ // on its own. The agent does it instead. Here and not in suggest's body: the body is paid on every
18
+ // turn by every assistant, Claude Code included, which already checks from its hook.
19
+ export const UPDATE_NOTE = '**rsc updates.** Claude Code, Codex, Gemini CLI, Cursor and OpenCode check for a new rsc on their '
20
+ + 'own. In any other assistant, run `node .rsc/auto-update.mjs` once on the first turn of a session and relay any '
21
+ + 'notice it prints in one line; "up to date" needs no mention.\n';
16
22
 
17
23
  export function writeSkill(id, fromDir, toPath) {
18
24
  return linkOrCopy(fromDir, toPath);
@@ -23,7 +29,7 @@ export function wireHook(paths, sourceMd, policy = {}) {
23
29
  const body = policy.codeHooks === false
24
30
  ? `# rsc-suggest — always-on operations layer\n\nRead \`02-DOCS/wiki/harness/user-profile.md\` before acting. Use \`orient\` to keep the user situated and \`suggest\` to offer a missing skill only when the current task needs it. Close with the configured orientation block.\n`
25
31
  : full;
26
- const block = `${MARK_START}\n${body}\n${MARK_END}`;
32
+ const block = `${MARK_START}\n${body}\n${UPDATE_NOTE}\n${MARK_END}`;
27
33
  let doc = existsSync(paths.hookTarget) ? readFileSync(paths.hookTarget, 'utf8') : '';
28
34
  if (doc.includes(MARK_START)) {
29
35
  doc = doc.replace(new RegExp(`${MARK_START}[\\s\\S]*?${MARK_END}`), block);