AI 8 min read By Kyler Berry

An Agentic Engineering Factory Inside GitHub.

GitHub already has the governance layer coding agents need. I use it to route agent work from a human-triaged issue through review and back to a human merge decision.

Not because GitHub has the best agents. Because it already has the governance layer agents need.


A dark factory is an idea in manufacturing where the factory runs with the lights off, because there’s no one on the floor to need them on. You just need one person at the door and one at the exit.

That’s the shape agentic coding is starting to take, and everyone is trying their hand at the implementation that works best for them. The loop looks something like this: a human decides what work enters the queue. Agents research, implement, evaluate, and revise. A human decides what ships.

Between the two human gates, the rest can happen autonomously without anyone watching it happen in real time.

That’s what makes it worth building: coding agents are now extremely capable, and with the right context and evaluation gates can produce real, production-level software. So the goal becomes this: how do I engineer context delivery and evaluation so that one human can oversee many coding agents and still deliver a high degree of trust?

This is my factory. It exists entirely on one platform. GitHub.

Why GitHub

Every agent framework I looked at wants to be the whole platform, with its own idea of what permissions and delegation look like. And how do we reconcile workflows where agents and humans are working collaboratively, on the same product and in the same ecosystem? How do we define permissions at an organizational or repository level?

GitHub already answers that question. It has been answering that question for over a decade, for every team that’s ever shipped code through it. Issues, labels, permissions, actions, secrets, required reviews, CI, branch protection, audit logs, PRs. None of that is agent infrastructure. All of it happens to be exactly the infrastructure agentic engineering needs, especially in enterprise, sitting there unused by most agent tooling because most agent tooling was built to avoid it.

So the platform, the guardrails, the adoption is already there. It just needs some space for agents to do the work humans (used to) do locally with some added connective tissue.

The loop, mapped to GitHub

  • Projects are planning and resourcing
  • Issues are work orders.
  • Labels are routing.
  • GitHub Actions are the orchestration layer.
  • Coding agents on runners are the machines on the floor.
  • CRAFTS is the standard operating procedure they follow.
  • PRs, reviews, and required checks are the gates.
  • Humans hold intake and merge authority. Always.

How it actually runs

Concretely, the door and the exit look like this:

  1. An issue gets created.
  2. A human triages it. This step doesn’t disappear, and I’m not trying to make it disappear.
  3. It gets labeled agent:research or agent:implement.
  4. If it’s research, an agent investigates and comments its findings back on the issue.
  5. If it’s implementation, an agent runs a coding agent inside a GitHub Actions runner and opens a PR.
  6. Copilot review runs against that PR.
  7. A material review comment gets a /agent fix-this reply, and a revision agent pushes fixes to the same branch. Up to three passes.
  8. A human reviews and merges. Or doesn’t.

Step 7 is the part that separates this from typical platforms. A revision loop is where it earns trust, because it’s where an agent behaves less like a code generator and more like a contributor who takes feedback.

There’s a governance detail hiding in step 3. Whoever labels the issue agent:implement is the person an action assigns as reviewer. You don’t get to point an agent at a problem and walk away. Putting work on the floor makes you the one who signs off on what comes back off it.

Watching the floor

With one agent, you watch the run log. With ten, you need a board.

The project has a view filtered to active agents only. At a glance I can see what’s running, what’s stalled, and what’s waiting on me.

Issues and project statuses don’t line up one to one, though. An issue moves through gates, triaged, researching, in review, revising, that don’t map cleanly onto kanban columns. So a script watches the gates each issue crosses and moves its card to the matching status. The board stays useful without me manually dragging anything around.

Why not just use Copilot’s agents

Because I’d be locked into GitHub’s harness and GitHub’s pricing, with no say in either. It’s convenience at a cost. Cost in both inference and configurability.

Deploying my own agent in a runner means I can use any harness I choose, Claude Code, Codex, Pi, etc. That flexibility means I can swap coding agents and inference providers in an hour - maximizing token value with no downtime. It allows me to define how my agents work, when they’re triggered, and set usage and turn limits.

I want GitHub to orchestrate the loop. I don’t want it to own every machine on the floor.

Platform secured

The part that earns GitHub the orchestration role isn’t Actions. It isn’t PRs.

It’s security.

GitHub has spent over a decade owning the boring, load-bearing parts of shipping software: who can touch which repo, which secrets reach which job, what runs in an isolated environment and what doesn’t. That’s org and repo-level permission controls, scoped secret injection, runner isolation, branch protection. Infrastructure that enterprise security teams have already audited and already trust.

Drop an agent into that and it inherits all of it. The runner is an isolated sandbox. Secrets are scoped and injected per job, never handed over wholesale. Access is delegated at the org and repo level, the same way it is for a human contributor. I didn’t design a security model for my agents. I put them somewhere that already had one.

Every run leaves a full log behind, too. Not a summary of what the agent claims it did, but the actual transcript of what it did, kept the same way any other CI run is kept. When someone asks why a line of code exists, the answer is a link to the run that wrote it. Auditing an agent is the same motion as auditing a build.

Every bespoke agent framework has to rebuild this or skip it. It’s slow, it’s unglamorous, and it doesn’t feed the hype train.

The beauty here is it meets organizations where they already are. Look at the lifecycle of a single diff. The only part that never lived on GitHub was the writing of it, delegated to an engineer on their personal machine. Now the engineer is a small compute box in the cloud.

Where this works

Bugs, tests, docs, clear refactors, scoped features, research spikes, resolving review comments. Anything where the definition of done fits in an issue description without me having to explain it twice.

Where it doesn’t

Vague issues, first. If the issue is vague the agent decides for you, and it’s usually wrong. That’s the failure mode I’ve hit most, and it’s a context delivery problem before it’s anything else. Either you spend more time sculpting the specification and breaking it down - or it’s a candidate for human-AI pair programming.

Long-running tasks are the second limit, and it’s a mechanical one. A hosted runner has a runtime threshold. Work that outlives it gets cut off mid-thought and you’ve wasted tokens and compute for nothing.

Large, messy repos are the third. Though I’d argue that’s a symptom of bad design and process, not a limit of the loop. It comes down to context management: supplying the right data to the agent at the right time. A repo that can’t do that for a human reviewer won’t do it for an agent either.

Roadmap

A few things stand between this and something I’d hand to a team that isn’t me.

Protected-path policies come first. Files like migrations, auth, and CI config should never get touched without a named human in the loop. Right now that’s a convention I follow. It should be a rule the platform enforces.

Then the runner problem. Hosted runners are fine for scoped work and frustrating for anything long. A self-hosted runner or a queue-backed worker would let a job run as long as the work actually takes, and open up more flexibility for sub-agent orchestration and parallel execution of multiple agents on one goal.

If you want to run this

Clone the template. Start with docs, run the onboarding scripts and set up your repo / organization. Set it loose on a couple of small tasks, then monitor and review it closely. Tweak the gates and workflow for your codebase.

All of this works, not because the orchestration is particularly clever, but because the agents can be trusted, and that trust didn’t come from the platform.

It came from two things I’ve written about before. CRAFTS, the coding methodology every agent follows, which makes the work come out consistent. And a knowledge base that hands each agent the exact context it needs at the moment it needs it, so it moves with intent and doesn’t waste its context window. One makes them reliable. The other makes them efficient.

The platform is what pulls it together. It’s where a reliable, efficient agent picks up a work order and carries it through every gate a human contributor would, and where I stand waiting at the end of the line ready to hit that big green “Merge” button.

So I can take an idea from a one-line issue to a merged PR without ever opening my editor.

If this resonated
I help teams skip a few of these lessons.