@company-semantics/contracts 92.0.0 → 93.1.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 (68) hide show
  1. package/package.json +13 -12
  2. package/src/__tests__/resource-keys.test.ts +1 -0
  3. package/src/action-items/README.md +12 -4
  4. package/src/action-items/schemas.ts +10 -0
  5. package/src/affordances/README.md +52 -1
  6. package/src/affordances/__tests__/README.md +10 -1
  7. package/src/affordances/__tests__/affordances.test.ts +13 -1
  8. package/src/affordances/__tests__/catalog-wave.test.ts +237 -0
  9. package/src/affordances/affordance.ts +56 -4
  10. package/src/affordances/args.ts +44 -1
  11. package/src/affordances/available.ts +59 -0
  12. package/src/affordances/coverage.ts +51 -0
  13. package/src/affordances/ids.ts +28 -0
  14. package/src/affordances/index.ts +17 -0
  15. package/src/api/README.md +1 -0
  16. package/src/api/generated-spec-hash.ts +2 -2
  17. package/src/api/generated.ts +506 -1
  18. package/src/api/primitives.ts +13 -0
  19. package/src/billing/README.md +1 -0
  20. package/src/billing/refusals.ts +12 -0
  21. package/src/chat/__tests__/page-context.test.ts +22 -43
  22. package/src/chat/__tests__/runtime-profile.test.ts +20 -44
  23. package/src/generated/openapi-routes.ts +1 -0
  24. package/src/message-parts/README.md +5 -0
  25. package/src/message-parts/affordance-offer.ts +44 -0
  26. package/src/message-parts/index.ts +7 -0
  27. package/src/message-parts/types.ts +7 -1
  28. package/src/message-parts/wire.ts +18 -0
  29. package/src/notifications/README.md +17 -3
  30. package/src/notifications/__tests__/README.md +4 -0
  31. package/src/notifications/__tests__/__snapshots__/render-snapshot.test.ts.snap +27 -25
  32. package/src/notifications/__tests__/fixtures.ts +7 -1
  33. package/src/notifications/__tests__/grounded-ctas.test.ts +103 -0
  34. package/src/notifications/__tests__/render-snapshot.test.ts +1 -1
  35. package/src/notifications/content.ts +9 -0
  36. package/src/notifications/kinds/billing-auto-recharge-failed.ts +4 -2
  37. package/src/notifications/kinds/billing-payment-past-due.ts +2 -0
  38. package/src/notifications/kinds/billing-suspended.ts +2 -0
  39. package/src/notifications/kinds/chat-shared.ts +10 -3
  40. package/src/notifications/kinds/company-md-access-approved.ts +13 -6
  41. package/src/notifications/kinds/share-granted.ts +1 -1
  42. package/src/notifications/kinds/unit-owner-granted.ts +9 -2
  43. package/src/notifications/payloads.ts +6 -0
  44. package/src/proactive/README.md +18 -2
  45. package/src/proactive/__tests__/README.md +11 -1
  46. package/src/proactive/__tests__/chat-templates.test.ts +7 -6
  47. package/src/proactive/__tests__/proactive-offers.test.ts +124 -0
  48. package/src/proactive/__tests__/vocabulary.test.ts +1 -1
  49. package/src/proactive/composer.ts +11 -0
  50. package/src/proactive/templates/README.md +11 -3
  51. package/src/proactive/templates/billing-auto-recharge-failed.ts +1 -0
  52. package/src/proactive/templates/billing-balance-exhausted.ts +2 -6
  53. package/src/proactive/templates/billing-payment-past-due.ts +1 -0
  54. package/src/proactive/templates/billing-subscription-canceled.ts +1 -5
  55. package/src/proactive/templates/billing-suspended.ts +1 -0
  56. package/src/proactive/templates/morning-brief.ts +1 -0
  57. package/src/proactive/templates/org-became-shared.ts +4 -3
  58. package/src/proactive/templates/source-sync-review-ready.ts +3 -8
  59. package/src/proactive/templates/workflow-needs-attention.ts +1 -0
  60. package/src/rate-limit/README.md +27 -1
  61. package/src/rate-limit/__tests__/README.md +23 -0
  62. package/src/rate-limit/__tests__/rate-limited-error.test.ts +53 -0
  63. package/src/rate-limit/index.ts +33 -0
  64. package/src/resource-key-tables.ts +1 -0
  65. package/src/resource-key-types.ts +3 -0
  66. package/src/resource-keys.ts +1 -0
  67. package/src/root-exports/agent-runtime.ts +14 -2
  68. package/src/root-exports/delivery.ts +15 -0
