CORTEX_TOOLS: plug Syd into the company-wide document corpus

↗ view on GitHub · emileriksenkeev · 2026-08-05 · 6fc550b0

Syd's library goes stale the moment an upload is forgotten. Cortex is the
group's system of record for documents - 28k+ legal documents synced
continuously from Gmail/Drive/Slack/Notion/Asana, deduplicated, OCR'd,
classified and version-aware, including ~11k contract-negotiation emails
Syd has never held. This connects the two; it does not copy the corpus.

Adds lib/cortexBridge.ts (pattern: lib/bryBridge.ts) with five read-only
tools - search_legal_corpus, list_corpus_documents, read_corpus_document,
counterparty_profile, legal_calendar - plus CORTEX_GUIDANCE, the prompt
layer that teaches the retrieval doctrine. Wired into global chat, project
chat, and the headless agent bridge. Cortex tools are safe on the agent
bridge in a way BRY_TOOLS are not: they are REST reads, not an agent hop,
so they cannot extend the Bry -> Syd chain.

Nothing changes until credentials exist: cortexEnabled() requires both
CORTEX_API_URL and CORTEX_API_KEY, and when false neither the tools nor
the prompt layer are registered at all (precedent: embeddingsEnabled).
Deploying this ahead of the key and the Cloudflare service token is a no-op.

Three things learned by running it against the real API rather than
assuming:

- /api/search takes 23-27s from off-droplet (Voyage embed + rerank + thread
  cards over the pooler), so a flat 30s timeout turned a working search into
  a timeout. Timeouts are now per-endpoint, and a timeout is never retried:
  a slow endpoint retried is just the same cost paid twice, while genuine
  transients (5xx, 429, network faults) still get two retries inside a
  100s budget.
- The signed Apotheca Partner Agreement returns 109 characters of
  "[Page 1] ... [Page 10]" - a scan with no text layer. A naive non-empty
  check reads that as a document, which is how an assistant ends up
  summarising a contract it never read. Now detected via the same
  marker-stripping rule as meaningfulPdfTextLength, including the sparse
  middle case, and reported as "you have NOT read this" with the file link.
- Filters this deployment does not support yet (function, lifecycle, q,
  legal_entity) are ignored rather than rejected, so the bridge compares the
  echoed filter and warns when a list is broader than what was asked for.
  A filter silently dropped is worse than one refused.

Entity-optional listing and /api/obligations are still shipping on the
Cortex side; both are feature-detected and degrade with an instruction
rather than an error. Every failure path returns guidance the model can
act on, because a legal assistant guessing because a service was down is
the failure mode worth engineering against.

Tested against the live read-only API with a temporary read key (since
deleted, along with its audit rows): profile of a counterparty with 5,491
documents, a 7-row contract set with 11 duplicate copies collapsed and
coverage gaps stated, full text of an 18k-character MOU, and correct
degradation for unknown entities, bad ids, missing endpoints, bad
credentials, and an unconfigured instance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Repository emileriksenkeev/sydOS
Author emileriksenkeev <emil@keev.co>
Authored
Parents 45ff8f21
Stats 5 files changed , +880 , -4
Part of Cortex - company-wide document corpus integration

Capture this commit into my fork

Download a Markdown prompt that tells Claude how to port this exact commit into your working tree. Run it via claude -p < capture-commit-6fc550b0.md from inside the repo you want the change in.

⬇ Download capture-commit-6fc550b0.md