Don’t make the model pay 200 lines to find a function

Coding agents still read like find | cat: dump the tree, grep wide, page 200-line windows until context is landfill. Codeloom’s engine makes reading a cost hierarchy, then puts TypeSafe System One (jev-latest) on a few choke points.
The LLM generates. TypeSafe (JEV) judges. Code decides.
JEV never writes a query, invents a path, or authors an edit.
Who reads
The user talks to the orchestrator. It has no list_files / search / read_file. ask is the reader. coder read_files before an edit — that is a write-funnel stamp, not discovery.
Cheaper-first ladder
Prompt policy, not a hard state machine. Tool descriptions push the same order.
| Step | Tool | Cost | Why it exists |
|---|---|---|---|
| Locate | search |
rg, 10s cap, skip-dirs | Prefer this over listing |
| Locate (last) | list_files |
flatten whole tree | Model tends to dump; prompt says don’t |
| Outline | list_symbols |
one parse, no LSP | See a file without reading it |
| One def | find_symbol |
same parse | Body + coordinate handoff |
| Local CST | query_tree / get_node_at / parse_file |
instant | Imports, calls, nesting |
| Types | LSP | server wait | Cross-file truth; fall back to sitter |
| Context | read_file |
200–400 numbered lines | Surrounding source + write stamp |
coder: skip search. Read the briefing’s paths. Search once only if a path is missing.
JEV in one table
~100ms calibrated classifier. One state + N parallel questions. Missing key / timeout / 5xx → None → pre-judge path. Engine works without it.
| Primitive | Returns | Read-path use |
|---|---|---|
Noul |
P(yes) 0–1 | injection? answers the question? |
Choice |
option + per-option P | which rg hit? what intent? |
Score |
ordinal | mostly exec blast radius, not reads |
Judgments only add restriction or information. They never override guard_write_path, the syntax gate, staleness, or the write denylist.
Modes: off / advisory (events only) / enforcing. Per-site overrides (ENGINE_JUDGE_SEARCH, _SCREEN, _INTENT, …). Write gate does not inherit a blanket enforcing.
Judged read path
Child reports ([agent ask … finished]) skip this. Injecting search into orch history — orch has no FS tools — stalled the model.
Four call sites on reads
| Tag | When | Question | Enforcing effect |
|---|---|---|---|
intent_route |
before the loop | meta / locate / edit / execute | skip loop, or bump turns |
search_rerank |
rg hits > 10 | which line answers the query? | return top 15, not 80 |
intent_route (gate) |
after 2 windows | does gathered context answer it? | seed history or fall through |
call_verify |
LSP / edits, not search/read | coords from find_symbol? path was read? |
error string, don’t run |
result_screen |
large tool results | instruction / override / secrets / ordinary code? | flag wrap, or redact secrets |
list_files is never verified or screened. Cheap to get wrong, cheap to retry.
Search re-rank
One Choice scores every candidate. A lexical miss that the model then read_files is 200 lines and a round trip.
Result screen
| Signal | Role |
|---|---|
contains_instruction_to_agent |
hazard |
attempts_override |
hazard |
requests_secret_disclosure |
redact if high |
is_ordinary_source_code |
false-positive brake |
This repo is full of prompt strings. Hazard high and ordinary low → wrap, don’t strip. Only the first 4k chars are judged.
read_file itself
Edit without that stamp: error: read X before editing it. Sha drift: read again.
Other personalities
| Profile | First read |
|---|---|
| ask | Full ladder |
| coder | read_file named paths |
| debugger | Same NAV + shell/git/browser. Don’t stop at the first filename. |
| reviewer | git_diff in the writer’s worktree, then sitter/LSP on changed files |
| researcher | Remote first. Workspace search only after external facts |
| tester | Read code under test, then write tests |
Pros
| Right model for a choke point | Classifier over closed sets. Cannot hallucinate a path. |
| Restriction-only | Cannot punch through deterministic write/exec guards. |
| Optional | No key / None verdict = old behaviour. Tests assert that. |
| Search re-rank is asymmetric | ~100ms vs N wasted read_files. Biggest quality-per-turn lever. |
| Screening closes a real hole | File contents and stdout used to enter context unscreened (80k cap). |
| Locate can delete 5–6 tool rounds | Model still writes the answer; it skips exploration. |
| Decisions are code | Thresholds in judge_decisions.py. Pure functions. Tunable. |
| Observable | JudgementMade: tag, signals, enforced?, latency. |
Cons
| Not ground truth | Parser/LSP beat a probability on syntax and types. |
| Cannot generate queries | Locate pattern = stopword-stripped identifiers. “How does auth work?” may miss authenticate. |
| Confidence compounds | 0.9⁴ ≈ 0.66. Resolver stopped before list_symbols → find_symbol. Fall through often, be right when you don’t. |
| Latency vs the brochure | Timeout 800ms. Screen fires on every large result. Fall-through pays classify and still runs ask. Advisory pays for nothing. |
| False positives already happened | git status scored as huge blast radius (it observes the repo). Prompt files need the ordinary-code brake. Thresholds are first guesses. |
| Orch / resolver clash | Orch has no FS tools. Seeding search into orch already stalled a turn. Inbox handoffs had to be excluded. |
| Knob sprawl | Global mode + ~10 site overrides. Write gate refuses to inherit enforcing. Correct, and not “turn the judge on.” |
| Extra vendor on the hot path | Key, cost, 800ms tail of no-ops. Cache (512) helps re-reads, not first reads. |
| Gaps on the read path | No list_symbols re-rank. Verify does not run on search/read_file. JEV will not stop list_files first — that’s still a prompt. |
| Screen is windowed | Injection after char 4000 is out of scope. |
The split worth keeping
| Enumerable (JEV can pick) | Not enumerable (LLM must generate) |
|---|---|
read_file given a known path |
search query |
find_symbol given a name from the outline |
str_replace / patch body |
goto_definition given find_symbol coords |
run_command |
Navigation can stop being an agent. Editing cannot.
Ship each site advisory until the false-positive rate is a number. Let JEV reorder rg and flag hostile bytes. Do not let it invent the next path.



