EventEmittingPropositionRepository

open class EventEmittingPropositionRepository<D : PropositionRepository>(delegate: D, listener: DiceEventListener = DiceEventListener.DEV_NULL) : PropositionRepository

Decorator that emits lifecycle events at the persistence boundary.

Wraps any PropositionRepository via by delegate. All read methods forward untouched. Only the write path is instrumented:

  • save persists via the delegate first, then emits exactly one event carrying the saved instance. The event type depends on whether a status transition occurred:

    • PropositionStatusChanged when a prior entry exists with a different status (e.g. ACTIVE → CONTRADICTED), so consumers can distinguish transitions from plain inserts.

    • PropositionPersisted for fresh inserts and non-status updates.

  • saveAll is explicitly overridden to call this decorator's own save per proposition, so one event fires per proposition. The default interface saveAll would bypass the decorator's save and emit nothing.

To keep fresh ACTIVE inserts read-free, the prior-status lookup is skipped when the incoming status is already ACTIVE. The tradeoff isn't only performance: it loses a real signal. A revival STALE → ACTIVE (reinforcement — arguably the most interesting lifecycle transition for a downstream index) is reported as a plain PropositionPersisted, not a PropositionStatusChanged. A consumer that needs the reinforcement signal should observe it at its origin — the reviser, which knows it is reinforcing — rather than infer it here on the hot path.

Throw isolation is the listener's responsibility — wrap the listener in SafeDiceEventListener if you need graceful degradation.

This class carries capabilities only when its delegate does. The wrapping factory method picks the right shape for whatever delegate you hand it, so a caller's as? SourceRevisionQueryCapable or as? ProvenanceSubtractionCapable probe on the wrapper answers the same way it would on the delegate.

Example usage:

val repo = EventEmittingPropositionRepository.wrapping(
delegate = inMemoryRepository,
listener = SafeDiceEventListener(myListener),
)

Inheritors

Constructors

Link copied to clipboard
constructor(delegate: D, listener: DiceEventListener = DiceEventListener.DEV_NULL)

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard
open override val storeType: PropositionStoreType

Which backend provides this repository. Implementations override to advertise their kind; used to select/flip between in-memory and persistent backends.

Link copied to clipboard
open override val supportsVector: Boolean

Whether this particular instance can actually run vector search. Implementing the interface is a type-level promise; this is the runtime truth. A store that can be wired without an embedder (so it satisfies the type but has nothing to embed with) should override this to report whether it was given one. Lets a caller — e.g. PropositionStoreTemplate.supportsVector — distinguish "configured for vectors" from "vector search will quietly return empty".

Functions

Link copied to clipboard
open override fun addProvenance(propositionId: String, entries: List<ProvenanceEntry>): Proposition?

Append provenance to a proposition (deduplicated); never removes existing entries.

Link copied to clipboard
open override fun clearAll(): Int

Delete every proposition.

Link copied to clipboard
open override fun clearByContext(contextId: String): Int

Delete all propositions in the given context.

Link copied to clipboard
open override fun clearByContextPrefix(contextIdPrefix: String): Int

Delete all propositions whose context id starts with the given prefix.

Link copied to clipboard
open override fun clearProvenance(propositionId: String): Proposition?

Remove all provenance from a proposition.

Link copied to clipboard
open override fun count(): Int

Get the total count of propositions.

open override fun count(query: PropositionQuery): Int

Count the propositions matching query. The default materialises query's results and counts them; a backend that can count server-side (e.g. the graph store) overrides to avoid loading the rows just to size them.

Link copied to clipboard
open override fun delete(id: String): Boolean

Delete a proposition by ID.

Link copied to clipboard
open override fun findAbstractionsOf(propositionId: String): List<Proposition>

Find propositions that were abstracted from the given proposition. Searches for propositions that cite the given ID in their Proposition.sourceIds.

Link copied to clipboard
open override fun findAll(withProvenance: Boolean): List<Proposition>

Get all propositions, optionally guaranteeing loaded provenance. With withProvenance = true every result has its Proposition.provenanceEntries populated (at extra read cost); the default delegates to the lean findAll — fine for backends that always carry provenance (e.g. in-memory).

open override fun findAll(): List<Proposition>

Get all propositions.

Link copied to clipboard

Find all propositions ordered by effective confidence (highest first). Applies time-based decay to confidence scores.

Link copied to clipboard
open override fun findByContextId(contextId: <Error class: unknown class>): List<Proposition>

Find propositions in the given context.

Link copied to clipboard
open override fun findByContextIdValue(contextIdValue: String): List<Proposition>

Java-friendly variant of findByContextId that accepts a plain string.

Link copied to clipboard
open override fun findByCreatedBetween(start: Instant, end: Instant): List<Proposition>

Find propositions created within a time range.

Find propositions from a time range, ordered by effective confidence as of a point in time. Useful for temporal analysis: "What was most confidently true during Q1?"

Link copied to clipboard
open override fun findByEffectiveConfidenceAbove(threshold: Double, k: Double): List<Proposition>

Find propositions with effective confidence above a threshold.

Link copied to clipboard
open override fun findByEntity(entityIdentifier: <Error class: unknown class>): List<Proposition>

