Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion services/imessage-bridge/src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7373,7 +7373,12 @@ export class IMessageSession {
// PROACTIVE INGESTER (unknown senders): appointment confirmations →
// surface to the owner + offer to add to the calendar; marketing/spam →
// suppress (no auto-reply). Behind LANTERN_APPT_INGEST (default on).
const ingest = await this.maybeIngestUnknownInbound(row.handle, text).catch(() => "pass" as const);
// DM-only, matching every sibling proactive-scan block above and the
// WhatsApp equivalent (isGroupJid guard) — a group participant's message
// is never an "unknown sender" appointment confirmation to swallow.
const ingest = !isGroup
? await this.maybeIngestUnknownInbound(row.handle, text).catch(() => "pass" as const)
: ("pass" as const);
if (ingest === "handled") {
// No silent drops: an unknown-inbound message owned by the life-event /
// appointment ingester means the CONTACT got no auto-reply. Leave a trace
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { describe, it, expect } from "vitest";
import { readFileSync } from "node:fs";

// Regression: PROACTIVE INGESTER (maybeIngestUnknownInbound) is designed for
// unknown 1:1 senders ("appointment confirmations from an unrecognized
// number"), but its iMessage call site had no !isGroup guard — unlike every
// sibling proactive-scan block in this file (style-learning, inner-circle
// agentic, proactive-memory) and unlike the WhatsApp bridge's own
// maybeIngestUnknownInbound (`!this.isGroupJid(from)`). A group participant's
// message pattern-matching delivery/appointment language got silently
// swallowed — "contact reply suppressed — unknown-inbound owned by
// life-event/appointment ingestion" — inside live GROUP threads, confirmed
// live 2026-08-18 (chatRowid 2656, isGroup:true) and reconfirmed repeatedly.
// This only fixes the group-scope leak; whether a genuine 1:1 unknown-sender
// appointment text should ever get a contact-facing reply is a separate,
// still-open product question (introspect state.json).

describe("maybeIngestUnknownInbound call site is DM-only", () => {
const src = readFileSync(new URL("./session.ts", import.meta.url), "utf8");

it("the call site checks !isGroup before invoking the ingester", () => {
const anchor = "const ingest = ";
const site = src.slice(src.indexOf(anchor), src.indexOf(anchor) + 300);
expect(site).toMatch(/!isGroup/);
expect(site).toMatch(/maybeIngestUnknownInbound/);
});
});
Loading