Loams v0.1.0 is out: run the whole stack yourself with Docker Compose. See the roadmap

Blog/Research

A software factory you own

Google and Meta built their own software factories. Everyone else rents one in pieces, and coding agents are about to rent the loop as well. The open-source parts are good enough to own now. What we ship in Loams today, what we are designing, and what we are not sure about.

A software factory you own
On this page
  1. What the big companies built
  2. What everyone else got
  3. Agents raise the stakes
  4. The open-source pieces are good enough now
  5. What Loams ships today
  6. The loop we are designing
  7. What we are not sure about
  8. What to do today
  9. Sources

Experimental The Loams Software Factory ships in Loams 0.1.0 as read-only panels and embedded app UIs inside Loams Desktop. The loop described in the second half of this post, where agents take a signal to a reviewed pull request, is Planned: designed, not built.

"Software factory" is an old phrase that keeps coming back. Each time it means a little more. Once it meant a standard process. Then it meant a standard toolchain. Now the vendors use it for something you buy: an agent that takes an issue and comes back with a pull request.

Our view is simple. A software factory is the toolchain plus the loop that runs through it: code, review, CI, issues, chat, errors, analytics and traces, wired so that a signal in one becomes work in the next. The large companies built theirs and own it. Everyone else rents it in pieces. Coding agents raise the stakes, because an agent is only as good as what it can read, and what it can read is your whole record of how your software gets made. We think that record should be yours, on hosts you run, in apps whose licences you can read.

This post looks at what the in-house factories taught, what the rented ones cost, which open-source apps can now do each job, what Loams does with them today, and the loop we are designing on top.

What the big companies built

Google is the usual example, because it has written about its factory in detail.

In Software Engineering at Google, the chapter on version control describes Piper, Google's in-house centralised version control system, run as a distributed service on Google's own storage and compute. Around 50,000 engineers work in a single monorepo. Piper holds "more than 80 TB of content and metadata", and 60,000 to 70,000 commits land on a working day, human and automated together. Creating a client at trunk, adding a file and committing an unreviewed change takes about 15 seconds. The rule that holds it together is One Version: for every dependency, "there must be only one version of that dependency to choose" (SWE book, ch. 16).

The workspace is not a full checkout. Rachel Potvin and Josh Levenberg's 2016 Communications of the ACM paper describes CitC ("clients in the cloud"): a developer's workspace lives on the server as the files they changed, shown over the repository snapshot through a filesystem, so nobody downloads the monorepo (Potvin and Levenberg, CACM 2016).

Around the repository sit the rest of the factory. Critique is Google's code review tool, "the most popular one by a large margin", and uploading a change triggers analyzers whose results show as chips on the change page (ch. 19). TAP, the Test Automation Platform, is the continuous build of the whole codebase. It handles more than 50,000 unique changes and runs more than 4 billion test cases a day. A change that passes its team's fast presubmit tests has a 95% or better chance of passing the rest (ch. 23).

Meta built its own version. Sapling began about a decade before its 2022 release as an extension to Mercurial and grew into its own system. With Meta's server and virtual filesystem behind it, Sapling serves a monorepo with "tens of millions of files, tens of millions of commits, and tens of millions of branches". Only the client was open-sourced; the server and the virtual filesystem were not (Meta Engineering, 2022).

The lesson is not any single tool. Plenty of companies have a good code review tool. What Google and Meta have is integration: one identity across every tool, one record of every change, and tools that know about each other. A test failure points at a change, the change points at a review, and the review points at a person. That is what makes a factory a factory and not a pile of tools.

What everyone else got

The rest of the industry assembled the same factory from SaaS: a code host with CI, an issue tracker, a chat, an error tracker, an analytics product and, lately, an LLM tracing product. The tools are good, and the integration is a set of webhooks and OAuth apps that someone set up once.

