@instruments/materialgraph 0.24.0 → 0.26.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 (124) hide show
  1. package/association-types.d.ts +20 -20
  2. package/associations-client.d.ts +4 -4
  3. package/associations-client.js +3 -10
  4. package/attribution-types.d.ts +3 -3
  5. package/brand-most-sampled-types.d.ts +4 -4
  6. package/brand-types.d.ts +6 -6
  7. package/brands-client.d.ts +4 -4
  8. package/brands-client.js +9 -13
  9. package/browse-types.d.ts +8 -8
  10. package/by-colour-types.d.ts +18 -18
  11. package/by-spec-types.d.ts +14 -14
  12. package/catalog-discovery-types.d.ts +14 -14
  13. package/catalogue-client.d.ts +4 -4
  14. package/catalogue-client.js +38 -37
  15. package/catalogue-types.d.ts +4 -4
  16. package/citation-types.d.ts +4 -4
  17. package/client-browse.d.ts +4 -4
  18. package/client-browse.js +24 -25
  19. package/client-config.d.ts +2 -2
  20. package/client-exploration.d.ts +3 -3
  21. package/client-exploration.js +4 -6
  22. package/client-source-material-comments.d.ts +4 -4
  23. package/client-source-material-comments.js +4 -38
  24. package/client-vocabulary.d.ts +8 -8
  25. package/client-vocabulary.js +20 -30
  26. package/client.d.ts +11 -45
  27. package/client.js +143 -188
  28. package/codes-client.d.ts +2 -2
  29. package/codes-client.js +8 -8
  30. package/codes-types.d.ts +34 -34
  31. package/colour-aggregate-types.d.ts +24 -24
  32. package/colours-client.d.ts +2 -2
  33. package/colours-client.js +15 -15
  34. package/compare-types.d.ts +10 -10
  35. package/composition-client.d.ts +3 -3
  36. package/composition-client.js +8 -7
  37. package/composition-types.d.ts +12 -12
  38. package/coordinate-client.d.ts +2 -2
  39. package/coordinate-client.js +1 -13
  40. package/corpus-scope-types.d.ts +3 -3
  41. package/corpus-scope-types.js +1 -25
  42. package/correction-types.d.ts +10 -10
  43. package/demand-batch-types.d.ts +18 -18
  44. package/demand-types.d.ts +24 -24
  45. package/errors.d.ts +12 -12
  46. package/errors.js +53 -52
  47. package/exploration-types.d.ts +29 -22
  48. package/fan-deck-types.d.ts +6 -6
  49. package/http-transport.d.ts +13 -21
  50. package/http-transport.js +31 -28
  51. package/identify-types.d.ts +10 -10
  52. package/index.d.ts +0 -6
  53. package/index.js +0 -2
  54. package/match-rejection-types.d.ts +6 -6
  55. package/match-stream-types.d.ts +32 -32
  56. package/match-stream.d.ts +2 -2
  57. package/match-stream.js +55 -41
  58. package/match-types.d.ts +8 -8
  59. package/material-asset-types.d.ts +26 -26
  60. package/material-block-types.d.ts +6 -6
  61. package/material-query-plan-types.d.ts +26 -26
  62. package/material-resources-client.d.ts +5 -5
  63. package/material-resources-client.js +10 -20
  64. package/material-types.d.ts +12 -12
  65. package/ndjson.js +16 -8
  66. package/operations.d.ts +6 -6
  67. package/operations.js +9 -39
  68. package/package.json +2 -2
  69. package/palette-completion-types.d.ts +22 -22
  70. package/palette-search-types.d.ts +28 -28
  71. package/query-understanding-types.d.ts +43 -36
  72. package/render-assets-types.d.ts +8 -8
  73. package/resolve-client.d.ts +2 -2
  74. package/resolve-client.js +4 -6
  75. package/resolve-colour-types.d.ts +22 -6
  76. package/resolve-types.d.ts +10 -10
  77. package/run-types.d.ts +70 -70
  78. package/runs.d.ts +13 -26
  79. package/runs.js +77 -89
  80. package/samplize-catalogue-types.d.ts +18 -18
  81. package/samplize-colorvec.d.ts +20 -20
  82. package/samplize-colorvec.js +66 -42
  83. package/schema-resource-types.d.ts +38 -38
  84. package/schema-resource-types.js +5 -5
  85. package/search-card-types.d.ts +14 -5
  86. package/search-collapse-types.d.ts +4 -4
  87. package/search-mood-types.d.ts +2 -2
  88. package/search-refinement-types.d.ts +8 -8
  89. package/search-request-types.d.ts +6 -6
  90. package/search-response-receipt-types.d.ts +135 -34
  91. package/search-response-types.d.ts +2 -2
  92. package/search-result-validation.d.ts +3 -3
  93. package/search-result-validation.js +53 -36
  94. package/search-window-types.d.ts +2 -2
  95. package/slot-pool-types.d.ts +20 -20
  96. package/source-material-validation.d.ts +3 -3
  97. package/source-material-validation.js +35 -39
  98. package/spec-facet-types.d.ts +10 -10
  99. package/spec-types.d.ts +6 -6
  100. package/specifications.d.ts +9 -25
  101. package/specifications.js +15 -21
  102. package/sse.d.ts +2 -2
  103. package/sse.js +32 -16
  104. package/substitute-types.d.ts +22 -22
  105. package/suggest-types.d.ts +7 -7
  106. package/suggest-types.js +3 -3
  107. package/taxonomy-coverage-types.d.ts +8 -8
  108. package/types.d.ts +119 -119
  109. package/validation.d.ts +26 -26
  110. package/validation.js +97 -92
  111. package/webmcp.d.ts +2 -2
  112. package/webmcp.generated.js +94 -87
  113. package/project-types.d.ts +0 -79
  114. package/project-types.js +0 -9
  115. package/projects.d.ts +0 -13
  116. package/projects.js +0 -46
  117. package/run-events.d.ts +0 -106
  118. package/run-events.js +0 -32
  119. package/schedule-reference-types.d.ts +0 -46
  120. package/schedule-reference-types.js +0 -1
  121. package/schedule-references-client.d.ts +0 -14
  122. package/schedule-references-client.js +0 -26
  123. package/schedule-types.d.ts +0 -261
  124. package/schedule-types.js +0 -1
