Efficiency Analysis of run transcripts #121
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
We now have several finished runs for the scratch project. I'd like to analzye the transcript of all the steps in each run and find inefficiencies that we can improve. I'm looking for places the agent didn't correctly follow a brief, or if the agent is duplicating work already done, or when the agent spends time because of some technical problem or missing dependency it has to work around. Really look deeply at all of the transcripts and find problems that we can fix and make the process faster and more reliable, faster is the key! Braid is currently painfully slow, and I have a hunch we are going to find tons of inefficiencies.
Of course, any other problems you can identify should also be analyzed, I'm just provided a few obvious things to look for.
Initially, just present the findings here in a concise, easy to parse by a human kind of way, and I'll decide what to implement as part of this issue, and what to spin off as other issues.
Findings: where the scratch runs spend their time
I read every step transcript of the eight finished scratch runs: the plan run 21, the feature runs 22, 23, 25, 26, 36 and 37 (git-flow), and the quick-fix verification run 33. The archived runs 24, 29 and 34 were used only to explain failures. Run numbers are Braid's ledger numbers, not issues. In total that is about 2,100 model turns and 4,100 tool calls. Unless noted, the figures are for the six feature runs: 1,251 min of wall clock.
The short version
Findings, biggest first
Very long thinking. Reasoning took 918 min across the eight runs. 129 single thoughts of 2 min or more make up 56% of it. The longest ran 15.8 min (114k characters, run 36 review[test]). They are not loops. They are exhaustive deliberation, such as a reviewer walking candidate issues A to Z. Reviewers spend 91% of their output on reasoning.
Apply spends most of its time before its first edit and after its last. Of 355 min of successful apply attempts, 44% passed before the first code edit (median 7 min) and 25% after the last one. The work in between is 31%. Before the first edit come long planning thoughts, baseline suite runs, and re-reads of files the prompt already pastes (139 such reads across all steps, up to 10 in one apply step). Agents also write and debug throwaway scripts such as
sim_game.pyandprobe.pyinstead of tests they keep (15 in these runs). After the last edit comes the "tick one task at a time" routine: re-run a test, tick, repeat. That was about 16 turns after the work was done in run 37 apply[1].Verification steps redo each other. reconcile-tasks (7–12 min) changed nothing in each of the last five runs. test.unit (7–14 min) mostly found the tests already written and touched 0–3 files. Code review then re-reads and re-runs everything again. Run 37 ran the full backend suite 13 times and the frontend suite or build 9 times. Its reconcile also ran a browser check, the job test.browser does next.
Review findings that no step acts on. Nine review rounds produced 87 findings: 6 blocking (all in round 1), 45 should-fix and 36 notes. Revise fixes blocking findings only, and the gate auto-approves, so no step is asked to handle should-fix. A few surfaced later by chance: run 25's unit step picked up the test lens's gaps, and run 37's code review noted one and left it. Round 2 re-runs all four lenses over everything. It ran three times, took 10–13 min each, and never found a blocking issue.
Run 37 died over
"line": 0. Code review wrote a file-level finding withline: 0, and the schema wants at least 1. Withmediate: missing, a report that is present but invalid counts as a deliberate "fail". So there was no retry, and the run failed at its second-to-last step after 2 h 43 min.Failures then waited for a person. Run 36's browser check used its whole hour without writing a report. The run sat failed for 2 h 22 min until a manual resume, and attempt 2 finished in 20 min. Run 26's feature commit swept in a root
.venv, hit a PredicateError, and took 74 min of manual redos. Run 22 lost about 100 min to early bugs and two osfd restarts. Fixed since: #117, #118, #119 (last call, two hours, automatic retry) and #105, #107. Finding 5 is a hole the retry still has.Browser checks of a five-player game. The browser check took 38 min in run 37 and 80 min over two attempts in run 36.
Briefs that disagree with their checks.
// spec: <capability>/<scenario>tags. So every lane report says 0/55 scenarios covered, 19 ban violations andgreen: false. The step still passes, because its completion is onlypaths-exist. Later steps readgreen: falseand deliberate over it. B7 (relative import) also flags Python tests by mistake./usr/local/lib/node_modulesin three steps to learn the RENAMED and MODIFIED rules. That took about 7 of run 36 spec[deal]'s 12.6 min.openspec validate --strictwith no change id ran 11 times, answering "Nothing to validate" each time.git diff develop...HEADfailed in 5 runs: onlyorigin/developexists."$OSF_PYTHON" -m osf.pipeline.plan check, butOSF_PYTHONis empty in the agent's shell.The environment, mostly fixed. In runs 22–26, nearly every apply or test step went looking for a Python with pytest, because
pythonis Braid's own venv. Agents made venvs in four places and pip-installed into the system Python. Fixed since by script.deps (#109), the app tool (#110) and the Chrome fix. Still open in runs 36 and 37:python3is still Braid's venv, andrg(8 tries) andps(4 tries) are not installed.$TMPDIRis advertised but not allowed. There were 36 permission rejections. The rejection message tells agents to use$TMPDIR(<run>/tmp), but only<run>/tmp/opencodeis allowed. Neither the app tool's own log (<run>/tmp/braid-app.log) nor the browser screenshots (<run>/screenshots/) can be read, so agents copy them, retry, or give up on looking.Background tests collide with edits. In run 37 apply[2], a test subagent ran the suite while the parent edited
test_flow.py. The suite hung until bash's 600 s timeout, because pytest has no per-test timeout.Parallelism goes unused. Several steps could overlap: code review with the browser check, test.unit with reconcile, and backend with frontend apply groups when their files are disjoint. Speculative decoding (n-gram or MTP) in vLLM may also lift single-stream speed on edit-heavy turns. That one needs a measurement.
Per run
line: 0, no retrySuggested split
Follow-up: one correction, and the split
Correction to finding 8. B7 (the relative-import rule) does not misfire on Python tests. It misfires on a TypeScript test whose
import {…} from "./game"spans several lines (frontend/src/game.test.ts). The Python problem is a different one: thespec:tag must start with//, so a Python test cannot carry one at all, and the scenarios it covers can never count as covered.Going with the suggested split.
claude/issue-121(not pushed yet):retry-malformed-reports: finding 5. It also fixes #122, which is the same run 37 failure.agent-shell-environment: findings 8 (OSF_PYTHON), 9 and 10.sharper-briefs: the brief half of finding 2, and findings 8 and 11.Shipped in
03b6fe6The #121 items are deployed (deploy run 91) and archived (
a268f71).retry-malformed-reports(finding 5; it also fixes #122). On the browser check and the code review, a report that is there but malformed is now tried again, and the retry is briefed with up to ten of the schema's errors. A well-formedfail, an unfixed blocking finding or failing tests still stop for a person. A code-review finding about a whole file may haveline0 or null, and the pull request names the file alone.agent-shell-environment(findings 8–10). Agents may read and write<run>/tmpand<run>/screenshotswithout a permission request; any other path outside the worktree is still rejected. Braid's venv is no longer first on an agent's PATH, sopython3is the system's.OSF_PYTHONis set for agents, so the plan step's check runs. The image hasrgandps.sharper-briefs(findings 2, 8 and 11). The test briefs name thespec:tags the lane report counts, and Python tests can carry them as# spec:. B7 reads imports that span several lines. The spec writer is told OpenSpec's MODIFIED and RENAMED rules. Every validate instruction names the change. The summary diffs againstorigin/<base>. Apply is told the pasted code is already in its context, and to tick each task as it finishes it. Test subagents run under a time limit (five minutes unless told otherwise) and report HUNG, and the primary leaves a running suite's files alone.Verified. The full lane with the
@livespecs. Opencode 1.18.21 against a fake model: nothing asked in the two directories, still asked for<run>/home, and the agent's PATH andOSF_PYTHONas intended. A delta written to the new spec rules validates with OpenSpec 1.10.0. On production after the deploy: the new commit and boot id with the counts unchanged, and in the containerpython3at/usr/local/bin/python3withrg,psand the run's tools resolving.Not yet seen on production: a malformed report being retried, and a run's
opencode.jsoncarrying the new rules. Both happen on the next runs, and the next scratch runs will show whether the friction counts in the analysis drop.Split off: #124 (thinking budget), #125 (verification overlap), #126 (review rounds), #127 (browser check of a multi-player app) and #128 (parallelism and speculative decoding).