feat(people): add person external enrichment - #686
Conversation
roborev: Combined Review (
|
dc18549 to
8ac86c0
Compare
roborev: Combined Review (
|
63ca8e8 to
bf9d2ff
Compare
roborev: Combined Review (
|
7078096 to
1a3e82e
Compare
roborev: Combined Review (
|
1a3e82e to
48e6206
Compare
roborev: Combined Review (
|
|
rebasing |
48e6206 to
60acf6f
Compare
roborev: Combined Review (
|
roborev: Combined Review (
|
roborev: Combined Review (
|
roborev: Combined Review (
|
roborev: Combined Review (
|
roborev: Combined Review (
|
roborev: Combined Review (
|
roborev: Combined Review (
|
roborev: Combined Review (
|
roborev: Combined Review (
|
roborev: Combined Review (
|
Enrichment must not treat an ended job as proof of a current employer. A same-name provider result could otherwise bind to the wrong person. A newer trigger can also arrive while a worker releases older work. Keep that trigger claimable instead of deleting it with the terminal release. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
A person can have a curated display-name override without a structured or observed name. Excluding that override prevents name-and-company providers from building a request and omits the same identity from deletion suppressions. Treat the display name as a primary identity candidate so request and deletion paths use the current curated identity. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
Synchronous provider results must not pass through a pending state that cannot be recovered after a worker restart. Keep dispatch authority fenced and commit the provider metadata and claims together. Policy-only terminal attempts are completed work, not provider failures. Display-name edits must also use the same identity invalidation gate as other identity changes. Give the backup overlap test enough time to reach its synchronization point on slow Windows runners without changing the behavior under test. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
Temporary failures before provider dispatch can repeat on an existing attempt. Those retries must consume the same configured retry allowance as provider result failures, or a run can remain pending without limit. Count each active retry release and stop retrying when the provider profile's limit is exhausted. Retries before an attempt exists remain unaffected. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
Untracking ends the current provider attempt, but a later enrollment must be able to enrich the unchanged person again. Reusing the revision-based trigger returned the terminal attempt because the durable request hash was unchanged. Give each new tracking enrollment its own trigger identity. Repeated tracking without an intervening untrack remains idempotent, and historical attempts stay available for audit. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
Person profile components share one revision even when a change does not alter the provider request. A result for the earlier revision must remain rejected, but deleting its work prevents the current person from being enriched. Keep replacement identity work only when terminal settlement detects a newer person revision. Ordinary terminal outcomes remain final. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
Profile cleanup and privacy changes must not commit while a provider start or poll is using their authority. Reuse the durable dispatch marker for each poll so the fence covers only the network call and does not block later identity or result invalidation. Manual idempotency keys deliberately outlive person deletion. Resolve their immutable historical target before checking current person authorization so a replay returns the original run. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
The retry-limit test tried to reclaim a poll scheduled one nanosecond in the future. On Windows, both clock reads can share the same tick, so the second worker pass observes no due work and never reaches the second failure. Advance the worker clock past each persisted due time. This tests retry accounting without relying on host clock resolution. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
A poll authorization marker fences privacy changes only while the owning worker performs the provider call. If that worker exits before settlement, the marker must not outlive its expired lease or a replacement cannot reauthorize the same durable job. Clear the marker when a pending attempt is reclaimed. Keep the marker for a starting attempt because its provider-start outcome remains uncertain. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
Catch-up repairs work from tracking and consent snapshots. Without the same authority gate as revocation, authority removal can finish between selection and publication, which lets stale work reappear or causes SQLite contention. Take the gate before both catch-up reads and work updates. Authority removal then follows publication and deletes its work, or publication observes the removed authority. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
The catch-up concurrency test has several assertions. The repository rejects repeated package-level testify calls, so the lint job fails after the behavior tests pass. Use local assertion helpers to meet the test style contract without changing the test scenario or its checks. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
Provider requests include current employers and CardDAV-projected identity fields. Changes to those sources must retire earlier provider bindings and replace work built from the old identity. Limit organization invalidation to current employees affected by a rename, lifecycle change, or merge. Route CardDAV projection changes through the same identity boundary. The PostgreSQL attempt gate now serializes the request-budget test before its old two-party barrier. Remove that obsolete barrier so the test exercises the production ordering instead of waiting forever. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
Exa search input must not disclose an insecure or local profile URL. Apply the adapter's public HTTPS policy before attempt creation and again before the HTTP request leaves the process. An expired worker lease no longer represents a live provider call. Let profile cleanup settle an abandoned start while active starts and polls remain fenced. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
Person deletion and merge absorption remove person-owned attempts through a database cascade. A reserved provider cost must be settled first, or run and provider-day accounting retain a reservation with no attempt left to close it. Use the existing invalidation fence so active provider calls still block removal and inactive work settles before the person row is deleted. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
roborev: Combined Review (
|
What changed
Why
The person fact ledger from #677 can ingest claims from any producer, but public-web enrichment previously had no privacy-preserving path to it. This adds the opt-in external enrichment stage of the profile-maintenance design (#534): minimum egress, durable accounting, and keyed suppression make provider access auditable and revocable end to end.
Usage
Stacked on #677. Refs #534