Learn from jj: change IDs, op log, first-class conflicts, working copy as commit
Overview
A load-bearing implementation ticket capturing concrete features Muse should adopt from Jujutsu (jj), informed by a direct feature comparison. These are not cosmetic improvements — each addresses a real gap in agent-first workflows.
What jj does that Muse should learn from
1. Working copy as a commit
In jj the working copy is always an actual commit (@). No staging area, no lost WIP. Every file save is implicitly part of an addressable object.
Muse application: Auto-snapshot the working tree on every meaningful state change. muse status always points to a real addressable object. Eliminates the entire class of "I lost my uncommitted work" bugs. The git-style stage/add/commit split adds friction that jj proves is unnecessary.
2. Change IDs (stable identity across rewrites)
jj tracks two identities per commit:
- Commit ID — content hash, changes on every rewrite
- Change ID — stable identity that persists through rebases and amendments
You can say "find me this logical change" regardless of how many times it's been rebased. Muse only has content-addressed sha256: commit IDs — a rebase produces a new ID with no link to the original.
Muse application: Add a change_id field to CommitRecord. Stable across muse rebase, muse cherry-pick, and muse code patch rewrites. muse log --json should expose both. Critical for agent workflows where a task-branch gets rebased repeatedly — agents need to track "is this the same logical unit of work."
3. First-class conflicts
jj stores conflicts inside commits rather than blocking on them. You can commit a conflicted state, keep working on descendants, and resolve later.
Muse application: Allow muse commit on a conflicted working tree, producing a "pending-resolution" commit. Harmony could track these and auto-resolve when the conflict pattern is seen again. Muse's current merge-halts-until-resolved model blocks agent pipelines unnecessarily.
4. Operations log (jj op log / jj op undo)
Every operation — rebase, branch move, merge, everything — is logged and reversible. Deeper than a reflog: it captures full repo state transitions. jj op undo reverses any operation cleanly.
Muse application: muse op log --json + muse op undo. One-command undo for any repo state transition. This would make the workspace HARD RULE ("no destructive actions without permission") less catastrophic in practice — everything becomes reversible. Harmony's audit log is a partial version of this; a full op log would subsume it.
5. Auto-rebase of descendants
When you edit an ancestor commit in jj, all descendants rebase automatically. No dangling commits, no manual rebase cascade.
Muse application: When muse code patch rewrites a symbol on an ancestor commit, auto-rebase descendant branches. Especially useful in multi-agent workflows where several agents are stacked on a shared base.
6. Immutable commits
jj marks remote/published commits as immutable by default, preventing accidental rewrites.
Muse application: Config-driven immutability: main and any pushed commit cannot be rewritten without an explicit --force and confirmation. Could be expressed as a .muse/attributes rule or a harmony policy.
7. Revsets — composable commit query language
jj's revset language (ancestors(x), heads(all()), merges(), author("gabriel") & description("feat")) is highly composable for selecting commit sets.
Muse application: Extend muse query with a proper revset grammar. Current predicate syntax covers basics but isn't composable. Agents need to express queries like "all commits by claude-code on task/* branches since v1.0 that touch billing.py."
Priority order
| # | Feature | Rationale |
|---|---|---|
| 1 | Change IDs | Highest leverage for agent workflows; touches CommitRecord schema |
| 2 | Op log + undo | Makes destructive-action guardrails reversible; unlocks safer agent autonomy |
| 3 | First-class conflicts | Unblocks agent pipelines; Harmony already has the resolution memory layer |
| 4 | Working copy as commit | Eliminates lost-work bugs; requires rethinking the staging model |
| 5 | Auto-rebase descendants | Quality-of-life for stacked agent branches |
| 6 | Immutable commits | Safety rail; straightforward to implement as a policy layer |
| 7 | Revsets | Power-user + agent query surface; parser work but no schema changes |
What Muse already has that jj lacks (context)
- Symbol-level VCS:
muse code cat/impact/patch/grep - Agent provenance:
--agent-id,--model-id,--sign - Harmony: conflict resolution memory with auto-replay
- Multi-agent coordination:
muse coord claim/complete/shard/forecast - Domain plugins: audio-aware merges, MIDI conflict strategies
- Code intelligence: hotspots, gravity, entangle, dead, breakage
- Hub: proposals, issues, webhooks, releases
The goal is to close jj's UX and safety gaps without losing any of the above.