Hi,
Agreed, I'll create a separate thread for implementation architecture. Such an architecture could mean a lot of different things and look a lot of different ways, so let's bounce some ideas around as to how to design it.
You raise an important point, but I don't think there's cause for concern in this case. The protocol should absolutely not be aware of an implementation architecture or make implicit assumptions about it, just as it isn't aware of any service implementations. The dependency and awareness graph needs to be strictly one-dimensional:
Service Implementation A (Version X) -> Implementation Architecture B (Version Y) -> Eiffel Protocol (Edition Z)
(With the exception of the implementation architecture listing implementations as reference implementations and/or examples.)
This means that when speaking strictly from a protocol standpoint, one has to assume a certain "deliberate stupidity" in terms of how the events are used in practice. When I say that we should expect an event like EiffelIssueStatusUpdatedEvent to be emitted by the tracker, I'm carelessly switching context without explicitly flagging that - my apologies. That being said, an understanding of that pragmatic reality still has to inform the design of the protocol, or it will end up in pristine ivory tower theory-land, with little practical use. Essentially, the goal is to design a protocol that creates a space in which a conducive implementation can fit.
The mental exercise I try to perform to maintain that balance is to not deal with physical services or other implementations from the viewpoint of the protocol, but with information entities. In the case of issues, this means that the protocol has very little notion of there being an issue tracker (beyond e.g. EiffelSourceChangeCreatedEvent.data.change.tracker) as an independent entity. For all the protocol knows, every event may be emitted by a single mastermind monolith. What it does know, however, is that there is such a thing as an issue, and that there are claims that can be made about an issue's intrinsic state, and claims that can be made about things happening in relation to that issue.
Let's take an example. You have a lawn, which has various properties, one of them being its state of being neatly mowed or not. I can do things to your lawn, which may or may not alter those properties. In this simile, announcing that I have taken a lawnmower to your lawn (EiffelIssueAddressedEvent) is very different from saying that the lawn has the property of being satisfactorily mown (EiffelIssueStatusUpdatedEvent, or perhaps rather EiffelIssueStatusChangedEvent to be consistent with EiffelConfidenceLevelChangedEvent?). If everything works out as expected, it would make sense to expect one to follow from the other, but that's not guaranteed. Also, by maintaining that separation, you create a space where a separation of concerns can be made in the implementation, without requiring it. In fact, the protocol would let you use either one of the events without the other, depending on what you think you need to communicate (if all you care about is that status change, then just do that and don't bother about its cause, or the other way around).
This is very similar to how other events are defined. Think of the example of test events and EiffelConfidenceLevelModifiedEvents, for instance. Test events report the outcome of tests for a certain IUT in a certain ENVIRONMENT. In this sense they are similar to the proposed EiffelIssueAddressedEvent. This is very different, however, from drawing actual conclusions about the quality of the IUT, which is what EiffelConfidenceLevelModifiedEvent does (and in that it is similar to the proposed EiffelIssueStatusUpdated/ChangedEvent). That doesn't mean they can't be sent by the same physical entity, but it also allows for separation of concerns.
This turned out to be a longer post than I anticipated. I hope it doesn't just come across as ramblings, but actually makes some sense :) Looking forward to hearing your thoughts.