Filter framework-internal message types from observability surfaces#2524
Merged
jeremydmiller merged 1 commit intomainfrom Apr 16, 2026
Merged
Filter framework-internal message types from observability surfaces#2524jeremydmiller merged 1 commit intomainfrom
jeremydmiller merged 1 commit intomainfrom
Conversation
…2520) ServiceCapabilities and IWolverineObserver hooks (MessageRouted, MessageCausedBy) were leaking framework-internal message types — IAgentCommand implementations from Wolverine.RDBMS, ISideEffect/IMartenOp/ IPolecatOp return types, etc. — alongside user message types. The previous filter only checked an assembly-level [ExcludeFromServiceCapabilities], which catches Wolverine.dll itself but misses persistence assemblies and provides no per-type opt-out. Changes: - Add IInternalMessage marker interface for fast per-type filtering (preferred to attribute lookup — single runtime type-test) - Add internal SystemMessageTypeExtensions.IsSystemMessageType() helper centralizing the four checks: IInternalMessage, IAgentCommand, INotToBeRouted (covers ISideEffect, ICritterWatchMessage, etc.), assembly attribute - Apply the filter in three emission sites: * ServiceCapabilities.readMessageTypes() — replaces assembly-only check * WolverineRuntime.Routing — gates Observer.MessageRouted() * MessageHandler.RecordCauseAndEffect — gates Observer.MessageCausedBy() on both incoming and outgoing message types - Mark Wolverine-owned persistence assemblies with [assembly: ExcludeFromServiceCapabilities] (defense in depth): RDBMS, Postgresql, SqlServer, MySql, Sqlite, Marten, Polecat, EntityFrameworkCore, Oracle - Add tests verifying the helper and end-to-end filtering through both ServiceCapabilities and IWolverineObserver Closes #2520 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced Apr 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #2520.
ServiceCapabilitiesandIWolverineObserver(MessageRouted,MessageCausedBy) were leaking framework-internal message types —IAgentCommandimpls fromWolverine.RDBMS,ISideEffect/IMartenOp/IPolecatOpreturn types — into observability tooling alongside user message types. The previous filter only checked an assembly-level[ExcludeFromServiceCapabilities], which catchesWolverine.dllitself but misses persistence assemblies and provides no per-type opt-out.Audit findings (the holes)
ServiceCapabilities.readMessageTypes()— only assembly-level filter; persistence-assemblyIAgentCommandimpls leakedObserver.MessageRouted()(WolverineRuntime.Routing.cs:158) — emitted unconditionally; CritterWatch's observer filters by assembly attr +ICritterWatchMessagebut not byIAgentCommandObserver.MessageCausedBy()(MessageHandler.RecordCauseAndEffect()) — zero filtering; reported every message including system commandsApproach
IInternalMessagemarker interface — fast per-type filtering (x is IInternalMessageover reflection)SystemMessageTypeExtensions.IsSystemMessageType()helper centralizing four checks:IInternalMessage(new)IAgentCommand(catches all internal agent commands)INotToBeRouted(catchesISideEffect,ICritterWatchMessage, acknowledgements,OutgoingMessages,ValidationOutcome)[ExcludeFromServiceCapabilities](preserves existing behavior)[assembly: ExcludeFromServiceCapabilities]as defense in depth (RDBMS, Postgresql, SqlServer, MySql, Sqlite, Marten, Polecat, EntityFrameworkCore, Oracle)Files
IInternalMessage.cs,SystemMessageTypeExtensions.cs,system_message_type_filtering.cs(tests)ServiceCapabilities.cs,WolverineRuntime.Routing.cs,MessageHandler.cs, 9 persistenceAssemblyAttributes.csTest plan
IsSystemMessageTyperecognizesIInternalMessage,IAgentCommand,INotToBeRouted; returns false for normal user messages and nullservice_capabilities_excludes_system_message_types— end-to-end: build a host, assert all three system markers are filtered while a normal user message appearsobserver_does_not_receive_message_routed_for_system_types— install a recording observer, route 4 types, assert only the user type was reportedexporting_service_capabilitiestests still pass🤖 Generated with Claude Code