Skip to content

fix(deriver): prevent cross-subject self-observations - #943

Open
Diaspar4u wants to merge 1 commit into
plastic-labs:mainfrom
Diaspar4u:fix/deriver-subject-attribution
Open

fix(deriver): prevent cross-subject self-observations#943
Diaspar4u wants to merge 1 commit into
plastic-labs:mainfrom
Diaspar4u:fix/deriver-subject-attribution

Conversation

@Diaspar4u

@Diaspar4u Diaspar4u commented Jul 27, 2026

Copy link
Copy Markdown

Summary

Fix deriver subject attribution without disabling peer self-observation or filtering stored messages.

  • distinguish the message speaker from the fact's subject;
  • allow target-specific derivation to retain facts supplied by any speaker;
  • require the structured deriver output to classify whether each conclusion is a durable target fact;
  • discard transient cross-subject speech/knowledge conclusions before persistence.

Motivation

With self-observation enabled, an assistant reply such as You play tennis on Tuesdays can produce an AI self-conclusion such as assistant knows the user plays tennis on Tuesdays, or worse, misattribute the tennis schedule directly to the assistant. Disabling self-observation prevents the corruption but also removes useful AI identity, capability, and preference learning.

This fixes the attribution boundary while preserving assistant messages, cross-peer observation, and genuine AI self-representation.

Implementation

The existing single deriver call now returns is_durable_target_fact for each explicit conclusion. Only conclusions classified as durable facts about the target peer are converted into persistent observations. The prompt includes speaker/subject rules and paired positive and negative examples.

This deliberately does not apply the SQL speaker filter proposed in #823. Interleaved messages remain available so another speaker can provide valid evidence about the target peer, matching the maintainer guidance on that PR.

End-to-end enqueue promotion for assistant-authored facts about the other participant is provided by the stacked follow-up #944.

Validation

  • Added prompt, cache-prefix, and persistence-filter tests.
  • Ruff and focused basedpyright checks pass.
  • Repeated live model tests confirmed:
    • an echoed user tennis schedule is rejected from AI self-memory;
    • a genuine AI preference remains in AI self-memory;
    • when evaluated with the user as target, an assistant-authored user schedule is accepted as a durable user fact.

Fixes #817.
Supersedes the attribution approach in #823 while preserving its reported reproduction and maintainer feedback.

Summary by CodeRabbit

  • New Features
    • Improved fact extraction to identify durable facts specifically about the target peer.
    • Added clearer handling for speaker attribution, pronouns, ambiguous subjects, and statements about others.
    • Excludes transient communication states and non-durable observations from results.
    • Returns no observations when no valid durable target-peer facts are found.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6b57fa89-17ac-45b9-a827-c171127a5b86

📥 Commits

Reviewing files that changed from the base of the PR and between 1baed39 and a0e725f.

📒 Files selected for processing (9)
  • src/deriver/prompts.py
  • src/utils/representation.py
  • tests/conftest.py
  • tests/deriver/test_deriver_processing.py
  • tests/deriver/test_prompts.py
  • tests/deriver/test_representation_crud.py
  • tests/integration/test_representation.py
  • tests/integration/test_token_metrics.py
  • tests/utils/test_length_finish_reason.py
🚧 Files skipped from review as they are similar to previous changes (8)
  • src/deriver/prompts.py
  • src/utils/representation.py
  • tests/deriver/test_deriver_processing.py
  • tests/utils/test_length_finish_reason.py
  • tests/deriver/test_prompts.py
  • tests/conftest.py
  • tests/integration/test_token_metrics.py
  • tests/integration/test_representation.py

Walkthrough

The deriver prompt now applies explicit speaker and subject attribution rules, marks durable target-peer facts, and excludes non-durable observations during representation conversion. Tests and fixtures adopt the new prompt-specific observation model and validate filtering behavior.

Changes

Durable target observations

