Introduction
gpp (git++) is an AI-native version control system in Rust. Git was built for humans making deliberate, sequential commits; gpp is built for a world where AI agents produce changes continuously, across many files, faster than humans can review.
Core ideas:
- Continuous timeline capture instead of manual
add/commit. - Curated changesets promoted from the timeline, each with intent.
- Graphex — an encrypted, tier-gated knowledge graph agents query for context (they never see raw or over-tier nodes).
- Trust, policy, cost, anomaly governance enforced at the storage layer.
- P2P sync over Noise, with GitHub/GitLab/Bitbucket as first-class targets — Git only ever sees clean commits.
Everything works locally and offline; hosted infrastructure is optional.
Installation
From crates.io (recommended)
cargo install gpp-cli
This builds the gpp binary. The relay is a separate binary:
cargo install gpp-relay
To track unreleased development instead, install from git:
cargo install --git https://github.com/mahabubul470/gpp gpp-cli
Prebuilt binaries
Each GitHub release
attaches archives for Linux x86_64, macOS (Apple Silicon and Intel),
and Windows x86_64 — unpack and put gpp (and optionally gpp-relay)
on your PATH.
Homebrew
brew install mahabubul470/tap/gpp
Docker
docker run --rm -v "$PWD:/work" -w /work ghcr.io/mahabubul470/gpp:latest status
docker run -p 9473:9473 -p 9474:9474 -v gpp-data:/data ghcr.io/mahabubul470/gpp-relay
Install script
curl -fsSL https://raw.githubusercontent.com/mahabubul470/gpp/main/scripts/install.sh | sh
Verify:
gpp --version
Concepts
| Layer | What it does |
|---|---|
| Storage | Content-addressed, zstd-compressed object store (BLAKE3) |
| Timeline | Continuous file-change capture (SQLite index) |
| History | Curated changesets promoted from the timeline, with intent |
| Graphex | Encrypted, tier-gated knowledge graph + context projection |
| Trust | Agent reputation → behavioral status (auto-merge … blocked) |
| Policy | Compliance-as-code, enforced at promotion |
| Cost | Token/compute attribution per changeset |
| Anomaly | Behavioral detection (scope/burst/size) |
| Diff | Tree-sitter semantic diff (Rust/Python/TS/Go) |
| Sync | Noise P2P; objects/refs/policies/graphex |
| Replay | Reproducible environment snapshots |
| Review/RBAC/Notify | Reviews, roles, events + inbox + webhooks |
| Remote | GitHub/GitLab/Bitbucket PRs, plain Git push |
Access tiers (Graphex): public < agent-readable < agent-restricted < human-only. An accessor only ever sees nodes at or below its tier; the rest
are never decrypted.
Tutorial: Migrating from Git to gpp
cd my-existing-git-repo
gpp init .
gpp git-import . # import all local branches' history
gpp log --oneline # your Git history, now as gpp changesets
gpp diff HEAD # semantic diff for supported languages
Keep using Git in parallel — export back any time:
gpp git-export . # gpp history → Git commits (idempotent)
gpp git-bridge <path> --watch keeps the two in sync continuously.
Nothing about Graphex/timeline/trust/cost leaks into Git.
Tutorial: Setting up Graphex
gpp init --graphex . # provisions the key hierarchy
gpp keys show
gpp graphex add --type service --name orders-service \
-d "Core orders processing engine" --tier public
gpp graphex add --type convention --name money-format \
-d "All monetary values stored as integer cents" --tier public
gpp graphex add --type glossary --name idempotency-key \
-d "Token making retries safe" --tier human-only
gpp graphex link orders-service --relation depends-on --to currency-utils
gpp graphex query "orders-service -> depends-on -> *"
gpp graphex project --tier agent-readable # what an agent would receive
The human-only glossary node is never decrypted for an agent-readable
projection. Rotate keys with gpp keys rotate (re-encrypts every node).
Tutorial: Connecting AI agents via MCP
gpp ships an MCP server over stdio. Point your agent tool at it. For
Claude Code, drop this in .mcp.json at your repo root (or merge it into an
existing one):
{
"mcpServers": {
"gpp": {
"command": "gpp",
"args": ["mcp-server", "--stdio"]
}
}
}
Other MCP clients use the same command/args. To raise what the agent may
read, pass a trust tier: "args": ["mcp-server", "--stdio", "--trust-tier", "raw"]
(default is agent-readable).
On connect, the server returns an instructions block that teaches the agent
the gpp workflow, so you don’t have to explain it in your prompt.
The agent workflow
- Get context before editing —
graphex_queryprojects the knowledge graph (architecture, modules, conventions), tier-filtered to what the agent’s trust level permits.graphex_glossaryandgraphex_conventionsanswer narrower questions. - Edit files normally — the timeline captures every change; no tool call needed.
- Propose a changeset —
propose_changesetwith amessageandintent(feature/fix/refactor/test/docs/chore). It returns the changeset id. - Report cost —
report_costwith that id and your token usage. This is how gpp attributes real cost; without it the changeset is recorded as free. Reports accumulate, so multi-turn work can call it repeatedly. - Propose knowledge —
propose_graph_updateto suggest a durable fact (module, invariant, glossary term). It lands as Proposed, never applied silently.
Tools exposed: graphex_query, graphex_status, graphex_glossary,
graphex_conventions, propose_changeset, propose_graph_update,
report_cost.
All reads are tier-gated by --trust-tier (default agent-readable).
Agent-proposed nodes require human approval:
gpp graphex pending
gpp graphex accept <name> # or: reject
Reporting cost without MCP
Any tool — not just MCP clients — can report usage through the CLI, so a Tier-1 agent (or a wrapper script) can attribute cost too:
# After the agent's changeset is promoted (HEAD, a short id, or a full hash):
gpp cost --report HEAD --model claude-opus-4-8 \
--input 1500 --output 300 --cost-micro 22000
gpp cost --json # roll-up; reports accumulate onto the record
(--cost-micro is integer micro-dollars: 1 = $0.000001.)
Native (Tier 3) agents
Native agents use the Rust gpp-sdk directly:
#![allow(unused)]
fn main() {
let sess = AgentSession::open(".", "agent:claude", "Claude", AccessTier::AgentReadable)?;
let ctx = sess.query_graphex(None, 8_000)?; // context
let cs = sess.propose_changeset(None, None, "add retry queue", IntentType::Feature)?;
sess.report_cost(&cs, "claude-opus-4-8", &Usage { // real cost
input_tokens: 1500, output_tokens: 300, cost_microdollars: 22_000,
..Default::default()
})?;
}
Tutorial: Compliance for regulated industries
gpp policy templates # secrets-scan, pci-dss, soc2
gpp policy template pci-dss # install it
gpp policy template secrets-scan
gpp policy check # run against the working tree
Policies are enforced at promotion — a block-severity hit aborts
gpp promote before any changeset object is written, so a leaked key never
enters history. Branch protection adds review gates:
gpp rbac assign lead@acme.io maintainer
gpp rbac protect main --min-reviewers 2 --require-human true --require-role maintainer
Audit across every layer (trust, anomaly, cost, graphex access):
gpp audit --include-cost --include-graphex
The gpp-policy-check / gpp-trust-gate / gpp-audit-report GitHub
Actions (and the GitLab template) run the same checks in CI.
Tutorial: Using gpp with GitHub
gpp remote setup --platform github --repository acme/webapp --token-env GITHUB_TOKEN
export GITHUB_TOKEN=ghp_…
gpp promote -m "Add retry queue"
gpp remote pr-create --base main # PR enriched with gpp metadata
The PR description carries intent, semantic-change summary, agent, policy and trust — while GitHub only receives clean Git commits.
Or use the gh extension end-to-end:
gh extension install ./extensions/gh-gpp
gh gpp promote -m "Add retry queue"
gh gpp trust # post trust scores as a PR comment
gh gpp sync # import the GitHub default branch back into gpp
For platforms without an API, gpp remote push exports clean Git and
git pushes it.
Tutorial: Setting up a relay node
A relay is just an always-on peer. It stores encrypted objects and forwards them; it never has tier keys and cannot read your code or graph.
On the relay host:
gpp-relay --port 9473 --storage /data/gpp \
--auth-keys /etc/gpp/authorized_keys
# health: curl http://relay:9474/health → {"status":"ok","objects":N}
Or via Docker:
docker run -p 9473:9473 -p 9474:9474 -v gpp-data:/data ghcr.io/mahabubul470/gpp-relay
On each developer machine:
gpp relay add office relay.host:9473
gpp relay push office # then teammates: gpp relay pull office
Divergent same-name branches are preserved as name.fork.<peer> — resolve
explicitly with gpp merge name.fork.<peer> (never a silent merge).
Command reference
The authoritative, exhaustive spec lives in
docs/CLI_SPEC.md.
gpp <command> --help is generated from the same definitions.
Quick map:
| Area | Commands |
|---|---|
| Core | init status config |
| History | timeline promote log diff branch merge |
| Git bridge | git-import git-export git-bridge |
| Graphex | keys graphex mcp-server |
| Governance | trust policy cost anomaly audit |
| Collaboration | review rbac inbox notify |
| Decentralized | sync replay relay |
| Remote | remote |
| Clients | ui deps |
API reference (rustdoc):
cargo doc --workspace --no-deps --open