= IRC/soju integration for Pi sessions

== Conclusion

Yes: this is feasible on the laptop. Pi does not have a built-in IRC transport, but its extension and RPC APIs are sufficient to add one. The exact desired design—one persistent Pi session per IRC identity, visible as separate conversations—needs a small bridge/supervisor. The send-only fallback is much simpler and is immediately practical once an IRC client is available.

The important distinction is:

== Laptop inspection

No repository files were changed for this investigation.

== Designs

=== 1. Send-only: recommended first step

Run one ii process for each Pi identity/session. A Pi extension or small command writes an explicit message to that process’s channel FIFO. Alternatively, the model can call a restricted irc_send tool.

Example shape, after the bouncer and current ii are set up:

SOJU_PASSWORD='...' \
ii -s bouncer.example.org -t -p 6697 \
  -n 'pi-a/irc.example.org@pi-a' -k SOJU_PASSWORD \
  -i "$XDG_STATE_HOME/pi-irc/pi-a"

The USER/nickname value selects the soju user, network, and client name for clients that do not support soju.im/bouncer-networks. The password stays in an environment variable rather than the process arguments. The actual credentials should be stored in a protected service environment, not in a repository.

Advantages:

Limitations:

The safe default should be an explicit /irc-send <message> command, not automatic forwarding of every assistant response.

=== 2. Full one-session/one-IRC-identity bridge: best match

For each Pi session, run an isolated worker containing:

Pi session JSONL  <->  Pi RPC process  <->  IRC adapter/ii  <->  soju  <->  ii/mobile clients

Map a stable Pi session ID to one soju account, one visible agent nickname, and one private channel. On agent_settled, send only the final assistant text. On an allowlisted incoming IRC message, queue one Pi prompt. Queueing is required because a Pi session cannot safely process simultaneous prompts.

Pi already exposes the required hooks and commands:

There are two transport implementations:

The ii-backed version is adequate for private text conversations. The native adapter is preferable only if IRC history queries, replies, files, or richer IRCv3 behavior become requirements.

For the exact “different user per Pi session” requirement, use separate soju users such as pi-a, pi-b, and pi-c. A single IRC connection has one visible upstream nickname. Separate channels alone provide separate threads but do not provide separate IRC identities.

=== 3. One IRC bot identity, one channel per Pi session

This is a simpler variation: one soju account/nickname, with #pi-a, #pi-b, etc. Each channel maps to a separate Pi RPC worker/session.

It gives separate conversations and is easier to operate, but all messages appear from one IRC user. It does not meet the preferred identity model. It is a good compromise if provisioning many soju accounts is inconvenient.

=== 4. One Pi process/session at a time

A single RPC worker can switch between saved sessions using Pi’s session-switch operation. This is technically possible, but it is not a good communication model: the active session is ambiguous, messages can arrive during a switch, and independent IRC conversations cannot progress concurrently. It should be retained only as an emergency fallback or administrative control path.

Running several independent Pi processes is supported; there is no Pi setting that limits the laptop to one session. Do not open the same saved session file in two Pi processes at once.

== IRC history and threading

soju supports multiple users, detached channels, message storage, backlog playback, and per-client buffers. For clients without IRCv3 chathistory, its documented username convention is:

<soju-user>/<network>@<client-name>

Use stable client names such as human-laptop, human-mobile, and pi-a. This lets soju track per-client delivery state. ii itself writes timestamped lines to out files and accepts outgoing lines through in FIFOs; it does not provide native Pi-session or chat-thread semantics.

Use one channel or private conversation per Pi session. IRC channels are the visible “threads”; Pi’s full context remains in its local session JSONL file. They are two separate histories and should not be treated as one lossless transcript.

== Security and reliability requirements

A full inbound bridge turns IRC text into prompts. It must therefore:

TLS protects transport, not the soju database or the IRC participants. IRC is not end-to-end encrypted.

== Recommendation

Implement in this order:

Deploy soju with TLS and a database-backed message store. Create separate human and pi-* accounts. Build/install current upstream ii 2.0 (the distro package currently available here is too old for -t). Run one human ii client and verify the mobile client against the same soju account. Add the send-only Pi command first, with explicit messages and one test Pi account. If two-way communication is wanted, add an RPC bridge modeled on the existing Matrix bridge: one worker and one saved Pi session per channel, with strict sender/channel allowlists. Only add automatic final-answer forwarding after the message limits and redaction policy are tested.

This gives the desired simultaneous multi-session model without changing Pi core, while preserving the simpler send-only mode as a reliable fallback.

== Sources