diff --git a/AGENTS.md b/AGENTS.md index 1b42d4f9..555f7d87 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -315,8 +315,11 @@ Existing command families to be aware of: - `proposals/novaseal` is a submodule (`NovaSeal.git`, branch `main`). Same for `proposals/evolving-dob/evolving-dob-profile-v1`. - `tools/ckb-tx-measure` depends on `../ckb/util/jsonrpc-types` and - `../ckb/util/types`; the gate builds the helper with CellScript's pinned - Rust 1.97.1 toolchain so its declared `rust-version` remains enforceable. + `../ckb/util/types`; when release validation receives `--ckb-repo`, the gate + stages the helper's tracked workspace under `target/` so those same relative + paths resolve to the explicit checkout. The gate builds the helper with + CellScript's pinned Rust 1.97.1 toolchain so its declared `rust-version` + remains enforceable. - `--primitive-strict 0.16` is the current production assurance gate; the README mentions it and the policy lives in `docs/`. diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f945f50..05aab5a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,16 @@ # Changelog -## Unreleased +## 0.24.0 - 2026-08-17 + +- Close the 0.24 audit blockers: reject transitive executable resolvers and + unsafe Git refs, bound and origin-bind Registry downloads, preserve exact + LS-IDL Type-script identity, and stop exposing unexpected service errors. + Restore a deliberate Clippy boundary for legacy explicit-context helpers, + align package identities with 0.24, and carry the closed 0.23 release and + NovaSeal evidence forward. +- Isolate every CKB-dependent gate check. The backend stateful wrapper accepts + `CELLSCRIPT_CKB_REPO`, and release modes propagate `--ckb-repo` to the staged + `ckb-tx-measure` workspace instead of silently using another sibling checkout. - Remove the unreachable external RISC-V toolchain fallback and make the audited internal assembler the sole ELF-emission path. Reassign `E2400` to diff --git a/Cargo.lock b/Cargo.lock index b92e72b7..1392a0df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -314,7 +314,7 @@ dependencies = [ [[package]] name = "cellscript" -version = "0.22.0" +version = "0.24.0" dependencies = [ "anyhow", "base64 0.22.1", @@ -354,7 +354,7 @@ dependencies = [ [[package]] name = "cellscript-artifact-checker" -version = "0.22.0" +version = "0.24.0" dependencies = [ "blake2b_simd", "clap", @@ -365,7 +365,7 @@ dependencies = [ [[package]] name = "cellscript-ckb-adapter" -version = "0.22.0" +version = "0.24.0" dependencies = [ "anyhow", "ckb-hash", @@ -388,7 +388,7 @@ dependencies = [ [[package]] name = "cellscript-fiber-adapter" -version = "0.22.0" +version = "0.24.0" dependencies = [ "anyhow", "camino", @@ -408,7 +408,7 @@ dependencies = [ [[package]] name = "cellscript-tools" -version = "0.22.0" +version = "0.24.0" dependencies = [ "anyhow", "blake2b-ref", @@ -431,7 +431,7 @@ dependencies = [ [[package]] name = "cellscript-wasm" -version = "0.22.0" +version = "0.24.0" dependencies = [ "cellscript", "serde", diff --git a/Cargo.toml b/Cargo.toml index 124516cd..b3566a61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ resolver = "3" [package] name = "cellscript" -version = "0.22.0" +version = "0.24.0" edition = "2024" rust-version = "1.97.1" autobins = false @@ -82,7 +82,7 @@ blake2b_simd = "1.0" toml = "0.8" hex = "0.4" semver = "1.0" -cellscript-artifact-checker = { version = "=0.22.0", path = "crates/cellscript-artifact-checker" } +cellscript-artifact-checker = { version = "=0.24.0", path = "crates/cellscript-artifact-checker" } indexmap = "=2.2.6" diff --git a/README.md b/README.md index 08cfc346..1891ec9d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@
[](https://github.com/CellScript-Labs/CellScript/actions/workflows/ci.yml) -[](https://github.com/CellScript-Labs/CellScript/releases/tag/v0.22.0) +[](https://github.com/CellScript-Labs/CellScript/releases/tag/v0.23.0) [](LICENSE-MIT) [](Cargo.toml) [](#target-profiles) @@ -20,8 +20,8 @@ artifacts, together with typed metadata for auditing, policy checks, schema binding, and scheduler-aware execution. The current stable release is -[CellScript v0.22.0](https://github.com/CellScript-Labs/CellScript/releases/tag/v0.22.0). -See the [0.22 release notes](docs/releases/CELLSCRIPT_0_22_RELEASE_NOTES.md) +[CellScript v0.23.0](https://github.com/CellScript-Labs/CellScript/releases/tag/v0.23.0). +See the [0.23 release notes](docs/releases/CELLSCRIPT_0_23_RELEASE_NOTES.md) for its shipped surface, evidence boundaries, and migration checklist. The completed 0.23 implementation scope is tracked in the [0.23 release notes](docs/releases/CELLSCRIPT_0_23_RELEASE_NOTES.md); those @@ -122,7 +122,7 @@ curl -fsSL https://raw.githubusercontent.com/CellScript-Labs/CellScript/main/scr Or pin a specific version: ```bash -CELLSCRIPT_VERSION=0.22.0 curl -fsSL https://raw.githubusercontent.com/CellScript-Labs/CellScript/main/scripts/install.sh | sh +CELLSCRIPT_VERSION=0.23.0 curl -fsSL https://raw.githubusercontent.com/CellScript-Labs/CellScript/main/scripts/install.sh | sh ``` The release page publishes `SHA256SUMS` alongside all four platform archives. @@ -130,7 +130,7 @@ The release page publishes `SHA256SUMS` alongside all four platform archives. Build the exact published source instead: ```bash -git clone --branch v0.22.0 --depth 1 https://github.com/CellScript-Labs/CellScript.git +git clone --branch v0.23.0 --depth 1 https://github.com/CellScript-Labs/CellScript.git cd CellScript cargo install --locked --path . ``` @@ -732,7 +732,7 @@ policy defaults: [package] edition = "2026" name = "token" -version = "0.22.0" +version = "0.24.0" entry = "src/main.cell" source_roots = ["src"] @@ -916,9 +916,11 @@ the manual, CI, recovery, and external-wallet path. - The default source-package authority is `https://api.registry.cellscript.dev`; only publicly accepted statuses enter ordinary version selection. `CELLSCRIPT_REGISTRY_API_URL` changes that API - origin, while `CELLSCRIPT_REGISTRY_URL` explicitly selects the legacy - Git/offline discovery authority. An unavailable production API does not - silently downgrade to Git discovery. + origin, and `CELLSCRIPT_REGISTRY_STATIC_ORIGIN` explicitly trusts a separate + immutable-object origin for a private Registry. Snapshot downloads are + origin-bound; a lockfile cannot redirect the client to an unrelated host. + `CELLSCRIPT_REGISTRY_URL` selects the legacy Git/offline discovery authority. + An unavailable production API does not silently downgrade to Git discovery. - Registry discovery may grow to include CellScript packages, verifier artifacts, deployed artifact records, reproducible artifacts, and external CKB tooling artifacts. Dependency resolution stays narrower than discovery. diff --git a/contracts/registry-type-script/Cargo.lock b/contracts/registry-type-script/Cargo.lock index 8e1964bd..2218782d 100644 --- a/contracts/registry-type-script/Cargo.lock +++ b/contracts/registry-type-script/Cargo.lock @@ -176,7 +176,7 @@ dependencies = [ [[package]] name = "cellscript-registry-type-script" -version = "0.22.0" +version = "0.24.0" dependencies = [ "ckb-hash", "ckb-std", diff --git a/contracts/registry-type-script/Cargo.toml b/contracts/registry-type-script/Cargo.toml index de75b24d..5be5777b 100644 --- a/contracts/registry-type-script/Cargo.toml +++ b/contracts/registry-type-script/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cellscript-registry-type-script" -version = "0.22.0" +version = "0.24.0" edition = "2024" rust-version = "1.97.1" publish = false diff --git a/contracts/registry-type-script/README.md b/contracts/registry-type-script/README.md index 6c26ae72..0926bcaa 100644 --- a/contracts/registry-type-script/README.md +++ b/contracts/registry-type-script/README.md @@ -43,7 +43,8 @@ Reproduce the canonical Linux artifact with the pinned container digest: contracts/registry-type-script/build_canonical_container.sh ``` -The deployable artifact is tracked under `artifacts/v0.22.0` and was produced +The current deployable artifact is tracked under `artifacts/v0.24.0`; the +identical historical release bytes remain under their versioned directories. It was produced for the `x86_64-unknown-linux-gnu` host with the builder image digest recorded in `release-manifest.json`. Rust/LLVM may order identical RISC-V functions differently on another build host, so the script claims a byte-for-byte diff --git a/contracts/registry-type-script/artifacts/v0.23.0/cellscript-registry-type-script b/contracts/registry-type-script/artifacts/v0.23.0/cellscript-registry-type-script new file mode 100755 index 00000000..9a756b8a Binary files /dev/null and b/contracts/registry-type-script/artifacts/v0.23.0/cellscript-registry-type-script differ diff --git a/contracts/registry-type-script/artifacts/v0.24.0/cellscript-registry-type-script b/contracts/registry-type-script/artifacts/v0.24.0/cellscript-registry-type-script new file mode 100755 index 00000000..623c30ac Binary files /dev/null and b/contracts/registry-type-script/artifacts/v0.24.0/cellscript-registry-type-script differ diff --git a/contracts/registry-type-script/release-manifest.json b/contracts/registry-type-script/release-manifest.json index 42689997..73466ccc 100644 --- a/contracts/registry-type-script/release-manifest.json +++ b/contracts/registry-type-script/release-manifest.json @@ -1,15 +1,15 @@ { "schema": "cellscript-registry-type-script-release-v1", - "version": "0.22.0", + "version": "0.24.0", "target": "riscv64imac-unknown-none-elf", - "artifact": "artifacts/v0.22.0/cellscript-registry-type-script", + "artifact": "artifacts/v0.24.0/cellscript-registry-type-script", "canonical_build_host": "x86_64-unknown-linux-gnu", "canonical_builder_image": "rust@sha256:77fac8b98f9f46062bb680b6d25d5bcaabfc400143952ebc572e924bcbedc3fa", "artifact_bytes": 3352, - "sha256": "6a7ab8eaa2281fe77ca8c7b092006c52f96006ac2c7e4b013f8f88b7bf1f742a", - "ckb_data_hash": "0x8b6de99567accdca438818a55c16534ed10fc335f117709b1487fd2666808bfb", + "sha256": "0f48a8736360c121f6ae0f04ab4b0496834f6715d47e3284a0a07add609dede9", + "ckb_data_hash": "0x0dd596ade29e06e5bcc00f56abf36ecbe9afaa09f1b26a64436aa37854da622b", "script_template": { - "code_hash": "0x8b6de99567accdca438818a55c16534ed10fc335f117709b1487fd2666808bfb", + "code_hash": "0x0dd596ade29e06e5bcc00f56abf36ecbe9afaa09f1b26a64436aa37854da622b", "hash_type": "data1", "args_schema": "ckb_script_hash(custody_lock)", "args_bytes": 32 diff --git a/contracts/registry-type-script/tests/ckb_vm.rs b/contracts/registry-type-script/tests/ckb_vm.rs index 31c02d11..03226587 100644 --- a/contracts/registry-type-script/tests/ckb_vm.rs +++ b/contracts/registry-type-script/tests/ckb_vm.rs @@ -22,7 +22,7 @@ struct Scripts { } fn contract_binary() -> Bytes { - let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("artifacts/v0.22.0/cellscript-registry-type-script"); + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("artifacts/v0.24.0/cellscript-registry-type-script"); std::fs::read(&path).unwrap_or_else(|error| panic!("read tracked canonical artifact {}: {error}", path.display())).into() } diff --git a/crates/cellscript-artifact-checker/Cargo.toml b/crates/cellscript-artifact-checker/Cargo.toml index 42affa58..16696998 100644 --- a/crates/cellscript-artifact-checker/Cargo.toml +++ b/crates/cellscript-artifact-checker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cellscript-artifact-checker" -version = "0.22.0" +version = "0.24.0" edition = "2024" rust-version = "1.97.1" description = "Bounded independent verifier for CellScript lowering records and CKB RISC-V artifacts" diff --git a/crates/cellscript-ckb-adapter/Cargo.toml b/crates/cellscript-ckb-adapter/Cargo.toml index 97f72ab1..5af32a89 100644 --- a/crates/cellscript-ckb-adapter/Cargo.toml +++ b/crates/cellscript-ckb-adapter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cellscript-ckb-adapter" -version = "0.22.0" +version = "0.24.0" edition = "2024" rust-version = "1.97.1" publish = false diff --git a/crates/cellscript-fiber-adapter/Cargo.toml b/crates/cellscript-fiber-adapter/Cargo.toml index b488bd48..0ec961fb 100644 --- a/crates/cellscript-fiber-adapter/Cargo.toml +++ b/crates/cellscript-fiber-adapter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cellscript-fiber-adapter" -version = "0.22.0" +version = "0.24.0" edition = "2024" rust-version = "1.97.1" publish = false diff --git a/crates/cellscript-tools/Cargo.toml b/crates/cellscript-tools/Cargo.toml index f3f71157..93664e1f 100644 --- a/crates/cellscript-tools/Cargo.toml +++ b/crates/cellscript-tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cellscript-tools" -version = "0.22.0" +version = "0.24.0" edition = "2024" rust-version = "1.97.1" publish = false diff --git a/crates/cellscript-tools/src/tooling_release.rs b/crates/cellscript-tools/src/tooling_release.rs index 2b740b4b..fdfc0036 100644 --- a/crates/cellscript-tools/src/tooling_release.rs +++ b/crates/cellscript-tools/src/tooling_release.rs @@ -470,6 +470,19 @@ pub fn run(root: &Path) -> Result<()> { !tx_measure_gate.contains("RUSTUP_TOOLCHAIN"), "CKB transaction measure tooling must use CellScript's pinned Rust toolchain", )?; + for token in [ + "release_ckb_repo_from_args() {", + "staging_dir=\"$(mktemp -d \"$ROOT_DIR/target/cellscript-ckb-tx-measure.XXXXXX\")\"", + "cp tools/ckb-tx-measure/Cargo.toml tools/ckb-tx-measure/Cargo.lock", + "cp src/bin/ckb_tx_measure.rs", + "ln -s \"$ckb_repo\" \"$staging_dir/ckb\"", + ] { + require(gate_script.contains(token), format!("release CKB checkout propagation is missing '{token}'"))?; + } + require( + gate_script.matches("run_release_auxiliary_checks \"$ckb_repo\"").count() == 2, + "release and release-quick must both propagate the selected CKB checkout to auxiliary checks", + )?; require( gate_script.contains("--root \"$ROOT_DIR\" workspace-version"), "release source identity must read the root package version from Cargo.toml", diff --git a/crates/cellscript-wasm/Cargo.toml b/crates/cellscript-wasm/Cargo.toml index 1afa4081..4533776d 100644 --- a/crates/cellscript-wasm/Cargo.toml +++ b/crates/cellscript-wasm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cellscript-wasm" -version = "0.22.0" +version = "0.24.0" edition = "2024" rust-version = "1.97.1" publish = false diff --git a/docs/CELLSCRIPT_CKB_ADAPTER.md b/docs/CELLSCRIPT_CKB_ADAPTER.md index 9955bab7..9e3d202b 100644 --- a/docs/CELLSCRIPT_CKB_ADAPTER.md +++ b/docs/CELLSCRIPT_CKB_ADAPTER.md @@ -524,7 +524,7 @@ cargo build -p cellscript-ckb-adapter --bin cellscript-deploy # Build the canonical Registry Type Script deployment for external signing export LOCK_ARG=0x$(cat ~/.ckb/default-lock-arg) # your secp256k1 lock arg cellscript-deploy --rpc http://127.0.0.1:8114 --json build-deploy \ - --artifact contracts/registry-type-script/artifacts/v0.22.0/cellscript-registry-type-script \ + --artifact contracts/registry-type-script/artifacts/v0.24.0/cellscript-registry-type-script \ --lock-arg $LOCK_ARG \ --name cellscript-registry-type-script \ --hash-type data1 \ diff --git a/docs/CELLSCRIPT_GATE_POLICY.md b/docs/CELLSCRIPT_GATE_POLICY.md index b88ed5f1..893c5be6 100644 --- a/docs/CELLSCRIPT_GATE_POLICY.md +++ b/docs/CELLSCRIPT_GATE_POLICY.md @@ -165,6 +165,18 @@ and validates every step's commit, spent-input liveness, live outputs, cycles, serialized size, and occupied capacity. `--stateful-scenarios` remains only as an explicit option for bounded runs. +The backend gate normally resolves that checkout as the sibling `../ckb` +directory. When that path is occupied by another development worktree, set +`CELLSCRIPT_CKB_REPO` to a separate clean checkout at the exact pinned revision; +the stateful wrapper forwards it as the acceptance harness's `--ckb-repo`. +This avoids modifying or stashing an unrelated CKB worktree during validation. + +For `release` and `release-quick`, pass the same checkout with `--ckb-repo`. +The release gate stages the independent `ckb-tx-measure` workspace under +`target/` with its tracked manifest, lockfile, and source so its relative CKB +dependencies resolve against that explicit checkout too. The default remains +the sibling `../ckb`; the tracked lockfile remains bound to the release pin. + The transaction matrix is produced by the native Rust acceptance harness and is intentionally labelled as recipe-replayer evidence, not generated-builder output. Separately, the gate runs the public `cellc action build` and diff --git a/docs/CELLSCRIPT_LS_IDL_REGISTRY_PROFILE.md b/docs/CELLSCRIPT_LS_IDL_REGISTRY_PROFILE.md index c877cbc6..70256812 100644 --- a/docs/CELLSCRIPT_LS_IDL_REGISTRY_PROFILE.md +++ b/docs/CELLSCRIPT_LS_IDL_REGISTRY_PROFILE.md @@ -107,10 +107,12 @@ uniquely identify executable data. More than one matching deployment returns The compatibility route is: ```text -GET /idl/:code_hash +GET /idl/:code_hash[?data_hash=0x...] ``` It is retained for existing LS-IDL clients and returns the same original +bytes for immutable `data`/`data1`/`data2` identities. A Type-hash candidate +still requires `data_hash`; code hash alone never selects upgradeable code bytes. New integrations should use the canonical route so network, hash type, and data-hash identity are explicit. diff --git a/docs/CELLSCRIPT_PACKAGE_PROVENANCE_AND_DEPLOYMENT_IDENTITY.md b/docs/CELLSCRIPT_PACKAGE_PROVENANCE_AND_DEPLOYMENT_IDENTITY.md index b3265c13..5bc7ad92 100644 --- a/docs/CELLSCRIPT_PACKAGE_PROVENANCE_AND_DEPLOYMENT_IDENTITY.md +++ b/docs/CELLSCRIPT_PACKAGE_PROVENANCE_AND_DEPLOYMENT_IDENTITY.md @@ -454,7 +454,7 @@ source_hash = "blake2b:0xabcd..." [package_build] edition = "2026" compatibility_profile_hash = "blake2b:0xprofile..." -compiler_version = "0.22.0" +compiler_version = "0.24.0" target_profile = "ckb" artifact_hash = "blake2b:0x1234..." metadata_hash = "blake2b:0x5678..." @@ -840,7 +840,7 @@ for audit, offline fixtures, and direct-Git fallback: "version": "1.2.0", "tag": "v1.2.0", "source_hash": "blake2b:0xabcd...", - "cellscript_version": "0.22.0", + "cellscript_version": "0.24.0", "dependencies": { "token": { "namespace": "cellscript", "version": "0.3.0" } }, diff --git a/docs/releases/CELLSCRIPT_0_24_RELEASE_NOTES.md b/docs/releases/CELLSCRIPT_0_24_RELEASE_NOTES.md index 8d9ac847..497fb65c 100644 --- a/docs/releases/CELLSCRIPT_0_24_RELEASE_NOTES.md +++ b/docs/releases/CELLSCRIPT_0_24_RELEASE_NOTES.md @@ -1,9 +1,9 @@ # CellScript 0.24 Development Release Notes -**Status**: implementation-complete merge candidate; `dev`, `ci`, and -`backend` passed on 2026-08-10. The refreshed iCKB evidence submodule commit -`0e18ccd97bd75cac7de9211dc8d344c0bc08942f` is published and bound by the -parent gitlink; the full release gate remains required before production claims +**Status**: audit-remediation merge candidate. The refreshed iCKB evidence +submodule commit `0e18ccd97bd75cac7de9211dc8d344c0bc08942f` is published and +bound by the parent gitlink. The merge gates must pass for the exact candidate, +and the full release gate remains required before production claims. **Source edition**: 2026 @@ -301,13 +301,11 @@ or conversion of executable/copy artifacts into source dependencies. ## Validation -The package/Registry closure passed `dev` and `ci` on 2026-08-10, with the CI -website phase using the required Node 22 toolchain. The complete `backend` gate -then passed from an isolated clean checkout containing the refreshed iCKB -differential evidence, pinned CKB revision -`f7fa4436737756f97a24e254f22c13a36316ecea`, and CKB SDK `v5.1.0`. This -covered the compiler tests, Clippy, full strict backend audit, all 218 iCKB -differential cases, and the production stateful CKB scenario harness: +The 2026-08-10 `dev`, `ci`, and `backend` results predated later changes on the +0.24 branch and are not evidence for this merge candidate. The exact audit-fix +snapshot must pass all three commands below in an isolated checkout using Node +22, CKB revision `f7fa4436737756f97a24e254f22c13a36316ecea`, and CKB SDK +`v5.1.0` before merge: ```bash ./scripts/cellscript_gate.sh dev diff --git a/docs/wiki/Tutorial-12-Phase1-Registry-End-to-End.md b/docs/wiki/Tutorial-12-Phase1-Registry-End-to-End.md index 7331f6ba..8e6dd282 100644 --- a/docs/wiki/Tutorial-12-Phase1-Registry-End-to-End.md +++ b/docs/wiki/Tutorial-12-Phase1-Registry-End-to-End.md @@ -294,7 +294,9 @@ curl --fail \ --output idl.json ``` -The compatibility route `/idl/:code_hash` returns the same original bytes. +The compatibility route `/idl/:code_hash` returns the same original bytes for +immutable hash types. Type-hash deployments require `?data_hash=0x...` even on +that route so an upgrade cannot resolve by code hash alone. The Registry proves the document schema, raw-byte digest, executable suffix, and deployment identity. It does not prove that the Lock Script correctly implements the interface, and it is not a security audit. See the diff --git a/docs/wiki/_Sidebar.md b/docs/wiki/_Sidebar.md index b82ceafa..94e80852 100644 --- a/docs/wiki/_Sidebar.md +++ b/docs/wiki/_Sidebar.md @@ -20,6 +20,7 @@ - [Spore and RGB++ Interoperability Boundaries](https://github.com/CellScript-Labs/CellScript/wiki/Spore-and-RGBPP-Interop-Boundaries) - [BIP340 Verifier CellDep ABI](https://github.com/CellScript-Labs/CellScript/blob/nightly-0.24/docs/CELLSCRIPT_SIGNATURE_VERIFIER_ABI.md) - [LS-IDL Registry Profile](https://github.com/CellScript-Labs/CellScript/blob/nightly-0.24/docs/CELLSCRIPT_LS_IDL_REGISTRY_PROFILE.md) +- [CellScript 0.23 Release Notes](https://github.com/CellScript-Labs/CellScript/blob/v0.23.0/docs/releases/CELLSCRIPT_0_23_RELEASE_NOTES.md) - [CellScript 0.22 Release Notes](https://github.com/CellScript-Labs/CellScript/blob/v0.22.0/docs/releases/CELLSCRIPT_0_22_RELEASE_NOTES.md) - [CellScript 0.24 Development Release Notes](https://github.com/CellScript-Labs/CellScript/blob/nightly-0.24/docs/releases/CELLSCRIPT_0_24_RELEASE_NOTES.md) - [Bounded Fiber Interoperability Guide](https://github.com/CellScript-Labs/CellScript/blob/nightly-0.24/examples/fiber/README.md) diff --git a/editors/vscode-cellscript b/editors/vscode-cellscript index 54bd33d2..0c9f426b 160000 --- a/editors/vscode-cellscript +++ b/editors/vscode-cellscript @@ -1 +1 @@ -Subproject commit 54bd33d2de2e9fe508818cad622a00e96a69f47f +Subproject commit 0c9f426bdc617c4847f38da68fc300586bcc1428 diff --git a/proposals/novaseal b/proposals/novaseal index 919f042f..e2ce6737 160000 --- a/proposals/novaseal +++ b/proposals/novaseal @@ -1 +1 @@ -Subproject commit 919f042f6e0c08aab31dd63fc99aec5d49e4e04d +Subproject commit e2ce6737741c7b13c682ad278bba19644aeed93f diff --git a/scripts/cellscript_ckb_stateful_scenarios.sh b/scripts/cellscript_ckb_stateful_scenarios.sh index 99e21945..625c86de 100755 --- a/scripts/cellscript_ckb_stateful_scenarios.sh +++ b/scripts/cellscript_ckb_stateful_scenarios.sh @@ -3,4 +3,12 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +if [[ -n "${CELLSCRIPT_CKB_REPO:-}" ]]; then + exec "$SCRIPT_DIR/ckb_cellscript_acceptance.sh" \ + --production \ + --stateful-scenarios \ + --ckb-repo "$CELLSCRIPT_CKB_REPO" \ + "$@" +fi + exec "$SCRIPT_DIR/ckb_cellscript_acceptance.sh" --production --stateful-scenarios "$@" diff --git a/scripts/cellscript_gate.sh b/scripts/cellscript_gate.sh index 574a9d94..4878be33 100755 --- a/scripts/cellscript_gate.sh +++ b/scripts/cellscript_gate.sh @@ -477,8 +477,50 @@ check_wasm_release_bundle() { fi } +release_ckb_repo_from_args() { + local ckb_repo="$ROOT_DIR/../ckb" + while (($# > 0)); do + case "$1" in + --ckb-repo) + if (($# < 2)); then + printf 'missing value for --ckb-repo\n' >&2 + return 2 + fi + ckb_repo="$2" + shift 2 + ;; + *) + shift + ;; + esac + done + printf '%s\n' "$ckb_repo" +} + check_ckb_tx_measure_tool() { - run cargo test --manifest-path tools/ckb-tx-measure/Cargo.toml --locked + local ckb_repo="$1" + local default_ckb_repo="$ROOT_DIR/../ckb" + if [[ ! -d "$ckb_repo" ]]; then + printf 'CKB checkout does not exist: %s\n' "$ckb_repo" >&2 + return 1 + fi + ckb_repo="$(cd "$ckb_repo" && pwd -P)" + if [[ -d "$default_ckb_repo" ]]; then + default_ckb_repo="$(cd "$default_ckb_repo" && pwd -P)" + if [[ "$ckb_repo" == "$default_ckb_repo" ]]; then + run cargo test --manifest-path tools/ckb-tx-measure/Cargo.toml --locked + return + fi + fi + + local staging_dir + staging_dir="$(mktemp -d "$ROOT_DIR/target/cellscript-ckb-tx-measure.XXXXXX")" + mkdir -p "$staging_dir/cellscript/tools/ckb-tx-measure" "$staging_dir/cellscript/src/bin" + cp tools/ckb-tx-measure/Cargo.toml tools/ckb-tx-measure/Cargo.lock \ + "$staging_dir/cellscript/tools/ckb-tx-measure/" + cp src/bin/ckb_tx_measure.rs "$staging_dir/cellscript/src/bin/" + ln -s "$ckb_repo" "$staging_dir/ckb" + run cargo test --manifest-path "$staging_dir/cellscript/tools/ckb-tx-measure/Cargo.toml" --locked } check_novaseal_rust_tooling() { @@ -608,6 +650,7 @@ run_backend_gate() { } run_release_auxiliary_checks() { + local ckb_repo="$1" require_cmd npm run cargo run --quiet --locked -p cellscript-tools --bin cellscript-tools -- \ @@ -616,7 +659,7 @@ run_release_auxiliary_checks() { check_ckb_release_docs check_ckb_acceptance_boundaries check_novaseal_acceptance_boundaries - check_ckb_tx_measure_tool + check_ckb_tx_measure_tool "$ckb_repo" check_novaseal_rust_tooling check_novaseal_verifier_pinning check_wasm_release_bundle @@ -628,18 +671,22 @@ run_release_auxiliary_checks() { } run_release_quick_gate() { + local ckb_repo + ckb_repo="$(release_ckb_repo_from_args "$@")" check_release_source_identity run_ci_gate - run_release_auxiliary_checks + run_release_auxiliary_checks "$ckb_repo" run ./scripts/ckb_cellscript_acceptance.sh --compile-only --production "$@" printf '\nCellScript backend shape report: %s\n' "$CELLSCRIPT_BACKEND_SHAPE_REPORT" printf 'CellScript Molecule schema manifest report: %s\n' "$CELLSCRIPT_MOLECULE_SCHEMA_MANIFEST_REPORT" } run_release_gate() { + local ckb_repo + ckb_repo="$(release_ckb_repo_from_args "$@")" check_release_source_identity run_ci_gate - run_release_auxiliary_checks + run_release_auxiliary_checks "$ckb_repo" run ./scripts/ckb_cellscript_acceptance.sh --production --stateful-scenarios "$@" printf '\nCellScript backend shape report: %s\n' "$CELLSCRIPT_BACKEND_SHAPE_REPORT" printf 'CellScript Molecule schema manifest report: %s\n' "$CELLSCRIPT_MOLECULE_SCHEMA_MANIFEST_REPORT" diff --git a/services/registry-api/README.md b/services/registry-api/README.md index 81731554..51c5a352 100644 --- a/services/registry-api/README.md +++ b/services/registry-api/README.md @@ -174,7 +174,8 @@ The canonical LS-IDL lookup returns `application/vnd.ckb.ls-idl+json` plus digest, coordinate, commitment, and verification headers. `data_hash` is required for `hash_type=type`; ambiguous matches return `409`. `/idl/:code_hash` is a compatibility route for existing -clients and returns the same exact raw bytes. +clients and returns the same exact raw bytes for immutable hash types; a +Type-hash candidate still requires `?data_hash=0x...`. ## Publisher Authorisation @@ -325,6 +326,9 @@ cellc publish --artifact-manifest Artifact.toml ``` `CELLSCRIPT_REGISTRY_API_URL` overrides the API base URL. +`CELLSCRIPT_REGISTRY_STATIC_ORIGIN` declares a separate trusted object origin +for private registries; source snapshots are rejected unless their origin is +the configured API/static origin or the production/testnet static origin. `CELLSCRIPT_CAPABILITY_PRIVATE_KEY_PKCS8_B64` supplies the delegated key in CI. `CELLSCRIPT_REGISTRY_IDEMPOTENCY_KEY` pins the exact retry key. diff --git a/services/registry-api/src/index.ts b/services/registry-api/src/index.ts index af3155b6..54851a8c 100644 --- a/services/registry-api/src/index.ts +++ b/services/registry-api/src/index.ts @@ -201,7 +201,7 @@ export function registryRuntimeConfig(env: Env): RegistryRuntimeConfig { throw new ApiError(503, "invalid_registry_environment", "REGISTRY_ENVIRONMENT must be production or testnet-sandbox"); } export const CANONICAL_REGISTRY_TYPE_SCRIPT = Object.freeze({ - code_hash: "0x8b6de99567accdca438818a55c16534ed10fc335f117709b1487fd2666808bfb", + code_hash: "0x0dd596ade29e06e5bcc00f56abf36ecbe9afaa09f1b26a64436aa37854da622b", hash_type: "data1", }); export const CKB_MAINNET_SIGHASH_LOCK = Object.freeze({ @@ -722,7 +722,7 @@ async function handleLsIdlRead( } const candidate = candidates[0]!; const deployment = candidate.deployment.evidence; - if (!compatibilityRoute && deployment["hash_type"] === "type" && !dataHash) { + if (deployment["hash_type"] === "type" && !dataHash) { throw new ApiError( 409, "ls_idl_data_hash_required", @@ -4700,7 +4700,7 @@ function errorResponse(error: unknown, requestId: string): Response { const headers = corsHeaders(requestId); const status = error instanceof ApiError ? error.status : 500; const code = error instanceof ApiError ? error.code : "internal_error"; - const message = error instanceof Error ? error.message : "internal error"; + const message = error instanceof ApiError ? error.message : "internal server error"; return json({ request_id: requestId, error: { code, message } }, status, headers); } diff --git a/services/registry-api/test/registry-api.test.ts b/services/registry-api/test/registry-api.test.ts index 8f375c5d..d427890c 100644 --- a/services/registry-api/test/registry-api.test.ts +++ b/services/registry-api/test/registry-api.test.ts @@ -667,7 +667,7 @@ async function completeBrowserAuthorisationSession( }, {}, { authorization: `Bearer ${browserToken}` }); } -async function lsIdlLookupApp(idlBytes: Uint8Array) { +async function lsIdlLookupApp(idlBytes: Uint8Array, hashType: "data1" | "type" = "data1") { const store = new MemoryRegistryStore(); const idl = new TextDecoder().decode(idlBytes); const digest = await sha256Hex(idlBytes); @@ -718,7 +718,7 @@ async function lsIdlLookupApp(idlBytes: Uint8Array) { network: "mainnet", code_hash: codeHash, data_hash: codeHash, - hash_type: "data1", + hash_type: hashType, dep_type: "code", }, request_id: "test", @@ -773,6 +773,23 @@ describe("registry api", () => { expect(await formal.text()).toBe(idl); }); + it("requires exact code-cell data identity for Type-hash LS-IDL compatibility reads", async () => { + const idl = "{\"witness\":[]}\n"; + const { app, codeHash } = await lsIdlLookupApp(new TextEncoder().encode(idl), "type"); + + const ambiguous = await get(app, `/idl/${codeHash.slice(2)}`); + expect(ambiguous.status).toBe(409); + expect((await ambiguous.json() as any).error.code).toBe("ls_idl_data_hash_required"); + + const compatibility = await get(app, `/idl/${codeHash.slice(2)}?data_hash=${codeHash}`); + expect(compatibility.status).toBe(200); + expect(await compatibility.text()).toBe(idl); + + const formal = await get(app, `/v1/ckb/scripts/${codeHash}/interfaces/ls-idl?hash_type=type&data_hash=${codeHash}`); + expect(formal.status).toBe(200); + expect(await formal.text()).toBe(idl); + }); + it.runIf(Boolean(process.env.CELLSCRIPT_CKB_IDL_CLIENT_REPO))( "interoperates with the pinned upstream Rust client over the compatibility route", async () => { @@ -2803,7 +2820,10 @@ describe("registry api", () => { ); expect(response.status).toBe(500); - expect((await response.json() as any).error.code).toBe("internal_error"); + const internalError = await response.json() as any; + expect(internalError.error.code).toBe("internal_error"); + expect(internalError.error.message).toBe("internal server error"); + expect(JSON.stringify(internalError)).not.toContain("static registry object write failed"); expect(store.packageVersions.get("cellscript/demo@1.2.3")?.availability_status).toBe("active"); expect(store.auditEvents.some((event) => event.event_type === "admin.package_version.status_updated")).toBe(false); const staticEntryWrites = snapshots.filter((snapshot) => snapshot.key === "artifacts/cellscript/demo/releases/1.2.3.json"); diff --git a/services/registry-api/wrangler.example.toml b/services/registry-api/wrangler.example.toml index f17f8445..9852a727 100644 --- a/services/registry-api/wrangler.example.toml +++ b/services/registry-api/wrangler.example.toml @@ -24,7 +24,7 @@ CLEANUP_QUOTA_EVENT_RETENTION_HOURS = "48" NAMESPACE_CLAIM_COOLDOWN_SECONDS = "3600" CKB_REGISTRY_SCAN_MAX_CELLS = "1000" # Enable only after the canonical mainnet Registry Type Script is deployed. -# REGISTRY_TYPE_SCRIPT_JSON = '{"code_hash":"0x8b6de99567accdca438818a55c16534ed10fc335f117709b1487fd2666808bfb","hash_type":"data1","args":"0x