IT-RAT the stack/heraldyx Guides Live demo
alerts plane · v0.2.2

Heraldyx. Your agents run on your infrastructure. This is the part that writes to you.

Every other plane in the stack records what happened. None of them wakes anybody. Heraldyx reads the shared event log the others already write, decides which of those events a human should hear about tonight rather than tomorrow, and sends one mail. It comes from your own box, and it carries a link into your own console. It reads a file and sends mail: that narrowness is the design, because this is the one component of the box allowed to open a connection to anything outside it.

shippedv0.2.2, pinned in the deploy
coreGo 1.26 · one direct dependency
one way outreads the log, speaks SMTP, nothing else
limitsfloor · dedup 10 min · 20 an hour
leaves behinda hash-chained dispatch record
licenceApache-2.0
one burst, measured

A hundred and twenty events arrive. Twenty-one messages leave.

This is a simulation of a real run: scripts/burst-demo.sh in the repository feeds 120 events to the actual binary with the default limits and counts what comes out. Watch where the other hundred stop. An alerting system that forwards everything teaches its operator to filter the sender to trash, and then the one that mattered is in trash too.

under the hood

Four checks, in this order, and the order is the point.

The decision layer is a pure function over an event and a few counters. It performs no I/O at all, which is what makes the awkward cases (a burst, a restart, a clock that moved) testable without a mail server.

a severity this build knows? five levels, nothing else at or above the floor? high, by default said already, within 10 min? one condition, one mail 20 already sent this hour? 0 turns the ceiling off NOTIFY one mail, one record DIGEST not escalated and not silently dropped either DIGEST real signal, but not worth waking anyone DROP the event stays in the log. Only mail is spared SUPPRESSED one notice per window, never the events inside dedup runs BEFORE the ceiling, on purpose a condition that trips two hundred times must not eat an operator's whole hourly budget every limit is a limit on messages, never on evidence
what actually arrives

Four short paragraphs, and one link that is a view.

What happened with its numbers, what the box already did about it, what happens if nobody acts, and where to look. Nothing in it is text a model wrote.

A new message from your box prod-box · 02:14 · budget_exhausted Plain text, no images, no tracking pixel, and no button that acts. Open it to read the whole thing, headers included. open ↗
ops@meridian.io three messages from your own box

                
Every line above is built from an event's type and its numeric fields. Nothing in it is text a model wrote. In a real mail the three links point at your own console; here they open the live demo at the panel each one names, sign-in and all.

The link is a view, never an action

A link that acts is an unauthenticated capability held by anyone who sees or forwards the message. Mail gateways also prefetch links, which would fire the action before a human read the sentence next to it. You sign in at the console, and a destructive action asks for your passkey there.

Identifiers and numbers, never content

An event's data can hold anything a producer put there, and some producers sit next to prompts, model output and matched secrets. Mail leaves your perimeter through a server nobody here controls, so the renderer allows eleven named keys and then checks the shape of every value on top. A live secret is perfectly identifier-shaped, so the key list is what stands between it and your inbox.

Who is answerable comes from a passport

Not from the event, which carries the agent and who it acted for, and neither of those is the owner. No passport means no owner line rather than a guess: naming the wrong team at three in the morning is worse than naming nobody at all.

afterwards

Every message it sent, sealed, on a volume the planes cannot reach.

"We wrote to you at 03:14, and your mail server took it at 03:14:02" is a claim somebody eventually has to prove, in an argument they did not choose. So every message leaves one hash-chained record behind it, in the same envelope the rest of the stack speaks.

"Accepted", never "delivered"

What the process observes is a mail server taking the message. Whether it reached a mailbox, a spam folder, or a filter that drops it silently is not knowable from here, so the record does not say it.

A chain of one is not "verified"

The first record has no predecessor to hash, so editing it is undetectable. The tool says so instead of reporting a good chain. A check that cannot fail is worse than no check, because it is louder.

It reports, and never repairs

A tool that could mend the chain would be a tool that could forge it. It exits non-zero on a break, so a deployment check can use it directly.

heraldyx --journalthe image is distroless: there is no shell in it to read the file with
what it does not do

The boundaries, stated rather than discovered at three in the morning.

It does not queue

A message that cannot be delivered is logged, written into the dispatch record as a refusal, and dropped. A retry queue inside the one process allowed out would be the opposite of the design, and the event itself is still in the log, which outlives this process.

It does not talk to any plane

No API, no credential, no client. It holds nothing that could act on an agent. If a fact is not in the event log, heraldyx does not know it.

It does not report anything about a whole organisation

The shared envelope requires an agent id, so a fact about an org has no subject to travel under, and no producer is allowed to invent one to make it fit. Those facts live in the console and in each plane's own API. A mail whose subject line named an agent that had not done the thing would be worse than silence.

It does not carry history

A first run starts at the end of the log. A month of old incidents arriving at once is how an operator learns to filter this sender to trash.