That works until the terms change, and they do change:

  • Sentry moved its code to the Functional Source License in November 2023. FSL is source-available, not open source: it forbids a "Competing Use", and each version converts to Apache 2.0 or MIT two years later (Sentry). Self-hosting Sentry is allowed, and its own docs ask for 4 cores and 16 GB of RAM plus 16 GB of swap, with 32 GB recommended (Sentry self-hosted).
  • Gitea's domains and trademark went to a for-profit company in October 2022, "without knowledge or approval of the community". Forgejo forked under Codeberg e.V., a non-profit, and became a hard fork in early 2024 (Forgejo).
  • Atlassian ended support for its Server products, Jira Server among them, on 15 February 2024 (Atlassian). Data Center, the self-managed path that remained, reaches end of life on 28 March 2029, when subscriptions expire and the products become read-only (Atlassian).

None of these companies did anything unusual. Licences and products change because businesses change. The point is about you: your issues, your discussions, your error history and your traces sit in other companies' databases, under terms you do not control. For most of the last decade that was a fair trade. Agents change it.

Agents raise the stakes

In March 2024 Cognition introduced Devin as "the first AI software engineer". It reported resolving 13.86% of SWE-bench issues end to end, unassisted, against a previous best of 1.96% (Cognition). SWE-bench is the benchmark behind most of these claims: 2,294 tasks, each built from a real pull request linked to a GitHub issue in one of 12 popular Python repositories. The system gets the issue text and edits the code, and the benchmark runs the tests the original fix made pass (SWE-bench; Jimenez et al., ICLR 2024).

The products followed. GitHub's Copilot coding agent, announced in May 2025, starts when you assign it an issue. It runs in a development environment powered by GitHub Actions and pushes commits to a draft pull request. Its pull requests "require human approval before any CI/CD workflows are run". It can push only to branches it created, and the developer who asked for the pull request cannot approve it (GitHub, 2025). GitHub's earlier Copilot Workspace, an issue-to-plan-to-code environment, ended its technical preview on 30 May 2025 (GitHub Next). Factory calls itself an "agent-native software development platform" whose Droids work from Jira, Linear, Slack and Teams (Factory). Sweep began as a GitHub app and now builds an AI coding assistant for JetBrains (Sweep).

Two things stand out. First, the guardrails GitHub chose are the right ones: a draft PR, CI that waits for a person, no self-approval, existing branch protection. Any factory loop should start from that list. Second, the products churn. Workspaces come and go, and startups pivot. The agent is becoming the replaceable part. There are several good ones, and Loams Studio already drives Claude Code, Codex, opencode and others through one daemon on your own subscriptions.

What does not churn is the loop and the record. To fix an error well, an agent needs the stack trace, the release, the issue and its discussion, the CI log, and afterwards the metric that says whether the fix worked. If those live in six SaaS products, the agent vendor becomes the integrator, and you are now renting the loop as well as the tools. Every new agent you want to try needs read access to everything, granted again, vendor by vendor.

Our opinion: own the record, rent the model if you like. The tools where your work happens should run on your hosts, under licences you can read. The agents should be able to come and go.

The open-source pieces are good enough now

Ten years ago a self-hosted factory meant a weekend of compromises. Today there is a solid open-source app for each job, and most of them say plainly what they are a replacement for:

JobAppLicenceWhat it says about itself
Code host, review, CIForgejoGPL-3.0-or-later since v9 (August 2024; earlier releases MIT)Governed by Codeberg e.V.; Forgejo Actions is "designed to be familiar to users of GitHub Actions, but it is not designed to be compatible"
Issues and planningPlaneAGPL-3.0"Open-source Jira, Linear, Monday, and ClickUp alternative"
ChatZulipApache-2.0Topic-based threading that "combines the best of email and chat"
ErrorsGlitchTipMIT"Compatible with Sentry client SDKs, but easier to run"
Product analyticsOpenPanelAGPL-3.0"An open-source alternative to Mixpanel"
Web analyticsMatomoGPL-3.0-or-later"The leading open-source alternative to Google Analytics"
LLM and agent tracesLangfuseMIT, except the ee foldersTracing, prompt management, evaluations
Logs, metrics, tracesOpenObserveAGPL-3.0 open-source edition; a commercial enterprise editionClaims "140x lower storage cost" than Elasticsearch. That is the vendor's own figure, and we have not measured it

