Skip to content

Add schema-v1 metadata state outputs#83

Merged
punk6529 merged 4 commits into
mainfrom
codex/metadata-schema-state
Jun 10, 2026
Merged

Add schema-v1 metadata state outputs#83
punk6529 merged 4 commits into
mainfrom
codex/metadata-schema-state

Conversation

@punk6529

@punk6529 punk6529 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the next P1-META-001 metadata-schema slice: schema-versioned on-chain metadata output with explicit pending/final state.

This PR:

  • adds METADATA_SCHEMA_VERSION = "6529stream-v1"
  • exposes metadataSchemaVersion() and tokenMetadataState(tokenId) views
  • switches on-chain tokenURI JSON from raw UTF-8 data URIs to base64 JSON data URIs
  • adds metadata_schema_version and metadata_state fields to on-chain JSON
  • stops pending on-chain metadata from building final generative HTML with a zero token hash
  • updates golden fixtures, docs, roadmap, and autonomous run-state traceability

Refs #46.

Roadmap

Security And Maturity

  • This PR does not claim production readiness unless the relevant launch gate evidence is merged.
  • Security-sensitive behavior is identified, or this PR is docs/tooling-only.
  • New external behavior is documented.
  • No private keys, signer material, RPC secrets, or production deployment secrets are included.

Review Routing

  • Protocol review is required or not applicable.
  • Security review is required or not applicable.
  • Tooling/CI review is required or not applicable.
  • Docs review is required or not applicable.

Validation

Local commands run:

forge test --match-contract StreamMetadataGoldenTest -vvv
# Passed: 5 tests, 0 failed

make check
# Passed: 211 tests, 0 failed

powershell -ExecutionPolicy Bypass -File scripts\check.ps1
# Passed: 211 tests, 0 failed

forge fmt --check smart-contracts\StreamCore.sol test\StreamMetadataGolden.t.sol
# Passed

git diff --check
# Passed

rg -n "^#|^##|^###" docs\metadata.md docs\status.md docs\known-blockers.md test\README.md ops\ROADMAP.md ops\AUTONOMOUS_RUN.md
# Passed

rg -n "P1-META-001|metadata_schema_version|metadata_state|metadataSchemaVersion|tokenMetadataState|onchain-pending-schema-v1|onchain-final-schema-v1|codex/metadata-schema-state|Queue Item 40" smart-contracts docs test ops
# Passed

slither . --config-file slither.config.json --foundry-compile-all --json <temp-file>
# Expected non-zero baseline exit; high/medium unchanged: 717 total, 4 High, 19 Medium
  • make check or platform equivalent passed.
  • Tests were added/updated, or this PR explains why no tests are required.
  • CI is green.
  • Bot and human review comments are resolved or explicitly accepted with rationale.

Impact

Reviewer Notes

CodeRabbit-only review for this PR. Claude is intentionally skipped per maintainer instruction.

Summary by CodeRabbit

  • New Features

    • On-chain metadata now emits base64-encoded JSON data URIs with explicit schema version and metadata_state ("pending"/"final"); animation_url is included only for final metadata. Read-only views expose the schema version and per-token metadata state.
  • Bug Fixes

    • Attempts to set a zero token hash are rejected to preserve the pending state semantics.
  • Documentation

    • Docs, status, roadmap, and ops updated to reflect schema-v1 behavior and a narrowed public‑beta checklist.
  • Tests

    • Golden fixtures and tests updated/renamed to validate schema-v1 outputs and state views.

@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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 604b9932-b41e-49b5-8b53-1afb30c0596c

📥 Commits

Reviewing files that changed from the base of the PR and between 3dc56d6 and 78664b0.

📒 Files selected for processing (2)
  • ops/AUTONOMOUS_RUN.md
  • test/StreamMetadataGolden.t.sol
✅ Files skipped from review due to trivial changes (1)
  • ops/AUTONOMOUS_RUN.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/StreamMetadataGolden.t.sol

📝 Walkthrough

Walkthrough

This PR exposes metadata schema-v1/state in StreamCore, refactors tokenURI to produce base64 JSON data URIs with metadata_schema_version and metadata_state, updates golden tests and fixtures for schema-v1 pending/final outputs, and updates docs and ops tracking to match the new behavior.

Changes

