bigtech.sucks: living database + first assessment
The database is the source of truth; the site is a view over it.
- packages/core/db/schema.sql: vendors, products, categories, the 8-dimension
instrument, assessments, scores, evidence, findings, off-ramp, plus the
derived v_product_score view the game reads.
- packages/core/db/build.mjs: rebuilds bigtech.db, absorbs the legacy 43-product
roster as unassessed, applies seeds, then verifies the instrument's own rules
(weights sum to 100, totals recompute, grades match bands, every score has a
rationale, no tier-4 evidence on a scored dimension, reproducible-build caps
actually enforced).
- packages/core/db/seed/0001-signal.sql: Signal Desktop 8.36.0-alpha.1 on linux,
75.9/100 grade B, weakest dimension local_data_exposure. Evidence points at
the re-runnable audit artifacts in the Servetus vault.
- packages/core/src/data/generated/catalog.{ts,json}: generated export.
Verified: 44 products, 1 assessed, all checks pass.
2026-10-29 13:16:29 -05:00
|
|
|
-- bigtech.sucks — living database schema
|
|
|
|
|
-- The website is a view over this. Nothing in the site may hardcode a number
|
|
|
|
|
-- that lives here.
|
|
|
|
|
--
|
|
|
|
|
-- Design rule: an assessment is an ARTIFACT with a date, a version, a method and
|
|
|
|
|
-- evidence. A score without an assessment is a placeholder and is stored as NULL,
|
|
|
|
|
-- never as a guess.
|
|
|
|
|
|
|
|
|
|
PRAGMA foreign_keys = ON;
|
|
|
|
|
PRAGMA journal_mode = WAL;
|
|
|
|
|
|
|
|
|
|
-- ---------------------------------------------------------------- who owns it
|
|
|
|
|
CREATE TABLE IF NOT EXISTS vendor (
|
|
|
|
|
id TEXT PRIMARY KEY,
|
|
|
|
|
name TEXT NOT NULL,
|
|
|
|
|
legal_entity TEXT,
|
|
|
|
|
entity_type TEXT CHECK (entity_type IN ('nonprofit','private','public','state','unknown')),
|
|
|
|
|
jurisdiction TEXT, -- ISO 3166-1 alpha-2
|
|
|
|
|
business_model TEXT CHECK (business_model IN ('advertising','subscription','hardware','license','mixed','none','unknown')),
|
|
|
|
|
parent_id TEXT REFERENCES vendor(id),
|
|
|
|
|
founded TEXT,
|
|
|
|
|
notes TEXT
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- ---------------------------------------------------------------- what it is
|
|
|
|
|
CREATE TABLE IF NOT EXISTS category (
|
|
|
|
|
id TEXT PRIMARY KEY,
|
|
|
|
|
label TEXT NOT NULL,
|
|
|
|
|
sensitivity REAL NOT NULL CHECK (sensitivity BETWEEN 0 AND 1),
|
|
|
|
|
nextcloud TEXT
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CREATE TABLE IF NOT EXISTS product (
|
|
|
|
|
id TEXT PRIMARY KEY,
|
|
|
|
|
vendor_id TEXT NOT NULL REFERENCES vendor(id),
|
|
|
|
|
name TEXT NOT NULL,
|
|
|
|
|
category_id TEXT REFERENCES category(id),
|
|
|
|
|
-- platform is part of the identity: Signal iOS != Signal Desktop
|
|
|
|
|
platform TEXT NOT NULL,
|
|
|
|
|
source_url TEXT,
|
|
|
|
|
license TEXT,
|
|
|
|
|
sovereign INTEGER NOT NULL DEFAULT 0 CHECK (sovereign IN (0,1)),
|
|
|
|
|
boss INTEGER NOT NULL DEFAULT 0 CHECK (boss IN (0,1)),
|
|
|
|
|
art_slot TEXT,
|
|
|
|
|
monthly_cost REAL,
|
feat: the closed-source rule, and the board
Christian, 2026-10-29: 'Closed source software, you have no idea. And then all
we have is reputation. So you kind of start with one arm or two arms tied
behind your back.'
That is now arithmetic instead of an opinion.
- assessment.source_available: 1 = we can read the code, 0 = we cannot.
- Closed source cannot exceed 5 on ANY dimension without tier-1 or tier-2
evidence of kind 'capture' or 'filing'. Reputation is tier 3, and tier 3 is
not a measurement. The build fails if a closed-source score breaks the rule.
- Verifiability still caps at 3 with no reproducible build.
Practical ceiling for closed source: 86/100 in theory, if every dimension is
backed by a capture or a court filing. In practice it is a fight for a C.
- product.priority puts a human's ask ahead of a crawler's discovery.
- v_backlog orders by priority, then measured usage.
- migrate(): the database authors itself, so it must survive its own schema
changes. Add columns, drop views, let schema.sql recreate them. Never drop
and rebuild, which would destroy the self-authored roster.
On the board: Slack (closed, capped) and Kino (closed, capped, founders call
2026-10-30 17:00). Neither is scored. Neither gets a number until it has
evidence.
2026-10-29 15:23:31 -05:00
|
|
|
-- priority > 0 puts a product on the board even before anything discovers it
|
|
|
|
|
priority INTEGER NOT NULL DEFAULT 0,
|
bigtech.sucks: living database + first assessment
The database is the source of truth; the site is a view over it.
- packages/core/db/schema.sql: vendors, products, categories, the 8-dimension
instrument, assessments, scores, evidence, findings, off-ramp, plus the
derived v_product_score view the game reads.
- packages/core/db/build.mjs: rebuilds bigtech.db, absorbs the legacy 43-product
roster as unassessed, applies seeds, then verifies the instrument's own rules
(weights sum to 100, totals recompute, grades match bands, every score has a
rationale, no tier-4 evidence on a scored dimension, reproducible-build caps
actually enforced).
- packages/core/db/seed/0001-signal.sql: Signal Desktop 8.36.0-alpha.1 on linux,
75.9/100 grade B, weakest dimension local_data_exposure. Evidence points at
the re-runnable audit artifacts in the Servetus vault.
- packages/core/src/data/generated/catalog.{ts,json}: generated export.
Verified: 44 products, 1 assessed, all checks pass.
2026-10-29 13:16:29 -05:00
|
|
|
notes TEXT,
|
|
|
|
|
UNIQUE(id, platform)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- ---------------------------------------------------------------- the instrument
|
|
|
|
|
CREATE TABLE IF NOT EXISTS dimension (
|
|
|
|
|
id TEXT PRIMARY KEY,
|
|
|
|
|
label TEXT NOT NULL,
|
|
|
|
|
weight REAL NOT NULL CHECK (weight > 0),
|
|
|
|
|
anchor_10 TEXT NOT NULL,
|
|
|
|
|
anchor_0 TEXT NOT NULL
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CREATE TABLE IF NOT EXISTS assessment (
|
|
|
|
|
id TEXT PRIMARY KEY,
|
|
|
|
|
product_id TEXT NOT NULL REFERENCES product(id),
|
|
|
|
|
version TEXT NOT NULL,
|
|
|
|
|
source_commit TEXT,
|
|
|
|
|
assessed_on TEXT NOT NULL,
|
|
|
|
|
method_version TEXT NOT NULL,
|
|
|
|
|
-- 0 = none, 1 = available but experimental/unverified, 2 = verified
|
|
|
|
|
reproducible_build INTEGER NOT NULL DEFAULT 0 CHECK (reproducible_build IN (0,1,2)),
|
feat: the closed-source rule, and the board
Christian, 2026-10-29: 'Closed source software, you have no idea. And then all
we have is reputation. So you kind of start with one arm or two arms tied
behind your back.'
That is now arithmetic instead of an opinion.
- assessment.source_available: 1 = we can read the code, 0 = we cannot.
- Closed source cannot exceed 5 on ANY dimension without tier-1 or tier-2
evidence of kind 'capture' or 'filing'. Reputation is tier 3, and tier 3 is
not a measurement. The build fails if a closed-source score breaks the rule.
- Verifiability still caps at 3 with no reproducible build.
Practical ceiling for closed source: 86/100 in theory, if every dimension is
backed by a capture or a court filing. In practice it is a fight for a C.
- product.priority puts a human's ask ahead of a crawler's discovery.
- v_backlog orders by priority, then measured usage.
- migrate(): the database authors itself, so it must survive its own schema
changes. Add columns, drop views, let schema.sql recreate them. Never drop
and rebuild, which would destroy the self-authored roster.
On the board: Slack (closed, capped) and Kino (closed, capped, founders call
2026-10-30 17:00). Neither is scored. Neither gets a number until it has
evidence.
2026-10-29 15:23:31 -05:00
|
|
|
-- 1 = we can read the code. 0 = closed. Closed source cannot exceed 5 on any
|
|
|
|
|
-- dimension unless independent evidence (a capture or a court filing) says so.
|
|
|
|
|
source_available INTEGER NOT NULL DEFAULT 1 CHECK (source_available IN (0,1)),
|
bigtech.sucks: living database + first assessment
The database is the source of truth; the site is a view over it.
- packages/core/db/schema.sql: vendors, products, categories, the 8-dimension
instrument, assessments, scores, evidence, findings, off-ramp, plus the
derived v_product_score view the game reads.
- packages/core/db/build.mjs: rebuilds bigtech.db, absorbs the legacy 43-product
roster as unassessed, applies seeds, then verifies the instrument's own rules
(weights sum to 100, totals recompute, grades match bands, every score has a
rationale, no tier-4 evidence on a scored dimension, reproducible-build caps
actually enforced).
- packages/core/db/seed/0001-signal.sql: Signal Desktop 8.36.0-alpha.1 on linux,
75.9/100 grade B, weakest dimension local_data_exposure. Evidence points at
the re-runnable audit artifacts in the Servetus vault.
- packages/core/src/data/generated/catalog.{ts,json}: generated export.
Verified: 44 products, 1 assessed, all checks pass.
2026-10-29 13:16:29 -05:00
|
|
|
weighted_total REAL NOT NULL CHECK (weighted_total BETWEEN 0 AND 100),
|
|
|
|
|
grade TEXT NOT NULL,
|
|
|
|
|
weakest_dimension TEXT NOT NULL REFERENCES dimension(id),
|
|
|
|
|
headline TEXT NOT NULL, -- the caveat, in one sentence
|
|
|
|
|
not_tested TEXT,
|
|
|
|
|
UNIQUE(product_id, version, assessed_on)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CREATE TABLE IF NOT EXISTS score (
|
|
|
|
|
assessment_id TEXT NOT NULL REFERENCES assessment(id) ON DELETE CASCADE,
|
|
|
|
|
dimension_id TEXT NOT NULL REFERENCES dimension(id),
|
|
|
|
|
value REAL NOT NULL CHECK (value BETWEEN 0 AND 10),
|
|
|
|
|
rationale TEXT,
|
|
|
|
|
PRIMARY KEY (assessment_id, dimension_id)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- evidence is the only thing that makes a score legitimate
|
|
|
|
|
CREATE TABLE IF NOT EXISTS evidence (
|
|
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
|
|
assessment_id TEXT NOT NULL REFERENCES assessment(id) ON DELETE CASCADE,
|
|
|
|
|
dimension_id TEXT REFERENCES dimension(id),
|
|
|
|
|
claim TEXT NOT NULL,
|
|
|
|
|
tier INTEGER NOT NULL CHECK (tier IN (1,2,3,4)),
|
|
|
|
|
kind TEXT CHECK (kind IN ('source','capture','record','filing','advisory','paper','claim')),
|
|
|
|
|
artifact TEXT, -- path inside the vault, or URL
|
|
|
|
|
sha256 TEXT,
|
|
|
|
|
observed_at TEXT
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CREATE TABLE IF NOT EXISTS finding (
|
|
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
|
|
assessment_id TEXT NOT NULL REFERENCES assessment(id) ON DELETE CASCADE,
|
|
|
|
|
severity TEXT NOT NULL CHECK (severity IN ('critical','high','medium','low','info')),
|
|
|
|
|
title TEXT NOT NULL,
|
|
|
|
|
detail TEXT,
|
|
|
|
|
status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open','fixed','by_design','disputed','accepted')),
|
|
|
|
|
disclosed_on TEXT,
|
|
|
|
|
cve TEXT
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CREATE TABLE IF NOT EXISTS offramp (
|
|
|
|
|
product_id TEXT NOT NULL REFERENCES product(id),
|
|
|
|
|
replacement TEXT NOT NULL,
|
|
|
|
|
nextcloud TEXT,
|
|
|
|
|
notes TEXT,
|
|
|
|
|
PRIMARY KEY (product_id, replacement)
|
|
|
|
|
);
|
|
|
|
|
|
feat: self-authoring ingest, relevance gate, and the Ranch Oath
The roster writes itself. The scores do not.
- db/ingest/sources.mjs: GitHub and Flathub adapters. GitHub is ranked by
stars (usage); Flathub is a curated store of end-user Linux apps, so
relevance is free there and has to be earned on GitHub.
- db/ingest/run.mjs: discovers into the roster as unassessed products, never
as scores. Every discovery leaves a receipt (source, url, usage metric,
timestamp) so a reader can see where a product came from and why it ranks.
- LooksLikeUserSoftware gate: topic:messaging sorts RabbitMQ to the top
because brokers are highly starred and are not things people install.
- build.mjs no longer wipes the database. The DB authors itself, so a rebuild
would have thrown the roster away. --fresh is now explicit.
- v_backlog view: what to assess next, ordered by measured usage.
- packages/web/public/oath.html: the Ranch Oath, with an ASCII Bible crest,
bound to a SHA-256 of catalog.json. The page recomputes the digest in the
browser and reports VERIFIED or BROKEN. An oath you cannot break is decoration.
Roster now 122 products, 1 assessed. All instrument checks pass.
2026-10-29 13:23:57 -05:00
|
|
|
-- ---------------------------------------------------------------- discovery
|
|
|
|
|
-- The database authors itself. Every product the ingest finds leaves a receipt
|
|
|
|
|
-- here, so a reader can see WHERE it came from and HOW MUCH it is used.
|
|
|
|
|
-- Discovery may create a product. Discovery may NEVER create a score.
|
|
|
|
|
CREATE TABLE IF NOT EXISTS discovery (
|
|
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
|
|
product_id TEXT NOT NULL REFERENCES product(id),
|
|
|
|
|
source TEXT NOT NULL CHECK (source IN ('github','flathub','alternativeto','manual','seed')),
|
|
|
|
|
source_url TEXT,
|
|
|
|
|
usage_signal INTEGER,
|
|
|
|
|
usage_metric TEXT,
|
|
|
|
|
observed_at TEXT NOT NULL,
|
|
|
|
|
raw TEXT,
|
|
|
|
|
UNIQUE(product_id, source, source_url)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_discovery_product ON discovery(product_id);
|
|
|
|
|
|
2026-10-29 16:07:55 -05:00
|
|
|
-- ---------------------------------------------------------------- attestation
|
|
|
|
|
-- Closed source can earn its way up, but only by producing evidence that expires.
|
|
|
|
|
--
|
|
|
|
|
-- The level is NOT claimed by the vendor and NOT assigned by us. It is COMPUTED
|
|
|
|
|
-- from which required artifacts actually exist. A vendor can claim level 4 all day;
|
|
|
|
|
-- if the capture report is missing, the validator grants level 1.
|
|
|
|
|
--
|
|
|
|
|
-- Every attestation is bound to one artifact hash on one version. Any new build
|
|
|
|
|
-- invalidates it. There is no such thing as a standing certificate here.
|
|
|
|
|
CREATE TABLE IF NOT EXISTS attestation (
|
|
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
|
|
product_id TEXT NOT NULL REFERENCES product(id),
|
|
|
|
|
version TEXT NOT NULL,
|
|
|
|
|
artifact_sha256 TEXT NOT NULL,
|
|
|
|
|
level INTEGER NOT NULL CHECK (level BETWEEN 0 AND 4),
|
|
|
|
|
-- L1 declared: the vendor tells the world what is in the box
|
|
|
|
|
sbom_url TEXT, -- CycloneDX or SPDX
|
|
|
|
|
signed_hash_url TEXT, -- signed release manifest
|
|
|
|
|
destination_allowlist_url TEXT, -- every host it may contact, and why
|
|
|
|
|
-- L2 observed: we watched this exact binary
|
|
|
|
|
capture_report TEXT, -- D1-D4 output, hash-bound
|
|
|
|
|
-- L3 reproducible: the binary is provably the build they claim
|
|
|
|
|
rebuild_recipe_url TEXT,
|
|
|
|
|
rebuild_matches INTEGER CHECK (rebuild_matches IN (0,1)),
|
|
|
|
|
-- L4 adversarial: someone tried to break it and published the attempt
|
|
|
|
|
adversarial_report_url TEXT,
|
|
|
|
|
differential_clean INTEGER CHECK (differential_clean IN (0,1)),
|
|
|
|
|
issued_on TEXT NOT NULL,
|
|
|
|
|
expires_on TEXT NOT NULL,
|
|
|
|
|
auditor TEXT NOT NULL,
|
|
|
|
|
-- Who ran the test. This is the load-bearing column.
|
|
|
|
|
-- A vendor running our harness produces a DECLARATION, not an observation.
|
|
|
|
|
-- Declarations are capped at level 1, because a self-run test is a claim.
|
|
|
|
|
-- Levels 3 and 4 survive a self-run, because a public rebuild recipe and a
|
|
|
|
|
-- published adversarial review can be re-checked by anyone.
|
|
|
|
|
attestor TEXT NOT NULL DEFAULT 'vendor'
|
|
|
|
|
CHECK (attestor IN ('vendor','binary-ranch','third-party','community')),
|
|
|
|
|
UNIQUE(product_id, version, artifact_sha256)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_attestation_product ON attestation(product_id, version);
|
|
|
|
|
|
feat: the hook prober, and the list becomes the front door
Christian: 'drop any URL and say tell me where Big Tech has its hooks... we're
not just rating software, we're rating software as a service.'
db/hooks/probe.mjs answers that from public records only: DNS, MX, SPF, ASN via
Team Cymru, HTTP headers, and the third-party hosts named in the page's own HTML.
Nothing is scanned. If a site tells the world it sends mail through Google, this
reads it.
Verified live, 2026-10-29:
parler.com -> AS16509 AMAZON, plus Microsoft email, plus Vercel
netflix.com -> AS40027 NETFLIX (their own Open Connect edge), NOT AWS
signal.org -> Cloudflare CDN, Google touchpoints
bigtech.sucks-> AS16509 AMAZON (GoDaddy parking sits on AWS)
That netflix result is the important one. The front door is Netflix's own network;
the catalog and user data are in AWS. Edge ASN is not backend custody, and the tool
says so in its own header comment rather than pretending otherwise.
Also:
- The list is now the front door (public/index.html, generated from the DB).
The game moved to /game.html and keeps working, ready for its own subdomain.
- suggestion table + v_requested view: anyone can ask for a product to be rated,
no account, no email. Optional contact. Addresses are salted-hashed, never stored.
- POST /api/suggest on the existing server package, with a graceful fallback on the
static page to a Forgejo issue so requests are never lost when the server is down.
2026-10-29 17:23:11 -05:00
|
|
|
-- ---------------------------------------------------------------- suggestions
|
|
|
|
|
-- Anyone can ask for a product to be rated. The backlog is built from these.
|
|
|
|
|
-- No account, no email required. An optional contact so we can tell them it shipped.
|
|
|
|
|
CREATE TABLE IF NOT EXISTS suggestion (
|
|
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
|
|
product_name TEXT NOT NULL,
|
|
|
|
|
category_hint TEXT,
|
|
|
|
|
note TEXT,
|
|
|
|
|
contact TEXT,
|
|
|
|
|
suggested_at TEXT NOT NULL,
|
|
|
|
|
ip_hash TEXT, -- salted, never the raw address
|
|
|
|
|
status TEXT NOT NULL DEFAULT 'pending'
|
|
|
|
|
CHECK (status IN ('pending','accepted','duplicate','declined'))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_suggestion_name ON suggestion(LOWER(product_name));
|
|
|
|
|
|
|
|
|
|
-- What the public is asking for, most-requested first.
|
|
|
|
|
CREATE VIEW IF NOT EXISTS v_requested AS
|
|
|
|
|
SELECT
|
|
|
|
|
LOWER(TRIM(s.product_name)) AS key,
|
|
|
|
|
TRIM(MIN(s.product_name)) AS product_name,
|
|
|
|
|
COUNT(*) AS requests,
|
|
|
|
|
MAX(s.suggested_at) AS latest
|
|
|
|
|
FROM suggestion s
|
|
|
|
|
WHERE s.status = 'pending'
|
|
|
|
|
GROUP BY LOWER(TRIM(s.product_name))
|
|
|
|
|
ORDER BY requests DESC, latest DESC;
|
|
|
|
|
|
bigtech.sucks: living database + first assessment
The database is the source of truth; the site is a view over it.
- packages/core/db/schema.sql: vendors, products, categories, the 8-dimension
instrument, assessments, scores, evidence, findings, off-ramp, plus the
derived v_product_score view the game reads.
- packages/core/db/build.mjs: rebuilds bigtech.db, absorbs the legacy 43-product
roster as unassessed, applies seeds, then verifies the instrument's own rules
(weights sum to 100, totals recompute, grades match bands, every score has a
rationale, no tier-4 evidence on a scored dimension, reproducible-build caps
actually enforced).
- packages/core/db/seed/0001-signal.sql: Signal Desktop 8.36.0-alpha.1 on linux,
75.9/100 grade B, weakest dimension local_data_exposure. Evidence points at
the re-runnable audit artifacts in the Servetus vault.
- packages/core/src/data/generated/catalog.{ts,json}: generated export.
Verified: 44 products, 1 assessed, all checks pass.
2026-10-29 13:16:29 -05:00
|
|
|
-- ---------------------------------------------------------------- derived views
|
|
|
|
|
-- The single number the game and the report both use.
|
|
|
|
|
CREATE VIEW IF NOT EXISTS v_product_score AS
|
|
|
|
|
SELECT
|
|
|
|
|
p.id AS product_id,
|
|
|
|
|
p.name AS product,
|
|
|
|
|
p.platform,
|
|
|
|
|
p.category_id,
|
|
|
|
|
v.id AS vendor_id,
|
|
|
|
|
v.name AS vendor,
|
|
|
|
|
v.business_model,
|
|
|
|
|
v.jurisdiction,
|
|
|
|
|
a.id AS assessment_id,
|
|
|
|
|
a.assessed_on,
|
|
|
|
|
a.version,
|
|
|
|
|
a.weighted_total,
|
|
|
|
|
a.grade,
|
|
|
|
|
a.weakest_dimension,
|
|
|
|
|
a.headline,
|
|
|
|
|
-- policy axis: who holds your data, and what can they be made to hand over
|
|
|
|
|
CAST(ROUND(10 * (
|
|
|
|
|
0.40 * (SELECT value FROM score WHERE assessment_id = a.id AND dimension_id = 'server_retention')
|
|
|
|
|
+ 0.30 * (SELECT value FROM score WHERE assessment_id = a.id AND dimension_id = 'ownership_jurisdiction')
|
|
|
|
|
+ 0.30 * (SELECT value FROM score WHERE assessment_id = a.id AND dimension_id = 'user_control_exit')
|
|
|
|
|
)) AS INTEGER) AS policy,
|
|
|
|
|
-- infra axis: can you verify it, and what does it leave on your disk
|
|
|
|
|
CAST(ROUND(10 * (
|
|
|
|
|
0.50 * (SELECT value FROM score WHERE assessment_id = a.id AND dimension_id = 'verifiability')
|
|
|
|
|
+ 0.30 * (SELECT value FROM score WHERE assessment_id = a.id AND dimension_id = 'dependency_surface')
|
|
|
|
|
+ 0.20 * (SELECT value FROM score WHERE assessment_id = a.id AND dimension_id = 'local_data_exposure')
|
|
|
|
|
)) AS INTEGER) AS infra
|
|
|
|
|
FROM product p
|
|
|
|
|
JOIN vendor v ON v.id = p.vendor_id
|
|
|
|
|
LEFT JOIN assessment a
|
|
|
|
|
ON a.product_id = p.id
|
|
|
|
|
AND a.assessed_on = (SELECT MAX(assessed_on) FROM assessment WHERE product_id = p.id);
|
|
|
|
|
|
|
|
|
|
-- A product with no assessment must surface as unassessed, not as a number.
|
|
|
|
|
CREATE VIEW IF NOT EXISTS v_coverage AS
|
|
|
|
|
SELECT
|
|
|
|
|
p.id AS product_id,
|
|
|
|
|
p.name,
|
|
|
|
|
p.platform,
|
|
|
|
|
CASE WHEN a.id IS NULL THEN 'unassessed' ELSE a.grade END AS status,
|
|
|
|
|
a.weighted_total
|
|
|
|
|
FROM product p
|
|
|
|
|
LEFT JOIN assessment a ON a.product_id = p.id
|
|
|
|
|
AND a.assessed_on = (SELECT MAX(assessed_on) FROM assessment WHERE product_id = p.id);
|
feat: self-authoring ingest, relevance gate, and the Ranch Oath
The roster writes itself. The scores do not.
- db/ingest/sources.mjs: GitHub and Flathub adapters. GitHub is ranked by
stars (usage); Flathub is a curated store of end-user Linux apps, so
relevance is free there and has to be earned on GitHub.
- db/ingest/run.mjs: discovers into the roster as unassessed products, never
as scores. Every discovery leaves a receipt (source, url, usage metric,
timestamp) so a reader can see where a product came from and why it ranks.
- LooksLikeUserSoftware gate: topic:messaging sorts RabbitMQ to the top
because brokers are highly starred and are not things people install.
- build.mjs no longer wipes the database. The DB authors itself, so a rebuild
would have thrown the roster away. --fresh is now explicit.
- v_backlog view: what to assess next, ordered by measured usage.
- packages/web/public/oath.html: the Ranch Oath, with an ASCII Bible crest,
bound to a SHA-256 of catalog.json. The page recomputes the digest in the
browser and reports VERIFIED or BROKEN. An oath you cannot break is decoration.
Roster now 122 products, 1 assessed. All instrument checks pass.
2026-10-29 13:23:57 -05:00
|
|
|
|
feat: the closed-source rule, and the board
Christian, 2026-10-29: 'Closed source software, you have no idea. And then all
we have is reputation. So you kind of start with one arm or two arms tied
behind your back.'
That is now arithmetic instead of an opinion.
- assessment.source_available: 1 = we can read the code, 0 = we cannot.
- Closed source cannot exceed 5 on ANY dimension without tier-1 or tier-2
evidence of kind 'capture' or 'filing'. Reputation is tier 3, and tier 3 is
not a measurement. The build fails if a closed-source score breaks the rule.
- Verifiability still caps at 3 with no reproducible build.
Practical ceiling for closed source: 86/100 in theory, if every dimension is
backed by a capture or a court filing. In practice it is a fight for a C.
- product.priority puts a human's ask ahead of a crawler's discovery.
- v_backlog orders by priority, then measured usage.
- migrate(): the database authors itself, so it must survive its own schema
changes. Add columns, drop views, let schema.sql recreate them. Never drop
and rebuild, which would destroy the self-authored roster.
On the board: Slack (closed, capped) and Kino (closed, capped, founders call
2026-10-30 17:00). Neither is scored. Neither gets a number until it has
evidence.
2026-10-29 15:23:31 -05:00
|
|
|
-- What to assess next. Anything a human put on the board outranks anything a
|
|
|
|
|
-- crawler found, and within each tier usage decides.
|
feat: self-authoring ingest, relevance gate, and the Ranch Oath
The roster writes itself. The scores do not.
- db/ingest/sources.mjs: GitHub and Flathub adapters. GitHub is ranked by
stars (usage); Flathub is a curated store of end-user Linux apps, so
relevance is free there and has to be earned on GitHub.
- db/ingest/run.mjs: discovers into the roster as unassessed products, never
as scores. Every discovery leaves a receipt (source, url, usage metric,
timestamp) so a reader can see where a product came from and why it ranks.
- LooksLikeUserSoftware gate: topic:messaging sorts RabbitMQ to the top
because brokers are highly starred and are not things people install.
- build.mjs no longer wipes the database. The DB authors itself, so a rebuild
would have thrown the roster away. --fresh is now explicit.
- v_backlog view: what to assess next, ordered by measured usage.
- packages/web/public/oath.html: the Ranch Oath, with an ASCII Bible crest,
bound to a SHA-256 of catalog.json. The page recomputes the digest in the
browser and reports VERIFIED or BROKEN. An oath you cannot break is decoration.
Roster now 122 products, 1 assessed. All instrument checks pass.
2026-10-29 13:23:57 -05:00
|
|
|
CREATE VIEW IF NOT EXISTS v_backlog AS
|
|
|
|
|
SELECT
|
|
|
|
|
p.id AS product_id,
|
|
|
|
|
p.name,
|
|
|
|
|
p.platform,
|
|
|
|
|
p.category_id,
|
feat: the closed-source rule, and the board
Christian, 2026-10-29: 'Closed source software, you have no idea. And then all
we have is reputation. So you kind of start with one arm or two arms tied
behind your back.'
That is now arithmetic instead of an opinion.
- assessment.source_available: 1 = we can read the code, 0 = we cannot.
- Closed source cannot exceed 5 on ANY dimension without tier-1 or tier-2
evidence of kind 'capture' or 'filing'. Reputation is tier 3, and tier 3 is
not a measurement. The build fails if a closed-source score breaks the rule.
- Verifiability still caps at 3 with no reproducible build.
Practical ceiling for closed source: 86/100 in theory, if every dimension is
backed by a capture or a court filing. In practice it is a fight for a C.
- product.priority puts a human's ask ahead of a crawler's discovery.
- v_backlog orders by priority, then measured usage.
- migrate(): the database authors itself, so it must survive its own schema
changes. Add columns, drop views, let schema.sql recreate them. Never drop
and rebuild, which would destroy the self-authored roster.
On the board: Slack (closed, capped) and Kino (closed, capped, founders call
2026-10-30 17:00). Neither is scored. Neither gets a number until it has
evidence.
2026-10-29 15:23:31 -05:00
|
|
|
p.priority AS priority,
|
|
|
|
|
COALESCE(MAX(d.usage_signal), 0) AS usage,
|
feat: self-authoring ingest, relevance gate, and the Ranch Oath
The roster writes itself. The scores do not.
- db/ingest/sources.mjs: GitHub and Flathub adapters. GitHub is ranked by
stars (usage); Flathub is a curated store of end-user Linux apps, so
relevance is free there and has to be earned on GitHub.
- db/ingest/run.mjs: discovers into the roster as unassessed products, never
as scores. Every discovery leaves a receipt (source, url, usage metric,
timestamp) so a reader can see where a product came from and why it ranks.
- LooksLikeUserSoftware gate: topic:messaging sorts RabbitMQ to the top
because brokers are highly starred and are not things people install.
- build.mjs no longer wipes the database. The DB authors itself, so a rebuild
would have thrown the roster away. --fresh is now explicit.
- v_backlog view: what to assess next, ordered by measured usage.
- packages/web/public/oath.html: the Ranch Oath, with an ASCII Bible crest,
bound to a SHA-256 of catalog.json. The page recomputes the digest in the
browser and reports VERIFIED or BROKEN. An oath you cannot break is decoration.
Roster now 122 products, 1 assessed. All instrument checks pass.
2026-10-29 13:23:57 -05:00
|
|
|
GROUP_CONCAT(DISTINCT d.source) AS found_via
|
|
|
|
|
FROM product p
|
feat: the closed-source rule, and the board
Christian, 2026-10-29: 'Closed source software, you have no idea. And then all
we have is reputation. So you kind of start with one arm or two arms tied
behind your back.'
That is now arithmetic instead of an opinion.
- assessment.source_available: 1 = we can read the code, 0 = we cannot.
- Closed source cannot exceed 5 on ANY dimension without tier-1 or tier-2
evidence of kind 'capture' or 'filing'. Reputation is tier 3, and tier 3 is
not a measurement. The build fails if a closed-source score breaks the rule.
- Verifiability still caps at 3 with no reproducible build.
Practical ceiling for closed source: 86/100 in theory, if every dimension is
backed by a capture or a court filing. In practice it is a fight for a C.
- product.priority puts a human's ask ahead of a crawler's discovery.
- v_backlog orders by priority, then measured usage.
- migrate(): the database authors itself, so it must survive its own schema
changes. Add columns, drop views, let schema.sql recreate them. Never drop
and rebuild, which would destroy the self-authored roster.
On the board: Slack (closed, capped) and Kino (closed, capped, founders call
2026-10-30 17:00). Neither is scored. Neither gets a number until it has
evidence.
2026-10-29 15:23:31 -05:00
|
|
|
LEFT JOIN discovery d ON d.product_id = p.id
|
feat: self-authoring ingest, relevance gate, and the Ranch Oath
The roster writes itself. The scores do not.
- db/ingest/sources.mjs: GitHub and Flathub adapters. GitHub is ranked by
stars (usage); Flathub is a curated store of end-user Linux apps, so
relevance is free there and has to be earned on GitHub.
- db/ingest/run.mjs: discovers into the roster as unassessed products, never
as scores. Every discovery leaves a receipt (source, url, usage metric,
timestamp) so a reader can see where a product came from and why it ranks.
- LooksLikeUserSoftware gate: topic:messaging sorts RabbitMQ to the top
because brokers are highly starred and are not things people install.
- build.mjs no longer wipes the database. The DB authors itself, so a rebuild
would have thrown the roster away. --fresh is now explicit.
- v_backlog view: what to assess next, ordered by measured usage.
- packages/web/public/oath.html: the Ranch Oath, with an ASCII Bible crest,
bound to a SHA-256 of catalog.json. The page recomputes the digest in the
browser and reports VERIFIED or BROKEN. An oath you cannot break is decoration.
Roster now 122 products, 1 assessed. All instrument checks pass.
2026-10-29 13:23:57 -05:00
|
|
|
WHERE NOT EXISTS (SELECT 1 FROM assessment a WHERE a.product_id = p.id)
|
feat: the closed-source rule, and the board
Christian, 2026-10-29: 'Closed source software, you have no idea. And then all
we have is reputation. So you kind of start with one arm or two arms tied
behind your back.'
That is now arithmetic instead of an opinion.
- assessment.source_available: 1 = we can read the code, 0 = we cannot.
- Closed source cannot exceed 5 on ANY dimension without tier-1 or tier-2
evidence of kind 'capture' or 'filing'. Reputation is tier 3, and tier 3 is
not a measurement. The build fails if a closed-source score breaks the rule.
- Verifiability still caps at 3 with no reproducible build.
Practical ceiling for closed source: 86/100 in theory, if every dimension is
backed by a capture or a court filing. In practice it is a fight for a C.
- product.priority puts a human's ask ahead of a crawler's discovery.
- v_backlog orders by priority, then measured usage.
- migrate(): the database authors itself, so it must survive its own schema
changes. Add columns, drop views, let schema.sql recreate them. Never drop
and rebuild, which would destroy the self-authored roster.
On the board: Slack (closed, capped) and Kino (closed, capped, founders call
2026-10-30 17:00). Neither is scored. Neither gets a number until it has
evidence.
2026-10-29 15:23:31 -05:00
|
|
|
AND (d.id IS NOT NULL OR p.priority > 0)
|
feat: self-authoring ingest, relevance gate, and the Ranch Oath
The roster writes itself. The scores do not.
- db/ingest/sources.mjs: GitHub and Flathub adapters. GitHub is ranked by
stars (usage); Flathub is a curated store of end-user Linux apps, so
relevance is free there and has to be earned on GitHub.
- db/ingest/run.mjs: discovers into the roster as unassessed products, never
as scores. Every discovery leaves a receipt (source, url, usage metric,
timestamp) so a reader can see where a product came from and why it ranks.
- LooksLikeUserSoftware gate: topic:messaging sorts RabbitMQ to the top
because brokers are highly starred and are not things people install.
- build.mjs no longer wipes the database. The DB authors itself, so a rebuild
would have thrown the roster away. --fresh is now explicit.
- v_backlog view: what to assess next, ordered by measured usage.
- packages/web/public/oath.html: the Ranch Oath, with an ASCII Bible crest,
bound to a SHA-256 of catalog.json. The page recomputes the digest in the
browser and reports VERIFIED or BROKEN. An oath you cannot break is decoration.
Roster now 122 products, 1 assessed. All instrument checks pass.
2026-10-29 13:23:57 -05:00
|
|
|
GROUP BY p.id
|
feat: the closed-source rule, and the board
Christian, 2026-10-29: 'Closed source software, you have no idea. And then all
we have is reputation. So you kind of start with one arm or two arms tied
behind your back.'
That is now arithmetic instead of an opinion.
- assessment.source_available: 1 = we can read the code, 0 = we cannot.
- Closed source cannot exceed 5 on ANY dimension without tier-1 or tier-2
evidence of kind 'capture' or 'filing'. Reputation is tier 3, and tier 3 is
not a measurement. The build fails if a closed-source score breaks the rule.
- Verifiability still caps at 3 with no reproducible build.
Practical ceiling for closed source: 86/100 in theory, if every dimension is
backed by a capture or a court filing. In practice it is a fight for a C.
- product.priority puts a human's ask ahead of a crawler's discovery.
- v_backlog orders by priority, then measured usage.
- migrate(): the database authors itself, so it must survive its own schema
changes. Add columns, drop views, let schema.sql recreate them. Never drop
and rebuild, which would destroy the self-authored roster.
On the board: Slack (closed, capped) and Kino (closed, capped, founders call
2026-10-30 17:00). Neither is scored. Neither gets a number until it has
evidence.
2026-10-29 15:23:31 -05:00
|
|
|
ORDER BY p.priority DESC, usage DESC;
|