fix(public): land the TinyStudio document titles on /pricing and /brief-requested (kills the returned "The Tiny Studio" titles) - #98
Conversation
…kill the two "The Tiny Studio" document titles The homepage and /audit intake forms labelled their fields only with placeholder text, which disappears the moment a buyer starts typing and is not a persistent programmatic label; both served pages now carry a stable aria-label on the website and email inputs. /pricing and /brief-requested still branded their document titles "The Tiny Studio" — the spaced name the site's own identity copy disavows — while every other page said TinyStudio; both titles now match the brand (and the pricing title matches its own og:title). Two deterministic guards in check-site.mjs make both regressions impossible: every one of the six served appraisal titles must name TinyStudio and never "The Tiny Studio", and every intake website/email input must carry a non-empty aria-label. The retired /agent-desk page is excluded deliberately: its title frames itself as retired and it is noindex. verify: npm run check
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe change updates TinyStudio branding in public page titles, adds accessible labels to appraisal signup fields, and extends site validation for titles and form labels. ChangesBranding and accessibility updates
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/check-site.mjs`:
- Around line 1581-1588: Update the intake-page validation loop around
pageHtml.matchAll to track required website and email fields per page, parse
name and aria-label attributes with whitespace- and quote-tolerant matching, and
mark each discovered field as present. After scanning each page, add failures
for any required field that is missing or whose parsed aria-label is empty,
preserving the existing diagnostic context.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 184c6c06-a59b-45ed-8783-437d12c54d02
📒 Files selected for processing (5)
public/audit.htmlpublic/brief-requested.htmlpublic/index.htmlpublic/pricing.htmlscripts/check-site.mjs
| for (const [pageName, pageHtml] of intakePages) { | ||
| for (const input of pageHtml.matchAll(/<input\b[^>]*>/gi)) { | ||
| const tag = input[0]; | ||
| if (!/\bname="(?:website|email)"/.test(tag)) continue; | ||
| const aria = tag.match(/\baria-label="([^"]*)"/)?.[1] ?? ""; | ||
| if (!aria.trim()) { | ||
| failures.push(`Intake input on ${pageName} must carry a persistent programmatic aria-label (placeholder-only labels disappear as buyers type): ${tag}`); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Make the intake-field check fail closed.
The loop validates only inputs that it finds. It does not fail when a required website or email input is missing. The attribute checks also accept only double quotes with no spaces around =. Valid markup such as <input name = 'email' aria-label = ''> can bypass the check.
Track the expected field names, use format-tolerant attribute parsing, and fail when either expected field is absent or unlabeled.
Suggested validation change
for (const [pageName, pageHtml] of intakePages) {
+ const expectedNames = new Set(["website", "email"]);
+ const seenNames = new Set();
for (const input of pageHtml.matchAll(/<input\b[^>]*>/gi)) {
const tag = input[0];
- if (!/\bname="(?:website|email)"/.test(tag)) continue;
- const aria = tag.match(/\baria-label="([^"]*)"/)?.[1] ?? "";
+ const name = tag.match(/(?:^|\s)name\s*=\s*(["'])([\s\S]*?)\1/i)?.[2]?.toLowerCase();
+ if (!expectedNames.has(name)) continue;
+ seenNames.add(name);
+ const aria = tag.match(/(?:^|\s)aria-label\s*=\s*(["'])([\s\S]*?)\1/i)?.[2] ?? "";
if (!aria.trim()) {
failures.push(`Intake input on ${pageName} must carry a persistent programmatic aria-label (placeholder-only labels disappear as buyers type): ${tag}`);
}
}
+ for (const name of expectedNames) {
+ if (!seenNames.has(name)) {
+ failures.push(`Missing intake input on ${pageName}: ${name}.`);
+ }
+ }
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| for (const [pageName, pageHtml] of intakePages) { | |
| for (const input of pageHtml.matchAll(/<input\b[^>]*>/gi)) { | |
| const tag = input[0]; | |
| if (!/\bname="(?:website|email)"/.test(tag)) continue; | |
| const aria = tag.match(/\baria-label="([^"]*)"/)?.[1] ?? ""; | |
| if (!aria.trim()) { | |
| failures.push(`Intake input on ${pageName} must carry a persistent programmatic aria-label (placeholder-only labels disappear as buyers type): ${tag}`); | |
| } | |
| for (const [pageName, pageHtml] of intakePages) { | |
| const expectedNames = new Set(["website", "email"]); | |
| const seenNames = new Set(); | |
| for (const input of pageHtml.matchAll(/<input\b[^>]*>/gi)) { | |
| const tag = input[0]; | |
| const name = tag.match(/(?:^|\s)name\s*=\s*(["'])([\s\S]*?)\1/i)?.[2]?.toLowerCase(); | |
| if (!expectedNames.has(name)) continue; | |
| seenNames.add(name); | |
| const aria = tag.match(/(?:^|\s)aria-label\s*=\s*(["'])([\s\S]*?)\1/i)?.[2] ?? ""; | |
| if (!aria.trim()) { | |
| failures.push(`Intake input on ${pageName} must carry a persistent programmatic aria-label (placeholder-only labels disappear as buyers type): ${tag}`); | |
| } | |
| } | |
| for (const name of expectedNames) { | |
| if (!seenNames.has(name)) { | |
| failures.push(`Missing intake input on ${pageName}: ${name}.`); | |
| } | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/check-site.mjs` around lines 1581 - 1588, Update the intake-page
validation loop around pageHtml.matchAll to track required website and email
fields per page, parse name and aria-label attributes with whitespace- and
quote-tolerant matching, and mark each discovered field as present. After
scanning each page, add failures for any required field that is missing or whose
parsed aria-label is empty, preserving the existing diagnostic context.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c6480b50db
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ]; | ||
|
|
||
| for (const [pageName, pageHtml] of titlePages) { | ||
| const title = pageHtml.match(/<title>([^<]*)<\/title>/i)?.[1] ?? ""; |
There was a problem hiding this comment.
Ignore commented-out titles when enforcing branding
If an editor leaves a branded <title>TinyStudio…</title> inside an HTML comment before restoring a live The Tiny Studio title, this first-match regex selects the inert commented tag and the check passes even though the browser serves the stale branding. Strip HTML comments before matching—like the canonical check immediately above already does—and preferably inspect the live <head> content.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0ba96cc159
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!title.includes("TinyStudio")) { | ||
| failures.push(`Document title on ${pageName} must name TinyStudio (found ${JSON.stringify(title)}).`); | ||
| } | ||
| if (title.includes("The Tiny Studio")) { |
There was a problem hiding this comment.
Compare the forbidden title case-insensitively
If a title regresses to a capitalization variant such as The tiny studio — TinyStudio, this check passes even though the page still returns the spaced brand form the guard is intended to prohibit. The existing identity scan above normalizes both sides to lowercase; apply the same normalization here so casing changes cannot bypass this regression check.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5d1048a90f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!/\bname="(?:website|email)"/.test(tag)) continue; | ||
| const aria = tag.match(/\baria-label="([^"]*)"/)?.[1] ?? ""; |
There was a problem hiding this comment.
Parse intake attributes independent of quoting
If a live intake field is rewritten with single-quoted or differently cased attributes—both valid in HTML—this exact name="..." filter skips the field entirely, allowing its aria-label to be removed while npm run check still passes. For example, changing the homepage email field to name='email' without an accessible label bypasses this guard, so attribute extraction should accept valid HTML quoting and casing.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fd0040952a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for (const [pageName, pageHtml] of intakePages) { | ||
| for (const input of pageHtml.matchAll(/<input\b[^>]*>/gi)) { | ||
| const tag = input[0]; | ||
| if (!/\bname="(?:website|email)"/.test(tag)) continue; |
There was a problem hiding this comment.
Require the email field before validating its label
If the email input is deleted or renamed on either intake page, this filter simply finds no email field and npm run check still passes; the resulting form then submits without body.email, which signupResponse rejects as invalid_email, making that intake unusable. Assert that each page contains exactly one website and one email input before checking their accessible labels.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
…s item against current main and live (#147) PR #98 (d4a2c30) fixed the two 'The Tiny Studio' document titles on /pricing and /brief-requested and added the six-page title guard in check-site.mjs. This receipt re-verifies every acceptance criterion of the backlog item against the current head (ad9cee3) and live (2026-08-12): all six served document titles name TinyStudio, 'The Tiny Studio' returns zero matches across them, npm run check passes, and the full suite is 92/92. The spaced form remains only in the /pricing and /brief-requested footers, which PR #112 (fix/footer-brand-tinystudio) owns. verify: npm run check; npm test
…, and guard them (#112) The site's own identity copy disavows the spaced 'The Tiny Studio' name (it collides with 'The Tiny Studio LA' and other unrelated businesses), and the merged title fix (#98) killed the two 'The Tiny Studio' document titles. But the /pricing and /brief-requested footers still served the spaced brand name while every other page footer said 'TinyStudio · tinystudio.io'. Fix both footers to the brand-consistent form and extend the check-site.mjs stale-identity guard (ownedPages) to cover the pricing and brief-requested pages, so the spaced form cannot return on any served appraisal surface. Verified: npm run check passes; npm test green (6/7/55/16/8); the extended guard rejects both old footer strings when reverted (proven by revert test).
What and why
The live site and
origin/mainstill return<title>Pricing & terms — The Tiny Studio</title>(/pricing) and<title>Request received — The Tiny Studio</title>(/brief-requested) — the spaced name the site's own identity copy disavows (it collides with "The Tiny Studio LA" and other unrelated businesses). Every other served page already saysTinyStudio.The prior naming item fixed these exact titles in commit
4555252on branchfix/intake-labels-and-stale-titles(open, unreviewed PR #67), but that PR never landed — main and the live deployment still return the old titles. This PR lands that fix fresh against currentorigin/main(cherry-picked4555252, same content) and supersedes the unmerged PR #67.Changes (5 files, +63/−6)
public/pricing.html:<title>Pricing & terms — The Tiny Studio</title>→<title>TinyStudio — Pricing & terms</title>(matches its own og:title).public/brief-requested.html:<title>Request received — The Tiny Studio</title>→<title>Request received — TinyStudio</title>.public/audit.html+public/index.html: persistentaria-labels on both appraisal intake website/email inputs (the rest of the prior item's commit).scripts/check-site.mjs: two deterministic guards — every one of the six served appraisal document titles must nameTinyStudioand never the spaced "The Tiny Studio" form; every intake website/email input must carry a non-emptyaria-label. The retired/agent-deskpage is deliberately excluded (its title frames itself as retired and it is noindex).Verification
npm run check→ "TinyStudio.io checks passed."npm test→ all 5 suites, 90 subtests, 0 fail.git diff --checkclean./pricingand/brief-requestedreturn the "The Tiny Studio" titles (curl-verified).Summary by CodeRabbit
Accessibility
Branding
Quality Improvements