@company-semantics/contracts 91.1.0 → 93.0.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 +11 -10
  2. package/src/action-items/README.md +12 -4
  3. package/src/action-items/schemas.ts +10 -0
  4. package/src/affordances/README.md +52 -1
  5. package/src/affordances/__tests__/README.md +10 -1
  6. package/src/affordances/__tests__/affordances.test.ts +13 -1
  7. package/src/affordances/__tests__/catalog-wave.test.ts +237 -0
  8. package/src/affordances/affordance.ts +56 -4
  9. package/src/affordances/args.ts +44 -1
  10. package/src/affordances/available.ts +59 -0
  11. package/src/affordances/coverage.ts +51 -0
  12. package/src/affordances/ids.ts +28 -0
  13. package/src/affordances/index.ts +17 -0
  14. package/src/api/README.md +1 -0
  15. package/src/api/generated-spec-hash.ts +2 -2
  16. package/src/api/generated.ts +401 -11
  17. package/src/api/primitives.ts +13 -0
  18. package/src/billing/README.md +1 -0
  19. package/src/billing/refusals.ts +12 -0
  20. package/src/message-parts/README.md +5 -0
  21. package/src/message-parts/affordance-offer.ts +44 -0
  22. package/src/message-parts/index.ts +7 -0
  23. package/src/message-parts/types.ts +7 -1
  24. package/src/message-parts/wire.ts +18 -0
  25. package/src/notifications/README.md +17 -3
  26. package/src/notifications/__tests__/README.md +4 -0
  27. package/src/notifications/__tests__/__snapshots__/render-snapshot.test.ts.snap +27 -25
  28. package/src/notifications/__tests__/fixtures.ts +7 -1
  29. package/src/notifications/__tests__/grounded-ctas.test.ts +103 -0
  30. package/src/notifications/__tests__/render-snapshot.test.ts +1 -1
  31. package/src/notifications/content.ts +9 -0
  32. package/src/notifications/kinds/billing-auto-recharge-failed.ts +4 -2
  33. package/src/notifications/kinds/billing-payment-past-due.ts +2 -0
  34. package/src/notifications/kinds/billing-suspended.ts +2 -0
  35. package/src/notifications/kinds/chat-shared.ts +10 -3
  36. package/src/notifications/kinds/company-md-access-approved.ts +13 -6
  37. package/src/notifications/kinds/share-granted.ts +1 -1
  38. package/src/notifications/kinds/unit-owner-granted.ts +9 -2
  39. package/src/notifications/payloads.ts +6 -0
  40. package/src/proactive/README.md +18 -2
  41. package/src/proactive/__tests__/README.md +11 -1
  42. package/src/proactive/__tests__/chat-templates.test.ts +7 -6
  43. package/src/proactive/__tests__/proactive-offers.test.ts +124 -0
  44. package/src/proactive/__tests__/vocabulary.test.ts +1 -1
  45. package/src/proactive/composer.ts +11 -0
  46. package/src/proactive/templates/README.md +11 -3
  47. package/src/proactive/templates/billing-auto-recharge-failed.ts +1 -0
  48. package/src/proactive/templates/billing-balance-exhausted.ts +2 -6
  49. package/src/proactive/templates/billing-payment-past-due.ts +1 -0
  50. package/src/proactive/templates/billing-subscription-canceled.ts +1 -5
  51. package/src/proactive/templates/billing-suspended.ts +1 -0
  52. package/src/proactive/templates/morning-brief.ts +1 -0
  53. package/src/proactive/templates/org-became-shared.ts +4 -3
  54. package/src/proactive/templates/source-sync-review-ready.ts +3 -8
  55. package/src/proactive/templates/workflow-needs-attention.ts +1 -0
  56. package/src/rate-limit/README.md +27 -1
  57. package/src/rate-limit/__tests__/README.md +23 -0
  58. package/src/rate-limit/__tests__/rate-limited-error.test.ts +53 -0
  59. package/src/rate-limit/index.ts +33 -0
  60. package/src/root-exports/agent-runtime.ts +14 -2
  61. package/src/root-exports/delivery.ts +15 -0
  62. package/src/source-sync/README.md +2 -1
  63. package/src/source-sync/__tests__/approval-schemas.test.ts +2 -13
  64. package/src/source-sync/__tests__/current-synthesis.test.ts +1 -0
  65. package/src/source-sync/__tests__/schemas.test.ts +5 -32
  66. package/src/source-sync/schemas.ts +6 -15
  67. package/src/workflows/deferred-route.ts +2 -0
  68. package/src/workflows/outcome-reasons.ts +4 -0