Metadata Schema-v1 and State Exposure

Layer / File(s) Summary
Metadata schema constants and finality helpers
smart-contracts/StreamCore.sol
StreamCore introduces METADATA_SCHEMA_VERSION constant, private state labels for pending/final, and a _isTokenMetadataFinal helper that checks tokenToHash[tokenId] presence to determine token metadata state.
TokenURI entry point and on-chain JSON pipeline
smart-contracts/StreamCore.sol
TokenURI is refactored to call finality checks and route to _onchainTokenURI, which generates base64-encoded JSON data URIs. New helpers _onchainMetadataJson and _onchainAnimationURI build the JSON with explicit metadata_schema_version and metadata_state and embed base64 HTML only for final metadata.
Schema-v1 golden tests and fixture files
test/README.md, test/StreamMetadataGolden.t.sol, test/fixtures/metadata/*
New testMetadataSchemaVersionAndTokenStateViews asserts schema version and token state; on-chain URI tests renamed to schema-v1 variants and updated to compare against onchain-pending-schema-v1-token-uri.txt and onchain-final-schema-v1-token-uri.txt fixtures containing base64 JSON data URIs.
Metadata specification and blockers documentation
docs/metadata.md, docs/known-blockers.md, docs/status.md
Docs updated to document base64 JSON data URIs, metadata_schema_version and metadata_state fields, final-only animation_url, adjusted golden-fixture naming, and revised remaining blockers/status items.
Autonomous run log and roadmap progression
ops/AUTONOMOUS_RUN.md, ops/ROADMAP.md
Ops recording updated active PR branch and merged PR references, PR queue updated for Queue Item 40, and roadmap/test-matrix locked to schema-v1 base64 JSON pending/final outputs with metadata state exposure.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I nibble bytes of base64 light,

Pending hops, then final takes flight,
Schema pinned, state clear as day,
Golden fixtures show the way,
Tests and docs—our garden bright.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add schema-v1 metadata state outputs' clearly and accurately summarizes the main feature addition: implementing schema-versioned on-chain metadata with explicit pending/final state tracking.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/metadata-schema-state

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

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review latest head 12ccd37 for the schema-v1 metadata state output slice.

Local validation on this branch:

forge test --match-contract StreamMetadataGoldenTest -vvv
# Passed: 5 tests, 0 failed

make check
# Passed: 211 tests, 0 failed

powershell -ExecutionPolicy Bypass -File scripts\check.ps1
# Passed: 211 tests, 0 failed

forge fmt --check smart-contracts\StreamCore.sol test\StreamMetadataGolden.t.sol
# Passed

git diff --check
# Passed

slither . --config-file slither.config.json --foundry-compile-all --json <temp-file>
# Expected non-zero baseline exit; high/medium unchanged: 717 total, 4 High, 19 Medium

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

@punk6529 Acknowledged — kicking off a full review of head 12ccd37 for the schema-v1 metadata state output slice now.

✅ Action performed

Full review finished.

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@smart-contracts/StreamCore.sol`:
- Around line 539-540: The invariant was changed so bytes32(0) now means
"pending", but setTokenHash still allows a zero hash; update the setter to
enforce finality by rejecting zero values: in setTokenHash add a guard that
requires _hash != bytes32(0) (or alternatively add a separate boolean/enum to
track finality and set that when writing any hash) so that
_isTokenMetadataFinal, tokenMetadataState, and tokenURI will not treat a
completed token as pending when a randomizer callback writes the hash.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e26c6c29-13c8-468b-bb5c-7c8f65d46b66

📥 Commits

Reviewing files that changed from the base of the PR and between 944f614 and 12ccd37.

📒 Files selected for processing (12)
  • docs/known-blockers.md
  • docs/metadata.md
  • docs/status.md
  • ops/AUTONOMOUS_RUN.md
  • ops/ROADMAP.md
  • smart-contracts/StreamCore.sol
  • test/README.md
  • test/StreamMetadataGolden.t.sol
  • test/fixtures/metadata/current-onchain-final-token-uri.txt
  • test/fixtures/metadata/current-onchain-pending-token-uri.txt
  • test/fixtures/metadata/onchain-final-schema-v1-token-uri.txt
  • test/fixtures/metadata/onchain-pending-schema-v1-token-uri.txt
💤 Files with no reviewable changes (2)
  • test/fixtures/metadata/current-onchain-pending-token-uri.txt
  • test/fixtures/metadata/current-onchain-final-token-uri.txt

Comment thread smart-contracts/StreamCore.sol

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review latest head 3dc56d6 after addressing the zero-hash metadata-state finding from thread PRRT_kwDOM7REis6IpsTo.

Follow-up change:

  • setTokenHash now rejects bytes32(0) because zero is the pending metadata sentinel.
  • StreamMetadataGoldenTest now has a configured-randomizer regression proving zero hash writes revert and the token remains pending.
  • ops/AUTONOMOUS_RUN.md records the review thread and validation evidence.

Local validation after the fix:

forge test --match-contract StreamMetadataGoldenTest -vvv
# Passed: 6 tests, 0 failed

make check
# Passed: 212 tests, 0 failed

powershell -ExecutionPolicy Bypass -File scripts\check.ps1
# Passed: 212 tests, 0 failed

forge fmt --check smart-contracts\StreamCore.sol test\StreamMetadataGolden.t.sol
# Passed

git diff --check
# Passed

slither . --config-file slither.config.json --foundry-compile-all --json <temp-file>
# Expected non-zero baseline exit; high/medium unchanged: 717 total, 4 High, 19 Medium

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect setTokenHash for bytes32(0) guard
rg -n "setTokenHash" smart-contracts/StreamCore.sol -A 10

echo "---"

# Look for the zero-hash revert in the contract
rg -n "bytes32(0)\|zero\|ZeroHash\|ZERO_HASH\|zero.hash\|revert.*[Hh]ash\|require.*hash" smart-contracts/StreamCore.sol -A 2

echo "---"

# Check the new test
rg -n "zero\|revert\|ZeroHash" test/StreamMetadataGolden.t.sol -A 5 -B 2

echo "---"

# Show AUTONOMOUS_RUN additions
tail -60 ops/AUTONOMOUS_RUN.md

Length of output: 13907


🏁 Script executed:

#!/bin/bash
echo "=== setTokenHash full context ==="
rg -n "setTokenHash" smart-contracts/StreamCore.sol -A 15 -B 2

echo ""
echo "=== New regression test in StreamMetadataGolden.t.sol ==="
cat test/StreamMetadataGolden.t.sol

echo ""
echo "=== AUTONOMOUS_RUN PR `#83` section ==="
rg -n "PR `#83`\|3dc56d6\|PRRT_kwDOM7REis6IpsTo\|zero.hash\|zero.*hash\|hash.*zero\|ZeroHash" ops/AUTONOMOUS_RUN.md -A 3 -B 1

echo ""
echo "=== Check error message consistency - all revert strings around hash ==="
rg -n "require\|revert\|error" smart-contracts/StreamCore.sol | grep -i "hash\|zero"

echo ""
echo "=== Check NoopRandomizer / MockRandomizer for setTokenHash call ==="
rg -n "setTokenHash\|NoopRandomizer\|MockRandomizer\|ConfiguredRandomizer" test/ -A 5 -B 2

echo ""
echo "=== StreamCore.sol full setTokenHash + _isTokenMetadataFinal area ==="
rg -n "_isTokenMetadataFinal\|tokenToHash\|METADATA_STATE" smart-contracts/StreamCore.sol -A 3 -B 1

Length of output: 8972



@punk6529 The zero-hash guard implementation looks solid. A few observations from code inspection:

setTokenHash guard (line 408):

require(_hash != bytes32(0), "Zero token hash");

Correctly placed — before the slot-check and the assignment. The caller check → zero-hash check → existing-slot check → write ordering is all correct.

One minor style note: the existing slot-check at lines 409–412 uses the full 0x0000...0000 hex literal and has no revert message, while the new guard uses bytes32(0) and has a message. Both are functionally equivalent but a light inconsistency. Pre-existing issue, so out of scope here.

New regression test testSetTokenHashRejectsZeroHashReservedForPendingState:

  • vm.prank(address(noopRandomizer)) — correctly impersonates the registered randomizer contract
  • vm.expectRevert("Zero token hash") — exact string match
  • Post-revert assertions confirm both no write occurred (retrieveTokenHash == bytes32(0)) and metadata state remained "pending" — good two-part guard

One nit on the assertion label: "zero hash stored" at:

deployed.core.retrieveTokenHash(TOKEN_ID).assertEq(bytes32(0), "zero hash stored");

This reads ambiguously — "zero hash stored" sounds like it describes a successful zero-hash write rather than "hash should still be zero/unset after rejected write." Something like "token hash should remain unset after zero-hash rejection" would be clearer for a future reader hitting a failing test. Minor nit, not blocking.

Overall the fix is correct and the test coverage is comprehensive. Triggering the full review now.

✅ Action performed

Full review finished.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review final head 78664b0 after accepting the non-blocking assertion-label nit from comment 4675802795.

Delta since 3dc56d6:

  • Clarified the zero-hash regression failure message.
  • Updated ops/AUTONOMOUS_RUN.md with the final review/validation state.

Validation after this final cleanup:

forge test --match-contract StreamMetadataGoldenTest -vvv
# Passed: 6 tests, 0 failed

make check
# Passed: 212 tests, 0 failed

powershell -ExecutionPolicy Bypass -File scripts\check.ps1
# Passed: 212 tests, 0 failed

forge fmt --check smart-contracts\StreamCore.sol test\StreamMetadataGolden.t.sol
# Passed

git diff --check
# Passed

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== Verify assertion message fix in regression test ==="
rg -n "zero hash\|unset\|rejection\|pending.*reject\|token hash should" test/StreamMetadataGolden.t.sol -A 2 -B 2

echo ""
echo "=== Full regression test context ==="
rg -n "testSetTokenHashRejectsZeroHash\|ZeroHash\|expectRevert\|retrieveTokenHash\|tokenMetadataState" test/StreamMetadataGolden.t.sol -A 3 -B 1

echo ""
echo "=== AUTONOMOUS_RUN.md tail for final state ==="
tail -40 ops/AUTONOMOUS_RUN.md

echo ""
echo "=== Confirm setTokenHash guard still in place ==="
rg -n "setTokenHash\|Zero token hash\|bytes32(0)" smart-contracts/StreamCore.sol -A 5 -B 2

Length of output: 8990


🏁 Script executed:

#!/bin/bash
echo "=== test/StreamMetadataGolden.t.sol full content ==="
cat test/StreamMetadataGolden.t.sol

echo ""
echo "=== setTokenHash and zero guard in StreamCore.sol ==="
grep -n "setTokenHash\|Zero token hash\|bytes32(0)\|_isTokenMetadataFinal\|tokenToHash" smart-contracts/StreamCore.sol | head -40

echo ""
echo "=== Last 80 lines of ops/AUTONOMOUS_RUN.md ==="
tail -80 ops/AUTONOMOUS_RUN.md

Length of output: 25284



@punk6529 The delta at 78664b0 is verified:

Assertion label fix (the raised nit) — confirmed in testSetTokenHashRejectsZeroHashReservedForPendingState:

// before (3dc56d6)
.assertEq(bytes32(0), "zero hash stored");

// after (78664b0)
.assertEq(bytes32(0), "token hash should remain unset after zero-hash rejection");

Both post-revert assertions are now unambiguous — the hash check and the "zero hash changed metadata state" state check together give a clear failure narrative for any future regression.

Everything else (guard ordering at line 408, _isTokenMetadataFinal, the schema-version and state view tests, golden fixture paths) remains intact and correct. ops/AUTONOMOUS_RUN.md update is documentation-only — no concerns. Triggering the full review now.

✅ 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

Merge readiness for PR #83:

  • Head: 78664b0bc1976122c3d1e5d1fc4ec33f44860721.
  • CI: Foundry smoke passed on the current head: https://github.com/6529-Collections/6529Stream/actions/runs/27314086506/job/80690684028
  • Review: CodeRabbit thread PRRT_kwDOM7REis6IpsTo is resolved after commit 3dc56d6.
  • Final CodeRabbit verification: comment 4675822063 verified head 78664b0, confirmed the assertion-label cleanup, and reported no concerns.
  • Aggregate status note: the CodeRabbit status context remains pending after the final incremental review command, but the resolved thread plus final verification comment provide the actionable review evidence for this head.
  • Per maintainer instruction for this PR, CodeRabbit review is sufficient; no Claude review was requested.

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.

1 participant