EVENT SCHEMA
The complete event contract.
Every field. Every type. The exact rules for canonical serialization and event_hash computation. This is the contract every SDK and integrator implements against.
DEFINITION
An event is the unit of governed agent behavior. It is a JSON object. It is canonicalized. It is SHA-256 hashed. It is chained to the previous event for the same agent.
WHY THE SCHEMA IS FIXED
What goes wrong without a contract.
01
Hashes drift.
If the schema is loose, two SDKs serialize the same event differently. Their hashes do not match. The chain becomes unverifiable across clients.
02
Auditors cannot reproduce.
An auditor must be able to recompute the event_hash from the raw event. That requires a deterministic encoding rule. Without one, the chain is not evidence.
03
Federation breaks.
When agents from different organizations federate, they must produce identical hashes for identical events. A fixed schema is the prerequisite for cross-org governance.
HOW IT WORKS · TECHNICAL
Canonical JSON, then SHA-256.
01 SERIALIZE
Canonical JSON
Keys are sorted lexicographically. Strings are UTF-8. Numbers use the shortest unique representation. Insignificant whitespace is removed. There is exactly one canonical encoding for any given event.
02 EXCLUDE
Remove event_hash before hashing
The event_hash field is excluded from the canonical JSON before hashing. This is the only field omitted. previous_event_hash is included. chain_index is included. The exclusion is deterministic.
03 HASH
SHA-256 hex
Compute SHA-256 over the UTF-8 bytes of the canonical JSON. Encode as lowercase hex. The result is the event_hash. Write it back into the event object before persisting or transmitting.
04 CHAIN
Bind to the prior event
Set previous_event_hash to the event_hash of the prior event for this agent. For the genesis event of an agent, previous_event_hash is the empty string. The chain extends one event at a time.
HOW IT WORKS · PLAIN ENGLISH
One event. One hash. One link to the past.
Every action your agent takes becomes a small JSON document. RANKIGI puts the keys in a fixed order, runs a fingerprint over the result, and writes that fingerprint into the document. The next event carries the previous fingerprint forward. That is how the chain forms. If anyone tries to change a past event, its fingerprint changes, and every event after it stops matching. The break is detectable in milliseconds.
ANATOMY
Every field in the event.
| Field | Type | Description |
|---|---|---|
| event_id | uuid | Globally unique identifier. Generated client-side or assigned by RANKIGI on receipt. |
| agent_id | string | The passport ID of the agent producing the event. Format RNK-ORG-XXXXXX. |
| org_id | uuid | Organization the agent belongs to. Used for row-level security scoping. |
| action_type | enum | Discrete category of action. See enum table below. |
| timestamp | iso-8601 | Time the action occurred on the agent. RFC 3339 with timezone. |
| received_at | iso-8601 | Time RANKIGI received the event. Server-assigned. |
| input_hash | sha256 hex | Hash of the canonical input payload. Raw input is never stored. |
| output_hash | sha256 hex | Hash of the canonical output payload. Raw output is never stored. |
| tool_name | string? | Name of the tool invoked. Required for tool_call and tool_result. |
| intent_ciphertext | string? | AES-256-GCM encrypted intent payload. Used for intent_declared events. |
| previous_event_hash | sha256 hex | The event_hash of the previous event for this agent. Empty string for the genesis event. |
| chain_index | int | Zero-indexed position in the agent's chain. Strictly monotonic. |
| metadata | object? | Optional structured metadata. Keys must be deterministic for canonical serialization. |
| event_hash | sha256 hex | SHA-256 of the canonical JSON of the event with this field excluded. Computed by client or server. |
EXAMPLE
A real tool_call event.
{
"event_id": "5e3f8a12-4c0e-4b9c-9f1a-bf3a4e7d8c91",
"agent_id": "RNK-ACME-MN766QRS",
"org_id": "9b2e4d11-7c0a-4d3e-91b8-7e2c4a1f9b80",
"action_type": "tool_call",
"timestamp": "2026-04-27T14:32:18.514Z",
"received_at": "2026-04-27T14:32:18.602Z",
"input_hash": "9c3b4f2a8d7e1c5b6a09f8e7d6c5b4a39281706f5e4d3c2b1a09f8e7d6c5b4a3",
"output_hash": "",
"tool_name": "stripe.charges.create",
"intent_ciphertext": null,
"previous_event_hash": "2e7dc4b95a8f1e3d6c2b9a08f7e6d5c4b3a29180717263544352617281930405",
"chain_index": 4821,
"metadata": { "trace_id": "trc_01J9X8Y" },
"event_hash": "a3f8b2c19d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f01"
}ENUM · action_type
The discrete categories of agent action.
| action_type | Description |
|---|---|
| tool_call | Agent invoked an external tool or function. Records the tool name and the input hash. |
| tool_result | Tool returned a result. Records the output hash and the tool name. |
| message_in | Inbound message from a user or another system to the agent. |
| message_out | Outbound message from the agent to a user or downstream system. |
| intent_declared | Agent declared its intent before acting. Encrypted with AES-256-GCM. Used for intent chains. |
| federation_propose | Agent proposed an action to a federation of validator agents. |
| federation_vote | Validator agent recorded its vote on a federation proposal. |
| federation_consensus | Final consensus event. Records the quorum and the consensus hash. |
| agent_offline_start | Agent went offline or stopped emitting. Marks a known gap in the chain. |
| agent_offline_end | Agent resumed emission. Marks the close of the gap. |
| policy_violation | A policy enforcement check failed. Records the policy ID and the violation hash. |
| kill_switch | Operator-initiated halt. Records the operator and the reason hash. |
WHO IT IS FOR
Three audiences. One contract.
SDK AUTHOR
You are implementing canonical JSON, the hash routine, and the chain semantics in your language. The schema on this page is the contract. The example is the conformance test.
INTEGRATOR
You are wiring an existing agent into RANKIGI. You map your agent's actions to action_type values, compute the hashes, and POST the events. This page is the field reference.
AUDITOR
You are independently verifying a chain. You receive an evidence bundle, recompute event_hash for every event, and check the previous_event_hash links. This page is your serialization spec.
QUESTIONS AND ANSWERS
What integrators ask first.
Why exclude event_hash from the canonical JSON before hashing?
Including a field in its own hash would create a circular dependency. Standard practice is to compute the hash over everything else and write it in afterward. previous_event_hash is included because it is fixed before this event is hashed.
What is the canonical encoding rule for numbers?
Numbers use the shortest decimal representation that round-trips to the same IEEE-754 value. No trailing zeros. No exponent for integers. The reference implementation in the Node SDK is the conformance source.
Are tool inputs and outputs ever stored in raw form?
No. RANKIGI stores hashes, not raw payloads. If you need to retain raw payloads for replay, you store them in your own systems and reference them by hash from the event metadata.
How are gaps in the chain represented?
Use agent_offline_start to mark the beginning of a known gap and agent_offline_end to close it. Both are real events with hashes. The chain is continuous. The gap is documented inside the chain, not by skipping events.
Can I add custom fields?
Yes, inside metadata. Top-level fields are fixed by the schema. The metadata object is free-form, but its keys must be deterministically ordered for canonicalization. Stick to JSON-compatible types.
Ed25519, SHA-256, AES-256-GCM, and post-quantum readiness.
SDKs in Node and Python. First event into the chain in ten minutes.