← Orbit journal

Wtf is Charon?

The ferryman between your messy digital life and the tiny, attributed pieces of context Orbit can actually use.

Short answer: the ferryman

In mythology, Charon ferries souls across the river Styx into the underworld ruled by Pluto. In Orbit, Charon ferries email, calendar events, documents, and eventually a lot more into Pluto, the context and inference system.

Charon owns the crossing. Connectors understand provider APIs. Pluto understands conversations. Charon is the deliberately boring, extremely important machinery between them.

Your inbox is not a prompt

Every provider has its own idea of a resource. Gmail has threads and messages. Calendar has events. Drive has files with MIME types, revisions, links, and occasionally a Google Doc pretending to be a file. Feeding those objects directly to a model would couple every answer to every provider quirk.

Connectors flatten their objects into one normalized document contract. Charon does not know how Gmail authentication works and Gmail does not know how retrieval works. That separation is how I can add Notion, Slack, Granola, GitHub, Outlook, or something I have not imagined yet without rebuilding Orbit’s brain each time.

IntegrationDocument {
  provider, collection, external_id,
  title, source_url, mime_type,
  content, modified_at, metadata
}

If it did not change, do absolutely nothing

Charon normalizes line endings and whitespace, removes null bytes, and caps a single resource at 500,000 Unicode code points. Then it computes a SHA-256 hash of the normalized content.

The stable resource identity is `(provider, subject, collection, external_id)`. If the stored content hash matches the new one, Charon skips chunking, embedding, and persistence entirely. Syncing 10,000 things should not mean reprocessing 10,000 things because one calendar description changed.

resource_key = (provider, subject, collection, external_id)

if sha256(normalize(content)) == stored_hash:
  return "nothing to see here"

Chunking, but with object permanence

Changed documents are split near 1,200 runes with a 160-rune overlap. Charon searches backward for a sensible whitespace or newline boundary instead of blindly cutting a sentence in half. Each chunk gets an ordinal and its own content hash, so source order survives retrieval.

The overlap is intentionally unglamorous. Retrieval gets weird when the person’s name is at the end of chunk seven and the decision they made begins chunk eight. A little repetition is cheaper than amnesia at the boundary.

target = 1,200 runes
overlap = 160 runes
cut = nearest useful whitespace before target

Search has two brains

At query time Charon embeds the request once, scores candidate chunks by cosine similarity, and mixes that score with lexical token overlap. Pure vector search is elegant right up until a project codename, invoice number, or exact surname matters more than semantic vibes.

The default local feature-hash embedder requires lexical overlap and weights the final score 65% semantic, 35% lexical. An explicitly configured model embedding path uses 82% semantic, 18% lexical with its own floor. Scores below the relevant threshold do not become context.

local_score = 0.65 · semantic + 0.35 · lexical
model_score = 0.82 · semantic + 0.18 · lexical
  • The normal turn asks for at most eight excerpts.
  • No resource can contribute more than two chunks to the result.
  • Equal scores break toward the more recently modified source.
  • Every excerpt retains provider, collection, source identity, URL, and modification time.

A cache miss is not a fact

Orbit continuously maintains bounded Gmail and Calendar indexes, but it does not vacuum every Drive file into a database just in case. Drive and Docs use targeted hydration: when local context cannot answer a specific request, Orbit performs a narrow provider search, fetches at most five matches, and adds only those resources to the private index.

That creates an important inference rule: missing local context means “not cached,” not “does not exist.” Charon can fail open for an ordinary turn. Orbit continues without connector context and marks retrieval incomplete, but the assistant must not claim it searched successfully.

The data stays source material

Resource titles, URLs, metadata, and chunk bodies are encrypted at rest.

For a turn, only the bounded winning excerpts are decrypted and handed to inference. Their use is recorded against that turn. They remain attributed, untrusted source material: an instruction inside an email is not an instruction to Orbit, and a sentence inside a Doc does not become durable memory about the owner.

Why Charon matters

The flashy part of an assistant is the answer. Charon is the system that makes the answer specific without making the entire connected account part of the prompt.

It gives Orbit a reusable ingestion boundary, cheap incremental sync, hybrid retrieval, explicit attribution, bounded disclosure, and a clean distinction between what a source says and what Orbit remembers about you. Tiny moon. Huge job.