@ifc-lite/sdk 9.2.0 → 9.4.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 (70) hide show
  1. package/README.md +30 -0
  2. package/dist/review/capture-budget.d.ts +6 -0
  3. package/dist/review/capture-budget.d.ts.map +1 -0
  4. package/dist/review/capture-budget.js +47 -0
  5. package/dist/review/capture-budget.js.map +1 -0
  6. package/dist/review/capture-retention.d.ts +47 -0
  7. package/dist/review/capture-retention.d.ts.map +1 -0
  8. package/dist/review/capture-retention.js +141 -0
  9. package/dist/review/capture-retention.js.map +1 -0
  10. package/dist/review/capture-types.d.ts +57 -0
  11. package/dist/review/capture-types.d.ts.map +1 -0
  12. package/dist/review/capture-types.js +5 -0
  13. package/dist/review/capture-types.js.map +1 -0
  14. package/dist/review/clash-identity.d.ts +9 -0
  15. package/dist/review/clash-identity.d.ts.map +1 -0
  16. package/dist/review/clash-identity.js +18 -0
  17. package/dist/review/clash-identity.js.map +1 -0
  18. package/dist/review/clash.d.ts +25 -0
  19. package/dist/review/clash.d.ts.map +1 -0
  20. package/dist/review/clash.js +97 -0
  21. package/dist/review/clash.js.map +1 -0
  22. package/dist/review/native-captures.d.ts +21 -0
  23. package/dist/review/native-captures.d.ts.map +1 -0
  24. package/dist/review/native-captures.js +325 -0
  25. package/dist/review/native-captures.js.map +1 -0
  26. package/dist/review/native-snapshot.d.ts +47 -0
  27. package/dist/review/native-snapshot.d.ts.map +1 -0
  28. package/dist/review/native-snapshot.js +98 -0
  29. package/dist/review/native-snapshot.js.map +1 -0
  30. package/dist/review/portable-analysis-binding.d.ts +29 -0
  31. package/dist/review/portable-analysis-binding.d.ts.map +1 -0
  32. package/dist/review/portable-analysis-binding.js +60 -0
  33. package/dist/review/portable-analysis-binding.js.map +1 -0
  34. package/dist/review/portable-analysis.d.ts +103 -0
  35. package/dist/review/portable-analysis.d.ts.map +1 -0
  36. package/dist/review/portable-analysis.js +119 -0
  37. package/dist/review/portable-analysis.js.map +1 -0
  38. package/dist/review/portable-automation-provenance.d.ts +32 -0
  39. package/dist/review/portable-automation-provenance.d.ts.map +1 -0
  40. package/dist/review/portable-automation-provenance.js +68 -0
  41. package/dist/review/portable-automation-provenance.js.map +1 -0
  42. package/dist/review/portable-ids-report.d.ts +125 -0
  43. package/dist/review/portable-ids-report.d.ts.map +1 -0
  44. package/dist/review/portable-ids-report.js +124 -0
  45. package/dist/review/portable-ids-report.js.map +1 -0
  46. package/dist/review/portable-manual-report.d.ts +66 -0
  47. package/dist/review/portable-manual-report.d.ts.map +1 -0
  48. package/dist/review/portable-manual-report.js +121 -0
  49. package/dist/review/portable-manual-report.js.map +1 -0
  50. package/dist/review/portable-report-metadata.d.ts +42 -0
  51. package/dist/review/portable-report-metadata.d.ts.map +1 -0
  52. package/dist/review/portable-report-metadata.js +41 -0
  53. package/dist/review/portable-report-metadata.js.map +1 -0
  54. package/dist/review/portable-saved-validation.d.ts +12 -0
  55. package/dist/review/portable-saved-validation.d.ts.map +1 -0
  56. package/dist/review/portable-saved-validation.js +32 -0
  57. package/dist/review/portable-saved-validation.js.map +1 -0
  58. package/dist/review/portable-validation-evidence.d.ts +53 -0
  59. package/dist/review/portable-validation-evidence.d.ts.map +1 -0
  60. package/dist/review/portable-validation-evidence.js +52 -0
  61. package/dist/review/portable-validation-evidence.js.map +1 -0
  62. package/dist/review/saved-validation.d.ts +14 -0
  63. package/dist/review/saved-validation.d.ts.map +1 -0
  64. package/dist/review/saved-validation.js +31 -0
  65. package/dist/review/saved-validation.js.map +1 -0
  66. package/dist/review.d.ts +19 -0
  67. package/dist/review.d.ts.map +1 -1
  68. package/dist/review.js +14 -0
  69. package/dist/review.js.map +1 -1
  70. package/package.json +5 -5
package/README.md CHANGED
@@ -91,6 +91,12 @@ coverage when native evaluated counts cover the population. Existing
91
91
  model-name card keys do not establish durable source or captured-run identity.
