Repository navigation
fix(harness): bound the framework check's walk by the folders it lists (TH-9511) - #275
Merged
khushalsonawat merged 2 commits intoNov 11, 2026
Conversation
The framework check's limits count Python files, bytes read and parsing work. A deep tree with many sibling folders and no Python reaches none of them, so os.walk's list of folders still to visit grew without end, and in the agent scan's sandbox it could take the memory the scan's own walk had just kept free. The walk now keeps a running total of every folder it keeps to walk into, at what its full path costs as a str in that list. Past 64 MiB it stops as at its other limits, before that folder's files, and the word is unknown. The checked folder's own path counts as at least 184 characters, so the scan, a build and a reading stop at the same folder on the same tree while that path is short ASCII. The tests build each tree from fixed numbers and work out each stop by hand. One reads os.walk's own list as it walks, and holds it to the bound under short, long, wide-character and deep paths. TH-9511 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
… loose Both reviewers cleared round 1. This fixes what they found: - A top with a wide character in it, and ASCII names below, now has its own case: only the top makes every path wide, and no test held that half of the width rule. - Exact totals below depth 1, and for an installed tree, whose folders the walk never enters and so must add nothing. - The short and deep cases are sized so their brooms pass the bound on a Linux tmp_path too, and under the plant aimed at each. - The cost's docstring names everything its 120 covers. TH-9511 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
1 task done
cdileep23
approved these changes
Nov 11, 2026
2 tasks done
khushalsonawat
merged commit Nov 11, 2026
60159ab
into
feat/TH-8804-source-subfolder
11 checks passed
khushalsonawat
added a commit
that referenced
this pull request
Nov 11, 2026
… into TH-9491 - tools.py: _save_contract keeps the single writer (write_contract) and takes #268's new reply text, which names unconfirmed prompt lines. - contract.py: #268's new fields, unconfirmed_prompt_from and model (ModelSource), are marked as kept as written: they hold source lines and the cited model name, read by the build. The test that fails on an unmarked field caught them. Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
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
The framework check (
folder_findings) walks an agent's folder withos.walk. Its limits count Python files, bytesread and parsing work. A deep tree with many sibling folders and no Python reaches none of them. So
os.walk's list offolders still to visit grew without end, and in the agent scan's 4 GB sandbox it could take the room the scan's own
walk keeps free (#273).
The walk now keeps a running total of every folder it keeps to walk into, at what that folder's full path costs as a
str in that list. Past 64 MiB it stops as at its other limits, and the word is
unknown. A crafted tree then ends thescan with a finished row, not
scan_crashed. That holds together with #273, which bounds the scan's own walk.Type of Change
Changes
framework_detection.py:_MAX_FOLDER_BYTES(64 MiB) and_TOP_FLOOR(184);_folder_bytes(top, below):width × (max(len(top), 184) + 1 + len(below)) + 120, wherewidthis 1 if the wholepath is ASCII and 4 otherwise;
folder_findings, a running total that is never reduced. Past the bound,over_limitis set before thatfolder's files are read.
os.walkholds, under pymalloc and glibc.tree the same, so they stop at the same folder.
test_framework_detection.py. Every tree is sized from fixed numbers, and every expectedstop is worked out by hand.
os.walk's own list from its generator while it walks, and holds it to the bound under short, long,wide-character, wide-top and deep paths.
Testing
One file at a time, on Python 3.12.14 and 3.12.3:
test_framework_detectiontest_scan_folderstest_scan_walktest_agent_scantest_reading_entrytest_scenario_source_provision_agenttest_hosted_entrypointtest_harness_architectureOn 3.12.3, 6
test_hosted_entrypointtests fail withNo module named 'livekit'. That's the local venv, and the same6 fail on the base,
cf3ebb44.Planted breaks: 12, one per guard, each caught and restored.
Real trees: the most the total reaches is 3.15 MiB, on a monorepo checkout. That's about 5% of the bound.
A crafted tree at the real 64 MiB (60 levels × 2,000 folders) stops at level 54.
End to end, through the scan with its real folder-check child, on this branch merged with 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:
unknown;crewai, which shows the bound tripped;truncated: true), still a finished row withunknown.Nothing is killed in any run. The ticket's full 700-level tree can't be built under macOS's path limit, so "Done
when" on that tree rests on the sandbox memory sum.
Review, on Lane N:
13 Low.
What wasn't reviewed
ae5364d2fixes the change review's findings without another round. It's tests plus one docstring:tmp_path.Known, not changed here
These have their own tickets:
Related Issues
Refs: TH-9511