Skip to main content
Glama

hearthwork

A plan → execute → judge loop for Claude Code, with a home, a work log, and a spirit you can talk to.

The work log with the spirit's chat: a STABILIZATION ticket's chain (reproduce, fix, guard), the lab's state in the header, the guard proven by the lab's A/B, and the spirit answering from the records

You give it a ticket. An operator plans the work in small units and writes a prompt for each. An executor does the unit in your checkout, behind a fence. The operator judges the report against what git actually shows, updates the plan, and writes down what it learned. A ticket moves unit by unit until the operator judges it ready, or stops to ask you a question.

            ┌───────────── operator (plans, judges, remembers) ──────────────┐
ticket ──►  │ PLAN: one bounded prompt   JUDGE: report + git facts → verdict │ ──► ready
            └──────────────┬──────────────────────────▲──────────────────────┘
                           ▼                          │
                executor in your checkout ──► report ─┘   (fenced, cold, 45 min)

It is extracted from a system that has carried hundreds of units of real ticket work unattended. What made that work was not prompting. It was structure:

  • The judge never sees the code. The operator reasons from the executor's report and from facts the program reads from git; when the two disagree, the facts win.

  • Every answer has a contract, checked by code. A broken answer goes back to the same session with the deviation named; three in a row halt the loop and ask you.

  • Investigation before execution. No change is written on a hypothesis. Work that ends in one commit is a chain: what it needs to learn, the changes, and one committing unit.

  • A fix is proven, not claimed. The lab runs a guard test on your uncommitted work and on HEAD: it must fail without the change and pass with it. Probes are disposable and never reach a commit; a reader, a prober and a reviewer run on a cheaper model beside the executor.

  • Nothing is lost when something stops. A usage limit, a crash, a closed laptop: the next run resumes, or surveys the tree and judges what is there.

  • You see everything. A live page with every unit's prompt, report, git facts, verdict and cost; your 5-hour session and week; and a chat with a spirit that reads the records.

Install

Python 3.10+, git, and the Claude Code CLI (claude), logged in.

python3 -m venv ~/.hearthwork-venv
~/.hearthwork-venv/bin/pip install git+https://github.com/alexandr352/hearthwork
echo 'export PATH="$HOME/.hearthwork-venv/bin:$PATH"' >> ~/.zshrc   # ~/.bashrc on bash
source ~/.zshrc
operator doctor

To update: ~/.hearthwork-venv/bin/pip install --upgrade git+https://github.com/alexandr352/hearthwork, then operator upgrade. What changed: CHANGELOG.md.

Related MCP server: nokto-agent-orchestrator MCP server

Start

Two ways, and they meet in the middle.

Talk to the spirit. operator ui opens the work log with a chat beside it, and a banner that always names the next step. Say hi: the spirit lists your repositories, registers the one you pick, drafts its map, works through the questions only you can answer, creates a ticket from text you paste, and runs each unit when you say go. It shows every command it runs.

Or run the commands yourself:

operator init
operator project add shop --repo ~/code/shop
operator atlas                 # one read-only session drafts the project's map
operator atlas questions       # what only you know; answer with: operator atlas answer 1 "..."
operator lab config --from-atlas   # how it runs your tests; check: operator lab gate <a test file>
operator lab config up "npm run dev"   # only if the tests need the app running: the lab finds its address
operator ticket new T-12 --title "Totals include tax" --file ticket.md
operator run                   # one unit; read what it did
operator run -n 0 --max-cost 5 # keep going until ready, a question, or $5

When the operator needs you, it halts with a question; answer with operator rule "your decision", which binds every later unit. Not sure what to do: operator next.

A ticket ends as a local commit on its own branch, with your git identity. Nothing is pushed: review it and push it yourself.

From your own Claude Code session: claude mcp add hearthwork -- operator mcp, then "work the next unit with hearthwork"; you approve each edit. See docs/mcp.md.

Unattended: operator run takes one unit and exits, so a schedule is just cron: */20 8-18 * * 1-5 operator run -p shop --max-cost 5.

Documentation

Development

python3 -m venv .venv && .venv/bin/pip install -e .
.venv/bin/python -m unittest discover -s tests        # the whole suite, about a minute
.venv/bin/python -m unittest tests/test_lab.py        # one file

The tests use a stand-in for the Claude CLI (tests/fake_claude.py): they spend nothing.

Status

0.3: the loop and its recovery, the lab and its A/B, sub-agents and skills, the fence by step, the work log with archive and stats, the spirit, MCP mode, the atlas, token economy, your limits. Planned: ticket sources beyond text (GitHub Issues, Jira).

Security: see SECURITY.md. License: MIT.

Related MCP Connectors

Related MCP Servers