@@ -3911,6 +3911,23 @@ export interface paths {
3911
3911
  patch?: never;
3912
3912
  trace?: never;
3913
3913
  };
3914
+ "/api/factory/lineage": {
3915
+ parameters: {
3916
+ query?: never;
3917
+ header?: never;
3918
+ path?: never;
3919
+ cookie?: never;
3920
+ };
3921
+ /** Read change lineage: each release with its commits, PRDs, workers, run and health */
3922
+ get: operations["factoryLineage"];
3923
+ put?: never;
3924
+ post?: never;
3925
+ delete?: never;
3926
+ options?: never;
3927
+ head?: never;
3928
+ patch?: never;
3929
+ trace?: never;
3930
+ };
3914
3931
  "/api/factory/quality/changes": {
3915
3932
  parameters: {
3916
3933
  query?: never;
@@ -6893,6 +6910,13 @@ export interface components {
6893
6910
  requiredScope?: string;
6894
6911
  };
6895
6912
  };
6913
+ workspace?: {
6914
+ manageSettings: {
6915
+ /** @enum {string} */
6916
+ state: "allowed" | "blocked";
6917
+ requiredScope?: string;
6918
+ };
6919
+ };
6896
6920
  };
6897
6921
  chatMentions: boolean;
6898
6922
  chatMultiParty: boolean;
@@ -7161,6 +7185,63 @@ export interface components {
7161
7185
  } | {
7162
7186
  /** @constant */
7163
7187
  id: "hris.resyncDirectory";
7188
+ } | {
7189
+ /** @constant */
7190
+ id: "integrations.open";
7191
+ } | {
7192
+ /** @constant */
7193
+ id: "hris.connect";
7194
+ } | {
7195
+ /** @constant */
7196
+ id: "account.editProfile";
7197
+ } | {
7198
+ /** @constant */
7199
+ id: "workspace.openOrgSettings";
7200
+ } | {
7201
+ /** @constant */
7202
+ id: "sourceSync.addFile";
7203
+ } | {
7204
+ /** @constant */
7205
+ id: "sourceSync.openUpdate";
7206
+ args: {
7207
+ proposalId: string;
7208
+ };
7209
+ } | {
7210
+ /** @constant */
7211
+ id: "orgStructure.openReview";
7212
+ args: {
7213
+ proposalId: string;
7214
+ };
7215
+ } | {
7216
+ /** @constant */
7217
+ id: "chat.open";
7218
+ args: {
7219
+ chatId: string;
7220
+ };
7221
+ } | {
7222
+ /** @constant */
7223
+ id: "companyMd.openDoc";
7224
+ args: {
7225
+ docId: string;
7226
+ };
7227
+ } | {
7228
+ /** @constant */
7229
+ id: "companyMd.openHistory";
7230
+ args: {
7231
+ docId: string;
7232
+ };
7233
+ } | {
7234
+ /** @constant */
7235
+ id: "team.open";
7236
+ args: {
7237
+ unitId: string;
7238
+ };
7239
+ } | {
7240
+ /** @constant */
7241
+ id: "execution.open";
7242
+ args: {
7243
+ executionId: string;
7244
+ };
7164
7245
  })[];
7165
7246
  } | {
7166
7247
  /** @constant */
@@ -7202,6 +7283,63 @@ export interface components {
7202
7283
  } | {
7203
7284
  /** @constant */
7204
7285
  id: "hris.resyncDirectory";
7286
+ } | {
7287
+ /** @constant */
7288
+ id: "integrations.open";
7289
+ } | {
7290
+ /** @constant */
7291
+ id: "hris.connect";
7292
+ } | {
7293
+ /** @constant */
7294
+ id: "account.editProfile";
7295
+ } | {
7296
+ /** @constant */
7297
+ id: "workspace.openOrgSettings";
7298
+ } | {
7299
+ /** @constant */
7300
+ id: "sourceSync.addFile";
7301
+ } | {
7302
+ /** @constant */
7303
+ id: "sourceSync.openUpdate";
7304
+ args: {
7305
+ proposalId: string;
7306
+ };
7307
+ } | {
7308
+ /** @constant */
7309
+ id: "orgStructure.openReview";
7310
+ args: {
7311
+ proposalId: string;
7312
+ };
7313
+ } | {
7314
+ /** @constant */
7315
+ id: "chat.open";
7316
+ args: {
7317
+ chatId: string;
7318
+ };
7319
+ } | {
7320
+ /** @constant */
7321
+ id: "companyMd.openDoc";
7322
+ args: {
7323
+ docId: string;
7324
+ };
7325
+ } | {
7326
+ /** @constant */
7327
+ id: "companyMd.openHistory";
7328
+ args: {
7329
+ docId: string;
7330
+ };
7331
+ } | {
7332
+ /** @constant */
7333
+ id: "team.open";
7334
+ args: {
7335
+ unitId: string;
7336
+ };
7337
+ } | {
7338
+ /** @constant */
7339
+ id: "execution.open";
7340
+ args: {
7341
+ executionId: string;
7342
+ };
7205
7343
  })[];
