Skip to content

[Architecture][Builder] Add an artifact-only multi-Script ProtocolBundle #9

Closed

Description

@a19q3

Summary

Add an artifact-only ProtocolBundle that composes multiple independently compiled CellScript artifacts into one CKB transaction plan, validates their combined builder contracts, runs every relevant Script Group against the same candidate transaction, and emits one evidence bundle.

This is intentionally an off-chain composition layer first. It must not add an ELF linker, merge executable business logic, or imply runtime calls between CKB Scripts.

Problem

CellScript currently has strong per-entry artifacts:

  • typed metadata and ProofPlan;
  • entry witness ABI;
  • generated builder contracts;
  • deployment and resource-identity manifests;
  • cellc tx validate;
  • CKB-VM and stateful evidence.

However, realistic protocols often require several independent Lock and Type Scripts to accept the same atomic transaction. Today, applications must manually reconcile their input/output indexes, witnesses, CellDeps, HeaderDeps, capacities, identity policies, and dry-run evidence.

The compiler documentation correctly states that each CKB Script remains an independent artifact. The missing feature is not runtime linkage; it is a typed, verifiable composition object above those artifacts.

Argent's ArtifactBundle and unified transaction context are useful product-design signals. CellScript needs a CKB-native version based on Script Groups, Molecule witnesses, exact deployments, occupied capacity, and per-artifact evidence.

Target architecture

flowchart TB
    A1["Artifact A<br/>metadata + ELF + deployment"] --> PB["ProtocolBundle resolver"]
    A2["Artifact B<br/>metadata + ELF + deployment"] --> PB
    A3["Artifact C<br/>metadata + ELF + deployment"] --> PB

    PB --> MERGE["Merge transaction roles and constraints"]
    MERGE --> CONFLICT{"Index / witness / identity<br/>conflicts?"}
    CONFLICT -- "yes" --> FAIL["Fail before signing"]
    CONFLICT -- "no" --> TX["One candidate CKB transaction"]

    TX --> VM1["Run Script Group A"]
    TX --> VM2["Run Script Group B"]
    TX --> VM3["Run Script Group C"]

    VM1 --> EVID["Combined evidence bundle"]
    VM2 --> EVID
    VM3 --> EVID
Loading

The bundle is valid only if every selected artifact accepts the exact same serialized transaction.

Proposed bundle contract

A canonical cellscript-protocol-bundle-v1 should include:

Artifact identity

For every participating artifact:

  • package coordinate and Cell.lock identity;
  • entry/action/lock identity;
  • deployable ELF hash;
  • metadata, typed-semantics, lowering-record, and source-map hashes;
  • public interface and interface_hash;
  • target/profile/VM/ABI versions;
  • deployment identity and network;
  • code CellDep identity;
  • selected Script role: Lock, Type, or spawned verifier.

Transaction-role bindings

  • named inputs, outputs, CellDeps, HeaderDeps, and witnesses;
  • global and Script Group-relative indexes;
  • expected Lock and Type Script identities;
  • resource/schema identities;
  • entry witness ABI placement;
  • required output construction and input consumption;
  • capacity, fee, change, and signature policies;
  • builder-assumption evidence requirements.

Composition result

  • deterministic merged transaction plan;
  • explicit conflict report;
  • resolved indexes and witness ownership;
  • per-Script-Group dry-run/CKB-VM result;
  • serialized transaction hash and size;
  • occupied-capacity report;
  • aggregate cycle report without erasing per-group cycles;
  • complete evidence identities.

Conflict classes

The resolver must reject rather than guess:

Conflict Example
input ownership two roles claim exclusive control of the same input
output placement two artifacts require different values at the same output index
witness ABI incompatible payloads claim the same WitnessArgs field
CellDep ordering positional ABI assumptions disagree
Script identity one role expects data hash X while another expects type hash Y
resource identity incompatible Type ID or logical identity requirements
capacity one artifact's floor exceeds the selected output capacity
fee/change two manifests assign the same capacity remainder differently
network/deployment artifacts resolve against different CKB networks
profile/version incompatible VM, source encoding, or ABI profiles
signature policy conflicting sighash or witness-lock ownership

A bundle may share a resource only when the participating artifact contracts explicitly permit compatible observation.

CLI shape to design

The exact command names require an accepted design, but the workflow should support:

protocol bundle create  -> canonical unresolved bundle
protocol bundle resolve -> concrete live Cells and deployment facts
protocol bundle check   -> structural + identity + builder validation
protocol bundle dry-run -> run every relevant Script Group
protocol bundle submit  -> dry-run first, then delegate signing/submission
protocol bundle inspect -> human and JSON evidence report

The runtime adapter remains responsible for live-cell resolution, signing, submission, and RPC interaction. The compiler and bundle checker must remain deterministic and usable offline with supplied facts.

Implementation phases

