@company-semantics/contracts 26.1.0 → 27.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@company-semantics/contracts",
3
- "version": "26.1.0",
3
+ "version": "27.1.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
2
- export const SPEC_HASH = 'eb984ad65268' as const;
3
- export const SPEC_HASH_FULL = 'eb984ad65268ce0b6877c26b331bef135bab04876e6fe9aa732844cd52f29353' as const;
2
+ export const SPEC_HASH = '0a8d3435dba9' as const;
3
+ export const SPEC_HASH_FULL = '0a8d3435dba94642fe2cf529b1743d868363875302393e23cf0b9238a4f5cd47' as const;
@@ -1645,6 +1645,40 @@ export interface paths {
1645
1645
  patch?: never;
1646
1646
  trace?: never;
1647
1647
  };
1648
+ "/api/company-md/context-bank/search": {
1649
+ parameters: {
1650
+ query?: never;
1651
+ header?: never;
1652
+ path?: never;
1653
+ cookie?: never;
1654
+ };
1655
+ /** Search org-wide context docs the caller may view */
1656
+ get: operations["searchCompanyMdContextDocs"];
1657
+ put?: never;
1658
+ post?: never;
1659
+ delete?: never;
1660
+ options?: never;
1661
+ head?: never;
1662
+ patch?: never;
1663
+ trace?: never;
1664
+ };
1665
+ "/api/company-md/docs/:id/context-bank/suggestions": {
1666
+ parameters: {
1667
+ query?: never;
1668
+ header?: never;
1669
+ path?: never;
1670
+ cookie?: never;
1671
+ };
1672
+ /** Suggest context docs semantically nearest to a parent the caller may view */
1673
+ get: operations["companyMdContextDocSuggestions"];
1674
+ put?: never;
1675
+ post?: never;
1676
+ delete?: never;
1677
+ options?: never;
1678
+ head?: never;
1679
+ patch?: never;
1680
+ trace?: never;
1681
+ };
1648
1682
  "/api/company-md/search": {
1649
1683
  parameters: {
1650
1684
  query?: never;
@@ -4437,6 +4471,14 @@ export interface components {
4437
4471
  DenyAccessRequest: {
4438
4472
  reason?: string;
4439
4473
  };
4474
+ /** @description Org-wide context-doc discovery hits the caller may view. */
4475
+ SearchContextDocsResponse: {
4476
+ items: components["schemas"]["ContextDocDiscoveryHit"][];
4477
+ };
4478
+ /** @description Semantically nearest context-doc suggestions the caller may view. */
4479
+ SuggestContextDocsResponse: {
4480
+ items: components["schemas"]["ContextDocDiscoveryHit"][];
4481
+ };
4440
4482
  /** @description Ranked retrieval hits plus the source kinds actually searched. */
4441
4483
  CompanyMdSearchResponse: {
4442
4484
  hits: {
@@ -5005,65 +5047,6 @@ export interface components {
5005
5047
  /** @enum {string} */
5006
5048
  relationshipType: "solid" | "dotted";
5007
5049
  }[];
5008
- nodes: {
5009
- /** Format: uuid */
5010
- id: string;
5011
- fullName: string;
5012
- jobTitle: string | null;
5013
- avatarUrl: string | null;
5014
- primaryUnitId: string | null;
5015
- ownedUnits: {
5016
- /** Format: uuid */
5017
- id: string;
5018
- name: string;
5019
- /** @enum {string} */
5020
- mutability: "derived" | "user_managed";
5021
- }[];
5022
- }[];
5023
- edges: {
5024
- report: {
5025
- /** @constant */
5026
- kind: "member";
5027
- /** Format: uuid */
5028
- userId: string;
5029
- } | {
5030
- /** @constant */
5031
- kind: "open-role";
5032
- /** Format: uuid */
5033
- openRoleId: string;
5034
- };
5035
- manager: {
5036
- /** @constant */
5037
- kind: "member";
5038
- /** Format: uuid */
5039
- userId: string;
5040
- } | {
5041
- /** @constant */
5042
- kind: "open-role";
5043
- /** Format: uuid */
5044
- openRoleId: string;
5045
- };
5046
- /** @enum {string} */
5047
- relationshipType: "solid" | "dotted";
5048
- }[];
5049
- openRoles: {
5050
- /** Format: uuid */
5051
- id: string;
5052
- /** Format: uuid */
5053
- unitId: string;
5054
- title: string | null;
5055
- reportsTo: ({
5056
- /** @constant */
5057
- kind: "member";
5058
- /** Format: uuid */
5059
- userId: string;
5060
- } | {
5061
- /** @constant */
5062
- kind: "open-role";
5063
- /** Format: uuid */
5064
- openRoleId: string;
5065
- }) | null;
5066
- }[];
5067
5050
  };
5068
5051
  /** @description Polling snapshot of a generic ingestion operation. */
5069
5052
  IngestionOperationPollResponse: {
@@ -5754,6 +5737,19 @@ export interface components {
5754
5737
  userAgent: string;
5755
5738
  } | null;
5756
5739
  };
5740
+ /** @description An ACL-admitted context-doc discovery hit. */
5741
+ ContextDocDiscoveryHit: {
5742
+ id: string;
5743
+ slug: string;
5744
+ title: string;
5745
+ /** @enum {string} */
5746
+ visibility: "private" | "unit" | "org";
5747
+ updatedAt: string;
5748
+ score: number;
5749
+ distance?: number;
5750
+ /** @enum {string} */
5751
+ matchedVia: "fts" | "vector";
5752
+ };
5757
5753
  };
5758
5754
  responses: never;
5759
5755
  parameters: never;
@@ -8325,6 +8321,80 @@ export interface operations {
8325
8321
  };
8326
8322
  };
8327
8323
  };
8324
+ searchCompanyMdContextDocs: {
8325
+ parameters: {
8326
+ query: {
8327
+ q?: string;
8328
+ parentId: string;
8329
+ limit?: number;
8330
+ };
8331
+ header?: never;
8332
+ path?: never;
8333
+ cookie?: never;
8334
+ };
8335
+ requestBody?: never;
8336
+ responses: {
8337
+ /** @description ACL-admitted context-doc discovery hits */
8338
+ 200: {
8339
+ headers: {
8340
+ [name: string]: unknown;
8341
+ };
8342
+ content: {
8343
+ "application/json": components["schemas"]["SearchContextDocsResponse"];
8344
+ };
8345
+ };
8346
+ /** @description Invalid query parameters */
8347
+ 400: {
8348
+ headers: {
8349
+ [name: string]: unknown;
8350
+ };
8351
+ content?: never;
8352
+ };
8353
+ /** @description Requires org.view_company_md scope */
8354
+ 403: {
8355
+ headers: {
8356
+ [name: string]: unknown;
8357
+ };
8358
+ content?: never;
8359
+ };
8360
+ };
8361
+ };
8362
+ companyMdContextDocSuggestions: {
8363
+ parameters: {
8364
+ query?: {
8365
+ limit?: number;
8366
+ };
8367
+ header?: never;
8368
+ path?: never;
8369
+ cookie?: never;
8370
+ };
8371
+ requestBody?: never;
8372
+ responses: {
8373
+ /** @description ACL-admitted semantically-nearest context-doc suggestions */
8374
+ 200: {
8375
+ headers: {
8376
+ [name: string]: unknown;
8377
+ };
8378
+ content: {
8379
+ "application/json": components["schemas"]["SuggestContextDocsResponse"];
8380
+ };
8381
+ };
8382
+ /** @description Invalid path or query parameters */
8383
+ 400: {
8384
+ headers: {
8385
+ [name: string]: unknown;
8386
+ };
8387
+ content?: never;
8388
+ };
8389
+ /** @description Requires org.view_company_md scope */
8390
+ 403: {
8391
+ headers: {
8392
+ [name: string]: unknown;
8393
+ };
8394
+ content?: never;
8395
+ };
8396
+ };
8397
+ };
8328
8398
  searchCompanyMd: {
8329
8399
  parameters: {
8330
8400
  query?: never;
@@ -24,6 +24,8 @@ export const openApiRoutes = {
24
24
  '/api/company-md/access-requests/{id}/approve': ['POST'],
25
25
  '/api/company-md/access-requests/{id}/deny': ['POST'],
26
26
  '/api/company-md/context-bank': ['POST'],
27
+ '/api/company-md/context-bank/search': ['GET'],
28
+ '/api/company-md/docs/:id/context-bank/suggestions': ['GET'],
27
29
  '/api/company-md/docs/{id}': ['GET'],
28
30
  '/api/company-md/docs/{id}/access-requests': ['GET', 'POST'],
29
31
  '/api/company-md/docs/{id}/content': ['PUT'],
@@ -51,12 +51,6 @@ TypeScript types and functions for user identity and display name resolution.
51
51
  - `NameSource` _(type)_ — Source of the user's name data.
52
52
  - `OrgChartActorRef` _(type)_
53
53
  - `OrgChartActorRefSchema`
54
- - `PeopleOrgChartEdge` _(type)_
55
- - `PeopleOrgChartEdgeSchema`
56
- - `PeopleOrgChartNode` _(type)_
57
- - `PeopleOrgChartNodeSchema`
58
- - `PeopleOrgChartOpenRole` _(type)_
59
- - `PeopleOrgChartOpenRoleSchema`
60
54
  - `PeopleOrgChartOwnedUnit` _(type)_
61
55
  - `PeopleOrgChartOwnedUnitSchema`
62
56
  - `PeopleOrgChartResponse` _(type)_
@@ -65,10 +65,7 @@ export type {
65
65
  export {
66
66
  ReportingRelationshipTypeSchema,
67
67
  OrgChartActorRefSchema,
68
- PeopleOrgChartNodeSchema,
69
68
  PeopleOrgChartOwnedUnitSchema,
70
- PeopleOrgChartEdgeSchema,
71
- PeopleOrgChartOpenRoleSchema,
72
69
  PeopleOrgChartSeatStatusSchema,
73
70
  PeopleOrgChartSeatOccupantSchema,
74
71
  PeopleOrgChartSeatSchema,
@@ -78,10 +75,7 @@ export {
78
75
  export type {
79
76
  ReportingRelationshipType,
80
77
  OrgChartActorRef,
81
- PeopleOrgChartNode,
82
78
  PeopleOrgChartOwnedUnit,
83
- PeopleOrgChartEdge,
84
- PeopleOrgChartOpenRole,
85
79
  PeopleOrgChartSeatStatus,
86
80
  PeopleOrgChartSeatOccupant,
87
81
  PeopleOrgChartSeat,
@@ -4,8 +4,10 @@
4
4
  * Zod response schemas for GET /api/users/org-chart — the people-org-chart
5
5
  * view rendered from the settings page Structure → Org chart drill-down.
6
6
  *
7
- * Nodes are users (with optional avatar + job title); edges encode
8
- * person-to-person reporting lines from the `user_reporting` table.
7
+ * The chart is position-centric (ADR-CONT-093/094): every actor is a `seat`
8
+ * (a `positions` row) carrying its seat-scoped attributes plus an `occupants[]`
9
+ * array; reporting is expressed seat→seat in `seatEdges[]`. A VACANT seat (no
10
+ * occupants) is the old "open role"; an OCCUPIED seat is the old "member".
9
11
  *
10
12
  * Person-level reporting is intentionally distinct from
11
13
  * `org_unit_relationships.type = 'reports_to'` (unit-to-unit graph overlay,
@@ -23,17 +25,16 @@ export type ReportingRelationshipType = z.infer<
23
25
  typeof ReportingRelationshipTypeSchema
24
26
  >;
25
27
 
26
- // Actor reference — either endpoint of a reporting edge (member | open-role).
27
- // Defined in its own zero-dependency module to avoid a module-init cycle with
28
- // `org/schemas` (which this file imports AuthorityMutabilitySchema from, and
29
- // which needs the actor ref for the set-manager request/response). Re-exported
30
- // here so the existing import site keeps working.
28
+ // Actor reference (member | open-role). Retained WRITE-ONLY: the set-manager
29
+ // request/response (`org/schemas`) still speaks this vocabulary; the read model
30
+ // is now seat→seat (ADR-CONT-094) and no longer references it. Defined in its
31
+ // own zero-dependency module to avoid a module-init cycle with `org/schemas`,
32
+ // and re-exported here so the existing barrel import site keeps working.
31
33
  export { OrgChartActorRefSchema } from "./org-chart-actor";
32
34
  export type { OrgChartActorRef } from "./org-chart-actor";
33
- import { OrgChartActorRefSchema } from "./org-chart-actor";
34
35
 
35
36
  // ---------------------------------------------------------------------------
36
- // Nodea person in the chart
37
+ // Owned unit shared by the seat occupant (below)
37
38
  // ---------------------------------------------------------------------------
38
39
 
39
40
  // A unit this person is a *local structural owner* of — i.e. holds a grant with
@@ -58,61 +59,6 @@ export type PeopleOrgChartOwnedUnit = z.infer<
58
59
  typeof PeopleOrgChartOwnedUnitSchema
59
60
  >;
60
61
 
61
- export const PeopleOrgChartNodeSchema = z.object({
62
- id: z.string().uuid(),
63
- fullName: z.string(),
64
- jobTitle: z.string().nullable(),
65
- avatarUrl: z.string().nullable(),
66
- primaryUnitId: z.string().uuid().nullable(),
67
- // Units this person is a local structural owner of. Empty ⇒ not a unit owner.
68
- // Drives the chart's owner key + tooltip; the account owner (root-unit owner)
69
- // is rendered with the org owner icon (crown) instead.
70
- ownedUnits: z.array(PeopleOrgChartOwnedUnitSchema),
71
- });
72
-
73
- export type PeopleOrgChartNode = z.infer<typeof PeopleOrgChartNodeSchema>;
74
-
75
- // ---------------------------------------------------------------------------
76
- // Edge — a reporting line between two people
77
- // ---------------------------------------------------------------------------
78
-
79
- export const PeopleOrgChartEdgeSchema = z.object({
80
- // Either endpoint may be a member or an open-role seat. An edge whose
81
- // `manager` is an open-role seat is "a person reports to a vacant role"
82
- // (ADR-BE-312); whose `report` is an open-role seat is "an open role reports
83
- // to someone" (ADR-BE-291) — both are now expressible symmetrically.
84
- report: OrgChartActorRefSchema,
85
- manager: OrgChartActorRefSchema,
86
- relationshipType: ReportingRelationshipTypeSchema,
87
- });
88
-
89
- export type PeopleOrgChartEdge = z.infer<typeof PeopleOrgChartEdgeSchema>;
90
-
91
- // ---------------------------------------------------------------------------
92
- // Open role — a persisted placeholder seat rendered as a dashed "Open role"
93
- // card in its unit's sibling column. Only active roles (open + hiring) are
94
- // included; filled/closed roles never appear here. `unitId` seats the card in
95
- // the right column. `reportsTo` is the open role's OWN reporting edge
96
- // (ADR-BE-291): it defaults to the role's creator and is editable/clearable, so
97
- // a person-less seat is placed by reporting like everyone else (the chart owns
98
- // placement, ADR-CTRL-159). Null → the role hangs in its unit's projection-only
99
- // Unassigned bucket. This replaces the retired unit-head anchor (ADR-BE-284).
100
- // ---------------------------------------------------------------------------
101
-
102
- export const PeopleOrgChartOpenRoleSchema = z.object({
103
- id: z.string().uuid(),
104
- unitId: z.string().uuid(),
105
- title: z.string().nullable(),
106
- // The open role's OWN reporting edge (ADR-BE-291). An actor ref so an open
107
- // role can report to a person OR to another open-role seat (ADR-BE-312). Null
108
- // → the role hangs in its unit's projection-only Unassigned bucket.
109
- reportsTo: OrgChartActorRefSchema.nullable(),
110
- });
111
-
112
- export type PeopleOrgChartOpenRole = z.infer<
113
- typeof PeopleOrgChartOpenRoleSchema
114
- >;
115
-
116
62
  // ---------------------------------------------------------------------------
117
63
  // Seat — the position-centric unification (ADR-CONT-093)
118
64
  // ---------------------------------------------------------------------------
@@ -126,12 +72,11 @@ export type PeopleOrgChartOpenRole = z.infer<
126
72
  // for a co-occupied seat — forward-compatible; live data is 0/1). Reporting is
127
73
  // expressed seat→seat in `seatEdges[]`, NOT on the seat, so the edge list stays
128
74
  // the single source of truth for placement (ADR-CTRL-159). `OrgChartActorRef`
129
- // is retained write-only (set-manager request/response) and is removed from
130
- // this read model.
75
+ // is retained write-only (set-manager request/response) and is absent from this
76
+ // read model.
131
77
  //
132
- // This pair (`seats[]` + `seatEdges[]`) is ADDITIVE alongside the legacy
133
- // `nodes`/`edges`/`openRoles` during the transition; the projector dual-emits
134
- // both from one position pass. A later breaking minor removes the legacy half.
78
+ // `seats[]` + `seatEdges[]` are now the ONLY shape — the legacy
79
+ // `nodes`/`edges`/`openRoles` half was removed in ADR-CONT-094 (breaking).
135
80
 
136
81
  export const PeopleOrgChartSeatStatusSchema = z.enum([
137
82
  "planned",
@@ -204,25 +149,16 @@ export type PeopleOrgChartSeatEdge = z.infer<
204
149
  // GET /api/users/org-chart
205
150
  // ---------------------------------------------------------------------------
206
151
  //
207
- // Person-less cards (empty-unit placeholders, ghosts, open roles) no longer
208
- // anchor under a stored unit-head "tether" (ADR-BE-284, retired by ADR-BE-292).
209
- // Open roles carry their own `reportsTo` edge; placeholders fall back to
210
- // the render-time reporting heuristic.
152
+ // Position-centric (ADR-CONT-093/094): `seats[]` carries every chart actor
153
+ // (occupied or vacant) and `seatEdges[]` the seat→seat reporting graph — the
154
+ // single source of truth for placement (ADR-CTRL-159). A vacant seat with no
155
+ // edge hangs in its unit's projection-only Unassigned bucket.
211
156
 
212
157
  export const PeopleOrgChartResponseSchema = z.object({
213
- // Position-centric unified view (ADR-CONT-093). `seats[]` carries every chart
214
- // actor (occupied or vacant) and `seatEdges[]` the seat→seat reporting graph.
215
- // ADDITIVE alongside the legacy fields below during the transition; a later
216
- // breaking minor removes the legacy half.
158
+ // Every chart actor (occupied or vacant), keyed by the stable positionId.
217
159
  seats: z.array(PeopleOrgChartSeatSchema),
160
+ // The seat→seat reporting graph (one row per `position_reporting` row).
218
161
  seatEdges: z.array(PeopleOrgChartSeatEdgeSchema),
219
- // Legacy, transitional (ADR-CONT-093 supersedes). Derived from the same
220
- // position pass as `seats`/`seatEdges`; consumers should migrate to the seat
221
- // model. `nodes` = occupied actors, `openRoles` = vacant 'open' actors,
222
- // `edges` = the same reporting graph keyed by person/open-role actor refs.
223
- nodes: z.array(PeopleOrgChartNodeSchema),
224
- edges: z.array(PeopleOrgChartEdgeSchema),
225
- openRoles: z.array(PeopleOrgChartOpenRoleSchema),
226
162
  });
227
163
 
228
164
  export type PeopleOrgChartResponse = z.infer<
package/src/index.ts CHANGED
@@ -176,10 +176,7 @@ export type {
176
176
  export {
177
177
  ReportingRelationshipTypeSchema,
178
178
  OrgChartActorRefSchema,
179
- PeopleOrgChartNodeSchema,
180
179
  PeopleOrgChartOwnedUnitSchema,
181
- PeopleOrgChartEdgeSchema,
182
- PeopleOrgChartOpenRoleSchema,
183
180
  PeopleOrgChartSeatStatusSchema,
184
181
  PeopleOrgChartSeatOccupantSchema,
185
182
  PeopleOrgChartSeatSchema,
@@ -189,10 +186,7 @@ export {
189
186
  export type {
190
187
  ReportingRelationshipType,
191
188
  OrgChartActorRef,
192
- PeopleOrgChartNode,
193
189
  PeopleOrgChartOwnedUnit,
194
- PeopleOrgChartEdge,
195
- PeopleOrgChartOpenRole,
196
190
  PeopleOrgChartSeatStatus,
197
191
  PeopleOrgChartSeatOccupant,
198
192
  PeopleOrgChartSeat,