The obvious objection is GitLab: one self-managed application that does most of this. It is a fair choice. Its docs set a single-node baseline of 8 vCPU and 16 GB of memory, and it can run with at least 8 GB in a tight spot (GitLab). We went the other way, toward several single-purpose apps, for three reasons. Each one is the strongest open-source option for its job. You can run only the ones you need: a team with Forgejo and GlitchTip has a factory, just a smaller one. And when one of them stops fitting, you replace that one and keep the rest. The cost is real, though: eight services to upgrade and back up instead of one. We come back to that below.

Two licence notes, because they matter if you plan to offer any of this to others. AGPL's network clause applies to whoever modifies the software and serves it over a network. Our design runs every app unmodified, from its official image, and adds panels and agents from outside. Hosting these apps for paying customers is a separate question with its own obligations, and the design sends it to counsel rather than answering it.

What Loams ships today

The left column was never for sale. The middle column is free to run. The right column is what Loams adds: one window today, the loop later.

In Loams 0.1.0 the factory is the Factory group in Loams Studio, on the desktop. It covers eight apps: Forgejo, Zulip, Plane (through the ItsAPlan adapter), GlitchTip, OpenPanel, Matomo, Langfuse and OpenObserve. You run them. Loams Desktop asks for each one's URL and a token, tests the connection, and then gives you two views of the app.

  • Native panels that only read. Open pull requests and issues from Forgejo, streams and recent messages from Zulip, open issues by state from Plane, unresolved errors from GlitchTip, metric tiles from OpenPanel and Matomo, and recent traces with daily cost and tokens from Langfuse. OpenObserve has no panel, only its full UI. The desktop's main process accepts only operations named get, list, search, health, fetch or query, each with a strict schema and a cap of 50 rows. There are no writes.
  • The app's own UI, inside the window, as an Electron view with its own storage partition, no preload, a sandbox and navigation locked to the app's origin. You sign in with the app's own login. Its cookies never meet the console's.

The tokens are encrypted on your machine and decrypted only in the desktop's main process. They never reach the page, and the agent transcript scrubber masks them.

The part that points toward the loop is how the factory meets Studio. On a Plane issue, Start thread gives you a draft with the issue's key, title and priority and a branch named after the key. On a GlitchTip error, Fix this error gives you a draft with the latest stack trace and the release. You paste the draft into a new Studio thread. One of your agent CLIs works on it in its own git worktree. When the branch is pushed, loams-agentd opens the pull request on Forgejo, and you review and merge it.

That is the whole loop, by hand: you are the one passing work from one tool to the next. We would rather say that plainly than call it autonomous. Today the factory is a window over your toolchain, plus a short path from an issue to an agent to a pull request. It is not in the browser console yet, the panels cannot write, and nothing merges or deploys on its own.

The loop we are designing

Dashed: designed, not built. Gates in red are where a person decides; the design keeps them by default. Solid accent: the manual path you can walk in Loams 0.1.0.

The design, §39 of the Loams design docs, turns those hand-offs into one durable workflow per signal, factory.run, on the durable execution engine Loams already has. It has eight stages. Intake takes a signal, such as a GlitchTip alert, an analytics anomaly, a failing evaluation score or a request in chat, and deduplicates it against open runs. Triage opens a Zulip topic with the evidence and waits for a person to decide. Plan creates the Plane issue. Fix has the Forgejo agent run a sandboxed coding session, open a pull request and wait for CI. If CI fails, the log goes back to the coder, up to three attempts, and then the run hands off to a person with a labelled draft PR. Review waits for a human review and a merge approval. Deploy waits for a deploy approval. Observe watches the fingerprint, the metric and the traces for a window. Close resolves the issue, or opens a revert PR (which needs the same approval) and a new signal.