7206
7344
  } | {
7207
7345
  /** @constant */
@@ -7245,6 +7383,63 @@ export interface components {
7245
7383
  } | {
7246
7384
  /** @constant */
7247
7385
  id: "hris.resyncDirectory";
7386
+ } | {
7387
+ /** @constant */
7388
+ id: "integrations.open";
7389
+ } | {
7390
+ /** @constant */
7391
+ id: "hris.connect";
7392
+ } | {
7393
+ /** @constant */
7394
+ id: "account.editProfile";
7395
+ } | {
7396
+ /** @constant */
7397
+ id: "workspace.openOrgSettings";
7398
+ } | {
7399
+ /** @constant */
7400
+ id: "sourceSync.addFile";
7401
+ } | {
7402
+ /** @constant */
7403
+ id: "sourceSync.openUpdate";
7404
+ args: {
7405
+ proposalId: string;
7406
+ };
7407
+ } | {
7408
+ /** @constant */
7409
+ id: "orgStructure.openReview";
7410
+ args: {
7411
+ proposalId: string;
7412
+ };
7413
+ } | {
7414
+ /** @constant */
7415
+ id: "chat.open";
7416
+ args: {
7417
+ chatId: string;
7418
+ };
7419
+ } | {
7420
+ /** @constant */
7421
+ id: "companyMd.openDoc";
7422
+ args: {
7423
+ docId: string;
7424
+ };
7425
+ } | {
7426
+ /** @constant */
7427
+ id: "companyMd.openHistory";
7428
+ args: {
7429
+ docId: string;
7430
+ };
7431
+ } | {
7432
+ /** @constant */
7433
+ id: "team.open";
7434
+ args: {
7435
+ unitId: string;
7436
+ };
7437
+ } | {
7438
+ /** @constant */
7439
+ id: "execution.open";
7440
+ args: {
7441
+ executionId: string;
7442
+ };
7248
7443
  })[];
7249
7444
  } | {
7250
7445
  /** @constant */
@@ -7288,6 +7483,63 @@ export interface components {
7288
7483
  } | {
7289
7484
  /** @constant */
7290
7485
  id: "hris.resyncDirectory";
7486
+ } | {
7487
+ /** @constant */
7488
+ id: "integrations.open";
7489
+ } | {
7490
+ /** @constant */
7491
+ id: "hris.connect";
7492
+ } | {
7493
+ /** @constant */
7494
+ id: "account.editProfile";
7495
+ } | {
7496
+ /** @constant */
7497
+ id: "workspace.openOrgSettings";
7498
+ } | {
7499
+ /** @constant */
7500
+ id: "sourceSync.addFile";
7501
+ } | {
7502
+ /** @constant */
7503
+ id: "sourceSync.openUpdate";
7504
+ args: {
7505
+ proposalId: string;
7506
+ };
7507
+ } | {
7508
+ /** @constant */
7509
+ id: "orgStructure.openReview";
7510
+ args: {
7511
+ proposalId: string;
7512
+ };
7513
+ } | {
7514
+ /** @constant */
7515
+ id: "chat.open";
7516
+ args: {
7517
+ chatId: string;
7518
+ };
7519
+ } | {
7520
+ /** @constant */
7521
+ id: "companyMd.openDoc";
7522
+ args: {
7523
+ docId: string;
7524
+ };
7525
+ } | {
7526
+ /** @constant */
7527
+ id: "companyMd.openHistory";
7528
+ args: {
7529
+ docId: string;
7530
+ };
7531
+ } | {
7532
+ /** @constant */
7533
+ id: "team.open";
7534
+ args: {
7535
+ unitId: string;
7536
+ };
7537
+ } | {
7538
+ /** @constant */
7539
+ id: "execution.open";
7540
+ args: {
7541
+ executionId: string;
7542
+ };
7291
7543
  })[];
