@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
@@ -0,0 +1,59 @@
1
+ /**
2
+ * "What can I do here": the RESULT shape of the context tool (control ADR
3
+ * affordance-system, amended by PRD-01135).
4
+ *
5
+ * The tool reads the offer rules for the current context, drops what the
6
+ * viewer's policy blocks, and pairs each remaining instance with its live
7
+ * availability. It NEVER enumerates the catalog: existing is not a reason to
8
+ * offer (INV-AFFORD-RELEVANT), so an empty context returns an empty list.
9
+ *
10
+ * INVARIANTS:
11
+ * - POLICY-FILTERED. An entry is present only when the viewer's policy allows
12
+ * it, so the shape carries no policy field and cannot leak a blocked one.
13
+ * - AVAILABILITY IS LIVE and non-authoritative; only the server executes.
14
+ * - BOUNDED and DISTINCT. At most MAX_OFFERED_AFFORDANCES entries, no
15
+ * instance twice.
16
+ */
17
+ import { z } from "zod";
18
+
19
+ import {
20
+ AffordanceSchema,
21
+ MAX_OFFERED_AFFORDANCES,
22
+ sameAffordances,
23
+ } from "./affordance";
24
+ import { AffordanceAvailabilitySchema } from "./availability";
25
+
26
+ /** One affordance the viewer may take here, with its live availability. */
27
+ export const AvailableAffordanceSchema = z
28
+ .object({
29
+ affordance: AffordanceSchema,
30
+ availability: AffordanceAvailabilitySchema,
31
+ })
32
+ .strict();
33
+ export type AvailableAffordance = z.infer<typeof AvailableAffordanceSchema>;
34
+
35
+ /** The tool result: the offered, policy-allowed instances for this context. */
36
+ export const AvailableAffordancesSchema = z
37
+ .object({
38
+ affordances: z
39
+ .array(AvailableAffordanceSchema)
40
+ .max(MAX_OFFERED_AFFORDANCES),
41
+ })
42
+ .strict()
43
+ .superRefine((value, ctx) => {
44
+ const seen = value.affordances.map((entry) => entry.affordance);
45
+ seen.forEach((affordance, i) => {
46
+ if (
47
+ seen
48
+ .slice(0, i)
49
+ .some((earlier) => sameAffordances([earlier], [affordance]))
50
+ ) {
51
+ ctx.addIssue({
52
+ code: "custom",
53
+ path: ["affordances", i],
54
+ message: "an available affordance appears at most once",
55
+ });
56
+ }
57
+ });
58
+ });
59
+ export type AvailableAffordances = z.infer<typeof AvailableAffordancesSchema>;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Reverse coverage: every capability a person can act on DECLARES its
3
+ * affordance, or why it has none (control ADR affordance-system, amended by
4
+ * PRD-01135).
5
+ *
6
+ * The forward direction (an affordance resolves to a real capability) is
7
+ * proven by each binding repo's architecture test. This is the reverse: a
8
+ * mounted backend command operation, an app navigate route or an app launch
9
+ * surface either names the affordance that offers it, or names a reason from a
10
+ * CLOSED vocabulary — so "nobody decided" is not a representable state.
11
+ *
12
+ * INVARIANTS:
13
+ * - CLOSED. NO_AFFORDANCE_REASONS is append-only and never prose; a reason is
14
+ * a classification an architecture test can count, not an excuse.
15
+ * - EXACTLY ONE. A declaration is `{ affordance }` or `{ noAffordance }`,
16
+ * never both (strict members of a union).
17
+ */
18
+ import { z } from "zod";
19
+
20
+ import { AffordanceIdSchema, type AffordanceId } from "./ids";
21
+
22
+ /**
23
+ * Why a capability offers no affordance. Measured 2026-10-06 against backend
24
+ * routeRegistry (725 GET, the rest mutating; seams for auth-identity,
25
+ * internal-admin, test-only, webhooks and factory ingest, chat / comments
26
+ * inline actions) and the app's routes and launch surfaces.
27
+ */
28
+ export const NO_AFFORDANCE_REASONS = [
29
+ /** Reads only (a POST that searches, previews or resolves); nothing to offer. */
30
+ "readOnly",
31
+ /** Performed by the control that shows it (send, post a comment, save a form). */
32
+ "inlineControl",
33
+ /** Staff-only internal administration. */
34
+ "internalAdmin",
35
+ /** Machine to machine: webhooks, ingest, station/factory, test-only. */
36
+ "systemOnly",
37
+ /** Part of sign-in, sign-up, invite acceptance or session handling. */
38
+ "authFlow",
39
+ ] as const;
40
+ export type NoAffordanceReason = (typeof NO_AFFORDANCE_REASONS)[number];
41
+ export const NoAffordanceReasonSchema = z.enum(NO_AFFORDANCE_REASONS);
42
+
43
+ /** One capability's reverse-coverage declaration. */
44
+ export type AffordanceCoverage =
45
+ | { readonly affordance: AffordanceId }
46
+ | { readonly noAffordance: NoAffordanceReason };
47
+
48
+ export const AffordanceCoverageSchema = z.union([
49
+ z.object({ affordance: AffordanceIdSchema }).strict(),
50
+ z.object({ noAffordance: NoAffordanceReasonSchema }).strict(),
51
+ ]);
@@ -38,6 +38,34 @@ export const AFFORDANCE_IDS = [
38
38
  * workflow outcome's `review` disposition). See PROJECTED_AFFORDANCE_IDS.
39
39
  */
40
40
  "review.open",
41
+ // ---------------------------------------------------------------------------
42
+ // Burn-down wave (PRD-01137): the next steps the 2026-10-06 census found
43
+ // carried as prose. Appended, never inserted.
44
+ // ---------------------------------------------------------------------------
45
+ /** Open Settings → Integrations. */
46
+ "integrations.open",
47
+ /** Connect the HR system (BambooHR), or reconnect it when its sign-in died. */
48
+ "hris.connect",
49
+ /** Open the person's own profile (their name). */
50
+ "account.editProfile",
51
+ /** Open the org's settings. */
52
+ "workspace.openOrgSettings",
53
+ /** Add one file to Source Sync by hand. */
54
+ "sourceSync.addFile",
55
+ /** Open one Source Sync update (a proposal) for review, in chat. */
56
+ "sourceSync.openUpdate",
57
+ /** Open the org-structure review of one proposal (in chat). */
58
+ "orgStructure.openReview",
59
+ /** Open one chat. */
60
+ "chat.open",
61
+ /** Open one company.md document. */
62
+ "companyMd.openDoc",
63
+ /** Open one company.md document's version history. */
64
+ "companyMd.openHistory",
65
+ /** Open one team (org unit). */
66
+ "team.open",
67
+ /** Open one execution's detail (the target of an execution confirmation). */
68
+ "execution.open",
41
69
  ] as const;
