// Package connector_inbound is the L0 generic inbound connector runtime.
//
// # L0 boundary
//
// This package is platform substrate — it contains ZERO connector-specific
// strings (no vendor names, no tenant object names, no picklist values). All
// connector identity surfaces (namespace, signing scheme config, envelope
// mapping rules, event→Flow routing) are supplied via pack manifest config
// applied through the platform's component machinery.
//
// # Components
//
// Signature verification: [SignatureVerifier] implements
// [connectorcapabilities.SignatureVerifierHandler]. Construction binds a
// namespace and pack-supplied [SignatureSchemeConfig]; each [SignatureVerifier.Verify]
// call resolves its own secret via
// [webhooks.ResolveWebhookSecretForVerification].
//
// Envelope parsing: [EnvelopeParser] implements
// [connectorcapabilities.EnvelopeParserHandler]. Construction binds a
// namespace and [EnvelopeMappingConfig] (declarative JSON-path DSL). No
// connector-specific parsing logic lives here.
//
// # Event routing
//
// The production Worker depends on a
// [connector_inbound_routing.RouteResolver] interface (passed via
// [NewWorkItemWorker]). Implementations of RouteResolver determine, per
// (namespace, eventKind), the AutoLaunched Flow DeveloperName the Worker invokes.
//
// The routing substrate shipped as NCRM-INT-11b (PR #1608) and provides:
//   - [connector_inbound_routing.NoopRouteResolver] — always returns ErrRouteNotDeclared
//   - [connector_inbound_routing.DBRouteResolver] — DB-backed production implementation
//   - _System_ConnectorInboundRoute table + ComponentKindConnectorInboundRoute pack component
//
// The production application supervisor wires
// [connector_inbound_routing.NewDBRouteResolver] into [NewWorkItemWorker] with
// one complete [WorkItemService]. The v0.2.0 WorkItem-only contract has no
// public legacy Event or split-claim worker constructor; tests wire stubs or
// connector_inbound_routing.NoopRouteResolver inside this package.
//
// # Execution ownership
//
// The production supervisor constructs every inbound executor with
// [NewWorkItemWorker]. [WorkItemService] owns WorkItem selection, execution
// transitions, and their compare-and-swap lease: claim, renewal, retry,
// failure, completion, and atomic coalescing. The immutable connector Event is
// loaded only as delivery, routing, payload, and audit input. It is not the
// production executor-state owner.
//
// A [Worker] resolves the target Flow via the injected [RouteResolver],
// batch-fetches details via [BatchReadClient] (INT-10), and invokes the Flow
// via [FlowInvoker].
//
// Flow inputs are passed as map[string]any — both payload and record are
// unmarshalled from JSON so that Flow formulas can navigate into nested fields
// (e.g. {!payload.objectId}). A non-nil error from BatchReadClient.BatchRead
// fails the claimed WorkItem (queue retries / DLQs) rather than silently
// swallowing the error. An absent record entry for the sourceID means
// enrichment is unavailable for that event; payload-only startup contracts may still route
// to Flow, but the platform must not reinterpret absent enrichment as a
// deletion signal. Failure-budget paths record sync-state diagnostics and call
// [WorkItemService.FailWorkItem]; retry and release paths also transition the
// claimed WorkItem through its lease. On success the worker completes that
// WorkItem. The scheduler and dead-letter/replay contracts in
// docs/connector-inbound-scheduler.md and docs/workitem-dlq-replay.md define
// the durable ownership and operator paths.
//
// # Cross-process carriage via QueueEnvelope
//
// Every [EnvelopeMappingRule] carries two required declarations:
//
//   - ObjectKind (literal, e.g. "contact", "deal") — the connector object kind.
//   - SourceIDPath (JSON-path, e.g. ".objectId") — the path to the external
//     source / object ID within the envelope item.
//
// The parser populates [connectorcapabilities.ConnectorEvent.ObjectKind] and
// [connectorcapabilities.ConnectorEvent.SourceID] (typed struct fields) from
// these declarations. Before Enqueue the dispatcher calls [EncodeQueueEnvelope],
// which serialises ObjectKind, SourceID, and the user Payload bytes into a
// [QueueEnvelope] struct (typed fields, no reserved-key injection). The encoded
// bytes are stored in _System_ConnectorEvent.
//
// The worker calls [DecodeQueueEnvelope] to recover ObjectKind, SourceID, and
// the original user payload. It uses objectKind + sourceID as arguments to
// [BatchReadClient.BatchRead]. If either field is absent (decode error or
// empty string) the worker fails the claimed WorkItem immediately (parser-bug
// class — no SyncState write).
//
// Note: the pre-R22 model injected reserved keys ("__objectKind", "__sourceID")
// directly into the Payload JSON bytes. That path has been removed; do not
// re-introduce it. See EncodeQueueEnvelope / DecodeQueueEnvelope for the
// current wire format.
//
// # EventType ↔ EventKind bridge
//
// The names "EventType" and "EventKind" differ historically (the parser was
// scoped before the queue), but the values pass through 1:1:
//
//   - Parser emits [connectorcapabilities.ConnectorEvent.EventType].
//   - Dispatcher (connector_events #338) calls
//     [connector_events.Service.Enqueue] with eventKind = ev.EventType.
//   - Queue stores the value in column EventKind.
//   - Worker reads event.EventKind and calls
//     [RouteResolver.ResolveFlow](ctx, namespace, event.EventKind).
//
// The values are identical throughout the pipeline; only the field names
// differ. A future cleanup PR may rename EventType → EventKind in
// connectorcapabilities; until then this bridging is intentional and
// documented here.
//
// # Adding a second connector
//
// Once the routing-substrate (INT-11b) lands, adding a second connector pack
// requires zero engine-code change: the pack manifest declares routes via the
// connector_inbound_route component; install/apply persists rows to
// _System_ConnectorInboundRoute; the DB-backed RouteResolver picks them up.
// The Worker is connector-agnostic.
package connector_inbound
