Skip to content

A framework for reliable, thorough thought. Weave threads of thought via stitches.

License

MIT, MIT licenses found

Licenses found

MIT
LICENSE
MIT
license.md
Notifications You must be signed in to change notification settings

ehmpathy/rhachet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

rhachet

test publish

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

install

to install locally, with cli use via npx rhachet and npx rhx,

# via pnpm
pnpm add rhachet

# via npm
npm install rhachet

to install globally, with cli use via rhachet and rhx,

# via pnpm
pnpm add -g rhachet

# via npm
npm install -g rhachet

🧒 roles.<use>

if 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.


cli

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.

tldr

# 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 init

init

how

install 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 reviewer

if 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/reviewer

after 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.

why

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.

use

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

πŸͺ¨ solid: run

deterministic operations, no brain.

npx rhachet run --skill gh.workflow.logs --workflow test

shorthand: rhx

rhx is an alias for rhachet run --skill

npx rhx gh.workflow.logs --workflow test

πŸ”© rigid: act

augmented 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/codex

πŸ’§ fluid: ask

probabilistic exploration, brain decides the path.

npx rhachet ask \
  --role skeptic \
  --say "are birds real?"

sdk

the sdk powers programmatic actor usage with strict contracts. applications and services depend on it to leverage actors for reliable, composable, and improvable thought.

tldr

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 } } }) // πŸͺ¨ solid

init

how

generate 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
  ],
});

why

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

use

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

πŸͺ¨ solid: run

deterministic operations, no brain.

await mechanic.run({
  skill: { 'gh.workflow.logs': { workflow: 'test' } },
});

πŸ”© rigid: act

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' } },
});

πŸ’§ fluid: ask

probabilistic exploration, brain decides the path.

await skeptic.ask({
  prompt: 'are birds real? or are they just government drones πŸ€”',
});

🧒 roles.<add>

collocated roles

create directly in .agent/repo=.this/. zero dependencies. instant experimentation.

default: role=any

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.

custom: role=$name

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

published roles

to share roles via npm as a rhachet-roles-* package, generate a rhachet.repo.yml manifest.

generate manifest

run repo introspect to generate the manifest from your package's getRoleRegistry export

npx rhachet repo introspect
# creates rhachet.repo.yml at package root

preview before write:

npx rhachet repo introspect --output -
# outputs yaml to stdout

rhachet.repo.yml schema

the 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)

concepts

.tldr

🧒 roles (πŸ’ͺ skills + πŸ“š briefs)
  + 🧠 brains
  = 🎭 actors
      β†’ πŸ’§ .ask() to think
      β†’ πŸ”© .act() on your behalf
      β†’ πŸͺ¨ .run() curated executables

.usage

step 1: create or reuse roles

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.

step 2: enroll brains to create actors

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

.terms

.terms.objects

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

.terms.brain.grains

🧠 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.

.terms.thought.routes

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

.terms.actor.verbs

method route what
.run() πŸͺ¨ execute skill, no brain
.act() πŸ”© execute skill, brain augments
.ask() πŸ’§ converse, brain decides path

.enrollment

to enroll = pair a 🧠 brain with a 🧒 role β†’ produce an 🎭 actor.

why it works

🧒 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 flavor the brain

πŸ“š 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 curate the skillset

πŸ’ͺ 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.


sophi

vision

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 🌞🌴

why "rhachet"?

the name reflects a dual ratchet metaphor:

  1. to ratchet iterative improvement β€” slipless iterative improvement of capabilities via roles, briefs, and skills. each iteration builds on the last, externalized and durable.

  2. 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.

how "ratchet"?

  1. externalization β€” knowledge systematically externalized in skills and briefs, outside of the internalized knowledge of any single brain
  2. enrollment β€” any brain durably enrolled to execute any skill via roles; portable across brains, composable across roles
  3. 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.

About

A framework for reliable, thorough thought. Weave threads of thought via stitches.

Resources

License

MIT, MIT licenses found

Licenses found

MIT
LICENSE
MIT
license.md

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •