← Plainsight

How Plainsight checks a website

This document is the contract. If a report ever says something this document doesn't explain, that is a bug.

Principles

  1. Evidence or silence. Every finding shows what was measured and how. If we can't measure something, the finding says "Couldn't check". We never guess quietly.
  2. Read-only. Plainsight does what one visitor's phone does, plus reading public files every search engine reads. It never logs in, submits forms, guesses hidden paths, or tests for vulnerabilities.
  3. No AI judges the site. Findings come from written rules in src/checks/ and src/profiles/. The same page always gets the same findings.
  4. No overall score. A single number hides more than it shows and invites gaming. Reports count what's urgent, worth fixing and working.
  5. Good news counts. What already works is reported too, so owners see an honest picture instead of a sales pitch.
  6. Labelled confidence. Measured means read directly from the page, headers or network. Best guess means a pattern match (for example "is there a price on the page?") and can be wrong.
  7. The report itself is private. It is a single file with a Content-Security-Policy that blocks all network access. No fonts, scripts, trackers or images load from anywhere.
  8. The same for everyone. Findings don't change based on who ran the scan or whether anyone is selling anything. An optional "Prepared by" note sits at the end, clearly separate.

What one scan does

StepRequests
Open the homepage in Chromium, emulating a Pixel 7 on Lighthouse's "slow 4G" profile (150 ms latency, 1.6 Mbps, 4× CPU slowdown), cache disabledOne page load, exactly as a browser would. A second load, measuring speed only, if the first was close to a limit
If the certificate is invalid: record it, then reload once ignoring the error so the rest of the check can runOne more page load
http://<domain>/ without following redirects1
/robots.txt, read first so an owner's opt-out is honoured before any visit1
/.well-known/security.txt, a public standard file (RFC 9116)1
The homepage again, as plain HTML without running JavaScript (what link-preview bots see)1
Source-map files named at the end of the site's own JavaScript, to see if they're publicUp to 3
Sitemap: the one declared in robots.txt, else /sitemap.xml, /sitemap-index.xml, /sitemap_index.xmlUp to 4
The share image named in og:image1
Links on the homepage to the same site (HEAD, falling back to GET)Up to 20, 4 at a time
api.wordpress.org/core/version-check (only for WordPress sites)1, to wordpress.org, not the site
Google PageSpeed Insights (only with PAGESPEED_API_KEY)1, to Google, not the site

Every request to the site carries Plainsight/<version> (read-only website check) in its user agent.

When you use the website

The website runs the same checks, with a few extra rules because anyone can use it:

User-agent: Plainsight then Disallow: /

This is read before any visit. A general User-agent: * rule doesn't stop a check, because it's meant for search engines indexing a site, not a single visit someone asked for.

The checks

Code and secrets (apps and websites)

Getting in touch (local-business profiles only)

Speed on a phone (lab measurements; one run varies by about ±20%)

Being found

Visitor privacy (everything recorded on first load, with no clicks or consent)

Security (passive only)

Upkeep

How rules are added

Every rule lives in src/rules/registry.js with a name, the most serious result it can give, a source, the date it was added and a version. The rule catalogue below is generated from it. A new rule:

  1. comes with tests that must match and tests that must not;
  2. starts as beta: shown one level softer and marked "New check";
  3. runs on the golden corpus (fixed test sites with known problems, plus real sites compared against an approved baseline), and any new finding there is reviewed by a person;
  4. becomes stable after a few weeks without a false alarm.

Changing what a rule matches bumps its version, and every finding in a report shows the rule and version that produced it.

Profiles

A profile adds checks for one kind of site and decides which problems go to "Start here". It never changes the core checks.

"Start here" picks three problems: urgent first, then the ones weighted highest for the profile, then ones the owner can fix themselves. Problems that block every visitor (a leaked secret key, an invalid certificate, no HTTPS, hidden from Google, not phone-ready) always outrank the rest.

Rule catalogue