Find all propositions that mention a specific entity.

Link copied to clipboard
open override fun findByGrounding(chunkId: String): List<Proposition>

Find all propositions grounded by a specific chunk.

Link copied to clipboard
open override fun findById(id: String): Proposition?

Find a proposition by its ID.

Link copied to clipboard
open override fun findByMinLevel(minLevel: Int): List<Proposition>

Find propositions at or above the specified abstraction level. Level 0 = raw observations, 1+ = abstractions.

Link copied to clipboard
open override fun findByRevisedBetween(start: Instant, end: Instant): List<Proposition>

Find propositions last touched within a time range. "Touched" means any update — content or administrative — so this anchors on Proposition.lastTouched (the later of contentRevised/metadataRevised), not the decay anchor alone.

Link copied to clipboard
open override fun findByStatus(status: PropositionStatus): List<Proposition>

Find all propositions with the given status.

Link copied to clipboard
open override fun findClusters(similarityThreshold: <Error class: unknown class>, topK: Int, query: PropositionQuery): List<<Error class: unknown class><Proposition>>

Find clusters of similar propositions.

Link copied to clipboard
open override fun findPinned(contextId: <Error class: unknown class>): List<Proposition>

All pinned propositions in contextId.

Link copied to clipboard
open override fun findSimilar(textSimilaritySearchRequest: <Error class: unknown class>): List<Proposition>

Find propositions similar to the given text using vector similarity.

Link copied to clipboard
open override fun findSimilarWithScores(textSimilaritySearchRequest: <Error class: unknown class>): List<<Error class: unknown class><Proposition>>

Find propositions similar to the given text with similarity scores.

open override fun findSimilarWithScores(textSimilaritySearchRequest: <Error class: unknown class>, query: PropositionQuery): List<<Error class: unknown class><Proposition>>

Vector similarity search with an additional PropositionQuery filter applied to results.

Link copied to clipboard
open override fun findSources(proposition: Proposition): List<Proposition>

Find the source propositions that a given proposition was abstracted from. Resolves the proposition's Proposition.sourceIds to actual propositions.

Link copied to clipboard
open override fun keywordOverlap(base: PropositionQuery, tokens: List<String>, limit: Int): List<Proposition>

Find propositions in base's scope whose text contains at least one of tokens (case-insensitive), ranked by how many distinct tokens each contains (descending), ties broken by base's ordering. At most limit results; empty tokens or non-positive limit returns nothing.

Link copied to clipboard
open override fun pin(id: String): Proposition?

Pin a proposition so it resists reclamation: pinned propositions are skipped by the decay collector and the sweep policy, are decay-exempt in the default status policy, and are not auto-retired by contradiction resolution.

Link copied to clipboard
open override fun provenanceOf(propositionId: String): List<ProvenanceEntry>

The provenance entries of a proposition, or an empty list if it has none or does not exist.

Link copied to clipboard
open override fun query(query: PropositionQuery): List<Proposition>

Resolves the diamond: both PropositionStore and VectorSearchCapable declare query. This explicitly routes to the base store's implementation; concrete stores can still override for backend-level filtering.

open override fun query(query: PropositionQuery, withProvenance: Boolean): List<Proposition>

Query propositions, optionally guaranteeing loaded provenance. With withProvenance = true every result has its Proposition.provenanceEntries populated (at extra read cost); the default delegates to the lean query. See the provenance read contract on PropositionStore.findAll.

Link copied to clipboard
open override fun reembedAll(): Int

Re-embed every stored proposition with the currently-configured embedding service.

Link copied to clipboard
open override fun save(proposition: Proposition): Proposition

Persists via the delegate, then emits one lifecycle event carrying the saved instance.

Link copied to clipboard
open override fun saveAll(propositions: Collection<Proposition>)

Persists each proposition through this decorator's own save, emitting one event per proposition. Explicitly overridden — not delegated — because the default interface saveAll forwards to delegate.saveAll, which bypasses this decorator's save.

Link copied to clipboard

The same, keeping what each proposition landed on. Overridden for the same reason saveAll is: by delegate forwards an interface default straight to the delegate, so the default body would run the delegate's save and this decorator would emit nothing.

Link copied to clipboard
open override fun setProvenance(propositionId: String, entries: List<ProvenanceEntry>): Proposition?

Authoritatively set a proposition's provenance to exactly entries, removing any not listed.

Link copied to clipboard
open override fun supportsType(type: String): Boolean
Link copied to clipboard
open override fun <T> textSearch(request: <Error class: unknown class>, clazz: Class<T>): List<<Error class: unknown class><T>>
Link copied to clipboard
open override fun touchAccessed(ids: Collection<String>)

Refresh Proposition.lastAccessed to now for ids — the read-side reinforcement that lets a DECAYING proposition's decay anchor (see Proposition.effectiveConfidenceAt) track actual use rather than only content edits. Best-effort and silent about unknown ids (a stale eager id that has since been deleted is not an error).

Link copied to clipboard
open override fun unpin(id: String): Proposition?

Clear a proposition's pin, returning it to normal reclamation.

Link copied to clipboard
open override fun <T> vectorSearch(request: <Error class: unknown class>, clazz: Class<T>): List<<Error class: unknown class><T>>