Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
68d3956
Add edge case tests for LibParseStackTracker
thedavidmeister Feb 18, 2026
a60d67f
Add fuzzed round-trip tests and output overflow test
thedavidmeister Feb 18, 2026
b83f0ae
Fuzz too-few-inputs test and add paren nesting boundary tests
thedavidmeister Feb 18, 2026
67b6e19
Require triage rigor for existing tests in AUDIT.md
thedavidmeister Feb 18, 2026
6d5d031
Fuzz comment and hex literal error tests, document paren limit
thedavidmeister Feb 18, 2026
1022437
Codify jidoka process in CLAUDE.md and mark triage findings FIXED
thedavidmeister Feb 18, 2026
918f852
Prohibit fabricated self-narratives in process documentation
thedavidmeister Feb 18, 2026
f82c569
Add unsafeParse tests and mark A48-1 FIXED
thedavidmeister Feb 18, 2026
525395f
Add TESTING.md with testing conventions
thedavidmeister Feb 18, 2026
3ae7c4a
Add maxOutputs truncation test and document bytecode construction rule
thedavidmeister Feb 18, 2026
6949934
Add newState initialization test and mark A12-5 FIXED
thedavidmeister Feb 18, 2026
6ab4d0f
Add multi-output highwater advancement test and mark A12-6 FIXED
thedavidmeister Feb 18, 2026
a6e5883
Add selectLiteralParserByIndex direct test and update triage
thedavidmeister Feb 18, 2026
73e812b
Add happy-path tests for parseDecimalFloatPacked and mark A34-1 FIXED
thedavidmeister Feb 18, 2026
3a16974
Add RepeatLiteralTooLong and output value fuzz tests, mark A36-1 A36-…
thedavidmeister Feb 18, 2026
66644c8
Add subParseLiteral rejection fuzz tests and mark A38-1 FIXED
thedavidmeister Feb 18, 2026
3fb2b85
Add handleOperandDisallowedAlwaysOne tests and mark A39-1 FIXED
thedavidmeister Feb 18, 2026
3b66223
Add DanglingSource revert test and mark A43-4 FIXED
thedavidmeister Feb 18, 2026
35c7dcf
Add ParenInputOverflow revert test and mark A43-5 FIXED
thedavidmeister Feb 18, 2026
a674d30
Add highwater ParseStackOverflow test and mark A43-6 FIXED
thedavidmeister Feb 18, 2026
5f42dfd
Add pushOpToSource direct unit tests and mark A43-7 FIXED
thedavidmeister Feb 18, 2026
474c90e
Add endSource direct unit tests and mark A43-8 FIXED
thedavidmeister Feb 18, 2026
9008cc9
Add buildBytecode direct unit tests and mark A43-9 FIXED
thedavidmeister Feb 18, 2026
c3e136f
Add UnknownWord direct test with mock sub-parser and mark A44-2 FIXED
thedavidmeister Feb 18, 2026
5d183ed
Mark A44-3 FIXED — already covered by A38-1 testSubParseLiteralAllReject
thedavidmeister Feb 18, 2026
7897151
Add parse2 direct tests for empty, parse error, and integrity error a…
thedavidmeister Feb 18, 2026
3158b06
Add parsePragma1 deployer proxy tests and mark A47-2 FIXED
thedavidmeister Feb 18, 2026
49db70d
Add namespace isolation fuzz tests and mark A50-1 FIXED
thedavidmeister Feb 18, 2026
ee5e748
Add zero-opcode source eval tests and mark A05-4 FIXED
thedavidmeister Feb 18, 2026
22ac7cd
Add multiple source eval tests and mark A05-5 FIXED
thedavidmeister Feb 18, 2026
d5e5ce9
Add eval with matching non-zero inputs fuzz test and mark A05-6 FIXED
thedavidmeister Feb 18, 2026
cb7e0e6
Add evalLoop multiple-of-8 opcode count edge case tests
thedavidmeister Feb 18, 2026
d44b4d6
Fuzz extern address in LibExtern encode/decode roundtrip test
thedavidmeister Feb 18, 2026
7a09fc1
Add standalone decode tests for LibExtern dispatch and call
thedavidmeister Feb 18, 2026
6cc2a9a
Add fuzz test for LibExternOpContextCallingContract.subParser
thedavidmeister Feb 18, 2026
6825e95
Add fuzz test for LibExternOpContextRainlen.subParser
thedavidmeister Feb 18, 2026
67be772
Add fuzz test for LibExternOpContextSender.subParser
thedavidmeister Feb 18, 2026
7a4c784
Add fuzz test for LibExternOpStackOperand.subParser
thedavidmeister Feb 18, 2026
aa5ba1e
Add stackMaxIndex peak tracking test for LibIntegrityCheck
thedavidmeister Feb 18, 2026
3dd41ef
Add zero-source bytecode tests for integrity check
thedavidmeister Feb 18, 2026
25975c3
Add multi-source bytecode integrity check tests
thedavidmeister Feb 18, 2026
e352c38
Move fingerprint from src to test library and add tests
thedavidmeister Feb 18, 2026
cc0514b
Add stackBottoms tests and mask stackTrace source indices to 16 bits
thedavidmeister Feb 18, 2026
6cf7f75
Add pass 3 and pass 4 findings to triage
thedavidmeister Feb 18, 2026
4eb5f26
Add NatSpec to InterpreterState, ParseState, math ops, and reference …
thedavidmeister Feb 18, 2026
9c6c5db
Fix inaccurate NatSpec in stackTrace, eval2, exp2, and headroom
thedavidmeister Feb 18, 2026
a674638
Remove @notice tags from library and contract NatSpec
thedavidmeister Feb 18, 2026
59f4ccd
Fix inaccurate operand handler NatSpec in LibParseOperand
thedavidmeister Feb 18, 2026
ffe38e6
Fix inaccurate NatSpec across eval, state, math, and parse libs
thedavidmeister Feb 18, 2026
768e57f
Remove dead code, unused imports, and fix code quality issues
thedavidmeister Feb 18, 2026
666710f
Fix code quality issues across bitwise, math, erc20, and concrete con…
thedavidmeister Feb 18, 2026
11ad106
Dismiss 5 false positive Rust audit findings
thedavidmeister Feb 18, 2026
ae94a3e
Add missing @param/@return NatSpec tags to error files and opcode lib…
thedavidmeister Feb 18, 2026
d1d070b
Update triage for NatSpec fixes across error files and opcode libraries
thedavidmeister Feb 18, 2026
7355aca
Address CodeRabbit review feedback on PR #430
thedavidmeister Feb 19, 2026
2fad791
Add @param/@return NatSpec to hash, any, binary-equal, conditions, en…
thedavidmeister Feb 19, 2026
44072a3
Add explicit @notice to all @title NatSpec blocks
thedavidmeister Feb 19, 2026
a1cdaba
Add explicit @notice to all @title NatSpec blocks in test files
thedavidmeister Feb 19, 2026
76ba1e5
Add explicit @notice to function-level and error NatSpec blocks
thedavidmeister Feb 19, 2026
9379a58
Add @param/@return NatSpec to all remaining opcode libraries
thedavidmeister Feb 19, 2026
cc6e325
Add @param/@return NatSpec to core libs, parse libs, extern ops, and …
thedavidmeister Feb 19, 2026
8865768
Fix missing using directive for Float.eq in selectByIndex test
thedavidmeister Feb 19, 2026
d7f9baa
Exclude audit directory from CodeRabbit reviews
thedavidmeister Feb 19, 2026
bd92a9d
Exclude Claude and audit config files from CodeRabbit reviews
thedavidmeister Feb 19, 2026
44f0748
Exclude TESTING.md from CodeRabbit reviews
thedavidmeister Feb 19, 2026
1cb75f1
Fix pragma version mismatch in stackTrace test
thedavidmeister Feb 19, 2026
34fe844
Update triage with 197 verified FIXED findings across passes 3 and 4
thedavidmeister Feb 19, 2026
103fa61
Complete pass 3 NatSpec audit and add IDISPaiRegistry interface
thedavidmeister Feb 19, 2026
ee84095
Remove gh from nix flake dev shell
thedavidmeister Feb 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
reviews:
path_filters:
- "!audit/**"
- "!CLAUDE.md"
- "!AUDIT.md"
- "!TESTING.md"
- "!.claude/**"
3 changes: 3 additions & 0 deletions AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Each agent must write its findings to `audit/<YYYY-MM-DD>-<NN>/pass<M>/<FileName

During triage, maintain `audit/<YYYY-MM-DD>-<NN>/triage.md` recording the disposition of every LOW+ finding, keyed by finding ID (e.g., A03-1). Each entry has a status: **FIXED** (code changed), **DOCUMENTED** (NatSpec/comments added), **DISMISSED** (no action needed), or **PENDING** (not yet triaged). This file is the durable record of triage progress — conversation context is lost on compaction, but the file persists. Before presenting the next finding, check the triage file for the first PENDING ID in sort order. Present findings neutrally and let the user decide the disposition.

When triaging a finding as already FIXED (test already exists), apply the same rigor as writing a new fix: read the actual test code, verify it covers the finding, check for missing edge cases and boundary conditions, and add tests if gaps exist. "Test exists" is not the same as "properly tested." One finding at a time — no batch-marking.

## Pass 0: Process Review

Review CLAUDE.md and AUDIT.md for issues that would cause future sessions to misinterpret instructions. This pass reviews process documents, not source code. No subagents needed — the documents are small enough to review in the main conversation. Record findings to `audit/<YYYY-MM-DD>-<NN>/pass0/process.md`.
Expand Down Expand Up @@ -67,6 +69,7 @@ Review all documentation for completeness and accuracy, including but not limite
- Systematically enumerate every function in every contract and library, and verify each has NatSpec documentation
- Explicitly list undocumented functions as findings
- All NatSpec must include `@param` and `@return` tags as relevant for functions, structs, errors, etc.
- When a doc block contains any explicit tag (e.g. `@title`), all entries must be explicitly tagged. Untagged lines after a tag are parsed as continuation of the previous tag, not as implicit `@notice`. Every contract/library-level doc block with `@title` must also have an explicit `@notice`.
- After ensuring documentation exists, review it against the implementation for accuracy

## Pass 4: Code Quality
Expand Down
18 changes: 15 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,29 @@ External contracts can extend the interpreter with additional opcodes. `src/conc
- Custom bytecode serialization is used instead of ABI encoding for gas efficiency
- Function pointer dispatch (no switch/if chains) for opcode routing
- Assembly blocks are used extensively and marked `memory-safe` where applicable
- NatSpec: when a doc block contains any explicit tag (e.g. `@title`), all entries must be explicitly tagged — untagged lines continue the previous tag, not implicit `@notice`

