Lacunari

Coordination infrastructure for people and machines

A hundred workers.
One project.
Nothing collides.

Lacunari reads your entire project — code, documents, scans, research — and turns it into a living roadmap: what exists, what is missing, and what to do next. Engineers, contractors and AI agents work it at the same time, on the same repository, without duplicating each other or overwriting each other's files.

$ lac doc index . --source my-repo $ lac doc extract && lac web build $ lac web gaps files 92 · 6 languages · 13,582 lines no docs mention 29 nothing calls 122 nothing names it 2 no test mentions 86 $ lac web suggest --dispatch → 47 tasks filed, all claimable $ lac work & lac work & lac work & and you go to bed.
the board● live
#49Corroborate the 1943 gapopen
#48Document lac-webclaimed
#47Add coverage for auth.pyopen
#45Rotate the log archivesdone
#44Renew the TLS certificateneeds you

The bottleneck was never how fast the model writes code. It is that the plan lives in a handful of people's heads — and it only comes out one prompt, one standup, one ticket at a time.

The 2005 model is over

Your version control was designed for
humans typing. In 2005.

Git is superb at what it was built for: recording that bytes changed and reconciling two people who changed them, at the speed people work. It has never read a file, has no idea what your project is, and detects a collision only once both parties have finished. That was a reasonable set of assumptions when the whole team was human and typing. It is not the world you are working in now.

QuestionGitLacunari
What changed?Line diffs between commitsEvery version content-addressed, who contributed it, when, in an immutable audit trail
What is this codebase?Stores your files, never reads themEvery symbol, import and language, and what calls what
What is unfinished?Absence is not a diffUndocumented, untested, uncalled, orphaned — already filed as claimable work
Who is on it right now?A merge conflict, after both did the workAn atomic claim, before a keystroke is spent
What is this goal made of?NothingDecomposed into a tree, one level at a time, against the real files
Merging two parties' workConflicts when you touched the same linesCannot conflict — same bytes, same hash, so a merge is a union
What did it cost?NothingDollars and human minutes, per task, with hard ceilings

Merging is worth sitting with. Because documents are keyed by the hash of their contents, two parties combining catalogues is a union, not a negotiation — the same document is the same document, whatever either of you named it. Where you genuinely disagree, both readings are kept and the disagreement becomes visible, rather than one side winning and the evidence being destroyed.

The long version: what git cannot answer →

The wall everyone hits

One agent is a typist.
A hundred is an organisation.

Adding people or agents does not help past a point, and everyone who has run a large team knows why. Two of them edit the same file. Three redo work a fourth already finished. One stops at 3am and takes its context with it. None of them know the plan, because the plan was never written anywhere they can read — it lives in a lead's head, a stale ticket, and a Slack thread nobody can find.

Nobody wrote the roadmap down

It lives in your head, or in a ticket system describing what someone thought six weeks ago rather than what the code says today. An agent can read neither.

Nothing knows what is unfinished

Git stores your files and has never read one. Search ranks what exists. Neither can tell you which modules have no tests, which functions nothing calls, or which claim rests on a single unverified source.

Collisions are detected far too late

A merge conflict is a fine collision detector at human speed, with a standup and a Slack channel. It fires after both parties did the work — useless when eleven agents reach for the same file inside the same minute. By the time git objects, the tokens are spent.

Work dies with the process

A session that crashes takes its context with it. Nobody else knows what it was doing, how far it got, or that it should be picked up.

Roadmap & product development

State the objective.
It decomposes against your real code.

A roadmap is normally a document somebody maintains by hand until they stop. Here it is derived from the project itself, expanded one level at a time against what is actually in the tree, and it updates itself as work lands.

$ lac goal add "Ship multi-tenant support" \ --criteria "every query scoped to a tenant, with tests" \ --depth 3 --budget 40.00 $ lac goal plan 1 # expand ONE level, grounded in the code ○ Ship multi-tenant support ○ Add tenant_id to the 9 tables that lack it work ○ Scope the 41 queries in core/ that ignore it work ○ Decide the isolation boundary: RLS or app-level needs a human ○ Backfill fixtures for the 12 untested paths work $ lac work & lac work & lac work & → the roadmap is the queue. nobody assigns anything.

Planned one level at a time

The decomposition at depth 4 depends on what depth 2 learned, so leaves expand when they are reached — with their siblings' findings in hand. Work starts before planning ends, and a wrong branch is pruned before its subtree exists.

It grooms itself

Every derived item carries a stable identity, so when the work is genuinely done the item withdraws itself. No backlog triage, no tickets describing a codebase that moved on six weeks ago.

Status without a status meeting

Rollups by subtree: what is open, claimed, blocked and shipped per epic or department, with the dollars and human minutes each one actually cost. The report is the database, not a slide someone rebuilt on Friday.

Judgement calls come back to you

A planner marks what it cannot decide — an isolation boundary, a migration strategy, a pricing rule — and escalates it instead of guessing confidently. Humans stay on the decisions, not the dispatching.

Every expansion records what the planner was shown and what it returned. So "why is this on the roadmap?" has an answer you can read, which is the difference between a plan and a pile of tasks of unknown origin. Depth is capped, budget is checked before expanding, and malformed output is dropped rather than filed.

