{"slug": "show-hn-heddle-atc-for-your-subagents", "title": "Show HN: Heddle- ATC for Your Subagents", "summary": "Heddle, a new open-source tool formerly known as loom-vcs, launches as version control for AI coding agents, preventing file collisions by using intent leases and isolated worktrees. The tool reports conflicts before tokens are spent, unlike git which discovers them after the fact, and targets fleets of agents working on a single repository. Heddle is serverless and git-native, offering leaderless, warn-only leases and an always-green mainline.", "body_md": "*Version control for many hands moving at once.*\n\nGit is the filesystem; Heddle is air traffic control.\n\nA heddle is the part of a loom that keeps threads separated so they never tangle. That's the product.\n\nFormerly known as loom-vcs; renamed to avoid collision with several unrelated Loom projects.\n\n**Without Heddle.** You point two Claude Code sessions at your repo. Agent A\nspends 40 minutes and ~200k tokens rewriting `src/auth/`\n\naround a new session\nmodel. Agent B, told to \"clean up the login flow\", touches the same files with\nthe opposite assumption. Neither knows the other exists — git has nowhere to\nput that knowledge. B finishes last, so B's edits win; A's work is silently\ngone from the tree. The test suite goes red at commit time, and you spend the\nevening (and another few hundred thousand tokens) having a third session\ndiagnose a breakage that is really two AIs' half-rewrites interleaved. The\nmost expensive thing agents do is semantically reconcile two overlapping\nrewrites after the fact — and this workflow makes it routine.\n\n**With Heddle.** A leases `src/auth/**`\n\nwith the goal \"move auth to the new\nsession model\". When B's session asks Heddle what's being worked on — one MCP\ncall — it sees that lease, goal attached, and self-partitions: it either takes\nthe suggested disjoint scope or waits. The collision is reported at the\n*start*, when handling it costs one tool call, not at the *end*, after both\nbudgets are spent. If both proceed anyway, each works in its own worktree,\nnothing is overwritten, and the second landing is told exactly which files\nmoved and rebases once — the expensive reconciliation becomes rare instead of\nfast.\n\nThat is the entire bet: **git reports collisions after the tokens are spent;\nHeddle reports them before.**\n\nYou run several coding agents on one repo. They overwrite each other's files,\nland red on top of red, and die mid-task leaving dirty worktrees nobody owns.\nYou can't see who is doing what, so every collision is discovered at the end\n— at merge or in CI — when the only fix is expensive re-work. Git has no\nconcept of *intent*: a branch name is a string, so agents can't ask \"who is\nalready working on this?\" and route around each other.\n\n**Isolation**— every task gets its own git worktree; two threads*physically cannot*clobber each other's edits.**Coordination**— before editing, a thread declares an** intent lease**(machine-readable goal + file globs); overlaps warn at declaration time, which lets agents self-partition work over MCP with no human traffic cop. Leases warn, they never block — an agent is never stopped; the only gate is at landing.**Integration**— the mainline (** fabric**) advances only through a green verify run plus a human/consent gate, with an honest file-level merge: a file changed in both the fabric and the thread refuses to land (\"fabric moved under you — rebase\") instead of overwriting either side. Never-red main means no fleet-wide token burn diagnosing a stranger's breakage.**Recovery**— a dead agent's thread becomes an** orphan**: goal, acceptance criteria, and a seconds-old checkpoint attached, claimable by anyone. That is schedulable work, not a mystery dangling branch.\n\nAn honest concession: two careful humans working slowly don't need this. The value scales with writer count and edit frequency — it exists for fleets of agents (and humans who work like them).\n\nHeddle is not alone in this space. Several projects have converged on\nworktree isolation + gated merging — that convergence is evidence the\nproblem is real. What Heddle claims as its own is narrower and specific:\n**leaderless, warn-only intent leases** (no dispatcher, no locks), an\n**always-green fabric advanced only by compare-and-swap over bare git\nremotes** (no server), **decentralized orphan adoption**, and\n**stitch-level history** — a serverless, git-native *protocol* and one\nbinary, not a platform. See [Adjacent projects](#adjacent-projects) for the\nneighbors and what each does that Heddle doesn't.\n\n**N agents racing the SAME task.** Heddle coordinates*different*tasks on one repo. For redundant attempts at one task, use a judge/tournament harness — then lease the winner's landing.**Replacing git.** Heddle sits on top; git stays your history, remotes, and review tooling. The optional bridge projects each landed weave into local git history — one commit per weave by default, checkpoint-level if you ask (see`bridge_mode`\n\nbelow) — and never pushes.**Humans doing normal PRs.** Slow, coordinated-out-of-band work is what git+GitHub already does well.\n\nThe disaster being prevented, on your own machine. One repo, two terminals (\"agents\" A and B):\n\n```\ncargo install --path .        # one binary: heddle\ncd your-repo\nheddle init --verify \"cargo check\"     # or any command that exits 0 on green\n```\n\n**Keep the verify fast.** It runs on *every* `heddle propose`\n\n, and every agent\nwaits for it before its work can land — a 49-second suite is 49 seconds of\nevery agent's time, every attempt. Point it at a quick subset (a few seconds:\n`cargo check`\n\n, `pytest -q -m \"not slow\"`\n\n, `npm run test:fast`\n\n) and let the full\nsuite run in CI. `heddle init`\n\ntimes the command once and tells you if it is\nslow (it skips that when stdout isn't a terminal, or with\n`HEDDLE_SKIP_VERIFY_TIMING=1`\n\n).\n\n**A:**\n\n```\nheddle lease \"greet in french\" 'greeting.txt'\n#   WORK IN: ~/.heddle/<repo>/worktrees/<thread-A>     ← A's own worktree\n```\n\n**B, at the same time:**\n\n```\nheddle lease \"greet louder\" 'greeting.txt'\n#   TOE-STEP: your 'greet louder' overlaps 'greet in french'\n#   (a lease warns, it never blocks — coordinate or continue)\n#   WORK IN: ~/.heddle/<repo>/worktrees/<thread-B>     ← a DIFFERENT worktree\n```\n\nBoth edit the same file — in their own worktrees, so nothing clobbers. A finishes first:\n\n```\n# A (use --lease/--thread ids from the lease output when sharing a terminal):\nheddle stitch          # checkpoint (content-addressed; deletions tracked)\nheddle propose         # verify runs in a scratch copy; on green it asks y/N\n# → woven: 1 files applied\n```\n\nB proposes next, and gets the truth instead of a silent overwrite:\n\n```\nheddle stitch && heddle propose\n# → verify green … but landing refuses:\n#   fabric moved under you on greeting.txt — rebase the thread and re-propose\nheddle rebase\n#   CONFLICTS — both the fabric and this thread changed:\n#     greeting.txt (your version kept in the worktree; the fabric's is in the repo tree)\n# reconcile the file in B's worktree, then:\nheddle stitch && heddle propose\n# → woven — B's landing includes A's work instead of erasing it\n```\n\nKill a session mid-task (or let its lease TTL lapse) and `heddle status`\n\nshows\nthe thread as an **orphan** — `heddle adopt <thread-id>`\n\nhands the next agent\nits goal, criteria, and worktree, checkpoint intact.\n\n```\nclaude mcp add heddle -- heddle mcp\n```\n\nThe tool flow an agent follows:\n\n`heddle_status`\n\n— who's working on what (threads, live leases, orphans).`heddle_lease`\n\n— declare goal + scope. The response's`working_dir`\n\nis the thread's worktree:**cd there and make all edits in it.** Toe-step warnings come back in the same response — the moment to renegotiate scope.- work →\n`heddle_stitch`\n\nevery few edits (checkpoints + heartbeats the lease). `heddle_propose`\n\n— runs the verify in a scratch copy and reports green/red. The apply is always refused over MCP: landing takes a human at a terminal (`heddle propose`\n\n) or a host with an approvals queue. Proposing verifies; it never lands.- On \"fabric moved\":\n`heddle_rebase`\n\n, reconcile any conflicts in the worktree, stitch, re-propose.`heddle_adopt`\n\npicks up orphans (local or a synced peer's).\n\nTwo people, one private GitHub repo. Heddle syncs through it over hidden\n`refs/heddle/*`\n\nrefs — no server, no daemon, nothing new to host.\n\n```\n# Both of you, once, in your own clone:\nheddle init --verify \"npm test\"        # whatever green means for the project\nheddle sync --remote origin            # remembers the remote for this repo\n```\n\nThen work exactly as in the quickstart — lease, edit in your worktree,\nstitch, propose — and run `heddle sync`\n\nwhenever you want to exchange state\n(or opt in to `heddle sync --auto`\n\nto sync after every stitch/propose):\n\n```\nyou>    heddle lease \"dark mode styles\" 'style.css'      # + edit, stitch\nfriend> heddle lease \"compact header\" 'style.css'        # + edit, stitch\nyou>    heddle propose && heddle sync                      # lands, publishes\nfriend> heddle sync        # pulls your weave into their tree\nfriend> heddle propose     # green — but landing says: fabric moved under you\nfriend> heddle rebase      # your change fast-forwards in; real conflicts kept\nfriend> heddle stitch && heddle propose && heddle sync       # merged result lands\nyou>    heddle sync        # both trees now identical, both changes present\n```\n\nZero merge fear in two sentences: neither of you can overwrite the other, because edits live in per-thread worktrees and the shared line only advances through a compare-and-swap ref push that refuses when it moved under you. The worst case is not a broken tree — it is being told, by name of file, what to look at before your work lands.\n\nWhat sync shares, plainly: your heddle metadata (goals, scopes, holders) and\nthe file content of your stitched scope go to that remote — the same\nexposure as pushing a branch there. `--auto`\n\nis opt-in per repo. Dead\nmachines' threads show up as adoptable orphans; claims are first-push-wins\non a git ref, and the loser is told who won.\n\nOne concrete breakage. Agents A and B both edit `config.rs`\n\non branches.\nMerge time: git sees the same *lines* touched, declares a conflict, and hands\nit to whoever merges last — a fresh agent session with no memory of either\nintent, reconciling two rewrites token-by-token. Or worse: they touched\n*different* lines, git auto-merges silently, and main is red with a breakage\nneither author can reproduce alone. Every agent then pulls red main and burns\ntokens on a failure that was manufactured by the workflow.\n\nHeddle's answer, point by point:\n\n- The overlap was knowable at lease time; git had nowhere to record it. Heddle reports it before either agent spends anything.\n- Reconciliation, when it must happen, goes to the\n*surviving author*(who has the context), scoped to named files, against a green tree — not to a stranger at merge time against a red one. - Rebases are made\n**rare**, not fast: self-partitioning at lease time means most collisions never happen.\n\n**Landing is consent-gated.** A green verify is evidence, not an action. The terminal asks y/N; MCP always refuses the apply; embedding hosts park an approval. Nothing reaches the repo tree without a yes.**Deletions are first-class.** A file you delete in your worktree is recorded as a tombstone, lands as a deletion, and delete-vs-edit collisions refuse like any other conflict.**Big files are skipped, loudly.** Files over 8 MiB are not snapshotted; each one is named in the stitch result. Raise the cap with`HEDDLE_MAX_FILE_MB`\n\nif you must; prefer a`.heddleignore`\n\nat the repo root (gitignore-lite: literal dirs and simple globs, one per line) — it extends the built-in`.git`\n\n/`target`\n\n/`node_modules`\n\nexcludes and cannot un-ignore them.removes worktrees of woven threads — and refuses if the worktree holds anything not captured in a stitch.`heddle clean`\n\n**Verify is whole-repo, in a scratch copy, with a hard timeout.** Red never lands; a gate that can't even stage its check reports red, not silence.**Rename compatibility (loom-vcs → heddle).** The old`LOOM_DATA`\n\nand`LOOM_MAX_FILE_MB`\n\nenv vars are honored as silent fallbacks when the`HEDDLE_*`\n\nones are unset, and a`.loomignore`\n\nis read when no`.heddleignore`\n\nexists. If`~/.loom`\n\nexists and`~/.heddle`\n\ndoesn't, Heddle keeps using`~/.loom`\n\n(with a one-line notice) — data is never moved silently; migrate with`mv ~/.loom ~/.heddle`\n\nwhen convenient.\n\nThe philosophy: **one lease = one goal = one commit.** Scope leases small and\nthe bridge's default gives you a semantic git log where every commit is a\ngoal that verified green. `bridge_mode`\n\nexists for teams who want\ncheckpoint-level history in git itself — set it at `heddle init --bridge-mode <mode>`\n\nor later with `heddle config --bridge-mode <mode>`\n\n:\n\n| mode | what lands in git | one-line guidance |\n|---|---|---|\n`squash` (default) |\none commit per weave: goal + criteria + verify | scope leases small; keep the log semantic |\n`stitches` |\nevery checkpoint as a commit on a `heddle/<thread>-<goal>` branch, then a merge commit carrying the weave message |\nyou want checkpoint-level `git bisect` /review without losing the semantic landing |\n`both` |\nthe squash commit + the per-thread branch preserved, unmerged | clean mainline log, archaeology on the side |\n\nCheckpoint replay is pure git plumbing (a temporary index; `read-tree`\n\n→\n`hash-object`\n\n→ `update-index`\n\n→ `write-tree`\n\n→ `commit-tree`\n\n) — it never\ntouches your working tree, real index, or current branch; empty-diff\ncheckpoints are skipped. Nothing is ever pushed, in any mode.\n\n`heddle export [--thread <id>]`\n\nwrites an **unlanded** thread's checkpoints to\nthe same per-thread branch — review an agent's in-flight work with plain\n`git log -p heddle/<thread>-<goal>`\n\n; nothing lands, nothing moves.\n\n| rung | status |\n|---|---|\n| Several agents, one machine | shipped — worktree isolation, leases, green gate, orphans, configurable git bridge + draft-branch export (45 tests) |\n| A few people/machines, one shared git remote | shipped — `heddle sync` : state over `refs/heddle/*` , CAS fabric ref, cross-machine adoption claims; metadata is unsigned (machine ids are identity, not authentication) |\n| Team knobs (consent dials, envelopes) | exists in the Aether integration, which embeds this crate; the generic mailbox namespace here is the hook it rides on |\n| Many peers, no blessed remote (gossip) | design only — see\n|\n\nAgainst the substrates Heddle builds on or replaces the workflow of:\n\n| git worktrees alone | Jujutsu | CI-gated trunk | Heddle | |\n|---|---|---|---|---|\n| Per-task isolation | yes | yes (working-copy commits) | no | yes (worktree per thread) |\n| Machine-readable intent, collision warning at start | no | no | no | yes (leases + toe-steps) |\n| Mainline can't go red | no | no | yes (post-hoc, in CI) | yes (verify before land, local) |\n| Refuses to overwrite concurrent work | manual merge | manual resolve | last merge wins | yes (three-way refusal + rebase) |\n| Crashed work is claimable with its goal attached | no | no | no | yes (orphans + adoption) |\n| Agent-native interface (MCP) | no | no | no | yes |\n| Multi-machine without new infra | via remotes, manual | via git remotes, manual | server | any shared git remote (`heddle sync` ) |\n| Is your git history | yes | yes | yes | yes (bridge: squash, per-checkpoint, or both — never pushed) |\n\nAgainst the adjacent agent-coordination projects (see\n[Adjacent projects](#adjacent-projects) for links; claims below are from\ntheir own docs as of July 2026):\n\n| what it is | needs a server / control plane? | coordination style | multi-machine without new infra? | always-green invariant? | crash-recovery semantics | |\n|---|---|---|---|---|---|---|\n| aweb | platform (coordination server + identity registry) | yes — server (FastAPI/Postgres/Redis) plus `awid` identity service |\nmail, chat, tasks, roles, presence, file locks; MCP tools |\nyes, but through its server (team certificates) | not documented | not documented |\n| batty | platform (Rust daemon driving tmux agent teams) | yes — persistent daemon | hierarchical dispatch: architects plan, managers route, engineers execute — each engineer in its own worktree | single host (daemon + tmux) | yes — daemon auto-tests completions and merges on green; no agent in the merge path | crash respawn, stall detection (all roles), auto-restart |\n| stoneforge | platform (TypeScript web control plane) | yes — local server + web dashboard | dispatch daemon assigns dependency-ordered tasks; Director / Worker / Steward roles; worktree per worker | not addressed — local orchestration | merge steward runs your test command, squash-merges on pass, hands failures to a new worker | event-sourced log; session resumption not yet implemented |\n| valkor-ai/loom | delivery harness (local MCP state machine for one agent) | no | single-agent plan → build → test → fix loop; not multi-agent coordination | n/a (per-machine, per-project) | review/repair loop with recorded evidence; no hard merge block | state saved under `.loom/` ; resume with `/loom continue` |\n| Heddle | protocol + one binary on top of git | no — state lives in your repo and any ordinary git remote | leaderless, warn-only intent leases; no dispatcher, no locks |\nyes — any shared git remote (`heddle sync` ) |\nyes — verify in a scratch copy + consent gate; fabric advances only by CAS ref push | orphans: goal, criteria, seconds-old checkpoint attached; adoptable cross-machine, first CAS claim wins |\n\nRead the columns honestly: the platforms above do things Heddle deliberately does not — orchestration, role hierarchies, task boards, chat, presence, automated dispatch. Heddle only coordinates writers and keeps the shared line green.\n\n[aweb](https://github.com/awebai/aweb)— a team-coordination platform for agents: mail, chat, tasks, file locks, presence, and roles behind a server and an identity registry.[batty](https://github.com/battysh/batty)— a Rust daemon that runs hierarchical agent teams in tmux, with a worktree per engineer and a verify-then-auto-merge loop that keeps agents out of the merge path.[stoneforge](https://github.com/stoneforge-ai/stoneforge)— a TypeScript web control plane with Director/Worker/Steward roles, a dispatch daemon, worktree isolation, and test-gated merge review.[valkor-ai/loom](https://github.com/valkor-ai/loom)— a delivery harness that keeps a single agent on track through a multi-step task (plan, build, test, fix) with resumable state between sessions.[rjwalters/loom](https://github.com/rjwalters/loom)— orchestration that uses your git forge as the coordination layer, driving agents through labels on issues and PRs.\n\nHeddle is deliberately the thin layer: a protocol and a binary, not a platform. If you want orchestration on top, these are good; Heddle aims to be what they could coordinate through.\n\nMIT — see [LICENSE](/zyads/heddle/blob/main/LICENSE).", "url": "https://wpnews.pro/news/show-hn-heddle-atc-for-your-subagents", "canonical_source": "https://github.com/zyads/heddle", "published_at": "2026-07-27 22:42:19+00:00", "updated_at": "2026-07-27 23:22:27.456691+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents", "artificial-intelligence"], "entities": ["Heddle", "Claude Code", "MCP"], "alternates": {"html": "https://wpnews.pro/news/show-hn-heddle-atc-for-your-subagents", "markdown": "https://wpnews.pro/news/show-hn-heddle-atc-for-your-subagents.md", "text": "https://wpnews.pro/news/show-hn-heddle-atc-for-your-subagents.txt", "jsonld": "https://wpnews.pro/news/show-hn-heddle-atc-for-your-subagents.jsonld"}}