## Test Conventions

Testing patterns and conventions are in `TESTING.md`. Read that file before writing tests.

- Test files are in `test/` mirroring `src/` structure, suffixed `.t.sol`
- Base test contracts in `test/abstract/` — `OpTest` for opcodes, `ParseTest` for parser tests
- Use `opReferenceCheck` to test opcode runtime behavior against a reference implementation
- Rust test fixtures (`crates/test_fixtures/`) deploy all four contracts on a local Anvil instance

## Process (Jidoka)

Each fix is a complete cycle: understand → fix → build → test → verify. Do not move to the next item with incomplete work. The "test" step means both: write tests for any new code paths introduced by the fix, then run the full test suite to confirm nothing is broken. New code must meet the same audit requirements defined in `AUDIT.md` — a fix that introduces untested error paths, missing NatSpec, or other audit findings is not complete. When a process defect is found, stop and fix the process before resuming. When the user asks "why" about a defect, they are asking for root cause analysis of the process failure — not requesting that you go do the thing. Answer the "why" first, agree on the process fix, then resume.
Jidoka is a priority: process correctness (correct future) over ad hoc progress (present state). Quality at the source enables throughput; skipping quality steps creates rework and slows overall flow. Process introspection takes precedence over following the process.

Each fix is a complete cycle: understand → fix → build → test → verify. Do not move to the next item with incomplete work. The "test" step means both: write tests for any new code paths introduced by the fix, then run the full test suite to confirm nothing is broken. New code must meet the same audit requirements defined in `AUDIT.md` — a fix that introduces untested error paths, missing NatSpec, or other audit findings is not complete.

