@fourier-labs/harbour-contracts 0.86.0 → 0.88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -40,7 +40,7 @@ exist here first.
40
40
  | `ai-pricing-revision`, `ai-metering-policy`, `ai-budget-ledger-event`, `ai-trace-event-v2` | Additive metering v2 records, including media dimensions and P5 trace attribution; v1 records remain readable | AI governance §9 |
41
41
  | `app-integrations-declaration.schema.json` | Committed `.isomorph/integrations.json` (`isomorph.app-integrations/2.0`): closed eighty-one-operation set (Slack read/post/update/delete/DM/lookup, Gmail list/thread/read/send/attachment — ADR 0018; Basecamp project/to-do list/to-do/message/comment/people lists, to-do create and complete, message, comment and Campfire posts — ADR 0022; SharePoint list/item/drive/file lists, file search and read, item create and update, file upload — ADR 0024; phone SMS list — ADR 0028; phone number read — ADR 0029; Google Calendar, Drive, Docs and Sheets and Outlook, OneDrive, Excel and Teams reads and writes as the signed-in person — ADR 0032; warehouse view read and table append, the view mapping saying `access: read|append` — ADR 0028; service request) with fixed or declared identity modes; owns the shared operation/identity/environment enums | Dev kit §4 |
42
42
  | `integration-execute-request`, `integration-execute-result`, `integration-connect-result`, `integration-error-details` | App SDK integrations wire contract on `/_harbour/integrations/*`: per-operation input bounds (a warehouse read filters, groups, aggregates and sorts in the warehouse and says when it was `truncated` — ADR 0017; Slack and Gmail reads page, posts thread, mail carries HTML and attachments — ADR 0018; a development warehouse read may carry the app's `sampleRows` and the result says `sample` — ADR 0021; Basecamp lists page by `pageToken`, ids are digit strings, writes answer `{id, appUrl}` — ADR 0022; SharePoint lists page by a Graph `$skiptoken`, ids are Graph ids, `fields` is a bounded record, writes answer `{id, webUrl}` — ADR 0024; a warehouse append takes `rows`, a bounded list of records, and a phone SMS list takes `since`/`from` — ADR 0028; a phone number read takes no input — ADR 0029; calendar events take RFC 3339 `start`/`end`, Sheets and Excel take `values`, a bounded matrix of cells, Docs take `replacements`, and the event read, document read, values and worksheet results have their own shapes — ADR 0032), the per-operation result shapes, consent states and the closed `details.code` reason set | Dev kit §4, §8 |
43
- | `saas-connection.schema.json`, `data-grant-v2.schema.json` | Tenant SaaS connection record (one installation and channel map per tenant and provider; IT's optional `oauthClient`, `userModeApproval`, `directMessages`, `externalRecipients` — ADR 0018; a Basecamp connection's pinned `account` and project ids in `channels` — ADR 0022; a SharePoint connection's pinned Microsoft 365 tenant in `account` and site ids in `channels` — ADR 0024; up to 20 `approvers` who may approve access requests beside the tenant admins — ADR 0026; a phone connection's E.164 numbers in `channels` — ADR 0028, which an app reads back by alias — ADR 0029; eight Google Workspace and Microsoft 365 providers, user-consent only, a Teams connection's pinned tenant and `<teamId>/<channelId>` channel map — ADR 0032) and the additive `harbour.data-grant/2.0` grant record with structured resources and provisioning lease/cleanup (status machine generated; legacy `data-grant` untouched) | Dev kit §5 |
43
+ | `saas-connection.schema.json`, `data-grant-v2.schema.json` | Tenant SaaS connection record (one installation and channel map per tenant and provider; IT's optional `oauthClient`, `userModeApproval`, `directMessages`, `externalRecipients` — ADR 0018; a Basecamp connection's pinned `account` and project ids in `channels` — ADR 0022; a SharePoint connection's pinned Microsoft 365 tenant in `account` and site ids in `channels` — ADR 0024; up to 20 `approvers` who may approve access requests beside the tenant admins — ADR 0026; a phone connection's E.164 numbers in `channels` — ADR 0028, which an app reads back by alias — ADR 0029; eight Google Workspace and Microsoft 365 providers, user-consent only, a Teams connection's pinned tenant and `<teamId>/<channelId>` channel map — ADR 0032; optional `startedBy` when a builder's first request created the connection — ADR 0034) and the additive `harbour.data-grant/2.0` grant record with structured resources and provisioning lease/cleanup (status machine generated; legacy `data-grant` untouched) | Dev kit §5 |
44
44
  | `kit-bundle-manifest.schema.json`, `kit-lock.schema.json` | Published kit bundle identity (SDK tarball digest plus optional `sdk.version` and https `sdk.url` download location) and the committed `.isomorph/kit.lock.json` the CodeBuild SDK-vendoring gate compares against | Dev kit §3 |
45
45
  | `deploy-response.schema.json` | 202 Accepted body for `POST /v1/tenants/{tenant}/apps/{app}/deployments`, returned only after the authoritative QUEUED version exists and its SQS message is accepted | — |
46
46
  | `deployment-source.schema.json` | Credential-free source in the `DeployRequest` body: `provider` is `github` or `gitlab`, `repositoryUrl` is shape-only and the deployment control plane checks the host against the tenant's source connection (ADR 0023); credentials are resolved internally by MaterializeSource | — |
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "schema": "harbour.contract-release/1.0",
3
- "repositoryVersion": "0.86.0.0",
4
- "publishVersion": "0.86.0",
5
- "publishTag": "v0.86.0",
6
- "schemasDigest": "sha256:f510802c5ba082d403b8f4c5210da322861197b8ea5558384ac5c6403777fbd7",
3
+ "repositoryVersion": "0.88.0.0",
4
+ "publishVersion": "0.88.0",
5
+ "publishTag": "v0.88.0",
6
+ "schemasDigest": "sha256:23e1cb0d9f92c4ea5c2b827aeab9266dfee0ed503457ba5bdc101c39212e8c6f",
7
7
  "aiFixturesDigest": "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6",
8
- "generatedGoDigest": "sha256:641550cc398b29feeec00af2b0e79b52ceb4ee5ac77b0a4f0e6e7b7447adde39",
9
- "generatedTypeScriptDigest": "sha256:6961f95736c7a41ac7af014d78bc877a07677bdedccfed2255395c956a3ef405",
8
+ "generatedGoDigest": "sha256:05eef493dc05e9f7ef4fbbf0aa4dbba5743ceb12a9baded16c875c33e9ed50bb",
9
+ "generatedTypeScriptDigest": "sha256:20e6bfe9e9c7689331b42ea841f6bcc6b0450fb0accc81b451ffba2f1ec2befb",
10
10
  "generatedExclusions": {
11
11
  "gen-go/contract_release.go": "contains the generated aggregate digests (self-reference)",
12
12
  "gen-ts/contract-release.ts": "contains the generated aggregate digests (self-reference)"
@@ -60,13 +60,13 @@
60
60
  "schema/integration-execute-request.schema.json": "sha256:57506400fdf5dcf64b2d7b5bec995c4d7c0ef2e819a35e4bef4e14ff43d79937",
61
61
  "schema/integration-execute-result.schema.json": "sha256:75ab17fa611b72221ece10883ad206813aaeee005695bfbc46d7558d201e94b9",
62
62
  "schema/internal-configuration-request.schema.json": "sha256:229d44a3458f68dceddfba802e5c1adcd95523a45af29b93b972706b88461a7d",
63
- "schema/kit-bundle-manifest.schema.json": "sha256:4a9fcdd52ba0d55718ef4dbdab112b145ef90471d9356d4d3fb41e50fe9e400d",
63
+ "schema/kit-bundle-manifest.schema.json": "sha256:d8fc6ca9c30d791e785b021687e084e9171c0ea1a3a176d0f1582fcccf2c0e19",
64
64
  "schema/kit-lock.schema.json": "sha256:a48154d9471e49a893d928f7b0e1e0bc77708a4a7edce4fdf14073203e0e8987",
65
65
  "schema/kvs-routing-entry.schema.json": "sha256:b75f3a5dfa93a428b2764e03222b66b6ef2bed980f8bac8ffac54afdf3526bc5",
66
66
  "schema/promotion-request.schema.json": "sha256:00e96dfd8ddbdba88ea222941d43f3609ff6c815a79e34f6705cab458101c969",
67
67
  "schema/promotion-response.schema.json": "sha256:4129712d2e29d6ef21d93d4bd0bacfd60ada3f2ee0ade852824e64346b817634",
68
68
  "schema/resolved-app-serving.schema.json": "sha256:1912f3224db1a1699618e6322358e07f76425d3097aec2fbe5d38a10e5c967e3",
69
- "schema/saas-connection.schema.json": "sha256:aaec4b21bf50ab3935541d564fc2339fb626be1cbc5d171e8e0709d3bc360b09",
69
+ "schema/saas-connection.schema.json": "sha256:1bdccb9212ce6d4e448ea1331d023ed42e1e79afb2ef93a946e36d1e5cfcb69b",
70
70
  "schema/sanitized-binding-evidence.schema.json": "sha256:1191ab88e2764df927e5f17837674cebebe068d480da2b2fdb390e589f96b51f",
71
71
  "schema/secret-reference.schema.json": "sha256:db4e3c2c6a2dbd72d7ea0f9c91cb3b2343a7e67b601996c6818b2ef08e440895",
72
72
  "schema/security-scan-input-v2.schema.json": "sha256:0d418342078c9b5046ea6f4bef3c2c57539285dfee99cc0850d4f0d03739ee13",
@@ -116,7 +116,7 @@
116
116
  "gen-go/integration_execute_input_rules_test.go": "sha256:eb7650cc66b7bebe9b36cfd6e7233eb20f74aba0006977f2f009bfdf8e05d83a",
117
117
  "gen-go/integration_operations.go": "sha256:43ada077eca1da6666929e724096f93ddab6469826834f55a8b7332828efa898",
118
118
  "gen-go/schema_documents.go": "sha256:c19c0d540f602ee997a84b90e20702d9bc63ed7d27aec267e76c04655fc182e0",
119
- "gen-go/types.go": "sha256:07dfe0e26ff93e706d5f4ee05178eae66c4daf126d47df611c8c90b85527e8c8",
119
+ "gen-go/types.go": "sha256:bf9ee7498942f73b4c0434ec826007cf1d4b0f834ab4fd0a82add61953b8cf54",
120
120
  "gen-go/version_state.go": "sha256:4ef8abb126414c0025cf2c59bc9c79a74ef4a2ff89e8f316cbf05acc872371c1"
121
121
  },
122
122
  "generatedTypeScript": {
@@ -175,13 +175,13 @@
175
175
  "gen-ts/integration-execute-result.ts": "sha256:d6aa0edc16bea60271414ee78cc96b380522246eb223cf4ff729b19d2e3c7fe4",
176
176
  "gen-ts/integration-operations.ts": "sha256:871cc5a777b155733373d6fa66aa846a9f6cd2b1c5d1229b11bb4aaee8d948fb",
177
177
  "gen-ts/internal-configuration-request.ts": "sha256:7032437797473fa1c581d134adef2f3d4b4f4132f482cd17743e9d47097886bc",
178
- "gen-ts/kit-bundle-manifest.ts": "sha256:2777a268aef8787b81e71d154a7d05f6f5ded09d66f378211ff5493ddb885171",
179
- "gen-ts/kit-lock.ts": "sha256:00ceeb97e9b7d0187bec00728f5099fd34e775e9cc44c85c4714f7a3a4118ef6",
178
+ "gen-ts/kit-bundle-manifest.ts": "sha256:73f5271d2eb3b5ce91e28933c5ab6883615c72a3808aa386f860f58f6df8edf6",
179
+ "gen-ts/kit-lock.ts": "sha256:06bddeaf1e2c449c9cc0dbbc696210355a9005349c604d4050eb22385fb4c22e",
180
180
  "gen-ts/kvs-routing-entry.ts": "sha256:d92e85ee9f257d77850d1d3aac9438e2055f38084ff84a48fcedae239d47d4ca",
181
181
  "gen-ts/promotion-request.ts": "sha256:9db88cef67f777a16bac628039ec3f582acb9e8cfff6fb592b30d0a0e55abc68",
182
182
  "gen-ts/promotion-response.ts": "sha256:f1c9cafac96faeb02a443a31786f67714e818f38d90108e7af41958396524d6f",
183
183
  "gen-ts/resolved-app-serving.ts": "sha256:584792e8e0dcaf4322129b6f78579cd8cd21652c8db8a1606f802408c892534c",
184
- "gen-ts/saas-connection.ts": "sha256:af333b238862d7cf23d1a7ecfcf5cd1a3d2140593d01e44d7e9f29022485924d",
184
+ "gen-ts/saas-connection.ts": "sha256:aeb6d57d8fdedc8d151df1dad60aae2d5176b7457ebe536c45c4c3175ea75f45",
185
185
  "gen-ts/sanitized-binding-digest-helper.ts": "sha256:c47d7fdc20500e2e72c23fe39ecdd610fc397c47fcba51335ebec3c380fe6872",
186
186
  "gen-ts/sanitized-binding-evidence.ts": "sha256:f3fb7b1d7d2e0929eb0ea981eaf32db3104010647185f6ae59f67167d42538a9",
187
187
  "gen-ts/secret-reference.ts": "sha256:731fbcde7315cb4128d5b01bdbe6e6f248f13c7ad8dea04a3a4e927ac4890198",
@@ -1,7 +1,7 @@
1
- export declare const ContractRepositoryVersion: "0.86.0.0";
2
- export declare const ContractPublishVersion: "0.86.0";
3
- export declare const ContractPublishTag: "v0.86.0";
4
- export declare const ContractSchemasDigest: "sha256:f510802c5ba082d403b8f4c5210da322861197b8ea5558384ac5c6403777fbd7";
1
+ export declare const ContractRepositoryVersion: "0.88.0.0";
2
+ export declare const ContractPublishVersion: "0.88.0";
3
+ export declare const ContractPublishTag: "v0.88.0";
4
+ export declare const ContractSchemasDigest: "sha256:23e1cb0d9f92c4ea5c2b827aeab9266dfee0ed503457ba5bdc101c39212e8c6f";
5
5
  export declare const ContractAiFixturesDigest: "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6";
6
- export declare const ContractGeneratedGoDigest: "sha256:641550cc398b29feeec00af2b0e79b52ceb4ee5ac77b0a4f0e6e7b7447adde39";
7
- export declare const ContractGeneratedTypeScriptDigest: "sha256:6961f95736c7a41ac7af014d78bc877a07677bdedccfed2255395c956a3ef405";
6
+ export declare const ContractGeneratedGoDigest: "sha256:05eef493dc05e9f7ef4fbbf0aa4dbba5743ceb12a9baded16c875c33e9ed50bb";
7
+ export declare const ContractGeneratedTypeScriptDigest: "sha256:20e6bfe9e9c7689331b42ea841f6bcc6b0450fb0accc81b451ffba2f1ec2befb";
@@ -1,9 +1,9 @@
1
1
  /* eslint-disable */
2
2
  // Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
3
- export const ContractRepositoryVersion = "0.86.0.0";
4
- export const ContractPublishVersion = "0.86.0";
5
- export const ContractPublishTag = "v0.86.0";
6
- export const ContractSchemasDigest = "sha256:f510802c5ba082d403b8f4c5210da322861197b8ea5558384ac5c6403777fbd7";
3
+ export const ContractRepositoryVersion = "0.88.0.0";
4
+ export const ContractPublishVersion = "0.88.0";
5
+ export const ContractPublishTag = "v0.88.0";
6
+ export const ContractSchemasDigest = "sha256:23e1cb0d9f92c4ea5c2b827aeab9266dfee0ed503457ba5bdc101c39212e8c6f";
7
7
  export const ContractAiFixturesDigest = "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6";
8
- export const ContractGeneratedGoDigest = "sha256:641550cc398b29feeec00af2b0e79b52ceb4ee5ac77b0a4f0e6e7b7447adde39";
9
- export const ContractGeneratedTypeScriptDigest = "sha256:6961f95736c7a41ac7af014d78bc877a07677bdedccfed2255395c956a3ef405";
8
+ export const ContractGeneratedGoDigest = "sha256:05eef493dc05e9f7ef4fbbf0aa4dbba5743ceb12a9baded16c875c33e9ed50bb";
9
+ export const ContractGeneratedTypeScriptDigest = "sha256:20e6bfe9e9c7689331b42ea841f6bcc6b0450fb0accc81b451ffba2f1ec2befb";
@@ -36,6 +36,7 @@ export interface KitBundleManifest {
36
36
  */
37
37
  nativeRuntime?: {
38
38
  darwinArm64?: NativeExecutable;
39
+ linuxArm64?: NativeExecutable;
39
40
  linuxX64?: NativeExecutable;
40
41
  windowsX64?: NativeExecutable;
41
42
  };
@@ -48,6 +48,7 @@ interface KitBundleManifest {
48
48
  */
49
49
  nativeRuntime?: {
50
50
  darwinArm64?: NativeExecutable;
51
+ linuxArm64?: NativeExecutable;
51
52
  linuxX64?: NativeExecutable;
52
53
  windowsX64?: NativeExecutable;
53
54
  };
@@ -75,6 +75,7 @@ export interface SaasConnection {
75
75
  * @maxItems 20
76
76
  */
77
77
  approvers?: string[];
78
+ startedBy?: StartedBy;
78
79
  createdAt: string;
79
80
  updatedAt: string;
80
81
  /**
@@ -192,6 +193,20 @@ export interface ExternalRecipientPolicy {
192
193
  */
193
194
  allowedDomains?: string[];
194
195
  }
196
+ /**
197
+ * Set when a builder's first access request created this connection instead of IT (0.88.0, ADR 0034): who, when, and the app that asked. Such a connection is an ordinary ACTIVE connection whose `userModeApproval` starts as `it`, so development is granted by the development preapproval and production waits for IT's one decision; IT may relax the switch afterwards. Absent on connections IT created.
198
+ */
199
+ export interface StartedBy {
200
+ /**
201
+ * One bare email address (no display name).
202
+ */
203
+ email: string;
204
+ at: string;
205
+ /**
206
+ * The app whose request created the connection, when known.
207
+ */
208
+ appId?: string;
209
+ }
195
210
  /**
196
211
  * @deprecated
197
212
  */
@@ -1,10 +1,10 @@
1
1
  /* eslint-disable */
2
2
  // Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
3
3
 
4
- export const ContractRepositoryVersion = "0.86.0.0" as const;
5
- export const ContractPublishVersion = "0.86.0" as const;
6
- export const ContractPublishTag = "v0.86.0" as const;
7
- export const ContractSchemasDigest = "sha256:f510802c5ba082d403b8f4c5210da322861197b8ea5558384ac5c6403777fbd7" as const;
4
+ export const ContractRepositoryVersion = "0.88.0.0" as const;
5
+ export const ContractPublishVersion = "0.88.0" as const;
6
+ export const ContractPublishTag = "v0.88.0" as const;
7
+ export const ContractSchemasDigest = "sha256:23e1cb0d9f92c4ea5c2b827aeab9266dfee0ed503457ba5bdc101c39212e8c6f" as const;
8
8
  export const ContractAiFixturesDigest = "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6" as const;
9
- export const ContractGeneratedGoDigest = "sha256:641550cc398b29feeec00af2b0e79b52ceb4ee5ac77b0a4f0e6e7b7447adde39" as const;
10
- export const ContractGeneratedTypeScriptDigest = "sha256:6961f95736c7a41ac7af014d78bc877a07677bdedccfed2255395c956a3ef405" as const;
9
+ export const ContractGeneratedGoDigest = "sha256:05eef493dc05e9f7ef4fbbf0aa4dbba5743ceb12a9baded16c875c33e9ed50bb" as const;
10
+ export const ContractGeneratedTypeScriptDigest = "sha256:20e6bfe9e9c7689331b42ea841f6bcc6b0450fb0accc81b451ffba2f1ec2befb" as const;
@@ -40,6 +40,7 @@ export interface KitBundleManifest {
40
40
  */
41
41
  nativeRuntime?: {
42
42
  darwinArm64?: NativeExecutable;
43
+ linuxArm64?: NativeExecutable;
43
44
  linuxX64?: NativeExecutable;
44
45
  windowsX64?: NativeExecutable;
45
46
  };
@@ -51,6 +51,7 @@ interface KitBundleManifest {
51
51
  */
52
52
  nativeRuntime?: {
53
53
  darwinArm64?: NativeExecutable;
54
+ linuxArm64?: NativeExecutable;
54
55
  linuxX64?: NativeExecutable;
55
56
  windowsX64?: NativeExecutable;
56
57
  };
@@ -174,6 +174,7 @@ export interface SaasConnection {
174
174
  * @maxItems 20
175
175
  */
176
176
  approvers?: string[];
177
+ startedBy?: StartedBy;
177
178
  createdAt: string;
178
179
  updatedAt: string;
179
180
  /**
@@ -291,6 +292,20 @@ export interface ExternalRecipientPolicy {
291
292
  */
292
293
  allowedDomains?: string[];
293
294
  }
295
+ /**
296
+ * Set when a builder's first access request created this connection instead of IT (0.88.0, ADR 0034): who, when, and the app that asked. Such a connection is an ordinary ACTIVE connection whose `userModeApproval` starts as `it`, so development is granted by the development preapproval and production waits for IT's one decision; IT may relax the switch afterwards. Absent on connections IT created.
297
+ */
298
+ export interface StartedBy {
299
+ /**
300
+ * One bare email address (no display name).
301
+ */
302
+ email: string;
303
+ at: string;
304
+ /**
305
+ * The app whose request created the connection, when known.
306
+ */
307
+ appId?: string;
308
+ }
294
309
  /**
295
310
  * @deprecated
296
311
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fourier-labs/harbour-contracts",
3
- "version": "0.86.0",
3
+ "version": "0.88.0",
4
4
  "description": "Single source of truth for every data shape that crosses a boundary between Isomorph components.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -35,6 +35,7 @@
35
35
  "description": "Native local App Gateway executables for supported builder platforms; hosted workloads continue to use images.",
36
36
  "properties": {
37
37
  "darwinArm64": { "$ref": "#/definitions/NativeExecutable" },
38
+ "linuxArm64": { "$ref": "#/definitions/NativeExecutable" },
38
39
  "linuxX64": { "$ref": "#/definitions/NativeExecutable" },
39
40
  "windowsX64": { "$ref": "#/definitions/NativeExecutable" }
40
41
  }
@@ -52,6 +52,7 @@
52
52
  "items": { "$ref": "integration-execute-request.schema.json#/definitions/EmailAddress" },
53
53
  "description": "Lower-cased emails who may approve an app's access requests for this connection, besides tenant admins. Empty or absent means tenant admins only."
54
54
  },
55
+ "startedBy": { "$ref": "#/definitions/StartedBy" },
55
56
  "createdAt": { "type": "string", "format": "date-time" },
56
57
  "updatedAt": { "type": "string", "format": "date-time" },
57
58
  "clientId": { "type": "string", "minLength": 1, "maxLength": 255, "deprecated": true, "description": "Deprecated (pre-T25 tenant-owned provider client). Dropped on read; never written." },
@@ -87,6 +88,17 @@
87
88
  "enum": ["slack", "gmail", "basecamp", "sharepoint", "phone", "calendar", "drive", "docs", "sheets", "outlook", "onedrive", "excel", "teams"],
88
89
  "description": "Slack carries an installation and a channel map; Gmail is user-consent only; Basecamp is user-consent only with an IT-pinned account and a project map in `channels`; SharePoint (0.78.0) is user-consent only, pinned to the company's Microsoft 365 tenant in `account`, with a site map in `channels`. Phone (0.82.0) is app mode only with no installation: the tenant's inbound SMS numbers (E.164) mapped from aliases in `channels`, and the SMS the platform received on them listed by phone.sms.list; since 0.83.0 an app reads the number an alias maps to with phone.number.get. Google Workspace (0.86.0, ADR 0032: calendar, drive, docs, sheets on the Google OAuth client) and Microsoft 365 (outlook, onedrive, excel, teams on the Microsoft client) are user-consent only like Gmail, one connection per provider with its own consent and scopes; the seven personal providers have no `account` and empty `channels` (their one fixed alias is the signed-in person's own calendar, drive, documents, spreadsheets, mailbox or workbooks); teams is pinned to the Microsoft 365 tenant in `account` like SharePoint and maps channel aliases in `channels`."
89
90
  },
91
+ "StartedBy": {
92
+ "type": "object",
93
+ "additionalProperties": false,
94
+ "required": ["email", "at"],
95
+ "description": "Set when a builder's first access request created this connection instead of IT (0.88.0, ADR 0034): who, when, and the app that asked. Such a connection is an ordinary ACTIVE connection whose `userModeApproval` starts as `it`, so development is granted by the development preapproval and production waits for IT's one decision; IT may relax the switch afterwards. Absent on connections IT created.",
96
+ "properties": {
97
+ "email": { "$ref": "integration-execute-request.schema.json#/definitions/EmailAddress", "description": "The builder's lower-cased company email." },
98
+ "at": { "type": "string", "format": "date-time" },
99
+ "appId": { "type": "string", "minLength": 1, "maxLength": 128, "description": "The app whose request created the connection, when known." }
100
+ }
101
+ },
90
102
  "BasecampAccount": {
91
103
  "type": "object",
92
104
  "additionalProperties": false,
@@ -367,7 +379,8 @@
367
379
  "channels": {},
368
380
  "operations": ["sheets.spreadsheet.read", "sheets.values.read", "sheets.values.append", "sheets.values.update", "sheets.values.clear", "sheets.spreadsheet.create"],
369
381
  "developmentPreapproval": { "enabled": true, "hours": 24 },
370
- "userModeApproval": "automatic",
382
+ "userModeApproval": "it",
383
+ "startedBy": { "email": "builder@example.com", "at": "2026-10-17T08:00:00Z", "appId": "app-7f3a2c91" },
371
384
  "createdAt": "2026-10-17T08:00:00Z",
372
385
  "updatedAt": "2026-10-17T08:00:00Z"
373
386
  },