Uh oh!
There was an error while loading. Please reload this page.
Bump rain-sol-codegen 0.1.6 -> 0.1.36 and forge-std 1.16.1 -> 1.16.2 - #134
Conversation
`rain-sol-codegen` 0.1.35 replaces the API this repo generated through, so the bump is a rewrite of the calls rather than a version string. forge-std goes with it, forced rather than chosen: 0.1.35's own `LibFs.sol` and `LibCodeGen.sol` import `forge-std-1.16.2/src/Vm.sol`, and a `Vm` from 1.16.1 is a different type at every seam the two libraries share. The licence and the copyright holder are now PARAMETERS of `LibRainDeploySnapshot`, declared in `script/Build.sol` as `GENERATED_SPDX_LICENSE_IDENTIFIER` / `GENERATED_COPYRIGHT_TEXT` and threaded down to `LibCodeGen.filePrefix`. `rain-deploy` is itself published and `rain.factory.deploy` consumes it, so a header chosen inside this library would stamp Rain's licence permanently into another org's append-only `src/generated/<tag>/` — the defect one layer down that codegen made unrepresentable. `LIB_FS_ROOT` is now `LibFs`'s exported `GENERATED_DIR` rather than a second `"src/generated"` literal held equal to it by an assertion. One constant is what the assertion was standing in for. `snapshotName` is deleted. It existed only to smuggle `dir + "/" + name` through an argument documented to be a Solidity identifier, which codegen now refuses; `LibFs.pathForTaggedContract` takes the directory as a directory. The root-aware `dirForSnapshot`/`pathForSnapshot` overloads carry the writer's own guards in `pathForTaggedContract`'s order, so the reader and the writer agree on which paths EXIST as well as on how they are spelled — `testRootAwareSnapshotPathIsTheWritersAtTheRealRoot` now compares the two as OUTCOMES across the whole fuzz domain, revert data included, rather than only over the names both accept. `writeSnapshot` no longer creates the snapshot directory: the writer creates it from the same tag the path is derived from, so there is no second `createDir` to disagree with it. Fixture directories are renamed to the tag alphabet (`write-snapshot-not-a-tag` -> `writeSnapshotNotATag`, same for the dependencies fixture). They must stay non-`isTag` — a tag-shaped scratch directory under the real `src/generated/` is a release every parallel test suite has to fail on — while being alphabet-legal, because the writer places files only in directories whose names are. Regenerating `src/generated/` and both alias libs with 0.1.35 produces output byte-identical to what is committed: `forge script ./script/Build.sol` followed by `forge fmt` leaves the tree clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The licence and the copyright holder are parameters of `LibRainDeploySnapshot` rather than constants inside it, so that deploy repos in other orgs get their own header in their own append-only `src/generated/<tag>/`. That freedom is only worth having if what is handed in is what comes out. The alias and released emitters each already assert their output byte for byte. The snapshot writer had no such assertion: the two values are strings of the same type in adjacent positions, so a call that swapped them compiles and writes a file carrying both, in the wrong tags. Every other test that reads a snapshot header reads the COMMITTED file, which is evidence about a generation that already happened rather than about what the writer emits now. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Warning Review limit reached
Next review available in:39 minutes Limit details: You’ve used all 1 included review currently available under your plan. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (22)
Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review. WalkthroughThe pull request updates Forge Std and Rain Sol Codegen versions. It changes snapshot path handling to use validated tagged-contract paths and adds caller-provided SPDX license and copyright metadata to generated files. Build wiring and snapshot tests were updated. ChangesSnapshot generation
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk:⚪ Minimal · up to This dependency and snapshot-path update is merge-ready after normal checks; no actionable merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
thedavidmeister
commented
Aug 17, 2026
@coderabbitai review The earlier review failed during the GitHub outage, and the head has moved to |
❌ Action failedReview failed.
|
0.1.35 predates the licence defaults. 0.1.36 is the release that carries `RAIN_SPDX_LICENSE_IDENTIFIER` and `RAIN_COPYRIGHT_TEXT` and the arities of `filePrefix` and the `LibFs` writers that resolve to them. `soldeer update` adds the new remapping but leaves the superseded one in place, so `rain-sol-codegen-0.1.35/` is deleted here rather than left to resolve against a directory that no longer exists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
thedavidmeister
commented
Aug 18, 2026
Re-pointed 0.1.35 -> 0.1.36. 0.1.35 predates the licence defaults; 0.1.36 is the release cut from rainlanguage/rain.sol.codegen#144, which restores Also deleted the Local: |
`script/Build.sol` declared `GENERATED_SPDX_LICENSE_IDENTIFIER` and `GENERATED_COPYRIGHT_TEXT` as its own string literals, holding the same two values `rain-sol-codegen` 0.1.36 exports as `RAIN_SPDX_LICENSE_IDENTIFIER` and `RAIN_COPYRIGHT_TEXT`. Two definitions of one invariant, free to drift, with nothing comparing them. Both are deleted and the call sites — three in `Build.sol`, twelve in `LibRainDeploySnapshot.t.sol` — name codegen's. `LibRainDeploySnapshot` and `LibFs` still take the header as parameters, because both are dependencies of deploy repos in other orgs whose generated trees are append-only; what changes is only which repo the values are written down in. `testWriteAliasLibWritesTheLibAtItsPath` emits with these constants and asserts the result is the committed generated file byte for byte. It passes, and no file under `src/generated/` moves, so the emitted header is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
thedavidmeister
commented
Aug 18, 2026
Removed rain.deploy's own licence constants.
The emitted header is unchanged. Local, before and after, identical: 206 passed; 51 failures, all |
192 lines of which 111 were comment. The doc block argued for the design — why one list rather than two, why candidates are reached by name, what would go wrong under alternatives nobody wrote — rather than saying what the script does. Same in the alias-lib test's NatSpec. Now 115 lines, 34 comment: what each entry point rewrites, what the struct fields place and name, what the test asserts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codegen 0.1.36 defaults the header at its own writers, but every caller reaches them through this library, whose three writers each had one arity requiring the licence and copyright. So a repo in this org still had to name the values, and `script/Build.sol` did — which is the same either/or the codegen change already removed one layer down: taking the values as parameters is what a repo outside this org needs, and it never ruled out an arity that defaults. `writeSnapshot`, `writeAliasLib` and `writeReleasedSuitesLib` each gain the defaulting overload. Build.sol drops the arguments and the import; nothing in this repo now names a licence in the build path. Covered three ways: the two tests that emit over the committed generated files and assert byte equality now go through the defaulting arity, and one test per writer asserts the defaulting arity writes exactly what the parameterised one writes when handed the org values — which a swapped or wrong constant breaks. `testWriteSnapshotDefaultsToTheOrgHeader` reverts EVM state between its two writes: the Zoltu deploy is CREATE2, so writing one creation code twice lands on an address that already has code. 209 passed, up from 206. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
thedavidmeister
commented
Aug 18, 2026
Pushed the defaults one layer up, which is where the question actually was. Codegen 0.1.36 defaults the header at its own writers, but nothing in this repo calls those directly — every caller goes through Each of the three writers now has the defaulting overload. Covered three ways:
Mutations, applied to the branch and reverted:
209 passed, up from 206. Same 51 RPC-env failures. |
Uh oh!
There was an error while loading. Please reload this page.
Bumps
rain-sol-codegenfrom0.1.6to0.1.35, the latest published release.forge-stdgoes1.16.1->1.16.2in the same change, and that is forced rather than scope creep: codegen 0.1.35's ownLibFs.solandLibCodeGen.solimportforge-std-1.16.2/src/Vm.sol, and aVmfrom 1.16.1 is a different type — nothing compiles otherwise.Why this is more than a prefix rewrite
filePrefix()now takes required(spdxLicenseIdentifier, copyrightText)with no defaulting overload — rain.sol.codegen#135, closing its issueExampleDeploySuitesdocumentsAddressRegistryas the only concrete in the repo, which is no longer true #75, so the library stops stamping one org's licence into another repo's generated files.buildFileForContractgained the same parameters.LibRainDeploySnapshotwas smuggling a path separator through the contract-name argument (pathForContract(snapshotName(dir, contractName))). Current codegen refuses that.pathForTaggedContract/buildFileForTaggedContractwere added for exactly this layout (rain.sol.codegen#137, its issue solc warning 2018:candidateContractNamedeclaredviewwhen it can bepure#78), and this repo is the consumer they were built for.Decisions
Licence and copyright are parameters of
LibRainDeploySnapshot, not constants inside it. Declared inscript/Build.soland threaded down.rain-deployis itself published andrain.factory.deployconsumes it, so hardcoding Rain's header in the library would recreate one layer up the precise defect codegen #135 fixed.snapshotNameis deleted — it existed only to build the smuggled name.LIB_FS_ROOT = GENERATED_DIRimported fromLibFsrather than a second"src/generated"literal.The root-aware
dirForSnapshot/pathForSnapshotoverloads carry the writer's guards (requireTagthenrequireIdentifier, inpathForTaggedContract's order), so both path spellings share one validity rule.Fixture dirs renamed to the tag alphabet (
write-snapshot-not-a-tag->writeSnapshotNotATag); they must stay non-isTagwhile being alphabet-legal. Record roots and rawstring.concatfixtures are untouched.The regeneration is byte-identical, and that is now measured
forge script script/Build.solon this head, thengit status: empty. Not justsrc/generated/candidate/— nothing anywhere in the tree moved. Both rolling snapshots, both alias libs and both released-suites libs regenerate to the bytes already committed under codegen 0.1.6.That claim was previously reasoning about the two versions' emitters. It is now the measurement, which matters because rainix runs
frozen-snapshots-append-onlyand because the deploy pins consumers hold are exactly these bytes: a bump that moved them would moveDEPLOYED_ADDRESS.QA
Discriminating tests.
testRootAwareSnapshotPathIsTheWritersAtTheRealRoot, rewritten as a staticcall outcome-parity fuzz — both path spellings accept/refuse the same names and return the same bytes, through newexternalPathForSnapshotAt/externalPathForSnapshotwrappers. Writer-test expected headers are built fromscript/Build.sol's licence/copyright constants, so those constants are anchored to the committed artifacts rather than restated. Each fails on base by construction:snapshotNameno longer exists on this head and the writers take two more arguments, so the base spelling does not compile.Added here:
testWriteSnapshotDeclaresTheLicenceItWasHanded. Making the header a parameter is only worth doing if what is handed in is what comes out, and the snapshot writer had no assertion on that — the alias and released emitters each have a byte-for-byte one, and every other test that reads a snapshot header reads the committed file, which is evidence about a generation that already happened. The two values are strings of the same type in adjacent positions, so a call that swapped them compiles and writes a file carrying both, in the wrong tags, into a consumer's append-only record. The test asserts the header entire — everything beforepragma— against text spelled out rather than taken fromLibCodeGen.filePrefix, so the oracle is not the code that wrote the file.Mutations. The pass over the changed lines recorded 11 mutants, 11/11 killed, 0 survived — the deleted
snapshotNamepath, the guard placement in the root-aware overloads, and the licence/copyright threading. That pass is not re-run here.Run here, for the test added here: swapping
spdxLicenseIdentifierandcopyrightTextat thebuildFileForTaggedContractcall inwriteSnapshot. Killed —LibRainDeploySnapshot.t.solgoes 43 passed to 42 passed / 1 failed, and the single failure is the new test, on// SPDX-License-Identifier: Copyright (c) 2020 Rain Open Source Software Ltd. Nothing else in the file notices, which is the gap it was written for.Oracle. The committed artifacts under
src/generated/candidate/, and now the empty regeneration diff against them rather than an argument about emitters.Category check. The ask is one thing — bump to the latest codegen release. Covered: the pin,
soldeer.lock,remappings.txt, all 19.solimport prefixes (zerorain-sol-codegen-0.1.6orforge-std-1.16.1survive), both API changes above, and the README versions.Checks run locally
forge script script/Build.sol— successful, zero diff.reuse lint— compliant, 82/82 files.forge fmt --check— clean.slither .— 49 contracts, 100 detectors, 0 results.forge test— 206 passed, 51 failed, 0 skipped, 257 total across 18 suites. All 51 failures arevm.createSelectFork: environment variable ARBITRUM_RPC_URL / BASE_RPC_URL / POLYGON_RPC_URL not found— fork tests wanting RPC secrets CI has and a local shell does not. Counted, not sampled: zero of the 51 is anything else, and none is related to this change.The symlink/ffi risk is closed
codegen 0.1.35 reaches
removeSymlink, and itsvm.tryFfi, only insideif (vm.exists(path) && isSymlinkIn(vm, dir, path))— an actual symlink sitting at a generated path. This repo does not setffi = true, so that branch would revert.It is unreachable here:
find src test script -type lis empty, there is noln -sor symlink-creating call anywhere outsidedependencies/, and both the regeneration and the full suite write generated files withffiunset without hitting it.About the earlier red on
db4e887All three checks on
db4e887failed at step 1, "Set up job", 48-88 seconds after starting at14:51:18Z— before checkout, before dependencies, before anything in this diff ran. That is inside the critical-impact GitHub incident opened at13:40:03Zwith Actions in major outage. The runner never started, so those reds are not a verdict on this code and nothing about them was fixed, because there was nothing there to fix.Actions has since recovered.
rainix / static,rainix / legalandrainix / testare all completed/success ondc3204f, started15:42:03Z.Summary by CodeRabbit
Documentation
Refactor
Tests
Chores