350 Lines Is a Routing Decision
Six offline probes of Spotify's Shunt hooks separate delegation policy from model quality, token accounting and enforceable read limits.
At 350 lines, Shunt lets a full-file read proceed. At 351, it blocks the read and points the coding agent toward a bulk-reader skill. Add an explicit offset, or pipe a shell read into another command, and the request can pass again.
I tested those decisions without invoking a model. They show where this delegation design begins: a cheap local heuristic decides whether the main agent should bring a file into its own context.
Retrospective for September 6. The offline checks ran September 12, 2026, against Spotify's plugin revision 3c24ca30ff63e1f5bbad1c43fe5324daff579123, available since August 17.
Spotify's engineering account describes routing bulk reading and predictable code generation through Portal modes. Its reported token savings motivated the design, but my experiment does not reproduce that benchmark. I supplied no Portal tenant, model credentials or Java monorepo. The evidence here concerns the local hooks and the transport code I inspected.
Six Requests at the Gate
The Read hook parses the tool input with jq. It allows a request when an offset or limit is supplied. Otherwise it counts newline characters with wc -l and compares the count with SHUNT_MIN_LINES, whose default is 350.
I generated two files with exactly 350 and 351 newline-terminated fixture lines. Then I passed JSON inputs to the original Bash scripts using Git Bash and jq 1.8.1 on Windows. I did not install the hooks into an agent session.
| Requested operation | Decision returned |
|---|---|
| Full Read, 350 lines | Allow |
| Full Read, 351 lines | Block |
Read 351-line file with limit: 1 | Allow |
Read 351-line file with offset: 1 | Allow |
Plain cat of the 351-line file | Block |
Same cat, piped into cat | Allow |
All six assertions passed in the reproduction script. The last input was tested as a command string sent to the hook; the probe did not execute that proposed shell command.
The Bash hook explains the result directly. It allows any command containing a pipe before parsing a filename. Piping a file into cat does not reduce its output, but it satisfies that shortcut. Similarly, an offset alone does not establish a strict output-size bound.
These are routing preferences intended to steer a cooperative agent. They should not be treated as a sandbox or an enforced token ceiling. A line count is also only a proxy for context size: a generated file can put a very large payload on one line.
A Worker Answer Has Its Own Failure Modes
Once delegation occurs, the main agent has traded the full file for an answer produced elsewhere. Saving context only helps if the answer preserves the details required for the next decision.
The plugin's transport helper constructs an aika:invoke-chat request, checks the serialized payload size, invokes the Portal CLI and parses its response. It rejects failed calls, malformed JSON, a missing mode name and empty answer text. These are useful checks on the delivery contract.
They do not validate the answer's interpretation of the source. A nonempty mode name establishes that the response reported a mode; it does not, by itself, prove that a particular instruction set was used correctly. Likewise, a concise explanation can omit a locking condition or invert an exception rule while remaining perfectly valid JSON.
That is why I would keep direct, narrow source reads in the workflow. A bulk reader can locate the relevant method and outline its responsibilities. Before changing synchronization or error handling, the main agent should inspect the exact implementation it will edit. The hook already permits such reads.
Measure the Whole Delegation
To evaluate this routing policy on a real project, I would record the main model's input and output tokens, the worker's usage, round-trip latency and any follow-up reads needed to complete the task. I would also check the final change against the same tests used without delegation.
A useful fixture would ask both paths to explain one method in a large file, then modify it correctly. If the worker summary sends the main agent back for most of the source, the initial reduction in context may overstate the total benefit. If it reliably identifies a small relevant section, the two-stage read has done useful work.
The local result is narrower and concrete: the 350-line rule changes which path an ordinary read takes. Whether that path saves money while preserving correctness depends on the worker response and the rest of the task, neither of which a Bash hook can establish.