Context
PurposePath_Api has completed and deployed the NotificationProcessor side for issue #912 with EventBridge-first AI kickoff + API fallback.
Backend references:
Goal
Implement the AI-side async handshake so email insight requests can be consumed via EventBridge and resolved via existing job-status API semantics, while preserving canonical payload semantics across transports.
Required Handshake Contract (AI side)
1) EventBridge kickoff consumption
Consume EventBridge entries with routing keys:
- source = configured backend source (default
purposepath.api)
- detail-type = configured kickoff type (default
ai.job.requested)
- event bus = configured backend bus (default
default)
Expected EventBridge detail payload shape (minimum):
{
"eventId": "uuid",
"occurredAtUtc": "2026-04-09T13:00:00.0000000Z",
"sourceService": "PurposePath.NotificationProcessor.Lambda",
"schemaVersion": "2.0",
"correlationId": "corr-123",
"idempotencyKey": "req-123:goal_created_email_insight:uuid",
"retryAttempt": 0,
"tenantId": "tenant-1",
"userId": "user-1",
"topicCategory": "email_insight",
"topicId": "goal_created_email_insight",
"eventSignal": "goal_created_email_insight",
"locale": "en-US",
"timezone": "UTC",
"activityData": {
"goal_id": "goal-1"
},
"authContext": {
"serviceToken": "opaque-token",
"expiresAtUtc": "2026-04-09T13:05:00Z",
"issuer": "purposepath-api",
"tokenType": "service_enrichment"
},
"jobId": "job-uuid",
"eventType": "goal_created_email_insight",
"kickoffTransport": "eventbridge"
}
2) Job status contract (must stay compatible)
Backend polls AI status endpoint and expects:
{
"data": {
"status": "completed|failed|cancelled|timed_out|running|queued",
"result": {
"schemaVersion": "1.0.0",
"title": "...",
"summary": "...",
"blocks": [],
"generationMeta": {}
}
}
}
Contract rules:
- data.status is required.
- data.result is required only when status=completed.
- completed with missing/empty result is treated by backend as terminal non-success (no fallback).
3) API fallback compatibility
Backend fallback kickoff still calls POST /api/v1/ai/execute-async with the same canonical envelope semantics.
Response should remain:
{ "data": { "jobId": "job-uuid" } }
(data.job_id may be tolerated but canonical is data.jobId.)
AI Implementation Requirements
- Add EventBridge consumer for above routing keys and detail payload.
- Use detail.jobId as the authoritative async job identity.
- Persist and propagate correlation fields unchanged:
- correlationId
- idempotencyKey
- eventId
- Ensure existing status API returns the exact wrapper shape expected by backend polling.
- Ensure completed status returns valid result object matching email insight schema expectations.
- Ensure enrichment requests use authContext.serviceToken as opaque bearer token.
Fallback/Behavior Expectations from backend side
Backend will fallback to API kickoff when EventBridge path cannot resolve quickly enough:
- EventBridge publish failure
- status request HTTP failure
- status payload missing data.status
- EventBridge await window timeout
Backend does NOT fallback on:
- completed without payload
- terminal failed/cancelled/timed_out status
Acceptance Criteria
Suggested Test Matrix
Context
PurposePath_Api has completed and deployed the NotificationProcessor side for issue #912 with EventBridge-first AI kickoff + API fallback.
Backend references:
Goal
Implement the AI-side async handshake so email insight requests can be consumed via EventBridge and resolved via existing job-status API semantics, while preserving canonical payload semantics across transports.
Required Handshake Contract (AI side)
1) EventBridge kickoff consumption
Consume EventBridge entries with routing keys:
purposepath.api)ai.job.requested)default)Expected EventBridge detail payload shape (minimum):
{ "eventId": "uuid", "occurredAtUtc": "2026-04-09T13:00:00.0000000Z", "sourceService": "PurposePath.NotificationProcessor.Lambda", "schemaVersion": "2.0", "correlationId": "corr-123", "idempotencyKey": "req-123:goal_created_email_insight:uuid", "retryAttempt": 0, "tenantId": "tenant-1", "userId": "user-1", "topicCategory": "email_insight", "topicId": "goal_created_email_insight", "eventSignal": "goal_created_email_insight", "locale": "en-US", "timezone": "UTC", "activityData": { "goal_id": "goal-1" }, "authContext": { "serviceToken": "opaque-token", "expiresAtUtc": "2026-04-09T13:05:00Z", "issuer": "purposepath-api", "tokenType": "service_enrichment" }, "jobId": "job-uuid", "eventType": "goal_created_email_insight", "kickoffTransport": "eventbridge" }2) Job status contract (must stay compatible)
Backend polls AI status endpoint and expects:
{ "data": { "status": "completed|failed|cancelled|timed_out|running|queued", "result": { "schemaVersion": "1.0.0", "title": "...", "summary": "...", "blocks": [], "generationMeta": {} } } }Contract rules:
3) API fallback compatibility
Backend fallback kickoff still calls POST /api/v1/ai/execute-async with the same canonical envelope semantics.
Response should remain:
{ "data": { "jobId": "job-uuid" } }(
data.job_idmay be tolerated but canonical isdata.jobId.)AI Implementation Requirements
Fallback/Behavior Expectations from backend side
Backend will fallback to API kickoff when EventBridge path cannot resolve quickly enough:
Backend does NOT fallback on:
Acceptance Criteria
data.resultpayload compatible with current backend parser.goal_created_email_insightcase.Suggested Test Matrix