Observed on the operator's machine 2026-10-30 while reinstalling to put the app to use. Four months after the package was purged, a fresh install found ~/.config/Signal/sql/db.sqlite (54,214,656 bytes, mtime 2026-06-21), tried to open it, and aborted before the linking screen: MainSQL: sqlite(SQLITE_NOTADB): file is not a database in PRAGMA journal_mode = WAL MainSQL: migrateDatabase: Migration without cipher change failed sql.initialize was unsuccessful; returning early The SQLCipher key in config.json no longer resolved. The UI named nothing and offered only 'Delete data and restart', which discards the history. Moving the config directory aside fixes it; nothing in the product says so. Recorded as a medium finding, status open. The score does not move: 76.4 / B. local_data_exposure was already 5 for exactly this behaviour, and a finding is evidence, not a point. What changes is that the number now has a receipt instead of a rationale. Artifact: Servetus/00-Artifacts/2026/10-Oct/30/clu-signal-startup-failure/ main.log.excerpt - the failing run, verbatim 00-provenance.txt - package version, file sizes, sha256 of the retained db Retained state moved to ~/Signal-backup-2026-10-30-0026, not deleted. |
||
|---|---|---|
| deploy | ||
| packages | ||
| .gitignore | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
bigtech.sucks — Draw the Line
V0.1 scaffold per master spec. A retro frontier game that scopes Big Tech exposure and sequences the off-ramp.
Structure
packages/
core/ Render-agnostic game logic, seed data, scoring
core/db/ The living database: schema, seeds, build + verify
web/ React + Vite SPA (V1 funnel)
server/ Minimal waitlist API (email + channel only)
The living database
The database is the source of truth. The site is a view over it. Nothing in the UI may
hardcode a number that lives in bigtech.db.
npm run db:build # rebuild the db, apply seeds, verify, regenerate the catalog
npm run db:verify # run the instrument's own checks against the existing db
packages/core/db/bigtech.db is built, not committed. What is committed is the part that
matters: db/schema.sql, db/seed/*.sql, and db/build.mjs.
The build refuses to pass if a score breaks the instrument's own rules:
- dimension weights must sum to 100
- every stored
weighted_totalmust recompute from its scores - every grade must match its band
- every score must carry a written rationale
- no tier-4 claim may attach to a scored dimension
- the reproducible-build caps are enforced, not documented: no reproducible build caps verifiability at 3, an experimental one at 6
A product with no assessment surfaces as unassessed. It is never given a guessed number.
That is why the 43 legacy roster entries sit in the database as placeholders and exactly one
product carries a real score.
Adding an assessment
- Write
packages/core/db/seed/000N-<slug>.sqlusing the shape in0001-signal.sql. - Every score needs a
rationaleand at least three tier-1 or tier-2evidencerows. npm run db:build. If it fails, the report is not ready to publish.
What the numbers mean
See the instrument spec. Scores are 0 to 100, and a weighted average is not the headline: the weakest dimension is, because a 90 with a 5 on local data exposure is a 90 that will leak.
Quick start
npm install
npm run build -w @bigtech-sucks/core
npm run dev # web on :5173
npm run dev:server # waitlist API on :3001
V1 flow
Welcome → Meet Red → Draw the Line → Overworld → Showdown → Homestead → Reveal (Binary Ranch) → Waitlist
Governance
- Creative assets are candidates — director approval required before ship
- Company name revealed only at homestead/reveal phase
- §13 open decisions are not silently resolved (see
packages/core/src/data/config.ts) - Client-side sovereignty report; server stores waitlist fields only
Roadmap
- V1.5: Terminal/SSH render (Go + Charm)
- V2: Concierge migration, journey chronicle, physical fulfillment (stubs in
v2-stubs.ts)