The query surface your team already wanted.

Every answer cites the objects it was assembled from, and every object keeps the permission it had in its source system.

Inside the workspace

A single query box over a typed graph. No folders to maintain, no index to rebuild.

app.cobalt.surge.sh / query
Query
Sources
Decisions
Handoffs
Audit
Settings
Why did we drop the batch importer? 4 citations
decision
Batch import removed in favour of incremental sync
Partial failures left the graph in an inconsistent state and there was no safe retry boundary.
→ decisions/2026-07-14-batch-importer · linear/ENG-2841
issue
ENG-2841 · Import job wedged on malformed row
Reproduced twice on staging. Root cause: no per-row transaction boundary.
→ linear/ENG-2841
note
Sync design review — 16 Jul
Decided on cursor-based incremental pull with idempotent upserts.
→ notes/2026-07-16-sync-review

What makes it different

Permissions travel with the object

If a page was restricted to three people in the source system, it stays restricted here. We never flatten permissions into a shared index.

Every answer is auditable

Citations point at concrete objects, not at model output. You can walk any answer back to the records that produced it.

Read-only by default

Write scopes are opt-in per object type. Most teams never enable one.

No migration project

Content is indexed in place. Nothing moves unless you explicitly export it.

API

The same graph, over HTTP. Bearer token, JSON in and out.

curl https://api.cobalt.surge.sh/v1/query \
  -H "Authorization: Bearer $MW_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "workspace": "acme",
    "q": "why did we drop the batch importer",
    "limit": 5
  }'

{
  "answer": "Batch import was removed in favour of incremental sync ...",
  "citations": [
    {"kind": "decision", "id": "2026-07-14-batch-importer", "score": 0.94},
    {"kind": "issue",    "id": "linear/ENG-2841",           "score": 0.88}
  ]
}

Limits we are honest about