Primitive Objects
Six primitive types form the evidence grammar. They are intentionally minimal so they can describe any AI-assisted banking workflow.
- DecisionWhat was decided
- SourceWhat was used as input
- ClaimWhat the system asserted
- PolicyWhat rule applied
- ActorWho or what acted
- EventWhat happened, in order
pub struct Claim {
pub claim_id: ClaimId,
pub text: String,
pub claim_type: ClaimType,
pub materiality: Materiality,
pub status: ClaimStatus,
pub supporting_sources: Vec<SourceId>,
pub calculations: Vec<CalculationRef>,
pub policy_refs: Vec<PolicyId>,
pub generated_by: ActorId,
pub confidence: Option<Confidence>,
pub supersedes: Option<ClaimId>,
}Bundle Format
A portable directory or archive. baink-bundle.json is the entrypoint and lists every artifact with its hash and required flag.
{
"bundle_id": "loan_123",
"standard_version": "0.1.0",
"profile": "baink-cm-0.1",
"decision_id": "dec_8f3a",
"artifacts": [
{ "path": "manifest.json", "type": "manifest", "required": true, "hash": "sha256:…" },
{ "path": "events.jsonl", "type": "event_log", "required": true, "hash": "sha256:…" },
{ "path": "evidence_map.json", "type": "evidence_map", "required": true, "hash": "sha256:…" }
],
"bundle_hash": "sha256:…"
}Canonicalization Rules
Pretty JSON is for humans. Canonical JSON is for machines. The hash is for proof. Every object is serialized in canonical key order before hashing.
pub trait Canonicalize {
fn canonical_bytes(&self) -> Result<Vec<u8>, BainkError>;
fn canonical_hash(&self) -> Result<Hash256, BainkError> {
let bytes = self.canonical_bytes()?;
Ok(Hash256::sha256(&bytes))
}
}Hash-Chain Protocol
The event ledger is append-only. Each event hash includes the canonical body and the previous event's hash, so removing or reordering events breaks every later fingerprint.
pub fn verify_hash_chain(events: &[Event]) -> VerificationResult {
for w in events.windows(2) {
let (prev, next) = (&w[0], &w[1]);
if next.prev_event_hash != Some(prev.event_hash.clone()) {
return VerificationResult::fail("broken_hash_chain");
}
if next.compute_hash()? != next.event_hash {
return VerificationResult::fail("invalid_event_hash");
}
}
VerificationResult::pass()
}EvidenceMap Protocol
The EvidenceMap links claims to sources, policies, reviewers, and exceptions. Every material claim must have source, calculation, policy, or reviewer support.
pub struct EvidenceMappedClaim {
pub claim_id: ClaimId,
pub claim_text: String,
pub claim_type: ClaimType,
pub generated_by: ActorId,
pub materiality: Materiality,
pub support: ClaimSupport,
pub policy_refs: Vec<PolicyId>,
pub review: Option<ReviewRecord>,
pub exceptions: Vec<ExceptionRef>,
}Conformance Levels
Conformance is executable, not a marketing badge. Each level maps to a required set of verification rules.
- L0Compatibleschemas validate
- L1Verifiablerequired artifacts present, hashes match, chain valid
- L2Controlledclaims linked, policies versioned, actors resolved, exceptions recorded
- L3AuditGradesignoffs, replay recipe, retention policy, signed verification report
- L4Insurableincident workflow, control history, metrics, insurer intake fields
Profile System
The base standard defines what a claim is. A profile defines what a specific workflow's claims require — for example, every financial-metric claim in a credit memo must have both source support and calculation support.
L6 · Research
Math Behind BAINK
BAINK's verification math layer — not the UI, not the prose. The geometric reason an evidence bundle is trustworthy: a decision is robust when its evidence transport loop has stable holonomy across perturbation, policy version, and scale.
Core mapping
| Banking concept | Geometric object |
|---|---|
| Banking workflow | Dynamic hypergraph |
| Customer / market / risk state | Dynamic manifold |
| Evidence bundle | Figure-eight transport loop |
| Auditability | Persistent holonomy invariant |
Decision Trust = persistent stability of evidence transport around the loop.
Credit decision as geometry
A credit case lives on a continuous risk manifold and is observed through a discrete evidence-policy hypergraph. The two are stitched together at a moving correspondence.
M_t = continuous risk manifold
( income, cash flow, DTI, utilization, volatility,
macro conditions, fraud signals, time-series behavior )H_t = evidence-policy hypergraph
( documents, policies, rules, model outputs,
adverse-action reasons, human reviews, regulatory constraints )Γ_t ⊂ M_t × H_t
where continuous borrower state becomes discrete evidence,
and policy/evidence pushes back onto the risk geometry.The decision loop
Every decision traces a closed path through data, evidence, policy, explanation, and back to risk state. Its holonomy is the composition of transports around that loop.
γ_decision : M_t → Γ_t → H_t → Γ_t → M_t
Hol(γ_decision) = U_{H→M} · U_H · U_{M→H} · U_MStability test
The verifier perturbs evidence, policy version, thresholds, and missing-document substitutions, then compares holonomy across scales ε.
Hol_ε(γ) ≈ Hol_{ε'}(γ)‖ Hol_ε(γ) − Hol_{ε'}(γ) ‖ > τ_warn‖ Hol_ε(γ) − Hol_{ε'}(γ) ‖ ≫ 0 → UNSTABLE DECISION PATHPipeline
raw bank data
↓
risk-state manifold M_t
↓
evidence extraction Γ_t
↓
policy/evidence graph H_t
↓
decision loop γ
↓
persistent holonomy PHol(γ)
↓
BAINK evidence bundle + verifier resultBundle extension (L6)
When a profile opts into L6, the bundle carries a holonomy signature alongside the existing hash chain and EvidenceMap.
{
"decision_id": "dec_8f3a",
"manifold_state_hash": "sha256:…",
"hypergraph_hash": "sha256:…",
"correspondence_hash": "sha256:…",
"policy_version": "cm-credit-2024.11",
"evidence_sources": ["src_paystub_01", "src_bureau_02", "…"],
"holonomy_signature": "phol1:…",
"persistence_band": {
"epsilon_min": 0.01,
"epsilon_max": 0.20,
"stability_score": 0.94
},
"warnings": []
}BAINK does not merely store evidence. It verifies that the path from evidence to decision remains geometrically stable across scale, perturbation, and policy context.