Observation
When propositions change state (created, revised, superseded, contradicted), there's no event-driven notification. Consumers that need to react — cache invalidation, audit logging, metrics, cascading updates — must poll the repository or wrap every service method with callbacks.
PropositionReviser returns RevisionResult (New/Merged/Reinforced/Contradicted/Generalized), but this is a return value from a synchronous call. Independent components can't observe revision outcomes without being directly coupled to the caller.
What DICE already has
RevisionResult sealed hierarchy — captures what happened, but only as a return value
PropositionStatus — ACTIVE, SUPERSEDED, CONTRADICTED, PROMOTED — status changes are implicit in repository updates
PropositionPipeline — orchestrates extract → revise → persist, but no event hooks
- Spring Framework — DICE already uses Spring;
ApplicationEventPublisher + @EventListener is the idiomatic pattern
Proposal
A sealed event hierarchy published via Spring's ApplicationEventPublisher:
sealed class PropositionLifecycleEvent(
val contextId: ContextId,
val propositionId: String,
val timestamp: Instant = Instant.now()
) {
class Created(contextId, propositionId, val proposition: Proposition)
class Revised(contextId, propositionId, val revisionResult: RevisionResult)
class StatusChanged(contextId, propositionId,
val oldStatus: PropositionStatus, val newStatus: PropositionStatus)
class Deleted(contextId, propositionId)
}
PropositionPipeline and PropositionReviser implementations publish events after state-changing operations. The publisher is optional (ApplicationEventPublisher? = null) for backward compatibility.
Consumers listen via standard Spring:
@EventListener
fun onCreated(event: PropositionLifecycleEvent.Created) {
metricsRegistry.counter("dice.propositions.created").increment()
}
Use cases
- Cache invalidation on state change
- OTEL metrics/spans on lifecycle transitions
- Audit trail with timestamps and reasons
- Cascading updates (superseded proposition → update dependent abstractions)
- Real-time UI updates
Observation
When propositions change state (created, revised, superseded, contradicted), there's no event-driven notification. Consumers that need to react — cache invalidation, audit logging, metrics, cascading updates — must poll the repository or wrap every service method with callbacks.
PropositionReviserreturnsRevisionResult(New/Merged/Reinforced/Contradicted/Generalized), but this is a return value from a synchronous call. Independent components can't observe revision outcomes without being directly coupled to the caller.What DICE already has
RevisionResultsealed hierarchy — captures what happened, but only as a return valuePropositionStatus— ACTIVE, SUPERSEDED, CONTRADICTED, PROMOTED — status changes are implicit in repository updatesPropositionPipeline— orchestrates extract → revise → persist, but no event hooksApplicationEventPublisher+@EventListeneris the idiomatic patternProposal
A sealed event hierarchy published via Spring's
ApplicationEventPublisher:PropositionPipelineandPropositionReviserimplementations publish events after state-changing operations. The publisher is optional (ApplicationEventPublisher? = null) for backward compatibility.Consumers listen via standard Spring:
Use cases