Skip to content

API: Connectors

Capability state: every operation in this file is staging-durable (sandbox/fixture-only). Connector consent, sandbox-external evidence ingest, and connector status are recorded in durable M7 state but refuse production admission and reject raw connector payloads or credential secrets at the membrane. See 022 gap report item 11 for the broader connector surface.

The connector cluster covers the sandbox connector ingress surface — the operations that record connector consent, ingest hash-only redacted witnesses, and inspect connector status without exposing raw payloads, credential secrets, or biometric material.

Three coupled lanes:

  • Consent laneevidence.connector.consent records sandbox connector consent, an adapter profile reference, scope, and a credential commitment, with no credential secret ingress.
  • Ingestion laneevidence.connector.ingest admits fixture or sandbox_external redacted witness material tied to a consented low-risk adapter profile (and optionally to a connector consent ref).
  • Status laneevidence.connector.status returns redacted summaries (ref counts, no payload bytes) for the current tenant.

The contract names these operations evidence.connector.consent, evidence.connector.ingest, and evidence.connector.status (i.e. they live under the evidence.connector.* family). The TypeScript SDK exposes them as connectorConsent, connectorEvidenceIngest, and connectorEvidenceStatus.

A connector consent or witness never creates standing or authority on its own — see standing-and-mandates.md and authority.md for those surfaces.

See also:

Record sandbox connector consent scope, hash-only adapter profile, and credential reference without credential secret ingress.

POST /v1/evidence/connectors/consent
state: staging-durable
sdk_role: record sandbox connector consent scope, hash-only adapter profile, and credential reference without credential secret ingress
request_record: CloudConnectorConsentRequest
responses: connector_consent | connector_witness | connector_adapter_profile | refusal | receipt
interface ConnectorConsentRequest {
tenant: GestaltRef;
subject: GestaltRef;
connector_kind: string;
connector_mode: string; // must be "sandbox_external"
source_system: string;
source_label: string;
consent_ref?: GestaltRef;
credential_ref?: GestaltRef;
adapter_id?: GestaltRef;
adapter_version?: string;
adapter_manifest_hash?: string;
scopes: string[];
fixture: boolean; // must be true
contains_customer_data: boolean; // refused if true
raw_credential_material?: unknown; // refused if present
}
{
"operation": "evidence.connector.consent",
"outcome": "admitted",
"body": {
"connector_consent": "connector_consent:...",
"connector_witness": "connector_witness:...",
"adapter_profile": {...},
"credential_ref": "connector_credential:...",
"status": "active",
"credential_secret_stored": false,
"raw_connector_payload_stored": false,
"production_admission": false,
"durable_state": {...}
},
"receipt": {...}
}

The handler refuses with connector_mode_unsupported if connector_mode is not "sandbox_external", customer_data_forbidden if contains_customer_data is true, and connector_credential_material_refused if raw_credential_material is supplied.

const consent = await client.connectorConsent({
tenant: "tenant_node:rheinwerk_calibration",
subject: "company_geist:rheinwerk_calibration",
connector_kind: "invoice",
connector_mode: "sandbox_external",
source_system: "sandbox_payment_feed",
source_label: "sandbox://payments/m26",
credential_ref: "connector_credential:m26_sandbox_reference",
scopes: ["read:payments", "read:invoices"],
fixture: true,
contains_customer_data: false,
});

Submit fixture or sandbox hash-only connector evidence as redacted witness material tied to a consented low-risk adapter profile.

A worked example with refusal codes and the observed_input → transform_receipt → evidence_bundle pipeline is documented in evidence.md.