@@ -4936,7 +4936,7 @@ export interface paths {
4936
4936
  put?: never;
4937
4937
  /**
4938
4938
  * Approve the draft candidate set as reviewed, per scope
4939
- * @description Approves the named scopes (or every scope still open) at the revision the person reviewed. Per scope, the items freeze, a hash binds them to that scope’s share of the spending cap, and a landing job is scheduled on one landing-and-synthesis workflow.
4939
+ * @description Approves the named scopes (or every scope still open) at the revision the person reviewed. Per scope, the items freeze, a hash binds the approval to exactly those files and treatments, and a landing job is scheduled on one landing-and-synthesis workflow. Approval authorizes the revision only; it carries no spend.
4940
4940
  */
4941
4941
  post: operations["approveSourceCandidateSet"];
4942
4942
  delete?: never;
@@ -7161,6 +7161,63 @@ export interface components {
7161
7161
  } | {
7162
7162
  /** @constant */
7163
7163
  id: "hris.resyncDirectory";
7164
+ } | {
7165
+ /** @constant */
7166
+ id: "integrations.open";
7167
+ } | {
7168
+ /** @constant */
7169
+ id: "hris.connect";
7170
+ } | {
7171
+ /** @constant */
7172
+ id: "account.editProfile";
7173
+ } | {
7174
+ /** @constant */
7175
+ id: "workspace.openOrgSettings";
7176
+ } | {
7177
+ /** @constant */
7178
+ id: "sourceSync.addFile";
7179
+ } | {
7180
+ /** @constant */
7181
+ id: "sourceSync.openUpdate";
7182
+ args: {
7183
+ proposalId: string;
7184
+ };
7185
+ } | {
7186
+ /** @constant */
7187
+ id: "orgStructure.openReview";
7188
+ args: {
7189
+ proposalId: string;
7190
+ };
7191
+ } | {
7192
+ /** @constant */
7193
+ id: "chat.open";
7194
+ args: {
7195
+ chatId: string;
7196
+ };
7197
+ } | {
7198
+ /** @constant */
7199
+ id: "companyMd.openDoc";
7200
+ args: {
7201
+ docId: string;
7202
+ };
7203
+ } | {
7204
+ /** @constant */
7205
+ id: "companyMd.openHistory";
7206
+ args: {
7207
+ docId: string;
7208
+ };
7209
+ } | {
7210
+ /** @constant */
7211
+ id: "team.open";
7212
+ args: {
7213
+ unitId: string;
7214
+ };
7215
+ } | {
7216
+ /** @constant */
7217
+ id: "execution.open";
7218
+ args: {
7219
+ executionId: string;
7220
+ };
7164
7221
  })[];
