Skip to main content

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.

Abstract

AI systems making consequential decisions — approving loans, blocking transactions, processing insurance claims — operate without cryptographic proof that their decisions followed stated policies. Parmana Systems provides deterministic governance infrastructure that closes this gap. Every governed decision produces a cryptographically signed attestation, independently verifiable by any party, without access to the original runtime.

1. The Problem

1.1 AI decisions are ungoverned promises

When a bank’s AI system approves a ₹10 lakh loan, several things are claimed but none are proved:
"The AI followed our credit policy"             ← claimed, not proved
"The same inputs give the same decision"        ← claimed, not proved
"The decision cannot be altered retroactively"  ← claimed, not proved
"An auditor can verify the decision"            ← claimed, not proved
Today’s governance tools — audit logs, model monitors, dashboards — record what happened. They do not prove it. The distinction matters:
  • A log says the decision was X. A log can be altered.
  • An attestation proves the decision was X. A signature cannot be faked.

1.2 What regulators actually need

RBI, IRDAI, and SEBI do not require blockchain. They require:
  1. Proof the decision followed stated policy
  2. Proof the decision cannot be altered
  3. Ability to independently verify
  4. Audit trail linking decision to evidence
Parmana provides all four — inside your own infrastructure, at millisecond latency, without consensus or gas fees.

2. The Governance Lifecycle

Evaluate → Simulate → Execute → ConfirmExecution
StageMeaningAttestation issued
EvaluateHypothetical — what would happen?No
SimulateDry-run — full pipeline without signingNo
ExecuteAuthoritative — governed decisionYes
ConfirmExecutionIntegrity — did execution match authorization?Yes
Each stage is distinct. Evaluate is free and reversible. Execute is authoritative and replay-protected. ConfirmExecution closes the loop between authorization and action.

3. The Execution Pipeline

When executeFromSignals() is called the pipeline runs in this exact order:
1. loadPolicy       — load versioned policy from content-addressed bundle
2. validateSignals  — validate every signal against declared schema
3. evaluatePolicy   — evaluate rules → decision
4. fingerprint      — sha256(canonicalize({ policyId, policyVersion, signals }))
5. reserve          — replay protection phase 1
6. issueToken       — build execution token
7. sign             — Ed25519 signature over canonical attestation
8. confirm          — replay protection phase 2
9. return           — ExecutionAttestation
Evaluation happens before reservation. The decision is computed first, then committed atomically.

4. The Attestation

Every executeFromSignals() call produces an ExecutionAttestation signed with Ed25519 over 17 fields:
{
  executionId,           // unique per event — random UUID
  execution_fingerprint, // sha256({ policyId, policyVersion, signals })
  policyId,              // which policy governed this
  policyVersion,         // which version of the policy
  schemaVersion,         // schema used for evaluation
  runtimeVersion,        // runtime that produced this decision
  signalsHash,           // same as execution_fingerprint
  decision,              // { action, requires_override, reason? }
  execution_state,       // pipeline state at signing
  runtimeHash,           // hash of runtime code
  bundleHash,            // hash of policy bundle files
  manifestHash,          // hash of bundle manifest
  manifestSignature,     // bundle's own Ed25519 signature
  trustRootVersion,      // which trust root was used
  signerKeyId,           // which key signed this
  evaluatorHash,         // hash of the evaluation engine
  releaseManifestHash,   // hash of release manifest
}
If any field is altered — the signature breaks. Every field is independently verifiable by anyone with the public key.

Raw signals are not embedded

Raw signals are committed via execution_fingerprint — the SHA-256 hash of { policyId, policyVersion, signals }. This keeps attestations compact while making signals tamper-evident. An auditor can verify any claim about what signals were used by re-evaluating the policy and checking the fingerprint matches.

5. The Determinism Guarantee

Same governed inputs always produce the same governed decision. This is enforced at runtime — not promised:
// FORBIDDEN inside the evaluation scope:
Date.now()     // wall clock — different on every call
Math.random()  // non-deterministic by definition
new Date()     // wall clock contamination
Violations throw InvariantViolation immediately. Execution stops. No partial results. The evaluation engine runs in a sealed scope. Forbidden globals are blocked before evaluation begins. A CI invariant gate detects forbidden API usage in governed paths.

Why determinism enables verification

Because the evaluation is deterministic, any party can verify a decision:
1. Obtain the attestation
2. Obtain the public key
3. Verify the signature
4. Obtain the policy version referenced in the attestation
5. Re-evaluate the policy with the same signals
6. Confirm the decision matches
No access to the original runtime is needed. No trust in the original operator is required.

6. Replay Protection

The same governed execution cannot run twice. Two-phase commit:
Phase 1 RESERVE  — before evaluation begins
  executionId reserved in replay store
  If already reserved → InvariantViolation thrown immediately
  Nothing has happened yet — safe to fail

Phase 2 CONFIRM  — after signing completes
  executionId confirmed as executed
  Reservation consumed permanently
  Cannot be replayed by any caller
Three replay store implementations:
// Development — in-memory, not persistent
new MemoryReplayStore()

// Production — persistent, atomic, configurable TTL
new RedisReplayStore(process.env.REDIS_URL)

// Custom — implement ReplayStore interface
// must provide: hasExecuted(), markExecuted()

7. Signal Provenance

7.1 The gap that remains after governance

Before provenance:
  unverified signals → governed decision → signed attestation

The decision is proved. The signals are not.

7.2 What provenance adds

