Repository navigation
[0.32][ZK] Prioritize application tooling, multi-Cell binding and verifier lifecycle #42
Description
Completed P1 and planning disposition — 2026-10-12
P1 is implemented and published on 0.32. The clean-source CCC application and migration record and its manifest bind signed source bfb1910070d90a15e6268796a0e329e584806305, pinned local CKB, native/CCC workflows, actual fee signatures, confirmed predecessor continuity, interrupted proving recovery and named rejection cases.
On 2026-10-12 the five archived files were retrieved from their pinned Git objects and both compressed/stored and raw sizes/SHA-256 identities were rechecked against the manifest. The application's contracts/zk-private-counter, native client and examples/zk sources are unchanged between that accepted source and published 16b9e583. The current focused native migration replay also passes. The earlier comments describing unpublished changes and absent clean-backend evidence are superseded.
The continuous flow is old-key update -> OLD-key-authorized migration consuming that actual predecessor -> new-key update of the committed successor. New-key self-installation, old-key reuse, replay, stale configuration, repeated migration and raw-transaction mutation reject. Immutable legacy Cells remain non-migratable. Public owner/counter/configuration and transaction linkage are explicitly documented; privacy and setup admission are not inferred from proof validity.
The maintainer instructed this work to run no CI or gates. No new gate execution is claimed here. Historical clean-source backend/dev evidence retains its recorded source scope; full CI/backend also completed for published 16b9e583 before this instruction. Both migration keys in the CCC replay are explicit public-test fixtures; no production setup, public deployment or external review is claimed.
P2, P3 and P4 retain the full scoped work in #44, #45 and #46, which remain open. This satisfies #42's stated completion rule: executable P1 plus linked scoped follow-ups with priorities/blockers, without claiming those follow-ups are finished.
Objective
Make the first exact ZK profile usable for complete CellScript applications: reproducible proving, reliable transaction construction, explicit state binding and diagnosable failures.
Follow-up to #22 and its 0.32 direction after Cecilia's review, informed by her implementation feedback.
Target: 0.32, as promoted by the maintainer on 2026-10-04. The completion contract remains executable P1 evidence plus accepted outcomes or linked, scoped follow-ups for P2–P4. This does not declare the first profile released or waive remaining acceptance conditions. Work is maintainer-led on the CellScript side; no deliverables are assigned to Cecilia.
Prerequisite: finish the first profile
#22 owns initial circuit/statement binding, exact verifier and VK identities, canonical codecs, bounded Spawn/IPC, result enforcement, compiler/checker/builder/editor agreement and stateful acceptance. Any unfinished item stays a prerequisite.
Initial dependency pinning, setup provenance, resource bounds and independent review also belong there. The lifecycle work below extends those foundations across versions.
Priority and dependency map
Start with the SDK and one complete application. Use their evidence to select broader semantics and optimizations.
flowchart TD
A["#22: admitted exact profile and transaction evidence"] --> B["P1: SDK and prover workflow"]
B --> C["P1: complete reference application"]
C --> D["P2: bounded multi-Cell transitions"]
B --> E["P3: circuit and verifier lifecycle"]
C --> E
C --> F["Measured application bottlenecks"]
D --> F
F --> G["P4: performance and additional proof profiles"]
P3 can proceed alongside P2 once the first application exposes its upgrade requirements. Broader implementation needs a scoped decision, named implementer/reviewer and acceptance budget.
P1 — SDK and a complete reference application
Provide a versioned statement contract that drives builder encoding, prover inputs and on-chain public-input derivation, with shared vectors checked by independent consumers.
The workflow must define:
- which transaction fields freeze before proving, which may change, and what invalidates a proof;
- coin selection, fees, change, output order and witness ownership;
- bounded external prover invocation, pinned tools, cancellation/timeouts and protection of private witness data from logs;
- final public-input recomputation, proof placement, signing and dry-run in the required order.
Choose one initial application: a private committed-state update is the default candidate. Exercise creation, proof generation, update, stale-state rejection, recovery and migration. Specify what is public and what privacy is actually claimed.
Acceptance:
- Reproduce the complete flow from a clean checkout with exact artifacts and shared vectors.
- Mutating a bound field invalidates the proof workflow; changes to permitted unbound fields preserve the stated contract.
- Recover from stale inputs or interrupted proving without signing a mismatched transaction.
- Explain failures by stage: statement derivation, encoding, verifier identity, proof verification or transaction validation.
- Review public-input and transaction-linkage leakage separately from proof validity.
P2 — Bounded multi-Cell state transitions
Extend the single-state profile only through explicit cardinalities and roles. Specify canonical source/index ordering, input-set completeness, output correspondence, duplicate rejection and fee/change exclusions. Reuse #7/#8 lifecycle rules and #9/#10 composition.
Where an application uses nullifiers, specify uniqueness enforcement and concurrent-update behavior. Measure whether a shared state Cell creates contention and document the chosen state layout.
Acceptance:
- Insertion, omission, duplication, substitution and reordering of relevant Cells have specified outcomes and executable negative tests.
- Every protected input and successor is accounted for on chain.
- Same-proof replay and concurrent conflicting transitions reject under the application policy.
- Maximum admitted cardinalities have measured cycles, memory, witness and transaction-size budgets.
P3 — Circuit, key and verifier lifecycle
Bind circuit source/compiled identity, VK, applicable setup transcript, prover toolchain, codecs and deployed verifier bytes in versioned manifests. Keep large proving artifacts outside ordinary compilation.
Build change-impact and migration tooling on the existing package, exact-handle and upgrade-plan boundaries (#11/#20). Answer explicitly whether old Cells remain spendable, old proofs remain usable and a change requires reproving or state migration. Type ID or interface compatibility alone cannot authorize a new verifier.
Acceptance:
- Wrong circuit/VK, codec drift, verifier substitution and downgrade are rejected.
- An upgrade exercise covers old-state spending and authorized migration with reproducible evidence.
- Deployment, circuit/setup trust and package discovery remain separate authorities.
P4 — Performance and additional proof profiles
Measure local proving time/memory alongside parent/child/total CKB cycles, proof/PI/VK bytes, deployed capacity and full transaction size. Keep valid, late-invalid and largest admitted cases.
Use those measurements to choose whether to optimize transport, add another proof system, or investigate batching/aggregation/recursion. Every additional profile needs its own identity, decoding, statement, trust and resource contract; a shared API must retain those distinctions.
Acceptance:
- Publish reproducible per-case measurements and explicit adopt/reject/defer decisions.
- Demonstrate application benefit without weakening bindings or changing budgets merely to pass.
- Preserve the [0.32][Research] Find remaining ELF/cycle costs and measure the optimization frontier #40 cost baseline and existing outcomes; separately budget the new ZK corpus.
Completion and boundaries
Close this planning issue when P1 has executable evidence and each remaining track has either an accepted implementation outcome or a linked, scoped follow-up with its priority and blocker. Do not close it merely because a roadmap was written.
Use the unified dev gate for implementation, backend for ABI/IR/codegen/ELF changes, CI for merge-readiness and fresh release evidence before production claims. Compiler structural acceptance, circuit correctness, setup integrity, proof-system security and application privacy remain separate claims.
A circuit DSL, open verifier registry and arbitrary runtime-selected roles are outside this plan. #28/#29 are optional later extensions, not prerequisites for the exact-profile SDK or reference application.
Scoped follow-ups — 2026-10-05
The duplicate check covered open and closed issues, including #7–#11, #20, #22, #35 and #40. The following 0.32 issues own the remaining tracks with explicit priorities, blockers and acceptance criteria:
| Track | Follow-up | Priority and boundary |
|---|---|---|
| P2 | #44 | After the complete P1 application; bounded protected-set/statement binding extends existing lifecycle and exact composition |
| P3 | #45 | After P1's first executable authorized migration; general cross-version circuit/key/verifier lifecycle extends #11/#20/#22 |
| P4 | #46 | Measure the reproducible single-state application first; add P2 cases when available, and decide profiles from evidence |
These are scoped implementation/research follow-ups, not claims that their acceptance checkboxes have passed. P1's initial migration remains mandatory; its continuous old-state/new-state execution is now evidenced by the completion record above. New-instance creation is not used as migration evidence. The separate finance program #43 is unchanged.
Activity
[-][Post-0.32][ZK] Prioritize application tooling, multi-Cell binding and verifier lifecycle[/-][+][0.32][ZK] Prioritize application tooling, multi-Cell binding and verifier lifecycle[/+]a19q3 commentedon Oct 4, 2026
0.32 implementation progress; this issue remains open.
Commit 622c8505 hardens the existing native and CCC reference clients:
Validation of this increment included the unified
devgate, the native/real-proof walkthrough, nine TypeScript client tests, and the pinned-node flow with two confirmed updates. Cancellation/retry and witness-substitution cases passed; a corrupted proof reached the intended parent verification failure (error 79, input Type group index 0). These are local fixture-chain results, not a public deployment or privacy audit.The next increment adds a checked executable digest before reading private witness data, then executes a private copy of those checked bytes; its eleven TypeScript tests and pinned-node replay have passed locally and publication is pending.
P1 is not complete: the current immutable, non-burnable lifecycle requires the same successor Type Script, so creating a fresh counter or changing SDK configuration does not migrate existing Cells. Authorized migration needs its own executable old-state/new-state contract. P2–P4 now have linked scoped follow-ups: #44 (multi-Cell binding), #45 (cross-version lifecycle) and #46 (application costs/profile decisions). Their creation does not complete P1 or claim that those implementations have passed acceptance. #28/#29 remain independent of this exact-profile application.
a19q3 commentedon Oct 5, 2026
The first authorized migration now has an executable local prototype; #42 remains open.
Two new immutable data2 Scripts implement the contract in
contracts/zk-private-counter/MIGRATION.md: a counter lifecycle and a unique configuration guard with exactly two pinned parent hashes and one allowed 0 -> 1 switch. The migration consumes the actual counter/configuration inputs and must be authorized by the OLD parent's owner proof over the final raw transaction. The new parent cannot authorize its own installation. This is application-level work using the existing circuit/statement interface; no open handles or new CellScript syntax were added.The continuous all-Script-group test executes creation, an old-VK update, old-proof-authorized migration, and an update of the actual successor under a different VK. Its 39 cases include new-VK self-installation, old-VK use after migration, replay, configuration-only spending, input/dependency overlap, missing/ambiguous parent code, custody changes, burn/duplicate successors, rollback and a second migration. Custody mutations receive a freshly valid owner proof when necessary, so they reach the intended guard instead of merely failing on a stale transaction hash. A separately created legacy instance rejects migration at its existing burn error 94; the legacy lifecycle ELF remains byte-identical.
The maximum case covers 64 inputs, 64 outputs, 64 dependencies and a 16,384-byte transaction. Each one-past limit rejects. Complete transaction execution consumes 111,064,375 cycles under the pre-frozen 250,000,000 ceiling. Independent instruction replay agrees with authoritative group execution and records separate stack peaks: lifecycle 1,584 bytes; EXEC parent 7,152; verifier child 20,208; configuration guard 1,664. Allocator budgets are not reported as measured heap peaks. The two new ELFs are 67,536 and 65,024 bytes and reproduce across the independent build directories.
The unified
devgate passes for the local snapshot based on622c850550428bbe000017c1b55944a9248717cd, tracked diff SHA-256b6e8584d7b5dfdb7157a2e95c001ea35ac89ac0d8e928a1dcdb570a059035bac, with 26 additional files captured by per-file hashes. The source snapshot was unchanged across the gate; reports and a replayable source/fixture archive were retained locally. These changes are not yet committed/published while the repository's GPG signing key remains locked.P1 is not complete. Native/CCC migration manifest and workflow integration, node liveness/commit/stale-configuration evidence, final CI/clean-backend validation and migration-profile admission remain outstanding. This run used the existing local single-party setup for the old VK and explicitly non-production public test parameters for the second VK. Testtool's Cell bookkeeping is not node liveness evidence, and the original application's admission does not admit the new Scripts. #44–#46 retain their separate scopes.
a19q3 commentedon Oct 5, 2026
The fixed-pair migration now has native client integration; #42 remains open.
cellscript-zk-counter-client::migrationloads a bounded, versioned manifest against an externally trusted digest and observed chain/genesis. It checks actual lifecycle/guard/child/VK bytes, setup/circuit identities and both freshly generated exact parents. The manifest pins the COMPLETE counter and configuration Scripts, including Type IDs: another internally consistent pair using the same code and parents cannot substitute for the intended instance. The manifest and public-test setup records do not admit themselves for production.The client validates the finalized creation transaction, recomputing both Type IDs from the actual first input and output positions. For updates/migration it checks ordered input resolution, bounded code/dep-group expansion, configuration dependency versus input/output exclusivity, custody and the single 0 -> 1 transition. The actual configuration selects the proof parent; callers cannot replace its compiled metadata, handle or VK at proof attachment. Required artifact bytes must be unique at the pinned OutPoints, and the exact child must occupy resolved dependency slot 0.
The existing proof/signature snapshot protections are reused, including clearing the accepted snapshot after failed proof attachment. Complete transaction limits are checked again after proof insertion and wallet signing. Negative cases cover network/manifest/code/instance substitution, changed creation coordinates, configuration rollback/custody/overlap, missing or ambiguous dependency bytes, dep-group expansion, raw/non-Lock witness mutation and oversized proof/signature witnesses.
The application test now exports its three actual continuous transactions and proofs. The native client consumes them and reproduces byte-identical proof attachment for old-key update, old-key-authorized migration and new-key successor update; every transaction executes all Script groups successfully in CKB-VM. This includes native preparation at the frozen 64-Cell and 16,384-byte limits. Client tests and strict clippy pass, and the unified
devgate passes, including the producer/client sequence, ELF reproduction and separate resource replay. The source snapshot was unchanged across that gate.Evidence remains local, based on
622c850550428bbe000017c1b55944a9248717cd: tracked diff SHA-256cf898540f2dbcd23bc99c81823eb5b20d1204d3524cdad5948e44eb1d4c9a4b8, plus 28 additional files recorded by per-file hashes. The complete source manifest SHA-256 is090dd27a87be8bf0ab7f00e06d6f4e61d9b84e284352f5e0ff76af1e811d4638. Source, fixtures, manifests and reports are preserved in a replay archive. The signing key is still uncached, so this is not a published commit. An earlier dev run was deliberately terminated before adding full instance binding; only the subsequent unchanged-source run is reported as passing.P1 still requires CCC migration workflow integration, continuous node commitment and stale-configuration evidence, final CI/clean-backend validation and explicit migration-profile admission. Native provider observations and testtool bookkeeping do not prove liveness. The second key in this run uses public test parameters; no production or public deployment claim is made. #44–#46 retain their separate scopes.
a19q3 commentedon Oct 5, 2026
The paired application now has a CCC migration workflow, runnable CLI and confirmed pinned-node successor lineage. #42 remains open while final validation/publication is outstanding.
MigrationDeploymentconsumes the native manifest format and pins the complete instance Scripts, both SDK/handle bindings, network and both versions' live artifacts. The adapter expands actual code/dep-group dependencies, derives the old configuration's selected parent, preserves both state Cells' custody and reserves proof space before wallet preparation/fees. Inputs, configuration dependencies and artifacts are checked again before signing and before dry-run. It reuses the original proof/cancellation/signature snapshot flow; the legacy client's eleven tests and its original node flow still pass.Six CCC migration tests cover actual native/CCC statement and transaction-byte parity across all three transitions, manifest/SDK/instance substitution, custody/rollback/overlap, ambiguous code, bounded dep-group expansion, stale configuration before wallet invocation, witness limits and caller mutation of snapshots. The standalone runner generates both SDKs from the native exports and is included in the CI walkthrough. The developer guide documents the API and CLI, fixed successor order, separate fee inputs, uncertain-confirmation recovery and privacy boundaries: owner commitment, counter, parent versions and the switch remain public and linkable.
The final node run confirmed creation followed by old-key update, OLD-key-authorized migration and new-key update of the actual committed successor. Every update has a real secp256k1 fee signature and normal
send_transactionadmission. A new-key proof cannot install itself, and an old-key proof cannot update after migration; both reach the real node and reject at parent error 79. Dead predecessors, the live configuration successor, stale configuration and a second-migration attempt are checked explicitly.All remain below the frozen 250,000,000-cycle / 16,384-byte ceilings. These node measurements are separate from the existing maximum-size testtool resource replay.
The unified
devgate passes, including native client/contract tests, reproduction and separate resource replay. Source was unchanged across the successful dev run. Its baseline is622c850550428bbe000017c1b55944a9248717cd, tracked diff SHA-2563a30e2d16896a4932a8add558d67b84a87725b64afde14584e20ec8edd6206d1, with 34 additional files hashed individually; complete source-manifest SHA-2564131dc08277dc2dd5ccee2c1f8126e836bba50e35b85500c2e2f8176fe75d53d. The node snapshot differs only by a later test-export iterator cleanup required by Clippy; client/contract/node execution sources did not change. Both snapshots, the exact delta and reports were retained. A SIGTERM-interrupted node attempt is not counted as passing; the subsequent completed run is the evidence above.Full CI is now running; clean-backend and signed source publication remain outstanding. The signing key is still uncached. The second setup in this run is explicitly a public test fixture. Neither these results nor the original profile's admission admit the new migration setup or claim a public deployment. #44–#46 keep their separate scopes.
a19q3 commentedon Oct 5, 2026
The full unified
./scripts/cellscript_gate.sh cihas now completed successfully for the migration/client snapshot described above. The source manifest was byte-identical before and after the gate: base622c850550428bbe000017c1b55944a9248717cd, tracked diff SHA-2563a30e2d16896a4932a8add558d67b84a87725b64afde14584e20ec8edd6206d1, 34 additional files with individual hashes, complete source-manifest SHA-2564131dc08277dc2dd5ccee2c1f8126e836bba50e35b85500c2e2f8176fe75d53d.This includes the original eleven CCC tests and all six migration tests through the generated-SDK walkthrough, native/contract tests and resource replay, strict backend CI-mode auditing, package verification, Registry services and the website. The completed gate log SHA-256 is
382e5831edf2be98edd1f61d982439b5bd96fb15a0b59059041ff8176719efac; it and both source snapshots were added to the retained replay archive without replacing the prior node evidence.Keeping #42 open for signed source publication and fresh clean-source full backend acceptance. CI-mode auditing is not that full backend gate. The second setup remains a public test fixture, with no new setup admission or public deployment claim. Subsequent #28 checker work will have its own source identity and validation; this CI pass is not attributed to future changes.