Skip to content
Cockpit0.29.0
A snapshot: read at commit 707a04c7ce8 on 2026-10-18T00:06:01Z by majordomus 0.29.0. Nothing on this page is read again. See it live

mesh.events

The cooperation journal

What it is

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`.

Descriptor

Canonical id
mesh.events
Module
mesh
Kind
query
Stability
experimental
Provenance
declared
Source
apps/majordomus-cli/src/capability/builtin/mesh.rs
Cache
disabled
Benchmark
required
Tags
meshcoordinationcooperation

Run

query
A query. It reads and changes nothing.

Only events whose Lamport stamp is above this.

At most this many (default 100, at most 1000).

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.

GET /api/v1/mesh/events

Projections

InterfaceAsWhere
MCP toolmajordomus_mesh_events-
MCP resourcenot exposed-
HTTPGET /api/v1/mesh/eventsSwagger
Command linenot exposed-

Schemas

Input · MeshEventsInput
{
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "after": {
      "type": [
        "integer",
        "null"
      ],
      "format": "uint64",
      "minimum": 0,
      "description": "Only events whose Lamport stamp is above this."
    },
    "limit": {
      "type": [
        "integer",
        "null"
      ],
      "format": "uint64",
      "minimum": 0,
      "description": "At most this many (default 100, at most 1000)."
    },
    "newest": {
      "type": [
        "boolean",
        "null"
      ],
      "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."
    }
  },
  "description": "The input of `mesh.events`.",
  "title": "MeshEventsInput"
}
Output · EventList
{
  "type": "object",
  "properties": {
    "active": {
      "type": "boolean",
      "description": "Whether cooperation runs."
    },
    "count": {
      "type": "integer",
      "format": "uint",
      "minimum": 0,
      "description": "How many events this answer carries."
    },
    "lamport": {
      "type": "integer",
      "format": "uint64",
      "minimum": 0,
      "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)."
    },
    "events": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/MeshEvent"
      },
      "description": "The events, in Lamport order."
    }
  },
  "required": [
    "active",
    "count",
    "lamport",
    "events"
  ],
  "description": "The answer of `mesh.events`.",
  "title": "EventList",
  "$defs": {
    "MeshEvent": {
      "type": "object",
      "properties": {
        "v": {
          "type": "integer",
          "format": "uint32",
          "minimum": 0,
          "description": "The event format version."
        },
        "stream": {
          "$ref": "#/$defs/StreamId",
          "description": "The stream that wrote it."
        },
        "seq": {
          "type": "integer",
          "format": "uint64",
          "minimum": 0,
          "description": "Dense from 1 within the stream."
        },
        "lamport": {
          "type": "integer",
          "format": "uint64",
          "minimum": 0,
          "description": "The Lamport stamp: above every stamp its writer had seen."
        },
        "at": {
          "type": "integer",
          "format": "uint64",
          "minimum": 0,
          "description": "The writer's wall clock, seconds since the Unix epoch. Informational only: nothing\nis decided by comparing it with another machine's clock."
        },
        "repo": {
          "type": "string",
          "description": "The mesh repository id the event belongs to."
        },
        "pk": {
          "type": "string",
          "description": "The writer's Ed25519 public key, hex; its digest is the stream's node."
        },
        "body": {
          "description": "The body, `kind` tagged."
        },
        "sig": {
          "type": "string",
          "description": "Ed25519 over the canonical bytes of everything above, hex."
        }
      },
      "required": [
        "v",
        "stream",
        "seq",
        "lamport",
        "at",
        "repo",
        "pk",
        "body",
        "sig"
      ],
      "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```"
    },
    "StreamId": {
      "type": "string",
      "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```"
    }
  }
}

Examples

These are the capability's own benchmark cases: the same inputs the benchmark runs and the OpenAPI document shows.

default
{
  "limit": 100
}