7292
7544
  }) | null;
7293
7545
  error?: string;
@@ -7316,7 +7568,7 @@ export interface components {
7316
7568
  AffordanceStateResponse: {
7317
7569
  entries: {
7318
7570
  /** @enum {string} */
7319
- id: "sourceSync.findFiles" | "integrations.connectGoogleDrive" | "sourceSync.enable" | "billing.open" | "orgStructure.reanalyze" | "hris.resyncDirectory" | "review.open";
7571
+ id: "sourceSync.findFiles" | "integrations.connectGoogleDrive" | "sourceSync.enable" | "billing.open" | "orgStructure.reanalyze" | "hris.resyncDirectory" | "review.open" | "integrations.open" | "hris.connect" | "account.editProfile" | "workspace.openOrgSettings" | "sourceSync.addFile" | "sourceSync.openUpdate" | "orgStructure.openReview" | "chat.open" | "companyMd.openDoc" | "companyMd.openHistory" | "team.open" | "execution.open";
7320
7572
  /** @enum {string} */
7321
7573
  policy: "allowed" | "blocked";
7322
7574
  availability: {
@@ -8415,6 +8667,90 @@ export interface components {
8415
8667
  contextLabel: string;
8416
8668
  provider: string | null;
8417
8669
  href: string;
8670
+ affordance?: {
8671
+ /** @constant */
8672
+ id: "sourceSync.findFiles";
8673
+ } | {
8674
+ /** @constant */
8675
+ id: "integrations.connectGoogleDrive";
8676
+ } | {
8677
+ /** @constant */
8678
+ id: "sourceSync.enable";
8679
+ } | {
8680
+ /** @constant */
8681
+ id: "billing.open";
8682
+ } | {
8683
+ /** @constant */
8684
+ id: "orgStructure.reanalyze";
8685
+ } | {
8686
+ /** @constant */
8687
+ id: "hris.resyncDirectory";
8688
+ } | {
8689
+ /** @constant */
8690
+ id: "integrations.open";
8691
+ } | {
8692
+ /** @constant */
8693
+ id: "hris.connect";
8694
+ } | {
8695
+ /** @constant */
8696
+ id: "account.editProfile";
8697
+ } | {
8698
+ /** @constant */
8699
+ id: "workspace.openOrgSettings";
8700
+ } | {
8701
+ /** @constant */
8702
+ id: "sourceSync.addFile";
8703
+ } | {
8704
+ /** @constant */
8705
+ id: "sourceSync.openUpdate";
8706
+ args: {
8707
+ proposalId: string;
8708
+ };
8709
+ } | {
8710
+ /** @constant */
8711
+ id: "orgStructure.openReview";
8712
+ args: {
8713
+ proposalId: string;
8714
+ };
8715
+ } | {
8716
+ /** @constant */
8717
+ id: "chat.open";
8718
+ args: {
8719
+ chatId: string;
8720
+ };
8721
+ } | {
8722
+ /** @constant */
8723
+ id: "companyMd.openDoc";
8724
+ args: {
8725
+ docId: string;
8726
+ };
8727
+ } | {
8728
+ /** @constant */
8729
+ id: "companyMd.openHistory";
8730
+ args: {
8731
+ docId: string;
8732
+ };
8733
+ } | {
8734
+ /** @constant */
8735
+ id: "team.open";
8736
+ args: {
8737
+ unitId: string;
8738
+ };
8739
+ } | {
8740
+ /** @constant */
8741
+ id: "execution.open";
8742
+ args: {
8743
+ executionId: string;
8744
+ };
8745
+ } | {
8746
+ /** @constant */
8747
+ id: "review.open";
8748
+ args: {
8749
+ /** @enum {string} */
8750
+ requestType: "org-structure/review" | "source-sync/candidates" | "source-sync/synthesis";
8751
+ requestId: string;
8752
+ };
8753
+ };
8418
8754
  createdAt: string;
8419
8755
  }[];
8420
8756
  };
@@ -8437,6 +8773,90 @@ export interface components {
8437
8773
  contextLabel: string;
8438
8774
  provider: string | null;
8439
8775
  href: string;
8776
+ affordance?: {
8777
+ /** @constant */
8778
+ id: "sourceSync.findFiles";
8779
+ } | {
8780
+ /** @constant */
8781
+ id: "integrations.connectGoogleDrive";
8782
+ } | {
8783
+ /** @constant */
8784
+ id: "sourceSync.enable";
8785
+ } | {
8786
+ /** @constant */
8787
+ id: "billing.open";
8788
+ } | {
8789
+ /** @constant */
8790
+ id: "orgStructure.reanalyze";
8791
+ } | {
8792
+ /** @constant */
8793
+ id: "hris.resyncDirectory";
8794
+ } | {
8795
+ /** @constant */
8796
+ id: "integrations.open";
8797
+ } | {
8798
+ /** @constant */
8799
+ id: "hris.connect";
8800
+ } | {
8801
+ /** @constant */
8802
+ id: "account.editProfile";
8803
+ } | {
8804
+ /** @constant */
8805
+ id: "workspace.openOrgSettings";
8806
+ } | {
8807
+ /** @constant */
8808
+ id: "sourceSync.addFile";
8809
+ } | {
8810
+ /** @constant */
8811
+ id: "sourceSync.openUpdate";
8812
+ args: {
8813
+ proposalId: string;
8814
+ };
8815
+ } | {
8816
+ /** @constant */
8817
+ id: "orgStructure.openReview";
8818
+ args: {
8819
+ proposalId: string;
8820
+ };
8821
+ } | {
8822
+ /** @constant */
8823
+ id: "chat.open";
8824
+ args: {
8825
+ chatId: string;
8826
+ };
8827
+ } | {
8828
+ /** @constant */
8829
+ id: "companyMd.openDoc";
8830
+ args: {
8831
+ docId: string;
8832
+ };
8833
+ } | {
8834
+ /** @constant */
8835
+ id: "companyMd.openHistory";
8836
+ args: {
8837
+ docId: string;
8838
+ };
8839
+ } | {
8840
+ /** @constant */
8841
+ id: "team.open";
8842
+ args: {
8843
+ unitId: string;
8844
+ };
8845
+ } | {
8846
+ /** @constant */
8847
+ id: "execution.open";
8848
+ args: {
8849
+ executionId: string;
8850
+ };
8851
+ } | {
8852
+ /** @constant */
8853
+ id: "review.open";
8854
+ args: {
8855
+ /** @enum {string} */
8856
+ requestType: "org-structure/review" | "source-sync/candidates" | "source-sync/synthesis";
8857
+ requestId: string;
8858
+ };
8859
+ };
8440
8860
  createdAt: string;
8441
8861
  };
8442
8862
  } | {
@@ -8857,6 +9277,11 @@ export interface components {
8857
9277
  };
8858
9278
  eventTimestamp: string;
8859
9279
  }[];
9280
+ pausedAuth?: {
9281
+ since: string;
9282
+ lane: number;
9283
+ reason: string | null;
9284
+ } | null;
8860
9285
  }[];
8861
9286
  };
