> ## Documentation Index
> Fetch the complete documentation index at: https://docs.findmydata.io/llms.txt
> Use this file to discover all available pages before exploring further.

# ADR 0008 connector contract and mock m365

# ADR-0008: Connector contract, deterministic mock M365, live Graph gating

**Status:** Accepted · 2026-07-14

## Decision

* Versioned `Connector` interface per the reference architecture (as implemented
  in `connectors/types.ts`): `probe / discoverScopes / inventoryPage(scope,
  cursor) / changes(scope, deltaCursor) / getPermissions / getLabel /
  getContent(bounded) / getItemVersion / previewLabelAction /
  executeLabelAction(idempotencyKey)`, returning canonical observations
  (external ID, source version/eTag + content version/cTag, change type,
  observed times, completeness). Item metadata arrives inside the
  inventory/changes observations rather than via a separate `getMetadata`;
  post-execution *verification* is performed by the actions service re-reading
  the source through `getLabel`/`getItemVersion` (ADR-0010), not by a dedicated
  `verifyAction` method.
* **MockM365Connector (default):** deterministic fixture tenant ("Meridian Grove")
  with two SharePoint sites + one OneDrive, paged inventory, scripted delta
  sequences (add/edit/rename/permission-change/label-change/delete), cursor
  semantics including simulated `410 resync` and duplicate delivery for tests,
  and per-item content streams from fixture files.
* **GraphM365Connector:** real endpoint shapes (`driveItem` delta, `nextLink`/
  `deltaLink` cursors persisted opaquely — verbatim and currently unencrypted,
  see threat model T16 — `Retry-After` handling, permissions completeness
  marking). Live execution requires explicit config with a resolvable secret
  reference; it was subsequently **validated read-only against the live Contoso
  CDX tenant** (ADR-0013).
* **Label catalog** sync is its own path, outside the `Connector` contract,
  because Graph label listing remains beta: the `sensitivity_labels` table
  records provenance via `catalog_source` (`fixture` | `get_label_import` |
  `graph_beta` | `manual`); the fixture seeder (`fixtures/labels.ts`) is the
  exercised path and `Get-Label` CSV import is the documented production path.
  Label identity is `(msTenantId, labelGuid)` only.

## Consequences

* Every connector-derived observation records acquisition identity and completeness;
  "no broad share observed" ≠ "no broad share exists."
* Teams/Exchange get contracts + capability notes + backlog entries, no fake depth.
