Relationship proposals fire before the entries they should relate exist, so a session's own lore is never connected #286

Closed
opened 2026-08-05 20:33:21 +00:00 by claude-bot · 0 comments
Contributor

Found in the LLM trigger audit that produced #278 and #279. Verified against the code.

The bug

propose_lore_relationships is enqueued at two places, both at the completion of lore proposal generation:

webapp/backend/app/tasks/reminder_tasks.py:467   # single-pass pipeline done
webapp/backend/app/tasks/reminder_tasks.py:900   # multi-pass consolidate done

But the entries it loads are filtered to already-approved ones (reminder_tasks.py:3814-3816):

select(LoreEntry)
  .where(
      LoreEntry.campaign_id == session.campaign_id,
      LoreEntry.proposed_by_bot == False,   # noqa: E712
  )

Everything the pipeline just produced is proposed_by_bot = True. So the task runs at the exact moment a batch of new entries appears and then deliberately ignores all of them.

Consequence

Relationship proposals only ever connect entries that were already approved before this session ran. The NPCs, locations, and factions that came out of tonight's transcript never get related to anything — which is precisely the moment their relationships are most obvious and most worth capturing.

It also means the task does redundant work: every session re-examines the same static set of previously-approved entries, and if that set hasn't changed it re-proposes the same relationships (or none).

Fix direction

Fire it on proposal approval, not proposal generation — when a GM approves bot-proposed entries, those become proposed_by_bot = False and are exactly the new material worth relating. The approval path is campaigns.py:2746.

Worth considering whether it should be debounced: approving five entries one at a time would fire it five times over a nearly-identical entry set. A short delay, or firing once per approval batch, would avoid that.

While in here: propose_lore_relationships silently returns when the LLM is unconfigured (reminder_tasks.py:3800-3803, log + return), whereas the lore pipeline it is chained from raises and retries in the same situation (:563, :648, :747). Two tasks in one pipeline behaving differently on the same condition is confusing to debug — see the broader inconsistency tracked separately.

Acceptance

  • Relationship proposals consider entries approved from the session that just ran
  • Not fired at a point where its input set is guaranteed to exclude the new material
  • Repeated approvals don't trigger redundant near-identical runs
  • Test covering "approve a bot proposal → relationships consider it"

Labels: backend

Found in the LLM trigger audit that produced #278 and #279. Verified against the code. ## The bug `propose_lore_relationships` is enqueued at two places, both at the completion of **lore proposal generation**: ``` webapp/backend/app/tasks/reminder_tasks.py:467 # single-pass pipeline done webapp/backend/app/tasks/reminder_tasks.py:900 # multi-pass consolidate done ``` But the entries it loads are filtered to **already-approved** ones (`reminder_tasks.py:3814-3816`): ```python select(LoreEntry) .where( LoreEntry.campaign_id == session.campaign_id, LoreEntry.proposed_by_bot == False, # noqa: E712 ) ``` Everything the pipeline just produced is `proposed_by_bot = True`. So the task runs at the exact moment a batch of new entries appears and then deliberately ignores all of them. ## Consequence Relationship proposals only ever connect entries that were *already* approved before this session ran. The NPCs, locations, and factions that came out of tonight's transcript never get related to anything — which is precisely the moment their relationships are most obvious and most worth capturing. It also means the task does redundant work: every session re-examines the same static set of previously-approved entries, and if that set hasn't changed it re-proposes the same relationships (or none). ## Fix direction Fire it on **proposal approval**, not proposal generation — when a GM approves bot-proposed entries, those become `proposed_by_bot = False` and are exactly the new material worth relating. The approval path is `campaigns.py:2746`. Worth considering whether it should be debounced: approving five entries one at a time would fire it five times over a nearly-identical entry set. A short delay, or firing once per approval batch, would avoid that. ## Related inconsistency While in here: `propose_lore_relationships` **silently returns** when the LLM is unconfigured (`reminder_tasks.py:3800-3803`, log + return), whereas the lore pipeline it is chained from **raises** and retries in the same situation (`:563`, `:648`, `:747`). Two tasks in one pipeline behaving differently on the same condition is confusing to debug — see the broader inconsistency tracked separately. ## Acceptance - [ ] Relationship proposals consider entries approved from the session that just ran - [ ] Not fired at a point where its input set is guaranteed to exclude the new material - [ ] Repeated approvals don't trigger redundant near-identical runs - [ ] Test covering "approve a bot proposal → relationships consider it" Labels: backend
rbrooks referenced this issue from a commit 2026-08-06 00:46:35 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Quest-Board#286
No description provided.