Observation
PropositionReviser classifies incoming propositions as CONTRADICTORY when they conflict with existing ones, but this is part of the revision pipeline — it requires the full LLM classification flow and produces a RevisionResult. There's no way to ask "does this proposition conflict with existing knowledge?" outside of revision.
Use cases that need conflict detection without full revision:
- Pre-persistence validation — check before committing
- Real-time monitoring — detect contradictions in a conversation stream without modifying the repository
- Batch auditing — scan existing propositions for internal contradictions
- Domain-specific rules — some applications need lexical/structural conflict checks (negation detection) alongside semantic ones, with different performance/cost tradeoffs
Additionally, PropositionReviser.classify() treats all conflicts as binary (CONTRADICTORY or not). Real-world conflicts have nuance — a "revision" (updating a fact) differs from a "contradiction" (asserting the opposite), which differs from "world progression" (the situation changed, not an error).
What DICE already has
PropositionReviser — classify() returns ClassifiedProposition with PropositionRelation.CONTRADICTORY, but it's coupled to the revision pipeline
PropositionRelation enum — IDENTICAL, SIMILAR, UNRELATED, CONTRADICTORY, GENERALIZES
RevisionResult.Contradicted — stores both original and new proposition
PropositionRepository.findSimilar() — vector similarity search that could identify candidates for conflict checking
The question
Should conflict detection be separable from revision?
Some possibilities:
-
Extract from PropositionReviser — make classify() usable standalone. It's already an interface method, but it returns ClassifiedProposition tied to the revision model. Could be sufficient if the only need is "check for conflicts before revising."
-
ConflictDetector SPI — a separate interface for conflict-only checks:
interface ConflictDetector {
fun detect(text: String, candidates: List<Proposition>): List<ConflictResult>
}
With implementations ranging from cheap (negation keyword detection + text overlap) to expensive (LLM semantic analysis). A composite detector could chain cheap-then-expensive.
-
Richer conflict types — extend PropositionRelation or introduce a ConflictType that distinguishes contradiction, revision, and world progression. This would benefit PropositionReviser too.
-
Detection quality tracking — when LLM-based detection fails (parse error, timeout), signal degraded quality rather than silently returning no conflicts. Consumers can route degraded results to human review.
Open questions
- Is separating detection from revision worth the API surface? If most consumers run conflict detection as part of revision anyway, a standalone SPI may be overhead.
- How reliable is negation-based detection? Cheap lexical checks ("not", "never", "no longer") catch obvious contradictions but miss semantic ones ("the door is locked" vs. "you can walk through the door").
- Should conflict resolution be part of this? Detection tells you that a conflict exists. Resolution tells you what to do about it. These could be separate SPIs or combined.
Observation
PropositionReviserclassifies incoming propositions asCONTRADICTORYwhen they conflict with existing ones, but this is part of the revision pipeline — it requires the full LLM classification flow and produces aRevisionResult. There's no way to ask "does this proposition conflict with existing knowledge?" outside of revision.Use cases that need conflict detection without full revision:
Additionally,
PropositionReviser.classify()treats all conflicts as binary (CONTRADICTORYor not). Real-world conflicts have nuance — a "revision" (updating a fact) differs from a "contradiction" (asserting the opposite), which differs from "world progression" (the situation changed, not an error).What DICE already has
PropositionReviser—classify()returnsClassifiedPropositionwithPropositionRelation.CONTRADICTORY, but it's coupled to the revision pipelinePropositionRelationenum —IDENTICAL,SIMILAR,UNRELATED,CONTRADICTORY,GENERALIZESRevisionResult.Contradicted— stores both original and new propositionPropositionRepository.findSimilar()— vector similarity search that could identify candidates for conflict checkingThe question
Should conflict detection be separable from revision?
Some possibilities:
Extract from PropositionReviser — make
classify()usable standalone. It's already an interface method, but it returnsClassifiedPropositiontied to the revision model. Could be sufficient if the only need is "check for conflicts before revising."ConflictDetector SPI — a separate interface for conflict-only checks:
With implementations ranging from cheap (negation keyword detection + text overlap) to expensive (LLM semantic analysis). A composite detector could chain cheap-then-expensive.
Richer conflict types — extend
PropositionRelationor introduce aConflictTypethat distinguishes contradiction, revision, and world progression. This would benefitPropositionRevisertoo.Detection quality tracking — when LLM-based detection fails (parse error, timeout), signal degraded quality rather than silently returning no conflicts. Consumers can route degraded results to human review.
Open questions