Documentation Index
Fetch the complete documentation index at: https://docs.manthan.systems/llms.txt
Use this file to discover all available pages before exploring further.
@parmanasystems/provenance is the foundational lineage package for the Parmana governance stack. It provides signal provenance types and hashing, provenance validation, source adapters, execution receipts, append-only lineage chains, authority tokens, fail-closed gating, portable proof bundles, and independent verification — all implemented deterministically using the Node.js built-in crypto module for the core logic, with optional Redis and Postgres adapters for production persistence.
Installation
npm install @parmanasystems/provenance
Most applications import directly from @parmanasystems/core, which re-exports the signal provenance functions (withProvenance, extractSignalValues, validateProvenance, the adapters, and the provenance types) without requiring a separate install. Use this package directly when you need the full governance lifecycle API — execution receipts, lineage chains, proof bundles, authority tokens, or independent verification.
Core types
GovernedSignal<T>
Wraps a raw signal value with optional provenance metadata. When no provenance is attached the signal is treated identically to a plain value — there is no breaking change.
interface GovernedSignal<T = unknown> {
value: T; // deterministic value evaluated by policy
provenance?: SignalProvenance; // optional origin metadata
}
type GovernedSignalMap = Record<string, GovernedSignal>;
SignalProvenance
Full provenance record describing where a signal came from, how it was obtained, and how trustworthy the source is.
interface SignalProvenance {
schemaVersion?: string; // provenance schema version ("1.0.0")
source: string; // e.g. "AccountAggregator", "CIBIL"
sourceType: SourceType; // source classification
sourceVerified: boolean; // whether provenance lineage was verified
verificationMethod?: VerificationMethod; // how it was verified
sourceTimestamp?: string; // ISO-8601 UTC timestamp from source
adapterIdentity?: string; // e.g. "aa-adapter@1.0.0"
transformationLineage?: string[]; // ordered transformations applied
evidenceHash?: string; // sha256:hex of canonical source payload
trustLevel?: ProvenanceTrustLevel;
metadata?: Record<string, unknown>; // source-specific context
}
sourceVerified: true means the provenance lineage was verified, not that the underlying claim is objectively true. Provenance records evidence chains, not real-world facts.
SourceAttestation
Cryptographic proof that a payload originated from a specific external system.
interface SourceAttestation {
source: string; // human-readable source identifier
signature: string; // base64 signature over canonical payload hash
algorithm: SignatureAlgorithm; // signing algorithm used
signedAt: string; // ISO-8601 UTC timestamp of signing event
payloadHash: string; // sha256:hex of canonical signed payload
keyId?: string; // optional signing key identifier
}
ProvenanceTrustLevel
type ProvenanceTrustLevel =
| "unverified" // no verification attempted
| "claimed" // source claims validity, not cryptographically proven
| "verified" // provenance cryptographically verified
| "trusted"; // verified by trusted authority
Trust ordering: unverified < claimed < verified < trusted. Comparison functions in this package use this ordering for minimum-trust enforcement.
TrustLevel
Application-layer simplified trust scale, re-exported for compatibility:
type TrustLevel = "low" | "medium" | "high";
SourceType
type SourceType =
| "financial_api" // Account Aggregator, CIBIL, credit bureaus
| "government_api" // DigiLocker, Aadhaar, GST, MCA
| "banking_api" // Core banking systems
| "document_ai" // Claude, Sarvam, OCR pipelines
| "voice_transcript" // Voice call analysis
| "internal_system" // Internal databases/services
| "manual_entry" // Human-entered values
| "unknown";
VerificationMethod
type VerificationMethod =
| "signature" // cryptographic signature verified
| "tls" // TLS channel verification
| "api-key" // API key authentication
| "manual" // human-verified
| "unknown";
SignatureAlgorithm
type SignatureAlgorithm =
| "ed25519"
| "rsa-pss-sha256"
| "ecdsa-p256"
| "unknown";
Evidence functions
hashEvidencePayload(rawEvidence) / hashEvidence
Hash a piece of raw evidence before adapter normalization occurs. Store the result in SignalProvenance.evidenceHash to create a tamper-evident link between the governed signal and the raw source payload.
function hashEvidencePayload(
rawEvidence: string | Buffer | Record<string, unknown>
): string // "sha256:abc123..."
hashEvidence is a backward-compatible alias for hashEvidencePayload.
import { hashEvidencePayload } from "@parmanasystems/provenance";
const hash = hashEvidencePayload(aaApiResponse);
// "sha256:3f4a9b..."
hashProvenance(provenance)
Deterministically hash a complete SignalProvenance record. Used for provenance attestations, audit lineage, and compact attestation storage.
function hashProvenance(provenance: SignalProvenance): string
hashSignalProvenance(signals) / hashProvenanceSummary
Hash the provenance layer of all governed signals in a map. Returns null if no signal has provenance. Signal values themselves are not hashed — this hashes metadata only.
function hashSignalProvenance(signals: GovernedSignalMap): string | null
hashProvenanceSummary is a backward-compatible alias.
This is the critical function. Strips provenance metadata and returns plain Record<string, unknown> for policy evaluation. Policy rules only ever see what this function returns — provenance never enters deterministic evaluation.
function extractSignalValues(
input: Record<string, unknown>
): Record<string, unknown>
Backward compatible with plain signal objects: if an entry does not have a value property (i.e., is a raw value, not a GovernedSignal), it passes through unchanged.
const governed = {
monthly_income: withProvenance(82000, provenance),
employed: withProvenance(true, provenance),
};
// Before calling executeFromSignals:
const signals = extractSignalValues(governed);
// { monthly_income: 82000, employed: true }
// Provenance is gone. Policy sees only values.
normalizeGovernedSignals(signals)
Core implementation of the extraction boundary. Identical to extractSignalValues but accepts the union type GovernedSignalMap | Record<string, unknown> explicitly.
function normalizeGovernedSignals(
signals: GovernedSignalMap | Record<string, unknown>
): Record<string, unknown>
Extract the provenance layer only. Signals without provenance are represented as null to preserve explicit absence semantics.
function extractProvenanceMap(
signals: GovernedSignalMap
): Record<string, SignalProvenance | null>
Useful for audit reconstruction and evidence lineage pipelines.
Validation
validateProvenance(signals, options?)
Evaluate provenance admissibility and trust characteristics of a governed signal map. Performs deterministic local evaluation only — does not fetch remote systems, resolve PKI chains, or validate real-world truth.
function validateProvenance(
signals: GovernedSignalMap | Record<string, unknown>,
options?: {
requireProvenance?: boolean; // all signals must have provenance
minimumTrustLevel?: ProvenanceTrustLevel; // reject below this trust level
requiredSources?: string[]; // allowed source identifiers
}
): ProvenanceValidationResult
ProvenanceValidationResult
interface ProvenanceValidationResult {
valid: boolean;
errors: string[]; // policy violations (block execution)
warnings: string[]; // missing timestamps, missing evidenceHash (informational)
trustSummary: {
totalSignals: number;
signalsWithProvenance: number;
verifiedSignals: number;
unverifiedSignals: number;
signalsMissingEvidenceHash: number;
signalsMissingTimestamp: number;
minimumTrustLevel: ProvenanceTrustLevel | null;
};
}
import { validateProvenance } from "@parmanasystems/provenance";
const result = validateProvenance(governedSignals, {
requireProvenance: true,
minimumTrustLevel: "verified",
requiredSources: ["AccountAggregator", "CIBIL"],
});
if (!result.valid) {
throw new Error(`Provenance check failed: ${result.errors.join(", ")}`);
}
console.log(result.trustSummary.minimumTrustLevel); // "verified"
Adapters
withProvenance<T>(value, provenance)
Wrap a raw signal value with a SignalProvenance record.
function withProvenance<T>(value: T, provenance: SignalProvenance): GovernedSignal<T>
withoutProvenance<T>(value)
Backward-compatible wrapper for signals that have no provenance. Returns a GovernedSignal with provenance absent.
function withoutProvenance<T>(value: T): GovernedSignal<T>
stripProvenance<T>(signal)
Explicitly strip provenance and return the raw value. This is a trust-reduction operation — use only when you intentionally want to discard lineage.
function stripProvenance<T>(signal: GovernedSignal<T>): T
accountAggregatorProvenance(options)
Build provenance for signals sourced from the RBI Account Aggregator framework. Sets trustLevel: "verified", sourceVerified: true, verificationMethod: "signature".
function accountAggregatorProvenance(options: {
consentId: string; // AA consent handle
fiuId: string; // your FIU registration ID
fetchedAt: string; // ISO-8601 UTC timestamp of fetch
rawDataHash?: string; // pre-computed evidence hash (or provide rawData)
rawData?: unknown; // raw FI data — hashed automatically for evidenceHash
transformations?: string[]; // defaults to ["rbi-aa-schema-normalization"]
}): SignalProvenance
documentProvenance(options)
Build provenance for signals extracted by an AI or OCR pipeline from a document. Sets trustLevel: "claimed", sourceVerified: false — AI extraction is not automatically trusted.
function documentProvenance(options: {
modelName: string; // e.g. "claude-3-5-sonnet"
modelVersion: string; // e.g. "20241022"
extractedAt?: string; // ISO-8601 UTC extraction timestamp
documentHash?: string; // pre-computed evidence hash (or provide rawDocument)
rawDocument?: unknown; // raw document bytes — hashed for evidenceHash
confidence?: number; // model confidence score stored in metadata
transformations?: string[];
}): SignalProvenance
voiceTranscriptProvenance(options)
Build provenance for signals extracted from a voice call transcript. Sets trustLevel: "claimed", sourceVerified: false.
function voiceTranscriptProvenance(options: {
callId: string; // call identifier
sttModel: string; // e.g. "sarvam-1"
language: string; // e.g. "hi-IN"
extractedAt: string; // ISO-8601 UTC extraction timestamp
transcriptHash?: string; // pre-computed evidence hash (or provide transcript)
transcript?: unknown; // transcript text — hashed for evidenceHash
confidence?: number;
}): SignalProvenance
Complete example: Account Aggregator income verification
A full flow from raw evidence to governed decision:
import {
withProvenance,
accountAggregatorProvenance,
validateProvenance,
extractSignalValues,
} from "@parmanasystems/provenance";
import {
executeFromSignals,
LocalSigner,
LocalVerifier,
MemoryReplayStore,
} from "@parmanasystems/core";
async function governedLoanDecision(
aaResponse: AccountAggregatorResponse,
cibilScore: number,
) {
// Step 1: Build provenance-aware governed signals
const governedSignals = {
monthly_income: withProvenance(
aaResponse.derivedMonthlyIncome,
accountAggregatorProvenance({
consentId: aaResponse.consentId,
fiuId: "FIU-NBFC-001",
fetchedAt: aaResponse.fetchedAt,
rawData: aaResponse.rawFiData, // hashed → evidenceHash
transformations: [
"rbi-aa-schema-normalization",
"monthly-average-v2",
],
})
),
cibil_score: withProvenance(
cibilScore,
{
source: "CIBIL",
sourceType: "financial_api",
sourceVerified: true,
verificationMethod: "api-key",
trustLevel: "verified",
sourceTimestamp: new Date().toISOString(),
}
),
employed: withProvenance(
aaResponse.hasRegularIncome,
accountAggregatorProvenance({
consentId: aaResponse.consentId,
fiuId: "FIU-NBFC-001",
fetchedAt: aaResponse.fetchedAt,
})
),
};
// Step 2: Validate provenance before execution
const validation = validateProvenance(governedSignals, {
requireProvenance: true,
minimumTrustLevel: "verified",
});
if (!validation.valid) {
throw new Error(`Provenance requirements not met: ${validation.errors.join(", ")}`);
}
// Step 3: Extract values — this is the determinism boundary.
// Policy evaluation never sees provenance metadata.
const signals = extractSignalValues(governedSignals);
// { monthly_income: 82000, cibil_score: 742, employed: true }
// Step 4: Execute governed decision
const signer = new LocalSigner(privateKey);
const verifier = new LocalVerifier(publicKey);
const store = new MemoryReplayStore();
const attestation = await executeFromSignals(
{ policyId: "personal-loan", policyVersion: "1.0.0", signals },
signer, verifier, store
);
return { attestation, provenanceSummary: validation.trustSummary };
}
Source attestation verification
verifySourceAttestation(payload, attestation, publicKey)
Verify a SourceAttestation against its canonical evidence payload. Fully local and deterministic — does not fetch certificates, resolve PKI chains, or query remote systems.
Verifies that the payload hash, signature, and supplied public key cryptographically match. Nothing more.
function verifySourceAttestation(
payload: unknown,
attestation: SourceAttestation,
publicKey: string, // PEM public key
): VerificationResult
interface VerificationResult {
valid: boolean;
reason?: string; // present on failure
}
Supports "ed25519", "rsa-pss-sha256", and "ecdsa-p256".
Provenance attestation summary
buildProvenanceAttestationSummary(signals)
Build a deterministic provenance summary for inclusion in governance attestations. Informational lineage metadata — must not affect the execution fingerprint or deterministic decision semantics.
function buildProvenanceAttestationSummary(
signals: GovernedSignalMap
): ProvenanceAttestationSummary
interface ProvenanceAttestationSummary {
provenanceHash: string | null;
signalsWithProvenance: number;
verifiedSignals: number;
unverifiedSignals: number;
minimumTrustLevel: ProvenanceTrustLevel | null;
}
Execution receipts
Record that a governed action was reported as executed. An execution receipt proves reported execution — not truthful execution or successful side effects.
function createExecutionReceipt(input: {
executionId: string;
attestationHash: string;
executorIdentity: string;
executedAction: string;
executedParameters: unknown; // hashed → executedParametersHash
outcome: "success" | "failure" | "partial" | "unknown";
executedAt?: string; // ISO-8601 UTC; defaults to now
minimumTrustLevel?: ProvenanceTrustLevel | null;
metadata?: Record<string, unknown>;
}): ExecutionReceipt
hashExecutionReceipt(receipt) / hashExecutionParameters(parameters)
function hashExecutionReceipt(receipt: ExecutionReceipt): string
function hashExecutionParameters(parameters: unknown): string
ExecutionReceipt
interface ExecutionReceipt {
executionId: string;
attestationHash: string;
executorIdentity: string;
executedAction: string;
executedParametersHash: string; // SHA-256 of canonical execution parameters
outcome: "success" | "failure" | "partial" | "unknown";
executedAt: string;
minimumTrustLevel?: ProvenanceTrustLevel | null;
metadata?: Record<string, unknown>;
}
Reconciliation
Reconcile authorized execution intent against a reported execution receipt to verify consistency.
reconcileExecution(authorized, receipt)
function reconcileExecution(
authorized: AuthorizedExecution,
receipt: ExecutionReceipt,
): ExecutionReconciliationResult
interface AuthorizedExecution {
executionId: string;
attestationHash: string;
authorizedAction: string;
authorizedParametersHash: string;
}
interface ExecutionReconciliationResult {
match: boolean;
mismatches: string[]; // which fields differed
reconciliationHash: string;
authorizedExecution: AuthorizedExecution;
executionReceipt: ExecutionReceipt;
}
A match: true result proves reported execution is consistent with authorized intent. It does not prove truthful execution or correct downstream side effects.
hashReconciliationResult(result)
function hashReconciliationResult(result: ExecutionReconciliationResult): string
Execution gateway
validateExecutionRequest(request)
Deterministically validate an incoming execution request against authorized intent. Validates authorization consistency only.
function validateExecutionRequest(
request: GovernedExecutionRequest
): GatewayValidationResult
interface GovernedExecutionRequest {
authorizedExecution: AuthorizedExecution;
executorIdentity: string;
executionParameters: unknown;
metadata?: Record<string, unknown>;
}
interface GatewayValidationResult {
allowed: boolean;
reasons: string[];
validatedAt: string;
}
interface GatewayExecutionResult {
success: boolean;
executionReceipt?: ExecutionReceipt;
error?: string;
}
GovernedExecutionGateway (interface)
Implement this interface to build a governed execution gateway. Implementations must remain deterministic in authorization behavior, replay-safe, and fail-closed.
interface GovernedExecutionGateway {
validateExecution(request: GovernedExecutionRequest): Promise<GatewayValidationResult> | GatewayValidationResult;
execute(request: GovernedExecutionRequest): Promise<GatewayExecutionResult> | GatewayExecutionResult;
}
Provenance policy evaluation
Evaluate explicit governance rules about provenance requirements. Provenance never implicitly affects deterministic policy evaluation — these rules must be explicit.
evaluateProvenancePolicy(signals, requirements)
function evaluateProvenancePolicy(
signals: GovernedSignalMap,
requirements: ProvenancePolicyRequirements,
): ProvenancePolicyResult
interface ProvenancePolicyRequirements {
requireProvenance?: boolean;
minimumTrustLevel?: ProvenanceTrustLevel;
allowedSources?: string[];
requireEvidenceHash?: boolean;
requireSourceTimestamp?: boolean;
requireVerifiedSources?: boolean;
}
interface ProvenancePolicyResult {
allowed: boolean;
violations: string[];
warnings: string[];
}
Evidence admissibility
Evaluate whether signal provenance meets the requirements to participate in governed authorization.
evaluateAdmissibility(signals, policy)
function evaluateAdmissibility(
signals: GovernedSignalMap,
policy: AdmissibilityPolicy,
): AdmissibilityResult
interface AdmissibilityPolicy {
requireProvenance?: boolean;
minimumTrustLevel?: ProvenanceTrustLevel;
allowedSources?: string[];
requireEvidenceHash?: boolean;
requireSourceTimestamp?: boolean;
requireVerifiedSources?: boolean;
}
interface AdmissibilityResult {
admissible: boolean;
signalResults: Record<string, SignalAdmissibilityResult>;
violations: string[];
}
interface SignalAdmissibilityResult {
admissible: boolean;
reasons: string[];
provenance?: SignalProvenance;
}
Audit timeline
Build a deterministic, reconstructable event timeline from execution receipts and reconciliation results.
function buildAuditTimeline(input: {
executionReceipt?: ExecutionReceipt;
reconciliation?: ExecutionReconciliationResult;
additionalEvents?: AuditEvent[];
}): AuditTimeline
function hashAuditEvent(event: AuditEvent): string
AuditEvent
interface AuditEvent {
eventId: string;
type:
| "signal_ingested"
| "provenance_verified"
| "decision_authorized"
| "execution_requested"
| "execution_reported"
| "execution_reconciled"
| "policy_violation"
| "audit_warning";
timestamp: string;
summary: string;
trustLevel?: ProvenanceTrustLevel | null;
references?: {
attestationHash?: string;
provenanceHash?: string;
executionReceiptHash?: string;
reconciliationHash?: string;
};
metadata?: Record<string, unknown>;
}
interface AuditTimeline {
timelineHash: string;
generatedAt: string;
events: AuditEvent[];
}
Append-only lineage chain
Tamper-evident, hash-linked lineage events. Events are append-only and chain-linked — each event embeds the lineageHash of the previous event.
function createLineageEvent(input: {
type: string;
payload: unknown; // hashed → payloadHash
previousHash: string | null; // null for genesis event
timestamp?: string; // provide explicitly for determinism
metadata?: Record<string, unknown>;
}): LineageEvent
interface LineageEvent {
eventId: string; // same as lineageHash
type: string;
timestamp: string;
payloadHash: string;
previousHash: string | null;
lineageHash: string;
metadata?: Record<string, unknown>;
}
verifyLineageChain(events)
Verify cryptographic continuity of an append-only lineage chain. Provides tamper evidence — not distributed consensus.
function verifyLineageChain(
events: LineageEvent[]
): { valid: boolean; errors: string[] }
Lineage replay
Deterministically reconstruct operational state from an append-only lineage event sequence.
replayLineage(events)
function replayLineage(events: LineageEvent[]): ReplayResult
interface ReplayState {
executionId?: string;
attestationHash?: string;
lineageHashes: string[]; // append-only, never sorted
provenanceHashes: string[];
executionReceiptHashes: string[];
reconciliationHashes: string[];
verificationBundleHashes: string[];
timelineHashes: string[];
eventCount: number;
reconstructedAt: string; // last event timestamp, not wall clock
}
interface ReplayResult {
valid: boolean;
replayHash: string;
errors: string[];
state: ReplayState;
}
Replay reconstructs observable evidence only. It does not prove truthful execution, infrastructure correctness, or external settlement integrity.
Execution authority
Deterministic, time-bounded tokens that authorize a specific executor to perform a specific governed action exactly once. Replay safety comes from consumption tracking, not randomness — the same inputs always produce the same token.
function createExecutionAuthority(input: {
executionId: string;
attestationHash: string;
authorizedAction: string;
authorizedParameters: unknown;
executorIdentity: string;
ttlSeconds: number;
issuedAt: string; // required for deterministic generation
}): ExecutionAuthority
interface ExecutionAuthority {
executionId: string;
attestationHash: string;
authorizedAction: string;
authorizedParametersHash: string;
executorIdentity: string;
nonce: string; // deterministically derived
issuedAt: string;
expiresAt: string;
authorityHash: string;
}
function verifyExecutionAuthority(
authority: ExecutionAuthority,
input: { executorIdentity: string; currentTime?: string }
): ExecutionAuthorityVerification
function hashExecutionAuthority(
authority: Omit<ExecutionAuthority, "authorityHash">
): string
interface ExecutionAuthorityVerification {
valid: boolean;
reasons: string[]; // integrity failures, executor mismatch, expiry
}
verifyExecutionAuthority validates integrity, expiration, and executor binding. It does not prevent replay by itself — pair with an AuthorityConsumptionStore.
Authority consumption
Atomically consume execution authorities to enforce single-execution replay protection.
async function verifyAuthorityConsumption(input: {
authority: ExecutionAuthority;
consumerIdentity: string;
store: AuthorityConsumptionStore;
currentTime?: string; // explicit for determinism; defaults to now
}): Promise<ConsumptionVerificationResult>
async function consumeExecutionAuthority(input: {
authority: ExecutionAuthority;
consumerIdentity: string;
store: AuthorityConsumptionStore;
currentTime?: string;
}): Promise<boolean> // false = already consumed or expired (fail closed)
AuthorityConsumptionStore (interface)
Implement to provide atomic single-consumption semantics. Implementations must guarantee atomicity and replay safety.
interface AuthorityConsumptionStore {
consume(authority: ExecutionAuthority, consumerIdentity: string): Promise<boolean> | boolean;
getStatus(authority: ExecutionAuthority): Promise<AuthorityConsumptionStatus> | AuthorityConsumptionStatus;
}
type AuthorityConsumptionStatus = "available" | "consumed" | "expired" | "invalid";
interface AuthorityConsumptionRecord {
executionId: string;
authorityHash: string;
nonce: string;
consumed: boolean;
consumedAt?: string;
consumedBy?: string;
}
interface ConsumptionVerificationResult {
allowed: boolean;
reasons: string[];
status: AuthorityConsumptionStatus;
}
Fail-closed execution gate
Aggregate all critical governance enforcement checkpoints. Any verification uncertainty results in denied execution — this is the core fail-closed guarantee.
function evaluateExecutionGate(input: ExecutionGateInput): ExecutionGateDecision
interface ExecutionGateInput {
authority: ExecutionAuthorityVerification; // required
consumption: ConsumptionVerificationResult; // required
admissibility?: AdmissibilityResult; // optional
invariants?: InvariantVerificationResult; // optional
}
interface ExecutionGateDecision {
allowed: boolean;
reasons: string[];
failedChecks: string[]; // "authority" | "consumption" | "admissibility" | "invariants"
}
Governance invariants
Verify operational integrity rules over a reconstructed lineage replay.
function verifyGovernanceInvariants(input: {
lineageEvents: LineageEvent[];
replay: ReplayResult;
verificationBundle?: VerificationBundle;
}): InvariantVerificationResult
interface InvariantViolation {
invariant: string;
severity: "low" | "medium" | "high" | "critical";
message: string;
}
interface InvariantVerificationResult {
valid: boolean;
violations: InvariantViolation[];
}
Checked invariants: replay validity, execution-without-authorization, reconciliation-without-receipt, bundle/execution mismatch, bundle/attestation mismatch, empty lineage.
Governance explanation
Produce a human-readable operational explanation from replay and invariant results.
function explainGovernance(input: {
replay: ReplayResult;
invariants: InvariantVerificationResult;
verificationBundle?: VerificationBundle;
}): GovernanceExplanation
interface GovernanceExplanation {
summary: string;
authorization: { attestationHash?: string; executionId?: string };
evidence: {
provenanceCount: number;
verificationBundlePresent: boolean;
minimumTrustObserved: string | null;
};
execution: {
executionReported: boolean;
reconciliationPerformed: boolean;
reconciliationConsistent: boolean;
};
integrity: {
replayValid: boolean;
invariantsValid: boolean;
violationCount: number;
};
observations: string[];
}
Ed25519 signing
Sign and verify canonical governance payloads using Ed25519. The payload must already be canonicalized before signing.
function signGovernancePayload(input: {
payload: string; // pre-canonicalized payload
privateKey: crypto.KeyObject;
keyId: string;
}): GovernanceSignature
function verifyGovernanceSignature(input: {
payload: string;
signature: GovernanceSignature;
publicKey: crypto.KeyObject;
}): boolean
function exportPublicKey(publicKey: crypto.KeyObject): string // PEM
function importPublicKey(pem: string): crypto.KeyObject
function generateGovernanceKeyPair(): { privateKey: crypto.KeyObject; publicKey: crypto.KeyObject }
// ^ Dev/test only. Production: use KMS, HSM, or hardware-backed roots.
interface GovernanceSignature {
algorithm: "ed25519";
keyId: string;
signature: string; // base64
}
interface SignablePayload {
payload: string;
}
Portable governance proof bundles
Signed, portable bundles containing lineage and replay state for independent verification without access to any trusted runtime.
function createGovernanceProofBundle(input: {
lineage: LineageEvent[];
replay: ReplayResult;
privateKey: crypto.KeyObject;
keyId: string;
generatedAt?: string;
}): GovernanceProofBundle
function verifyGovernanceProofBundle(input: {
bundle: GovernanceProofBundle;
publicKey: crypto.KeyObject;
}): { valid: boolean; errors: string[] }
interface GovernanceProofBundle {
schemaVersion: string;
generatedAt: string;
lineage: LineageEvent[];
replay: ReplayResult;
replayHash: string;
manifestHash: string;
signature: GovernanceSignature;
}
Independent verifier
Fully independent verification of a governance proof bundle. Assumes no trusted runtime, no hidden state, no infrastructure access — verification depends only on the portable bundle and the supplied trust root.
Runs five sequential checks: bundle signature, lineage chain integrity, independent replay, replay hash consistency, and governance invariants.
function verifyGovernanceProof(input: {
bundle: GovernanceProofBundle;
publicKey: crypto.KeyObject;
}): IndependentVerificationResult
interface IndependentVerificationResult {
valid: boolean;
errors: string[];
verification: {
signatureValid: boolean;
lineageValid: boolean;
replayValid: boolean;
invariantsValid: boolean;
replayHashMatches: boolean;
};
}
Verification bundles
Portable, independently verifiable evidence artifacts containing all operational lineage records for a single execution.
function createVerificationBundle(input: {
executionId: string;
attestationHash: string;
provenance?: ProvenanceAttestationSummary;
executionReceipt?: ExecutionReceipt;
reconciliation?: ExecutionReconciliationResult;
auditTimeline?: AuditTimeline;
}): VerificationBundle
function verifyVerificationBundle(bundle: VerificationBundle): boolean
function hashVerificationBundle(bundle: Omit<VerificationBundle, "bundleHash">): string
interface VerificationBundle {
schemaVersion: string;
generatedAt: string;
executionId: string;
attestationHash: string;
provenance?: ProvenanceAttestationSummary;
executionReceipt?: ExecutionReceipt;
reconciliation?: ExecutionReconciliationResult;
auditTimeline?: AuditTimeline;
bundleHash: string;
}
Audit report
Generate a human-readable narrative report from lineage events and a replay result.
function generateAuditReport(input: {
lineage: LineageEvent[];
replay: ReplayResult;
}): GovernanceAuditReport
interface GovernanceAuditReport {
executionId?: string;
attestationHash?: string;
replayHash: string;
generatedAt: string;
eventCount: number;
timeline: AuditNarrativeEvent[];
summary: {
authorizationOccurred: boolean;
executionOccurred: boolean;
reconciliationOccurred: boolean;
provenancePresent: boolean;
};
}
interface AuditNarrativeEvent {
timestamp: string;
type: string;
summary: string;
}
Persistence stores
InMemoryConsumptionStore
In-memory reference implementation of ExecutionConsumptionStore. For tests and local development only — not production-safe.
import { InMemoryConsumptionStore } from "@parmanasystems/provenance";
const store = new InMemoryConsumptionStore();
await store.consume({ authorityHash, executionId, consumerIdentity, consumedAt });
RedisConsumptionStore
Redis-backed atomic consumption store. Uses SET key value NX for replay protection. Redis unavailable → fail closed.
import { RedisConsumptionStore } from "@parmanasystems/provenance";
import Redis from "ioredis";
const store = new RedisConsumptionStore(
new Redis(process.env.REDIS_URL),
"parmana:consumed", // optional key prefix
);
Requires ioredis (listed as a production dependency).
PostgresLineageStore
PostgreSQL append-only lineage persistence. Uses INSERT only — no UPDATE semantics.
import { PostgresLineageStore } from "@parmanasystems/provenance";
import { Pool } from "pg";
const store = new PostgresLineageStore(new Pool({ connectionString: process.env.DATABASE_URL }));
// Intended schema:
// CREATE TABLE governance_lineage (
// id BIGSERIAL PRIMARY KEY,
// execution_id TEXT NOT NULL,
// lineage_hash TEXT NOT NULL UNIQUE,
// event_json JSONB NOT NULL,
// created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
// );
Requires pg (listed as a production dependency).
Persistence store interfaces
interface ExecutionConsumptionStore {
consume(input: { authorityHash: string; executionId: string; consumerIdentity: string; consumedAt: string }): Promise<ConsumptionResult>;
get(authorityHash: string): Promise<ConsumptionResult | null>;
}
interface LineagePersistenceStore<T> {
append(event: T): Promise<void>;
getByExecutionId(executionId: string): Promise<T[]>;
getAll(): Promise<T[]>;
}
interface GovernanceProofStore<T> {
persist(proof: T): Promise<void>;
get(replayHash: string): Promise<T | null>;
}
interface ConsumptionResult {
consumed: boolean;
consumedAt?: string;
consumerIdentity?: string;
}
verifyPersistedLineage(events)
Verify that a sequence of lineage events retrieved from a persistence store is cryptographically continuous and append-only.
function verifyPersistedLineage(events: LineageEvent[]): PersistedLineageVerificationResult
interface PersistedLineageVerificationResult {
valid: boolean;
errors: string[];
continuity: {
ordered: boolean;
appendOnly: boolean;
tamperFree: boolean;
};
}
Use Cases
Account Aggregator income verification with complete lineage
An NBFC fetches bank statement data via the RBI Account Aggregator framework and uses accountAggregatorProvenance to wrap each derived signal before execution:
import {
withProvenance,
accountAggregatorProvenance,
validateProvenance,
extractSignalValues,
} from "@parmanasystems/provenance";
const governedSignals = {
monthly_income: withProvenance(
aaResponse.derivedMonthlyIncome,
accountAggregatorProvenance({
consentId: aaResponse.consentId,
fiuId: "FIU-NBFC-001",
fetchedAt: aaResponse.fetchedAt,
rawData: aaResponse.rawFiData,
transformations: ["rbi-aa-schema-normalization", "monthly-average-v2"],
})
),
employed: withProvenance(
aaResponse.hasRegularIncome,
accountAggregatorProvenance({
consentId: aaResponse.consentId,
fiuId: "FIU-NBFC-001",
fetchedAt: aaResponse.fetchedAt,
})
),
};
const validation = validateProvenance(governedSignals, {
requireProvenance: true,
minimumTrustLevel: "verified",
});
if (!validation.valid) throw new Error(validation.errors.join(", "));
// Policy evaluation sees only raw values — never provenance
const signals = extractSignalValues(governedSignals);
The resulting audit chain: AA consent → evidenceHash of raw FI data → derived income signal → governed decision. Auditors can trace each signal to its source system without embedding raw financial data in the attestation.
A loan processor uses Claude to extract monthly_income and emi_obligations from uploaded bank statement PDFs. Each extracted value is wrapped with documentProvenance:
import { withProvenance, documentProvenance } from "@parmanasystems/provenance";
const governedSignals = {
monthly_income: withProvenance(
extractedIncome,
documentProvenance({
modelName: "claude-3-5-sonnet",
modelVersion: "20241022",
extractedAt: new Date().toISOString(),
rawDocument: pdfBytes,
confidence: 0.95,
transformations: ["pdf-text-extraction", "income-normalization"],
})
),
};
// trustLevel: "claimed" — AI extraction is not automatically trusted
The trust level is "claimed". The NBFC then validates these signals against Account Aggregator data before execution, or expresses the verification result explicitly as a boolean signal: income_source_verified: true.
Voice KYC for rural microfinance
A microfinance institution conducts video KYC via voice call for rural borrowers. Signals extracted from the transcript are wrapped with voiceTranscriptProvenance:
import { withProvenance, voiceTranscriptProvenance } from "@parmanasystems/provenance";
const governedSignals = {
monthly_income: withProvenance(
statedIncome,
voiceTranscriptProvenance({
callId: "CALL-2024-XYZ789",
sttModel: "sarvam-1",
language: "hi-IN",
extractedAt: new Date().toISOString(),
transcript: transcriptText,
confidence: 0.87,
})
),
};
// trustLevel: "claimed" — voice extraction is not automatically trusted
The compliance team can trace every signal back to the specific call recording via the evidenceHash — without embedding the full transcript in the attestation.
Progressive trust adoption
An NBFC starts with plain signals and no provenance. Over time it adds provenance to individual signal sources. Because extractSignalValues handles both plain values and GovernedSignal wrappers, there is no breaking change:
// Stage 1: plain signals — no provenance
const signals = { monthly_income: 82000, credit_score: 720 };
// Stage 2: add provenance to AA signals only
const signals = {
monthly_income: withProvenance(82000, accountAggregatorProvenance({ ... })),
credit_score: 720, // still plain — mixed is fine
};
// Stage 3: full provenance coverage
const signals = {
monthly_income: withProvenance(82000, accountAggregatorProvenance({ ... })),
credit_score: withProvenance(720, { source: "CIBIL", sourceType: "financial_api", ... }),
};
Each stage is independently deployable. No flag day, no forced migration.
Design principles
OPTIONAL — Provenance is entirely optional. Code that passes plain Record<string, unknown> signals continues to work unchanged. extractSignalValues handles both plain values and GovernedSignal wrappers. No migration required.
ADJACENT — Provenance is never embedded into deterministic policy evaluation. The execution_fingerprint is SHA-256({ policyId, policyVersion, signals }) — not signals + provenance. Two executions with identical signal values but different provenance produce identical decisions.
EXTRACTABLE — extractSignalValues is the critical boundary. Everything above it (provenance, adapters, validation) is ingestion-layer tooling. Everything below it (policy evaluation, attestation, fingerprinting) never sees provenance.
HASHABLE — Every provenance record reduces to an evidenceHash for compact storage and lineage linkage. Use hashEvidencePayload before transformation, store the hash in SignalProvenance.evidenceHash, and link the governed signal to its raw source without embedding the raw payload.
EXTENSIBLE — The metadata field on SignalProvenance stores source-specific additional context without requiring schema changes. Metadata must not affect deterministic policy evaluation.
DETERMINISTIC — All hash functions use canonical serialization (sorted object keys, stable array ordering). The same inputs always produce the same outputs across runtimes, operating systems, and object insertion orders.
Dependencies
The core logic (types, evidence hashing, provenance, validation, adapters, lineage, replay, execution authority, fail-closed gate, signing, proof bundles, independent verifier) uses only the Node.js built-in node:crypto module — no external dependencies required.
RedisConsumptionStore requires ioredis. PostgresLineageStore requires pg. Both are listed as production dependencies.