Vraimony
SDK v2.2.0 — ERF record builder for developers

Build review-ready records from your own code.

The Vraimony SDK gives you everything you need to assemble an ERF-compatible evidence record, assess its readiness, and generate the portable JSON that travels with it — and now also includes local-first helpers for browser-first upload routing, lightweight cache, compact receiver-pack sync, and template recommendation without any third-party runtimes or hidden telemetry. Final signing, premium compilation, and verify issuance stay on the server.

Zero dependencies No telemetry Node.js + Browser ERF/1.0 compatible

SHA-256: c766c295ed878511c4c9fe5bd75ac37e82c3016ede16f396c679c241da7ed935 — verify against SHA256SUMS.txt before deploying.

What the SDK does

Seven functions. One consistent record model.

FUNCTIONPURPOSERETURNS
createRecord(opts) Build an ERF-compatible record from structured input — parties, timeline, evidence, ask ERF record object with light footprint baked in
assessReadiness(record) Assess whether a record is weak / partial / review-ready. Returns gaps list. { state, gaps[], score }
validateERF(json) Validate ERF record format (structure only — not truth) { ok, errors[], status_hint }
buildExportJSON(record) Generate portable ERF JSON with packaged_by, protocol, verify_url baked in Export-ready JSON object
statusLabel(item) Get PASS / Declared / Unverified for a single evidence item 'PASS' | 'Declared' | 'Unverified'
formatReviewerSummary(record) Plain-text reviewer summary — suitable for email or handoff Formatted string with verify URL
canonicalize(value) Deterministic JSON serialization (Vraimony canonical profile — keys sorted lexicographically) Canonical JSON string
What the SDK does NOT do: Cryptographic signing (ed25519), receiver-aware premium playbook compilation, entitlement checks, or final verify issuance — those require server-side control. The SDK stays a local runtime and helper layer.
Quick start

Build a record in under a minute.

// Node.js or browser const { createRecord, assessReadiness, buildExportJSON } = require('./vraimony-sdk'); // 1. Build the record const record = createRecord({ type: 'dispute', title: 'Invoice #2891 — Scope Change Dispute', sender: { name: 'Acme Agency', ref: 'AGCY-001' }, receiver: { name: 'Client Co', ref: 'CLT-042' }, ask: 'Confirm the scope change in the March change order is payable.', timeline: [ { date: '2026-01-15', event: 'Original contract signed' }, { date: '2026-02-28', event: 'Scope change requested by client' }, { date: '2026-03-10', event: 'Change order sent for approval' }, { date: '2026-03-20', event: 'Invoice #2891 issued' } ], evidence: [ { label: 'Original contract', value: 'contract_2026-01.pdf', verified: true, mechanism: 'sha256' }, { label: 'Change order email', value: 'email_2026-02-28.eml', verified: false }, { label: 'Signed change order', value: null } // gap — not yet received ], template: 'disputes/standard', record_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6' }); // 2. Check readiness const readiness = assessReadiness(record); console.log(readiness.state); // 'partial' console.log(readiness.gaps); // ['evidence_no_values'] — signed change order missing console.log(readiness.score); // 70 // 3. Export portable JSON (light footprint baked in) const exportJSON = buildExportJSON(record); // exportJSON.packaged_by === 'Vraimony' // exportJSON.protocol === 'https://www.vraimony.com/protocol.html' // exportJSON.verify_url === 'https://verify.vraimony.com/r/3fa85f64-...'
PASS / Declared / Unverified

Every evidence item gets an honest status — not fake certainty.

const { statusLabel } = require('./vraimony-sdk'); // Confirmed via mechanism (sha256, server, etc.) statusLabel({ value: 'file.pdf', verified: true, mechanism: 'sha256' }); // → 'PASS' // Exists but not independently confirmed statusLabel({ value: 'approval_email.eml', verified: false }); // → 'Declared' // Missing — honest gap statusLabel({ value: null }); // → 'Unverified'
PASS

Confirmed via verifiable mechanism. SHA-256 hash, server signature, or explicit verification flag.

Declared

Stated by sender — value exists in the record but not independently confirmed. Reviewer sees this explicitly.

Unverified

Missing or null. Gap is visible — the record does not pretend completeness it does not have.

