Skip to content

chore: remove the submodule-era residue — dead foundry.lock, .gitmodules//lib references, and a slither filter pointed at lib/forge-std - #27

Merged
thedavidmeister merged 1 commit into
mainfrom
2026-08-21-remove-submodule-residue
Aug 21, 2026
Merged

thedavidmeister merged 1 commit into
mainfrom
2026-08-21-remove-submodule-residue

Conversation

@thedavidmeister

@thedavidmeister thedavidmeister commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Closes #15.

What this removes

foundry.lock is Foundry's git submodule lockfile — it records the commit each dependency vendored under lib/ is pinned to, so forge install / forge update can restore identical revisions. It is only meaningful in a repo that vendors dependencies as git submodules.

This repo does not. Verified on a fresh clone of main: no .gitmodules, no lib/, and git ls-files --stage reports zero gitlinks (mode 160000). Dependencies come from soldeer — foundry.toml sets libs = ["dependencies"] and soldeer.lock is the live lockfile for the single package that lands under dependencies/, forge-std 1.16.1.

The two lockfiles disagreed. foundry.lock pinned lib/forge-std at b8f065fda83b8cd94a6b2fec8fcd911dc3b444fd, an untagged forge-std commit from 2025-10-14; the build has been using 1.16.1 the whole time, per both foundry.toml [dependencies] and soldeer.lock. Nothing reconciled them, because nothing read the foundry.lock side.

Submodules also cannot come back — rainix CI runs a no-submodules check that fails on a root .gitmodules or any committed gitlink.

It was not silent

forge build emitted one warning per entry in the file. Reproduced on main in the pinned rainix#sol-shell (3d1c85eca08ef5a852215f77c8f3684c8313a8b3):

Warning: Dependency 'lib/forge-std' not found at expected path
Compiling 24 files with Solc 0.8.25
Compiler run successful!

Same command on this branch:

Compiling 24 files with Solc 0.8.25
Compiler run successful!

The warning is gone. (forge build still emits an unrelated pre-existing unsafe-typecast lint on test/LibCast.t.sol:134, unchanged by this PR and present identically on main.)

Everything in the diff

Deleting the file alone would have left every reference to it behind, silently, because not one of them fails anything — reuse lint tolerates annotation paths that do not exist, and a .soldeerignore line for a nonexistent path is a no-op. So this takes the whole set in one pass.

File Change Why
foundry.lock deleted dead submodule lockfile, contradicted by soldeer.lock
REUSE.toml drop "foundry.lock", from the annotation path list the file it annotates is gone
.soldeerignore drop /foundry.lock same
.soldeerignore drop /lib no lib/ in the tree; libs = ["dependencies"] means forge never creates one
.soldeerignore drop .gitmodules no .gitmodules, no gitlinks, and no-submodules keeps it that way
.soldeerignore drop .coderabbit.yaml no such file here, and not gitignored. The org repos that do have one spell it .coderabbitai.yaml
.soldeerignore drop CLAUDE.md this repo has none
slither.config.json filter_paths → dependencies/forge-std-,test forge-std is not under lib/ any more

.soldeerignore entries deliberately kept

Each remaining line was checked individually rather than dropped by pattern:

  • .gas-snapshot stays. That file does exist in this repo (532 bytes, tracked). It is a live ignore, not residue.
  • .DS_Store, .vscode, .pre-commit-config.yaml — OS junk and local developer files. .pre-commit-config.yaml in particular is written into the working tree on devShell entry, so it is present exactly when soldeer push would run.
  • /out, /cache, /dependencies, /remappings.txt — generated at forge soldeer install / forge build time. Absent from a clean checkout by design, present when publishing.
  • .git, .github, .gitignore, .soldeerignore, /audit, /flake.lock, /flake.nix, /foundry.toml, /slither.config.json, /soldeer.lock, /REUSE.toml — all exist and are correctly excluded from the published package.

On the slither filter

