@company-semantics/contracts 93.0.0 → 93.2.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": "93.0.0",
3
+ "version": "93.2.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -168,7 +168,7 @@
168
168
  "pnpm": {
169
169
  "overrides": {
170
170
  "brace-expansion@<5.0.11": ">=5.0.11",
171
- "smol-toml@<1.7.1": ">=1.7.1",
171
+ "smol-toml@<1.9.0": ">=1.9.0",
172
172
  "minimatch@<10.2.3": ">=10.2.3",
173
173
  "nanoid@<3.3.18": ">=3.3.18",
174
174
  "js-yaml@>=4.0.0 <4.3.2": ">=4.3.2 <5.0.0",
@@ -181,7 +181,8 @@
181
181
  "postcss@<8.5.23": ">=8.5.23",
182
182
  "source-map-js@<1.2.2": ">=1.2.2",
183
183
  "markdown-it@<14.2.0": ">=14.2.0",
184
- "@humanfs/node@<0.16.8": ">=0.16.8 <0.17.0"
184
+ "@humanfs/node@<0.16.8": ">=0.16.8 <0.17.0",
185
+ "katex@<0.18.2": ">=0.18.2 <0.19.0"
185
186
  }
186
187
  },
187
188
  "lint-staged": {
@@ -189,5 +190,5 @@
189
190
  "*.md": "markdownlint-cli2",
190
191
  "package.json": "node -e \"JSON.parse(require('fs').readFileSync('package.json'))\""
191
192
  },
192
- "securityRequirementsVersion": "4b88755e9a43a82b2f5eb55b953581526f1982de362da77bc579888d1f6a1bb0"
193
+ "securityRequirementsVersion": "71a26f10642b9fc598f6da99c75200fd174ebd0e6a9e32437a3f1b245e906792"
193
194
  }
@@ -157,6 +157,8 @@ describe("resource-keys: system-scoped internalAdmin* types", () => {
157
157
  "factoryFloor",
158
158
  "factorySnapshot",
159
159
  "factoryKpis",
160
+ "factoryLineage",
161
+ "factoryProduction",
160
162
  ] as const;
161
163
 
162
164
  for (const type of systemTypes) {
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
2
- export const SPEC_HASH = '4eb1b17b3340' as const;
3
- export const SPEC_HASH_FULL = '4eb1b17b3340b7613c5f8189f7fef55164ea1d859c67b31790297ce5709b2db4' as const;
2
+ export const SPEC_HASH = 'a57011cbdcd2' as const;
3
+ export const SPEC_HASH_FULL = 'a57011cbdcd2d9be32d330cc97eb33954aaa55d6936e0f644496644e0bb66e11' as const;
@@ -3911,6 +3911,40 @@ 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
+ };
3931
+ "/api/factory/production": {
3932
+ parameters: {
3933
+ query?: never;
3934
+ header?: never;
3935
+ path?: never;
3936
+ cookie?: never;
3937
+ };
3938
+ /** Read the production view: each production signal with its verdict, age, staleness and breach run */
3939
+ get: operations["factoryProduction"];
3940
+ put?: never;
3941
+ post?: never;
3942
+ delete?: never;
3943
+ options?: never;
3944
+ head?: never;
3945
+ patch?: never;
3946
+ trace?: never;
3947
+ };
3914
3948
  "/api/factory/quality/changes": {
3915
3949
  parameters: {
3916
3950
  query?: never;
@@ -6893,6 +6927,13 @@ export interface components {
6893
6927
  requiredScope?: string;
6894
6928
  };
6895
6929
  };
6930
+ workspace?: {
6931
+ manageSettings: {
6932
+ /** @enum {string} */
6933
+ state: "allowed" | "blocked";
6934
+ requiredScope?: string;
6935
+ };
6936
+ };
6896
6937
  };
6897
6938
  chatMentions: boolean;
6898
6939
  chatMultiParty: boolean;
@@ -9253,6 +9294,11 @@ export interface components {
9253
9294
  };
9254
9295
  eventTimestamp: string;
9255
9296
  }[];
9297
+ pausedAuth?: {
9298
+ since: string;
9299
+ lane: number;
9300
+ reason: string | null;
9301
+ } | null;
9256
9302
  }[];
9257
9303
  };