When the user says "jidoka," they are signaling a process defect. The response is:
1. Identify the process defect.
2. Propose a durable fix (document edit, rule change).
3. **Stop and wait for agreement.** Do not resume task work, run commands, or do anything else. The process fix is the deliverable of that moment.

When the user asks "why" about a defect, they are asking for root cause analysis of the process failure — not requesting that you go do the thing. Answer the "why" first, agree on the process fix, then resume.

Do not claim motivations or internal states. Describe what you actually did, not a story about why. Say "I skipped the test suite run" not "I was optimizing for throughput." Say "the rule is in CLAUDE.md" not "I've internalized it." You have no metrics, no persistence, and no self-observation — narratives about your own reasoning are fabrications.

## Audit Review

Expand Down
41 changes: 41 additions & 0 deletions TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Testing Conventions

## Base Contracts

Test base contracts in `test/abstract/`:

- **`RainterpreterExpressionDeployerDeploymentTest`** — Full stack deployment. Exposes `I_PARSER`, `I_INTERPRETER`, `I_STORE`, `I_DEPLOYER`.
Comment thread
thedavidmeister marked this conversation as resolved.
- **`OpTest`** — Opcode tests. Provides `opReferenceCheck()`, `checkHappy()`, `checkUnhappy()`.
- **`ParseTest`** — Parser tests. Provides `parseExternal()`.
- **`OperandTest`** — Operand handler tests. Provides `checkOperandParse()`.
- **`ParseLiteralTest`** — Literal parsing tests. Provides `checkLiteralBounds()`.

