mesh.events
The journal's events above a Lamport stamp, in Lamport order, at most a page: each with its stream, sequence, stamp, repository, signing key, kind and body. The answer's lamport is the next page's `after`.
The journal's events above a Lamport stamp, in Lamport order, at most a page: each with its stream, sequence, stamp, repository, signing key, kind and body. The answer's lamport is the next page's `after`.
- query
- experimental
- module mesh
- #mesh
- #coordination
- #cooperation
Exposure
Where this one definition is reachable. Absence is explicit: a surface not listed does not carry it.
| surface | as |
|---|---|
| MCP | tool majordomus_mesh_events |
| HTTP | GET /api/v1/mesh/events operationId mesh.events |
| command line | — |
Schemas
The canonical input and output, from the Rust types; the MCP tool schema and the OpenAPI parameters and responses are derived from these.
input · MeshEventsInput
mesh.events.| property | type | required | description |
|---|---|---|---|
| after | integer | null | no | Only events whose Lamport stamp is above this. |
| limit | integer | null | no | At most this many (default 100, at most 1000). |
| newest | boolean | null | no | The newest limit events above after instead of the first ones: what a reader who
wants the journal as it stands now asks for. Still in Lamport order, and lamport is
then the newest stamp the journal holds, so resuming after it reads only what comes
next. Without it the journal is read forward from after, a page at a time. |
JSON Schema
{
"additionalProperties": false,
"description": "The input of `mesh.events`.",
"properties": {
"after": {
"description": "Only events whose Lamport stamp is above this.",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"limit": {
"description": "At most this many (default 100, at most 1000).",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"newest": {
"description": "The newest `limit` events above `after` instead of the first ones: what a reader who\nwants the journal as it stands now asks for. Still in Lamport order, and `lamport` is\nthen the newest stamp the journal holds, so resuming after it reads only what comes\nnext. Without it the journal is read forward from `after`, a page at a time.",
"type": [
"boolean",
"null"
]
}
},
"title": "MeshEventsInput",
"type": "object"
}output · EventList
mesh.events.| property | type | required | description |
|---|---|---|---|
| active | boolean | yes | Whether cooperation runs. |
| count | integer | yes | How many events this answer carries. |
| events | array | yes | The events, in Lamport order. |
| lamport | integer | yes | The after of the next page: the stamp of the last event this page carries, or the
after that was asked when it carries none. A page never ends inside a run of equal
stamps, so resuming after it misses nothing (I2140). |
JSON Schema
{
"$defs": {
"MeshEvent": {
"description": "One event as the wire and the store carry it. The body is kept as JSON so that an\nevent of an unknown kind survives storage and relay byte-for-byte; `MeshEvent::body`\ninterprets it.\n\nEvery field above the signature is covered by it, which is what makes a relay harmless:\na runtime that forwards an event cannot alter its stream, its sequence, its repository\nor its body without the next reader noticing, and so vouches for nothing. The wall\nclock is the one field nothing is decided by — freshness is measured with beats and\nmonotonic clocks, never by comparing two machines' idea of the time.\n\n```\nuse std::sync::Arc;\nuse majordomus_cli::mesh::identity::NodeIdentity;\nuse majordomus_cli::mesh::journal::{EventBody, Journal, MeshEvent};\n\nlet j = Journal::open(Arc::new(NodeIdentity::ephemeral().unwrap()), \"0000000000000001\",\n \"repo\".into(), None).unwrap();\nj.append_own(EventBody::SessionClosed { session: \"s1\".into() }).unwrap();\n\nlet event: &MeshEvent = &j.events()[0];\nassert_eq!(event.seq, 1, \"dense from 1 within its stream\");\nassert_eq!(event.kind(), \"session_closed\");\nassert_eq!(event.id(), format!(\"{}/1\", event.stream));\n\n// a relayed byte changed anywhere under the signature is a different event\nlet mut tampered = event.clone();\ntampered.repo = \"another-repository\".into();\nassert_ne!(tampered.signing_bytes(), event.signing_bytes());\n```",
"properties": {
"at": {
"description": "The writer's wall clock, seconds since the Unix epoch. Informational only: nothing\nis decided by comparing it with another machine's clock.",
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"body": {
"description": "The body, `kind` tagged."
},
"lamport": {
"description": "The Lamport stamp: above every stamp its writer had seen.",
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"pk": {
"description": "The writer's Ed25519 public key, hex; its digest is the stream's node.",
"type": "string"
},
"repo": {
"description": "The mesh repository id the event belongs to.",
"type": "string"
},
"seq": {
"description": "Dense from 1 within the stream.",
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"sig": {
"description": "Ed25519 over the canonical bytes of everything above, hex.",
"type": "string"
},
"stream": {
"$ref": "#/$defs/StreamId",
"description": "The stream that wrote it."
},
"v": {
"description": "The event format version.",
"format": "uint32",
"minimum": 0,
"type": "integer"
}
},
"required": [
"v",
"stream",
"seq",
"lamport",
"at",
"repo",
"pk",
"body",
"sig"
],
"type": "object"
},
"StreamId": {
"description": "One stream: a run of one runtime of one node. `<node 32 hex>-<runtime 16 hex>-<instance\n16 hex>`. The node is the machine's key, the runtime is one checkout's server on that\nmachine, the instance is one process run of that server — so two worktrees on one\nmachine are two streams, and a restart is a new stream of the same runtime.\n\nNumbering events within a stream rather than globally is what makes replication cheap\nand unambiguous: a gap in one stream is visible without coordinating with anyone, and\n`(stream, seq)` identifies an event on every machine that holds it.\n\n```\nuse majordomus_cli::mesh::journal::StreamId;\n\nlet id = StreamId::new(&\"a\".repeat(32), &\"b\".repeat(16), &\"c\".repeat(16)).unwrap();\nassert_eq!(id.node(), \"a\".repeat(32));\nassert_eq!(id.runtime(), \"b\".repeat(16));\n\n// a restart is a new stream, and the same runtime\nlet after = StreamId::new(&\"a\".repeat(32), &\"b\".repeat(16), &\"d\".repeat(16)).unwrap();\nassert_ne!(after, id);\nassert_eq!(after.runtime_key(), id.runtime_key());\n```",
"type": "string"
}
},
"description": "The answer of `mesh.events`.",
"properties": {
"active": {
"description": "Whether cooperation runs.",
"type": "boolean"
},
"count": {
"description": "How many events this answer carries.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"events": {
"description": "The events, in Lamport order.",
"items": {
"$ref": "#/$defs/MeshEvent"
},
"type": "array"
},
"lamport": {
"description": "The `after` of the next page: the stamp of the last event this page carries, or the\n`after` that was asked when it carries none. A page never ends inside a run of equal\nstamps, so resuming after it misses nothing (I2140).",
"format": "uint64",
"minimum": 0,
"type": "integer"
}
},
"required": [
"active",
"count",
"lamport",
"events"
],
"title": "EventList",
"type": "object"
}Policies
- benchmark
- required — a target on every transport the exposure declares; the cases are the input type's
- cache
- disabled — every call runs the handler
Benchmark targets
Derived from the registry for this repository: one requirement per transport, and the cases the input type provides. The whole matrix is on the benchmarks page.