arizuko

arizuko › reference › Topics

topics

The topic of a message, the four ways a topic starts, the order that picks the active topic, and the MCP tools for topic sessions. Topics explains the concept.

Three records carry topic state

recordfieldmeaning
messagetopicThe topic of the message. An empty string is the default topic.
chatsticky topicThe topic pin of a chat. Empty means no pin. store/chats.go:272
session(folder, topic)One Claude session for each folder and topic pair.

The chat record also holds the sticky group, a folder pin. It is a different pin and appears here only to tell the two apart. schema lists the full store.

Four sources set a topic

An inline #name prefix
A message whose text starts with #name opens the topic #name. The regex is ^\s*#(\w[\w-]*), rePrefixHash in routd/steer.go:443. handlePrefixLayer removes the prefix, writes the rest as a new message with Topic = "#" + name and queues the chat.
A bare #name message
A message that is only #name sets the sticky topic of the chat. A message that is only # clears it. handleStickyCommand in routd/steer.go:49 replies topic → <name> or topic reset to default.
/new and /new #name
/new alone clears the session of the default topic. /new #name [rest] clears the session of #name, then writes #name rest as a new inbound message, which goes through the prefix path. cmdNew in routd/steer.go:411.
Platform threads
Discord: a message in a thread gets the thread ID as its topic, under the JID of the parent channel, in chatAndTopic, discd/bot.go:304. Telegram: a message in a forum topic gets the MessageThreadID as its topic, teled/bot.go:396. Slack: a thread uses its thread_ts. Other adapters leave the topic empty.

A sticky topic wins over the topic of the message

When routd forms a turn, effectiveTopic in routd/loop.go:681 picks the topic:

func (l *Loop) effectiveTopic(chatJID, msgTopic string) string {
	if _, sticky := l.db.StickyState(chatJID); sticky != "" {
		return sticky
	}
	return msgTopic
}
  1. The sticky topic of the chat, if it is not empty.
  2. The topic of the message, from the prefix or from a platform thread.
  3. The empty string, the default topic.

The result selects the Claude session of the turn.

A sticky topic also wins over an inline prefix. When the chat is pinned to #current, a message with #other still runs under #current. Send a bare # to clear the pin first.

Two MCP tools act on topic sessions

reset_session(groupFolder)
Clears the Claude session of a folder, so the next message starts with a new context. The caller must hold mcp:reset_session with a scope that covers groupFolder. Registered in ipc/ipc.go:1738.
inspect_session(topic?, limit?)
Returns the current session_id of the own folder and the topic, with recent session_log rows. limit defaults to 10; a value of 0 or less, or over 100, gives the default. Registered in ipc/inspect.go.

inject_message writes an inbound message, and the next turn applies the sticky and prefix rules to it as to any other message. No set_topic or get_topic tool exists. A sticky change goes through the #name chat command.

Observed messages ignore the topic

Every turn also gets the observed messages of its folder. store.ObservedSince in store/message_folders.go:284 reads them by folder and cursor, not by topic, up to OBSERVE_WINDOW_MESSAGES messages and OBSERVE_WINDOW_CHARS characters. routd calls it in routd/prompt_db.go:82. So a turn in topic #tickets-42 of folder support sees the recent observed messages of support, whatever their topic. For strict isolation, use separate folders.

Operators change topics from the chat

Reset a topic
/new #name clears that session. /new clears the session of the default topic.
Pin or unpin a topic
Send a bare #name to pin and a bare # to clear.
Inspect from the agent
Call inspect_session with a topic.
Reset from the agent
Call reset_session with the target groupFolder.

No arizuko subcommand sets or reads topics. Topics has the narrative, routing shows how a chat reaches a folder, and MCP tools lists every tool.