Light footprint — baked into every export

Every JSON export carries three fields that make Vraimony visible to the receiver.

// buildExportJSON() always includes: { "packaged_by": "Vraimony", "protocol": "https://www.vraimony.com/protocol.html", "verify_url": "https://verify.vraimony.com/r/RECORD_ID", "sdk_version": "2.0.0" }

Every developer who opens this JSON sees the protocol link. Every reviewer who receives it can follow the verify URL. This is how the SDK distributes awareness — not through tracking, but through the record itself.

packaged_by: "Vraimony" protocol: vraimony.com/protocol verify_url: verify.vraimony.com/r/...
Readiness assessment

Know whether the record is ready before packaging anything.

const { assessReadiness } = require('./vraimony-sdk'); const result = assessReadiness(record); result.state // 'weak' | 'partial' | 'review-ready' result.gaps // ['missing_timeline', 'missing_or_weak_ask', ...] result.score // 0–100 // Gap codes: // missing_timeline — no events recorded // timeline_missing_dates — events exist but no ISO dates // missing_evidence — no evidence items // evidence_no_values — items exist but all null // missing_or_weak_ask — ask is absent or <10 chars // missing_parties — sender or receiver not set

weak

Multiple critical gaps. Record stays as local draft. Cannot be sealed. Use gap list to guide remediation.

partial

Most elements present, 1–2 gaps remain. Can be sealed as Provisional. Reviewer sees which elements are declared vs confirmed.

review-ready

All required elements present. Ready to seal as Final. Full PASS/Declared/Unverified labels. Tamper-evident.

Seal levels

Set in the SDK, enforced on the platform.

L1_PROVISIONAL

Draft — local only. The record is being assembled. Not yet sealed or tamper-evident.

L2_STANDARD

Sealed — server-signed, ed25519, tamper-evident. Review page active. Verify URL live.

L3_FINAL

Finalized — no further amendments. Used when the record is complete and the review has concluded.

Sealing happens on the Vraimony platform — not in the SDK. The SDK sets the intended seal level; the platform enforces it.

Evidence Degree (1–10) — optional precision layer

Declare how independently verifiable each evidence item is.

// evidence_degree: 1–10 how independently verifiable // confidence: 0–100 sender confidence in the claim statusLabel({ value: 'bill-of-lading.pdf', verified: true, mechanism: 'sha256', evidence_degree: 9, confidence: 95, externally_anchored: true }); // → 'PASS' · Degree 9/10 · Externally anchored statusLabel({ value: 'email.eml', verified: false, evidence_degree: 5, confidence: 75 }); // → 'Declared' · Degree 5/10 · 75% sender confidence // Quality Stop: PASS requires evidence_degree >= 6 // High confidence + low degree = overclaim warning
Degree 8–10 → PASS. Degree 4–7 → Declared. Degree 1–3 → Unverified. Full reference →
Timestamp anchor — independent time proof

SHA-256 commitment verifiable offline — no Vraimony servers needed.

// Formula: SHA256(content_hash + "|" + created_at + "|" + receipt_id) const anchor = buildTimestampAnchor({ contentHash: 'a3f4...', createdAt: '2026-03-25T10:00:00Z', receiptId: '3fa85f64-...' }); const result = verifyTimestampAnchor(anchor); // → { ok: true, commitment_hex: '...', anchored_at: '2026-03-25...' } // Submit anchor.ots_submit.url to opentimestamps.org for Bitcoin anchoring (free)
Actor model — nested under Case

Every Case knows who its parties are.

The Actor model is stored internally under each Case (GA session, dispute, claim). It handles permissions, task routing, submission tokens, and audit trail. It is not exposed directly in the public API — it powers the logic behind it.

// Actor model — nested under Case/Session (internal) // Roles: submitter | receiver | reviewer | operator | observer const actors = [ { actor_id: 'actor-adjuster-001', role: 'reviewer', party_name: 'Richards Hogg Lindley', permissions: ['read_all', 'download_all', 'close_session'] }, { actor_id: 'actor-submitter-001', role: 'submitter', party_name: 'Acme Freight Forwarding', interest_id: 'GA-2025-0441-001', permissions: ['submit:GA-2025-0441-001'] } ]; // buildActors() runs automatically on POST /v1/ga/request // Actors are stored in the GA session JSON — not returned in public responses // They enable: permissions, task routing, audit trail, reminder logic
Why internal? Exposing actors publicly would leak party relationships to unauthorised requests. The Actor model is the enforcement layer — it powers submission tokens, status visibility, and future multi-user access without appearing in public responses.
Workspace-specific examples

