Skip to content

draft/persistence#503

Open
slingamn wants to merge 4 commits into
ircv3:masterfrom
slingamn:persistence
Open

draft/persistence#503
slingamn wants to merge 4 commits into
ircv3:masterfrom
slingamn:persistence

Conversation

@slingamn

Copy link
Copy Markdown
Contributor

This is a draft of an extension for automating certain interactions around persistent connections (i.e. connections where the user remains present on the server even after the connection is lost, as with a typical bouncer or Ergo's "always-on" functionality). The core goals as per the introduction:

  • Servers can communicate to clients whether their connection is "persistent" in the above sense, so clients can adjust their behavior accordingly
  • Clients can request that the server make their connection persistent or non-persistent, and the server can grant or deny the request

@slingamn

slingamn commented Sep 2, 2022

Copy link
Copy Markdown
Contributor Author

A question that has come up a few times about this specification: why isn't it simply a CAP?

CAPs have always been per-connection (and this distinction is especially important in the bouncer context). For example, ZNC separately tracks client-to-ZNC CAPs and ZNC-to-server CAPs. It is not the expectation that requesting a client-to-ZNC CAP will directly affect the persistent connection (the ZNC-to-server connection).

Since this affects the "global" or "persistent" presence state, it's more like a NickServ command than a CAP.

@slingamn

slingamn commented Sep 2, 2022

Copy link
Copy Markdown
Contributor Author

Another objection that's come up: this specification is more general than required by any implementation other than Ergo.

This is true, but IMO the spec doesn't place an excessive burden on less general implementations:

  1. Clients that don't want to introduce a user-controllable toggle can treat this the same way they would treat an informational CAP. The only difference is, an informational CAP would be seen during connection registration, but this comes as part of the registration burst (but since it's before RPL_ENDOFMOTD/ERR_NOMOTD, it will be seen alongside other successful registration numerics like RPL_ISUPPORT, so there's still time to make decisions based on the result).
  2. Servers that don't support toggling (because the user is always persistent) just have to store the value of the user's requested setting (it should be simple to store this alongside other persistent user state).

Comment thread extensions/persistence.md Outdated
Comment thread extensions/persistence.md Outdated
Comment thread extensions/persistence.md
@emersion

Copy link
Copy Markdown
Contributor

-1 from me. I think the cap is good, but I don't see the need for a standard command to get/set persistence setting.

@spb

spb commented Oct 27, 2023

Copy link
Copy Markdown

Another objection that's come up: this specification is more general than required by any implementation other than Ergo.

My problem is that it's not general enough - it assumes that there can be at most one persistent session per account. I'd rather see a newly-connecting client able to authenticate, request a list of available sessions, and choose which one to attach to.

@slingamn

Copy link
Copy Markdown
Contributor Author

@spb I had this conversation with Jess a while back; I think this specification can actually be decoupled from that assumption. See proposed change here: slingamn@16e6cbc

@spb

spb commented Oct 27, 2023

Copy link
Copy Markdown

That change does go some way towards it, but then you have the problem that a client needs to implement this spec and also whatever other spec defines the session selection mechanism. Combining them would make the ecosystem as a whole simpler.

@slingamn

Copy link
Copy Markdown
Contributor Author

From discussion in #ircv3, I'm open to an extension of this spec that would:

  1. Mandate SASL as a prerequisite for reattaching to a session (allowing a bearer token mechanism to cover hypothetical cases where there is no conventional account system)
  2. After this prerequisite is met, allow optionally enumerating the sessions and choosing one. It will still be possible for the client to proceed to CAP END without choosing a session, in which case they will get the "default" behavior (e.g. for a conventional bouncer or Ergo, they will attach to the unique session associated with the account)

MrLenin added a commit to MrLenin/testnet that referenced this pull request May 17, 2026
Captures the design dialog from 2026-05-17 for unifying our in-house
bouncer wire surface with the IRCv3 draft/persistence proposal.

Sources:
- ircv3/ircv3-specifications#503 — minimal PERSISTENCE STATUS/GET/SET
- MrLenin/814a674c gist — Afternet extension with LIST/ATTACH/DETACH +
  persistence batch (CAP value tokens, pre-CAP-END session select)
- This plan: implements both, plus a REPLAY trio for auto-replay
  opt-out, plus a vendor-scoped bouncer-replay batch
  (evilnet.github.io/bouncer-replay) around the missed-message replay

Phasing (each phase is a separate commit stack):

1. Base protocol — PERSISTENCE STATUS/GET/SET, unsolicited STATUS at
   registration, CAP advertise, server-managed metadata prefix
   carve-out (bouncer/* reserved, exempt from client metadata limits,
   rejects raw METADATA SET via KEY_NO_PERMISSION).  Optional legacy
   alias: BOUNCER SET HOLD default → deletes metadata.

2. Persistence batch + bouncer-replay batch — wrap channel-state
   restoration in draft/persistence; wrap missed-message replay in
   evilnet.github.io/bouncer-replay; per-target chathistory batches
   nest inside as parent.

3. REPLAY trio + DETACH + hs_enforced flag — mirror HOLD with REPLAY
   subcommands, gate replay_start_bouncer on the user setting + the
   chathistory CAP, add the enforced-class persistence flag, implement
   DETACH with refused-when-enforced semantics.

4. LIST + ATTACH — pre-CAP-END session enumeration and selection.

5. Legacy surface deprecation — NOTICE on BOUNCER SET/INFO/LISTCLIENTS
   and on umode +b.  Drop +b in a future major version after window.

Decisions captured inline:

- Vendor scope: evilnet.github.io/bouncer-replay (settled 2026-05-17 —
  vendor follows the software/evilnet GH org, not the network
  operator; github.io domain resolves and is controlled by the org).
- Server-managed metadata prefix: bouncer/* reserved; clients use
  PERSISTENCE SET (not raw METADATA SET) to influence; server-managed
  keys don't count against the user's max-keys budget.
- Umode +b stays through Phase 1-4 as the preference-only view, drops
  in Phase 5 because it only tracks preference (not effective state)
  which is what PERSISTENCE STATUS provides cleanly.
- Pool-cleanup hook from 515419f retires after Phase 1 — tests use
  PERSISTENCE SET DEFAULT (or BOUNCER SET HOLD default legacy alias)
  in afterEach instead of the oper-direct METADATA wipe.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants