fshy: the f-research corpus as one read-only SQLite store store: public; commit 872967ae4177 (2026-10-27T11:15:10+05:45); as_of 2026-10-27; 4133 records, 2899 entities, 12534 evidence rows, 9881 parsed claims The dossier JSON in git is the truth; this store is derived from it and never edited. Operations: help, search, filter, get, entity, need, sql, worklist (same names in fr, the API and MCP). IDS - rid = topic/slug, stable (storage/hetzner-storage-box). Quote rids; never show or store rno. - rno is build-local: the text_fts docid and leaf key. Join on it, never cite it. - eid = vendor entity. An entity only groups records; each record carries its own verdict. RULES - needs_card, needs_phone, needs_id, needs_institution: 1 yes, 0 no, NULL UNKNOWN (never 'no'). 'No card' is needs_card=0 AND identity_basis='stated'. identity_basis='defaulted' means unknown. - Freshness: stale on day D when stale_on <= D (today UTC unless you pick as_of). verified_basis='inherited' means checked_on is only an upper bound. - usd_month, usd_per_tb_month: headline USD prices, NULL when nothing parsed. Say how many rows a filter or sort on them drops for NULL. interfaces: comma list, NULL = unknown. - duplicate_of IS NOT NULL marks a duplicate; lists exclude them unless asked. - vorder 0..7 orders verdicts best first; grp groups them. TABLES (key columns) - record(rid, topic, slug, eid, provider, url, category, verdict, vorder, grp, confidence, binding, identity_kind, identity_basis, needs_card, needs_phone, needs_id, needs_institution, crypto, interfaces, usd_month, usd_per_tb_month, verified_basis, checked_on, stale_on, summary, duplicate_of, doc, rno, +20 more): one row per record; doc is the projected JSON - entity(eid, name, domain, resolved_by, topics, n_records, best_vorder, review): a vendor; groups records - alias(eid, alias, kind): kind: name, provider, slug, alias, domain - evidence(rid, ord, url, url_kind, date, proved, capture): what each source proved - limit_row(rid, ord, kind, value, source, is_binding): is_binding=1 for the kind named in binding - claim(rid, path, kind, num, unit, per, currency, usd, fx_date, parse): parsed numbers; parse ok, partial or unparsed - unknown(rid, path, class, rule): placeholder, default or withheld values - leaf(lid, rno, path, type, value): projected JSON leaves; a record is lid BETWEEN lid_min AND lid_max - edge(src, dst, kind): kind: duplicate_of, variant_of, successor_of, same_offer_as, same-product, mentions - drift(kind, subject, other, field, a, b, detail): records of one product that disagree - history(hid, when_utc, status, confidence, title, supersedes, body) - history_link(hid, rid) - ledger(at, rid, path, old, new, rung, url, date, proved, reason): one row per amendment (history/ledger.jsonl) - also fx(ccy, date, usd_per_unit, source), capture(url, captured_at, path, sha256), vocab(domain, term, ord, meaning), meta(key, value) - text_fts: FTS4, contentless, one row per record (docid = record.rno). Columns in order: name, offer, limits, egress, identity, access, notes, evidence, extras. Terms are AND-ed; 'word*' is a prefix, 'col:word' limits to a column. CJK text is indexed as runs plus overlapping bigrams: query a CJK run as its bigrams separated by spaces. All columns: SELECT name FROM pragma_table_info('record'). Meanings: SELECT * FROM vocab. VOCABULARIES - verdict: qualifies = usable as stated; the read path was probed; qualifies-with-caveat = usable, with a named limit or an unprobed read path; trial-only = a time-boxed or one-time trial, not a recurring allowance; paid-only = no free allowance; listed for its price; fails-identity = the identity required is not reachable without it; fails-egress = data cannot be read back out at a usable rate or price; fails-quota = the free allowance is too small to matter; dead = the offer or the service no longer exists - grp: usable = verdict qualifies or qualifies-with-caveat; trial = verdict trial-only; paid = verdict paid-only; rejected = verdict fails-identity, fails-egress or fails-quota; dead = verdict dead - confidence: measured = a live request was made and its output kept; documented = a first-party page was read and the sentence quoted; reported = a third party said so; inferred = reasoned from other evidence; unverified = asserted and not checked - binding: request-rate, pull-count, per-ip-shaping, per-object-cap, write-gated, retention-clamped, volume-quota, none - identity_kind: anonymous, email, any-phone, country-phone, national-id, card, institution - identity_basis: stated = the identity requirement was read from a source; defaulted = the identity kind is a placeholder; card and phone are unknown - verified_basis: live = the record was checked against the service; inherited = carried from an earlier source; checked_on is an upper bound - unknown_class: not-applicable, defaulted, not-recorded, not-extracted, none-observed, not-stated, process, private-url, withheld, partly-held, interface-unknown, egress-unknown, identity-defaulted EXAMPLES (each runs as written) 1. Usable storage with no card, cheapest per TB-month first (NULL price last) SELECT rid, provider, usd_per_tb_month FROM record WHERE topic='storage' AND grp='usable' AND needs_card=0 AND identity_basis='stated' AND duplicate_of IS NULL ORDER BY usd_per_tb_month IS NULL, usd_per_tb_month LIMIT 10 2. Full text, one column filter plus a prefix term (CJK: query bigrams, e.g. MATCH '百度') SELECT r.rid, r.verdict FROM text_fts JOIN record r ON r.rno = text_fts.docid WHERE text_fts MATCH 'offer:gpu* hours' ORDER BY r.vorder LIMIT 10 3. Every record of a vendor, by alias SELECT rid, topic, verdict FROM record WHERE eid IN (SELECT eid FROM alias WHERE alias LIKE 'hetzner%') ORDER BY vorder, rid LIMIT 20 4. What goes stale in the next 30 days SELECT rid, stale_on, verified_basis FROM record WHERE stale_on <= date('now','+30 days') AND grp <> 'dead' ORDER BY vorder, stale_on LIMIT 20 5. Parsed prices per TB in USD, with the FX date used SELECT rid, num, currency, usd, fx_date FROM claim WHERE kind='price-per-tb' AND usd IS NOT NULL ORDER BY usd LIMIT 10 6. The binding request-rate limits, and who cites a host SELECT l.rid, l.value FROM limit_row l WHERE l.is_binding=1 AND l.kind='request-rate' AND l.rid IN (SELECT rid FROM evidence WHERE url LIKE '%github.com%') LIMIT 10