libnoa 0.1.1

AI-native distributed version control system with per-agent workspace isolation, JSONL append-only logs, snapshot-based history, and full git protocol compatibility
Documentation

[English]简体中文繁體中文日本語한국어FrançaisEspañolРусскийالعربية

noa is an AI-native distributed version control system. It coexists with .git — git manages source code, noa manages AI agent iteration data — with per-agent zero-lock JSONL logs, snapshot-based history, and full git protocol compatibility.

Why noa

Challenge Git noa
Concurrent writes Lock files, merge conflicts Per-agent JSONL append-only logs
Agent identity user.name/email per repo Workspace-scoped agent_id
Partial contributions All changes in working tree Agent logs only touched files
Iteration tracking Rebase/squash destroys history Immutable snapshot chain per workspace
Multi-agent merge Three-way text merge Merge snapshots, file-level conflicts
Git compatibility N/A System git CLI bridge

Table of Contents

Architecture

graph TD
    subgraph WT["Working Tree (.git + .noa coexist)"]
        direction LR
        subgraph NOA[".noa/"]
            DB["noa.redb<br/>(embedded KV store)"]
            LOGS["agent-logs/"]
            HEAD["HEAD"]
            CFG["config"]
        end
    end

    subgraph DB["noa.redb Tables"]
        direction LR
        BLOBS["blobs<br/>(content-addressed)"]
        TREES["trees<br/>(directory snapshots)"]
        SNAPS["snapshots<br/>(metadata + hash chain)"]
        WS["workspaces<br/>(agent partitions)"]
        REFS["refs<br/>(symbolic pointers)"]
    end

    subgraph LOGS["agent-logs/"]
        direction LR
        DL["default.log<br/>(main workspace)"]
        F1["feat-*.log<br/>(feature workspaces)"]
    end

Core concepts:

  • Workspace: An isolated linear namespace for one agent. Each has its own JSONL log.
  • Snapshot: A point-in-time record of a workspace tree (SHA-256 content-addressed blobs + trees).
  • Agent Log: Append-only JSONL file recording atomic file operations (write, delete, rename) with blob IDs and timestamps.
  • Merge: Three-way merge of two workspace snapshots against their common base.

Installation

From GitHub Releases

# Download the latest release binary for your platform:
#   https://github.com/celestia-island/noa/releases

chmod +x noa
mv noa /usr/local/bin/

From Source (Requires Rust 1.85+)

git clone https://github.com/celestia-island/noa.git
cd noa
cargo build --release
# Binaries: target/release/noa, target/release/noa-server

As a Library (Cargo)

[dependencies]
libnoa = { git = "https://github.com/celestia-island/noa" }

Note: The package name on crates.io is libnoa (the name noa was already taken). The binary is still named noa.

Quick Start

Initialize in an existing git repo

cd my-git-project
noa init                              # creates .noa/ alongside .git/
noa remote add origin "git@github.com:user/repo.git"
noa pull                              # import current git HEAD into noa

Create agent workspaces and iterate

# Agent A works on auth feature
noa workspace create feat-auth -a agent-auth
noa workspace switch feat-auth

# Agent writes to its agent log
# (AI agents write JSONL directly; here is a manual example)
cat >> .noa/agent-logs/feat-auth.log << EOF
{"seq":1,"op":"write","path":"src/auth.rs","blob_id":"<sha256>","ts":1717000000000000}
EOF

# Save the workspace state
noa snapshot create -m "add auth module" -a agent-auth

Merge features and sync with git

noa workspace switch default
noa workspace merge feat-auth          # merge into default
noa push                               # export to git commit + git push

Commands

Workspace Management

noa workspace create <name> [-a <agent-id>]   # Create a new workspace
noa workspace switch <name>                    # Switch active workspace
noa workspace list                              # List all workspaces
noa workspace delete <name>                     # Delete a workspace
noa workspace merge <from>                      # Merge another workspace into current

Snapshot Management

noa snapshot create -m <msg> [-a <author>]     # Create a snapshot from agent log
noa snapshot list                               # List snapshots
noa snapshot diff <id-a> <id-b>                # Diff two snapshots (file-level)

Remote Operations

noa remote add <name> <url>                     # Add a remote
noa remote remove <name>                        # Remove a remote
noa remote list                                 # List remotes
noa fetch [-r <remote>]                         # List remote refs
noa pull [-r <remote>]                          # Git pull + re-import into noa
noa push [-r <remote>]                          # Export snapshot → git commit → git push