@@ -5,35 +5,61 @@
5
5
  */
6
6
  import type { OpenEnum } from "./types.js";
7
7
  /** Inspectable metadata for an opaque, principal-bound search refinement receipt. */
8
- export interface SearchRefinementReceipt {
8
+ export type SearchRefinementReceipt = {
9
9
  token: string;
10
10
  expiresAt: string;
11
11
  poolSize: number;
12
12
  schemaVersion: string;
13
13
  projectionVersion: number;
14
- }
14
+ };
15
15
  /** The primary ranking source a query resolved to and reports as its mode. */
16
- export type SearchMode = OpenEnum<"image" | "colour" | "text" | "lexical" | "entity-browse">;
16
+ export type SearchMode = OpenEnum<"image" | "colour" | "text" | "lexical" | "entity-browse" | "agent">;
17
17
  /**
18
18
  * Compatibility receipt for non-mode colour handling. Current one-signal
19
19
  * ordering reports it skipped at weight 0; colour may still be diagnostic or a
20
20
  * hard displayed-image constraint, but does not blend into score.
21
21
  */
22
- export interface SearchRerankReport {
22
+ export type SearchRerankReport = {
23
23
  colour?: OpenEnum<"ok" | "failed" | "skipped">;
24
24
  colourWeight?: number;
25
25
  colourLabel?: string;
26
- }
27
- /** Stage counts retained when an explain-enabled search returns no results. */
28
- export interface SearchEmptyOutcomeCounts {
26
+ };
27
+ /**
28
+ * A part of the search that can fail without stopping it.
29
+ *
30
+ * Coarse on purpose: a caller needs to know that something did not answer, not
31
+ * which provider it was. OPEN, and it will grow — read it with a default
32
+ * branch.
33
+ */
34
+ export type SearchDegradedPart = OpenEnum<"filter-coverage" | "term-coverage">;
35
+ /**
36
+ * Which parts of the search did not answer, on EVERY response (MG-1913).
37
+ *
38
+ * `parts: []` says no part reported a failure. It does NOT promise every check
39
+ * ran: a check the request never needed is skipped rather than failed. ABSENT
40
+ * means the response came from a server that does not report this, never that
41
+ * nothing was degraded.
42
+ */
43
+ export type SearchDegraded = {
44
+ parts: SearchDegradedPart[];
45
+ };
46
+ /** Stage counts retained when a search returns no results. */
47
+ export type SearchEmptyOutcomeCounts = {
29
48
  retrieved: number;
30
49
  afterPrune: number;
31
50
  final: number;
32
- }
51
+ };
33
52
  /**
34
- * Explain-only evidence for why a completed search returned no results.
35
- * `proven-corpus-empty` is exhaustive; every other empty remains explicitly
36
- * unproven rather than being presented as catalogue absence.
53
+ * Why a search returned no results, on EVERY empty response (MG-1911).
54
+ *
55
+ * `proven-corpus-empty` is exhaustive and is the only member that supports
56
+ * telling someone the catalogue holds nothing. `unproven-empty` is an honest
57
+ * end to a search that ran without establishing that. `search-degraded` means
58
+ * part of the search did not answer, so the empty page describes the runtime
59
+ * rather than the catalogue, and the right response is to retry.
60
+ *
61
+ * Read it by `kind` with a default branch: this union has grown once and the
62
+ * reason and basis enums are open.
37
63
  */
