Skip to main content
Getting started~5 minutes

Immutable releases

Ship something you can verify forever — starting with a safe dry-run. No wallets. No daemons. Just a first win.

  1. 1

    Try the dry-run

    One script proves the pipeline on your laptop.

  2. 2

    Publish locally

    A signed manifest you can verify anytime.

  3. 3

    Go permanent later

    Add IPFS or Arweave only when you want to.


title: Getting started: immutable releases (clawql-release)

Getting started: immutable releases (clawql-release)

This guide walks through Layer 0 end to end: parallel workspaces → signed artifacts → IPFS staging → optional Lit/x402 encryption → Arweave permanence → verify and pull.

Vision (why): Immutable releases · source docs/vision/clawql-hybrid-decentralized-github-alternative.md

CLI package: packages/clawql-release


What you get

Step Command Outcome
Init clawql-release init .clawql/release.json, signed commits by default
Workspaces immutable-volume snapshot Parallel git-worktree or rift CoW checkouts
Golden image golden-image build Signed attestations (+ cosign/syft when installed)
Publish publish --stage-ipfs --permanent Manifest + Merkle root; staged then permanent
Paid / private publish --encrypt --price "…" Lit condition + x402 access metadata
Consume verify / pull Tamper check; decrypt when paid

Day-to-day collaboration stays on Radicle (primary) with GitHub as a mirror. Official releases become permanent and verifiable on Arweave (via ar.io when configured).


Prerequisites

  • Node.js ≥ 22
  • Git (for worktrees and commit signing)
  • From a ClawQL checkout (or any repo using the CLI):
npm ci
npm run build -w clawql-core
npm run build -w clawql-release
# binary: npx clawql-release …  or  clawql release …

Optional tools (used when present):

Tool Role
rift-snapshot (rift) Fast CoW workspaces (needs btrfs / APFS / XFS reflinks)
ipfs (Kubo) Real IPFS CIDs instead of local content-addressed staging
rad Radicle push as primary git surface
gh Attach manifest to a GitHub Release (mirror)
cosign / syft Container signatures / SBOM generation

Path A: dry-run (start here)

No wallets, no daemons. Proves the full control plane locally or in CI.

export CLAWQL_RELEASE_DRY_RUN=1

clawql-release init

# Parallel agent-style workspaces
clawql-release immutable-volume snapshot --backend git-worktree --name agent-a
clawql-release immutable-volume snapshot --backend git-worktree --name agent-b
clawql-release immutable-volume snapshot --backend rift --name rift-a

# Fixture artifacts (replace with real SBOM / digests in production)
printf '%s\n' '{"bomFormat":"CycloneDX","specVersion":"1.5","version":1}' > /tmp/sbom.cdx.json

clawql-release golden-image build \
  --image-digest clawql-mcp=sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

clawql-release publish --tag v0.0.0-local \
  --sbom /tmp/sbom.cdx.json \
  --image-digest clawql-mcp=sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
  --stage-ipfs --permanent --encrypt --price "0.01 USDC" \
  --dry-run

# Print tx id from the publish output, then:
clawql-release verify local_<…>
clawql-release pull local_<…> --rift

One-shot CI/local script (same flow GitHub Actions runs):

CLAWQL_RELEASE_DRY_RUN=1 node scripts/release/ci-pipeline-e2e.mjs

Workflow: .github/workflows/clawql-release-pipeline.yml

Dry-run stores live under .clawql/ (gitignored):

Path Purpose
.clawql/ipfs-staging/ Content-addressed staging (clawql-cid:sha256:…)
.clawql/arweave/<tx>/ Permanent bundle stand-in
.clawql/escrow/ Content-encryption keys for Lit dry-run release
.clawql/keys/ Ed25519 release signing + optional SSH commit signing
.clawql/workspaces/ Snapshot metadata + git-worktree roots
.rifts/ Rift CLI or local fallback workspaces

Path B: real workspaces (laptop)

Git worktree (always available)

clawql-release immutable-volume snapshot --backend git-worktree --name feature-42
cd .clawql/workspaces/git-worktree/feature-42
# edit / test / commit as usual (shared object store with the main repo)

List / remove:

clawql-release immutable-volume list
clawql-release immutable-volume remove --name feature-42

Rift CoW (when the filesystem supports it)

npm install --prefix ~/.local/clawql-rift rift-snapshot
export PATH="$HOME/.local/clawql-rift/node_modules/.bin:$PATH"

rift init    # must succeed on btrfs / APFS / XFS with reflinks
clawql-release immutable-volume snapshot --backend rift --name agent-42

If rift init fails with "copy-on-write cloning unavailable" (typical on ext4 / overlay / many CI runners), clawql-release still creates a local fallback under .rifts/ for provenance. True CoW needs a capable volume — use a laptop APFS volume, a btrfs disk, or a self-hosted runner with that FS.


Path C: full publish (production-shaped)

1. Collect artifacts

Build your SBOM, npm pack, and record image digests (from GHCR / cosign):

# examples — adjust to your pipeline
npm pack
# syft . -o cyclonedx-json=sbom.cdx.json
# skopeo inspect … → digests

2. Snapshot the build environment

clawql-release immutable-volume snapshot --backend rift --name build-$(date -u +%Y%m%d)
# or: --backend git-worktree

3. Golden image attestations

