In the 30 days from 2026-08-24 to 2026-09-23, 489 pull requests merged to the main branch of the Analytical Insider platform repository. Together they added 488,174 lines and deleted 77,067. That is roughly half a million lines a month and about 490 pull requests a month. A human merged every one of them: two people hold merge rights, none of the 489 used auto-merge, and no model merges, deploys, or marks work Done. This post is an engineering write-up of the internal system behind those numbers. It covers the retrieval layer that decides what a model reads before it writes, and the work graph that decides who owns what. It covers the audit gate that has read 138 of the 139 unattended builds merged since 2026-09-08, and the lesson log meant to stop the loop making the same mistake twice. Unless a section names an earlier measurement date, every figure was measured on 2026-09-23 from the repository's git history and the GitHub API. The post deliberately leaves out customer data, the vendors we buy data from, and anything financial. It also leaves out a claim we cannot back: this is not millions of lines a day. The busiest single day added 44,151 lines.
Key takeaway: The loop runs on retrieval from systems of record that already exist (git, GitHub, the issue tracker, the error tracker and a lesson log), not on a vector database. A small in-memory graph answers the ownership and duplicate-work questions that a flat issue list cannot. The throughput is measured, and what stands between a build and main is a read-only model auditor plus humans who still own merge, deploy and Done.
The first pull request merged to main on 2026-03-24. As of 2026-09-23 the repository holds 1,148 merged pull requests, 6,856 tracked files, 779,828 lines of TypeScript and TSX under the application source directory, and 1,192 test files. The two busiest weeks on record, 2026-W37 (125 merged pull requests) and 2026-W38 (168), are the week the audit gate and the context pack (the retrieved-facts bundle explained below) went live on the unattended lane, 2026-09-08, and the week after. We mark that on the chart and do not claim the gate caused the rise; this post does not isolate it.
What RAG means here: retrieval without a vector store
Retrieval-augmented generation, in this loop, means one thing: before a model builds or audits a change, a deterministic step gathers the recorded facts that bear on that change and puts them in the prompt. There is no vector store, no embedding model and no similarity search. Every source is a system of record the team already keeps, and every lookup is an exact match. The keys are concrete: a file path the issue names, an issue key, a commit that touched a path, a pull request that owns a key, an edge in the tracker, an error with a stack frame. The output is a short markdown pack of six sections, capped at 14,000 characters and ranked newest first. The builder and its auditor receive the same pack, framed as recorded facts to verify rather than instructions to follow. If one section fails to load, the failure is logged and the build runs without it.
The six sections, and the cap on each:
| Section | What it retrieves | Cap |
|---|---|---|
| lessons | Lessons whose path globs match any file the issue names, plus lessons that mention the issue key | 12 |
| history | Recent commits touching those paths, and commits that name the issue key | 12 |
| related | Pull requests that own any other issue key the issue text references, one hop on the work graph | 8 |
| relations | The issue's own tracker edges: blocked by, blocks, duplicate, related | 12 |
| sentry | For a bug linked to a production error: event and user counts, first and last seen, release, top in-app stack frame | 3 |
| overlap | Open pull requests already changing the same paths | 10 |
Each section exists because a specific question kept coming up that the issue text alone could not answer.
History finds work that already shipped. A fix sometimes lands inside a sibling pull request opened for a different issue, while the board still shows the original as open. A commit that names the issue key, or one that touched the exact files the issue names, is evidence the work may already be on main.
Relations carries what the issue never says. A blocked-by or duplicate edge rarely appears in the issue's own description. Without it a model will build an issue whose blocker has not shipped.
Sentry points at the line to reproduce. For a bug filed from a production error, the builder starts from the top stack frame inside our own code, not from a paraphrase of it.
Overlap prevents two builds colliding. The same list feeds a file-conflict check that runs before the dispatcher (the scheduler that hands queued issues to a builder) claims the issue at all.
The lessons section deserves one more note. Interactive sessions get lessons from a hook that fires before every edit (covered below). The unattended builder runs without interactive hooks, so the pack calls the same matcher directly against every path the issue names. One lesson grammar, two readers, no second copy.
The design rule, paraphrased from the architecture record:
No vector store, no embeddings, no new database. Every source is already a system of record with exact-match retrieval that fits in a prompt. A similarity index over a few hundred lessons and a git log would be a second copy with its own staleness.
This is a deliberate choice, not a roadmap gap. The questions a builder needs answered are exact: has anyone committed to this file recently, does a lesson fire on this path, does another pull request own this key, is this issue blocked? A similarity search answers a different question, what looks like this, and returns plausible neighbors with the same confidence as the real record. Exact retrieval returns the record or nothing, and nothing is an honest result. The pack added zero new dependencies and zero new stores: no index to rebuild, no embedding model to version, no second copy to go stale.
What graph engineering means here: a work graph that is never the source of truth
Graph engineering, in this loop, means modeling the work itself as a graph and asking it bounded questions. The nodes are issues, pull requests, commits and files. The edges are relationships the tools already record: a pull request owns an issue, a commit belongs to a pull request, a commit touches a file, an issue blocks or duplicates another issue. The graph lives in memory. It is a projection built from git, GitHub and the issue tracker, never the system of record, and when it is wrong it is thrown away and rebuilt from source rather than repaired. Every traversal is bounded to a depth of 3 and a maximum of 1,000 results, so a question such as "what else touches the files this issue names" returns in bounded time and bounded size. The graph exists to answer two questions a flat issue list cannot: who owns this work, and was it already done?
Ownership is the branch and the title, not a body mention
A pull request can mention many issue keys: the one it fixes, the ones it relates to, the ones it explicitly does not fix. Infer ownership from any mention and the graph invents owners. On 2026-08-02 we measured it across 30 pull requests. An issue key in the branch name or the pull request title identified the owning pull request correctly 7 of 7 and 11 of 11 times. A bare mention in the pull request body invented an owner it did not have on 10 of 21. So the rule is simple and mechanical: ownership comes from the branch name or the title, never from a body mention, and a closing keyword counts only at the start of a line.
Two consequences follow. The dispatcher offers a build or a re-dispatch only when no open and no merged pull request references the issue, and it checks GitHub before claiming. The board recomputes each issue's state from GitHub on every load, so a status field in the tracker is never treated as proof that code merged.
A merge that changes zero files is a duplicate build
The second question, was it already done, has a signal that needs no issue linkage at all. On 2026-07-27 we looked at the last 300 commits on main and found 11 merged pull requests that changed zero files. In each case a build ran, a review happened, a merge happened, and nothing shipped. In one, a pull request re-merged another's work 6 minutes after it landed. In another, a fix was re-merged 14 hours after it had already shipped. None of the 11 carried an issue reference in the body, the title or the branch, so no issue-level guard could have seen them.
The duplicate-build detector now grades three signals: an empty merge (confirmed), a title collision (probable) and a file overlap (probable). It reports after the fact. It does not block a merge, and we are explicit about that: the rule that a zero-file merge is a duplicate build is kept by the human reviewing the diff. A mechanical pre-merge block belongs in branch protection, which models in this loop are not allowed to change.
The loop end to end
The loop has a strict role split. Claude Fable 5.1 is the auditor and orchestrator: it plans, reads and judges, and it never builds. Opus, Sonnet and Haiku are the workhorses: they search, implement and fix. Codex runs as a second read-only auditor when configured, and as an optional builder lane. The auditor role belongs to Claude Fable 5.1, with Opus as the fallback only when Fable is unavailable, and the auditor never writes to the branch it reviews.
An unattended build moves through the same steps every time:
- An issue in the tracker is set to In Progress and carries exactly one lane label (a tag naming which worker lane should build it). That pair, and nothing else, is the dispatch queue.
- The dispatcher picks it up on its next tick, after confirming on GitHub that no open or merged pull request already owns it.
- The context pack is assembled: lessons, history, related, relations, sentry and overlap.
- A workhorse model builds the change.
- The four gates every pull request runs: lint, typecheck, unit tests, production build.
- A protected-path check on the diff; a hit fails the attempt and nothing is pushed.
- The read-only audit.
The audit gate is the step that turns a passing build into a reviewed build. After the change passes lint, typecheck, unit tests and a production build, the diff must clear the protected-path check. Claude Fable 5.1 then reads the diff read-only, with the same context pack the builder saw, and returns a structured verdict: approve or request changes, with findings. When Codex is configured it audits second, also read-only; either auditor's request for changes vetoes, and approval needs every auditor that ran. On approve, the branch is pushed and the pull request opens with the verdict attached. On request changes with an attempt left, the findings go back into the builder's prompt for one fix round on the same commits, and the audit runs again. The auditor cannot write to the repository, so it cannot fix what it flags.
The other two outcomes keep the gate honest. If attempts run out with a request for changes standing, the pull request still opens, with the verdict on top and a do-not-merge banner. If the auditor is unavailable, it opens marked not audited. Neither outcome is hidden or allowed to look like an approval.
Then the loop stops being autonomous on purpose. Three gates are human and stay human: merge to main, deploy to production, and Done. Merging does not complete an issue. Done requires two labels that only a human adds, one for a dev verification and one for a QA pass. The reconciler (the process that moves issue status to match what shipped) moves issues no further than Deployed and writes no labels, because a machine that sets a verification label is asserting that a human's judgment happened.
The unattended lane built 169 of the pull requests that merged in the 30-day window. The median build took 28 builder-minutes, with a p75 of 35 and a p90 of 45; the fastest took 13 and the slowest 65. In total that is 5,053 builder-minutes, about 84 hours, for 169 merged pull requests, with a median of one commit each. The first attempt succeeded on 116 and 53 needed the second, which is the maximum. By build model, a Haiku-plus-Opus pair built 139 and Opus alone built 30.
The audit gate went live on the unattended lane on 2026-09-08. Of the 139 unattended pull requests merged after that date, 86 were approved on the first audit round (62%) and 35 were approved after one fix round (25%). Another 17 opened with a request-changes verdict still on top for the human to judge (12%), and 1 opened marked not audited because the auditor was unavailable (1%). The other 30 predate the gate.
Two things in those numbers matter more than the approval rate. First, a human merged all 169, including the 17 the auditor did not approve. The auditor's verdict informs the merge; it does not make it. Second, the gate costs time. Median builder-minutes rose from 24 before the gate to 29 after it, and the p90 rose from 36 to 45. The audit and its fix rounds are the obvious cause, though this post does not isolate them from other differences between the 30 pre-gate and 139 post-gate builds. We would rather pay it.
The memory layer: a lesson log with a reader
Retrieval is only as good as what was written down. The rule is that every session ends with either a one-line lesson or an explicit statement that there was none. A lesson is the thing the session did not know at the start, with the evidence that proved it. "Check the build arguments list, not the deploy spec" is a lesson; "be more careful with configuration" is not.
As of 2026-09-23 the log holds 683 lessons. There are 78 in a frozen archive file (30 from 2026-07, 46 from 2026-08 and 2 whose entry lines carry no month) and 605 in a directory that holds one file per lesson (196 from 2026-08 and 409 from 2026-09 through 2026-09-23). Of those 605 files, 420 (69%) carry a mechanical predicate: a list of path globs that says which files the lesson is about. The rest are judgment lessons, read on demand.
Why one file per lesson. The log started as a single append-only file, so every concurrently open pull request edited the same tail and the first to merge put the others into conflict. On 2026-08-16, 24 of 27 conflicting open pull requests conflicted on that one file alone. The archive was frozen that day and every lesson since is a new file with a date-first name. New files never collide.
Why the reader exists. From 2026-07-09 to 2026-08-03 the log had a write half and no read half. In that period the same class of defect was caught three separate times, recorded correctly each time, and recurred each time, because no later session ever saw the earlier entry.
How recall works. A hook runs before every edit and every file write in an interactive session. It reads both the archive and the lesson directory, matches the path being edited against every predicate, and injects the matching lessons as context before the edit lands. It caps at 3 lessons per path, newest first, and fires each lesson at most once per session. Predicates are globs that evaluate in milliseconds. The hook never blocks an edit, because a guard that can break every edit gets disabled, but it degrades loudly, and a check script fails on an unparseable predicate or malformed entry so a formatting slip cannot silently switch recall off.
The unattended lane reads the same log through the context pack, using the same matcher. The standing rule that came out of the write-only period applies to everything in the loop, not only lessons: any store the loop writes to needs a named reader before it counts as done, and the change that adds the store names the reader.
What the numbers show, and what they do not
For the same 489 pull requests, open-to-merge time has a p50 of 3.3 hours, a p75 of 10.9 hours and a p90 of 18.9 hours. By bucket, 109 merged in under an hour, 152 in 1 to 4 hours, 203 in 4 to 24 hours, 16 in 1 to 3 days and 9 took longer than 3 days. Size, counted as lines added plus lines deleted, has a p50 of 552, a p75 of 1,279 and a p90 of 2,802, with a median of 7 files changed. By bucket, 126 were under 200 lines, 200 were 200 to 1,000 lines, 148 were 1,000 to 5,000 lines, and 15 were 5,000 lines or more.
Attribution is visible in the history itself. Of the 489 squash commits (the single combined commit each pull request produces on merge), 462 (94%) carry a model co-author trailer. 466 came from branches the models open under their own prefix. 438 squash subjects (90%) carry the tracker's issue key, and 374 branch names do. That linkage is what lets the work graph and the duplicate-build detector work at all: an unlinked pull request is invisible to every issue-level check, which is exactly how the 11 zero-file merges went unnoticed.
Generated files are not what inflates the count. Excluding lockfiles, JSON, snapshots and database migrations, the same window added 480,695 lines and deleted 69,865.
The limits, stated plainly
Lines are a cost, not a value. Every line added is a line someone has to read, test and maintain. We report lines because they are measurable, not because they measure progress.
The count includes churn. Week 2026-W35 deleted 48,527 lines, and the single day 2026-08-28 deleted 32,435, from removals and rewrites. Across the window, added plus deleted comes to 565,241 lines over 5,244 file changes. A rewrite adds and deletes the same feature; it is not two features.
Throughput says nothing about defect rate. This post does not measure how many of the 489 pull requests introduced a bug, and we are not going to imply an answer. The gates, the audit and the human merge exist because throughput without them would be dangerous, not because they have been shown to drive defects to zero.
The peaks are modest. The busiest day by line count was 2026-09-17 with 44,151 lines added. The busiest day by pull request count was 2026-09-14 with 47. Those are the ceilings in the data. Anyone telling you their agents write millions of lines a day should be able to show you the git log.
Four lessons from running it
1. Write-only memory is an audit trail, not a memory. From 2026-07-09 to 2026-08-03 we recorded every lesson and read none, and the same class of defect came back three times. The fix was not better lessons; it was a reader wired into the edit path and the unattended builder's context.
2. One append file is a merge-conflict machine. A single shared file that every change appends to makes concurrent pull requests conflict. On 2026-08-16, 24 of 27 conflicting pull requests conflicted on that file alone. One file per record, named by date and slug, removes the class entirely.
3. A body mention is not ownership. Inferring ownership from a mention invented an owner on 10 of 21 pull requests; branch name or title was right every time we measured it. Pick the mechanical signal and make every tool that reads ownership use the same one.
4. A zero-file merge is a duplicate build. It is the one duplicate-work signal that needs no linkage and no judgment: the diff is empty, so the work was already there. Eleven slipped through in 300 commits because every other guard depended on an issue reference those pull requests did not carry.
How to build the smallest version of this yourself
None of this needs a new platform. The smallest useful version needs git, an issue tracker, a CI gate you already run, and two model roles.
- Put the issue key in the branch name or the pull request title, always. Treat that as the only ownership signal. Count a closing keyword only at the start of a line.
- Keep lessons one file per lesson, with a path glob when one exists. Date first, short slug, one line of lesson, one line of evidence. Add a check that fails on a malformed entry.
- Retrieve by exact match before every build. Match the lesson globs against the files the issue names, pull the recent commits on those files, pull any commit that names the issue key, and list the open pull requests touching the same paths. Cap the result and rank it newest first.
- Split the roles. One model builds. A different model audits read-only with the same retrieved context and returns approve or request changes. Allow one fix round, and when the reader still objects, open the pull request with the objection on top instead of hiding it.
- Keep merge, deploy and Done human. Let the machine move work forward on the board; never let it assert that a human verified something.
- Run a zero-file check on every merge. Report every merged pull request that changed nothing. It will find duplicate builds that no issue-level guard can see.
Start with steps 1 and 6. They cost almost nothing and they make every later step measurable.
Why a lead-intelligence company built this
Analytical Insider sells qualified sales leads with the reason each one surfaced and the evidence that proves it. The engineering loop runs on the same discipline: nothing is accepted without the evidence attached. A pull request carries its audit verdict. A lesson carries the proof that taught it. A number in this post carries the date it was measured and the system it came from. When we say a lead is worth a call, we hold that claim to the same standard, which is what verified pipeline means in practice, and it is the approach behind the verified pipeline launch.
The retrieval rule carries over too. Our AI visibility work measures how AI engines describe a company, and the answer to "what does the model say" is only useful when it is tied to the exact prompt, engine and date that produced it. Exact, dated, sourced records beat plausible summaries, whether the reader is a builder model deciding what to change or a sales team deciding who to call.
Frequently Asked Questions
How many lines of code does the Analytical Insider engineering loop produce?
Measured on 2026-09-23 over the prior 30 days: 489 pull requests merged to main, 488,174 lines added and 77,067 deleted, which is roughly half a million lines a month. The busiest single day added 44,151 lines and the busiest day by count merged 47 pull requests. It is not millions of lines a day, and lines are a cost measure, not a value measure.
Does the loop use a vector database or embeddings for RAG?
No. The retrieval step is exact-match lookup against systems of record that already exist: the lesson log, git history, the pull request list, the issue tracker's own relations, production error evidence, and open pull requests touching the same files. The six-section pack is capped at 14,000 characters. A similarity index over a few hundred lessons and a git log would be a second copy with its own staleness.
What is the work graph and is it a database?
The work graph is an in-memory projection over git, GitHub and the issue tracker. Its nodes are issues, pull requests, commits and files. It is never the system of record: when it is wrong it is rebuilt from source, never repaired. Every traversal is bounded to depth 3 and 1,000 results. It answers who owns a piece of work and whether that work already shipped.
Do AI models merge or deploy code in this loop?
No. Models build and audit. A human merges every pull request (two people hold merge rights and none of the 489 used auto-merge), a human deploys, and an issue reaches Done only when a human adds both a dev verification label and a QA pass label. Of the 169 pull requests the unattended lane built in the 30-day window, every one was merged by a human.
What does the audit gate do?
After a workhorse model builds a change and it passes lint, typecheck, unit tests and build, Claude Fable 5.1 reads the diff read-only and returns approve or request changes, with Codex as a second read-only auditor when configured. Of 139 unattended pull requests merged after the gate went live on 2026-09-08, 62% were approved on the first round, 25% after one fix round, and 12% reached the human with a request-changes verdict on top.
How does the loop avoid repeating the same mistake?
The rule is that every session ends by logging a lesson or stating that there was none. Lessons live one file per lesson, and 420 of the 605 lesson files carry a glob predicate. A hook runs before every edit, matches the file path against every predicate, and injects at most 3 matching lessons per path. The unattended builder receives the same matched lessons in its context pack.
Can a small team build a version of this?
Yes, with git, an issue tracker, a CI gate and two model roles. Put the issue key in the branch name or pull request title, keep lessons one file per lesson with a path glob, retrieve by exact match before every build, give a separate model read-only audit authority, keep merge and deploy human, and treat any merge that changes zero files as a duplicate build.
Tags