42
70
 
43
71
  export type AffordanceId = (typeof AFFORDANCE_IDS)[number];
@@ -6,8 +6,14 @@ export { AFFORDANCE_IDS, AffordanceIdSchema } from "./ids";
6
6
  export type { AffordanceId } from "./ids";
7
7
  export {
8
8
  AFFORDANCE_ARGS,
9
+ ChatOpenArgsSchema,
10
+ CompanyMdDocArgsSchema,
11
+ ExecutionOpenArgsSchema,
9
12
  NO_ARG_AFFORDANCE_IDS,
13
+ OrgStructureOpenReviewArgsSchema,
10
14
  ReviewOpenArgsSchema,
15
+ SourceSyncOpenUpdateArgsSchema,
16
+ TeamOpenArgsSchema,
11
17
  } from "./args";
12
18
  export type { AffordanceArgs } from "./args";
13
19
  export {
@@ -37,3 +43,14 @@ export type {
37
43
  OfferedAffordance,
38
44
  ProjectedAffordanceId,
39
45
  } from "./affordance";
46
+ export {
47
+ AffordanceCoverageSchema,
48
+ NO_AFFORDANCE_REASONS,
49
+ NoAffordanceReasonSchema,
50
+ } from "./coverage";
51
+ export type { AffordanceCoverage, NoAffordanceReason } from "./coverage";
52
+ export {
53
+ AvailableAffordanceSchema,
54
+ AvailableAffordancesSchema,
55
+ } from "./available";
56
+ export type { AvailableAffordance, AvailableAffordances } from "./available";
package/src/api/README.md CHANGED
@@ -48,6 +48,7 @@ The file is committed to the repo (not .gitignored) so consumers can import type
48
48
 
49
49
  **Internal domains:**
50
50
 
51
+ - `affordances`
51
52
  - `mcp`
52
53
  - `resource-response`
53
54
 
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
2
- export const SPEC_HASH = '9937d3953931' as const;
3
- export const SPEC_HASH_FULL = '9937d39539319f5173df9f15191c8dc5af40aca8c8cd62a9995f7221436909d2' as const;
2
+ export const SPEC_HASH = 'aebd06a13983' as const;
3
+ export const SPEC_HASH_FULL = 'aebd06a139833549518e70adbcd3af333598cf06fa6669a838f605231395c8cf' as const;