Skip to content

Scaffold, sign, install

Seven steps from nothing to a running plugin. None of them require touching Yano.

flowchart LR
    S[scaffold] --> I[implement + test]
    I --> G[sign]
    G --> V[validate / inspect]
    V --> P["init --plugin-jar<br/>(pin into a project)"]
    P --> D[doctor]
    D --> C["copy into plugins/<br/>on every member"]
Terminal window
./yano.sh appchain plugin scaffold \
--mode state-machine \
--id shipment \
--package com.example.shipment \
--yano-version 0.1.0-pre13 \
--output shipment-plugin

Modes are state-machine, composite-role, effect-executor, and sink. All four share the same runtime manifest, signed product catalog, and ServiceLoader conventions.

The generated provider deliberately does no business work: state-machine admission is closed and executor/sink factories return no instances until you implement them. The tool refuses a non-empty output directory.

Write the codec, the admission check, and the transitions. Before you do, read Determinism rules — the constraints are strict and the failure mode (a cluster that stops finalizing) is expensive to debug.

Then work up the testing ladder.

Sign the exact catalog, runtime manifest, and optional configuration metadata.

Terminal window
./yano.sh appchain plugin sign \
--catalog shipment-plugin/src/main/resources/META-INF/yano/appchain-component-catalog-v1.json \
--runtime-manifest shipment-plugin/src/main/resources/META-INF/yano/plugins/plugin-bundle.shipment.json \
--seed-file /secure/publisher.seed \
--key-id example-release-2026 \
--output shipment-plugin/src/main/resources/META-INF/yano/appchain-component-catalog-v1.sig.json
Terminal window
cd shipment-plugin && gradle jar && cd ..
./yano.sh appchain plugin validate shipment-plugin/build/libs/shipment-yano-plugin.jar \
--trust-key example-release-2026=<64-hex-public-key> \
--output shipment-catalog.json

inspect prints the same verified catalog and its capabilities.

Neither command loads provider classes, runs plugin code, fetches a registry, or installs the JAR. The exported snapshot is the safe, data-only local-import format used by Studio and by generated projects.

Terminal window
./yano.sh appchain init --non-interactive \
--recipe custom-plugin --network devnet --members 3 --runtime jvm \
--capability state:shipment \
--plugin-jar shipment-plugin/build/libs/shipment-yano-plugin.jar \
--trust-key example-release-2026=<64-hex-public-key> \
--output shipment-chain
./yano.sh appchain config validate --mode project shipment-chain

The project stores the signed data-only snapshot under component-catalogs/. Its lock pins the snapshot, the catalog, the runtime manifest, the configuration metadata, and the complete plugin-JAR digests. Rendering and doctor reverify the project snapshot automatically.

6. Check readiness against a real distribution

Section titled “6. Check readiness against a real distribution”
Terminal window
./yano.sh appchain doctor shipment-chain --distribution /opt/yano-x

A missing or different JAR fails artifact readiness. A native distribution reports a direct incompatibility, because Yano X plugins target the JVM host.

Copy the exact pinned JAR into plugins/ in every member’s distribution, then validate the resulting set:

Terminal window
tools/yano-plugins/bin/yano-plugins validate plugins/*.jar

The plugin directory property is yano.plugins.directory. Restart the nodes; Yano is not rebuilt.

Adding a member or a node is routine. Changing what a plugin computes is not — see Consensus rules. In short:

  • Give every bundle a stable plugin id and a semantic version.
  • Never silently change semantics behind an existing machine or component id.
  • Use activation heights and profile governance for compatible evolution.
  • Use a new namespace and a migration plan for incompatible state.
Terminal window
./yano.sh appchain diff previous.lock shipment-chain/appchain.lock
./yano.sh appchain migrate shipment-chain --dry-run
./yano.sh appchain drift shipment-chain --peer <node-identity-url>

diff classifies a blueprint change before you apply it. drift compares a project against running nodes when identities are available — the fastest way to find the one member that is out of step.