Skip to content

docs: state the fixed-point bound and how a non-converging build reports - #136

Merged
thedavidmeister merged 5 commits into
mainfrom
2026-08-16-issue-81
Aug 17, 2026
Merged

docs: state the fixed-point bound and how a non-converging build reports#136
thedavidmeister merged 5 commits into
mainfrom
2026-08-16-issue-81

Conversation

@thedavidmeister

@thedavidmeisterthedavidmeister commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Closes#81

Note

Rewritten against post-#140main, and no longer blocked. The paragraph
this PR previously added documented a bound that does not exist, and patched a
README that #140 has since rewritten. Both are corrected here — see "What
changed since the last push". The PR no longer depends on
rainlanguage/rainix#319, because it no longer states anything that PR would
make true.

What #81 asks for here

#81 has two halves and says so: the loop itself "is rainix's to own and is filed
separately at rainlanguage/rainix#314", leaving this repo the half that lives
here — README.md stating the fixed-point invariant as prose with no bound,
and .github/workflows/build-pointers.yaml inheriting the single-shot
behaviour.

The second half is void: #138 deleted build-pointers.yaml outright along with
the worked example it regenerated. This repo generates nothing and no longer
calls rainix-copy-artifacts.yaml at all, so there is no single-shot behaviour
left here to inherit or to fix.

The first half is what this PR discharges. #81 files it as a hazard: a build
that does not converge is indistinguishable, from CI, from a build the developer
forgot to re-run. The README cannot remove that hazard — removing it means
putting the loop in the machine, which is rainix's and is tracked at
rainlanguage/rainix#314. What the README can do, and now does, is stop leaving
the reader to guess: it says who owns the loop, what to do at a shell, and how
to tell "one more pass" from "this will never settle".

What the README says now

One paragraph, immediately after the fixed-point invariant it qualifies:

Reaching that fixed point is the consumer's job: nothing bounds or iterates
the loop. A tree that has not settled fails the currency check exactly as a
tree nobody regenerated does — see
rainix-copy-artifacts.yaml
— so regenerate until the working tree stops changing before committing, and
read a tree that never stops changing as a cycle that does not converge rather
than one more pass to run. Committing part-way records a deployed-bytecode
hash for a contract compiled against a different pass of the same file.

It is addressed to consumers — rain.deploy and every other repo that drives
this library from script/Build.sol. Nothing in this repo is generated, so
nothing here loops.

What changed since the last push

1. The bound it documented does not exist. Re-verified independently
against rainlanguage/rainix at HEAD 7f223b4:
.github/workflows/rainix-copy-artifacts.yaml runs
forge script ./script/Build.sol exactly once, inside a plain if [ -f ... ]
guard. No loop. max-codegen-passes gets 0 hits across the whole rainix
repo
, so there is no such input and no default of 5. fixed point and
did not reach get 0 hits too; the only failure that step's currency check
can emit is Committed artifacts are stale.
rainlanguage/rainix#319,
which would add the bound, is still open (checked at this push).

So the previous paragraph stated a bound, a default, an input name and a failure
message that no deployed workflow has. It is replaced, not softened: the
regeneration loop is unbounded, nothing iterates it, and the operator repeats
until the working tree stops changing.

2. It patched a README that no longer exists.#140 landed today, closing
#139, and rewrote the README so it stops narrating rainix's workflow internals —
mechanism cut, consequence kept, one link to the workflow that owns it. #139
names this PR explicitly as adding a fifth instance of the defect it fixes.

The replacement paragraph is written in that register: the consequence for
someone working in a consuming repo, plus the one link, and no transcription of
what the reusable does step by step. It says what the reader must do and what CI
will and will not tell them; it does not describe the workflow's steps, name its
inputs, or quote its messages.

What was cut

The false-bound paragraph, in full — see above for why. Everything it
asserted about max-codegen-passes, the default of 5, and a
did not reach a fixed point failure is gone rather than hedged.

An earlier paragraph, cut on the previous push and confirmed still cut
through this merge:

One run settles it here: CodeGennable imports nothing from src/generated/,
so its codehash does not move when the file recording it is rewritten. A
consumer whose contracts import what they generate has no such guarantee, and
locally has only git status to tell it that a run changed nothing — repeat
until it does.

Every noun in it is gone: #138 deleted script/Build.sol,
src/generated/CodeGennable.sol and build-pointers.yaml. A plain git merge
does not cut it — its anchor was deleted, so git reattaches it silently to
whatever paragraph now precedes that line. It was removed by hand, and the
merged tree here was diffed against main to confirm it stayed removed.

The blocked-on-rainix#319 banner, because the PR no longer claims anything
#319 would make true.

QA

The README named the regeneration cycle and left the loop unbounded prose, so
"several times until they reach a fixed point" gave a reader no way to tell a
tree that is behind from a cycle that will never settle, and no number at which
to stop trying. It now states the bound CI applies, names the two distinct
failures and their distinct fixes, and says what this repo's own example does —
one pass, because CodeGennable imports nothing it generates.
Closes#81
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@thedavidmeisterthedavidmeister self-assigned this Aug 16, 2026
@coderabbitai

coderabbitaiBot commented Aug 16, 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:16 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 @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: 16ee1008-5cb9-4d13-8662-a0f4195dc755

📥 Commits

Reviewing files that changed from the base of the PR and between c816251 and 0bba9fa.

📒 Files selected for processing (1)
  • README.md

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.

thedavidmeisterand others added 2 commits August 17, 2026 03:40
`main` no longer carries `script/Build.sol` or the committed
`src/generated/CodeGennable.sol` artifact, so the "One run settles it here"
paragraph had nothing left to be about: there is no local regeneration step in
this repo and no `CodeGennable` artifact whose codehash could move.
The `max-codegen-passes` paragraph is about rainix's reusable, which consumers
still run, and is kept unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
thedavidmeisterand others added 2 commits August 17, 2026 04:52
The paragraph this branch added documented a `max-codegen-passes` bound, a
default of 5 and a `did not reach a fixed point` failure. None of them exist:
rainix at HEAD 7f223b4 runs `forge script ./script/Build.sol` exactly once
inside an `if [ -f ... ]` guard, `max-codegen-passes` has 0 hits across the
whole repo, and the only failure that step emits is `Committed artifacts are
stale`. rainlanguage/rainix#319, which would add the bound, is still open.
State what is true instead: the loop is unbounded, nothing iterates it, and the
operator regenerates until the working tree stops changing.
Written in the register #140 established for this README (closing #139):
the consequence for someone working in a consuming repo plus one link to the
workflow that owns it, not a transcription of what that workflow does.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@thedavidmeister
thedavidmeister merged commit 97c351f into mainAug 17, 2026
4 checks passed
Sign up for freeto 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.

The generation fixed point is a human loop with no bound and no diagnosis

2 participants

@thedavidmeister@claude