@fabrika/control-contract 0.3.3 → 0.4.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.
Files changed (3) hide show
  1. package/package.json +4 -4
  2. package/src/index.ts +74 -1
  3. package/src/rpc.ts +36 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fabrika/control-contract",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,8 +25,8 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "zod": "^3.25.76",
28
- "@fabrika/auth-core": "^0.3.3",
29
- "@fabrika/app": "^0.3.3",
30
- "@fabrika/provider-contract": "^0.3.3"
28
+ "@fabrika/auth-core": "^0.4.0",
29
+ "@fabrika/app": "^0.4.0",
30
+ "@fabrika/provider-contract": "^0.4.0"
31
31
  }
32
32
  }
package/src/index.ts CHANGED
@@ -183,6 +183,17 @@ export interface AppEnvDto {
183
183
  domain: string | null
184
184
  publicOrigin: string | null
185
185
  triggerRef: string | null
186
+ /** An MCP authoring target (ADR-0049): users with `source.workspace.*` grants may edit and deploy it. */
187
+ authoring: boolean
188
+ /** A widening of access waits for a human's approval here (ADR-0050); `prod` is protected by default. */
189
+ protected: boolean
190
+ /** The run whose snapshot is this environment's active access; null until a run publishes one. */
191
+ publishedRunId: string | null
192
+ /**
193
+ * The published snapshot's steps off the paved road, one line each: the reach its sites declare and the database code
194
+ * its migrations declare. Each needs closer review; listed whether or not the environment is protected.
195
+ */
196
+ deviations: string[]
186
197
  namespaceId: string | null
187
198
  provider: string
188
199
  target: ProviderEnvelopeDto
@@ -194,6 +205,8 @@ export interface PutAppEnvRequest {
194
205
  domain?: string | null
195
206
  publicOrigin?: string | null
196
207
  triggerRef?: string | null
208
+ /** Omitted keeps the stored value. Only a Zerops environment of an app with a GitHub connection qualifies. */
209
+ authoring?: boolean
197
210
  namespaceId?: string | null
198
211
  target: ProviderEnvelopeDto
199
212
  artifact: ProviderEnvelopeDto
@@ -216,6 +229,11 @@ export interface DeploymentNamespaceDto {
216
229
  */
217
230
  lastError: string | null
218
231
  lastErrorCode: string | null
232
+ /**
233
+ * Present only while a `namespaces.update` is unconfirmed (`lastErrorCode` `namespaceUpdateUnconfirmed`):
234
+ * the target that update was moving to. Retrying `namespaces.update` with it finishes the update.
235
+ */
236
+ unconfirmedTarget?: ProviderEnvelopeDto
219
237
  createdAt: number
220
238
  }
221
239
 
@@ -252,6 +270,16 @@ export interface AdoptDeploymentNamespaceRequest {
252
270
  target: ProviderEnvelopeDto
253
271
  }
254
272
 
273
+ /**
274
+ * A namespace's new provider target. Its payload may name only what changes; the provider merges it over
275
+ * the stored one. Only what the provider can change in place is accepted — on Zerops the PostgreSQL
276
+ * profile. A field the target does not have is a 400; any other change is a 409 that names the supported
277
+ * path, a new namespace under a new id.
278
+ */
279
+ export interface UpdateDeploymentNamespaceRequest {
280
+ target: ProviderEnvelopeDto
281
+ }
282
+
255
283
  export interface DeploymentNamespaceFactDto {
256
284
  readonly label: string
257
285
  readonly value: string
@@ -367,7 +395,8 @@ export interface RegisterAppResponse {
367
395
  }
368
396
 
369
397
  export type RunTrigger = 'webhook' | 'manual' | 'poll'
370
- export type RunStatus = 'pending' | 'running' | 'succeeded' | 'failed'
398
+ /** `awaiting_approval`: the run widens access on a protected environment and waits for a human (ADR-0050). */
399
+ export type RunStatus = 'pending' | 'running' | 'awaiting_approval' | 'succeeded' | 'failed'
371
400
 
372
401
  export interface RunDto {
373
402
  id: string
@@ -376,6 +405,8 @@ export interface RunDto {
376
405
  ref: string
377
406
  commitSha: string | null
378
407
  trigger: RunTrigger
408
+ /** Who created the run: `user:<id>`, `service:<id>`, `oauth:<id>` (an MCP client acting for a user), `webhook:<connection>` or `poll`. */
409
+ actor: string | null
379
410
  status: RunStatus
380
411
  exitCode: number | null
381
412
  externalRunId: string | null
@@ -385,6 +416,46 @@ export interface RunDto {
385
416
  finishedAt: number | null
386
417
  }
387
418
 
419
+ /**
420
+ * One plain-language line of an access change; `widens` when it can grant access the baseline did not. `review: 'closer'`
421
+ * marks a step off the paved road (declared reach, database code) or a change the diff cannot classify.
422
+ */
423
+ export interface AccessChangeDto {
424
+ widens: boolean
425
+ line: string
426
+ review?: 'closer'
427
+ }
428
+
429
+ /** A run's access change against its environment's active snapshot (ADR-0050 §3). */
430
+ export interface ApprovalDto {
431
+ run: RunDto
432
+ outcome: 'unchanged' | 'removal' | 'widening'
433
+ changes: AccessChangeDto[]
434
+ /** The digest of the run's snapshot and of the active one it was compared with: an approval is bound to both. */
435
+ candidateDigest: string
436
+ baselineDigest: string
437
+ /** The published run the change was compared with; null when nothing was published. */
438
+ baselineRunId: string | null
439
+ protected: boolean
440
+ /** The human who approved it, once one did. */
441
+ approval: { principalId: string; label: string; approvedAt: number } | null
442
+ }
443
+
444
+ /** Approve or refuse one parked run. The digests are the ones the approver read; a reclassified run refuses them. */
445
+ export interface CompleteApprovalRequest {
446
+ runId: string
447
+ decision: 'approve' | 'reject'
448
+ candidateDigest: string
449
+ baselineDigest: string
450
+ }
451
+
452
+ /** Change whether a widening waits for approval on one environment (ADR-0050 §4). */
453
+ export interface SetEnvironmentProtectionRequest {
454
+ appId: string
455
+ env: string
456
+ protected: boolean
457
+ }
458
+
388
459
  export interface TriggerDeployRequest {
389
460
  appId: string
390
461
  env: string
@@ -410,6 +481,7 @@ export type {
410
481
  AppNamedValueInput,
411
482
  ControlRpcContract,
412
483
  CreateAppRequest,
484
+ DescribeConnectorRequest,
413
485
  GitHubSourceConnectionInput,
414
486
  GitHubSourceConnectionRpcContract,
415
487
  NamespaceIdInput,
@@ -422,4 +494,5 @@ export type {
422
494
  SecretValueInput,
423
495
  SecretValueResponse,
424
496
  TailRunInput,
497
+ UpdateNamespaceInput,
425
498
  } from './rpc.js'
package/src/rpc.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { RpcProcedureContract } from '@fabrika/app'
2
+ import type { ExportDescription } from '@fabrika/auth-core'
2
3
  import type { BuilderConnectionReceiptDto, CreateBuilderConnectionReceiptRequest, GetBuilderConnectionReceiptRequest } from './builder-connections.js'
3
4
  import type {
4
5
  ApproveDeviceAuthorizationResult,
@@ -14,8 +15,10 @@ import type {
14
15
  AdoptDeploymentNamespaceRequest,
15
16
  AppDto,
16
17
  AppEnvDto,
18
+ ApprovalDto,
17
19
  AppSecretDto,
18
20
  AppVarDto,
21
+ CompleteApprovalRequest,
19
22
  CreateDeploymentNamespaceRequest,
20
23
  CursorList,
21
24
  DeploymentNamespaceDetailDto,
@@ -36,10 +39,12 @@ import type {
36
39
  RunDto,
37
40
  RunLogResponse,
38
41
  RunTailResponse,
42
+ SetEnvironmentProtectionRequest,
39
43
  StartGitHubSourceConnectionRequest,
40
44
  StartGitHubSourceConnectionResponse,
41
45
  TriggerDeployRequest,
42
46
  UpdateAppRequest,
47
+ UpdateDeploymentNamespaceRequest,
43
48
  } from './index.js'
44
49
 
45
50
  type RpcProcedure<TInput, TOutput> = RpcProcedureContract<TInput, TOutput>
@@ -95,6 +100,10 @@ export interface AdoptNamespaceInput extends NamespaceIdInput {
95
100
  readonly namespace: AdoptDeploymentNamespaceRequest
96
101
  }
97
102
 
103
+ export interface UpdateNamespaceInput extends NamespaceIdInput {
104
+ readonly namespace: UpdateDeploymentNamespaceRequest
105
+ }
106
+
98
107
  export interface RunListInput {
99
108
  readonly appId?: string
100
109
  readonly env?: string
@@ -148,6 +157,8 @@ export interface ControlRpcContract {
148
157
  list: RpcProcedure<AppIdInput, ListResponse<AppEnvDto>>
149
158
  put: RpcProcedure<PutAppEnvironmentInput, AppEnvDto>
150
159
  delete: RpcProcedure<AppEnvironmentInput, OkResponse>
160
+ /** Human user principals with `access.approve` only, from the console (ADR-0050 §4). */
161
+ protect: RpcProcedure<SetEnvironmentProtectionRequest, AppEnvDto>
151
162
  }
152
163
  secrets: {
153
164
  list: RpcProcedure<AppIdInput, ListResponse<AppSecretDto>>
@@ -172,6 +183,8 @@ export interface ControlRpcContract {
172
183
  create: RpcProcedure<CreateDeploymentNamespaceRequest, DeploymentNamespaceDetailDto>
173
184
  adopt: RpcProcedure<AdoptNamespaceInput, DeploymentNamespaceDetailDto>
174
185
  reconcile: RpcProcedure<NamespaceIdInput, DeploymentNamespaceDetailDto>
186
+ /** Change a ready namespace in place, synchronously (backlog 79); also the retry after an unconfirmed update. */
187
+ update: RpcProcedure<UpdateNamespaceInput, DeploymentNamespaceDetailDto>
175
188
  /** Free a namespace id. Refused while any app environment is registered in it (backlog 73). */
176
189
  remove: RpcProcedure<NamespaceIdInput, RemoveDeploymentNamespaceResponse>
177
190
  }
@@ -182,6 +195,29 @@ export interface ControlRpcContract {
182
195
  tail: RpcProcedure<TailRunInput, RunTailResponse>
183
196
  cancel: RpcProcedure<RunIdInput, RunDto>
184
197
  }
198
+ /** Runs whose access change waits for a human (ADR-0050 §5), behind `access.approve`. */
199
+ approvals: {
200
+ list: RpcProcedure<void, ListResponse<ApprovalDto>>
201
+ get: RpcProcedure<RunIdInput, ApprovalDto>
202
+ /** A human user principal, from the console's own origin; no key, service or OAuth token completes one. */
203
+ complete: RpcProcedure<CompleteApprovalRequest, ApprovalDto>
204
+ }
185
205
  deploy: RpcProcedure<TriggerDeployRequest, RunDto>
186
206
  register: RpcProcedure<RegisterAppRequest, RegisterAppResponse>
207
+ /** What a consumer vendors (`fabrika connect add`): the export its owner's environment approved for it. */
208
+ connectors: {
209
+ describe: RpcProcedure<DescribeConnectorRequest, ExportDescription>
210
+ }
211
+ }
212
+
213
+ /**
214
+ * One export version of `app` as the environment `env` approved it, read for its consumer `consumer`. Unknown, not
215
+ * approved, or not exported to that consumer: 404 alike.
216
+ */
217
+ export interface DescribeConnectorRequest {
218
+ readonly consumer: string
219
+ readonly env: string
220
+ readonly app: string
221
+ readonly export: string
222
+ readonly version: number
187
223
  }