Abstract
This report is about something Alera was used to build: a factory for open-source libraries. Give it a kind of library that already exists elsewhere and a target language, and it writes a new one from scratch, in that language’s idiom, and publishes it on GitHub. The owner steps in as little as possible. The factory has three parts:
- Specialist agents: a planner, a project manager, a build orchestrator, engineers, and independent reviewers.
- An opinionated process, written into the prompts those agents share.
- A fixed architecture for every library: from scratch, no dependency beyond the language’s base library, judged by outside tests, losses published.
Each library is one run of the factory. None of this started from zero: Kurtis had two years of building with agents behind him, then built Alera from scratch over the ten months before the first of these libraries.
Between 26 September and 23 October 2026 the factory delivered four results:
- oneyaml-rust;
- oneyaml-go and oneyaml-csharp, built together with their shared test kit, oneyaml-kit;
- oneimage-csharp;
- onepdf-csharp.
A fifth run, oneocr-csharp, started on 23 October. Every cycle went the same way. The factory took a library to its 1.0 release. Kurtis and the agents then adjusted the factory in light of that release, and the next library started.
The headline measure is how much of the owner’s attention each run took. It shows how much of the work the factory had taken over:
- oneyaml-rust: 112 messages, over 9 days and 5 hours;
- oneyaml-go and oneyaml-csharp together: 108, over just under 4 days;
- oneimage-csharp: 14, first message to v1.0.0 in 22 hours 56 minutes;
- onepdf-csharp: 11, in 17 hours 27 minutes.
The clock hours in which he sent at least one message fell from 34 to 3. These runs were never his only work: the devlog records client work on 14 of the 17 days they ran.
Each refinement between runs took a few hours or less. It took about an hour after oneyaml-rust, under four hours after oneyaml-go and oneyaml-csharp, and about an hour after oneimage-csharp and after onepdf-csharp. How long the next run waited after a result depended on when Kurtis was free (section 3).
The speed is checkable. Every library was run against an outside test suite or public corpus, benchmarked against the library people use today, and fuzzed, and its losses are published in its own repository. Each build has its own case study, which this report links to rather than repeats.
The main findings:
- The factory took over the owner’s work. Messages per run fell by an order of magnitude, from 112 to 11, while the outside checks stayed the same or got stronger.
- Refining the factory between runs was short work. The two longest refinements were about an hour of planning after oneyaml-rust and a review of under four hours after oneyaml-go and oneyaml-csharp. Each one moved work Kurtis had done by hand into the agents, their prompts or the platform (section 3).
- The biggest single handover was the design interview. In the first run Kurtis answered the agents’ open questions himself, often with a single letter. From oneimage-csharp on, a project manager agent answered the planner’s design questions on his behalf, and every decision in the record says who made it.
1. The runs in one table
Each row runs from Kurtis’s first message about the library to its 1.0 release.
| Run | Library | First message → 1.0 | Owner messages | Clock hours with a message |
|---|---|---|---|---|
| 1 | oneyaml-rust | 9 d 5 h | 112 | 34 |
| 2 | oneyaml-go and oneyaml-csharp, with oneyaml-kit | 3 d 21 h | 108 | 23 |
| 3 | oneimage-csharp | 22 h 56 min | 14 | 4 |
| 4 | onepdf-csharp | 17 h 27 min | 11 | 3 |
Notes on the table:
- 1.0 is the public release: the crates.io publish for oneyaml-rust, and the v1.0.0 git tag for the others. For oneyaml-go and oneyaml-csharp, the row runs to the later of the two tags, oneyaml-go’s. oneyaml-csharp was tagged two hours earlier, at 3 d 20 h.
- oneyaml-go and oneyaml-csharp can’t be split per library. 33 messages went to the oneyaml-go project manager and 21 to the oneyaml-csharp one. The other 54 went to agents that served both: oneyaml-kit, the family architect and planning.
- onepdf-csharp’s 11 include three shared messages. Two were about a build machine and the agent changes that came with it, and one asked for the roadmap of both onepdf-csharp and oneimage-csharp. Counted strictly, onepdf-csharp took 8.
- Calendar time isn’t effort. None of these runs had Kurtis’s full attention (section 5).
Agent runs and cost are given in each case study, counted over that study’s own period. That period runs past 1.0, so these figures aren’t on the same window as the table above:
| Case study | Period counted | Agent runs | Cost basis |
|---|---|---|---|
| oneyaml-rust | 26 Sep – 13 Oct | 162 | ~$4,400, estimated at the Opus 4.5 list prices the project used |
| oneyaml-go and oneyaml-csharp | 12 – 17 Oct | 396 | ~$2,800 metered-equivalent at list prices |
| oneimage-csharp | 21 – 22 Oct | 66 | ~$460 metered-equivalent at list prices |
| onepdf-csharp | In its case study | ||
Every model ran through a subscription, so the recorded spend is $0. The cost figures are what the same tokens would cost at list prices.
2. How the owner’s attention was measured
The measure is messages Kurtis typed into agent conversations about the library, from his first message about it to its 1.0 release.
- Source. Every agent conversation is stored with its full message history. The platform doesn’t record who sent each message. A message in a conversation can come from Kurtis, from another agent, or from the platform (alerts and notices).
- Attribution by elimination. A message counts as Kurtis’s unless:
- its text exactly matches a prompt another agent sent to that conversation;
- it is the brief an agent was started with;
- it is a platform notice;
- it is a relay that names its sender (“From the build orchestrator: …”).
- Scope. The conversations count if they worked on that library or its build: planners, project managers, architects, general-purpose sessions in the project, and the odd direct question to a worker agent. One project manager served both oneimage-csharp and onepdf-csharp, so each of its messages is assigned by what it is about.
- Not counted: messages about other projects sent in the same window, and a handful of messages about a build sent to unrelated conversations. One was found for oneyaml-go and oneyaml-csharp.
The method reproduces the oneyaml-rust report’s published figures. Run over that report’s own window (26 September to 11 October), it finds 161 messages with a median of 48 characters, 17 of them a single letter, and 72 of 40 characters or fewer. That report gives about 160, 48, 17 and 73. The 112 in the table is lower for two reasons. It stops at 1.0 on 5 October, and it leaves out a general-purpose conversation from 30 September that planned the libraries for other languages.
A message is a coarse unit. A single letter answering a multiple-choice question and a pasted 4,600-character review both count as one. Section 4 gives total characters typed as a second view. Neither measure counts the time Kurtis spent reading what agents wrote.
3. The loop, cycle by cycle
Each cycle is a run, a result and a refinement. The table times each step from the record.
| Cycle | Result in (1.0) | Refining the factory | Next go-ahead | Result → next go-ahead |
|---|---|---|---|---|
| 1 · oneyaml-rust | 5 Oct, 16:09 | Timing analysis and the procedure for the next batch: 12 Oct, 20:22–21:24, and 13 Oct, 10:37–10:45 (about 1 h 10 min) | 12 Oct, 20:22 | 7 d 4 h |
| 2 · oneyaml-go, oneyaml-csharp | 16 Oct, 17:52 (oneyaml-csharp 15:57) | A review of every agent run in the batch, settled with Kurtis: 17 Oct, 14:34–18:19 (3 h 45 min) | 21 Oct, 12:04 (oneimage-csharp) | 4 d 18 h |
| 3 · oneimage-csharp | 22 Oct, 11:00 | A rule on how competitors may be studied, recorded at 12:15 | 22 Oct, 13:24 (onepdf-csharp) | 2 h 24 min |
| 4 · onepdf-csharp | 23 Oct, 06:43 | A GPU set-up on the second machine started, and a new ML-engineer agent role in place at 07:46 | 23 Oct, 06:47 (oneocr-csharp) | 5 min |
Times are US Central. The time between a result and the next go-ahead was set by Kurtis’s availability, not by work on the factory. After the first result he spent six days finishing and publishing oneyaml-rust. After the second, client work and his other projects came first (section 5).
3.1 Cycle 1: oneyaml-rust, building the factory while getting the first result
Run. Kurtis started with a question to a general-purpose agent at 11:09 on 26 September: “Is there a good open-source yaml library for rust?” Up to 1.0 he sent 112 messages, across 16 conversations, on all 10 calendar days. Fifteen were single-letter answers to multiple-choice questions. The agents ran on Claude Opus 5.5.
The factory didn’t exist yet, so Kurtis did by hand much of what it later did:
- he asked for status and told architects to keep waiting;
- he noticed when an agent’s context was full and asked for a handoff;
- he killed runaway processes;
- he answered the agents’ policy questions, one letter at a time.
An agent answered the first design interview, but the questions that came up later in the build were his to answer. He also changed the process during the run:
- dropping an agent-invented governance gate on the first evening;
- handing off to a fresh architect on 1 October;
- asking on 3 October, “Is there unnecessary procedure that’s holding us up?”, which led to a merge bar and stopping rules;
- having a documentation editor agent built, and the architect write its own retrospective, on 4 October.
Planning for the next batch also started during this run. On 30 September Kurtis began planning YAML libraries for other languages around a shared test kit and benchmark harness.
Collect. oneyaml-rust 1.0.0 was published on crates.io at 16:09 on 5 October. Finishing and publishing it took the next six days:
- the public repository was re-published with a fresh history;
- typed reads with merge keys went from 1.26× to 0.89× of the incumbent’s instructions;
- an outside user review was acted on;
- 1.1.0 was tagged on 10 October;
- the repository was made public again on 11 October.
Details: Building oneyaml-rust with a team of AI agents.
Refine. At 20:22 on 12 October Kurtis opened the next cycle:
… (oneyaml-rust) is done and live
The next two languages I want to tackle are c# and go
An agent timed every tool call of the oneyaml-rust run. About 64% of active implementer and reviewer time had gone on waiting for commands. The procedure for the next batch was built on that finding: targeted tests, tiered gates and no time estimates. It was settled in two short sessions, about an hour that evening and eight minutes the next morning.
3.2 Cycle 2: oneyaml-go and oneyaml-csharp, the factory in a second and third language
Run. The refined factory’s first job was infrastructure. oneyaml-kit, the shared test kit that judges every library in the family and its competitors, had its first commit at 19:35 on 13 October and reached v0.1.0 at 01:50 on 15 October. Each language started with one line from Kurtis, for example “Kick off a project planner to plan out the oneyaml-go build, and then make sure it gets executed end to end.” The oneyaml-go and oneyaml-csharp project managers started at 13:18 and 15:24 on 14 October. Claude Sonnet 5.5 wrote the code. Claude Opus 5.5 planned, reviewed and managed. GPT-6 Astra ran five outside reviews.
The factory was also refined during this run:
- 14 October:
- a context-window monitor. Long-running agents get an alert at 400,000 tokens, write a handoff note, start a successor and stop.
- the Project Planner and Project Manager agents, with a shared “streamlined development” prompt. Its rules: record who decided; the owner’s latest word wins; act without asking on builder-level choices; verify in proportion to risk; a review judges the change in front of it.
- 15 October: an API-ergonomics reviewer and a pair of repository reviewers, added at Kurtis’s request.
When he specified the new agents, Kurtis pointed the agent building them at the oneyaml-rust write-ups:
Agents drift hard into process and rules. Way overly so, so the extent that we wind up with an instane number of tests, and running full e2e test suites for every little change. It’s super important that we build into both of these agents that we want streamlined dev processes and what exactly that means.
Two days later he reviewed how the agents had behaved on a first small project, and set the principle their prompts were trimmed to:
The more you tell an agent to do, the more it does wrong when it comes to agents that are highly flexible.
Collect. oneyaml-csharp 1.0.0 was tagged at 15:57 on 16 October, and oneyaml-go v1.0.0 at 17:52. Measured from each project manager’s first message, that is about 49 and 52 hours. The run took 108 messages for two libraries and oneyaml-kit. That is about as many as oneyaml-rust took, in less than half the time, and the messages were shorter, with a median of 39 characters. Details: Building oneyaml-go and oneyaml-csharp with a team of AI agents.
Refine. On 17 October, from 14:34 to 18:19, a planner reviewed every agent run of the oneyaml builds. Kurtis then settled the changes with it in a question-and-answer session:
- one project manager per project;
- clear rules for who watches whose context;
- taste settled from the owner’s examples;
- long commands run in the foreground instead of being polled in the background.
The prompt changes were committed at 15:47 that afternoon. The next run started on 21 October.
3.3 Cycle 3: oneimage-csharp, the first run with the full factory
Run. Kurtis opened a Project Planner conversation at 12:04 on 21 October. He sent it four messages: the goal, the scope, the order of work with the shape of the engine, and “Ok, let’s do the q&a”. The planner proposed building a shared test kit first, believing that was how the oneyaml family had started. He corrected the order: “It built rust first, then built the kit based on those learnings.” Then he handed the interview to a Project Manager. It answered the planner’s 50 design questions in nine minutes. The design record marks every answer as the manager’s, not his.
He sent the manager ten more messages before the release. They covered:
- a restart of his PC;
- a license key he refused to apply for;
- how the library compares with others;
- whether v1 covered everything ImageSharp does;
- the name and “Ship v1”;
- the NuGet package ID;
- publishing credentials;
- a status check.
Claude Sonnet 5.5 wrote the code. Claude Opus 5.5 planned, managed and released.
Collect. v1.0.0 was tagged at 11:00 on 22 October, 22 hours 56 minutes after the first message. Work went on after the tag, and v1.1.0 followed that afternoon. Details: Building oneimage-csharp with a team of AI agents.
Refine. At 12:15 a rule on how competitors may be studied went into the oneimage-csharp record: through public documents and black-box output only, never through their source. Eighty minutes later it was a binding decision in the next library’s first planning commit.
3.4 Cycle 4: onepdf-csharp, started while oneimage-csharp was finishing
Run. It began with questions to the oneimage-csharp project manager, the first at 13:16 on 22 October. At 13:19 he asked:
would it make sense for us to have a separate “OnePDF” library that does the PDF parsing, and references OneImage for rendering?
He asked the manager to check the name. Five minutes after the question above he wrote: “nah, that works. Go ahead and kick off a planning session, and get to work.” The project manager answered a 33-question planning interview on his behalf. Kurtis sent one message during it, telling the manager not to stop at its context limit until the interview was finished. The planner was active from 13:25 to 13:39, and the repository’s first commit came at 13:41.
After the interview Kurtis sent the manager six more messages about onepdf-csharp:
- early evening, a question about the text-quality bar, then “how close are we to 1.0 right now? What’s missing?”;
- two about a second machine he had set up for heavy runs, and adding a remote-run tool to every library’s agents. That refinement went into the running builds the same evening, and onepdf-csharp’s release benchmarks ran on it;
- at 06:29 the next morning, “Make OnePDF public / Sign into chrome and publish nuget”;
- a request for the feature set and roadmap.
Collect. v1.0.0 was tagged at 06:43 on 23 October, 17 hours 1 minute after the first commit. onepdf-csharp 1.0 is a read-only .NET library written entirely in managed code, with no dependency beyond .NET itself. It covers:
- opening, repairing and decrypting files;
- the document model;
- text extraction in reading order;
- interpreting each page into an abstract drawing device.
At the tag it had 40,024 lines of C# in the library and 13,780 in tests, across 115 commits. Claude Sonnet 5.5 wrote the code. Claude Opus 5.5 planned, orchestrated and built the agents. Details: Building onepdf-csharp with a team of AI agents.
Refine and send. At 06:47, under five minutes after the tag, Kurtis wrote “oneocr next.” The project manager started setting up a GPU on the second machine. The oneocr-csharp planning interview ran from 07:20 and closed at 07:43. Its agents, including a new ML-engineer role, were in place at 07:46, and the library’s first commit was at 07:48.
3.5 Cycle 5: the next run and the queue
oneocr-csharp is an OCR library for .NET, built from first principles with small local models, designed to plug into oneimage-csharp and onepdf-csharp. It is still being built, so this report makes no claims about it.
Behind it are 15 written-up library ideas, all from 22 October. They include archive, barcode, charting and search libraries, and each records what has been decided and by whom.
4. What the factory took over
The number of messages fell, and so did the kind of message.
| Library | Messages | Median length | Single letters | 40 chars or fewer | Chars typed | Conversations |
|---|---|---|---|---|---|---|
| oneyaml-rust | 112 | 45 | 15 | 52 | 12,941 | 16 |
| oneyaml-go and oneyaml-csharp, with oneyaml-kit | 108 | 39 | 12 | 56 | 13,955 | 12 |
| oneimage-csharp | 14 | 147 | 0 | 2 | 2,677 | 2 |
| onepdf-csharp | 11 | 82 | 0 | 0 | 2,148 | 1 |
Median length and characters typed are in characters, pasted text included.
The rest of this section is interpretation, not measurement. The counts show that attention fell and when the factory changed. They don’t prove which change caused how much of the drop.
Read that way, the drop is the factory taking over work the owner did by hand in the first run:
- Single-letter answers disappear once a project manager answers the design interview in Kurtis’s place.
- The short “keep waiting” and “where are we at?” messages disappear once agents hand themselves off and supervisors wait properly.
What is left is longer and rarer: the goal, a name, money, credentials, and a priority call after 1.0.
Other things changed too. onepdf-csharp 1.0 is a read-only library, a smaller scope than a YAML library with a lossless editor. And by the fourth run, the questions a run would raise, and who should answer them, were known.
5. Not a full-time job
These runs went on alongside client work and other projects. The public devlog counts Kurtis’s completed agent tasks by day. A task is one finished piece of agent work, from a bug fix to a feature. Client work appears there as a count only.
| Run window (whole days) | Days | Days with client work | Client tasks | Other own projects active |
|---|---|---|---|---|
| oneyaml-rust, 26 Sep – 5 Oct | 10 | 7 | 134 | 8 |
| oneyaml-go and oneyaml-csharp, 12 – 16 Oct | 5 | 5 | 175 | 7 |
| oneimage-csharp, 21 – 22 Oct | 2 | 2 | 607 | 7 |
| onepdf-csharp, 22 Oct (the devlog ends there) | 1 | 1 | 43 | 4 |
The oneimage-csharp run went on during the client emergency described in PHP2Shell: switching off a client’s Drupal in two hours. That emergency accounts for most of the 607 client tasks.
The time between runs was busy too. Between the second result and the third go-ahead (17–21 October) the devlog shows 227 client tasks on 19 and 20 October, and work on five of Kurtis’s other projects.
The onepdf-csharp evening shows where the freed attention went. While onepdf-csharp was building, Kurtis sent 62 messages to agents working on the open-source projects. 11 were about onepdf-csharp, and 42 went to six planner sessions exploring new ideas. In one of them, at 13:41 on 22 October, he asked: “can you do OCR without a heavy ML model behind it? Like, can I release a decent OCR lib for .net that runs locally?” Later that night he summed up the pace in one line:
Let’s put this in perspective right quick. We’re building things with Alera. OneImage was an idea yesterday. OnePDF was an idea this morning.
6. Is it slop? The outside checks
Fewer human messages would mean little if the libraries were worse. Each run was held to the same four kinds of outside check:
- a test suite or corpus it didn’t write;
- a benchmark against the library people already use;
- fuzzing;
- published losses.
The checks got stronger as the factory was refined. They started with one official suite, then a shared kit that judges every competitor too, then a release gate fixed before the final run, and finally three public file corpora.
| Library | Outside tests | Against the incumbent | Fuzzing | Published losses |
|---|---|---|---|---|
| oneyaml-rust 1.0 | yaml-test-suite 402/402 (308 valid, 94 error) | Fewer CPU instructions than the strongest competitor in 16 of 20 workload cells, 2 ties (1.1.0 figures) | 10 targets, about 45 CPU-hours over two campaigns | 2 losing cells (a serde read and a small edit script). Wall-clock serde reads slower on 4 of 5 workloads (0.74–0.96×). |
| oneyaml-go 1.0 | yaml-test-suite 680/681 (loose); oneyaml-kit’s own cases 599/605 | Won 129 of 129 rows that had a rival, on time and on memory | 400,000+ executions before the first reviews (agents’ account) | 14 published deviations; the generic value type drops tags |
| oneyaml-csharp 1.0 | yaml-test-suite 680/681 (loose); oneyaml-kit’s own cases 605/605 | 34 losing rows at 1.0, all on unchanged emit; 8 at 1.1.0 | Not reported in its case study | The 8 remaining losses are published as losses |
| oneimage-csharp 1.0 | JPEG decode bit-exact against libjpeg-turbo; CMYK error 0.19 CIEDE2000 (agents’ account, color figure published) | Faster than ImageSharp 3.1.12 on 27 of 29 tasks | A target per input surface, 10 minutes each, clean (agents’ record) | CMYK conversion 1.64× slower than ImageSharp, which skips the ICC profile. JPEG thumbnail peak memory 1.0 MiB higher. Four rows beyond 1.5× of the fastest native wrapper. |
| onepdf-csharp 1.0 | GovDocs1 (5,767 files), 5,000 SafeDocs files and the veraPDF corpus (2,906 files): 0 crashes and 0 hangs. Opens every file PdfPig opens, plus 20. | Faster than PdfPig 0.1.16 on all 17 rows. Text error on 92 real-world files 5.6% against 13.5% (content) and 15.9% against 36.5% (reading order). | 13 targets, 600 s each, no findings (agents’ record) | PDFium and mutool use less peak memory (43 and 45 MiB against 104 MiB on a 300-page file). Read-only, no OCR. |
The figures for the first four libraries come from their case studies, where each is sourced. The onepdf-csharp figures come from its README and decision record at the v1.0.0 tag, and were not re-run for this report. Its competitor and corpus results are the agents’ own measurements, with the method published alongside them.
Hold every run to the same checks, not only the first. A factory’s output stays credible only if the fast runs are judged by the same rules as the slow one.
7. What went wrong
Each case study lists its own failures. Across the runs:
- The first run carried costs the factory later removed. Agents waited on test runs, review rounds didn’t converge, and agents invented rules and then obeyed them. These problems were the raw material for the refinements in section 3.
- oneyaml-go and oneyaml-csharp still needed supervising. Kurtis told supervising agents to keep waiting seven times, and rejected both 1.0 READMEs after they shipped.
- The oneimage-csharp run lost 5 hours 25 minutes to a restart of the workstation.
- onepdf-csharp needed a patch release 46 minutes after 1.0. v1.0.1 fixed README links that didn’t work on the NuGet page. By the agents’ account, its first run on all four operating systems needed three fixes to tests and CI before the tag. The last gate work found a real cache race, which was fixed before the tag.
- The owner-attention measure itself has gaps. The platform doesn’t record who sent each message, so the counts rest on elimination and a hand read (section 2). Reading time isn’t counted.
8. Kurtis’s claim: the same approach works beyond libraries
This section is Kurtis’s interpretation, not a measurement.
Kurtis sees the library factory as one instance of a general capability. In his view, Alera can be used to set up the same combination of specialist agents, a set process and a set architecture for many other kinds of work, and the number of these setups is growing. He also reads the timings in that light. The first run took ten days because a first result has to exist before there is anything to learn from. Once it existed, each later adjustment was small.
This report measures one factory. The published record shows one other piece of agent work at volume. In the PHP2Shell case study, a builder agent turned each of a client’s 82 credit-application form specs into a web component, and all 82 are live.
9. Recommendations
- Build the factory on the first run, and expect that run to take days. The procedure, agents and prompts that made the later runs fast came out of the first one.
- Refine as soon as a result is in, in small changes. The review after the second result took under four hours. The rule added after oneimage-csharp was in the next library’s record 80 minutes later.
- Measure the owner’s attention per run, not only the calendar. oneyaml-go and oneyaml-csharp took less than half of oneyaml-rust’s time, but almost as many messages.
- Let an agent answer the design interview, and mark every answer with who made it. In the two runs that did this, Kurtis sent 14 and 11 messages, and the record still shows which decisions were his.
- Keep the outside checks fixed while the speed changes. Every run gets an outside suite or corpus, the incumbent as the benchmark, fuzzing, and published losses.
Limits of this report
- Owner messages are counted from the stored agent conversations, by the method in section 2. The rule-based step was applied to every conversation. The hand read covered the conversations assigned to each library.
- Agent runs, models and cost are the figures published in each case study, counted by that study’s method over its own period.
- Cycle timings come from git commits and tags, the crates.io publish record, agent run records and message timestamps, in US Central time. A refinement is dated by its first record: a commit, a written decision or the session that made it.
- Line counts include comments and blank lines.
- Parallel work comes from the public devlog, counted by whole calendar day. The devlog was generated through 22 October, so onepdf-csharp’s second day isn’t in it.
- Library comparisons are not like for like. A YAML library, an image library and a PDF reader differ in size and difficulty. The tables compare the same owner, the same factory and the same platform across runs. They do not compare the libraries with each other.
Links
- Case studies:
- oneyaml family: recursiveai.org/oneyaml. Repositories:
- oneimage-csharp: github.com/recursive-ai-oss/oneimage-csharp
- onepdf-csharp:
- Devlog: recursiveai.org/devlog