Every Action Leaves a Trace. For an agent, provenance is a usable evidence record, not an adjective attached to an answer.

Ask for the exact identity and window

After a successful read, keep its bound-function ID, returned field names, and resolved window. Invoke provenance with the same identity and paired block or UTC period window. Its block ends are optional in the wire schema because period windows use their own pair. It takes no attribute or key selector; the evidence describes the bound function's window. A different window is a different evidence request.

{"tool":"provenance","arguments":{"bound_function_id":"<BOUND_FUNCTION_ID>","from_block":100,"to_block":110}}

Provenance is a separate tool call. Do not claim that every read automatically contains the expanded source-block list.

For period-based Functions, use the matching pair, such as from_day and to_day. A period-end read can cite its source blocks directly. A derived period row can instead cite dependency rows in sources without a blocks field; follow each cited bound-function/window to expand its block evidence. An absent blocks field is not the same as an enumerated empty block list.

What to preserve

The implementation returns chain sources and contributing rows or blocks for the requested identity and window. Preserve only evidence the response actually supplies; do not invent absent blocks or digests. Provenance is available through this MCP tool, not through an HTTP route.

Persist the identity, chain, measure, window, compact record where supplied, expanded source list, digest, and comparison outcome. Preserve the algorithm and encoding supplied by the contract if independently recomputing; an invented concatenation of hashes is not a valid verification procedure.

Canonical source-digest encoding

The observed implementation sorts contributing pairs by ascending block number, then hashes UTF-8 lines in this exact form:

{chain_id}:{block_number}:{lowercase_0x_block_hash}\n

The result is sha256: followed by lowercase SHA-256 hex. The newline is one actual LF byte per pair, including the final pair. Chain ID and block number are decimal integers. Use the exact contributing set returned by the contract; do not add every block in the enclosing span.

A verifier can reproduce that digest locally:

import hashlib

def source_digest(chain_id, blocks):
    ordered = sorted(blocks, key=lambda block: block["number"])
    encoded = "".join(
        f"{chain_id}:{block['number']}:{block['block_hash'].lower()}\n"
        for block in ordered
    ).encode("utf-8")
    return "sha256:" + hashlib.sha256(encoded).hexdigest()

This verifies encoding consistency for the supplied list. For independent source verification, obtain the corresponding canonical block hashes independently as well.

Two range conventions differ: tool requests use the exclusive to_block, while a compact ChainRange citation's from and to are the inclusive minimum and maximum contributing block numbers. Its block_count is the actual contributing count and may be smaller than the enclosing span because of gaps. Do not pass the citation's inclusive end directly into a half-open tool request.

Source evidence and computation evidence

Matching source hashes establishes the requested source evidence's consistency with its digest. It does not, by itself, prove the metric definition matches the operator's intent or independently replay the computation. Distinguish source verification, definition review, and independent recomputation in the final answer.

Missing coverage and empty blocks

A block with no matching event can be legitimate evidence. A missing block is unavailable coverage. Do not conflate them or collapse both into a zero value. Provenance requires its stated window to be covered; inspect the reported geometry and complete missing work before asserting verification.

Bounded expansion

Expansion is limited to 10,000 contributing blocks per response. For larger requests, use smaller meaningful windows and retain the boundaries of each verification record. Do not claim that independently expanded subwindows match one whole-window digest unless the contract supplies a valid composition rule.

Credentials stay out of evidence

Agent-facing source descriptions should identify providers or chains without exposing credential-bearing RPC URLs. Block numbers, hashes, function identity, and reproducible definitions are more useful evidence than a secret endpoint string.