Fork-friendly governance primitives. Not another vendor lock-in.
Architecture, hash-chained audit internals, fastworker control plane, FIX gateway as peer service, MCP boundary, OpenTelemetry traces from agent → engine → audit. Every primitive is replaceable.
Four layers. No drift between callers.
The policy gate is a pure function called by every governed surface — the FIX gateway, the curve ingester, the operator workspace. One decision surface, not five drift-prone copies.
The control plane (gate, envelopes, audit, eval) is isolated from the bond domain (QuantLib, curves, FIX). Fork the repo, swap packages/bondfoundry_engine for your own domain, inherit AIGF alignment.
Agent loop
-
Claude (or any model) via MCP -
Tool-call manifest pinned + allowlisted -
Prompt firewall, 8 patterns, 4 modes
Policy gate (pure function)
-
decide(action, context) → Decision -
No I/O, no clock, deterministic -
Verbatim rule citation in payload
Control plane
-
HMAC envelopes, server-issued -
OIDC sessions, JWKS TTL cache -
OpenTelemetry traces, peer services
Engine + audit
-
QuantLib pricing (parity vanilla) -
Postgres triggers reject UPDATE/DELETE -
sha256 row chain, sequence-folded
In Postgres. Not in your application.
Application-layer immutability survives until someone has psql access. Database-layer immutability survives the application being compromised.
- Triggers reject UPDATE and DELETE on audit_log
- sha256 chain folds in sequence numbers; identical timestamps don't break ordering
- framework_ref NOT NULL with taxonomy CHECK constraint
CREATE OR REPLACE FUNCTION reject_mutation()
RETURNS trigger LANGUAGE plpgsql AS $$
BEGIN
RAISE EXCEPTION 'audit_log is append-only (tg_op=%, row=%)',
TG_OP, OLD.id;
END;
$$;
CREATE TRIGGER audit_immutable
BEFORE UPDATE OR DELETE ON audit_log
FOR EACH ROW EXECUTE FUNCTION reject_mutation();
ALTER TABLE audit_log
ADD COLUMN framework_ref text[] NOT NULL
CHECK (cardinality(framework_ref) > 0); Architecture deep-dives.
Open-Source vs Vendor SaaS: Building Your Own Governed AI Desk
Why self-hosting an AI agent for the buy-side desk is a board-level conversation in 2026 — and the fork-and-swap pattern that makes it tractable.
From CSV to Real-Time: Curve Provider Architecture for Multi-Source Bond Markets
How BondFoundry ingests yield curves from ECB, US Treasury, Bloomberg BVAL, Refinitiv RDP, and CSV — with stale-curve detection that survives the morning.
The Four Pillars of Governed AI in Finance
Policy gate, audit chain, HITL envelopes, and the AIGF coverage gate — the four primitives every agentic-AI system in a regulated workflow needs.
What engineers ask before forking
Why a pure-function policy gate?
Because you can fuzz it, reason about invariants from the signature, embed it into multiple callers without drift, and replay any historical decision from the audit row context payload. "Show me the decision logic on June 1" is answered with `git show`, not a runtime config archive.
How does immutability work if I have psql access?
Postgres BEFORE UPDATE/DELETE triggers reject mutations at the database layer. To remove a row you would have to drop and recreate the trigger — which itself writes to a meta-audit log and is monitored.
Can I swap the LLM?
Yes. The agent loop communicates with the model via MCP and tool calls. Replacing the provider is a config change. We default to Claude because the policy + audit story is easier to demonstrate with a frontier model, but the boundary is provider-agnostic.
How do I add my own domain (loans, derivatives, equities)?
Fork the repo. The control plane (policy gate, audit, HITL, eval) is isolated from the bonds domain. Swap packages/bondfoundry_engine for your domain, keep the control plane, inherit AIGF alignment.