8862
9287
  FactorySnapshotResponse: {
@@ -8993,6 +9418,49 @@ export interface components {
8993
9418
  [key: string]: unknown;
8994
9419
  } | null;
8995
9420
  };
9421
+ FactoryLineageResponse: {
9422
+ releases: {
9423
+ key: string;
9424
+ manifestId: string | null;
9425
+ stationId: string;
9426
+ /** @enum {string} */
9427
+ status: "in_progress" | "applied" | "rolled_back";
9428
+ intendedAt: string | null;
9429
+ appliedAt: string | null;
9430
+ durationMs: number | null;
9431
+ surfaces: string[];
9432
+ shas: {
9433
+ [key: string]: string;
9434
+ } | null;
9435
+ run: {
9436
+ id: string;
9437
+ attempt: number;
9438
+ repository: string;
9439
+ url: string;
9440
+ } | null;
9441
+ health: {
9442
+ /** @enum {string} */
9443
+ releaseInvariant: "ok" | "failed" | "unproven" | "unknown";
9444
+ /** @enum {string} */
9445
+ windowMetric: "ok" | "failed" | "unproven" | "unknown";
9446
+ /** @enum {string} */
9447
+ pointProbe: "ok" | "failed" | "unproven" | "unknown";
9448
+ rolledBack: boolean;
9449
+ } | null;
9450
+ commitsRecorded: boolean;
9451
+ changesTruncated: boolean;
9452
+ changes: {
9453
+ repo: string;
9454
+ sha: string;
9455
+ prdId: string | null;
9456
+ pr: number | null;
9457
+ worker: {
9458
+ stationId: string;
9459
+ executorId: string;
9460
+ } | null;
9461
+ }[];
9462
+ }[];
9463
+ };
8996
9464
  CreateQualityChangeResponse: {
8997
9465
  /** Format: uuid */
8998
9466
  planId: string;
@@ -17501,6 +17969,43 @@ export interface operations {
17501
17969
  };
17502
17970
  };
