@mack1ch/fingerprint-js 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/LICENSE +21 -0
  3. package/README.md +716 -205
  4. package/demo/index.html +285 -0
  5. package/dist/collectors/audio.d.ts +3 -0
  6. package/dist/collectors/audio.d.ts.map +1 -0
  7. package/dist/collectors/canvas.d.ts +3 -0
  8. package/dist/collectors/canvas.d.ts.map +1 -0
  9. package/dist/collectors/fonts.d.ts +3 -0
  10. package/dist/collectors/fonts.d.ts.map +1 -0
  11. package/dist/collectors/locale.d.ts +3 -0
  12. package/dist/collectors/locale.d.ts.map +1 -0
  13. package/dist/collectors/navigator.d.ts +3 -0
  14. package/dist/collectors/navigator.d.ts.map +1 -0
  15. package/dist/collectors/permissions.d.ts +3 -0
  16. package/dist/collectors/permissions.d.ts.map +1 -0
  17. package/dist/collectors/screen.d.ts +3 -0
  18. package/dist/collectors/screen.d.ts.map +1 -0
  19. package/dist/collectors/storage.d.ts +3 -0
  20. package/dist/collectors/storage.d.ts.map +1 -0
  21. package/dist/collectors/webgl.d.ts +3 -0
  22. package/dist/collectors/webgl.d.ts.map +1 -0
  23. package/dist/core/collector.d.ts +20 -0
  24. package/dist/core/collector.d.ts.map +1 -0
  25. package/dist/core/runCollectors.d.ts +9 -0
  26. package/dist/core/runCollectors.d.ts.map +1 -0
  27. package/dist/core/serializer.d.ts +3 -0
  28. package/dist/core/serializer.d.ts.map +1 -0
  29. package/dist/hash/hash.d.ts +3 -0
  30. package/dist/hash/hash.d.ts.map +1 -0
  31. package/dist/hash/syncHash.d.ts +2 -0
  32. package/dist/hash/syncHash.d.ts.map +1 -0
  33. package/dist/index.cjs +2245 -1421
  34. package/dist/index.cjs.map +1 -0
  35. package/dist/index.d.ts +23 -170
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +2240 -1390
  38. package/dist/index.js.map +1 -0
  39. package/dist/index.umd.js +2299 -0
  40. package/dist/index.umd.js.map +1 -0
  41. package/dist/normalizers/canonicalize.d.ts +2 -0
  42. package/dist/normalizers/canonicalize.d.ts.map +1 -0
  43. package/dist/risk/anomaly.d.ts +3 -0
  44. package/dist/risk/anomaly.d.ts.map +1 -0
  45. package/dist/risk/scoring.d.ts +6 -0
  46. package/dist/risk/scoring.d.ts.map +1 -0
  47. package/dist/types/public.d.ts +70 -0
  48. package/dist/types/public.d.ts.map +1 -0
  49. package/dist/utils/env.d.ts +4 -0
  50. package/dist/utils/env.d.ts.map +1 -0
  51. package/dist/utils/timeout.d.ts +3 -0
  52. package/dist/utils/timeout.d.ts.map +1 -0
  53. package/dist/v2/browser.d.ts +14 -0
  54. package/dist/v2/browser.d.ts.map +1 -0
  55. package/dist/v2/core.d.ts +8 -0
  56. package/dist/v2/core.d.ts.map +1 -0
  57. package/dist/v2/index.d.ts +5 -0
  58. package/dist/v2/index.d.ts.map +1 -0
  59. package/dist/v2/server.d.ts +24 -0
  60. package/dist/v2/server.d.ts.map +1 -0
  61. package/dist/v2/types.d.ts +162 -0
  62. package/dist/v2/types.d.ts.map +1 -0
  63. package/dist/vnext/artifacts.d.ts +11 -0
  64. package/dist/vnext/artifacts.d.ts.map +1 -0
  65. package/dist/vnext/calibration.d.ts +14 -0
  66. package/dist/vnext/calibration.d.ts.map +1 -0
  67. package/dist/vnext/contracts.d.ts +36 -0
  68. package/dist/vnext/contracts.d.ts.map +1 -0
  69. package/dist/vnext/dataset.d.ts +16 -0
  70. package/dist/vnext/dataset.d.ts.map +1 -0
  71. package/dist/vnext/features.d.ts +3 -0
  72. package/dist/vnext/features.d.ts.map +1 -0
  73. package/dist/vnext/index.d.ts +18 -0
  74. package/dist/vnext/index.d.ts.map +1 -0
  75. package/dist/vnext/inference.d.ts +5 -0
  76. package/dist/vnext/inference.d.ts.map +1 -0
  77. package/dist/vnext/labeling.d.ts +13 -0
  78. package/dist/vnext/labeling.d.ts.map +1 -0
  79. package/dist/vnext/logging.d.ts +53 -0
  80. package/dist/vnext/logging.d.ts.map +1 -0
  81. package/dist/vnext/models.d.ts +44 -0
  82. package/dist/vnext/models.d.ts.map +1 -0
  83. package/dist/vnext/monitoring.d.ts +10 -0
  84. package/dist/vnext/monitoring.d.ts.map +1 -0
  85. package/dist/vnext/quality.d.ts +9 -0
  86. package/dist/vnext/quality.d.ts.map +1 -0
  87. package/dist/vnext/retrieval.d.ts +32 -0
  88. package/dist/vnext/retrieval.d.ts.map +1 -0
  89. package/dist/vnext/runtime.d.ts +44 -0
  90. package/dist/vnext/runtime.d.ts.map +1 -0
  91. package/dist/vnext/storage.d.ts +49 -0
  92. package/dist/vnext/storage.d.ts.map +1 -0
  93. package/dist/vnext/types.d.ts +103 -0
  94. package/dist/vnext/types.d.ts.map +1 -0
  95. package/docs/API.md +26 -0
  96. package/docs/ARCHITECTURE.md +48 -0
  97. package/docs/BROWSER_SDK_V2.md +18 -0
  98. package/docs/PAYMENT_FLOW_MAPPING_V2.md +20 -0
  99. package/docs/SECURITY_PRIVACY.md +21 -0
  100. package/docs/SERVER_SDK_V2.md +25 -0
  101. package/docs/TESTING.md +33 -0
  102. package/docs/UPGRADE_V2.md +21 -0
  103. package/docs/VNEXT_PHASE2.md +65 -0
  104. package/docs/rollout-checklist.md +54 -0
  105. package/docs/threshold-policy.md +50 -0
  106. package/package.json +60 -85
  107. package/dist/index.d.cts +0 -170
