Cohere

A coherence layer for Elixir/Phoenix projects.

Docs live at mhyrr.github.io/cohere: the ladder, the loop, the document kinds, and the FAQ, with an 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:

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

Quickstart

# mix.exs
{:cohere, "~> 0.1", only: [:dev, :test]}
$ 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:

$ 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.

$ 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:

### 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

$ 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

LevelPropertyMechanism
0Context by discoveryraw repo; agents grep and hope
1Static guidanceAGENTS.md / usage_rules
2Derived truththe map (mix cohere.map)
3Authored intent, checkedintent cards + drift sentinel
4Governed verbs, verified behaviorboundary enforcement, Tidewave runtime introspection
5Delivered contextwork 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

TaskDoes
mix cohereladder status + designs in flight
mix cohere.initscaffold 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.checkthe 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.mapregenerate 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, ...:

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

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, an accepted design doc in cohere's own coherence layer. The feature loop's own design is cohere/design/feature-loop.md — completed by the tool it specifies.

License

MIT