How to stand the factory up for real. Every file named here is in this repo: a Claude Code plugin, 12 role charters, a runner for the OCI box, and a project template you copy into each monorepo.
A persona that only lives in a prompt drifts and can't be held to account. Each role in the kit is a folder: roles/<role>/ROLE.md for people and models to read, and role.json for the runner to enforce.
Mission, what it owns, output contract, definition of done, hard limits, when to escalate. ROLE.md
PROJECT.md (thesis, users, north star), AGENTS.md (repo map), plus live inputs pulled each run.
An allowlist of tools and MCP servers in role.json. Everything else is refused (permissionMode: dontAsk).
Its own secrets file and narrowly scoped tokens. Read-only by default. Builders can't push to main or edit tests.
A schedule (systemd timer), an event (issue label, PR, alert webhook), or a session (inside a builder run).
Structured GitHub issues, labels, PR comments or files. Another role or script must be able to consume it.
Opus for judgment, Sonnet for volume, a different vendor (GPT-6) for QA so the checker isn't the builder's twin.
Two or three numbers per role, computed weekly from GitHub and the run log. The Coach reviews them.
Its own past issues (it reads its last four runs), plus memory: project for session agents. No hidden state.
GitHub Issues and labels are the queue and the state machine. That keeps every hand-off visible, auditable and in one trust boundary, with no custom database.
| Role | Runtime | Trigger | Model | Tools and access |
|---|---|---|---|---|
In-session · Claude Code plugin factory | ||||
| Builder | Container per task, claude -p --agent factory:builder | Dispatcher sees ready | Sonnet; Opus for stop-lane tasks | Own DB clone, Grafana read-only, branch push only, done-gate hook |
| Design reviewer | Subagent inside the builder session | Done-gate, when UI changed | Opus | Read, Bash (Playwright, axe); no edits |
| Event · GitHub Actions in each project repo | ||||
| Spec Architect | claude-code-action@v1 | You label a bet approved | Opus | Read repo, create issues |
| QA Lead | codex exec in CI | Issue labelled spec; PR ready or updated | GPT-6 Astra | Writes only tests/acceptance/<n>; reads private scenarios repo; runs the app and a browser |
| Verdict | scripts/verdict.ts (code, not AI) | After QA | none | Labels, auto-merge |
| Scheduled · runner on the OCI box (Agent SDK, API key) | ||||
| Chief of Staff | run-role | Daily 07:30 | Sonnet | GitHub read-only, Sentry, run log; push via ntfy |
| Market Scout | run-role | Mon 05:00 | Opus | Web, Exa, DataForSEO; checks every link |
| Product Strategist | run-role | Mon 06:30 | Opus | PostHog read-only, issues |
| Outcome Analyst | run-role | Daily 06:00 | Sonnet | PostHog read-only, issue comments |
| Janitor | run-role + Sentry webhook | Nightly 02:00, on alert | Sonnet | Sentry, Grafana read-only, create issues |
| Growth Lead | run-role | Tue 06:00 | Opus | PostHog, DataForSEO; no spend, no posting |
| Support & Voice | run-role via inbox webhook | New message | Sonnet | Inbox MCP, create issues |
| Designer | run-role | approved + UI | Opus | Figma MCP, writes design/ only |
| Coach | run-role | Sun 20:00 | Opus | Scorecards, transcripts; opens PRs on the factory repo only |
Before code. QA turns each acceptance criterion into failing tests on branch task/<n>. Builders inherit that branch and can't edit those files; the verdict also rejects any later change to them.
During code. The done-gate keeps the builder working until lint, types, dead code, duplication, tests, simplify, review, verify and design review all pass, with evidence written down.
After code. QA runs the real app, hidden scenarios and attacks. verdict.ts decides: AUTO_MERGE, FIX (back to the builder with findings, max 3 tries) or NEEDS_HUMAN.
"A manager who assesses work and gives feedback" is three loops at different speeds. Only the slowest needs a manager agent; the fast ones are mechanical.
needs-human.Mechanism: labels + dispatch.ts
scorecard.ts computes each role's numbers from GitHub and runs.jsonl.Plugin changes are tested with claude plugin eval (with vs without, in fresh sandboxes) before merging.
audit-miss with one line on what went wrong.The same mistake twice is a Coach failure, and it's on the Coach's scorecard.
Visibility: set CLAUDE_CODE_ENABLE_TELEMETRY=1 and the OTEL_* exporter vars in the runner's environment (not a repo's settings, where they're ignored). Cost, tokens and tool decisions per session then flow into your existing Grafana.
| Need | Use | Why, and the alternative |
|---|---|---|
| Personas, gates, skills | Claude Code plugin from a marketplace (this repo) | One version for every repo and container; update once |
| Unattended Claude | Claude Agent SDK + API key | Subscriptions are for your attended sessions |
| Second-vendor QA | Codex CLI codex exec + OpenAI API | Different model family catches more of the builder's blind spots |
| Queue and state | GitHub Issues + labels | One trust boundary. Linear if you want its triage UI |
| Event runtime | GitHub Actions, anthropics/claude-code-action@v1 | Already wired to PRs and issues |
| Scheduled runtime | systemd timers on the OCI box | Boring and reliable. Restate if you outgrow it |
| Builder isolation | Docker per task + Postgres 18 template clone | Fly Sprites or Daytona if you move execution off ARM |
| Product data | PostHog MCP; Sentry MCP; Grafana MCP read-only | Amplitude MCP if you're on Amplitude |
| Market research | Exa MCP, DataForSEO MCP, WebFetch for link checks | Ahrefs or Semrush MCP |
| Design | Figma MCP or Claude Design for drafts; Playwright + axe for review | Stitch MCP |
| Hidden scenarios | Private repo factory-scenarios, Playwright journeys | Only QA's CI token can read it |
| Push to phone | ntfy (private topic) | Telegram bot, Pushover |
| Secrets | Per-role env files on the box, chmod 600 | 1Password service accounts or Infisical when you scale |
| Observability | Claude Code OpenTelemetry → your Grafana | Langfuse for transcript search |
Pilot on one repo for the first two weeks. Copy to the others when the scorecard is stable.
project-template/scripts.example.json into package.json; copy .factory/gate.json./run-skill-generator once so /verify can start the app with its DB and env.claude plugin marketplace add pungoyal/agent-factory --scope project claude # then: /plugin install factory@agent-factory pnpm add -D github:pungoyal/agent-factory#path:packages/config knip jscpd dependency-cruiser
a session in auto mode cannot finish without passing checks and writing evidence. You stop typing follow-up prompts.
eslint.config.js, tsconfig, knip, jscpd and dependency-cruiser at @pungoyal/factory-config.the repo is green under the shared rules; any later rule change lands everywhere.
main: require the qa-review checks and code-owner review; no direct pushes.factory-builder (contents and PRs, branches only) and factory-qa. Remove personal tokens from the box..claude/settings.json deny rules and CODEOWNERS. Test that a deny rule actually blocks in auto mode.runner/bin/setup-db-clones.sh; build a scrubbed golden DB per project.no credential an agent can reach can deploy, delete data or push to main.
qa-tests.yml, qa-review.yml, spec.yml and scripts/verdict.ts (with its test) into the pilot repo.ANTHROPIC_API_KEY, OPENAI_API_KEY, FACTORY_QA_APP_KEY, SCENARIOS_READ_TOKEN. Variable FACTORY_SHADOW_MODE=true.factory-scenarios and write 10 journeys for the pilot (this one is yours).every PR gets a QA verdict and a merge decision you can compare with your own.
docker build -t factory-builder:latest runner/builder cp runner/factory.config.example.json runner/factory.config.json # edit install -m 600 secrets/*.env /var/lib/factory/secrets/ systemctl enable --now factory-dispatch
approved and watch it flow: spec issues, QA tests, a build, a QA verdict.one approved bet reaches a merge-ready PR with no prompt from you.
factory-role@chief-of-staff:portfolio, factory-role@janitor:<project>.your day starts with one digest, and production errors become fix tasks without you.
PROJECT.md first.you approve bets, not tasks.
scorecard.ts weekly before the Coach; review its first PR line by line.FACTORY_SHADOW_MODE=false.GROWTH.md and SUPPORT.md written first.reversible changes ship on their own, and every miss turns into a check.
These are the artifacts agents can't be trusted to write, because they define what "right" means.
Thesis, users, north star, guardrails, budget cap. The Strategist optimises for whatever this says.
10–20 journeys per lead project that must never break. QA runs them; builders never see them.
Brand voice, allowed channels, spend cap, what support may promise. The limits for the roles that face the public.
Edit the twelve ROLE.md files once to your taste. After that, the Coach proposes and you approve.
Edit(/tests/acceptance/**) really blocks in your setup before relying on it. Branch protection and the verdict's tamper check are the backstops.runner/mcp.catalog.json change often. Confirm each against the vendor's docs.gpt-6-astra, claude-opus-5-5) and the Codex CLI flags were checked on 2 Nov 2026 (Codex 0.166).