2026-09-23·by Sijie Wang#standmeet#architecture#design

connector-deps

Connector dependencies — Requires, resolved fail-closed

Parent: connector

The formal interface between the capabilities pillar and the connector pillar — fail-closed and consumer-agnostic by design. A plugin manifest declares Requires: ["calendar", "smtp"] — NAMES of in-app dependency providers, each backed by a connector category. capreg/depresolver.go is the registry; resolution happens at assembly: any required dep not Connected → the capability is globally hidden (fail-closed) — degraded discovery, not runtime error. Providers expose exactly two things: a Connected predicate and a call handle — never credentials (the connector-plugins boundary).

The consumer-agnostic decision makes the mechanism universal and bidirectional: the same named-dep resolution serves the agent, platform features, and future consumers (IM gateway, job-loop), in both directions (action and sync).

Class view

Precision note: DepProvider answers only Connected — it is a predicate, not the call handle. The actual handle a consumer uses is the category proxy (connector-plugins's CalendarProxy/MailProxy), wired separately; the dep mechanism just decides whether the capability is exposed at all (AllConnected false → hidden, fail-closed).

Since 2026-08-20 (a9c446937) there is a second predicate on top: OpProvider.CanPerform(ctx, ownerID, op) (depresolver.go:151), built by NamedOpProvider. A capability can require an operation (calendar:events.insert), not just a connection, so a read-only grant hides "book a meeting" but not "free slots". At 36789537d the composition root registers calendar as a NamedOpProvider (backed by ConnectorSlots.CanPerform) and smtp as a plain NamedProvider (cmd/server/axisconn/register.go:207-214) — those two names are the whole provider table.

about this entry

One of sijie's wiki entries. The AI on this site is grounded in the same corpus and answers in sijie's voice, with citations back to entries like this one — answering costs sijie money, so it waits behind a code: enter an access code →