autosetup: anchor on the project whose artifacts these actually are - #187
Open
shellygr wants to merge 1 commit into
Open
autosetup: anchor on the project whose artifacts these actually are#187shellygr wants to merge 1 commit into
shellygr wants to merge 1 commit into
Conversation
find_build_config_dir accepts a directory once it holds a build config and its artifact directory exists. Two configs can name the same physical directory: a root config building the tree with out = 'pkg/out', and pkg/foundry.toml with the default out = 'out' that never ran. The walk stops at pkg/, and everything after it reads artifacts in the wrong frame — the extractor builds its project-file set relative to pkg/ while the artifacts record paths relative to the root, so no source path matches, every artifact is filtered out, and a build that fully succeeded ends as "no project-local logic contracts found". The artifacts themselves say which project wrote them: their recorded source paths resolve against it. A candidate now has to pass that test, so a directory holding somebody else's artifacts is skipped and the walk continues to the one they belong to. Artifacts that record no source path answer yes, leaving projects with older or stripped metadata where they were. Measured on a 399-project sweep: one project lost 110 matching artifacts this way, from a build with no errors at all.
shellygr
marked this pull request as ready for review
August 22, 2026 15:19
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.
Follow-up to the artifact-directory work in #169, from the same sweep that produced #186.
What goes wrong
find_build_config_dirwalks up from the contract and stops at the first directory that holds abuild config and has its artifact directory on disk. That test is satisfiable by a directory that
never built anything, because two configs can name the same physical directory:
pkg/outexists andpkg/foundry.tomlis a config, so the walk stops atpkg/. Everythingdownstream then reads those artifacts in the wrong frame: the extractor builds its project-file set
relative to
pkg/, while the artifacts recordpkg/src/Widget.solrelative to the root. No sourcepath matches, the scope filter drops every artifact, and the run dies with "No project-local logic
contracts found in FoundryManager build output" — from a build that had no errors at all.
In the sweep this cost one project 110 matching artifacts, and the class it lands in is the run's
largest.
The change
The artifacts say which project wrote them: Foundry records
metadata.settings.compilationTarget,Hardhat records
sourceName, and both are relative to the project the build ran in. A candidatedirectory now has to pass that test — at least one recorded source path has to resolve inside it —
so a directory holding somebody else's artifacts is skipped and the walk continues to the one they
belong to.
This extends #169's own principle rather than reversing it: decide from what is on disk, not from
the directory layout. A genuinely nested project that built its own artifacts records paths relative
to itself, passes, and still anchors where #169 put it. Artifacts with no recorded source (older
Foundry, stripped metadata) answer yes, so nothing moves for them.
Sampling is capped at 20 artifacts per candidate, so the check costs a few JSON reads on a path that
already walks the tree.
Tests
tests/test_project_dir.pygains three cases: the shared-out-dir layout above (fails without thechange), a nested project that really did write its own artifacts (must keep anchoring there), and
artifacts with no metadata (must not move). 24 pass in that file, 111 across the parser and
workaround suites.
The repo's full run fails 14 for me and 15 on a clean tree, all in integration tests that vary
between runs; none of them is unique to this change.
Draft, and worth reviewing alongside #186: both come out of the same sweep, and this one touches the
path #169 introduced.
🤖 Generated with Claude Code