17503
17971
  };
17972
+ factoryLineage: {
17973
+ parameters: {
17974
+ query?: {
17975
+ limit?: number;
17976
+ prdId?: string;
17977
+ };
17978
+ header?: never;
17979
+ path?: never;
17980
+ cookie?: never;
17981
+ };
17982
+ requestBody?: never;
17983
+ responses: {
17984
+ /** @description Lineage records, newest release first */
17985
+ 200: {
17986
+ headers: {
17987
+ [name: string]: unknown;
17988
+ };
17989
+ content: {
17990
+ "application/json": components["schemas"]["FactoryLineageResponse"];
17991
+ };
17992
+ };
17993
+ /** @description Not authenticated */
17994
+ 401: {
17995
+ headers: {
17996
+ [name: string]: unknown;
17997
+ };
17998
+ content?: never;
17999
+ };
18000
+ /** @description Not an internal admin */
18001
+ 403: {
18002
+ headers: {
18003
+ [name: string]: unknown;
18004
+ };
18005
+ content?: never;
18006
+ };
18007
+ };
18008
+ };
17504
18009
  createQualityChange: {
17505
18010
  parameters: {
17506
18011
  query?: never;
@@ -1,5 +1,10 @@
1
1
  import { z } from "zod";
2
2
 
3
+ import {
4
+ AffordanceSchema,
5
+ MAX_OFFERED_AFFORDANCES,
6
+ } from "../affordances/affordance";
7
+
3
8
  /** Generic factory for cursor-paginated responses. */
4
9
  export function CursorPageSchema<T extends z.ZodTypeAny>(itemSchema: T) {
5
10
  return z.object({
@@ -15,6 +20,14 @@ export const ErrorResponseSchema = z.object({
15
20
  code: z.string(),
16
21
  message: z.string(),
17
22
  retryable: z.boolean(),
23
+ /**
24
+ * The catalog affordances that resolve this error, when any do (control ADR
25
+ * affordance-system) — e.g. billing.open on a billing refusal for a viewer
26
+ * who may open billing. Present only when non-empty; the message states the
27
+ * fact and never tells the reader what to do.
28
+ */
29
+ // prettier-ignore
30
+ affordances: z.array(AffordanceSchema).min(1).max(MAX_OFFERED_AFFORDANCES).optional(),
18
31
  }),
19
32
  });
20
33
 
@@ -221,6 +221,7 @@ owner is always its owner contradicts ADR-BE-296, and nothing imported them.
221
221
 
222
222
  **Internal domains:**
223
223
 
224
+ - `affordances`
224
225
  - `api`
225
226
 
226
227
  **External packages:**
@@ -40,6 +40,11 @@
40
40
  */
41
41
  import { z } from "zod";
42
42
 
43
+ import {
44
+ AffordanceSchema,
45
+ MAX_OFFERED_AFFORDANCES,
46
+ } from "../affordances/affordance";
47
+
43
48
  import { type AiPauseReason } from "./vocabulary";
44
49
 
45
50
  /* -------------------------------------------------------------------------- */
@@ -216,5 +221,12 @@ export const BillingRefusalPartSchema = z
216
221
  orgId: z.string(),
217
222
  /** Whether retrying the same turn could succeed once the cause clears. */
218
223
  retryable: z.boolean(),
224
+ /**
225
+ * The catalog affordances that resolve the refusal for this viewer (control
226
+ * ADR affordance-system), e.g. billing.open. Present only when non-empty;
227
+ * the app renders them as controls beside the code's fact.
228
+ */
229
+ // prettier-ignore
230
+ affordances: z.array(AffordanceSchema).min(1).max(MAX_OFFERED_AFFORDANCES).optional(),
219
231
  })
220
232
  .strict();