The choices we think are right, and why:

One agent per app, not one agent with every key. Each app gets its own agent (zulip, plane, forgejo, glitchtip, analytics). Each is an A2A server with its own principal, its own policy and a signed Agent Card that lists its skills and how risky each one is: read, write or destructive. A chat called Loams Bot delegates to them in natural language and never calls an app's API itself. When something goes wrong, the action shows up in the app under a named user like loams-plane-agent, and you can suspend that one agent without stopping the rest.

Agents never hold credentials. A broker makes the app call for them. For a destructive call, the broker checks that a matching approval has been settled before it proceeds. This is where we disagree with putting safety in the prompt. Issue bodies, chat messages, error text and PR descriptions are untrusted input. An agent that has been talked out of waiting for approval still cannot get the key, because the check is not in the agent.

Approvals belong to a person. The approval is signed by the person's device, and the requester cannot approve their own request, which is the same rule GitHub chose. Merges always need an approval. Deploys need one by default. A policy can allow auto-merge or auto-deploy only for listed repositories or services in unprotected environments, and that change goes into the audit log.

Budgets and a kill switch in the engine. Each run has limits on tokens, money, wall time, attempts and open PRs. The owner's defaults are $5 per run and $50 per organisation per day. There is a kill switch for a run, an agent or the whole organisation, a cap on how many times a fix can regress and start a new run, and a cooldown per fingerprint so that a bad fix cannot set off a storm of new runs.

Every step traced, and content kept in one place. Spans that carry model content go to Langfuse, through a collector that masks them and fails closed if masking cannot run. Every span, log and metric without content goes to OpenObserve and to Loams' own ingest. Each run is a record that links its Zulip thread, Plane issue, Forgejo PR, deploy and traces, so a person can see what a fix cost and why it happened.

None of this is built. The plans are SF1 (the collaboration UIs in the browser, with its spike done), SF2 (the agents), SF3 (Loams Bot), SF4 (the loop) and SF5 (the observability wiring). The decisions are recorded as proposed.

What we are not sure about

Eight services is a lot to run. This is the cost of choosing several apps over GitLab, and we will not pretend it is small. The design ships a Helm chart and a catalog patch for a single-organisation factory you install yourself, but they are not in the repository yet. Until they are, each app's own self-hosting guide is how you run it.

Two apps have no per-person identity in their free editions. OpenPanel and the open-source edition of OpenObserve have no free OIDC. The design puts them behind an authenticating proxy that signs in as one shared, read-only service user. The design says so: for those two, the record of who looked comes from the proxy's log, not from the app.

The protocols are young. A2A 1.0 is a Linux Foundation project with an official Rust SDK, but that SDK is new. The fallback in the design is a thin server of our own over the specification's protobuf.

Agents that fix things can cause things. The loop exists to act on its own findings, and that is exactly what makes runaway loops possible. The limits above are our answer: a generation cap, cooldowns, budgets enforced twice, and no auto-merge. We expect to tune them on real runs before we trust them.

The naming will settle. The desktop labels the planning app "Plane (ItsAPlan)". The owner ruled that ItsAPlan is the Plane-compatible product the factory means, and its adapter is what the panels call. The design text still says Plane.

What to do today

If you already run Forgejo, GlitchTip or any of the others, install Loams Desktop, open Studio, Factory, and connect the ones you have. Use read-only tokens everywhere except Forgejo, where Studio needs a token that can open pull requests. Try the path from an issue to a thread to a pull request with the agent CLI you already use, and tell us where it breaks.

If you run none of them, start with two: Forgejo for code and CI, and GlitchTip for errors. Your apps already speak Sentry's SDKs, and a code host plus an error tracker is enough for the smallest useful loop.

The product page has the setup steps and the full status table: Loams Software Factory.

Sources

More from the blog