## Fuzz Testing

- Use `bound()` to constrain fuzz inputs, not `vm.assume()`. `vm.assume()` wastes runs by discarding inputs. `vm.assume()` is acceptable when the rejection rate is low or `bound()` cannot express the constraint.
- When fuzzing over a non-contiguous set (e.g., non-hex bytes), `bound()` to the count of valid values, then map with arithmetic to skip excluded ranges.
- When a fuzz parameter affects expression structure, build rainlang dynamically. The fuzz variable must match what the rainlang produces.
Comment thread
thedavidmeister marked this conversation as resolved.

## Library Internals

Internal library functions need an external wrapper in the test contract. Construct `ParseState` inside the wrapper so memory pointers are valid. Call via `this.externalFoo()`.

## Revert Paths

Use `vm.expectRevert` with `abi.encodeWithSelector` and the custom error type. Call through `this.externalFoo()` for library functions or directly on `I_PARSER`/`I_INTERPRETER` for integration tests.

## Bytecode Construction

Use the parse library to generate bytecode from rainlang when the test needs valid bytecode. Only hand-encode bytecode when the test intentionally needs invalid or malformed bytecode that the parser cannot produce.

## Bytecode Inspection

Use `LibBytecode` from `rain.interpreter.interface/lib/bytecode/LibBytecode.sol`. Do not manually index into bytecode bytes.

## Opcode Testing

Use `opReferenceCheck` to validate that `run` output matches a pure reference implementation and that `integrity` correctly declares inputs/outputs.

## Boundary Tests

Always test both sides: the max valid value (should succeed) and one past it (should revert).
Loading