At LogicStar we run a software factory on our own code: coding agents pick up tickets from our issue tracker and work them without anyone watching, and a person reviews the pull requests they open. In the first week of November 2026 we measured what it did with tickets from our own platform, including tickets made from findings of the review bot that checks our pull requests.
Four of those tickets turned into pull requests that passed CI and our review bot. Nobody wanted any of them. Each one asked for something a person had already answered: a fix that was already in, or a change the team had decided against. The answers were written down in replies on old pull requests, and none of the agents read them.
We wanted to know what would have caught this, so we compared the options: a stronger model, a different coding agent, a simulated author answering the agent's questions, and a read-only investigation before any code is written. This post covers what we measured, why it matters more when agents work without anyone watching, and the controls we keep on the work once it starts.
Summary
On ten hard tickets, a stronger model, a different coding agent and simulated answers from the author each solved the same two.
Of six tickets made from review bot findings, five asked for something a person had already answered in the review thread. Four of those became pull requests that passed CI and the review bot.
A read-only investigation that reads the review history stopped all five, naming the decision each time.
The investigation then ran on 19 fresh tickets that played no part in its design. It went ahead on 9 of 10 wanted changes and held back 7 of 9 requests an author had already declined.
The investigation blocks only on a recorded decision or work that is already done. For anything else it states an assumption in the pull request and proceeds.
In a software factory nobody watches the run, so this check has to happen on every ticket by itself.
Why it matters more in a software factory
When you run a coding agent yourself, you are the gatekeeper. You know the history, you remember the thread where the team said no, and you stop before you write the prompt.
A software factory takes that person out of the loop on purpose. Tickets come from many people, agents work them unattended, and the first person to see the result is a reviewer looking at a finished pull request. A wrong pull request costs review time, and one that looks right can get merged. Whatever a person would check in their head before starting has to become a step the factory runs on every ticket.
Where agents get their work
The main coding agents now pick up tasks where people already discuss and assign work: an issue, a tracker or a chat thread. Mention an agent or assign it a task and it starts working; when it is done, a person reviews the result.
Where coding agents get their work
ProductStarts fromComes back asBefore coding
GitHub Copilot cloud agentStarts fromAn assigned issue, chat, the IDE, the CLI, Jira, LinearComes back asA pull request, for an assigned issueBefore codingAn optional plan, on GitHub.com
OpenAI Codex cloudStarts fromChatGPT, the CLI, Linear, chat apps, GitHub commentsComes back asA diff; you open the pull requestBefore codingNot documented
Claude CodeStarts fromThe web and apps, the CLI, @claude on GitHub, chat appsComes back asA branch; a pull request on requestBefore codingAn optional plan mode
Cursor Cloud AgentsStarts fromThe web, desktop, mobile, Linear, chat apps, GitHubComes back asA pull requestBefore codingA short plan in chat for complex work
DevinStarts fromChat apps, Linear, Jira, the web app, the CLIComes back asA draft pull requestBefore codingQuestions in the thread
Reads past review threads before it starts: not documented for any of the five.
From each vendor's documentation, November 2026
Some of them can show a plan first, and some ask questions in the thread. None of the five documents reading past review threads before it starts. What happens between the ticket and the code is left to the agent and to whoever wrote the ticket.
With several ways in, we keep one record per piece of work: the issue. A chat thread or a document can start a task, but it files an issue and links back to it. Questions from the factory go to the issue and mention its author, and the answers come back there. Runs, questions, holds and cost all sit on the issue, so nobody has to watch a second queue.
One record, many front doorsChat messageDocumentIssueBefore the agent startsThe agent worksAsked on the issueHeldStopped, a person decidesMerged by a personIssue recordTriageClarityInvestigateCodeChecksReviewPRMergeChatDocumentIssueBefore the agent startsThe agent worksIssue recordTriageHeldClarityAsked on the issueInvestigateStoppedCodeChecksReviewPull requestMergeMerged by a person
Hard tickets: three setups, the same two solved
We took ten hard tickets from our own platform and ran them through three setups: a stronger model, a different coding agent, and a simulated author who answered the agent's questions. Each setup solved the same two tickets. Retrying didn't change that: a third attempt after two failures never produced a correct patch.
Ten hard tickets, three setups
12345678910
Stronger model
Different agent
Author answers
SolvedFailedEach setup solved the same two tickets.
On small, clear tickets the same factory did well. Issues became pull requests for $0.16 to $0.69 each, in about ten minutes, and when a reviewer left a comment the factory fixed it in one more round.
OpenAI saw the same pattern at a larger scale. When it audited 138 SWE-bench Verified problems that its o3 model could not solve reliably, 59.4% had flawed tests or problem descriptions, which made them extremely difficult or impossible "even for the most capable model or human to solve".
Six review findings, five already answered
To get more tickets, we turned six findings from our review bot into issues. Five of them asked for a change that a person had already answered in the same review thread. One was already fixed in the pull request the finding came from. Three were explicit decisions to keep the code as it was ("keeping this as is, deliberately"). One was a design choice its author had defended.
Four of the five became pull requests that passed CI and the review bot. The agents followed their instructions: they read the ticket and the code, and the decision was in neither. It was in a reply on an old pull request.
Where decisions live
Agents read itDocs in the repositorySpecs, decision records, a README.
Agents read itComments in the codeNext to the lines they explain.
Agents skip itReview threads"Keeping this as is, deliberately."
Agents skip itPeople's headsWhoever was in the meeting.
Teams keep decisions in four places: docs in the repository, comments in the code, review threads and people's heads. Coding agents read the first two.
Other teams see this too. In a study of 600 agent-written pull requests that maintainers did not merge, 23% duplicated work that already existed, and another 4% were features the maintainers said they did not want.
A read-only investigation before any code
We added a step between the ticket and the code. A read-only agent run, which can't change anything, writes a short brief:
Restate the problem, and name the files and functions involved.
Reproduce it through the real entry point, not by calling an internal function.
Read the history of those lines: the commits, the pull requests behind them, and every reply in their review threads.
Check for an existing fix or a duplicate.
End with a verdict, proceed, ask or stop, and one line of reason.
The investigation brief
TicketRetry the upload when the storage call times outAdd paging to the export listRemove the rate limit on exports
01 ProblemThe upload handler, and the call to storage inside it.The export list and the query behind it.The rate limiter in front of the export endpoint.
02 ReproduceTimes out through the public upload endpoint.Large accounts wait for the whole list to load.The limit is reached at the volume it was set for.
03 HistoryNo earlier decision about retries in its history.Nothing decided about page size.A review thread on the line: "keeping this as is, deliberately".
04 DuplicatesNo existing fix, no earlier ticket.No existing fix, no earlier ticket.Not needed: the decision answers it.
05 VerdictProceed: clear, reproducible, nothing against it.Ask: which page size do people expect?Stop: it reopens a recorded decision.
ProceedThe brief goes to the coding agent.
AskA question on the issue, to its author.
StopThe brief on the issue. A person decides.
Proceed hands the brief to the coding agent. Ask and stop post the brief on the issue and wait for a person. A stop never closes the issue; a person decides.
The history lookup has to follow lines, not line numbers. The review comment behind one of our tickets was on line 327 of the file at the time. The same code is on line 160 today, so a lookup of line 327 no longer finds it. The lookup has to follow each line back through every commit.
Follow lines, not line numbers
export async function exportRows(account) {
const rows = await loadRows(account);
log.info('export started', { account });
const started = Date.now();
metrics.count('export');
if (!account.active) {
throw new InactiveAccount(account);
}
const format = account.format ?? 'csv';
const limit = EXPORT_RATE_LIMIT;
await limiter.wait(account, limit);
return toCsv(rows, format);
}
Review"Keeping this as is, deliberately."
The review comment sits on line 12.A commit adds three lines above it. The code moves down; the comment stays on its number.Another commit adds four more.Line 12 today is different code.Followed back through each commit, the line is found again, with its comment.
First run: the 20 tickets that shaped it
We first ran the investigation on the 20 tickets that motivated it, with the links to the review threads removed and the history cut off at each ticket's starting commit, so it couldn't see answers from later.
The first 20 tickets
Reopened a decision5 stop
Wanted3 proceed, 2 ask
Hard5 proceed, 5 ask
ProceedAskStopThree to five minutes and $0.12 to $0.32 per ticket
All five unwanted tickets stopped, and each brief named the decision or the earlier fix. An investigation took three to five minutes and cost $0.12 to $0.32.
When the factory should block
It also asked a lot: two of the five wanted tickets got a question. Both were fair, but a factory that questions half its tickets will be ignored.
Asking does help when the answer is missing. In controlled tests on deliberately vague tickets, agents that could ask a simulated user did up to 74% better than agents that couldn't, and the models rarely asked on their own.
So we split the decision. The investigation now blocks only when the ticket contradicts a recorded decision (a policy comment, a design document or a person's reply in review) or when the work is already done. For any other open detail it picks a reasonable default, states it as an assumption with the line it rests on, and proceeds. The assumptions go into the pull request for the reviewer.
Block, or state an assumption
Block
When
A recorded decision, or work already done
The factory
Asks on the issue and waits
A person sees it
On the issue, before any code
State an assumption
When
Any other open detail
The factory
Picks a default, states it, proceeds
A person sees it
In the pull request, at review
A fresh test: 19 tickets it never saw
Then the real test: 19 tickets the investigation was never shaped around, built from the team's own merged work and frozen before the run. Ten were changes the team wanted, written from the problem only. Nine were suggestions an author had explicitly declined in review, written as plain requests.
19 fresh tickets
Wanted changes9 ahead, 1 held
Declined in review7 held, 2 ahead
Went aheadHeld backEach of the seven holds cited the author's reply
It went ahead on 9 of the 10 wanted changes and held back 7 of the 9 declined ones, each time citing the author's reply. The two misses had the author's reply on a different line from the code the investigation looked at, so the lookup now also reads the other review threads of the pull request it finds.
On the original 20, the same version went ahead on all five wanted tickets and still held four of the five unwanted ones. The fifth showed a new failure: it treated a partial existing fix as permission to build the rest. A partial fix now produces a question instead.
Controls after the agent starts
Once a ticket is cleared, a few plain controls keep the work in check. Each one is there because something went wrong without it.
Controls after the agent starts
CapA budget per ticketCounted across every run of the ticket, and enforced at the gateway that holds the model keys.
12HoldA size check that needs two signalsOurs once held a four-file change as too big, because it counted file names mentioned in a comment.
SilentA stall watchdogOne run sat silent for an hour after its tests passed, and nothing else noticed.
Held: split this issueResolved by an ownerHolds resolved in publicEvery hold notice is edited to say what resolved it, by whom and when.
IssuePRA closed issue stops the workClosing an issue closes the factory's pull request for it.
PersonThe factory never mergesA person decides. The factory counts pull requests merged unchanged, merged after edits, and closed.
Limits and next steps
All of this is one repository and about 40 tickets, and a person graded every reason the investigation gave. The last two fixes, reading the pull request's other review threads and asking on a partial fix, have not been re-measured yet; that is the next run. Everything measured here came in through the issue tracker, and the chat and document front doors are the part we are building now.
What to take from this
If agents work tickets in your team without anyone watching:
Put a read-only investigation in front of the coding agent, and make it read the review threads behind the code, not only the code.
Let it block only on a recorded decision or work that is already done. Everything else should become a stated assumption a reviewer can check.
Before paying for a stronger model, look at the tickets. In our tests it solved the same two hard tickets as every other setup.
A coding agent can turn a ticket into a green pull request in minutes. We split the merge decision into narrow checks, let fixed rules decide, set the strictness by the blast radius of a change, and bring in a person only where the agent gets stuck.
We ran three coding agents through four gateways to see what a gateway controls, what it measures correctly and where it misleads you, from budgets that overshoot to telemetry that leaks prompts and data residency set hop by hop.
We ran OpenSpec, Spec Kit, Superpowers and Claude Code plan mode on a real ticket, then planted drift and contradictions. For one feature we couldn't separate the code, and plan mode cost about half. What differs most is the record each leaves for the next agent.
We use cookies to run the site and understand how it’s used. You can accept all cookies or reject non-essential ones. See our Cookie Policy.
Cookie settings
By clicking 'Accept all cookies', you agree to storing cookies on your device to enhance site navigation, analyze site usage and assist in our marketing efforts as outlined in our cookie policy.