Repository navigation
Description
Engineering closure — 2026-09-25
Engineering closure through 0.31 follows the maintainer’s September 25 instruction to skip #30 and exclude 0.32. Release version promotion, fresh distribution bundles, the final release gate and independent release review remain under #30. This closure neither transfers the 0.30 review waiver nor claims an independent security audit or published 0.31 release.
Commit 648bb836, boundary review and acceptance map, isolated attribution, and reproduction/coverage map reconcile the checklist below.
Accepted decisions — 2026-09-21
D1: retain transaction-success baselines and introduce explicit measurement availability in cost-report v2. Use the pinned detailed_run path for exact-group nonzero-exit cycles while normal verification remains the acceptance oracle. Require static call-chain stack bounds for closed acyclic graphs; unknown effects stay unknown. Per-VM observed stack instrumentation is deferred to a follow-up targeting 0.32. Freeze the expanded fixture matrix before accepting new static budgets.
Full decision record — baseline: 8d6e200caa58d81429912df925a9322f691cb41d; research baseline remains 6d75a6e7. The choices below were the original open questions; this decision record now governs implementation. The issue stays open until its implementation acceptance passes.
Parent: #30
Target: 0.31. Baseline: branch 0.30, commit 6d75a6e7e4ce55b940697428d895eda74a51ca86. Implementation and engineering acceptance are complete; the accepted decisions define the bounded scope and deferred work.
Problem and evidence
The current contract covers three matched Rust samples and 18 growth rows. It budgets ELF bytes, successful cycles, witness size, and the largest recorded individual frame. Rejection behavior is tested, but rejection-path cycle costs are not separately budgeted. Multirecord policies, generic-instantiation growth, broader composition, and call-chain stack peaks need additional evidence.
Sources: docs/CELLSCRIPT_COST_REGRESSION.md and tests/support/cost_growth.rs.
Decisions to record
- What exact programs and bounds belong in the 0.31 corpus? Start with wide constants, repeated/mixed policy parameter layouts, dense/sparse tags, multirecord envelopes, scalar live ranges, and repeated/distinct generic instantiations. Add only admitted executable compositions.
- Define a stack metric: VM-observed stack high-water mark, a conservative call-graph bound, or both. State handling of recursion, dynamic stack adjustment, external Script execution, and unknown bounds; report unsupported evidence explicitly.
- How are byte-versus-cycle regressions accepted? Prefer per-fixture absolute ceilings plus the existing matched-Rust ratios, with a written exception for any intentional tradeoff.
- Which malformed inputs represent expensive rejection paths? Bound input sizes and distinguish a measured maximum over fixtures from a proven worst-case bound.
- Does the report schema need a version change, and which CI/checker/report consumers need updating?
Acceptance
- Publish the agreed fixture matrix, metric definitions, and budget-review policy before using them to judge the other optimization issues.
- Preserve the existing 3 matched and 18 growth rows as comparable baselines, with source/compiler/toolchain identities.
- Add executed rejection-cycle cases: late tag lookup, last-byte mismatch, malformed envelope/length, and over-bound inputs where applicable.
- Add representative composition, generic-growth, and nested-call measurements within the supported surface.
- Store per-entry frame size separately from observed or statically bounded call-chain stack use; add meaningful checks of the new measurement method.
- Retain fresh machine-readable reports, fail on missing tooling/incomplete execution, and keep budgets reviewed and static rather than regenerated by tests.
- Run
./scripts/cellscript_gate.sh ci; also run./scripts/cellscript_gate.sh backendif backend instrumentation or artifact contracts change. - Report remaining gaps without claiming universal Rust equivalence or globally optimal costs.
Agree the metric definitions early. Extend the corpus alongside the backend work and use the completed reports for 0.31 acceptance.
Activity
a19q3 commentedon Sep 21, 2026
Research notes, 2026-09-21. CellScript source checked at
6d75a6e7. These are proposed experiments and decisions, not implementation results.The first task here is to make failure measurements observable. Adding another budget field to the current report would not be enough.
Current evidence gap
tests/support/ckb_script_runner.rs:523 gets successful cycles from
Context::verify_tx, but its error branch setscycles: 0. The result type even documents this behavior. Zero means unavailable on failure, not that rejection was free. New rejection-budget assertions must not accept it as measured evidence.Successful values from this path also cover transaction script verification, rather than isolating only the Script under study. Keep those existing figures for baseline continuity and add a separately named per-group metric.
A concrete upstream API to evaluate
Cargo.lock pins ckb-script 1.1.0, ckb-testtool 1.1.1, and ckb-vm 0.24.14. In the published ckb-script source, TransactionScriptsVerifier::detailed_run returns
TerminatedResult; that result contains bothexit_codeandconsumed_cycles. The ordinaryrunwrapper subsequently converts a nonzero exit into a validation error and loses those cycles from its return value.This offers a concrete experiment for ordinary nonzero script exits without injecting a new syscall or changing the contract. It still requires resolving the same transaction and selecting the exact group. Mirror the existing consensus/hardfork/VM configuration, and keep normal transaction validation as the acceptance oracle. The scheduler result includes its VMs, so document that scope for child execution.
A VM trap, setup failure, or cycle-limit exhaustion may still return an error rather than a terminated result. Represent unavailable measurements explicitly, or expose separately justified scheduler accounting. Do not silently substitute zero, the configured limit, or an unlabelled lower bound.
Proposed report and validation work
Suggested decision: use explicit measurement availability, preserve the old accounting scope, and prototype detailed_run before building custom instrumentation. Keep actual nonzero-exit costs distinct from fixture maxima and mathematically proven worst-case bounds.
a19q3 commentedon Sep 23, 2026
Review after the 0.31 implementation, 2026-09-23.
D1 is implemented at
65df937f: cost-report v2 distinguishes measured group exits from unavailable traps/setup/limit failures, retains transaction-success accounting, and reports static call-chain bounds separately from individual frames. Measurement regressions cover real nonzero-exit cycles, unavailable results and nested frames. CI at 65df937f passed, and the final local backend gate passed. The final implementation and validation record records 6,781 baseline comparisons without regression and 88,204 identical numeric fields between final local and GitHub reports.Remaining work is evidence packaging and review:
The child can close once the measurement contract, fixed ceilings and retrievable evidence receive review. “No regression in this corpus” must retain its bounded scope; it does not establish globally optimal code or universal Rust equivalence.
a19q3 commentedon Sep 25, 2026
Engineering acceptance complete at 648bb836.
Validation on clean commit
648bb8362a82586821c0d4ae9f8b2250dd56ab11: localdev, fullci, and fullbackendpassed; GitHub CI also passed and retains the fresh cost/shape/strict-audit artifacts. The final clean-source cost pair passes another 6,782-metric comparison against the archived candidate. The full backend gate rebuilt pinned CKBf7fa4436and passed the local-node 43-action, 17-Lock and 26-stateful-scenario matrix. Local acceptance report SHA-256:8a1aeb4221409f187e82a342c7335db19432a3fd800e9182e1c65806655a889c. This is local-node evidence, not a new public-network deployment.The frozen coverage map, baseline/candidate pair, isolated D2/D3 controls, source reconstruction and native comparison outputs are now durably tracked. Each comparison covers 6,782 comparable metrics without regression. The accepted matrix retains 3 matched and 18 growth rows, 41 policy rows, 9 scalar rows and 1,830 executions, plus 6 multi-Script transactions with 5 measured groups each. Source review confirmed exact-group selection, the normal transaction oracle, nonzero exit accounting and explicit unavailable results. Static call-chain tests include outgoing reservations and unknown effects; #36 owns observed per-VM peaks.
Boundary review / acceptance map · attribution and exact report pairs · frozen coverage and reproduction.
Engineering closure through 0.31 follows the maintainer’s September 25 instruction to skip #30 and exclude 0.32. Release version promotion, fresh distribution bundles, the final release gate and independent release review remain under #30. This closure neither transfers the 0.30 review waiver nor claims an independent security audit or published 0.31 release.