@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.
- package/README.md +63 -21
- package/manifest.json +18 -85
- package/package.json +5 -1
- package/scripts/consult.js +8 -8
- package/scripts/install-apply.js +48 -11
- package/scripts/lib/default-skill-floor.js +5 -4
- package/scripts/lib/divergence.js +7 -3
- package/scripts/lib/domains.js +2 -2
- package/scripts/lib/onboarding-apply.js +43 -26
- package/scripts/lib/onboarding.js +5 -5
- package/scripts/lib/recommend.js +1 -1
- package/scripts/lib/repair.js +4 -2
- package/scripts/lib/retired-skills.js +20 -0
- package/scripts/rsc.js +25 -19
- package/scripts/skill-behavior-rubric.md +1 -1
- package/scripts/skill-migration-brief.md +3 -3
- package/skills/analyze/SKILL.md +3 -8
- package/skills/analyze/evals/cases.yaml +1 -1
- package/skills/author-skill/SKILL.md +3 -3
- package/skills/author-skill/evals/cases.yaml +1 -1
- package/skills/author-skill/references/rsc-conventions.md +1 -1
- package/skills/clarify/SKILL.md +7 -14
- package/skills/clarify/evals/cases.yaml +2 -2
- package/skills/code-review/SKILL.md +1 -1
- package/skills/constitution/SKILL.md +10 -13
- package/skills/constitution/evals/cases.yaml +3 -3
- package/skills/continuous-learning/SKILL.md +1 -1
- package/skills/continuous-learning/evals/cases.yaml +1 -1
- package/skills/debug/SKILL.md +8 -12
- package/skills/debug/evals/cases.yaml +1 -1
- package/skills/decision-challenge/SKILL.md +1 -1
- package/skills/deprecation/SKILL.md +1 -1
- package/skills/ftd/SKILL.md +1 -3
- package/skills/ftd/evals/cases.yaml +1 -1
- package/skills/harness/SKILL.md +10 -9
- package/skills/harness/references/claude-md-template.md +1 -1
- package/skills/harness/references/wiki-protocol.md +5 -6
- package/skills/idea-refinement/SKILL.md +1 -1
- package/skills/implement/SKILL.md +14 -18
- package/skills/implement/evals/cases.yaml +1 -1
- package/skills/init/SKILL.md +36 -45
- package/skills/init/evals/README.md +3 -3
- package/skills/init/evals/cases.yaml +7 -7
- package/skills/init/references/accompaniment-and-profile.md +22 -40
- package/skills/init/references/discovery.md +2 -2
- package/skills/init/references/recommend-skills.md +5 -5
- package/skills/init/scripts/verify.sh +3 -7
- package/skills/knowledge-ops/SKILL.md +1 -1
- package/skills/orient/SKILL.md +52 -41
- package/skills/orient/evals/README.md +11 -9
- package/skills/orient/evals/cases.yaml +39 -29
- package/skills/orient/references/explain-ladder.md +93 -0
- package/skills/orient/references/orientation-contract.md +70 -18
- package/skills/parallel/SKILL.md +1 -1
- package/skills/parallel/evals/cases.yaml +2 -2
- package/skills/plan/SKILL.md +9 -13
- package/skills/review/SKILL.md +5 -8
- package/skills/roast-me/SKILL.md +1 -1
- package/skills/sdd/SKILL.md +10 -14
- package/skills/sdd/evals/README.md +2 -2
- package/skills/sdd/evals/cases.yaml +4 -4
- package/skills/sdd/references/model-routing.md +5 -12
- package/skills/sdd-init/SKILL.md +3 -3
- package/skills/ship/SKILL.md +6 -11
- package/skills/simplify-code/SKILL.md +1 -1
- package/skills/skill-scout/SKILL.md +1 -1
- package/skills/source-grounded-development/SKILL.md +1 -1
- package/skills/specify/SKILL.md +13 -14
- package/skills/specify/evals/cases.yaml +1 -1
- package/skills/specify/references/eliciting-requirements.md +5 -5
- package/skills/suggest/SKILL.md +3 -9
- package/skills/suggest/evals/cases.yaml +1 -1
- package/skills/tasks/SKILL.md +6 -7
- package/skills/tasks/evals/cases.yaml +1 -1
- package/skills/unslop/SKILL.md +39 -10
- package/skills/unslop/evals/README.md +7 -7
- package/skills/unslop/evals/cases.yaml +10 -9
- package/skills/verify/SKILL.md +5 -8
- package/skills/verify/evals/cases.yaml +1 -1
- package/skills/worktrees/SKILL.md +14 -18
- package/skills/worktrees/evals/cases.yaml +1 -1
- package/targets/_md-block.js +7 -1
- package/targets/auto-update.mjs +200 -0
- package/targets/claude.js +2 -0
- package/targets/clone-bootstrap.mjs +5 -2
- package/targets/opt-outs.js +1 -0
- package/targets/session-start.mjs +5 -78
- package/targets/update-wiring.js +153 -0
- package/skills/bro/SKILL.md +0 -76
- package/skills/bro/evals/README.md +0 -22
- package/skills/bro/evals/cases.yaml +0 -62
- package/skills/eli5/SKILL.md +0 -63
- package/skills/eli5/evals/README.md +0 -22
- package/skills/eli5/evals/cases.yaml +0 -54
- package/skills/show-me/SKILL.md +0 -140
- package/skills/show-me/evals/README.md +0 -23
- package/skills/show-me/evals/cases.yaml +0 -61
package/skills/specify/SKILL.md
CHANGED
|
@@ -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
|
|
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 (
|
|
57
|
+
## Read the room first (register)
|
|
58
58
|
|
|
59
|
-
Before asking anything, read `02-DOCS/wiki/harness/user-profile.md
|
|
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
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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**
|
|
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 +
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
88
|
-
|
|
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
|
|
package/skills/suggest/SKILL.md
CHANGED
|
@@ -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
|
|
114
|
-
|
|
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 ·
|
|
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 `
|
|
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`)"
|
package/skills/tasks/SKILL.md
CHANGED
|
@@ -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
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
and
|
|
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
|
-
|
|
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
|
|
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."
|
package/skills/unslop/SKILL.md
CHANGED
|
@@ -1,17 +1,44 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: unslop
|
|
3
|
-
description: "Use when a
|
|
4
|
-
tags: [unslop, ai-tells, editing,
|
|
5
|
-
recommends: [
|
|
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:
|
|
10
|
+
# unslop: text that leaves the session sounds like a person
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
the session: a README, a post, an email, a landing
|
|
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
|
-
- **`
|
|
110
|
-
|
|
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. `
|
|
4
|
-
|
|
5
|
-
|
|
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
|
|
12
|
-
|
|
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. `
|
|
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`
|
|
4
|
-
#
|
|
5
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
33
|
-
|
|
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"
|
package/skills/verify/SKILL.md
CHANGED
|
@@ -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
|
|
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 (
|
|
24
|
+
## Read the room first (register)
|
|
25
25
|
|
|
26
|
-
Before running anything, read `02-DOCS/wiki/harness/user-profile.md
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
|
134
|
-
|
|
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
|
|
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
|
-
##
|
|
174
|
+
## Talking about it
|
|
175
175
|
|
|
176
|
-
The isolation is identical
|
|
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
|
-
|
|
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
|
|
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"
|
package/targets/_md-block.js
CHANGED
|
@@ -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);
|