Skip to content

Ask the parts of long files without a finding whether each does a job of its own - #36

Merged
tauanbinato merged 7 commits into
mainfrom
large-file-parts
Sep 27, 2026
Merged

tauanbinato merged 7 commits into
mainfrom
large-file-parts

Conversation

@tauanbinato

@tauanbinato tauanbinato commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

JevGate cleared every large file of its own code (src/units/compose.rs at 1,866 lines, src/analysis/clones.rs, src/units/security.rs), so I checked why, and whether a careful refactor would split them.

Where the answer came from. compose.rs's recheck raised the split to a consider (0.81). Then the kind-of-file Choice cleared it, because the kinds that serve one feature added up to 0.85. On the corpus, the kind cleared 384 outlines, 44 of them non-test files of 800+ lines.

Labels. Opus agents labeled 50 large application files blind, from the code. These are files the kind cleared (400+ lines, no Bend). 15 were worth splitting, 8 debatable, 27 to keep.

  • Keep: one central type (cobra's Command, Flask), one SQL dialect's implementation (shiori's sqlite, mysql and pg), httpx's sync/async mirror, a mailer with one function per template.
  • Split: a part with its own job and vocabulary inside the file. Examples: a URL scraper inside lobsters' Story, a diff engine inside a renderer, a JSON parser inside a protocol module.

Nothing in the existing answers separated the two: not the split levels, the kind, size, or size relative to the project. Several new questions over the outline didn't either: boundaries between consecutive members, and a per-member "does this do what the file's path names?". The details are in evaluation/experiments/large-file-parts.md (local).

What changed. Following Jev's docs (one atomic question per candidate, and only the state the question needs):

  • Candidate parts come from a variant of the outline grouping (groups::parts):

    • no owner link inside a type of more than 12 members (that link had merged every method of Story into one group);
    • no link through a helper that more than three in ten members call;
    • one extra link for neighbours and for names sharing a distinctive word.

    Against the parts the labelers named (F1 over member lines, 23 files), the best match went from 0.45 to 0.72. Files to split that have a matching part went from 5 to 9 of 15.

  • The part follow-up. Each part of 100+ lines, in an application file of 400+ lines whose outline, recheck and kind raised no finding, gets one request. It carries the part's source and the rest of the file by signature, and asks two questions:

    • a Noul: "Does part do a job of its own that a reader would look for apart from the rest of the file?"
    • a Choice: its own job, more of what the rest does, helpers used throughout, or the file's main job.

    Own ≥ 0.65 with the role leaning to its own job (≥ 0.50) is a consider naming the part's members.

  • Not asked: benchmark, example, scripts and docs directories (5 of 5 such findings were wrong: hash-pinned benchmark drivers, build scripts), or a part holding main.

  • A new parts stage in reports. First-pass requests are unchanged, so nothing already cached is asked again.

Measured. Each new consider was labeled blind, a debatable one counting as not right.

Set Considers added Right
The 50 tuning files 4 4, each at the part the labeler named
Corpus, 181 projects 11 (nothing else changed; 1 undecided outline resolved) 9; wrong: saas-lite's demo placeholder table, wp-two-factor's public static API
↳ outside the tuning files 7 5
↳ held-out projects 1 1
9 projects never used before (click, rich, zod, hono, viper, ripgrep, sinatra, jsoup, guzzle) 2 2 (Guzzle's WWW-Authenticate parser inside DigestAuth, ripgrep's --hyperlink-format language)

File-organization considers were 63% right before. Parts of 80–99 lines were right 2 times in 4, so 100 is the floor. Cost: about $0.08 on the corpus, plus $0.22 for the fresh projects' whole file-organization rule.

Rechecks that send a whole file near the token limit can flip between two runs of the same binary. Whether they fit depends on each clone's saved token-budget.json calibration, which every run updates; pi-fabric's src/agents/manager.ts differed that way between two release runs. So the comparison restores every clone's calibration from one snapshot before each run (evaluation/pinned_run.sh, local). With that, the release and this branch differ by exactly the 11 considers and one undecided outline resolved: reviews and notes are unchanged, at $0.00 from the cache.

What it doesn't do. JevGate's own large files still stay clear: Jev reads their parts as one job (compose.rs's parts get 0.30 to 0.43). What decided compose.rs for the labeler was that only follow_ups.rs uses the follow-up selectors. JevGate's callers map misses that, because Rust functions passed by name (follow_ups(plan, files, compose::unconfirmed_units, …)) aren't recorded as calls. Counting those references, and sending a part's users with it, is the next step. #37, stacked on this one, makes the compose.rs split by hand.

Also: the self-check found that document_split and the file-kind weighing repeat the same steps (now one helper), and that two wordings build the same name list. FILE_ORGANIZATION rule version is now 22.

Tests (planning, composition thresholds, an outline with a finding asks nothing, grouping of a large type), clippy (also 1.98) and cargo +1.90.0 check --locked pass. The self-check with --rule all --include-tests reports no review or consider.

@tauanbinato
tauanbinato merged commit 7b9c617 into main Sep 27, 2026
9 checks passed
@tauanbinato
tauanbinato deleted the large-file-parts branch September 27, 2026 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant