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, prose reconciled 2026-09-02. Verify before starting β€” this page decays fast: #3147 closed 2026-08-31 β€” its premise was confirmed stale, not left open for later. 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). One gating precondition remains: the silent-audience-drop (#3243) still needs a fix before any scope-classified tenant enables nudges β€” the ungated-extraction issue (#3116) and the recipient-list issue (#3147) both closed, resolved. Event-driven nudges are parked, not closed: the owner reversed the 2026-08-30 won't-do ruling on 2026-08-31 β€” the triggered-handlers story (#1033) and its five acceptance claims (#1034–#1038) are open again, carrying state:parked as deferred future scope; the nightly cadence remains the product for now.
1 open β€” 1 open p1 gating precondition (#3243) Β· one open product decision Β· 5 granular claims + their parent story reopened 2026-08-31 and parked, not closed.

Measured

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

Open work

Gating precondition β€” 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.

Event-driven nudges β€” reopened and parked 2026-08-31

The triggered-handlers story (#1033) and all five of its acceptance claims (#1034–#1038) were closed won't-do on 2026-08-30 as part of a nine-issue group ruling, then reopened on 2026-08-31 β€” the owner reversed the ruling: "this is valuable future scope we intend to build, not scope we are declining… Closing it was my recommendation and it was wrong. 'No code exists and nothing has moved in three months' is evidence about scheduling, not about intent." All six now carry state:parked β€” open, out of the startable queue, deferred rather than declined. Full detail in History.

What this leaves: the nightly cadence is the product for now. This track is about whether the nightly nudge reaches the right person with the right words, not about event-driven delivery, unless the un-park condition on #1033 is met.

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 remaining gating gap live. Then the one gating precondition left (#3243 silent audience drop) β€” its two former companions, #3116 (ungated extraction) and #3147 (stale-premise recipient list), both closed resolved and moved to History. The event-driven work that used to sit last, closed won't-do on 2026-08-30, was reopened and parked on 2026-08-31 (#1033, #1034–#1038) β€” open again but out of the startable queue, so it still does not sort against the live gating item.

Deliberately ignored: issue age and filing order; priority labels alone; 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 before it closed.

What the audit found β€” generated

Evidence below is generated from the read-only audit of 2026-08-29 and reconciled against the open issues at build time. Every claim cites the issue it came from. Nothing here is a decision β€” rulings stay in the prose above, which is written by hand.

#3243 [L2-g3-w5] A linked account that resolves to no person node is silently dropped from the…prodhigh confidence

The measured condition is gone. `viewer_enumeration.py:105-131` (origin/main) derives `unresolvable_accounts = max(linked_count - (len(pairs)+suppressed), 0)` where linked_count = person_identities with user_id NOT NULL and the bound set comes from viewer_bindings. Prod query (Supabase MCP, run 2026-08-29): Regina has linked_identities=3 and viewer_bindings=3 -> unresolvable_accounts = 0. Every other tenant with a linked identity is also 1/1. pg_cron job 33 `reconcile-viewer-bindings` runs `public.reconcile_viewer_bindings_all()` hourly, last succeeded 13:17 UTC 2026-08-29, so the repair is continuous, not a one-off. The DESIGN half of the issue is unchanged on main: `nightly_orchestrator.py:133-137` still carries the counter on the result model with a comment explaining a warning log 'reaches nobody', and the value only lands in one `logger.info` line (nightly_orchestrator.py:255-263) β€” there is no raise, no alert, no platform-admin signal. `git grep unresolvable_accounts origin/main` (whole repo) returns only the model, the log line, the repo derivation and tests; no alerting consumer.

Open questions β€” what the audit could not settle
  • #3243 Question 3 of the issue (is the same account unresolvable on surfaces other than the nudge) cannot be answered retrospectively β€” the offending binding no longer exists. Closable going forward by: `select t.name, count(*) filter (where pi.user_id is not null) linked, (select count(*) from viewer_bindings vb where vb.tenant_id=t.id) bound from tenants t left join person_identities pi on pi.tenant_id=t.id group by 1,t.id having count(*) filter (where pi.user_id is not null) <> (select count(*) from viewer_bindings vb where vb.tenant_id=t.id)` run on a schedule; today nothing runs it.

15 assessed issues closed since the audit and are not shown β€” a closed issue's evidence is history, and printing it as current is how a page starts lying.

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, closed 2026-08-31). 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. Closed after a verification pass, confirmed independently by an adversarial critic that re-derived every p0/p1 verdict: viewer_identity_bridge.py is gone, the recipient list reads only viewer_bindings, and the suppression-skip ordering (#3079) that its one open caution named is satisfied structurally at viewer_enumeration.py:220.

#3116 (closed 2026-09-01) β€” disclosure gating landed. Closed by the 2026-08-29 track reconciliation: proactive/disclosure.py exists with disclosed_recent_messages / disclosed_recall_topics, imported and called from the nudge substrate (substrate.py:345,477). Live exposure had already measured at zero (2026-08-07 census below); this closed the design gap the census could not.

#1033 and its acceptance claims (#1034–#1038) β€” closed won't-do 2026-08-30, reopened and parked 2026-08-31. An owner ruling grouped this with eight sibling issues as not-planned scope from the May-2026 demo-roadmap epics. The next day the owner reversed it: "this is valuable future scope we intend to build, not scope we are declining… 'No code exists and nothing has moved in three months' is evidence about scheduling, not about intent." All six issues are open again, tagged state:parked β€” deferred, not declined; still no trigger-handler module, dispatch, or test on origin/main as of the 2026-08-30 reconciliation pass.