← Back to Yichus

Provenance: See Why Any Value Exists

Yichus tracks how every value is computed. When a derived value changes, you can trace exactly which sources contributed and which operations produced it. This is provenance -- and it's built into the language.

Automatic Tracking Why? Queries Audit Trail

Live Demo

1

The Dependency Graph

The demo has two source values (source_a, source_b) and a derived value (derived_sum = source_a + source_b). This forms a dependency graph:

source_a
10
derived_sum
13
source_b
3

When you click "bump source_a," the graph lights up: source_a and the arrow feeding into derived_sum turn gold, showing exactly which dependency path was activated.

2

How the Code Tracks Provenance

The bump_a handler doesn't just update values -- it records the full derivation chain in the provenance trail and why panel.

def bump_a(_: Unit) -> IO[Unit]: (
  # 1. Read current sources
  current_a <- sa.read().flatMap()
  current_b <- sb.read().flatMap()
  next_a = current_a.add(1)
  new_sum = next_a.add(current_b)

  # 2. Update values
  _ <- sa.write(next_a).flatMap()
  _ <- total.write(new_sum).flatMap()

  # 3. Update visual highlights
  _ <- ba.write(lit_color).flatMap()  # gold
  _ <- bs.write(sum_lit).flatMap()    # green
  _ <- aa.write(lit_color).flatMap()  # gold arrow

  # 4. Record provenance trail
  tt.write("source_a: 10 -> 11 | sum: 13 -> 14")
)

Every state write goes through the binding map. The box colors, arrow colors, formula, trail, and why text all update via O(1) direct DOM writes -- no re-render of the entire UI.

3

The Provenance Trail

Below the graph, a dark panel shows the provenance trail: what changed, what was the old value, what is the new value, and which derived values were recomputed.

After clicking bump_a twice:

"source_a changed: 10 -> 11 | sum recomputed: 13 -> 14"
"source_a changed: 11 -> 12 | sum recomputed: 14 -> 15"

The "Why?" panel explains the current value in terms of its sources:

"sum = 15 because source_a(12) + source_b(3) -- triggered by bump_a"

This is the essence of provenance: at any point, you can ask "why is this value what it is?" and get a complete answer tracing back to inputs.

4

Visual Feedback via Style Bindings

The graph boxes use style-background bindings. Each box has its own State[String] for its background color. When bump_a fires, it writes "#fbbf24" (gold) to the source_a box's background state and "#22c55e" (green) to the sum box.

def source_box(label: String, value_str: String, bg: String) -> VNode:
  h("div", [
    ("style-background", bg)  # reactive: bound to state
  ], [text(value_str)])

Each color change is a single style.background property write dispatched through the binding map. With 5 boxes and 2 arrows changing, that's 7 direct DOM property writes -- no tree diffing.

Compare to React
In React, highlighting a dependency graph means re-rendering the entire graph component. Even with React.memo, the framework must check every component for changes. Yichus skips the check entirely -- the binding map tells it exactly which DOM properties to update.
5

Why Provenance Matters

Use CaseWhat Provenance Enables
DebuggingTrace any unexpected value back to the exact input and operation that produced it
AuditingProve how a financial calculation was derived for regulatory compliance
AI DetectionDetect when AI-generated code ignores inputs and returns hardcoded values
What-If AnalysisChange an input and see which outputs are affected, with full derivation chains
CollaborationWhen someone asks "where did this number come from?" -- Yichus has the answer

Most frameworks treat provenance as an afterthought -- something you add with logging or debugging tools. In Yichus, provenance is a first-class feature of the language: the compiler tracks which inputs flow to which outputs, and the runtime makes this information available for querying.

Learn more: AI Code Detection
Provenance is the foundation of Yichus's AI code detection feature. When AI generates code that ignores its inputs and returns hardcoded values, the provenance trail reveals the deception: the output has no dependency on the input.