@ericrisco/rsc 3.0.17 → 3.0.18

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 (3) hide show
  1. package/README.md +356 -692
  2. package/manifest.json +1 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  <div align="center">
2
2
 
3
- <img src="https://raw.githubusercontent.com/ericrisco/rsc-harness/main/site/og.png" alt="rsc-harness — You decide what to build. rsc-harness builds your agent’s harness, following strict best practices instead of improvising a Frankenstein stack." width="960">
3
+ <img src="https://raw.githubusercontent.com/ericrisco/rsc-harness/main/site/og.png" alt="rsc-harness: you build the product, rsc-harness builds your agent's harness, following strict best practices instead of improvising one." width="960">
4
4
 
5
- # `rsc-harness` — You decide what to build. It builds your agent's harness.
5
+ # `rsc-harness`
6
+
7
+ **You build the product. rsc-harness builds its harness.**
6
8
 
7
9
  [![npm](https://img.shields.io/npm/v/@ericrisco/rsc?color=63d68a&labelColor=12161c&label=npm)](https://www.npmjs.com/package/@ericrisco/rsc)
8
10
  [![downloads](https://img.shields.io/npm/dm/@ericrisco/rsc?color=63d68a&labelColor=12161c&label=downloads)](https://www.npmjs.com/package/@ericrisco/rsc)
@@ -10,11 +12,11 @@
10
12
  [![license](https://img.shields.io/badge/license-MIT-63d68a?labelColor=12161c)](LICENSE)
11
13
  [![stars](https://img.shields.io/github/stars/ericrisco/rsc-harness?color=63d68a&labelColor=12161c)](https://github.com/ericrisco/rsc-harness/stargazers)
12
14
 
13
- **You decide what to build. rsc-harness builds your agent’s harness.** Tell it whether you are
14
- shipping software, running operations, researching, creating content, or mixing them. Its wizard
15
- reads the project, applies strict best practices, and shows the exact harness plan before writing.
15
+ Every time you open a project, your agent starts from zero. rsc is a meta-harness: it gives the
16
+ assistant you already use (Claude Code, Codex, Cursor and 15 more) a memory, hands, a trade and
17
+ reflexes, so it stops starting over.
16
18
 
17
- Give this URL to your agent:
19
+ Give this URL to your agent and paste the request in the chat:
18
20
 
19
21
  ```text
20
22
  Read https://ericrisco.github.io/rsc-harness/ and set up rsc for this project.
@@ -27,167 +29,131 @@ Or start from the terminal:
27
29
  npx @ericrisco/rsc@latest onboard
28
30
  ```
29
31
 
30
- <img src="https://raw.githubusercontent.com/ericrisco/rsc-harness/main/site/meta-harness.png" alt="rsc-harness wizard turns an outcome into a verified plan: memory, tools, knowledge and rules selected, deferred or excluded according to evidence." width="960">
31
-
32
32
  </div>
33
33
 
34
- ## 🐋 New: DeepSeek Harness
34
+ ---
35
35
 
36
- [DeepSeek Harness](https://www.npmjs.com/package/@deepseek-ai/dsh) (`dsh`) is now a supported
37
- assistant, the 18th. Pick it in the wizard or pass `--target deepseek`:
36
+ ## The problem
38
37
 
39
- ```bash
40
- npx @ericrisco/rsc@latest onboard --target deepseek
41
- ```
38
+ - **You explain everything again.** Every new session, every new project: the stack, the
39
+ conventions, what was decided, what must not be touched.
40
+ - **What the agent does not know, it invents.** And the guess looks plausible, which is worse than
41
+ an obvious error.
42
+ - **Decisions die with the chat.** What you settled yesterday is gone the moment the window closes.
42
43
 
43
- - **Skills** go to `.dsh/skills/`, where dsh finds them on its own.
44
- - **Instructions** go in the rsc block of `AGENTS.md`, which dsh already reads.
45
- - **Session memory, knowledge sync and the update notice** run from dsh's own hooks. dsh has no
46
- hooks per project, so rsc adds one marked block to `~/.dsh/cordis.patch.yml` once per machine. That
47
- block runs the hooks of whichever project the session is in. It works in `dsh web` with several
48
- projects open, and in a project without rsc it does nothing. Restart dsh once after the first
49
- install. To turn it off, delete the block.
44
+ The most important thing an agent needs is documentation, and nobody keeps it for the agent.
50
45
 
51
- Details: [targets table](#multi-target).
46
+ When people fix this by hand, the result is a **Frankenstein harness**: duplicated instructions,
47
+ unrelated skills, premature hooks, unnecessary MCPs and no clear owner. Open standards cover single
48
+ parts ([Agent Skills](https://agentskills.io/specification), [MCP](https://modelcontextprotocol.io/),
49
+ [AGENTS.md](https://agents.md/)), but none of them decides which complete harness your project needs.
52
50
 
53
51
  ---
54
52
 
55
- ## Your agent needs a harness. It should not improvise one.
53
+ ## The idea: documentation is your agent's memory
56
54
 
57
- A model is only the brain. Real work also needs project memory, tools, domain knowledge, rules and
58
- repeatable workflows. Add those pieces ad hoc and the result becomes a **Frankenstein harness**:
59
- duplicated instructions, unrelated skills, premature hooks, unnecessary MCPs and no clear owner.
55
+ <img src="https://raw.githubusercontent.com/ericrisco/rsc-harness/main/site/meta-harness.png" alt="rsc-harness turns an outcome into a verified plan: memory, tools, knowledge and rules selected, deferred or excluded according to evidence." width="960">
60
56
 
61
- Open standards already cover individual parts — [Agent Skills](https://agentskills.io/specification),
62
- [MCP](https://modelcontextprotocol.io/) and [AGENTS.md](https://agents.md/) — but they do not decide
63
- which complete harness this project needs. rsc-harness does that job through one guided flow:
57
+ The model is the brain your agent rents, and you already have it. rsc adds the rest, in four pieces:
64
58
 
65
- 1. **You state the outcome.** No skill, hook or MCP vocabulary required.
66
- 2. **The wizard reads only the project root** and asks how technical to talk, project kind, goal and
67
- assistants.
68
- 3. **A proportional plan explains every choice.** Selected, deferred and excluded pieces all have a
69
- reason. Nothing writes before you accept the exact plan.
70
- 4. **The result is verified.** Shared sources prevent duplication; knowledge loads progressively;
71
- local state stays local; deterministic checks prove the installed harness matches the plan.
72
- 5. **It grows from evidence.** A deferred capability is proposed later only when the project actually
73
- develops the need for it.
59
+ | Piece | Where it lives | What it does |
60
+ | --- | --- | --- |
61
+ | **Memory** | `02-DOCS/` | A wiki the agent reads before it works and keeps up to date while it works. |
62
+ | **Hands** | `01-TOOLS/` | One folder per tool, with a test that proves the connection works. |
63
+ | **Trade** | skills | Only the skills your project needs: 271 available, a handful installed. |
64
+ | **Reflexes** | hooks | Rules that hold even when the agent forgets them mid-session. |
74
65
 
75
- That is what “best practices” means here: a small, separated, project-bound and auditable harness —
76
- not a pile of whatever an agent happened to install.
66
+ ### Why documentation comes first
77
67
 
78
- ---
68
+ An agent without documentation spends most of its effort searching. It opens files, greps, reads the
69
+ same module twice, and still ends up guessing. Every one of those turns costs tokens, and the guess
70
+ costs more later.
79
71
 
80
- ## 🛡️ New in 3.0: safe for teams by default
72
+ With a well-structured `02-DOCS/`, the agent knows where to look. It finds what it needs in one read
73
+ instead of ten, so the same task costs fewer tokens.
81
74
 
82
- Day one with agents is easy. Day ninety is where harnesses break, especially with several people,
83
- several assistants and several sessions on one project:
75
+ And because it finds what already exists, it builds on it:
84
76
 
85
- - every machine drifts, and what one person teaches their agent never reaches anyone else;
86
- - two agents end up working in the same folder and switch branches under each other;
87
- - someone's agent commits straight to `main` on a project in production;
88
- - every request gets the same process, whether it is a typo or a new subsystem.
77
+ - It reuses the function you already have instead of writing a second one.
78
+ - It follows the structure your project already uses, every time.
79
+ - It works from what is true about your code, not from a plausible guess, so less of what it writes
80
+ breaks.
89
81
 
90
- rsc 3.0 fixes all four, by default, with no new commands to learn:
82
+ Good documentation is not overhead for your agent. It is what makes it cheaper and better at the
83
+ same time.
91
84
 
92
- | | What happens | Turn it off |
93
- | --- | --- | --- |
94
- | **You choose how the project works** | The install asks once: straight on `main`, or branches and pull requests? Branches are recommended only for long-lived, complex code. With `main` the agent works on it and never asks about branches. With branches a commit on `main` is refused, and before each code change the agent asks: this branch, a new one, or unlock `main`? It never opens a branch on its own. | Say **«unlock main»** / **«lock main»**, or `rsc main unlock` / `lock` |
95
- | **One workspace per agent** | If another assistant session is working in the same folder, new work goes to a worktree under `.worktrees/<branch>/`. It stays inside the project, is never committed, and is removed once that branch is merged. | `rsc isolation off` |
96
- | **The agent picks the method** | A simple change takes Fast-Track (one document, proof for every task). Something big or complex takes the spec-driven chain. The agent decides and says why. You still approve *what* gets built: the spec and the clarifications, then step by step or autopilot. | Ask for the other lane |
97
- | **Knowledge reaches everyone** | `01-TOOLS/`, `02-DOCS/wiki/` and `02-DOCS/attachments/` travel through one exchange branch, `rsc/knowledge`. They go up when your turn ends and come down into whatever branch each person is on. They reach `main` inside your normal pull requests. | `rsc knowledge-sync off` |
98
-
99
- **Commit, push and pull request without a prompt each time.** A harness installed from scratch lets
100
- the agent run `git commit`, `git push` and `gh pr create` without asking, because those are the steps
101
- that close every lane. A force-push still asks. In Claude Code, rsc's guards still decide: a commit on a
102
- closed `main` is refused whatever the permission says. No other assistant runs those guards. It is a project decision, saved as `gitPermissions` in
103
- `.rsc.json`. A clone gets the same setting. A project adopted before this is left as it was until
104
- someone runs `rsc git-permissions on`.
85
+ ---
105
86
 
106
- | Assistant | Where it goes |
107
- | --- | --- |
108
- | Claude Code | `.claude/settings.json` → `permissions.allow` (force-push under `ask`). Claude Code applies it once the folder is trusted. |
109
- | Codex | `.codex/rules/rsc-git.rules` (`prefix_rule`; force-push → `prompt`). Loaded when the project is trusted. |
110
- | Gemini | `.gemini/settings.json` → `tools.allowed` |
111
- | OpenCode | `opencode.json`. With OpenCode 2 installed: the top-level `permissions` list (`shell` rules; force-push → `ask`). rsc's rules go before yours, so any rule of yours that matches later still wins; only a leading `"*"` allow/ask default stays in front. With OpenCode 1.x, or when `opencode --version` cannot be read: `permission.bash`, which both versions read. Moving to 2 moves rsc's entries over. An `opencode.jsonc` is read but never rewritten (its comments would be lost): rsc prints the rules to paste. |
112
- | Cursor | Not covered: its CLI matches only the first word, so allowing a push would allow every git command. |
113
- | DeepSeek Harness | Not covered: dsh has no per-command allow list. Its own Permissions selector (`/permission`) sets approval for every command at once. |
87
+ ## A day with rsc
114
88
 
115
- ```bash
116
- rsc git-permissions status # per assistant: wired or not, and in which format (--json for scripts)
117
- rsc git-permissions off # remove rsc's rules (saved in .rsc.json)
118
- rsc git-permissions on # turn it on, also for a project adopted before
119
- ```
89
+ <img src="https://raw.githubusercontent.com/ericrisco/rsc-harness/main/site/lanes.svg" alt="The rsc lane decisor: the agent classifies each request into answer (read-only), FTD (simple change, one feature document) or SDD (the ten-phase chain for big or complex work, entered by the agent; you approve the spec)." width="960">
120
90
 
121
- **What `off` turns off.** Only rsc's allow rules. Each command says, per assistant, what rsc controls
122
- there, what stops when it is off, and what is left to the assistant. `off` does not hand rsc's
123
- protections to the assistant. Claude Code keeps rsc's guards (branch-guard, danger-guard), because
124
- they do not depend on this switch. OpenCode, Codex and Gemini run no rsc guard. There, your own
125
- settings decide. With no rule matching, OpenCode 2 asks and OpenCode 1.x runs the command. To refuse a
126
- force-push in OpenCode 2, add this at the end of `permissions` (use `"ask"` to get a human approval):
127
-
128
- ```json
129
- { "action": "shell", "resource": "git push --force*", "effect": "deny" },
130
- { "action": "shell", "resource": "git push -f*", "effect": "deny" },
131
- { "action": "shell", "resource": "git push * --force*", "effect": "deny" },
132
- { "action": "shell", "resource": "git push * -f*", "effect": "deny" }
133
- ```
91
+ 1. **You install it.** It asks a few questions in plain language: how technical to talk, what the
92
+ project is for, its goal, and which assistants you use. It reads only the project root.
93
+ 2. **It shows the plan before it writes anything.** Every piece is selected, deferred or excluded,
94
+ each with its reason. Nothing is written until you accept that exact plan.
95
+ 3. **You ask for things.** The agent decides how much process each request needs, and says so in one
96
+ line: an answer, a quick change (FTD), or the full chain (SDD).
97
+ 4. **It documents as it goes.** Decisions, connections and progress land in `02-DOCS/`, not in the
98
+ chat.
99
+ 5. **Tomorrow, the agent already knows.** You, a teammate on another machine, or another assistant
100
+ open the project and continue where the last session stopped.
134
101
 
135
- In OpenCode 1.x the same patterns go at the end of `permission.bash` (`"git push --force*": "deny"`, …).
102
+ ---
136
103
 
137
- **How does it know a project is "complex or in production"?** There are two layers. A hook counts
138
- what anyone can check: a CI setup, a deployment file (`Dockerfile`, `vercel.json`, `fly.toml`…) or
139
- at least two people in the last 50 commits. If any of those is there, a commit on the default branch
140
- is refused before it runs, and the agent asks you whether to open a branch or unlock it. If none is,
141
- `main` is open and the agent simply works on it. **The answer you gave at install always wins over
142
- this detection**; it only decides for projects installed before the question existed. If the hook gets it wrong and the project really is simple, «unlock main» opens it for
143
- the project. That decision is saved in `.rsc.json`, so the whole team gets it.
104
+ ## What changes for you
144
105
 
145
- Every refusal says how to carry on, and the choice between a branch and unlocking goes back to you.
146
- An agent is never left stuck. The rules only see what the **agent** runs; a person
147
- committing in their own terminal is never touched.
106
+ - **You never explain your project again.** The knowledge lives in the repo, not in your head.
107
+ - **Fewer tokens, more consistent code.** The agent finds instead of searching (see
108
+ [why documentation comes first](#why-documentation-comes-first)).
109
+ - **The right amount of process.** A typo gets fixed; a new subsystem gets a spec. The agent picks.
110
+ - **Safe for teams by default.** Shared knowledge, one workspace per agent, and no surprise commits
111
+ on `main`.
112
+ - **Any assistant, or several at once.** 18 are supported, and they share one installation.
113
+ - **It talks so you understand.** Short sentences, in your language, technical or with analogies.
148
114
 
149
- **The first session after upgrading** does three things, once:
115
+ ---
150
116
 
151
- - It explains these changes in a few lines.
152
- - If an agent left commits on a closed `main` that never reached the remote, it moves them to a
153
- `rescue/main-<date>` branch and puts `main` back to what the remote has. Nothing is lost.
154
- - It moves worktrees older versions created next to the project into `.worktrees/`.
117
+ ## Install in one minute
155
118
 
156
119
  ```bash
157
- rsc main status # open or closed for the agent, and the signals behind it
158
- rsc main unlock # this project is simple: the agent may work on main (saved in .rsc.json)
159
- rsc main lock # back to the default
160
- rsc isolation status # whether another session would send new work to a worktree
161
- rsc isolation off # never use worktrees for parallel sessions in this project
120
+ npx @ericrisco/rsc@latest onboard
162
121
  ```
163
122
 
164
- > **Limit, stated plainly.** The hook that refuses the commit or the branch switch runs in
165
- > **Claude Code**, like the other rsc guards. In Codex, Gemini, Cursor and OpenCode the same rules
166
- > are carried by the skills and by the session memory, which tells the agent that another session is
167
- > active. They are followed, but no hook enforces them. Knowledge sync works in all five.
123
+ The first run asks **one** question about conversation (technical, or with analogies), then what the
124
+ project is for, its goal and the assistants to target. Then it presents the complete plan. A small
125
+ website can defer SDD, agents and code guards; an operations harness does not receive them merely
126
+ because it lives in a repository. Deferred components record the evidence that would make rsc
127
+ recommend them later, and `rsc reassess` reports it without installing anything.
128
+
129
+ Everything stays **in the project**. The real skill files are written once to `.rsc/skills/<id>/`, and
130
+ each assistant gets a symlink back to that shared base, so picking several duplicates nothing. Skills
131
+ load progressively: only their description is paid for until a task needs them.
168
132
 
169
- ---
133
+ Prefer a short `rsc` command? `npm install -g @ericrisco/rsc`.
134
+
135
+ > **Run it inside the project you are equipping, not inside a clone of this repo.** The catalog's own
136
+ > `package.json` is named `@ericrisco/rsc`, so `npx @ericrisco/rsc` from within a clone resolves to
137
+ > the local bin and fails with `sh: rsc: command not found`. Working on the catalog itself? Use
138
+ > `node scripts/rsc.js …` or `npm link`.
170
139
 
171
- ## 🤖 For agents: "install this harness"
140
+ ### For agents: "install this harness"
172
141
 
173
- If you're an AI coding agent (Claude Code, Cursor, Copilot, Codex, Gemini…) and your user
174
- asked you to **install rsc / this harness / these skills**, run this in the **root of the
175
- project they're equipping** — not inside a clone of this repo (see the note under *Install*):
142
+ If you are an AI coding agent and your user asked you to **install rsc, this harness or these
143
+ skills**, run this in the root of the project they are equipping:
176
144
 
177
145
  ```bash
178
146
  npx @ericrisco/rsc@latest onboard
179
147
  ```
180
148
 
181
- That launches the binding plain-language onboarding. It asks the user how technical to talk
182
- (technical or with analogies), project kind and goal **before it writes anything**, reads only the selected project
183
- root, and shows every selected or deferred skill, agent and hook with its reason. Relay those
184
- questions to the user; never invent or default their answers. The first pass writes nothing and
185
- prints a SHA-256 plan id. Only rerun with `--accept-plan <id>` after the user accepts that exact plan.
186
- If the project already has a skill of its own with a catalog name, the plan lists it under
187
- **Your own skills this plan replaces** — tell the user before accepting; renaming their folder and
188
- regenerating the plan keeps theirs.
149
+ It asks the user how technical to talk, the project kind and the goal **before it writes anything**,
150
+ and shows every selected or deferred skill, agent and hook with its reason. Relay those questions;
151
+ never invent or default the answers. The first pass writes nothing and prints a SHA-256 plan id. Rerun
152
+ with `--accept-plan <id>` only after the user accepts that exact plan. If the project already has a
153
+ skill of its own with a catalog name, the plan lists it under **Your own skills this plan replaces**:
154
+ tell the user before accepting.
189
155
 
190
- For a non-interactive agent, collect the answers and preview the same plan explicitly:
156
+ Non-interactive, with the answers collected first:
191
157
 
192
158
  ```bash
193
159
  npx @ericrisco/rsc@latest onboard --technical-level technical \
@@ -199,553 +165,318 @@ npx @ericrisco/rsc@latest onboard --technical-level technical \
199
165
  --software-scope small --target codex --accept-plan PRINTED_SHA256_ID
200
166
  ```
201
167
 
202
- - **Choose assistants non-interactively:** add `--target claude` (comma-separate for several) to `onboard`.
203
- - **Two assistants already installed?** rsc asks instead of guessing. `--target` settles it in one word.
204
- - **Already installed, just refreshing skills + hooks:** `rsc sync` (or re-run the command above).
205
- - **Add one skill by id:** `rsc add <id>` · **browse the catalog:** `rsc consult "<what you want>"` or `rsc list`.
206
-
207
- From then on it's self-driving: `rsc-suggest` proposes the next skill as tasks appear, and in
208
- Claude Code a hook re-asserts the **lane decisor** on every turn — so every request is classified
209
- before anything is written.
168
+ If project evidence changes between preview and acceptance, rsc returns `RSC_PLAN_CHANGED` and writes
169
+ nothing. After applying, it verifies the result and prints `RSC_ONBOARDING_READY`, or
170
+ `RSC_ONBOARDING_INCOMPLETE` with each missing path and the action that creates it.
210
171
 
211
172
  ---
212
173
 
213
- ## 🛣️ Three lanes, and the agent picks the right one for you
174
+ ## How it works inside
214
175
 
215
- <img src="https://raw.githubusercontent.com/ericrisco/rsc-harness/main/site/lanes.svg" alt="The rsc lane decisor: the agent classifies each request into answer (read-only), FTD (simple change, one feature document) or SDD (the ten-phase chain for big or complex work, entered by the agent; you approve the spec)." width="960">
176
+ ### The knowledge model: `02-DOCS/` and `01-TOOLS/`
216
177
 
217
- Every turn takes exactly one lane, and your agent names the one it took in a line.
218
-
219
- 1. **Answer.** The request asks for information — explain, compare, investigate, audit, review,
220
- propose. It is **read-only**: nothing is written, no artifact is created, no writer is delegated.
221
- Asking your agent to *think about* building something is still this lane. When intent is
222
- ambiguous it asks one question and stays here; ambiguity slows the lane down, it never raises it.
223
- 2. **FTD — Fast-Track Development.** The request authorises a change. This is the default for
224
- ordinary work and needs no ceremony. One feature document per feature holds intent, scope, a
225
- checklist, the evidence and the next step. Tasks are checked off against observed proof, never
226
- against intention. For the simple changes.
227
- 3. **SDD — the ten-phase chain.** For the big or complex: several decisions that affect each other,
228
- or doubts that change the result. **The agent enters it on its own** — you never have to decide
229
- which method to use. Inside, you still decide *what* gets built: you approve the spec and answer
230
- the clarifying questions, then choose to review every phase yourself or let it run on autopilot
231
- to verified code. Publishing always asks.
232
-
233
- The agent says which lane it took and why, in one line. Ask for the other one and it switches.
234
-
235
- **The review only brings you what is real.** In SDD, `review` sends three adversarial reviewers at
236
- the diff (correctness, security, tests). They often find the same defect in different words, and a
237
- reviewer hunting for problems can overstate one. So before anything reaches you,
238
- `rsc review consolidate` merges the duplicates (same place, or the same quoted line), and every
239
- serious finding left goes to a fresh `finding-verifier` agent whose starting position is that the
240
- finding is false. It blocks the merge only if the verifier reproduces it or traces it. You get
241
- "11 reported → 4 unique → 2 confirmed", and the refuted ones are listed with the reason.
242
-
243
- **Isolation cleans itself up.** When a lane opens a branch or a worktree, you no longer have to
244
- remember to retire it: a `post-merge` hook does it the moment the work lands on the trunk, on both
245
- landing paths — a local merge and the pull after a forge merge. It removes only what is provably
246
- landed and holds nothing unsaved; anything it refuses tells you why. The previous version asked an
247
- agent to run the cleanup at the end of a long phase, and that step was skipped on both features that
248
- reached it.
249
-
250
- Earlier versions asked you to accept a proposal before entering the chain. People do not want to
251
- choose a method; they want the work done right. Since 3.0 the agent chooses, and you keep the part
252
- that is genuinely yours: deciding what is built.
178
+ <img src="https://raw.githubusercontent.com/ericrisco/rsc-harness/main/site/company-brain.svg" alt="The rsc company brain as a 3D knowledge graph: loose material drifts in from the inbox and is absorbed into the wiki cluster, whose brightest hubs are its .base views; dim clusters are raw sources and the agent's own worklog; an amber cluster is gaps.md, what the wiki knows it is missing." width="960">
253
179
 
254
- ---
180
+ Anything you drop into `02-DOCS/inbox/` is ingested. The wiki consolidates it as plain markdown that
181
+ every skill reads before acting, so the next session starts where the last one stopped. Raw sources
182
+ and the agent's worklog stay underneath, never deleted. You can open `02-DOCS/` as an Obsidian vault,
183
+ and every `02-DOCS/wiki/` is a valid [Open Knowledge Format](https://github.com/GoogleCloudPlatform/knowledge-catalog/tree/main/okf)
184
+ bundle: markdown with YAML frontmatter, standard links, and the reserved `index.md` and `log.md`.
255
185
 
256
- ## 🗣️ It talks so you understand
257
-
258
- Agents assume you saw their reasoning, and they write too much. rsc fixes the voice, not the reader.
259
-
260
- - **Short sentences, one idea each.** The style comes from ASD-STE100, the controlled writing of
261
- aircraft maintenance manuals, applied at about 80% and in your language.
262
- - **Every answer stands alone.** No "that fix" or "the second commit": the answer names the thing,
263
- with the minimum context to understand it.
264
- - **One question at install:** technical, or with analogies. That is the only setting.
265
- - **A ladder when you do not follow.** Text first. Then one diagram. Then one HTML page. A video
266
- only if you ask for it.
267
-
268
- Every turn still closes with the compass: where you are, and the next step as a question. The voice
269
- lives in `orient`, which every harness installs. Text you send to other people (emails, posts,
270
- READMEs) goes through `unslop` instead: it sounds like a person and carries no AI tells.
271
-
272
- ---
186
+ `01-TOOLS/` holds one folder per tool: `.env.example`, `CREDENTIALS.md`, a README and a
187
+ `test_connection` that proves it works. When you name a tool ("connect my Holded", "can the agent
188
+ read our Sage?"), the `connect-tool` skill researches the vendor's current docs, picks the least
189
+ dangerous route (official MCP, API, export, a read-only copy of the database), and builds the folder.
190
+ For a read-only connection, the test also proves that writing fails.
273
191
 
274
- ## Why this exists
275
-
276
- An improvised harness tends to grow by accumulation: more files, more context and more rules, with
277
- no method deciding whether each piece belongs. rsc-harness keeps that construction disciplined:
278
-
279
- - **Granular by default.** The unit of installation is *one skill*. Install
280
- `fastapi` without ever pulling `go`. Nothing you don't use touches your context.
281
- - **Self-recommending.** Both the terminal (`rsc consult`) and the chat
282
- (`rsc-suggest`, an always-on detector) watch what you're doing and propose the
283
- *next* skill the moment a task needs it — a one-word confirm installs it.
284
- - **Not code-only.** First-class support for running a *company*: bookkeeping,
285
- invoicing, hiring, GDPR, pitch decks, SEO, a YouTube/TikTok/LinkedIn presence —
286
- each wired to a `02-DOCS/` knowledge loop that learns from your own results.
287
- - **Specialists follow the stack.** The four base agents stay small; installing a
288
- supported stack adds only its reviewer and build resolver. `rsc add go`, for
289
- example, adds the Go pair without pulling reviewers for every other language.
290
- - **A new local session continues the old one.** Claude Code, Codex, Gemini CLI,
291
- OpenCode and DeepSeek Harness load a bounded checkpoint for the current branch and worktree at
292
- session start. Cursor desktop uses an assisted read-before-action fallback.
293
- - **Honestly good.** Every skill was built by a research → spec → implement →
294
- *adversarial review* pipeline and had to clear an objective rubric
295
- (`scripts/skill-rubric.md`, written *before* any skill existed). The bar was
296
- real: skills that scored 8.0 were sent back and fixed, not waved through.
297
-
298
- `skills/<name>/` is the single source of truth. There are no bundles to argue
299
- over: you start with a tiny floor and grow one piece at a time.
192
+ ### Three lanes, and the agent picks
300
193
 
301
- ---
194
+ Every turn takes exactly one lane, and the agent names it in one line, in your language.
302
195
 
303
- ## New sessions pick up the latest local work
304
-
305
- On supported local targets, rsc checkpoints observable repository state at safe
306
- boundaries: branch, worktree, HEAD, changed paths, commits and SDD ledger status.
307
- When a new session opens in the same checkout, that state is injected before the
308
- first agent action. A completed edit is preserved even if the previous client
309
- closed before its normal session-end event.
310
-
311
- - **Full:** Claude Code, Codex, Gemini CLI, OpenCode and DeepSeek Harness (through rsc's machine
312
- bridge, see [targets](#multi-target)). Codex asks you to inspect
313
- and trust the project hook once with `/hooks`; until then `doctor` reports that
314
- trust is still required.
315
- - **Assisted:** Cursor desktop. Its start hook is fire-and-forget, so rsc also
316
- installs a local always-on rule that performs the read before acting.
317
- - **Never cloud:** Cursor Cloud, Codex Cloud, remote agents, cloud storage and
318
- synchronization are intentionally unsupported. The memory runtime makes no
319
- network request.
320
-
321
- The journal never stores prompts, responses, tool output, file contents or
322
- secrets. It stays in a git-excluded project-local path, retains 30 days, and
323
- injects at most 4,096 bytes. Disable every memory surface for a project with
324
- `rsc memory off`; re-enable it with `rsc memory on`.
196
+ 1. **Answer.** The request asks for information: explain, compare, investigate, audit, review,
197
+ propose. It is **read-only**: nothing is written and no artifact is created. When intent is
198
+ unclear it asks one question and stays here.
199
+ 2. **FTD, Fast-Track Development.** The request authorises a change. This is the default for ordinary
200
+ work. One feature document holds intent, scope, a checklist, the evidence and the next step. Tasks
201
+ are checked off against observed proof, never against intention.
202
+ 3. **SDD, the ten-phase chain.** For the big or complex: several decisions that affect each other.
203
+ **The agent enters it on its own**, and you still decide *what* gets built: you approve the spec
204
+ and answer the clarifying questions, then review each phase or let it run on autopilot. Publishing
205
+ always asks.
325
206
 
326
- ---
207
+ Ask for the other lane and it switches.
327
208
 
328
- ## Install
209
+ ### Skills, and how they are recommended
329
210
 
330
- ```bash
331
- npx @ericrisco/rsc@latest onboard
332
- ```
211
+ The unit of installation is **one skill**: install `fastapi` without ever pulling `go`. Two faces
212
+ share one catalog (`manifest.json`):
333
213
 
334
- Prefer the short `rsc` command? Install once, globally:
214
+ - **In the terminal**, `rsc consult` ranks the catalog against your words and what it detects in the
215
+ repo (`package.json` + `next` → `nextjs`, `go.mod` → `go`, `Dockerfile` → `docker`).
216
+ - **In the chat**, the always-on `suggest` notices when a task needs a skill you do not have, names
217
+ it, and installs it on a one-word yes.
335
218
 
336
- ```bash
337
- npm install -g @ericrisco/rsc # then just: rsc
338
- ```
219
+ Every skill passed a research → spec → implement → adversarial review pipeline and an objective
220
+ rubric (`scripts/skill-rubric.md`) written before any skill existed. Skills that scored 8.0 were sent
221
+ back and fixed, not waved through.
339
222
 
340
- Run it inside any project and describe what you want. Working on the catalog
341
- itself? Clone and link:
223
+ ### Hooks and guards
342
224
 
343
- ```bash
344
- git clone https://github.com/ericrisco/rsc-harness.git ~/rsc-skills
345
- cd ~/rsc-skills && npm install && npm link
346
- ```
225
+ In Claude Code, hooks enforce what instructions only ask for: the lane decisor on every turn, a
226
+ refusal before a commit on a closed `main`, a confirmation before destructive commands, and a nudge
227
+ to write the feature document before the first code edit. Every refusal says how to carry on. The
228
+ rules only see what the **agent** runs; a person committing in their own terminal is never touched.
347
229
 
348
- > **Run it inside the project you're equipping — not inside this repo.** The
349
- > catalog's own `package.json` is named `@ericrisco/rsc`, so `npx @ericrisco/rsc`
350
- > *from within a `rsc-harness` clone* resolves to the local (unlinked) bin and
351
- > dies with `sh: rsc: command not found`. Working on the catalog itself? Use
352
- > `node scripts/rsc.js …`, the `npm link` above, or pin the published build with
353
- > `npx @ericrisco/rsc@latest …`.
230
+ > **Limit, stated plainly.** Those guards run in **Claude Code**. In Codex, Gemini, Cursor and
231
+ > OpenCode the same rules travel in the skills and the session memory. They are followed, but no hook
232
+ > enforces them.
354
233
 
355
- The first run asks **one** question about conversation: technical, or with analogies. Then what the
356
- project is for, its goal and the assistants to target. It then presents the complete plan. A small
357
- website can defer SDD, agents and code guards; an operations harness does not receive them merely
358
- because it lives in a repository. Deferred components record the evidence that would make rsc
359
- recommend them later. `rsc reassess` reports that evidence but still cannot install anything
360
- without a newly accepted plan.
234
+ ### Working as a team
361
235
 
362
- Everything stays **in the project**, and the real skill files are written
363
- **once** to `.rsc/skills/<id>/`. Each assistant you pick gets a lightweight
364
- symlink back to that shared base — no copy is duplicated across IDEs. (If the
365
- filesystem can't symlink, it falls back to a real copy automatically.)
366
- On targets with file-based agents, the four base agents are installed too;
367
- stack specialists remain selective. Native command targets receive only entry
368
- points whose backing skill, agent or local-memory capability actually exists.
236
+ Day ninety is where harnesses break, especially with several people, assistants and sessions on one
237
+ project. rsc handles four things by default:
369
238
 
370
- ---
371
-
372
- ## 30-second tour
373
-
374
- ```
375
- $ rsc onboard
376
- ██████╗ ███████╗ ██████╗ ← animated gradient wordmark
377
- ██╔══██╗██╔════╝██╔════╝
378
- ██████╔╝███████╗██║
379
- 271 skills · one CLI · zero bloat
380
-
381
- How should I talk to you?
382
- What are you building or running?
383
- What do you want this project to achieve?
384
-
385
- RSC_ONBOARDING_PLAN
386
- Plan id: <sha256>
387
- Selected: …
388
- Deferred: …
389
- Accept this exact harness plan?
390
- ```
391
-
392
- The terminal and chat adapters produce the same normalized answers and plan id. If project evidence
393
- changes between preview and acceptance, rsc returns `RSC_PLAN_CHANGED` and writes nothing. After an
394
- accepted application it verifies the receipt and managed state before printing `RSC_ONBOARDING_READY`.
395
- That verdict is not just about the receipt: it also requires the harness floor to exist —
396
- `01-TOOLS/_TEMPLATE/`, `02-DOCS/wiki/harness/`, and the constitution when the plan selects SDD.
397
- If the floor is missing, the install applied but prints `RSC_ONBOARDING_INCOMPLETE` with each
398
- missing path and the action that creates it, because a plan that promised little used to be able to
399
- report success with three markdown files. When the plan selects SDD, onboarding writes the
400
- constitution itself as a draft (`status: draft`, only the facts it knows, no principles), so a
401
- non-interactive install still ends `RSC_ONBOARDING_READY`; the draft is listed as pending — under
402
- READY and in `rsc doctor` — until the `constitution` phase completes it. An existing constitution is
403
- never overwritten.
404
-
405
- ---
406
-
407
- ## The CLI
408
-
409
- Fresh projects enter through `rsc onboard`. The direct `add` and `install` forms below
410
- are maintenance controls for projects that already carry an `.rsc.json` declaration; they cannot
411
- bypass onboarding in a new folder.
412
-
413
- ```bash
414
- rsc onboard # binding plain-language onboarding (recommended)
415
- rsc reassess # check persisted deferral triggers; never installs by itself
416
- rsc add fastapi postgresdb # install specific skills, by name
417
- rsc add youtube-api remotion-video # …grow a channel, edit with Remotion
418
- rsc add fastapi --target claude,codex # install into several assistants at once
419
- rsc consult "I want to launch a SaaS" # recommend only, no install
420
- rsc registry refresh # write .rsc/skill-registry.{json,md}
421
- rsc list # installed skills, agents and commands
422
- rsc capabilities # installed/available surfaces + memory mode
423
- rsc doctor # health, missing backing, hooks and local memory; exits 1 when unhealthy
424
- rsc memory status # full / assisted / unsupported / degraded
425
- rsc memory save --session handoff # force a deterministic local checkpoint
426
- rsc memory resume # print this branch/worktree continuation
427
- rsc memory learn --text "…" --evidence "…" --confidence 0.8 --approve
428
- rsc memory off # disable hooks, commands and injection project-wide
429
- rsc sync --target claude,codex # refresh managed skills/hooks from the current package version
430
- rsc agent-model opencode openai/gpt-5 # pin the model the generated agents carry (saved in .rsc.json)
431
- rsc agent-model opencode inherit # back to the session's model (OpenCode's default)
432
- rsc agents status # installed agents, and which ones you edited
433
- rsc agents reset developer # take rsc's version of an agent you edited (yours is backed up first)
434
- rsc review consolidate c.md s.md t.md # merge the review lenses' findings; serious ones go to finding-verifier
435
- rsc backups # list project-local snapshots
436
- rsc restore latest --dry-run # preview restoring the newest snapshot
437
- rsc restore <snapshot-id> # restore a project-local snapshot
438
- rsc upgrade --dry-run # show npm upgrade + sync commands
439
- rsc uninstall postgresdb --dry-run # preview a removal
440
- ```
239
+ | | What happens | Turn it off |
240
+ | --- | --- | --- |
241
+ | **You choose how the project works** | The install asks once: straight on `main`, or branches and pull requests? With branches, a commit on `main` is refused and the agent asks before each change: this branch, a new one, or unlock `main`? It never opens a branch on its own. | «unlock main», or `rsc main unlock` |
242
+ | **One workspace per agent** | If another session works in the same folder, new work goes to `.worktrees/<branch>/`, inside the project and never committed. A `post-merge` hook retires it once the branch lands. | `rsc isolation off` |
243
+ | **The agent picks the method** | FTD for simple changes, SDD for complex ones. The agent decides and says why. | Ask for the other lane |
244
+ | **Knowledge reaches everyone** | `01-TOOLS/`, `02-DOCS/wiki/` and `02-DOCS/attachments/` travel through one exchange branch, `rsc/knowledge`, and reach `main` inside your normal pull requests. | `rsc knowledge-sync off` |
441
245
 
442
- ### `rsc doctor`: harness health vs onboarding readiness
246
+ **How it knows a project is complex.** A hook counts what anyone can check: a CI setup, a deployment
247
+ file (`Dockerfile`, `vercel.json`, `fly.toml`…) or at least two people in the last 50 commits. The
248
+ answer you gave at install always wins over this detection.
443
249
 
444
- `doctor` answers two different questions, and prints both first, on separate lines:
250
+ #### Knowledge sync, step by step
445
251
 
446
252
  ```text
447
- Harness health: healthy
448
- Onboarding readiness: pending
449
- Pending: 02-DOCS/wiki/sdd/constitution.md (draft)
450
- Next: Complete 02-DOCS/wiki/sdd/constitution.md with the `constitution` phase …
253
+ ana · feat/login edits 02-DOCS/wiki/api.md ──► rsc/knowledge (when her turn ends)
254
+ eric · feat/payments 📥 1 change from Ana ◄── rsc/knowledge (before his next message)
255
+ main · protected untouched, gets it inside the next merged pull request
256
+ new · clones main has it all after the first message
451
257
  ```
452
258
 
453
- - **Harness health** (`healthy` in `--json`) says whether what is installed works: skills, agents,
454
- commands and hook scripts are on disk. It is the only thing the exit code follows (1 when
455
- unhealthy), so CI and editor extensions can rely on it.
456
- - **Onboarding readiness** (`onboarding` in `--json`: `status`, `missing`, `pending`, `action`) says
457
- whether onboarding is finished. It checks the accepted plan's floor, the same check that prints
458
- `RSC_ONBOARDING_READY`, plus drafts. The status is `ready`; `pending` when a draft such as the
459
- onboarding constitution still has to be completed; `incomplete` when part of the floor is missing,
460
- for example a deleted constitution in an SDD plan, with the exact phase or command that fixes it;
461
- or `not onboarded` when there is no onboarding record, as in a manual `rsc add` install. Readiness
462
- never changes `healthy` or the exit code. `Missing:` and `Pending:` appear only when they have
463
- entries.
464
-
465
- ---
466
-
467
-
468
- ## 👥 Sharing a harness with your team
469
-
470
- The harness travels by git, but not all of it — and the split is the point.
471
-
472
- **Commit these:**
473
-
474
- | | |
475
- | --- | --- |
476
- | `.rsc.json` | The decision: which assistants, which skills, **which catalog version**, the developer tier, which gates you disarmed |
477
- | `01-TOOLS/` · `02-DOCS/` | Your tooling and your wiki, if you use them |
478
- | Skills and agents you wrote by hand | They are yours. rsc does not claim them, does not count them as drift, and does not touch them |
259
+ - **When a turn ends**, your changes in those folders are committed on your branch as
260
+ `📝 docs(auto): …` and sent to `rsc/knowledge`. Only the copy on `rsc/knowledge` carries
261
+ `[skip ci]`, so your own pushes still run CI. On a closed `main`, or with code of yours still
262
+ uncommitted, nothing is committed on your branch: the snapshot only goes to `rsc/knowledge`.
263
+ - **Before each message**, what teammates sent comes into the branch you are on as a
264
+ `📥 docs(auto): sync` commit, and you are told in one line. Only knowledge folders are touched.
265
+ - **It never** pushes to `main`, pushes your code, brings in anybody else's code, syncs your personal
266
+ `user-profile.md`, or overwrites a file you are editing.
479
267
 
480
- **Do not commit these** — rsc adds them to `.gitignore` for you:
268
+ It runs in the turn hooks of Claude Code, Codex, Gemini, Cursor, OpenCode and DeepSeek Harness. It is
269
+ a **project** switch: if one person stopped sending, the rest would stop seeing their work.
481
270
 
482
- | | Why |
483
- | --- | --- |
484
- | `.rsc/` | Machine state: hook scripts, seals, logs and fallback session memory |
485
- | `02-DOCS/raw/worklog/.rsc-memory/` | Preferred session journal when a local wiki exists; protected with git's local exclude |
486
- | The skill entries rsc manages | Symlinks on macOS/Linux, real copies on Windows — two incompatible shapes of one thing |
271
+ #### Sharing the harness through git
487
272
 
488
- Three files carry the harness through git: `.rsc.json` (what the team decided),
489
- `.claude/settings.json` (the wiring), and `.claude/rsc-bootstrap.mjs` — the small file that
490
- notices, in a clone, that the rest is not there yet. **Commit all three.** If your project
491
- ignores the assistant's directory wholesale, rsc adds the lines that keep those files versioned —
492
- verified against git, not against the pattern.
273
+ **Commit these:** `.rsc.json` (which assistants, which skills, which catalog version), `01-TOOLS/`,
274
+ `02-DOCS/`, and skills or agents you wrote by hand. **rsc ignores the rest for you:** `.rsc/` (machine
275
+ state) and the skill entries it manages (symlinks here, copies on Windows).
493
276
 
494
- **And say it plainly, because committing it is the point:** `.claude/rsc-bootstrap.mjs` is code that
495
- runs on every session and every shell call, so a pull request that edits *that file* runs on the
496
- machine of whoever reviews the branch. That is true of `.claude/settings.json` already, and of any
497
- hook-based harness — but it is worth knowing before you agree to commit a third one. Review changes
498
- to it the way you would review a CI workflow.
277
+ Three files carry the harness through git: `.rsc.json`, `.claude/settings.json` and
278
+ `.claude/rsc-bootstrap.mjs`, the small file that notices in a clone that the rest is not built yet.
279
+ Commit all three. Because `rsc-bootstrap.mjs` runs on every session, review changes to it the way you
280
+ would review a CI workflow.
499
281
 
500
- Whoever clones runs **one command** and ends up with the same harness — at the version the
501
- project pinned, which is the `catalogVersion` in its `.rsc.json`:
282
+ Whoever clones runs **one command** and gets the same harness, at the version the project pinned in
283
+ its `.rsc.json` as `catalogVersion`:
502
284
 
503
285
  ```bash
504
286
  npx @ericrisco/rsc@<catalogVersion> sync
505
287
  ```
506
288
 
507
- **You do not have to know that, or find it.** Open the project and the assistant tells you, in
508
- the first message: what is missing, what would be installed, and the exact command, naming the
509
- pinned version. It asks; it does not install anything on its own and it does not hold up
510
- whatever you sat down to do. Say no and it stops asking on that machine.
511
-
512
- Not `@latest`, and the difference is the whole point of sharing: a teammate who clones in three
513
- months gets what you had, not what shipped since. Once it is built, the same rules as any project
514
- apply: releases in the same major install themselves (see [Update](#update)), and the new
515
- `catalogVersion` in `.rsc.json` reaches everyone when somebody commits it.
516
-
517
- When someone changes the harness and you `git pull`, `rsc doctor` tells you what no longer
518
- matches. **Nothing is ever written to your machine by a pull** — you are told, and you decide.
289
+ You do not have to know that. Open the project and the assistant tells you, in the first message,
290
+ what is missing and the exact command, naming the pinned version. It asks; it never installs on its
291
+ own. A teammate who clones in three months gets what you had, not what shipped since. After a
292
+ `git pull`, `rsc doctor` tells you what no longer matches; nothing is written by a pull.
519
293
 
520
- **Own skills.** A skill your team wrote lives in the repo and already works for whoever clones,
521
- with no command at all. rsc never installs, updates or overwrites it: its version is the commit.
522
- Installing a catalog skill of the same name is refused rather than silently winning, and `doctor`
523
- lists what is yours by reading the files themselves — no list to keep in `.rsc.json`, because a
524
- list somebody has to remember to update is a list that goes quietly stale. Declaring a skill under
525
- `ownSkills` still works and still reports when someone is missing it.
294
+ **Own skills.** A skill your team wrote lives in the repo and works for whoever clones. rsc never installs, updates or overwrites
295
+ it: its version is the commit. Installing a catalog skill with the
296
+ same name is refused, and `doctor` lists what is yours by reading the files. Declaring a skill under
297
+ `ownSkills` still works.
526
298
 
299
+ #### Git permissions
527
300
 
528
- ### Your wiki and tools stay in sync — on by default
301
+ A harness installed from scratch lets the agent run `git commit`, `git push` and `gh pr create`
302
+ without asking, because those steps close every lane. A force-push still asks, and in Claude Code a
303
+ commit on a closed `main` is still refused. It is saved as `gitPermissions` in `.rsc.json`.
529
304
 
530
- `01-TOOLS/`, `02-DOCS/wiki/` and `02-DOCS/attachments/` are the team's knowledge, so rsc keeps them
531
- the same on every machine without anybody thinking about git, **and without ever pushing to `main`**.
532
- Exactly those three folders, minus rsc's own `01-TOOLS/_TEMPLATE/` and your personal
533
- `02-DOCS/wiki/harness/user-profile.md`. Your `main` is
534
- protected, or should be; rsc assumes it is.
535
-
536
- The knowledge travels through one exchange branch, `rsc/knowledge`, that nobody works on by hand:
537
-
538
- ```text
539
- ana · feat/login edits 02-DOCS/wiki/api.md ──► rsc/knowledge (when her turn ends)
540
- eric · feat/payments 📥 1 change from Ana ◄── rsc/knowledge (before his next message)
541
- main · protected untouched — gets it inside the next merged pull request
542
- new · clones main has it all after the first message
543
- ```
544
-
545
- - **When a turn ends**, your changes in those folders are committed on your branch as
546
- `📝 docs(auto): …` and sent to `rsc/knowledge` on `origin`, from whatever branch you are on. Only
547
- the copy on `rsc/knowledge` carries `[skip ci]`; the commit on your branch does not, so your next
548
- ordinary push still runs CI. Two cases commit nothing on your branch: a closed `main`, and code of
549
- yours still uncommitted (a docs commit would land ahead of the code it describes). Then the snapshot
550
- is built aside, only goes to `rsc/knowledge`, and the files stay modified for you to commit with
551
- your work. Knowledge that you or the agent already **committed** on the branch goes up too — only
552
- its knowledge part, under a `docs(auto) … [skip ci]` message. Commits that came in by merging
553
- `main` are your teammates', not yours, and are not sent again.
554
- - **Before each message**, what teammates sent is brought into **the branch you are on** as a
555
- `📥 docs(auto): sync` commit, and you are told in one line. Only the knowledge folders are touched.
556
- A doc that `main` on `origin` already has, identical, is left for your ordinary merge of `main`. On
557
- a closed `main` nothing is written at all — an uncommitted file there would make your next
558
- `git pull` refuse to run — you are told what is waiting, and it arrives with that pull or in the
559
- next branch you open. When the last fetch is more than ten minutes old, the message fetches first
560
- (three seconds at most), so even a one-message session sees fresh docs.
561
- A branch you open later catches up on its first message: everything on `rsc/knowledge` since it
562
- left `main` comes down, including what you wrote yourself on another branch.
563
- - **It reaches `main` the normal way.** Your feature branch now carries the team's knowledge, so it
564
- arrives in `main` inside the pull request you were going to open anyway. There is no extra pull
565
- request from `rsc/knowledge`, and nobody has to merge it.
566
- - The first time, `rsc/knowledge` is created from the remote's default branch. If someone deletes it,
567
- it is created again.
568
-
569
- What it will not do, by design:
570
-
571
- | | |
305
+ | Assistant | Where it goes |
572
306
  | --- | --- |
573
- | Push to `main` | Never. Only `rsc/knowledge` receives anything. |
574
- | Push your code or your unpushed commits | Only the knowledge folders go up, even from a commit that also has code. Your code waits for you. |
575
- | Trigger CI or a deploy | Every commit on `rsc/knowledge` says `[skip ci]`; the one on your branch does not, so it never skips the CI of your own push. |
576
- | Bring in anybody else's code | Only knowledge paths come down. Code, config and `.claude/` are never pulled. |
577
- | Sync `02-DOCS/wiki/harness/user-profile.md` | Those are one person's dials. |
578
- | Overwrite a file you are editing | It tells you, and your version stays. |
579
- | Run where it has no business | No `origin`, no knowledge folders, a rebase in progress, a cloud agent: it stays quiet. |
580
-
581
- It is wired into the assistant's own turn hooks (end of turn, new message) in Claude Code, Codex,
582
- Gemini, Cursor, OpenCode and DeepSeek Harness (tested end to end in Claude Code, Codex and OpenCode). The network part runs in the background, so a turn never waits for
583
- it. It is kept apart from the [local session memory](#new-sessions-pick-up-the-latest-local-work),
584
- which promises never to touch the network. The first turn says it is on. To turn it off for the
585
- project:
307
+ | Claude Code | `.claude/settings.json` → `permissions.allow` (force-push under `ask`) |
308
+ | Codex | `.codex/rules/rsc-git.rules` (force-push → `prompt`) |
309
+ | Gemini | `.gemini/settings.json` → `tools.allowed` |
310
+ | OpenCode | `opencode.json`: the `permissions` list on OpenCode 2, `permission.bash` on 1.x. An `opencode.jsonc` is never rewritten; rsc prints the rules to paste. |
311
+ | Cursor, DeepSeek Harness | Not covered: neither has a safe per-command allow list. |
586
312
 
587
- ```bash
588
- rsc knowledge-sync off # writes .rsc/.no-knowledge-sync and records it in .rsc.json — commit that
589
- rsc knowledge-sync status # active or not, and why
590
- ```
313
+ `rsc git-permissions status | on | off` explains, per assistant, what rsc controls and what is left
314
+ to the assistant.
591
315
 
592
- It is a **project** switch, not a personal one: if one person stopped sending, the rest of the team
593
- would stop seeing their work. For the rest of the 3.0 team defaults, see
594
- [New in 3.0](#️-new-in-30-safe-for-teams-by-default).
316
+ ### Memory between sessions
595
317
 
596
- ## 🩹 Something's off? One command
318
+ On supported local targets, rsc checkpoints observable repository state (branch, worktree, HEAD,
319
+ changed paths, commits, SDD status) and injects it before the first action of a new session in the
320
+ same checkout.
597
321
 
598
- Recognise any of these? They are all the same fix.
322
+ - **Full:** Claude Code, Codex, Gemini CLI, OpenCode and DeepSeek Harness. Codex asks you to trust the
323
+ project hook once with `/hooks`.
324
+ - **Assisted:** Cursor desktop, through an always-on rule that reads before acting.
325
+ - **Never cloud:** the memory runtime makes no network request.
599
326
 
600
- | What you see | |
601
- | --- | --- |
602
- | `"target": "codex"` when you work in Claude Code | |
603
- | `This target has no hook injection` and you did not expect that | |
604
- | Skills appear that you never asked for | |
605
- | A hook seems to run several times per turn | |
606
- | Template lines showed up inside your hand-written `AGENTS.md` | |
327
+ The journal never stores prompts, responses, tool output, file contents or secrets. It stays in a
328
+ git-excluded local path, keeps 30 days, and injects at most 4,096 bytes. `rsc memory off` disables it.
607
329
 
608
- (A *fresh* clone is not in this table any more: nothing is broken there, the harness was simply
609
- never built on that machine, and the assistant now says so itself — see **sharing by git** above.)
330
+ ### Review that only brings you what is real
610
331
 
611
- ```bash
612
- npx @ericrisco/rsc@latest repair
613
- ```
332
+ In SDD, `review` sends three adversarial reviewers at the diff (correctness, security, tests). They
333
+ often report the same defect in different words, and a reviewer hunting for problems can overstate
334
+ one. So `rsc review consolidate` merges the duplicates, and every serious finding left goes to a
335
+ fresh `finding-verifier` agent whose starting position is that the finding is false. It blocks the
336
+ merge only if the verifier reproduces or traces it. You get "11 reported → 4 unique → 2 confirmed",
337
+ with the refuted ones listed and their reason.
614
338
 
615
- Safe in any folder: with no rsc there, it says so and writes nothing. It shows what it
616
- found before touching anything, keeps a recoverable copy, and running it twice changes
617
- nothing the second time. Add `--dry-run` to see the whole pass without a single write.
339
+ ### It talks so you understand
618
340
 
619
- **What it fixes on its own** — putting the harness back to what was already declared:
620
- dangling links from a clone, hooks wired several times, the 0.1 layout no assistant reads.
341
+ - **Short sentences, one idea each,** in the style of ASD-STE100 (the controlled writing of aircraft
342
+ manuals), always in your language.
343
+ - **The answer first.** Every answer stands alone, without "that fix" or "as above".
344
+ - **One setting:** technical, or with analogies.
345
+ - **A ladder when you do not follow:** text, then a diagram, then an HTML page, and a video only if
346
+ you ask.
621
347
 
622
- **What it asks about** — anything that changes a decision: moving the harness to another
623
- assistant, or touching files you already committed.
348
+ Every turn closes with a short compass: where you are, and the next step as a question. Text you send
349
+ to other people (emails, posts, READMEs) goes through `unslop`, so it sounds like a person.
624
350
 
625
- **What it never touches:** skills and agents you wrote by hand. rsc did not install them,
626
- so rsc does not repair, move or delete them — not even when rebuilding from scratch.
351
+ ---
627
352
 
628
- ## Update
353
+ ## Supported assistants
629
354
 
630
- **rsc updates itself.** When a session starts, rsc checks npm for a newer version:
355
+ The real files land once in `.rsc/skills/<id>/`; each assistant gets a symlink or a converted file.
356
+ The wizard asks which ones; `--target a,b` does it non-interactively.
631
357
 
632
- - **Same major** (`2.1.0 → 2.1.1` or `2.2.0`): it installs that exact version in the background.
633
- It takes effect in the next session, and that session tells you it happened.
634
- - **New major** (`2.x → 3.0.0`): it can change how the harness works, so the assistant asks first.
635
- - **Failed:** the assistant asks instead, and rsc retries once a day. The output is in
636
- `.rsc/auto-update.log`.
358
+ | Target | Skill destination (→ `.rsc/skills/<id>/`) | Always-on detector |
359
+ | --- | --- | --- |
360
+ | `claude` | `.claude/skills/<id>/` → symlink (copy on Windows) | SessionStart hook in `.claude/settings.json` |
361
+ | `codex` | `.codex/rsc/<id>/` → symlink | block in `AGENTS.md` |
362
+ | `copilot` | `.github/rsc/<id>/` → symlink | block in `.github/copilot-instructions.md` |
363
+ | `cursor` | `.cursor/rules/<id>.mdc` (converted) | always-apply rule |
364
+ | `gemini` | `.gemini/rsc/<id>/` → symlink | block in `GEMINI.md` |
365
+ | `windsurf` | `.windsurf/rsc/<id>/` → symlink | rule in `.windsurf/rules/rsc-suggest.md` |
366
+ | `cline` | `.clinerules/rsc/<id>/` → symlink | rule in `.clinerules/rsc-suggest.md` |
367
+ | `antigravity` | `.antigravity/rsc/<id>/` → symlink | block in `.antigravity/AGENTS.md` |
368
+ | `zed` | `.zed/rsc/<id>/` → symlink | block in `AGENTS.md` |
369
+ | `continue` | `.continue/rsc/<id>/` → symlink | rule in `.continue/rules/rsc-suggest.md` |
370
+ | `roo` | `.roo/rsc/<id>/` → symlink | rule in `.roo/rules/rsc-suggest.md` |
371
+ | `amp` | `.amp/rsc/<id>/` → symlink | block in `AGENTS.md` |
372
+ | `opencode` | `.opencode/rsc/<id>/` → symlink | block in `AGENTS.md` |
373
+ | `deepseek` | `.dsh/skills/<id>/` → symlink (discovered natively) | block in `AGENTS.md` |
374
+ | `jules` | `.jules/rsc/<id>/` → symlink | block in `AGENTS.md` |
375
+ | `junie` | `.junie/rsc/<id>/` → symlink | block in `.junie/guidelines.md` |
376
+ | `kiro` | `.kiro/rsc/<id>/` → symlink | doc in `.kiro/steering/rsc-suggest.md` |
377
+ | `aider` | `.aider/rsc/<id>/` → symlink | block in `CONVENTIONS.md` |
637
378
 
638
- A new install asks whether you want this (yes by default). To turn it off later, create
639
- `.rsc/.no-auto-update`; every release then asks. It is a project decision: it travels in
640
- `.rsc.json` like the other switches. The update can leave harness files changed in git; rsc never
641
- commits them for you.
379
+ > `codex`, `zed`, `amp`, `opencode`, `deepseek` and `jules` share one root `AGENTS.md`; the block is
380
+ > written once.
642
381
 
643
- Where it runs on its own: **Claude Code, Codex, Gemini CLI, Cursor, OpenCode and DeepSeek Harness**, from a
644
- session-start hook. Every other assistant has no such hook, so the always-on instructions ask the
645
- agent to run `node .rsc/auto-update.mjs` on its first turn — same rules, but it depends on the agent
646
- doing it (and some assistants ask your permission before running a command). Codex asks you to
647
- trust new hooks once.
382
+ > **DeepSeek Harness** (`dsh`) has no project-level hooks, so once per machine rsc adds one marked
383
+ > block to `~/.dsh/cordis.patch.yml` that runs the hooks of whichever project the session is in.
384
+ > Restart dsh once after the first install; delete the block to turn it off.
648
385
 
649
- To update by hand, bump the package, then re-sync what's already wired into your project:
386
+ | Targets | Stack agents | Native commands | Session memory |
387
+ | --- | --- | --- | --- |
388
+ | Claude Code | yes | agent + memory entries | full |
389
+ | Codex | yes | no separate surface | full after `/hooks` trust |
390
+ | Cursor desktop | yes | yes | assisted |
391
+ | Gemini CLI, OpenCode | yes | yes | full |
392
+ | DeepSeek Harness | unsupported | unsupported | full (machine bridge) |
393
+ | GitHub Copilot | yes | yes | unsupported |
394
+ | Junie, Kiro | yes | unsupported | unsupported |
395
+ | Windsurf, Cline, Roo | unsupported | yes | unsupported |
396
+ | Antigravity, Zed, Continue, Amp, Jules, Aider | unsupported | unsupported | unsupported |
650
397
 
651
- ```bash
652
- npm install -g @ericrisco/rsc@latest # global install: pull the newest catalog
653
- rsc sync # refresh managed skills + hooks (auto-detects your assistant)
654
- ```
398
+ `manifest.json` is the generated public inventory: 34 agents (5 base + 29 selective specialists) and
399
+ 53 command entries (20 fixed + 33 stack aliases). Unsupported means rsc writes nothing for that
400
+ surface. Generated agents carry no `model:` on OpenCode, so they use the session's model; pin one for
401
+ the team with `rsc agent-model <target> <model>`. If you edit a generated agent, `rsc sync` keeps your
402
+ file, and `rsc agents reset <name>` takes rsc's version back after a backup.
655
403
 
656
- Not sure what a bump touches? Preview the exact commands without writing anything:
404
+ ---
405
+
406
+ ## CLI
657
407
 
658
408
  ```bash
659
- rsc upgrade --dry-run # prints the npm install + rsc sync lines for your target
409
+ # Setup
410
+ rsc onboard # plain-language onboarding; writes nothing until you accept
411
+ rsc reassess # check deferred components against new evidence
412
+ rsc add fastapi postgresdb # install skills by name
413
+ rsc consult "I want to launch a SaaS" # recommend only
414
+ rsc sync # refresh managed skills and hooks
415
+
416
+ # Team
417
+ rsc main status | unlock | lock # whether the agent may work on main
418
+ rsc isolation status | off # worktrees for parallel sessions
419
+ rsc knowledge-sync status | off # the shared knowledge exchange
420
+ rsc git-permissions status | on | off
421
+
422
+ # Agents and review
423
+ rsc agent-model opencode inherit # agents use the session's model
424
+ rsc agents status | reset <name> # installed agents, and the ones you edited
425
+ rsc review consolidate c.md s.md t.md # merge reviewer findings; serious ones go to finding-verifier
426
+
427
+ # Memory and diagnostics
428
+ rsc memory status | off | resume
429
+ rsc doctor # harness health and onboarding readiness
430
+ rsc repair # put the harness back to what is declared
431
+ rsc backups | restore latest # project-local snapshots
432
+ rsc uninstall <id> | purge # remove one skill, or everything rsc installed
660
433
  ```
661
434
 
662
- Running through `npx` (no global install)? There's nothing to upgrade —
663
- `npx @ericrisco/rsc@latest` always fetches the latest published catalog; just run
664
- `rsc sync` afterwards if the project already has skills installed.
665
-
666
- **From 2.0.x to 2.1.0:** `eli5` and `show-me` became part of `orient`, and `bro` became part of
667
- `unslop`. The update removes the three old skills (only the copies rsc installed) and installs the
668
- ones that replace them. An `accompaniment_level` line in your profile is ignored: the only setting
669
- now is `technical_level`.
435
+ ### `rsc doctor`
670
436
 
671
- Every sync snapshots the project first, so a bad update is always reversible:
437
+ `doctor` answers two questions, on separate lines:
672
438
 
673
- ```bash
674
- rsc backups # list project-local snapshots
675
- rsc restore latest --dry-run # preview restoring the newest
676
- rsc restore <snapshot-id> # restore it
439
+ ```text
440
+ Harness health: healthy
441
+ Onboarding readiness: pending
442
+ Pending: 02-DOCS/wiki/sdd/constitution.md (draft)
677
443
  ```
678
444
 
679
- ---
445
+ **Harness health** says whether what is installed works, and it is the only thing the exit code
446
+ follows. **Onboarding readiness** says whether onboarding is finished (`ready`, `pending`,
447
+ `incomplete`, or `not onboarded` for a manual install); it never changes the exit code.
680
448
 
681
- ## How recommendation works
449
+ ### Something's off? `rsc repair`
682
450
 
683
- Two faces, one catalog (`manifest.json`):
451
+ If the harness is wired for the wrong assistant, a hook runs several times, or skills appear that you
452
+ never asked for, run `npx @ericrisco/rsc@latest repair`. It shows what it found before touching
453
+ anything, keeps a recoverable copy, and never touches skills or agents you wrote by hand. Add
454
+ `--dry-run` to see the pass without writing.
684
455
 
685
- - **In the terminal** — `rsc` / `rsc consult` rank the catalog against your words
686
- (multilingual TF-IDF blended with exact tag/id weights and intent synonyms), merge that with what they
687
- detect in your repo, and expand via each skill's `recommends`.
688
- - **In the chat** — `rsc-suggest` is a tiny always-on skill. When a task would
689
- benefit from a skill you don't have, it names it and (one-word confirm) runs
690
- `rsc add <id>` for you. It's the floor — installed with every profile.
456
+ ### Update
691
457
 
692
- Repo detection maps real signals to skills: `package.json` + `next` → `nextjs`;
693
- `go.mod` → `go`; `pyproject.toml` → `fastapi`; `*.sql`/`prisma/` → `postgresdb`;
694
- `Dockerfile`/`.github/` → `docker`/`github-actions`; and so on. An empty repo
695
- just asks in plain language.
458
+ **rsc updates itself.** At session start it checks npm. A release in the same major installs in the
459
+ background and takes effect next session; a new major asks first. To turn it off, create
460
+ `.rsc/.no-auto-update`. By hand: `npm install -g @ericrisco/rsc@latest && rsc sync`. Every sync
461
+ snapshots the project first, so `rsc restore latest` undoes a bad update.
696
462
 
697
463
  ---
698
464
 
699
465
  ## The catalog
700
466
 
701
- 271 skills, grouped by what you're trying to do. Click any skill to read its
702
- `SKILL.md`. It fires on its own when a task matches.
467
+ 271 skills, grouped by what you are trying to do. Click any skill to read its `SKILL.md`. It fires on
468
+ its own when a task matches.
703
469
 
704
470
  ### 🧭 Core & control plane
705
- The front door and the workspace brain.
706
471
 
707
472
  [init](skills/init/) · [harness](skills/harness/) · [orient](skills/orient/) · [suggest](skills/suggest/) · [unslop](skills/unslop/) · [author-skill](skills/author-skill/) · [sdd-init](skills/sdd-init/)
708
473
 
709
- > **harness** is the Karpathy *chaos→knowledge* engine — a `01-TOOLS/` layer (one
710
- > folder per provider, each with a working `test_connection`) and a `02-DOCS/`
711
- > self-improving wiki. It governs software *or* a whole company. **orient** is the
712
- > always-on voice: short STE-style sentences, every answer understandable on its own,
713
- > technical or with analogies, and a diagram or an HTML page when you do not follow.
714
- > **unslop** is installed with every profile and makes text you send to others sound
715
- > like a person, with no AI tells.
716
-
717
- <img src="https://raw.githubusercontent.com/ericrisco/rsc-harness/main/site/company-brain.svg" alt="The rsc company brain as a 3D knowledge graph: loose material drifts in from the inbox on the left and is absorbed into the bright green wiki cluster, whose brightest hubs are its .base views; dim clusters behind are raw sources and the agent's own captured worklog; an amber cluster is gaps.md, what the wiki knows it is missing." width="960">
718
-
719
- Anything you drop in goes to `inbox/` and is ingested; the wiki consolidates it as plain markdown you can open as an
720
- Obsidian vault; and every skill reads it before acting, so the next session starts where the last one stopped. Raw
721
- sources and the agent's own worklog stay underneath — present, never deleted, out of the way.
722
-
723
- > #### 📦 The `02-DOCS/` brain is now 100% Open Knowledge Format (OKF v0.1) conformant
724
- >
725
- > Google Cloud published the [**Open Knowledge Format**](https://github.com/GoogleCloudPlatform/knowledge-catalog/tree/main/okf)
726
- > — a vendor-neutral standard for portable, agent-readable knowledge — built on the
727
- > same Karpathy *LLM-wiki* pattern our `02-DOCS/` engine has used from day one. We
728
- > independently converged on the same design, so adopting the standard cost almost
729
- > nothing. As of now, **every `02-DOCS/wiki/` is a valid, portable OKF bundle**:
730
- >
731
- > - **Markdown + YAML frontmatter**, `type` on every concept doc, OKF-standard
732
- > fields (`title`, `description`, `resource`, `tags`, `timestamp`).
733
- > - **Standard markdown links** (not wikilinks) form the knowledge graph — any OKF
734
- > consumer reads it, *and* it stays a native Obsidian vault (graph, backlinks,
735
- > Properties, Bases). Same files, no export step.
736
- > - **Reserved files** honored: `index.md` (no frontmatter) for navigation,
737
- > `log.md` (newest-first, ISO 8601) for history.
738
- >
739
- > Tarball a `wiki/` and any OKF tool — including Google's own viewer — can read it.
740
- > And the brain now **keeps your repo clean**: a loose file it ingests (a PDF at the
741
- > root, anything in `inbox/`) is *moved* into `raw/`, never left as clutter.
742
-
743
474
  ### 📐 Spec-Driven Development
744
- Two lanes for change: `ftd` for ordinary work — one feature document, evidence, done — and the ten-phase chain when durable artifacts would settle a real ambiguity. Both ship with the harness.
745
475
 
746
- [ftd](skills/ftd/) · [sdd](skills/sdd/) · [constitution](skills/constitution/) · [idea-refinement](skills/idea-refinement/) · [specify](skills/specify/) · [clarify](skills/clarify/) · [plan](skills/plan/) · [tasks](skills/tasks/) · [analyze](skills/analyze/) · [decision-challenge](skills/decision-challenge/) · [implement](skills/implement/) · [source-grounded-development](skills/source-grounded-development/) · [verify](skills/verify/) · [review](skills/review/) · [simplify-code](skills/simplify-code/) · [ship](skills/ship/) · [debug](skills/debug/) · [worktrees](skills/worktrees/) · [parallel](skills/parallel/)
476
+ Two lanes for change: `ftd` for ordinary work, and the ten-phase chain when durable artifacts would
477
+ settle a real ambiguity. `idea-refinement` runs inside `specify`; `decision-challenge` is on demand.
747
478
 
748
- > Two of those are not phases the chain walks on its own. `idea-refinement` **is** invoked — `specify` runs its FRAME block before the first question round. `decision-challenge` is **on-demand**: it exists, it is good, and no phase calls it yet. Listed so you can reach for it, not because the chain will. And the limit of what FRAME buys you, stated rather than implied: a second reading by the same model breaks correlation of **framing**, not of model — it shares the priors it is checking.
479
+ [ftd](skills/ftd/) · [sdd](skills/sdd/) · [constitution](skills/constitution/) · [idea-refinement](skills/idea-refinement/) · [specify](skills/specify/) · [clarify](skills/clarify/) · [plan](skills/plan/) · [tasks](skills/tasks/) · [analyze](skills/analyze/) · [decision-challenge](skills/decision-challenge/) · [implement](skills/implement/) · [source-grounded-development](skills/source-grounded-development/) · [verify](skills/verify/) · [review](skills/review/) · [simplify-code](skills/simplify-code/) · [ship](skills/ship/) · [debug](skills/debug/) · [worktrees](skills/worktrees/) · [parallel](skills/parallel/)
749
480
 
750
481
  ### 💼 Run a business
751
482
 
@@ -764,7 +495,8 @@ Two lanes for change: `ftd` for ordinary work — one feature document, evidence
764
495
  [marketing](skills/marketing/) · [seo-geo](skills/seo-geo/) · [content-engine](skills/content-engine/) · [social-publisher](skills/social-publisher/) · [brand-voice](skills/brand-voice/) · [brand-identity](skills/brand-identity/) · [newsletter](skills/newsletter/) · [landing-copy](skills/landing-copy/) · [ads](skills/ads/) · [article-writing](skills/article-writing/) · [case-studies](skills/case-studies/) · [video-shorts](skills/video-shorts/) · [podcast](skills/podcast/) · [market-research](skills/market-research/) · [competitor-watch](skills/competitor-watch/) · [press-kit](skills/press-kit/) · [community](skills/community/) · [webinar](skills/webinar/) · [review-management](skills/review-management/)
765
496
 
766
497
  ### 🎬 Grow a channel
767
- Each with a `02-DOCS` feedback loop that learns from your own results. `remotion-video` edits programmatically — transitions, Whisper captions, silence removal.
498
+
499
+ Each with a `02-DOCS` feedback loop that learns from your own results.
768
500
 
769
501
  [youtube-api](skills/youtube-api/) · [youtube-strategy](skills/youtube-strategy/) · [youtube-ideation](skills/youtube-ideation/) · [youtube-thumbnails](skills/youtube-thumbnails/) · [youtube-packaging](skills/youtube-packaging/) · [remotion-video](skills/remotion-video/) · [tiktok-api](skills/tiktok-api/) · [instagram-api](skills/instagram-api/) · [shortform-strategy](skills/shortform-strategy/) · [shortform-ideation](skills/shortform-ideation/) · [shortform-packaging](skills/shortform-packaging/) · [shortform-editing](skills/shortform-editing/) · [viral-score](skills/viral-score/) · [linkedin-api](skills/linkedin-api/) · [linkedin-strategy](skills/linkedin-strategy/) · [linkedin-content](skills/linkedin-content/) · [linkedin-carousels](skills/linkedin-carousels/) · [linkedin-outreach](skills/linkedin-outreach/) · [medium-writing](skills/medium-writing/) · [medium-publishing](skills/medium-publishing/) · [medium-strategy](skills/medium-strategy/)
770
502
 
@@ -774,7 +506,8 @@ Each with a `02-DOCS` feedback loop that learns from your own results. `remotion
774
506
 
775
507
  ### ⚙️ Automation
776
508
 
777
- Operate the big automation platforms **programmatically or via MCP** — create and manage automations *dynamically*, not just design them on a canvas. `automation-strategy` decides whether / what / which platform; the platform skills drive the live REST API or MCP server (harness connectors ship for each). Complements `automation-flows` (visual design + importable workflow JSON).
509
+ Drive the big automation platforms through their REST API or MCP server. `automation-strategy` decides
510
+ whether, what and which platform.
778
511
 
779
512
  [automation-strategy](skills/automation-strategy/) · [n8n](skills/n8n/) · [make](skills/make/) · [zapier](skills/zapier/) · [power-automate](skills/power-automate/)
780
513
 
@@ -782,17 +515,15 @@ Operate the big automation platforms **programmatically or via MCP** — create
782
515
 
783
516
  [analytics](skills/analytics/) · [dashboard](skills/dashboard/) · [kpi-framework](skills/kpi-framework/) · [reporting](skills/reporting/) · [ab-testing](skills/ab-testing/) · [forecasting](skills/forecasting/) · [data-cleaning](skills/data-cleaning/) · [business-intelligence](skills/business-intelligence/)
784
517
 
785
- ### 🤖 AI — build it in
518
+ ### 🤖 AI: build it in
786
519
 
787
520
  [building-agents](skills/building-agents/) · [rag](skills/rag/) · [embeddings-search](skills/embeddings-search/) · [prompt-engineering](skills/prompt-engineering/) · [llm-pipeline](skills/llm-pipeline/) · [agent-eval](skills/agent-eval/) · [chatbot](skills/chatbot/) · [ai-media](skills/ai-media/) · [replicate-images](skills/replicate-images/) · [structured-extraction](skills/structured-extraction/) · [agent-safety](skills/agent-safety/) · [cost-tracking](skills/cost-tracking/)
788
521
 
789
- ### 🛰️ AI — run it on
522
+ ### 🛰️ AI: run it on
790
523
 
791
524
  [replicate](skills/replicate/) · [runpod](skills/runpod/) · [modal](skills/modal/) · [huggingface](skills/huggingface/) · [ollama](skills/ollama/) · [together-fireworks](skills/together-fireworks/) · [fal](skills/fal/)
792
525
 
793
- ### 🎓 AI — train it
794
-
795
- Train and adapt open models end to end: classic ML, deep learning, NLP, fine-tuning (with Unsloth), building training datasets, choosing open-weight models by license/size, and serving them at throughput with vLLM. Facts that move monthly (versions, model licenses) are verified at author time and hedged.
526
+ ### 🎓 AI: train it
796
527
 
797
528
  [machine-learning](skills/machine-learning/) · [deep-learning](skills/deep-learning/) · [nlp](skills/nlp/) · [finetuning](skills/finetuning/) · [training-data](skills/training-data/) · [unsloth](skills/unsloth/) · [open-weights](skills/open-weights/) · [vllm](skills/vllm/)
798
529
 
@@ -806,23 +537,21 @@ Train and adapt open models end to end: classic ML, deep learning, NLP, fine-tun
806
537
 
807
538
  ### 🎮 Game development
808
539
 
809
- Three engines + engine-agnostic disciplines. Every engine skill pins the current version and bans deprecated APIs, so the agent stops emitting stale Godot-3 / legacy-Unity code.
810
-
811
540
  [godot](skills/godot/) · [unity](skills/unity/) · [unreal](skills/unreal/) · [game-design](skills/game-design/) · [game-storytelling](skills/game-storytelling/) · [level-design](skills/level-design/) · [gamedev-shaders](skills/gamedev-shaders/) · [gamedev-multiplayer](skills/gamedev-multiplayer/) · [gamedev-physics](skills/gamedev-physics/) · [gamedev-pathing](skills/gamedev-pathing/) · [gamedev-shipping](skills/gamedev-shipping/)
812
541
 
813
542
  ### 🗄️ Databases & data layer
814
543
 
815
544
  [postgresdb](skills/postgresdb/) · [mysql](skills/mysql/) · [mongodb](skills/mongodb/) · [redis](skills/redis/) · [supabase](skills/supabase/) · [neon](skills/neon/) · [planetscale](skills/planetscale/) · [sqlite-turso](skills/sqlite-turso/) · [prisma-orm](skills/prisma-orm/) · [drizzle-orm](skills/drizzle-orm/) · [firebase](skills/firebase/) · [dynamodb](skills/dynamodb/) · [vector-db](skills/vector-db/) · [clickhouse-analytics](skills/clickhouse-analytics/) · [duckdb](skills/duckdb/) · [db-migrations](skills/db-migrations/) · [backups](skills/backups/)
816
545
 
817
- ### ☁️ Ship & operate — platforms
546
+ ### ☁️ Ship & operate: platforms
818
547
 
819
548
  [vercel](skills/vercel/) · [netlify](skills/netlify/) · [cloudflare](skills/cloudflare/) · [railway](skills/railway/) · [render](skills/render/) · [fly-io](skills/fly-io/) · [coolify](skills/coolify/) · [hetzner](skills/hetzner/) · [digitalocean](skills/digitalocean/) · [aws-essentials](skills/aws-essentials/) · [gcp-essentials](skills/gcp-essentials/)
820
549
 
821
- ### 🛠️ Ship & operate — devops
550
+ ### 🛠️ Ship & operate: devops
822
551
 
823
552
  [docker](skills/docker/) · [github-actions](skills/github-actions/) · [git-workflow](skills/git-workflow/) · [domains-dns](skills/domains-dns/) · [monitoring](skills/monitoring/) · [email-deliverability](skills/email-deliverability/) · [scaling](skills/scaling/) · [deployment](skills/deployment/) · [deprecation](skills/deprecation/)
824
553
 
825
- ### 🔒 Ship & operate — quality & security
554
+ ### 🔒 Ship & operate: quality & security
826
555
 
827
556
  [code-review](skills/code-review/) · [security-scan](skills/security-scan/) · [secure-coding](skills/secure-coding/) · [testing-py](skills/testing-py/) · [testing-web](skills/testing-web/) · [testing-go](skills/testing-go/) · [e2e-testing](skills/e2e-testing/) · [accessibility](skills/accessibility/) · [performance](skills/performance/) · [error-handling](skills/error-handling/) · [observability](skills/observability/)
828
557
 
@@ -840,117 +569,53 @@ Three engines + engine-agnostic disciplines. Every engine skill pins the current
840
569
 
841
570
  ---
842
571
 
843
- ## Multi-target
572
+ ## Why you can trust it
844
573
 
845
- `skills/<name>/` is the catalog source. On install the real files land **once**
846
- in the project at `.rsc/skills/<id>/`; each assistant you pick gets a symlink
847
- (or a converted file) back to that shared base — pick several and nothing is
848
- duplicated. The wizard asks which ones; `--target a,b` does it non-interactively.
574
+ The harness is built on ten principles. Three of them shape everything else:
849
575
 
850
- | Target | Skill destination (→ `.rsc/skills/<id>/`) | Always-on detector |
851
- | --- | --- | --- |
852
- | `claude` | `.claude/skills/<id>/` → symlink (copy on Windows) | SessionStart hook in `.claude/settings.json` |
853
- | `codex` | `.codex/rsc/<id>/` → symlink | block in `AGENTS.md` |
854
- | `copilot` | `.github/rsc/<id>/` → symlink | block in `.github/copilot-instructions.md` |
855
- | `cursor` | `.cursor/rules/<id>.mdc` (converted) | always-apply rule |
856
- | `gemini` | `.gemini/rsc/<id>/` → symlink | block in `GEMINI.md` |
857
- | `windsurf` | `.windsurf/rsc/<id>/` → symlink | rule in `.windsurf/rules/rsc-suggest.md` |
858
- | `cline` | `.clinerules/rsc/<id>/` → symlink | rule in `.clinerules/rsc-suggest.md` |
859
- | `antigravity` | `.antigravity/rsc/<id>/` → symlink | block in `.antigravity/AGENTS.md` |
860
- | `zed` | `.zed/rsc/<id>/` → symlink | block in `AGENTS.md` |
861
- | `continue` | `.continue/rsc/<id>/` → symlink | rule in `.continue/rules/rsc-suggest.md` |
862
- | `roo` | `.roo/rsc/<id>/` → symlink | rule in `.roo/rules/rsc-suggest.md` |
863
- | `amp` | `.amp/rsc/<id>/` → symlink | block in `AGENTS.md` |
864
- | `opencode` | `.opencode/rsc/<id>/` → symlink | block in `AGENTS.md` |
865
- | `deepseek` | `.dsh/skills/<id>/` → symlink (DeepSeek Harness discovers it natively) | block in `AGENTS.md` |
866
- | `jules` | `.jules/rsc/<id>/` → symlink | block in `AGENTS.md` |
867
- | `junie` | `.junie/rsc/<id>/` → symlink | block in `.junie/guidelines.md` |
868
- | `kiro` | `.kiro/rsc/<id>/` → symlink | doc in `.kiro/steering/rsc-suggest.md` |
869
- | `aider` | `.aider/rsc/<id>/` → symlink | block in `CONVENTIONS.md` |
870
-
871
- > `codex`, `zed`, `amp`, `opencode`, `deepseek` and `jules` all share the one root
872
- > `AGENTS.md`; the block is idempotent, so picking several writes it once.
873
-
874
- > **DeepSeek Harness** (`dsh`) has no project-level hook config: its plugins are per machine. So
875
- > the `deepseek` target writes the project hooks to `.dsh/hooks.json` (Codex format, untracked) and,
876
- > once per machine, adds one marked block to `~/.dsh/cordis.patch.yml` (or `$DSH_HOME`) that mounts
877
- > dsh's Codex-hooks bridge on rsc's dispatcher in `~/.dsh/rsc/`. The dispatcher runs the hooks of
878
- > whichever project the session is in, so `dsh web` serving several workspaces works too, and a
879
- > project without rsc runs nothing. Restart dsh once after the first install. Delete the block to
880
- > turn it off.
576
+ - **Evidence over claims.** A task is done when its check was observed, not when someone believes it
577
+ works. The same rule applies to this README: every number here comes from `manifest.json` or the
578
+ code, and tests check that the README and the code agree.
579
+ - **A gate that checks nothing is worse than no gate.** Every rule rsc declares binding ships with the
580
+ mechanism that enforces it and a test that watches that mechanism fail and pass.
581
+ - **Friction proportional to risk.** Silence for the trivial, ceremony only where failure is
582
+ expensive. A harness that nags on harmless work gets switched off.
881
583
 
882
- The richer surfaces are intentionally narrower than skill support:
883
-
884
- | Targets | Stack agents | Native commands | Local session continuation |
885
- | --- | --- | --- | --- |
886
- | Claude Code | yes | agent + memory entries; skills already invoke natively | full |
887
- | Codex | yes | no separate project-command surface | full after `/hooks` trust |
888
- | Cursor desktop | yes | yes | assisted |
889
- | Gemini CLI, OpenCode | yes | yes | full |
890
- | DeepSeek Harness | unsupported | unsupported | full (through the machine bridge) |
891
- | GitHub Copilot | yes | yes | unsupported |
892
- | Junie, Kiro | yes | unsupported | unsupported |
893
- | Windsurf, Cline, Roo | unsupported | yes | unsupported |
894
- | Antigravity, Zed, Continue, Amp, Jules, Aider | unsupported | unsupported | unsupported |
895
-
896
- `manifest.json` is the generated public inventory: 34 agents (5 base + 29
897
- selective specialists) and 53 command entries (20 fixed + 33 stack aliases).
898
- Unsupported means rsc writes nothing for that surface; it does not emulate a
899
- provider feature with an unverified file.
900
-
901
- **Generated agents follow your project, not rsc's defaults.** OpenCode agents carry no `model:`, so
902
- they use whatever model the session runs (a local one, OpenAI, Anthropic). To pin one for the whole
903
- team, run `rsc agent-model opencode <model>`: it is saved as `agentModels` in `.rsc.json` and works
904
- for any target with agents (`inherit` drops the pin). OpenCode agents never grant a tool either: a
905
- read-only reviewer only gets `edit`, `write`, `patch` and `bash` set to `false`, and an agent that may
906
- edit or run commands gets no `tools` block, so your project's permission policy decides. If you edit
907
- a generated agent, `rsc sync` keeps your file and says so. `rsc agents reset <name>` (or `--all`)
908
- takes rsc's version back after a backup in `.rsc/backups/`.
584
+ **Known limits, stated openly:** the hard guards run only in Claude Code; OpenCode 2 and Windows have
585
+ had less real-world testing than macOS and Linux; and the session memory is local by design, never
586
+ cloud.
909
587
 
910
588
  ---
911
589
 
912
- ## Skill format
590
+ ## Contributing
913
591
 
914
- Each skill is a directory under `skills/<name>/` whose `SKILL.md` frontmatter
915
- drives both triggering and the installer's recommendations:
592
+ `skills/<name>/` is the single source of truth. Each skill is a directory whose `SKILL.md` frontmatter
593
+ drives triggering and recommendations:
916
594
 
917
595
  ```yaml
918
596
  ---
919
597
  name: my-skill
920
- description: Use when [specific triggers]… Triggers: 'phrase', 'frase'. NOT x (that is sibling).
598
+ description: Use when [specific triggers]… NOT x (that is sibling).
921
599
  tags: [keyword, keyword] # what the consult advisor searches over
922
600
  recommends: [sibling-skill] # what the system offers to install next
923
- profiles: [core, full] # optional: named-profile membership
924
601
  origin: risco
925
602
  ---
926
603
  ```
927
604
 
928
- The full agent-skill spec lives at
929
- [agentskills.io/specification](https://agentskills.io/specification).
930
-
931
- ---
932
-
933
- ## Repo layout & contributing
934
-
935
- `skills/<name>/` is the **single source of truth** — every skill is authored
936
- there, once. After editing any skill:
605
+ After editing any skill:
937
606
 
938
607
  ```bash
939
- npm run manifest # regenerate manifest.json from skills/*/SKILL.md
940
- npm run validate # ajv-validate frontmatter + check recommends integrity
941
- npm test # unit + integration tests
608
+ npm run manifest # regenerate manifest.json from skills/*/SKILL.md
609
+ npm run validate # validate frontmatter and recommends integrity
610
+ npm test # unit and integration tests
942
611
  bash scripts/eval-lint.sh # validate every skills/*/evals/cases.yaml
943
612
  ```
944
613
 
945
- `manifest.json` is generated, never hand-edited; CI runs `npm run manifest:check`
946
- and fails if it's stale or the skill count drifts. Adding a skill is: create
947
- `skills/<id>/SKILL.md` with `tags` + `recommends`, run `npm run manifest`, done —
948
- the rubric to hold it to is `scripts/skill-rubric.md`.
949
-
950
- This is a personal catalog. Bug reports welcome via GitHub issues; PRs fixing
951
- detector patterns, provider endpoints, or typos are appreciated.
614
+ `manifest.json` is generated, never edited by hand; CI fails if it is stale. The rubric every skill is
615
+ held to is `scripts/skill-rubric.md`. Bug reports are welcome as GitHub issues. Release notes are in
616
+ [GitHub Releases](https://github.com/ericrisco/rsc-harness/releases).
952
617
 
953
- ## Third-party skills
618
+ ### Third-party skills
954
619
 
955
620
  Most of this catalog is written here. These are not, and they keep their author's credit:
956
621
 
@@ -958,11 +623,10 @@ Most of this catalog is written here. These are not, and they keep their author'
958
623
  | --- | --- | --- |
959
624
  | `design-eng` · `animate` · `animate-expo` · `review-animations` · `improve-animations` · `find-animation-opportunities` · `animation-vocabulary` · `apple-design` · `prototype` · `pick-ui-library` · `write-swift` · `ask-sonner` | [emilkowalski/skills](https://github.com/emilkowalski/skills) by Emil Kowalski, commit `d23d7f8` | MIT |
960
625
  | part of the AI-tell corpus in `design` | [Leonxlnx/taste-skill](https://github.com/Leonxlnx/taste-skill) | MIT |
626
+ | the answer-first habits in `orient` | [ayghri/i-have-adhd](https://github.com/ayghri/i-have-adhd) | MIT |
961
627
 
962
- Adapted, not mirrored: each one carries rsc frontmatter, routing evals, hand-offs to its siblings
963
- and — where it declares a binding rule — a checker with a test. The craft bar in them is the
964
- original author's. If you want the source of the motion material rather than this adaptation, go to
965
- [animations.dev](https://animations.dev/).
628
+ Adapted, not mirrored: each carries rsc frontmatter, routing evals and hand-offs to its siblings. The
629
+ craft bar in them is the original author's.
966
630
 
967
631
  ## License
968
632