Skip to content

fix(persons): reject a split that leaves the person with no distinct ids - #116701

Merged
trunk-io[bot] merged 6 commits into
masterfrom
eli/person-split-keep-a-distinct-id
Oct 15, 2026
Merged

trunk-io[bot] merged 6 commits into
masterfrom
eli/person-split-keep-a-distinct-id

Conversation

@eli-r-ph

@eli-r-ph eli-r-ph commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Problem

A split can leave a person with no distinct IDs: it stays live, no event reaches it, and no cleanup removes it.
This happens when a request moves every ID, or names a main_distinct_id the person does not own.

Changes

Note

A request that moves the person's creating ID along with every other ID now gets a 400.

How did you test this code?

Test rationale: no test covered a split that empties a person.

  • API and task tests for both requests. Removing either check fails them.

Release status

  • No feature flag controls this change

Docs update

None.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, Claude Opus 5.5. Skills: /writing-tests, /writing-code-comments, /writing-pr-descriptions, /improving-drf-endpoints.

🤖 Generated with Claude Code

A split that moves every distinct id off a person, or that names a main
distinct id the person does not own, leaves a live person no event can
reach and no cleanup job picks up. The API now returns 400 for both
requests, and the split task re-checks before it moves anything.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@eli-r-ph eli-r-ph self-assigned this Oct 14, 2026
@trunk-io

trunk-io Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

😎 Merged successfully - details.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Trunk lane — backend Python lane

This PR is assigned to the backend Python lane. It runs backend Python tests and may merge in parallel with PRs in other lanes.

✅ Duplication (Python) — clean

New Python code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

✅ Duplication (TypeScript) — clean

New TypeScript code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

✅ Comment density — 3% of added code lines are comments (2 of 69)

This section warns when comments are more than 3% of the code lines a PR adds, and alerts above 6%. Before agent-assisted PRs, the typical share was about 2%. Only full-line comments count. Docstrings, generated files, snapshots, migrations, and workflow files are left out.

Comments that restate the code, record how the change came about, or narrate the next line add noise for the next reader. Keep the comments that explain a reason the code cannot show, and remove the rest. See .agents/skills/writing-code-comments/SKILL.md for the house rules.

Files with the most added comment lines:

File Comment lines Added lines
posthog/api/person.py 1 5
posthog/models/person/person.py 1 25

This check does not block merging. It updates on every push and clears when the share drops.

✅ Playwright — all passed

All tests passed.

View test results →

@eli-r-ph
eli-r-ph marked this pull request as ready for review October 14, 2026 02:21
@parameterai

parameterai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Risk: Low · 2 low

This increment drops the database-timeout retry loop from _split_distinct_ids_batch (and its helper and tests), leaving a single SplitPerson RPC call whose errors propagate. The removal introduces no new security issue; both previously reported concurrency findings (the unlocked keeps-check race and the detach-vs-split race in personhog-replica) remain in unchanged code, pending the server-side fix in #116730.

Sentinel reviewed 2f22581 · Review settings

@eli-r-ph
eli-r-ph requested a review from a team October 14, 2026 02:21
@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team October 14, 2026 02:22
@trunk-io

trunk-io Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Static Badge   Static Badge   Static Badge

View Full Report ↗︎ ⋅ Docs

Comment thread posthog/models/person/person.py
Two splits of the same person could each see an id the other was about
to move and together leave the person with no live distinct id. The
SplitPerson RPC now claims the source person's lifecycle mark before any
row lock, as ingestion merges and the tombstone RPC do, and then refuses
with FailedPrecondition a split that would leave no live distinct id.
A held mark or row fails the call within a 2s lock timeout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@eli-r-ph eli-r-ph changed the title fix(persons): reject a split that leaves the person with no distinct ids fix(persons): never leave a person without distinct ids after a split Oct 14, 2026
Comment thread rust/personhog-replica/src/storage/postgres/person.rs Outdated
The tombstone RPC locks persons in id order, and the split locked its
target persons in no particular order, so a split and a tombstone call
naming two of the same persons could deadlock. The comment on the lock
timeout now says it bounds each wait, not the whole call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The merge queue keeps Python and Rust changes in separate lanes, so the
SplitPerson lifecycle mark change moves to #116730. This branch keeps
the API and task checks only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@eli-r-ph eli-r-ph changed the title fix(persons): never leave a person without distinct ids after a split fix(persons): reject a split that leaves the person with no distinct ids Oct 14, 2026
eli-r-ph and others added 2 commits October 13, 2026 22:10
A split that waits behind a merge of the same person can hit a database
lock or statement timeout. The server rolls the whole batch back, so the
task now sends it again, up to three times, instead of failing after the
user already saw the split succeed. Other errors are not retried.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@eli-r-ph eli-r-ph added the stamphog Request AI approval (no full review) label Oct 14, 2026

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Not approved — this change needs a human reviewer.

Re-add the stamphog label to request another review once you have addressed this.

The change enters API-contract and person-data territory, with owning-team authorship but no current-head reviews. The bot's retained-ID concurrency concern remains unaddressed; request review from @PostHog/team-ingestion and @PostHog/team-product-analytics after addressing it or obtaining explicit acceptance.

  • Author wrote 0% of the modified lines and has 16 merged PRs in these paths (familiarity MODERATE).
  • @parameterai[bot]'s concurrency concern remains in posthog/models/person/person.py: the retained-ID checks occur separately from the split RPC, so concurrent splits can each pass the check and move complementary IDs. rust/personhog-replica/src/storage/postgres/person.rs locks only requested ID rows and does not enforce a retained ID atomically. Address this concern with server-side transactional enforcement or obtain explicit non-author acceptance before re-requesting; suggested reviewers are Nick Best and Zach Brown.
Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✓ 39L, 2F substantive, 85L/4F incl. docs/generated/snapshots — within ceiling
tier ✓ T1-agent / T1b-small (85L, 4F, single-area, fix)
stamphog 2.5.1 .stamphog/policy.yml @ 2f22581 · reviewed head 2f22581

@stamphog stamphog Bot removed the stamphog Request AI approval (no full review) label Oct 14, 2026
@eli-r-ph

Copy link
Copy Markdown
Contributor Author

/trunk merge

@trunk-io
trunk-io Bot merged commit 93b19f9 into master Oct 15, 2026
323 checks passed
@trunk-io
trunk-io Bot deleted the eli/person-split-keep-a-distinct-id branch October 15, 2026 01:48
@deployment-status-posthog

deployment-status-posthog Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-10-15 02:09 UTC Run
prod-us ✅ Deployed 2026-10-15 02:23 UTC Run
prod-eu ✅ Deployed 2026-10-15 02:24 UTC Run

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.

2 participants