All 101 rules, generated from the code. 19 are new (beta): they're shown one level softer and marked "New check" until they've run on our test corpus for a few weeks without a false alarm. "Fix now" is the most serious result a rule can give. End-of-life data from endoflife.date, refreshed 2026-10-21.

Code and secrets

RuleWhat it checksAt mostStageAddedSource
code.secret.stripe-secretLeaked Live secret key (Stripe, Clerk or similar)Fix nowStable2026-10-21 · v1docs.stripe.com
code.secret.stripe-webhookLeaked Stripe webhook signing secretFix nowNew (beta)2026-10-21 · v1docs.stripe.com
code.secret.openaiLeaked OpenAI API keyFix nowStable2026-10-21 · v1platform.openai.com
code.secret.anthropicLeaked Anthropic API keyFix nowStable2026-10-21 · v1docs.anthropic.com
code.secret.huggingfaceLeaked Hugging Face access tokenFix nowNew (beta)2026-10-21 · v1huggingface.co
code.secret.groqLeaked Groq API keyFix nowNew (beta)2026-10-21 · v1console.groq.com
code.secret.replicateLeaked Replicate API tokenFix nowNew (beta)2026-10-21 · v1replicate.com
code.secret.awsLeaked AWS access keyFix nowStable2026-10-21 · v1docs.aws.amazon.com
code.secret.google-oauth-secretLeaked Google OAuth client secretFix nowNew (beta)2026-10-21 · v1developers.google.com
code.secret.githubLeaked GitHub tokenFix nowStable2026-10-21 · v1github.blog
code.secret.npmLeaked npm access tokenFix nowNew (beta)2026-10-21 · v1docs.npmjs.com
code.secret.pypiLeaked PyPI API tokenFix nowNew (beta)2026-10-21 · v1pypi.org
code.secret.shopifyLeaked Shopify access tokenFix nowNew (beta)2026-10-21 · v1shopify.dev
code.secret.digitaloceanLeaked DigitalOcean tokenFix nowNew (beta)2026-10-21 · v1docs.digitalocean.com
code.secret.linearLeaked Linear API keyFix nowNew (beta)2026-10-21 · v1developers.linear.app
code.secret.slackLeaked Slack tokenFix nowStable2026-10-21 · v1api.slack.com
code.secret.slack-webhookLeaked Slack webhook addressWorth fixingNew (beta)2026-10-21 · v1api.slack.com
code.secret.discord-webhookLeaked Discord webhook addressWorth fixingNew (beta)2026-10-21 · v1discord.com
code.secret.telegram-botLeaked Telegram bot tokenFix nowNew (beta)2026-10-21 · v1core.telegram.org
code.secret.sendgridLeaked SendGrid API keyFix nowStable2026-10-21 · v1twilio.com
code.secret.supabase-secretLeaked Supabase secret keyFix nowNew (beta)2026-10-21 · v1supabase.com
code.secret.private-keyLeaked Private keyFix nowStable2026-10-21 · v1rfc-editor.org
code.secret.database-urlLeaked Database address with passwordFix nowStable2026-10-21 · v1owasp.org
code.secret.google-apiLeaked Google API keyGood to knowStable2026-10-21 · v1cloud.google.com
code.secret.supabase-serviceLeaked Supabase service-role keyFix nowStable2026-10-21 · v1supabase.com
code.secret.supabase-anonLeaked Supabase anon keyGood to knowStable2026-10-21 · v1supabase.com
code.secretsNo secret keys in the code sent to browsersReassuranceStable2026-10-21 · v1Plainsight
code.dev-modeDevelopment build or dev server in productionFix nowStable2026-10-21 · v1vite.dev
code.localhostRequests to localhostFix nowStable2026-10-21 · v1Plainsight
code.source-mapsPublic source mapsGood to knowStable2026-10-21 · v1developer.mozilla.org
code.errorsJavaScript errors on first loadWorth fixingStable2026-10-21 · v1developer.mozilla.org
code.failing-requestsData requests that fail on loadWorth fixingStable2026-10-21 · v1developer.mozilla.org
code.auth-requestsRequests that need a signed-in userGood to knowStable2026-10-21 · v1developer.mozilla.org

