Skip to content

Block randomizer migration with pending requests#67

Merged
punk6529 merged 2 commits into
mainfrom
codex/randomizer-pending-migration
Jun 10, 2026
Merged

Block randomizer migration with pending requests#67
punk6529 merged 2 commits into
mainfrom
codex/randomizer-pending-migration

Conversation

@punk6529

@punk6529 punk6529 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #41.

This implements ADR 0005's default randomizer migration policy for lifecycle-aware providers: ordinary StreamCore.addRandomizer migration is blocked while the current randomizer reports pending randomness requests for the collection.

  • adds IRandomizerLifecycle for lifecycle-aware pending request views
  • tracks per-collection and total pending request counts in StreamRandomizerLifecycle
  • makes StreamCore.addRandomizer revert with PendingRandomnessRequests before advancing the randomizer epoch when the current provider still has pending work
  • clears pending counts on fulfillment or explicit admin stale marking, so migration can proceed after terminal request state
  • extends VRF/arRNG tests for blocked migration, fulfilled/stale unblocking, old-provider duplicate callback rejection, event evidence, and new-provider request/fulfillment after migration
  • updates ADR/status/blocker/test/roadmap/run-state docs for P0-RAND-005 traceability

Compatibility note

The guard is lifecycle-aware and fails open for old randomizers that do not implement supportsRandomizerLifecycle(). That preserves existing synchronous/legacy provider compatibility while enforcing the pending-request guard for the VRF/arRNG lifecycle adapters added by the randomness hardening work.

Validation

  • scripts/bootstrap-windows.ps1 installed/confirmed Foundry v1.7.1 because the app shell did not initially have forge on PATH
  • forge test --match-contract StreamRandomizerLifecycleTest -vvv passed: 16 tests, 0 failed
  • make check passed: build plus 158 tests, 0 failed
  • powershell -ExecutionPolicy Bypass -File scripts\check.ps1 passed: 158 tests, 0 failed
  • forge fmt --check smart-contracts\IRandomizerLifecycle.sol smart-contracts\StreamRandomizerLifecycle.sol smart-contracts\StreamCore.sol test\helpers\CharacterizationTestBase.sol test\StreamRandomizerLifecycle.t.sol passed
  • git diff --check passed
  • traceability grep passed for P0-RAND-005, PendingRandomnessRequests, pendingRandomnessRequests, branch name, and Queue Item 26
  • Markdown heading scan passed for changed docs/run-state files
  • repo-local Slither returned the accepted baseline: slither_exit=-1 total=686 high=9 medium=29 weak-prng=2 arbitrary-send-eth=0 reentrancy-eth=0

Follow-up left intentionally out of scope

  • canonical core/coordinator-owned lifecycle storage
  • bulk stale-marking incident tooling
  • retry/re-request policy for permanently stuck requests
  • metadata behavior for failed or stale randomness

Summary by CodeRabbit

  • New Features

    • Added pending randomness request tracking and lifecycle visibility
    • Provider migration now blocked while pending requests exist
    • Pending request counts clear upon fulfillment or stale marking
  • Tests

    • Expanded test coverage for randomizer lifecycle, migration scenarios, and pending request state assertions
  • Documentation

    • Updated architecture decisions, status tracking, and roadmap to reflect lifecycle-aware randomizer behavior and provider migration blocking policies

@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

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2e18845e-4b21-4a6c-b8c0-d639f579aedf

📥 Commits

Reviewing files that changed from the base of the PR and between 1b5c14c and dce56c4.

📒 Files selected for processing (11)
  • docs/adr/0005-randomness.md
  • docs/known-blockers.md
  • docs/status.md
  • ops/AUTONOMOUS_RUN.md
  • ops/ROADMAP.md
  • smart-contracts/IRandomizerLifecycle.sol
  • smart-contracts/StreamCore.sol
  • smart-contracts/StreamRandomizerLifecycle.sol
  • test/README.md
  • test/StreamRandomizerLifecycle.t.sol
  • test/helpers/CharacterizationTestBase.sol

📝 Walkthrough

Walkthrough

This PR implements the ADR-0005 migration-guard policy by introducing lifecycle-aware pending-request tracking and blocking ordinary randomizer provider migration when pending requests exist. The changes span a new IRandomizerLifecycle interface contract, pending-count state and query methods in StreamRandomizerLifecycle, a conditional blocking check in StreamCore.addRandomizer, expanded test infrastructure for log capture, five comprehensive migration test scenarios, and coordinated documentation updates.

Changes

Randomizer migration guard with pending-request blocking

