{"record":{"id":"4bbe60194ba25df3","repo":"astrid-runtime/astrid","slug":"our-own-event-is-delivered","errorCode":null,"errorMessage":"our own event is delivered","messagePattern":"our own event is delivered","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-gateway/src/routes/stream.rs","lineNumber":310,"sourceCode":"\n        // Publish a foreign-principal lifecycle event FIRST, then our own.\n        // The foreign one must be dropped at enqueue; the recv must surface\n        // OUR event, proving the scope filters by publisher principal.\n        bus.publish(ipc_event(\n            \"session.v1.event.created\",\n            \"mallory\",\n            serde_json::json!({ \"kind\": \"created\", \"session_id\": \"m1\", \"summary\": null }),\n        ));\n        bus.publish(ipc_event(\n            \"session.v1.event.created\",\n            me,\n            serde_json::json!({ \"kind\": \"created\", \"session_id\": \"a1\", \"summary\": null }),\n        ));\n\n        let event = feed_rx\n            .recv(Some(Duration::from_secs(2)))\n            .await\n            .expect(\"our own event is delivered\");\n        let AstridEvent::Ipc { message, .. } = &*event else {\n            panic!(\"expected an IPC event\");\n        };\n        // The delivered event is OURS — the foreign one was dropped at\n        // enqueue, so the very first (and only) event on the route is alice's.\n        assert_eq!(message.principal.as_deref(), Some(me));\n        if let IpcPayload::RawJson(v) = &message.payload {\n            assert_eq!(\n                v[\"session_id\"], \"a1\",\n                \"must be our session, never mallory's\"\n            );\n        } else {\n            panic!(\"expected RawJson payload\");\n        }\n\n        // No second event: the foreign publish never entered the route's\n        // budget. A short timeout confirms the route is now empty.\n        assert!(","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-gateway/src/routes/stream.rs#L292-L328","documentation":"This panic comes from `.expect(\"our own event is delivered\")` on `feed_rx.recv(Some(Duration::from_secs(2)))` in `scoped_feed_drops_foreign_principal_events`. It fires when no event arrives within the 2-second window (recv timed out or the feed closed). The test expects alice's own event to be the first delivered after a foreign-principal event was dropped at enqueue.","triggerScenarios":"The scoped feed never delivers alice's published event within 2s: the event was dropped by the principal filter, published on the wrong topic, the feed subscription filtered everything, or the receiver channel closed (recv returns None instead of Some).","commonSituations":"Publisher/consumer principal mismatch in the fixture; topic prefix constants changed; event-bus backpressure or slow CI causing the 2s window to be missed; the enqueue-time drop logic now also drops own events (over-filtering).","solutions":["Confirm the event is published with principal matching `me` so the scoped filter keeps it.","Check the scoped-feed drop-at-enqueue logic did not begin filtering out the owner's own events.","Widen the 2s recv window or retry loop for slow CI environments.","Distinguish timeout vs closed channel by matching on recv's None/Some result for a clearer failure."],"exampleFix":"// before\nlet event = feed_rx.recv(Some(Duration::from_secs(2))).await.expect(\"our own event is delivered\");\n// after\nlet Some(event) = feed_rx.recv(Some(Duration::from_secs(2))).await else {\n    panic!(\"our own event is delivered: no event within 2s (timeout or feed closed)\");\n};","handlingStrategy":"retry","validationCode":"assert_eq!(event_principal, me, \"publish with the feed owner's principal\");","typeGuard":null,"tryCatchPattern":"let Some(event) = feed_rx.recv(Some(Duration::from_secs(2))).await else {\n    panic!(\"own event not delivered within 2s\");\n};","preventionTips":["Publish events stamped with the subscriber's principal","Use retry-with-deadline rather than a single fixed recv window","Test the drop-at-enqueue filter with both foreign and own events"],"tags":["rust","tokio","test","timeout","event-bus"],"backgroundTag":"request-timeout","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}