A JJ-native backend for one continuous software loop
Storage, control plane, policy, leases, and runtime signals are separated by role so the graph can move at agent throughput without losing human-governed truth.
This stack is based on the backend implementation in jj-backend. Its current design is intentionally explicit: immutable object storage for bytes, transactional SQL for active state, and a gRPC contract that is friendly to both human workflows and high-throughput automated clients.
Object storage as immutable truth
Content-addressed blobs, trees, commits, views, operations, and future packs are addressed by SHA-256 and persisted in S3/GCS-compatible object storage.
Postgres as mutable control plane
Repository state, op-head sets, refs, workspace leases, upload sessions, tenant metadata, and audit indexes stay in SQL for transactional correctness.
gRPC API aligned with JJ-native structure
Native operations around BeginUpload, FinalizeUpload, GetObjects, GetOpHeads, CommitOperation, ResolveRefs, UpdateRefs, and future signal/event APIs.
Agentic-era contracts
A live software organism needs contracts Git never had to expose as first-class concepts. VEX makes these explicit so agents can act quickly while the system can still explain, reject, replay, or reverse what happened.
Workspace overlays
Agents need isolated write surfaces that can become JJ changes, be handed to humans, or be discarded without corrupting the base graph.
Actor-scoped leases
High-throughput actors need temporary authority, expiry, ownership, and auditability around the paths and refs they are changing.
Signal events
Runtime health, cache misses, deploy state, and incident conclusions should be written as graph-adjacent events that agents can reason from.
Automation levels
Observe, recommend, guardrailed action, and autonomous remediation are platform states, not informal conventions hidden in prompts.
Consistency and conflict model
CAS on operation heads
Commits advance through compare-and-swap checks so competing updates fail fast instead of silently clobbering remote state.
CAS on refs
Bookmark updates carry versions and can be safely merged with explicit conflict loops.
No hidden mutable state
Presence indexes and op state are explicit and queryable, making caching and policy checks cheap and testable.
Service boundaries we are implementing
jj_backend_service
gRPC transport, config loading, startup migrations, request orchestration.
jj_backend_store
SQL schema, CAS checks for refs/op-heads, transactional safety, presence tracking.
jj_backend_object_store
Object-keyed immutable get/put/exists with pluggable backends.
jj_backend_indexer
Future worker plane for GC, pack materialization, and cross-repo reachability.
Storage layout in one line
The layout already matches explicit object-key patterns for blobs, trees, commits, views, ops, and pack/manifests for future bundling. Repo-scoped paths stay deterministic so pack and manifest builds can be attached without changing history semantics. That matters when the same graph may be read and rewritten by many automated actors in one continuous loop.