docs(ai-copilot): 📝 Add prospect-detail.screen.md and update specialist-prospect-resolver.contract.md, specialist-strategist.contract.md for AI copilot feature documentation

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
autocommit 2026-05-18 22:41:28 -07:00
parent b91f9da2f4
commit 2a5aaf2eef
3 changed files with 48 additions and 6 deletions

View file

@ -12,6 +12,18 @@ Implementation breakdown of [brief B](./B-drawers.brief.md) §B3 — the cross-s
│ first DM Mar 12 · last contact 2h ago │
│ [ funnel: PPV ▾ ] value: $1,420 ytd │ ← funnel chip + value-to-date strip
├────────────────────────────────────────┤
│ Touchpoint chain · [ Time-decay ▾ ] │ ← attribution model picker (per T-attr-model)
│ ┌──────────────────────────────────┐ │
│ │ Tryst (Apr 8 14:02) │ │
│ │ ↓ 19h │ │
│ │ iMessage (Apr 9 09:14) │ │
│ │ ↓ 13h │ │
│ │ OF subscription (Apr 9 22:11) │ │
│ │ ↓ ongoing · 3 tips $47 │ │
│ │ │ │
│ │ Credit: Tryst 60% · X 0% · OF40%│ │
│ └──────────────────────────────────┘ │
├────────────────────────────────────────┤
│ ⚠ Coop intel · 2 peer reports │ ← coop callout (plain register)
│ Berlin Providers · UNSAFE │
│ [ open report ] │
@ -53,6 +65,9 @@ Implementation breakdown of [brief B](./B-drawers.brief.md) §B3 — the cross-s
| `ReplyComposer` | new (B3 + P) | Channel picker (defaults to last-contact channel) + text + "ask Cocotte to draft" — routes through `mcp__quinn-prospector__draft_message`. |
| `ShareWithOrgButton` | new (W) | Cross-context handoff affordance; gated on org membership + share scope. |
| `UnresolvedIdentifierBanner` | new (B3 + P §prospect-resolver) | Renders when `prospect-resolver` has unmerged candidate identifiers for this prospect. |
| `TouchpointChain` | new (B3 + T §T-attribution) | Reads `prospect_touchpoints` for this `prospect_id`, oldest-first. Each touchpoint shows surface + kind + occurred_at; arrows show the elapsed time between consecutive touchpoints. Anonymous touchpoints never appear here (per [_engineering-surface-metrics.md](./_engineering-surface-metrics.md) §9 invariant). |
| `AttributionModelPicker` | shared (T §T-attribution-model) | Dropdown: First-touch / Last-touch / Time-decay (default) / Position-based. Same component used in T2 funnel `Top paths`. Persists to `users.attribution_model_pref`. |
| `AttributionCreditStrip` | new (B3 + T §T-attribution-model) | Per-surface credit weights for this prospect under the selected model. Shows `—` (unmeasured) for surfaces with tier-gated analytics off, never `0%` (which would falsely imply "no influence" rather than "we can't tell"). |
## States to render
@ -62,7 +77,9 @@ Implementation breakdown of [brief B](./B-drawers.brief.md) §B3 — the cross-s
4. **Funnel-stage cold** — value strip muted, hearth chip suggests "On the back burner. Want strategist to draft a re-engagement?" Reply composer still available; no auto-draft pre-filled.
5. **Peer-coop reports present** (per brief N) — `CoopIntelCallout` rendered above the timeline in plain register. Reply composer **soft-warns** but is not disabled; Quinn judges.
6. **Blocked in K1** — drawer renders for replay/audit purposes only. Composer + approval strips are disabled with a plain-register notice: "This prospect is on your blocklist. Reply disabled. Manage in safety settings."
7. **Cross-surface unresolved**`prospect-resolver` hasn't merged yet. Banner above the timeline: "2 unmerged identifiers — Cocotte is still confirming this is the same person. Showing what's matched so far." Identity line shows resolved channels only.
7. **Cross-surface unresolved**`prospect-resolver` hasn't merged yet. Banner above the timeline: "2 unmerged identifiers — Cocotte is still confirming this is the same person. Showing what's matched so far." Identity line shows resolved channels only. **Touchpoint chain stays empty** until merge resolves — anonymous touchpoints never render per-prospect (surface-metrics §9 invariant).
9. **Single-touch prospect** — only one resolved touchpoint exists. `TouchpointChain` renders the single node without arrows; `AttributionCreditStrip` shows 100% credit to that surface under any model. Strategist insight chip (working): "Single-touch prospect. Worth nudging onto a second surface — typical Felix-types convert at 3× after the second touchpoint."
10. **Chain-confidence hedge**`prospect-resolver` linked touchpoints via `identifier_hash` match but didn't confirm. Chain renders with dotted arrows + plain-register hint: "Linked by identifier hash — Cocotte's 78% confident this is the same person." Quinn can confirm/break the link from a long-press menu on any arrow.
8. **Share-with-org pending** (per brief W) — header `share` button shows a confirmation sheet before any data crosses scopes. Org-context voice shift applies once confirmed.
## Gestures
@ -71,6 +88,8 @@ Implementation breakdown of [brief B](./B-drawers.brief.md) §B3 — the cross-s
- **Swipe left on a timeline row**: set aside the draft (same semantics as A's chat cards).
- **Tap a timeline row**: opens the source's raw thread (audit-shadow view).
- **Long-press the funnel chip**: opens funnel-stage history sheet (when did this prospect move from free → tip, etc.).
- **Tap the attribution-model picker**: switches model; credit strip + insight chip recompute instantly (all 4 models pre-computed per [T §T-attribution-model](./T-analytics-dashboard.brief.md)).
- **Long-press a chain arrow**: opens "confirm / break link" sheet for hedged identifier-hash links (state 10).
- **Tap the coop callout**: opens [`coop-intel-detail.screen.md`](./coop-intel-detail.screen.md).
- **Swipe down**: dismiss to the surface that opened this drawer (chat / inbox / search / audit).
@ -125,3 +144,7 @@ Implementation breakdown of [brief B](./B-drawers.brief.md) §B3 — the cross-s
- [brief W](./W-org-overlay.brief.md) — share-with-org cross-context handoff.
- [brief K](./K-safety-blocklist.brief.md) §K1 (blocked-in-drawer), §K3c-1 (govt-name hard rule), §K3h (cross-channel identifier guard).
- [voice](./00-system-voice.md) §V2b working register · §V2c plain on coop callout + safety stubs.
- [T-analytics-dashboard.brief.md §T-attribution](./T-analytics-dashboard.brief.md) — per-prospect chain is the drilldown surface from T2 `Top paths`.
- [T-analytics-dashboard.brief.md §T-attribution-model](./T-analytics-dashboard.brief.md) — model picker shared with this screen.
- [specialist-prospect-resolver.contract.md](./specialist-prospect-resolver.contract.md) — writes the `prospect_touchpoints` rows this screen renders; handles state-10 hedged links.
- [_engineering-surface-metrics.md](./_engineering-surface-metrics.md) §4 (touchpoints schema) + §9 (privacy: anonymous-aggregate-only invariant).

View file

@ -8,31 +8,40 @@
Cross-surface identity glue. Never speaks to anyone.
## Does
Cross-surface prospect dedup (same person on Tryst + OF + iMessage gets one `prospects` row). Intent classification (browsing / engaged / paying / lapsed). Scoring (heat tier, churn risk, LTV proxy). Feeds `strategist` and `triage` with resolved prospect context.
Cross-surface prospect dedup (same person on Tryst + OF + iMessage gets one `prospects` row). Intent classification (browsing / engaged / paying / lapsed). Scoring (heat tier, churn risk, LTV proxy). **Touchpoint linking**: every new `engagement_event` is matched against existing prospects to write a corresponding `prospect_touchpoints` row (per [_engineering-surface-metrics.md §4](./_engineering-surface-metrics.md)) — including setting `attributed_to_touchpoint_id` to build the attribution chain. **Identifier hashing**: writes `identifier_hash = sha256(lower(surface || ':' || raw_identifier) || user_salt)` (per surface-metrics §9) when storing touchpoints with no resolved `prospect_id`. Feeds `strategist` and `triage` with resolved prospect context.
## Auto
- Dedup writes (matching new event to existing prospect record).
- Score updates.
- Cross-surface link assertions when match confidence > threshold.
- **Touchpoint linking**: for every new `engagement_event`, write a `prospect_touchpoints` row with `prospect_id` (resolved) or `identifier_hash` only (anonymous).
- **Chain inference**: when a resolved touchpoint follows a prior anonymous touchpoint with matching `identifier_hash`, retroactively set `attributed_to_touchpoint_id` to thread the chain. (Backward-fill is bounded — only within the past 90 days per surface-metrics §10 immutability rule.)
- **Photo-hash dedup**: when a new touchpoint carries a photo (e.g. profile_view from a surface that exposes the prospect's avatar), run perceptual-hash match against existing prospects' known photos via the ported `photo-hasher.ts` (per [_engineering-talent-scout-port.md](./_engineering-talent-scout-port.md) §"Detection module").
## Proposes
Nothing user-facing directly. Surfaces high-confidence dedup proposals through `strategist` ("This Tryst inquiry looks like the same person as last week's OF DM — link?").
Nothing user-facing directly. Surfaces high-confidence dedup proposals through `strategist` ("This Tryst inquiry looks like the same person as last week's OF DM — link?"). Surfaces **chain hypotheses** through `strategist` ("3 anonymous Tryst profile-views in the past 48h match Felix's identifier-hash — the chain that led to his OF subscription likely starts there. Backfill?").
## Never
- Contacts a prospect.
- Sends a DM.
- Posts.
- Crosses K3h channel-vs-surface separation.
- **Exposes anonymous-touchpoint rows in any prospect-scoped query** (per surface-metrics §9 invariant 2). Anonymous touchpoints are aggregate-only.
- **Stores plaintext identifiers** in `prospect_touchpoints` when no resolved `prospect_id` exists. Only `identifier_hash` is permitted.
## Correction lens
- False-dedup (Quinn says "no, these are two different people").
- Wrong tier (Quinn corrects the heat classification).
- Missed link (Quinn manually links two prospect records).
- **False chain inference** (Quinn rejects a proposed `attributed_to_touchpoint_id` link — the touchpoint chain is unset on that row).
## Surfaces
None directly — reads `engagement_events` across all surfaces.
None directly — reads `engagement_events` across all surfaces; writes `prospect_touchpoints`.
## Related
- [brief L](./L-specialists-fleet.brief.md) §L3h — original contract.
- [brief I](./I-audit-trust-replay.brief.md) — dedup decisions land in audit.
- [_engineering-surface-metrics.md](./_engineering-surface-metrics.md) §4 (touchpoints schema) + §9 (privacy invariants).
- [_engineering-talent-scout-port.md](./_engineering-talent-scout-port.md) §"Detection module" — `photo-hasher.ts` is the ported photo-dedup primitive.
- [T-analytics-dashboard.brief.md §T-attribution](./T-analytics-dashboard.brief.md) — UX consumer of touchpoint chains.
- v2 `quinn-prospector` MCP per `_engineering/v2-port-map.md`.

View file

@ -8,7 +8,7 @@
The reader of patterns. Speaks in plans, not actions.
## Does
Reads recent `engagement_events`, `content_posts` performance, `agent_actions` history, prospect funnel data. Produces weekly content plans, tour-timing windows, prospect-follow-up clustering recommendations, cohort warmth reads, OF-X funnel reads. Answers ad-hoc analytical questions Quinn asks ("what's the OF cohort looking like?").
Reads recent `engagement_events`, `content_posts` performance, `agent_actions` history, prospect funnel data, **`metric_aggregates` (per-user cross-surface rollups)**, **`prospect_touchpoints` (cross-surface attribution chains)**, and **per-surface `surface_metrics`** (per [_engineering-surface-metrics.md](./_engineering-surface-metrics.md)). Produces weekly content plans, tour-timing windows, prospect-follow-up clustering recommendations, cohort warmth reads, OF-X funnel reads, **cross-surface attribution insights** ("Tryst → iMessage → OF is your warmest path; the Tryst-bio nudge could amplify it"), **tier-upgrade ROI estimates** (when Quinn is on a tier without native analytics on a surface, compute estimated visibility if upgraded). Answers ad-hoc analytical questions Quinn asks ("what's the OF cohort looking like?", "what did Tryst contribute this month?", "which model attributes Tryst lowest?").
## Auto
Nothing. Pure proposal layer.
@ -18,15 +18,21 @@ Nothing. Pure proposal layer.
- Tour timing windows ("Berlin warmer in early Oct than mid-Sep based on prior tours").
- Prospect-follow-up clusters ("12 OF subs cooled since Berlin tease — send a follow-up cluster Friday").
- Cohort warmth digest entries.
- **Cross-surface attribution narratives** for analytics-dashboard insight chips (per [T-analytics-dashboard.brief.md §T-attribution](./T-analytics-dashboard.brief.md)).
- **Top-path drilldowns** when Quinn taps a path row in T2 funnel `Top paths` view.
- **Anomaly chat-surfacing** when a cross-surface aggregate or top-path delta crosses thresholds (per [T6c](./T-analytics-dashboard.brief.md)).
- **Tier-upgrade prompts** when computed metrics suggest a surface's hidden contribution (e.g. "Your Tryst search rank is unmeasured at Basic — upgrade to Standard for ~$47/mo would unlock 30-day analytics and probably reveal $X in Tryst-attributed revenue").
## Never
Posts. Sends DMs. Mutates anything. Acts directly on a surface. Engages a prospect.
Posts. Sends DMs. Mutates anything. Acts directly on a surface. Engages a prospect. **Writes to `surface_metrics`, `metric_aggregates`, or `prospect_touchpoints`** (read-only on all three — write authority lives at surface adapters + `prospect-resolver`).
## Correction lens
- Bad reads of cohort warmth.
- Missed seasonality.
- Wrong-frame analytics (looking at the wrong cohort, wrong window).
- Plan proposals that ignore declared vacations (brief H1) or tours (brief H3).
- **Wrong attribution model framing** (Quinn corrects: "Don't anchor on Time-decay for this question, use Last-touch — I want to see what closed.").
- **Over-weighting unmeasured surfaces** in narratives (e.g. claiming "X is 30% of your reach" when X's analytics aren't tier-enabled; strategist must use `—` not estimates in those cases).
## Surfaces
None directly — reads across all.
@ -35,3 +41,7 @@ None directly — reads across all.
- [brief I](./I-audit-trust-replay.brief.md) — strategist's proposals are tracked + corrected through audit.
- [brief H](./H-recurring-chores.brief.md) §H3 — tour-timing inputs.
- [brief L](./L-specialists-fleet.brief.md) §L3b — original contract.
- [T-analytics-dashboard.brief.md](./T-analytics-dashboard.brief.md) — strategist's front-window; consumer of all read tables.
- [_engineering-surface-metrics.md](./_engineering-surface-metrics.md) — schema reference for read paths.
- [specialist-prospect-resolver.contract.md](./specialist-prospect-resolver.contract.md) — sibling specialist that writes `prospect_touchpoints` strategist reads.
- [surface-tryst.brief.md §canonical-facts](./surface-tryst.brief.md) — tier-gating fact source; informs tier-upgrade prompts.