Skip to main content

README.md

# Cohere

**A coherence layer for Elixir/Phoenix projects.**

Docs live at [mhyrr.github.io/cohere](https://mhyrr.github.io/cohere/):
the ladder, the loop, the document kinds, and the FAQ, with an
[llms.txt](https://mhyrr.github.io/cohere/llms.txt) for agents.

> A project is coherent to the degree that, at any point in its development,
> it can furnish any actor — human or model — with the minimal context
> sufficient to act in line with the user's intent, and can mechanically
> detect when the project has drifted from that intent.

Models are intelligent but context-starved, and the failure mode of context
starvation is incoherence: sessions rediscover the same facts expensively,
and codebases drift as hundreds of locally-reasonable changes accumulate
with no shared frame. Cohere makes coherence a **measurable property of the
project** instead of a hoped-for behavior of the agent.

It does this with three document kinds in one directory, each checked as
hard as its nature allows:

- **The map** — the actual shape of your system, *derived* from the
  compiled application: contexts and their public API, Ecto schemas with
  real types and associations, Phoenix routes (LiveView unwrapped), Oban
  workers with queue and cron wiring. Never hand-edited, regenerated on
  demand — therefore it cannot lie.
- **Intent cards** — one small authored file per context holding only what
  cannot be derived: purpose, invariants, decisions with their rejected
  alternatives, non-goals. Each card is hash-bound to its context's public
  surface. Living constraints, kept fresh by the check gate.
- **Design docs** — one authored file per design: problem, existing
  ground, shape, promised surface, decisions. Drafts are work in flight;
  accepted designs are immutable, dated history. The design conversation
  you'd have anyway, landing in one format the tooling reads — instead of
  a hairy pile of wiki pages and gists no gate keeps honest.

No LLM calls. Zero runtime dependencies. Everything is deterministic and
CI-runnable; models *consume* the outputs but are never required to
produce them.

## Quickstart

```elixir
# mix.exs
{:cohere, "~> 0.1", only: [:dev, :test]}
```

```console
$ mix cohere.init            # scaffold cohere/, derive the first map
$ mix cohere                 # where does this project stand?

Coherence ladder — my_app

  ✓ L1 static guidance — AGENTS.md
  ✓ L2 derived map — map present and fresh
  ✗ L3 authored intent, checked — no intent cards
  ~ L4 governed verbs / runtime verification — tidewave installed; write paths not compiler-governed (boundary)
  ✓ L5 delivered context — work packets available via `mix cohere.packet`
```

Then, incrementally:

```console
$ mix cohere.gen.intent deals      # card skeleton, born bound to the current surface
$ mix cohere.check                 # CI gate: exit 1 on any drift
$ mix cohere.packet deals billing  # assemble delivered context for a task
$ mix cohere.packet --diff         # …or for exactly the contexts this branch touches
```

## The feature loop

The developer surface is three verbs; everything else is plumbing their
output points at.

```console
$ mix cohere.design deal-reversals --contexts deals   # START
  ... design in the doc, against its Existing ground ...
$ mix cohere.check                                    # CHECK — anytime; fix, repeat
  ... build ...
$ mix cohere.check                                    # same command, new findings
$ mix cohere.complete deal-reversals                  # COMPLETE — when check is quiet
```

**Start** scaffolds `cohere/design/deal-reversals.md` (status: draft) and
assembles its *Existing ground*: each anchored context's current API from
the map, plus the invariants and decisions from its intent card. A no-LLM
tool can't judge that your design contradicts INV-DEA-002 — it delivers
INV-DEA-002 onto the page where you're designing, so the contradiction
gets seen. The tool assembles; the mind judges.

**Check** is one iterative command, identical locally and in CI. Hard
findings exit 1: stale map, drifted cards, dead card references. Design
findings are advisories, never failures — an accepted design is a dated
record, and drift on history is information, not a bug. A drifted card
means: re-read it against the new surface, update what your change
invalidated, then `mix cohere.check --accept deals`. Accepted drift is
documented drift; the failure mode this tool exists to kill is the
*silent* kind.

**Complete** is the land step, one command. It regenerates the map,
requires the check hard-clean (which forces the card re-review where the
design's durable decisions get distilled into cards), then verifies every
backticked ref in the design's *Promised surface* exists in the compiled
app. A design that promised `reverse_deal/1` cannot complete until
`reverse_deal/1` exists — the design doc is a mechanically checkable
spec, not aspirational prose. On success: `draft → accepted`, dated,
immutable. New thinking later? A new design with `supersedes:` in its
frontmatter — history is superseded, never rewritten.

The PR that lands a feature carries the map delta (the ontology change),
the card delta (the intent change), the accepted design (the why), and
the code — reviewable together.

## What the map looks like

Derived from a real ~185-module Phoenix app, entries read like the
language of the business, because they are the business — reflected out of
the compiled code:

```markdown
### MyApp.Deals — domain `[surface:df8be63a83b8]`

**API** (32): approve_deal/1 create_deal/1 extract_deal_data/1 get_financial_summary/1 …
**Schemas:** Deal, DealParty, DealPartyFeeComponent
**Support:** AccountKeys, DealReset, EditTracker, Insights, JournalCalculator

### MyApp.Deals.Deal → `deals`
- fields: …, side:enum(listing|buyer|both|lease|referral),
  status:enum(draft|needs_review|approved|posting|posted|posting_failed|reversed), …
- belongs_to reviewed_by → MyApp.Users.User via reviewed_by_user_id
- belongs_to agency → MyApp.Agencies.Agency via agency_id
```

Enum vocabularies, custom foreign keys, queue/cron wiring from config —
the facts agents otherwise rediscover by grepping, delivered in one
git-tracked file whose PR diff *is* the ontology change.

## What check finds

```console
$ mix cohere.check
✗ cohere/intent/deals.md
  surface drifted: +approve_deal/1
  → re-review the card, then `mix cohere.check --accept deals`
⚠ cohere/design/deal-reversals.md — draft, advisory only
  anchor "Reversals" not in the map — fine if this design introduces it;
  `mix cohere.complete` verifies it lands

drift detected

$ mix cohere.check --accept deals
cohere/intent/deals.md — rebound to surface df8be63a83b8, drift annotated
```

## The coherence ladder

| Level | Property | Mechanism |
|---|---|---|
| 0 | Context by discovery | raw repo; agents grep and hope |
| 1 | Static guidance | AGENTS.md / [usage_rules](https://hex.pm/packages/usage_rules) |
| 2 | Derived truth | the map (`mix cohere.map`) |
| 3 | Authored intent, checked | intent cards + drift sentinel |
| 4 | Governed verbs, verified behavior | [boundary](https://hex.pm/packages/boundary) enforcement, [Tidewave](https://tidewave.ai) runtime introspection |
| 5 | Delivered context | work packets (`mix cohere.packet`) |

Each level is useful alone; none requires the previous. Phoenix 1.8 ships
every new project at level 1. Cohere is levels 2–5, adopted incrementally.

Cohere **probes** for what's present rather than requiring anything:
Ecto present → objects and links appear in the map; Oban present → the job
surface appears; boundary present → level 4 lights up; Tidewave present →
work packets direct agents to verify behavior in the running app
(`project_eval`, `execute_sql_query`) instead of inferring it from source.

## Mix tasks

| Task | Does |
|---|---|
| `mix cohere` | ladder status + designs in flight |
| `mix cohere.init` | scaffold `cohere/`, first map, workflow README |
| `mix cohere.design [<slug>]` | no args: list designs + statuses; with a slug: start a design (`--contexts a,b`) |
| `mix cohere.check` | the iterative check + CI gate; exit 1 on hard drift (`--accept <card>` to rebind) |
| `mix cohere.complete <slug>` | verify the design's promises landed, flip it to accepted |
| `mix cohere.map` | regenerate the derived map |
| `mix cohere.gen.intent <ctx>` | intent card skeleton (`--all`, `--force`) |
| `mix cohere.packet <ctx…>` | assemble a work packet; `--diff` for the contexts this branch touches (`--base REF`, `--out FILE`) |

## Configuration

Everything is optional, via `config :cohere, ...`:

```elixir
config :cohere,
  dir: "cohere",                    # artifact directory
  namespace: MyApp,                 # default: camelized app name
  web_namespace: MyAppWeb,          # default: <Namespace>Web when present
  ignore: [MyApp.DevHelpers]        # modules to exclude from derivation
```

## Design constraints

- **Derived or checked, nothing else.** Every artifact gets the strongest
  binding its nature allows: the map is regenerated from code (cannot
  drift), cards are authored-but-hash-bound (drift fails the build), and
  designs are authored-but-dated — anchored to the map, promise-verified
  at completion, advisory ever after. Unbound prose is future lies.
- **Zero runtime dependencies.** Ecto/Phoenix appear only as test deps for
  fixture reflection. Consumers inherit nothing.
- **No LLM calls.** Deterministic, CI-runnable, same bytes for same code.
- **Link, don't restate.** Packets carry source records and pointers; they
  never paraphrase code into a second truth.

The full research and design rationale — what Palantir's Ontology and
8090's Software Factory are actually selling, why the failure modes of
spec-driven development all point the same direction, and why Elixir is
the cheapest stack to build this on — lives in
[cohere/design/design-spec.md](https://github.com/mhyrr/cohere/blob/main/cohere/design/design-spec.md),
an accepted design doc in cohere's own coherence layer. The feature loop's own design
is [cohere/design/feature-loop.md](https://github.com/mhyrr/cohere/blob/main/cohere/design/feature-loop.md) —
completed by the tool it specifies.

## License

MIT