@parmanasystems/provenance adds optional metadata to signals:
const signals = {
  monthly_income: withProvenance(82000, {
    source: "AccountAggregator",
    sourceType: "financial_api",
    sourceVerified: true,
    verificationMethod: "signature",
    trustLevel: "verified",
    adapterIdentity: "aa-income-adapter@1.2.0",
    evidenceHash: "sha256:abc123...",
    transformationLineage: [
      "rbi-aa-schema-normalization",
      "monthly-average-v2",
    ],
  }),
};
Provenance is optional. Existing signal maps work unchanged.

7.3 The determinism boundary

Provenance never enters policy evaluation:
// extractSignalValues() strips provenance
// Policy evaluation sees only values — never metadata
const policySignals = extractSignalValues(governedSignals);
// { monthly_income: 82000, employed: true }

const attestation = await executeFromSignals({
  signals: policySignals,
  ...
});
The execution_fingerprint hashes only raw signal values. Provenance is adjacent — it never affects fingerprints, replay identity, or attestation hashes.

7.4 Source adapters for Indian financial infrastructure

// RBI Account Aggregator
accountAggregatorProvenance({
  consentId, fiuId, fetchedAt, rawDataHash
})
// → sourceVerified: true, trustLevel: "verified"

// AI document extraction
documentProvenance({
  modelName, modelVersion, extractedAt, rawDocument
})
// → sourceVerified: false, trustLevel: "claimed"

// Voice call transcript
voiceTranscriptProvenance({
  callId, sttModel, language, transcript
})
// → sourceVerified: false, trustLevel: "claimed"

7.5 The complete trust chain

Before provenance:
  anonymous signals → governed decision → signed attestation

After provenance:
  AA consent → evidenceHash → income signal

                         governed decision

                         signed attestation

                         execution integrity proof

Full trace: evidence → signal → decision → execution

8. Execution Integrity

8.1 The execution gap

Governance proves the decision. It does not prove the execution.
Attestation says: approve ₹5 lakh loan to CUST-9823741
System does:      ??? ← unobserved

8.2 confirmExecution()

confirmExecution() produces a signed ExecutionIntegrityProof by running seven steps in order:
1. Verify original attestation signature
2. Check not already confirmed
   (replay key: "confirm:" + attestation.executionId)
3. Compute integrityHash:
   sha256(canonicalizeForSigning({
     authorizationId: attestation.executionId,
     execution_fingerprint,
     executedAction,
   }))
4. Check actionTypeMatch
5. Check payloadConsistent
6. Check withinTimeWindow (default 300 seconds)
7. Sign the ExecutionIntegrityProof

8.3 What is and is not proved

ClaimStatus
Attestation was valid before confirmation✅ Cryptographically proved
Authorization confirmed only once✅ Cryptographically proved
Reported action is linked to authorization✅ Cryptographically proved
Reported action matched authorization✅ Proved — or divergence recorded
Reported action is truthful❌ Self-reported
No other action occurred outside the system❌ Unobserved
When match: false — divergence between authorization and reported execution is itself a signed, tamper-evident record. This is evidence, not silence.

9. Indian Regulatory Alignment

9.1 RBI

RequirementParmana mechanism
Audit trailAppend-only lineage with cryptographic chain
Change managementVersioned policy bundles with bundle hash
Decision explainabilityrule_id in decision, reason field
Non-discrimination auditPolicy is auditable JSON — not a black box
Grievance redressal evidenceAttestation as cryptographic evidence

9.2 IRDAI

RequirementParmana mechanism
AI governance frameworkPolicy compilation with error codes
AuditabilitySigned attestations, independent verification
Human oversightrequires_override flag in every decision
DocumentationBundle manifests, release manifests

9.3 SEBI

RequirementParmana mechanism
System audit trailCryptographic lineage per decision
Tamper-evident logsEd25519 signatures — any change detectable
Independent verificationverifyAttestation() needs only public key

10. What Parmana Proves and What It Does Not

Cryptographically guaranteed

✅ Decision followed exactly this policy version
✅ Signals used are exactly what was fingerprinted
✅ Decision cannot be altered without detection
✅ Same policy + signals → same decision always
✅ Execution was not replayed
✅ Runtime that produced this decision is identified
✅ Signal provenance is recorded and hashable
✅ Reported execution is linked to authorization

Trust-based — not cryptographically proved

❌ Signals accurately reflect reality
❌ Reported execution actually occurred
❌ No other execution occurred outside the system
❌ Signing key is controlled by the right party
Parmana is honest about this boundary. The architecture is designed to extend it — not pretend it does not exist.

The roadmap to stronger guarantees

Phase 1 (shipped)  Signal provenance — trace where signals came from
Phase 2 (next)     Source attestation — verify signals signed by source
Phase 3 (future)   TEE integration — hardware-proved execution
Phase 4 (future)   Governed execution gateway — authorization-bound actions

11. Getting Started

import {
  executeFromSignals,
  LocalSigner,
  LocalVerifier,
  MemoryReplayStore,
} from "@parmanasystems/core";

const attestation = await executeFromSignals(
  {
    policyId: "personal-loan",
    policyVersion: "1.0.0",
    signals: {
      monthly_income:   82000,
      loan_amount:      500000,
      employed:         true,
      emi_obligations:  12000,
      blacklisted:      false,
    },
  },
  new LocalSigner(privateKey),
  new LocalVerifier(publicKey),
  new MemoryReplayStore()
);

// attestation.decision.action === "approve"
// attestation.signature — Ed25519, independently verifiable
// attestation.execution_fingerprint — SHA-256 binding
Full documentation: docs.manthan.systems