Methodology
How Preflight decides
Twelve rules, first match wins. Each one names what it reads, and every verdict Preflight returns cites the rule that decided it. This page is rendered from the same table the verdict functions decide from, so it cannot drift away from the code it describes.
A verdict is a description of evidence
A Preflight verdict names what was checked and when, from Sato Hub's own records and probes. It is not a security review, a quality judgment, or a statement about returns. Unknown means we hold no record — not that anything is wrong.
What each verdict is — and what it is not
Active, scored High, and at least one check we ran ourselves came back.
Not an endorsement, not a security review, not an audit, and not a statement that the thing will work for you. It describes readings, on a date.
We hold a record, and it does not meet all of R5 at once.
Not an allegation and not a warning about conduct. Most listings sit here, including good ones that are simply young or thinly documented.
Something we read came back negative: retired, did not answer, unregistered, mostly failing, or nothing token-shaped at the address.
Not a claim about intent, honesty or risk. It names the reading that failed and nothing beyond it.
We hold no record, or too few readings completed.
Not a negative verdict. Unknown never becomes no — absence of a record is absence of a record.
Unknown never becomes no
Unknown never becomes no. A reading we could not take, a chain we do not cover, a listing we have never seen — each of these produces `unknown`, and `unknown` is never silently downgraded into a negative verdict. A null is unknown, never zero.
The rules for a repository, package, endpoint or agent
Applied in order to whatever resolved: a directory listing, a live probe, an on-chain registration, or nothing at all.
- R1noThe listing is retired.
A listing carries status "Deprecated" after a sweep found no public activity across website, repository and social over 90 days. A retirement is an observation about silence, not a judgment about the project or the people who built it.
reads: resources.status
- R2noA probed endpoint did not answer, or a claimed ERC-8004 id is not registered.
The endpoint was asked for an MCP handshake and did not complete one, or the identity registry holds no record for the agent id given. Both are readings taken at checked_at: an endpoint that answers an hour later was still not answering when we asked.
reads: probe.ok · registration.registered
- R3noOur own daily checks mostly failed, and the failures were attributed to the host, over at least 14 days.
Below 50% success across at least 14 days observed, with at least one day attributed to the host rather than to us. This is the share of OUR checks that succeeded — never uptime. A failure we could not attribute never lands here.
reads: resources.uptime_observed.days_observed · resources.uptime_observed.success_rate_pct · resources.uptime_observed.attributed_down_days
- R4unknownNothing resolved and nothing was probed — we hold no record of this target.
Unknown is a real answer and the honest one. It says Sato Hub has no record, not that anything is wrong with the target. An unknown never hardens into a no.
reads: resources.slug
- R5goActive, scored in tier High, and carrying at least one earned check.
All three at once. An earned check is one of: the documented install re-run in an isolated container; a successful daily check within 14 days; or at least 95% success across our own checks over at least 14 days. A provisional score never promotes.
reads: resources.last_activity_at · resources.trust_score · resources.trust_tier · resources.trust_provisional · resources.deploy_spec.deploy_status · resources.live_check · resources.uptime_observed
- R6cautionEverything else that resolved or probed.
The default once we hold a record. Caution is not an accusation — it is the absence of the three things R5 wants at once. A live handshake against an unlisted endpoint also lands here: a handshake is not a record.
reads: resources.slug · probe.ok · registration.registered
The rules for a token address
Six keyless chain readings, and six rules over them. The lane is EVM-shaped and Uniswap v3-scoped, which is why a rule that would fire on silence needs two silent legs, not one.
- T1noNothing at the address holds bytecode, so there is no token there.
An address with no code is an address with no code. Nothing further was read.
reads: contract.is_contract
- T2unknownFewer than 3 of the six lanes returned a determinate reading.
An unsupported chain, or reads that did not complete. Unknown, never zero: a reading we could not take says nothing about the thing we were reading.
reads: contract · erc20 · deployer · venue · liquidity · holders
- T3noBytecode is present but not one ERC-20 view answered.
Whatever is deployed at the address does not present as an ERC-20 to a standard call. It may be something else entirely; this lane only reads tokens.
reads: contract.name · contract.symbol · contract.decimals · contract.total_supply
- T4noNo Uniswap v3 pool against wrapped native at any standard fee tier, and no known launch venue deployed it.
Scope is Uniswap v3 only — a v4-only or off-Uniswap market is never queried, which is exactly why the venue leg has to be absent too before this fires. Both legs silent is a reading; one leg silent is not.
reads: liquidity.pools · venue.name
- T5goAn ERC-20 that reads back, deployed by a known launch venue, with at least one pool found and its LP position held by a known locker or burn address.
A locker holds a position on the terms its own code enforces. Read that contract for those terms: this line says where the position sits, and stops there.
reads: contract · venue.name · liquidity.pools · liquidity.lp_holder
- T6cautionEverything else that resolved.
Enough lanes answered to say something, not enough to satisfy T5.
reads: contract · venue.name · liquidity.pools
The numbers the rules turn on
| Name | Value | What it decides |
|---|---|---|
| MIN_DAYS | 14 | Days of our own checks before an observed record is allowed to rank or decide anything. |
| GO_SUCCESS_PCT | 95% | Success across our checks, over at least 14 days, that counts as an earned check under R5. |
| NO_SUCCESS_PCT | 50% | Success below this, with at least one failure attributed to the host, is R3. |
| PROBE_FRESH_MS | 14 days | After this, a daily check is history rather than a current reading. |
| MIN_TOKEN_CHECKS | 3 | Determinate token readings required before the token lane says anything but unknown. |
Worked examples
Each block below is a hand-built record put through the real verdict engine at render time, with a frozen clock. The listings are invented; they are not real projects, and none of them says anything about a real one.
?repo=example-org/example-kit
- ▸Public activity three days ago.
- ▸Sato Score 82, tier High, not provisional.
- ▸The documented install was re-run in a container and completed.
Evidence returned
- Directory record: Listed as Example Kit (Framework).resources.slug · 2026-09-11
- Public activity: Last public activity 4d ago (active).resources.last_activity_at · 2026-09-09
- Sato Score: 82 of 100, tier High. The score measures how open, active and verifiable the project is, not safety or quality.resources.trust_score · 2026-09-11
- Reproduced install: The documented install path was re-run in an isolated container and completed. Proves installability, not runtime behaviour.resources.deploy_spec.deploy_status · 2026-09-03
?repo=example-org/example-mcp
- ▸Public activity two days ago.
- ▸Sato Score 55, tier Medium.
- ▸No reproduced install, no fresh successful daily check, no observed record.
Evidence returned
- Directory record: Listed as Example MCP (Framework).resources.slug · 2026-09-11
- Public activity: Last public activity 3d ago (active).resources.last_activity_at · 2026-09-10
- Sato Score: 55 of 100, tier Medium. The score measures how open, active and verifiable the project is, not safety or quality.resources.trust_score · 2026-09-11
?repo=example-org/example-retired
- ▸Status "Deprecated" — a sweep found no public activity across website, repository and social over 90 days.
Evidence returned
- Directory record: Listed as Example Retired (Framework).resources.slug · 2026-09-11
- Listing status: Retired (Deprecated) — no public activity found across website, repository and social over 90 days. A retirement is an observation, not a verdict on the project.resources.status · 2026-09-11
?repo=example-org/never-seen
- ▸Nothing resolved against the directory, and nothing was probed.
Evidence returned
- Directory record: No listing matches this identifier.resources.slug · no date on this field
?token=0x…&chain=base
- ▸Bytecode present; all four ERC-20 views answered.
- ▸Deployed through a known launch venue.
- ▸One Uniswap v3 pool against wrapped native, LP position at a burn address.
- ▸Deployer and holder concentration read as unknown, and say why.
Evidence returned
- Chain: Read on Base (chain id 8453).preflight.token.chain · 2026-09-12
- Contract at the address: Bytecode is present (4821 bytes). Code exists at the address; what the code does was not analysed.eth_getCode · 2026-09-12
- ERC-20 reads: name "Example Token", symbol "EXMPL", 18 decimals, total supply 1000000000000000000000000 base units. Read from the contract now; a supply can change later if the contract allows it.eth_call erc20.name/symbol/decimals/totalSupply · 2026-09-12
- Deployer: Unknown (no explorer key configured)contract creation record · 2026-09-12
- Deployer age: Unknown (no explorer key configured)contract creation record · 2026-09-12
- Launch venue: Deployed through Clanker v4 — deployed through the documented v4 factory. Names the factory that created it, nothing about the launch's terms.factory match · 2026-09-12
- Uniswap v3 liquidity: 1 Uniswap v3 pool(s) against wrapped native: fee tier 10000 at 0x00000000000000000000000000000000000po0l. A pool existing is not depth — no reserves were read.uniswap v3 factory getPool · 2026-09-12
- LP position holder: The liquidity position is held by burn address (0x000000000000000000000000000000000000dEaD) — a burn address. It holds that position on the terms that address enforces; read the contract for those terms.ownerOf(positionId) · 2026-09-12
- Holder concentration: Not checked (no keyless public source; explorers are not scraped)none · 2026-09-12
- Directory record: Neither the token nor its deployer matches a Sato Hub listing — unknown, not disqualifying.resources.onchain_address · no date on this field
?token=0x…&chain=base
- ▸Bytecode present, and nothing else completed. Two readings is under the minimum, so the lane says unknown rather than guessing.
Evidence returned
- Chain: Read on Base (chain id 8453).preflight.token.chain · 2026-09-12
- Contract at the address: Bytecode is present (1200 bytes). Code exists at the address; what the code does was not analysed.eth_getCode · 2026-09-12
- ERC-20 reads: name "Unnamed". Read from the contract now; a supply can change later if the contract allows it.eth_call erc20.name/symbol/decimals/totalSupply · 2026-09-12
- Deployer: Unknown (no explorer key configured)contract creation record · 2026-09-12
- Deployer age: Unknown (no explorer key configured)contract creation record · 2026-09-12
- Launch venue: No known launch venue matched (no known factory matched)factory match · 2026-09-12
- Uniswap v3 liquidity: Not read (the read did not complete)uniswap v3 factory getPool · 2026-09-12
- LP position holder: Unknown (no pool to read a position from)ownerOf(positionId) · 2026-09-12
- Holder concentration: Not checked (no keyless public source; explorers are not scraped)none · 2026-09-12
- Directory record: Neither the token nor its deployer matches a Sato Hub listing — unknown, not disqualifying.resources.onchain_address · no date on this field
Where the readings come from
| Evidence | Field | Method | Refreshed |
|---|---|---|---|
| Directory record | resources.slug | The identifier is resolved against Sato Hub's own listings by repository, package name or host. | On every listing edit; re-checked by the daily pipeline. |
| Listing status | resources.status | Weekly hygiene sweep of website, repository and social over 90 days; confirmed-silent listings are retired as "Deprecated". | Weekly. |
| Public activity | resources.last_activity_at | Newest of commit, release and post dates read from public sources. | Daily. |
| Sato Score | resources.trust_score / trust_tier / trust_provisional | Recomputed from evidence fields only — how open, active and verifiable the project is. Not safety, quality or returns. | Daily. |
| Reproduced install | resources.deploy_spec.deploy_status | The documented install path re-run in an isolated container. Proves installability, not runtime behaviour. | Weekly. |
| Daily check | resources.live_check | One MCP handshake or HTTP check per day. A refusal of an anonymous check is recorded as a refusal, not as a failure. | Daily. |
| Observed record | resources.uptime_observed | The daily checks rolled up: days observed, share that succeeded, and how many failures we could attribute to the host. | Daily. |
| Live endpoint probe | probe.mcp_probe | An initialize + tools/list handshake run at request time against the endpoint given. | At request time. |
| ERC-8004 registration | erc8004.identity_registry.ownerOf / tokenURI | A keyless chain read of the identity registry, plus a fetch of the registration file when one resolves. | At request time. |
| Token contract and ERC-20 reads | eth_call erc20.name/symbol/decimals/totalSupply | Keyless RPC reads against the address given, on the chain given. | At request time. |
| Launch venue and liquidity | preflight.token.venue / liquidity | Factory match against the known launch-venue table, plus Uniswap v3 pool lookups against wrapped native at the standard fee tiers. | At request time. |
What Preflight cannot see
Printed, because a gap that is never mentioned reads as “nothing to report” — which is the one thing a preflight must never imply.
- ▸Holder concentration — there is no keyless public source for it, and we do not scrape explorers.
- ▸Uniswap v4 and every non-Uniswap venue. A token with no v3 pool may still have a market we never queried.
- ▸Solana and every other non-EVM chain. This lane is EVM-shaped.
- ▸The deployer address without an Etherscan key — a contract-creation record is not a keyless RPC read.
- ▸What the code does. Bytecode existing is not bytecode read.
- ▸Anything after checked_at. A reading is a reading at a moment, not a subscription.
Questions
How does Preflight decide a verdict?
By the first rule that matches, in order. There are 6 rules for repositories, packages, endpoints and agents (R1–R6) and 6 for the token lane (T1–T6). Each returned verdict names the rule that decided it, so the reasoning can be looked up rather than taken on faith.
Does a Preflight verdict mean something is safe?
No. A verdict describes readings Sato Hub holds or took, and the date each was written. It is not a security review, a code audit, a quality judgment or a statement about returns — for any of the four verdicts.
What does unknown mean in Preflight?
Unknown never becomes no. A reading we could not take, a chain we do not cover, a listing we have never seen — each of these produces `unknown`, and `unknown` is never silently downgraded into a negative verdict. A null is unknown, never zero.
What can Preflight not see?
Several things it states rather than hides: Holder concentration — there is no keyless public source for it, and we do not scrape explorers. Uniswap v4 and every non-Uniswap venue. A token with no v3 pool may still have a market we never queried. Solana and every other non-EVM chain. This lane is EVM-shaped. The deployer address without an Etherscan key — a contract-creation record is not a keyless RPC read.
Can I reproduce a Preflight verdict myself?
Yes. Every evidence line carries the field it was read from and the date that field was written, and every threshold the rules turn on is published on this page (MIN_DAYS = 14, GO_SUCCESS_PCT = 95%, NO_SUCCESS_PCT = 50%, PROBE_FRESH_MS = 14 days, MIN_TOKEN_CHECKS = 3). The free exports and the MCP server serve the same records the verdict read.
Related: Run a Preflight · House rules · How Sato Route chooses · Sato Score