@fourier-labs/harbour-contracts 0.88.0 → 0.90.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.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "schema": "harbour.contract-release/1.0",
3
- "repositoryVersion": "0.88.0.0",
4
- "publishVersion": "0.88.0",
5
- "publishTag": "v0.88.0",
6
- "schemasDigest": "sha256:23e1cb0d9f92c4ea5c2b827aeab9266dfee0ed503457ba5bdc101c39212e8c6f",
3
+ "repositoryVersion": "0.90.0.0",
4
+ "publishVersion": "0.90.0",
5
+ "publishTag": "v0.90.0",
6
+ "schemasDigest": "sha256:332836a0ce8cb9ace1540cf172e5991f5e9b2fe4cfc48230f3956bc832a282d8",
7
7
  "aiFixturesDigest": "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6",
8
- "generatedGoDigest": "sha256:05eef493dc05e9f7ef4fbbf0aa4dbba5743ceb12a9baded16c875c33e9ed50bb",
9
- "generatedTypeScriptDigest": "sha256:20e6bfe9e9c7689331b42ea841f6bcc6b0450fb0accc81b451ffba2f1ec2befb",
8
+ "generatedGoDigest": "sha256:16ef224065767ea2fd06545bfdd22a4e3d58fe6c903512952424a010c29508fa",
9
+ "generatedTypeScriptDigest": "sha256:53846b6ac7df436c1dd49293fbb73e93d8f6cbf4d74e10c9cf8a020bd76de086",
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)"
@@ -37,7 +37,7 @@
37
37
  "schema/binding-classification-subject.schema.json": "sha256:a8825ce652e7e00a18759c4249bd5bcd0cae552dd58440513f867e87f685133c",
38
38
  "schema/builder-input-proposal.schema.json": "sha256:fe85cffa6d76b1e1effe1f5d75525f8fe0e1eaa3be4a304e491aa23ad72c0e72",
39
39
  "schema/data-dependency.schema.json": "sha256:b4cc2b2484e982cfed64c0f56b8f1e9d1363c71854cd71f845b24fbe7d85c971",
40
- "schema/data-grant-v2.schema.json": "sha256:495f60e44fce2e5aa00153b191c3bb93f99c4473a0f5bf8cf15b2751de1ff82b",
40
+ "schema/data-grant-v2.schema.json": "sha256:bc27332a9e8967f932ad52b34b15d4d103e611d0898ae5b7b6893b8471631536",
41
41
  "schema/data-grant.schema.json": "sha256:e640553831ecc1c01cc9a37fe388b84d0ffeaa0d0050e63712b48f65fa437c8a",
42
42
  "schema/data-source.schema.json": "sha256:f32b2b4312bc06e023f4e1da60eed52ddfade59b74c1a1cc8e4b740a6f9c930b",
43
43
  "schema/deploy-request.schema.json": "sha256:c978406c273fa430db262888f0a8646b14e3057f64b0633780fcd6cfa646bc67",
@@ -65,8 +65,8 @@
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
- "schema/resolved-app-serving.schema.json": "sha256:1912f3224db1a1699618e6322358e07f76425d3097aec2fbe5d38a10e5c967e3",
69
- "schema/saas-connection.schema.json": "sha256:1bdccb9212ce6d4e448ea1331d023ed42e1e79afb2ef93a946e36d1e5cfcb69b",
68
+ "schema/resolved-app-serving.schema.json": "sha256:3b49268e189429310c2a5dcfd45e9d2187c80b6dbb9d329a0177e96e065c31c0",
69
+ "schema/saas-connection.schema.json": "sha256:f4ad2f72f8349f9a465767914ad70eb3c3407c43ee56ed70521479e80014b6c4",
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:bf9ee7498942f73b4c0434ec826007cf1d4b0f834ab4fd0a82add61953b8cf54",
119
+ "gen-go/types.go": "sha256:bc0acfe7b5ce8ac053bc509b63d5c06c567816096fbdb66b9cbb5b656c6b1cb7",
120
120
  "gen-go/version_state.go": "sha256:4ef8abb126414c0025cf2c59bc9c79a74ef4a2ff89e8f316cbf05acc872371c1"
121
121
  },
