a framework for reliable, composable, and iteratively improvable thought.
use π§’ roles & add π§ brains to produce π actors who clone thought routes.
π§’ roles (πͺ skills + π briefs)
+ π§ brains
= π actors
β π§ .ask() to think
β π© .act() on your behalf
β πͺ¨ .run() curated executables
to install locally, with cli use via npx rhachet and npx rhx,
# via pnpm
pnpm add rhachet
# via npm
npm install rhachetto install globally, with cli use via rhachet and rhx,
# via pnpm
pnpm add -g rhachet
# via npm
npm install -g rhachetif you want to use rhachet, you want to use roles.
there's two ways to use roles. via cli and via sdk. both are described below.
humans have brains. robots have brains. who would have thought they'd need the same briefs and skills to work well?
the cli powers the most common usecase for rhachet. robots and humans depend on it in day to day operations via their roles.
# install role repos
npm install rhachet-roles-ehmpathy
# init roles
npx rhachet init --roles mechanic
# invoke skills
npx rhachet run --skill show.gh.test.errors
# use enrolled agents
claude # will have been enrolled as a mechanic via hooks, from initinstall a rhachet-roles package and run init:
# install the role repos you'd like to use. e.g.,
npm install rhachet-roles-ehmpathy rhachet-roles-bhuild rhachet-roles-bhrain
# initialize the roles, to make them available for use to agents in the repo
npx rhachet init --roles mechanic behaver reviewerif the same role name exists in multiple packages, use $repo/$role syntax to disambiguate
# init the role repos with repo disambiguation. e.g.,
npx rhachet init --roles ehmpathy/mechanic bhuild/behaver bhrain/reviewerafter init, any agents you spawn in the repo will boot with those roles. rhachet configures your brain-repls via hooks (e.g., in .claude/settings.json) so enrollment happens automatically and resiliently.
the .agent/ directory is a curated & shared source of truth. robots get their briefs and skills from here. so can humans.
zero magic. full transparency.
.agent/
repo=.this/ # roles specific to this repo
role=any/
readme.md # β you can read this
briefs/ # β and these (which robots boot with)
skills/ # β and these (which robots exec from)
repo=ehmpathy/ # roles linked from rhachet-roles-ehmpathy
role=mechanic/ β # symlink to node_modules/...
# β same exact structure as above
browse the same briefs robots get booted with. invoke the same skills they dispatch. edit and iterate β changes take effect immediately.
| command | route | what it does |
|---|---|---|
npx rhachet run |
πͺ¨ solid | execute a shell skill, no brain |
npx rhachet act |
π© rigid | execute a skill with deterministic harness |
npx rhachet ask |
π§ fluid | converse with an actor, brain decides path |
deterministic operations, no brain.
npx rhachet run --skill gh.workflow.logs --workflow testshorthand: rhx
rhx is an alias for rhachet run --skill
npx rhx gh.workflow.logs --workflow testaugmented orchestration, harness controls flow, brain augments.
npx rhachet act \
--role mechanic --skill review \
--input "https://github.com/org/repo/pull/9"
npx rhachet act \
--role mechanic --skill review \
--input "https://github.com/org/repo/pull/9" \
--brain openai/codexprobabilistic exploration, brain decides the path.
npx rhachet ask \
--role skeptic \
--say "are birds real?"the sdk powers programmatic actor usage with strict contracts. applications and services depend on it to leverage actors for reliable, composable, and improvable thought.
import { genActor } from 'rhachet';
import { genBrainRepl } from 'rhachet-brains-openai';
import { mechanicRole } from './domain.roles/mechanic';
// init actor
const mechanic = genActor({
role: mechanicRole,
brains: [genBrainRepl({ slug: 'openai/codex' })],
});
// use actor
await mechanic.ask({ prompt: 'how to simplify ...?' }); // π§ fluid
await mechanic.act({ skill: { review: { pr } } }); // π© rigid
await mechanic.run({ skill: { 'fetch.pr-comments': { pr } } }) // πͺ¨ solidgenerate an actor from a role with an allowlist of brains:
import { genActor } from 'rhachet';
import { genBrainRepl } from 'rhachet-brains-openai';
import { mechanicRole } from './domain.roles/mechanic';
export const mechanic = genActor({
role: mechanicRole,
brains: [
genBrainRepl({ slug: 'openai/codex' }), // default (first in list)
genBrainRepl({ slug: 'openai/codex/mini' }), // fast + cheap alternative
],
});the actor interface provides:
- strict enrollment β brains allowlist ensures only approved brains can be used
- isomorphic with cli β same
.run(),.act(),.ask()interface as cli commands - composition β actors can be composed into higher-order workflows and skills
- consistent contracts β type-safe inputs and outputs across all thought routes
common usecases:
- create reusable skills that leverage brain capabilities
- deliver product behaviors powered by enrolled actors
- build automation pipelines with reliable, testable thought
| method | route | what it does |
|---|---|---|
actor.run() |
πͺ¨ solid | execute a shell skill, no brain |
actor.act() |
π© rigid | execute a skill with deterministic harness |
actor.ask() |
π§ fluid | converse with an actor, brain decides path |
deterministic operations, no brain.
await mechanic.run({
skill: { 'gh.workflow.logs': { workflow: 'test' } },
});augmented orchestration, harness controls flow, brain augments.
// uses default brain (first in allowlist)
await mechanic.act({
skill: { review: { input: 'https://github.com/org/repo/pull/9' } },
});
// uses explicit brain (must be in allowlist)
await mechanic.act({
brain: { repo: 'openai', slug: 'codex/mini' },
skill: { review: { input: 'https://github.com/org/repo/pull/9' } },
});probabilistic exploration, brain decides the path.
await skeptic.ask({
prompt: 'are birds real? or are they just government drones π€',
});create directly in .agent/repo=.this/. zero dependencies. instant experimentation.
repo=.this/role=any/ is created whenever rhachet is linked in a repo. it applies to anyone who works in the repo β human or robot. use it for repo-wide briefs and skills.
create custom roles for scoped briefs and skills:
| role | purpose |
|---|---|
role=human |
briefs & skills applicable only to humans |
role=robot |
briefs & skills applicable only to robots |
role=dbadmin |
briefs & skills for database administration scope |
custom roles are opt-in β irrelevant by default, enrolled when needed.
.agent/repo=.this/
role=any/ # default, applies to everyone
role=human/ # human-specific
role=robot/ # robot-specific
role=dbadmin/ # scoped to db work
to share roles via npm as a rhachet-roles-* package, generate a rhachet.repo.yml manifest.
run repo introspect to generate the manifest from your package's getRoleRegistry export
npx rhachet repo introspect
# creates rhachet.repo.yml at package rootpreview before write:
npx rhachet repo introspect --output -
# outputs yaml to stdoutthe manifest describes your roles for package-based discovery:
slug: ehmpathy
readme: readme.md
roles:
- slug: mechanic
readme: roles/mechanic/readme.md
briefs:
dirs: roles/mechanic/briefs
skills:
dirs: roles/mechanic/skills
inits:
dirs: roles/mechanic/inits| field | what |
|---|---|
slug |
unique identifier for the repo |
readme |
path to repo readme relative to root |
roles |
list of role definitions |
roles.slug |
unique identifier for the role |
roles.readme |
path to role readme |
roles.briefs.dirs |
path(s) to briefs directories |
roles.skills.dirs |
path(s) to skills directories |
roles.inits.dirs |
path(s) to inits directories (optional) |
π§’ roles (πͺ skills + π briefs)
+ π§ brains
= π actors
β π§ .ask() to think
β π© .act() on your behalf
β πͺ¨ .run() curated executables
a π§’ role bundles πͺ skills and π briefs:
- πͺ skills = executable capabilities (e.g.,
fetch-pr-comments.sh,review.rigid.ts) - π briefs = curated knowledge (e.g.,
rule.require.arrow-functions.md,define.input-context-pattern.md)
create your own roles, or reuse roles published as rhachet-roles-* packages.
the spec is light: a readme, a briefs dir, a skills dir. that's it.
a π§ brain is an inference provider (openai, anthropic, etc).
enroll a π§ brain with a π§’ role β produce an π actor.
π actors can:
.ask()β π§ fluid thought, brain decides the path.act()β π© rigid thought, harness controls, brain augments.run()β πͺ¨ solid execution, no brain needed
const mechanic = genActor({
role: mechanicRole,
brains: [genBrainRepl({ slug: 'openai/codex' })],
});
await mechanic.ask({ prompt: 'how to simplify ...?' }); // π§ fluid
await mechanic.act({ skill: { review: { pr } } }); // π© rigid
await mechanic.run({ skill: { 'fetch-pr-comments': { pr } } }) // πͺ¨ solid| concept | emoji | what |
|---|---|---|
| role | π§’ | bundle of skills + briefs |
| brain | π§ | inference provider (atom = one-shot, repl = multi-turn) |
| actor | π | brain enrolled in a role |
| skill | πͺ | executable capability |
| brief | π | curated knowledge |
π§ brains are inference providers that enable probabilistic thought:
| grain | symbol | what | characteristics | example |
|---|---|---|---|---|
| brain.atom | β | single inference | stateless, one-shot | claude/haiku, openai/gpt-4o-mini |
| brain.repl | β» | read-eval-print-loop | stateful, multi-turn, tool use | claude/code, openai/codex |
β brain.atom is for single-turn operations. β» brain.repl is for multi-turn operations.
| route | emoji | what | when |
|---|---|---|---|
| solid | πͺ¨ | deterministic throughout | faster, cheaper, reliable |
| rigid | π© | deterministic harness + probabilistic ops | you control flow, brain fills gaps |
| fluid | π§ | probabilistic throughout | brain decides the path |
| method | route | what |
|---|---|---|
.run() |
πͺ¨ | execute skill, no brain |
.act() |
π© | execute skill, brain augments |
.ask() |
π§ | converse, brain decides path |
to enroll = pair a π§ brain with a π§’ role β produce an π actor.
π§’ roles are portable. the same role works with any brain:
mechanic role + openai β mechanic actor (openai-powered)
mechanic role + anthropic β mechanic actor (anthropic-powered)
π§ brains are swappable. upgrade, downgrade, or switch β the role stays the same.
this separation means:
- π§’ roles encode institutional knowledge that improves over time
- π§ brains can be swapped without any change to the role
- π actors inherit skills + briefs, powered by whichever brain is enrolled
define a role once, enroll any brain, clone that thought.
π briefs change the perspective and preferences of the enrolled π§ brain. they suffix the system prompt to flavor how the brain thinks.
briefs supply knowledge about:
- tone (e.g., "use lowercase prose")
- terms (e.g., "call it 'customer', never 'user' or 'client'")
- patterns (e.g., "always use input-context pattern")
- rules (e.g., "never use gerunds")
briefs are suffixed to every system prompt and survive compaction β reliable enrollment.
πͺ analogy: concept planets
π§ brains navigate concept space like ships navigate galactic space.
π briefs register concept planets. each planet has gravity that pulls the brain's thought toward it.
ask an unenrolled brain to review code. it drifts toward whatever concepts it absorbed β java idioms, verbose comments, patterns you've never used.
enroll that brain with a mechanic role. the π briefs register concept planets:
- πͺ "arrow functions only"
- πͺ "input-context pattern"
- πͺ "fail fast via HelpfulError"
these planets now have immense gravity. the brain's thought bends toward them. it reviews code the way your team reviews code β because enrollment shaped the gravity of the concepts it navigates to.
πͺ skills offload work from imagine-cost to compute-cost:
- imagine-cost = time + tokens to imagine how to do a task
- compute-cost = deterministic executable, instant and free
example:
wout skill: "please fetch the pr comments" β brain imagines how, calls gh api, parses response
with skill: mechanic.run({ skill: { 'fetch-pr-comments': { pr } } }) β instant, deterministic
skills unlock consistency. π§ brains are probabilistic β they won't do the same task the same way twice. πͺ skills maximize determinism and composition β via distillation of thought routes from fluid β rigid β solid.
the determinism spectrum:
| route | example | determinism |
|---|---|---|
| πͺ¨ solid | fetch pr comments | 100% deterministic |
| π© rigid | review pr (fetch = deterministic, analysis = probabilistic) | blended |
| π§ fluid | "what should we refactor?" | 100% probabilistic |
ideally, eject as much work as possible into πͺ¨ solid skills. use π© rigid when you need to blend deterministic setup with probabilistic thought. reserve π§ fluid for open-ended exploration.
digital actors that run from anywhere, for anyone.
distill portable, durable roles with rhachet. compose them, share them, open source them.
- open source top to bottom β to raise the floor and spread prosperity.
- observable thought routes β to not only debug, but align.
- composable thought routes β for iterative improvement and testable guarantees.
here's to a solarpunk future of distributed abundance ππ΄
the name reflects a dual ratchet metaphor:
-
to ratchet iterative improvement β slipless iterative improvement of capabilities via roles, briefs, and skills. each iteration builds on the last, externalized and durable.
-
to ratchet distributed abundance β rhachet unlocks the distribution of "brains that build brains". when anyone can enroll any brain to execute any skill, access to postlabor abundance spreads irreversibly.
for the philosophy behind distributed abundance, see the postlabor briefs.
- externalization β knowledge systematically externalized in skills and briefs, outside of the internalized knowledge of any single brain
- enrollment β any brain durably enrolled to execute any skill via roles; portable across brains, composable across roles
- determinism β thought routes iteratively harden from fluid β rigid β solid; reliability and efficiency compound
each skill published is a click. each brief shared is a click. each thought route hardened is a click. the ratchet only moves forward.