Skip to content

docs: version is the last publish, not a name for a snapshot that exists - #110

Merged
thedavidmeister merged 1 commit into
mainfrom
2026-08-15-issue-67-version-snapshot-invariant
Aug 16, 2026
Merged

docs: version is the last publish, not a name for a snapshot that exists#110
thedavidmeister merged 1 commit into
mainfrom
2026-08-15-issue-67-version-snapshot-invariant

Conversation

@thedavidmeister

Copy link
Copy Markdown
Contributor

Closes #67

The claim that did not hold

README.md:310-311 and foundry.toml:3-5 both stated [package].version is
"the LAST released version, naming the current src/generated/<tag>/
snapshots
". The appositive is false: version = "0.1.5", src/generated/
holds only candidate/, and both releasedSuites() libs return empty arrays.

I checked why, rather than assuming. sol-v0.1.5 is a real Soldeer release
(published 2026-07-30, confirmed live in the Soldeer registry — 0.1.5 is the
latest published rain-deploy, and 0.1.6 was never published). Its tag tree has
no src/generated/ at all: the snapshot machinery landed after it. So no
0_1_5/ record was ever written, and none can be — cutRelease() freezes to
deployTag(vm), read from foundry.toml, and 0.1.5 is already published.

The "LAST released version" half is true and deliberate. Only the clause about
naming an existing snapshot directory was wrong.

The fix

Reworded so the rule holds in both windows instead of describing a transient
state:

  • version is the version of the LAST Soldeer publish;
  • a release cut under this lifecycle also names the frozen
    src/generated/<tag>/ record cutRelease() wrote for it;
  • a version published before this lifecycle has none, so src/generated/ holds
    no directory for it.

That last line is what a reader seeing 0.1.5 beside a lone candidate/ needs
to reconcile the two, and it stays true after the first tag. I deliberately did
not take the issue's suggested wording verbatim: it said src/generated/
"currently holds candidate/ and nothing else", which becomes false at the
first release and would trade one stale sentence for another. Naming 0.1.5
explicitly has the same problem; the rule does not.

An earlier draft was discarded for being newly false rather than merely stale:
it said "from the first sol-v* tag onward", but sol-v0.1.4 and sol-v0.1.5
already exist (the old merge-driven workflow cut them) and froze nothing.

Beyond the two sites the issue cites

The issue names README and foundry.toml. The same claim appears in a third
place, so I fixed the category rather than the examples:

  • CLAUDE.md:397-398 — "[package].version is the LAST released version and
    moves only in lockstep with its snapshots". Same false possessive.
  • src/lib/LibRainDeploySnapshot.sol:75 — illustrated the layout as
    candidate/ 0_1_5/ 0_1_6/, naming a directory that provably can never exist.
    Now candidate/ 0_1_6/ 0_1_7/, consistent with the 0.1.7 example ten lines
    below it.

A repo-wide grep confirms the only remaining 0.1.5 is foundry.toml's actual
version value.

QA

  • Discriminating tests: n/a — the diff changes only markdown prose, a TOML
    comment and a Solidity docstring. Nothing in the repo reads any of these four
    sites: no test, script, workflow or pin parses README/CLAUDE.md prose, and
    deployTag() reads [package].version (unchanged, still "0.1.5") via
    parseTomlString, which ignores TOML comments. There is no behavior to
    discriminate on, so a test here could only assert the text of a sentence.
  • Mutations applied: n/a — a docs-only diff has no executable lines to mutate.
    The generated-lib docstrings that are asserted
    (LibRainDeploySnapshot.sol:638 against LibRainDeploySnapshot.t.sol:316)
    are untouched by this diff; :75 is a source comment, not generated output.
  • Oracle: external to the repo's own prose, which is the thing under suspicion.
    The Soldeer registry API (api.soldeer.xyz/api/v1/revision) gives 0.1.5 as
    the newest published revision (2026-07-30T17:14:56Z) with no 0.1.6;
    git ls-tree -r sol-v0.1.5 -- src/generated is empty; git log -p foundry.toml shows the old autopublish bumping to 0.1.6 and a later commit
    setting it back to 0.1.5; .github/workflows/package-release.yaml confirms
    the tag names the version and cutRelease() writes the frozen record.
  • Category check: issue cites README.md:310-313 and foundry.toml:3-5; covered
    both, plus CLAUDE.md:397-398 and LibRainDeploySnapshot.sol:75, which carry the
    same false claim and were not cited. Category is "prose asserting that
    [package].version names an existing src/generated/<tag>/ snapshot"; a
    repo-wide grep for 0_1_5|0.1.5|LAST released|naming the current shows no
    remaining instance.