122
122
  "generatedTypeScript": {
@@ -148,7 +148,7 @@
148
148
  "gen-ts/binding-classification-subject.ts": "sha256:c409a3fd7b942b50419632c51d9a79474fb30d6374bdc79c0e25c73618e800c3",
149
149
  "gen-ts/builder-input-proposal.ts": "sha256:b0108c3787873d3cf1a39f00967379418a6766275d3474cfa55f5a9d93ead174",
150
150
  "gen-ts/data-dependency.ts": "sha256:259f19e2759395d72ead90b8ed74a6dcef0c2641124f4f182823138cfd19bedf",
151
- "gen-ts/data-grant-v2.ts": "sha256:19d3e2c942f1628861715dcac3213673910ffc45817a8e07dfd1bd04d9e76aa1",
151
+ "gen-ts/data-grant-v2.ts": "sha256:ed8bb2c68d76631c5821b908db27706a6a7f415224b9a9c35bf6de0e394154b4",
152
152
  "gen-ts/data-grant.ts": "sha256:2358579d8aa1e57b01a6f2b0eacce5531e7f21ef226404c9809925365e0d6155",
153
153
  "gen-ts/data-source.ts": "sha256:2566f0d5c72e44278869f55211cf3d433aeb3552e57ae0ace0ff0b85e769dde6",
154
154
  "gen-ts/deploy-request.ts": "sha256:913245577a95354849d3a8cb43fbaedbf895efe7b653c8502d25edfa22b7a864",
@@ -180,8 +180,8 @@
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
- "gen-ts/resolved-app-serving.ts": "sha256:584792e8e0dcaf4322129b6f78579cd8cd21652c8db8a1606f802408c892534c",
184
- "gen-ts/saas-connection.ts": "sha256:aeb6d57d8fdedc8d151df1dad60aae2d5176b7457ebe536c45c4c3175ea75f45",
183
+ "gen-ts/resolved-app-serving.ts": "sha256:3264e85827be47bf391781cb13a1e58318d356f7bee8c2ff3e5b00a062253b23",
184
+ "gen-ts/saas-connection.ts": "sha256:edd55d84416673a5689e5ab56e1264036e69f3b116d7cfbd73b03244dfb71c3e",
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.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";
1
+ export declare const ContractRepositoryVersion: "0.90.0.0";
2
+ export declare const ContractPublishVersion: "0.90.0";
3
+ export declare const ContractPublishTag: "v0.90.0";
4
+ export declare const ContractSchemasDigest: "sha256:332836a0ce8cb9ace1540cf172e5991f5e9b2fe4cfc48230f3956bc832a282d8";
5
5
  export declare const ContractAiFixturesDigest: "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6";
6
- export declare const ContractGeneratedGoDigest: "sha256:05eef493dc05e9f7ef4fbbf0aa4dbba5743ceb12a9baded16c875c33e9ed50bb";
7
- export declare const ContractGeneratedTypeScriptDigest: "sha256:20e6bfe9e9c7689331b42ea841f6bcc6b0450fb0accc81b451ffba2f1ec2befb";
6
+ export declare const ContractGeneratedGoDigest: "sha256:16ef224065767ea2fd06545bfdd22a4e3d58fe6c903512952424a010c29508fa";
7
+ export declare const ContractGeneratedTypeScriptDigest: "sha256:53846b6ac7df436c1dd49293fbb73e93d8f6cbf4d74e10c9cf8a020bd76de086";
@@ -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.88.0.0";
4
- export const ContractPublishVersion = "0.88.0";
5
- export const ContractPublishTag = "v0.88.0";
6
- export const ContractSchemasDigest = "sha256:23e1cb0d9f92c4ea5c2b827aeab9266dfee0ed503457ba5bdc101c39212e8c6f";
3
+ export const ContractRepositoryVersion = "0.90.0.0";
4
+ export const ContractPublishVersion = "0.90.0";
5
+ export const ContractPublishTag = "v0.90.0";
6
+ export const ContractSchemasDigest = "sha256:332836a0ce8cb9ace1540cf172e5991f5e9b2fe4cfc48230f3956bc832a282d8";
7
7
  export const ContractAiFixturesDigest = "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6";
8
- export const ContractGeneratedGoDigest = "sha256:05eef493dc05e9f7ef4fbbf0aa4dbba5743ceb12a9baded16c875c33e9ed50bb";
9
- export const ContractGeneratedTypeScriptDigest = "sha256:20e6bfe9e9c7689331b42ea841f6bcc6b0450fb0accc81b451ffba2f1ec2befb";
8
+ export const ContractGeneratedGoDigest = "sha256:16ef224065767ea2fd06545bfdd22a4e3d58fe6c903512952424a010c29508fa";
9
+ export const ContractGeneratedTypeScriptDigest = "sha256:53846b6ac7df436c1dd49293fbb73e93d8f6cbf4d74e10c9cf8a020bd76de086";
@@ -40,6 +40,7 @@ export interface DataGrantV2 {
40
40
  * @maxItems 64
41
41
  */
42
42
  resources: IntegrationResource[];
43
+ reviewedScope?: ReviewedIntegrationScope;
43
44
  /**
44
45
  * Absent only for explicitly approved ongoing production access.
45
46
  */
@@ -97,6 +98,19 @@ export interface IntegrationResource {
97
98
  */
98
99
  columns?: string[];
99
100
  }
101
+ /**
102
+ * Only for SaaS grants mixing reviewed and automatic access: the previously human-reviewed scope. The remaining scope must satisfy current automatic rules. Homogeneous grants continue using approvedBy alone. Governance validates this is a subset of the grant; database behaviour is unchanged.
103
+ */
104
+ export interface ReviewedIntegrationScope {
105
+ /**
106
+ * @maxItems 78
107
+ */
108
+ operations: ('slack.channel.history' | 'slack.message.post' | 'slack.message.update' | 'slack.message.delete' | 'slack.dm.send' | 'slack.user.lookup' | 'gmail.thread.list' | 'gmail.thread.read' | 'gmail.message.read' | 'gmail.message.send' | 'gmail.attachment.read' | 'basecamp.project.list' | 'basecamp.todolist.list' | 'basecamp.todo.list' | 'basecamp.todo.create' | 'basecamp.todo.complete' | 'basecamp.message.list' | 'basecamp.message.post' | 'basecamp.comment.list' | 'basecamp.comment.post' | 'basecamp.campfire.post' | 'basecamp.people.list' | 'sharepoint.list.list' | 'sharepoint.item.list' | 'sharepoint.item.create' | 'sharepoint.item.update' | 'sharepoint.drive.list' | 'sharepoint.file.list' | 'sharepoint.file.search' | 'sharepoint.file.read' | 'sharepoint.file.upload' | 'phone.sms.list' | 'phone.number.get' | 'calendar.calendar.list' | 'calendar.event.list' | 'calendar.event.read' | 'calendar.event.create' | 'calendar.event.update' | 'calendar.event.cancel' | 'drive.file.list' | 'drive.file.search' | 'drive.file.read' | 'drive.file.upload' | 'drive.folder.create' | 'docs.document.read' | 'docs.document.create' | 'docs.document.append' | 'docs.text.replace' | 'sheets.spreadsheet.read' | 'sheets.values.read' | 'sheets.values.append' | 'sheets.values.update' | 'sheets.values.clear' | 'sheets.spreadsheet.create' | 'outlook.message.list' | 'outlook.message.read' | 'outlook.attachment.read' | 'outlook.message.send' | 'outlook.message.reply' | 'outlook.event.list' | 'outlook.event.read' | 'outlook.event.create' | 'outlook.event.update' | 'outlook.event.cancel' | 'onedrive.file.list' | 'onedrive.file.search' | 'onedrive.file.read' | 'onedrive.file.upload' | 'onedrive.folder.create' | 'excel.worksheet.list' | 'excel.range.read' | 'excel.range.update' | 'excel.table.list' | 'excel.row.add' | 'excel.worksheet.add' | 'teams.message.list' | 'teams.message.post' | 'teams.reply.post' | 'warehouse.view.read' | 'warehouse.table.append' | 'service.request')[];
109
+ /**
110
+ * @maxItems 64
111
+ */
112
+ resources: IntegrationResource[];
113
+ }
100
114
  /**
101
115
  * App-mode Slack grants only: how the app's posts are presented, as IT approved it. Absent means the posts carry the bot's own name.
102
116
  */
@@ -19,6 +19,10 @@ export interface ResolvedAppServing {
19
19
  * The platform cell (LLD §3.7) whose routing store and template distribution serve this app.
20
20
  */
21
21
  cellId?: string;
22
+ /**
23
+ * How the tenant's cells run the app's server (ADR 0035): `kubernetes`, the cluster cell, or `serverless`, the gateway service with Lambda Web Functions, which serves kit apps only. One choice per tenant, the same in every environment; governance copies it from the tenant's deployment destination, and build and Provision branch on it. Absent means kubernetes.
24
+ */
25
+ hosting?: 'kubernetes' | 'serverless';
22
26
  /**
23
27
  * The cell's CloudFront KeyValueStore ARN; equals edge.routingStoreArn unless the cell record names its own.
24
28
  */
@@ -58,6 +58,18 @@ export interface SaasConnection {
58
58
  * @maxItems 78
59
59
  */
60
60
  operations: ('slack.channel.history' | 'slack.message.post' | 'slack.message.update' | 'slack.message.delete' | 'slack.dm.send' | 'slack.user.lookup' | 'gmail.thread.list' | 'gmail.thread.read' | 'gmail.message.read' | 'gmail.message.send' | 'gmail.attachment.read' | 'basecamp.project.list' | 'basecamp.todolist.list' | 'basecamp.todo.list' | 'basecamp.todo.create' | 'basecamp.todo.complete' | 'basecamp.message.list' | 'basecamp.message.post' | 'basecamp.comment.list' | 'basecamp.comment.post' | 'basecamp.campfire.post' | 'basecamp.people.list' | 'sharepoint.list.list' | 'sharepoint.item.list' | 'sharepoint.item.create' | 'sharepoint.item.update' | 'sharepoint.drive.list' | 'sharepoint.file.list' | 'sharepoint.file.search' | 'sharepoint.file.read' | 'sharepoint.file.upload' | 'phone.sms.list' | 'phone.number.get' | 'calendar.calendar.list' | 'calendar.event.list' | 'calendar.event.read' | 'calendar.event.create' | 'calendar.event.update' | 'calendar.event.cancel' | 'drive.file.list' | 'drive.file.search' | 'drive.file.read' | 'drive.file.upload' | 'drive.folder.create' | 'docs.document.read' | 'docs.document.create' | 'docs.document.append' | 'docs.text.replace' | 'sheets.spreadsheet.read' | 'sheets.values.read' | 'sheets.values.append' | 'sheets.values.update' | 'sheets.values.clear' | 'sheets.spreadsheet.create' | 'outlook.message.list' | 'outlook.message.read' | 'outlook.attachment.read' | 'outlook.message.send' | 'outlook.message.reply' | 'outlook.event.list' | 'outlook.event.read' | 'outlook.event.create' | 'outlook.event.update' | 'outlook.event.cancel' | 'onedrive.file.list' | 'onedrive.file.search' | 'onedrive.file.read' | 'onedrive.file.upload' | 'onedrive.folder.create' | 'excel.worksheet.list' | 'excel.range.read' | 'excel.range.update' | 'excel.table.list' | 'excel.row.add' | 'excel.worksheet.add' | 'teams.message.list' | 'teams.message.post' | 'teams.reply.post' | 'warehouse.view.read' | 'warehouse.table.append' | 'service.request')[];
61
+ /**
62
+ * Explicit user-mode operations eligible for automatic app access, subject to the connection operation ceiling and personal consent. Empty means review all; absent inherits company defaults or the existing userModeApproval migration rule. Governance validates provider and mode compatibility. Background execution still requires personal background consent, not a separate admin grant.
63
+ *
64
+ * @maxItems 78
65
+ */
66
+ automaticUserOperations?: ('slack.channel.history' | 'slack.message.post' | 'slack.message.update' | 'slack.message.delete' | 'slack.dm.send' | 'slack.user.lookup' | 'gmail.thread.list' | 'gmail.thread.read' | 'gmail.message.read' | 'gmail.message.send' | 'gmail.attachment.read' | 'basecamp.project.list' | 'basecamp.todolist.list' | 'basecamp.todo.list' | 'basecamp.todo.create' | 'basecamp.todo.complete' | 'basecamp.message.list' | 'basecamp.message.post' | 'basecamp.comment.list' | 'basecamp.comment.post' | 'basecamp.campfire.post' | 'basecamp.people.list' | 'sharepoint.list.list' | 'sharepoint.item.list' | 'sharepoint.item.create' | 'sharepoint.item.update' | 'sharepoint.drive.list' | 'sharepoint.file.list' | 'sharepoint.file.search' | 'sharepoint.file.read' | 'sharepoint.file.upload' | 'phone.sms.list' | 'phone.number.get' | 'calendar.calendar.list' | 'calendar.event.list' | 'calendar.event.read' | 'calendar.event.create' | 'calendar.event.update' | 'calendar.event.cancel' | 'drive.file.list' | 'drive.file.search' | 'drive.file.read' | 'drive.file.upload' | 'drive.folder.create' | 'docs.document.read' | 'docs.document.create' | 'docs.document.append' | 'docs.text.replace' | 'sheets.spreadsheet.read' | 'sheets.values.read' | 'sheets.values.append' | 'sheets.values.update' | 'sheets.values.clear' | 'sheets.spreadsheet.create' | 'outlook.message.list' | 'outlook.message.read' | 'outlook.attachment.read' | 'outlook.message.send' | 'outlook.message.reply' | 'outlook.event.list' | 'outlook.event.read' | 'outlook.event.create' | 'outlook.event.update' | 'outlook.event.cancel' | 'onedrive.file.list' | 'onedrive.file.search' | 'onedrive.file.read' | 'onedrive.file.upload' | 'onedrive.folder.create' | 'excel.worksheet.list' | 'excel.range.read' | 'excel.range.update' | 'excel.table.list' | 'excel.row.add' | 'excel.worksheet.add' | 'teams.message.list' | 'teams.message.post' | 'teams.reply.post' | 'warehouse.view.read' | 'warehouse.table.append' | 'service.request')[];
67
+ /**
68
+ * Reusable permissions for admitted builders on explicit shared SaaS resources. Governance checks registered resources, provider/mode compatibility and the connection operation ceiling. Connection version and audit record changes; no per-entry approval metadata.
69
+ *
70
+ * @maxItems 128
71
+ */
72
+ reusableAccess?: ReusableSaasAccess[];
61
73
  developmentPreapproval: DevelopmentPreapproval;
62
74
  oauthClient?: SaasOauthClient;
63
75
  userModeApproval?: UserModeApproval;
@@ -141,6 +153,21 @@ export interface BasecampAccount {
141
153
  */
142
154
  name: string;
143
155
  }
156
+ export interface ReusableSaasAccess {
157
+ /**
158
+ * Tenant-wide logical alias of a connection (governance sourceId) or of a resource under it.
159
+ */
160
+ resource: string;
161
+ /**
162
+ * Whose authority an operation runs under. Fixed per operation, except the declared-mode Slack operations (slack.message.post; since 0.71.0 also slack.channel.history, slack.message.update, slack.message.delete): declared per app for the access request, and named per call among the app's approved modes (execute request `mode`, 0.55.0).
163
+ */
164
+ mode: 'app' | 'user';
165
+ /**
166
+ * @minItems 1
167
+ * @maxItems 78
168
+ */
169
+ operations: ('slack.channel.history' | 'slack.message.post' | 'slack.message.update' | 'slack.message.delete' | 'slack.dm.send' | 'slack.user.lookup' | 'gmail.thread.list' | 'gmail.thread.read' | 'gmail.message.read' | 'gmail.message.send' | 'gmail.attachment.read' | 'basecamp.project.list' | 'basecamp.todolist.list' | 'basecamp.todo.list' | 'basecamp.todo.create' | 'basecamp.todo.complete' | 'basecamp.message.list' | 'basecamp.message.post' | 'basecamp.comment.list' | 'basecamp.comment.post' | 'basecamp.campfire.post' | 'basecamp.people.list' | 'sharepoint.list.list' | 'sharepoint.item.list' | 'sharepoint.item.create' | 'sharepoint.item.update' | 'sharepoint.drive.list' | 'sharepoint.file.list' | 'sharepoint.file.search' | 'sharepoint.file.read' | 'sharepoint.file.upload' | 'phone.sms.list' | 'phone.number.get' | 'calendar.calendar.list' | 'calendar.event.list' | 'calendar.event.read' | 'calendar.event.create' | 'calendar.event.update' | 'calendar.event.cancel' | 'drive.file.list' | 'drive.file.search' | 'drive.file.read' | 'drive.file.upload' | 'drive.folder.create' | 'docs.document.read' | 'docs.document.create' | 'docs.document.append' | 'docs.text.replace' | 'sheets.spreadsheet.read' | 'sheets.values.read' | 'sheets.values.append' | 'sheets.values.update' | 'sheets.values.clear' | 'sheets.spreadsheet.create' | 'outlook.message.list' | 'outlook.message.read' | 'outlook.attachment.read' | 'outlook.message.send' | 'outlook.message.reply' | 'outlook.event.list' | 'outlook.event.read' | 'outlook.event.create' | 'outlook.event.update' | 'outlook.event.cancel' | 'onedrive.file.list' | 'onedrive.file.search' | 'onedrive.file.read' | 'onedrive.file.upload' | 'onedrive.folder.create' | 'excel.worksheet.list' | 'excel.range.read' | 'excel.range.update' | 'excel.table.list' | 'excel.row.add' | 'excel.worksheet.add' | 'teams.message.list' | 'teams.message.post' | 'teams.reply.post' | 'warehouse.view.read' | 'warehouse.table.append' | 'service.request')[];
170
+ }
144
171
  export interface DevelopmentPreapproval {
145
172
  /**
146
173
  * Auto-approve development requests within the allowlist.
@@ -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.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;
4
+ export const ContractRepositoryVersion = "0.90.0.0" as const;
5
+ export const ContractPublishVersion = "0.90.0" as const;
6
+ export const ContractPublishTag = "v0.90.0" as const;
7
+ export const ContractSchemasDigest = "sha256:332836a0ce8cb9ace1540cf172e5991f5e9b2fe4cfc48230f3956bc832a282d8" as const;
8
8
  export const ContractAiFixturesDigest = "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6" as const;
9
- export const ContractGeneratedGoDigest = "sha256:05eef493dc05e9f7ef4fbbf0aa4dbba5743ceb12a9baded16c875c33e9ed50bb" as const;
10
- export const ContractGeneratedTypeScriptDigest = "sha256:20e6bfe9e9c7689331b42ea841f6bcc6b0450fb0accc81b451ffba2f1ec2befb" as const;
9
+ export const ContractGeneratedGoDigest = "sha256:16ef224065767ea2fd06545bfdd22a4e3d58fe6c903512952424a010c29508fa" as const;
10
+ export const ContractGeneratedTypeScriptDigest = "sha256:53846b6ac7df436c1dd49293fbb73e93d8f6cbf4d74e10c9cf8a020bd76de086" as const;
@@ -126,6 +126,7 @@ export interface DataGrantV2 {
126
126
  * @maxItems 64
127
127
  */
128
128
  resources: IntegrationResource[];
129
+ reviewedScope?: ReviewedIntegrationScope;
129
130
  /**
130
131
  * Absent only for explicitly approved ongoing production access.
131
132
  */
@@ -183,6 +184,101 @@ export interface IntegrationResource {
183
184
  */
184
185
  columns?: string[];
185
186
  }
187
+ /**
188
+ * Only for SaaS grants mixing reviewed and automatic access: the previously human-reviewed scope. The remaining scope must satisfy current automatic rules. Homogeneous grants continue using approvedBy alone. Governance validates this is a subset of the grant; database behaviour is unchanged.
189
+ */
190
+ export interface ReviewedIntegrationScope {
191
+ /**
192
+ * @maxItems 78
193
+ */
194
+ operations: (
195
+ | 'slack.channel.history'
196
+ | 'slack.message.post'
197
+ | 'slack.message.update'
198
+ | 'slack.message.delete'
199
+ | 'slack.dm.send'
200
+ | 'slack.user.lookup'
201
+ | 'gmail.thread.list'
202
+ | 'gmail.thread.read'
203
+ | 'gmail.message.read'
204
+ | 'gmail.message.send'
205
+ | 'gmail.attachment.read'
206
+ | 'basecamp.project.list'
207
+ | 'basecamp.todolist.list'
208
+ | 'basecamp.todo.list'
209
+ | 'basecamp.todo.create'
210
+ | 'basecamp.todo.complete'
211
+ | 'basecamp.message.list'
212
+ | 'basecamp.message.post'
213
+ | 'basecamp.comment.list'
214
+ | 'basecamp.comment.post'
215
+ | 'basecamp.campfire.post'
216
+ | 'basecamp.people.list'
217
+ | 'sharepoint.list.list'
218
+ | 'sharepoint.item.list'
219
+ | 'sharepoint.item.create'
220
+ | 'sharepoint.item.update'
221
+ | 'sharepoint.drive.list'
222
+ | 'sharepoint.file.list'
223
+ | 'sharepoint.file.search'
224
+ | 'sharepoint.file.read'
225
+ | 'sharepoint.file.upload'
226
+ | 'phone.sms.list'
227
+ | 'phone.number.get'
228
+ | 'calendar.calendar.list'
229
+ | 'calendar.event.list'
230
+ | 'calendar.event.read'
231
+ | 'calendar.event.create'
232
+ | 'calendar.event.update'
233
+ | 'calendar.event.cancel'
234
+ | 'drive.file.list'
235
+ | 'drive.file.search'
236
+ | 'drive.file.read'
237
+ | 'drive.file.upload'
238
+ | 'drive.folder.create'
239
+ | 'docs.document.read'
240
+ | 'docs.document.create'
241
+ | 'docs.document.append'
242
+ | 'docs.text.replace'
243
+ | 'sheets.spreadsheet.read'
244
+ | 'sheets.values.read'
245
+ | 'sheets.values.append'
246
+ | 'sheets.values.update'
247
+ | 'sheets.values.clear'
248
+ | 'sheets.spreadsheet.create'
249
+ | 'outlook.message.list'
250
+ | 'outlook.message.read'
251
+ | 'outlook.attachment.read'
252
+ | 'outlook.message.send'
253
+ | 'outlook.message.reply'
254
+ | 'outlook.event.list'
255
+ | 'outlook.event.read'
256
+ | 'outlook.event.create'
257
+ | 'outlook.event.update'
258
+ | 'outlook.event.cancel'
259
+ | 'onedrive.file.list'
260
+ | 'onedrive.file.search'
261
+ | 'onedrive.file.read'
262
+ | 'onedrive.file.upload'
263
+ | 'onedrive.folder.create'
264
+ | 'excel.worksheet.list'
265
+ | 'excel.range.read'
266
+ | 'excel.range.update'
267
+ | 'excel.table.list'
268
+ | 'excel.row.add'
269
+ | 'excel.worksheet.add'
270
+ | 'teams.message.list'
271
+ | 'teams.message.post'
272
+ | 'teams.reply.post'
273
+ | 'warehouse.view.read'
274
+ | 'warehouse.table.append'
275
+ | 'service.request'
276
+ )[];
277
+ /**
278
+ * @maxItems 64
279
+ */
280
+ resources: IntegrationResource[];
281
+ }
186
282
  /**
187
283
  * App-mode Slack grants only: how the app's posts are presented, as IT approved it. Absent means the posts carry the bot's own name.
188
284
  */
@@ -22,6 +22,10 @@ export interface ResolvedAppServing {
22
22
  * The platform cell (LLD §3.7) whose routing store and template distribution serve this app.
23
23
  */
24
24
  cellId?: string;
25
+ /**
26
+ * How the tenant's cells run the app's server (ADR 0035): `kubernetes`, the cluster cell, or `serverless`, the gateway service with Lambda Web Functions, which serves kit apps only. One choice per tenant, the same in every environment; governance copies it from the tenant's deployment destination, and build and Provision branch on it. Absent means kubernetes.
27
+ */
28
+ hosting?: 'kubernetes' | 'serverless';
25
29
  /**
26
30
  * The cell's CloudFront KeyValueStore ARN; equals edge.routingStoreArn unless the cell record names its own.
27
31
  */
@@ -157,6 +157,100 @@ export interface SaasConnection {
157
157
  | 'warehouse.table.append'
158
158
  | 'service.request'
159
159
  )[];
160
+ /**
161
+ * Explicit user-mode operations eligible for automatic app access, subject to the connection operation ceiling and personal consent. Empty means review all; absent inherits company defaults or the existing userModeApproval migration rule. Governance validates provider and mode compatibility. Background execution still requires personal background consent, not a separate admin grant.
162
+ *
163
+ * @maxItems 78
164
+ */
165
+ automaticUserOperations?: (
166
+ | 'slack.channel.history'
167
+ | 'slack.message.post'
168
+ | 'slack.message.update'
169
+ | 'slack.message.delete'
170
+ | 'slack.dm.send'
171
+ | 'slack.user.lookup'
172
+ | 'gmail.thread.list'
173
+ | 'gmail.thread.read'
174
+ | 'gmail.message.read'
175
+ | 'gmail.message.send'
176
+ | 'gmail.attachment.read'
177
+ | 'basecamp.project.list'
178
+ | 'basecamp.todolist.list'
179
+ | 'basecamp.todo.list'
180
+ | 'basecamp.todo.create'
181
+ | 'basecamp.todo.complete'
182
+ | 'basecamp.message.list'
183
+ | 'basecamp.message.post'
184
+ | 'basecamp.comment.list'
185
+ | 'basecamp.comment.post'
186
+ | 'basecamp.campfire.post'
187
+ | 'basecamp.people.list'
188
+ | 'sharepoint.list.list'
189
+ | 'sharepoint.item.list'
190
+ | 'sharepoint.item.create'
191
+ | 'sharepoint.item.update'
192
+ | 'sharepoint.drive.list'
193
+ | 'sharepoint.file.list'
194
+ | 'sharepoint.file.search'
195
+ | 'sharepoint.file.read'
196
+ | 'sharepoint.file.upload'
197
+ | 'phone.sms.list'
198
+ | 'phone.number.get'
199
+ | 'calendar.calendar.list'
200
+ | 'calendar.event.list'
201
+ | 'calendar.event.read'
202
+ | 'calendar.event.create'
203
+ | 'calendar.event.update'
204
+ | 'calendar.event.cancel'
205
+ | 'drive.file.list'
206
+ | 'drive.file.search'
207
+ | 'drive.file.read'
208
+ | 'drive.file.upload'
209
+ | 'drive.folder.create'
210
+ | 'docs.document.read'
211
+ | 'docs.document.create'
212
+ | 'docs.document.append'
213
+ | 'docs.text.replace'
214
+ | 'sheets.spreadsheet.read'
215
+ | 'sheets.values.read'
216
+ | 'sheets.values.append'
217
+ | 'sheets.values.update'
218
+ | 'sheets.values.clear'
219
+ | 'sheets.spreadsheet.create'
220
+ | 'outlook.message.list'
221
+ | 'outlook.message.read'
222
+ | 'outlook.attachment.read'
223
+ | 'outlook.message.send'
224
+ | 'outlook.message.reply'
225
+ | 'outlook.event.list'
226
+ | 'outlook.event.read'
227
+ | 'outlook.event.create'
228
+ | 'outlook.event.update'
229
+ | 'outlook.event.cancel'
230
+ | 'onedrive.file.list'
231
+ | 'onedrive.file.search'
232
+ | 'onedrive.file.read'
233
+ | 'onedrive.file.upload'
234
+ | 'onedrive.folder.create'
235
+ | 'excel.worksheet.list'
236
+ | 'excel.range.read'
237
+ | 'excel.range.update'
238
+ | 'excel.table.list'
239
+ | 'excel.row.add'
240
+ | 'excel.worksheet.add'
241
+ | 'teams.message.list'
242
+ | 'teams.message.post'
243
+ | 'teams.reply.post'
244
+ | 'warehouse.view.read'
245
+ | 'warehouse.table.append'
246
+ | 'service.request'
247
+ )[];
248
+ /**
249
+ * Reusable permissions for admitted builders on explicit shared SaaS resources. Governance checks registered resources, provider/mode compatibility and the connection operation ceiling. Connection version and audit record changes; no per-entry approval metadata.
250
+ *
251
+ * @maxItems 128
252
+ */
253
+ reusableAccess?: ReusableSaasAccess[];
160
254
  developmentPreapproval: DevelopmentPreapproval;
161
255
  oauthClient?: SaasOauthClient;
162
256
  userModeApproval?: UserModeApproval;
@@ -240,6 +334,103 @@ export interface BasecampAccount {
240
334
  */
241
335
  name: string;
242
336
  }
337
+ export interface ReusableSaasAccess {
338
+ /**
339
+ * Tenant-wide logical alias of a connection (governance sourceId) or of a resource under it.
340
+ */
341
+ resource: string;
342
+ /**
343
+ * Whose authority an operation runs under. Fixed per operation, except the declared-mode Slack operations (slack.message.post; since 0.71.0 also slack.channel.history, slack.message.update, slack.message.delete): declared per app for the access request, and named per call among the app's approved modes (execute request `mode`, 0.55.0).
344
+ */
345
+ mode: 'app' | 'user';
346
+ /**
347
+ * @minItems 1
348
+ * @maxItems 78
349
+ */
350
+ operations: (
351
+ | 'slack.channel.history'
352
+ | 'slack.message.post'
353
+ | 'slack.message.update'
354
+ | 'slack.message.delete'
355
+ | 'slack.dm.send'
356
+ | 'slack.user.lookup'
357
+ | 'gmail.thread.list'
358
+ | 'gmail.thread.read'
359
+ | 'gmail.message.read'
360
+ | 'gmail.message.send'
361
+ | 'gmail.attachment.read'
362
+ | 'basecamp.project.list'
363
+ | 'basecamp.todolist.list'
364
+ | 'basecamp.todo.list'
365
+ | 'basecamp.todo.create'
366
+ | 'basecamp.todo.complete'
367
+ | 'basecamp.message.list'
368
+ | 'basecamp.message.post'
369
+ | 'basecamp.comment.list'
370
+ | 'basecamp.comment.post'
371
+ | 'basecamp.campfire.post'
372
+ | 'basecamp.people.list'
373
+ | 'sharepoint.list.list'
374
+ | 'sharepoint.item.list'
375
+ | 'sharepoint.item.create'
376
+ | 'sharepoint.item.update'
377
+ | 'sharepoint.drive.list'
378
+ | 'sharepoint.file.list'
379
+ | 'sharepoint.file.search'
380
+ | 'sharepoint.file.read'
381
+ | 'sharepoint.file.upload'
382
+ | 'phone.sms.list'
383
+ | 'phone.number.get'
384
+ | 'calendar.calendar.list'
385
+ | 'calendar.event.list'
386
+ | 'calendar.event.read'
387
+ | 'calendar.event.create'
388
+ | 'calendar.event.update'
389
+ | 'calendar.event.cancel'
390
+ | 'drive.file.list'
391
+ | 'drive.file.search'
392
+ | 'drive.file.read'
393
+ | 'drive.file.upload'
394
+ | 'drive.folder.create'
395
+ | 'docs.document.read'
396
+ | 'docs.document.create'
397
+ | 'docs.document.append'
398
+ | 'docs.text.replace'
399
+ | 'sheets.spreadsheet.read'
400
+ | 'sheets.values.read'
401
+ | 'sheets.values.append'
402
+ | 'sheets.values.update'
403
+ | 'sheets.values.clear'
404
+ | 'sheets.spreadsheet.create'
405
+ | 'outlook.message.list'
406
+ | 'outlook.message.read'
407
+ | 'outlook.attachment.read'
408
+ | 'outlook.message.send'
409
+ | 'outlook.message.reply'
410
+ | 'outlook.event.list'
411
+ | 'outlook.event.read'
412
+ | 'outlook.event.create'
413
+ | 'outlook.event.update'
414
+ | 'outlook.event.cancel'
415
+ | 'onedrive.file.list'
416
+ | 'onedrive.file.search'
417
+ | 'onedrive.file.read'
418
+ | 'onedrive.file.upload'
419
+ | 'onedrive.folder.create'
420
+ | 'excel.worksheet.list'
421
+ | 'excel.range.read'
422
+ | 'excel.range.update'
423
+ | 'excel.table.list'
424
+ | 'excel.row.add'
425
+ | 'excel.worksheet.add'
426
+ | 'teams.message.list'
427
+ | 'teams.message.post'
428
+ | 'teams.reply.post'
429
+ | 'warehouse.view.read'
430
+ | 'warehouse.table.append'
431
+ | 'service.request'
432
+ )[];
433
+ }
243
434
  export interface DevelopmentPreapproval {
244
435
  /**
245
436
  * Auto-approve development requests within the allowlist.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fourier-labs/harbour-contracts",
3
- "version": "0.88.0",
3
+ "version": "0.90.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,
@@ -29,6 +29,7 @@
29
29
  "items": { "$ref": "#/definitions/IntegrationResource" },
30
30
  "description": "Approved logical resources. Never inherited by wildcard. Empty until the first approval."
31
31
  },
32
+ "reviewedScope": { "$ref": "#/definitions/ReviewedIntegrationScope" },
32
33
  "expiresAt": { "type": "string", "format": "date-time", "description": "Absent only for explicitly approved ongoing production access." },
33
34
  "expiredAt": { "type": "string", "format": "date-time", "description": "Set by the recovery sweep once expiry has passed; enforcement itself is the UTC check on every call." },
34
35
  "approvedBy": { "type": "string", "minLength": 1, "maxLength": 255 },
@@ -58,6 +59,21 @@
58
59
  }
59
60
  },
60
61
  "definitions": {
62
+ "ReviewedIntegrationScope": {
63
+ "type": "object", "additionalProperties": false,
64
+ "required": ["operations", "resources"],
65
+ "description": "Only for SaaS grants mixing reviewed and automatic access: the previously human-reviewed scope. The remaining scope must satisfy current automatic rules. Homogeneous grants continue using approvedBy alone. Governance validates this is a subset of the grant; database behaviour is unchanged.",
66
+ "properties": {
67
+ "operations": {
68
+ "type": "array", "maxItems": 78, "uniqueItems": true,
69
+ "items": { "$ref": "app-integrations-declaration.schema.json#/definitions/IntegrationOperation" }
70
+ },
71
+ "resources": {
72
+ "type": "array", "maxItems": 64, "uniqueItems": true,
73
+ "items": { "$ref": "#/definitions/IntegrationResource" }
74
+ }
75
+ }
76
+ },
61
77
  "IntegrationResource": {
62
78
  "type": "object",
63
79
  "additionalProperties": false,
@@ -24,6 +24,7 @@
24
24
  }
25
25
  },
26
26
  "cellId": {"type": "string", "minLength": 1, "description": "The platform cell (LLD §3.7) whose routing store and template distribution serve this app."},
27
+ "hosting": {"type": "string", "enum": ["kubernetes", "serverless"], "description": "How the tenant's cells run the app's server (ADR 0035): `kubernetes`, the cluster cell, or `serverless`, the gateway service with Lambda Web Functions, which serves kit apps only. One choice per tenant, the same in every environment; governance copies it from the tenant's deployment destination, and build and Provision branch on it. Absent means kubernetes."},
27
28
  "routingStoreArn": {"type": "string", "minLength": 1, "description": "The cell's CloudFront KeyValueStore ARN; equals edge.routingStoreArn unless the cell record names its own."},
28
29
  "pageHost": {"type": "string", "format": "hostname", "description": "Bare hostname of frontendUrl."},
29
30
  "apiHost": {"type": "string", "format": "hostname", "description": "Bare hostname of apiUrl."},
@@ -33,6 +33,17 @@
33
33
  "not": { "anyOf": [{ "contains": { "const": "warehouse.view.read" } }, { "contains": { "const": "warehouse.table.append" } }] },
34
34
  "description": "Operations IT allows apps to request on this connection: the provider's own SaaS operations (Slack: slack.channel.history, slack.message.post, slack.message.update, slack.message.delete, slack.dm.send, slack.user.lookup; Gmail: gmail.thread.list, gmail.thread.read, gmail.message.read, gmail.message.send, gmail.attachment.read; Basecamp (0.76.0): basecamp.project.list, basecamp.todolist.list, basecamp.todo.list, basecamp.todo.create, basecamp.todo.complete, basecamp.message.list, basecamp.message.post, basecamp.comment.list, basecamp.comment.post, basecamp.campfire.post, basecamp.people.list; SharePoint (0.78.0): sharepoint.list.list, sharepoint.item.list, sharepoint.item.create, sharepoint.item.update, sharepoint.drive.list, sharepoint.file.list, sharepoint.file.search, sharepoint.file.read, sharepoint.file.upload; Google Workspace and Microsoft 365 (0.86.0): the calendar.*, drive.*, docs.*, sheets.*, outlook.*, onedrive.*, excel.* and teams.* operations of the connection's provider). Never warehouse.view.read. Phone (0.82.0): phone.sms.list; 0.83.0 adds phone.number.get. Seventy-eight SaaS operations in all since 0.86.0."
35
35
  },
36
+ "automaticUserOperations": {
37
+ "type": "array", "maxItems": 78, "uniqueItems": true,
38
+ "items": { "$ref": "app-integrations-declaration.schema.json#/definitions/IntegrationOperation" },
39
+ "not": { "anyOf": [{ "contains": { "const": "warehouse.view.read" } }, { "contains": { "const": "warehouse.table.append" } }, { "contains": { "const": "service.request" } }] },
40
+ "description": "Explicit user-mode operations eligible for automatic app access, subject to the connection operation ceiling and personal consent. Empty means review all; absent inherits company defaults or the existing userModeApproval migration rule. Governance validates provider and mode compatibility. Background execution still requires personal background consent, not a separate admin grant."
41
+ },
42
+ "reusableAccess": {
43
+ "type": "array", "maxItems": 128, "uniqueItems": true,
44
+ "items": { "$ref": "#/definitions/ReusableSaasAccess" },
45
+ "description": "Reusable permissions for admitted builders on explicit shared SaaS resources. Governance checks registered resources, provider/mode compatibility and the connection operation ceiling. Connection version and audit record changes; no per-entry approval metadata."
46
+ },
36
47
  "developmentPreapproval": { "$ref": "#/definitions/DevelopmentPreapproval" },
37
48
  "oauthClient": { "$ref": "#/definitions/SaasOauthClient" },
38
49
  "userModeApproval": { "$ref": "#/definitions/UserModeApproval" },
@@ -83,6 +94,19 @@
83
94
  }
84
95
  },
85
96
  "definitions": {
97
+ "ReusableSaasAccess": {
98
+ "type": "object", "additionalProperties": false,
99
+ "required": ["resource", "mode", "operations"],
100
+ "properties": {
101
+ "resource": { "$ref": "app-integrations-declaration.schema.json#/definitions/IntegrationAlias" },
102
+ "mode": { "$ref": "app-integrations-declaration.schema.json#/definitions/IntegrationIdentityMode" },
103
+ "operations": {
104
+ "type": "array", "minItems": 1, "maxItems": 78, "uniqueItems": true,
105
+ "items": { "$ref": "app-integrations-declaration.schema.json#/definitions/IntegrationOperation" },
106
+ "not": { "anyOf": [{ "contains": { "const": "warehouse.view.read" } }, { "contains": { "const": "warehouse.table.append" } }, { "contains": { "const": "service.request" } }] }
107
+ }
108
+ }
109
+ },
86
110
  "SaasProvider": {
87
111
  "type": "string",
88
112
  "enum": ["slack", "gmail", "basecamp", "sharepoint", "phone", "calendar", "drive", "docs", "sheets", "outlook", "onedrive", "excel", "teams"],