Get Conflict Provenance
const url = 'https://example.com/api/canvas/example/conflict-provenance?limit=500&only_conflicts=false';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}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 whereconflict_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.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”Query Parameters
Section titled “Query Parameters ”Responses
Section titled “ Responses ”Successful Response
Top-level response for GET /canvas/{deal_id}/conflict-provenance.
object
A single recorded PROV-O resolution event for a reconciled metric.
object
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.
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
object
object
object
Example generated
{ "detail": [ { "loc": [ "example" ], "msg": "example", "type": "example", "input": "example", "ctx": {} } ]}