Crucible is Sigil’s primitive for coordinating distributed model training. Coordinators open a run with an escrowed reward pool; workers submit off-chain rollouts and commit their Merkle roots on-chain; attesters sign reward distributions; and weight artifacts are published with content-addressed commitments. For the full lifecycle and economic model see Primitive: Crucible training.

When to use this

  • You’re a coordinator running a training run and need on-chain settlement for rollout rewards.
  • You’re a worker participating in a run and need to submit batches.
  • You’re building tooling around Crucible (a dashboard, a stake leaderboard, etc.).

Prerequisites

  • A funded coordinator DID with the run’s reward pool ready to escrow.
  • A signed-off model configuration that all participants agree on (hosted on Weave/IPFS).

Recipe (coordinator side)

1

Open the run

await signAndSend({
  CrucibleOpen: {
    run_id: 'crucible:gpt-mini-2026-05',
    coordinator_did: process.env.SIGIL_SENDER_DID,
    config_cid: 'bafkrei.../model-config.json',
    reward_pool_base_units: '1000000000',     // 1,000 MINT, decimal string
    batch_size: 256,
    max_workers: 32,
    ends_at_height: 1_200_000,
  },
});
The reward pool is locked in escrow until Close or expiry.
2

Commit a rollout batch

Each batch is a Merkle root over the worker’s off-chain rollout records. The chain stores the root and the batch’s claimed reward budget; the records themselves stay off-chain.
await signAndSend({
  CrucibleCommitRollout: {
    run_id: 'crucible:gpt-mini-2026-05',
    worker_did: 'did:oas:sigil:agent:worker-7...',
    batch_id: 'batch:42',
    rollout_root: rolloutMerkleRootHex,
    records_count: 256,
    records_cid: 'bafkrei.../batch-42-records.json',
    claimed_reward_base_units: '5000000',
  },
});
Same shape via CLI:
sigil-cli crucible commit-rollout \
  --run-id crucible:gpt-mini-2026-05 \
  --worker-did did:oas:sigil:agent:worker-7... \
  --batch-id batch:42 \
  --rollout-root <hex> \
  --records-count 256 \
  --records-cid bafkrei.../batch-42-records.json \
  --claimed-reward 5000000
3

Attest rewards

Attesters review off-chain rollout records and sign a reward attestation that aligns or revises the claimed reward.
await signAndSend({
  CrucibleAttestRewards: {
    run_id: 'crucible:gpt-mini-2026-05',
    batch_id: 'batch:42',
    attestation: {
      worker_did: 'did:oas:sigil:agent:worker-7...',
      final_reward_base_units: '4750000',
      quality_score: 92,
      notes_cid: null,
    },
  },
});
The chain pays final_reward from the escrow when the attestation lands.
4

Publish weights

When a run produces a checkpointable weight artifact, publish its content address and commitment.
await signAndSend({
  CruciblePublishWeights: {
    run_id: 'crucible:gpt-mini-2026-05',
    weights_cid: 'bafkrei.../weights-step-10000.safetensors',
    weights_root: weightsBlake3Hex,
    params_count: 70_000_000_000,
    step: 10_000,
  },
});
5

Close the run

On normal completion the coordinator closes the run. Any remaining escrow returns to the coordinator.
await signAndSend({
  CrucibleClose: {
    run_id: 'crucible:gpt-mini-2026-05',
    reason: 'completed',
  },
});
To cancel early, use reason: 'cancelled'. Cancellation honours all already-attested rewards.

Slashing dishonest workers

If a worker submits a rollout batch whose records do not match the committed Merkle root, anyone can submit CrucibleSlash with the evidence:
await signAndSend({
  CrucibleSlash: {
    run_id: 'crucible:gpt-mini-2026-05',
    worker_did: 'did:oas:sigil:agent:worker-7...',
    batch_id: 'batch:42',
    evidence_cid: 'bafkrei.../slash-evidence.json',
    slash_amount_base_units: '10000000',
  },
});
The chain verifies the evidence proof against the committed root and applies the slash. See sigil-cli crucible slash for the CLI form.

Inspecting state

# Run summary
curl -s "$SIGIL_RPC_URL" -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"sigil_getTrainingRun",
       "params":{"run_id":"crucible:gpt-mini-2026-05"}}'

# A single batch
curl -s "$SIGIL_RPC_URL" -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"sigil_getTrainingRolloutBatch",
       "params":{"run_id":"crucible:gpt-mini-2026-05","batch_id":"batch:42"}}'

# Rewards history
curl -s "$SIGIL_RPC_URL" -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"sigil_getTrainingRewards",
       "params":{"run_id":"crucible:gpt-mini-2026-05"}}'

# Slash history
curl -s "$SIGIL_RPC_URL" -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"sigil_getTrainingSlashes",
       "params":{"run_id":"crucible:gpt-mini-2026-05"}}'

Common errors

SymptomCauseFix
run already closedTried to commit to a closed runOpen a new run; closed runs are immutable
worker not in allowlistWorker is not eligibleCheck the run’s worker policy
reward exceeds escrow remainderCumulative attested rewards > escrowTop up via CrucibleDeposit or attest a lower amount
weights commitment mismatchweights_root ≠ BLAKE3 of file at weights_cidRecompute the root before publishing

See also