Skip to content

Restore the Protofire reports as inherited audit records (reverses #1) - #6

Open
thedavidmeister wants to merge 1 commit into
mainfrom
2026-07-25-inherited-audit-provenance
Open

Restore the Protofire reports as inherited audit records (reverses #1)#6
thedavidmeister wants to merge 1 commit into
mainfrom
2026-07-25-inherited-audit-provenance

Conversation

@thedavidmeister

Copy link
Copy Markdown
Contributor

This reverses #1

PR #1 deleted this repo's two Protofire PDFs on the reasoning that
rain.factory.deploy has never itself been audited. Every fact in that commit
message is true — 1a92a86, 08fecb98… and a v0.1.1 tag genuinely do not
exist in this repo, and the only tag here is sol-v0.1.6. The conclusion drawn
from them was wrong.

"The ref does not resolve here" is not "the provenance is fake." This repo
was split out of rain.factory on 2026-07-24. The audits happened in the
predecessor, on the source that builds snapshots pinned here. src/generated/0_1_3
and 0_1_4 pin bytecode of audited source — I rebuilt rain.factory's audited
v0.1.1 CloneFactory.sol (blob acbbcf7e…) under rainix 53e96a7d sol-shell
and it reproduces both snapshots' CREATION_CODE and RUNTIME_CODE
byte-for-byte, keccak 0xf21b813c…, matching their BYTECODE_HASH. Stronger
still, 0x444acC29d63fa643E8adCC35FD9aa6DE111dCb39 and that codehash are
constants inside src/lib/LibCloneFactoryDeploy.sol, a named scope item of
both reports — the coverage is written into the audited source, not inferred
from my rebuild.

So #1 destroyed real provenance rather than removing a false claim. The claim
that needed fixing was never "we have an audit"; it was that nothing said which
part
the audit covers.

What this PR does

  • Restores both PDFs at their original blob OIDs (84d57a5d…, 6829af27…)
    recovered from b3000dd^, verified byte-identical to rain.factory main
    today — the same bytes, not a re-export.
  • Renames them with a mandatory inherited. prefix: a discriminant visible in
    ls, checkable with no network.
  • Adds audit/protofire/inherited.json, carrying what a filename cannot hold:
    source org/repo/ref, sha256, and a per-snapshot coverage list.
  • Adds a short README ## Audit section that points at the manifest and states
    the live pin is uncovered.

What the record now asserts

report source ref (resolves in rain.factory) covers
inherited.rain.factory.v0.1.1-r2.0.may-2026.pdf (r2.0, 27/05/26) v0.1.1 = 08fecb985efbc811cde85c73f18e2e658884e5b6 src/generated/0_1_3, src/generated/0_1_4 (both 0xf21b813c…)
inherited.rain.factory.1a92a86.feb-2026.pdf (r1.0, 11/02/26) 1a92a8688249aa5a8f4e82d5ed584604515f1ea0 nothing

"covers": [] on r1.0 is load-bearing, not an oversight. r1.0 audits an earlier
state of the same ICloneableFactoryV2 source (blob 3299755d…) compiled
against OpenZeppelin 5.5.0 as a git submodule; every snapshot here builds
from the 5.6.1 soldeer pin. No snapshot builds from it, and r2.0's Reviews
table re-lists the 11/02/26 pass, so r2.0 subsumes it. It stays as audit
history, claiming nothing.

What the record does NOT assert

src/generated/0_1_5/ is not covered by either report and has never been
audited by anyone.
It is the ICloneableFactoryV3 rewrite —
cloneDeterministic, msg.sender-namespaced salts, 5-arg NewClone — at
0x7053c1D000192f1FeC1fbe20350139F3300dBBaD / 0x3ec02e2f…. No Protofire scope
list ever contained ICloneableFactoryV3.sol; that interface did not exist in
rain.factory until 2026-07-11, after both audits. And it is the snapshot
LibCloneFactoryDeploy aliases here, live on Arbitrum, Base, Base Sepolia,
Flare and Polygon.

Also uncovered and stated for completeness: this repo's own CloneFactory.sol
and LibCloneFactoryDeploy.sol (a file of the same name is in the audit
scope, but the audited content is the hand-written V2 constants, not this
generated alias — which is exactly why coverage is keyed on snapshot directories
and never on filenames), plus script/, test/ and CI.

The uncovered set is deliberately not written down anywhere. It is computed
as the complement of covers against the live src/generated/ listing, so a
future 0_1_6 appears as uncovered with no manifest edit and no chance of a
stale list quietly under-reporting the gap.

Conventions this respects

  • Vendor subdir preserved (audit/<vendor>/), flat — no audit/protofire/inherited/.
  • inherited.json is the only permitted non-PDF in a vendor dir.
  • The prefix is anchor-parser-safe: roh-scan's parse_audited_tag still
    captures v0.1.1 through it, and its hex-token rule cannot match inherited.
  • REUSE.toml already annotates audit/**/ and .soldeerignore already
    excludes /audit, so no packaging change was needed. reuse lint passes,
    31/31 files.
  • src/generated/ is untouched. Snapshots stay frozen and append-only;
    coverage is asserted about them, never written into them.

Known-red CI, do not chase

testProdDeployArbitrum fails on an exhausted drpc quota, unrelated to this
change (this PR adds no Solidity).

Follow-on, not in this PR

roh-scan at HEAD cannot yet represent this. Its classify_anchor early-returns
a Tag without resolving it, so with these files present the dashboard will
again publish a daysSinceAudit computed off this repo's history and a
compareUrl that 404s. That is a scanner defect these files expose, not one
they create — and it is the reason the convention is a machine-readable manifest
rather than a note. The scanner needs ExternalAudit::Inherited, manifest
parsing, foreign-ref resolution, typed-absent dates, and computed coverage;
rainlanguage/rainix#287's proposed CI gate needs its rule 2 amended so an
inherited.-prefixed PDF validates via the manifest instead of failing on a
ref that by definition does not resolve here.

The two reports audit rain.factory, not this repo, at refs that resolve only
there. That makes them inherited provenance, not a local audit record, and the
convention now says so explicitly rather than by deletion.

Both PDFs return at their original blobs (84d57a5, 6829af2 — byte-identical
to rain.factory main), renamed with the mandatory `inherited.` prefix that is
the machine discriminant for the inherited case.

audit/protofire/inherited.json carries what a filename cannot: the source repo
and ref for each report, its sha256, and the snapshots it covers.
src/generated/0_1_3 and 0_1_4 are covered by r2.0 — the audited v0.1.1 source
rebuilds their pinned bytecode byte-for-byte, and their address and codehash
are constants inside an audited file. r1.0 covers nothing: its source state
compiled against a different OpenZeppelin pin and no snapshot builds from it.

The uncovered set is deliberately not written down. It is the complement of
covers against the live src/generated listing, so 0_1_5 — the unaudited
ICloneableFactoryV3 pin that is live on every chain — shows as uncovered
without anyone maintaining a list, and so will any snapshot added later.

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

coderabbitai Bot commented Jul 25, 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: 24 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

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: 78323643-4e16-471f-b063-fb8275d05828

📥 Commits

Reviewing files that changed from the base of the PR and between 6173d3e and cb61f5b.

⛔ Files ignored due to path filters (2)
  • audit/protofire/inherited.rain.factory.1a92a86.feb-2026.pdf is excluded by !**/*.pdf
  • audit/protofire/inherited.rain.factory.v0.1.1-r2.0.may-2026.pdf is excluded by !**/*.pdf
📒 Files selected for processing (2)
  • README.md
  • audit/protofire/inherited.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 2026-07-25-inherited-audit-provenance

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 thedavidmeister added the ai:ready AI vetter: passes review, ready for human decision label Jul 28, 2026
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

🤖 ai:vetter
Reviewed cb61f5b: ready — Reverses #1 (no linked issue): restores Protofire PDFs at pre-#1 blob OIDs + inherited.json coverage manifest + README; all tree-checkable claims verified (0_1_3/0_1_4 pin 0xf21b813c at 0x444acC29, uncovered 0_1_5 live pin, REUSE/.soldeerignore); PDF internals and rebuild reproduction rest on precisely-anchored stated evidence.
cost 372 — cross-repo audit provenance claims

@thedavidmeister thedavidmeister added ai:blocked-on AI producer: blocked on a dependency PR and removed ai:ready AI vetter: passes review, ready for human decision labels Jul 28, 2026
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

🤖 ai:producer
Blocked-on: Blocked on rainlanguage/rainix#289 (fork-RPC failover preflight), which is now ai:design pending a human ruling. The single failing test is testProdDeployArbitrum and it fails entirely upstream of this diff: vm.createSelectFork could not instantiate a forked environment because drpc returned error code -32001, You've reached the usage limit for your current plan. 19 of 20 tests pass. Foundry maps one rpc_endpoints alias to exactly one URL and --fork-retries only re-hits that same dead URL, so no code change in this repo can route around an exhausted vendor quota. Goes green once the failover lands on rainix main.

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

Labels

ai:blocked-on AI producer: blocked on a dependency PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant