@thehammer/template-verification 0.2.9 → 0.2.11

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/dist/types.d.ts CHANGED
@@ -60,19 +60,50 @@ export interface VerificationSource {
60
60
  /** The LLM call (ApiLog id) that produced this citation, via the source message. */
61
61
  api_log_id?: number | string | null;
62
62
  }
63
+ /**
64
+ * One piece of evidence a {@link SourceDiscrepancy} cites — the page a conflicting value
65
+ * was read off, plus the classifier's own per-page confidence/explanation for it.
66
+ */
67
+ export interface SourceDiscrepancyEvidence {
68
+ page_number: number | null;
69
+ stored_file_id: string | null;
70
+ confidence: number | null;
71
+ explanation: string | null;
72
+ }
73
+ /**
74
+ * A genuine SOURCE-DOCUMENT conflict a host pipeline already reconciled before this value
75
+ * was settled — e.g. Input Organization's dedup pass merging two group names that disagreed
76
+ * because of a typo/OCR error in the source document itself, not because they name two
77
+ * different real entities (SG-217). Distinct from a *candidate* discrepancy (two candidates
78
+ * — override/extracted/claim — disagreeing): this is ONE candidate's own value, already
79
+ * resolved from conflicting SOURCE data. Present only on the rare field the host actually
80
+ * reconciled this way; null/undefined on every ordinary field.
81
+ */
82
+ export interface SourceDiscrepancy {
83
+ /** Which field disagreed — a constant naming the data point (e.g. "group_name"). */
84
+ field: string;
85
+ /** The literal conflicting values recorded before reconciliation. */
86
+ conflicting_values: string[];
87
+ /** The evidence pages/sources the reconciliation was decided from. */
88
+ evidence: SourceDiscrepancyEvidence[];
89
+ /** The value that won. */
90
+ winning_value: string;
91
+ /** The reconciling explanation (which values disagreed, why, and what corroborated the winner). */
92
+ reason: string;
93
+ }
63
94
  /**
64
95
  * The extracted (pipeline) candidate — carries provenance: confidence, reasoning, citation.
65
96
  *
66
97
  * SG-392: the host's BASE render (`data.__meta`) ships only `value`/`confidence`/
67
98
  * `state` plus the two `_count` integers below — `reasoning`/`basis`/`sources`/
68
- * `history` are `undefined` there. They populate only after
69
- * `fetchDataPointDetail()` resolves for this field's anchor (see
70
- * `VerificationModal.vue`, which fetches the instant the Inspector dialog opens
71
- * and merges the result in). A real production render was shipping every field's
99
+ * `history` are `undefined` there, and NOTHING IN THIS LIBRARY FILLS THEM IN ANY
100
+ * MORE. They used to be lazy-fetched by the in-letter Inspector dialog, which is
101
+ * deleted; the embedding app reads a data point's full detail against its own
102
+ * session instead. A real production render was shipping every field's
72
103
  * full retry history — each carrying its own `sources[]`, each source carrying two
73
104
  * full `StoredFile` objects — unconditionally, on every load (~9MB, WI-1090); this
74
105
  * split is the fix. Every consumer here degrades gracefully on the undefined case
75
- * (a length-based count/tooltip/scoreboard reads `*_count` first, `.length` as a
106
+ * (a length-based count/accessible-name/scoreboard reads `*_count` first, `.length` as a
76
107
  * fallback for a fixture/detail-response that already carries the full arrays).
77
108
  */
