Immutable releases
Ship something you can verify forever — starting with a safe dry-run. No wallets. No daemons. Just a first win.
- 1
Try the dry-run
One script proves the pipeline on your laptop.
- 2
Publish locally
A signed manifest you can verify anytime.
- 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 flagartifacts.*/images.*with SHA-256 (+ Ed25519 signatures)merkleRootover those leavesbuildEnvironment(worktree / rift snapshot ancestry when present)collaboration(Radicle primary + GitHub mirror banner)staging.ipfs·permanence.arweave·access(public or paid)
Runtime checks:
clawql doctor --smokeresolvesreleases/v\{version\}/manifest.jsonwhen presentCLAWQL_RELEASE_MANIFEST=/path/to/manifest.jsonverifies at MCP startup (strict withCLAWQL_RELEASE_MANIFEST_STRICT=1or production)
Container digests are also verified with cosign separately — see docs/security/golden-image-pipeline.md.
Suggested learning order
- Dry-run —
ci-pipeline-e2e.mjsor Path A above - Parallel worktrees on your laptop — Path B
- Rift CoW on APFS/btrfs if you run many agents
- Local Kubo — publish with
--stage-ipfswithout dry-run - One tiny Arweave publish with a funded wallet outside CI
- 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
- Vision: Immutable releases
- Package README:
packages/clawql-release/README.md - Golden images:
docs/security/golden-image-pipeline.md - Modularization Layer 0:
docs/vision/clawql-modularization-v2.md
© Copyright 2026. All rights reserved. · ClawQL on GitHub