In one minute
Lore Week 1: where a change lands, what a check really checks, and who may press the button
33 merged, about 16 minutes from open to merge (median)
Lab, weekly paper. Week of Mon 12 Oct to Sun 18 Oct 2026, Europe/Istanbul. Counts were taken on Sunday 18 Oct at about 22:15 Istanbul time, so the last hour and a half of the week is not in them.
This week we merged 33 pull requests. A pull request is a proposal to change our code: someone, usually a coding agent for us, opens it, and it is reviewed before it joins the main version. The typical one merged about 16 minutes after it was opened. Most of the work went into AutoReal, where we are building a content engine and a chat interface for it, and into the rules that keep agents safe while they build.
A list of everything that changed would be long and dull. Instead we want to teach three ideas that the week made clear to us:
1. Where a change lands. One of our fixes went to the wrong branch, and it shows how chains of pull requests can fail without any error.
2. What a check really checks. A green tick is worth what it tested, and it is only useful if it arrives quickly.
3. Who may press the button. When an agent can spend money or publish, a gate in front of that action does more than a rule on a page.
For each idea we say what it is, why it matters, how it works in plain words, what others have written about it, and how our week compares.
Method
How we looked at the week
We counted merged pull requests in each of our repositories for the week, read the text of every one, and looked at the automated check runs. We also read each product's state file, a short document that says what exists right now, and our internal decision records. Our internal rules repository has no state file, so its decision records stand in for it. This is one week of a small team, so the numbers show a pattern and prove nothing. Where a figure comes from a pull request's own text and not from our count, we say so.
Idea 1
Where a change lands
Intended
What happened
Later: the whole branch landed again as a new pull request
What it is. In Git, the tool most teams use to track code, every change lives on a branch. A pull request says: take the changes on this branch and add them to that branch, which is called the base. Usually the base is the main branch, the version that ships. But a base can be another feature branch. Then we have a chain, often called a stack: a small change built on top of a bigger one that is still under review.
Why it matters. A chain lets work continue while reviews wait. It also adds a rule that is easy to forget: the order of merging is part of the design. Merge a link in the middle and it lands on the link below it, not on main. No error appears. The change just sits somewhere you did not mean it to.
How it works, in simple words. Picture a stack of trays. The bottom tray goes on the shelf, which is main, and each tray above rests on the one below. You cannot put a middle tray on the shelf without lifting everything under it. GitHub's documentation for its stacked pull requests says the same: they merge from the bottom up, and a mid-stack pull request cannot be merged alone, because the ones below it always go with it. A plain pull request whose base is another branch has no such protection. If it is merged, the changes land on its base, the lower branch, not on main.
What happened to us. The pull request with the real-post work of our content engine was big: it added about 3,650 lines across 62 files. It was blocked by three things: a file that exported something it should not, a paid test script with no gate, and a conflict with main. The fixes went into a second pull request whose base was the big one's branch. On Saturday evening the second one was merged, which put the fixes on the big branch and not on main. The big pull request was then closed instead of merged. Nothing of it was on main until we landed the whole branch again as a new pull request about an hour and a half later, resolving three conflicts by keeping both sides. The text of the fix said clearly where it was going, so the label was right. What we lacked was a plan for the order of the chain.
What others say. GitHub's Merging a pull request page says that if you delete a branch after its pull request is merged, GitHub moves any open pull request that used the deleted branch as its base onto the base of the one you just merged. In the tray stack the bottom pull request's base is main, so that move puts the next pull request on main when the bottom one is merged and its branch is deleted. Engineers who worked at Meta and Google describe stacking as a way to keep changes small and keep working while reviews wait, and they are frank that it takes tooling and a lot of rebasing. The author of that widely read account says he has a small investment in a stacking tool company. Size matters here too. Google's engineering book puts a small change at about 200 lines, and the DORA research programme argues for small batches, adding that large changes written quickly by AI coding assistants are hard to review, test and integrate safely.
How we compare. We used plain branch chains, the case with the least protection. We named the target, which is good, but not the merge order, and the change was more than 18 times Google's size for a small one. We count both as lessons: from now on the merge order goes in the first lines of any chain, and big work gets cut into smaller pieces earlier.
Idea 2
What a check really checks
Whole check run0 to 16 min
Fast core job0 to 1000 s
Figures from one run each, as reported in the pull request. Not measured again since the build step was added.
What it is. Every time someone opens a pull request, our automated checks run. They read the code for mistakes, run tests, and build the app the way a server would. This is usually called continuous integration. The result is a green tick or a red cross.
Why it matters. A green tick is a promise. If the check does not look at what you ship, the promise is empty. And if the check is slow, people stop waiting for it, and small pull requests stop being small.
How it works, in simple words. Two things must be true. The check has to look at what goes live, or at something at least as strict. And it has to be quick. Martin Fowler's advice on speed is that the extreme programming guideline of a ten minute build is "perfectly within reason". The DORA programme asks for the same shape: every commit triggers a build, and tests give feedback in a few minutes. DORA adds that the package made by the CI build should be the authoritative one, used by everything downstream.
What happened to us, part one: the wrong check. The same app can be built by more than one tool. The content engine pull request built fine with the tool that runs in production, and failed with a second, stricter tool, because a route file exported something it should not. Our automated checks did not build the app at all, so the mistake reached review. We added a build step that runs the stricter tool and then the production one. The same change renamed one of a pair of files whose names differed only in upper and lower case, because that pair broke the type check on a default Mac disk.
What happened to us, part two: the slow check. One earlier change had stretched our main checks job from about 2 minutes to about 14. The pull request that repaired it reports two real runs: the whole check run took 14 minutes 36 seconds before and 6 minutes 21 seconds after, and the fast core job fell from 872 seconds to 111. The fix moved the slow browser-rendering tests into their own job that runs alongside, so the quick checks come back quickly. These are that pull request's own figures, one run each. We have not measured again since the build step was added.
How we compare. As of that run we sit under Fowler's ten minutes. We are further from DORA's single authoritative build, because our strict build is an extra guard and not the thing that ships. We keep both until we have measured the combined run.
Idea 3
Who may press the button
Readfree, no gate
Write a draftcan be undone, no gate
- a typed yes does not count
- one answer per card
- old cards expire
Spend or publishcannot be undone, gate
What it is. An agent that can only draft text can do little harm. An agent that can spend money, publish a post or delete data is a different case. A gate is a step that stops the action until something confirms it. The questions are where to put the gate and what it checks.
Why it matters. A badly written sentence can be fixed. A paid call cannot be taken back, and a post that went out has already been seen. Security people now list this as a named risk. OWASP's list for applications built on language models includes "excessive agency", and one of its causes is an application that fails to independently verify and approve high-impact actions. A neighbouring entry, unbounded consumption, covers the cost side, and recommends rate limits and user quotas.
How it works, in simple words. Sort actions by how hard they are to undo. Reading is free. Writing a draft can be undone. Spending and publishing cannot. AWS's guidance for agent systems makes the same cut and adds a warning we like: sending every action to review produces rubber-stamp approvals, and sending none produces unbounded autonomy, so pause only where a decision matters. It also says the sorting should follow plain rules and not the model's own judgment, because untrusted content could talk the model into calling a risky action safe. Anthropic's guide to agents describes a related brake: it is common to add stopping conditions, such as a maximum number of iterations, to keep control.
What we did. We built gates in three places. First, our content engine is closed unless switched on, and it has its own quota. Second, a script that tests our post planner used to make about twenty paid calls with no confirmation. It now prints an estimate and refuses to run without an explicit flag. The estimate is rough: it counts characters divided by three, not real tokens, and the pull request says plainly that it is not a bound. For the twenty requests it gives about $0.07, which matches the one recorded run that cost $0.0707, plus a rough ceiling of about $1.34. Third, in our chat interface, anything that spends or publishes needs an approval card that the server checks. A typed "yes" in the conversation does not count, each card is answered once, and an old card expires.
How we compare. The shape matches the guidance: tiers by reversibility, a check outside the model, a ceiling and a quota. We have not yet seen the gate under real customer use, so we cannot say whether it produces careful approvals or rubber stamps.
Lessons
What we learned
Say the order, not only the target. Our fix named where it was going and still went wrong, because nobody wrote down which merge came first. A chain of pull requests is one plan, and we now treat it that way.
A passing check is only as good as what it builds. We had green ticks that never looked at the app. The stricter build was a small change. Knowing we needed it took a failure.
Make a failure say which step failed. Connecting our app to a social network failed in production and told us nothing. The first fix logged which step failed and what the network answered. That showed one step returned a good answer in a shape the network's own documentation did not show, and the second fix accepted it. The two fixes merged about 21 minutes apart. Later steps of the connection are still unconfirmed.
A raw count flatters. Our 33 includes a pull request that merged into a branch, so it is not 33 changes on main. In the documents we read, 45 of the 54 commits on the main branch of our internal rules repository from 1 to 15 October came from automated routines. Counting helps. Counting alone does not tell us what was worth doing.
A line limit does not keep a file short to read. One product's state file grew from about 44,000 to about 69,000 characters in the week, up about 57 percent, while its line count stayed near 200. The lines simply got longer. We did not check whether that bothers readers.
We corrected our own first essay. Six source lines were fixed 19 minutes after it merged. The lesson is to run the fact check before the merge. We did not check whether the uncorrected lines were live in between.
What surprised us. The role of one coding agent was set one way and corrected within the same session on 15 Oct, before it was written down, and the written rule changed again the next day. Short decision records kept in one place let us keep up.
Next
What happens next
This comes from our open pull requests, plans and decision records. Anything marked Proposal is ours and is not decided.
- The chat interface gets scheduling and a calendar next, according to its state file. An open stabilization pull request aims at screens that never crash and at showing every post status.
- Two decisions are waiting in writing: whether agents may commit straight to the main branch of a repository with one owner, and whether a second person may merge in one product repository.
- An open plan writes our branch rules down for now, because the paid setting that would enforce them is not available to us. It also raises an open question about giving the cloud agents an identity of their own.
- Proposal: write the merge order in the first lines of any chain of pull requests, and ask agents to open smaller pieces.
- Proposal: measure the check run again with the new build step and report it against the ten minute line.
- Proposal: add the base branch of every pull request and the reason for each failed run to next week's counts, so a raw count flatters us less.
- Open questions: should a chain exist at all for work of this size, or should we cut it into independent pieces? Does the extra build step cost more time than it saves?
Limits
What we could not verify
- Whether the chat interface and the content engine work for real customers. They sit behind switches for administrators, and the paid run covered the planner only.
- Whether the social network connection works end to end. Only the first steps were confirmed.
- The hosting platform's own build. Our checks prove lint, types and tests, and we did not observe that build.
- Why the big pull request was closed instead of merged. The text we read says it was closed and does not say why.
- Which agent wrote each pull request. All 33 were opened by one account, and the agent is named only in the text.
- The target branch of 32 of the 33, and any direct pushes that never became a pull request.
- Whether GitHub's native stacked pull requests would have prevented our mistake. We read their documentation and did not try them.
- The check times: one run each, as the pull request reports them.
- External claims are as each source states them.
18 Oct 2026
Sources
We opened each link on 18 Oct 2026 and checked that it loads and says what we use it for.
- GitHub Docs, Merging a pull request: if you delete a head branch after its pull request has been merged, GitHub moves any open pull request that used the deleted branch as its base onto the base of the pull request you just merged.
- GitHub Docs, About stacked pull requests and Merging stacked pull requests: merging from the bottom up, and no merging of a mid-stack pull request alone.
- Gergely Orosz, Stacked Diffs (and why you should know about them), Pragmatic Engineer, 17 Oct 2023: how stacking works at large companies, why it is rare elsewhere, and the author's disclosure of his investment.
- Software Engineering at Google, Chapter 9, Code Review: the section "Write Small Changes", with "about 200 lines of code" as a general limit.
- DORA, Working in small batches: small batches, and the note on large changes written quickly by AI coding assistants.
- Martin Fowler, Continuous Integration: the section "Keep the Build Fast" and the ten minute guideline.
- DORA, Continuous integration: a build and fast tests on every commit, and the authoritative CI package.
- OWASP GenAI Security Project, LLM06:2025 Excessive Agency: excessive autonomy and approval of high-impact actions.
- OWASP GenAI Security Project, LLM10:2025 Unbounded Consumption: rate limits, user quotas and the cost risk.
- AWS Well-Architected Framework, Agentic AI Lens, AGENTSEC04-BP02, risk-tiered approval of critical decisions: risk tiers, rubber-stamp approvals, and plain rules in place of model judgment for the tiering.
- Anthropic, Building effective agents: stopping conditions such as a maximum number of iterations.
Everything else is from our own records: pull request lists, workflow run lists, state files and decision records, taken 18 Oct 2026. Our repositories are private, so we link nothing from them.