The old lib/forge-std half of filter_paths named nothing, so it was not filtering anything. The new value uses the dependencies/forge-std- prefix rather than the full dependencies/forge-std-1.16.1/, so a version bump does not silently blank the filter the same way the migration did.

Checked for newly surfaced findings, as the issue asks. slither . in the pinned shell, before and after:

INFO:Slither:. analyzed (2 contracts with 99 detectors), 0 result(s) found

Identical, exit 0 both times — nothing new appeared, and nothing was widened to hide anything.

Worth stating plainly rather than implying more than was tested: filter_paths is inert in this repo today, on both the old value and the new one. slither . builds with --skip ./test/** ./script/**, and src/LibCast.sol and src/LibConvert.sol contain no import statements at all, so neither forge-std nor test/ ever enters the analysis for a filter to exclude. The line is fixed because it should name a real path when it starts mattering, not because it was hiding a finding.

Verification

All in nix develop github:rainlanguage/rainix/3d1c85eca08ef5a852215f77c8f3684c8313a8b3#sol-shell, matching what rainix-sol runs.

Check Result
forge build successful, no Dependency '...' not found at expected path
forge test -vvv 17 passed, 0 failed, 0 skipped (LibCast 11, LibConvert 6)
slither . 2 contracts, 99 detectors, 0 results, exit 0 — same as main
forge fmt --check clean
rainix-sol-single-contract exit 0
reuse lint compliant, 19/19 files with copyright and license information

And on CI, on this PR's own rainix-sol run (32500412818) — static, legal and test all pass, the static job's slither step prints the same 2 contracts with 99 detectors, 0 result(s) found, and the string Dependency appears nowhere in that job's log.

Residue sweep over tracked files after the change:

$ git ls-files -z | xargs -0 grep -nE '\.gitmodules|foundry\.lock|(^|[^A-Za-z0-9_.-])lib/'
(no hits)

Scope

Issue #15 is one repo of a 17-repo pass. Only rain.lib.typecast is touched here. No Solidity source, no deployed bytecode and no audited artifact changes.

QA

  • Discriminating tests: n/a — configuration-only diff, no behaviour for a Solidity test to discriminate. The discriminating evidence here is the build itself, and it is a real before/after: forge build on main prints Warning: Dependency 'lib/forge-std' not found at expected path, and on this branch it does not. Both runs in the pinned rainix#sol-shell, transcribed above. The existing 17-test suite is the regression guard and is green unchanged (17 passed / 0 failed / 0 skipped on both sides).
  • Mutations applied: n/a — the diff is configuration only. The four touched files are a deleted git-submodule lockfile, a REUSE annotation list, a soldeer publish-ignore list and a slither filter string. There is no executable line in the diff to negate, flip or drop, so there is no mutant for mutation-probe to generate; the compiled bytecode is byte-identical either way. The repo's existing mutation coverage (audit/mutation-test-scans.json) is untouched and still describes the same tree.
  • Oracle: the tools that own each file, not a re-derivation. forge build's own warning is the oracle for foundry.lock being dead (it names the missing path) and for it being fixed (the warning stops). git ls-files --stage reporting zero gitlinks plus the absence of .gitmodules is the oracle for "no submodules here". forge soldeer install writing dependencies/forge-std-1.16.1/ and remappings.txt reading forge-std-1.16.1/=dependencies/forge-std-1.16.1/ is the oracle for the real forge-std path. reuse lint is the oracle for REUSE.toml. Every .soldeerignore line was tested by existence check against a fresh clone, one path at a time — which is why .gas-snapshot survived while the five dangling entries did not.
  • Category check: issue Remove the submodule-era residue — dead foundry.lock, .gitmodules/lib/ references, and a slither filter pointed at lib/forge-std #15 asks for (a) foundry.lock deleted, (b) its REUSE.toml entry removed, (c) five .soldeerignore entries removed, (d) slither.config.json filter_paths repointed at dependencies/forge-std- with the static job checked for new findings, (e) forge build no longer emitting the not-found warning, (f) no .gitmodules / lib/ / foundry.lock reference left in the tree outside dependencies/, (g) CI green. Covered a, b, c, d, e, f locally; (d)'s "checked for newly surfaced findings" is the identical 0-result slither run above; (g) is this PR's own rainix-sol run.

`foundry.lock` is Foundry's git-submodule lockfile: it pins the commit each
dependency vendored under `lib/` is checked out at. This repo has no
`.gitmodules`, no `lib/` and no gitlinks — dependencies come from soldeer,
`foundry.toml` sets `libs = ["dependencies"]`, and `soldeer.lock` is the live
lockfile. The two disagreed: `foundry.lock` pinned `lib/forge-std` at
b8f065fd (an untagged 2025-10-14 forge-std commit) while the build has been
using 1.16.1 the whole time. Nothing reconciled them because nothing read the
`foundry.lock` side.

It was not silent. `forge build` emitted one warning per entry:

    Warning: Dependency 'lib/forge-std' not found at expected path

Submodules cannot come back either — rainix CI runs a `no-submodules` check
that fails on a root `.gitmodules` or any committed gitlink.

Removing the file alone would have left the references behind, so this takes
all of them in one pass:

- `foundry.lock` deleted.
- `REUSE.toml` drops its `"foundry.lock"` annotation entry.
- `.soldeerignore` drops `/foundry.lock` and `/lib`, plus three more entries
  found while checking that name nothing in this tree: `.gitmodules`,
  `.coderabbit.yaml` (no such file here, not gitignored; the org repos that
  have one spell it `.coderabbitai.yaml`) and `CLAUDE.md` (this repo has
  none). `.gas-snapshot` stays — that file does exist. So do `.DS_Store`,
  `.vscode`, `.pre-commit-config.yaml` and the build/publish outputs
  (`/out`, `/cache`, `/dependencies`, `/remappings.txt`): absent from a clean
  checkout by design, present when `soldeer push` runs.
- `slither.config.json` `filter_paths` moves from `lib/forge-std` to
  `dependencies/forge-std-`, which is where forge-std actually lands
  (`dependencies/forge-std-1.16.1/`). The prefix stops short of the version so
  a bump does not silently blank the filter again.

Configuration only. No Solidity source, no deployed bytecode, no audited
artifact changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 21, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 42596afe-c89a-4fad-a7f5-aa97319f0d69

📥 Commits

Reviewing files that changed from the base of the PR and between f73f293 and 388bc0c.

⛔ Files ignored due to path filters (1)
  • foundry.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • .soldeerignore
  • REUSE.toml
  • slither.config.json
💤 Files with no reviewable changes (2)
  • REUSE.toml
  • .soldeerignore

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


Walkthrough

The change removes obsolete migration-era paths from repository configuration and updates Slither to filter the current dependencies/forge-std- path.

Changes

Configuration cleanup

Layer / File(s) Summary
Remove stale configuration entries
.soldeerignore, REUSE.toml
.soldeerignore no longer ignores obsolete repository paths. REUSE.toml no longer lists foundry.lock for annotation.
Update Slither dependency path
slither.config.json
Slither now filters dependencies/forge-std- and test instead of lib/forge-std and test.

Estimated code review effort: 1 (Trivial) | ~3 minutes

Merge Risk: ⚪ Minimal · up to 388bc

This change removes obsolete dependency and packaging references and updates the static-analysis path without changing Solidity source or deployed behavior; no actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive Visible changes match issue #15, but deletion of foundry.lock cannot be verified because it is excluded by !**/*.lock. Include foundry.lock in the review or provide direct evidence that it was deleted.
✅ Passed checks (4 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed All reviewed changes are configuration cleanup items directly covered by issue #15.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (1 skipped: 1 unsupported.)
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the cleanup of submodule-era residue and the Slither path update.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 2026-08-21-remove-submodule-residue

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@thedavidmeister
thedavidmeister merged commit 24b6513 into main Aug 21, 2026
4 checks passed
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.

Remove the submodule-era residue — dead foundry.lock, .gitmodules/lib/ references, and a slither filter pointed at lib/forge-std

1 participant