jj-axi

July 15, 2026 · View on GitHub

A machine-first companion to Jujutsu for non-trivial history editing using AXI principles.

Use jj for everyday work. Use jj-axi when an agent needs to route hunks, partition changes, reorder history, recover operations, or publish deterministically. jj-axi uses jj-lib directly while preserving ordinary Jujutsu repository compatibility.

Status: Experimental · Language: Rust · License: MIT

Listed in the AXI community catalog.

Why

Jujutsu already provides a strong model and an effective CLI for routine agent work: status, log, new changes, descriptions, and many other operations need no replacement. The leverage gap appears when history editing requires an interactive editor, manual interpretation of patches, or several dependent mutations.

jj-axi targets that narrow interface:

  • one command per reasoning question;
  • stable machine-first schemas;
  • no prompts or editors;
  • exact, fail-loud selectors;
  • atomic workflow-level mutations;
  • structured empty, conflict, partial-result, and recovery states;
  • raw repository compatibility—no private jj-axi metadata model.

A compact fallback instruction is usually enough to introduce the tool:

Use jj for ordinary repository inspection and simple change creation. Before interactive or multi-step history editing—such as full-content squash, patch splitting, moving hunks between changes, or rebasing a stack—run jj-axi and follow its instructions.

Example

# No arguments prints a short guide explaining when to switch from raw jj.
jj-axi

# Repository inspection remains explicit when structured state is useful.
jj-axi inspect

# Discover exact post-image hunks from one immutable snapshot.
jj-axi diff <change> --hunks

# Route one hunk into a new change without an editor.
jj-axi split <change> \
  --source-commit-id '<full snapshot commit id>' \
  --hunks 'src/lib.rs:12-18' \
  --into 'extract parser'

# Undo the latest user-visible mutation while preserving newer work.
jj-axi undo

Normal operational output is TOON:

schema_version: 1
kind: inspect
data:
  current_change:
    change_id: qxkokwlpypzqokvnrrnlxtqnrrpzoorl
    description: ""
    status:
      conflicted: false
  diff_stat:
    changed_files: 2
    added_lines: 14
    removed_lines: 3
    skipped_files: 0
  conflict_count: 0
  divergence_count: 0

Atomic multi-way partitioning

A mixed change can be decomposed into several ordered changes from one guarded snapshot. This avoids repeated diff → split → diff → split loops and routes the remainder explicitly.

First obtain canonical hunks and the full snapshot commit ID:

jj-axi diff <change> --hunks

Create a JSON manifest:

{
  "schema_version": 1,
  "source_commit_id": "<full commit id>",
  "parts": [
    {
      "description": "refactor validation helpers",
      "hunks": [
        {"path": "src/lead.rs", "lines": "21-27"}
      ]
    },
    {
      "description": "tune lead scoring",
      "hunks": [
        {"path": "src/lead.rs", "lines": "38-43"}
      ]
    }
  ],
  "remainder": {"destination": "working_copy"}
}

Preview and apply it through stdin so creating the plan cannot stale the guarded source:

cat partition.json | jj-axi partition <change> --spec-file - --dry-run --details
cat partition.json | jj-axi partition <change> --spec-file -

Remainder policies:

  • remaining_change — create a separate remainder change;
  • working_copy — route unfinished content into the invoking workspace change;
  • require_empty — reject the plan unless every source hunk is assigned.

Partition applies all parts, descendant rewrites, bookmarks, and workspace updates as one operation and one undo boundary. Rewrite conflicts are successful structured state rather than ambiguous command failure. If post-commit colocated-Git synchronization or working-copy update fails, operation_incomplete identifies the failed step and reports that repository state was already updated; inspect before retrying.

Command surface

Repository inspection

  • inspect — current change, diff statistics, conflicts, and divergence;
  • log — bounded structured history with selectable fields;
  • show — one change and its patch;
  • diff [change] [--hunks] — bounded patch and optional canonical hunk inventory;
  • operations — classified operation history.

Change construction and history editing

Routine creation and description can stay on raw jj; compatibility and composite commands remain available:

  • new, describe, checkpoint;
  • split, partition, move, absorb;
  • reorder, squash, abandon;
  • undo [--to <operation-id>].

Bookmarks and publication

  • bookmark list, bookmark set, bookmark push;
  • finish — readiness validation with optional exact bookmark publication;
  • pr status — GitHub pull-request readiness through non-interactive gh api.

Agent integration

  • no arguments — print the routing skill body without YAML frontmatter;
  • skill — print the complete installable routing skill;
  • skill --full — print the detailed agent reference;
  • skill --output <path> [--force] — install the routing skill atomically with conflict protection;
  • setup skill — compatibility alias for protected installation.

Run jj-axi --help or jj-axi <command> --help for the installed command contract.

Installation

Prerequisites:

  • Rust 1.89 or newer when building from source;
  • Jujutsu 0.43.0 available as jj on PATH for working-copy synchronization;
  • gh only when using pr status.

