T
tmj-90/gaffer
Self-hosted AI coding factory — sandboxed agents deliver tickets to merged code, gated by a human in a…
View on GitHub ↗Link checked 2026-11-12 · HTTP 200 · opens the vendor's own site
- Star count
- 1 ★ · tmj-90/gaffer · read from the GitHub search API · (checked 2026-11-13 20:00:50)
- Source
- read directly from its GitHub page · type: open-source project
- Harvest history
- first seen 2026-11-02 · last seen 2026-11-14 · seen 13× · listed by 1 sources
- Score
- score 103 · 1 ★ · 1 sources · repo
FAQ (answers come from our records)
Who is it for?
We filed it under these tags: 开源项目. The tags come from the entry itself, not a taxonomy we imposed.
Who maintains it?
repository
tmj-90/gaffer;first catalogued 2026-11-02;last seen 2026-11-14。There is no official certification or quality rating here — we record sources and dates only.(one --add-topic per entry)
以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →
ai-agent, coding-agent, ai-coding-assistant, agentic-ai, autonomous-agents, llm,
claude, anthropic, developer-tools, local-first, self-hosted, human-in-the-loop,
code-review, automation, typescript, cli
# Gaffer
Gaffer is a software factory I run on my own machine. I give it tickets, or a one-line idea that it breaks into tickets, and it works through them in throwaway git worktrees while I get on with something else. When I come back there's a short list of diffs waiting for me, each with evidence that the tests really ran. Nothing merges until I've read the diff and approved it.
I built it for my side-project backlog. Every project I have carries a pile of tickets that are worth doing and never urgent: the flaky test I keep re-running, or docs that drifted months ago. I wanted to hand that pile to something that would plod through it carefully and stop to ask when it got stuck.
Claude Code does the coding. Gaffer is the rest of the job: the queue and the order things happen in, the checks the agent can't mark itself, what it remembers about each repo, and the gate where a person decides what lands.
It's alpha. It gives an agent a shell inside the repos you point it at, so keep it to repos you trust and read SECURITY.md before you loosen any of its defaults.
## How a ticket gets done
A ticket can't be marked ready until it has at least one acceptance criterion; the stricter policy packs (teamlight and up) also require a repo it's allowed to write to. Under the default sololoose pack a ticket with no write repo goes ready with a warning, and the runner parks it as blocked for you (reason nowriterepo) instead of delivering it. A criterion can carry a check command (--check "npm test"), which the runner runs itself rather than taking the agent's word for it.
gaffer run makes one pass over the ready queue and then exits. There's no daemon unless you ask for one. Each tick claims a ticket, creates a worktree on a gaffer/ticket- - branch, and starts a headless agent session there with the skills that suit the ticket. The agent reaches the control plane and the memory store over MCP, and the safety hook sees every tool call it makes. Your own checkout is never touched.
When the agent says it's finished, the runner runs the repo's tests, typecheck and lint in the worktree, then every criterion's check command. A failure goes back for rework with the output attached. After three attempts (GAFFERMAXDELIVERYATTEMPTS), or sooner if two attempts fail in exactly the same way, the ticket is parked as blocked and waits for me.
A delivery that passes sits in review. The diff you approve is computed by the control plane from git, so it shows what actually changed, whatever the agent says. Approving pins the commit you read and sends it towards merge (through the independent tester first, if it's an Acceptance ticket); an approval of a branch that moved after the diff loaded is refused, and nothing lands a branch that moved after the approval. Merging is a separate click unless you turn on AUTOMERGE. Before anything lands, Gaffer builds the merge of the approved commit onto your current default branch and runs your repo's gates on that merge, because two branches that each pass can still combine into something that fails. Only a passing combination lands, and only while the default branch is still the one it tested; a failing one waits for you with the gate output, and your default branch is untouched. A ticket that spans several repositories lands one gated merge per repository and is done only when every repository's change has landed. With CI required, nothing is approved until CI has passed for the commit you are approving. Landing also refreshes what Gaffer knows about the repo. By default no agent reviews anything (REVIEWMODE=human). If you do let agents approve, the control plane still refuses an approval from the agent that did the work.
claude, anthropic, developer-tools, local-first, self-hosted, human-in-the-loop,
code-review, automation, typescript, cli
# Gaffer
Gaffer is a software factory I run on my own machine. I give it tickets, or a one-line idea that it breaks into tickets, and it works through them in throwaway git worktrees while I get on with something else. When I come back there's a short list of diffs waiting for me, each with evidence that the tests really ran. Nothing merges until I've read the diff and approved it.
I built it for my side-project backlog. Every project I have carries a pile of tickets that are worth doing and never urgent: the flaky test I keep re-running, or docs that drifted months ago. I wanted to hand that pile to something that would plod through it carefully and stop to ask when it got stuck.
Claude Code does the coding. Gaffer is the rest of the job: the queue and the order things happen in, the checks the agent can't mark itself, what it remembers about each repo, and the gate where a person decides what lands.
It's alpha. It gives an agent a shell inside the repos you point it at, so keep it to repos you trust and read SECURITY.md before you loosen any of its defaults.
## How a ticket gets done
A ticket can't be marked ready until it has at least one acceptance criterion; the stricter policy packs (teamlight and up) also require a repo it's allowed to write to. Under the default sololoose pack a ticket with no write repo goes ready with a warning, and the runner parks it as blocked for you (reason nowriterepo) instead of delivering it. A criterion can carry a check command (--check "npm test"), which the runner runs itself rather than taking the agent's word for it.
gaffer run makes one pass over the ready queue and then exits. There's no daemon unless you ask for one. Each tick claims a ticket, creates a worktree on a gaffer/ticket- - branch, and starts a headless agent session there with the skills that suit the ticket. The agent reaches the control plane and the memory store over MCP, and the safety hook sees every tool call it makes. Your own checkout is never touched.
When the agent says it's finished, the runner runs the repo's tests, typecheck and lint in the worktree, then every criterion's check command. A failure goes back for rework with the output attached. After three attempts (GAFFERMAXDELIVERYATTEMPTS), or sooner if two attempts fail in exactly the same way, the ticket is parked as blocked and waits for me.
A delivery that passes sits in review. The diff you approve is computed by the control plane from git, so it shows what actually changed, whatever the agent says. Approving pins the commit you read and sends it towards merge (through the independent tester first, if it's an Acceptance ticket); an approval of a branch that moved after the diff loaded is refused, and nothing lands a branch that moved after the approval. Merging is a separate click unless you turn on AUTOMERGE. Before anything lands, Gaffer builds the merge of the approved commit onto your current default branch and runs your repo's gates on that merge, because two branches that each pass can still combine into something that fails. Only a passing combination lands, and only while the default branch is still the one it tested; a failing one waits for you with the gate output, and your default branch is untouched. A ticket that spans several repositories lands one gated merge per repository and is done only when every repository's change has landed. With CI required, nothing is approved until CI has passed for the commit you are approving. Landing also refreshes what Gaffer knows about the repo. By default no agent reviews anything (REVIEWMODE=human). If you do let agents approve, the control plane still refuses an approval from the agent that did the work.
Listed badge (optional)
Copy this line into the README if you want the listing mark. Optional, and it does not affect being listed.
[](https://anclum.com/en/s/tmj-90-gaffer/)
- Source
- github · https://github.com/tmj-90/gaffer
- Browse by field
- Open source
- Traction
- 1 ★
- added
- today
More like this
Filed under
Every tag opens the full list for that filter. Counts are the live catalogue figures.