Same SDK core. Different workspace context.

🚢 Shipping / GA
// POST /v1/ga/request fetch('/v1/ga/request', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ga_reference: 'GA-2025-0441', adjuster_name: 'Average Adjusters Ltd', interests: [ { role: 'forwarder', bl_ref: 'BL-001' }, { role: 'insurer' } ] }) })
🛒 Commerce / Dispute
// POST /v1/seal with evidence_degree fetch('/v1/seal', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ hash: sha256(file), evidence: [ { label: 'Invoice', status: 'PASS', evidence_degree: 9 }, { label: 'Delivery email', status: 'Declared', evidence_degree: 5 } ] }) })
Event authenticity — HMAC signing

Verify signed GA submissions before processing them.

Every GA submission generates a signed event envelope. The adjuster verifies the HMAC-SHA256 signature before updating their system. Constant-time comparison prevents timing attacks.

// Every submission response includes a signed event: { event_type: 'ga.interest.submitted', ga_reference: 'GA-2025-0441', timestamp_ms: 1748000000000, signature: 'sha256=a3f4...', algorithm: 'hmac-sha256', signed: true } // Verify locally (HMAC-SHA256): const canonical = `${event_type}:${ga_reference}:${timestamp_ms}:${sha256(data)}`; const expected = 'sha256=' + hmacSHA256(canonical, GA_WEBHOOK_SECRET); // Verify locally using verifyGAEvent(): const { verifyGAEvent, signGAEvent, GA_EVENT_TYPES } = require('./lib/webhookSignatures'); const result = verifyGAEvent(envelope, GA_WEBHOOK_SECRET); // → { ok: true } or { ok: false, reason: 'invalid_signature' | 'expired' } // Or verify via API: // POST /v1/ga/verify-event → { ok: true } or { ok: false, reason }
GA_WEBHOOK_SECRET: Set in server env. If absent, events are signed: false (graceful — not a fatal error). Absent secret = unsigned events, not broken events. Security Architecture v1 →
Verdict Stack — reading the multi-layer verdict

Every /v1/seal response now includes a verdict object.

// Seal response includes verdict: { receipt: { ... }, verdict: { label: 'SEALED', // SEALED | SEALED_WITH_FLAGS | QUARANTINED | REJECTED score: 87, // 0–100 weighted across 4 layers stack: { structural: { ok: true, score: 100, issues: [] }, integrity: { ok: true, score: 100, anchor_verified: true }, policy: { ok: true, score: 90, quarantine_triggers: [] }, readiness: { ok: true, score: 80, readiness_label: 'review_ready' }, risk_flags: [] } } } // Quarantined example — core record usable, items flagged: verdict: { label: 'QUARANTINED', score: 62, quarantine: { flagged_items: [{ type: 'overclaim', item: 'delivery_proof', reason: 'confidence=90 but degree=3' }], safe_to_share: true, restore_path: 'Correct flagged items and re-seal' }, appeal: { endpoint: '/v1/seal/explain', why_flagged: ['evidence_pass_below_min_degree:delivery_proof'], what_would_clear_it: ['Set evidence_degree >= 6 or downgrade to Declared'] } } // Get explanation for any receipt: const explain = await fetch(`/v1/seal/explain?id=${receiptId}`).then(r => r.json()); // → { why_flagged, what_would_clear_it, verdict_stack, quarantine }
Reviewer state API — four endpoints

Track what the reviewer did with the record.