Phase 0 — format and threat model

  • define the canonical bundle schema and hash;
  • enumerate trust boundaries and conflict classes;
  • define artifact admission and exact deployment requirements;
  • specify global versus group-relative indexes;
  • define shared versus exclusive role ownership;
  • specify evidence tiers and failure behavior.

Phase 1 — offline composition

  • ingest existing builder manifests and metadata;
  • verify all artifact identities with the standalone checker;
  • merge role/index/witness/CellDep constraints;
  • reject all unresolved conflicts;
  • emit a deterministic transaction skeleton and evidence template.

No new CellScript syntax is required in this phase.

Phase 2 — runtime adapter integration

  • resolve live Cells and named deployments;
  • compute occupied capacity, fees, change, and transaction size;
  • build one concrete transaction;
  • dry-run every selected Script Group;
  • return per-artifact errors with source and role attribution.

Phase 3 — generated SDK and ecosystem closure

  • generate a typed TypeScript/Rust-facing bundle API;
  • support resumable signing without exposing private keys;
  • emit one audit bundle that preserves each artifact's evidence level;
  • integrate VS Code and Registry discovery after the format is stable.

End-to-end example

A useful acceptance fixture should contain at least three independent artifacts:

flowchart LR
    ORDER_IN["Order input<br/>Order Type Script"] --> TX["Atomic settlement transaction"]
    TOKEN_IN["Token input<br/>Token Type Script"] --> TX
    AUTH_IN["Authorization input<br/>Lock Script"] --> TX

    TX --> ORDER_OUT["Updated/closed order"]
    TX --> TOKEN_OUT["Transferred token"]
    TX --> CHANGE["Capacity change"]

    ORDER["Order verifier"] -. "accepts same tx" .-> TX
    TOKEN["Token verifier"] -. "accepts same tx" .-> TX
    AUTH["Authorization verifier"] -. "accepts same tx" .-> TX
Loading

The fixture must demonstrate both a successful composition and adversarial conflicts in witness placement, Script identity, output indexing, capacity, and deployment network.

Completion criteria

  • A versioned canonical ProtocolBundle schema and hash are documented.
  • Multiple independently checked artifacts can be composed without recompilation.
  • The resolver detects every documented conflict class deterministically.
  • One concrete transaction is validated against every participating artifact.
  • Every selected Script Group is dry-run against byte-identical transaction bytes.
  • Per-artifact and combined evidence levels remain distinct.
  • The runtime adapter, not generated code, owns RPC/signing/submission.
  • A three-artifact positive fixture and adversarial matrix pass.
  • Bundle validation is available in JSON and human-readable forms.
  • No claim of ELF linking or cross-Script runtime calls is introduced.
  • Package, website, Registry, docs, and generated SDK surfaces agree on the schema version.

Non-goals

  • an ELF linker;
  • in-VM calls between independent CKB Scripts;
  • merging multiple artifacts into one trust boundary;
  • accepting Registry metadata as on-chain identity proof;
  • automatic conflict resolution;
  • hiding fee, capacity, signature, or change policies;
  • source-level cross-Script role syntax in the first phase.

Relationship to other work

References