7165
7222
  } | {
7166
7223
  /** @constant */
@@ -7169,7 +7226,7 @@ export interface components {
7169
7226
  /** @enum {string} */
7170
7227
  kind: "produced" | "empty" | "partial" | "stopped" | "failed" | "abandoned" | "unknown";
7171
7228
  /** @enum {string} */
7172
- reason: "updates_ready" | "updates_applied" | "stopped_by_user" | "paused_billing" | "synthesis_incomplete" | "approval_mismatch" | "landing_refused" | "standing_order_refused" | "no_connection" | "source_sync_off" | "internal_error" | "abandoned" | "unrecognized_terminal_state";
7229
+ reason: "updates_ready" | "updates_applied" | "stopped_by_user" | "paused_billing" | "run_ceiling_reached" | "pricing_unconfigured" | "synthesis_incomplete" | "approval_mismatch" | "landing_refused" | "standing_order_refused" | "no_connection" | "source_sync_off" | "internal_error" | "abandoned" | "unrecognized_terminal_state";
7173
7230
  facts: {
7174
7231
  scopeCount: number;
7175
7232
  violationCount: number;
@@ -7202,6 +7259,63 @@ export interface components {
7202
7259
  } | {
7203
7260
  /** @constant */
7204
7261
  id: "hris.resyncDirectory";
7262
+ } | {
7263
+ /** @constant */
7264
+ id: "integrations.open";
7265
+ } | {
7266
+ /** @constant */
7267
+ id: "hris.connect";
7268
+ } | {
7269
+ /** @constant */
7270
+ id: "account.editProfile";
7271
+ } | {
7272
+ /** @constant */
7273
+ id: "workspace.openOrgSettings";
7274
+ } | {
7275
+ /** @constant */
7276
+ id: "sourceSync.addFile";
7277
+ } | {
7278
+ /** @constant */
7279
+ id: "sourceSync.openUpdate";
7280
+ args: {
7281
+ proposalId: string;
7282
+ };
7283
+ } | {
7284
+ /** @constant */
7285
+ id: "orgStructure.openReview";
7286
+ args: {
7287
+ proposalId: string;
7288
+ };
7289
+ } | {
7290
+ /** @constant */
7291
+ id: "chat.open";
7292
+ args: {
7293
+ chatId: string;
7294
+ };
7295
+ } | {
7296
+ /** @constant */
7297
+ id: "companyMd.openDoc";
7298
+ args: {
7299
+ docId: string;
7300
+ };
7301
+ } | {
7302
+ /** @constant */
7303
+ id: "companyMd.openHistory";
7304
+ args: {
7305
+ docId: string;
7306
+ };
7307
+ } | {
7308
+ /** @constant */
7309
+ id: "team.open";
7310
+ args: {
7311
+ unitId: string;
7312
+ };
7313
+ } | {
7314
+ /** @constant */
7315
+ id: "execution.open";
7316
+ args: {
7317
+ executionId: string;
7318
+ };
7205
7319
  })[];
7206
7320
  } | {
7207
7321
  /** @constant */
@@ -7245,6 +7359,63 @@ export interface components {
7245
7359
  } | {
7246
7360
  /** @constant */
7247
7361
  id: "hris.resyncDirectory";
7362
+ } | {
7363
+ /** @constant */
7364
+ id: "integrations.open";
7365
+ } | {
7366
+ /** @constant */
7367
+ id: "hris.connect";
7368
+ } | {
7369
+ /** @constant */
7370
+ id: "account.editProfile";
7371
+ } | {
7372
+ /** @constant */
7373
+ id: "workspace.openOrgSettings";
7374
+ } | {
7375
+ /** @constant */
7376
+ id: "sourceSync.addFile";
7377
+ } | {
7378
+ /** @constant */
7379
+ id: "sourceSync.openUpdate";
7380
+ args: {
7381
+ proposalId: string;
7382
+ };
7383
+ } | {
7384
+ /** @constant */
7385
+ id: "orgStructure.openReview";
7386
+ args: {
7387
+ proposalId: string;
7388
+ };
7389
+ } | {
7390
+ /** @constant */
7391
+ id: "chat.open";
7392
+ args: {
7393
+ chatId: string;
7394
+ };
7395
+ } | {
7396
+ /** @constant */
7397
+ id: "companyMd.openDoc";
7398
+ args: {
7399
+ docId: string;
7400
+ };
7401
+ } | {
7402
+ /** @constant */
7403
+ id: "companyMd.openHistory";
7404
+ args: {
7405
+ docId: string;
7406
+ };
7407
+ } | {
7408
+ /** @constant */
7409
+ id: "team.open";
7410
+ args: {
7411
+ unitId: string;
7412
+ };
7413
+ } | {
7414
+ /** @constant */
7415
+ id: "execution.open";
7416
+ args: {
7417
+ executionId: string;
7418
+ };
7248
7419
  })[];
7249
7420
  } | {
7250
7421
  /** @constant */
@@ -7288,6 +7459,63 @@ export interface components {
7288
7459
  } | {
7289
7460
  /** @constant */
7290
7461
  id: "hris.resyncDirectory";
7462
+ } | {
7463
+ /** @constant */
7464
+ id: "integrations.open";
7465
+ } | {
7466
+ /** @constant */
7467
+ id: "hris.connect";
7468
+ } | {
7469
+ /** @constant */
7470
+ id: "account.editProfile";
7471
+ } | {
7472
+ /** @constant */
7473
+ id: "workspace.openOrgSettings";
7474
+ } | {
7475
+ /** @constant */
7476
+ id: "sourceSync.addFile";
7477
+ } | {
7478
+ /** @constant */
7479
+ id: "sourceSync.openUpdate";
7480
+ args: {
7481
+ proposalId: string;
7482
+ };
7483
+ } | {
7484
+ /** @constant */
7485
+ id: "orgStructure.openReview";
7486
+ args: {
7487
+ proposalId: string;
7488
+ };
7489
+ } | {
7490
+ /** @constant */
7491
+ id: "chat.open";
7492
+ args: {
7493
+ chatId: string;
7494
+ };
7495
+ } | {
7496
+ /** @constant */
7497
+ id: "companyMd.openDoc";
7498
+ args: {
7499
+ docId: string;
7500
+ };
7501
+ } | {
7502
+ /** @constant */
7503
+ id: "companyMd.openHistory";
7504
+ args: {
7505
+ docId: string;
7506
+ };
7507
+ } | {
7508
+ /** @constant */
7509
+ id: "team.open";
7510
+ args: {
7511
+ unitId: string;
7512
+ };
7513
+ } | {
7514
+ /** @constant */
7515
+ id: "execution.open";
7516
+ args: {
7517
+ executionId: string;
7518
+ };
7291
7519
  })[];
