{"_id":"@adhd/sox-claim-verification","_rev":"6-b173a9e7f7337754b8df9f41cb5b1778","name":"@adhd/sox-claim-verification","dist-tags":{"latest":"0.1.5"},"versions":{"0.1.0":{"name":"@adhd/sox-claim-verification","version":"0.1.0","license":"MIT","_id":"@adhd/sox-claim-verification@0.1.0","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"sox":{"area":"data","group":"verify","concerns":["NLI claim grounding via cross-encoder","worker-thread ONNX inference (BL-11 isolation)","embedding pre-filter for topic gating","configurable truncation (tail/head)","LRU verification cache","multi-source verification (one claim, many sources)","streaming batch verification","model registry with version tracking"],"invariants":["ONNX inference runs exclusively in worker threads - never on main thread","pre-filter uses its OWN embedding provider instance (not coupled to retrieval pipeline)","warmUp() must complete before verify* calls","language mismatch downgrades to 'neutral' with warning flag - never throws","claim normalization strips citation markers and quotation marks before NLI"],"entrypoints":["dist/index.js"]},"dist":{"shasum":"55e00c7f01d1ee2f97377ee366a8bad234839d2f","tarball":"https://registry.npmjs.org/@adhd/sox-claim-verification/-/sox-claim-verification-0.1.0.tgz","fileCount":38,"integrity":"sha512-ESCDSit7fJ1qcw4dxDBgAkX46bL4J00s7yb1djn7qji7GtufwiBTEMFldXf8rhmUkvyXN8ZXRDwS2gqyL0IUeQ==","signatures":[{"sig":"MEUCIQCWqS9FrnVQAA/PxH8ajx0Et6lK4iiTgjcXQ9KCurjc8QIgI55Ez9quRwz1xnv87zHO1EFHc5G1bwOacdog92lFp+E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":80142},"main":"./dist/index.js","type":"module","_from":"file:adhd-sox-claim-verification-0.1.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/06e260e93012ccab231d9a4ef7702455/adhd-sox-claim-verification-0.1.0.tgz","_integrity":"sha512-ESCDSit7fJ1qcw4dxDBgAkX46bL4J00s7yb1djn7qji7GtufwiBTEMFldXf8rhmUkvyXN8ZXRDwS2gqyL0IUeQ==","_npmVersion":"11.6.2","description":"NLI-based (Natural Language Inference) claim grounding engine. Cross-encoder NLI via worker thread, embedding pre-filter, configurable truncation strategy, LRU result cache. Worker-thread isolated from better-sqlite3 (BL-11).","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@adhd/sox-embedding-provider":"0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@adhd/sox-blob-store":"0.1.0","@adhd/sox-hybrid-search":"0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/sox-claim-verification_0.1.0_1784239337529_0.6141610233031345","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@adhd/sox-claim-verification","version":"0.1.1","license":"MIT","_id":"@adhd/sox-claim-verification@0.1.1","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"sox":{"area":"data","group":"verify","concerns":["NLI claim grounding via cross-encoder","worker-thread ONNX inference (BL-11 isolation)","embedding pre-filter for topic gating","configurable truncation (tail/head)","LRU verification cache","multi-source verification (one claim, many sources)","streaming batch verification","model registry with version tracking"],"invariants":["ONNX inference runs exclusively in worker threads - never on main thread","pre-filter uses its OWN embedding provider instance (not coupled to retrieval pipeline)","warmUp() must complete before verify* calls","language mismatch downgrades to 'neutral' with warning flag - never throws","claim normalization strips citation markers and quotation marks before NLI"],"entrypoints":["dist/index.js"]},"dist":{"shasum":"e1d926251a658f2083eb6d2fce351e2a2806d3ea","tarball":"https://registry.npmjs.org/@adhd/sox-claim-verification/-/sox-claim-verification-0.1.1.tgz","fileCount":30,"integrity":"sha512-2pFzUVHDI7hKanXLFl3ynLQuBPNFkzNdrxs+BbGpq56tsRTKHK3iirCWWwiuoofq5Dniey9yTcYgzuX4FjoLoA==","signatures":[{"sig":"MEQCIAbtixp3Ocde0MS2MWYiHf1WuIeuCB3PtcHUocKrve89AiAKe+gbaCa4UWYVCiaT7j0XVbTQ6jHPnObPC3NLlDA8lw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62555},"main":"./dist/index.js","type":"module","_from":"file:adhd-sox-claim-verification-0.1.1.tgz","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/77dddee54f9e800de2a2090629f03ca3/adhd-sox-claim-verification-0.1.1.tgz","_integrity":"sha512-2pFzUVHDI7hKanXLFl3ynLQuBPNFkzNdrxs+BbGpq56tsRTKHK3iirCWWwiuoofq5Dniey9yTcYgzuX4FjoLoA==","_npmVersion":"11.6.2","description":"NLI-based (Natural Language Inference) claim grounding engine. Cross-encoder NLI via worker thread, embedding pre-filter, configurable truncation strategy, LRU result cache. Worker-thread isolated from better-sqlite3 (BL-11).","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@adhd/sox-embedding-provider":"0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@adhd/sox-blob-store":"0.2.4","@adhd/sox-hybrid-search":"0.3.4"},"_npmOperationalInternal":{"tmp":"tmp/sox-claim-verification_0.1.1_1786144734317_0.5613159627719311","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@adhd/sox-claim-verification","version":"0.1.2","license":"MIT","_id":"@adhd/sox-claim-verification@0.1.2","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"sox":{"area":"data","group":"verify","concerns":["NLI claim grounding via cross-encoder","worker-thread ONNX inference (BL-11 isolation)","embedding pre-filter for topic gating","configurable truncation (tail/head)","LRU verification cache","multi-source verification (one claim, many sources)","streaming batch verification","model registry with version tracking"],"invariants":["ONNX inference runs exclusively in worker threads - never on main thread","pre-filter uses its OWN embedding provider instance (not coupled to retrieval pipeline)","warmUp() must complete before verify* calls","language mismatch downgrades to 'neutral' with warning flag - never throws","claim normalization strips citation markers and quotation marks before NLI"],"entrypoints":["dist/index.js"]},"dist":{"shasum":"e468f4a38052661c8c92e635055d91fab893e611","tarball":"https://registry.npmjs.org/@adhd/sox-claim-verification/-/sox-claim-verification-0.1.2.tgz","fileCount":30,"integrity":"sha512-2uTRaD16E/62hiEMsbuviYCAh/EA3eB14oAJvdGsUNZBqjwN9Th3Uli5aT8kO3Oe5OrUkWZyQV+CXGWCFGmgjw==","signatures":[{"sig":"MEUCIQD2sMdu3cOwDCwTUvSkmmIesOpkj/nJGP3pIsjNPkQiZwIgf5lkfQKQ3TIlPyB4vF3TOjuh5klDobi0HjXhM1U+CAo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62555},"main":"./dist/index.js","type":"module","_from":"file:adhd-sox-claim-verification-0.1.2.tgz","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/54d449899e04b53254b376c23826e5a5/adhd-sox-claim-verification-0.1.2.tgz","_integrity":"sha512-2uTRaD16E/62hiEMsbuviYCAh/EA3eB14oAJvdGsUNZBqjwN9Th3Uli5aT8kO3Oe5OrUkWZyQV+CXGWCFGmgjw==","_npmVersion":"11.6.2","description":"NLI-based (Natural Language Inference) claim grounding engine. Cross-encoder NLI via worker thread, embedding pre-filter, configurable truncation strategy, LRU result cache. Worker-thread isolated from better-sqlite3 (BL-11).","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@adhd/sox-embedding-provider":"0.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@adhd/sox-blob-store":"0.2.6","@adhd/sox-hybrid-search":"0.3.6"},"_npmOperationalInternal":{"tmp":"tmp/sox-claim-verification_0.1.2_1786494960047_0.6058651844682075","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@adhd/sox-claim-verification","version":"0.1.3","license":"MIT","_id":"@adhd/sox-claim-verification@0.1.3","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"sox":{"area":"data","group":"verify","concerns":["NLI claim grounding via cross-encoder","worker-thread ONNX inference (BL-11 isolation)","embedding pre-filter for topic gating","configurable truncation (tail/head)","LRU verification cache","multi-source verification (one claim, many sources)","streaming batch verification","model registry with version tracking"],"invariants":["ONNX inference runs exclusively in worker threads - never on main thread","pre-filter uses its OWN embedding provider instance (not coupled to retrieval pipeline)","warmUp() must complete before verify* calls","language mismatch downgrades to 'neutral' with warning flag - never throws","claim normalization strips citation markers and quotation marks before NLI"],"entrypoints":["dist/index.js"]},"dist":{"shasum":"6f1b945d1bf456e86dfa33f55c173402cdcc3396","tarball":"https://registry.npmjs.org/@adhd/sox-claim-verification/-/sox-claim-verification-0.1.3.tgz","fileCount":30,"integrity":"sha512-KaIUh/YxLQNbyt/gR5Q+UbbsGxLtuNJEt5seVPczTEPtFMPMbCQzQ9jP98zteO/13OkTLAxc5xOACb23beYHzQ==","signatures":[{"sig":"MEUCIAtZ/+gXhA34kggcDK1Lj0oQ/bOG3P51U3BGe/g1+85gAiEAv/Unk30+5tmLTlmjXDadIh7xYRgvdwNv5wHy6JGWfPo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62558},"main":"./dist/index.js","type":"module","_from":"file:adhd-sox-claim-verification-0.1.3.tgz","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/94c71ad4ac1075e7e2adcbe1bbd2e068/adhd-sox-claim-verification-0.1.3.tgz","_integrity":"sha512-KaIUh/YxLQNbyt/gR5Q+UbbsGxLtuNJEt5seVPczTEPtFMPMbCQzQ9jP98zteO/13OkTLAxc5xOACb23beYHzQ==","_npmVersion":"11.6.2","description":"NLI-based (Natural Language Inference) claim grounding engine. Cross-encoder NLI via worker thread, embedding pre-filter, configurable truncation strategy, LRU result cache. Worker-thread isolated from better-sqlite3 (BL-11).","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@adhd/sox-embedding-provider":"^0.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@adhd/sox-blob-store":"^0.2.9","@adhd/sox-hybrid-search":"^0.3.8"},"_npmOperationalInternal":{"tmp":"tmp/sox-claim-verification_0.1.3_1787113044193_0.9551883656683555","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@adhd/sox-claim-verification","version":"0.1.4","keywords":["nli","verification","claims","embedding","typescript"],"license":"MIT","_id":"@adhd/sox-claim-verification@0.1.4","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"homepage":"https://github.com/PseudoSky/adhd","bugs":{"url":"https://github.com/PseudoSky/adhd/issues"},"sox":{"area":"data","group":"verify","concerns":["NLI claim grounding via cross-encoder","worker-thread ONNX inference (BL-11 isolation)","embedding pre-filter for topic gating","configurable truncation (tail/head)","LRU verification cache","multi-source verification (one claim, many sources)","streaming batch verification","model registry with version tracking"],"invariants":["ONNX inference runs exclusively in worker threads - never on main thread","pre-filter uses its OWN embedding provider instance (not coupled to retrieval pipeline)","warmUp() must complete before verify* calls","language mismatch downgrades to 'neutral' with warning flag - never throws","claim normalization strips citation markers and quotation marks before NLI"],"entrypoints":["dist/index.js"]},"dist":{"shasum":"18f71dc3a1f5f4a480218f82decbb3b4ea95754f","tarball":"https://registry.npmjs.org/@adhd/sox-claim-verification/-/sox-claim-verification-0.1.4.tgz","fileCount":32,"integrity":"sha512-YAuLBEi6Up2e0Q6WAcSx1iZP3DPFLSL2bkhKcnb1SvaD5mRE8MqpmMHrQgXeZqahA+L5Legz1xdMR9II9DnkXQ==","signatures":[{"sig":"MEUCIGZ/aL3NOyOcA59KF5P6eUXot8erlN8InWgVKV7gy0egAiEAxMT0h2pFKw4EIKzbzSSF4pfjsXDgm1Da+mSyfuELLIM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":75759},"main":"./dist/index.js","type":"module","_from":"file:adhd-sox-claim-verification-0.1.4.tgz","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/39bc3a5f1980ad26837d66c5e92562e2/adhd-sox-claim-verification-0.1.4.tgz","_integrity":"sha512-YAuLBEi6Up2e0Q6WAcSx1iZP3DPFLSL2bkhKcnb1SvaD5mRE8MqpmMHrQgXeZqahA+L5Legz1xdMR9II9DnkXQ==","repository":{"url":"git+https://github.com/PseudoSky/adhd.git","type":"git"},"_npmVersion":"11.6.2","description":"NLI-based (Natural Language Inference) claim grounding engine. Cross-encoder NLI via worker thread, embedding pre-filter, configurable truncation strategy, LRU result cache. Worker-thread isolated from better-sqlite3 (BL-11).","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@adhd/sox-embedding-provider":"^0.5.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@adhd/sox-blob-store":"^0.2.11","@adhd/sox-hybrid-search":"^0.4.3"},"_npmOperationalInternal":{"tmp":"tmp/sox-claim-verification_0.1.4_1788566484545_0.7807833260214305","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"_id":"@adhd/sox-claim-verification@0.1.5","sox":{"area":"data","group":"verify","concerns":["NLI claim grounding via cross-encoder","worker-thread ONNX inference (BL-11 isolation)","embedding pre-filter for topic gating","configurable truncation (tail/head)","LRU verification cache","multi-source verification (one claim, many sources)","streaming batch verification","model registry with version tracking"],"invariants":["ONNX inference runs exclusively in worker threads - never on main thread","pre-filter uses its OWN embedding provider instance (not coupled to retrieval pipeline)","warmUp() must complete before verify* calls","language mismatch downgrades to 'neutral' with warning flag - never throws","claim normalization strips citation markers and quotation marks before NLI"],"entrypoints":["dist/index.js"]},"bugs":{"url":"https://github.com/PseudoSky/adhd/issues"},"dist":{"shasum":"3adf9c78f8a8077121bf21c91bd66ab919da132e","tarball":"https://registry.npmjs.org/@adhd/sox-claim-verification/-/sox-claim-verification-0.1.5.tgz","fileCount":32,"integrity":"sha512-kecdAwxgQs7oZeytYH1g4bP/Jyb2wWDWm/WEAECrxx01x4GX3WiaV9hD9a/cAdAN9ojhYUYLTDLeEmx8ybjzDw==","signatures":[{"sig":"MEQCIDsj/4dYEVDdO7VzAQDwidtcpzo64wvsU2RIY2m4fTqrAiBv6yWCIYrLMIzT1Is2sC4pAS+ygEBfCF2nsXXLNVXANw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIA+9k4UzPqH3Vk7tqvZ4V7G9yAEqpDxPBM7zF1qvXMpPAiEAiVcovQ1DT7Srn26UpMZOa7DYOySJuZTfwKae+Z1/pww="}],"unpackedSize":75759},"main":"./dist/index.js","name":"@adhd/sox-claim-verification","type":"module","_from":"file:adhd-sox-claim-verification-0.1.5.tgz","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"license":"MIT","private":false,"version":"0.1.5","_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"homepage":"https://github.com/PseudoSky/adhd","keywords":["nli","verification","claims","embedding","typescript"],"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/a734dea16722b7fe3f47d99845a27ec0/adhd-sox-claim-verification-0.1.5.tgz","_integrity":"sha512-kecdAwxgQs7oZeytYH1g4bP/Jyb2wWDWm/WEAECrxx01x4GX3WiaV9hD9a/cAdAN9ojhYUYLTDLeEmx8ybjzDw==","repository":{"url":"git+https://github.com/PseudoSky/adhd.git","type":"git"},"_npmVersion":"11.6.2","description":"NLI-based (Natural Language Inference) claim grounding engine. Cross-encoder NLI via worker thread, embedding pre-filter, configurable truncation strategy, LRU result cache. Worker-thread isolated from better-sqlite3 (BL-11).","directories":{},"maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"_nodeVersion":"24.11.1","dependencies":{"@adhd/sox-embedding-provider":"^0.6.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@adhd/sox-blob-store":"^0.2.12","@adhd/sox-hybrid-search":"^0.5.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sox-claim-verification_0.1.5_1790391216600_0.011438313037620995"}}},"time":{"created":"2026-07-16T22:02:17.416Z","modified":"2026-09-26T02:53:36.855Z","0.1.0":"2026-07-16T22:02:17.733Z","0.1.1":"2026-08-07T23:18:54.460Z","0.1.2":"2026-08-12T00:36:00.182Z","0.1.3":"2026-08-19T04:17:24.342Z","0.1.4":"2026-09-05T00:01:24.679Z","0.1.5":"2026-09-26T02:53:36.686Z"},"bugs":{"url":"https://github.com/PseudoSky/adhd/issues"},"license":"MIT","homepage":"https://github.com/PseudoSky/adhd","keywords":["nli","verification","claims","embedding","typescript"],"repository":{"url":"git+https://github.com/PseudoSky/adhd.git","type":"git"},"description":"NLI-based (Natural Language Inference) claim grounding engine. Cross-encoder NLI via worker thread, embedding pre-filter, configurable truncation strategy, LRU result cache. Worker-thread isolated from better-sqlite3 (BL-11).","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"readme":"# @adhd/sox-claim-verification\n\nAn NLI (Natural Language Inference) claim-grounding engine: given a claim and one or more candidate source texts, it returns a per-source entailment verdict (`entails` / `contradicts` / `neutral` / `unverifiable`) with a confidence score. Inference runs on a real cross-encoder NLI model, always inside a worker thread — never on the main thread — with an optional embedding pre-filter to skip NLI entirely for sources that are topically unrelated to the claim, and an LRU cache so repeat claim/source/model triples are free.\n\n```bash\npnpm add @adhd/sox-claim-verification\n```\n\n## Quick start\n\n```typescript\nimport { createClaimVerifier } from '@adhd/sox-claim-verification';\n\nconst verifier = await createClaimVerifier({\n  modelId: 'MiniCheck',\n  modelVersion: '1',\n});\n// createClaimVerifier() calls warmUp() for you — verifier.isReady is true once it resolves\n\nconst result = await verifier.verify(\n  { id: 'claim-1', text: 'Paris is the capital of France.' },\n  {\n    id: 'source-1',\n    text:\n      'Paris is the capital of France and its most populous city, ' +\n      'situated on the river Seine in the north of the country.',\n  },\n);\n\nconsole.log(result.sourceResults[0].entailment);   // \"entails\"\nconsole.log(result.sourceResults[0].confidence);    // e.g. 0.93\nconsole.log(result.aggregateConfidence);            // 0.93\n\nawait verifier.shutdown();\n```\n\n## API reference\n\n### `createClaimVerifier(config)`\n\n```typescript\nfunction createClaimVerifier(config: ClaimVerifierConfig): Promise<ClaimVerifier>;\n\ninterface ClaimVerifierConfig {\n  modelId: string;                 // required\n  modelVersion: string;            // required\n  defaultPreFilterThreshold?: number; // 0..1 cosine-similarity gate; see \"Embedding pre-filter\" below\n  minConfidenceThreshold?: number;    // default 0.5 — entailment below this downgrades to 'neutral'\n  workerCount?: number;               // default 1 — number of worker threads to spin up\n  maxQueueDepth?: number;\n  embeddingProvider?: EmbeddingProvider; // from '@adhd/sox-embedding-provider'; required to use pre-filtering\n  cache?: {\n    maxSize?: number; // default 10_000\n    ttlMs?: number;   // default: no expiry\n  };\n}\n```\n\nThrows `InvalidClaimInputError` synchronously if `modelId` or `modelVersion` is missing.\n\n### `ClaimVerifier`\n\n```typescript\ninterface ClaimVerifier {\n  readonly modelId: string;\n  readonly modelVersion: string;\n  readonly isReady: boolean;\n\n  verify(claim: Claim, source: SourceRef, opts?: { preFilterThreshold?: number }): Promise<VerificationResult>;\n\n  verifyBatch(pairs: ClaimSourcePair[], opts?: { preFilterThreshold?: number }): Promise<VerificationResult[]>;\n\n  verifyStream(\n    pairs: AsyncIterable<ClaimSourcePair>,\n    opts?: { preFilterThreshold?: number },\n  ): AsyncIterable<VerificationResult>;\n\n  warmUp(): Promise<void>;        // idempotent; createClaimVerifier() already calls this\n  healthCheck(): Promise<VerifierHealth>;\n  shutdown(): Promise<void>;      // terminates every worker thread\n}\n```\n\n### Core types\n\n```typescript\ninterface Claim {\n  id: string;\n  text: string;\n  language?: string;\n  context?: string;\n  metadata?: Record<string, unknown>;\n}\n\ninterface SourceRef {\n  id: string;\n  text: string;\n  language?: string;\n  title?: string;\n  url?: string;\n  metadata?: Record<string, unknown>;\n}\n\ninterface ClaimSourcePair {\n  claim: Claim;\n  sources: SourceRef[]; // one claim checked against many sources\n}\n\ntype EntailmentLabel = 'entails' | 'contradicts' | 'neutral' | 'unverifiable';\n\ninterface SingleSourceResult {\n  sourceId: string;\n  entailment: EntailmentLabel;\n  confidence: number;\n  preFilterSkipped: boolean;\n  preFilterScore?: number;    // present when a pre-filter ran\n  languageMismatch?: boolean;\n  timingMs: number;\n}\n\ninterface VerificationResult {\n  claimId: string;\n  sourceResults: SingleSourceResult[];\n  aggregateConfidence: number; // = confidence when 'entails', min(confidence,1) when 'contradicts', 0 otherwise;\n                                // for verifyBatch, the MIN confidence across all sources for that claim\n  modelId: string;\n  modelVersion: string;\n  totalTimingMs: number;\n  metadata?: Record<string, unknown>;\n}\n```\n\n### Health and lifecycle\n\n```typescript\nconst health = await verifier.healthCheck();\n// {\n//   isReady: true, isWarmingUp: false,\n//   modelId: 'MiniCheck', modelVersion: '1',\n//   queuedJobs: 0, activeJobs: 0,\n//   workerStatus: [{ workerId: 0, isBusy: false, queuedJobs: 0, lastActivityMs: 12 }],\n//   uptimeMs: 4213,\n// }\n```\n\n```typescript\ninterface VerifierHealth {\n  isReady: boolean;\n  isWarmingUp: boolean;\n  modelId: string;\n  modelVersion: string;\n  queuedJobs: number;\n  activeJobs: number;\n  workerStatus: WorkerStatus[];\n  lastError?: string;\n  uptimeMs: number;\n}\n\ninterface WorkerStatus {\n  workerId: number;\n  isBusy: boolean;\n  queuedJobs: number;\n  lastActivityMs: number;\n}\n```\n\nAlways call `verifier.shutdown()` when you're done — it terminates every worker thread the verifier started.\n\n## Verifying multiple sources for one claim\n\n```typescript\nconst results = await verifier.verifyBatch([\n  {\n    claim: { id: 'c1', text: 'The company was founded in 2015.' },\n    sources: [\n      { id: 's1', text: 'Founded in 2015, the company grew quickly.' },\n      { id: 's2', text: 'The company has no publicly stated founding date.' },\n    ],\n  },\n]);\n\nconsole.log(results[0].sourceResults.length); // 2 — one result per source\nconsole.log(results[0].aggregateConfidence);   // the MIN confidence across both sources\n```\n\n## Streaming verification\n\n`verifyStream` accepts an async iterable of pairs and yields results as they complete — useful when claim/source pairs are themselves produced incrementally:\n\n```typescript\nasync function* pairs(): AsyncIterable<ClaimSourcePair> {\n  yield { claim: { id: 'c1', text: 'X happened in 2020.' }, sources: [{ id: 's1', text: 'X happened in 2020.' }] };\n  yield { claim: { id: 'c2', text: 'Y is true.' }, sources: [{ id: 's2', text: 'Y is false.' }] };\n}\n\nfor await (const result of verifier.verifyStream(pairs())) {\n  console.log(result.claimId, result.aggregateConfidence);\n}\n```\n\n## Embedding pre-filter\n\nPass an `embeddingProvider` and a `defaultPreFilterThreshold` to skip the (comparatively expensive) NLI pass for claim/source pairs that aren't even topically related — a cosine-similarity check runs first, and only pairs above the threshold reach the worker thread:\n\n```typescript\nimport { createEmbeddingProvider } from '@adhd/sox-embedding-provider';\nimport { createClaimVerifier } from '@adhd/sox-claim-verification';\n\nconst embeddingProvider = await createEmbeddingProvider({ /* ... */ });\n\nconst verifier = await createClaimVerifier({\n  modelId: 'MiniCheck',\n  modelVersion: '1',\n  embeddingProvider,\n  defaultPreFilterThreshold: 0.3,\n});\n\nconst result = await verifier.verify(\n  { id: 'c1', text: 'The stock market crashed in 1929.' },\n  { id: 's1', text: 'Recipe for banana bread: mix flour, sugar, and bananas.' },\n);\n// result.sourceResults[0].entailment === 'unverifiable'\n// result.sourceResults[0].preFilterSkipped === true\n// result.sourceResults[0].preFilterScore is set, and NLI never ran for this pair\n```\n\nYou can also override the threshold per call via `opts.preFilterThreshold` on `verify()`/`verifyBatch()`/`verifyStream()` without changing the verifier's configured default. The pre-filter uses its own `embeddingProvider` instance — it is never coupled to a retrieval/embedding pipeline elsewhere in your application.\n\n## Claim normalization\n\nEvery claim and source is normalized before it reaches the model — citation markers (`[1]`, `[1, 2, 3]`), `(p. 12)`-style page references, `(Smith et al., 2020)`-style inline citations, and both straight and curly quotation marks are stripped, while sentence-ending punctuation is preserved:\n\n```typescript\nimport { DefaultClaimNormalizer } from '@adhd/sox-claim-verification';\n\nconst normalizer = new DefaultClaimNormalizer();\nnormalizer.normalizeClaim('This is a test [1].');           // \"This is a test.\"\nnormalizer.normalizeClaim('He said \"hello\"');                // \"He said hello\"\nnormalizer.normalizeSource('Section 1: Introduction');        // \"Section 1: Introduction\" (unchanged — source text keeps its markers)\n```\n\n`ClaimVerifier` uses `DefaultClaimNormalizer` internally; the exported class and `ClaimNormalizer` interface exist for callers who want to normalize text themselves before inspecting it, or plug in a custom implementation.\n\n## Result caching\n\n`ClaimVerifier` caches results keyed by `sha256(claimText + sourceText + modelVersion)` via an `LRUVerificationCache`, sized by `config.cache.maxSize` (default 10,000) with an optional `ttlMs`. The same class is exported directly if you want an independent cache:\n\n```typescript\nimport { LRUVerificationCache } from '@adhd/sox-claim-verification';\n\nconst cache = new LRUVerificationCache(1000, 60_000); // maxSize=1000, ttlMs=60s\nawait cache.set('key', { sourceId: 's1', entailment: 'entails', confidence: 0.9, preFilterSkipped: false, timingMs: 10 });\nconst hit = await cache.get('key'); // undefined once maxSize is exceeded (LRU-evicted) or ttlMs elapses\n```\n\n## Model registry\n\n`InMemoryModelRegistry` tracks which models are currently loaded — `createClaimVerifier` registers its model automatically on `warmUp()`:\n\n```typescript\nimport { InMemoryModelRegistry } from '@adhd/sox-claim-verification';\n\nconst registry = new InMemoryModelRegistry();\nawait registry.register({\n  modelId: 'MiniCheck',\n  version: '1',\n  nliModel: true,\n  loadedAt: new Date().toISOString(),\n});\nawait registry.isLoaded('MiniCheck'); // true\nawait registry.list();                // [{ modelId: 'MiniCheck', version: '1', ... }]\nawait registry.deregister('MiniCheck');\n```\n\n```typescript\ninterface ModelRegistration {\n  modelId: string;\n  version: string;\n  displayName?: string;\n  providerUri?: string;\n  nliModel: boolean;\n  dimensions?: number;\n  loadedAt: string;\n}\n\ninterface ModelRegistry {\n  register(model: ModelRegistration): Promise<void>;\n  deregister(modelId: string): Promise<void>;\n  get(modelId: string): Promise<ModelRegistration | undefined>;\n  list(): Promise<ModelRegistration[]>;\n  isLoaded(modelId: string): Promise<boolean>;\n}\n```\n\n## Error taxonomy\n\n```typescript\nclass ModelNotLoadedError extends Error { modelId: string; }       // thrown by verify() before warmUp() completes\nclass VerifierBusyError extends Error { retryAfterMs?: number; }\nclass UnsupportedLanguageError extends Error { language: string; }\nclass PreFilterSkippedError extends Error { score: number; threshold: number; }\nclass InvalidClaimInputError extends Error {}                       // e.g. empty claim/source text, missing modelId\n```\n\n## Invariants\n\n- **ONNX inference runs exclusively in worker threads, never on the main thread.** `workerCount` controls how many worker threads are started; `verify()` load-balances across whichever workers aren't currently busy.\n- **`warmUp()` must complete before any `verify*` call.** `createClaimVerifier()` already awaits this for you; calling `verify()` on a verifier that hasn't warmed up throws `ModelNotLoadedError`.\n- **A claim/source language mismatch downgrades the result to `'neutral'` — it never throws.**\n- **A result below `minConfidenceThreshold` (default `0.5`) for an `entails`/`contradicts` verdict is downgraded to `'neutral'`** before being returned or cached.\n- **Claim normalization always strips citation markers and quotation marks before the text reaches NLI** — `normalizeSource` is deliberately gentler, preserving structural markers like `\"Section 1:\"`.\n","readmeFilename":"README.md"}