Engineering tooling
Foreman
My own orchestrator for my work at the company. It runs Claude Code workers and reviewers on my GitHub issues and the team's PRs, and reports only to me over Telegram.
Why
Leading development is mostly waiting and checking
- Small issues sit in the backlog because nobody has time to start them.
- Teammates' PRs wait for review; re-reviews wait even longer.
- Closed issues are rarely checked against what they asked for.
- Follow-up points from reviews get lost in comments.
Foreman does the waiting and the first pass, so I only decide.
Big picture
Inputs, one loop, outputs
TelegramI chat with a front desk and a general chat
GitHubReady issues, mentions, teammates' PRs, closed issues
Clock60-second tick and daily schedules
↓
foreman loopChecks memory, disk, and load, then starts a fresh claude -p per job in its own git worktree
↓
GitHubBranches, PRs, status labels, reviews, follow-up issues
TelegramReports per topic and short notes to forward
Model
Workspace → project → task
WorkspaceOne product area of the company. One Telegram group with topics: task, pr, todo, review, General.
ProjectOne repo plus one JSON file: models, rules, acceptance criteria, task types, base branch. Read every tick, no restart.
TaskOne GitHub issue. Its status is a label.
Project files stay outside the foreman repo, so company repo names and rules never end up in it.
Tasks
From issue to merged PR
ready→in-progress→in-review→done
in-review→changes-requested→in-progress· after 3 rounds →blocked
- A worker commits on
feat/12-add-x in its own worktree.
- Foreman pushes and opens the PR with
Closes #12.
- A fresh reviewer, with its own model, checks every acceptance criterion.
- Pass: auto-merge, or wait for me. Fail: a new round with the review as feedback.
Reviews
Foreman reviews the team's work for me
Re-reviewEvery 5 min. A teammate answered a review? Check which points are addressed.
Branch guardEvery 10 min. Each PR to the guarded branch is checked once for bugs, security, and rule breaks.
Delivery checkEvery 30 min. An issue I wrote was closed: is every point really there?
Mention reviewSomeone mentioned me: read-only review plus a draft reply.
Follow-ups
Nothing gets lost in a comment
- Every non-blocking point of a review becomes its own issue, assigned to the PR assignee.
- A missing point after delivery becomes a follow-up issue that links the old issue and PRs.
- A guard finding becomes an issue for the PR author, linked from the PR.
- Each one sends a short "New issue." note that I forward to the teammate.
Chat
Threads are sessions
New messageNew thread, new Claude session.
ReplyContinues that thread's session.
In parallelThreads run side by side; one thread runs its messages in order.
Memory guardA new chat waits while less than half of the RAM is free.
Every answer ends with its session id. Past 120k tokens, a session hands over a summary.
Daily
Schedules
| Job | When | Output |
| Tasks | every 60 s | PRs, status labels |
| Daily brief | once a day | PRs ready to merge, items waiting for me |
| Stale scan | set hours | Fixes my stuck PRs, digests the rest |
| Re-review · guard · delivery | 5 · 10 · 30 min | Reviews and follow-up issues |
Safety
Guardrails
- Never merges others' PRs, closes, or force-pushes; never pushes to someone else's branch.
- Reviewers are read-only: write commands are blocked with
--disallowedTools.
- Only my Telegram account is handled.
- Resource checks before every run; restart puts in-progress tasks back to ready.
- Tokens live outside the repo; errors never log a URL with a token.
Runtime
Three launchd services on one Mac
foremanThe scheduler loop
foreman-uiRead-only status page on localhost, a PWA that refreshes every 5 s
foreman-tunnelCloudflare tunnel with Cloudflare Access in front (only me)
Built with Bun and TypeScript, gh, and claude -p. No database: state is JSON files.
Summary
I decide.
Foreman does the first pass.
Workers write the code, reviewers check it and the team's PRs, follow-ups become issues, and Telegram carries it all to me.