Layer / File(s) Summary
IRandomizerLifecycle interface definition
smart-contracts/IRandomizerLifecycle.sol
Introduces the IRandomizerLifecycle interface defining read-only capability detection (supportsRandomizerLifecycle) and pending-request count queries (pendingRandomnessRequests per collection and total).
StreamRandomizerLifecycle pending request tracking
smart-contracts/StreamRandomizerLifecycle.sol
Adds private per-collection and global pending-request counters, implements the lifecycle interface functions for capability and view queries, increments counters when recording requests, and decrements via a new helper when fulfilling or marking requests stale.
StreamCore addRandomizer migration guard
smart-contracts/StreamCore.sol
Imports IRandomizerLifecycle, defines the PendingRandomnessRequests error, calls a new blocking check before updating randomizer state, and implements the check with try/catch to safely detect lifecycle support and revert when pending requests exist.
Test infrastructure for log recording
test/helpers/CharacterizationTestBase.sol
Extends Vm cheatcode interface with Log struct (containing topics, data, emitter) and recordLogs()/getRecordedLogs() functions to enable event log capture and assertion in tests.
Migration test suite and test utilities
test/StreamRandomizerLifecycle.t.sol, test/README.md
Adds test constants and helper functions; covers five migration scenarios (success with no pending, blocked when pending, fulfillment unblocking old-duplicate rejection, stale unblocking new-provider fulfillment, ARRNG-specific blocking); enhances existing VRF/ARRNG tests with pending-count assertions before/after fulfillment and stale marking; refactors stale-epoch test setup with explicit mock wiring; adds _mintToken overload and _assertCollectionRandomizerUpdated log-scanning helper.
Documentation and operational updates
docs/adr/0005-randomness.md, docs/known-blockers.md, docs/status.md, ops/ROADMAP.md, ops/AUTONOMOUS_RUN.md
Updates ADR-0005 with implementation detail on migration blocking and terminal states, adds blocker constraint to known-blockers, updates status baseline with randomizer test coverage scope, revises ROADMAP with explicit migration-blocking policy and test-matrix assertions, and advances operational logs with PR #66 merge and PR #67 opening state/worklog.

Sequence Diagram

sequenceDiagram
  participant Admin
  participant StreamCore
  participant OldRandomizer as OldRandomizer<br/>(IRandomizerLifecycle)
  participant StreamRandomizer as StreamRandomizer<br/>(New)

  Admin->>StreamCore: addRandomizer(collection, newRandomizer)
  StreamCore->>OldRandomizer: try supportsRandomizerLifecycle()
  activate OldRandomizer
  OldRandomizer-->>StreamCore: true
  deactivate OldRandomizer
  
  alt Old Randomizer has pending requests
    StreamCore->>OldRandomizer: pendingRandomnessRequests(collection)
    OldRandomizer-->>StreamCore: count > 0
    StreamCore-->>Admin: revert PendingRandomnessRequests
  else No pending requests (or fulfilled/stale)
    StreamCore->>OldRandomizer: pendingRandomnessRequests(collection)
    OldRandomizer-->>StreamCore: 0
    StreamCore->>StreamCore: epoch++, update randomizer
    StreamCore-->>StreamRandomizer: new provider active
    StreamCore-->>Admin: CollectionRandomizerUpdated
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • 6529-Collections/6529Stream#40: Implements explicit randomness state tracking and terminal-state behavior (fulfilled/stale clearing) that directly address P0-RAND-004 requirements for lifecycle observability.
  • 6529-Collections/6529Stream#37: Implements the ADR-0005 contract-level request lifecycle and migration-hardening features through the new IRandomizerLifecycle interface, pending-count tracking, and StreamCore blocking logic.

Possibly related PRs

  • 6529-Collections/6529Stream#65: Directly precedes this PR; extends the request lifecycle work by adding pending-count tracking via IRandomizerLifecycle and migration blocking in StreamCore.addRandomizer.

Poem

🐰 A guardian hops forth to guard the randomness stream,
With pending counts tracked, no provider scheme—
Migration blocked while requests still roam free,
Until fulfilled or stale they peacefully be.
Tests bloom like clover, covering each case,
Lifecycle-aware, at a steady pace! 🌿✨

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/randomizer-pending-migration
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch codex/randomizer-pending-migration

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

@punk6529

Copy link
Copy Markdown
Contributor Author

@claude review

Please review latest head ecd8810c19ba2e1d80bebae108d318add4ad1fc9 for PR #67.

