Story-3137 · functions lane

Keep asks only when evidence says they work

The onboarding bar can now leave durable, per-counsel receipts for asks returned, acted on, dismissed, and retired by real completion. Aggregate analysis can compare those receipts over time without relying on trace retention.

The distinction that protects the bar

retired by completion
  = previously returned + live completion fact observed
  before or while dismissal is recorded

retired by dismissal
  = suppression reaches infinity while completion is still false

Temporary or permanent suppression never masquerades as completion. Matter, document, WhatsApp, and Vani state remain the only completion truth. A stale bar may still emit a dismissal after the action has completed; that dismissal stays measurable, but the retirement cause remains completion.

What is durable

identity.nudge_outcome_events is an append-only, firm-RLS ledger containing only firm/user scope, registry keys, counts, and timestamps. Dismissal receipts copy the count and suppression returned by the existing dismissal upsert in the same database statement.

The honest measurement limits

“Shown” is bound to the server eligibility response. Every returned, unsuppressed measured key gets a receipt although the browser renders one sticky key, so this systematically overcounts actual impressions and repeated reads add more receipts. “Acted” is an authenticated client report through POST /app/onboarding/nudges/{key}/act; it is intentionally spoofable and replayable, so reports should count distinct callers.

Scope boundary

No nudge key, eligibility predicate, backoff rule, dashboard, reporting UI, model call, manual trace span, or behavior decision changed. Existing HTTP/database auto-instrumentation remains the observability floor.