Repository navigation
fix(harness): take the build-hazard look's folders in name order (TH-9514) - #285
Merged
khushalsonawat merged 11 commits intoNov 11, 2026
Merged
khushalsonawat merged 11 commits into
khushalsonawat merged 11 commits into
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>
The hazard look walked folders in whatever order the file system listed them. Its caps stop it partway, so on a tree big enough to reach one, which agent.py files it had seen depended on the file system: the same tree could say agent_py on a Mac and "" on Linux. Each folder's subfolders and files are now sorted before anything else, as the scan's walk and the framework check already do. The look then goes depth first in name order everywhere, and a cap stops it at the same folder. A test forces both listing orders a level below the top, once where the cap is avoided and once where it stops the look. TH-9514 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
Both change reviewers cleared round 1, and found the same gap: the test put its whole tree a level down, so a sort skipped only at the folder the look starts from passed. Each case now runs with its tree at the top and a level below it. A sort skipped at the top fails the top cases, and a sort only at the top fails the nested ones. The forced order comes from a small factory rather than default arguments. TH-9514 Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
cdileep23
approved these changes
Nov 11, 2026
khushalsonawat
merged commit Nov 11, 2026
d60dbf7
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.
Review only the commits after
bc3dd187This branch starts from #273's head (
bc3dd187,feat/TH-9449-scan-followups), so it carries #273's nine commits. Those are reviewed in #273. This PR's own change is the last two commits:bc778b61fix(harness): take the build-hazard look's folders in name order6c12b363test(harness): hold the hazard look's order at its top and below itCompare:
bc3dd187...feat/TH-9514-hazard-name-order. Merge #273 first. This PR's diff then shrinks to those two commits.Description
For each agent the scan lists, a quick "hazard" look asks whether a build of that folder may stop on its own fallback, such as two
agent.pyfiles below it. The look stops early at its caps:It took folders in whatever order the file system lists them. So on a tree big enough to reach a cap, the same tree could say
agent_pyon a Mac and""on Linux. That's how #273's CI failed on Linux after passing on the Mac.Each folder's subfolders and files are now sorted before anything else, as the scan's walk (
_source_files) and the framework check (folder_findings) already do. The look goes depth first in name order everywhere, so a cap stops it at the same folder.Type of Change
Changes
scan_walk._hazard:directories.sort()andfiles.sort()before the ignore list.build_hazard's docstring names its three stops and the order.test_a_hazard_look_stopped_by_its_cap_gives_one_answer_in_any_listing_order[found|stopped]-[top|nested]. It forces both listing orders through a wrappedos.walk, with the tree at the top and a level below it:foundmust giveagent_pyin both orders;stoppedmust give""in both, with neitheragent.pyever listed, so the""comes from the cap.Testing
One file at a time, on Python 3.12.14 and 3.12.3:
test_scan_walktest_agent_scantest_scan_folderstest_scan_documenttest_scan_aitest_authoring_entrypoint_find_agentstest_framework_detectiontest_reading_entrytest_harness_architecturegives 35 passed and 11 failed, the same as atbc3dd187without this change. The 11 are TH-9444's hosted-GitHub tests, which CI deselects at this base.Planted breaks, each run against each of the four cases:
git merge-treeintofeat/TH-8804-source-subfolderis clean.Review, on Lane N: the design review, the plan review and the change review each cleared in round 1. Both change reviewers ran every plant.
What wasn't reviewed
6c12b363fixes the change review's one shared Medium, a test that missed the top folder. It changes tests only.Not changed here
#273's listed-paths cap counts absolute paths. So where it stops still depends on the checkout's root length, not just the order. That's left as it is.
Related Issues
Refs: TH-9514