Insurance math that runs as a streaming system — and pins its own answers to a ledger.
Every policy event flows RabbitMQ into the actuarial engine: enrichment, prospective reserves, equivalence-principle pricing, throttled LLM analysis. External systems report over AMCP — MCP over AMQP. Reserves and custody land as SHA-256 Merkle roots on Stellar, and a watcher reconciles the world against them every five minutes. This is the operating rail behind deepgalaxy's verification case.
The field behind this page is decorative — a particle sweep of the event rail: most packets verify and glow amber, flagged ones flare red and are held at the SIU gate. Drawn locally in your browser; nothing here phones home. The explorer below is the real topology, and it runs.
One rail, four subsystems, zero spreadsheets.
Actuary.Finance is the production system this site documents: an Elixir/Phoenix event-streaming platform with RabbitMQ as the backbone, an embedded actuarial engine, an MCP-over-AMQP ingress for external systems, and a Stellar commitment oracle that anchors the outputs.
RabbitMQ pipeline
Topic + direct exchanges, DLX on every in-queue, event-dedup at every consumer. Redeliveries and burst reruns never double-book a reserve.
Promislow semantics
Force of mortality, survival probabilities, prospective reserves, equivalence-principle pricing — implemented as streaming consumers, not batch jobs.
AMCP ingress
JSON-RPC report envelopes on actuary.amcp, REST twin on /api/amcp. Reinsurers, cat models and the chain itself are just publishers.
Stellar oracle
Merkle roots on Soroban, selective-reveal proofs, watcher reconciliation with on-chain integrity reports and admin-gated halts.
Watch a policy event earn its reserve.
Press run. A single event walks the real topology — producers, the enricher, the actuarial consumers, the AMCP wire, the Stellar anchor — and each hop lights up as its consumer would see it.
Producers
emitEvent envelopes are JSON-RPC-shaped: id, event_type, timestamp, source, payload. Sixteen event types mirror the actuarial lifecycle from policy.created to analysis.completed. Every event gets an id at birth so dedup is exact — RabbitMQ redeliveries never double-book.
topology mirrors the live RabbitMQ declarations: actuary.events topic, direct in-queues with DLX, actuary.amcp topic, amcp.events fanout.
MCP over AMQP. The wire contract other systems actually speak.
Actuarial Model Context Protocol: JSON-RPC envelopes on RabbitMQ topic exchanges. External systems — reinsurers, cat modelers, regulators, the Stellar chain itself — publish reports with no integration committee. HTTP twin included for systems that won't touch a broker.
{
"jsonrpc": "2.0",
"method": "report.submit",
"params": {
"report_type": "reserve_assessment",
"source_system": "bermuda.reinsurance",
"payload": { …capital adequacy data… }
},
"id": "req-2026-10-29-001"
}| type | source | carries |
|---|---|---|
| reserve_assessment | bermuda.reinsurance | capital adequacy |
| claim_outcome | claims.network | final settlements |
| catastrophe_model | cat.modeling | hurricane / quake |
| mortality_experience | mortality.lab | actual vs expected |
| risk_transfer | ceding.co | transfer pricing |
| stellar_anchor | horizon.stellar.org | on-chain events |
| solvency_report | regulator | solvency capital |
Every number the engine produces can be pinned to a ledger anyone can check.
Reserves, custody verdicts, balance snapshots — all of it ends up as a SHA-256 Merkle root committed on Stellar (Soroban). The reserve verification industry standard is still a periodic third-party PDF; here it is a continuous, on-chain, selective-reveal proof.
commit_root
Any bundle — a reserve vector, a custody chain, a balance snapshot — splits into N chunks, each hashed to a leaf, paired up to a single SHA-256 root. The root lands on Soroban: 32 bytes on-chain with provenance.
leaf = sha256("leaf:" ‖ chunk)
node = sha256("node:" ‖ L ‖ R)
commit_root(subject, root, provenance)selective reveal
A proof for chunk i is just the sibling path — a verifier recomputes the root locally and compares against the on-chain commitment, without ever seeing the other chunks. Data stays private; the math stays checkable.
verify(leaf_i, proof_i) == on_chain_root ?custody fanout
Granted’s verify+compress gates publish request.custody_anchor on the amcp.events fanout. This consumer commits the custody vector as a Merkle root and fires report.custody_anchored back — idempotent on {organ, head}.
amcp.events (fanout) → commit_vector → actuary.amcpwatcher reconciliation
Every 300s: live SAC balance vs last anchored snapshot. Severity 0 drift is recorded and non-halting. Severity 1 files report_integrity on-chain with the evidence hash and publishes halt until an admin clears. Clean state becomes the new baseline.
drift > tolerance ? report_integrity + halt : re-anchorThe partner view: real-world asset yield with a risk engine behind it.
The RWA dashboard is the default tab for staking partners: TVL, projected annual yield, per-asset yield generation and live staking positions. Three tiers, each with its allocation priced by the equivalence principle — not vibes. Pick one.
Treasury-debt tokens with continuous reserve verification. Duration-matched, no cat exposure.
- USDC Stablecoins
- EURC Stablecoins
- BENJI US Treasury Debt
- USDY US Treasury Debt
- USYC US Treasury Debt
- RZUT US Treasury Debt
- wGOLD Commodities
imported via rwa_toolkit — keyless read-only Soroban RPC over the testnet registry
settlement on the rail — Stellar finality, not a batch window
RWA provider poll cycle — reserve backing stays current
tracked register entries — every one reserve-verified, watchered
A flagged claim doesn't open a ticket. It stops the money.
Most fraud pipelines produce a report someone reads next quarter. Here the flag is a control-plane event with actuarial teeth: it freezes a reserve and reprices a premium until investigators close the case. Four steps, all on the wire, all idempotent.
claim.flagged hits the wire
An adjuster, the LLM analysis window, or a soft-risk scan flags the claim. The event carries the claim id, policy id and a reason code — and the loop takes over from there. No committee, no ticket queue.
the reserve freezes
Reserves consumer intercepts the release: the flagged claim’s reserve is HELD instead of flowing toward payment. The money does not move. This is the detection interrupting the task, not a dashboard badge.
the premium is loaded
Pricing re-runs the equivalence principle with a fraud load on that policy. The insurer now literally prices the fraud it carries — the cost of suspicion lands on the book that raised it, in real time.
claim.cleared is the only exit
The SIU registry owns the lifecycle. Until the investigation closes with claim.cleared, the hold and the load persist. When it clears, reserves release and pricing re-runs clean. Idempotent on event id throughout.
# 1 — flag lands on the topic
actuary.events ◀── {"event_type": "claim.flagged", "payload": {"claim_id": "C-8841", "policy_id": "P-2209"}}
# 2 — reserves consumer: hold, not release
dispatch("claim.flagged") → reserve → HELD # payment blocked until exit
# 3 — pricing consumer: equivalence principle with fraud load
Premium × ä = Benefit × A + fraud_load(policy) # re-marked on the wire
# 4 — the only exit
claim.cleared → reserve releases → pricing re-runs cleanThe reserve that watches itself.
Actuarial math as a streaming system: events in, reserves and premiums re-marked continuously, fraud flagged with teeth, and every material output committed as a Merkle root on Stellar. Verification isn't a report you request — it's a property of the rail.
deepgalaxy.ai makes the security case for the chain. This is the system that does the verifying — and it runs today.