38
64
  export type SearchEmptyOutcome = {
39
65
  kind: "proven-corpus-empty";
@@ -46,18 +72,93 @@ export type SearchEmptyOutcome = {
46
72
  reason: OpenEnum<"allowlist-truncated" | "retrieval-window-not-exhaustive" | "source-empty" | "post-retrieval-rejected" | "pagination-empty" | "no-authoritative-empty-proof">;
47
73
  sourceEmpty?: boolean | null;
48
74
  counts?: SearchEmptyOutcomeCounts;
75
+ } | {
76
+ kind: "search-degraded";
77
+ /** Which parts did not answer. Coarse: never a provider's name. */
78
+ parts: SearchDegradedPart[];
79
+ sourceEmpty?: boolean | null;
80
+ counts?: SearchEmptyOutcomeCounts;
49
81
  };
50
82
  /** Explain-only coverage of substantive query terms in the lexical projection. */
51
- export interface SearchTermCoverageReceipt {
83
+ /**
84
+ * Which of the query's substantive words the catalogue holds at all
85
+ * (MG-1858), on every text-family response. `terms` names the words found in
86
+ * no document; `checkedTerms` is how many were asked about; `noneMatched` is
87
+ * true when no checked word is attested anywhere. `unavailable` means the read
88
+ * failed and never means everything matched; `skipped` means this mode never
89
+ * claimed to match words.
90
+ */
91
+ export type SearchTermCoverageReceipt = {
52
92
  status: OpenEnum<"covered" | "uncovered" | "unavailable" | "skipped">;
53
93
  terms: string[];
94
+ checkedTerms: number;
95
+ noneMatched: boolean;
54
96
  note?: string;
55
- }
56
- /** Explain-only outcome receipts shared by full and card search responses. */
57
- export interface SearchResponseExplainReceipts {
97
+ };
98
+ /** The Search workflow run a ledger receipt belongs to. */
99
+ export type SearchRunRef = {
100
+ contextId: string;
101
+ runId: string;
102
+ schemaVersion: 1;
103
+ };
104
+ /** One artifact a Search workflow step read or wrote. */
105
+ export type SearchRunArtifactRef = {
106
+ artifactId: string;
107
+ kind: string;
108
+ producedBy: string;
109
+ runRef: SearchRunRef;
110
+ schemaVersion: 1;
111
+ };
112
+ /** What one Search workflow step did: its reads, its write and its time. */
113
+ export type SearchStageReceipt = {
114
+ stageId: string;
115
+ status: "succeeded";
116
+ /** The step's own work, excluding reading and writing its artifacts. */
117
+ durationMs: number;
118
+ inputArtifacts: SearchRunArtifactRef[];
119
+ outputArtifact: SearchRunArtifactRef;
120
+ inputCount: number | null;
121
+ outputCount: number | null;
122
+ runRef: SearchRunRef;
123
+ /** The outcome the step chose, when it chooses one. */
124
+ outcome?: string;
125
+ /** The arm a fork took and why. */
126
+ branch?: {
127
+ decision: string;
128
+ reason: string;
129
+ };
130
+ };
131
+ /** One ledger line: a step's receipt and its span since the run opened. */
132
+ export type SearchRunLedgerEntry = {
133
+ receipt: SearchStageReceipt;
134
+ /** The nested workflows the step ran under, outermost first. */
135
+ workflowPath: string[];
136
+ startedAtMs: number;
137
+ endedAtMs: number;
138
+ };
139
+ /**
140
+ * Outcome receipts shared by full and card search responses. `degraded`,
141
+ * `emptyOutcome` and `termCoverage` are on every response; `diagnostics` and
142
+ * `explain` are explain-only.
143
+ */
144
+ export type SearchResponseExplainReceipts = {
145
+ degraded?: SearchDegraded;
58
146
  emptyOutcome?: SearchEmptyOutcome;
59
147
  termCoverage?: SearchTermCoverageReceipt;
60
- }
148
+ /**
149
+ * The engine's notes written for an engineer (tier timings, cache states,
150
+ * index names), under `explain` only. `note` carries the reader's sentences
151
+ * alone (MG-1919).
152
+ */
153
+ diagnostics?: string[];
154
+ /**
155
+ * Present under `explain` when the Search workflow answered the request:
156
+ * every step receipt, in completion order. Absent when the engine answered.
157
+ */
158
+ explain?: {
159
+ ledger: readonly SearchRunLedgerEntry[];
160
+ };
161
+ };
61
162
  /** One stage in the explain-only ledger of transformations that actually ran. */
62
163
  export type SearchQueryTransformStage = {
63
164
  stage: OpenEnum<"normalise" | "resolve-spec" | "resolve-paint" | "resolve-brand">;
@@ -68,7 +169,7 @@ export type SearchQueryTransformStage = {
68
169
  reason: string;
69
170
  };
70
171
  /** Explain-only category gate selected by query understanding. */
71
- export interface SearchCategoryAnchor {
172
+ export type SearchCategoryAnchor = {
72
173
  /**
73
174
  * A leaf type id; the group key when `source` is `"group"`; or the canonical
74
175
  * category noun when `source` is `"head-noun"`. Gate on `productTypeIds`.
@@ -86,9 +187,9 @@ export interface SearchCategoryAnchor {
86
187
  /** Hard category eligibility is applied inside lexical candidate selection. */
87
188
  candidateSource?: OpenEnum<"lexical">;
88
189
  applied: boolean;
89
- }
190
+ };
90
191
  /** Explain-only brand gate selected by query understanding. */
91
- export interface SearchBrandAnchor {
192
+ export type SearchBrandAnchor = {
92
193
  brandSlug: string;
93
194
  brandName: string;
94
195
  confidence: number;
@@ -96,18 +197,18 @@ export interface SearchBrandAnchor {
96
197
  tier: OpenEnum<"exact_id" | "exact_alias" | "lexical" | "semantic">;
97
198
  variantCount: number;
98
199
  applied: boolean;
99
- }
200
+ };
100
201
  /** A real brand candidate the engine deliberately declined to gate on. */
101
- export interface SearchBrandSkip {
202
+ export type SearchBrandSkip = {
102
203
  reason: OpenEnum<"ambiguous" | "weak-tier" | "too-broad">;
103
204
  candidates?: string[];
104
- }
205
+ };
105
206
  /**
106
207
  * EXPLAIN-only receipt of the query shape that executed. This is distinct from
107
208
  * the separate Search Plan compiler operation: it reports execution and never
108
209
  * causes it.
109
210
  */
110
- export interface SearchExecutionPlan {
211
+ export type SearchExecutionPlan = {
111
212
  grain: OpenEnum<"variant" | "product">;
112
213
  /** Which 2048D Voyage projection served a text-mode request. */
113
214
  textLane?: OpenEnum<"image-text" | "variant-text">;
@@ -121,30 +222,30 @@ export interface SearchExecutionPlan {
121
222
  };
122
223
  queryTransform: SearchQueryTransformStage[];
123
224
  /** Ordered, explain-only request-understanding execution trace. */
124
- steps?: Array<{
225
+ steps?: {
125
226
  key: string;
126
227
  status: OpenEnum<"executed" | "skipped">;
127
228
  reason: string;
128
229
  durationMs: number;
129
- }>;
230
+ }[];
130
231
  categoryAnchor?: SearchCategoryAnchor;
131
232
  brandAnchor?: SearchBrandAnchor;
132
233
  brandSkipped?: SearchBrandSkip;
133
- }
234
+ };
134
235
  /** Why a compound colour constraint returned a full or short page. */
135
- export interface CompoundColourAbundanceReceipt {
236
+ export type CompoundColourAbundanceReceipt = {
136
237
  grain: OpenEnum<"variant" | "product">;
137
238
  requested: number;
138
239
  eligible: number;
139
240
  candidateWindow: number;
140
241
  sourceExhausted: boolean;
141
242
  state: OpenEnum<"filled" | "corpus_scarcity" | "evidence_unavailable" | "retrieval_window_exhausted">;
142
- }
243
+ };
143
244
  /**
144
245
  * Eligibility proof for an explicit or taxonomy-backed colour inside a compound
145
246
  * text query. Counts describe the bounded candidate pool, not the whole corpus.
146
247
  */
147
- export interface CompoundColourConstraintReceipt {
248
+ export type CompoundColourConstraintReceipt = {
148
249
  basis: OpenEnum<"explicit" | "detected-strong">;
149
250
  family: string;
150
251
  queryHexes: string[];
@@ -154,21 +255,21 @@ export interface CompoundColourConstraintReceipt {
154
255
  unknown: number;
155
256
  adjacent: number;
156
257
  abundance?: CompoundColourAbundanceReceipt;
157
- }
258
+ };
158
259
  /** Why a hard form constraint returned a full or short page. */
159
- export interface CompoundFormAbundanceReceipt {
260
+ export type CompoundFormAbundanceReceipt = {
160
261
  grain: OpenEnum<"variant" | "product">;
161
262
  requested: number;
162
263
  eligible: number;
163
264
  candidateWindow: number;
164
265
  sourceExhausted: boolean;
165
266
  state: OpenEnum<"filled" | "corpus_scarcity" | "evidence_unavailable" | "retrieval_window_exhausted">;
166
- }
267
+ };
167
268
  /**
168
269
  * Hard form eligibility for a compound text query. Product and variant names
169
270
  * may retrieve a candidate but never prove that it satisfies the form.
170
271
  */
171
- export interface CompoundFormConstraintReceipt {
272
+ export type CompoundFormConstraintReceipt = {
172
273
  instruction: OpenEnum<"subway" | "plank" | "square" | "hexagon" | "penny-round">;
173
274
  considered: number;
174
275
  kept: number;
@@ -176,4 +277,4 @@ export interface CompoundFormConstraintReceipt {
176
277
  contradicted: number;
177
278
  unknown: number;
178
279
  abundance: CompoundFormAbundanceReceipt;
179
- }
280
+ };
@@ -1,6 +1,6 @@
1
1
  import type { SearchData } from "./types.js";
2
2
  /** Canonical Search wire response. Raw SDK methods preserve this envelope. */
3
- export interface SearchResponse {
3
+ export type SearchResponse = {
4
4
  data: SearchData;
5
5
  meta: {
6
6
  operationId: "search_materials_post" | "search_materials_get";
@@ -8,4 +8,4 @@ export interface SearchResponse {
8
8
  };
9
9
  links: Record<string, never>;
10
10
  warnings: never[];
11
- }
11
+ };
@@ -1,4 +1,4 @@
1
- import { type ValidationFailure } from "./validation.js";
1
+ import type { ValidationFailure } from "./validation.js";
2
2
  /** `verdictStateSchema` — the six live cell states. */
3
3
  export declare const VERDICT_STATES: readonly ["matched", "deviated", "failed", "unverified", "missing", "not_evaluated"];
4
4
  /** `attributeVerdictSchema.strength`. */
@@ -22,6 +22,6 @@ export declare const VISUAL_MEANING_BASES: readonly ["canonical_attribute", "ima
22
22
  * contract (nothing on the emit path parses, so stripping would invent a
23
23
  * normalisation the wire never had).
24
24
  */
25
- export declare function checkSearchResultItem(value: unknown, what: string, fail: ValidationFailure): void;
25
+ export declare const checkSearchResultItem: (value: unknown, what: string, fail: ValidationFailure) => void;
26
26
  /** Prove every entry of a `results[]` array is a {@link SearchResultItem}. */
27
- export declare function checkSearchResultItems(items: readonly unknown[], what: string, fail: ValidationFailure): void;
27
+ export declare const checkSearchResultItems: (items: readonly unknown[], what: string, fail: ValidationFailure) => void;
@@ -41,20 +41,21 @@ export const VISUAL_MEANING_BASES = [
41
41
  ];
42
42
  // ── Leaf checks ──────────────────────────────────────────────────────────────
43
43
  /** `palette[]` — `{ hex, proportion, name: string.nullable().optional() }`. */
44
- function checkPaletteSwatch(value, what, fail) {
44
+ const checkPaletteSwatch = (value, what, fail) => {
45
45
  const record = requireRecord(value, what, fail);
46
46
  requireString(record.hex, `${what}.hex`, fail);
47
47
  requireNumber(record.proportion, `${what}.proportion`, fail);
48
48
  // `.nullable().optional()` — absent OR null OR a string.
49
- if (record.name !== undefined)
49
+ if (record.name !== undefined) {
50
50
  requireNullableString(record.name, `${what}.name`, fail);
51
- }
51
+ }
52
+ };
52
53
  /**
53
54
  * `variants[]` — one entry of a product-collapsed result's ranked variant list
54
55
  * (`collapsedVariantSchema`). A SLIM projection, not a nested result item: the
55
56
  * checks here are the whole shape.
56
57
  */
57
- function checkCollapsedVariant(value, what, fail) {
58
+ const checkCollapsedVariant = (value, what, fail) => {
58
59
  const record = requireRecord(value, what, fail);
59
60
  requireString(record.variantId, `${what}.variantId`, fail);
60
61
  requireNullableString(record.variantName, `${what}.variantName`, fail);
@@ -65,16 +66,16 @@ function checkCollapsedVariant(value, what, fail) {
65
66
  requireNullableString(record.imageUrl, `${what}.imageUrl`, fail);
66
67
  requireOptionalString(record.materialBankId, `${what}.materialBankId`, fail);
67
68
  requireNumber(record.score, `${what}.score`, fail);
68
- }
69
+ };
69
70
  /** `colourMeta` — three independently optional strings. */
70
- function checkColourMeta(value, what, fail) {
71
+ const checkColourMeta = (value, what, fail) => {
71
72
  const record = requireRecord(value, what, fail);
72
73
  requireOptionalString(record.mood, `${what}.mood`, fail);
73
74
  requireOptionalString(record.dominantFamily, `${what}.dominantFamily`, fail);
74
75
  requireOptionalString(record.dominantHex, `${what}.dominantHex`, fail);
75
- }
76
+ };
76
77
  /** `searchResultSignalsSchema` — five required scores plus additive portrait. */
77
- function checkSignals(value, what, fail) {
78
+ const checkSignals = (value, what, fail) => {
78
79
  const record = requireRecord(value, what, fail);
79
80
  if (record.portrait !== undefined) {
80
81
  requireNullableNumber(record.portrait, `${what}.portrait`, fail);
@@ -82,9 +83,9 @@ function checkSignals(value, what, fail) {
82
83
  for (const signal of ["image", "category", "colour", "lexical", "text"]) {
83
84
  requireNullableNumber(record[signal], `${what}.${signal}`, fail);
84
85
  }
85
- }
86
+ };
86
87
  /** `visualMeaningSchema` — note the NON-EMPTY `values` array and the closed `basis`. */
87
- function checkVisualMeaning(value, what, fail) {
88
+ const checkVisualMeaning = (value, what, fail) => {
88
89
  const record = requireRecord(value, what, fail);
89
90
  requireString(record.id, `${what}.id`, fail);
90
91
  requireString(record.label, `${what}.label`, fail);
@@ -94,39 +95,43 @@ function checkVisualMeaning(value, what, fail) {
94
95
  requireOptionalString(record.sourceBasis, `${what}.sourceBasis`, fail);
95
96
  requireOptionalString(record.version, `${what}.version`, fail);
96
97
  requireOptionalString(record.appliedAt, `${what}.appliedAt`, fail);
97
- }
98
+ };
98
99
  // ── Verdict subtree ──────────────────────────────────────────────────────────
99
100
  /**
100
101
  * `verdictBaselineSchema` — a discriminated union on `kind`. An unknown
101
102
  * discriminant is rejected, exactly as `z.discriminatedUnion` rejects it, and
102
103
  * each arm carries only the fields it needs.
103
104
  */
104
- function checkVerdictBaseline(value, what, fail) {
105
+ const checkVerdictBaseline = (value, what, fail) => {
105
106
  const record = requireRecord(value, what, fail);
106
107
  const kind = requireEnum(record.kind, VERDICT_BASELINE_KINDS, `${what}.kind`, fail);
107
108
  switch (kind) {
108
- case "term":
109
+ case "term": {
109
110
  requireNonEmptyString(record.term, `${what}.term`, fail);
111
+ break;
112
+ }
113
+ case "presence": {
110
114
  return;
111
- case "presence":
112
- return;
113
- case "seed":
115
+ }
116
+ case "seed": {
114
117
  requireNonEmptyString(record.variantId, `${what}.variantId`, fail);
115
118
  return;
116
- default:
119
+ }
120
+ default: {
117
121
  // `image` — the like-this-picture arm.
118
122
  requireEnum(record.source, VERDICT_IMAGE_SOURCES, `${what}.source`, fail);
119
123
  requireNullableNonEmptyString(record.variantId, `${what}.variantId`, fail);
124
+ }
120
125
  }
121
- }
126
+ };
122
127
  /** `verdictDeviationSchema` — a named near-miss. */
123
- function checkVerdictDeviation(value, what, fail) {
128
+ const checkVerdictDeviation = (value, what, fail) => {
124
129
  const record = requireRecord(value, what, fail);
125
130
  requireEnum(record.direction, VERDICT_DEVIATION_DIRECTIONS, `${what}.direction`, fail);
126
131
  requireNullableNumber(record.delta, `${what}.delta`, fail);
127
132
  requireNullableString(record.unit, `${what}.unit`, fail);
128
133
  requireNonEmptyString(record.label, `${what}.label`, fail);
129
- }
134
+ };
130
135
  /**
131
136
  * `attributeVerdictSchema` — nine fields plus the TWO cross-field invariants its
132
137
  * `.superRefine()` enforces. Those are relational rather than field-wise, which
@@ -134,7 +139,7 @@ function checkVerdictDeviation(value, what, fail) {
134
139
  * schema's own doc calls them out as the reason a malformed cell can never reach
135
140
  * a consumer.
136
141
  */
137
- function checkAttributeVerdict(value, what, fail) {
142
+ const checkAttributeVerdict = (value, what, fail) => {
138
143
  const record = requireRecord(value, what, fail);
139
144
  requireNonEmptyString(record.attributeId, `${what}.attributeId`, fail);
140
145
  const state = requireEnum(record.state, VERDICT_STATES, `${what}.state`, fail);
@@ -152,9 +157,10 @@ function checkAttributeVerdict(value, what, fail) {
152
157
  throw fail(`${what}.citation.count must be a positive integer`);
153
158
  }
154
159
  }
155
- const deviation = record.deviation;
156
- if (deviation !== null)
160
+ const { deviation } = record;
161
+ if (deviation !== null) {
157
162
  checkVerdictDeviation(deviation, `${what}.deviation`, fail);
163
+ }
158
164
  const trustGap = requireNullableEnum(record.trustGap, VERDICT_TRUST_GAPS, `${what}.trustGap`, fail);
159
165
  // superRefine invariant 1 — a deviation only describes a `deviated` cell.
160
166
  if (deviation !== null && state !== "deviated") {
@@ -164,15 +170,17 @@ function checkAttributeVerdict(value, what, fail) {
164
170
  if (trustGap !== null && state !== "unverified") {
165
171
  throw fail(`${what}.trustGap is set on a cell whose state is "${state}", not "unverified"`);
166
172
  }
167
- }
173
+ };
168
174
  /** `candidateVerdictSchema` — the whole report card. */
169
- function checkCandidateVerdict(value, what, fail) {
175
+ const checkCandidateVerdict = (value, what, fail) => {
170
176
  const record = requireRecord(value, what, fail);
171
177
  const cells = requireArray(record.cells, `${what}.cells`, fail);
172
- cells.forEach((cell, index) => checkAttributeVerdict(cell, `${what}.cells[${index}]`, fail));
178
+ cells.forEach((cell, index) => {
179
+ checkAttributeVerdict(cell, `${what}.cells[${index}]`, fail);
180
+ });
173
181
  requireEnum(record.grade, VERDICT_GRADES, `${what}.grade`, fail);
174
182
  requireNullableBoundedNumber(record.minConfidence, `${what}.minConfidence`, fail, 0, 1);
175
- }
183
+ };
176
184
  // ── The item ─────────────────────────────────────────────────────────────────
177
185
  /**
178
186
  * Prove one wire value is a {@link SearchResultItem}, raising through `fail` at
@@ -181,7 +189,7 @@ function checkCandidateVerdict(value, what, fail) {
181
189
  * contract (nothing on the emit path parses, so stripping would invent a
182
190
  * normalisation the wire never had).
183
191
  */
184
- export function checkSearchResultItem(value, what, fail) {
192
+ export const checkSearchResultItem = (value, what, fail) => {
185
193
  const record = requireRecord(value, what, fail);
186
194
  requireString(record.variantId, `${what}.variantId`, fail);
187
195
  requireString(record.brand, `${what}.brand`, fail);
@@ -209,12 +217,15 @@ export function checkSearchResultItem(value, what, fail) {
209
217
  requireBoolean(record.hasImage, `${what}.hasImage`, fail);
210
218
  requireNumber(record.score, `${what}.score`, fail);
211
219
  const palette = requireArray(record.palette, `${what}.palette`, fail);
212
- palette.forEach((swatch, index) => checkPaletteSwatch(swatch, `${what}.palette[${index}]`, fail));
220
+ palette.forEach((swatch, index) => {
221
+ checkPaletteSwatch(swatch, `${what}.palette[${index}]`, fail);
222
+ });
213
223
  if (record.colourMeta !== undefined) {
214
224
  checkColourMeta(record.colourMeta, `${what}.colourMeta`, fail);
215
225
  }
216
- if (record.signals !== undefined)
226
+ if (record.signals !== undefined) {
217
227
  checkSignals(record.signals, `${what}.signals`, fail);
228
+ }
218
229
  requireOptionalBoolean(record.retired, `${what}.retired`, fail);
219
230
  requireOptionalBoolean(record.sampleable, `${what}.sampleable`, fail);
220
231
  requireOptionalBoolean(record.belowFloor, `${what}.belowFloor`, fail);
@@ -224,17 +235,23 @@ export function checkSearchResultItem(value, what, fail) {
224
235
  }
225
236
  if (record.variants !== undefined) {
226
237
  const variants = requireArray(record.variants, `${what}.variants`, fail);
227
- variants.forEach((variant, index) => checkCollapsedVariant(variant, `${what}.variants[${index}]`, fail));
238
+ variants.forEach((variant, index) => {
239
+ checkCollapsedVariant(variant, `${what}.variants[${index}]`, fail);
240
+ });
228
241
  }
229
242
  if (record.visualMeanings !== undefined) {
230
243
  const meanings = requireArray(record.visualMeanings, `${what}.visualMeanings`, fail);
231
- meanings.forEach((meaning, index) => checkVisualMeaning(meaning, `${what}.visualMeanings[${index}]`, fail));
244
+ meanings.forEach((meaning, index) => {
245
+ checkVisualMeaning(meaning, `${what}.visualMeanings[${index}]`, fail);
246
+ });
232
247
  }
233
248
  if (record.verdict !== undefined) {
234
249
  checkCandidateVerdict(record.verdict, `${what}.verdict`, fail);
235
250
  }
236
- }
251
+ };
237
252
  /** Prove every entry of a `results[]` array is a {@link SearchResultItem}. */
238
- export function checkSearchResultItems(items, what, fail) {
239
- items.forEach((item, index) => checkSearchResultItem(item, `${what}[${index}]`, fail));
240
- }
253
+ export const checkSearchResultItems = (items, what, fail) => {
254
+ items.forEach((item, index) => {
255
+ checkSearchResultItem(item, `${what}[${index}]`, fail);
256
+ });
257
+ };
@@ -1,5 +1,5 @@
1
1
  /** The bounded candidate window that produced a search page. */
2
- export interface SearchWindowReceipt {
2
+ export type SearchWindowReceipt = {
3
3
  /** Versioned budget profile; interpret the remaining fields under this version. */
4
4
  profile: "interactive-r1" | (string & {});
5
5
  /** Candidate depth used by the final retrieval. */
@@ -22,4 +22,4 @@ export interface SearchWindowReceipt {
22
22
  /** Canonical candidates returned by the selected retrieval arm. */
23
23
  hydratedCanonicalCandidates: number;
24
24
  };
25
- }
25
+ };