Security

RuleWhat it checksAt mostStageAddedSource
security.httpsSecure connection (HTTPS)Fix nowStable2026-10-21 · v1web.dev
security.http-redirecthttp:// forwards to https://Worth fixingStable2026-10-21 · v1web.dev
security.certificateValid TLS certificateFix nowStable2026-10-21 · v1letsencrypt.org
security.headersSix recommended security headersWorth fixingStable2026-10-21 · v1owasp.org
security.cookiesLogin cookies are HttpOnly and SecureWorth fixingStable2026-10-21 · v1developer.mozilla.org
security.version-disclosureSoftware versions announced in headersGood to knowStable2026-10-21 · v1owasp.org
security.software-eolServer software past end of lifeWorth fixingStable2026-10-21 · v1endoflife.date
security.compromised-cdnCode loaded from a known-compromised hostFix nowStable2026-10-21 · v1sansec.io
security.vulnerable-libraryFront-end library with known vulnerabilitiesWorth fixingNew (beta)2026-10-21 · v1github.com
security.sriCDN scripts without an integrity checkGood to knowNew (beta)2026-10-21 · v1developer.mozilla.org
security.hsts-shortHSTS remembered for under six monthsGood to knowNew (beta)2026-10-21 · v1hstspreload.org
security.error-traceServer error or debug output on the pageWorth fixingNew (beta)2026-10-21 · v1owasp.org
security.security-txtsecurity.txt for vulnerability reportsGood to knowNew (beta)2026-10-21 · v1rfc-editor.org
security.mixed-contentFiles loaded over insecure http://Worth fixingStable2026-10-21 · v1developer.mozilla.org
security.insecure-formsForms that send data without encryptionFix nowStable2026-10-21 · v1developer.mozilla.org
security.wordpressWordPress behind the latest releaseWorth fixingStable2026-10-21 · v1wordpress.org

Speed

RuleWhat it checksAt mostStageAddedSource
speed.main-contentMain content time (Largest Contentful Paint)Fix nowStable2026-10-21 · v1web.dev
speed.fully-loadedPage keeps loading for over 10 secondsWorth fixingStable2026-10-21 · v1developer.mozilla.org
speed.real-visitorsReal-visitor speed (Chrome UX Report)Worth fixingStable2026-10-21 · v1developer.chrome.com
speed.javascriptJavaScript sent before the page is usableFix nowStable2026-10-21 · v1web.dev
speed.page-weightData used to open the homepageFix nowStable2026-10-21 · v1httparchive.org
speed.oversized-imagesImages far larger than shownWorth fixingStable2026-10-21 · v1web.dev
speed.server-responseServer response timeWorth fixingStable2026-10-21 · v1web.dev
speed.layout-shiftLayout shift while loadingWorth fixingStable2026-10-21 · v1web.dev

Being found and shared

RuleWhat it checksAt mostStageAddedSource
findability.hiddenHidden from Google (noindex or robots.txt)Fix nowStable2026-10-21 · v1developers.google.com
findability.mobileSet up for phone screensFix nowStable2026-10-21 · v1developer.mozilla.org
findability.titlePage titleWorth fixingStable2026-10-21 · v1developers.google.com
findability.descriptionSearch descriptionWorth fixingStable2026-10-21 · v1developers.google.com
findability.share-previewLink preview visible to preview botsWorth fixingStable2026-10-21 · v1ogp.me
findability.x-cardLarge image card on XWorth fixingStable2026-10-21 · v1developer.x.com
findability.empty-without-jsPage empty until JavaScript runsWorth fixingStable2026-10-21 · v1developers.google.com
findability.discoverLarge images allowed in Google DiscoverGood to knowStable2026-10-21 · v1developers.google.com
findability.iconsFavicon and home-screen iconWorth fixingStable2026-10-21 · v1developer.mozilla.org
findability.business-detailsStructured data for the siteWorth fixingStable2026-10-21 · v1developers.google.com
findability.sitemapSitemapGood to knowStable2026-10-21 · v1sitemaps.org

