+
TinyStudio — The Desk
diff --git a/public/audit.html b/public/audit.html
index ecf2c437..504a425c 100644
--- a/public/audit.html
+++ b/public/audit.html
@@ -3,6 +3,7 @@
+
TinyStudio — The Website Appraisal
diff --git a/public/index.html b/public/index.html
index 4f3f153d..25bd282a 100644
--- a/public/index.html
+++ b/public/index.html
@@ -3,6 +3,7 @@
+
TinyStudio — The Website Appraisal
diff --git a/public/pricing.html b/public/pricing.html
index 60b057a9..6a4c7594 100644
--- a/public/pricing.html
+++ b/public/pricing.html
@@ -3,6 +3,7 @@
+
Pricing & terms — The Tiny Studio
diff --git a/public/specimen.html b/public/specimen.html
index cdf3d93d..d4817f27 100644
--- a/public/specimen.html
+++ b/public/specimen.html
@@ -3,6 +3,7 @@
+
TinyStudio — The Website Appraisal — specimen
diff --git a/scripts/check-site.mjs b/scripts/check-site.mjs
index 2f72b51a..a4c148e8 100644
--- a/scripts/check-site.mjs
+++ b/scripts/check-site.mjs
@@ -866,6 +866,49 @@ for (const [pageName, pageHtml] of ownedPages) {
}
}
+// ---- Meta descriptions (dogfood) -------------------------------------------
+// The leak audit this site sells flags a homepage whose served HTML carries no
+// description, so the site's own five public pages must not carry the same
+// fault. Each page keeps exactly one valid, non-empty description meta tag in
+// its head, within a practical search-snippet length, distinct per page, and
+// free of the offer promises the repo refuses to make.
+const metaDescriptionPages = [
+ ["homepage", siteHome],
+ ["audit page", siteAudit],
+ ["desk page", read("public/agents.html")],
+ ["pricing page", read("public/pricing.html")],
+ ["specimen page", read("public/specimen.html")]
+];
+
+const seenDescriptions = new Map();
+for (const [pageName, pageHtml] of metaDescriptionPages) {
+ const tags = [...pageHtml.matchAll(/]*\bname="description"[^>]*>/gi)].map((match) => match[0]);
+ if (tags.length !== 1) {
+ failures.push(`Meta description must appear exactly once in the head of ${pageName} (found ${tags.length}).`);
+ continue;
+ }
+ const content = tags[0].match(/\bcontent="([^"]*)"/i)?.[1] ?? "";
+ const trimmed = content.trim();
+ if (!trimmed) {
+ failures.push(`Meta description on ${pageName} must not be empty.`);
+ continue;
+ }
+ if (trimmed.length > 160) {
+ failures.push(`Meta description on ${pageName} must fit a search snippet (${trimmed.length} > 160 chars).`);
+ }
+ const prior = seenDescriptions.get(trimmed);
+ if (prior) {
+ failures.push(`Meta description on ${pageName} must be unique; it duplicates ${prior}.`);
+ } else {
+ seenDescriptions.set(trimmed, pageName);
+ }
+ for (const claim of forbiddenClaims) {
+ if (trimmed.toLowerCase().includes(claim.toLowerCase())) {
+ failures.push(`Meta description on ${pageName} must not promise: ${claim}`);
+ }
+ }
+}
+
for (const migration of ["migrations/0002_agent_runs.sql", "migrations/0003_agent_usage_limits.sql"]) { if (!existsSync(new URL(`../${migration}`, import.meta.url))) {
failures.push(`Missing migration: ${migration}`);
continue;