7292
7520
  }) | null;
7293
7521
  error?: string;
@@ -7316,7 +7544,7 @@ export interface components {
7316
7544
  AffordanceStateResponse: {
7317
7545
  entries: {
7318
7546
  /** @enum {string} */
7319
- id: "sourceSync.findFiles" | "integrations.connectGoogleDrive" | "sourceSync.enable" | "billing.open" | "orgStructure.reanalyze" | "hris.resyncDirectory" | "review.open";
7547
+ 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
7548
  /** @enum {string} */
7321
7549
  policy: "allowed" | "blocked";
7322
7550
  availability: {
@@ -8415,6 +8643,90 @@ export interface components {
8415
8643
  contextLabel: string;
8416
8644
  provider: string | null;
8417
8645
  href: string;
8646
+ affordance?: {
8647
+ /** @constant */
8648
+ id: "sourceSync.findFiles";
8649
+ } | {
8650
+ /** @constant */
8651
+ id: "integrations.connectGoogleDrive";
8652
+ } | {
8653
+ /** @constant */
8654
+ id: "sourceSync.enable";
8655
+ } | {
8656
+ /** @constant */
8657
+ id: "billing.open";
8658
+ } | {
8659
+ /** @constant */
8660
+ id: "orgStructure.reanalyze";
8661
+ } | {
8662
+ /** @constant */
8663
+ id: "hris.resyncDirectory";
8664
+ } | {
8665
+ /** @constant */
8666
+ id: "integrations.open";
8667
+ } | {
8668
+ /** @constant */
8669
+ id: "hris.connect";
8670
+ } | {
8671
+ /** @constant */
8672
+ id: "account.editProfile";
8673
+ } | {
8674
+ /** @constant */
8675
+ id: "workspace.openOrgSettings";
8676
+ } | {
8677
+ /** @constant */
8678
+ id: "sourceSync.addFile";
8679
+ } | {
8680
+ /** @constant */
8681
+ id: "sourceSync.openUpdate";
8682
+ args: {
8683
+ proposalId: string;
8684
+ };
8685
+ } | {
8686
+ /** @constant */
8687
+ id: "orgStructure.openReview";
8688
+ args: {
8689
+ proposalId: string;
8690
+ };
8691
+ } | {
8692
+ /** @constant */
8693
+ id: "chat.open";
8694
+ args: {
8695
+ chatId: string;
8696
+ };
8697
+ } | {
8698
+ /** @constant */
8699
+ id: "companyMd.openDoc";
8700
+ args: {
8701
+ docId: string;
8702
+ };
8703
+ } | {
8704
+ /** @constant */
8705
+ id: "companyMd.openHistory";
8706
+ args: {
8707
+ docId: string;
8708
+ };
8709
+ } | {
8710
+ /** @constant */
8711
+ id: "team.open";
8712
+ args: {
8713
+ unitId: string;
8714
+ };
8715
+ } | {
8716
+ /** @constant */
8717
+ id: "execution.open";
8718
+ args: {
8719
+ executionId: string;
8720
+ };
8721
+ } | {
8722
+ /** @constant */
8723
+ id: "review.open";
8724
+ args: {
8725
+ /** @enum {string} */
8726
+ requestType: "org-structure/review" | "source-sync/candidates" | "source-sync/synthesis";
8727
+ requestId: string;
8728
+ };
8729
+ };
8418
8730
  createdAt: string;
8419
8731
  }[];
8420
8732
  };
@@ -8437,6 +8749,90 @@ export interface components {
8437
8749
  contextLabel: string;
8438
8750
  provider: string | null;
8439
8751
  href: string;
8752
+ affordance?: {
8753
+ /** @constant */
8754
+ id: "sourceSync.findFiles";
8755
+ } | {
8756
+ /** @constant */
8757
+ id: "integrations.connectGoogleDrive";
8758
+ } | {
8759
+ /** @constant */
8760
+ id: "sourceSync.enable";
8761
+ } | {
8762
+ /** @constant */
8763
+ id: "billing.open";
8764
+ } | {
8765
+ /** @constant */
8766
+ id: "orgStructure.reanalyze";
8767
+ } | {
8768
+ /** @constant */
8769
+ id: "hris.resyncDirectory";
8770
+ } | {
8771
+ /** @constant */
8772
+ id: "integrations.open";
8773
+ } | {
8774
+ /** @constant */
8775
+ id: "hris.connect";
8776
+ } | {
8777
+ /** @constant */
8778
+ id: "account.editProfile";
8779
+ } | {
8780
+ /** @constant */
8781
+ id: "workspace.openOrgSettings";
8782
+ } | {
8783
+ /** @constant */
8784
+ id: "sourceSync.addFile";
8785
+ } | {
8786
+ /** @constant */
8787
+ id: "sourceSync.openUpdate";
8788
+ args: {
8789
+ proposalId: string;
8790
+ };
8791
+ } | {
8792
+ /** @constant */
8793
+ id: "orgStructure.openReview";
8794
+ args: {
8795
+ proposalId: string;
8796
+ };
8797
+ } | {
8798
+ /** @constant */
8799
+ id: "chat.open";
8800
+ args: {
8801
+ chatId: string;
8802
+ };
8803
+ } | {
8804
+ /** @constant */
8805
+ id: "companyMd.openDoc";
8806
+ args: {
8807
+ docId: string;
8808
+ };
8809
+ } | {
8810
+ /** @constant */
8811
+ id: "companyMd.openHistory";
8812
+ args: {
8813
+ docId: string;
8814
+ };
8815
+ } | {
8816
+ /** @constant */
8817
+ id: "team.open";
8818
+ args: {
8819
+ unitId: string;
8820
+ };
8821
+ } | {
8822
+ /** @constant */
8823
+ id: "execution.open";
8824
+ args: {
8825
+ executionId: string;
8826
+ };
8827
+ } | {
8828
+ /** @constant */
8829
+ id: "review.open";
8830
+ args: {
8831
+ /** @enum {string} */
8832
+ requestType: "org-structure/review" | "source-sync/candidates" | "source-sync/synthesis";
8833
+ requestId: string;
8834
+ };
8835
+ };
8440
8836
  createdAt: string;
8441
8837
  };
8442
8838
  } | {
@@ -9829,11 +10225,6 @@ export interface components {
9829
10225
  } | null;
9830
10226
  approvedAt: string | null;
9831
10227
  }[];
9832
- estimate: {
9833
- lowMicroUsd: string;
9834
- highMicroUsd: string;
9835
- capMicroUsd: string;
9836
- } | null;
9837
10228
  discovery: {
9838
10229
  foundThisRun: number;
9839
10230
  retainedDecisions: number;
@@ -9909,7 +10300,7 @@ export interface components {
9909
10300
  workflowId: string;
9910
10301
  batchId: string | null;
9911
10302
  /** @enum {string} */
9912
- phase: "landing" | "drafting" | "waiting_for_review" | "paused_billing" | "applied" | "applied_partial" | "failed" | "closed";
10303
+ phase: "landing" | "drafting" | "waiting_for_review" | "paused_billing" | "paused_ceiling" | "applied" | "applied_partial" | "failed" | "closed";
9913
10304
  fileCount: number | null;
9914
10305
  proposedDocumentCount: number;
9915
10306
  appliedAt: string | null;
@@ -19984,7 +20375,6 @@ export interface operations {
19984
20375
  content: {
19985
20376
  "application/json": {
19986
20377
  revision: number;
19987
- spendCapMicroUsd: string;
19988
20378
  scopeKeys?: string[];
19989
20379
  };
19990
20380
  };
@@ -19999,7 +20389,7 @@ export interface operations {
19999
20389
  "application/json": components["schemas"]["SourceSyncApproveResponse"];
20000
20390
  };
20001
20391
  };
20002
- /** @description Invalid request, a scope with no files (SOURCE_SYNC_SCOPE_UNKNOWN), or a cap too large to hold exactly (SOURCE_SYNC_SPEND_CAP_INVALID) */
20392
+ /** @description Invalid request (an unknown field such as a spend cap is refused by the schema), or a scope with no files (SOURCE_SYNC_SCOPE_UNKNOWN) */
20003
20393
  400: {
20004
20394
  headers: {
20005
20395
  [name: string]: unknown;
@@ -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();
@@ -17,6 +17,7 @@ Canonical vocabulary for structured assistant message output. Defines the type s
17
17
  - `SuggestedRepliesPart` is a surface but NOT a governed one: a chip fires an ordinary user turn (no `executionId`, no `submitEndpoint`), is stateless (clicking never consumes it) and advisory (the composer stays enabled) — so it is outside the at-most-one-governed-surface-per-turn rule
18
18
  - `WorkflowProgressPart` is the second non-governed surface: a two-field ANCHOR (`workflowId`, `workflowType`) to a durable background workflow. It presents no decision, carries no result snapshot (minted at t=0; parts are never rewritten) and no `startedAt` (operational state stays off immutable content), and names no domain vocabulary — live state is hydrated from the generic workflow projection read
19
19
  - `InputRequestPart` (`data-input-request` on the wire) is the GENERIC, GOVERNED anchor for a reviewed request: `{ requestType, requestId, stepCount, withheldCount }`, with every invariant of the structure-review anchor (anchor only — no cards, no endpoints, no staleness hashes; counts against the at-most-one-governed-surface-per-turn rule; emission is orchestration-driven). `isInputRequestDataPartShape` checks `requestType` as a non-empty string, NOT as a member of `INPUT_REQUEST_TYPES`: an unknown type renders nothing but never invalidates a persisted part
20
+ - `AffordanceOfferPart` (`data-affordance-offer` on the wire) is the fourth non-governed surface: the next steps a pushed chat OFFERS, frozen with it as `OfferedAffordance` instances (control ADR `affordance-system`). Ids and args only — never labels, hrefs or a projected id (`review.open`), at most `MAX_OFFERED_AFFORDANCES`; written once with its message and never re-derived; the app renders each as a real control, re-gated per viewer. Built by `WireSurfaceBuilder.affordanceOffer`; emission is orchestration-driven (the proactive chat writer), never a model choice
20
21
  - `StructureReviewPart` (`data-structure-review`) is FROZEN, not retired: it stays in `SurfacePart` and parses forever because persisted transcripts carry it, and org-structure keeps emitting it
21
22
 
22
23
  <!-- BEGIN GENERATED: readme-public-api — derived from code by `pnpm readme-api`. Do not edit. -->
@@ -24,6 +25,9 @@ Canonical vocabulary for structured assistant message output. Defines the type s
24
25
  ## Public API
25
26
 
26
27
  - `AddPartResult` _(type)_ — Result of adding a part to the builder.
28
+ - `AffordanceOfferData` _(type)_ — Affordance offer data payload: the frozen, ordered offer.
29
+ - `AffordanceOfferDataPart` _(type)_ — Affordance offer data part (wire format, as persisted in `chat_messages.parts`).
30
+ - `AffordanceOfferPart` _(type)_ — Affordance offer message part (semantic type, as rendered).
27
31
  - `AssistantMessagePart` _(type)_ — All assistant message part types.
28
32
  - `CONFIRMATION_LABELS` — Human-readable confirmation dialog titles for each execution kind.
29
33
  - `CandidateSource` _(type)_ — How the frontend sources candidate values for an editable field. - `inline`: the options are shipped with the…
@@ -116,6 +120,7 @@ Canonical vocabulary for structured assistant message output. Defines the type s
116
120
 
117
121
  **Internal domains:**
118
122
 
123
+ - `affordances`
119
124
  - `chat`
120
125
  - `execution`
121
126
  - `input-requests`
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Affordance Offer Part Types
3
+ *
4
+ * The next steps a message OFFERS, frozen with it (control ADR
5
+ * affordance-system). A pushed proactive chat carries its composer's
6
+ * `affordances` here so the app renders them as real controls — re-gated per
7
+ * viewer at render, live availability read separately, executed only by the
8
+ * server — instead of as chips that merely send a prompt.
9
+ *
10
+ * AFFORDANCE OFFER INVARIANTS:
11
+ * - OFFERED INSTANCES ONLY. Ids and their args, never labels or hrefs (the app
12
+ * owns both), never a projected id (`review.open`), at most
13
+ * MAX_OFFERED_AFFORDANCES.
14
+ * - WRITTEN ONCE, with the message it belongs to; never re-derived.
15
+ * - SHARE-SAFE. Ids and opaque target ids only.
16
+ * - NON-GOVERNED. It presents no decision and consumes no surface budget.
17
+ * - Emission is orchestration-driven (the proactive chat writer), never a model
18
+ * choice.
19
+ *
20
+ * Purely additive: an app that predates this part normalizes unknown part
21
+ * types to null and drops it.
22
+ */
23
+
24
+ import type { OfferedAffordance } from "../affordances/affordance";
25
+
26
+ /** Affordance offer data payload: the frozen, ordered offer. */
27
+ export interface AffordanceOfferData {
28
+ affordances: readonly OfferedAffordance[];
29
+ }
30
+
31
+ /** Affordance offer message part (semantic type, as rendered). */
32
+ export interface AffordanceOfferPart {
33
+ type: "affordance-offer";
34
+ data: AffordanceOfferData;
35
+ }
36
+
37
+ /**
38
+ * Affordance offer data part (wire format, as persisted in
39
+ * `chat_messages.parts`). Uses AI SDK's data-{name} convention.
40
+ */
41
+ export interface AffordanceOfferDataPart {
42
+ type: "data-affordance-offer";
43
+ data: AffordanceOfferData;
44
+ }
@@ -97,6 +97,13 @@ export type {
97
97
  WorkflowOutcomeDataPart,
98
98
  } from "./workflow-outcome";
99
99
 
100
+ // Affordance offer types (non-governed, the frozen offer on a pushed chat)
101
+ export type {
102
+ AffordanceOfferData,
103
+ AffordanceOfferPart,
104
+ AffordanceOfferDataPart,
105
+ } from "./affordance-offer";
106
+
100
107
  // Execution result types
101
108
  export type {
102
109
  ExecutionArtifactStatus,
@@ -22,6 +22,7 @@ import type { InputRequestPart } from "./input-request";
22
22
  import type { SuggestedRepliesPart } from "./suggested-replies";
23
23
  import type { WorkflowProgressPart } from "./workflow-progress";
24
24
  import type { WorkflowOutcomePart } from "./workflow-outcome";
25
+ import type { AffordanceOfferPart } from "./affordance-offer";
25
26
 
26
27
  // =============================================================================
27
28
  // Narrative Parts (Streamable)
@@ -130,6 +131,10 @@ export interface TablePart {
130
131
  * workflow's execution epoch, carried on its settlement message. It presents no
131
132
  * decision; a review disposition is delivered as its own InputRequestPart.
132
133
  *
134
+ * AffordanceOfferPart is the fourth non-governed member: the next steps a pushed
135
+ * chat offers, frozen with it as affordance instances (control ADR
136
+ * affordance-system). It presents no decision and consumes no surface budget.
137
+ *
133
138
  * InputRequestPart is GOVERNED, like StructureReviewPart: it anchors a reviewed
134
139
  * request that asks the person to decide, so it counts against the
135
140
  * at-most-one-governed-surface-per-turn budget. It is the generic anchor;
@@ -148,7 +153,8 @@ export type SurfacePart =
148
153
  | InputRequestPart
149
154
  | SuggestedRepliesPart
150
155
  | WorkflowProgressPart
151
- | WorkflowOutcomePart;
156
+ | WorkflowOutcomePart
157
+ | AffordanceOfferPart;
152
158
 
153
159
  /**
154
160
  * All assistant message part types.