Types
All of these are exported from cynapse as types (import type { Channel, Entry } from 'cynapse') and
are what Store methods accept and return. Timestamps are ISO 8601 strings.
Participant
Section titled “Participant”Anything that reads or writes: an agent, a person, a service. See Participants.
type ParticipantKind = 'agent' | 'human' | 'service'
type ParticipantStatus = 'live' | 'retired'
interface Participant { id: string // UUIDv5 of `key` when registered kind: ParticipantKind name: string // not unique; resolveAddress matches it among live participants status: ParticipantStatus // asserted by the registering runtime, never measured key?: string // the registration key, such as cyberlegion:role/reviewer registeredBy?: string // the service participant that registered it; itself, for a unit}A participant from before the registry has no key, no registeredBy and no address channel. It is
live, and still resolves by name.
Channel
Section titled “Channel”A named, ordered log of entries. See Channels.
interface Channel { id: string // UUID: v7 when minted, v5 when derived from an anchor or key handle: string // the current human-readable name aliases: string[] // handles it used to have; they still resolve type: string // namespaced, defined by the consumer, e.g. 'sdd.mission' title: string purpose?: string parent?: Anchor // set on a child channel members: Member[] context: string[] // reference shorthands, e.g. 'gh:cyberuni/cynapse#12' traits: ChannelTraits state: string // the lifecycle state: 'active', 'paused', 'reconciled', ... pinned: number[] // seqs of the pinned entries conventions: string[] // names of the conventions that apply, plugin-prefixed stats: ChannelStats createdAt: string}ChannelTraits
Section titled “ChannelTraits”Behaviour switches stored on the channel. See Types, tags and traits.
interface ChannelTraits { membership: 'open' | 'fixed' retention?: string wake: boolean // advice to the runtime; cynapse never wakes anyone defaultView?: string}A new channel gets { membership: 'open', wake: false } unless createChannel says otherwise.
Member
Section titled “Member”interface Member { participant: string role: string cursor: number // the last seq this member has read; 0 when nothing}Anchor
Section titled “Anchor”The entry in a parent channel that a child channel branches from.
interface Anchor { channelId: string entryId: string seq: number}ChannelStats
Section titled “ChannelStats”interface ChannelStats { entries: number lastSeq: number lastAt?: string unread?: number // present only when read on behalf of a participant}ChannelTree
Section titled “ChannelTree”interface ChannelTree { channel: Channel children: ChannelTree[]}An immutable record in a channel. See Entries.
interface Entry { id: string // UUIDv7 minted by the writer; also the idempotency key channelId: string channel: string // the channel's current handle: `${channel}#${seq}` is the short reference seq: number // arrival order within the channel author: string type: string tags: string[] // the current set: write-time tags adjusted by cynapse.label entries parent?: string parentSeq?: number root?: string rootSeq?: number refs: string[] body: string // Markdown; '' when empty or read metadata-only data?: Record<string, unknown> // typed payload; absent when read metadata-only createdAt: string // when the writer minted it, from the UUIDv7 recordedAt: string // when it arrived in the channel}StateRecord
Section titled “StateRecord”What is true on a channel right now: a pending answer, a needs-input, a lease. See State and lifecycle.
type StateStatus = 'open' | 'resolved'
interface StateRecord { channelId: string key: string // unique within the channel kind: string status: StateStatus subject?: string // the participant it waits on or is held by entryId?: string value?: unknown seq: number // the entry that logged the latest transition updatedAt: string}View and ViewFilter
Section titled “View and ViewFilter”A saved filter over a channel’s entries. See Views.
interface ViewFilter { types?: string[] // exact types, or a prefix ending in '.*' ('sdd.*') excludeTypes?: string[] tags?: string[] // an entry matches when it carries any of these excludeTags?: string[] // excluded when it carries any of these now authors?: string[] excludeAuthors?: string[]}
interface View { channelId: string name: string filter: ViewFilter}Briefing
Section titled “Briefing”The result of brief: everything needed to start work on a channel in
one call.
interface Briefing { channel: Channel states: StateRecord[] // open state records only pinned: Entry[] views: View[] children: Pick<Channel, 'id' | 'handle' | 'type' | 'title' | 'state'>[]}Changes
Section titled “Changes”What changes returns. Pass token to the next call.
interface Changes { token: string // opaque, local to one store; not an order of entries channels: ChannelChange[] // ordered by handle}
interface ChannelChange { channelId: string handle: string lastSeq: number}UnreadCount
Section titled “UnreadCount”interface UnreadCount { channelId: string handle: string count: number}Inputs and queries
Section titled “Inputs and queries”CreateChannelInput, AppendInput, EntryMatch, ConditionalAppend, SetStateInput,
ListChannelsQuery, EntryQuery, SearchQuery and StateQuery are documented with the methods that take them on the Store
page.