@exellix/narrix-adapters-core
v2.0.0
Published
Deterministic, crypto-only core for Narrix adapters
Readme
@exellix/narrix-adapters-core
Deterministic, crypto-only core for Narrix adapters. Produces CNI v1.1–compatible output with no LLM, network, or filesystem use. Built for use by thin adapter packages (text, chat, docs, records).
Where This Package Fits
┌─────────────────────────────────────────────────────────────────────────┐
│ NARRIX ECOSYSTEM │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ @exellix/narrix-cni Schema & types (CNI v1.1) │
│ ▲ │
│ │ │
│ @exellix/narrix-adapters-core ◄── YOU ARE HERE │
│ (this package) Shared algorithms: normalize, chunk, │
│ ▲ entities, hash, evidence, diagnostics │
│ │ │
│ ┌────────┴────────┬─────────────────┬─────────────────┐ │
│ │ │ │ │ │
│ narrix-adapter- narrix-adapter- narrix-adapter- narrix-adapter- │
│ text chat docs records │
│ (separate pkgs) (separate pkgs) (separate pkgs) (separate pkgs) │
│ │
└─────────────────────────────────────────────────────────────────────────┘This package provides the shared foundation. Adapter packages (text, chat, docs, records) depend on it and implement NarrixAdapter.toCni() for their input types. Golden tests (T1–T7, C1–C6, D1–D6) live in those adapter packages, not here.
Install
npm install @exellix/narrix-adapters-coreRegistry: This package is published to GitHub Packages. Ensure your .npmrc includes:
@exellix:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=<YOUR_TOKEN>Constraints
- No LLM calls — pure functions only
- No network or fs — Node built-in
cryptoonly - No timestamps in IDs or hashes
- Deterministic — same input ⇒ same output (stable IDs, sorted diagnostics/entities)
Adapter-specific logic (chat/docs/records) lives in adapter packages; this package provides shared contracts, normalization, chunking, entity extraction, and evidence helpers.
API
Contracts and options
AdapterKind,AdapterOptions,AdapterResult,AdapterDiagnostics— adapter contracts and result shapeNarrixAdapter<TInput>— interface adapters implementNormalizationPolicy,ChunkingConfig,EntityExtractionPolicy— policy typesapplyDefaults(partial)— fill in deterministic defaults forAdapterOptions
Algorithms
normalizeText(input, policy?)— newline normalization, zero-width removal, optional trim/collapsechunkText(text, config?, limits?)— paragraph or hard chunking with overlap; surrogate-safeextractEntities(text, policy?, limits?)— CVE, IP, URL, email, etc. with dedupe and prioritysha256(input),stableStringify(value)— hashing and canonical JSONcomputeSubjectId(parts),computeContentId(parts)— deterministic IDs for CNI subject/contentcreateSpanEvidence(...),createPathEvidence(...)— buildEvidencePointerV11for CNIcreateRoleMapRegistry(config)— tiered role-map resolution (Tier 1: collection, Tier 2: record type, Tier 3: generic field-name matching) for the record adapter; returns{ resolve(params) }withResolveResult { map, tiersApplied }
Diagnostics
DiagnosticsCollector—warn(),error(),stat(),finalize({ sort })- Warning codes:
TEXT_EMPTY,TEXT_TRUNCATED,CHAT_*,DOCS_*,ENTITY_LIMIT_REACHED - Role-map registry types:
RoleMap,ResolvedRoleMap,TiersApplied,RoleMapRegistry,RoleMapRegistryConfig,ResolveParams,ResolveResult,FactEntry,GenericRoleMap
Example
import {
normalizeText,
chunkText,
extractEntities,
computeSubjectId,
computeContentId,
createSpanEvidence,
applyDefaults,
} from "@exellix/narrix-adapters-core";
const opts = applyDefaults({ kind: "text", adapterId: "my-adapter", adapterVersion: "1.0.0" });
const { text } = normalizeText(input, opts.normalization);
const { chunks, truncated } = chunkText(text, opts.chunking, opts.limits);
const { entities } = extractEntities(text, opts.entities, opts.limits);
const subjectId = computeSubjectId({ kind: "text", stableKey: "source-1", normalizedText: text });
const contentIds = chunks.map((ch, i) =>
computeContentId({ subjectId, chunkIndex: i, chunkText: ch.text })
);Scripts
npm run build— compile TypeScript todist/npm test— build and run tests (Nodenode:test)
Publishing (private GitHub package)
- Ensure
.npmrcexists with@exellix:registryand_authToken(or copy from.npmrc.exampleand add your token)..npmrcis gitignored to avoid committing secrets. - Run
npm run buildthennpm publish. The package will be published to GitHub Packages as a private package for the@exellixscope.
Status & Gap Analysis
| Status | Description | |--------|-------------| | ✅ Complete | All core modules implemented per spec | | ✅ No open issues | No TODOs, FIXMEs, or known bugs | | ✅ Tests passing | 31 unit tests (hash, chunk, entities, normalize, diagnostics) |
Gap analysis: See GAP_ANALYSIS.md for a detailed comparison against the NARRIX Adapters spec. Summary: one gap (entity kind default order) was fixed; the core is otherwise complete and ready for adapter consumption.
License
See repository license file.
