Docs/System Modules/Connector Runtime

Connector Runtime

A Connector package implements an external protocol. Each configured integration becomes a Source with its own identity and lifecycle.

Runtime v1Last updated July 17, 2026

Package installation and Source creation are separate operations. Installing code creates zero Sources; a user or Host explicitly configures each Source instance.

Package

connectors/
└── oura/
    ├── connector.yaml
    ├── events.json
    └── index.mjs

The installed entry is a JavaScript ESM module. Authors may use TypeScript during development, but the package must expose built ESM at the manifest's entry path.

Connector code is a trusted extension, not an App workload. Before import, the Host accepts either an official signature/hash or a human approval bound to the current package hash. Modifying package material invalidates a prior custom approval.

Trust boundary

The child-process runner isolates lifecycle and mediates durable capabilities, but it is not the App sandbox. Only install Connector code you trust to run locally.

Manifest

manifestVersion: 1
id: oura
name: Oura
description: Imports sleep, readiness, activity, heart-rate, and related health records from Oura.
eventCatalog: ./events.json
entry: ./index.mjs
runtime:
  mode: poll
  defaultSchedule: "0 */6 * * *"
integrations:
  mode: multiple
platforms:
  darwin: {}
  linux: {}
  windows: {}
  cloud: {}
auth:
  type: managedProvider
  providerId: oura
config:
  lookback-days:
    type: number
    label: Lookback days
    default: 3
FieldContract
descriptionRequired natural-language explanation of what the Connector captures.
eventCatalogRequired package-relative JSON file declaring event types, descriptions, and payload JSON Schemas.
entryBuilt ESM entry relative to the package root.
runtime.modeExactly watch, poll, or manual.
defaultScheduleValid only for poll. Copied into a new Source; later schedule edits live in system state.
integrations.modeRequired singleton or multiple; declares Source identity cardinality.
platformsAlternative supported placements, not simultaneous collection lanes.
authnone, apiKey, oauth2-public, or managedProvider.
configUser-facing typed fields and author defaults. Tokens, checkpoints, and pause state never belong here.

The event catalog is strict catalogVersion: 1 data with a non-empty eventTypes map. Every event type declares a natural-language description and a standard JSON Schema payloadSchema. Core validates and trust-hashes the file with the package; it does not infer output semantics from Connector source code.

Manifest material is static. Per-Source configuration, schedule, credential reference, checkpoint, warnings, and status live in .lamarck/system.db.

Source identity and lifecycle

A Source is one configured integration instance owned by its Connector package.

# singleton
connector:app-commits

# multiple; integration key is stable and user-selected
connector:google-calendar:work
connector:google-calendar:personal
OperationEffect
Install ConnectorAdd package code, manifest, and event catalog. Create zero Sources.
Add SourceCreate integration identity, apply config defaults, attach auth, and initialize Source-owned state.
Pause SourceStop automatic execution while preserving config, credentials, checkpoint, and schedule.
Resume SourceReturn automatic execution policy to active; readiness is evaluated separately.
Remove SourceStop it and remove its control-plane record. Previously appended D0 Events remain.
Remove ConnectorStop its runners and remove all owned Sources. Historical D0 Events remain.

Active means automatic execution is allowed; it does not mean ready or currently running. Setup readiness, trust, platform requirements, observed run status, error, and pause policy are independent state.

Runtime modes

ModeInvocationExamples
watchLong-lived, self-driven process emits as data arrives. The Host supervises it.Mac AX, Telegram getUpdates, filesystem watch.
pollScheduler invokes one bounded pass according to Source-owned cron state.Oura, GitHub, Calendar synchronization.
manualExplicit bounded invocation with no automatic schedule.Exports, imports, and on-demand capture.

push is reserved for a future inbound delivery path and is not a v1 runtime mode.

Runner and capability broker

Host trust gate
    ↓
spawned Node child → import connector entry → run(context)
    │
    └─ IPC capability broker
         ├─ Guard writes + Host-injected source
         ├─ integration-scoped state
         ├─ integration-scoped warnings
         ├─ credential token access / refresh
         └─ cancellation + run status

The child receives no SQLite handle, Guard internals, scheduler internals, or raw credential record. auth.getToken() asks the Host broker for the current token. state and warnings are automatically scoped to the active Source.

Operational warnings belong in system.db, not in D0. D0 records observations and meaningful product activity; it is not a connector log sink.

Code contract

export default defineConnector({
  async run({ guard, auth, state, warnings, config, host, signal }) {
    const cursor = await state.get();
    const token = await auth.getToken();

    // Fetch, redact, and normalize external data.
    await guard.writeEvent({
      type: "source.event",
      externalId: "upstream-id",
      startedAt: Date.now(),
      payload: { cursor }
    });

    await state.set({ cursor: "next" });
    await warnings.clear("backfill");
  }
});

Do not pass source. The bound Guard derives it from the integration the Host invoked. externalId should be stable within that Source so the D0 uniqueness constraint makes retries idempotent.

Next moduleCredential