@@ -0,0 +1,36 @@
1
+ import type { CalibrationKind, ThresholdPolicy, VersionSet } from "./types.js";
2
+ export interface VersionedEnvelope {
3
+ collectorVersion: string;
4
+ featureSchemaVersion: string;
5
+ modelVersion: string;
6
+ calibrationVersion: string;
7
+ thresholdPolicyVersion: string;
8
+ }
9
+ export interface ModelArtifact {
10
+ artifactType: "model";
11
+ modelKind: "logreg_baseline" | "gbdt_production";
12
+ modelVersion: string;
13
+ featureSchemaVersion: string;
14
+ featureList: string[];
15
+ payload: Record<string, unknown>;
16
+ }
17
+ export interface CalibrationArtifact {
18
+ artifactType: "calibration";
19
+ calibrationKind: CalibrationKind;
20
+ calibrationVersion: string;
21
+ expectedModelVersion: string;
22
+ payload: Record<string, unknown>;
23
+ }
24
+ export interface ThresholdArtifact {
25
+ artifactType: "threshold_policy";
26
+ thresholdPolicyVersion: string;
27
+ expectedModelVersion: string;
28
+ payload: ThresholdPolicy;
29
+ }
30
+ export interface CompatibilityResult {
31
+ ok: boolean;
32
+ errors: string[];
33
+ }
34
+ export declare function buildVersionSet(input?: Partial<VersionSet>): VersionSet;
35
+ export declare function validateArtifactCompatibility(versions: VersionedEnvelope, model: ModelArtifact, calibration: CalibrationArtifact, threshold: ThresholdArtifact): CompatibilityResult;
36
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/vnext/contracts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE/E,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,iBAAiB,GAAG,iBAAiB,CAAC;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,aAAa,CAAC;IAC5B,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,kBAAkB,CAAC;IACjC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,eAAe,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,eAAe,CAAC,KAAK,GAAE,OAAO,CAAC,UAAU,CAAM,GAAG,UAAU,CAQ3E;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,mBAAmB,EAChC,SAAS,EAAE,iBAAiB,GAC3B,mBAAmB,CAkCrB"}
@@ -0,0 +1,16 @@
1
+ import type { FingerprintSnapshotVNext, PairwiseTrainingRow } from "./types.js";
2
+ export interface SnapshotWithLabel {
3
+ snapshotId: string;
4
+ snapshot: FingerprintSnapshotVNext;
5
+ deviceId: string;
6
+ cohort: PairwiseTrainingRow["cohort"];
7
+ }
8
+ export declare function buildPairwiseTrainingDataset(positives: Array<{
9
+ left: SnapshotWithLabel;
10
+ right: SnapshotWithLabel;
11
+ }>, negatives: Array<{
12
+ left: SnapshotWithLabel;
13
+ right: SnapshotWithLabel;
14
+ difficulty: "easy" | "medium" | "hard";
15
+ }>): PairwiseTrainingRow[];
16
+ //# sourceMappingURL=dataset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../../src/vnext/dataset.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEhF,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,wBAAwB,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC;CACvC;AAMD,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAA;CAAE,CAAC,EACvE,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;CAAE,CAAC,GAC9G,mBAAmB,EAAE,CA0CvB"}
@@ -0,0 +1,3 @@
1
+ import type { FingerprintSnapshotVNext, PairwiseRow } from "./types.js";
2
+ export declare function buildPairwiseFeatures(leftSnapshotId: string, left: FingerprintSnapshotVNext, rightSnapshotId: string, right: FingerprintSnapshotVNext, candidateType: string): PairwiseRow;
3
+ //# sourceMappingURL=features.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../src/vnext/features.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAoCxE,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,wBAAwB,EAC9B,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,wBAAwB,EAC/B,aAAa,EAAE,MAAM,GACpB,WAAW,CA6Gb"}
@@ -0,0 +1,18 @@
1
+ export type { CalibrationKind, CandidateContext, CandidateItem, CohortMetrics, FingerprintSnapshotVNext, MatchDecision, PairwiseRow, PairwiseTrainingRow, RolloutMode, SnapshotComponentVNext, ThresholdPolicy, VersionSet } from "./types.js";
2
+ export type { CalibrationArtifact, ModelArtifact, ThresholdArtifact, VersionedEnvelope } from "./contracts.js";
3
+ export { retrieveCandidates } from "./retrieval.js";
4
+ export { recallAtK } from "./retrieval.js";
5
+ export { buildPairwiseFeatures } from "./features.js";
6
+ export { LogisticRegressionBaselineModel, GBDTProductionModel } from "./models.js";
7
+ export { ProbabilityCalibrator } from "./calibration.js";
8
+ export { buildPairwiseTrainingDataset } from "./dataset.js";
9
+ export { inferMatchDecisions } from "./inference.js";
10
+ export { cohortMetrics, distributionDrift, quickMetrics } from "./monitoring.js";
11
+ export { buildVersionSet, validateArtifactCompatibility } from "./contracts.js";
12
+ export { loadArtifacts } from "./artifacts.js";
13
+ export { InMemoryVNextLogger, toPairwiseLog, toRetrievalLog } from "./logging.js";
14
+ export { InMemoryVNextStorage } from "./storage.js";
15
+ export { buildLabels } from "./labeling.js";
16
+ export { VNextRuntime } from "./runtime.js";
17
+ export { groupQualityScore, resolveComponentQuality } from "./quality.js";
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vnext/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,wBAAwB,EACxB,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,+BAA+B,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { PairwiseModel } from "./models.js";
2
+ import type { CandidateItem, FingerprintSnapshotVNext, MatchDecision, ThresholdPolicy } from "./types.js";
3
+ import type { ProbabilityCalibrator } from "./calibration.js";
4
+ export declare function inferMatchDecisions(currentSnapshotId: string, current: FingerprintSnapshotVNext, candidates: CandidateItem[], model: PairwiseModel, calibrator: ProbabilityCalibrator, thresholds: ThresholdPolicy, calibrationVersion?: string): MatchDecision[];
5
+ //# sourceMappingURL=inference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference.d.ts","sourceRoot":"","sources":["../../src/vnext/inference.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,wBAAwB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC1G,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAS9D,wBAAgB,mBAAmB,CACjC,iBAAiB,EAAE,MAAM,EACzB,OAAO,EAAE,wBAAwB,EACjC,UAAU,EAAE,aAAa,EAAE,EAC3B,KAAK,EAAE,aAAa,EACpB,UAAU,EAAE,qBAAqB,EACjC,UAAU,EAAE,eAAe,EAC3B,kBAAkB,SAAW,GAC5B,aAAa,EAAE,CA2BjB"}
@@ -0,0 +1,13 @@
1
+ import type { PairwiseTrainingRow } from "./types.js";
2
+ import type { PairwiseLogEvent, SnapshotLogEvent } from "./logging.js";
3
+ export interface LabelAnchor {
4
+ anchorType: "confirmed_same_device" | "verified_business_link" | "same_entity_verified" | "manual_review_positive" | "manual_review_negative";
5
+ value: string;
6
+ }
7
+ export interface LabelingInput {
8
+ snapshots: SnapshotLogEvent[];
9
+ pairwiseLogs: PairwiseLogEvent[];
10
+ anchorsBySnapshotId: Record<string, LabelAnchor[]>;
11
+ }
12
+ export declare function buildLabels(input: LabelingInput): PairwiseTrainingRow[];
13
+ //# sourceMappingURL=labeling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labeling.d.ts","sourceRoot":"","sources":["../../src/vnext/labeling.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEvE,MAAM,WAAW,WAAW;IAC1B,UAAU,EACN,uBAAuB,GACvB,wBAAwB,GACxB,sBAAsB,GACtB,wBAAwB,GACxB,wBAAwB,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;CACpD;AAoBD,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,mBAAmB,EAAE,CAsCvE"}
@@ -0,0 +1,53 @@
1
+ import type { CandidateItem, FingerprintSnapshotVNext, MatchDecision, VersionSet } from "./types.js";
2
+ import type { PairwiseRow } from "./types.js";
3
+ export interface SnapshotLogEvent {
4
+ snapshotId: string;
5
+ collectedAt: string;
6
+ schemaVersion: string;
7
+ versions: VersionSet;
8
+ ids: FingerprintSnapshotVNext["ids"];
9
+ cohortTags: Record<string, string | boolean | null>;
10
+ componentMetadata: Record<string, unknown>;
11
+ qualityMetadata: Record<string, unknown>;
12
+ businessAnchors: Record<string, string | undefined>;
13
+ }
14
+ export interface RetrievalLogEvent {
15
+ snapshotId: string;
16
+ retrievalSources: string[];
17
+ candidates: Array<{
18
+ candidateSnapshotId: string;
19
+ candidateRank: number;
20
+ candidateSource: string;
21
+ retrievalReason: string;
22
+ }>;
23
+ }
24
+ export interface PairwiseLogEvent {
25
+ pairId: string;
26
+ snapshotId: string;
27
+ candidateSnapshotId: string;
28
+ features: Record<string, number>;
29
+ rawScore: number;
30
+ calibratedProbability: number;
31
+ decision: MatchDecision["decision"];
32
+ reasons: string[];
33
+ versions: VersionSet;
34
+ }
35
+ export interface VNextLogger {
36
+ enabled: boolean;
37
+ logSnapshot(event: SnapshotLogEvent): void;
38
+ logRetrieval(event: RetrievalLogEvent): void;
39
+ logPairwise(event: PairwiseLogEvent): void;
40
+ }
41
+ export declare class InMemoryVNextLogger implements VNextLogger {
42
+ enabled: boolean;
43
+ readonly snapshotEvents: SnapshotLogEvent[];
44
+ readonly retrievalEvents: RetrievalLogEvent[];
45
+ readonly pairwiseEvents: PairwiseLogEvent[];
46
+ constructor(enabled?: boolean);
47
+ logSnapshot(event: SnapshotLogEvent): void;
48
+ logRetrieval(event: RetrievalLogEvent): void;
49
+ logPairwise(event: PairwiseLogEvent): void;
50
+ }
51
+ export declare function toRetrievalLog(snapshotId: string, candidates: CandidateItem[]): RetrievalLogEvent;
52
+ export declare function toPairwiseLog(pair: PairwiseRow, rawScore: number, calibratedProbability: number, decision: MatchDecision, versions: VersionSet): PairwiseLogEvent;
53
+ //# sourceMappingURL=logging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../src/vnext/logging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,wBAAwB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACrG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,UAAU,CAAC;IACrB,GAAG,EAAE,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;IACpD,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,EAAE,KAAK,CAAC;QAChB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,UAAU,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC3C,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC7C,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC5C;AAED,qBAAa,mBAAoB,YAAW,WAAW;IACrD,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,cAAc,EAAE,gBAAgB,EAAE,CAAM;IACjD,QAAQ,CAAC,eAAe,EAAE,iBAAiB,EAAE,CAAM;IACnD,QAAQ,CAAC,cAAc,EAAE,gBAAgB,EAAE,CAAM;gBAErC,OAAO,UAAO;IAI1B,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAK1C,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAK5C,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;CAI3C;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,iBAAiB,CAWjG;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,MAAM,EAChB,qBAAqB,EAAE,MAAM,EAC7B,QAAQ,EAAE,aAAa,EACvB,QAAQ,EAAE,UAAU,GACnB,gBAAgB,CAYlB"}
@@ -0,0 +1,44 @@
1
+ import type { ModelKind } from "./types.js";
2
+ export interface PairwiseModel {
3
+ kind: ModelKind;
4
+ modelVersion: string;
5
+ train(rows: Array<{
6
+ features: Record<string, number>;
7
+ label: 0 | 1;
8
+ }>): void;
9
+ score(features: Record<string, number>): number;
10
+ explain(features: Record<string, number>): {
11
+ positive: string[];
12
+ negative: string[];
13
+ };
14
+ }
15
+ export declare class LogisticRegressionBaselineModel implements PairwiseModel {
16
+ kind: ModelKind;
17
+ modelVersion: string;
18
+ private weights;
19
+ private bias;
20
+ train(rows: Array<{
21
+ features: Record<string, number>;
22
+ label: 0 | 1;
23
+ }>): void;
24
+ score(features: Record<string, number>): number;
25
+ explain(features: Record<string, number>): {
26
+ positive: string[];
27
+ negative: string[];
28
+ };
29
+ }
30
+ export declare class GBDTProductionModel implements PairwiseModel {
31
+ kind: ModelKind;
32
+ modelVersion: string;
33
+ private importance;
34
+ train(rows: Array<{
35
+ features: Record<string, number>;
36
+ label: 0 | 1;
37
+ }>): void;
38
+ score(features: Record<string, number>): number;
39
+ explain(features: Record<string, number>): {
40
+ positive: string[];
41
+ negative: string[];
42
+ };
43
+ }
44
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/vnext/models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;IAC7E,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;IAChD,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACvF;AAMD,qBAAa,+BAAgC,YAAW,aAAa;IACnE,IAAI,EAAE,SAAS,CAAqB;IACpC,YAAY,SAAe;IAC3B,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,IAAI,CAAK;IAEjB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC,GAAG,IAAI;IAuB5E,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM;IAQ/C,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE;CAmBtF;AAED,qBAAa,mBAAoB,YAAW,aAAa;IACvD,IAAI,EAAE,SAAS,CAAqB;IACpC,YAAY,SAAa;IACzB,OAAO,CAAC,UAAU,CAA6B;IAE/C,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC,GAAG,IAAI;IAY5E,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM;IAgB/C,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE;CAmBtF"}
@@ -0,0 +1,10 @@
1
+ import type { CohortMetrics, PairwiseTrainingRow } from "./types.js";
2
+ export declare function quickMetrics(rows: PairwiseTrainingRow[], probabilities: number[]): {
3
+ prAuc: number;
4
+ rocAuc: number;
5
+ logLoss: number;
6
+ brier: number;
7
+ };
8
+ export declare function cohortMetrics(rows: PairwiseTrainingRow[], probabilities: number[], cohortKey: keyof PairwiseTrainingRow["cohort"]): CohortMetrics[];
9
+ export declare function distributionDrift(reference: number[], current: number[]): number;
10
+ //# sourceMappingURL=monitoring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitoring.d.ts","sourceRoot":"","sources":["../../src/vnext/monitoring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAMrE,wBAAgB,YAAY,CAC1B,IAAI,EAAE,mBAAmB,EAAE,EAC3B,aAAa,EAAE,MAAM,EAAE,GACtB;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAgCA;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,mBAAmB,EAAE,EAC3B,aAAa,EAAE,MAAM,EAAE,EACvB,SAAS,EAAE,MAAM,mBAAmB,CAAC,QAAQ,CAAC,GAC7C,aAAa,EAAE,CAgBjB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAoBhF"}
@@ -0,0 +1,9 @@
1
+ import type { FingerprintSnapshotVNext } from "./types.js";
2
+ export type ComponentQualityStatus = "present" | "missing" | "unstable" | "privacy_reduced" | "collector_error";
3
+ export interface ComponentQuality {
4
+ status: ComponentQualityStatus;
5
+ qualityScore: number;
6
+ }
7
+ export declare function resolveComponentQuality(snapshot: FingerprintSnapshotVNext): Record<string, ComponentQuality>;
8
+ export declare function groupQualityScore(snapshot: FingerprintSnapshotVNext): number;
9
+ //# sourceMappingURL=quality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../../src/vnext/quality.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D,MAAM,MAAM,sBAAsB,GAC9B,SAAS,GACT,SAAS,GACT,UAAU,GACV,iBAAiB,GACjB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;CACtB;AAkBD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAc5G;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,MAAM,CAK5E"}
@@ -0,0 +1,32 @@
1
+ import type { CandidateContext, CandidateItem, FingerprintSnapshotVNext } from "./types.js";
2
+ export interface CandidateRetrievalStore {
3
+ getAllSnapshots(): Array<{
4
+ snapshotId: string;
5
+ snapshot: FingerprintSnapshotVNext;
6
+ }>;
7
+ getByStableId(stableId: string): Array<{
8
+ snapshotId: string;
9
+ snapshot: FingerprintSnapshotVNext;
10
+ }>;
11
+ getByEnvironmentId(environmentId: string): Array<{
12
+ snapshotId: string;
13
+ snapshot: FingerprintSnapshotVNext;
14
+ }>;
15
+ getByBucket(bucket: string): Array<{
16
+ snapshotId: string;
17
+ snapshot: FingerprintSnapshotVNext;
18
+ }>;
19
+ getByContext(context: CandidateContext): Array<{
20
+ snapshotId: string;
21
+ snapshot: FingerprintSnapshotVNext;
22
+ }>;
23
+ }
24
+ export interface CandidateRetrievalConfig {
25
+ maxCandidates: number;
26
+ includeEnvironmentId: boolean;
27
+ includeBucketRetrieval: boolean;
28
+ includeContextRetrieval: boolean;
29
+ }
30
+ export declare function retrieveCandidates(current: FingerprintSnapshotVNext, store: CandidateRetrievalStore, context: CandidateContext, config: CandidateRetrievalConfig): CandidateItem[];
31
+ export declare function recallAtK(retrievedCandidateIds: string[], trueMatchIds: string[], k: number): number;
32
+ //# sourceMappingURL=retrieval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retrieval.d.ts","sourceRoot":"","sources":["../../src/vnext/retrieval.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE5F,MAAM,WAAW,uBAAuB;IACtC,eAAe,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,wBAAwB,CAAA;KAAE,CAAC,CAAC;IACrF,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,wBAAwB,CAAA;KAAE,CAAC,CAAC;IACnG,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,wBAAwB,CAAA;KAAE,CAAC,CAAC;IAC7G,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,wBAAwB,CAAA;KAAE,CAAC,CAAC;IAC/F,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,wBAAwB,CAAA;KAAE,CAAC,CAAC;CAC5G;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,sBAAsB,EAAE,OAAO,CAAC;IAChC,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAgDD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,uBAAuB,EAC9B,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,wBAAwB,GAC/B,aAAa,EAAE,CAmCjB;AAED,wBAAgB,SAAS,CAAC,qBAAqB,EAAE,MAAM,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAKpG"}
@@ -0,0 +1,44 @@
1
+ import { type CalibrationArtifact, type ModelArtifact, type ThresholdArtifact } from "./contracts.js";
2
+ import { type VNextLogger } from "./logging.js";
3
+ import type { CandidateContext, FingerprintSnapshotVNext, MatchDecision, RolloutMode, VersionSet } from "./types.js";
4
+ import { type CandidateRetrievalConfig, type CandidateRetrievalStore } from "./retrieval.js";
5
+ import type { InMemoryVNextStorage } from "./storage.js";
6
+ export interface RuntimeConfig {
7
+ rolloutMode: RolloutMode;
8
+ versions: VersionSet;
9
+ retrievalConfig: CandidateRetrievalConfig;
10
+ logger?: VNextLogger;
11
+ }
12
+ export interface RuntimeContext {
13
+ candidateContext: CandidateContext;
14
+ cohortTags: Record<string, string | boolean | null>;
15
+ businessAnchors: Record<string, string | undefined>;
16
+ }
17
+ export interface RuntimeResult {
18
+ mode: RolloutMode;
19
+ decisions: MatchDecision[];
20
+ compareDiff?: {
21
+ previousDecision: string;
22
+ newDecision: string;
23
+ };
24
+ }
25
+ export declare class VNextRuntime {
26
+ private readonly config;
27
+ private readonly store;
28
+ private readonly logger;
29
+ private readonly retrievalStore;
30
+ private readonly modelArtifact;
31
+ private readonly calibrationArtifact;
32
+ private readonly thresholdArtifact;
33
+ constructor(args: {
34
+ config: RuntimeConfig;
35
+ storage: InMemoryVNextStorage;
36
+ retrievalStore: CandidateRetrievalStore;
37
+ modelArtifact: ModelArtifact;
38
+ calibrationArtifact: CalibrationArtifact;
39
+ thresholdArtifact: ThresholdArtifact;
40
+ });
41
+ processSnapshot(snapshotId: string, snapshot: FingerprintSnapshotVNext, context: RuntimeContext): RuntimeResult;
42
+ private scoreDeterministic;
43
+ }
44
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/vnext/runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAAiC,KAAK,mBAAmB,EAAE,KAAK,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAErI,OAAO,EAAsD,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACpG,OAAO,KAAK,EAAE,gBAAgB,EAAiB,wBAAwB,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACpI,OAAO,EAAsB,KAAK,wBAAwB,EAAE,KAAK,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACjH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGzD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,UAAU,CAAC;IACrB,eAAe,EAAE,wBAAwB,CAAC;IAC1C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;IACpD,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE;QACZ,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0B;IACzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAC1D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;gBAE1C,IAAI,EAAE;QAChB,MAAM,EAAE,aAAa,CAAC;QACtB,OAAO,EAAE,oBAAoB,CAAC;QAC9B,cAAc,EAAE,uBAAuB,CAAC;QACxC,aAAa,EAAE,aAAa,CAAC;QAC7B,mBAAmB,EAAE,mBAAmB,CAAC;QACzC,iBAAiB,EAAE,iBAAiB,CAAC;KACtC;IAUD,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,wBAAwB,EAAE,OAAO,EAAE,cAAc,GAAG,aAAa;IAuF/G,OAAO,CAAC,kBAAkB;CA6C3B"}
@@ -0,0 +1,49 @@
1
+ import type { CandidateItem, FingerprintSnapshotVNext, MatchDecision, PairwiseRow, VersionSet } from "./types.js";
2
+ export interface SnapshotRecord {
3
+ snapshotId: string;
4
+ snapshot: FingerprintSnapshotVNext;
5
+ versions: VersionSet;
6
+ cohortTags: Record<string, string | boolean | null>;
7
+ createdAt: number;
8
+ }
9
+ export interface RetrievalLogRecord {
10
+ snapshotId: string;
11
+ createdAt: number;
12
+ candidates: CandidateItem[];
13
+ retrievalSources: string[];
14
+ }
15
+ export interface PairwiseLogRecord {
16
+ pair: PairwiseRow;
17
+ createdAt: number;
18
+ rawScore: number;
19
+ calibratedProbability: number;
20
+ decision: MatchDecision["decision"];
21
+ reasons: string[];
22
+ versions: VersionSet;
23
+ }
24
+ export interface DecisionRecord {
25
+ snapshotId: string;
26
+ decision: MatchDecision;
27
+ createdAt: number;
28
+ }
29
+ export interface DeviceProfileRecord {
30
+ deviceId: string;
31
+ snapshots: string[];
32
+ scoreHistory: number[];
33
+ stabilityHistory: number[];
34
+ updatedAt: number;
35
+ }
36
+ export declare class InMemoryVNextStorage {
37
+ readonly snapshots: Map<string, SnapshotRecord>;
38
+ readonly retrievalLogs: RetrievalLogRecord[];
39
+ readonly pairwiseLogs: PairwiseLogRecord[];
40
+ readonly decisions: DecisionRecord[];
41
+ readonly deviceProfiles: Map<string, DeviceProfileRecord>;
42
+ putSnapshot(record: SnapshotRecord): void;
43
+ getSnapshot(snapshotId: string): SnapshotRecord | undefined;
44
+ addRetrievalLog(record: RetrievalLogRecord): void;
45
+ addPairwiseLog(record: PairwiseLogRecord): void;
46
+ addDecision(record: DecisionRecord): void;
47
+ upsertDeviceProfile(deviceId: string, snapshotId: string, calibratedProbability: number, stabilityScore: number): void;
48
+ }
49
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/vnext/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,wBAAwB,EACxB,aAAa,EACb,WAAW,EACX,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,wBAAwB,CAAC;IACnC,QAAQ,EAAE,UAAU,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;IACpD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,UAAU,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,aAAa,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,oBAAoB;IAC/B,QAAQ,CAAC,SAAS,8BAAqC;IACvD,QAAQ,CAAC,aAAa,EAAE,kBAAkB,EAAE,CAAM;IAClD,QAAQ,CAAC,YAAY,EAAE,iBAAiB,EAAE,CAAM;IAChD,QAAQ,CAAC,SAAS,EAAE,cAAc,EAAE,CAAM;IAC1C,QAAQ,CAAC,cAAc,mCAA0C;IAEjE,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAIzC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI3D,eAAe,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAIjD,cAAc,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAI/C,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAIzC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI;CAiBvH"}
@@ -0,0 +1,103 @@
1
+ export type ModelKind = "logreg_baseline" | "gbdt_production";
2
+ export type CalibrationKind = "sigmoid" | "isotonic";
3
+ export type RolloutMode = "shadow" | "compare" | "assist" | "enforcement";
4
+ export interface SnapshotComponentVNext {
5
+ normalizedValue?: unknown;
6
+ hash?: string;
7
+ isPresent: boolean;
8
+ isStable?: boolean;
9
+ privacyReduced?: boolean;
10
+ errorCode?: string | null;
11
+ collectionTimeMs?: number;
12
+ }
13
+ export interface FingerprintSnapshotVNext {
14
+ schemaVersion: string;
15
+ sdkVersion: string;
16
+ collectedAt: string;
17
+ ids: {
18
+ fingerprintId: string;
19
+ stableId?: string;
20
+ environmentId: string;
21
+ };
22
+ meta: {
23
+ mode: "fast" | "balanced" | "strict";
24
+ totalCollectionTimeMs: number;
25
+ };
26
+ components: Record<string, SnapshotComponentVNext>;
27
+ topLevelFlags: {
28
+ webdriver: boolean | null;
29
+ automationLikely: boolean;
30
+ incognitoLikely: boolean | null;
31
+ uaSpoofLikely: boolean;
32
+ emulatorLikely: boolean;
33
+ };
34
+ }
35
+ export interface CandidateContext {
36
+ payerId?: string;
37
+ instrumentId?: string;
38
+ sessionId?: string;
39
+ accountId?: string;
40
+ }
41
+ export interface CandidateItem {
42
+ snapshotId: string;
43
+ snapshot: FingerprintSnapshotVNext;
44
+ retrievalReason: string;
45
+ }
46
+ export interface PairwiseRow {
47
+ pairId: string;
48
+ leftSnapshotId: string;
49
+ rightSnapshotId: string;
50
+ features: Record<string, number>;
51
+ metadata: {
52
+ candidateType: string;
53
+ };
54
+ }
55
+ export interface PairwiseTrainingRow {
56
+ pairId: string;
57
+ leftSnapshotId: string;
58
+ rightSnapshotId: string;
59
+ label: 0 | 1;
60
+ cohort: {
61
+ browserFamily?: string;
62
+ osFamily?: string;
63
+ mobileDesktop?: "mobile" | "desktop";
64
+ privateMode?: boolean | null;
65
+ spoofingLikely?: boolean;
66
+ };
67
+ features: Record<string, number | string | boolean | null>;
68
+ }
69
+ export interface CalibratedScore {
70
+ rawScore: number;
71
+ calibratedProbability: number;
72
+ }
73
+ export interface MatchDecision {
74
+ candidateSnapshotId: string;
75
+ rawScore: number;
76
+ calibratedProbability: number;
77
+ decision: "same_device" | "likely_same" | "review" | "different";
78
+ reasons: string[];
79
+ modelVersion: string;
80
+ calibrationVersion: string;
81
+ thresholdPolicyVersion: string;
82
+ }
83
+ export interface ThresholdPolicy {
84
+ thresholdPolicyVersion: string;
85
+ sameDeviceMin: number;
86
+ likelySameMin: number;
87
+ reviewMin: number;
88
+ }
89
+ export interface VersionSet {
90
+ collectorVersion: string;
91
+ featureSchemaVersion: string;
92
+ modelVersion: string;
93
+ calibrationVersion: string;
94
+ thresholdPolicyVersion: string;
95
+ }
96
+ export interface CohortMetrics {
97
+ cohort: string;
98
+ prAuc: number;
99
+ rocAuc: number;
100
+ logLoss: number;
101
+ brier: number;
102
+ }
103
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/vnext/types.ts"],"names":[],"mappings":"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"}
package/docs/API.md ADDED
@@ -0,0 +1,26 @@
1
+ # Справка по API
2
+
3
+ ## `FingerprintOptions`
4
+
5
+ Поддерживает таймауты, выбор режима, включение/отключение collectors, debug/raw вывод, `salt` и пользовательские компоненты.
6
+
7
+ Все методы Promise-based. Для каждого collector используется fail-soft поведение.
8
+
9
+ ## `FingerprintResult`
10
+
11
+ - `fingerprintId`, `stableId`, `environmentId`
12
+ - `confidenceScore` (`0..100`)
13
+ - `riskScore` (`0..100`)
14
+ - `flags` (индикаторы automation/tamper/privacy)
15
+ - `components` (опциональные сырые данные)
16
+ - `debug` (опциональная диагностика collectors + timings)
17
+
18
+ ## Коды ошибок
19
+
20
+ - `ERR_UNSUPPORTED_API`
21
+ - `ERR_TIMEOUT`
22
+ - `ERR_SECURITY_RESTRICTED`
23
+ - `ERR_PERMISSION_DENIED`
24
+ - `ERR_RENDER_UNSTABLE`
25
+ - `ERR_TAMPER_SUSPECTED`
26
+ - `ERR_BROWSER_CONTEXT_REQUIRED`
@@ -0,0 +1,48 @@
1
+ # Архитектура
2
+
3
+ ## Слои
4
+
5
+ 1. Слой collectors (`src/collectors/*`)
6
+ 2. Слой нормализации (`src/normalizers/*`)
7
+ 3. Слой stability + anomaly (`src/risk/*`)
8
+ 4. Слой хэширования (`src/hash/*`)
9
+ 5. Оркестрация API (`src/index.ts`)
10
+
11
+ ## Collectors
12
+
13
+ - navigator/browser identity
14
+ - locale/timezone/Intl formats
15
+ - screen + media queries
16
+ - canvas (text + geometry + повторная проверка стабильности)
17
+ - WebGL (renderer/extensions/caps/hash)
18
+ - audio (OfflineAudioContext + повторная проверка стабильности)
19
+ - fonts (безопасный detection + strict расширение)
20
+ - storage capability
21
+ - permissions (только query, без prompts)
22
+
23
+ ## Модель scoring
24
+
25
+ - `confidenceScore` уменьшается при недоступных/нестабильных/ограниченных сигналах.
26
+ - `riskScore` растет при automation/emulator/spoof/tamper индикаторах.
27
+
28
+ ## Модель деградации
29
+
30
+ Недоступные API помечаются как `unsupported`/`restricted`/`timeout` и не ломают итоговый результат.
31
+
32
+ ## Архитектура апгрейда V2
33
+
34
+ V2 расширяет v1 до единого browser + server antifraud контура:
35
+
36
+ - Browser SDK: `src/v2/browser.ts`
37
+ - Server SDK: `src/v2/server.ts`
38
+ - Shared core: `src/v2/core.ts`
39
+ - Shared types/contracts: `src/v2/types.ts`
40
+
41
+ ### План миграции
42
+
43
+ 1. Shadow mode: запуск v2 scoring/profile linking без влияния на решения.
44
+ 2. Compare mode: сравнение качества match/risk между v1 и v2.
45
+ 3. Assist mode: показ explainability v2 в админке.
46
+ 4. Enforcement mode: v2 сигналы влияют на прод-решения.
47
+
48
+ Обратная совместимость реализована через `migrateV1PayloadToV2()`.
@@ -0,0 +1,18 @@
1
+ # Руководство по Browser SDK (v2)
2
+
3
+ ## Lifecycle hooks
4
+
5
+ - Stage A: `page_open` (fast)
6
+ - Stage B: `pre_submit` (balanced/strict)
7
+ - Stage C: `post_init` (after order/redirect)
8
+
9
+ ## Пример
10
+
11
+ Используйте `BrowserFingerprintSession`:
12
+
13
+ - `collectStage(...)` для формирования stage envelope
14
+ - `registerSubmitAttempt()` при попытках submit
15
+
16
+ Передавайте бизнес-контекст:
17
+
18
+ - `partnerId`, `projectId`, `flowType`, `paymentType`, `userId`, `userData`, `shopUrl`, `lang`
@@ -0,0 +1,20 @@
1
+ # Маппинг платежных флоу (v2)
2
+
3
+ ## card_form
4
+
5
+ - page_open -> pre_submit -> payment init -> callback
6
+ - token (если есть) связывает device <-> instrument profile
7
+
8
+ ## card_recurring
9
+
10
+ - `tokenHash` — сильный сигнал exact-link
11
+ - знакомый token + новое аномальное устройство повышают риск
12
+
13
+ ## sbp_form
14
+
15
+ - `phone`/`email`/`pay_ttl` включаются в контекст
16
+ - `redirect_url` может прийти позже через notify flow
17
+
18
+ ## sbp_gate
19
+
20
+ - поддерживается отложенный `redirect_url` и post-init linking по `orderId`