Visitor privacy

RuleWhat it checksAt mostStageAddedSource
privacy.advertisingAdvertising trackers on first loadWorth fixingStable2026-10-21 · v1gdpr.eu
privacy.analyticsAnalytics that identify visitors before consentWorth fixingStable2026-10-21 · v1gdpr.eu
privacy.session-replaySession recordingWorth fixingStable2026-10-21 · v1gdpr.eu
privacy.cookiesTracking cookies before consentWorth fixingStable2026-10-21 · v1gdpr.eu
privacy.consent-bannerCookie banner presentGood to knowStable2026-10-21 · v1Plainsight
privacy.policyPrivacy policy linkWorth fixingStable2026-10-21 · v1meity.gov.in
privacy.google-fontsFonts loaded from GoogleGood to knowStable2026-10-21 · v1developers.google.com
privacy.youtubeYouTube embeds in standard modeGood to knowStable2026-10-21 · v1support.google.com
privacy.external-formsForms that post to another companyGood to knowStable2026-10-21 · v1Plainsight
privacy.third-partiesOther companies the page connects toGood to knowStable2026-10-21 · v1Plainsight

Polish

RuleWhat it checksAt mostStageAddedSource
upkeep.copyright-yearFooter year up to dateWorth fixingStable2026-10-21 · v1Plainsight
upkeep.broken-linksBroken links to your own pagesWorth fixingStable2026-10-21 · v1developer.mozilla.org
upkeep.missing-filesPage files that fail to loadWorth fixingStable2026-10-21 · v1developer.mozilla.org
upkeep.image-descriptionsImages have descriptions (alt text)Worth fixingStable2026-10-21 · v1w3.org
upkeep.control-namesButtons, links and fields have namesWorth fixingStable2026-10-21 · v1w3.org
upkeep.zoomZoom allowedWorth fixingStable2026-10-21 · v1w3.org
upkeep.languagePage language declaredGood to knowStable2026-10-21 · v1w3.org

Apps

RuleWhat it checksAt mostStageAddedSource
business.ctaClear call to action on the first screenWorth fixingStable2026-10-21 · v1Plainsight
business.legalPrivacy policy and termsWorth fixingStable2026-10-21 · v1support.google.com
business.contactA way for users to reach youGood to knowStable2026-10-21 · v1Plainsight

Local businesses

RuleWhat it checksAt mostStageAddedSource
contact.first-screenCall, WhatsApp or book from the first screenWorth fixingStable2026-10-21 · v1Plainsight
contact.callTap-to-call phone numberWorth fixingStable2026-10-21 · v1Plainsight
contact.whatsappWhatsApp linkWorth fixingStable2026-10-21 · v1Plainsight
contact.directionsDirections linkWorth fixingStable2026-10-21 · v1Plainsight
contact.emailClickable email addressReassuranceStable2026-10-21 · v1Plainsight

Homestays

RuleWhat it checksAt mostStageAddedSource
homestay.direct-bookingDirect booking instead of commission sitesWorth fixingStable2026-10-21 · v1Plainsight
homestay.pricesPrices visibleWorth fixingStable2026-10-21 · v1Plainsight
homestay.photosEnough photosWorth fixingStable2026-10-21 · v1Plainsight
homestay.reviewsGuest reviewsGood to knowStable2026-10-21 · v1Plainsight
homestay.house-infoCheck-in and house detailsGood to knowStable2026-10-21 · v1Plainsight

Clinics

RuleWhat it checksAt mostStageAddedSource
clinic.hoursClinic timingsWorth fixingStable2026-10-21 · v1Plainsight
clinic.credentialsDoctor qualificationsGood to knowStable2026-10-21 · v1Plainsight
clinic.booking-platformAppointments through a platformGood to knowStable2026-10-21 · v1Plainsight