// 1. Review surface auto-calls this when reviewer opens the link await fetch('/v1/review/open', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ receipt_id: '3fa85f64-...' }) }); // → { ok: true, first_open: true, open_count: 1 } // 2. Reviewer sends ACK await fetch('/v1/review/ack', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ receipt_id: '3fa85f64-...', note: 'Confirmed. Cargo release authorised.' }) }); // 3. Reviewer requests amendment (MER) await fetch('/v1/review/mer', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ receipt_id: '3fa85f64-...', content: 'Commercial invoice CIF value missing' }) }); // 4. Sender checks state (certificate_token from seal response) const state = await fetch(`/v1/review/state?id=3fa85f64-...`, { headers: { Authorization: `Bearer ${certToken}` } }).then(r => r.json()); // → { reviewer_state: { state: 'acknowledged', link_opened: true, open_count: 2, // ack_received: true, ack_at: '2026-03-26T...', mer_requested: false } }
Privacy: No reviewer identity stored. Actions only. State stored in reviewer_states/, never in the sealed ERF record.
Recovery paths — Authenticator-inspired fallback design

Every critical path has a recovery. The delete_token is your backup code.

// ① Re-issue certificate_token (lost access) // delete_token = backup code from original seal response fetch('/v1/seal/reissue-access', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ receipt_id: '3fa85f64-...', delete_token: 'your_backup_code' }) }) // → { ok: true, certificate_token: 'new_token', reviewer_state_url: '...' } // ② Supersede a record (create corrected version, preserve original) fetch('/v1/seal/supersede', { method: 'POST', body: JSON.stringify({ receipt_id: '3fa85f64-...', delete_token: 'backup', reason: 'Invoice value updated' }) }) // → { superseded_id: '...', next_step: 'POST /v1/seal with supersedes_id in payload' } // ③ Re-access GA session (adjuster lost token) fetch('/v1/ga/reopen?ref=GA-2025-0441&name=Average+Adjusters+Ltd') // → { adjuster_token: 'new_token', status_url: '...' }
Design rule: delete_token = backup code. Never lose it. Store separately from certificate_token. Like Google Authenticator: backup codes are the recovery path when the primary fails.
Install in 3 steps

No package manager required. Works anywhere JS runs.

1. Download

Download the official ZIP from www.vraimony.com. Verify SHA-256 before deploying.

2. Include

// Node.js const SDK = require('./vraimony-sdk'); // Browser<script src="vraimony-sdk.js"></script> // window.VraimonySDK

3. Start narrow

Build one record. Run assessReadiness(). Check the gaps. Expand only when the basic flow proves itself.

Security and privacy

What we promise about the SDK.

✓ No telemetry. No tracking. No analytics. No phone-home.

✓ No remote dependencies. Works fully offline.

✓ Full ed25519 signature verification requires verify.vraimony.com — the SDK provides the validation stub and structure only.

✓ This SDK does not claim legal admissibility, compliance certification, or official validation. Integrity packaging only.

New in v2.2.0

Local-first workflow helpers.

Use capabilityProbe() to decide between local and hybrid mode, summarizeUploads(), assessBundleVerdict(), and recommendTemplate() to route bundles in the browser, createIndexedCaseCache() for IndexedDB state, and fetchTemplatePacks() for same-owner server packs only. No third-party runtimes. Same-server workflows only.

Core decision assets

Everything here should map back to four assets only.

PFRP

Pre-Flight Rejection Predictor

Predict likely pushback before the case is packaged, then fix the structural blockers first.

Receiver Packs

Receiver Packs

Signed, receiver-specific guidance packs: required evidence, preferred order, rejection patterns, delivery lane, wording bans, and official-source deltas.

ZRDR

Zero-Read Decision Receipt

Give the receiving side a summary they can act on fast, without reading the whole file first.

Final Approval / Delivery

Final Approval + Delivery

Apply receiver-aware approval rules, then send the file through the lane that fits that workflow best.

Receiver Profiles

Receiver Profiles are the guidance layer across scan, packaging, verify, and rails.

Vraimony uses the same Receiver Profiles layer across Free Scan, One Case, Viewer, Verify, Downloads, SDK, and plugin rails — so the file is guided by the receiver, not by a generic template.

Decision layer fit

Not another tool. A receiver-aware decision layer.

Use the same four assets everywhere: PFRP, Receiver Packs, ZRDR, and Final Approval / Delivery. The plugin, SDK, verify surface, and templates are rails around that layer — not the layer itself.

PFRPReceiver PacksZRDRFinal Approval / Delivery