9258
9304
  FactorySnapshotResponse: {
@@ -9389,6 +9435,72 @@ export interface components {
9389
9435
  [key: string]: unknown;
9390
9436
  } | null;
9391
9437
  };
9438
+ FactoryLineageResponse: {
9439
+ releases: {
9440
+ key: string;
9441
+ manifestId: string | null;
9442
+ stationId: string;
9443
+ /** @enum {string} */
9444
+ status: "in_progress" | "applied" | "rolled_back";
9445
+ intendedAt: string | null;
9446
+ appliedAt: string | null;
9447
+ durationMs: number | null;
9448
+ surfaces: string[];
9449
+ shas: {
9450
+ [key: string]: string;
9451
+ } | null;
9452
+ run: {
9453
+ id: string;
9454
+ attempt: number;
9455
+ repository: string;
9456
+ url: string;
9457
+ } | null;
9458
+ health: {
9459
+ /** @enum {string} */
9460
+ releaseInvariant: "ok" | "failed" | "unproven" | "unknown";
9461
+ /** @enum {string} */
9462
+ windowMetric: "ok" | "failed" | "unproven" | "unknown";
9463
+ /** @enum {string} */
9464
+ pointProbe: "ok" | "failed" | "unproven" | "unknown";
9465
+ rolledBack: boolean;
9466
+ } | null;
9467
+ commitsRecorded: boolean;
9468
+ changesTruncated: boolean;
9469
+ changes: {
9470
+ repo: string;
9471
+ sha: string;
9472
+ prdId: string | null;
9473
+ pr: number | null;
9474
+ worker: {
9475
+ stationId: string;
9476
+ executorId: string;
9477
+ } | null;
9478
+ }[];
9479
+ }[];
9480
+ };
9481
+ FactoryProductionResponse: {
9482
+ generatedAt: string;
9483
+ signals: {
9484
+ /** @enum {string} */
9485
+ signal: "api_availability" | "http_5xx" | "latency_p95" | "ecs_tasks" | "database" | "deploy_lag" | "app_host_edge" | "chat_success" | "ingestion_backlog" | "release_safety";
9486
+ /** @enum {string} */
9487
+ source: "hosted" | "computed";
9488
+ targetText: string;
9489
+ cadenceMinutes: number;
9490
+ /** @enum {string} */
9491
+ verdict: "ok" | "breach" | "unavailable";
9492
+ value: number | null;
9493
+ target: number | null;
9494
+ unit: string | null;
9495
+ detail: string | null;
9496
+ windowMinutes: number | null;
9497
+ sampledAt: string | null;
9498
+ ageSeconds: number | null;
9499
+ stale: boolean;
9500
+ consecutiveBreaches: number;
9501
+ passRate30d: number | null;
9502
+ }[];
9503
+ };
9392
9504
  CreateQualityChangeResponse: {
9393
9505
  /** Format: uuid */
9394
9506
  planId: string;
@@ -17897,6 +18009,77 @@ export interface operations {
17897
18009
  };
17898
18010
  };
17899
18011
  };
