Files
node/README.md
T
Kevin Codex 3f08d9936b Release automation (#127)
* ci(release): add Windows target and cross-platform packaging

Add x86_64-pc-windows-msvc to the release matrix. Windows ships a .zip
(7z) while unix keeps .tar.gz; a portable sha256 helper handles
sha256sum/shasum/certutil. Smoke test and packaging now resolve the
.exe suffix on Windows. Release attach uses globs to cover both formats.

* feat(release): vendor npm wrapper and auto-publish to npm

Vendor the @gitlawb/gl npm wrapper (optionalDependencies platform-package
pattern) into npm/, replacing the standalone gl-npm repo. A new npm-publish
job downloads the four unix release tarballs from the GitHub release, lays in
the binaries, stamps every package.json with the release version, and runs
npm publish --provenance. Guarded on NPM_TOKEN so it no-ops until the secret
is configured.

* feat(release): auto-bump Homebrew tap on release

Add a homebrew-bump job that regenerates Formula/gl.rb in Gitlawb/homebrew-tap
from the release tarballs' sha256 checksums (macOS+Linux, arm64+x64) and pushes
the bump. Guarded on HOMEBREW_TAP_PAT so it no-ops until the secret and tap repo
exist. Enables 'brew install gitlawb/tap/gl'.

* feat(release): Windows installer and web auto-sync on release

Add install.ps1 (Windows PowerShell installer, source of truth in node).
Add a web-sync job that opens a PR to Gitlawb/web on each release syncing
install.sh + install.ps1 + public/version.json, plus idempotent drift fixes
(remove orphaned public/bin, fix stale skill.md releases link). Guarded on
WEB_SYNC_PAT. Vercel deploys on merge.

* docs(readme): document npm, Homebrew, and Windows install methods

* ci(release): build only CLI binaries on Windows

The gitlawb-node daemon targets Linux/macOS; building it on Windows risks
a compile failure that would block the whole release (npm/brew/web jobs all
depend on release-binaries). Windows now builds only gl + git-remote-gitlawb;
the smoke-test and package loops follow the per-target binary list.

* fix(release): reconcile release-please manifest with v0.3.9 and bump action to v5

The manifest still said 0.3.8 while the only tag is a manual v0.3.9 and
Cargo.toml is 0.3.9, so release-please had no valid baseline (no v0.3.8 tag)
and never cut a release. Set the manifest to 0.3.9 so release-please diffs
v0.3.9..main and opens a proper release PR for the next version. Also pin
release-please-action to v5.0.0 to match the openclaude pipeline.

* ci(release): set explicit minimal permissions on homebrew-bump and web-sync

CodeQL flagged both jobs for lacking a permissions block, leaving GITHUB_TOKEN
at broad default scopes. Both only need contents: read (cross-repo writes use
dedicated PATs).

* fix(release): harden installers and workflow per review

- install.ps1: fail closed if the .sha256 cannot be fetched; pure ASCII (no BOM)
- npm install.js: fail (exit 1 / throw) when the platform payload or a binary is
  missing instead of reporting a successful but broken install
- workflow: top-level permissions {} + persist-credentials: false on read-only
  checkouts
- docs: PowerShell-only Windows note; text language tag on npm/README fenced block

* fix(installer): require core CLI binaries on Windows

install.ps1 only failed when zero binaries were present, so a partial archive
missing gl.exe could still report success. Require gl.exe + git-remote-gitlawb.exe
(gitlawb-node.exe stays optional, matching the Windows build) and fail early if a
required binary is absent.

* ci(release): make Windows non-blocking and stop persisting cross-repo PATs

- release-binaries: continue-on-error for the Windows leg so a failure there
  no longer fails the job or blocks npm/Homebrew (matches the best-effort intent)
- homebrew-bump/web-sync: persist-credentials: false on the PAT-backed checkouts;
  supply the token only on the git push via an x-access-token URL

* fix(release): gate web-sync on binaries and detect native arch in installer

- web-sync now needs release-binaries so the site never advertises a release
  whose artifacts failed to build
- install.ps1 reads PROCESSOR_ARCHITEW6432 before PROCESSOR_ARCHITECTURE so a
  32-bit PowerShell host on x64 Windows is not wrongly rejected

* ci(release): make npm publish idempotent across reruns

Skip any @gitlawb package version already on the registry so rerunning the
job after a partial publish no longer errors on the first existing package
and leaves the wrapper/platform packages out of sync.

* fix(release): harden web-sync and tap commit per review

- web-sync: verify the Windows ZIP + .sha256 exist on the release before
  syncing install.ps1/version.json (Windows is best-effort, so a failed leg
  must not make the site advertise a missing installer)
- stage generated files before the no-op check so brand-new untracked files
  (formula, version.json) are committed instead of skipped
- gh pr create: only swallow the 'PR already exists' case; surface auth/API errors
- npm README: scope npm/yarn/pnpm/bun install to macOS/Linux/WSL, point native
  Windows at the PowerShell installer

* ci(release): guard npm-publish before doing any work

Check NPM_TOKEN in an up-front guard step (like homebrew-bump/web-sync) and
skip checkout, release downloads, extraction, version rewrites, and publish
when it is absent, instead of doing all that work and bailing in Publish.

* fix(release): robust web PR error handling and Windows installer hardening

- web-sync: capture gh pr list output so a real API/auth failure surfaces
  instead of being misread as 'PR already exists'
- install.ps1: enforce TLS 1.2 and use -UseBasicParsing so downloads work on
  stock Windows PowerShell 5.1; remove binaries no longer shipped on upgrade so
  an in-place update can't leave a mixed-version install; handle an empty user
  PATH without a leading separator
2026-06-30 16:56:58 +08:00

12 KiB

Gitlawb Node

Decentralized git infrastructure for developers, AI agents, and app delivery.

Gitlawb Node is the open-source node software behind the Gitlawb network. It lets anyone run a self-hosted node, publish repositories under a DID, sign writes with Ed25519 HTTP signatures, replicate git activity across peers, and move toward a resilient app-delivery network where code and build assets can be served closer to users.

Gitlawb is not trying to be only “another git host.” The long-term direction is:

Decentralized GitHub
+ signed agent-native workflows
+ resilient repo replication
+ CDN-style app/code delivery

The mission is simple: once code is pushed to the network, it should not disappear because one server went down.


What is in this repository?

This is a Rust workspace with four crates:

Crate Purpose
gitlawb-node The node daemon: Axum HTTP server, git smart-HTTP, Postgres metadata, libp2p gossip, optional S3/Tigris/IPFS/Arweave/Base PoS hooks.
gl The Gitlawb CLI for identity, repos, issues, PRs, bounties, tasks, peers, node status, MCP, and setup flows.
git-remote-gitlawb Git remote helper for gitlawb:// URLs, so normal git clone, git fetch, and git push can talk to Gitlawb nodes.
gitlawb-core Shared primitives: Ed25519 identities, did:key, CIDs, RFC 9421 HTTP signatures, certificates, and UCAN tokens.

Why Gitlawb Nodes?

Most git hosting today depends on a small number of centralized platforms. Gitlawb Nodes are designed for a different model:

  • Own your identity — every user, agent, and node is an Ed25519 keypair represented as did:key:z6Mk....
  • Signed writes by default — write requests use RFC 9421 HTTP Signatures instead of passwords.
  • Git-native transport — repositories are still real git repositories served over smart HTTP.
  • Agent-native workflows — the gl CLI and MCP server expose repo, issue, task, PR, and UCAN flows to AI agents.
  • Peer-aware delivery — nodes can announce, discover, gossip, and sync with each other.
  • App CDN direction — the network can evolve from decentralized code storage into code + asset + app delivery.

Current status

Gitlawb Node is live early infrastructure. It is useful today, but some security and reliability features are intentionally staged for compatibility with existing nodes.

Good today:

  • Local or Docker node startup.
  • Postgres-backed repo metadata.
  • Bare git repository storage.
  • Git smart-HTTP clone/fetch/push.
  • RFC 9421-signed writes.
  • DID identities.
  • gl CLI workflows.
  • libp2p peer discovery/gossip foundation.
  • Optional Tigris/S3 storage.
  • Optional IPFS/Pinata and Arweave/Irys hooks.
  • Optional Base node-operator staking/heartbeat hooks.

Known limitations:

  • Private repository read enforcement is not wired yet. Treat public nodes as public infrastructure unless you restrict access at your proxy/firewall.
  • UCAN chain validation and revocation are not complete.
  • Repository write authorization is not capability-complete yet; HTTP signatures prove identity, not full authorization policy.
  • Peer writes are signed by upgraded nodes, but strict signed-peer enforcement is opt-in during rolling upgrades.
  • GraphQL mutations need mutation-aware auth before becoming a public write surface.

See:


Quickstart: run a local node

The fastest path is Docker Compose. It starts a node and Postgres.

git clone https://github.com/Gitlawb/node.git
cd node
cp .env.example .env
docker compose up -d

Your local node will serve:

Service Default
HTTP API + git smart-HTTP http://localhost:7545
libp2p QUIC/UDP 7546
Postgres compose-managed

Verify:

curl http://localhost:7545/health
curl http://localhost:7545/api/v1/stats

Expected health response:

{ "status": "ok" }

Stop it:

docker compose down

Install the CLI

# npm (macOS / Linux)
npm install -g @gitlawb/gl

# Homebrew (macOS / Linux)
brew install gitlawb/tap/gl

# curl (macOS / Linux)
curl -fsSL https://gitlawb.com/install.sh | sh

# PowerShell (Windows)
irm https://gitlawb.com/install.ps1 | iex

Or build from source:

cargo build --release -p gl -p git-remote-gitlawb -p gitlawb-node

Put these binaries on your PATH:

target/release/gl
target/release/git-remote-gitlawb
target/release/gitlawb-node

Check your setup:

gl doctor

First repo flow

Create an identity:

gl identity new
gl identity show

Register against your local node:

gl register --node http://localhost:7545

Create a repo:

gl repo create my-repo --description "My first Gitlawb repo" --node http://localhost:7545

Use the git remote helper:

export GITLAWB_NODE=http://localhost:7545
git clone gitlawb://did:key:z6Mk.../my-repo

For public-network use, make sure GITLAWB_NODE points to the node you want. The helper defaults to localhost for local development.


Architecture

┌──────────────────────────┐
│ gl CLI / git / AI agents │
└────────────┬─────────────┘
             │ signed HTTP writes / git smart-HTTP
             ↓
┌──────────────────────────┐
│ gitlawb-node             │
│ Axum API + git routes    │
└────────────┬─────────────┘
             │
    ┌────────┴────────┐
    ↓                 ↓
Postgres        Bare git repos
metadata        local disk / optional S3
    │                 │
    └────────┬────────┘
             ↓
       libp2p peers
  gossip + discovery + sync
             ↓
 optional IPFS / Arweave / Base PoS

Core concepts

Concept Meaning
DID A user, agent, or node identity derived from an Ed25519 public key.
HTTP Signature RFC 9421 signature proving control of the DID key for write requests.
Ref certificate Signed record of a ref update. Useful for audit and replication.
UCAN Delegation token for future capability-based workflows.
Peer announce Node-to-node HTTP announcement of DID + public URL.
Gossipsub libp2p topic for ref-update events.
Smart HTTP Standard git protocol over HTTP for clone/fetch/push.

API surface

The node exposes both git smart-HTTP routes and JSON APIs.

Common public read routes:

GET /health
GET /
GET /api/v1/stats
GET /api/v1/contracts
GET /api/v1/repos
GET /api/v1/repos/{owner}/{repo}
GET /api/v1/repos/{owner}/{repo}/tree
GET /api/v1/repos/{owner}/{repo}/blob/{path}
GET /api/v1/repos/{owner}/{repo}/issues
GET /api/v1/repos/{owner}/{repo}/pulls
GET /api/v1/peers
GET /{owner}/{repo}/info/refs
POST /{owner}/{repo}/git-upload-pack

Signed write routes include:

POST /api/v1/repos
POST /api/register
POST /api/v1/repos/{owner}/{repo}/fork
POST /api/v1/repos/{owner}/{repo}/issues
POST /api/v1/repos/{owner}/{repo}/pulls
POST /api/v1/repos/{owner}/{repo}/pulls/{number}/merge
POST /api/v1/repos/{owner}/{repo}/hooks
POST /api/v1/bounties/{id}/...
POST /{owner}/{repo}/git-receive-pack

Peer write routes support staged rollout:

POST /api/v1/peers/announce
POST /api/v1/sync/notify
POST /api/v1/sync/trigger

When GITLAWB_REQUIRE_SIGNED_PEER_WRITES=false, unsigned legacy peers are accepted, but signed requests are verified when signature headers are present. Once all live peers upgrade, operators can set:

GITLAWB_REQUIRE_SIGNED_PEER_WRITES=true

Configuration

All configuration is via environment variables. See .env.example for the full reference.

Minimum required for a persistent node:

DATABASE_URL=postgresql://gitlawb:changeme@localhost:5432/gitlawb

Important node settings:

Variable Purpose
GITLAWB_HOST / GITLAWB_PORT HTTP bind address and port.
GITLAWB_REPOS_DIR Local bare repo storage directory.
GITLAWB_PUBLIC_URL Public HTTP URL announced to peers.
GITLAWB_P2P_PORT libp2p QUIC/UDP port. Use 0 to disable.
GITLAWB_BOOTSTRAP_PEERS Comma-separated HTTP peer URLs.
GITLAWB_P2P_BOOTSTRAP Comma-separated libp2p multiaddrs.
GITLAWB_BOOTSTRAP_DISABLE_SEEDS Disable embedded seed peers for isolated dev/test networks.
GITLAWB_REQUIRE_SIGNED_PEER_WRITES Require signed peer announce/sync writes.
GITLAWB_AUTO_SYNC Enable automatic sync from known peers.
GITLAWB_MAX_PACK_BYTES Max git pack body size for smart-HTTP routes.
GITLAWB_TIGRIS_BUCKET Optional S3/Tigris shared repo storage bucket.
GITLAWB_PINATA_JWT Optional Pinata/IPFS warm-storage pinning.
GITLAWB_IRYS_URL Optional Irys/Arweave permanent anchoring.

Production note: change the default Postgres password before exposing a node publicly.


Optional node staking

Gitlawb Node includes optional Base L2 node-operator hooks. Operators can register a node DID, stake $GITLAWB, and post heartbeats.

PoS is disabled unless these are configured:

GITLAWB_CONTRACT_NODE_STAKING=0x...
GITLAWB_OPERATOR_PRIVATE_KEY=0x...
GITLAWB_CHAIN_RPC_URL=https://mainnet.base.org

Recommended for operators:

GITLAWB_OPERATOR_STRICT_MODE=true
GITLAWB_HEARTBEAT_INTERVAL_HOURS=20

Read:

Use a dedicated low-balance operator wallet. Do not use a treasury wallet as the heartbeat key.


Building from source

Requires Rust 1.91+.

cargo build --release -p gitlawb-node -p gl -p git-remote-gitlawb

Run tests:

cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace

Run the node from source:

DATABASE_URL=postgresql://gitlawb:changeme@localhost:5432/gitlawb \
  cargo run -p gitlawb-node --release

macOS menu bar app

A native Swift/AppKit menu bar app is included for managing a local Docker Compose stack without living in the terminal.

Requirements:

  • macOS 26+
  • Xcode Command Line Tools
  • Docker Desktop, OrbStack, or Colima

Build:

./scripts/build-macos-app.sh

Output:

dist/Gitlawb Node.app
dist/Gitlawb Node.dmg

Features:

  • Start/stop local node stack.
  • Status indicator.
  • Settings GUI.
  • Auto-start on login.
  • Docker runtime detection.

Unsigned local build:

xattr -cr "dist/Gitlawb Node.app"

Roadmap

The current maintainer focus is live-network stability first.

Short-term priorities:

  1. Keep CI green: fmt, clippy, tests, release build.
  2. Add Docker and installer smoke tests.
  3. Improve operator docs and gl doctor checks.
  4. Harden peer writes and publish the signed-peer rollout plan.
  5. Implement repo write authorization: owner checks, protected branches, and UCAN capability checks.
  6. Implement private-read enforcement or remove private repo affordances until it exists.
  7. Add metrics for pushes, fetches, pack sizes, peer sync, failed auth, and webhooks.

Product direction:

  1. Reliable repo replication.
  2. Health-aware peer syncing.
  3. CDN-style clone/fetch routing to healthy replicas.
  4. App asset/build delivery from nodes.
  5. Operator dashboard and desktop UX.

Read the maintainer roadmap:

docs/MAINTAINER-ROADMAP.md

Contributing

Start here:

Good first contribution areas:

  • docs and install polish
  • Docker smoke tests
  • CLI error messages
  • gl doctor checks
  • operator dashboard UX
  • test coverage for peer sync and signed writes

Security issues should follow SECURITY.md.


License

Licensed under either of:

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project shall be dual licensed as above, without any additional terms or conditions.