Repository navigation
fix(harness): bound the scan walk by what it holds, merge its two readers, test its untested branches (TH-9449, TH-9450, TH-9451) - #273
Merged
khushalsonawat merged 9 commits intoNov 11, 2026
Conversation
A settings template the decoder rejects marks the description's row short, against a readable control, with no reader fault logged and the next file still read. The walk's summary line tells reader faults from other unread files. A kit fault escaping the description keeps what was read, with its trace. A MemoryError in one folder's check comes back as a trace, so the child's loop goes on. TH-9451 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
…ed reader The walk's and the description's capped readers were copies. One reader now counts reads and bytes, in the order every stop point relies on, and each caller says what a cap means: the walk stops, the description marks its row partial. No behaviour changes; the walk's tests pass unchanged. TH-9450 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
What the walk keeps grows with the names its files hold, not with their number: a crafted 51 KB file of unique dotted imports keeps 671 KB, so 5,100 of them, inside the byte cap and under the 40,000-file cap, kept 3.3 GiB in a 4 GB sandbox. Everything the walk and its join keep is now charged where it is kept, at the allocator's blocks, against one 1,536 MiB budget: each file's facts, key and import list, its share of the join, templates, graph entries, prompt paths, folder lookups, project module sets and the folders os.walk holds to enter. Past it the walk stops at "limit" with nothing of that file kept. Four things stop growing instead of being counted: a resolved import holds the walk's own path, the places an import is looked for follow a link per folder to its nearest project, a row keeps at most the 50 setting names the answer file writes, and a hazard look gives up past 64 MiB of listed paths. The file cap now counts only files the join works on, so many small files are read whole. The join's two quadratic loops, and its pass over the files for each row, become linear. TH-9449 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
TH-9449 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
Round the measured blocks apart from the code's own rounding, measure a project lookup on its own, hold the first-names pass's limit and early stop, a row that leaves out a deeper listed folder and a sibling with the same start, and the clock check counted only after the walk. The description's names are capped once, where the row is built. TH-9449 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
…s up TH-9449 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
TH-9449 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
Both reviewers cleared round 1. This fixes what they found: - A cap reached while joining now ends as limit, like the edge budget. No lookup in the join charges today; this keeps a future one off the crash path. - A row's pass skips the 50-name merge for a file with no settings. - describe_entry's comment says only the platform's secret values are masked, and the hazard look's count says it is in characters. - New tests hold what no test held: a charge outside one file's read (a listing, a prompt path) ends as limit; the file that crosses the budget is kept nowhere; a cap while joining ends as limit; an import inside an inner project resolves at an outer project's root; the description's byte cap, and that it reads nothing past its cap; each lookup charge and ancestor link; the hazard look counting full paths; import levels and line numbers over 256, as a shape and as pairs. TH-9449 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
…isted in os.walk doesn't sort, and Linux lists a and b before the long folders under c, so the look found both agent.py files before its listed-path bound was passed and CI failed. The long folders now sit beside a and b, so the root's own listing passes the bound first on any file system. TH-9449 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
khushalsonawat
added a commit
that referenced
this pull request
Nov 10, 2026
This was referenced Nov 10, 2026
cdileep23
approved these changes
Nov 11, 2026
khushalsonawat
merged commit Nov 11, 2026
bc3dd18
into
feat/TH-8804-source-subfolder
11 checks passed
2 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
These are the agent scan's three follow-ups from round 2 of the review of #251.
things are kept, rounded to the allocator's blocks. It covers everything the walk and its join keep. The file limit
now counts only files the join works on (40,000), so a repository of many small files isn't cut early.
Type of Change
Changes
scan_walk.py, the budget (_MAX_HELD= 1,536 MiB).folders
os.walkholds to enter.limitand keeps what it found. A cap reached while joining ends the same way.scan_walk.py, the join._rootsis gone. Imports are looked for through the nearest-project links.the clock.
ENV_NAMES_KEPTnow lives inscan_walk.scan_walk.py, one_CappedReaderfor the walk anddescribe_entry.scan_ai.py,scan_folders.py,scan_walk.py: comments say only the platform's secret values are masked.model of the allocator;
Testing
Run on this branch merged into the target's head (
c1685ecb), on Python 3.12.14 and 3.12.3, one file at a time,all passed on both:
test_scan_walktest_scan_folderstest_scan_documenttest_scan_aitest_agent_scantest_authoring_entrypoint_find_agentstest_reading_entrytest_framework_detectiontest_harness_architecturePlanted breaks: 46, one per guard, each caught by a test and restored.
Walk only, no model, base (
22bcbb87) against this branch atb1633742: the agent learning kit (20 rows) and amonorepo checkout (43 rows,
stopped=limit).budget.
Review. A plan review took three rounds, and round 3 cleared. A change review of
22bcbb87..b1633742by twocold reviewers cleared in round 1, with 0 High, 4 Medium and 18 Low between them. One reviewer's differential over
1,400 generated repositories found no row that differs from the base.
What wasn't reviewed
Round 3's plan fixes. They are in the code the change review read.
811a918c, which fixes the change review's Mediums and Lows without another round.src/, that'swalk_repomapping a cap raised while joining tolimit, a row's pass skipping the name mergefor files with no settings, and two comments.
f82106fcis titledtest(harness), but it also removes one redundant 50-name slice indescribe_entry. Theslice changed nothing, because
_env_namesalready returns at most 50.bc3dd187, after CI:test_a_hazard_look_gives_up_past_its_listed_pathsassumed an order in which folders are listed, and failed on Linux.os.walkdoesn't sort, so the look found bothagent.pyfiles first. The long folders now sit at the root, so the root's own listing passes the bound on any file system. This is test-only.The other failure in that first CI run,
test_post_terminal_wire_block_is_bounded_by_the_remaining_flush_window, is a timing test in the hosted entrypoint, which this PR doesn't touch. It passed on the second CI run and three times here.Known, not changed here
The folder check's child process (
framework_detection.py) has no memory bound. Its limit counts only Python files, soa crafted tree of many folders with no Python files could grow it after the walk has stopped. That's pre-existing and
outside this change. It's filed as TH-9511.
Related Issues
Refs: TH-9449, TH-9450, TH-9451