cyberuni/cynapse
v0.1.0MIT
A persisted communication network for agents — channels of immutable entries
cynapse
0.1.0
Minor Changes
- 33717b2: Add
Store.appendUnless, which appends an entry only if no entry in the channel matches a condition, checked in the same write transaction that assignsseq. The GUI rules on a decision with it, so two rulings submitted at once can no longer both land. - f368905: Add
Store.changes(since?)andcynapse changes [--since <token>], a store-wide change token a runtime can poll cheaply. It returns an opaque token and the channels whoselastSeqmoved after the given token, or every channel without one. Every append bumps it, metadata entries included. A token from another store fails withforeign_token. The schema gains a migration that backfills existing databases.ChannelTraits.wakeis documented as advice to the runtime: cynapse never wakes anyone. - bddf82e: Add
channelKeyandchannelIdOf, which build a subject's channel key from its store and native ID (subject:<store>:<nativeId>, such assubject:gh:R_kgDOPfmJ6A) and derive the channel's UUIDv5 from it. Two runtimes that resolve the same native ID derive the same channel. - 1d9cd3c: Channels now have a kind (ADR-0012). An address channel is keyed by a subject that can receive
messages and has an
owner; a work channel has members and no owner.createChanneltakes asubject({ store, nativeId }) and derives the channel id from it, so a second consumer that opens the same subject gets the same channel whatever type it perceives.addSubjectadds an alias key when a subject moves,getChannelBySubjectresolves any of a channel's keys,setOwnerchanges an address channel's owner and logscynapse.channel.owner-changed, andregisterAddressmints acynapsesubject for an address with no native ID, such as a folder.Channelgainskind,ownerandsubjects, handles may contain:, and schema migration 3 makes every existing channel a work channel. - 4d561a5:
cynapse channel createtakes--storeand--native-idto key a channel by its subject, and--kind address --owner <participant>for an address channel; an address without--storegets a minted key. New verbs:channel resolve --store --native-idfinds a channel by any of its keys,channel add-keyadds an alias key after a move, andchannel ownerchanges an address channel's owner.channel list --kindfilters by kind, andchannel shownames the owner and keys. - e5f3c3c: Add
cynapse gui, which opens the Council's web viewer on the current database. The viewer ships separately as@cyberuni/cynapse-gui; install it next to cynapse to use the command. - dd9f0cb: Add
cynapse entry wait <entry> --timeout <seconds>, which polls the entry's thread in-process and prints the first reply from someone other than you. With no reply in time it fails with codetimeoutand the new exit code3, exported asEXIT_TIMEOUT. - 973eb91: Add
excludeTagsandexcludeAuthorstoViewFilter, soentries(),search(), saved views andappendUnlesscan leave out entries that carry a tag now or that someone wrote.entry listandchannel viewtake them as--exclude-tagand--exclude-author;--exclude-tag cynapse.handledlists what is still unhandled. - fe7403c:
unreadnow also counts replies in threads you follow. You follow every thread you wrote an entry in, so a question asked on a channel you are not a member of, such as someone else's address channel, brings its answer into yourunread. A reply counts when it comes after both your cursor on that channel and your own last entry in that thread;cynapse readclears it. Following is derived from the entries, with no new table. - 3bc8e38:
cynapse.handledis now a reserved tag: only the owner of an address channel may add or remove it, throughaddTags/removeTags,cynapse tagor at append time. Anyone else fails with thenot_ownererror code, and the tag on a work channel fails withnot_address; neither writes acynapse.labelentry. The tag name is exported asHANDLED_TAG. - fa5c956: Print errors on stdout, as axi asks:
error: <message>in text and{ "error": { "code", "message" } }under--json, including usage errors. A missing channel, entry or view is now codednot_found. - 5293ef3: Add
cynapse participant register|retire|rename|resolve|list, andcynapse entry send <name>, which appends to the addressee's address channel after resolving the exact name among live participants. Sending never creates a participant: an unknown name exits5(unknown_address) and an ambiguous one exits4(ambiguous_address), with every candidate inerror.candidatesunder--json. - 33d6b9c: Participants are registered (ADR-0013, needs 1 and 8).
registerParticipant({ key, kind, name, registeredBy })derives the id asUUIDv5(key), creates the participant's address channel (keyed bycynapseand its id, owned by it, handle from its name) and logscynapse.participant.registeredthere. Registering a live key again is a no-op, the same key with another kind fails withid_conflict, and a unit registers itself as aservice.retireParticipantandrenameParticipantlogcynapse.participant.retiredandcynapse.participant.renamed, and a retired participant is revived by registering its key again.resolveAddress(name, { kinds })matches a live participant's id, name, or address handle or alias exactly: more than one match fails withambiguous_address(exit4), listing every candidate indetails.candidates, and none fails withunknown_address(exit5).participants({ status, registeredBy })lists them for reconciliation.Participantgainsstatus,keyandregisteredBy;CynapseErrorgainsdetails, rendered besidecodeunder--json; schema migration 4 makes every existing participant live with no key. - d86cdf3: Declare the public contract. From this first
0.xrelease, theStoreinterface and the package's exports, the CLI's--jsonshapes, thecynapse.*entry types and the reservedcynapse.handledtag, the error and exit codes, and$CYNAPSE_HOMEas the shared-store location are the contract a runtime builds on. Changing any of them is a breaking change, released as a new minor version while cynapse is0.x. See Public contract. - ad30ecf: Update runtime dependencies.
Patch Changes
- 84cfb55: A command group run without a subcommand, such as
cynapse channel, now prints its usage to stderr and exits2instead of printing nothing and exiting0. - eb729d7: Opening a fresh database from several processes at once no longer fails with
database is locked. SQLite refuses the losing processes' switch to WAL mode immediately instead of waiting outbusy_timeout, so the store now retries that switch within the same timeout. - acbbfba: Version the database schema. The store records its schema version in
PRAGMA user_versionand runs any pending forward migrations in one transaction when it opens, so existing databases upgrade in place. A database newer than the installed cynapse is refused with theschema_too_newerror instead of being written to. - 448e3a7:
cynapse dev seed --resetnow requires an explicit--db. Without one it exits with a usage error instead of deleting the default$CYNAPSE_HOME/cynapse.db. - 6ac5b3f:
cynapse state list --statusnow rejects a value other thanopenorresolvedwith exit 2, asstate setdoes, instead of returning an empty list.