feat(brain): hold the push until the brain is built, and land the browser on it - #422
Conversation
…wser on it Three things, all on the same failure. Roughly a third of the repo brains attempted in production die inside the miner, AFTER the push has succeeded — and nothing on either side says so. - `brain push` now follows the build instead of printing "watch it finish in your browser" and handing the prompt back. Four stages off the same row the browser reads, each printed once as it settles, and a failure reported at the stage it happened at: a repo read successfully and then lost in the miner says so rather than looking unreachable. Exits non-zero on a real failure, so a CI step hears about it. Ctrl-C detaches without cancelling; --no-watch restores the old fire-and-forget ending. - The handoff's 303 now lands on Trail's build screen. It pointed at /brain/<id>, which redirects to the graph the instant the row exists — minutes before it holds a rule — so every terminal signup saw an empty visualisation of a brain that was building fine. - writeLink gitignores .graft/. BrainLink's own comment has called that directory "git-ignored" since it was written and nothing ever made it true; ensureGitignored only ever ran for the graph cache. Every repo anyone ran `graft brain connect` in was one `git add -A` from publishing a read token.
🌱 graft blast radius3 areas changed → 4 areas can be affected. 8 dependent symbols, depth 2. flowchart TB
A0(("Workspace Graph Building<br/>3 symbols"))
A1(("Brain Connection<br/>2 symbols"))
A2(("Pull Request Review<br/>2 symbols"))
A3(("Graph Engine<br/>1 symbol"))
classDef reached fill:#D9EDF3,stroke:#3AA7C9,stroke-width:1.5px,color:#0E313C;
class A0,A1,A2,A3 reached;
Who knows this code — 3 people across 7 areas
Ownership is git history over each area's own files, weighted towards recent work (120-day half-life). Merge commits and bots are dropped, and you are dropped from your own PR. A name with no All 8 dependent symbols, grouped by areaWorkspace Graph Building — 3 symbols in 3 files
Brain Connection — 2 symbols in 1 file
Pull Request Review — 2 symbols in 2 files
Graph Engine — 1 symbol in 1 file
Test signal per changed area — 1 ✓ · 1 ⚠ · 1 –Reached = a node under a test path has a resolved edge into the changed symbol. It undercounts anything called indirectly — through a CLI, a spawned process or a dynamic import — so read a low ratio as “look here”, never as a coverage gate.
33 test suites also reference this code35 symbols, kept out of the diagram and the table so they cannot crowd out the areas a reviewer has to look at.
Open the interactive graph → — click an area to see its dependent symbols at file:line. |
Three changes, all on the same failure: roughly a third of the repo brains attempted in production die inside the miner — after the push has already succeeded — and nothing on either side ever says so.
1.
brain pushfollows the buildIt used to end here:
…and hand the prompt back. That sentence is the last thing the process says about the work, and it is said before the part that fails. On a CI runner or over SSH, where nobody is going to open a browser, the failure exists nowhere at all.
Now it holds, and prints the same four stages Trail's build screen shows, off the same row:
A failure is reported at the stage it happened at. A repo that was read successfully and then lost in the miner says so, rather than looking unreachable — which matters, because that wrong reading sends someone off to fix repository access for a problem that has nothing to do with it.
--no-watchrestores the old fire-and-forget ending.2. The handoff lands on the build screen
The 303 pointed at
/brain/<id>. That route redirects to the brain's graph, and it fires the instant the row exists — minutes before it holds a single rule. So every terminal signup landed on an empty visualisation of a brain that was, at that moment, building perfectly well. It now lands on/get-started?step=build&brain=<id>, which is the same wait the browser-first flow shows and leads to the graph once there is one.Pairs with NanoNets/assign#2760, which adds that screen. Merge that first — until it deploys, this URL lands on the get-started picker rather than the build screen. Not broken, just not yet better.
3.
writeLinkgitignores.graft/— please read this oneBrainLink's own comment has described that directory as "git-ignored" since the day it was written, and nothing ever made it true.ensureGitignoredonly ever ran for the graph cache (/graft/), never for.graft/config.json, which is where the brain id and its read token get written.So every repository anyone has run
graft brain connectorgraft brain pushin is onegit add -Aaway from publishing a credential. Found it because an automated scan flagged exactly that file in my own checkout of another repo.The token is a signature over one brain id, scoped to reading that brain and regenerable server-side, so this is not a five-alarm leak — but it is a credential in an unignored file, sitting in every user's working tree, contradicting the comment right above it. Worth a look from someone who knows whether any of these have already been committed anywhere.
Testing
npm test— 1243 pass, 0 fail. 11 new cases covering where a failure lands, that a log line prints once, that unreachable and timed-out and failed are three different outcomes, and that the handoff URL can never go back to/brain/. One existing test updated: it asserted the old redirect target, which is the thing being changed.