78
109
  export interface ExtractedCandidate {
@@ -90,7 +121,7 @@ export interface ExtractedCandidate {
90
121
  * the failure explanation instead of citation reasoning. Undefined/null for
91
122
  * candidates predating this field.
92
123
  */
93
- state?: "extracted" | "corrected" | "failed" | "absent" | null;
124
+ state?: "present" | "absent" | "removed" | "failed" | null;
94
125
  /**
95
126
  * The full per-field extraction history (SG-190) — every recorded attempt for this
96
127
  * field, oldest first, including the live winner and every non-live loser / FAILED
@@ -102,6 +133,13 @@ export interface ExtractedCandidate {
102
133
  history?: VerificationHistoryEntry[];
103
134
  /** Cheap `history?.length` equivalent — present even when `history` itself is not (SG-392). */
104
135
  history_count?: number;
136
+ /**
137
+ * Non-null when this candidate's value was reconciled from a genuine SOURCE-DOCUMENT
138
+ * conflict (SG-217). Shipped in BOTH light and full mode — unlike reasoning/sources/
139
+ * history above, it is a handful of short strings, not a per-attempt array, so it carries
140
+ * none of the SG-392 payload-size risk and `hasDiscrepancy()` needs it in light mode too.
141
+ */
142
+ source_discrepancy?: SourceDiscrepancy | null;
105
143
  }
106
144
  /**
107
145
  * One recorded attempt in a field's extraction history (SG-190). Mirrors the extracted
@@ -113,7 +151,7 @@ export interface VerificationHistoryEntry {
113
151
  confidence: number | null;
114
152
  reasoning?: string | null;
115
153
  basis?: "verbatim" | "inferred" | null;
116
- state?: "extracted" | "corrected" | "failed" | "absent" | null;
154
+ state?: "present" | "absent" | "removed" | "failed" | null;
117
155
  /** True for the single live/winning attempt; false for losers/FAILED/superseded values. */
118
156
  is_chosen: boolean;
119
157
  page?: number | null;
@@ -156,6 +194,13 @@ export interface DataPointMeta {
156
194
  candidates: CandidateSet;
157
195
  discrepancy: boolean;
158
196
  resolved: ResolvedValue;
197
+ /**
198
+ * Present (non-null) when `discrepancy` is true because of a SOURCE-DOCUMENT conflict
199
+ * rather than (or in addition to) disagreeing candidates (SG-217). Distinguishes a
200
+ * source-document discrepancy from an ordinary candidate discrepancy for copy/icon
201
+ * purposes — see {@link isSourceDiscrepancy} in `lib/discrepancy.ts`.
202
+ */
203
+ source_discrepancy?: SourceDiscrepancy | null;
159
204
  }
160
205
  /** An object node in the rendered `data` tree carrying a keyed `__meta` map. */
161
206
  export type MetaCarrier = Record<string, unknown> & {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thehammer/template-verification",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "description": "Read-write verification overlay for rendered template apps — per-data-point confidence, discrepancy, 3-source resolution (override > extracted > claim), inline edit, and a recursive comparison page. Consumes the host's __meta sidecar; fetches nothing.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,12 +0,0 @@
1
- import type { AuditLlmCall } from "../lib/dataPointDetail";
2
- /**
3
- * One LLM call in the Inspector's Audit trail — model/service chips, status +
4
- * timing header, and collapsible JSON request/response viewers (danx-ui
5
- * CodeViewer, mirroring the dashboard's ApiLogEntryCard UX). Pure presentational;
6
- * the parent owns fetching.
7
- */
8
- type __VLS_Props = {
9
- call: AuditLlmCall;
10
- };
11
- declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
- export default _default;
@@ -1,33 +0,0 @@
1
- import { type CitationEvidence } from "../lib/citations";
2
- /**
3
- * The evidence behind one value: why the pipeline chose it, and every source page
4
- * it cited with that page's own verbatim quotes.
5
- *
6
- * Replaces the retired single-blockquote treatment, which flattened every quote
7
- * from every page into one string joined with ellipses — page attribution, the
8
- * one thing a citation exists to establish, was unrecoverable from it.
9
- *
10
- * Reused by both the Inspector's Citations tab (collapsible, full size) and each
11
- * History attempt's panel (`dense` + flat), so a losing attempt's citations read
12
- * exactly like the winner's.
13
- */
14
- type __VLS_Props = {
15
- evidence: CitationEvidence;
16
- /** Why the pipeline chose this value. Null renders no reasoning card. */
17
- reasoning?: string | null;
18
- /** verbatim = the value appears as-is in a quote; inferred = derived from it. */
19
- basis?: "verbatim" | "inferred" | null;
20
- /** SG-189: extraction/citation-correction failed — `reasoning` is the failure. */
21
- failed?: boolean;
22
- /** Collapse pages behind an accordion (off inside a History panel). */
23
- collapsible?: boolean;
24
- dense?: boolean;
25
- };
26
- declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
27
- failed: boolean;
28
- collapsible: boolean;
29
- dense: boolean;
30
- reasoning: string | null;
31
- basis: "verbatim" | "inferred" | null;
32
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
- export default _default;
@@ -1,27 +0,0 @@
1
- import type { CitationPage } from "../lib/citations";
2
- /**
3
- * The expanded body of one cited page: its page image on the left, its own
4
- * ordered verbatim quotes on the right, and the page-level actions.
5
- *
6
- * Renders ONLY the body — the collapsed header row lives in
7
- * {@link CitationPageList} because the disclosure's header is itself a
8
- * `<button>`, and the view/download controls here are buttons too.
9
- *
10
- * The thumbnail is a `DanxFile` in `downloadable` mode: hovering it exposes
11
- * danx-ui's own download control, and clicking it opens the full-screen viewer.
12
- * A page whose file the host never resolved still renders its quotes; only the
13
- * image and its actions are withheld.
14
- */
15
- type __VLS_Props = {
16
- page: CitationPage;
17
- /** Compact treatment for the History tab's per-attempt citations. */
18
- dense?: boolean;
19
- };
20
- declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
21
- view: () => any;
22
- document: () => any;
23
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
24
- onView?: (() => any) | undefined;
25
- onDocument?: (() => any) | undefined;
26
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
27
- export default _default;
@@ -1,26 +0,0 @@
1
- import type { CitationPage as CitationPageModel } from "../lib/citations";
2
- /**
3
- * The cited-page list — one collapsible section per source page, each showing that
4
- * page's own verbatim quotes, with a full-screen viewer behind every page and
5
- * every parent document.
6
- *
7
- * Progressive disclosure is the point: a data point can cite many pages, so a
8
- * collapsed row carries only what you need to decide whether to open it (page
9
- * number, document, quote count, and the first quote truncated). Opening a row
10
- * reveals the page image and the full quote list.
11
- *
12
- * `collapsible: false` renders the same content flat, for the History tab's
13
- * per-attempt citations where the list is short and already inside a panel.
14
- */
15
- type __VLS_Props = {
16
- pages: CitationPageModel[];
17
- /** Collapse pages behind an accordion. Off = every page always expanded. */
18
- collapsible?: boolean;
19
- /** Compact treatment, passed through to each page body. */
20
- dense?: boolean;
21
- };
22
- declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
23
- collapsible: boolean;
24
- dense: boolean;
25
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
26
- export default _default;
@@ -1,61 +0,0 @@
1
- /**
2
- * A minimal, accessible collapsible-section list — the package's own, on purpose.
3
- *
4
- * danx-ui ships `DanxAccordion`, but a template app does NOT resolve danx-ui from
5
- * this package's node_modules: the danxbot build marks it external and the browser
6
- * resolves it at load time from the shell's vendor chunk, which pins
7
- * `@thehammer/danx-ui: ^0.8.17` (see danxbot `spa-template-shell/package.json`).
8
- * `DanxAccordion` does not exist there, and importing it fails the template's vite
9
- * build with a Rollup "not exported" error — which is exactly what happened on the
10
- * first attempt to ship this feature.
11
- *
12
- * The rule this encodes: this package must only use danx-ui surface that exists at
13
- * the FLOOR of its declared peer range, never whatever the local install happens to
14
- * resolve. A ~40-line disclosure is a much cheaper guarantee than a version bump
15
- * coordinated across the shell and every template.
16
- *
17
- * The header is a `<button>` (its own accessible toggle), so slot content placed in
18
- * it must not itself be interactive — put actions in the `panel` slot.
19
- */
20
- type __VLS_Props = {
21
- /** Sections to render, in order. `value` is the open/closed key. */
22
- items: Array<{
23
- value: string;
24
- label?: string;
25
- }>;
26
- /** Open section keys. Any number may be open at once. */
27
- modelValue: string[];
28
- /** Prefix for the generated aria ids — unique per usage on a page. */
29
- idPrefix?: string;
30
- };
31
- declare var __VLS_1: {
32
- item: {
33
- value: string;
34
- label?: string | undefined;
35
- };
36
- isOpen: boolean;
37
- }, __VLS_3: {
38
- item: {
39
- value: string;
40
- label?: string | undefined;
41
- };
42
- isOpen: boolean;
43
- };
44
- type __VLS_Slots = {} & {
45
- header?: (props: typeof __VLS_1) => any;
46
- } & {
47
- panel?: (props: typeof __VLS_3) => any;
48
- };
49
- declare const _default: __VLS_WithSlots<import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
50
- "update:modelValue": (value: string[]) => any;
51
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
52
- "onUpdate:modelValue"?: ((value: string[]) => any) | undefined;
53
- }>, {
54
- idPrefix: string;
55
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, __VLS_Slots>;
56
- export default _default;
57
- type __VLS_WithSlots<T, S> = T & {
58
- new (): {
59
- $slots: S;
60
- };
61
- };
@@ -1,48 +0,0 @@
1
- import type { DataPointMeta, SourceChoice } from "../types";
2
- /**
3
- * The Inspector — per-data-point detail dialog. 90vw × 90vh danx-ui DanxDialog
4
- * with a hero strip (resolved value, confidence meter, source of truth,
5
- * discrepancy alert) over four tabs:
6
- *
7
- * - Citations: why this value, then one collapsible section per cited SOURCE
8
- * PAGE carrying that page's own verbatim quotes, each openable full screen
9
- * (zoomable, downloadable) with the page's quotes alongside. Replaces the
10
- * retired treatment that flattened every quote from every page into one
11
- * blockquote, which made page attribution unrecoverable.
12
- * - Candidates: the resolution flow — one card per candidate with an Accept
13
- * action, plus custom-value entry. Saving toasts + flips the in-document pill.
14
- * - History: the live value's confidence + reasoning above the full extraction
15
- * history; every attempt (winner, losers, FAILED) collapses to a summary row
16
- * and expands to its own reasoning and page-grouped citations.
17
- * - Audit trail: every LLM call the pipeline made for this field; hidden
18
- * entirely when the host minted no `detail_url`.
19
- *
20
- * SG-392: `props.meta.candidates.extracted` may be LIGHT (no `sources`/
21
- * `history` — the base template render never ships those, only their
22
- * `*_count`; see `types.ts`'s `ExtractedCandidate` docblock for why). The
23
- * instant this dialog opens, it fetches the FULL detail (citation sources +
24
- * extraction history + the LLM audit trace, all in one request — one host
25
- * endpoint, `verification.detailUrl`) and merges it in; `extracted` (the
26
- * merged computed) below is what every tab actually reads. A caller that already passed a FULL
27
- * `extracted` (e.g. the live meta right after a save, which always carries
28
- * full detail) is used as-is — the fetch still fires (the audit trace is
29
- * needed either way) but never clobbers already-present sources/history with
30
- * an absent one.
31
- *
32
- * `save` is null when the field is read-only (no transport / no anchor) — the
33
- * resolution actions are hidden in that case.
34
- */
35
- type __VLS_Props = {
36
- modelValue: boolean;
37
- meta: DataPointMeta;
38
- label?: string;
39
- save?: ((value: string | null, sourceChoice: SourceChoice) => Promise<DataPointMeta>) | null;
40
- };
41
- declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
42
- "update:modelValue": (value: boolean) => any;
43
- saved: (meta: DataPointMeta) => any;
44
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
45
- "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
46
- onSaved?: ((meta: DataPointMeta) => any) | undefined;
47
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
48
- export default _default;
@@ -1,84 +0,0 @@
1
- import type { PreviewFile } from "@thehammer/danx-ui";
2
- import type { VerificationSource } from "../types";
3
- /**
4
- * One cited PAGE of a source document, with the verbatim quotes taken from it.
5
- *
6
- * This is the unit the extraction pipeline actually records: `sources[]` holds one
7
- * row per cited page, and that row carries its OWN ordered `texts[]` (SG-181). The
8
- * retired `groupSources()` model grouped by "file identity" and left the quotes
9
- * flattened across the whole candidate, so a reviewer could never tell which page a
10
- * given quote came from — the defect this model exists to remove.
11
- *
12
- * Two source rows that cite the SAME page image merge into one page, their quotes
13
- * concatenated in source order.
14
- */
15
- export interface CitationPage {
16
- /** Stable merge/render key — same page image ⇒ same key. */
17
- key: string;
18
- /** Page position inside the parent document, when the host resolved one. */
19
- pageNumber: number | null;
20
- /** Human label: "Page 4", else the file name, else a neutral fallback. */
21
- label: string;
22
- /** The parent document's name, when known — shown as the page's context. */
23
- documentName: string | null;
24
- /**
25
- * The page image itself, danx-ui `PreviewFile`-shaped, carrying `page_number`
26
- * so the viewer's own `sortByPageNumber()` orders a multi-page citation
27
- * correctly. Null when the host did not resolve a file for this source — the
28
- * quotes still render, the view/download affordances do not.
29
- */
30
- file: PreviewFile | null;
31
- /**
32
- * A direct URL to this page, from either host shape (`file.url`, else the
33
- * idealized `file_url`). Null when the host resolved neither — a plain-text
34
- * listing then names the page without linking it.
35
- */
36
- url: string | null;
37
- /** The FULL parent document (the whole PDF), when this page is a transcode child. */
38
- document: PreviewFile | null;
39
- /** This page's ordered verbatim quotes, duplicates removed. */
40
- quotes: string[];
41
- /** Any non-empty `explanation` recorded against this page. */
42
- explanations: string[];
43
- /** The source row ids that merged into this page. */
44
- sourceIds: Array<number | string>;
45
- }
46
- /** The full citation picture for one candidate (or one history attempt). */
47
- export interface CitationEvidence {
48
- /** Cited pages, ordered by page number, then by input order. */
49
- pages: CitationPage[];
50
- /** Distinct parent documents across every cited page. */
51
- documents: PreviewFile[];
52
- /** The LLM calls that produced this citation — the audit-trail anchor. */
53
- apiLogIds: Array<number | string>;
54
- /**
55
- * Citation sources the correction loop could never resolve to a real page
56
- * (`source_type: 'failed_file'`). Surfaced rather than dropped — recording
57
- * them instead of discarding them is the whole point of that source type.
58
- */
59
- unresolved: VerificationSource[];
60
- pageCount: number;
61
- quoteCount: number;
62
- /** True when there is nothing at all to show — no page, no unresolved citation. */
63
- isEmpty: boolean;
64
- }
65
- /**
66
- * Build the citation picture for a candidate's `sources[]`.
67
- *
68
- * Sources are classified by kind before anything is grouped, so provenance rows
69
- * never masquerade as evidence:
70
- *
71
- * - `failed_file` → `unresolved` (an unresolvable citation, shown as a warning)
72
- * - `api_log` → `apiLogIds` (the LLM call behind the citation)
73
- * - `user` → dropped (a human override is not a citation)
74
- * - anything else → a cited page, merged by page identity
75
- *
76
- * A source with quotes but no resolvable file still becomes a page, so a quote is
77
- * never silently discarded for want of a thumbnail.
78
- *
79
- * Tolerates both host shapes: the live gpt-manager payload (`file` + `page_number`)
80
- * and the idealized document-page shape (`file_url` / `file_name` / `page`).
81
- */
82
- export declare function citationEvidence(sources?: VerificationSource[] | null): CitationEvidence;
83
- /** "2 pages · 5 quotes" — the one-line summary used in tab badges and headers. */
84
- export declare function citationSummary(evidence: CitationEvidence): string;
@@ -1,41 +0,0 @@
1
- import type { DataPointAnchor, ExtractedCandidate } from "../types";
2
- /**
3
- * One sanitized LLM call from the host's token-sealed data-point detail endpoint
4
- * (gpt-manager `TemplateRenderDataController::dataPointDetail()`).
5
- * Request/response are the raw JSON payloads the team owns; headers/stack traces
6
- * never ship.
7
- */
8
- export interface AuditLlmCall {
9
- id: number | string;
10
- service?: string | null;
11
- endpoint?: string | null;
12
- model?: string | null;
13
- status_code?: number | null;
14
- run_time_ms?: number | null;
15
- started_at?: string | null;
16
- request?: unknown;
17
- response?: unknown;
18
- /**
19
- * Which pipeline stage this call belongs to (e.g. "Data Extraction Directive") —
20
- * the TaskOrchestrator name the host resolved this call's TaskWorker back to.
21
- * Null when the host could not attribute a stage (see gpt-manager's
22
- * DataPointAuditService for the current Extraction-only attribution scope).
23
- */
24
- stage?: string | null;
25
- }
26
- /** One host detail-endpoint response — the full candidate + its LLM-call trace. */
27
- export interface DataPointDetail {
28
- /** The full extracted candidate (sources/history included), or null when the
29
- * field has no verification provenance at all. */
30
- extracted: ExtractedCandidate | null;
31
- audit: AuditLlmCall[];
32
- }
33
- /**
34
- * Lazy-fetch the FULL detail for one data point (SG-392): its citation sources,
35
- * full extraction history, and the LLM-call trace behind it, all in ONE request.
36
- * The anchor's NEAREST object id + leaf field identify the attribute; the host
37
- * re-resolves its sources server-side (the client never names ApiLog ids). Throws
38
- * on a non-OK response — callers surface the failure state; an empty `audit`
39
- * array or a null `extracted` is a valid "nothing there" result, not an error.
40
- */
41
- export declare function fetchDataPointDetail(detailUrl: string, anchor: DataPointAnchor): Promise<DataPointDetail>;
@@ -1,17 +0,0 @@
1
- import type { Ref } from "vue";
2
- import type { Verification } from "./context";
3
- import type { DataPointMeta, SourceChoice } from "./types";
4
- /** A bound save: commit an override (pinned candidate or custom value). */
5
- export type SaveDataPointFn = (value: string | null, sourceChoice: SourceChoice) => Promise<DataPointMeta>;
6
- /** The transport-bearing slice of the verification state a save needs. */
7
- export type SaveContext = Pick<Verification, "saveOverride" | "workflowInputId">;
8
- /**
9
- * Build a save function for one data point, bound to its anchor + the host
10
- * transport. Reads the anchor from the CURRENT meta, commits an override, and
11
- * hands the host's recomputed {@link DataPointMeta} to `onSaved` so the caller can
12
- * update its writable state and re-render the new resolution.
13
- *
14
- * Returns null when no transport was passed to `initVerification` OR the meta
15
- * carries no anchor — both mean the field is read-only.
16
- */
17
- export declare function useSaveDataPoint(verification: SaveContext, currentMeta: Ref<DataPointMeta | null | undefined>, onSaved: (meta: DataPointMeta) => void): SaveDataPointFn | null;