clawql-release golden-image build \
  --version 7.1.0 \
  --image-digest clawql-mcp=sha256:YOUR_DIGEST

4. Publish

Public release (GitHub mirror + IPFS staging + Arweave):

clawql-release publish --tag v7.1.0 \
  --sbom sbom.cdx.json \
  --npm-tgz clawql-mcp-7.1.0.tgz \
  --image-digest clawql-mcp=sha256:YOUR_DIGEST \
  --stage-ipfs --permanent --github

Paid / private release:

clawql-release publish --tag v7.1.0 \
  --sbom sbom.cdx.json \
  --stage-ipfs --permanent \
  --encrypt --price "0.50 USDC"

5. Verify and pull

clawql-release verify releases/v7.1.0/manifest.json
clawql-release verify <arweave-tx-id>

clawql-release pull <arweave-tx-id> --rift
# Paid bundles: present PAYMENT-SIGNATURE / dry-run receipt; Lit releases the CEK

clawql release … is the same surface via the main ClawQL CLI.


Configuration

clawql-release init writes .clawql/release.json. Useful fields:

{
  "version": 1,
  "outputDir": "releases",
  "requireSignedCommits": true,
  "workspaceBackend": "git-worktree",
  "collaboration": {
    "primary": "radicle",
    "githubMirrorUrl": "https://github.com/org/repo"
  },
  "permanence": {
    "arweaveGateway": "https://arweave.net",
    "dryRun": true
  },
  "access": {
    "defaultPrice": "0.50 USDC",
    "asset": "USDC",
    "network": "base-sepolia"
  }
}

Signed commits: init enables commit.gpgsign when a signing identity exists, or configures an SSH key under .clawql/keys/. Opt out with requireSignedCommits: false.


Live network knobs (laptop / self-hosted)

Env Enables
CLAWQL_RELEASE_DRY_RUN=1 / CLAWQL_RELEASE_MODE=local Force local backends (CI default)
(ipfs on PATH) Real ipfs add CIDs
CLAWQL_IPFS_GATEWAY HTTP gateway base for IPFS
CLAWQL_ARWEAVE_WALLET_JWK ar.io / Turbo upload path
CLAWQL_ARIO_TURBO_URL Turbo endpoint
CLAWQL_ARWEAVE_GATEWAY / CLAWQL_ARIO_GATEWAY Fetch/verify gateways
CLAWQL_X402_ENFORCE=1 Live facilitator verify
CLAWQL_X402_FACILITATOR_URL Facilitator base URL
CLAWQL_X402_WALLET / CLAWQL_X402_NETWORK Payment metadata defaults
CLAWQL_LIT_NETWORK Lit network label for key release

Spendable Arweave wallets should stay off GitHub Actions secrets for the dry-run workflow. Prefer a laptop or self-hosted runner for any live --permanent publish.

Maturity of live adapters

Backend Dry-run / local Live
git-worktree Full Full
rift Fallback under .rifts/ Full when rift + CoW FS work
IPFS staging clawql-cid:sha256:… Kubo when ipfs is available
Ed25519 manifest/artifacts Full Full
Arweave / ar.io .clawql/arweave/<tx>/ Env-gated Turbo path (harden with a real wallet on laptop)
Lit + x402 Escrow CEK + dry-run receipt Soft facilitator / Lit hooks — validate on testnet before production

What the manifest records

Every publish writes releases/<tag>/manifest.json (schema v0.2) including:

  • repository.commit + dirty flag
  • artifacts.* / images.* with SHA-256 (+ Ed25519 signatures)
  • merkleRoot over those leaves
  • buildEnvironment (worktree / rift snapshot ancestry when present)
  • collaboration (Radicle primary + GitHub mirror banner)
  • staging.ipfs · permanence.arweave · access (public or paid)

Runtime checks:

  • clawql doctor --smoke resolves releases/v\{version\}/manifest.json when present
  • CLAWQL_RELEASE_MANIFEST=/path/to/manifest.json verifies at MCP startup (strict with CLAWQL_RELEASE_MANIFEST_STRICT=1 or production)

Container digests are also verified with cosign separately — see docs/security/golden-image-pipeline.md.


Suggested learning order

  1. Dry-runci-pipeline-e2e.mjs or Path A above
  2. Parallel worktrees on your laptop — Path B
  3. Rift CoW on APFS/btrfs if you run many agents
  4. Local Kubo — publish with --stage-ipfs without dry-run
  5. One tiny Arweave publish with a funded wallet outside CI
  6. x402 + Lit testnet for a paid decrypt round-trip

Troubleshooting

Symptom Likely cause Fix
Manifest records dirty git tree Uncommitted tracked changes at collect Commit or stash; untracked .clawql/ / .rifts/ are ignored
rift init fails (no reflinks) ext4 / overlay / cloud VM Use git-worktree or a CoW-capable volume
verify fails signature Wrong key / tampered file Re-publish; check .clawql/keys/
No Arweave tx on --permanent Dry-run or missing wallet Expected under CLAWQL_RELEASE_DRY_RUN; set wallet only on trusted hosts
Pull decrypt fails Missing escrow / payment Check .clawql/escrow/<tag>.key or live Lit+x402 config

Related docs

© Copyright 2026. All rights reserved. · ClawQL on GitHub

Source: docs/getting-started/immutable-releases.md