f8522edacd
The bridge cannot classify what it never emits. Fleet-health monitoring — detect a wedged member, decide, escalate — is blocked on that, so this is the foundation rather than the feature. A survey of Injector, CompletionResolver, StatusPoller, SessionManager, SessionReaper and MessageService found six conditions that ended a member's usefulness while saying nothing useful: * Injector.drop() — worker gone, queue cleared: SILENT * CompletionResolver.fail() — "via turn-stall fallback" at DEBUG, no reason * SessionManager.onFailed() — "session marked failed" at DEBUG, no stage * SessionManager.reapIdle() — indistinguishable from any other release * SessionManager.acquire() — spawn failure rethrown with no log at all * MessageService.abandon() — failed a caller's request at DEBUG The first two are the exact phrases that misled the CB-560 diagnosis: both name a symptom and neither names a cause. They are now WARN and carry the reason, the stage, and the counts. Conditions already loud were left alone, and so were two by-design timeouts in MessageService — an async model exists precisely for those, and promoting them would turn healthy operation into noise. Behaviour is unchanged: every edit is a log statement. Merge note: the recycle test deleted by CB-565 conflicted with a test added here. Resolved by keeping the new onTurnFailed assertion and dropping the recycle test, which tests a method that no longer exists.