Mindbridge Β· track status

NIGHTLY-NUDGE

Mindbridge's only push surface β€” proactive cards delivered to a user who did not ask; today they reach the wrong people, or nobody.

Measured 2026-08-16 from live gh issue list. Verify before starting β€” this page decays fast: #3147's premise already went stale when the recipient list was repointed. Never published; publish fresh per docs/status/artifacts.json.

Next β†’Decision β€” per-user opt-out: the only consent control is the per-tenant flag, so widening enablement needs the owner's ruling first (raised on the closed #3079). Code is latent/gated: the silent-audience-drop (#3243) and the ungated-extraction (#3116) measure zero live exposure, the recipient-list issue (#3147) is stale-premise, and the five granular claims (#1034–#1038) wait on the triggered-handlers story (#1033).
8 open β€” 2 latent p1s Β· 1 stale-premise p2 Β· 5 gated granular Β· zero live exposure Β· one open product decision.

Measured

8Open issues
4Tenants nudges on
2Active Β· 1 viewer each
0Scope-classified on them
0Live exposure
Tenant figures from the prod census recorded on #3116 (2026-08-07); the open-issue count is live at build time.
Open work Why this order Rulings History

Open work

Gating preconditions β€” fix before any scope-classified tenant enables nudges

p1 #3243 A linked account that resolves to no person node is silently dropped from the nightly nudge audience β€” Regina's audience is halved half of Regina's audience dropped Enterprise
Regina has 2 bound accounts; one resolves to no person node, so half the tenant's nudge audience gets nothing β€” silently, with no explanation and no alert, indistinguishable from a quiet week. The run reports success because the viewers it could resolve were all served. Its third question decides scope: if the binding is broken everywhere, this is VIEWER-TRUTH reconciler work, not a nudge fix. Shared with VIEWER-TRUTH.
p1 #3116 Nightly-nudge event extraction has no tier or disclosure gating at all no disclosure gate on push Latent
app/services/proactive/ extracts events from messages and splices a name + message excerpt into a pushed card with no disclosure evaluation on any path. Measured on prod 2026-08-07: live exposure is zero and structurally so β€” the active nudge tenants have no scope-classified messages, and Regina (the one tenant that does) has nudges off. Fix before any scope-classified tenant enables nudges.

Stale-premise cleanup β€” re-read before acting

p2 #3147 The nightly-nudge recipient list is a fourth answer to "which person node is this account?" stale premise β€” already repointed Dev only
πŸ›‘ Premise stale β€” re-read before acting. Its 2026-08-08 comment records both arms are gone: the recipient list now reads viewer_bindings (the same row every serving surface resolves through), so it is no longer a fourth answer and no longer blocks deleting the owner stamp. Open only to decide whether anything remains.

Gated future work β€” event-driven nudge acceptance claims

p2 #1034 Granular: Trigger handler exists with documented trigger types gated on five unfinished dependencies Latent
Acceptance claim: the trigger handler exists with documented trigger types. Hangs off #1033.
p2 #1035 Granular: Async/queued dispatch (non-blocking) gated on five unfinished dependencies Latent
Acceptance claim: dispatch is async/queued and non-blocking. Hangs off #1033.
p2 #1036 Granular: Noise filter applied gated on five unfinished dependencies Latent
Acceptance claim: the noise filter is applied. Hangs off #1033.
p2 #1037 Granular: Dedupe + snooze respected gated on five unfinished dependencies Latent
Acceptance claim: dedupe and per-contact snooze are respected. Hangs off #1033.
p3 #1038 Granular: Integration test passes gated on five unfinished dependencies Latent
Acceptance claim: the integration test passes. Hangs off #1033.
Why is it in this order?

Top to bottom. The blocking product decision first β€” the index pill is Needs a call, and nothing below can safely move until the owner rules on a per-user consent control, because widening enablement without one is what would turn the latent defects live. Then the two gating preconditions (#3243 silent audience drop, #3116 ungated extraction) β€” fix before any scope-classified tenant enables nudges; silent loss outranks a disclosure gap. Then stale-premise cleanup (#3147). Then gated future work (#1034–#1038), blocked on #1033's five dependencies.

Deliberately ignored: issue age and filing order (the five granular items are the oldest and sort last); priority labels alone (the two p1s are latent today, and the granular items were re-rated from an inherited p1 to p2/p3 on 2026-08-14); how cheap or well-understood an item looks; and the severity a body asserts before exposure was measured β€” #3116's body said it "may matter more than #2906", but its follow-up measured live exposure at zero.

Standing rulings

None recorded β€” the decided array for track:nightly-nudge in track-order.json is empty.
History Β· forensics

Census (prod, 2026-08-07, from #3116's follow-up). Every persisted nudge card was surfaced — 360 cards (229 event, 129 shift, 2 reachout), resolving to 611 card→message pairs. Every pair is scope IS NULL and tier-3-by-default, 0 genuinely scope-classified. Four tenants have proactive_nudges_enabled, two empty; the two active tenants (Ahmed El-Daly, Sudqi) carry one viewer each and zero scope-classified messages. Regina — the only tenant with real restrictive scopes (51,831 scoped messages) — does not have nudges enabled. Hence zero live exposure, structurally, not coincidentally.

Panel provenance (#3147). Found by the VIEWER-TRUTH W2 adversarial panel, which grepped for method names and missed these two files that build the query inline. Recorded as a trap in .ai/choke-points.md β€” census by access pattern, never by method name. Its 2026-08-08 comment declared the premise stale: the recipient list now reads viewer_bindings.