# Identities and data contracts

## Three names with different jobs

A **Function** is a reusable catalog template, identified by `function_slug` such as `erc20.holder_balance`. A **Bound Function** is that computation with its chain and scope parameters filled, identified by a content-addressed `bound_function_id` beginning `sha256:`. An **MCP tool** is a verb such as `bind`, `materialize`, or `read`.

Pass the returned bound-function ID unchanged. A readable `name`, metric phrasing, or function slug cannot stand in for it. Two phrasings may resolve to one identity; one template bound to two contracts can produce two different identities.

## Scope is structural

Obtain template parameter names from `inspect subject:function`. Pass addresses in typed fields or `params`, not hidden in explanatory prose. Set `chain_id` explicitly. There is no default chain. Use the exact JSON field names from the deployed schema: unknown fields are rejected.

The reviewed live 0.6.0 instructions advertise Function dependencies in `params`: a dependency can be supplied as nested scope parameters or as a declared binding name discovered through `inspect subject:function`. Use only the structure and names advertised for that Function. A declared binding name is not a substitute for the returned `bound_function_id` in data tools.

`bind` takes scope, not a block range. `ask` returns a resolution, not a metric value series.

## Every explicit block window is half-open

`[from_block, to_block)` includes the start and excludes the end. `[100, 110)` contains ten blocks; block 110 is not included. A single block `n` is `[n, n+1)`.

State both ends or omit both where the tool permits omission. One end alone is invalid. Never treat block numbers as timestamps or add ranges from different chains. A materialize window may extend beyond the current chain head; that tail waits for those blocks to exist. A read or provenance request requires full coverage of its stated window.

For a wall-clock request, first discover chain landmarks. The chain card includes `blocks_per_day` and either `head` or `unavailable`. A block-rate estimate is not an exact timestamp-to-block conversion; define the actual block boundaries before spending. The head does not establish finality.

## Schema once, values many times

A successful `read` returns bare `values`, one object per block and row key, with every attribute of that row. Obtain their types and key-part names from the Function’s `row` schema through inspect. Preserve declared types; do not round large integer strings through floating-point arithmetic. A sparse row, an empty result, and missing coverage are distinct states. Within fully materialized coverage, a block with no row means the Function emitted nothing there; consult its description before interpreting that absence.

Inspect the actual row schema and prefer exact integer fields for accounting when supplied. Human-readable floating-point units can lose precision above 2^53.

The optional `read.key` is an object of string values for a leading run of row-key parts. It filters stored rows without rebinding scope. `read.attributes`, `read.entity`, and `provenance.attribute` are no longer accepted. Provenance uses the bound identity and exact window.

## Keep useful agent state

Persist the endpoint, chain, function slug, bound-function ID, scope parameters, requested window, selected measures, quote/payment/job IDs, settlement receipts, and source verification evidence. Store secrets separately. This small state record lets another agent resume a workflow without reconstructing intent from prose.
