rain-sol-codegen's LibSnapshot already implements the release freeze, in Solidity, callable from a build script. #302 is reimplementing it in Rust, and two repos hand-roll it in bash. This asks which layer owns it before #302 lands.
What LibSnapshot already provides
rain.sol.codegen/src/lib/LibSnapshot.sol:
deployTag(Vm) — [package].version from foundry.toml, dots to underscores. Its NatSpec calls itself "the single definition of the tag form".
dirForTag(string) — src/generated/<tag>
frozenPathForContract(string, string)
freezeSnapshot(Vm, string[]) — creates the dir, copies each generated file to its frozen path, and enforces append-only:
require(
keccak256(bytes(vm.readFile(frozenPath))) == keccak256(bytes(content)),
"LibSnapshot: frozen snapshot would change; bump [package].version for a new release"
);
Where the same work is duplicated
| implementation |
language |
layer |
LibSnapshot.freezeSnapshot |
Solidity |
build script |
script/cut-release.sh in rain.factory.deploy |
bash |
CI step |
script/cut-release.sh in S01-Issuer/st0x.deploy |
bash |
CI step |
rainix-static cut-release (#302, open, HELD) |
Rust |
CI step |
Plus deployTag restated locally in rain.deploy's script/Build.sol (being fixed in rain.deploy#26), and in rain.factory.deploy's and st0x.deploy's BuildPointers.sol.
The question
Which layer owns the freeze? #302's stated value is making the regenerate-then-freeze ordering unrepresentable, after the inverted ordering was found live in st0x.deploy — it copies candidate and only then runs forge script, so a drifted candidate is frozen stale while regeneration moves candidate on, publishing one address and permanently recording another.
But LibSnapshot puts the freeze in the same forge script run as the generation, which is where #304 argues it belongs — pointer generation is part of build, not a separate step. If generation and freezing are one script, a CI-layer freeze may be solving an ordering problem that only exists because they were split.
Points to settle, from the source rather than from this summary:
Why this is blocking-shaped
#302 is already HELD pending #303 and #304. This adds a third reason to settle the design before merging: it may be reimplementing a published library in a different language at a different layer. Landing it would make five implementations of one operation.
Related: #301, #302, #303, #304; rain.deploy#26 (dropping its local deployTag and address-constant emitter for the shared ones).
rain-sol-codegen'sLibSnapshotalready implements the release freeze, in Solidity, callable from a build script. #302 is reimplementing it in Rust, and two repos hand-roll it in bash. This asks which layer owns it before #302 lands.What
LibSnapshotalready providesrain.sol.codegen/src/lib/LibSnapshot.sol:deployTag(Vm)—[package].versionfromfoundry.toml, dots to underscores. Its NatSpec calls itself "the single definition of the tag form".dirForTag(string)—src/generated/<tag>frozenPathForContract(string, string)freezeSnapshot(Vm, string[])— creates the dir, copies each generated file to its frozen path, and enforces append-only:Where the same work is duplicated
LibSnapshot.freezeSnapshotscript/cut-release.shin rain.factory.deployscript/cut-release.shin S01-Issuer/st0x.deployrainix-static cut-release(#302, open, HELD)Plus
deployTagrestated locally in rain.deploy'sscript/Build.sol(being fixed in rain.deploy#26), and in rain.factory.deploy's and st0x.deploy'sBuildPointers.sol.The question
Which layer owns the freeze? #302's stated value is making the regenerate-then-freeze ordering unrepresentable, after the inverted ordering was found live in st0x.deploy — it copies
candidateand only then runsforge script, so a drifted candidate is frozen stale while regeneration moves candidate on, publishing one address and permanently recording another.But
LibSnapshotputs the freeze in the sameforge scriptrun as the generation, which is where #304 argues it belongs — pointer generation is part ofbuild, not a separate step. If generation and freezing are one script, a CI-layer freeze may be solving an ordering problem that only exists because they were split.Points to settle, from the source rather than from this summary:
freezeSnapshotdo everythingcut-release.shdoes? Missing candidates: the strictX.Y.Zversion check, the refusal whencandidate/is absent, thediff -rassertion, theforge fmtstep.requirefires only when a frozen path ALREADY exists, so on a NEW tag a stale freeze writes silently. Prevented, merely visible, or neither?forge scriptrun?Why this is blocking-shaped
#302 is already HELD pending #303 and #304. This adds a third reason to settle the design before merging: it may be reimplementing a published library in a different language at a different layer. Landing it would make five implementations of one operation.
Related: #301, #302, #303, #304; rain.deploy#26 (dropping its local
deployTagand address-constant emitter for the shared ones).