Skip to main content
Getting startedLayer 0

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

StepCommandOutcome
Initclawql-release init.clawql/release.json, signed commits by default
Workspacesimmutable-volume snapshotParallel git-worktree or rift CoW checkouts
Golden imagegolden-image buildSigned attestations (+ cosign/syft when installed)
Publishpublish --stage-ipfs --permanentManifest + Merkle root; staged then permanent
Paid / privatepublish --encrypt --price "…"Lit condition + x402 access metadata
Consumeverify / pullTamper 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):

ToolRole
rift-snapshot (rift)Fast CoW workspaces (needs btrfs / APFS / XFS reflinks)
ipfs (Kubo)Real IPFS CIDs instead of local content-addressed staging
radRadicle push as primary git surface
ghAttach manifest to a GitHub Release (mirror)
cosign / syftContainer 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):

PathPurpose
.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):

# Omit CLAWQL_RELEASE_DRY_RUN for live backends when tools/env are set
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 — not hosted Actions wallets)

EnvEnables
CLAWQL_RELEASE_DRY_RUN=1 / CLAWQL_RELEASE_MODE=localForce local backends (CI default)
(ipfs on PATH)Real ipfs add CIDs
CLAWQL_IPFS_GATEWAYHTTP gateway base for IPFS
CLAWQL_ARWEAVE_WALLET_JWKar.io / Turbo upload path
CLAWQL_ARIO_TURBO_URLTurbo endpoint
CLAWQL_ARWEAVE_GATEWAY / CLAWQL_ARIO_GATEWAYFetch/verify gateways
CLAWQL_X402_ENFORCE=1Live facilitator verify
CLAWQL_X402_FACILITATOR_URLFacilitator base URL
CLAWQL_X402_WALLET / CLAWQL_X402_NETWORKPayment metadata defaults
CLAWQL_LIT_NETWORKLit network label for key release

Do not put spendable Arweave wallets in GitHub Actions secrets for the dry-run workflow. Prefer laptop or a self-hosted runner for one small live --permanent publish.

Maturity of live adapters

BackendDry-run / localLive
git-worktreeFullFull
riftFallback under .rifts/Full when rift + CoW FS work
IPFS stagingclawql-cid:sha256:…Kubo when ipfs is available
Ed25519 manifest/artifactsFullFull
Arweave / ar.io.clawql/arweave/<tx>/Env-gated Turbo path (harden with a real wallet on laptop)
Lit + x402Escrow CEK + dry-run receiptSoft 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

SymptomLikely causeFix
Manifest records dirty git treeUncommitted tracked changes at collectCommit or stash; untracked .clawql/ / .rifts/ are ignored
rift init fails (no reflinks)ext4 / overlay / cloud VMUse git-worktree or a CoW-capable volume
verify fails signatureWrong key / tampered fileRe-publish; check .clawql/keys/
No Arweave tx on --permanentDry-run or missing walletExpected under CLAWQL_RELEASE_DRY_RUN; set wallet only on trusted hosts
Pull decrypt failsMissing escrow / paymentCheck .clawql/escrow/<tag>.key or live Lit+x402 config