Skip to content

Get Conflict Provenance

GET
/api/canvas/{deal_id}/conflict-provenance
curl --request GET \
--url 'https://example.com/api/canvas/example/conflict-provenance?limit=500&only_conflicts=false' \
--header 'Authorization: Bearer <token>'

Return PROV-O resolutions recorded for deal_id.

RBAC: RequireViewer. The conflict-provenance panel exposes why metric values won — source precedence (USER/EXCEL/COSTAR/PDF), conflict detection, FormulaGraph evidence cells — but exposes no data beyond what the memo body itself already shows to a Viewer. Aligning with the other T6 surfaces (comparables_trail_routes and sponsor_patterns_routes, both RequireViewer) gives Commenters/Editors the same evidence-transparency the memo body grants them, which strengthens trust in PROV-O. The sensitive RBAC surface is deal sharing + role assignment upstream — granular per-route gating beyond that adds friction without security gain. (P38 F12.4 decision, 2026-05-28.)

Query params:

  • limit: max rows to return (1-500, default 500).
  • only_conflicts: when True, filter to rows where conflict_detected = true (multi-source conflicts only, hides single-source single-claim rows).

Response shape::

{
    "deal_id": "...",
    "resolutions": [
        {
            "event_id": "...",
            "ts": "ISO",
            "deal_id": "...",
            "subject_entity_id": "asset:..." | null,
            "predicate": "noi" | ...,
            "candidate_count": N,
            "candidate_source_types": ["excel", "pdf"],
            "winning_source_type": "excel",
            "winning_weight": 90,
            "winning_value": <any>,
            "winning_claim_id": "sha1...",
            "conflict_detected": True | False,
            "precedence_rule_version": "1.2.0",
            "resolver_duration_ms": N
        },
        ...
    ],
    "count": N,
    "conflict_count": N    # subset where conflict_detected = true
}

Empty-warehouse case (deal has no recorded resolutions): returns a well-formed body with resolutions = [] and counts at 0. Status is 200. Observability reads MUST NEVER break the route — any warehouse error degrades to empty.

Tier 2 follow-up (May 2026): each resolution carries fg_evidence_cells: List[str] (the T3 column on conflict_resolution_events — empty list when the resolver had no FG-grounded evidence). Top-level formula_graph_degradation: {fallback_path, skipped_sheets, per_sheet_timeouts} | None carries the per-deal FG telemetry sourced from the latest deal_finalizations row. None for pre-T3 deals (no finalization row) — UI’s banner is gated on non-null.

deal_id
required
Deal Id
string
limit
Limit
integer
default: 500
only_conflicts
Only Conflicts
boolean

Successful Response

Media type application/json
ConflictProvenanceResponse

Top-level response for GET /canvas/{deal_id}/conflict-provenance.

object
deal_id
required
Deal Id
string
resolutions
required
Resolutions
Array<object>
ConflictResolution

A single recorded PROV-O resolution event for a reconciled metric.

object
event_id
required
Event Id
string
ts
Any of:
string
deal_id
required
Deal Id
string
subject_entity_id
Any of:
string
predicate
required
Predicate
string
candidate_count
required
Candidate Count
integer
candidate_source_types
required
Candidate Source Types
Array<string>
winning_source_type
required
Winning Source Type
string
winning_weight
required
Winning Weight
integer
winning_value
Winning Value
winning_claim_id
Any of:
string
conflict_detected
required
Conflict Detected
boolean
precedence_rule_version
required
Precedence Rule Version
string
resolver_duration_ms
required
Resolver Duration Ms
integer
fg_evidence_cells
required
Fg Evidence Cells
Array<string>
count
required
Count
integer
conflict_count
required
Conflict Count
integer
formula_graph_degradation
Any of:
FormulaGraphDegradation

Per-deal FG build telemetry surfaced from the latest finalization row.

Mirrors the TS FormulaGraphDegradation interface. fallback_path ‘slot’ indicates a clean dedicated-subprocess build; any other value is treated as degraded by the UI banner.

object
fallback_path
Any of:
string
skipped_sheets
required
Skipped Sheets
Array<string>
per_sheet_timeouts
required
Per Sheet Timeouts
integer
Example generated
{
"deal_id": "example",
"resolutions": [
{
"event_id": "example",
"ts": "example",
"deal_id": "example",
"subject_entity_id": "example",
"predicate": "example",
"candidate_count": 1,
"candidate_source_types": [
"example"
],
"winning_source_type": "example",
"winning_weight": 1,
"winning_value": "example",
"winning_claim_id": "example",
"conflict_detected": true,
"precedence_rule_version": "example",
"resolver_duration_ms": 1,
"fg_evidence_cells": [
"example"
]
}
],
"count": 1,
"conflict_count": 1,
"formula_graph_degradation": {
"fallback_path": "example",
"skipped_sheets": [
"example"
],
"per_sheet_timeouts": 1
}
}

Validation Error

Media type application/json
HTTPValidationError
object
detail
Detail
Array<object>
ValidationError
object
loc
required
Location
Array
msg
required
Message
string
type
required
Error Type
string
input
Input
ctx
Context
object
Example generated
{
"detail": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example",
"input": "example",
"ctx": {}
}
]
}