Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ the release policy in `docs/release-policy.md`.
for required metadata image inputs.
- Added production collection base URI and external library URL validation,
keeping those fields optional while rejecting unsafe non-empty URI values.
- Added focused `StreamCore` custom-error regressions covering function-admin
authorization, artist signatures, metadata array lengths, and final-supply
timing.

### Fixed

Expand All @@ -38,6 +41,12 @@ the release policy in `docs/release-policy.md`.
- Rejected initial zero collection supply with a typed supply error instead of
arithmetic panic, and rejected dependency registry swaps to non-contract
addresses with `InvalidDependencyRegistryContract()`.
- Recovered `StreamCore` runtime bytecode headroom by replacing selected legacy
string reverts with typed custom errors and tightening repeated
`setCollectionData` storage access, bringing the production IR-optimized
runtime to 24,135 bytes with 441 bytes of EIP-170 headroom.
- Rejected `setFinalSupply` for collections with missing collection data using
`CollectionDataMissing(collectionId)` before final supply math can underflow.

### Release Impact

Expand Down Expand Up @@ -68,6 +77,10 @@ the release policy in `docs/release-policy.md`.
- Gate D/G release artifacts now include the ABI and bytecode deltas from
explicit initial zero-supply rejection and dependency registry target
validation.
- Gate D/G release artifacts now include the ABI and bytecode deltas from
`StreamCore` size-recovery custom errors:
`ArtistSignatureUnauthorized()`, `FunctionAdminUnauthorized()`,
`InvalidTokenMetadataInput()`, and `FinalSupplyTimeNotPassed()`.
- Detached checksum signatures, signed release tags, production address books,
and verified live deployment addresses remain future release-ceremony work.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"generated_by": "scripts/generate_address_books.py:1",
"source": {
"deployment_manifest": "deployments/examples/anvil-6529stream-v0.1.0-001-broadcast.json",
"deployment_manifest_sha256": "sha256:565975bbbe565eeeb0d53bfbe491b8080f77685997e26885c36e82a90ea7c2d5",
"deployment_manifest_sha256": "sha256:40bf0fc8c39ee577ecd1af1e17fcd6cef657ef9f62c29ff3e6a91e76d6e7f707",
"release_artifacts": "release-artifacts/latest",
"abi_checksums": "release-artifacts/latest/abi-checksums.json",
"event_topic_catalog": "release-artifacts/latest/event-topic-catalog.json"
Expand Down Expand Up @@ -65,8 +65,8 @@
"address": "0x1000000000000000000000000000000000000003",
"source": "smart-contracts/StreamCore.sol",
"artifact_path": "out/StreamCore.sol/StreamCore.json",
"abi_hash": "sha256:2e01e1c03a39528d9a90d2d0c2544431538c33103fbb6038c2ec6987866a883d",
"runtime_bytecode_hash": "sha256:15a9f2929ad9e43fbf5a4fd7293212b91a4a1fb377353b06abc153248310aae3",
"abi_hash": "sha256:ea674cbdafc9a379139e9998fd161d0cde58b82ed053f6e5cfc8d3a3653509cc",
"runtime_bytecode_hash": "sha256:909d5b85f9600b8550dda40ef08dded3a8a141d05d97a53e4bac2692130d469c",
"verification_status": "not_applicable"
},
"StreamCuratorsPool": {
Expand Down
6 changes: 3 additions & 3 deletions deployments/address-books/anvil-6529stream-v0.1.0-001.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"generated_by": "scripts/generate_address_books.py:1",
"source": {
"deployment_manifest": "deployments/examples/anvil-6529stream-v0.1.0-001.json",
"deployment_manifest_sha256": "sha256:58be318490fe0daedc978d2ae1e76bdf91ecefc87b30db4943d4f481310b0eac",
"deployment_manifest_sha256": "sha256:211887f2a8e15dba3a1f8f2daf3c9dc21d84ec1e921136fb77bd6de0bd0df45e",
"release_artifacts": "release-artifacts/latest",
"abi_checksums": "release-artifacts/latest/abi-checksums.json",
"event_topic_catalog": "release-artifacts/latest/event-topic-catalog.json"
Expand Down Expand Up @@ -65,8 +65,8 @@
"address": "0x0000000000000000000000000000000000000003",
"source": "smart-contracts/StreamCore.sol",
"artifact_path": "out/StreamCore.sol/StreamCore.json",
"abi_hash": "sha256:2e01e1c03a39528d9a90d2d0c2544431538c33103fbb6038c2ec6987866a883d",
"runtime_bytecode_hash": "sha256:15a9f2929ad9e43fbf5a4fd7293212b91a4a1fb377353b06abc153248310aae3",
"abi_hash": "sha256:ea674cbdafc9a379139e9998fd161d0cde58b82ed053f6e5cfc8d3a3653509cc",
"runtime_bytecode_hash": "sha256:909d5b85f9600b8550dda40ef08dded3a8a141d05d97a53e4bac2692130d469c",
"verification_status": "not_applicable"
},
"StreamCuratorsPool": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@
"0x0000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000002"
],
"abi_hash": "sha256:2e01e1c03a39528d9a90d2d0c2544431538c33103fbb6038c2ec6987866a883d",
"bytecode_hash": "sha256:15a9f2929ad9e43fbf5a4fd7293212b91a4a1fb377353b06abc153248310aae3",
"abi_hash": "sha256:ea674cbdafc9a379139e9998fd161d0cde58b82ed053f6e5cfc8d3a3653509cc",
"bytecode_hash": "sha256:909d5b85f9600b8550dda40ef08dded3a8a141d05d97a53e4bac2692130d469c",
"verification_status": "not_applicable"
},
"StreamCuratorsPool": {
Expand Down Expand Up @@ -166,11 +166,11 @@
]
},
"release_artifacts": {
"manifest_sha256": "sha256:565975bbbe565eeeb0d53bfbe491b8080f77685997e26885c36e82a90ea7c2d5",
"manifest_sha256": "sha256:40bf0fc8c39ee577ecd1af1e17fcd6cef657ef9f62c29ff3e6a91e76d6e7f707",
"abi_hashes": {
"StreamAdmins": "sha256:0dec302776ef6fe8038a96a716c7300d697c52c9b8d79559ab86c2b5c6599dd5",
"DependencyRegistry": "sha256:8600876198d591fdae934b20c5d370490939504890944dbd8249d85ef17a6795",
"StreamCore": "sha256:2e01e1c03a39528d9a90d2d0c2544431538c33103fbb6038c2ec6987866a883d",
"StreamCore": "sha256:ea674cbdafc9a379139e9998fd161d0cde58b82ed053f6e5cfc8d3a3653509cc",
"StreamCuratorsPool": "sha256:f5d65fb2b17cf0caae7c8c75c6736c5828c869502f55634279556ba8483e6daf",
"StreamMinter": "sha256:5464ee3c1b5c40867aba4565d11fe6b708ea2b2e93aba4f7e3a52ebbe4296c3e",
"StreamDrops": "sha256:2314f89858673138e8b9c2e421dd7a727c7e7746d5eb069e58a61699f2f4de6a",
Expand Down
8 changes: 4 additions & 4 deletions deployments/examples/anvil-6529stream-v0.1.0-001.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@
"0x0000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000002"
],
"abi_hash": "sha256:2e01e1c03a39528d9a90d2d0c2544431538c33103fbb6038c2ec6987866a883d",
"bytecode_hash": "sha256:15a9f2929ad9e43fbf5a4fd7293212b91a4a1fb377353b06abc153248310aae3",
"abi_hash": "sha256:ea674cbdafc9a379139e9998fd161d0cde58b82ed053f6e5cfc8d3a3653509cc",
"bytecode_hash": "sha256:909d5b85f9600b8550dda40ef08dded3a8a141d05d97a53e4bac2692130d469c",
"verification_status": "not_applicable"
},
"StreamCuratorsPool": {
Expand Down Expand Up @@ -166,11 +166,11 @@
]
},
"release_artifacts": {
"manifest_sha256": "sha256:58be318490fe0daedc978d2ae1e76bdf91ecefc87b30db4943d4f481310b0eac",
"manifest_sha256": "sha256:211887f2a8e15dba3a1f8f2daf3c9dc21d84ec1e921136fb77bd6de0bd0df45e",
"abi_hashes": {
"StreamAdmins": "sha256:0dec302776ef6fe8038a96a716c7300d697c52c9b8d79559ab86c2b5c6599dd5",
"DependencyRegistry": "sha256:8600876198d591fdae934b20c5d370490939504890944dbd8249d85ef17a6795",
"StreamCore": "sha256:2e01e1c03a39528d9a90d2d0c2544431538c33103fbb6038c2ec6987866a883d",
"StreamCore": "sha256:ea674cbdafc9a379139e9998fd161d0cde58b82ed053f6e5cfc8d3a3653509cc",
"StreamCuratorsPool": "sha256:f5d65fb2b17cf0caae7c8c75c6736c5828c869502f55634279556ba8483e6daf",
"StreamMinter": "sha256:5464ee3c1b5c40867aba4565d11fe6b708ea2b2e93aba4f7e3a52ebbe4296c3e",
"StreamDrops": "sha256:2314f89858673138e8b9c2e421dd7a727c7e7746d5eb069e58a61699f2f4de6a",
Expand Down
13 changes: 10 additions & 3 deletions docs/status.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ The current Gate A smoke baseline proves:
- Foundry is configured to compile `smart-contracts`.
- `forge build` runs against Solidity `0.8.19`.
- `forge build --sizes --via-ir --skip test --skip script --force` runs as the production
size gate. Current `StreamCore` production runtime size is 24,545 bytes,
leaving 31 bytes of EIP-170 headroom under the IR-optimized deployment
profile.
size gate. Current `StreamCore` production runtime size is 24,135 bytes,
leaving 441 bytes of EIP-170 headroom under the IR-optimized deployment
profile. This satisfies the current 384-byte minimum release floor; future
non-trivial `StreamCore` feature work should preserve at least 512 bytes of
warning-threshold headroom or document an explicit size-budget exception.
- `forge test -vvv` executes real tests for admin guards, target-scoped
function-admin permission regressions, domain-scoped pause controls,
signer-manager lifecycle controls with approved targets, EIP-712 and ERC-1271
Expand Down Expand Up @@ -77,6 +79,11 @@ The current Gate A smoke baseline proves:
`ipfs://`, and `ar://` content URIs plus rejected empty required token image
URIs, JavaScript, hostless HTTPS, whitespace-bearing token image/base URI
inputs, and non-HTTPS external library URLs.
`StreamCoreCustomErrors.t.sol` proves the typed failure selectors used to
recover `StreamCore` bytecode headroom for function-admin authorization,
artist-signature authorization, metadata-array length validation, and
final-supply timing, plus missing collection data rejection before final
supply math.
`scripts/test_metadata_fixtures.py` and
`scripts/check_metadata_fixtures.py` validate the committed metadata golden
fixtures outside Foundry by strictly decoding JSON and HTML data URIs,
Expand Down
79 changes: 72 additions & 7 deletions ops/AUTONOMOUS_RUN.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ tests, security hardening, deployment discipline, and release/audit readiness.
| Field | Value |
| --- | --- |
| Remote | `https://github.com/6529-Collections/6529Stream.git` |
| Active PR branch | `codex/metadata-collection-uri-policy` |
| Last merged PR | `https://github.com/6529-Collections/6529Stream/pull/113` |
| Active PR branch | `codex/recover-streamcore-headroom` |
| Last merged PR | `https://github.com/6529-Collections/6529Stream/pull/114` |
| Roadmap file | `ops/ROADMAP.md` |
| State file | `ops/AUTONOMOUS_RUN.md` |
| Last updated | `2026-06-11 18:22 UTC` |
| Last updated | `2026-06-11 19:17 UTC` |

## Packaging Notes

Expand Down Expand Up @@ -113,14 +113,73 @@ The queue will evolve as PRs merge and bot feedback arrives.
| 57 | Add metadata size limits | Gate D/Gate G support | Continue P1-META-006 by enforcing numeric byte caps for metadata storage inputs, generated `tokenURI` output, and dependency registry metadata, with focused tests, docs, release artifact refresh, and roadmap traceability | Merged in PR #111 |
| 58 | Add metadata render-sandbox fixture checks | Gate D | Continue P1-META-006 by validating committed metadata golden fixtures for JSON/data-URI/HTML script-boundary shape and URI scheme policy in local/CI gates, without changing production bytecode | Merged in PR #112 |
| 59 | Add metadata token image URI policy | Gate D/Gate G support | Continue P1-META-006 by defining renderer content/script URI policy helpers and rejecting unsafe token image URI writes in production while preserving collection base URI, external library URL, structured-attributes, invalid-UTF-8, and browser-sandbox work as follow-up slices | Merged in PR #113 |
| 60 | Add collection URI production enforcement | Gate D/Gate G support | Continue P1-META-006 by enforcing optional collection base URI and external library URL policy in production, preserving empty optional fields, using custom-error cleanup to keep `StreamCore` under EIP-170, and updating docs/artifacts/state traceability | Active |
| 60 | Add collection URI production enforcement | Gate D/Gate G support | Continue P1-META-006 by enforcing optional collection base URI and external library URL policy in production, preserving empty optional fields, using custom-error cleanup to keep `StreamCore` under EIP-170, and updating docs/artifacts/state traceability | Merged in PR #114 |
| 61 | Recover `StreamCore` bytecode headroom | Gate D/Gate G support | Implement P1-SIZE-001 by replacing selected legacy `StreamCore` string reverts with typed custom errors, adding focused selector regressions, documenting the minimum size floor and warning threshold, and refreshing release artifacts | Active |

## Current PR Worklog

### PR candidate: Collection URI production enforcement (Queue Item 60)
### PR candidate: Recover `StreamCore` bytecode headroom (Queue Item 61)

Status: CodeRabbit outside-diff follow-up implemented and validated locally;
ready to commit, push, and request CodeRabbit review.
Status: PR `#116` opened and follow-up validation complete; ready to merge.
Branch: `codex/recover-streamcore-headroom`.
Pull request: `https://github.com/6529-Collections/6529Stream/pull/116`.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Goal:

- Recover sustainable `StreamCore` runtime bytecode margin before further
non-trivial Core feature work.
- Preserve public success behavior and ABI compatibility while documenting the
intentional revert-data change from selected string reverts to typed custom
errors.
- Set the current Core size policy in repo docs: 384 bytes is the minimum
release floor under the production IR size gate, and 512 bytes is the warning
threshold for future non-trivial Core work.
- Regenerate release artifacts because the `StreamCore` ABI and bytecode change.

Candidate files:

- `smart-contracts/StreamCore.sol`
- `test/StreamCoreCustomErrors.t.sol`
- `docs/status.md`
- `ops/ROADMAP.md`
- `ops/AUTONOMOUS_RUN.md`
- `CHANGELOG.md`
- `release-artifacts/latest/`

Validation:

- `forge test --match-contract StreamCoreCustomErrorsTest -vvv` passed with
5 tests covering `FunctionAdminUnauthorized()`,
`ArtistSignatureUnauthorized()`, `InvalidTokenMetadataInput()`, and
`FinalSupplyTimeNotPassed()`, plus `setFinalSupply` rejection when collection
data is missing.
- `forge build --sizes --via-ir --skip test --skip script --force` passed;
final measured `StreamCore` runtime size is 24,135 bytes with 441 bytes of
EIP-170 headroom.
- `make release-checksums` passed and regenerated release/deployment artifacts.
- `make check` passed.
- `powershell -ExecutionPolicy Bypass -File scripts\check.ps1` passed.
- `forge fmt --check smart-contracts\StreamCore.sol
test\StreamCoreCustomErrors.t.sol` passed.
- `git diff --check` passed, with only the known Windows line-ending warning
for `release-artifacts/latest/SHA256SUMS`.

Notes:

- A separate `burn` authorization custom-error experiment increased runtime
size by 20 bytes versus the first pass, so it was intentionally dropped.
- CodeRabbit found that `setFinalSupply` could reach final supply math for a
created collection with missing collection data. The fix now checks the
existing mutable collection boundary, rejects missing data with
`CollectionDataMissing(collectionId)`, and keeps the size floor above 384
bytes by collapsing duplicated `setCollectionData` writes through a storage
pointer.
- The recovery is intentionally narrow: no contract state layout, external
function signatures, event signatures, or successful-path behavior changed.

### PR #114: Collection URI production enforcement (Queue Item 60)

Status: Merged in PR #114.
Branch: `codex/metadata-collection-uri-policy`.
Pull request: `https://github.com/6529-Collections/6529Stream/pull/114`.

Expand Down Expand Up @@ -5430,6 +5489,12 @@ Outcome:

| Time UTC | Decision | Rationale |
| --- | --- | --- |
| 2026-06-11 19:17 | Validate PR #116 review fix locally | `make release-checksums`, `make check`, Windows `scripts\check.ps1`, targeted `forge fmt --check`, and `git diff --check` pass after the CodeRabbit fix; `git diff --check` reports only the known Windows line-ending warning on `release-artifacts/latest/SHA256SUMS` |
| 2026-06-11 19:09 | Address CodeRabbit PR #116 finding | `setFinalSupply` now rejects created collections with missing collection data before final supply math, the focused suite passes with 5 tests, and the production size gate measures `StreamCore` at 24,135 runtime bytes with 441 bytes of EIP-170 headroom |
| 2026-06-11 18:51 | Open PR #116 | `StreamCore` bytecode headroom recovery PR published at `https://github.com/6529-Collections/6529Stream/pull/116`; state-only follow-up records the PR URL before requesting CodeRabbit on the final head |
| 2026-06-11 18:48 | Validate Queue Item 61 locally | Focused custom-error regressions, production size gate, regenerated release artifacts, full `make check`, Windows wrapper, targeted formatting, and whitespace checks all pass; the final review-fix pass records `StreamCore` at 24,135 runtime bytes with 441 bytes of EIP-170 headroom |
| 2026-06-11 18:39 | Set interim `StreamCore` size policy | The local P1-SIZE-001 pass established a repo policy of 384 bytes as the minimum release floor and 512 bytes as the warning threshold for future non-trivial Core work; final review-fix measurement is 24,135 runtime bytes with 441 bytes of EIP-170 headroom |
| 2026-06-11 18:37 | Drop burn custom-error experiment | Replacing the `burn` owner/approval string revert with a custom error increased `StreamCore` runtime by 20 bytes versus the narrower pass, so the change was abandoned before documentation and tests |
| 2026-06-11 18:22 | Validate PR #114 outside-diff follow-up locally | Focused regressions, production size gate, regenerated release artifacts, full `make check`, Windows wrapper, targeted formatting, and whitespace checks all pass; `StreamCore` remains deployable at 24,545 bytes with 31 bytes of EIP-170 headroom |
| 2026-06-11 18:15 | Accept CodeRabbit PR #114 outside-diff findings | The zero-supply path still reverted via arithmetic panic on first initialization, and dependency registry swaps still accepted EOAs or zero addresses; both are fixed locally with typed errors/regressions while keeping `StreamCore` deployable at 24,545 bytes and 31 bytes of EIP-170 headroom |
| 2026-06-11 18:00 | Track PR #114 bytecode headroom risk | CodeRabbit correctly highlighted that `StreamCore` has only 61 bytes of EIP-170 margin after the review fix, so issue #115 and the roadmap now track recovering sustainable Core headroom before further non-trivial Core feature work |
Expand Down
Loading
Loading