Activity

  1. a19q3 commented on Aug 27, 2026

    @a19q3
    CollaboratorAuthor

    Research update: define ProtocolBundle as an evidence closure, not another package format

    Comment audit

    There were no prior comments on this issue at the time of review.

    The relevant Argent work—portable artifacts/builder in PR #4, ArtifactBundle in PR #8, unified TxContext in PR #20, and artifact validation in PR #21—has little or no substantive review discussion. It should therefore be treated as product-design evidence, not a validated security specification.

    Existing CellScript boundary

    The audit confirms that CellScript is not missing the per-artifact foundations. It already has:

    • canonical public interfaces and six compatibility dimensions;
    • artifact/metadata/lowering/source-map identities;
    • entry witness ABI and generated builders;
    • deployment records and named CellDep policies;
    • CKB adapter materialization of one resolved action;
    • tx validation, CKB-VM execution, and stateful evidence.

    The missing abstraction is the closure over several already-verified artifacts.

    That distinction matters because ProtocolBundle should not re-resolve source packages, recompile them, or silently change their target/profile. It should consume immutable artifact descriptors and exact deployment facts.

    Two graphs must remain separate

    ProtocolBundle needs two linked graphs:

    1. Artifact graph: which exact checked artifacts, interfaces, deployments, code CellDeps, and entry ABIs participate.
    2. Transaction-role graph: which inputs, outputs, deps, headers, and witness slots each artifact reads, owns, or constrains.

    The package resolve/build graph proposed in #19 can help locate and build artifacts, but it is not the ProtocolBundle evidence graph. Likewise the workspace correction in #15 must not turn Cell.lock into a bundle manifest.

    Merge semantics need a field taxonomy

    A generic JSON merge is unsafe. Every bundle field should have one of these merge classes:

    • Exact-equal: network/genesis, transaction version, target VM contract, shared role identity.
    • Additive set with deduplication: CellDeps, HeaderDeps, independent witness requirements.
    • Single owner: a fixed witness slot, output index, signature group, change output, fee policy.
    • Constraint intersection: capacity lower/upper bounds, allowed Script identities, cardinality.
    • Ordered sequence: global inputs/outputs/witnesses when order is semantically visible.
    • Derived only: transaction hash, occupied capacity, fee, serialized sizes.

    Conflicts must name both producing artifacts and source obligations. First-writer-wins is not acceptable.

    Same transaction bytes is the key invariant

    Every CKB-VM run in the bundle must receive the exact same serialized RawTransaction and witnesses. It is insufficient to run each artifact against a separately synthesized transaction that merely has equivalent roles.

    The combined evidence should bind:

    • canonical transaction bytes/hash;
    • all selected Script Groups;
    • each group's exact Script identity;
    • artifact/metadata/lowering/source-map hashes;
    • cycle result and exit status;
    • resolver/deployment inputs used by the builder;
    • signature status, clearly separated from unsigned structural validation.

    CKB consensus executes all Script Groups independently. ProtocolBundle demonstrates that the candidate transaction satisfied each selected artifact; it does not create runtime calls between them.

    Recommended v1

    Start with an artifact-only JSON schema and CLI library API:

    • exact local artifact files and verified sidecars;
    • exact Deployed.toml records for one network;
    • named roles and deterministic global/group index mapping;
    • deterministic conflict detection;
    • unsigned transaction construction;
    • dry-run of every selected Script Group;
    • one canonical evidence bundle and hash.

    Do not add source syntax in v1. #10 can later compile typed role declarations into this same schema.

    Acceptance additions

    • Two artifacts require the same CellDep identically: deduplicate and pass.
    • Same CellDep name but different outpoint/data/type identity: fail.
    • Two artifacts claim the same witness field/slot with different codecs: fail.
    • One artifact inserts an output and shifts another artifact's global index: recompute from role bindings or fail; never retain a stale index.
    • Each artifact passes separately on a different transaction, but not on the merged transaction: bundle fails.
    • One selected Script Group is omitted from dry-run: evidence verifier fails.
    • Bundle verification in frozen/offline mode performs no Registry lookup.
    • Reordering artifact declarations does not change canonical bundle identity.
    • Reordering semantically ordered transaction roles does change identity.
    • An artifact target/profile mismatch is rejected before transaction construction.
    • A post-dry-run byte mutation invalidates the evidence hash.

    Dependency refinement

    Schema design can proceed in parallel, but production implementation should follow this order:

    1. [Toolchain][CKB environment][P0] Make transitive dependency selection chain-identity-safe #17 closes chain-identity propagation and the manifest-driven panic.
    2. [Toolchain][Workspace][P1] Replace member-loop builds and synthetic workspace locks with a canonical graph #15, [Toolchain][Resolver][P1] Define and enforce package instance, version, source, and feature unification #16, and [Toolchain][Compatibility][P1] Enforce package-declared CellScript compiler requirements #18 define trustworthy workspace, package-instance, and compiler-compatibility semantics.
    3. [Toolchain][Introspection] Expose a stable package resolve graph and build-unit plan #19 exposes that corrected resolve graph and build-unit plan; it must not stabilize the current inconsistent behavior as public JSON.
    4. This issue consumes immutable, independently verified artifacts only.
    5. [Language design] Model typed cross-Script transaction roles without runtime linkage #10 emits typed roles into the bundle.
    6. [Language/ABI] Bind runtime Script values to verified package interfaces #11 supplies exact runtime-selected Script/interface receipts for open roles.
    7. [Toolchain][Upgrade] Add a transactional package, interface, and deployment upgrade plan #20 evaluates bundle impact during package/deployment upgrades.

    Conclusion

    ProtocolBundle is a high-value tooling feature and can begin without consensus-language changes. Its security property is evidence closure over immutable artifacts and one exact transaction, not “multi-contract linking.” This is the most useful part of Argent's ArtifactBundle direction to adopt, while keeping CKB Script Groups and CellDep/deployment identity explicit.

  2. a19q3 commented on Sep 11, 2026

    @a19q3
    CollaboratorAuthor

    Completed for the bounded 0.30 artifact-only scope. The implementation spans offline deterministic conflict checking (c75cb113), builder contracts, exact CKB transaction materialization, live input/dependency checks, node dry-run/signing gates, typed clients, Registry/website surfaces, and the four-artifact ProtocolBundle business anchor (d6e49cf7, a2ee77aa). The bundle binds independently checked artifacts to one byte-identical transaction and does not introduce a source-language transaction DSL. The product capability ledger records remaining_work=[] and close-after-merge at cdc5b53c. No TAC or release workflow was invoked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions