TrackRecord · 0x7EE4…692D Connect your agent →

What is proven

Threat model

This is the precise claim behind "every trade committed before it ends". It is narrower than "results can't be faked", and we say so on purpose: a verification product has to be exact about its own limits.

Works today · verified claimsDesigned · items marked (planned)

Source: docs/THREAT-MODEL.md in the repository. Measurements refer to the public instance snapshot of 26 Sep 2026 (91 trades, 150 batches).

Threat model: what the TrackRecord proves, and what it does not

This is the precise claim behind "every trade committed before it ends". It is narrower than "results can't be faked", and we say so on purpose: a verification product has to be exact about its own limits.

Actors

What is proven (anyone can check, without trusting us)

Claim How it is checked Where
A recorded decision has not been changed since it was sealed leaf = keccak(0x00‖keccak(canonical JSON)), Merkle root stored on chain verify.js, verifyDecision()
A recorded entry was sealed before its committed exit block time of the entry's batch < time of the committed close decision verify.js judge()
Every time, amount and net multiple shown on the page equals the committed decisions entry/exit time (±5 s), ETH in, ETH out, net multiple from committed pnl_eth (so gas is included) verify.js judge(), page built from committed data
No recorded trade is missing from the page all batches for the strategy ids are fetched (batchCount must be answered), each root and count checked, every committed entry must be shown, position numbers have no gaps verify.js completeness()
Committed history is append-only windows per strategy must not overlap; no admin, no upgrade path TrackRecord.sol

Failures are loud: an RPC error or an unreadable batch count shows "Not verified", never a green summary. Warnings (seal later than 90 s after entry, exit outside the 120 ± 60 s rule, net result not committed) are counted separately and turn the summary yellow.

Measured on the public instance (snapshot 26 Sep 2026, 91 trades, 150 batches)

What is NOT proven (and what would close each gap)

Gap Why it matters Mitigation (status)
Signals the engine never recorded. The operator could filter decisions before they reach the journal. Position numbers catch gaps only after a number is assigned. Selective recording is still possible for a dishonest operator. The eligible universe is on chain (launchpad buys by the tracked wallets). Committing a hash of the wallet list at registration, plus the skip log (signals.csv, every signal with its skip reason), lets an auditor who is given the list replay a block range and find unrecorded signals. (planned)
The ~60 s before the seal. An operator sees 60 s of the price path before the entry is sealed and could drop bad entries in that window. "Before the result is known" is only true relative to the exit. Seal per block instead of per minute (cost is flat with the v2 single-root design); verifier fails entries sealed later than a fixed limit. (limit implemented as a warning at 90 s; per-block sealing planned)
Simulated fills. Paper prices come from our model of pool depth, fees and gas. A committed number is not an executable number. Each decision names token, time and price, so it can be re-simulated against block state. Live mode with signed transactions and receipts is the real guarantee. (re-simulation tooling in Results; public checker planned)
Rules followed. configHash fixes the declared rules; the chain does not check the engine followed them. Hidden logic could deviate. Public rules are published; strategy #0 was registered with a placeholder hash (keccak("config-v1")), so it is a legacy record. New registrations use the keccak of the canonical JSON manifest. (to be registered)
Other addresses, unregistered strategies. strategiesOf(owner) lists one address's registrations only. "You can't hide twenty strategies" is true only per address. Publish the operator's addresses; for external producers, bind registrations to a signed identity. (planned)
Operator stops committing. The contract cannot force the daemon to run. Missing periods. Visible as a gap in batch windows; the page shows the last commit time.

Canonical manifests of the public strategies

keccak256 of the canonical JSON (keys sorted) of each entry in engine/strategies-public.json:

Answers to the questions a jury will ask

  1. What is a mandatory event? Every entry/exit the engine journals for a registered strategy. The eligible universe (launchpad buys by tracked wallets) is on chain; committing the wallet-list hash and the skip log is next.
  2. Worst event→commit lag? 65 s on the snapshot above; the verifier warns above 90 s and fails if sealed after the exit.
  3. Why does commit-before-exit help if the operator sees the market first? It bounds the window for dropping trades to ~60 s instead of forever; per-block sealing reduces it to seconds.
  4. Secret strategies? A hash proves the rules did not change, not that they were followed. We publish rules; for private rules the options are later disclosure, TEE attestation or ZK — none is claimed today.
  5. Can every multiple be reproduced? Net multiple = (ETH in + committed pnl) / ETH in; the page recomputes it. Whether the fill was achievable needs re-simulation at the block (see Results).
  6. Why is #0 worse than the control? 29 vs 68 trades, overlapping samples, one day of data; no conclusion yet.
  7. Pre-registration? The protocol and registration date are on chain for #1; #0 is a legacy placeholder.
  8. Why not a broker statement / Dune / own signature? Those show what happened to money, or what the author says; this shows what was decided and when, before the outcome, in a form anyone can re-check.
  9. Why a contract rather than plain L2 timestamping? Per-strategy append-only windows, publisher permissions, registration history and on-chain verification in one place, with no admin.
  10. Which code is deployed? The repository tag submitted with the application; the contract source is verified (Blockscout + Sourcify, exact match).

Trade counts in the jury answers (29 vs 68) are the engine's journal counts at the 26 Sep snapshot; the passports, reconstructed from the committed batches, show 27 and 64 closed trades for the same period.