Focus areas:

  • lifecycle-aware pending request counters in StreamRandomizerLifecycle
  • StreamCore.addRandomizer guard before randomizer epoch migration
  • fulfilled/stale request unblocking semantics
  • legacy non-lifecycle provider compatibility
  • VRF/arRNG migration and callback regression coverage

Local validation passed:

  • focused StreamRandomizerLifecycleTest: 16/16
  • make check: 158/158
  • scripts/check.ps1: 158/158
  • touched-file forge fmt --check
  • git diff --check
  • docs traceability and heading scans
  • Slither accepted baseline: total=686 high=9 medium=29 weak-prng=2 arbitrary-send-eth=0 reentrancy-eth=0

@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.

@punk6529

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review latest head ecd8810c19ba2e1d80bebae108d318add4ad1fc9 for PR #67.

Local validation passed:

  • focused StreamRandomizerLifecycleTest: 16/16
  • make check: 158/158
  • scripts/check.ps1: 158/158
  • touched-file forge fmt --check
  • git diff --check
  • docs traceability and heading scans
  • Slither accepted baseline: total=686 high=9 medium=29 weak-prng=2 arbitrary-send-eth=0 reentrancy-eth=0

@punk6529

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review latest head dce56c4c2e3dccf9a53ff7669ce6a4533df5440b for PR #67. The latest push only records PR state in ops/AUTONOMOUS_RUN.md; implementation validation remains unchanged and CI is 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
# Get PR details and file list
gh pr view 67 --repo 6529-Collections/6529Stream --json files,headRefOid,baseRefOid | jq .

# Get the diff
gh pr diff 67 --repo 6529-Collections/6529Stream

Length of output: 46414



@punk6529 — reviewed head dce56c4c2e3dccf9a53ff7669ce6a4533df5440b. Implementation is clean and the conservative ADR policy is correctly enforced. Detailed findings below.


Review: PR #67 — Block randomizer migration with pending requests

IRandomizerLifecycle.sol

Minimal, correctly scoped interface. Three functions cover everything the guard needs. No concerns.


StreamRandomizerLifecycle.sol

Counter lifecycle is correct:

  • Increment on _recordRandomnessRequest — fires once per new request, before any state can transition.
  • Decrement via _decrementPendingRandomnessRequest only from _fulfilRandomnessRequest (after confirming Pending state) and _markRandomnessRequestStale (same guard). Solidity 0.8+ arithmetic will catch any underflow, so a double-decrement is impossible given the state-machine guards.

Both counters are private, exposed only through the IRandomizerLifecycle view functions — good encapsulation.


StreamCore._requireNoPendingRandomnessRequests — one minor note

The two-step lifecycle check pattern is correct:

try IRandomizerLifecycle(oldRandomizer).supportsRandomizerLifecycle() returns (bool supported) {
    if (!supported) return;
} catch {
    return;          // legacy / non-lifecycle provider → fails open
}

uint256 pendingRequests =
    IRandomizerLifecycle(oldRandomizer).pendingRandomnessRequests(_collectionID);
if (pendingRequests != 0) {
    revert PendingRandomnessRequests(_collectionID, oldRandomizer, pendingRequests);
}

Minor observation: once supported == true is confirmed, pendingRandomnessRequests() is called without a try/catch. If a lifecycle-aware adapter were to revert on this call (bug or malicious), addRandomizer would be permanently DOSed for that collection. This is low-risk because (a) admins control which randomizer was set, and (b) the two known lifecycle adapters (VRF, arRNG) are trusted — but it's worth documenting as a known assumption in the follow-up canonical lifecycle ownership work.

address(0) early return — correct for first-time randomizer installation.

supportsRandomizerLifecycle() OOG edge case — a Solidity try/catch treats an out-of-gas sub-call result as a revert and enters the catch block, which returns (fails open). This is acceptable given the admin-controlled context.


Test coverage ✅

All five focus areas are covered:

Test Covers
testRandomizerMigrationWithNoPendingRequestsSucceedsAndEmitsEpoch Happy path + event evidence
testRandomizerMigrationWithPendingRequestIsBlocked VRF blocks migration
testFulfilledRequestUnblocksMigrationAndOldDuplicateCannotOverwrite Fulfill → migrate → duplicate rejected
testMarkedStaleRequestUnblocksMigrationAndNewProviderFulfillment Stale → migrate → new provider works end-to-end
testArrngPendingRequestBlocksMigration arRNG variant

testVrfStaleEpochOrProviderFulfillmentFails refactor is correct — using MockRandomizerCore.setRandomizer to bypass the pending-request guard isolates the stale-epoch rejection test from the migration guard. The epoch values shifting from (2, 3) to (1, 2) follow naturally from the mock starting at epoch 1.

