JSPM

@fidacy/session

0.1.3
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 666
  • Score
    100M100P100Q8218F
  • License Apache-2.0

Conversation receipts for AI chatbots: hash every message into a tamper-evident session digest (locally, content never leaves your infrastructure), anchor it to Bitcoin via Fidacy at session close, and hand both sides a verifiable receipt.

Package Exports

  • @fidacy/session

Readme

@fidacy/session

Conversation receipts for AI chatbots.

Your support bot talks to customers about claims, prescriptions, refunds, contracts. When a dispute comes, the question is always the same: what exactly was said, and can either side prove the transcript wasn't edited after the fact? A court already answered what happens without proof (Air Canada, 2024: the airline was held to what its chatbot said).

This SDK gives every session a tamper-evident digest, computed locally, message by message. At session close you anchor the digest through Fidacy, where it joins an audit chain checkpointed to the Bitcoin blockchain, and you get a signed receipt. Hand the verify link to the customer too: proof both sides can hold is the only proof that settles arguments.

The transcript never leaves your infrastructure. Only a 64-hex SHA-256 travels. That is the whole privacy story, and it is why this works for hospitals and insurers.

Install

npm i @fidacy/session

Get a key (one minute, free)

Anchoring needs a Fidacy engine API key (fky_live_…/fky_test_…) with the assess:write scope. Sign up free at app.fidacy.com, open API keys, mint one, and export it as FIDACY_ENGINE_API_KEY. Everything below the anchor call (hashing, digests, offline verification) works with no key at all.

Use

import { createSession } from "@fidacy/session";

const session = createSession({ kind: "conversation", label: "case-4711" });

// wire into your chat loop
session.add("user", "I want to file a claim for water damage.");
session.add("assistant", "I can help. When did it happen?");
session.add("user", "Last Tuesday.");

// at session close: anchor the digest (content never leaves your machine)
const receipt = await session.anchor({ apiKey: process.env.FIDACY_ENGINE_API_KEY! });

// store the transcript + receipt; give the customer the public verify link
const transcript = session.export();
console.log(session.verifyUrl()); // https://fidacy.com/verify?sha256=…

Gate what the bot can commit to

Anchoring proves what was said. The gate controls what the bot may do. A refund, an approved claim, a quote above a threshold, a document sent: each is a commitment that needs a signed verdict from the engine, and the verdict is recorded into the same chain, so the anchored receipt itself proves the gate ran and what it decided.

// the bot wants to promise a refund — ask the engine first
const verdict = await session.gate(
  { type: "refund", amount: 900, currency: "USD", case: "case-4711" },
  { apiKey: process.env.FIDACY_ENGINE_API_KEY!, kind: "message_send" },
);

if (!verdict.allowed) {
  // deny-by-default: anything but "approve" means the bot must refuse.
  reply("I can't authorize that refund here, let me connect you to an agent.");
}

verdict.allowed is true only on approve; review is not a green light. On engine failure the call throws, and your bot refuses: fail closed, never fail open. The signed verdict (riskPayloadJws) verifies against the same public JWKS as everything else. gateCommitment(mandate, opts) is the standalone version if you gate outside a session; record: false skips writing the verdict into the chain.

Verify, without trusting anyone

The digest recipe is public. Anyone holding the exported transcript recomputes it offline:

import { digestTranscript } from "@fidacy/session";
digestTranscript(transcript.messages) === transcript.sha256; // true, or it was tampered
  • h_0 = sha256("fidacy.session.v1")
  • leaf_i = sha256(canonicalJson({ i, role, content, ts }))
  • h_i = sha256(h_{i-1} + "|" + leaf_i)

The final head is what gets anchored. Check any digest at fidacy.com/verify (no account), or via the public API: GET https://api.fidacy.com/v1/verify/artifact?sha256=<hex>. The signed receipt verifies against the engine JWKS at https://api.fidacy.com/.well-known/jwks.json.

Hashing is isomorphic (Node, browser, edge, Deno) via @noble/hashes, so digestTranscript recomputes the same hash wherever a consumer holds the transcript — including in the browser.

Changing one character of one message, reordering two messages, or dropping a message produces a different digest. That mismatch is the tampering signal.

What this is not

Fidacy never sees, stores or judges the conversation content. This is integrity and existence proof plus a commitment gate, not content moderation. The bot talks freely; it cannot obligate you outside what you authorized. For payments with hard enforcement (the money physically cannot move without a grant), pair it with the Fidacy firewall.

Apache-2.0.