The part nothing else does

It reports what is not there

Every search engine, vector database and RAG pipeline answers one question: what in here matches? Ask any of them what you are missing and they return nothing — which is indistinguishable from a question with no answer.

Nobody typed that year in. Lacunari read the dates out of the documents, saw the span was otherwise covered, and reported the hole.

01 — a hole in a span You hold 1942 and 1944. Needs three data points. Two establish no pattern, and one stray date would invent decades of false leads. 02 — one source only Nothing corroborates this. One copy is a claim. Three independent copies are evidence — and content hashes tell them apart for free. 03 — connected to nothing Named once, never placed. An edge means "named in the same document" and nothing more. It will never tell you what the link means. 04 — never read Held, but never extracted. The most common finding in any real archive, and the one nobody has a report for: material you have never opened.
Four shapes of absence. Each derived by set-based SQL over data you already hold — no model, no API key, no network. Every one becomes a task with a title and a priority, and withdraws itself when someone closes it.

Scale

Dozens of workers. One project.
No collisions.

Because the board is a database and a claim is a transaction, adding capacity is starting another process — or onboarding another engineer. Distributed teams, contractors and agents claim from the same queue across machines, vendors and time zones, and nobody hands out assignments.

$ lac work & lac work & lac work & lac work & lac work &

Twelve workers · four vendors · two humans · one board.

A claim is one atomic UPDATE

Two workers cannot take the same task. Postgres decides in the same round trip and the loser picks something else. No scheduler to run, no leader to elect.

A claim locks the files it declared

The second agent is told "dana holds schema.sql on task #12" before it starts. Readers coexist, writers are exclusive. Git tells you after both did the work; this refuses before either begins.

A dead worker loses its lease

Its files unlock and the task returns to the board with its history intact. Nothing is stranded because a process was killed, a laptop closed, or a container rescheduled.

Capabilities route the work

The agent with production credentials gets the deploy task; the one without never sees it. Judgement calls escalate to a human on a deduplicated backoff, because an agent that cries wolf gets ignored.

No daemon. No broker. No vendor in the coordination path. The whole substrate is a Postgres database you already know how to back up. Any process that can reach it is a peer: a Claude session, a local Llama, a GPT worker, a cron job, a contractor with psql.

The same engine, three fields

A corpus is a corpus

Historical research

Forty years of scans across a dozen members' drives. Content addressing turns three copies of one document into one record with three attributions — duplicates become corroboration. The missing year surfaces itself.

The archive case →

Medical & scientific literature

Where a finding rests on a single paper, that is the most important fact about it — and the one least likely to surface in a search ranked on relevance. Reported as a structural property of the set.

The literature case →

AI-assisted engineering

Point it at a repository and the same queries return undocumented modules, symbols nothing calls, files no test exercises. Your agents stop asking what to do next, and stop overwriting each other.

The engineering case →

Questions

The things people ask first

Does it run the AI agents for me?

No, deliberately. Lacunari coordinates agents; it does not execute them. You bring Claude Code, a local Llama, a GPT worker or a shell script — executors/ is the seam. That is why there is no vendor in the coordination path, no sandbox to live inside, and why agents from different providers can work the same board.

Does my code leave my machine?

No. Indexing, mapping and gap detection are set-based SQL over a Postgres database you run. No model, no API key, no network call in that path. What your agents do is between you and your provider; Lacunari never sends your corpus anywhere.

Is this a replacement for git?

It replaces what git was never built to do and sits alongside it for the rest. Git is better at short-lived topic branches and three-way merge at review time. Lacunari answers what the codebase is, what is unfinished, who is working on what right now, and what it cost. Most teams run both against the same tree.

How many agents can actually work at once?

The limit is your database, not the design. A claim is one indexed UPDATE, and Postgres has been settling that contention for thirty years. Path locks mean the practical ceiling is how much of your project can be edited simultaneously without two workers wanting the same file — a property of your codebase, not of this tool.

What happens when an agent crashes mid-task?

Its lease expires, a keeper releases the claim, the files unlock, and the task returns to the board with its history intact. Another worker picks it up. Nothing is stranded and nothing silently disappears — unlike most agent harnesses, where a dead session takes its context with it.

Can humans and agents really share one queue?

Yes, and that is the point. Identity is the connected Postgres role, permissions are row-level security, and the audit log is append-only in the database. A person in the CLI, an agent over MCP and a cron job are the same kind of participant under the same rules.

What does it cost to run?

Lacunari is AGPL-3.0 and free. It needs Postgres 12 or later — if you can run a database, you can run this. It also tracks what work costs in both model spend and human minutes, with hard ceilings that stop work when either runs out.

This is what an engineering organisation looks like when the roadmap is machine-readable and the team is not all human.

OfflineNo model, no API key, no network. Set-based SQL over data you already hold.
AGPL-3.0Source available and auditable. Commercial licences for proprietary use.
PostgresVersion 12 and later. No daemon, no broker, no framework to adopt.
Per-person rolesIdentity is the connected Postgres role. Lane permissions are row-level security, and the audit log is append-only.