Dear Stephen,

I went through the Systers wiki and the Brief Technical Details page, and
had a couple of thoughts along with a design question.

The Mailman 2 implementation is interesting in how it handled the
two-recipient-set problem. Instead of filtering the outgoing message, it
created two altered messages from the original and placed them into a
dedicated Dlist queue — one for subscribers to new conversations and one
for members who had explicitly opted into the thread. The original message
was archived only. This neatly avoided the incoming pipeline's
single-message assumption.

For Mailman 3, my initial thought is that the equivalent behavior might
live in two places. First, a new subaddress command `+new` in the command
runner — following the existing `join`, `leave`, and `confirm` subaddresses
— could intercept messages sent to `listname+new@domain` and create the
sublist. Second, replies could be routed through a delivery check before
`CookHeaders` that evaluates per-member, per-thread subscription state to
determine the two recipient sets.

This raised a design question I wanted to ask on-list.

The Mailman 2 implementation stored per-conversation subscription state in
a separate PostgreSQL database per list. For Mailman 3, would the preferred
direction be:

1. Introducing a new `ConversationSubscription` model in the core database
(member × thread × subscription_state), or
2. Extending the existing `IMember` / delivery preference infrastructure
with a per-thread layer?

Option 1 feels conceptually cleaner to me because it keeps
conversation-level state separate from member-level state and avoids
overloading `delivery_status`, which is currently a per-member, per-list
setting with no notion of per-thread granularity. However, option 2 would
reuse more existing infrastructure.

I'd appreciate your thoughts before I explore either direction further in
the proposal.

Tejas Pavan B
https://gitlab.com/tejaspavanb
https://github.com/tejaspavanb
https://linkedin.com/in/tejaspavanb

On Mon, 9 Mar 2026 at 21:24, Tejas Pavan B <[email protected]> wrote:

> Dear Stephen,
>
> Thank you for the detailed response, keeping this on-list as requested.
>
> On whether a sublist is *exactly* a filter on the parent's member set:
>
> I don't think it is. A filter implies the sublist membership is derived
> automatically from the parent, but the original Systers design was opt-in,
> which means a sublist member is someone who *chose* to subscribe in
> response
> to a post. That's fundamentally different from filtering. The constraint is
> weaker: sublist members must be parent members (or at least eligible to
> be),
> but the parent does not determine the sublist's membership mechanically.
>
> This has a structural implication: the sublist needs its own membership
> object, not a view over the parent's. The parent relationship is a
> constraint on eligibility, not a source of membership. Concretely, I'd
> model it as: a sublist has a `parent` reference to an IMailingList, and
> subscription validation checks that the subscriber is a member of the
> parent. The sublist's ISubscriptionService manages its own member set
> independently.
>
> On sublists of sublists:
>
> A tree structure seems natural and not overly constraining for the
> "issue tracker" use case, a task forks off a sublist, a sub-task forks
> off that. The eligibility constraint would propagate: to subscribe to a
> depth-2 sublist, you must be a member of the depth-1 parent. I'd represent
> this as a parent FK on the list model, with NULL indicating a root list.
> Depth could be limited (say, max 2-3 levels) to avoid pathological cases.
>
> On other use cases and affordances:
>
> Beyond the issue tracker pattern, I can see:
> - Working groups forked from a community-wide list (eg, a "security"
> sublist
>   of a project's general discussion list)
> - Staged discussion: announce → discuss → implement, each as a sublist of
>   the previous
> - Temporary sprint or event lists that expire after inactivity
>
> For affordances, the email-based subscription path (reply to the fork post)
> seems essential for the original use case. Beyond that:
> - Postorius UI to browse and subscribe to active sublists of a parent
> - An auto-expire mechanism for inactive sublists (configurable TTL)
> - HyperKitty threading that links a sublist's archive back to the parent
>   post that created it — so the fork is browsable in context
>
> The last point seems important for usability: if sublists are invisible in
> the archive, the "issue tracker" metaphor breaks down for anyone browsing
> the history.
>
> I'm sure there are cases I haven't thought of, happy to keep refining this
> here before the proposal stage.
>
> Tejas Pavan B
> https://gitlab.com/tejaspavanb
> https://github.com/tejaspavanb
> https://linkedin.com/in/tejaspavanb
>
> On Mon, 9 Mar 2026 at 10:01, Stephen J. Turnbull <[email protected]>
> wrote:
>
>> Tejas Pavan B via Mailman-Developers writes:
>>
>>  > I read Stephen's reply to Tanmay's question about the Dynamic
>>  > Sublists architecture. The suggestion to derive a sublist interface
>>  > from MailingList components makes sense to me. I started tracing
>>  > through mailman/model/mailinglist.py and noticed membership is
>>  > managed via ISubscriptionManager, my question is: would sublist
>>  > membership be best modelled as an extension of
>>  > ISubscriptionService, or does it warrant a new top-level interface
>>  > entirely, given that sublists would need to inherit and filter the
>>  > parent list's member set rather than manage their own?
>>
>> If I remember correctly, in Google Summer of Code, design at that
>> level is our responsibility.  However, to do a good job of
>> implementing a design, you need to believe it is correct and
>> understand it.  So I'd like to ask you to think about it a bit more
>> and explain how you think the parts should fit together, and why you
>> think that's good.  Please keep the discussion on-list.
>>
>> First comment, I think the insight that a sublist filters the parent's
>> member list is a good one.  That's a good starting point.  However, at
>> that point you need to ask, is the sublist *exactly* a filter on the
>> parent's member list?  What does that imply about the structure of
>> discussion?
>>
>> Consider that the original design was tuned to an organization that
>> basically used the Dynamic Sublist feature as today we would use an
>> issue tracker: people would discuss a task for one of their projects
>> at a high level on a mailing list, then fork off a sublist with a
>> single post to the parent list.  People who want to work on that task
>> subscribe to the sublist (note: opt-in, not opt-out).  They can
>> subscribe by replying to the post.  But what if you're a new member
>> and want to work on the issue, but didn't receive the post?
>>
>> How about sublists of sublists?
>>
>> Are there other use cases for this mechanism?  The "issue tracker" use
>> case suggests a tree structure on the sublists is not too
>> constraining.  What about other use cases (user stories)?  Besides
>> dynamically creating and subscribing to a sublist, what affordances
>> should be available for the sublists, and how would they be
>> implemented?
>>
>> I think I'll stop here for now.
>>
>> I think I can see how this task may factor pretty cleanly into parts,
>> for Mailman core, Postorius, and HyperKitty.  I think the Postorius
>> component is pretty straightforward, from the point of view of
>> subscription management "sublist" is a simple object.  HyperKitty's
>> would depend heavily on the core design, so whether we go into adding
>> sublist support to HyperKitty at this time or not, we should be
>> sensitive to applications like search and browsing the archives.  I
>> haven't thought deeply about it; it may not be that hard.
>>
>> --
>> GNU Mailman consultant (installation, migration, customization)
>> Sirius Open Source    https://www.siriusopensource.com/
>> Software systems consulting in Europe, North America, and Japan
>>
>
_______________________________________________
Mailman-Developers mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/mailman-developers.python.org/
Mailman FAQ: https://wiki.list.org/x/AgA3

Security Policy: https://wiki.list.org/x/QIA9

Reply via email to