Everything on this platform is built on one record shape. Detection reads it, response writes it, the auditor re-checks it a year later. This page follows a single event from the machine it happened on to the rule it eventually changed, and shows what it costs at every step.
Plain language drops the record and keeps the story.
Stop 1 · 11:02:14.318 UTC
It happens on a machine
A web server runs a shell. The kernel writes an audit record about it, in the format the kernel happens to use, with the arguments hex-encoded. Nothing about that record is designed to be read by a machine that also has to read a cloud audit log, a firewall syslog line and a SaaS webhook.
The agent's job is not to interpret this. It is to carry it, intact, to the one boundary where every source becomes the same shape.
Stop 2 · at the door
It becomes one shape
Twenty fields, one envelope, one schema version. A process execution, a failed login and a blocked connection all arrive as the same twenty fields, which is the only reason one detection engine can read all three. The taxonomy is four parts — domain, category, type, activity — and it is the routing and correlation key, not a display label.
subject
who or what acted
object
what it acted on
outcome
success, failure, blocked, unknown
severity
five normalised levels
Severity is stored as a number and written out as a word, and it reads both back, because a record that cannot survive a round trip through JSON cannot have its seal verified later. That is a small decision with a long shadow.
Stop 3 · naming
It gets a name it cannot lose
The identifier is derived from the content, so the same content decoded again produces the same identifier. That sounds academic until an agent's uplink drops. It spools telemetry, reconnects, and replays the backlog — the same frame legitimately arrives twice. With a random identifier, every duplicate becomes a distinct event and the outage is paid for in noise. Derived from content, the second delivery carries the identifier it carried the first time.
Kept
A 48-bit millisecond prefix taken from the event's own time, not the wall clock — so identifiers sort by when things happened, and the storage layer can cursor through them.
Declared
Version 8, the layout reserved for hash-derived identifiers. A reader can tell a content-derived name from a random one by looking at it.
The reason it matters this much: detections cite events by identifier, and other events point at their causes by identifier. An empty name is not a harmless blank. It is a pointer that looks like a pointer and resolves to nothing.
Stop 4 · ordering
Two clocks, both kept
When the thing happened and when the platform first saw it are different facts, and machines disagree about the first one. Both are recorded and neither is quietly corrected into the other. A logical clock and a sequence number sit alongside them so that events from hosts whose clocks drift can still be put in a defensible order.
time 2026-08-27T11:02:14.318Z
ingest_time 2026-08-27T11:02:14.906Z +588ms
That 588 milliseconds is not an error to be smoothed away. It is the transit, and an investigation is allowed to ask about it.
Stop 5 · the seal
It is signed, and it points backwards
The record is rendered to canonical bytes, hashed together with the previous event's hash, and that digest is signed. The signature makes a changed byte detectable. The backward pointer makes an insertion, a deletion or a reorder detectable too — the interesting attack on a log is rarely editing one line, it is removing one.
The digest binds
alg → which algorithm signed prev → the previous digest bytes → the canonical record
Deliberately outside it
The signature itself. Because it is not part of any digest, the chain never has to wait for the signer.
Measured, per event
20.2 µs
canonical render
6.1 µs
hash
37.2 µs
signature
~6 µs
contended section
Only the hash and the pointer swap are serialised. That is what lets one tenant's ingestion scale with cores instead of with one signing key.
If the signer fails, the event keeps its place in the chain and carries no signature. Every verifier then fails it closed and it is flagged unverified rather than dropped — because dropping it would leave a link that the next event still points at, and a silent gap is worse than a visible one.
Stop 6 · storage
It is stored once, and handed out as copies
One store, not one per product. Every capability queries it and none keeps a private copy, which is what makes the same record answer a detection question and an audit question. Reads hand back an independent copy, so no caller can reach through a returned pointer and mutate a sealed record. The original source line stays retrievable by reference, so an argument about interpretation can always be settled against what actually arrived.
Stop 7 · connection
It points at what led to it
Entities are nodes; events are the edges between them. Because each event names its causes, the store is already a graph — nothing has to be assembled into one later. An alert is therefore a piece of that graph rather than a row in a table: a path you can walk, with the events that produced it attached at every step.
http request
→
nginx
→
shell spawned
→
credential read
→
billing-db reached
Five events, one path. Each one is separately sealed and separately citable.
Stop 8 · the decision
Something is done about it
A world-changing action does not follow directly from a detection. It passes one approval gate, which can allow it, hold it for a person, or refuse it. The gate is told how far the action reaches before it decides, and its reason is recorded in the words it used, not summarised.
Allow
Narrow reach, reversible, inside policy.
Hold
A person decides. A hold that outlives its window is refused, not resurrected.
Refuse
Recorded as a refusal, with the reason. Silence never counts as approval.
From here it is the alert that travels; the original event stays where it was stored. An allowed containment goes to the Sensor on that host, canary first: the platform waits for that Sensor to report, and rolls the action back if it does not verify. Acting on the host is switched on per node. Where a node’s edge enforcement is not switched on, the gate still decides and records its reason, and the containment is a dry run that changes nothing. The containment itself then becomes an event, in the same twenty fields, sealed into the same chain. What the platform did to your estate is recorded on the same terms as what happened to it.
Stop 9 · the return path
The second machine does not wake anyone
What the analytics layer learned from this event is compiled into something the edge enforces by itself, and it goes out only when two things are true. The rule must already have earned trust from real outcomes, and the guardrails must allow the push outright. A push they hold or refuse publishes nothing. Each machine checks the signature before it applies the rule, then reports whether it did, so you can see where the rule is running.
This is the whole argument for one platform instead of four that share a login. The next machine to try the same thing is stopped where it stands, and nobody reads an alert about it at two in the morning.
Stop 10 · a year later
The same record answers the auditor
No export, no reconstruction, no second system of record. The event is re-read, its seal is re-verified, and if a link is broken the verification names which one. The answer to "how do you know" is the same object the detection used, which is the only version of that answer that survives being checked.
What this record does not prove
honest limits
Tampering before the seal is outside its reach
The seal proves the record has not changed since the platform sealed it. It says nothing about a source that lied before that boundary. That is addressed by attestation and source trust, and it is a different problem with different limits.
Duplicate delivery is detectable, not automatically removed
Content-derived identifiers make a replayed frame recognisable. Nothing silently discards a second copy at ingestion; de-duplication happens on the read path. Silently dropping records would be a decision we would have to make deliberately and tell you about.
A verifier that cannot check an algorithm flags it
Seals name the algorithm that signed them, so a store can hold more than one generation at once. A verifier that does not implement a newer algorithm marks those records unverified rather than vouching for them. Fail closed, then say so.
A graph edge is only as good as the field that made it
Causal pointers are recorded by the component that produced the event. Where a source cannot tell us what caused what, the path has a gap, and the interface shows a gap rather than inferring a plausible one.
Read the record against your own estate
Trial licences run 30 days from issue, on-premise or SaaS, licensed on daily ingest volume. One per legal entity.
Sensor — observed on web-07 · shipped unsealedIngest — one shape · an id derived from the contentSeal — Ed25519 at ingest · chained to the one beforeStore — stored once · every reader gets a copyDetect — a detection reads it · its alert is an eventGate — the alert meets one gate · allow, hold or refuse · reason keptCanary — sends it to the Sensor · waits for its report · rolls back if notSensor, again — applied and reported back · the loop closes
Sensor — observed on web-07 · shipped unsealedIngest — one shape · an id derived from the contentSeal — Ed25519 at ingest · chained to the one beforeStore — stored once · every reader gets a copyDetect — a detection reads it · its alert is an eventGate — the alert meets one gate · allow, hold or refuse · reason keptCanary — sends it to the Sensor · waits for its report · rolls back if notSensor, again — applied and reported back · the loop closes
One event’s journey, and the loop it closes.The Sensor on web-07 observes it; Ingest gives it one shape; it is sealed with Ed25519 at ingest and stored once; a detection reads it and raises an alert; the alert passes one gate and goes out canary-first to the Sensor on that host, which applies it and reports back.
Sensor — observed on web-07 · shipped unsealed
Ingest — one shape · an id derived from the content
Seal — Ed25519 at ingest · chained to the one before
Store — stored once · every reader gets a copy
Detect — a detection reads it · its alert is an event
Gate — the alert meets one gate · allow, hold or refuse · reason kept
Canary — sends it to the Sensor · waits for its report · rolls back if not
Sensor, again — applied and reported back · the loop closes
Any field, closer upid · derived identifierschema · envelope versiontime · when it happenedingest_time · when we first saw ithlc · logical clockseq · positionobserver · who reported itclass · the taxonomyseverity · five levelsoutcome · what resultedsubject · who or what actedobject · what was acted onsrc · source addressattributes · the specificsraw_ref · the original linecausal_parent · what led to thislabels · tenancy and scopeintegrity_seal · the proof
Twenty fields carry every event on the platform. Select one to read what it is for, and what keeping it honestly costs.Version 8 UUID whose first six bytes are the event's own millisecond timestamp and whose remainder is derived from the content. The same content decoded twice yields the same identifier, which is what makes a replayed frame recognisable.The canonical event schema this record conforms to. A reader that does not recognise the version refuses the record rather than guessing at its fields.Reported by the observer, from the machine where the event occurred. Never overwritten to agree with the ingestion clock.Set at the door. The difference between the two timestamps is the transit, and it is a fact an investigation is allowed to ask about.A hybrid logical clock reading, so events from hosts whose wall clocks disagree can still be placed in a defensible order.Monotonic position within the source's stream. A gap is visible.Which thing produced the record, in which form factor — agent, tap, agentless, gateway — and at which site. Provenance starts here.Four parts: domain, category, type, activity. This is the routing and correlation key, not a display label, which is why a process execution and a cloud API call can be read by the same engine.Stored as a number, written as a word, and parsed back from either — a record that cannot survive a JSON round trip cannot have its seal verified later.success, failure, blocked or unknown. Blocked is distinct from failure: it means something stopped it.A node in the graph: user, service, workload, device, process or file. The reference is the stable identity; the attributes are context.The other end of the edge. Together with the subject, this is what makes the store a graph without anything having to build one.Address, port, host, hardware address and geography where they are known. Absent fields are absent, not zero.Everything true of this event class and no other. Treated as immutable once recorded — a copy handed to a caller shares these values.A reference back to the source bytes as they arrived. An argument about interpretation can be settled against what was actually received.Identifiers of the events that caused this one. Where a source cannot tell us, the path has a visible gap rather than an inferred one.Tenant and compartment, carried on the record itself so isolation is a property of the data and not of the query that reads it.Algorithm, key identifier, signature, and the previous event's digest. The signature detects a changed byte; the backward pointer detects a removed one.
Values are a modelled scenario in the real record shape. Field names, types and the seal structure are the shipping contract.