Anchors
Pin an answer to on-chain state, so the number your agent acted on can be checked by anyone, later, without trusting us.
How anchoring works today
Anchoring has two halves, and they are at different stages.
Reading an anchor, comparing an answer against on-chain state before delivering it, is live on mainnet. Answers are checked against Chainlink Data Feeds read from the aggregator's own account state, and labelled anchored when they agree, with the feed, value, round timestamp and tolerances recorded on the trace. Six mainnet pairs are wired: SOL, BTC, EURC, JLP, JUP and WBTC.
Writing an anchor, leaving a record on chain that this answer was delivered, at this time, at this level, which anyone can check without asking us, is built and running on devnet. Each delivered answer is hashed into a Merkle leaf, batched, and committed to Solana in a single memo transaction; the trace then carries the signature, slot and Merkle path. An independent verifier can recompute the hash, walk the path to the on-chain root, and confirm the fee payer is our published key. Tampering with the record breaks the proof. Mainnet is next, once we have measured the real per-batch cost.
What reading gives you today
Chainlink Data Feeds on Solana, read from the aggregator's own account state rather than from an API in front of it. Six mainnet pairs are wired: SOL, BTC, EURC, JLP, JUP and WBTC. Exchange rate feeds are deliberately excluded, because a ratio is not a price and comparing a USD answer against a BTC-denominated ratio would diverge on every call.
Every round carries a timestamp, and it is checked against a limit derived from the heartbeat that feed publishes for itself. Mainnet heartbeats run from 180s to 600s by pair, so the limit is per feed. A price that agrees but is older than the feed's own guarantee does not earn the label.
If the reference is unreachable, the check fails rather than passing by omission. The oracle disagreeing and the oracle not answering are different events, and a system reporting them identically is reporting neither. Both are named in the trace, along with which oracle answered and whether the read came from chain state or from an oracle's HTTPS service.
Choosing what counts
By default an independent signed oracle read over HTTPS also earns the anchored label, and the answer says which through anchorKind. A caller who meant chain state specifically can set requireOnChainAnchor, and the off-chain fallback is then skipped rather than substituted. Combined with a minimum level, that turns into a refusal at no cost instead of a quiet substitution.
What writing adds
A commitment made at delivery time that cannot be revised afterwards. Useful when an agent has to defend a decision to someone who was not in the room and has no reason to take our word for what it was told. It is the difference between a log you hold and evidence someone else can verify.
Two of the three design constraints are built in, and one is not yet. The proof is a separate proof field on the trace, with its own status, so it can be ignored by an agent that does not need it. It commits to the trace rather than only to the value: the leaf hashes the whole record, since a number without its reasoning is exactly the thing this product exists to stop shipping. What is not built is the pricing. On devnet every delivered answer is anchored at no extra charge; on mainnet a chain write costs something real, so it will be opt-in and priced separately rather than folded into the call.
What we will not do
Publish an anchored answer as proof of correctness. An on-chain record proves what was delivered and when. It does not make the number right, and a product that let those two be confused would be selling certainty it does not have.