Skip to content

test: mutation-harden LibOpConditions coverage - #536

Merged
thedavidmeister merged 40 commits into
mainfrom
2026-06-15-libop-coverage
Sep 7, 2026
Merged

thedavidmeister merged 40 commits into
mainfrom
2026-06-15-libop-coverage

Conversation

@thedavidmeister

Copy link
Copy Markdown
Contributor

Summary

Scoped adversarial mutation-testing pass on LibOpConditions (src/lib/op/logic/LibOpConditions.sol). Tests-only; no source changes. git diff src/ is empty.

LibOpConditions returns the value of the first nonzero condition in a pairwise condition/value list; if the input count is odd the trailing input is an error-reason string used when no condition is met. Its run has subtle odd/even handling (loop range, output placement, reason read, and a no-match revert).

Mutation matrix

Mutated each behavior in LibOpConditions.sol, ran LibOpConditionsTest, recorded SURVIVED/KILLED, restored after each.

# Mutation Before After
I1 integrity min-inputs floor KILLED KILLED
I2 integrity > 2 boundary KILLED KILLED
R1 oddInputs := mod(inputs, 2) → mod(inputs, 3) KILLED KILLED
R2 end calc drops oddInputs (includes reason slot in loop) SURVIVED KILLED
R3 odd-input output placement sub(end, iszero(odd)*0x20) → sub(end, 0x20) SURVIVED KILLED
R4 output placement → end KILLED KILLED
R5 reason read mload(end) → mload(cursor) KILLED KILLED
R6 store condition instead of value KILLED KILLED
R7 pairwise stride +0x40 → +0x20 KILLED KILLED
R8 condition test !isZero → isZero KILLED KILLED
R9 remove no-match revert guard (if (conditionIsZero) → if (false)) SURVIVED KILLED

8/11 killed by the existing suite. The three survivors all hid in the odd-input (reason-carrying) paths:

  • The reference-check fuzz test (testOpConditionsRun) truncates odd inputs to even, so the odd-input success path was never asserted — R2 and R3 hid there.
  • The no-match revert tests route through opReferenceCheck, whose reference implementation also reverts, masking a missing revert in run itself — R9 hid there.

New tests (all pass clean on baseline; each fails under its target mutant)

  • testOpConditionsEval3InputsTrueOddReason / testOpConditionsEval5InputsSecondTrueOddReason — eval of conditions with an odd input count where a condition is met; assert the matched value, trailing reason ignored. (kills R2)
  • testOpConditionsRunOddMatchStackTopPlacement — direct run() call asserting the output stack-top pointer (words consumed), not just the value, for an odd-input match. (kills R3)
  • testOpConditionsRunRevertsNoMatchEven / testOpConditionsRunRevertsNoMatchOddReason — call run() in isolation (new runExternal wrapper, no reference fn) and assert it reverts with the correct reason (empty for even, trailing reason for odd). (kills R9)

Remaining-gaps checklist

  • integrity in/out counts (fuzzed, existing)
  • run-vs-reference value (fuzzed, existing) + odd-input success value (new)
  • pairwise stride / condition test / value-vs-condition store (existing)
  • odd-input loop range and output placement (new)
  • no-condition-met revert, isolated from the reference fn, even + odd reason (new)
  • bad inputs / bad outputs / operand-disallowed (existing)