Layer / File(s) Summary
Prompt attribution and durability rules
src/deriver/prompts.py, tests/deriver/test_prompts.py
The prompt distinguishes speakers from subjects, excludes ambiguous or transient observations, and defines durable target-fact labeling. Tests verify these rules and preserve the static prompt prefix.
Prompt representation and filtering
src/utils/representation.py
Adds PromptExplicitObservation with is_durable_target_fact and converts only durable prompt observations into Representation.explicit.
Fixtures and conversion validation
tests/conftest.py, tests/deriver/test_deriver_processing.py, tests/deriver/test_representation_crud.py, tests/integration/test_representation.py, tests/integration/test_token_metrics.py, tests/utils/test_length_finish_reason.py
Updates mocks, fixtures, integration inputs, and CRUD tests for the new observation model, including coverage for dropping non-durable facts.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Messages
  participant DeriverPrompt
  participant PromptRepresentation
  participant Representation
  Messages->>DeriverPrompt: provide speaker-labeled messages
  DeriverPrompt->>PromptRepresentation: emit target-peer observations with durability flags
  PromptRepresentation->>Representation: convert only durable target facts
Loading

Possibly related PRs

Suggested reviewers: rajat-ahuja1997

Poem

I’m a rabbit guarding facts tonight,
Speakers and subjects now align right.
Durable truths pass through the gate,
Fleeting chatter has to wait.
Hop, hop—memories shine bright!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: fixing deriver attribution to avoid cross-subject self-observations.
Linked Issues check ✅ Passed The prompt, representation, and tests all address #817 by separating speakers from subjects and filtering non-durable or ambiguous observations.
Out of Scope Changes check ✅ Passed The changes stay focused on deriver attribution, prompt wording, and related test updates with no obvious unrelated scope.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/deriver/prompts.py (1)

69-87: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Wrap the changed prompt-source lines.

Lines 70, 72, 73, 77, and 87 exceed the repository’s 88-character limit. As per coding guidelines, Python code must keep lines within 88 characters to match Black-compatible formatting.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/deriver/prompts.py` around lines 69 - 87, Wrap the overlong prompt-source
lines in the changed prompt text, specifically the lines corresponding to 70,
72, 73, 77, and 87, so each remains within the repository’s 88-character limit
while preserving the exact prompt wording and behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/deriver/prompts.py`:
- Around line 69-71: Make the prompt and structured-output schema consistently
accept durable facts about the target peer when directly supported by any
speaker’s message. In src/deriver/prompts.py lines 69-71, revise the
explicit-fact definition to use target-peer scope rather than speaker/user-only
scope; in lines 80-82, replace inferred or unanchored examples such as fixed
birthday, NYC residence, and education equivalence with directly supported
observations only. In src/utils/representation.py lines 130-133, update the
field description and inference guidance to match this any-speaker, target-peer
evidence contract.

---

Nitpick comments:
In `@src/deriver/prompts.py`:
- Around line 69-87: Wrap the overlong prompt-source lines in the changed prompt
text, specifically the lines corresponding to 70, 72, 73, 77, and 87, so each
remains within the repository’s 88-character limit while preserving the exact
prompt wording and behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f41a2a28-87c1-43da-9ba5-2dde31f0518b

📥 Commits

Reviewing files that changed from the base of the PR and between 3ee890f and 5cac360.

📒 Files selected for processing (9)
  • src/deriver/prompts.py
  • src/utils/representation.py
  • tests/conftest.py
  • tests/deriver/test_deriver_processing.py
  • tests/deriver/test_prompts.py
  • tests/deriver/test_representation_crud.py
  • tests/integration/test_representation.py
  • tests/integration/test_token_metrics.py
  • tests/utils/test_length_finish_reason.py

Comment thread src/deriver/prompts.py
@Diaspar4u
Diaspar4u force-pushed the fix/deriver-subject-attribution branch from 1baed39 to a0e725f Compare July 27, 2026 18:08
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.

[Bug]: Deriver misattributes AI agent speech to the human user in multi-peer sessions

1 participant