POST /v1/evidence/connectors/ingest
state: staging-durable
sdk_role: submit fixture or sandbox hash-only connector evidence as redacted witness material tied to a consented low-risk adapter profile
request_record: CloudConnectorEvidenceIngestRequest
responses: connector_witness | observed_input | transform_receipt | evidence_bundle | connector_adapter_profile | refusal | receipt
interface ConnectorEvidenceIngestRequest {
tenant: GestaltRef;
subject: GestaltRef;
kind: string;
connector_mode: string; // "fixture" or "sandbox_external"
connector_consent?: GestaltRef;
credential_ref?: GestaltRef;
adapter_id?: GestaltRef;
adapter_version?: string;
adapter_manifest_hash?: string;
idempotency_key?: string;
source_system: string;
source_label: string;
source_hash?: string;
transform_hash?: string;
raw_kind: string;
claims: string[];
amount_cents?: number;
currency?: string;
invoice?: GestaltRef;
human_presence_receipt?: GestaltRef;
face_match_receipt?: GestaltRef;
advisor_decision?: string;
stale: boolean;
outside_tenant: boolean;
fixture: boolean;
contains_customer_data: boolean;
raw_payload?: unknown; // refused if present
raw_credential_material?: unknown; // refused if present
}

See the worked example in evidence.md. Body keys include connector_witness, observed_input, transform_receipt, evidence_bundle, and assertions that raw_connector_payload_exposed, evidence_creates_authority, and production_admission are all false.

const ingested = await client.connectorEvidenceIngest({
tenant: "tenant_node:rheinwerk_calibration",
subject: "company_geist:rheinwerk_calibration",
kind: "invoice",
connector_mode: "fixture",
source_system: "fixture_connector",
source_label: "fixtures/connectors/m9-invoice.json",
raw_kind: "fixture_json",
claims: ["invoice_payload"],
amount_cents: 11900,
currency: "EUR",
stale: false,
outside_tenant: false,
fixture: true,
contains_customer_data: false,
});

Record connector revocation so future sandbox ingestion refuses with a stable code.

POST /v1/evidence/connectors/revoke
state: staging-durable
sdk_role: record connector revocation so future sandbox ingestion refuses with a stable code
request_record: CloudConnectorRevokeRequest
responses: connector_revocation | refusal | receipt
interface ConnectorRevokeRequest {
tenant?: GestaltRef;
connector_witness: GestaltRef;
connector_consent?: GestaltRef;
reason?: string;
fixture?: boolean; // must be true today
}

fixture: true is required today. The membrane refuses with connector_mode_unsupported for any non-fixture revocation.

{
"operation": "evidence.connector.revoke",
"outcome": "admitted",
"body": {
"connector_revocation": "connector_revocation:...",
"connector_witness": "connector_witness:...",
"status": "revoked",
"future_ingest_refuses": true,
"raw_connector_payload_stored": false,
"production_admission": false,
"durable_state": {...}
},
"receipt": {...}
}

After revocation, future evidence.connector.ingest calls referencing the revoked connector_witness fail closed.

const revoked = await client.connectorRevoke({
tenant: "tenant_node:rheinwerk_calibration",
connector_witness: "connector_witness:m26_sandbox_payment_feed",
reason: "operator_revoked",
fixture: true,
});

Inspect redacted connector evidence summaries without raw payload access. This operation is GET and takes no request body.

GET /v1/evidence/connectors/status
state: staging-durable
sdk_role: inspect redacted connector evidence summaries without raw payload access
responses: connector_witnesses | observed_inputs | transform_receipts | evidence_bundles | receipt

No request body. Tenant scope is resolved from the caller’s authority context.

{
"operation": "evidence.connector.status",
"outcome": "verified",
"body": {
"tenant": "tenant_node:rheinwerk_calibration",
"local_overlay": {
"connector_consents": [...],
"connector_revocations": [...],
"connector_witnesses": [...],
"observed_inputs": [...],
"transform_receipts": [...],
"evidence_bundles": [...],
"evidence_reviews": [...]
},
"remote_records": [...],
"raw_connector_payload_exposed": false,
"raw_db_exposed": false,
"production_admission": false
},
"receipt": {...}
}

Counts and refs only — raw payload bytes are never returned.

const status = await client.connectorEvidenceStatus();

Selected refusal codes returned by this cluster (see refusal.codes for the full list):

connector_fixture_only
connector_mode_unsupported
connector_credential_material_refused
connector_raw_payload_refused
connector_tenant_scope_mismatch
connector_idempotency_collision
connector_evidence_kind_unknown
customer_data_forbidden
evidence_stale
human_presence_creates_standing_refused
identity_fallback_creates_standing_refused