_assertCollectionRandomizerUpdated: address(uint160(uint256(log.topics[i]))) is the correct way to extract an indexed address from a raw log topic. Good log verification.


Legacy compatibility ✅

NoopRandomizer, RandomizerNXT, and any other non-lifecycle adapter silently pass the guard — either via the catch block or the !supported early return. Existing synchronous/legacy provider behavior is fully preserved.


Documentation ✅

ADR 0005, known-blockers.md, status.md, ROADMAP.md, and test/README.md are consistently updated. ops/AUTONOMOUS_RUN.md records Queue Item 26 state accurately. Traceability for P0-RAND-005 / PendingRandomnessRequests / pendingRandomnessRequests is thorough.


Summary

Implementation correctly realises ADR 0005's default conservative policy. The only item worth carrying forward is documenting the pendingRandomnessRequests-without-try/catch assumption as a known invariant in the canonical lifecycle ownership follow-up (P0-RAND-005 / future core/coordinator-owned storage work). No blocking concerns.

[approve]

@punk6529 punk6529 merged commit 428cbc8 into main Jun 10, 2026
2 checks passed
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":401,"request":{"method":"PATCH","url":"https://api.github.com/repos/6529-Collections/6529Stream/issues/comments/4671731634","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- review_stack_entry_start -->\n\n[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/6529-Collections/6529Stream/pull/67?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)\n\n<!-- review_stack_entry_end -->\n<!-- This is an auto-generated comment: failure by coderabbit.ai -->\n\n> [!CAUTION]\n> ## Review failed\n> \n> The pull request is closed.\n\n<!-- end of auto-generated comment: failure by coderabbit.ai -->\n\n<details>\n<summary>ℹ️ Recent review info</summary>\n\n<details>\n<summary>⚙️ Run configuration</summary>\n\n**Configuration used**: defaults\n\n**Review profile**: CHILL\n\n**Plan**: Pro\n\n**Run ID**: `a62f7297-dee0-4c99-80f6-586212ff44e5`\n\n</details>\n\n<details>\n<summary>📥 Commits</summary>\n\nReviewing files that changed from the base of the PR and between 1b5c14c802f2c10870f8ee7c089164372d393b54 and dce56c4c2e3dccf9a53ff7669ce6a4533df5440b.\n\n</details>\n\n<details>\n<summary>📒 Files selected for processing (11)</summary>\n\n* `docs/adr/0005-randomness.md`\n* `docs/known-blockers.md`\n* `docs/status.md`\n* `ops/AUTONOMOUS_RUN.md`\n* `ops/ROADMAP.md`\n* `smart-contracts/IRandomizerLifecycle.sol`\n* `smart-contracts/StreamCore.sol`\n* `smart-contracts/StreamRandomizerLifecycle.sol`\n* `test/README.md`\n* `test/StreamRandomizerLifecycle.t.sol`\n* `test/helpers/CharacterizationTestBase.sol`\n\n</details>\n\n</details>\n\n---\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nThis PR implements ADR-0005 provider migration policy: tracking pending randomness requests per collection in `StreamRandomizerLifecycle`, exposing query functions via `IRandomizerLifecycle`, and blocking randomizer migration in `StreamCore.addRandomizer` when the current provider reports pending requests. The change includes comprehensive test scenarios for migration success/failure paths, fulfillment/stale unblocking, and corresponding documentation and operational record updates.\n\n## Changes\n\n**Randomizer migration guard with pending-request blocking**\n\n|Layer / File(s)|Summary|\n|---|---|\n|**IRandomizerLifecycle interface definition** <br> `smart-contracts/IRandomizerLifecycle.sol`|New `IRandomizerLifecycle` interface exports `supportsRandomizerLifecycle()`, `pendingRandomnessRequests(uint256 collectionId)`, and `totalPendingRandomnessRequests()` for querying lifecycle capability and pending-request counts.|\n|**StreamRandomizerLifecycle pending-request tracking** <br> `smart-contracts/StreamRandomizerLifecycle.sol`|Added per-collection and global pending-request counters that increment on new requests and decrement on fulfillment or stale marking. Implemented `IRandomizerLifecycle` interface with view functions. New `_decrementPendingRandomnessRequest(collectionId)` helper centralizes counter decrements.|\n|**StreamCore addRandomizer migration guard** <br> `smart-contracts/StreamCore.sol`|Imports `IRandomizerLifecycle`, defines `PendingRandomnessRequests` error, and adds `_requireNoPendingRandomnessRequests` check invoked before updating a collection's randomizer. Uses try/catch to safely query lifecycle support and reverts with error if pending requests are non-zero.|\n|**Test infrastructure for log recording** <br> `test/helpers/CharacterizationTestBase.sol`|Extended `Vm` interface with `Log` struct capturing topics, data, and emitter, plus `recordLogs()` and `getRecordedLogs()` cheatcode functions to enable event log assertions.|\n|**Migration test suite and helpers** <br> `test/StreamRandomizerLifecycle.t.sol`, `test/README.md`|Five new migration scenarios: success with no pending, blocking with pending, fulfillment unblocks (rejecting old-provider callbacks), stale-marking unblocks (allowing new-provider fulfillment), and ARRNG-specific blocking. Extended VRF/ARRNG lifecycle tests with pending-count assertions. Added `_mintToken(deployed, tokenId)` overload and `_assertCollectionRandomizerUpdated` log-scanning helper.|\n|**Documentation and operational updates** <br> `docs/adr/0005-randomness.md`, `docs/known-blockers.md`, `docs/status.md`, `ops/ROADMAP.md`, `ops/AUTONOMOUS_RUN.md`|Updated ADR-0005 with pending-count lifecycle detail and migration-blocking policy. Expanded known-blockers and status with constraint details. Refined ROADMAP migration rules and test-matrix assertions. Advanced AUTONOMOUS_RUN with PR `#66` merge record, PR `#67` worklog, and decision log entries.|\n\n## Estimated code review effort\n\n🎯 4 (Complex) | ⏱️ ~60 minutes\n\n## Possibly related issues\n\n- [6529-Collections/6529Stream#38](https://github.com/6529-Collections/6529Stream/issues/38): Implements lifecycle storage and counters with pending-request view functions that directly satisfy the issue requirement for randomness request lifecycle storage and state views.\n- [6529-Collections/6529Stream#40](https://github.com/6529-Collections/6529Stream/issues/40): Adds lifecycle-aware pending/fulfilled/stale state tracking and state-transition handling that overlap the retrieved issue's requirement for explicit randomness states and transitions.\n- [6529-Collections/6529Stream#37](https://github.com/6529-Collections/6529Stream/issues/37): Implements ADR-0005 randomness lifecycle components (IRandomizerLifecycle, pending-request counters, StreamCore checks) that have code-level overlap with the issue scope.\n\n## Possibly related PRs\n\n- [6529-Collections/6529Stream#65](https://github.com/6529-Collections/6529Stream/pull/65): Extends lifecycle hardening by evolving `StreamRandomizerLifecycle` with pending-request counters and adding `IRandomizerLifecycle`-driven migration-blocking in `StreamCore.addRandomizer`, along with corresponding migration test expansions.\n- [6529-Collections/6529Stream#44](https://github.com/6529-Collections/6529Stream/pull/44): Codifies the pending/fulfillment/stale provider-migration policy in ADR-0005 and related docs that this PR operationalizes in Solidity and test coverage.\n\n## Poem\n\n> 🐰 A rabbit hops through pending queues,\n> Blocking migrations—proper cues!\n> Counts decrement when requests meet their fate,\n> Stale or fulfilled, they unblock the gate!\n> StreamCore now guards what StreamRNG tracks—\n> ADR-0005 has our backs! 🎲✨\n\n</details>\n\n<!-- walkthrough_end -->\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing Touches</summary>\n\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Commit unit tests in branch `codex/randomizer-pending-migration`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n<!-- tips_start -->\n\n---\n\n\n\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n<!-- internal state start -->\n\n\n<!-- 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 -->\n\n<!-- internal state end -->"},"request":{"retryCount":1,"signal":{}}},"response":{"url":"https://api.github.com/repos/6529-Collections/6529Stream/issues/comments/4671731634","status":401,"headers":{"access-control-allow-origin":"*","access-control-expose-headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset","connection":"close","content-security-policy":"default-src 'none'","content-type":"application/json; charset=utf-8","date":"Wed, 10 Jun 2026 15:29:27 GMT","referrer-policy":"origin-when-cross-origin, strict-origin-when-cross-origin","server":"github.com","strict-transport-security":"max-age=31536000; includeSubdomains; preload","vary":"Accept-Encoding, Accept, X-Requested-With","x-content-type-options":"nosniff","x-frame-options":"deny","x-github-media-type":"github.v3; format=json","x-github-request-id":"149B:1B83A7:4AE758D:11ADBB76:6A2982D6","x-xss-protection":"0"},"data":{"message":"Requires authentication","documentation_url":"https://docs.github.com/rest","status":"401"}}}

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-005] Define and test randomizer migration with pending requests

1 participant