VERSION CONTROL FOR AGENTS

Code review breaks when
half the contributors are agents.

Heddle gives every agent a name, a thread, and a signature. All three are woven into each merge.

01 Attribution

Know who wrote
which line.

Every change has an actor. Every actor is named. Heddle records the human who delegated, the agent that wrote, the model and version they used, and the confidence of each contribution. The diff is no longer a list of changes; it's a record of who changed what.

src/repo/import.rs hd-d01a8b4e
  1. 1 pub fn import_git_repo(path: &Path) -> Result<Import, Error> {
  2. 2 let repo = Repository::open(path)?;
  3. 3 let commits = collect_commits(&repo)?;
  4. 4
  5. 5 // Two-phase import preserves commit signatures.
  6. 6 // Single-pass would invalidate upstream GPG chains.
  7. 7 let mut builder = TreeBuilder::new();
  8. 8
  9. 9 for commit in commits.iter() {
  10. 10 let oid = commit.id();
  11. 11 let sig = commit.signature();
  12. 12 builder.add_orphan(oid, sig)?;
  13. 13 }
  14. 14
  15. 15 for commit in commits.iter() {
  16. 16 let parents = commit.parent_ids().collect();
  17. 17 builder.link_parents(commit.id(), parents)?;
  18. 18 }
  19. 19
  20. 20 // Validate: every commit must have its original
  21. 21 // signature reachable in the imported tree.
  22. 22 let imported = builder.build()?;
  23. 23 for commit in commits.iter() {
  24. 24 let got = imported.signature_for(commit.id())?;
  25. 25 ensure!(got == commit.signature(), "signature mismatch");
  26. 26 }
  27. 27
  28. 28 Ok(Import {
  29. 29 repo: imported,
  30. 30 n_commits: commits.len(),
  31. 31 ..Default::default()
  32. 32 })
  33. 33 }
02 Threads

Every agent. One repository.
No silent rewrites.

Each agent works in its own thread. Every thread tracks its own changes. A merge creates a new state. Simple, atomic, undoable. Heddle keeps every commit, every signature.

feature/auth/middleware

claude · opus 4.7

  1. pkka73 scaffold session middleware
  2. hxe72g verify JWT signatures
  3. 5xtkhq rate-limit per session
  4. 2qpsr7 extract token store

4 states

feature/auth/tests

gpt · 5.4

  1. zepss6 cover login happy path
  2. 3jmtnk test expired tokens
  3. 9fbcqm fuzz the rate limiter

3 states

feature/auth/docs

grok · 4.20

  1. x9r2qm draft auth API reference
  2. vknq84 add migration notes

2 states

MERGE feature/auth 9 commits · 3 agents · all signatures verified
claudefeature/auth/middleware · 4gptfeature/auth/tests · 3grokfeature/auth/docs · 2mainhd-pkka73p5zbe3b · claudepkka73hd-hxe72g89a4mq2 · claudehxe72ghd-zepss63kb2s5n · gptzepss6hd-x9r2qmf3a8wp · grokx9r2qmhd-vknq84llr2cm · grokvknq84hd-5xtkhq8wp3nv · claude5xtkhqhd-3jmtnkkkr9t8 · gpt3jmtnkhd-9fbcqmt2pxh4 · gpt9fbcqmhd-2qpsr7vn5cks · claude2qpsr7hd-d01a8b4e
03 Context

Reasoning woven
into the code.

Annotations anchor to files, symbols, and lines, not to threads that evaporate. Heddle parses the code, so when a function moves the annotation moves with it. Each one is typed: invariant, rationale, constraint. The next engineer (or agent) inherits the reasoning, not just the diff.

src/repo/import.rs 3 annotations · attached at object
  1. invariant · signature preservation

    import_git_repo line 1

    A single-pass import that interleaves add_orphan with link_parents will repack commits before validation, breaking the GPG chain on any signed upstream ref. Two-phase is the only structure that holds the chain intact.

    tagged enforces:import_signing.spec area:gpg-chain · since hd-c4f3a201

  2. 1 pub fn import_git_repo(path: &Path) -> Result<Import, Error> {
  3. 2 let repo = Repository::open(path)?;
  4. 3 let commits = collect_commits(&repo)?;
  5. 4
  6. 5 let mut builder = TreeBuilder::new();
  7. 6
  8. 7 for commit in commits.iter() {
  9. rationale · why two phases

    TreeBuilder::add_orphan line 8

    Splitting structural mutation from cryptographic check means a bad signature fails the import atomically, before any commit lands. Callers of Repository::open never observe a partial state.

    tagged pattern:two-phase pairs:link_parents · since hd-c4f3a201

  10. 8 builder.add_orphan(commit.id(), commit.signature())?;
  11. 9 }
  12. 10
  13. 11 for commit in commits.iter() {
  14. 12 builder.link_parents(commit.id(), commit.parent_ids())?;
  15. 13 }
  16. 14
  17. 15 let imported = builder.build()?;
  18. 16
  19. 17 for commit in commits.iter() {
  20. 18 let got = imported.signature_for(commit.id())?;
  21. constraint · atomic abort on mismatch

    ensure! line 19

    ensure! halts mid-loop on the first signature mismatch. The transaction wrapping builder.build() rolls back any tree mutations, so the on-disk repo is never half-imported.

    tagged enforces:import_atomicity.spec area:transactions · since hd-d01a8b4e

  22. 19 ensure!(got == commit.signature(), "signature mismatch");
  23. 20 }
  24. 21
  25. 22 Ok(Import {
  26. 23 repo: imported,
  27. 24 n_commits: commits.len(),
  28. 25 ..Default::default()
  29. 26 })
  30. 27 }
04 Control plane

One surface.
Full authority.

Namespaces, repositories, threads, and agent activity — governed from a single pane. You set policy once. Inheritance does the rest. Click into any thread.

4 repos · 6 threads · 4 agents K

AGENTS CONVERGING ON HEDDLE

claude opus 4.7 Anthropic 3 threads
gpt 5.4 OpenAI 1 thread
grok 4.20 xAI 1 thread
claude sonnet 4.6 Anthropic 1 thread
heddle main · hd-d01a8b4e

6 threads · 4 repos · 100% accountability

Names, not noise.

One verified state. Every change permanent, attributed, and inspectable.

Apply.

Onboarding teams who take provenance seriously.