@instruments/materialgraph 0.6.0 → 0.6.1

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/brand-types.d.ts CHANGED
@@ -1,7 +1,16 @@
1
- /** Query options and wire types for the canonical brands collection. */
1
+ /**
2
+ * Query options and wire types for the canonical brands collection
3
+ * (`GET /api/v1/brands`).
4
+ *
5
+ * The SDK's one OFFSET-paginated surface — everything else that pages uses an
6
+ * opaque cursor. `meta` is where the page/corpus distinction is settled here.
7
+ */
2
8
  export interface BrandsOptions {
9
+ /** Fuzzy name filter. Omit for the whole collection. */
3
10
  q?: string;
11
+ /** Page size. Never a bound on the collection. */
4
12
  limit?: number;
13
+ /** Row offset for the next page. Paired with `meta.hasMore`. */
5
14
  offset?: number;
6
15
  }
7
16
  export interface BrandCatalogListItem {
@@ -10,11 +19,21 @@ export interface BrandCatalogListItem {
10
19
  name: string;
11
20
  primaryMarketSegment: string;
12
21
  homepageUrl: string | null;
22
+ /** Products INGESTED into MaterialGraph, not the brand's own catalog size. */
13
23
  productCount: number;
24
+ /** Variants ingested into MaterialGraph. A coverage figure, not a claim about the brand. */
14
25
  variantCount: number;
15
26
  }
16
27
  export interface BrandCatalogListPage {
28
+ /** THIS PAGE. Its length is `meta.count`, never `meta.total`. */
17
29
  items: BrandCatalogListItem[];
30
+ /**
31
+ * A PAGE IS NOT A CORPUS, spelled out:
32
+ * - `count` — items on THIS page.
33
+ * - `total` — brands matching the query overall. The number to quote.
34
+ * - `limit` / `offset` — the window that produced this page.
35
+ * - `hasMore` — whether another page exists. Keep walking while true.
36
+ */
18
37
  meta: {
19
38
  count: number;
20
39
  total: number;
package/brand-types.js CHANGED
@@ -1 +1,8 @@
1
+ /**
2
+ * Query options and wire types for the canonical brands collection
3
+ * (`GET /api/v1/brands`).
4
+ *
5
+ * The SDK's one OFFSET-paginated surface — everything else that pages uses an
6
+ * opaque cursor. `meta` is where the page/corpus distinction is settled here.
7
+ */
1
8
  export {};
@@ -1,9 +1,33 @@
1
+ import type { VariantId } from "./identifiers.js";
2
+ /**
3
+ * One criterion a match satisfied, with the trust behind it.
4
+ *
5
+ * `confidence` (0–1) and `sourceBasis` are the CLAIM's provenance, not decoration
6
+ * — quote them wherever the value is quoted. A `null` on either means the trust
7
+ * is unrecorded, which is weaker than a low number, not stronger.
8
+ */
1
9
  export interface BySpecMatchedCell {
2
10
  attributeId: string;
3
11
  confidence: number | null;
4
12
  sourceBasis: string | null;
5
13
  }
6
- /** The six states a verdict cell can report; open per the response-enum policy. */
14
+ /**
15
+ * The six states a verdict cell can report — and what each licenses you to say.
16
+ *
17
+ * - `matched` — an accepted value satisfies the criterion. Claimable.
18
+ * - `deviated` — an accepted value is directionally off, and `deviation` names
19
+ * by how much. Claimable WITH the deviation, never as a plain pass.
20
+ * - `failed` — an accepted value exists and does not satisfy the criterion. A
21
+ * real negative: this material does not meet it.
22
+ * - `unverified` — a real value exists but did not clear the trust bar
23
+ * (`trustGap` says which). NOT a failure and NOT a pass — say "on record but
24
+ * unverified".
25
+ * - `missing` — no accepted value to evaluate. UNKNOWN, never "does not have
26
+ * it". This is the absent-is-not-false state.
27
+ * - `not_evaluated` — the engine did not check. Says nothing about the material.
28
+ *
29
+ * Only `failed` supports a negative claim. `missing` and `unverified` do not.
30
+ */
7
31
  export type BySpecVerdictState = "matched" | "deviated" | "failed" | "unverified" | "missing" | "not_evaluated";
8
32
  /**
9
33
  * One cell of a match's report card — how a single requested criterion scored.
@@ -27,6 +51,7 @@ export interface BySpecVerdictCell {
27
51
  source: "variant" | "vector";
28
52
  variantId: string | null;
29
53
  };
54
+ /** The candidate's own accepted value, or null when there is none to report. */
30
55
  value: string | null;
31
56
  deviation: {
32
57
  direction: "above" | "below" | "other";
@@ -34,11 +59,30 @@ export interface BySpecVerdictCell {
34
59
  unit: string | null;
35
60
  label: string;
36
61
  } | null;
62
+ /** Trust in `value`, 0–1. Null = unrecorded, which is weaker than a low score. */
37
63
  confidence: number | null;
64
+ /** Where `value` came from (`tested` > `declared` > `catalog_feed` > `derived`). */
38
65
  sourceBasis: string | null;
66
+ /**
67
+ * Why an `unverified` cell missed the bar; null otherwise.
68
+ * - `below_confidence` — the value is real but scored under the floor.
69
+ * - `basis_unmet` — the value's source is weaker than the criterion demanded.
70
+ * - `proposed` — the value is awaiting acceptance and is not yet on record.
71
+ */
39
72
  trustGap: "below_confidence" | "basis_unmet" | "proposed" | null;
40
73
  }
41
- /** A match's full report card: every cell, the rolled-up grade, weakest confidence. */
74
+ /**
75
+ * A match's full report card: every cell, the rolled-up grade, weakest confidence.
76
+ *
77
+ * `grade` folds `cells` and is deliberately conservative:
78
+ * - `meets_all` — every REQUIRED cell is `matched`. All-green, nothing else.
79
+ * - `close` — no required cell `failed`, but something is `deviated`,
80
+ * `unverified` or `missing`. Present the gap, never round it up to a pass.
81
+ * - `hard_no` — at least one required cell `failed` on a real value.
82
+ *
83
+ * `minConfidence` is the WEAKEST cell's confidence — the honest ceiling on the
84
+ * whole card, not an average. Quote it alongside the grade.
85
+ */
42
86
  export interface BySpecVerdict {
43
87
  cells: BySpecVerdictCell[];
44
88
  grade: "meets_all" | "close" | "hard_no";
@@ -51,7 +95,8 @@ export interface BySpecVerdict {
51
95
  */
52
96
  export type MaterialVerdict = BySpecVerdict;
53
97
  export interface BySpecMatch {
54
- variantId: string;
98
+ /** Opaque — round-trip verbatim. */
99
+ variantId: VariantId;
55
100
  brand: string;
56
101
  product: string;
57
102
  variant: string;
@@ -62,12 +107,26 @@ export interface BySpecMatch {
62
107
  minConfidence: number | null;
63
108
  verdict: BySpecVerdict;
64
109
  }
110
+ /**
111
+ * The find-by-spec envelope — A PAGE, AND NOTHING BUT A PAGE.
112
+ *
113
+ * Read `totalMatches` carefully: despite the name it is the route's own words,
114
+ * "Size of the returned (limited) sample, not the true corpus total" — it is
115
+ * literally `matches.length` under the `limit` you asked for. This surface
116
+ * states NO corpus total, so "N materials meet this specification" is not a
117
+ * claim you can make from one response. Raise `limit`, or say "at least N".
118
+ * `brandsSpanned` is likewise the brand count OF THIS SAMPLE.
119
+ */
65
120
  export interface BySpecResponse {
121
+ /** The criteria as parsed — check them before trusting a surprising result. */
66
122
  criteria: Array<{
67
123
  attribute: string;
68
124
  value: string;
69
125
  }>;
126
+ /** `matches.length`, i.e. THIS SAMPLE under `limit`. Never a corpus total. */
70
127
  totalMatches: number;
128
+ /** Distinct brands in the returned sample — a lower bound on cross-brand reach. */
71
129
  brandsSpanned: number;
130
+ /** The sample, photo-first, capped by `limit`. */
72
131
  matches: BySpecMatch[];
73
132
  }
@@ -1,10 +1,20 @@
1
- /** Catalog value-discovery contracts mirrored from the canonical HTTP routes. */
1
+ /**
2
+ * Catalog value-discovery contracts mirrored from the canonical HTTP routes.
3
+ *
4
+ * THE LENS: turning a HUMAN PHRASE into the canonical vocabulary the spec
5
+ * surfaces accept. Nothing here returns materials — it returns the tokens you
6
+ * then spend on `mg.bySpec()` or `mg.search({ filters })`.
7
+ */
2
8
  import type { OpenEnum } from "./types.js";
3
9
  /** Options for resolving a free-text value against one attribute's dictionary. */
4
10
  export interface ResolveAttributeValueOptions {
5
11
  limit?: number;
6
12
  }
7
- /** One ranked canonical value candidate. */
13
+ /**
14
+ * One ranked canonical value candidate. `tier` says HOW it matched, strongest
15
+ * first: `exact_id` > `exact_alias` > `lexical` > `semantic`. A `semantic` hit
16
+ * is a guess worth confirming, not an equivalence.
17
+ */
8
18
  export interface ResolveValueCandidate {
9
19
  id: string;
10
20
  label: string;
@@ -21,6 +31,13 @@ export interface ResolveAttributeValueResponse {
21
31
  name: string;
22
32
  dictionaryId: string;
23
33
  };
34
+ /**
35
+ * READ `recommendedAction`, NOT JUST `best`. `ambiguous` with a populated
36
+ * `candidates` list means the phrase genuinely matched several terms — taking
37
+ * `best` silently there is how a query ends up answering a question nobody
38
+ * asked. `unresolved` means the vocabulary holds nothing like it, which is not
39
+ * the same as the corpus holding no such materials.
40
+ */
24
41
  resolution: {
25
42
  status: OpenEnum<"resolved" | "ambiguous" | "unresolved">;
26
43
  query: string;
@@ -10,7 +10,13 @@
10
10
  * testing on its own.
11
11
  */
12
12
  import type { BrowseParams, BrowseResponse } from "./types.js";
13
- /** `client.browse(...)` — callable for one page, `.pages()` for the whole walk. */
13
+ /**
14
+ * `client.browse(...)` — callable for ONE PAGE, `.pages()` for the whole walk.
15
+ *
16
+ * The distinction is the whole point: the single-call form hands you a page and
17
+ * states no total, so a corpus claim can only come from `.pages()`. Never report
18
+ * one page's length as "how many materials there are".
19
+ */
14
20
  export interface BrowseNamespace {
15
21
  (params: BrowseParams, signal?: AbortSignal): Promise<BrowseResponse>;
16
22
  pages(params: BrowseParams, signal?: AbortSignal): AsyncGenerator<BrowseResponse, void, unknown>;