Prebuilt archives for Linux x86-64 and macOS x86-64/Apple Silicon are published on GitHub Releases after the normal CI matrix passes. Each release includes a SHA256SUMS file, and each archive includes the MIT license plus THIRD_PARTY_LICENSES.html. Verify the selected archive before extracting it (sha256sum -c SHA256SUMS on Linux or shasum -a 256 -c SHA256SUMS on macOS), then place jj-axi somewhere on PATH.

Build from source:

git clone https://github.com/aivv73/jj-axi.git
cd jj-axi
cargo build --release --locked
./target/release/jj-axi --version

Agent instructions

jj-axi uses one routing text for automatic skill discovery and manual bootstrap, avoiding two instruction files that can drift:

InvocationPurpose
jj-axiPrint the routing body without YAML frontmatter
jj-axi skillPrint the same routing body with installable skill frontmatter
jj-axi skill --fullDetailed reference for secondary commands and edge cases
jj-axi <command> --helpVersion-matched workflow, examples, and safety contract

Install the compact routing skill with the Vercel Skills CLI:

npx skills add aivv73/jj-axi --skill jj-axi

Alternatively, install the embedded skill atomically. Without --force, concurrent creation never overwrites the winner: identical content is reported unchanged and differing content remains protected. --force replaces differing regular-file content while preserving its permissions:

mkdir -p .agents/skills/jj-axi
jj-axi skill --output .agents/skills/jj-axi/SKILL.md

For shell composition, jj-axi skill prints the same exact bytes to stdout. Use jj-axi skill --full only when the detailed agent reference is needed. The older jj-axi setup skill --output ... spelling remains a compatibility alias. Installing the skill does not install the jj-axi binary itself.

Compatibility and safety

The v0.2.1 compatibility contract is intentionally narrow:

ComponentVerified version or platform
Embedded jj-lib and jj-cli cratesexactly 0.43.0
Installed jj executableexactly 0.43.0, available on PATH
LinuxUbuntu 24.04, x86-64; release binary targets static musl
macOSmacOS 15 on x86-64 and Apple Silicon

Other Jujutsu versions, operating systems, and architectures may work but are not part of the v0.2.1 compatibility contract. The installed jj version should match the embedded libraries to avoid repository-format or working-copy synchronization differences.

  • jj-axi operates on standard Jujutsu repositories through jj-lib.
  • History selectors use exact post-image hunk boundaries; stale or partial ranges fail with bounded canonical recovery candidates.
  • Hunk inventory and selection read at most 1 MiB per file and 8 MiB in aggregate; oversized paths are reported or rejected with materialization_limit.
  • Read commands do not fetch remotes.
  • Publication uses explicit bookmarks and structured partial results.
  • Mutations in colocated repositories synchronize Git state only after committing Jujutsu state; a synchronization failure is an explicit changed-state partial result.
  • GitHub authentication, SSO, and enterprise routing are delegated to gh; pr status runs it with prompts and stdin disabled, validates repository identity before invocation, and rejects inconsistent paginated PR snapshots.
  • Bare undo skips synchronization-only and foundation operations.

The architecture and trade-offs are documented in docs/adr/. Domain terminology lives in CONTEXT.md.

Preliminary benchmark evidence

A v0.2.1 candidate binary and medium-sized canonical skill were rerun with Codex gpt-5.6-sol at low effort across five version-control tasks (k=3, 15 graded runs):

CorrectTasks passing all 3 runsMean wall timeMean task VC commandsMean inspectionsFailed task VC commandsWarm transcript
15/155/570.0s9.16.9015.4 KB

No task-visible version-control command failed. In particular, the tested guidance distinguishes local bookmark placement (jj-axi bookmark set) from remote publication (finish --bookmark). A preceding calibration of v0.2.1 with an over-compressed 1.3 KB skill also passed 15/15, but required 85.5s, 16.5 task VC commands, 14.0 inspections, and 29.5 KB of warm transcript on average. The tested 4.9 KB workflow guide restored concrete workflows without requiring speculative help probes; subsequent wording and recovery hardening did not change the measured command workflow.

For historical context, an earlier k=3 calibration used the then-current v0.1 skill alongside three comparison arms:

ArmCorrectMean wall timeMean task VC commands
plain Git15/1550.1s20.1
GitButler + skill14/1571.5s11.0
raw Jujutsu + external skill14/1598.8s15.3
jj-axi + then-current v0.1 skill15/1546.3s9.9

The historical comparison arms and the current v0.2.1 rerun are separate small-sample batches, so wall-time differences between them are directional rather than paired estimates. These are pilot results, not a general ranking or statistical proof. A dedicated raw-jj-plus-jj-axi benchmark is still needed for the hybrid companion positioning. Correctness remains the gate, and benchmark work does not define product semantics.

The harness and task methodology are maintained in the aivv73/version-control-bench fork.

Design lineage

jj-axi is informed by the AXI principles, with deliberate product-specific adaptations. It does not claim strict AXI conformance. See the AXI applicability audit.

Project documentation