Build/test state

  • pre-commit (the repo's CI static toolchain): all hooks pass. denofmt
    rewrapped my markdown on the first attempt; that rewrap is included.
  • forge build: clean, exit 0. The one lint warning
    (LibRainDeploy.sol:304 unsafe-typecast) is pre-existing and untouched.
  • forge test: 168 passed, 47 failed locally. All 47 are
    vm.createSelectFork: environment variable BASE_RPC_URL/ARBITRUM_RPC_URL not found — I grepped every [FAIL line and zero have any other cause. Those
    are fork tests needing RPC secrets that CI supplies via secrets: inherit.

Note the first forge test I ran appeared to exit 0 while actually failing to
compile (deps not installed, exit code swallowed by a pipe to tail). The
numbers above are from a re-run with the real exit code.

🤖 Generated with Claude Code

`[package].version` was documented as "the LAST released version, naming the
current `src/generated/<tag>/` snapshots". The second half does not hold:
version is 0.1.5, `src/generated/` holds only `candidate/`, and both
`releasedSuites()` libs return empty. 0.1.5 was published to Soldeer on
2026-07-30, before the snapshot machinery existed — its own tag tree has no
`src/generated/` at all — so no `0_1_5/` record was ever written and none can
be, the version being already published.

State the rule so it holds in both windows rather than pinning it to a
transient fact: version is the version of the LAST Soldeer publish, a release
cut under this lifecycle also names the frozen record `cutRelease()` wrote for
it, and a version published before the lifecycle has none — which is what a
reader seeing 0.1.5 beside a lone `candidate/` needs to reconcile the two.
Naming 0.1.5 here would go stale at the first tag; the rule does not.

CLAUDE.md carried the same claim ("moves only in lockstep with its snapshots")
and is corrected with it. `LibRainDeploySnapshot.CANDIDATE` illustrated the
layout as `candidate/ 0_1_5/ 0_1_6/`, naming a directory that provably can
never exist; it now reads `candidate/ 0_1_6/ 0_1_7/`.

Closes #67

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@thedavidmeister thedavidmeister self-assigned this Aug 15, 2026
@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@thedavidmeister, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 21 minutes

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c42a5e72-6517-4628-bf8e-8166b1273303

📥 Commits

Reviewing files that changed from the base of the PR and between 86f8d96 and 15c77f5.

📒 Files selected for processing (4)
  • CLAUDE.md
  • README.md
  • foundry.toml
  • src/lib/LibRainDeploySnapshot.sol

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

Copy link
Copy Markdown
Contributor Author

Reviewed 1e4d5f9: ready — Closes #67. Docs only, across CLAUDE.md, README.md and the [package] comment, and the correction is factually right rather than a rewording. version was described as the last RELEASED version naming a current src/generated/<tag>/ snapshot; it is the version of the last Soldeer PUBLISH, and the two differ for every version published under the old merge-driven lifecycle. Confirmed independently: sol-v0.1.4 and sol-v0.1.5 both exist as tags, Soldeer holds 0.1.1 through 0.1.5, and neither tag carries a src/generated/<tag>/ directory — the tag-release path landed on 2026-08-08 and has never run here. The new wording is the only one that describes that state.

CI green, 0 unresolved threads — vacuous, CodeRabbit reports Review rate limited.

@thedavidmeister
thedavidmeister merged commit 0da4696 into main Aug 16, 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.

Stated invariant "[package].version … naming the current src/generated/<tag>/ snapshots" does not hold: no tag directory exists

1 participant