@company-semantics/contracts 85.2.0 → 86.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@company-semantics/contracts",
3
- "version": "85.2.0",
3
+ "version": "86.0.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 = '6572e2e103c5' as const;
3
- export const SPEC_HASH_FULL = '6572e2e103c545b6ff678396dbc2d00a17212b56f4c489b9b76c1b327ccc821e' as const;
2
+ export const SPEC_HASH = '4ec580fdf79a' as const;
3
+ export const SPEC_HASH_FULL = '4ec580fdf79abef6f817c1afee788dc61a640b4f903b3f5181d0c3a7fc934709' as const;
@@ -5334,7 +5334,7 @@ export interface components {
5334
5334
  pageContext?: {
5335
5335
  route: string;
5336
5336
  /** @enum {string} */
5337
- view: "chat" | "chats" | "company-md" | "execution-detail" | "internal-admin" | "notifications" | "org-settings" | "org-work" | "settings" | "team-md" | "teams" | "teamwork" | "teamwork-member" | "timeline" | "upgrade" | "user-md" | "work";
5337
+ view: "chat" | "company-md" | "execution-detail" | "internal-admin" | "notifications" | "org-settings" | "org-work" | "settings" | "team-md" | "teams" | "teamwork" | "teamwork-member" | "timeline" | "upgrade" | "user-md" | "work";
5338
5338
  /** @enum {string} */
5339
5339
  scope: "none" | "me" | "team" | "org";
5340
5340
  entity?: {
@@ -5380,7 +5380,7 @@ export interface components {
5380
5380
  pageContext?: {
5381
5381
  route: string;
5382
5382
  /** @enum {string} */
5383
- view: "chat" | "chats" | "company-md" | "execution-detail" | "internal-admin" | "notifications" | "org-settings" | "org-work" | "settings" | "team-md" | "teams" | "teamwork" | "teamwork-member" | "timeline" | "upgrade" | "user-md" | "work";
5383
+ view: "chat" | "company-md" | "execution-detail" | "internal-admin" | "notifications" | "org-settings" | "org-work" | "settings" | "team-md" | "teams" | "teamwork" | "teamwork-member" | "timeline" | "upgrade" | "user-md" | "work";
5384
5384
  /** @enum {string} */
5385
5385
  scope: "none" | "me" | "team" | "org";
5386
5386
  entity?: {
@@ -5426,7 +5426,7 @@ export interface components {
5426
5426
  pageContext?: {
5427
5427
  route: string;
5428
5428
  /** @enum {string} */
5429
- view: "chat" | "chats" | "company-md" | "execution-detail" | "internal-admin" | "notifications" | "org-settings" | "org-work" | "settings" | "team-md" | "teams" | "teamwork" | "teamwork-member" | "timeline" | "upgrade" | "user-md" | "work";
5429
+ view: "chat" | "company-md" | "execution-detail" | "internal-admin" | "notifications" | "org-settings" | "org-work" | "settings" | "team-md" | "teams" | "teamwork" | "teamwork-member" | "timeline" | "upgrade" | "user-md" | "work";
5430
5430
  /** @enum {string} */
5431
5431
  scope: "none" | "me" | "team" | "org";
5432
5432
  entity?: {
@@ -6925,7 +6925,7 @@ export interface components {
6925
6925
  CompanyMdSearchResponse: {
6926
6926
  hits: {
6927
6927
  /** @enum {string} */
6928
- sourceKind: "docs" | "slack" | "meetings";
6928
+ sourceKind: "docs" | "slack" | "meetings" | "org_facts";
6929
6929
  documentId: string;
6930
6930
  recordingId: string | null;
6931
6931
  title: string | null;
@@ -6933,18 +6933,45 @@ export interface components {
6933
6933
  score: number;
6934
6934
  /** @enum {string} */
6935
6935
  matchedVia: "fts" | "vector";
6936
+ /** @description Where the hit came from, projected per reader after admission; [] when none. */
6937
+ citations: ({
6938
+ /** @constant */
6939
+ kind: "company_md_section";
6940
+ docId: string;
6941
+ sectionAnchor: string;
6942
+ versionId: string | null;
6943
+ } | {
6944
+ /** @constant */
6945
+ kind: "landed_source";
6946
+ sourceId: string | null;
6947
+ title: string | null;
6948
+ classLabel: string;
6949
+ /** @enum {string} */
6950
+ use: "attached" | "direction_only";
6951
+ withheld: boolean;
6952
+ sectionAnchor: string;
6953
+ } | {
6954
+ /** @constant */
6955
+ kind: "org_fact";
6956
+ /** @enum {string} */
6957
+ entity: "unit" | "member";
6958
+ entityId: string;
6959
+ /** @enum {string} */
6960
+ authority: "system_of_record" | "human_confirmed" | "ai_inferred";
6961
+ })[];
6936
6962
  }[];
6937
- searchedSources: ("docs" | "slack" | "meetings")[];
6963
+ searchedSources: ("docs" | "slack" | "meetings" | "org_facts")[];
6938
6964
  };
6939
6965
  /** @description A Company.md retrieval query with optional per-source opt-in. */
6940
6966
  CompanyMdSearchRequest: {
6941
6967
  query: string;
6942
6968
  limit?: number;
6943
- /** @description Per-source opt-in. Server defaults: docs/slack ON, meetings OFF (INV-MTG-23) — applied even when this object or the meetings field is omitted. */
6969
+ /** @description Per-source opt-in. Server defaults: docs/slack/org facts ON, meetings OFF (INV-MTG-23) — applied even when this object or the meetings field is omitted. */
6944
6970
  includeSources?: {
6945
6971
  docs?: boolean;
6946
6972
  slack?: boolean;
6947
6973
  meetings?: boolean;
6974
+ orgFacts?: boolean;
6948
6975
  };
6949
6976
  };
6950
6977
  CompanyMdShareResponse: {
@@ -8489,7 +8516,7 @@ export interface components {
8489
8516
  surface: {
8490
8517
  route: string;
8491
8518
  /** @enum {string} */
8492
- view: "chat" | "chats" | "company-md" | "execution-detail" | "internal-admin" | "notifications" | "org-settings" | "org-work" | "settings" | "team-md" | "teams" | "teamwork" | "teamwork-member" | "timeline" | "upgrade" | "user-md" | "work";
8519
+ view: "chat" | "company-md" | "execution-detail" | "internal-admin" | "notifications" | "org-settings" | "org-work" | "settings" | "team-md" | "teams" | "teamwork" | "teamwork-member" | "timeline" | "upgrade" | "user-md" | "work";
8493
8520
  /** @enum {string} */
8494
8521
  scope: "none" | "me" | "team" | "org";
8495
8522
  entity?: {
@@ -8536,7 +8563,7 @@ export interface components {
8536
8563
  route?: {
8537
8564
  route: string;
8538
8565
  /** @enum {string} */
8539
- view: "chat" | "chats" | "company-md" | "execution-detail" | "internal-admin" | "notifications" | "org-settings" | "org-work" | "settings" | "team-md" | "teams" | "teamwork" | "teamwork-member" | "timeline" | "upgrade" | "user-md" | "work";
8566
+ view: "chat" | "company-md" | "execution-detail" | "internal-admin" | "notifications" | "org-settings" | "org-work" | "settings" | "team-md" | "teams" | "teamwork" | "teamwork-member" | "timeline" | "upgrade" | "user-md" | "work";
8540
8567
  /** @enum {string} */
8541
8568
  scope: "none" | "me" | "team" | "org";
8542
8569
  entity?: {
@@ -9598,7 +9625,7 @@ export interface components {
9598
9625
  /** Format: date-time */
9599
9626
  lastObservedAt: string;
9600
9627
  dismissedAt: string | null;
9601
- fingerprint?: string;
9628
+ fingerprint: string;
9602
9629
  }[];
9603
9630
  };
9604
9631
  SourceSyncFinding: {
@@ -9623,11 +9650,11 @@ export interface components {
9623
9650
  /** Format: date-time */
9624
9651
  lastObservedAt: string;
9625
9652
  dismissedAt: string | null;
9626
- fingerprint?: string;
9653
+ fingerprint: string;
9627
9654
  };
9628
9655
  SourceSyncDismissFindingRequest: {
9629
9656
  note?: string;
9630
- expectedFingerprint?: string;
9657
+ expectedFingerprint: string;
9631
9658
  };
9632
9659
  SourceSyncStandingOrdersResponse: {
9633
9660
  orders: {
@@ -65,7 +65,7 @@ A chat can belong to a SUBJECT — the durable case a hand-off to chat is about
65
65
  - `CHAT_DISCUSSION_REQUEST_TYPES` — The kinds of durable input request a turn can be scoped to.
66
66
  - `CHAT_PAGE_ENTITY_TYPES` — What kind of thing the reader has open, when they have one open.
67
67
  - `CHAT_PAGE_SCOPES` — The route parser's four URL scopes: unscoped, `/me/*`, `/team/*`, `/@:org/*`.
68
- - `CHAT_PAGE_VIEWS` — The app route parser's seventeen `type` values, projected onto the wire.
68
+ - `CHAT_PAGE_VIEWS` — The app route parser's sixteen `type` values, projected onto the wire.
69
69
  - `CHAT_RUNTIME_PROFILES` — Ordered list of available profiles for UI rendering.
70
70
  - `CONVERSATION_SUBJECT_KINDS` — The kinds of subject a chat can continue.
71
71
  - `ChatByInteractionResponse` _(type)_ — Response for GET /api/chats/by-interaction/:interactionId
@@ -211,9 +211,10 @@ describe("ChatPageContext is the ceiling on both axes", () => {
211
211
  expect(ChatPageContextSchema.safeParse(VALID).success).toBe(true);
212
212
  expect(
213
213
  ChatPageContextSchema.safeParse({
214
- route: "/new",
214
+ route: "/chat/abc",
215
215
  view: "chat",
216
216
  scope: "none",
217
+ entity: { type: "chat", id: "abc" },
217
218
  }).success,
218
219
  ).toBe(true);
219
220
  });
@@ -509,7 +509,7 @@ export const ChatMentionableResponseSchema = z.object({
509
509
  // =============================================================================
510
510
 
511
511
  /**
512
- * The app route parser's seventeen `type` values, projected onto the wire.
512
+ * The app route parser's sixteen `type` values, projected onto the wire.
513
513
  *
514
514
  * A PROJECTION, not a parallel vocabulary: keep it in step with
515
515
  * `company-semantics-app/src/platform/route-parser.ts`. A view the parser can
@@ -519,7 +519,6 @@ export const ChatMentionableResponseSchema = z.object({
519
519
  */
520
520
  export const CHAT_PAGE_VIEWS = [
521
521
  "chat",
522
- "chats",
523
522
  "company-md",
524
523
  "execution-detail",
525
524
  "internal-admin",
@@ -14,7 +14,6 @@ describe("VIEW_SCOPE_MAP golden snapshot", () => {
14
14
  teams: null,
15
15
  chat: null,
16
16
  settings: null,
17
- chats: null,
18
17
  "my-work": null,
19
18
  "user-md": null,
20
19
  "team-md": null,
@@ -37,7 +36,6 @@ describe("getViewScope", () => {
37
36
  it("returns null for public views", () => {
38
37
  expect(getViewScope("chat")).toBeNull();
39
38
  expect(getViewScope("settings")).toBeNull();
40
- expect(getViewScope("chats")).toBeNull();
41
39
  expect(getViewScope("upgrade")).toBeNull();
42
40
  // teams is membership-derived, not scope-gated (ADR-CONTRACTS-062).
43
41
  expect(getViewScope("teams")).toBeNull();
@@ -35,7 +35,6 @@ export const VIEW_SCOPE_MAP = {
35
35
  teams: null,
36
36
  chat: null,
37
37
  settings: null,
38
- chats: null,
39
38
  "my-work": null,
40
39
  "user-md": null,
41
40
  // Stubs for the viewer's team.md (/team/md) and the org's work (/@org/work);
@@ -27,6 +27,7 @@ import {
27
27
  const FINDING_ID = "d3b42536-f7a8-4b3a-9eb5-e3f4a5b6c7d8";
28
28
  const SOURCE_ID = "3f1a2b4c-5d6e-4f70-8192-a3b4c5d6e7f8";
29
29
  const DOC_ID = "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d";
30
+ const FINGERPRINT = "0123456789abcdef0123456789abcdef";
30
31
 
31
32
  function finding(overrides: Record<string, unknown> = {}) {
32
33
  return {
@@ -41,6 +42,7 @@ function finding(overrides: Record<string, unknown> = {}) {
41
42
  firstObservedAt: "2026-09-19T10:00:00Z",
42
43
  lastObservedAt: "2026-09-20T10:00:00Z",
43
44
  dismissedAt: null,
45
+ fingerprint: FINGERPRINT,
44
46
  ...overrides,
45
47
  };
46
48
  }
@@ -100,12 +102,28 @@ describe("staleness findings", () => {
100
102
  SourceSyncFindingsResponseSchema.safeParse({ findings: [finding()] })
101
103
  .success,
102
104
  ).toBe(true);
105
+ expect(
106
+ SourceSyncDismissFindingRequestSchema.safeParse({
107
+ expectedFingerprint: FINGERPRINT,
108
+ }).success,
109
+ ).toBe(true);
110
+ expect(
111
+ SourceSyncDismissFindingRequestSchema.safeParse({
112
+ expectedFingerprint: FINGERPRINT,
113
+ dismissedByLabel: "Dana Reyes",
114
+ }).success,
115
+ ).toBe(false);
116
+ });
117
+
118
+ it("a finding carries its fingerprint and a dismissal must send it back", () => {
119
+ const { fingerprint: _f, ...without } = finding();
120
+ expect(SourceSyncFindingSchema.safeParse(without).success).toBe(false);
103
121
  expect(SourceSyncDismissFindingRequestSchema.safeParse({}).success).toBe(
104
- true,
122
+ false,
105
123
  );
106
124
  expect(
107
125
  SourceSyncDismissFindingRequestSchema.safeParse({
108
- dismissedByLabel: "Dana Reyes",
126
+ expectedFingerprint: "0f3c9a",
109
127
  }).success,
110
128
  ).toBe(false);
111
129
  });
@@ -56,9 +56,9 @@ export const SourceSyncFindingSchema = z.object({
56
56
  dismissedAt: IsoDateTime.nullable(),
57
57
  /**
58
58
  * What the finding says right now, as the reader saw it. A dismissal sends it
59
- * back as `expectedFingerprint`. Optional while the backend starts sending it.
59
+ * back as `expectedFingerprint`. The backend sends it on every finding.
60
60
  */
61
- fingerprint: z.string().length(32).optional(),
61
+ fingerprint: z.string().length(32),
62
62
  });
63
63
 
64
64
  export const SourceSyncFindingsResponseSchema = z.object({
@@ -68,15 +68,15 @@ export const SourceSyncFindingsResponseSchema = z.object({
68
68
  /**
69
69
  * Dismiss one finding. Who dismissed it is the authenticated caller.
70
70
  * `expectedFingerprint` is the finding's fingerprint as the caller rendered it:
71
- * when present, a finding that moved since is refused as changed. Optional
72
- * during the expand step of the backend decision
73
- * `findings-lifecycle-is-domain-agnostic`; required once dismissal becomes
74
- * compare-and-set.
71
+ * a finding that moved since is refused as changed. Required in the contract
72
+ * ahead of the backend: every typed sender must send it before the backend's
73
+ * own route schema requires it and dismissal becomes compare-and-set (backend
74
+ * decision `findings-lifecycle-is-domain-agnostic`; control PRD-01064).
75
75
  */
76
76
  export const SourceSyncDismissFindingRequestSchema = z
77
77
  .object({
78
78
  note: z.string().max(500).optional(),
79
- expectedFingerprint: z.string().length(32).optional(),
79
+ expectedFingerprint: z.string().length(32),
80
80
  })
81
81
  .strict();
82
82