Repository Operations

noa init [-p <path>] [--noa-remote <url>]      # Initialize a .noa/ repository
noa clone <url> [-p <path>]                     # Git clone + import into noa
noa clone --svn <url> [-p <path>]              # SVN export → git init → import into noa
noa status                                       # Show current workspace status
noa log [-w <workspace>] [-n <limit>]          # Show snapshot history

Git Integration

noa uses the system git CLI for all network operations. This ensures 100% compatibility with any git remote.

Push Workflow

flowchart LR
    A["noa snapshot"] --> B["build tree"]
    B --> C["export files to working tree"]
    C --> D["git add -A"]
    D --> E["git commit"]
    E --> F["git push"]

Pull Workflow

flowchart LR
    A["git pull"] --> B["read HEAD commit"]
    B --> C["import tree into noa (via gix)"]
    C --> D["create snapshot"]
    D --> E["update workspace head"]

Clone Workflow

flowchart LR
    A["git clone"] --> B["import tree into noa"]
    B --> C["create default workspace"]
    C --> D["setup .gitignore"]

Key Design Decisions

  • Export is additive: Only files in the noa snapshot are written to the working tree. Existing git-tracked files not in the snapshot are left unchanged.
  • Import uses gix: For local tree traversal (no network needed). Network operations use system git CLI.
  • .noa/ auto-gitignored: noa init appends .noa/ to .gitignore so agent data never leaks into git history.

Compatibility

Platforms Tested

Provider Protocol Push Pull Clone LFS
GitHub HTTPS, SSH
Bitbucket HTTPS, SSH
GitLab HTTPS, SSH
Local bare repo file://
SVN svn:// Import only --svn

Git LFS

noa automatically detects Git LFS repositories:

  • noa clone: runs git lfs install + git lfs pull for LFS-tracked repos
  • noa push: runs git lfs push --all after git push
  • noa pull: runs git lfs pull after git pull
  • LFS pointer files are imported as regular blobs into noa

SVN

noa clone --svn file:///path/to/svn/repo -p ./my-project

This does svn export trunk → git init → noa import. It's a one-time import — for incremental sync, use svn export + noa snapshot create on a schedule.

Bitbucket

Both SSH (git@bitbucket.org:ws/repo.git) and HTTPS (https://user@bitbucket.org/ws/repo.git) URLs are supported natively through the git bridge.

API (libnoa)

libnoa exposes a Rust API for embedding noa functionality into other tools:

use libnoa::repo::Repository;
use libnoa::snapshot::SnapshotEngine;
use libnoa::log::FileAgentLog;

// Open a repository
let repo = Repository::open(&path)?;

// Create a workspace
let ws_mgr = repo.workspace_manager()?;
ws_mgr.create(&Workspace {
    name: "feat-x".into(),
    head: base_snap_id.clone(),
    base: base_snap_id.clone(),
    agent_id: Some("my-agent".into()),
    created_at: now,
    updated_at: now,
}).await?;

// Build a snapshot from agent logs
let engine = SnapshotEngine::new(
    FileAgentLog::new(&path, "my-agent")?,
    repo.snapshot_store()?,
    repo.object_store()?,
)
.with_repo_root(repo.root.clone());
let snapshot = engine.compute("feat-x", vec![], "author", "message").await?;

// Export snapshot to git
libnoa::git::export_noa_to_git(&repo.root, repo.db.clone()).await?;

See tests/smoke.rs and tests/compat.rs for more usage examples.

Building from Source

# Prerequisites: Rust 1.85+, git, pkg-config (optional for LFS/SVN)
git clone https://github.com/celestia-island/noa.git
cd noa

# Build
cargo build --release
# Output: target/release/noa (CLI), target/release/noa-server (API server)

# Run tests
cargo test -- --test-threads=1

# Start the noa server
NOA_PORT=3000 NOA_DB_PATH=/data/noa/server.redb target/release/noa-server

Related Projects

Project Relationship
entelecheia Multi-agent orchestration platform. Consumes noa for agent workspace versioning.
tairitsu WASM component model framework. Future: noa client as WASM component.
kirino Zero-trust auth/RBAC. Used by noa-server for authentication.

License

Apache-2.0. See LICENSE.