# AI preparation: source review and staff drafts

## What it does

Step 8 adds optional preparation in Follow up: quoted pending customer facts, explicit conflict decisions, an advisory summary and editable call/WhatsApp/email drafts. The interface displays all seven readiness areas for every customer. Initial enquiries explain which areas require a purchase journey, and a manager can create one before selecting a property.

## How it works

### Evidence and authority

`SourcePacketLoader` rereads the original authorized WhatsApp, email, Portal question/concierge, Zoom, Phone Call or Showroom F2F source. It requires a current accepted match. Recording text comes from the transcript, never a prior AI summary. Speaker A/B labels are unknown until staff explicitly map a customer speaker against the exact transcript revision. Unattributed recordings can produce an advisory summary, but no customer facts.

A request is committed to the immutable journey ledger before dispatch. The job rereads source, actor access and context before calling the existing AI client and again before storing results. At most 12 validated pending assertions are saved. Retrying a completion cannot duplicate them. Normal confirmation, rejection and edited replacement commands remain atomic, version checked and auditable. Confirming a conflicting proposal requires the exact prior fact to still be current. Edited facts retain the original source and proposal lineage.

AI facts and human-edited AI facts are rechecked against original text and source permissions at every read/review. Revoked source access removes them from that viewer's projection. Confirmed facts are visible through ordinary field access; pending suggestions stay limited to manager preview until the evaluation gate passes. An AI opt-out signal only asks staff to review the actual words; existing contact policy owns suppression.

A person can explicitly accept a purchase suggestion. Creation itself does not confirm its pending facts. First-purchase intake evidence uses immutable relevance links and retains original reviews; a later change requires checking relevance again. Inherited fields link to the initial enquiry for review.

### Drafts

Drafts use current confirmed facts, recent authorized conversation and the current next step. They are generated only on request, returned with private/no-store, editable in the dialog and not saved by this feature. They are rechecked against access/contact restrictions after the provider returns. A generated draft never calls a sender. Source links and the existing inbox open separately; staff decide what to send there.

### Privacy and traces

IC-like identity numbers are masked before the provider call. Raw general-purpose AI request logging is disabled for these jobs. The extraction completion ledger holds hashes, version, provider/model reference, token counts, timing and discard reasons. Redacted request messages and output are encrypted with the application encrypter into `audit_ciphertext`; no browser DTO exposes that payload. Support access requires restricted server/database access. Customer purge includes the journey ledger. Scheduled 12-month retention execution belongs to Step 9; this release does not claim it is active.

### Release controls and recovery

- `journey.extraction_enabled`: existing master extraction setting, also subject to the journey write switch.
- `JOURNEY_AI_GENERAL_ENABLED=false`: pending suggestions/drafts limited to scoped managers. Do not enable until the independent 20-recording mixed-language evaluation passes.
- `JOURNEY_AI_SCHEDULED_ENABLED=false`: optional background dispatch remains off in the manager preview.
- `JOURNEY_AI_SCHEDULER_ACTOR_UUID`: required explicit authorized staff identity before scheduled analysis can run.
- `journey:extract --dry-run --limit=1`: checks a bounded batch without writes/dispatch. Normal runs consider recent seven-day sources, at most 200 sources and ten requests per pass, rotate through older eligible sources, and never send messages.
- Stale queued requests can be redelivered after 30 minutes, at most once per hour per request. A job's terminal ledger prevents duplicate completed extraction. Failed fingerprints get at most three scheduled attempts with hourly backoff; staff may deliberately request fresh analysis.
- The scheduled dispatcher is registered every five minutes, but its separate flag prevents activity until explicitly activated. No bulk historical provider replay occurs when manager preview is enabled.

Provider/model routing uses `journey_extraction` and `journey_draft` in the existing AI prompt registry. No alternate provider is introduced or pinned by this change.

### Validation boundary

Feature/unit/browser tests verify pending evidence, exact conflict head, no duplicate writes, source revocation, speaker mapping, draft restrictions and seven-area UI. Synthetic fixtures are not evidence of multilingual extraction accuracy. The labelled recording gate and staff UX trial remain separately recorded acceptance checks.

## Related files

- `ai-validation-contract.md`
- `src/RevenueJourney/Repositories/AiExtractionRepository.php`
- `src/RevenueJourney/Services/JourneyDraftService.php`
- `src/RevenueJourney/Ai/SourcePacketLoader.php`
- `src/RevenueJourney/Ai/AiEvidenceGuard.php`
- `app/Jobs/RevenueJourney/ExtractJourneySource.php`
- `app/Console/Commands/ExtractRevenueJourneySources.php`
- `config/readiness_ai.php`
- `resources/js/Pages/Manage/Ai/Copilot/Journey/AiPreparation.vue`
