Skip to content

feat: Private Topics Only — opt-in group-scoped extraction for Personas and Rooms #44

@Flare576

Description

@Flare576

The Feature

Add a `private_topics_only` boolean setting to `PersonaEntity` and Room settings.

Default (false): extractions from any persona or room can write to any group, including `["General"]`. This is the current behavior and should remain the default. If someone has an emotional breakthrough talking to Frodo in a roleplay room, Frodo should absolutely be able to record that to a General topic.

Opt-in (true): extractions from this persona/room are scoped to within-group items only. Matches are filtered to items whose groups overlap with the persona's groups. New items are created within the persona's groups. Items in `["General"]` or non-overlapping groups are invisible to this persona's extraction pipeline.

The Problem It Solves

A story co-writing persona or roleplay room can accumulate rich character/narrative data without polluting the human's real-world topic/people/fact space. "Loyalty" in a fantasy epic shouldn't update your "Loyalty in Relationships" human topic unless you want it to.

Why It's Opt-In, Not Default

The default cross-group extraction is often exactly right. Real breakthroughs happen during fiction. Real feelings come up in roleplay. The system should capture those unless the user explicitly says "this space is private."

What Changes

Targeted filter in the extraction pipeline matchers (`TopicMatcher`, `PersonMatcher`, etc.): when `private_topics_only` is set on the persona, filter candidate matches to items with overlapping group membership before proposing updates.

The setting name makes it self-documenting in the UI:
```
[ ] Private Topics Only
Topics, People, and Facts discovered in conversations with this persona
will only be added to this persona's groups — not to your shared data.
```

Background / What `is_static` Actually Does (verified in code)

`is_static` was originally designed for story co-writing personas: skip ceremony to prevent the character from drifting mid-story. It only gates `ceremony.ts` (3 places) — it does NOT gate per-message extraction. Static personas still write to General data on every message. This feature is the clean solution to that original use case.

Open Questions

  1. Should rooms auto-create a dedicated group for `private_topics_only` to scope to, or reuse existing room persona groups?
  2. Multi-group personas: scope to intersection (strict) or union (permissive) of their groups?

Not Blocking Anything

Small, targeted change when the need is real. The Groups system already does display scoping — this extends it to extraction scoping, opt-in only.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions