<summary>Update a single prospect's stage, data, send priority, and/or stored
contact info (email address, LinkedIn profile URL). `stage` is applied to
`channel`'s per-channel stage (channel='email' → email_stage, channel='linkedin'
→ linkedin_stage), and `person` is resolved within that channel. For companies,
call update_monitored_company. To change contact info, ALWAYS update the existing
prospect through this tool (or retry_blocked_enactment for a blocked one) — never
re-add the person via track_prospects or a sequence call with the new info, which
creates a duplicate prospect row.
Set `priority=True` to push this person's queued sends — email and LinkedIn alike —
ahead of everyone else's; it's account-wide and durable, carrying across the sequence's
later steps for this person. `priority=False` clears it. One priority flag per prospect,
independent of `channel`: both channels' derived send order reads it.
Most stage transitions — sent, connected, messaged, replied — stamp
automatically from send and reply detection; don't set those by hand. The three
reply-outcome rungs above `replied` — `interested`/`meeting_booked` (positive) and
`not_interested` (an explicit decline) — normally stamp from the reply classifier
too, so set one by hand only to fix a wrong call or record an off-platform outcome:
stage='interested' for clear interest, stage='meeting_booked' when they agree to or
book a meeting, stage='not_interested' when they've declined. The mark only raises a
rung — a decline can't override a live positive (to lower a false
meeting_booked/interested, correct that reply with `correct_reply_outcome`) — and it
counts the person as replied, so to drop someone who never engaged use stage='skipped'.
Setting a reply-outcome rung also cancels the person's still-pending queued outreach
on both channels — automation stops; messages you queue afterwards still send.
A later positive reply lifts `not_interested` back up on its own.
When you set stage='skipped', pass skip_note with the reason in a few words,
so a later reader knows why this person was dropped without digging up the
chat — a bare skip records no reason.
To reverse a skip and put the person back in the funnel, set stage to the rung they
should resume at — normally stage='pending' to re-queue them from the top. That
re-enters them into outreach (a still-skipped prospect is held out of every send) and
clears the stale skip note; their flow position is preserved, so the sequence resumes
from where they were rather than restarting a step already taken.
To store an address you found for a prospect that reached an email step without
one (recovering an `email_not_found` block), pass `email`. Resolve that prospect
by its LinkedIn handle — channel='linkedin' — since a blank-email prospect has no
email to match on; the stamped address makes the step send when you retry it. For
a blocked prospect, `retry_blocked_enactment(email=...)` stamps and retries in
one call instead.
To undo an accidental hand-set mark (e.g. a prospect wrongly marked meeting_booked),
pass `clear_manual_mark=True` on `channel` — it removes the mark and re-derives the
stage from actual send/reply activity, the only way to lower past a manual mark (which
the mark path deliberately floors demotions at). This differs from `correct_reply_outcome`,
which re-judges a specific reply; use clear_manual_mark when the wrong rung came from a
hand mark, not a misjudged reply. Pass it on its own (no stage/data/priority/email).</summary>
<returns>
<description>Dict with the updated item details. After an `email` stamp, `profile_note` is
present only when the person's profile was left as it was because another
person in the workspace already carries that address — the campaign row still
took it; pass the note on to the user.</description>
</returns>