Verification

  • forge build: Compiler run successful (the boolean-cst lint warnings are pre-existing, unrelated to this diff).
  • forge fmt --check on the test file: clean.
  • LibOpConditionsTest: 20 passed, 0 failed.
  • Full logic-op suite subset (test/src/lib/op/logic/*): 181 passed, 0 failed.
  • No .gas-snapshot change (no new opcode / bytecode change), so no regen needed.

Conflict-avoidance with #535

Touches only test/src/lib/op/logic/LibOpConditions.t.sol. No overlap with #535's files (LibAllStandardOps.sol, LibOpPi.sol, src/generated/*.pointers.sol, parse-meta, LibOpE/LibOpPi). No .gas-snapshot edit.

🤖 Generated with Claude Code

Adversarial mutation testing of LibOpConditions surfaced three surviving
mutants, all in the odd-input (reason-carrying) code paths:

- end calc that ignores oddInputs (reason slot included in the loop range)
- output placement for odd inputs (sub(end, 0x20) instead of end)
- removal of the no-condition-met revert guard

The existing reference-check fuzz test truncates odd inputs to even, so the
odd-input success path was never asserted, and the no-condition-met revert was
masked by the reference implementation's own revert.

Add discriminating tests:
- eval of conditions with an odd number of inputs where a condition is met,
  asserting the matched value (3-input and 5-input cases)
- a direct run() call asserting the output stack-top placement for an odd-input
  match (pointer, not just value)
- direct run() revert tests (isolated from the reference implementation) for
  the no-condition-met case, both even (empty reason) and odd (trailing reason)

Tests-only; no source changes. All three mutants are now killed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@thedavidmeister thedavidmeister self-assigned this Jun 15, 2026
@coderabbitai

coderabbitai Bot commented Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 394 files, which is 294 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

Usage-priced reviews support at most 300 files.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 75909911-34d5-4b36-8460-2ac4aadbee13

📥 Commits

Reviewing files that changed from the base of the PR and between a6b7ad7 and 1addc75.

⛔ Files ignored due to path filters (13)
  • CLAUDE.md is excluded by !CLAUDE.md
  • Cargo.lock is excluded by !**/*.lock
  • soldeer.lock is excluded by !**/*.lock
  • src/generated/0_1_9/Rainlang.sol is excluded by !**/generated/**
  • src/generated/0_1_9/RainlangExpressionDeployer.sol is excluded by !**/generated/**
  • src/generated/0_1_9/RainlangInterpreter.sol is excluded by !**/generated/**
  • src/generated/0_1_9/RainlangParser.sol is excluded by !**/generated/**
  • src/generated/0_1_9/RainlangStore.sol is excluded by !**/generated/**
  • src/generated/Rainlang.pointers.sol is excluded by !**/generated/**
  • src/generated/RainlangExpressionDeployer.pointers.sol is excluded by !**/generated/**
  • src/generated/RainlangParser.pointers.sol is excluded by !**/generated/**
  • src/generated/RainlangReferenceExtern.pointers.sol is excluded by !**/generated/**
  • src/generated/RainlangReferenceExternPointers.sol is excluded by !**/generated/**
📒 Files selected for processing (394)
  • .cargo/config.toml
  • .gas-snapshot
  • .github/workflows/copy-artifacts.yaml
  • .github/workflows/git-clean.yaml
  • .github/workflows/manual-sol-artifacts.yaml
  • .github/workflows/package-release.yaml
  • .github/workflows/rainix-rs-static.yaml
  • .github/workflows/rainix-rs-test.yaml
  • .prettierignore
  • .soldeerignore
  • Cargo.toml
  • README.md
  • REUSE.toml
  • crates/bindings/Cargo.toml
  • crates/bindings/abi/IExpressionDeployerV3.json
  • crates/bindings/abi/IInterpreterStoreV3.json
  • crates/bindings/abi/IInterpreterV4.json
  • crates/bindings/abi/IParserPragmaV1.json
  • crates/bindings/abi/IParserV2.json
  • crates/bindings/abi/Rainlang.json
  • crates/bindings/src/lib.rs
  • crates/cli/Cargo.toml
  • crates/cli/src/commands/eval.rs
  • crates/cli/src/commands/mod.rs
  • crates/cli/src/commands/parse.rs
  • crates/cli/src/execute.rs
  • crates/cli/src/fork.rs
  • crates/cli/src/lib.rs
  • crates/cli/src/main.rs
  • crates/cli/src/output.rs
  • crates/dispair/Cargo.toml
  • crates/dispair/src/lib.rs
  • crates/eval/Cargo.toml
  • crates/eval/src/error.rs
  • crates/eval/src/eval.rs
  • crates/eval/src/fork.rs
  • crates/eval/src/lib.rs
  • crates/eval/src/namespace.rs
  • crates/eval/src/trace.rs
  • crates/parser/Cargo.toml
  • crates/parser/src/error.rs
  • crates/parser/src/lib.rs
  • crates/parser/src/v2.rs
  • crates/test_fixtures/Cargo.toml
  • crates/test_fixtures/abi/Rainlang.json
  • crates/test_fixtures/abi/RainlangExpressionDeployer.json
  • crates/test_fixtures/abi/RainlangInterpreter.json
  • crates/test_fixtures/abi/RainlangParser.json
  • crates/test_fixtures/abi/RainlangStore.json
  • crates/test_fixtures/abi/TestERC20.json
  • crates/test_fixtures/src/lib.rs
  • flake.nix
  • foundry.toml
  • meta/AuthoringMeta.rain.meta
  • meta/RainlangExpressionDeployer.rain.meta
  • remappings.txt
  • script/Build.sol
  • script/BuildAuthoringMeta.sol
  • script/CopyArtifacts.sol
  • script/Deploy.sol
  • script/lib/LibCopyArtifacts.sol
  • slither.config.json
  • src/abstract/BaseRainlang.sol
  • src/abstract/BaseRainlangExpressionDeployer.sol
  • src/abstract/BaseRainlangExtern.sol
  • src/abstract/BaseRainlangInterpreter.sol
  • src/abstract/BaseRainlangParser.sol
  • src/abstract/BaseRainlangStore.sol
  • src/abstract/BaseRainlangSubParser.sol
  • src/concrete/Rainlang.sol
  • src/concrete/extern/RainlangReferenceExtern.sol
  • src/error/ErrExtern.sol
  • src/lib/deploy/LibInterpreterDeploy.sol
  • src/lib/eval/LibEval.sol
  • src/lib/extern/LibExtern.sol
  • src/lib/extern/reference/op/LibExternOpContextCallingContract.sol
  • src/lib/extern/reference/op/LibExternOpContextRainlen.sol
  • src/lib/extern/reference/op/LibExternOpContextSender.sol
  • src/lib/extern/reference/op/LibExternOpIntInc.sol
  • src/lib/extern/reference/op/LibExternOpStackOperand.sol
  • src/lib/integrity/LibIntegrityCheck.sol
  • src/lib/op/00/LibOpConstant.sol
  • src/lib/op/00/LibOpContext.sol
  • src/lib/op/00/LibOpExtern.sol
  • src/lib/op/00/LibOpStack.sol
  • src/lib/op/LibAllStandardOps.sol
  • src/lib/op/bitwise/LibOpBitwiseAnd.sol
  • src/lib/op/bitwise/LibOpBitwiseCountOnes.sol
  • src/lib/op/bitwise/LibOpBitwiseDecode.sol
  • src/lib/op/bitwise/LibOpBitwiseEncode.sol
  • src/lib/op/bitwise/LibOpBitwiseOr.sol
  • src/lib/op/bitwise/LibOpBitwiseShiftLeft.sol
  • src/lib/op/bitwise/LibOpBitwiseShiftRight.sol
  • src/lib/op/call/LibOpCall.sol
  • src/lib/op/crypto/LibOpHash.sol
  • src/lib/op/erc20/LibOpERC20Allowance.sol
  • src/lib/op/erc20/LibOpERC20BalanceOf.sol
  • src/lib/op/erc20/LibOpERC20TotalSupply.sol
  • src/lib/op/erc20/uint256/LibOpUint256ERC20Allowance.sol
  • src/lib/op/erc20/uint256/LibOpUint256ERC20BalanceOf.sol
  • src/lib/op/erc20/uint256/LibOpUint256ERC20TotalSupply.sol
  • src/lib/op/erc5313/LibOpERC5313Owner.sol
  • src/lib/op/erc721/LibOpERC721BalanceOf.sol
  • src/lib/op/erc721/LibOpERC721OwnerOf.sol
  • src/lib/op/erc721/uint256/LibOpUint256ERC721BalanceOf.sol
  • src/lib/op/evm/LibOpBlockNumber.sol
  • src/lib/op/evm/LibOpBlockTimestamp.sol
  • src/lib/op/evm/LibOpChainId.sol
  • src/lib/op/logic/LibOpAny.sol
  • src/lib/op/logic/LibOpBinaryEqualTo.sol
  • src/lib/op/logic/LibOpConditions.sol
  • src/lib/op/logic/LibOpEnsure.sol
  • src/lib/op/logic/LibOpEqualTo.sol
  • src/lib/op/logic/LibOpEvery.sol
  • src/lib/op/logic/LibOpGreaterThan.sol
  • src/lib/op/logic/LibOpGreaterThanOrEqualTo.sol
  • src/lib/op/logic/LibOpIf.sol
  • src/lib/op/logic/LibOpIsZero.sol
  • src/lib/op/logic/LibOpLessThan.sol
  • src/lib/op/logic/LibOpLessThanOrEqualTo.sol
  • src/lib/op/math/LibOpAbs.sol
  • src/lib/op/math/LibOpAdd.sol
  • src/lib/op/math/LibOpAvg.sol
  • src/lib/op/math/LibOpCeil.sol
  • src/lib/op/math/LibOpDiv.sol
  • src/lib/op/math/LibOpE.sol
  • src/lib/op/math/LibOpExp.sol
  • src/lib/op/math/LibOpExp2.sol
  • src/lib/op/math/LibOpFloor.sol
  • src/lib/op/math/LibOpFrac.sol
  • src/lib/op/math/LibOpGm.sol
  • src/lib/op/math/LibOpHeadroom.sol
  • src/lib/op/math/LibOpInv.sol
  • src/lib/op/math/LibOpMax.sol
  • src/lib/op/math/LibOpMaxNegativeValue.sol
  • src/lib/op/math/LibOpMaxPositiveValue.sol
  • src/lib/op/math/LibOpMin.sol
  • src/lib/op/math/LibOpMinNegativeValue.sol
  • src/lib/op/math/LibOpMinPositiveValue.sol
  • src/lib/op/math/LibOpMul.sol
  • src/lib/op/math/LibOpPower.sol
  • src/lib/op/math/LibOpSqrt.sol
  • src/lib/op/math/LibOpSub.sol
  • src/lib/op/math/growth/LibOpExponentialGrowth.sol
  • src/lib/op/math/growth/LibOpLinearGrowth.sol
  • src/lib/op/math/uint256/LibOpUint256Add.sol
  • src/lib/op/math/uint256/LibOpUint256Div.sol
  • src/lib/op/math/uint256/LibOpUint256MaxValue.sol
  • src/lib/op/math/uint256/LibOpUint256Mul.sol
  • src/lib/op/math/uint256/LibOpUint256Power.sol
  • src/lib/op/math/uint256/LibOpUint256Sub.sol
  • src/lib/op/store/LibOpGet.sol
  • src/lib/op/store/LibOpSet.sol
  • src/lib/parse/LibParse.sol
  • src/lib/parse/LibParseOperand.sol
  • src/lib/parse/LibParseState.sol
  • src/lib/parse/LibSubParse.sol
  • src/lib/state/LibInterpreterState.sol
  • src/lib/state/LibInterpreterStateDataContract.sol
  • test/abstract/OpTest.sol
  • test/abstract/OperandTest.sol
  • test/abstract/ParseLiteralTest.sol
  • test/abstract/ParseTest.sol
  • test/abstract/RainlangExpressionDeployerDeploymentTest.sol
  • test/concrete/TestRainlang.sol
  • test/concrete/TestRainlangExpressionDeployer.sol
  • test/concrete/TestRainlangInterpreter.sol
  • test/concrete/TestRainlangParser.sol
  • test/concrete/TestRainlangStore.sol
  • test/lib/deploy/LibTestInterpreterDeploy.sol
  • test/lib/operand/LibOperand.sol
  • test/lib/parse/LibMetaFixture.sol
  • test/lib/string/LibCamelToKebab.t.sol
  • test/lib/typecast/LibTestCast.sol
  • test/src/abstract/BaseRainlangExtern.construction.t.sol
  • test/src/abstract/BaseRainlangExtern.ierc165.t.sol
  • test/src/abstract/BaseRainlangExtern.integrityOpcodeRange.t.sol
  • test/src/abstract/BaseRainlangSubParser.ierc165.t.sol
  • test/src/abstract/BaseRainlangSubParser.subParseLiteral2.t.sol
  • test/src/abstract/BaseRainlangSubParser.subParseWord2.t.sol
  • test/src/abstract/EmptyWordParsersSubParser.sol
  • test/src/abstract/MismatchedWordSubParser.sol
  • test/src/concrete/ModifierTestParser.sol
  • test/src/concrete/Rainlang.ierc165.t.sol
  • test/src/concrete/Rainlang.t.sol
  • test/src/concrete/RainlangExpressionDeployer.deployCheck.t.sol
  • test/src/concrete/RainlangExpressionDeployer.describedByMetaV1.t.sol
  • test/src/concrete/RainlangExpressionDeployer.ierc165.t.sol
  • test/src/concrete/RainlangExpressionDeployer.meta.t.sol
  • test/src/concrete/RainlangExpressionDeployer.parse2.t.sol
  • test/src/concrete/RainlangExpressionDeployer.parsePragma1.t.sol
  • test/src/concrete/RainlangExpressionDeployer.pointers.t.sol
  • test/src/concrete/RainlangInterpreter.eval.nonZeroSourceIndex.t.sol
  • test/src/concrete/RainlangInterpreter.eval.t.sol
  • test/src/concrete/RainlangInterpreter.extrospect.t.sol
  • test/src/concrete/RainlangInterpreter.ierc165.t.sol
  • test/src/concrete/RainlangInterpreter.pointers.t.sol
  • test/src/concrete/RainlangInterpreter.stateOverlay.t.sol
  • test/src/concrete/RainlangInterpreter.t.sol
  • test/src/concrete/RainlangInterpreter.zeroFunctionPointers.t.sol
  • test/src/concrete/RainlangParser.ierc165.t.sol
  • test/src/concrete/RainlangParser.parseMemoryOverflow.t.sol
  • test/src/concrete/RainlangParser.parsePragmaEmpty.t.sol
  • test/src/concrete/RainlangParser.parserPragma.t.sol
  • test/src/concrete/RainlangParser.pointers.t.sol
  • test/src/concrete/RainlangParser.unsafeParse.t.sol
  • test/src/concrete/RainlangReferenceExtern.bytecode.t.sol
  • test/src/concrete/RainlangReferenceExtern.contextRainlen.t.sol
  • test/src/concrete/RainlangReferenceExtern.describedByMetaV1.t.sol
  • test/src/concrete/RainlangReferenceExtern.ierc165.t.sol
  • test/src/concrete/RainlangReferenceExtern.intInc.t.sol
  • test/src/concrete/RainlangReferenceExtern.pointers.t.sol
  • test/src/concrete/RainlangReferenceExtern.subParserIndexOutOfBounds.t.sol
  • test/src/concrete/RainlangStore.getUninitialized.t.sol
  • test/src/concrete/RainlangStore.ierc165.t.sol
  • test/src/concrete/RainlangStore.namespaceIsolation.t.sol
  • test/src/concrete/RainlangStore.overwriteKey.t.sol
  • test/src/concrete/RainlangStore.setEmpty.t.sol
  • test/src/concrete/RainlangStore.setEvent.t.sol
  • test/src/concrete/RainlangStore.t.sol
  • test/src/concrete/ZeroFPRainlangInterpreter.sol
  • test/src/lib/deploy/LibInterpreterDeploy.t.sol
  • test/src/lib/deploy/LibInterpreterDeployProd.t.sol
  • test/src/lib/eval/LibEval.fBounds.t.sol
  • test/src/lib/eval/LibEval.inputsLengthMismatch.t.sol
  • test/src/lib/eval/LibEval.maxOutputs.t.sol
  • test/src/lib/eval/LibEval.multipleSource.t.sol
  • test/src/lib/eval/LibEval.opcodeCountEdgeCases.t.sol
  • test/src/lib/eval/LibEval.remainderOnly.t.sol
  • test/src/lib/extern/LibExtern.codec.t.sol
  • test/src/lib/extern/reference/literal/LibParseLiteralRepeat.t.sol
  • test/src/lib/extern/reference/op/LibExternOpContextCallingContract.subParser.t.sol
  • test/src/lib/extern/reference/op/LibExternOpContextRainlen.subParser.t.sol
  • test/src/lib/extern/reference/op/LibExternOpContextSender.subParser.t.sol
  • test/src/lib/extern/reference/op/LibExternOpStackOperand.subParser.t.sol
  • test/src/lib/integrity/IntegrityHighwater.sol
  • test/src/lib/integrity/IntegritySingleOp.sol
  • test/src/lib/integrity/LibIntegrityCheck.badOpIO.t.sol
  • test/src/lib/integrity/LibIntegrityCheck.multiSource.t.sol
  • test/src/lib/integrity/LibIntegrityCheck.newState.t.sol
  • test/src/lib/integrity/LibIntegrityCheck.stackMaxIndex.t.sol
  • test/src/lib/integrity/LibIntegrityCheck.t.sol
  • test/src/lib/integrity/LibIntegrityCheck.zeroSource.t.sol
  • test/src/lib/op/00/LibOpConstant.t.sol
  • test/src/lib/op/00/LibOpContext.t.sol
  • test/src/lib/op/00/LibOpExtern.t.sol
  • test/src/lib/op/00/LibOpStack.t.sol
  • test/src/lib/op/LibAllStandardOps.filesystemOrdering.t.sol
  • test/src/lib/op/LibAllStandardOps.t.sol
  • test/src/lib/op/bitwise/LibOpBitwiseAnd.t.sol
  • test/src/lib/op/bitwise/LibOpBitwiseCountOnes.t.sol
  • test/src/lib/op/bitwise/LibOpBitwiseDecode.t.sol
  • test/src/lib/op/bitwise/LibOpBitwiseEncode.t.sol
  • test/src/lib/op/bitwise/LibOpBitwiseOr.t.sol
  • test/src/lib/op/bitwise/LibOpBitwiseShiftLeft.t.sol
  • test/src/lib/op/bitwise/LibOpBitwiseShiftRight.t.sol
  • test/src/lib/op/call/LibOpCall.t.sol
  • test/src/lib/op/crypto/LibOpHash.t.sol
  • test/src/lib/op/erc20/LibOpERC20Allowance.t.sol
  • test/src/lib/op/erc20/LibOpERC20BalanceOf.t.sol
  • test/src/lib/op/erc20/LibOpERC20TotalSupply.t.sol
  • test/src/lib/op/erc20/uint256/LibOpUint256ERC20Allowance.t.sol
  • test/src/lib/op/erc20/uint256/LibOpUint256ERC20BalanceOf.t.sol
  • test/src/lib/op/erc20/uint256/LibOpUint256ERC20TotalSupply.t.sol
  • test/src/lib/op/erc5313/LibOpERC5313Owner.t.sol
  • test/src/lib/op/erc721/LibOpERC721BalanceOf.t.sol
  • test/src/lib/op/erc721/LibOpERC721OwnerOf.t.sol
  • test/src/lib/op/erc721/uint256/LibOpUint256ERC721BalanceOf.t.sol
  • test/src/lib/op/evm/LibOpBlockNumber.t.sol
  • test/src/lib/op/evm/LibOpBlockTimestamp.t.sol
  • test/src/lib/op/evm/LibOpChainId.t.sol
  • test/src/lib/op/logic/LibOpAny.t.sol
  • test/src/lib/op/logic/LibOpBinaryEqualTo.t.sol
  • test/src/lib/op/logic/LibOpConditions.t.sol
  • test/src/lib/op/logic/LibOpEnsure.t.sol
  • test/src/lib/op/logic/LibOpEqualTo.t.sol
  • test/src/lib/op/logic/LibOpEvery.t.sol
  • test/src/lib/op/logic/LibOpGreaterThan.t.sol
  • test/src/lib/op/logic/LibOpGreaterThanOrEqualTo.t.sol
  • test/src/lib/op/logic/LibOpIf.t.sol
  • test/src/lib/op/logic/LibOpIsZero.t.sol
  • test/src/lib/op/logic/LibOpLessThan.t.sol
  • test/src/lib/op/logic/LibOpLessThanOrEqualTo.t.sol
  • test/src/lib/op/math/LibOpAbs.t.sol
  • test/src/lib/op/math/LibOpAdd.t.sol
  • test/src/lib/op/math/LibOpAvg.t.sol
  • test/src/lib/op/math/LibOpCeil.t.sol
  • test/src/lib/op/math/LibOpDiv.t.sol
  • test/src/lib/op/math/LibOpE.t.sol
  • test/src/lib/op/math/LibOpExp.t.sol
  • test/src/lib/op/math/LibOpExp2.t.sol
  • test/src/lib/op/math/LibOpFloor.t.sol
  • test/src/lib/op/math/LibOpFrac.t.sol
  • test/src/lib/op/math/LibOpGm.t.sol
  • test/src/lib/op/math/LibOpHeadroom.t.sol
  • test/src/lib/op/math/LibOpInv.t.sol
  • test/src/lib/op/math/LibOpMax.t.sol
  • test/src/lib/op/math/LibOpMaxNegativeValue.t.sol
  • test/src/lib/op/math/LibOpMaxPositiveValue.t.sol
  • test/src/lib/op/math/LibOpMin.t.sol
  • test/src/lib/op/math/LibOpMinNegativeValue.t.sol
  • test/src/lib/op/math/LibOpMinPositiveValue.t.sol
  • test/src/lib/op/math/LibOpMul.t.sol
  • test/src/lib/op/math/LibOpPower.t.sol
  • test/src/lib/op/math/LibOpSqrt.t.sol
  • test/src/lib/op/math/LibOpSub.t.sol
  • test/src/lib/op/math/growth/LibOpExponentialGrowth.t.sol
  • test/src/lib/op/math/growth/LibOpLinearGrowth.t.sol
  • test/src/lib/op/math/uint256/LibOpUint256Add.t.sol
  • test/src/lib/op/math/uint256/LibOpUint256Div.t.sol
  • test/src/lib/op/math/uint256/LibOpUint256MaxValue.t.sol
  • test/src/lib/op/math/uint256/LibOpUint256Mul.t.sol
  • test/src/lib/op/math/uint256/LibOpUint256Power.t.sol
  • test/src/lib/op/math/uint256/LibOpUint256Sub.t.sol
  • test/src/lib/op/store/LibOpGet.t.sol
  • test/src/lib/op/store/LibOpSet.t.sol
  • test/src/lib/parse/BadLengthSubParser.sol
  • test/src/lib/parse/ConstantReturningSubParser.sol
  • test/src/lib/parse/ContextReturningSubParser.sol
  • test/src/lib/parse/LibParse.comments.t.sol
  • test/src/lib/parse/LibParse.empty.gas.t.sol
  • test/src/lib/parse/LibParse.empty.t.sol
  • test/src/lib/parse/LibParse.ignoredLHS.t.sol
  • test/src/lib/parse/LibParse.inputsOnly.gas.t.sol
  • test/src/lib/parse/LibParse.inputsOnly.t.sol
  • test/src/lib/parse/LibParse.lhsOverflow.t.sol
  • test/src/lib/parse/LibParse.literalIntegerDecimal.t.sol
  • test/src/lib/parse/LibParse.literalIntegerHex.t.sol
  • test/src/lib/parse/LibParse.literalString.t.sol
  • test/src/lib/parse/LibParse.nOutput.t.sol
  • test/src/lib/parse/LibParse.namedLHS.t.sol
  • test/src/lib/parse/LibParse.parseMemoryOverflow.t.sol
  • test/src/lib/parse/LibParse.parseWord.t.sol
  • test/src/lib/parse/LibParse.singleIgnored.gas.t.sol
  • test/src/lib/parse/LibParse.singleLHSNamed.gas.t.sol
  • test/src/lib/parse/LibParse.singleRHSNamed.gas.t.sol
  • test/src/lib/parse/LibParse.sourceInputs.t.sol
  • test/src/lib/parse/LibParse.unexpectedRightParen.t.sol
  • test/src/lib/parse/LibParse.wordsRHS.t.sol
  • test/src/lib/parse/LibParseError.t.sol
  • test/src/lib/parse/LibParseInterstitial.t.sol
  • test/src/lib/parse/LibParseOperand.handleOperand.t.sol
  • test/src/lib/parse/LibParseOperand.handleOperand8M1M1.t.sol
  • test/src/lib/parse/LibParseOperand.handleOperandDisallowed.t.sol
  • test/src/lib/parse/LibParseOperand.handleOperandDisallowedAlwaysOne.t.sol
  • test/src/lib/parse/LibParseOperand.handleOperandDoublePerByteNoDefault.t.sol
  • test/src/lib/parse/LibParseOperand.handleOperandM1M1.t.sol
  • test/src/lib/parse/LibParseOperand.handleOperandSingleFull.t.sol
  • test/src/lib/parse/LibParseOperand.handleOperandSingleFullNoDefault.t.sol
  • test/src/lib/parse/LibParseOperand.parseOperand.t.sol
  • test/src/lib/parse/LibParsePragma.keyword.t.sol
  • test/src/lib/parse/LibParseStackName.t.sol
  • test/src/lib/parse/LibParseStackTracker.t.sol
  • test/src/lib/parse/LibParseState.buildBytecode.t.sol
  • test/src/lib/parse/LibParseState.buildConstants.t.sol
  • test/src/lib/parse/LibParseState.checkParseMemoryOverflow.t.sol
  • test/src/lib/parse/LibParseState.constantValueBloom.t.sol
  • test/src/lib/parse/LibParseState.danglingSource.t.sol
  • test/src/lib/parse/LibParseState.endLine.unboundedLHS.t.sol
  • test/src/lib/parse/LibParseState.endSource.t.sol
  • test/src/lib/parse/LibParseState.exportSubParsers.t.sol
  • test/src/lib/parse/LibParseState.highwaterOverflow.t.sol
  • test/src/lib/parse/LibParseState.newActiveSourcePointer.t.sol
  • test/src/lib/parse/LibParseState.offsets.t.sol
  • test/src/lib/parse/LibParseState.parenInputOverflow.t.sol
  • test/src/lib/parse/LibParseState.pushConstantValue.t.sol
  • test/src/lib/parse/LibParseState.pushLiteral.t.sol
  • test/src/lib/parse/LibParseState.pushOpToSource.LHSCorruption.t.sol
  • test/src/lib/parse/LibParseState.pushOpToSource.t.sol
  • test/src/lib/parse/LibParseState.pushOpToSourceLHSCorruption.t.sol
  • test/src/lib/parse/LibParseState.pushSubParser.largeMemory.t.sol
  • test/src/lib/parse/LibParseState.pushSubParser.t.sol
  • test/src/lib/parse/LibSubParse.constantAccumulation.t.sol
  • test/src/lib/parse/LibSubParse.consumeSubParseLiteralInputData.t.sol
  • test/src/lib/parse/LibSubParse.consumeSubParseWordInputData.t.sol
  • test/src/lib/parse/LibSubParse.subParseLiteral.t.sol
  • test/src/lib/parse/LibSubParse.subParseWords.t.sol
  • test/src/lib/parse/LibSubParse.subParserConstant.t.sol
  • test/src/lib/parse/LibSubParse.subParserContext.t.sol
  • test/src/lib/parse/LibSubParse.subParserExtern.t.sol
  • test/src/lib/parse/LibSubParse.unknownWord.t.sol
  • test/src/lib/parse/MultiConstantSubParser.sol
  • test/src/lib/parse/literal/LibParseLiteral.dispatch.t.sol
  • test/src/lib/parse/literal/LibParseLiteral.selectByIndex.t.sol
  • test/src/lib/parse/literal/LibParseLiteralDecimal.parseDecimalFloat.t.sol
  • test/src/lib/parse/literal/LibParseLiteralHex.parseHex.t.sol
  • test/src/lib/parse/literal/LibParseLiteralString.boundString.t.sol
  • test/src/lib/parse/literal/LibParseLiteralString.parseString.t.sol
  • test/src/lib/parse/literal/LibParseLiteralSubParseable.parseSubParseable.t.sol
  • test/src/lib/state/LibInterpreterState.fingerprint.t.sol
  • test/src/lib/state/LibInterpreterState.stackBottoms.t.sol
  • test/src/lib/state/LibInterpreterState.stackTrace.t.sol
  • test/src/lib/state/LibInterpreterStateDataContract.t.sol
  • test/src/lib/state/LibInterpreterStateDataContractExtern.sol

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 2026-06-15-libop-coverage

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

🤖 ai:producer
Producer note: MAIN-STATE red, not PR-caused — the only failures on rainix-sol / test (run 28749053268) are the 5 testProdDeploy* 'Interpreter not deployed' prod-pins; main fails identically (run 28658876491, 2026-07-03). This PR is tests-only (src/ diff empty), so nothing here can move the pins; it greens when main's pending interpreter deploy lands. No empty-commit retrigger pushed — a re-run reproduces the same pins.

@thedavidmeister thedavidmeister added the ai:ready AI vetter: passes review, ready for human decision label Jul 6, 2026
@thedavidmeister

thedavidmeister commented Jul 7, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 ai:vetter
Reviewed 655a02b: ready — re-vet after merge-main-only commit, 5 discriminating tests killing mutants R2 R3 R9 unchanged, runE
cost 330 — tests-only, assembly op stack semantics

@thedavidmeister thedavidmeister added ai:blocked-deploy and removed ai:ready AI vetter: passes review, ready for human decision labels Jul 12, 2026
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

🤖 ai:producer
Blocked-deploy: Blocked on the same failed interpreter deploy as #534 (see its ai:blocked-deploy note): rainix-sol test red is main-state prod pins ('Interpreter not deployed' ×5 networks), no branch fix possible from this test-only PR. Deployer EOA 0x6698…9a88 unfunded on flare (0 FLR) / underfunded on polygon; greens when the funded re-dispatch of suite=interpreter lands.

@thedavidmeister

Copy link
Copy Markdown
Contributor Author

👤 human
Ruled 655a02b: reject — executing the 2026-08-06 ruling in rainlanguage/issue-pr-cron#221 — the retired ai:blocked-deploy residue (#162) migrates to ai:reject for rework to the split release lifecycle

@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Rework note @655a02b46c65ba0d61b03119dc7ac57236437b5c: rework the PR to fit the split release lifecycle — deploys never gate merges (the deploy-before-merge choreography is superseded); remove or restructure anything in the PR that waits on a deploy; where deploy constants/pins are involved, follow the *.deploy repo convention (audited code only; version ↔ snapshot ↔ pins internally consistent; tag-release lifecycle). Whatever states follow the rework (including a typed blocked-on the repo's migration if one is genuinely needed) are the producer's ordinary transitions. Executes the 2026-08-06 ruling: rainlanguage/issue-pr-cron#221

@thedavidmeister thedavidmeister added ai:needs-work Needs rework — the producer's inbox (vetter verdict or human ruling) and removed ai:blocked-deploy labels Aug 6, 2026
thedavidmeister and others added 11 commits August 15, 2026 07:46
`.soldeerignore` is a publish filter, not a description of the tree, so an
entry naming a file that is absent today is normally a forward-looking rule
worth keeping. These three are not: they are tied to a dependency mechanism
this repo no longer uses and cannot go back to.

- `.gitmodules` and `/lib` are the git-submodule vendoring layout. Rainix CI
  runs a `no-submodules` check that fails on a root `.gitmodules` or any
  committed gitlink, so no future commit can reintroduce either path for
  these entries to filter.
- `/foundry.lock` is Foundry's git-submodule lockfile — it pins the commit of
  each dependency vendored under `lib/` so `forge install` / `forge update`
  can restore identical revisions. It is only meaningful alongside that same
  banned layout. `soldeer.lock` is the live lockfile here and everything
  lands under `dependencies/`, because `foundry.toml` sets
  `libs = ['dependencies']`.

Every other entry is left alone, including the ones absent from a clean
checkout by design (`.DS_Store`, `/deployments`) — those are OS junk and
build output that IS present when `soldeer push` runs, so they still filter.

`forge soldeer push --dry-run` packs a byte-identical 525-entry set before
and after this change.

Closes #553

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
main landed the same test refactor this branch carried in 44fab0c
("[3b-attempt] test: one contract per file") via #549 (b051c94,
6bc2663). Every extracted helper this branch added now exists on main,
so the branch's copy is superseded: the four conflicting files
(BaseRainlangSubParser.subParseLiteral2.t.sol, MismatchedLiteralSubParser.sol,
NoMatchLiteralSubParser.sol, ZeroFPRainlangInterpreter.sol) resolve to
main's version.

No test is dropped: after this merge the branch differs from main by
exactly test/src/lib/op/logic/LibOpConditions.t.sol (+96), which is the
mutation-hardening this PR is about.
recursive_deps=false means vendored dep src resolves through this repo's
remappings, and three reachable deps hard-pin rain-solmem-0.1.3/ in src,
so the bump carries its minimum chain to keep one solmem tree:

- rain-solmem 0.1.3 -> 0.1.26
- rain-interpreter-interface 0.1.0 (orphaned name) -> rainlang-interface
  0.2.5 (successor package; src delta vs 0.1.0 is only the solmem and
  rain-math-binary import pins)
- rain-datacontract 0.1.0 -> 0.1.3
- rain-extrospection 0.1.1 -> 0.1.13
- rain-math-binary 0.1.1 -> 0.1.4 (required by rainlang-interface 0.2.x)

solmem 0.1.26 deleted LibStackPointer; its only two rainlang imports were
dead (using-directive never invoked) and are removed, not substituted.

Regenerated src/generated pointers to fixpoint via script/Build.sol:
RainlangParser, RainlangExpressionDeployer and Rainlang bytecode moved
(solmem LibBytes32Array codegen changes plus embedded address cascade);
RainlangInterpreter, RainlangStore, RainlangReferenceExtern unchanged.

Pruned stale remappings by hand (soldeer appends, never prunes),
including two pre-existing dangling lines (rain-deploy-0.1.2,
rain-extrospection-0.1.0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
copy-artifacts flagged the four committed ABI JSONs that embed the moved
bytecode (crates/bindings/abi/Rainlang.json and crates/test_fixtures/abi/
{Rainlang,RainlangExpressionDeployer,RainlangParser}.json); regenerated
via script/CopyArtifacts.sol.

rainix@main now enforces the 4096-byte agent-context cap in static and
rs-static; CLAUDE.md was 8587 bytes and failed both on every push. Cut
under the cap per the check's heuristic: kept the non-recoverable
rulings (jidoka process, NatSpec tagging, generated-pointers regen
cascade), cut what is discoverable from the repo (architecture tour,
dependency lists, command inventory).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bump rain-solmem 0.1.3 -> 0.1.26 (and the dep chain pinning it)
Adopts the org's current deploy/release machinery (rain-deploy 0.1.7) without
splitting the repo — the shape #545 describes, leaving #552 open.

- src/abstract/RainlangDeploySuites.sol is now the one declaration: five
  candidates (parser, store, interpreter, expression-deployer, rainlang) with
  their dependency lists. src/abstract/RainDeploySuitesBase.sol re-exports the
  package path the generated libs reach by relative import.
- src/generated/candidate/<Name>.sol replaces <Name>.pointers.sol for the five
  deploy candidates; the non-deploy codegen (parse meta, pointer tables,
  described-by hashes) moves to <Name>Pointers.sol. RainlangReferenceExtern is
  not a deploy candidate — the deploy script, dispatch choices and deploy lib
  all say five — so it keeps pointers only.
- script/Build.sol is a BuildScript; script/Deploy.sol is the one-line
  RainDeployBroadcast binding with no deployNetworks() override, so this repo
  targets all seven supported networks.
- package-release.yaml releases on sol-v* via rainix-tag-release; the five Rust
  crates move to their own crates-release.yaml so the two lifecycles stop
  sharing one next-version invariant.
- Chain and snapshot verification replace the hand-rolled pin tests, including
  the five LibInterpreterDeployProdTest fork tests red on main (#561): the
  standard scopes chain checks to RELEASED suites, and this repo has released
  none under the frozen-record model, so 0.1.8 stays and the record starts empty.

No pin moves: DEPLOYED_ADDRESS, BYTECODE_HASH, CREATION_CODE and RUNTIME_CODE
are byte-identical to their pre-migration values for all five candidates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The five `deps` arrays came across from `script/Deploy.sol` unchanged and
four of the five over-declared. `DeploySuite.dependencies` is what must
already have code on a network or the deployment is broken on arrival,
and `LibRainDeploy.deployToNetworks` refuses to broadcast without it, so
an address the bytecode never carries blocks the suite on every chain
that lacks it for a call that cannot happen. This PR is also what starts
writing those lists into the append-only frozen record.

Measured by scanning each candidate's creation code for each address at
the width solc emits it:

  parser              log tables               -> none
  store               log tables               -> none
  interpreter         log tables, TOFU         -> unchanged
  expression-deployer log tables, TOFU, parser,
                      store, interpreter       -> parser
  rainlang            TOFU, parser, store,
                      interpreter, deployer    -> the four siblings

No bytecode moves: only `DEPENDENCIES` in `src/generated/candidate/`.
The natspec on `expressionDeployerCandidate` claimed a reach into the
store and the interpreter that the source contradicts; corrected, along
with `rainlangCandidate`'s "facade" framing — it calls none of the four,
it publishes their addresses, which is the other half of what the struct
means.

Both directions are now asserted so neither over- nor under-declaration
can return quietly. `testCandidatesReachEveryDependencyTheyDeclare` is
the converse of `testCandidatesDependOnTheSiblingsTheyReach`;
`testCandidatesDependOnTheExternalsTheyReach` covers the log tables and
TOFU, which are not siblings and so were in neither. Both were mutation
checked: dropping the log tables from `interpreterCandidate()` fails the
second, and the pre-trim lists fail the first.

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

Migrate to the tag-driven release standard, in-repo
HyperEVM entered the network set in #563 and its RPC needs type-0
transactions; the verification retry loop can outlast the broadcast.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
It caps the window at 5 blocks rather than rejecting the call.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
thedavidmeister and others added 24 commits August 23, 2026 19:40
…inputs

Expose the deploy reusable's legacy and verify inputs
The repo's first release under the tag-driven machinery #563 migrated to.
One commit, exactly the runbook's release shape:

- foundry.toml [external.package].version 0.1.8 -> 0.1.9, in lockstep with
  the frozen record it names.
- forge script ./script/Build.sol --sig 'cutRelease()' output committed
  verbatim: src/generated/0_1_9/ (byte-identical copy of candidate/, five of
  five, verified) and the five released-suites libs regenerated from the
  record that now holds 0.1.9.

Nothing else moves. No pinned value changes: the frozen constants are the
candidate/ constants at the parent commit, and `run()` + `forge fmt` on the
parent tree was already a fixed point before the freeze.

0.1.8 is not re-cuttable and never was — it was published by the old
merge-driven autopublish and froze no record, so release-guard would reject
sol-v0.1.8 on this tree. #563 stated that; 0.1.9 is the first release the
lifecycle can carry.

Freezing arms RainlangDeployChainTest over the released record. Before this
commit releasedSuites() was empty and testSuitesLiveOnEverySupportedNetwork
early-returned on a length-0 derivation, touching no RPC; after it, the
suite forks all seven supported networks and asserts all five suites are
live there with the code they froze. Green: 1579 passed, 0 failed, 0
skipped.

Merging publishes nothing. Publication happens only when sol-v0.1.9 is
pushed on the merged commit, which re-runs the fork suite and release-guard
first.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The commands it named were removed from rainix org-wide; sol-tasks at the
pinned rev is rainix-sol-artifacts only. Build and test invocation is an org
standard carried by rainix, not something this repo restates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cut release 0.1.9: freeze candidate pins as src/generated/0_1_9/
…-env

Drop the Build Environment section from CLAUDE.md
Closes #571

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rename the Git is clean job id to git-clean
recursive_deps=false means vendored dep src resolves through this repo's
remappings, and three reachable deps import a versioned rain-solmem
prefix from src, so the bump carries its minimum chain to keep one
solmem tree:

- rain-solmem 0.1.26 -> 0.1.28
- rainlang-interface 0.2.5 -> 0.2.8
- rain-extrospection 0.1.13 -> 0.1.14
- rain-datacontract 0.1.3 -> 0.1.9 (first release whose src drops the
  solmem import; its src delta is NatSpec and local renames)

None of the four changed behaviour under src between the pinned
releases, and src/generated pointers are unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QyCCzi9WZPhuXcU1hwr2bq
Bump rain-solmem 0.1.26 -> 0.1.28 and the dep chain pinning it
First step of the library / deploy split (#552). The five deployed
contracts' logic moves into src/abstract/BaseRainlang{Parser,Store,
Interpreter,ExpressionDeployer,}.sol and src/concrete/* become thin
bindings of the generated tables and Zoltu addresses over them, which is
the shape the .deploy repo consumes from the package.

PARSE_META_BUILD_DEPTH is a source constant on BaseRainlangParser rather
than a value re-read from the generated file it parameterises.

test/concrete/Test*.sol are the bases built from current source with no
generated tables, placed at fixed test addresses by
test/lib/deploy/LibTestInterpreterDeploy.sol.
RainlangExpressionDeployerDeploymentTest types I_* as the bases and gets
one hook, deployRainlang(), defaulting to the test concretes, so the op,
integrity, eval and parse tests run against current source; the
concrete-specific tests keep exercising the real concretes and pins.

Parser, store and interpreter bytecode are unchanged.
RainlangExpressionDeployer is 15 bytes longer (the parser() and
integrityFunctionPointers() hooks are internal calls the legacy
optimizer does not inline), so its candidate address moves and Rainlang,
which embeds it, moves with it. The live 0.1.9 deployments are
untouched.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QyCCzi9WZPhuXcU1hwr2bq
script/CopyArtifacts.sol output: the devdoc in the Rainlang, expression
deployer and interpreter artifacts follows the moved NatSpec.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QyCCzi9WZPhuXcU1hwr2bq
Second step of the library / deploy split (#552, rainix#296), on top of
the BaseRainlang* abstracts. The concretes, their generated tables and
deploy records, LibInterpreterDeploy, the released-suites libs, the
deploy scripts and tests, the Rust crates and the deploy workflows leave
this repo; rainlang.deploy carries them over this package.

The 0_1_9 frozen record is a library-tagged pin and is deleted, not
relocated: the deploy repo freezes its own first release.

script/Build.sol now generates only the reference extern's pointers;
BuildAuthoringMeta and the prelude build only its meta. The concretes'
logic tests bind test/concrete/Test*.sol, the BaseRainlang* built from
current source.

package-release.yaml is rainix-autopublish on push to main; this removal
is breaking, so next-v0.2.0 ships it as rainlang 0.2.0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QyCCzi9WZPhuXcU1hwr2bq
…stracts

Move the deployed contracts' logic into BaseRainlang* abstracts (#552 step 1)
…brary

# Conflicts:
#	crates/bindings/abi/Rainlang.json
#	crates/test_fixtures/abi/Rainlang.json
#	crates/test_fixtures/abi/RainlangExpressionDeployer.json
#	crates/test_fixtures/abi/RainlangInterpreter.json
rainix's frozen-snapshots-append-only gate rejects deleting a tag dir.
Nothing in the library reads src/generated/0_1_9/ any more; it stays as
the record of the last release cut while this repo carried the deploy
half.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QyCCzi9WZPhuXcU1hwr2bq
The BaseRainlang* contracts are the library's product: their binding
hooks are implemented by rainlang.deploy's concretes and by the test
concretes, neither of which slither's src-only build sees, so every
base is a leaf with unimplemented functions by design.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QyCCzi9WZPhuXcU1hwr2bq
Slim to the library half: the deploy half moves to rainlang.deploy (#552 step 2)
…-entries

Remove submodule-era residue from .soldeerignore
forge-std-1.16.1/ -> forge-std-1.16.2/ and rain-sol-codegen-0.1.0/ ->
rain-sol-codegen-0.1.36/ across src, test and script, and the
remappings block that aliased the older prefixes onto the installed
packages is gone. An alias compiles a file against a version it does
not name, so the versioned prefix stops being the pin, and every
consumer of this package had to carry the same aliases to compile the
shipped harness.

Import paths only; the 0.1.36 tooling interfaces widen three functions
from pure to view and the implementations here keep pure.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QyCCzi9WZPhuXcU1hwr2bq
…sions

Spell the pinned forge-std and rain-sol-codegen versions in every import
The branch predates the solmem bump; main pins 0.1.28 and no other
version is installed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QyCCzi9WZPhuXcU1hwr2bq
@thedavidmeister
thedavidmeister merged commit 16c2d92 into main Sep 7, 2026
5 checks passed
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai assess this PR size classification for the totality of the PR with the following criterias and report it in your comment:

S/M/L PR Classification Guidelines:

This guide helps classify merged pull requests by effort and complexity rather than just line count. The goal is to assess the difficulty and scope of changes after they have been completed.

Small (S)

Characteristics:

  • Simple bug fixes, typos, or minor refactoring
  • Single-purpose changes affecting 1-2 files
  • Documentation updates
  • Configuration tweaks
  • Changes that require minimal context to review

Review Effort: Would have taken 5-10 minutes

Examples:

  • Fix typo in variable name
  • Update README with new instructions
  • Adjust configuration values
  • Simple one-line bug fixes
  • Import statement cleanup

Medium (M)

Characteristics:

  • Feature additions or enhancements
  • Refactoring that touches multiple files but maintains existing behavior
  • Breaking changes with backward compatibility
  • Changes requiring some domain knowledge to review

Review Effort: Would have taken 15-30 minutes

Examples:

  • Add new feature or component
  • Refactor common utility functions
  • Update dependencies with minor breaking changes
  • Add new component with tests
  • Performance optimizations
  • More complex bug fixes

Large (L)

Characteristics:

  • Major feature implementations
  • Breaking changes or API redesigns
  • Complex refactoring across multiple modules
  • New architectural patterns or significant design changes
  • Changes requiring deep context and multiple review rounds

Review Effort: Would have taken 45+ minutes

Examples:

  • Complete new feature with frontend/backend changes
  • Protocol upgrades or breaking changes
  • Major architectural refactoring
  • Framework or technology upgrades

Additional Factors to Consider

When deciding between sizes, also consider:

  • Test coverage impact: More comprehensive test changes lean toward larger classification
  • Risk level: Changes to critical systems bump up a size category
  • Team familiarity: Novel patterns or technologies increase complexity

Notes:

  • the assessment must be for the totality of the PR, that means comparing the base branch to the last commit of the PR
  • the assessment output must be exactly one of: S, M or L (single-line comment) in format of: SIZE={S/M/L}
  • do not include any additional text, only the size classification
  • your assessment comment must not include tips or additional sections
  • do NOT tag me or anyone else on your comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:needs-work Needs rework — the producer's inbox (vetter verdict or human ruling)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant