87 lines
4.9 KiB
Markdown
87 lines
4.9 KiB
Markdown
|
|
# specialist-auto-qualify.contract
|
||
|
|
|
||
|
|
**Subfeature:** `auto-qualify-draft`
|
||
|
|
**Tenancy:** Per-Person specialist instance.
|
||
|
|
**API plane:** `platform.api` (black). New routes prefixed `/auto-qualify/*`.
|
||
|
|
**Triggers:** Subscribes to `prospect_touchpoints` insert events from `specialist-prospect-resolver`.
|
||
|
|
|
||
|
|
## Scope
|
||
|
|
|
||
|
|
For each new inbound touchpoint, produce within 5s: a calibrated score, an action class, and a voice-matched draft reply. Hand off to the provider's surface (chat or web FE) via the existing `approval-card` primitive.
|
||
|
|
|
||
|
|
## Reads
|
||
|
|
|
||
|
|
| Source | Purpose |
|
||
|
|
|--------|---------|
|
||
|
|
| `prospects`, `prospect_touchpoints` (existing) | Local prospect state, message history. |
|
||
|
|
| `prospect_subject_aggregates` (graph) | Cross-provider fingerprint, outcomes histogram. |
|
||
|
|
| `provider_voice_profile` (new, derived from past sent messages) | Voice features for draft generation. |
|
||
|
|
| `provider_qualifications` (new) | What this provider needs to know to engage (form fields, gating questions). |
|
||
|
|
| `coop_peer_attestations` | Safety flags → suppress drafting. |
|
||
|
|
| Local copilot context (calendar, current capacity) | Whether to propose a slot vs. a soft-decline. |
|
||
|
|
|
||
|
|
## Writes
|
||
|
|
|
||
|
|
| Target | Purpose |
|
||
|
|
|--------|---------|
|
||
|
|
| `qualify_scores` (new, append-only, keyed on touchpoint) | Score + class + feature provenance. Powers replay + strategist analytics. |
|
||
|
|
| `drafts` (new) | Composed draft + voice-match metadata; surfaced via `approval-card`. |
|
||
|
|
| `corrections` (existing, fed by send/edit/decline/suppress events) | Per-provider improvement loop. |
|
||
|
|
| `audit_log` | Every drafting decision is replayable. |
|
||
|
|
|
||
|
|
## Never list
|
||
|
|
|
||
|
|
- **Never** auto-send a draft. The draft is always queued for a human tap. No exceptions, no "high-confidence auto-send" mode.
|
||
|
|
- **Never** quote another provider's message content in a draft (even paraphrased; the draft must be composable from sender content + local context + anonymised graph signal only).
|
||
|
|
- **Never** name a graph contributor or expose network-internal attribution in a draft.
|
||
|
|
- **Never** propose a calendar slot the provider's calendar does not actually have available.
|
||
|
|
- **Never** draft for a touchpoint flagged by `K-safety-blocklist`; route to suppression instead.
|
||
|
|
- **Never** exceed the 5s p95 latency budget without surfacing a partial response (score+class without draft).
|
||
|
|
- **Never** generate a draft for a tenant other than the local Person's; cross-tenant drafting is out of scope (that's `warm-intros`).
|
||
|
|
|
||
|
|
## Correction lens
|
||
|
|
|
||
|
|
Every provider action on a draft is a label:
|
||
|
|
|
||
|
|
| Action | Label |
|
||
|
|
|--------|-------|
|
||
|
|
| Send as-is | Positive on draft + class + score. |
|
||
|
|
| Edit then send | Diff-as-correction on draft; score/class retained. |
|
||
|
|
| Decline (override class) | Class correction; updates classifier. |
|
||
|
|
| Mark "wrong score" | Score correction; updates calibrator. |
|
||
|
|
| Suppress (safety) | Hard negative; reinforces the safety path. |
|
||
|
|
|
||
|
|
Corrections flow through `mcp__quinn-prospector__*` and update per-provider calibration nightly.
|
||
|
|
|
||
|
|
## Inputs (MCP tools / endpoints)
|
||
|
|
|
||
|
|
- `mcp__platform-prospecting__qualify_score(touchpoint_id)` — synchronous score+class; returns under 1s.
|
||
|
|
- `mcp__platform-prospecting__qualify_draft(touchpoint_id, class_override?)` — produces a draft; returns under 5s p95.
|
||
|
|
- `mcp__platform-prospecting__qualify_replay(score_id)` — feature provenance for audit.
|
||
|
|
- `mcp__platform-prospecting__qualify_correct(score_id, correction)` — accepts a labeled correction.
|
||
|
|
|
||
|
|
## Outputs
|
||
|
|
|
||
|
|
- To the provider's surface: an `approval-card` payload (per `approval-card.screen.md`) with class, score, draft, and one-line rationale.
|
||
|
|
- To `specialist-strategist`: anonymised qualify-funnel metrics (class distribution, edit-distance distribution, send-rate by class).
|
||
|
|
- To `specialist-graph-resolver`: outcome contributions when a draft converts to a booking (closes the graph loop).
|
||
|
|
|
||
|
|
## Failure modes
|
||
|
|
|
||
|
|
| Mode | Behaviour |
|
||
|
|
|------|-----------|
|
||
|
|
| Graph degraded | Score from provider-local features only; surface a "graph offline" badge on the draft card. |
|
||
|
|
| Voice profile cold (new provider) | Conservative default voice; explicitly mark "voice still calibrating" on cards for first N=50 sends. |
|
||
|
|
| Latency budget breach | Return score+class without draft; surface `approval-card` in a "score-only" state. |
|
||
|
|
| Calendar lookup fails | Suppress slot proposal in draft; ask the qualifying question instead. |
|
||
|
|
| Safety flag race | If a flag appears mid-draft, the draft is discarded and the touchpoint routes to safety. No partial leak. |
|
||
|
|
|
||
|
|
## Related docs
|
||
|
|
|
||
|
|
- `auto-qualify-draft.brief.md`, `auto-qualify-draft.screen.md`
|
||
|
|
- `cross-provider-graph.contract.md` (upstream signal)
|
||
|
|
- `@features/ai-copilot/docs/specialist-triage.contract.md` (peer specialist; auto-qualify supersedes its qualification responsibilities, triage continues to route)
|
||
|
|
- `@features/ai-copilot/docs/specialist-prospect-resolver.contract.md` (touchpoint producer)
|
||
|
|
- `@features/ai-copilot/docs/approval-card.screen.md`
|
||
|
|
- `@features/ai-copilot/docs/00-system-voice.md`
|