← Back to openfactory.digital Technical overview

How it works

The roles, where the agents may act on their own, how providers plug in, how it deploys, and what it does not do yet. Each claim links to the file or command behind it.

Roles

Four roles. One writes code.

The executor writes the diff. The reviewer, the tech-lead and the product role judge it, handle stalls, and decide what enters the queue. Which engine runs each role is configuration, per project and per role.

Executor

Works the ticket inside a sandbox that has already built the project, against the project's own gates. Runs on Claude Code, Codex, Kimi or OpenCode. The choice is a registry value.

Reviewer

Gets the specification, the diff and the gate results, and not the author's reasoning. Returns a decision, a score and findings tied to the acceptance criteria. It can run on a different harness and model than the executor.

Tech-lead

Called when a job stalls. Clones the repo, reads the failure against the code, classifies it by what would fix it, resolves what it safely can, and escalates the rest to a person.

Where the boundary is.

Product role

Talks to the requester, reads the board, and proposes tickets, each citing its requirement. Reading the codebase yields observations, not requirements. Only a person accepting one turns it into a commitment.

The panel is the reference surface and ships with the core. A chat channel such as Slack is an add-on package.

Autonomy

Where it acts alone, and where it stops

The tech-lead classifies each failure by what would fix it. The class decides who acts and how many times.

Incident · 2026-07-26 · ticket #478

GitHub rate-limited the API, the most self-healing failure there is. The factory parked the ticket, held the floor for eighteen hours, ran nothing else and notified nobody. The diagnosis that should have written the alert could not run either. The classification below came out of that.

ClassExampleWho resolves it
transientAPI throttling, a network blipthe factory: waits out the window, retries
credentiala token revoked or exhaustedthe factory: rotates, escalates only if the whole pool is bad
environmenta missing permission, a broken imagea named person, with the specific thing to change
codethe change is wrongan engineer, with the diagnosis
requirementthe ticket is ambiguous or contradicts itselfthe product role
unknownit cannot tella person, told that it cannot tell

Budgets are per failure class

Waiting is free. A throttled call retried after its window costs no tokens, so that budget is generous. Re-running an agent costs money, so that budget is small.

A remedy that has failed twice is not tried a third time. unknown never degrades to retry: repeating a failure nobody understands only spends money.

What it never does

  • Resume work a person already skipped.
  • Retry anything classified unknown, code or requirement.
  • Exceed its budget. An exhausted budget is itself an escalation.
  • Touch production. Releases need a human login, always.
read

Anyone in the project's channel can ask for status. No gate.

write

resume and skip need a user on the project's allowlist. The allowlist is empty by default.

production

Never actionable from chat, not even for an admin. An unauthorized attempt is refused and logged.

Classification will sometimes be wrong, so the bias is toward escalation. A wrong retry costs money and delays a real escalation. A wrong escalation costs a person a minute. Every action records what it did and what it tries next.

Design

What is different from an agent with repo access

The box is proven before any agent runs

On the container sandbox, the project's own image, setup and gates run once with no agent before a ticket is picked up. A box that cannot build the project is found before tokens are spent. The worktree sandbox has no image to prove, so the gate does not apply there.

No silent stalls

A stall either self-heals within its budget or puts a question on the card, with wait / merge / skip as options a person picks and the factory executes. Tests treat going quiet as a bug.

Failure is never an answer

Every adapter separates an unreadable result from an empty one.

None = I could not read. [] = I read it, and there is nothing.

The review is a second agent

It can run on a different engine and never sees the author's reasoning. It has rejected a diff that met its criteria but landed in the wrong repository, before any person looked at it.

Merging is policy

merge_policy: human opens the PR and waits. auto merges only when gates are green, the review did not reject, and no high-risk component was touched. A project that declares no gates is held, not passed.

It never deploys

It merges or tags, then watches your pipeline. Deployment stays in your CI with your credentials. Production promotion needs a human login, always.

Providers

Three claims you can check

01

A provider is a registry entry

Tracker, board, forge, CI, harness and sandbox each dispatch through a registry, and the axes are independent: Jira for tickets and GitHub for code is two lines of configuration. An unknown provider fails at startup and names what is supported. It never falls back to a default. docs/STATUS.md lists every axis and what implements it.

AxisProviders today
Trackergithub · jira · azure_devops
Boardgithub · jira · azure_devops
Forgegithub · azure_devops
CI / environmentgithub_actions · azure_pipelines
Harnessclaude_code · codex · kimi · opencode
Sandboxworktree · container · fargate (add-on: openfactory-aws)

Read from openfactory/adapters/tracker/registry.py and its siblings.

Verified end to end. GitHub: ticket to merged PR, with a live client in production. Jira: requirement to PR to merge, with the client's GitHub Actions deploy observed. Azure DevOps: work item to reviewed PR in Azure Repos with no GitHub involved, including a three-repository product where the card names its own repo.

02

Harness and model are per project and per role

Four coding agents behind one contract, chosen in the registry. The reviewer can run on a different engine than the executor.

.openfactory/project.yaml
harness: opencode
model:
  executor: eu.anthropic.claude-sonnet-5
  reviewer: eu.anthropic.claude-haiku-4-5   # a cheaper, independent second opinion

Model routes are configuration too: Anthropic direct, Amazon Bedrock, Vertex, or a corporate gateway. Keeping everything inside your own AWS account is one config value. This platform's own tickets have been written by Claude Code and by OpenCode, both over Bedrock.

03

Fewer tokens per ticket

A module map of the codebase goes into the agent's context, so it reads less to find the same code. The numbers and their caveats are on the home page.

Deployment

Runs on your machines

No cloud SDK is a core dependency. boto3 is optional, every cloud import is function-level, and each observability axis has a cloud-free option. A test blocks every cloud SDK in a subprocess and imports the core to prove it.

AWS and Azure are add-on packages. Without the Fargate add-on, jobs run in local containers. The only vendor coupling is where your data already lives: your tracker and your pipeline.

Start the stack
docker compose up
Prove the core needs no cloud
pytest tests/test_the_core_does_not_need_a_cloud.py
Extending

Adding a provider

A new provider is one module and one registry row. A published conformance suite checks it against the adapter contract, and every adapter is runtime-checked against its Protocol, so a partial implementation fails at load rather than in production.

The code is Apache-2.0 and may be forked freely. The OpenFactory name is reserved for builds that pass the conformance suite.

Check a new provider
openfactory conformance-adapter tracker my_pkg.my_tracker:MyTracker
openfactory conformance <project>
Also

Tests and decisions

pytest -q passes in fixed and randomised order; the count and the commit it was measured at are in docs/STATUS.md · every architecture decision is recorded in docs/adr/ · providers verified live on GitHub, Jira and Azure DevOps · Apache-2.0.

Limits

What it does not do yet

  • One deployment serves one GitHub organisation. A GitHub App installation belongs to one org and the forge credential is process-global. Registering a project in a second org is refused by name.
  • The knowledge map reads Python, TypeScript/JavaScript and C#. Other stacks get a structural map or none. The map reports which extensions it skipped.
  • No GitLab or Bitbucket. Adding one is a module and a registry row. Nobody has written it yet.

Read the code. Run it yourself.

Apache-2.0. No cloud account required.