92
92
  See the [SDK guide](https://ifclite.dev/docs/guide/scripting-sdk/#native-review-normalization).
93
93
 
94
+ `clashFindings`, `clashGlobalId`, `clashDisciplineCandidates`, and
95
+ `clashOccurrenceKey` share the existing viewer clash projection and occurrence
96
+ identity. `savedValidationFacts` projects saved IDS failure rows; callers supply
97
+ actual re-examination outcomes. Imported rows remain historical and incomplete,
98
+ and discipline candidates remain hints rather than verified responsibilities.
99
+
94
100
  ## Links
95
101
 
96
102
  - Docs: https://ifclite.dev/docs/
@@ -101,3 +107,27 @@ See the [SDK guide](https://ifclite.dev/docs/guide/scripting-sdk/#native-review-
101
107
  MPL-2.0
102
108
 
103
109
  Direct SDK property writes can supply an optional IFC datatype: `bim.mutate.setProperty(ref, "Pset_WallCommon", "ThermalTransmittance", 1, "IfcThermalTransmittanceMeasure")`. Declarations are schema-validated and retained through STEP export; omitted datatypes retain existing inference. See the [SDK guide](https://ifclite.dev/docs/guide/scripting-sdk/).
110
+
111
+ The Review leaf also provides `NativeReviewCaptures` and `readNativeReview` for
112
+ real native host producers. Capture starts before evaluation, binds full source
113
+ SHA-256 and owner/store/view revision, then retains cloned native facts/counts.
114
+ Reads revalidate source ownership, withhold entire out-of-scope target envelopes
115
+ and report incomplete/unsupported/bounded coverage. These live captures do not
116
+ claim portable historical recovery. See [the native capture contract](../../docs/guide/scripting-sdk.md#native-review-capture-lifecycle).
117
+
118
+ Native Review capture retention separates 32 pending operations from 32 settled producer/definition/source contexts. Successful reruns replace matching contexts; failures abandon pending reservations and preserve earlier matching facts as historical evidence. Distinct-context eviction reports unknown omitted history rather than complete coverage. Operation ordering is established before source proof awaits. See [the retention and failure contract](../../docs/guide/scripting-sdk.md#native-review-capture-lifecycle).
119
+
120
+ ### Portable saved evidence
121
+
122
+ The `@ifc-lite/sdk/review` entry point owns the existing viewer saved-analysis
123
+ and saved-validation wire contracts. `decodeSavedAnalysisRun` validates a saved
124
+ analysis run, and `validateSavedReport` validates an IDS, rules, or manual report
125
+ envelope. The same contracts are used by viewer save, backup import, and report
126
+ validation. Import validation preserves the original report dates, source
127
+ identities, coverage gaps, and unknown or stale freshness.
128
+
129
+ `bindSavedAnalysisModels` requires an unambiguous source match and the caller's
130
+ actual edit and placement evidence. A payload join key or model name is not a
131
+ durable model identity. Parsing a manual report retains historical answers;
132
+ it does not run a checklist or resolve a finding. These codecs do not persist
133
+ reports, change model state, or certify that an imported report was executed.
@@ -0,0 +1,6 @@
1
+ /** #7372: reject a whole capture instead of retaining a silently partial graph. */
2
+ export declare function reviewValueFits(value: unknown): boolean;
3
+ export declare function reviewSHA256(bytes: Uint8Array): Promise<string>;
4
+ /** Both raw and JSON-escaped credentials are excluded from cross-tool facts. */
5
+ export declare function reviewContainsSecret(serialized: string, values: readonly string[]): boolean;
6
+ //# sourceMappingURL=capture-budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-budget.d.ts","sourceRoot":"","sources":["../../src/review/capture-budget.ts"],"names":[],"mappings":"AAIA,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAqBvD;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAGrE;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAG3F"}
@@ -0,0 +1,47 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /** #7372: reject a whole capture instead of retaining a silently partial graph. */
5
+ export function reviewValueFits(value) {
6
+ const pending = [{ value, depth: 0 }];
7
+ let work = 0;
8
+ let text = 0;
9
+ while (pending.length) {
10
+ const item = pending.pop();
11
+ if (!item || ++work > 100_000 || item.depth > 24)
12
+ return false;
13
+ const x = item.value;
14
+ if (typeof x === 'string') {
15
+ if (x.length > 16_384 || (text += x.length) > 1_048_576)
16
+ return false;
17
+ }
18
+ else if (typeof x === 'number') {
19
+ if (!Number.isFinite(x))
20
+ return false;
21
+ }
22
+ else if (x instanceof Date) {
23
+ if (!Number.isFinite(x.getTime()))
24
+ return false;
25
+ }
26
+ else if (x !== null && typeof x === 'object') {
27
+ const children = Array.isArray(x) ? x : Object.values(x);
28
+ if (children.length > 10_000 || pending.length + children.length > 100_000)
29
+ return false;
30
+ for (const child of children)
31
+ pending.push({ value: child, depth: item.depth + 1 });
32
+ }
33
+ else if (x !== null && x !== undefined && typeof x !== 'boolean')
34
+ return false;
35
+ }
36
+ return true;
37
+ }
38
+ export async function reviewSHA256(bytes) {
39
+ const hash = await crypto.subtle.digest('SHA-256', new Uint8Array(bytes));
40
+ return [...new Uint8Array(hash)].map(x => x.toString(16).padStart(2, '0')).join('');
41
+ }
42
+ /** Both raw and JSON-escaped credentials are excluded from cross-tool facts. */
43
+ export function reviewContainsSecret(serialized, values) {
44
+ return values.some(value => value.length > 0 && (serialized.includes(value)
45
+ || serialized.includes(JSON.stringify(value).slice(1, -1))));
46
+ }
47
+ //# sourceMappingURL=capture-budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-budget.js","sourceRoot":"","sources":["../../src/review/capture-budget.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { NativeReviewModel, NativeReviewResult, ReviewCaptureToken, ReviewRunProvenance, ReviewSourceProof, ReviewSpecificationCoverage } from './capture-types.js';
2
+ import type { FindingSourceResult } from './types.js';
3
+ export interface OwnedTarget {
4
+ model: NativeReviewModel;
5
+ view: ReturnType<NativeReviewModel['mutationView']>;
6
+ revision: number;
7
+ proof: ReviewSourceProof;
8
+ }
9
+ export interface CaptureAttempt {
10
+ token: ReviewCaptureToken;
11
+ models: readonly NativeReviewModel[];
12
+ order: number | null;
13
+ outcome: 'pending' | 'succeeded' | 'failed' | 'aborted' | 'refused' | 'superseded';
14
+ refusal?: NativeReviewResult['refusal'];
15
+ targets?: OwnedTarget[];
16
+ provenance?: ReviewRunProvenance;
17
+ superseded: boolean;
18
+ proofHistoryUncertain?: boolean;
19
+ laterFailure?: NativeReviewResult['refusal'];
20
+ }
21
+ export interface SettledCapture {
22
+ attempt: CaptureAttempt;
23
+ targets: OwnedTarget[];
24
+ provenance: ReviewRunProvenance;
25
+ facts: FindingSourceResult;
26
+ coverage: ReviewSpecificationCoverage[];
27
+ laterFailure?: NativeReviewResult['refusal'];
28
+ }
29
+ /** Two bounded roles: pending reservations and latest successful native contexts. */
30
+ export declare class CaptureRetention {
31
+ readonly capacity: number;
32
+ readonly pending: Map<string, CaptureAttempt>;
33
+ readonly settled: Map<string, SettledCapture>;
34
+ latest: CaptureAttempt | null;
35
+ inventoryOmitted: boolean;
36
+ captureRefusal: 'capture-bound' | null;
37
+ private order;
38
+ constructor(capacity: number);
39
+ private nextOrder;
40
+ private replaceLatest;
41
+ refuse(models: readonly NativeReviewModel[], refusal: NativeReviewResult['refusal']): void;
42
+ reserve(models: readonly NativeReviewModel[]): CaptureAttempt | null;
43
+ prepare(attempt: CaptureAttempt, targets: OwnedTarget[], provenance: ReviewRunProvenance): void;
44
+ fail(attempt: CaptureAttempt, refusal: NativeReviewResult['refusal'], outcome: 'failed' | 'aborted' | 'refused'): void;
45
+ complete(attempt: CaptureAttempt, facts: FindingSourceResult, coverage: ReviewSpecificationCoverage[]): void;
46
+ }
47
+ //# sourceMappingURL=capture-retention.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-retention.d.ts","sourceRoot":"","sources":["../../src/review/capture-retention.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,mBAAmB,EAC1F,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,iBAAiB,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC,CAAC;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AACD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACrC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;IACnF,OAAO,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACxC,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,YAAY,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;CAC9C;AACD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,UAAU,EAAE,mBAAmB,CAAC;IAChC,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,2BAA2B,EAAE,CAAC;IACxC,YAAY,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;CAC9C;AAYD,qFAAqF;AACrF,qBAAa,gBAAgB;IAOf,QAAQ,CAAC,QAAQ,EAAE,MAAM;IANrC,QAAQ,CAAC,OAAO,8BAAqC;IACrD,QAAQ,CAAC,OAAO,8BAAqC;IACrD,MAAM,EAAE,cAAc,GAAG,IAAI,CAAQ;IACrC,gBAAgB,UAAS;IACzB,cAAc,EAAE,eAAe,GAAG,IAAI,CAAQ;IAC9C,OAAO,CAAC,KAAK,CAAK;gBACG,QAAQ,EAAE,MAAM;IAErC,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,aAAa;IAWrB,MAAM,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,EAAE,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,GAAG,IAAI;IAI1F,OAAO,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,GAAG,cAAc,GAAG,IAAI;IAOpE,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,UAAU,EAAE,mBAAmB,GAAG,IAAI;IAO/F,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI;IAetH,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,2BAA2B,EAAE,GAAG,IAAI;CAgC7G"}
@@ -0,0 +1,141 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ function sameContext(a, b) {
5
+ if (!a.provenance || !b.provenance || !a.targets || !b.targets)
6
+ return false;
7
+ return a.provenance.producer === b.provenance.producer
8
+ && a.provenance.definitionSHA256 === b.provenance.definitionSHA256
9
+ && a.targets.length === b.targets.length && a.targets.every(target => b.targets?.some(other => target.model.id === other.model.id && target.model.owner === other.model.owner
10
+ && target.model.store === other.model.store && target.model.source === other.model.source
11
+ && target.proof.sourceSHA256 === other.proof.sourceSHA256
12
+ && target.proof.sourceByteLength === other.proof.sourceByteLength));
13
+ }
14
+ /** Two bounded roles: pending reservations and latest successful native contexts. */
15
+ export class CaptureRetention {
16
+ capacity;
17
+ pending = new Map();
18
+ settled = new Map();
19
+ latest = null;
20
+ inventoryOmitted = false;
21
+ captureRefusal = null;
22
+ order = 0;
23
+ constructor(capacity) {
24
+ this.capacity = capacity;
25
+ }
26
+ nextOrder() {
27
+ // Only relative ordering among at most 65 live records matters. Resequence
28
+ // before a fixed bound; never accumulate lifetime counters or tombstones.
29
+ if (this.order >= 128) {
30
+ const records = new Set([...this.pending.values(), ...[...this.settled.values()].map(x => x.attempt),
31
+ ...(this.latest ? [this.latest] : [])]);
32
+ const ordered = [...records].filter(x => x.order !== null).sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
33
+ ordered.forEach((item, index) => { item.order = index + 1; });
34
+ this.order = ordered.length;
35
+ }
36
+ return ++this.order;
37
+ }
38
+ replaceLatest(next) {
39
+ const previous = this.latest;
40
+ if (previous?.refusal && previous.provenance && previous.targets) {
41
+ for (const pending of this.pending.values()) {
42
+ if ((pending.order ?? -1) >= (previous.order ?? -1))
43
+ continue;
44
+ if (!pending.targets)
45
+ pending.proofHistoryUncertain = true;
46
+ else if (sameContext(previous, pending))
47
+ pending.laterFailure = previous.refusal;
48
+ }
49
+ }
50
+ this.latest = next;
51
+ }
52
+ refuse(models, refusal) {
53
+ this.replaceLatest({ token: { runId: crypto.randomUUID() }, models, order: this.nextOrder(),
54
+ outcome: 'refused', refusal, superseded: false });
55
+ }
56
+ reserve(models) {
57
+ if (this.pending.size >= this.capacity) {
58
+ this.refuse(models, 'work-bound');
59
+ return null;
60
+ }
61
+ const attempt = { token: { runId: crypto.randomUUID() }, models, order: this.nextOrder(),
62
+ outcome: 'pending', superseded: false };
63
+ this.pending.set(attempt.token.runId, attempt);
64
+ this.replaceLatest(attempt);
65
+ return attempt;
66
+ }
67
+ prepare(attempt, targets, provenance) {
68
+ if (this.pending.get(attempt.token.runId) !== attempt)
69
+ throw new Error('Native Review reservation is no longer pending');
70
+ // Proof completion cannot turn an older attempt into the latest operation.
71
+ attempt.targets = targets;
72
+ attempt.provenance = provenance;
73
+ if ([...this.settled.values()].some(capture => sameContext(attempt, capture.attempt)
74
+ && (capture.attempt.order ?? -1) > (attempt.order ?? -1)))
75
+ attempt.superseded = true;
76
+ }
77
+ fail(attempt, refusal, outcome) {
78
+ if (this.pending.get(attempt.token.runId) !== attempt)
79
+ return;
80
+ this.pending.delete(attempt.token.runId);
81
+ attempt.outcome = outcome;
82
+ attempt.refusal = refusal;
83
+ for (const other of this.pending.values()) {
84
+ if (sameContext(attempt, other) && (attempt.order ?? -1) > (other.order ?? -1))
85
+ other.laterFailure = refusal;
86
+ // A proven failure that is no longer latest has no retained descriptor
87
+ // for a later proof to compare. Preserve bounded uncertainty instead of
88
+ // treating an older, currently unproven context as a current success.
89
+ else if (this.latest !== attempt && attempt.provenance && attempt.targets && !other.targets
90
+ && (other.order ?? -1) < (attempt.order ?? -1))
91
+ other.proofHistoryUncertain = true;
92
+ }
93
+ for (const capture of this.settled.values()) {
94
+ if (sameContext(attempt, capture.attempt) && (attempt.order ?? -1) > (capture.attempt.order ?? -1))
95
+ capture.laterFailure = refusal;
96
+ }
97
+ }
98
+ complete(attempt, facts, coverage) {
99
+ if (!attempt.targets || !attempt.provenance || attempt.order === null)
100
+ throw new Error('Native Review reservation has no producer proof');
101
+ const matching = [...this.settled.values()].find(capture => sameContext(attempt, capture.attempt));
102
+ this.pending.delete(attempt.token.runId);
103
+ if (attempt.superseded || matching && (matching.attempt.order ?? -1) > attempt.order) {
104
+ attempt.outcome = 'superseded';
105
+ return;
106
+ }
107
+ const latest = this.latest;
108
+ if (latest?.refusal && (latest.order ?? -1) > attempt.order && sameContext(attempt, latest)) {
109
+ attempt.laterFailure = latest.refusal;
110
+ }
111
+ if (attempt.proofHistoryUncertain) {
112
+ // Missing bounded history cannot prove that this old proof was not
113
+ // superseded. Refuse its capture, preserving the independent report.
114
+ attempt.outcome = 'refused';
115
+ attempt.refusal = 'capture-bound';
116
+ this.captureRefusal = 'capture-bound';
117
+ this.inventoryOmitted = true;
118
+ return;
119
+ }
120
+ for (const other of this.pending.values()) {
121
+ if (sameContext(attempt, other) && (other.order ?? Number.POSITIVE_INFINITY) < attempt.order)
122
+ other.superseded = true;
123
+ }
124
+ if (matching)
125
+ this.settled.delete(matching.attempt.token.runId);
126
+ else if (this.settled.size >= this.capacity) {
127
+ const oldest = this.settled.keys().next().value;
128
+ if (oldest === undefined)
129
+ throw new Error('Native Review retention has no settled context to retire');
130
+ for (const other of this.pending.values()) {
131
+ if (!other.targets && (other.order ?? -1) < attempt.order)
132
+ other.proofHistoryUncertain = true;
133
+ }
134
+ this.settled.delete(oldest);
135
+ this.inventoryOmitted = true;
136
+ }
137
+ attempt.outcome = 'succeeded';
138
+ this.settled.set(attempt.token.runId, { attempt, targets: attempt.targets, provenance: attempt.provenance, facts, coverage, ...(attempt.laterFailure ? { laterFailure: attempt.laterFailure } : {}) });
139
+ }
140
+ }
141
+ //# sourceMappingURL=capture-retention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-retention.js","sourceRoot":"","sources":["../../src/review/capture-retention.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import type { IfcSourceBytes } from '@ifc-lite/parser';
2
+ import type { ReviewModel, FindingSourceResult } from './types.js';
3
+ /** A real host-owned source. Reading this contract never allocates an editor. */
4
+ export interface NativeReviewModel extends ReviewModel {
5
+ readonly owner: object;
6
+ readonly store: object;
7
+ readonly source: IfcSourceBytes;
8
+ mutationView(): {
9
+ getMutationRevision(): number;
10
+ } | null;
11
+ }
12
+ export interface ReviewSourceProof {
13
+ readonly modelId: string;
14
+ readonly sourceSHA256: string;
15
+ readonly sourceByteLength: number;
16
+ }
17
+ export interface ReviewRunProvenance {
18
+ readonly runId: string;
19
+ readonly producer: 'ids' | 'rules';
20
+ readonly definitionSHA256: string;
21
+ readonly capturedAt: string;
22
+ readonly sources: readonly ReviewSourceProof[];
23
+ readonly origin: 'captured';
24
+ }
25
+ export interface ReviewSpecificationCoverage {
26
+ readonly specificationId: string;
27
+ readonly applicableCount: number;
28
+ readonly passedCount: number;
29
+ readonly failedCount: number;
30
+ readonly detailRows: number;
31
+ }
32
+ export interface NativeReviewResult extends FindingSourceResult {
33
+ provenance: ReviewRunProvenance[];
34
+ retention?: {
35
+ policy: 'latest-successful-native-context';
36
+ limit: number;
37
+ inventoryOmitted: boolean;
38
+ omittedHistoricalRuns: null;
39
+ captureRefusal: 'capture-bound' | null;
40
+ };
41
+ latestAttempt?: {
42
+ state: 'pending' | 'succeeded' | 'failed' | 'aborted' | 'refused' | 'superseded';
43
+ refusal?: NativeReviewResult['refusal'];
44
+ proof: ReviewRunProvenance | null;
45
+ } | null;
46
+ coverage: Array<{
47
+ runId: string;
48
+ specifications: ReviewSpecificationCoverage[];
49
+ }>;
50
+ availability: 'available' | 'not-run' | 'unavailable';
51
+ /** Closed host facts, never a raw exception or unauthorized model label. */
52
+ refusal?: 'source-unavailable' | 'work-bound' | 'capture-bound' | 'target-changed' | 'scope' | 'sensitive-input' | 'producer-pending' | 'producer-failed' | 'aborted';
53
+ }
54
+ export interface ReviewCaptureToken {
55
+ readonly runId: string;
56
+ }
57
+ //# sourceMappingURL=capture-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-types.d.ts","sourceRoot":"","sources":["../../src/review/capture-types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEnE,iFAAiF;AACjF,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,YAAY,IAAI;QAAE,mBAAmB,IAAI,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC1D;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,KAAK,GAAG,OAAO,CAAC;IACnC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC7B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,kCAAkC,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,OAAO,CAAC;QAAC,qBAAqB,EAAE,IAAI,CAAC;QAAC,cAAc,EAAE,eAAe,GAAG,IAAI,CAAA;KAAE,CAAC;IAC1K,aAAa,CAAC,EAAE;QAAE,KAAK,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;QACjG,OAAO,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACtF,QAAQ,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,2BAA2B,EAAE,CAAA;KAAE,CAAC,CAAC;IAClF,YAAY,EAAE,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;IACtD,4EAA4E;IAC5E,OAAO,CAAC,EAAE,oBAAoB,GAAG,YAAY,GAAG,eAAe,GAAG,gBAAgB,GAAG,OAAO,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,SAAS,CAAC;CACvK;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB"}
@@ -0,0 +1,5 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ export {};
5
+ //# sourceMappingURL=capture-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-types.js","sourceRoot":"","sources":["../../src/review/capture-types.ts"],"names":[],"mappings":"AAAA;;+DAE+D"}
@@ -0,0 +1,9 @@
1
+ import { type Clash } from '@ifc-lite/clash';
2
+ /** Native selector candidates remain hints, never verified responsibilities. */
3
+ export declare function clashDisciplineCandidates(clash: Pick<Clash, 'a' | 'b'>): {
4
+ a: string[];
5
+ b: string[];
6
+ };
7
+ /** Exact occurrence identity, distinct from model-independent human review keys. */
8
+ export declare function clashOccurrenceKey(clash: Pick<Clash, 'rule' | 'a' | 'b'>): string;
9
+ //# sourceMappingURL=clash-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clash-identity.d.ts","sourceRoot":"","sources":["../../src/review/clash-identity.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgC,KAAK,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE3E,gFAAgF;AAChF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG,CAAC;;;EAKtE;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,GAAG,MAAM,CAIjF"}
@@ -0,0 +1,18 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { DISCIPLINES, matchesSelector } from '@ifc-lite/clash';
5
+ /** Native selector candidates remain hints, never verified responsibilities. */
6
+ export function clashDisciplineCandidates(clash) {
7
+ function candidates(tag) {
8
+ return Object.values(DISCIPLINES).filter(discipline => matchesSelector(tag, discipline.selector)).map(discipline => discipline.code);
9
+ }
10
+ return { a: candidates(clash.a.tag), b: candidates(clash.b.tag) };
11
+ }
12
+ /** Exact occurrence identity, distinct from model-independent human review keys. */
13
+ export function clashOccurrenceKey(clash) {
14
+ const elements = [clash.a, clash.b].map(element => [element.model, element.key])
15
+ .sort(([modelA, keyA], [modelB, keyB]) => modelA < modelB ? -1 : modelA > modelB ? 1 : keyA < keyB ? -1 : keyA > keyB ? 1 : 0);
16
+ return JSON.stringify([clash.rule, ...elements]);
17
+ }
18
+ //# sourceMappingURL=clash-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clash-identity.js","sourceRoot":"","sources":["../../src/review/clash-identity.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,WAAW,EAAE,eAAe,EAAc,MAAM,iBAAiB,CAAC;AAE3E,gFAAgF;AAChF,MAAM,UAAU,yBAAyB,CAAC,KAA6B;IACrE,SAAS,UAAU,CAAC,GAAW;QAC7B,OAAO,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACvI,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;AACpE,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,kBAAkB,CAAC,KAAsC;IACvE,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAU,CAAC;SACtF,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjI,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Clash findings: the live run is current; the saved revision baseline is
3
+ * historical. Absence is decided by the native `compareClashRevisions`
4
+ * (skipped rules, empty-match rules, lost models and unre-examined elements
5
+ * stay `unretested`), and additionally never from a truncated or stale run.
6
+ */
7
+ import { type ClashElementRef, type ClashResult } from '@ifc-lite/clash';
8
+ import type { FindingSourceResult, ReviewModel, ReviewMessage } from './types.js';
9
+ export interface ClashFindingInput {
10
+ /** The live run with exclusions applied, and whether edits since make it stale. */
11
+ current: {
12
+ result: ClashResult;
13
+ stale: boolean;
14
+ } | null;
15
+ /** The saved baseline: its result plus the durable model names of its ephemeral model ids. */
16
+ baseline: {
17
+ result: ClashResult;
18
+ modelNames: Readonly<Record<string, string>>;
19
+ takenAt: number;
20
+ } | null;
21
+ }
22
+ /** Instanced occurrences fold `:<occurrenceKey>` into the key; GlobalIds never contain ':'. */
23
+ export declare function clashGlobalId(ref: Pick<ClashElementRef, 'key'>): string;
24
+ export declare function clashFindings<Message extends ReviewMessage = ReviewMessage>(input: ClashFindingInput, models: readonly ReviewModel[]): FindingSourceResult<Message>;
25
+ //# sourceMappingURL=clash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clash.d.ts","sourceRoot":"","sources":["../../src/review/clash.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,EAAqD,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG5H,OAAO,KAAK,EAAgD,mBAAmB,EAAiB,WAAW,EAAU,aAAa,EAAE,MAAM,YAAY,CAAC;AAEvJ,MAAM,WAAW,iBAAiB;IAChC,mFAAmF;IACnF,OAAO,EAAE;QAAE,MAAM,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACxD,8FAA8F;IAC9F,QAAQ,EAAE;QAAE,MAAM,EAAE,WAAW,CAAC;QAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACzG;AAED,+FAA+F;AAC/F,wBAAgB,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,GAAG,MAAM,CAGvE;AA+CD,wBAAgB,aAAa,CAAC,OAAO,SAAS,aAAa,GAAG,aAAa,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAsCnK"}
@@ -0,0 +1,97 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * Clash findings: the live run is current; the saved revision baseline is
6
+ * historical. Absence is decided by the native `compareClashRevisions`
7
+ * (skipped rules, empty-match rules, lost models and unre-examined elements
8
+ * stay `unretested`), and additionally never from a truncated or stale run.
9
+ */
10
+ import { clashReviewKey, compareClashRevisions } from '@ifc-lite/clash';
11
+ import { clashDisciplineCandidates } from './clash-identity.js';
12
+ import { clashOccurrenceKey as manualClashOccurrenceKey } from './clash-identity.js';
13
+ /** Instanced occurrences fold `:<occurrenceKey>` into the key; GlobalIds never contain ':'. */
14
+ export function clashGlobalId(ref) {
15
+ const at = ref.key.indexOf(':');
16
+ return at < 0 ? ref.key : ref.key.slice(0, at);
17
+ }
18
+ function ruleLabel(result) {
19
+ const names = result.rulesRun.map(rule => rule.name).filter(Boolean);
20
+ return names.length ? names.slice(0, 3).join(', ') + (names.length > 3 ? ` +${names.length - 3}` : '') : 'Clash detection';
21
+ }
22
+ function gaps(result, stale) {
23
+ return [
24
+ ...(result.truncated ? [{ code: 'truncated', detail: result.truncated.reason }] : []),
25
+ ...(stale ? [{ code: 'stale' }] : []),
26
+ ];
27
+ }
28
+ function storeyOf(element, models) {
29
+ const model = models.find(candidate => candidate.id === element.modelId);
30
+ if (!model?.storeyOf)
31
+ return [];
32
+ const expressId = model.expressIdOf(element.globalId);
33
+ const storey = expressId > 0 ? model.storeyOf(expressId) : null;
34
+ return storey ? [storey] : [];
35
+ }
36
+ function finding(clash, run, names, models, lifecycle, historical) {
37
+ const element = (ref) => ({
38
+ globalId: clashGlobalId(ref),
39
+ // A historical model id belonged to an earlier session; only its durable name identifies it now.
40
+ modelId: historical ? null : ref.model,
41
+ modelName: names[ref.model] ?? null,
42
+ ifcType: ref.tag,
43
+ ...(ref.name ? { name: ref.name } : {}),
44
+ });
45
+ const elements = [element(clash.a), element(clash.b)];
46
+ const candidates = clashDisciplineCandidates(clash);
47
+ const reviewKey = clashReviewKey(clash);
48
+ const distance = Number.isFinite(clash.distance) ? `${Number(clash.distance.toPrecision(3))}` : 'n/a';
49
+ return {
50
+ id: `${run.id}#${clash.id}`, lineage: `clash|${reviewKey}`, source: 'clash', run, elements,
51
+ nativeStatus: clash.status, title: `${clash.a.tag} × ${clash.b.tag}`,
52
+ detail: [`rule ${clash.rule}`, `severity ${clash.severity}`, `distance ${distance}${clash.distanceKind ? ` (${clash.distanceKind})` : ''}`],
53
+ lifecycle, disciplines: [...new Set([...candidates.a, ...candidates.b])],
54
+ storeys: [...new Set(elements.flatMap(item => storeyOf(item, models)))],
55
+ evidence: historical ? { kind: 'clash-baseline', reviewKey }
56
+ : { kind: 'clash', clashId: clash.id, occurrenceKey: manualClashOccurrenceKey(clash), reviewKey },
57
+ };
58
+ }
59
+ export function clashFindings(input, models) {
60
+ const liveNames = Object.fromEntries(models.map(model => [model.id, model.name]));
61
+ const runs = [];
62
+ const findings = [];
63
+ const { current, baseline } = input;
64
+ const currentRun = current ? {
65
+ id: 'clash:current', source: 'clash', temporal: 'current', label: ruleLabel(current.result), capturedAt: null,
66
+ incomplete: gaps(current.result, current.stale), complete: gaps(current.result, current.stale).length === 0,
67
+ models: [...new Set(current.result.clashes.flatMap(clash => [liveNames[clash.a.model], liveNames[clash.b.model]]).filter(Boolean))],
68
+ } : null;
69
+ const baselineRun = baseline ? {
70
+ id: 'clash:baseline', source: 'clash', temporal: 'historical', label: ruleLabel(baseline.result),
71
+ capturedAt: new Date(baseline.takenAt).toISOString(), incomplete: gaps(baseline.result, false),
72
+ complete: !baseline.result.truncated, models: [...new Set(Object.values(baseline.modelNames))],
73
+ } : null;
74
+ const revision = current && baseline ? compareClashRevisions({ result: baseline.result, modelNames: baseline.modelNames }, { result: current.result, modelNames: liveNames }) : null;
75
+ const added = new Set(revision?.added.map(clash => clash.id));
76
+ const resolvedIds = new Set(revision?.resolved.map(clash => clash.id));
77
+ const currentLineages = new Set(current?.result.clashes.map(clash => `clash|${clashReviewKey(clash)}`));
78
+ if (current && currentRun) {
79
+ runs.push(currentRun);
80
+ for (const clash of current.result.clashes) {
81
+ const lifecycle = !revision ? 'observed' : added.has(clash.id) ? 'new' : 'persistent';
82
+ findings.push(finding(clash, currentRun, liveNames, models, lifecycle, false));
83
+ }
84
+ }
85
+ if (baseline && baselineRun) {
86
+ runs.push(baselineRun);
87
+ for (const clash of baseline.result.clashes) {
88
+ const lineage = `clash|${clashReviewKey(clash)}`;
89
+ // Only a complete current run may turn native `resolved` into a resolution candidate.
90
+ const lifecycle = currentLineages.has(lineage) ? 'persistent'
91
+ : resolvedIds.has(clash.id) && currentRun?.complete ? 'no-longer-observed' : 'not-evaluated';
92
+ findings.push(finding(clash, baselineRun, baseline.modelNames, models, lifecycle, true));
93
+ }
94
+ }
95
+ return { runs, findings };
96
+ }
97
+ //# sourceMappingURL=clash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clash.js","sourceRoot":"","sources":["../../src/review/clash.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ValidationReport } from '@ifc-lite/ids';
2
+ import type { NativeReviewModel, NativeReviewResult, ReviewCaptureToken } from './capture-types.js';
3
+ /** Actual producer-start ownership, never a reconstructed last-result fingerprint. */
4
+ export declare class NativeReviewCaptures {
5
+ private readonly capacity;
6
+ private readonly retention;
7
+ private readonly credentials;
8
+ private credentialBytes;
9
+ private credentialBound;
10
+ constructor(capacity?: number);
11
+ /** Called only with values the actual run already resolved under its grants. */
12
+ enrollCredentials(values: readonly string[]): void;
13
+ acceptsEvidence(value: unknown): boolean;
14
+ private protect;
15
+ begin(producer: 'ids' | 'rules', definition: string, models: readonly NativeReviewModel[], liveModels: () => readonly NativeReviewModel[], allowed: (id: string) => boolean, signal?: AbortSignal): Promise<ReviewCaptureToken | null>;
16
+ /** Release only this producer's pending reservation; never delete settled facts. */
17
+ abandon(token: ReviewCaptureToken | null, reason?: 'producer-failed' | 'aborted'): void;
18
+ finish(token: ReviewCaptureToken | null, report: ValidationReport): void;
19
+ read<T>(liveModels: () => readonly NativeReviewModel[], allowed: (modelId: string) => boolean, project: (result: NativeReviewResult) => T, requested?: (modelId: string) => boolean): Promise<T>;
20
+ }
21
+ //# sourceMappingURL=native-captures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-captures.d.ts","sourceRoot":"","sources":["../../src/review/native-captures.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB,EAClD,MAAM,oBAAoB,CAAC;AAWhD,sFAAsF;AACtF,qBAAa,oBAAoB;IAOnB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IANrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAE7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,eAAe,CAAS;gBAEH,QAAQ,SAAK;IAK1C,gFAAgF;IAChF,iBAAiB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IAqBlD,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAOxC,OAAO,CAAC,OAAO;IAMT,KAAK,CAAC,QAAQ,EAAE,KAAK,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,iBAAiB,EAAE,EAAE,UAAU,EAAE,MAAM,SAAS,iBAAiB,EAAE,EAC7I,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAgD7F,oFAAoF;IACpF,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,EAAE,MAAM,GAAE,iBAAiB,GAAG,SAA6B,GAAG,IAAI;IAQ1G,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAgClE,IAAI,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,SAAS,iBAAiB,EAAE,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,CAAC,EAAE,SAAS,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAoB,GAAG,OAAO,CAAC,CAAC,CAAC;CAiGnN"}