18012
+ factoryLineage: {
18013
+ parameters: {
18014
+ query?: {
18015
+ limit?: number;
18016
+ prdId?: string;
18017
+ };
18018
+ header?: never;
18019
+ path?: never;
18020
+ cookie?: never;
18021
+ };
18022
+ requestBody?: never;
18023
+ responses: {
18024
+ /** @description Lineage records, newest release first */
18025
+ 200: {
18026
+ headers: {
18027
+ [name: string]: unknown;
18028
+ };
18029
+ content: {
18030
+ "application/json": components["schemas"]["FactoryLineageResponse"];
18031
+ };
18032
+ };
18033
+ /** @description Not authenticated */
18034
+ 401: {
18035
+ headers: {
18036
+ [name: string]: unknown;
18037
+ };
18038
+ content?: never;
18039
+ };
18040
+ /** @description Not an internal admin */
18041
+ 403: {
18042
+ headers: {
18043
+ [name: string]: unknown;
18044
+ };
18045
+ content?: never;
18046
+ };
18047
+ };
18048
+ };
18049
+ factoryProduction: {
18050
+ parameters: {
18051
+ query?: never;
18052
+ header?: never;
18053
+ path?: never;
18054
+ cookie?: never;
18055
+ };
18056
+ requestBody?: never;
18057
+ responses: {
18058
+ /** @description The ten production signals */
18059
+ 200: {
18060
+ headers: {
18061
+ [name: string]: unknown;
18062
+ };
18063
+ content: {
18064
+ "application/json": components["schemas"]["FactoryProductionResponse"];
18065
+ };
18066
+ };
18067
+ /** @description Not authenticated */
18068
+ 401: {
18069
+ headers: {
18070
+ [name: string]: unknown;
18071
+ };
18072
+ content?: never;
18073
+ };
18074
+ /** @description Not an internal admin */
18075
+ 403: {
18076
+ headers: {
18077
+ [name: string]: unknown;
18078
+ };
18079
+ content?: never;
18080
+ };
18081
+ };
18082
+ };
17900
18083
  createQualityChange: {
17901
18084
  parameters: {
17902
18085
  query?: never;
@@ -23,13 +23,21 @@
23
23
  * no-sibling-imports invariant intact (the same pattern as
24
24
  * runtime-profile.test.ts).
25
25
  *
26
- * It is skipped when the app is not checked out beside this repo — contracts
27
- * consumed standalone from npm, or contracts CI, which by design has no app
28
- * checkout because contracts is the root of the dependency tree. The inverted
29
- * marker test makes the reporter say so rather than showing a silent pass.
26
+ * Where the app is read from: `resolveSibling` (tests/workspace-sibling.ts), the
27
+ * workspace's sibling rule (ci ADR-CI-276): this session's app worktree when
28
+ * the session holds one, else app's committed origin/main; never a primary's
29
+ * working tree. It used to probe `<workspace>/company-semantics-app` (the
30
+ * PRIMARY) and `../company-semantics-app` from cwd for
31
+ * `src/platform/route-parser.ts`, a path app has since moved to
32
+ * `src/lib/nav/route-parser.ts`, so it skipped everywhere (ci ADR-CI-294
33
+ * follow-up). A moved file now fails the read.
34
+ *
35
+ * Inside the workspace a missing or unreadable app FAILS this file. The parity
36
+ * tests skip, and the inverted marker test says why, only in a standalone
37
+ * clone (no other company-semantics-* checkout beside it): contracts consumed
38
+ * from npm, or contracts CI, which by design has no app checkout because
39
+ * contracts is the root of the dependency tree.
30
40
  */
31
- import { existsSync, readFileSync } from "node:fs";
32
- import { resolve, sep } from "node:path";
33
41
  import { describe, it, expect } from "vitest";
34
42
  import {
35
43
  ChatPageContextSchema,
@@ -37,6 +45,7 @@ import {
37
45
  CHAT_PAGE_SCOPES,
38
46
  CHAT_PAGE_ENTITY_TYPES,
39
47
  } from "../schemas.js";
48
+ import { resolveSibling } from "../../../tests/workspace-sibling.js";
40
49
 
41
50
  // ---------------------------------------------------------------------------
42
51
  // Fixtures
@@ -56,52 +65,22 @@ const A_DOCUMENT_BODY = `# Q3 plan\n${"Revenue grew. ".repeat(200)}`;
56
65
  // Locating the app checkout that governs this run
57
66
  // ---------------------------------------------------------------------------
58
67
 
59
- /**
60
- * Probed in order:
61
- * 1. The app worktree mirroring this one. Ralph checks the same branch of
62
- * every repo out at the same relative path, so a contracts worktree has an
63
- * app worktree beside it carrying the branch's route grammar. The app MAIN
64
- * checkout sits on another branch entirely, and comparing against it would
65
- * report drift for a value this branch already corrected.
66
- * 2. The app main checkout in the same workspace.
67
- * 3. The plain sibling guess, for a non-worktree local dev layout.
68
- */
69
- function resolveAppRoot(): string | undefined {
70
- const candidates: string[] = [];
71
-
72
- const segments = process.cwd().split(sep);
73
- const contractsIdx = segments.lastIndexOf("company-semantics-contracts");
74
- if (contractsIdx !== -1) {
75
- const workspaceRoot = segments.slice(0, contractsIdx).join(sep);
76
- const worktreeSuffix = segments.slice(contractsIdx + 1);
77
- const appRoot = resolve(workspaceRoot, "company-semantics-app");
78
- if (worktreeSuffix.length > 0) {
79
- candidates.push(resolve(appRoot, ...worktreeSuffix));
80
- }
81
- candidates.push(appRoot);
82
- }
83
- candidates.push(resolve(process.cwd(), "..", "company-semantics-app"));
84
-
85
- return candidates.find((root) =>
86
- existsSync(resolve(root, "src", "platform", "route-parser.ts")),
87
- );
88
- }
68
+ const APP_ROUTE_PARSER = "src/lib/nav/route-parser.ts";
89
69
 
90
- const APP_ROOT = resolveAppRoot();
91
- const appAvailable = APP_ROOT !== undefined;
70
+ // Throws (failing this file loudly) inside the workspace when the app cannot
71
+ // be resolved; null only in a standalone clone.
72
+ const app = await resolveSibling("company-semantics-app");
73
+ const appAvailable = app !== null;
92
74
 
93
75
  /** The body of the app's `export type Route = ...;` union, as a string. */
94
76
  function appRouteUnionSource(): string {
95
- const source = readFileSync(
96
- resolve(APP_ROOT!, "src", "platform", "route-parser.ts"),
97
- "utf8",
98
- );
77
+ const source = app!.read(APP_ROUTE_PARSER);
99
78
  // Terminated by the blank line after the union, because `;` also ends every
100
79
  // member field inside it.
101
80
  const match = source.match(/export type Route =([\s\S]*?);\r?\n\r?\n/);
102
81
  if (!match?.[1]) {
103
82
  throw new Error(
104
- "Could not locate the `Route` union in app src/platform/route-parser.ts. " +
83
+ `Could not locate the \`Route\` union in app ${APP_ROUTE_PARSER}. ` +
105
84
  "If the declaration was renamed or restructured, update this test — do " +
106
85
  "NOT delete it, or the view vocabulary can drift out of step unseen.",
107
86
  );
@@ -18,59 +18,35 @@
18
18
  * imports, keeping the contracts no-sibling-imports invariant intact (the
19
19
  * same pattern as tests/org/reserved-slug-roundtrip.test.ts).
20
20
  *
21
- * They are skipped when the backend is not checked out beside this repo — e.g.
22
- * contracts consumed standalone from npm, or contracts CI, which by design has
23
- * no backend checkout because contracts is the root of the dependency tree.
24
- * Drift introduced on the backend side is therefore NOT gated by contracts CI;
25
- * it is caught here in a workspace checkout, and the inverted marker test below
26
- * makes the reporter say so rather than showing a silent pass.
21
+ * Where the backend is read from: `resolveSibling` (tests/workspace-sibling.ts),
22
+ * the workspace's sibling rule (ci ADR-CI-276): this session's backend worktree
23
+ * when the session holds one, else backend's committed origin/main; never a
24
+ * primary's working tree, which may hold another session's uncommitted work.
25
+ * It used to probe `<workspace>/company-semantics-backend` (the PRIMARY) and
26
+ * `../company-semantics-backend` from cwd (ci ADR-CI-294 follow-up).
27
+ *
28
+ * Inside the workspace a missing or unreadable backend FAILS this file. The
29
+ * parity tests skip, and the inverted marker test says why, only in a
30
+ * standalone clone (no other company-semantics-* checkout beside it): contracts
31
+ * consumed from npm, or contracts CI, which by design has no backend checkout
32
+ * because contracts is the root of the dependency tree. Drift introduced on the
33
+ * backend side is therefore NOT gated by contracts CI; it is caught here in a
34
+ * workspace checkout.
27
35
  */
28
- import { existsSync, readFileSync } from "node:fs";
29
- import { resolve, sep } from "node:path";
30
36
  import { describe, it, expect } from "vitest";
31
37
  import {
32
38
  CHAT_RUNTIME_PROFILES,
33
39
  DEFAULT_CHAT_RUNTIME_PROFILE,
34
40
  } from "../runtime-profile.js";
41
+ import { resolveSibling } from "../../../tests/workspace-sibling.js";
35
42
 
36
- /**
37
- * Locate the backend checkout that governs this run.
38
- *
39
- * Probed in order:
40
- * 1. The backend worktree mirroring this one. Ralph checks the same branch of
41
- * every repo out at the same relative path, so a contracts worktree has a
42
- * backend worktree beside it carrying the branch's constants. The backend
43
- * MAIN checkout sits on another branch entirely, and comparing against it
44
- * would report drift for a value this branch already corrected.
45
- * 2. The backend main checkout in the same workspace.
46
- * 3. The plain sibling guess, for a non-worktree local dev layout.
47
- */
48
- function resolveBackendRoot(): string | undefined {
49
- const candidates: string[] = [];
50
-
51
- const segments = process.cwd().split(sep);
52
- const contractsIdx = segments.lastIndexOf("company-semantics-contracts");
53
- if (contractsIdx !== -1) {
54
- const workspaceRoot = segments.slice(0, contractsIdx).join(sep);
55
- const worktreeSuffix = segments.slice(contractsIdx + 1);
56
- const backendRoot = resolve(workspaceRoot, "company-semantics-backend");
57
- if (worktreeSuffix.length > 0) {
58
- candidates.push(resolve(backendRoot, ...worktreeSuffix));
59
- }
60
- candidates.push(backendRoot);
61
- }
62
- candidates.push(resolve(process.cwd(), "..", "company-semantics-backend"));
63
-
64
- return candidates.find((root) =>
65
- existsSync(resolve(root, "src", "chat", "orchestrator", "factory.ts")),
66
- );
67
- }
68
-
69
- const BACKEND_ROOT = resolveBackendRoot();
70
- const backendAvailable = BACKEND_ROOT !== undefined;
43
+ // Throws (failing this file loudly) inside the workspace when the backend
44
+ // cannot be resolved; null only in a standalone clone.
45
+ const backend = await resolveSibling("company-semantics-backend");
46
+ const backendAvailable = backend !== null;
71
47
 
72
48
  function readBackendSource(...relative: string[]): string {
73
- return readFileSync(resolve(BACKEND_ROOT!, ...relative), "utf8");
49
+ return backend!.read(relative.join("/"));
74
50
  }
75
51
 
76
52
  /** Extract the single capture of `pattern`, or explain what moved. */
@@ -95,6 +95,8 @@ export const openApiRoutes = {
95
95
  '/api/executions/{executionId}/undo': ['POST'],
96
96
  '/api/factory/floor': ['GET'],
97
97
  '/api/factory/kpis': ['GET'],
98
+ '/api/factory/lineage': ['GET'],
99
+ '/api/factory/production': ['GET'],
98
100
  '/api/factory/quality/changes': ['POST'],
99
101
  '/api/factory/quality/corpus': ['GET'],
100
102
  '/api/factory/quality/deployments': ['POST'],
@@ -161,6 +161,8 @@ export const SYSTEM_SCOPED_TYPES = [
161
161
  "factoryFloor",
162
162
  "factorySnapshot",
163
163
  "factoryKpis",
164
+ "factoryLineage",
165
+ "factoryProduction",
164
166
  ] as const satisfies readonly SystemScopedType[];
165
167
 
166
168
  /** Every literal `fromQueryKey` can route, across all five tables. */
@@ -157,6 +157,12 @@ export type ResourceKey =
157
157
  // `useResource` disables a query whose `toQueryKey` throws, the panel it backs
158
158
  // never fetched at all. An unregistered key is not a stale read, it is no read.
159
159
  | { type: "factoryKpis"; scope: "system" }
160
+ // Change lineage over the release ledger (ADR-CONTRACTS-222, backend
161
+ // ADR-BE-926): each release with its commits, PRDs, workers, run and health.
162
+ | { type: "factoryLineage"; scope: "system" }
163
+ // The production view (ADR-CONTRACTS-224, backend ADR-BE-929): the ten
164
+ // production signals with verdict, age, staleness and breach run.
165
+ | { type: "factoryProduction"; scope: "system" }
160
166
  // Everything awaiting the viewer's decision, across every domain
161
167
  // (ADR-CONT-104). ORG-scoped, not user-scoped, even though the content is
162
168
  // per-viewer: the bucket differs per org, so a user-keyed entry would serve
@@ -137,6 +137,8 @@ export function toQueryKey(key: ResourceKey): readonly string[] {
137
137
  case "factoryFloor":
138
138
  case "factorySnapshot":
139
139
  case "factoryKpis":
140
+ case "factoryLineage":
141
+ case "factoryProduction":
140
142
  return [key.type, key.scope] as const;
141
143
 
142
144
  default: {