Skip to content

Expose randomizer lifecycle views by token#66

Merged
punk6529 merged 3 commits into
mainfrom
codex/randomizer-lifecycle-views
Jun 10, 2026
Merged

Expose randomizer lifecycle views by token#66
punk6529 merged 3 commits into
mainfrom
codex/randomizer-lifecycle-views

Conversation

@punk6529

@punk6529 punk6529 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #38.

This PR completes the request/view portion of the randomizer lifecycle work by making token-level lookup first-class:

  • adds retrieveRandomnessRequestForToken(tokenId) to return the stored lifecycle request for a token
  • adds randomnessRequestStateForToken(tokenId) for direct state reads by token
  • covers empty, pending, fulfilled, and stale token-level lookup behavior in StreamRandomizerLifecycleTest
  • updates the roadmap, known blockers, test README, and autonomous run state so issue [P0-RAND-002] Add randomness request lifecycle storage and views #38 is traceable

The unknown-token behavior intentionally mirrors unknown request-ID lookup: it returns the default empty request and None state.

Validation

  • forge test --match-contract StreamRandomizerLifecycleTest -vvv -> 11 tests passed, 0 failed
  • make check -> 153 tests passed, 0 failed
  • powershell -ExecutionPolicy Bypass -File scripts/check.ps1 -> 153 tests passed, 0 failed
  • forge fmt --check smart-contracts/StreamRandomizerLifecycle.sol test/StreamRandomizerLifecycle.t.sol -> passed
  • git diff --check -> passed
  • Heading and traceability greps for roadmap/run-state/test docs -> passed
  • Slither baseline read: total=686, high=9, medium=29, weak-prng=2; no accepted-baseline expansion from these view helpers

Notes

