Messages
messages
Section titled “messages”import "github.com/eljojo/nara/messages"Package messages contains all Nara message payload types.
This is the single source of truth for all message payloads exchanged in the Nara network. Every message kind has its payload defined here.
Structure
Section titled “Structure”Each file contains related payload types:
- stash.go: Distributed encrypted storage
- social.go: Social interactions (teases, trends)
- presence.go: Identity announcements, heartbeats
- checkpoint.go: Consensus checkpoints
- observation.go: Network state observations
- gossip.go: Peer-to-peer gossip bundles
Adding New Messages
Section titled “Adding New Messages”When adding a new message type:
-
Add the payload struct with godoc comments: - What the message does - Flow: who sends to whom - Response: what message comes back (if any) - Transport: MQTT, Mesh, or Local
-
Add a Validate() method for payload validation
-
Use ID fields as primary identifiers, names for display only
-
Document version history in comments
Example
Section titled “Example”// ExamplePayload demonstrates the pattern.//// Kind: example:request// Flow: Alice → Bob// Response: ExampleResponse// Transport: MeshOnly//// Version History:// v1 (2024-01): Initial versiontype ExamplePayload struct { ActorID NaraID `json:"actor_id"` // Primary identifier Actor NaraName `json:"actor,omitempty"` // Display name only Data []byte `json:"data"`}
func (p *ExamplePayload) Validate() error { if p.ActorID == "" { return errors.New("actor_id required") } return nil}- type StashRefreshPayload
- type StashRequestPayload
- type StashResponsePayload
- type StashStoreAck
- type StashStorePayload
type StashRefreshPayload
Section titled “type StashRefreshPayload”StashRefreshPayload triggers stash recovery from confidants.
Kind: stash-refresh Flow: Broadcast via MQTT plaza Transport: MQTT (ephemeral, not stored)
This is sent when a nara starts up and wants to recover its stash from confidants. Confidants who have a stash for this owner will respond via mesh with stash:response.
Version History:
v1 (2026-01): Initial versiontype StashRefreshPayload struct { // OwnerID is who wants their stash back OwnerID types.NaraID `json:"owner_id"`
// Owner is the display name (optional) Owner types.NaraName `json:"owner,omitempty"`}func (*StashRefreshPayload) Validate
Section titled “func (*StashRefreshPayload) Validate”func (p *StashRefreshPayload) Validate() errorValidate checks if the payload is well-formed.
type StashRequestPayload
Section titled “type StashRequestPayload”StashRequestPayload requests stored data from a confidant.
Kind: stash:request Flow: Owner → Confidant Response: StashResponsePayload Transport: MeshOnly
Version History:
v1 (2026-01): Initial versiontype StashRequestPayload struct { // OwnerID is who is requesting their stash back OwnerID types.NaraID `json:"owner_id"`
// RequestID for correlation (optional, for tracking) RequestID string `json:"request_id,omitempty"`}func (*StashRequestPayload) Validate
Section titled “func (*StashRequestPayload) Validate”func (p *StashRequestPayload) Validate() errorValidate checks if the payload is well-formed.
type StashResponsePayload
Section titled “type StashResponsePayload”StashResponsePayload returns stored data to the owner.
Kind: stash:response Flow: Confidant → Owner (response to stash:request) Transport: MeshOnly
Version History:
v1 (2026-01): Initial versiontype StashResponsePayload struct { // OwnerID is who the stash belongs to OwnerID types.NaraID `json:"owner_id"`
// RequestID is echoed from the request (for correlation) RequestID string `json:"request_id,omitempty"`
// Found indicates if the confidant has a stash for this owner Found bool `json:"found"`
// Nonce for decryption (only if Found is true) Nonce []byte `json:"nonce,omitempty"`
// Ciphertext of the stored data (only if Found is true) Ciphertext []byte `json:"ciphertext,omitempty"`
// StoredAt is when the stash was originally stored (Unix timestamp) StoredAt int64 `json:"stored_at,omitempty"`}type StashStoreAck
Section titled “type StashStoreAck”StashStoreAck acknowledges successful storage of a stash.
Kind: stash:ack Flow: Confidant → Owner (response to stash:store) Transport: MeshOnly
Version History:
v1 (2026-01): Initial versiontype StashStoreAck struct { // OwnerID is echoed back for correlation OwnerID types.NaraID `json:"owner_id"`
// StoredAt is when the confidant stored the data (Unix timestamp) StoredAt int64 `json:"stored_at"`
// Success indicates if the storage was successful Success bool `json:"success"`
// Reason explains why storage failed (if Success is false) Reason string `json:"reason,omitempty"`}type StashStorePayload
Section titled “type StashStorePayload”StashStorePayload is sent when storing encrypted data with a confidant.
Kind: stash:store Flow: Owner → Confidant Response: StashStoreAck Transport: MeshOnly (direct HTTP)
Version History:
v1 (2026-01): Initial versiontype StashStorePayload struct { // OwnerID is who the stash belongs to (primary identifier for retrieval) OwnerID types.NaraID `json:"owner_id"`
// Owner is the display name (optional, for logging/debugging) Owner types.NaraName `json:"owner,omitempty"`
// Nonce for XChaCha20-Poly1305 decryption (24 bytes) Nonce []byte `json:"nonce"`
// Ciphertext is the encrypted stash data Ciphertext []byte `json:"ciphertext"`
// Timestamp when the stash was created (Unix timestamp) Timestamp int64 `json:"ts"`}func (*StashStorePayload) Validate
Section titled “func (*StashStorePayload) Validate”func (p *StashStorePayload) Validate() errorValidate checks if the payload is well-formed.
Generated by gomarkdoc