-
Notifications
You must be signed in to change notification settings - Fork 0
Tutorial 06 Metadata Verification and Production Gates
Every CellScript artifact should be treated as a pair:
artifact
artifact.meta.json
The artifact is executable RISC-V assembly or ELF. The metadata sidecar is the explanation: source identity, target profile, artifact hash, schema layout, runtime requirements, scheduler information, and verifier obligations.
This chapter is about trust boundaries. It teaches you what compiler evidence can prove, and where you still need CKB transaction evidence.
Compiler verification is necessary, but it is not the same thing as a deployed transaction or chain acceptance report.
If verify-artifact passes, you know the artifact and metadata agree. You do
not yet know that a transaction builder can provide the right inputs, serialize
the right witness, satisfy capacity, pass dry-run, and commit.
That distinction prevents overclaiming.
Compile normally:
cellc build --jsonOr request metadata directly:
cellc metadata src/main.cell --target riscv64-elf --target-profile ckb -o /tmp/main.meta.jsonOpen the metadata when something is unclear. It is often easier to understand a compiler decision by reading the emitted facts than by guessing from the source alone.
Start with the basic check:
cellc verify-artifact build/main.elfPin the target profile:
cellc verify-artifact build/main.elf --expect-target-profile ckbVerify source units on disk:
cellc verify-artifact build/main.elf --verify-sourcesUse production checks when preparing release evidence:
cellc verify-artifact build/main.elf --production
cellc verify-artifact build/main.elf --deny-fail-closed
cellc verify-artifact build/main.elf --deny-runtime-obligationsRead this gate narrowly: it verifies the artifact, metadata, source hash expectations, and selected policy flags. It does not prove that a concrete CKB transaction has been built, deployed, dry-run, indexed, or measured.
Use check mode for CI and local feedback:
cellc check --all-targets --production
cellc check --target-profile ckb --jsonImportant policy flags:
| Flag | Purpose |
|---|---|
--production |
Reject unsafe or incomplete lowering paths. |
--deny-fail-closed |
Reject metadata that contains fail-closed runtime features or obligations. |
--deny-ckb-runtime |
Reject CKB runtime features when they are not allowed for the workflow. |
--deny-runtime-obligations |
Reject runtime-required verifier obligations. |
These flags are useful because they turn "remember to inspect this later" into a compiler-visible failure.
You do not need to memorize the whole sidecar. Start with these fields:
target_profileartifact_formatartifact_hashartifact_size_bytessource_hashsource_content_hashsource_unitsmetadata_schema_versionactionslocksschemaruntimeverifier_obligationsruntime.proof_planruntime.proof_plan_soundnessruntime.builder_assumptionsconstraintsruntime_error_registryconstraints.artifactconstraints.entry_abiconstraints.ckb.capacity_evidence_contractconstraints.ckb.declared_capacity_floorsconstraints.ckb.hash_type_policyconstraints.ckb.dep_group_manifestscheduler
When reviewing a contract, ask simple questions first:
- which action or lock is the entry;
- what witness does it expect;
- which Cells are consumed or created;
- which runtime obligations remain;
- which CKB profile assumptions are recorded.
CellScript 0.16 adds a checked assurance layer over ProofPlan metadata:
cellc explain-proof src/main.cell --json
cellc explain-assumptions src/main.cell --json
cellc validate-tx --against build/main.elf.meta.json tx.json --jsonruntime.proof_plan_soundness tells you whether verifier obligations and
ProofPlan records agree. --primitive-strict=0.16 rejects metadata-only or
runtime-required ProofPlan gaps.
runtime.builder_assumptions is the machine-readable contract for transaction
builders. validate-tx checks a transaction JSON shape against that contract
and requires schema-bound evidence objects for non-structural assumptions
before signing. This is still pre-chain evidence: dry-run, capacity, cycles, and
commit checks remain required for production claims.
Additional 0.16 reports are available for audit and deployment workflows:
cellc solve-tx src/main.cell --json # emits a template, not a final transaction
cellc deploy-plan src/main.cell --json
cellc proof-diff old.meta.json new.meta.json --json
cellc audit-bundle src/main.cell --output target/auditproof-diff reports added, removed, and changed ProofPlan records. For changed
records, changed_records[].fields names the exact trigger, scope, reads,
coverage, group cardinality, builder assumption, codegen coverage, or
on-chain-check field that changed.
For CKB packages, a useful compiler CI gate is:
cellc fmt --check
cellc check --target-profile ckb --all-targets --production
cellc build --target riscv64-elf --target-profile ckb --production
cellc verify-artifact build/main.elf --expect-target-profile ckb --verify-sources --productionFor CKB, make the profile explicit in every step:
cellc check --target-profile ckb --production
cellc build --target riscv64-elf --target-profile ckb --production
cellc verify-artifact build/main.elf --expect-target-profile ckb --verify-sources --productionThese gates are suitable for a compiler/package CI loop. They are not enough for a release claim that says a contract is production-ready on a chain.
Syntax and lowering bugs can pass ordinary example compilation when the risky shape is hidden in an uncommon combination. The reusable syntax-combination audit exists to catch those bugs before chain evidence is generated:
./scripts/cellscript_syntax_combo_audit.sh quick
./scripts/cellscript_syntax_combo_audit.sh ciThe syntax-combination audit is a release acceptance preflight. It exercises
parser, formatter, type checking, lowering, metadata, codegen, and negative
obsolete-syntax oracles with compact reports under
target/syntax-combo-audit/.
For CellScript releases, quick is part of the pre-push gate and ci runs
before builder-backed CKB acceptance. A direct CKB acceptance run does not
replace this preflight because it only proves selected concrete transactions.
For repository work, use the unified gate wrapper instead of hand-picking component scripts:
./scripts/cellscript_gate.sh dev
./scripts/cellscript_gate.sh ci
./scripts/cellscript_gate.sh backend
./scripts/cellscript_gate.sh releasedev is the local fast path. ci is the pull-request gate. backend is for
IR/codegen/RISC-V changes. release is the production CKB evidence gate. See
docs/CELLSCRIPT_GATE_POLICY.md for the exact command contract.
When you are ready to make a CKB production claim, move from compiler evidence to chain evidence. Run the CKB acceptance gate from the CellScript repository root:
./scripts/cellscript_gate.sh releaseFor pre-push checks, the development gate runs the compiler checks, strict backend quick audit, syntax-combination quick audit, and diff checks:
./scripts/cellscript_gate.sh devIf you specifically need the old compile-only production acceptance pass,
./scripts/cellscript_ckb_release_gate.sh quick remains supported and delegates
to ./scripts/cellscript_gate.sh release-quick. The legacy
./scripts/cellscript_ckb_release_gate.sh full command is also supported as a
compatibility wrapper for ./scripts/cellscript_gate.sh release. The production
mode is the release-facing gate because it first runs compiler and
backend-contract evidence, then runs builder-backed local CKB transactions and
stateful scenario/action coverage.
The CKB validator records primitive-strict original bundled-example coverage, including strict v0.16 PP0150 fail-closed records, then requires scoped action and lock compile coverage, builder-backed action runs, source-bound acceptance provenance, builder-backed lock valid-spend and invalid-spend matrices, valid transaction dry-runs, committed valid transactions, malformed rejection, measured cycles, consensus-serialized transaction size, occupied-capacity evidence, no under-capacity outputs, bundled example deployment, and a passed final production hardening gate. Fail-closed PP0150 records are evidence of a strict boundary, not deployable production acceptance.
The report must explicitly record a passed final production hardening gate and source provenance for the repository commit, tracked source file list, tracked source hash, acceptance runner hash, and evidence validator hash.
The production gate compiles the seven checked-in top-level
examples/*.cell bundled examples directly. Those files are the single
canonical business source and the cleaner reading surface; there are no
checked-in examples/business or examples/acceptance mirrors. Acceptance-only
profile/effect/scheduler metadata belongs in runner configuration or generated
files under target/.
Lock behavior coverage is machine-readable through
lock_acceptance_scope.onchain_lock_spend_matrix_scope; each listed lock must
have both valid-spend and invalid-spend evidence.
examples/registry.cell and every checked-in examples/language/*.cell file
are non-production language examples covered by compiler/tooling tests, not by
the bundled CKB production matrix.
--compile-only and bounded diagnostic runs can help development, but they are
not external production release evidence.
Once the verification boundary is clear, continue with LSP and Tooling.