Repository navigation
Conversation
roborev: Combined Review (
|
bc9bdf2 to
514da27
Compare
514da27 to
118d786
Compare
roborev: Combined Review (
|
118d786 to
45f3713
Compare
22a0f28 to
d093c94
Compare
roborev: Combined Review (
|
d093c94 to
b54c6fb
Compare
roborev: Combined Review (
|
b54c6fb to
8ae2eb5
Compare
roborev: Combined Review (
|
8ae2eb5 to
07e134f
Compare
roborev: Combined Review (
|
07e134f to
c364176
Compare
roborev: Combined Review (
|
c364176 to
3d1e35c
Compare
roborev: Combined Review (
|
2bb802b to
27b2325
Compare
roborev: Combined Review (
|
27b2325 to
8a09e57
Compare
roborev: Combined Review (
|
8a09e57 to
ef76954
Compare
roborev: Combined Review (
|
roborev: Combined Review (
|
062c1d1 to
af397a8
Compare
roborev: Combined Review (
|
af397a8 to
4118a12
Compare
roborev: Combined Review (
|
4118a12 to
33be50b
Compare
roborev: Combined Review (
|
33be50b to
882b052
Compare
roborev: Combined Review (
|
A cold room should not shape who msgvault thinks people are. Before this change, a large room's roster could still supply names, emails and provider IDs to identity suggestions, enrichment, person sweeps and person vectors. Participants are shared across the archive, so excluding a room means knowing which conversation backed each fact. Contact observations now record their supporting conversations, and identity, people and person vector readers accept only values backed by a full room, an independent contact or a manual decision. Importers resolve participants per conversation for the same reason. Older archives backfill this provenance from stored payloads: native email handles and Apple WhatsApp names. A room turning cold invalidates the people work it fed. That covers matches, person facts, sweep inputs, enrichment and person vectors. Promoting a room back to full replays its roster. Merges and source moves carry provenance with them, and recipient changes invalidate the contextual embeddings that named those participants. The daemon's idle-refresh check also treats an unbootstrapped people projection as due. Upgrading runs the new data migrations above, and the schema version moves to 17. This layer is cut from #1361 so it can be reviewed on its own. Follow-up changes: - fix(people): keep provider IDs when merging participants - test(people): opt people-layer tests into automatic classification - fix(people): close cold-room gaps in merges, bootstrap, and enrichment - fix(people): follow envelope support when it is withdrawn or restored - fix(people): stage deletions from the names and addresses users see - fix(people): give envelope writers the recipient lock order Co-authored-by: salmonumbrella <182032677+salmonumbrella@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Recipient replacement takes the recipient advisory lock before it locks message and person rows. Sweep publication locked its cited messages first, and undoing a dedup batch or clearing a source deletion updated message rows before invalidating shared contexts, both without that lock. On PostgreSQL either could deadlock with a concurrent replacement and abort one of the writes. These paths now take the advisory lock first. Sweeps already hold the shared identity lock, which replacement also takes before the advisory lock, so the order stays consistent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Source-message migration and duplicate merging locked message rows before the recipient advisory lock, while sweep admission takes them in the other order. On PostgreSQL a Teams reimport or a dedup merge could deadlock with a people sweep. Both now take the advisory lock first. Name observations store trimmed values, but participant rows keep the raw name. A native name with surrounding spaces therefore lost its independent support once a cold chat sighting gave the participant chat provenance, and the name vanished from queries, caches and people features. The comparison now trims the participant value. Beeper created a bare participant for every unseen user before rich resolution, which then merged it into the phone or email participant. Each merge loaded the identity graph and scanned room metadata under the exclusive policy and identity locks. Resolution now only adopts legacy identifiers first and lets rich resolution bind the identifier; the bare fallback remains for when admission fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…stent Replacing the only envelope behind a generated name match hid the name, but three things still disagreed with that. - The review page failed. Source rows for the hidden evidence had nothing to attach to, so listing a page returned an error. - Review tokens stayed the same, because fingerprints hashed stored evidence but not its eligibility. A token issued while the name was shown could still accept the match after the name was withdrawn. Fingerprints now also hash the IDs of hidden name evidence. They add this group only when it is present, so tokens for unaffected candidates do not change. - A native name padded with tabs or no-break spaces lost its support after a Cold chat sighting, because SQL TRIM strips only ASCII spaces. The check now trims the raw observed value the same way. Callers bind the name once per occurrence, so it still appears only once in the predicate. The enrichment worker also discards a completed result when the request identity changed during the provider call. That path ended the attempt with no actual cost, so a paid call recorded no spending on profiles without a hard cap. The worker now passes the reported charge through MarkTerminalWithCost, which reconciles it when it ends the attempt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Policy bootstrap initializes identity state, so link and rejection tests must assert the operation delta rather than an absolute starting revision. Contact-point edits also invalidate cached contact times. Seed the paging fixture with fresh contact state after those edits so it still tests sparse pages in both chronological orders. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
882b052 to
3432bac
Compare
roborev: Combined Review (
|
Cold rooms no longer shape people data: identity suggestions, enrichment, person sweeps, person facts and person vectors. Before this change, a large room's roster could still supply names, emails and provider IDs to those features.
Provenance
Participants are shared across the archive, so excluding a room requires knowing which conversation backed each fact.
participant_contact_observation_conversations.Merge fix
This layer also restores a step from
mainthat the original change dropped. When two participants merge and only the absorbed one has a stable provider ID for a shared address, the survivor now inherits it. This applies to sources without room tiers. Without it, the provider ID was lost and a resolved identity conflict stayed open. #1361's CI was failing on the two merge tests that cover this.A source merge also no longer aborts when clearing a cold provider ID makes it match a providerless full observation of the same address. The providerless row is kept and the other becomes history.
Upgrade cost
Upgrading runs data migrations and moves the schema version to 18:
These run during schema initialization, and the payload backfills decompress raw messages, so a large archive's first open after upgrade takes noticeably longer.
Where to look
internal/store/participant_observations.goandinternal/store/conversation_policy_{observations,people,rich_identity,sweep_input}.go.messages.goandsource_merge_transfer.go: participant merges, source merges and recipient-change invalidation.Stack 5/5, cut from #1361. With this layer the stack matches the combined change in #1517, apart from the opt-in default, the idle-refresh skip and the help trim.
Review items deferred from this stack are tracked in #1555.
🤖 Generated with Claude Code