Follow-up randomness work remains tracked separately: failed post-processing/retry states (#40), stale provider migration/bulk pending handling (#41), and metadata exposure (#42).

Summary by CodeRabbit

  • New Features

    • Added token-level randomness lifecycle views and direct per-token request lookup alongside existing request-level queries.
  • Documentation

    • Clarified known blockers to describe lifecycle views and updated roadmap and operational state to reflect progress and decisions.
  • Tests

    • Added tests validating token-level lifecycle visibility (None → Pending → Fulfilled) and extended stale-request coverage.
  • Chores

    • Updated operational run/state tracking and worklog entries.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds token-level view functions to expose randomness request state scoped to individual token IDs, validates the complete lifecycle through a comprehensive test, and synchronizes documentation and work-tracking artifacts to reflect completion of randomness lifecycle hardening.

Changes

Token-level randomness request views

Layer / File(s) Summary
Token-scoped randomness request view helpers
smart-contracts/StreamRandomizerLifecycle.sol
Two new public view functions retrieveRandomnessRequestForToken and randomnessRequestStateForToken map token IDs to their associated randomness request data and lifecycle state by resolving the tokenToRequest mapping.
Token-level lifecycle validation test
test/StreamRandomizerLifecycle.t.sol
testTokenLevelViewsExposeEmptyPendingAndFulfilledState validates token-scoped views across the full randomness lifecycle: asserts "None" state before request, "Pending" with correct metadata after request, and "Fulfilled" with derived seed and non-zero fulfillment timestamps after VRF fulfillment. The stale-request test is extended to assert token-level "Stale" visibility.
Documentation and tracking synchronization
docs/known-blockers.md, ops/ROADMAP.md, test/README.md, ops/AUTONOMOUS_RUN.md
Known-blockers now references token-level lifecycle views; roadmap and ops mark P0-RAND-001/PR #65 status and expand coverage to token-level request/state views; test README reflows coverage text; autonomous-run records PR #65 merge, PR #66 worklog, and decision-log entries.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • 6529-Collections/6529Stream#65: PR #65 introduced the underlying request lifecycle storage and mappings (tokenToRequest, request/state structs); this PR exposes token-scoped view accessors and adds token-level tests.

Poem

🐰 A token's tale now visible at last,
From none to pending, then fulfilled fast,
Views show the seed and timestamps bright,
Tokens tell their randomness plight—
Hooray for tests that keep it right!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Expose randomizer lifecycle views by token' directly and clearly describes the primary change: adding token-level view helpers to access randomizer lifecycle state.
Linked Issues check ✅ Passed All coding requirements from #38 are met: token-level view functions added, lifecycle data exposed, pending/terminal states covered, tests validate empty/pending/fulfilled/stale states, and unknown-token behavior mirrors request-ID behavior.
Out of Scope Changes check ✅ Passed All changes are scoped to #38 objectives: two token-level view helpers, comprehensive test coverage, and documentation/ops updates for traceability. No unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/randomizer-lifecycle-views

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor Author

@claude please review this PR.

Focus areas:

  • token-level randomizer lifecycle views: retrieveRandomnessRequestForToken(tokenId) and randomnessRequestStateForToken(tokenId)
  • whether unknown-token behavior correctly mirrors unknown request-ID behavior by returning the default empty request and None state
  • coverage for empty, pending, and fulfilled token-level lookup in StreamRandomizerLifecycleTest
  • whether exposing these read-only helpers introduces any API or indexing ambiguity before the failed/retry/metadata follow-up issues

Local validation is in the PR body; full make check and Windows scripts/check.ps1 both pass with 153 tests.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review latest head d391d68405029ce8323e4810282f684e530b4067. Focus on the new token-level randomizer lifecycle view helpers, the empty/pending/fulfilled lookup test, and the roadmap/test traceability updates. Full local make check, Windows wrapper, formatting, diff hygiene, docs traceability, and Slither baseline checks are green as summarized in the PR body.

Copy link
Copy Markdown
Contributor Author

@claude please review latest head 0b31e7a4696a71e03839542161f8a72367144462.

Only the durable run-state file changed after the initial review request; the Solidity/test scope remains the token-level randomizer lifecycle view helpers and their empty/pending/fulfilled coverage. Local validation remains as summarized in the PR body: focused lifecycle suite 11/11, full make check 153/153, and Windows wrapper 153/153.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review latest head 0b31e7a4696a71e03839542161f8a72367144462. The follow-up after PR creation only records the PR URL and bot request IDs in ops/AUTONOMOUS_RUN.md; the implementation remains the token-level randomizer lifecycle views, direct empty/pending/fulfilled coverage, and traceability docs from the PR body.

Copy link
Copy Markdown
Contributor Author

@claude correction: please review latest head 0b31e7afca9b243d2853ab712e19a3e1ababd274.

The previous latest-head comment expanded the short SHA incorrectly. Scope and validation remain unchanged.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Correction: please review latest head 0b31e7afca9b243d2853ab712e19a3e1ababd274. The previous latest-head comment expanded the short SHA incorrectly. Scope and validation remain unchanged.

Copy link
Copy Markdown
Contributor Author

@claude review

Please review latest head 0b31e7afca9b243d2853ab712e19a3e1ababd274. Focus on the token-level randomizer lifecycle view helpers, unknown-token default behavior, empty/pending/fulfilled coverage, and read-only API/indexing implications. CI is green and local validation is summarized in the PR body.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped — your organization has reached its monthly code review spending cap.

An organization admin can view or raise the cap at claude.ai/admin-settings/claude-code. The cap resets at the start of the next billing period.

Once the cap resets or is raised, comment @claude review on this pull request to trigger a review.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get the PR diff
gh pr view 66 --repo 6529-Collections/6529Stream --json title,body,files,commits,headRefName 2>/dev/null | jq .

echo "=== PR FILES ==="
gh pr diff 66 --repo 6529-Collections/6529Stream 2>/dev/null

Length of output: 25457



@punk6529 — reviewed at head 0b31e7a4696a71e03839542161f8a72367144462. Here is the full assessment.


Review: Expose randomizer lifecycle views by token

Solidity — StreamRandomizerLifecycle.sol

The two new helpers are clean and correct.

// unknown token → tokenToRequest[tokenId] == 0 (default)
//              → randomnessRequests[0]   == empty struct (state = None)
// ✓ correctly mirrors retrieveRandomnessRequest(unknownId) behavior
retrieveRandomnessRequestForToken(uint256 tokenId)
randomnessRequestStateForToken(uint256 tokenId)

Zero-mapping safety: The zero-default for an unmapped token ID is safe because zero request IDs are explicitly rejected in the arRNG path before any lifecycle state is recorded (zero arRNG request IDs fail before lifecycle state is recorded test). A zero requestId will therefore never carry meaningful state in randomnessRequests[0], so the empty-struct/None result for an unknown token is a genuine identity with unknown request-ID behavior.

One cosmetic observation: The existing retrieveRandomnessRequest parameter is named _requestId (underscore-prefixed convention for internal/private-style style guides), while the new functions use tokenId (no prefix). Neither is wrong — public function parameters typically omit the prefix — but the mixed style is worth noting if the project ever formalizes a naming convention.

Implementation note: randomnessRequestStateForToken duplicates the two-level lookup rather than delegating to retrieveRandomnessRequestForToken(...).state. This is intentional and correct — it avoids the unnecessary memory allocation of copying the full struct just to read one field.


Tests — StreamRandomizerLifecycle.t.sol

testTokenLevelViewsExposeEmptyPendingAndFulfilledState is thorough and well-structured:

Stage Fields validated
Empty (pre-mint) state == None, provider == address(0), randomnessRequestStateForToken == None
Pending (post-mint) providerRequestId, collectionId, tokenId, state == Pending, randomnessRequestStateForToken == Pending
Fulfilled (post-callback) state == Fulfilled, derivedSeed, fulfilledBlock > 0, fulfilledTimestamp > 0, randomnessRequestStateForToken == Fulfilled

The test correctly wires expectedSeed through the same keccak256(abi.encode(...)) path the contract uses, so the derived-seed assertion is a genuine correctness check, not just a smoke test.

Coverage gap (intentional): Stale-state token-level lookup is not covered here. The PR notes correctly attribute that to #40/#41. No action needed in this PR.


API / indexing ambiguity

No ambiguity is introduced. These are additive, pure view helpers:

  • tokenToRequest always holds the current active request ID for a token. Indexers reading retrieveRandomnessRequestForToken get exactly the same record they would retrieve by first calling tokenToRequest(tokenId) and then retrieveRandomnessRequest(requestId) — just with one fewer round-trip.
  • The failed/retry/stale-bulk-migration scenarios (#40, #41) may eventually require a token-level history view, but that is a separate concern and is not blocked or prejudiced by these helpers.

Docs traceability

All touched doc files are consistent:

  • known-blockers.md — updated bullet mentions token-level views ✓
  • ops/ROADMAP.md — P0-RAND-002 status updated; P0-RAND-003 closure noted; roadmap table row updated ✓
  • test/README.md — prose updated to include token-level view coverage ✓
  • ops/AUTONOMOUS_RUN.md — operational run-state and decision log updated ✓

Summary

The PR is correct, minimal, and closes #38 cleanly. The only item worth noting (not a blocker) is the mixed parameter-naming style (_requestId vs tokenId). Everything else — implementation, unknown-token parity, test coverage, and traceability — is solid.

[approve]

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the PR details and diff
gh pr view 66 --repo 6529-Collections/6529Stream --json number,title,body,headRefName,headRefOid,files

echo "=== PR FILES ==="
gh pr diff 66 --repo 6529-Collections/6529Stream

Length of output: 24313



@punk6529 Reviewed at head 0b31e7afca9b243d2853ab712e19a3e1ababd274. Here is my assessment:


Review: Token-level Randomizer Lifecycle Views

Implementation — StreamRandomizerLifecycle.sol

The two new helpers are a clean two-level delegation through existing maps:

randomnessRequests[tokenToRequest[tokenId]]

This is correct. For an unknown (or pre-request) token, tokenToRequest[tokenId] returns 0, and randomnessRequests[0] is always the zero-value struct (state = None) because request ID 0 is explicitly rejected before any lifecycle state is written. The unknown-token contract stated in the PR body holds without any special-case branching.

No state mutations, no events, no new access-control surface — the additions are pure views.

Minor observation: existing functions (retrieveRandomnessRequest, randomnessRequestState) use _requestId (underscore prefix) for their parameter names, while the new ones use tokenId (no underscore). For public functions the no-underscore form is more idiomatic Solidity, so the new style is arguably better, but the inconsistency is worth noting in case the project has a convention to harmonise later.


Test coverage — StreamRandomizerLifecycle.t.sol

testTokenLevelViewsExposeEmptyPendingAndFulfilledState hits all three claimed states in one coherent flow:

Stage Assertions
Pre-mint state == None, provider == address(0) via both helpers
Post-mint providerRequestId == 1, collectionId, tokenId, state == Pending
Post-fulfill state == Fulfilled, derivedSeed matches inline derivation, fulfilledBlock > 0, fulfilledTimestamp > 0

The inline seed derivation in the test (keccak256(abi.encode(address(vrf), 1, COLLECTION_ID, TOKEN_ID, 2, words))) is self-documenting and consistent with what the contract stores.

One gap worth flagging: the Stale state is not covered through the token-level path. It is covered indirectly through existing request-ID tests, but a testTokenLevelViewForStaleRequest (or extending the stale-marking test with a retrieveRandomnessRequestForToken assertion) would make the token-level API complete against all currently-reachable states. This is low-priority since Stale is not new in this PR, but it's the one path not exercised via the new entry points.


API / indexing ambiguity

No new ambiguity is introduced. The helpers return the same RandomnessRequest struct already exposed by request ID; no new state is fabricated. Consumers that observe Fulfilled should be aware that failed post-processing states (#40) are not yet represented in the enum — but that is a pre-existing limitation of the state machine, not something introduced here, and the PR notes it correctly.


Docs traceability

known-blockers.md, ROADMAP.md (P0-RAND-002 status, P0-RAND-003 closure), and test/README.md are all updated consistently and accurately reflect what is now implemented vs. what remains open.


Summary

LGTM. The implementation is minimal, correct, and well-tested for the claimed scope. The one actionable item is covering Stale through the token-level path, which I'd suggest tracking in #40 or as a standalone follow-up rather than blocking this PR.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor Author

@claude review

Please review latest head 4dc78079bd8e436413cda304770475d735e7848c. This follow-up addresses CodeRabbit comment 4671424817 by adding token-level Stale coverage to testMarkedStaleRequestIsObservableAndCannotFulfill and updating traceability docs. Local validation: lifecycle suite 11/11, make check 153/153, Windows wrapper 153/153, formatting and diff hygiene green.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review latest head 4dc78079bd8e436413cda304770475d735e7848c. This follow-up addresses your comment 4671424817 by asserting token-level Stale state in testMarkedStaleRequestIsObservableAndCannotFulfill and updating test/README.md, ops/ROADMAP.md, and ops/AUTONOMOUS_RUN.md traceability. Full local make check, Windows wrapper, formatting, and diff hygiene are green.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the PR diff at the latest head
gh pr diff 66 --repo 6529-Collections/6529Stream 2>/dev/null

Length of output: 24086



@punk6529 — reviewed at head 4dc78079bd8e436413cda304770475d735e7848c.

This follow-up cleanly resolves the only gap I flagged.

testMarkedStaleRequestIsObservableAndCannotFulfill — Stale coverage added

The two token-level assertions land exactly where they should — after the existing request-ID stale assertion and before the vm.expectRevert block:

markStaleRequest(1)
  → assert randomnessRequestState(1) == Stale          ← existing
  → assert retrieveRandomnessRequestForToken(TOKEN_ID).state == Stale  ← new
  → assert randomnessRequestStateForToken(TOKEN_ID) == Stale           ← new
  → assert fulfillment reverts (stale request)

This is the right placement: it verifies the state is observable through the token-level path while the subsequent expectRevert confirms the request is still non-fulfillable.

State coverage across token-level API — now complete

State Test
None testTokenLevelViewsExposeEmptyPendingAndFulfilledState
Pending testTokenLevelViewsExposeEmptyPendingAndFulfilledState
Fulfilled testTokenLevelViewsExposeEmptyPendingAndFulfilledState
Stale testMarkedStaleRequestIsObservableAndCannotFulfill ← added here

Docs

test/README.md, ops/ROADMAP.md, and ops/AUTONOMOUS_RUN.md are all consistent with the updated coverage. The roadmap test-matrix row now explicitly lists "token-level stale lookup."

LGTM. No further concerns.

[approve]

@punk6529 punk6529 merged commit 1b5c14c into main Jun 10, 2026
1 of 2 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.

[P0-RAND-002] Add randomness request lifecycle storage and views

1 participant