fix: preserve card styling in heading hierarchy repair - #23
Conversation
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.
|
Warning Review limit reached
Next review available in: 2 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe PR promotes six public info-card headings from H3 to H2, updates shared card-heading styles, and expands heading hierarchy tests across six public pages. ChangesPublic heading hierarchy
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c5393a3885
ℹ️ 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".
| console.log("test-public-heading-hierarchy: rendered heading outline on the four finding pages") | ||
| // Count <h2> used as .info-card card titles (inside <article class="info-card">). | ||
| const infoCardTitleCount = (html) => | ||
| (html.match(/<article class="info-card[^"]*"[^>]*>[\s\S]*?<h2\b/gi) || []).length |
There was a problem hiding this comment.
Keep the H2 match inside each article
This regex can continue past the matching </article> until it finds any later H2, so it does not establish the containment asserted by the test. For example, moving the third card title immediately after its closing article still produces a count of three, retains four total H2s and creates no level jump, causing every new hierarchy check to pass even though that card has no H2. Limit each match to the article body or inspect each article independently.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/test-public-heading-hierarchy.mjs`:
- Around line 33-35: Update infoCardTitleCount to bound each match from an
`<article class="info-card">` opening tag through its corresponding closing
`</article>`, then count only article bodies containing exactly one H2 heading.
Ensure H2 elements outside the matched article, including later cards or the
footer, cannot satisfy the count.
- Around line 78-79: Update the globalH2 extraction in the heading hierarchy
test to match only a standalone global h2 selector at a CSS rule boundary,
rather than any substring ending in “h2 {”. Preserve the existing max-width
assertion while preventing matches from more specific selectors or comments.
🪄 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: b0f5f283-9233-418a-ad8d-7842a939af31
📒 Files selected for processing (4)
public/drishti/support/index.htmlpublic/privacy-choices/index.htmlpublic/styles.cssscripts/test-public-heading-hierarchy.mjs
| // Count <h2> used as .info-card card titles (inside <article class="info-card">). | ||
| const infoCardTitleCount = (html) => | ||
| (html.match(/<article class="info-card[^"]*"[^>]*>[\s\S]*?<h2\b/gi) || []).length |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Scope each card match to its closing </article>.
The current pattern is not bounded by an article end tag. If a card regresses to H3, the match can consume the next card’s or footer’s H2 and still count that card. The test can therefore pass with fewer than three card H2 headings.
Match each article body separately and count articles that contain exactly one H2.
Proposed fix
const infoCardTitleCount = (html) =>
- (html.match(/<article class="info-card[^"]*"[^>]*>[\s\S]*?<h2\b/gi) || []).length
+ [...html.matchAll(
+ /<article\b[^>]*class="[^"]*\binfo-card\b[^"]*"[^>]*>([\s\S]*?)<\/article>/gi
+ )].filter(([, body]) => (body.match(/<h2\b/gi) || []).length === 1).lengthAlso applies to: 55-55
🤖 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/test-public-heading-hierarchy.mjs` around lines 33 - 35, Update
infoCardTitleCount to bound each match from an `<article class="info-card">`
opening tag through its corresponding closing `</article>`, then count only
article bodies containing exactly one H2 heading. Ensure H2 elements outside the
matched article, including later cards or the footer, cannot satisfy the count.
| const globalH2 = css.match(/h2\s*{[^}]*}/)?.[0] ?? "" | ||
| ok(globalH2.includes("max-width: 12ch"), "global h2 styling (12ch cap) is untouched") |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Anchor the global H2 assertion to the global selector.
css.match(/h2\s*{[^}]*}/) searches for the substring h2 {. It can match a more specific rule such as .info-card h2 { or a comment. The assertion can pass even when the standalone global H2 rule is missing.
Anchor the match to a rule boundary or parse the selector list.
Proposed fix
-const globalH2 = css.match(/h2\s*{[^}]*}/)?.[0] ?? ""
+const globalH2 =
+ css.match(/(?:^|[}\n])\s*h2\s*{[^}]*}/)?.[0] ?? ""📝 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.
| const globalH2 = css.match(/h2\s*{[^}]*}/)?.[0] ?? "" | |
| ok(globalH2.includes("max-width: 12ch"), "global h2 styling (12ch cap) is untouched") | |
| const globalH2 = | |
| css.match(/(?:^|[}\n])\s*h2\s*{[^}]*}/)?.[0] ?? "" | |
| ok(globalH2.includes("max-width: 12ch"), "global h2 styling (12ch cap) is untouched") |
🤖 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/test-public-heading-hierarchy.mjs` around lines 78 - 79, Update the
globalH2 extraction in the heading hierarchy test to match only a standalone
global h2 selector at a CSS rule boundary, rather than any substring ending in
“h2 {”. Preserve the existing max-width assertion while preventing matches from
more specific selectors or comments.
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.
The skipped-heading-level finding (Drishti support and Privacy Choices pages) was repaired in source by PR #23 (H1 -> H2 cards, no outline jumps), and the local suite (test-public-heading-hierarchy.mjs) guards the worktree HTML. But the live site still serves the June-20 bundle: both pages jump H1 -> H3 and the deployed stylesheet keeps the old .info-card h3-only rule, so the finding silently re-opens against tinystudio.in. Add scripts/test-public-live-heading-hierarchy.mjs, wired into npm test and npm run ci: it fetches the deployed pages and stylesheet and re-asserts the repaired outline (single H1 first, H2 card titles inside .info-card, flat H2 band before footer H3s, no jumps greater than one) and the shared .info-card :is(h2, h3) rule. Network-tolerant: skips when the site is unreachable, fails loudly when it serves stale pages. verify: node scripts/test-public-live-heading-hierarchy.mjs fails loudly on the current deployment (19 checks, 11 failures, all stale-deployment detections), node scripts/test-public-heading-hierarchy.mjs 44 checks 0 failures, npm test otherwise clean, find scripts -name '*.mjs' node --check clean, git diff --check clean
…nd now verified live (2026-08-21) (#229) The heading-hierarchy repair for the Drishti support and Privacy Choices pages is merged on main (PR #23, 9165305) and guarded live (793f162). With CLOUDFLARE_API_TOKEN provisioned on 2026-08-20, the deploy lane now runs green and the live site passes all 17 live-guard checks. No source change needed; this reverify report closes the item. Co-authored-by: minimax-vps <minimax-vps@MiniMax.local> Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Summary
Validation
{ (internal measurement marker) subject
"status": "passed",
"checks": 38
}
Sales and external-intake contract checks passed.
Active offer projection checks passed.
Active operator surface checks passed.
Direction proof gate checks passed.
Client readiness contract checks passed.
Validated service-client checks passed.
Client acceptance gate checks passed.
{
"status": "passed",
"surfaces": [
"README.md",
"MEMORY.md",
"PRODUCT.md",
"growth-brain/offer.md",
"growth-brain/sales/managed-it-one-page-offer.md",
"growth-brain/sales/one-page-offer.md",
"growth-brain/sales/proposal-template.md",
"growth-brain/sales/buyer-room-template.md",
"growth-brain/sales/sales-call-script.md",
"growth-brain/sales/follow-up-sequences.md",
"growth-brain/sprint-checklist.md",
"growth-brain/delivery-template.md",
"growth-brain/workflows/client-sprint-workflow.md",
"growth-brain/quality/sprint-acceptance-checklist.md",
"growth-brain/positioning/message-house.md",
"growth-brain/delivery/implementation-handoff-template.md",
"growth-brain/README.md",
"growth-brain/sales/pricing-rules.md",
"growth-brain/loom-audit-script.md",
"growth-brain/workflows/loom-audit-workflow.md",
"growth-brain/prospecting/warm-network-scripts.md",
"growth-brain/agency-operating-model.md",
"growth-brain/build-roadmap.md",
"growth-brain/sales/managed-it-one-page-offer.html"
],
"checked": [
"buyer",
"product",
"first-3 price",
"scope",
"fault map",
"rewrite or redesign",
"implementation pass or dev-ready handoff",
"search-trust basics",
"before/after proof",
"Loom",
"measurement plan",
"one revision",
"14-day implementation tracking",
"Day 0 prerequisites",
"client-delay pause",
"no revenue guarantee",
"no ranking guarantee",
"no ROAS guarantee",
"no conversion guarantee",
"no booked-call guarantee",
"no sales-volume guarantee",
"fit review gate",
"claims review gate",
"client-facing review gate",
"delivery/acceptance review gate",
"renewal review gate",
"automation preparation",
"no autonomous send",
"no autonomous publish",
"no autonomous spend",
"no autonomous approval",
"no autonomous acceptance",
"no autonomous renewal",
"SaaS graduation: 10 paid sprints",
"SaaS graduation: same problem",
"SaaS graduation: repeatability",
"SaaS graduation: usefulness",
"SaaS graduation: approval",
"SaaS graduation: recurring need",
"SaaS graduation: deposits"
],
"activeGeneratedOutputs": [
"growth-brain/ops/11-10-proof-run.md",
"growth-brain/ops/proof-library.md",
"growth-brain/ops/live-metrics.md",
"growth-brain/ops/market-parity-readiness.md",
"growth-brain/ops/sender-setup-guide.md",
"growth-brain/ops/sender-setup-guide.html",
"growth-brain/ops/competitive-proof-matrix.md",
"growth-brain/ops/competitive-proof-matrix.html",
"docs/strategy/market-parity-benchmark-2026.md"
],
"excluded": [
"public/",
"historical research"
]
}
{
"status": "passed",
"contract": "human-reviewed-service-kit",
"checkedFiles": 38,
"allowedCommands": 9,
"preservedGates": [
"client readiness",
"product truth",
"claims",
"send readiness",
"retention",
"agency defaults"
]
}
{
"status": "pass",
"checks": 16,
"labStatus": "blocked-before-fresh-mobbin-reference-packets"
}
{
"status": "pass",
"automationId": "tinystudio-retention-checkups",
"path": "/home/nish/.codex/automations/tinystudio-retention-checkups/automation.toml",
"weeklyCadence": "Friday retention prep",
"repo": "/home/nish/workspaces/products/tinystudio-in-autonomous-service",
"failures": [],
"warnings": []
}
Retention automation applicability checks passed.
{
"status": "passed",
"scanned": 110,
"requiredStringKeys": [
"founderName",
"offerName",
"buyer",
"founderSprintPrice",
"scope",
"dayZeroRule",
"automationBoundary",
"optOutLine",
"meetingPlaceholder",
"paymentPlaceholder"
],
"bannedValues": 0
}
{
"status": "pass",
"filesScanned": 7
}
{
"status": "pass",
"filesScanned": 0,
"findings": [],
"warnings": []
}
Outbound send readiness fixture checks passed.
test-public-conversion-signal: public conversion signal (The Website Correction application route)
A. signal definitions
ok registry names are unique
ok registry names are stable lowercase slugs
B. docs contract
ok docs/measurement/public-conversion-signal.md exists
ok docs document signal source homepage-hero
ok docs document signal source homepage-service
ok docs document signal source homepage-footer
ok docs name the offer truthfully as The Website Correction
ok docs never name the offer as a generic reviewed service
ok docs state the prefilled application subject is the operator-visible signal
ok docs pin the operator-visible subject format with the exact product name
ok docs pin the full propagated subject format
ok docs name the signal owner
ok docs state retention
ok docs state the privacy boundary
ok docs explain where the privacy disclosure lives
ok docs contain a falsifiable decision rule
ok docs are honest that tags are not application proof
ok docs count only received human messages as completion evidence
C. homepage Website Correction CTA source tags
ok every Website Correction CTA carries data-measure-source
ok source tag homepage-hero is a registered stable name
ok CTA homepage-hero routes to the application endpoint with source context
ok every Website Correction CTA carries data-measure-source
ok source tag homepage-service is a registered stable name
ok CTA homepage-service routes to the application endpoint with source context
D. contact endpoint source propagation
ok contact page has a Website Correction application mailto route
ok contact page default subject is exactly The Website Correction application
ok contact page application route names the offer as Website Correction
ok contact page names the offer truthfully as The Website Correction
ok contact page never names the offer as a generic reviewed service
ok contact page states the signal is for internal measurement only
ok contact page states nothing is sent automatically
ok contact page states the marker can be removed before sending
ok contact page reads the ?source= parameter
ok contact page allowlists every registered source name
ok contact page propagates the exact The Website Correction application — from
ok contact page rejects unregistered source values
ok contact page has no auto-send/auto-submit mechanism (<form)
ok contact page has no auto-send/auto-submit mechanism (<input)
ok contact page has no auto-send/auto-submit mechanism (<textarea)
ok contact page has no auto-send/auto-submit mechanism (location.href)
ok contact page has no auto-send/auto-submit mechanism (location.assign)
ok contact page has no auto-send/auto-submit mechanism (location.replace)
ok contact page has no auto-send/auto-submit mechanism (window.open)
ok contact page has no auto-send/auto-submit mechanism (.submit()
ok contact page has no auto-send/auto-submit mechanism (sendBeacon()
ok contact page has no auto-send/auto-submit mechanism (fetch()
E. no analytics provider, cookies, fingerprinting, or message-content collection
ok public/index.html has no document.cookie
ok public/index.html has no localStorage
ok public/index.html has no sessionStorage
ok public/index.html has no navigator.sendBeacon
ok public/index.html has no sendBeacon(
ok public/index.html has no fetch(
ok public/index.html has no XMLHttpRequest
ok public/index.html has no googletagmanager
ok public/index.html has no google-analytics
ok public/index.html has no gtag(
ok public/index.html has no plausible.io
ok public/index.html has no fathom.js
ok public/index.html has no posthog
ok public/index.html has no mixpanel
ok public/index.html has no amplitude
ok public/index.html has no window.analytics
ok public/index.html has no hotjar
ok public/index.html has no clarity.ms
ok public/index.html has no fbq(
ok public/index.html has no connect.facebook.net
ok public/index.html has no toDataURL
ok public/index.html has no hardwareConcurrency
ok public/index.html has no deviceMemory
ok public/index.html has no navigator.plugins
ok public/index.html has no FingerprintJS
ok public/index.html has no window.fingerprint
ok public/contact/index.html has no document.cookie
ok public/contact/index.html has no localStorage
ok public/contact/index.html has no sessionStorage
ok public/contact/index.html has no navigator.sendBeacon
ok public/contact/index.html has no sendBeacon(
ok public/contact/index.html has no fetch(
ok public/contact/index.html has no XMLHttpRequest
ok public/contact/index.html has no googletagmanager
ok public/contact/index.html has no google-analytics
ok public/contact/index.html has no gtag(
ok public/contact/index.html has no plausible.io
ok public/contact/index.html has no fathom.js
ok public/contact/index.html has no posthog
ok public/contact/index.html has no mixpanel
ok public/contact/index.html has no amplitude
ok public/contact/index.html has no window.analytics
ok public/contact/index.html has no hotjar
ok public/contact/index.html has no clarity.ms
ok public/contact/index.html has no fbq(
ok public/contact/index.html has no connect.facebook.net
ok public/contact/index.html has no toDataURL
ok public/contact/index.html has no hardwareConcurrency
ok public/contact/index.html has no deviceMemory
ok public/contact/index.html has no navigator.plugins
ok public/contact/index.html has no FingerprintJS
ok public/contact/index.html has no window.fingerprint
ok public/privacy-choices/index.html has no document.cookie
ok public/privacy-choices/index.html has no localStorage
ok public/privacy-choices/index.html has no sessionStorage
ok public/privacy-choices/index.html has no navigator.sendBeacon
ok public/privacy-choices/index.html has no sendBeacon(
ok public/privacy-choices/index.html has no fetch(
ok public/privacy-choices/index.html has no XMLHttpRequest
ok public/privacy-choices/index.html has no googletagmanager
ok public/privacy-choices/index.html has no google-analytics
ok public/privacy-choices/index.html has no gtag(
ok public/privacy-choices/index.html has no plausible.io
ok public/privacy-choices/index.html has no fathom.js
ok public/privacy-choices/index.html has no posthog
ok public/privacy-choices/index.html has no mixpanel
ok public/privacy-choices/index.html has no amplitude
ok public/privacy-choices/index.html has no window.analytics
ok public/privacy-choices/index.html has no hotjar
ok public/privacy-choices/index.html has no clarity.ms
ok public/privacy-choices/index.html has no fbq(
ok public/privacy-choices/index.html has no connect.facebook.net
ok public/privacy-choices/index.html has no toDataURL
ok public/privacy-choices/index.html has no hardwareConcurrency
ok public/privacy-choices/index.html has no deviceMemory
ok public/privacy-choices/index.html has no navigator.plugins
ok public/privacy-choices/index.html has no FingerprintJS
ok public/privacy-choices/index.html has no window.fingerprint
F. npm test/ci wiring
ok npm test runs the public conversion signal test
ok npm run ci runs the public conversion signal test
126 checks, 0 failures
test-public-structured-data: JSON-LD structured data on public pages
A. public/contact/index.html
ok contact page has exactly one application/ld+json block
ok contact page JSON-LD block parses as valid JSON
ok contact page uses the schema.org context
ok contact page JSON-LD uses an @graph array
ok contact page page declares a canonical URL
ok contact page page declares a title
ok contact page page declares a description
ok contact page JSON-LD carries the stable Tiny Studio organization reference
ok contact page JSON-LD declares the page as ContactPage
ok contact page JSON-LD url matches the page canonical URL
ok contact page JSON-LD name matches the page title
ok contact page JSON-LD description matches the meta description
ok contact page JSON-LD page is part of the Tiny Studio website
ok contact page JSON-LD page is about the Tiny Studio organization
A. public/promptly/privacy/index.html
ok Promptly privacy policy page has exactly one application/ld+json block
ok Promptly privacy policy page JSON-LD block parses as valid JSON
ok Promptly privacy policy page uses the schema.org context
ok Promptly privacy policy page JSON-LD uses an @graph array
ok Promptly privacy policy page page declares a canonical URL
ok Promptly privacy policy page page declares a title
ok Promptly privacy policy page page declares a description
ok Promptly privacy policy page JSON-LD carries the stable Tiny Studio organization reference
ok Promptly privacy policy page JSON-LD declares the page as WebPage
ok Promptly privacy policy page JSON-LD url matches the page canonical URL
ok Promptly privacy policy page JSON-LD name matches the page title
ok Promptly privacy policy page JSON-LD description matches the meta description
ok Promptly privacy policy page JSON-LD page is part of the Tiny Studio website
ok Promptly privacy policy page JSON-LD page is about the Tiny Studio organization
B. npm test/ci wiring
ok npm test runs the public structured data test
ok npm run check delegates to npm test
ok npm run ci runs the public structured data test
31 checks, 0 failures
test-public-heading-hierarchy: card headings are semantic H2s with the former card scale
A. public/contact/index.html
ok page contains at least one heading
ok page has exactly one H1
ok the H1 is the first heading in the outline
ok the three card headings are H2s inside .info-card articles
ok card H2s plus the footer H2 keep a flat H2 band before the footer H3s
ok no heading-level jump greater than one (no H1 -> H3 skip)
A. public/promptly/index.html
ok page contains at least one heading
ok page has exactly one H1
ok the H1 is the first heading in the outline
ok the three card headings are H2s inside .info-card articles
ok card H2s plus the footer H2 keep a flat H2 band before the footer H3s
ok no heading-level jump greater than one (no H1 -> H3 skip)
A. public/promptly/privacy/index.html
ok page contains at least one heading
ok page has exactly one H1
ok the H1 is the first heading in the outline
ok the three card headings are H2s inside .info-card articles
ok card H2s plus the footer H2 keep a flat H2 band before the footer H3s
ok no heading-level jump greater than one (no H1 -> H3 skip)
A. public/drishti/index.html
ok page contains at least one heading
ok page has exactly one H1
ok the H1 is the first heading in the outline
ok the three card headings are H2s inside .info-card articles
ok card H2s plus the footer H2 keep a flat H2 band before the footer H3s
ok no heading-level jump greater than one (no H1 -> H3 skip)
A. public/drishti/support/index.html
ok page contains at least one heading
ok page has exactly one H1
ok the H1 is the first heading in the outline
ok the three card headings are H2s inside .info-card articles
ok card H2s plus the footer H2 keep a flat H2 band before the footer H3s
ok no heading-level jump greater than one (no H1 -> H3 skip)
A. public/privacy-choices/index.html
ok page contains at least one heading
ok page has exactly one H1
ok the H1 is the first heading in the outline
ok the three card headings are H2s inside .info-card articles
ok card H2s plus the footer H2 keep a flat H2 band before the footer H3s
ok no heading-level jump greater than one (no H1 -> H3 skip)
B. card-heading CSS pairing
ok styles.css defines .info-card :is(h2, h3) {
ok card rule keeps margin-top: 12px
ok card rule keeps font-size: clamp(1.65rem, 2vw, 2.35rem)
ok card rule keeps max-width: none
ok global h2 styling (12ch cap) is untouched
ok the old .info-card h3-only rule is replaced by the shared :is(h2, h3) rule
C. npm test/ci wiring
ok npm test runs the public heading hierarchy test
ok npm run ci runs the public heading hierarchy test
44 checks, 0 failures passed: 38 checks plus all downstream suites, including 44 heading checks.
{ (internal measurement marker) subject
"status": "passed",
"checks": 38
}
Sales and external-intake contract checks passed.
Active offer projection checks passed.
Active operator surface checks passed.
Direction proof gate checks passed.
Client readiness contract checks passed.
Validated service-client checks passed.
Client acceptance gate checks passed.
{
"status": "passed",
"surfaces": [
"README.md",
"MEMORY.md",
"PRODUCT.md",
"growth-brain/offer.md",
"growth-brain/sales/managed-it-one-page-offer.md",
"growth-brain/sales/one-page-offer.md",
"growth-brain/sales/proposal-template.md",
"growth-brain/sales/buyer-room-template.md",
"growth-brain/sales/sales-call-script.md",
"growth-brain/sales/follow-up-sequences.md",
"growth-brain/sprint-checklist.md",
"growth-brain/delivery-template.md",
"growth-brain/workflows/client-sprint-workflow.md",
"growth-brain/quality/sprint-acceptance-checklist.md",
"growth-brain/positioning/message-house.md",
"growth-brain/delivery/implementation-handoff-template.md",
"growth-brain/README.md",
"growth-brain/sales/pricing-rules.md",
"growth-brain/loom-audit-script.md",
"growth-brain/workflows/loom-audit-workflow.md",
"growth-brain/prospecting/warm-network-scripts.md",
"growth-brain/agency-operating-model.md",
"growth-brain/build-roadmap.md",
"growth-brain/sales/managed-it-one-page-offer.html"
],
"checked": [
"buyer",
"product",
"first-3 price",
"scope",
"fault map",
"rewrite or redesign",
"implementation pass or dev-ready handoff",
"search-trust basics",
"before/after proof",
"Loom",
"measurement plan",
"one revision",
"14-day implementation tracking",
"Day 0 prerequisites",
"client-delay pause",
"no revenue guarantee",
"no ranking guarantee",
"no ROAS guarantee",
"no conversion guarantee",
"no booked-call guarantee",
"no sales-volume guarantee",
"fit review gate",
"claims review gate",
"client-facing review gate",
"delivery/acceptance review gate",
"renewal review gate",
"automation preparation",
"no autonomous send",
"no autonomous publish",
"no autonomous spend",
"no autonomous approval",
"no autonomous acceptance",
"no autonomous renewal",
"SaaS graduation: 10 paid sprints",
"SaaS graduation: same problem",
"SaaS graduation: repeatability",
"SaaS graduation: usefulness",
"SaaS graduation: approval",
"SaaS graduation: recurring need",
"SaaS graduation: deposits"
],
"activeGeneratedOutputs": [
"growth-brain/ops/11-10-proof-run.md",
"growth-brain/ops/proof-library.md",
"growth-brain/ops/live-metrics.md",
"growth-brain/ops/market-parity-readiness.md",
"growth-brain/ops/sender-setup-guide.md",
"growth-brain/ops/sender-setup-guide.html",
"growth-brain/ops/competitive-proof-matrix.md",
"growth-brain/ops/competitive-proof-matrix.html",
"docs/strategy/market-parity-benchmark-2026.md"
],
"excluded": [
"public/",
"historical research"
]
}
{
"status": "passed",
"contract": "human-reviewed-service-kit",
"checkedFiles": 38,
"allowedCommands": 9,
"preservedGates": [
"client readiness",
"product truth",
"claims",
"send readiness",
"retention",
"agency defaults"
]
}
{
"status": "pass",
"checks": 16,
"labStatus": "blocked-before-fresh-mobbin-reference-packets"
}
{
"status": "pass",
"automationId": "tinystudio-retention-checkups",
"path": "/home/nish/.codex/automations/tinystudio-retention-checkups/automation.toml",
"weeklyCadence": "Friday retention prep",
"repo": "/home/nish/workspaces/products/tinystudio-in-autonomous-service",
"failures": [],
"warnings": []
}
Retention automation applicability checks passed.
{
"status": "passed",
"scanned": 110,
"requiredStringKeys": [
"founderName",
"offerName",
"buyer",
"founderSprintPrice",
"scope",
"dayZeroRule",
"automationBoundary",
"optOutLine",
"meetingPlaceholder",
"paymentPlaceholder"
],
"bannedValues": 0
}
{
"status": "pass",
"filesScanned": 7
}
{
"status": "pass",
"filesScanned": 0,
"findings": [],
"warnings": []
}
Outbound send readiness fixture checks passed.
test-public-conversion-signal: public conversion signal (The Website Correction application route)
A. signal definitions
ok registry names are unique
ok registry names are stable lowercase slugs
B. docs contract
ok docs/measurement/public-conversion-signal.md exists
ok docs document signal source homepage-hero
ok docs document signal source homepage-service
ok docs document signal source homepage-footer
ok docs name the offer truthfully as The Website Correction
ok docs never name the offer as a generic reviewed service
ok docs state the prefilled application subject is the operator-visible signal
ok docs pin the operator-visible subject format with the exact product name
ok docs pin the full propagated subject format
ok docs name the signal owner
ok docs state retention
ok docs state the privacy boundary
ok docs explain where the privacy disclosure lives
ok docs contain a falsifiable decision rule
ok docs are honest that tags are not application proof
ok docs count only received human messages as completion evidence
C. homepage Website Correction CTA source tags
ok every Website Correction CTA carries data-measure-source
ok source tag homepage-hero is a registered stable name
ok CTA homepage-hero routes to the application endpoint with source context
ok every Website Correction CTA carries data-measure-source
ok source tag homepage-service is a registered stable name
ok CTA homepage-service routes to the application endpoint with source context
D. contact endpoint source propagation
ok contact page has a Website Correction application mailto route
ok contact page default subject is exactly The Website Correction application
ok contact page application route names the offer as Website Correction
ok contact page names the offer truthfully as The Website Correction
ok contact page never names the offer as a generic reviewed service
ok contact page states the signal is for internal measurement only
ok contact page states nothing is sent automatically
ok contact page states the marker can be removed before sending
ok contact page reads the ?source= parameter
ok contact page allowlists every registered source name
ok contact page propagates the exact The Website Correction application — from
ok contact page rejects unregistered source values
ok contact page has no auto-send/auto-submit mechanism (<form)
ok contact page has no auto-send/auto-submit mechanism (<input)
ok contact page has no auto-send/auto-submit mechanism (<textarea)
ok contact page has no auto-send/auto-submit mechanism (location.href)
ok contact page has no auto-send/auto-submit mechanism (location.assign)
ok contact page has no auto-send/auto-submit mechanism (location.replace)
ok contact page has no auto-send/auto-submit mechanism (window.open)
ok contact page has no auto-send/auto-submit mechanism (.submit()
ok contact page has no auto-send/auto-submit mechanism (sendBeacon()
ok contact page has no auto-send/auto-submit mechanism (fetch()
E. no analytics provider, cookies, fingerprinting, or message-content collection
ok public/index.html has no document.cookie
ok public/index.html has no localStorage
ok public/index.html has no sessionStorage
ok public/index.html has no navigator.sendBeacon
ok public/index.html has no sendBeacon(
ok public/index.html has no fetch(
ok public/index.html has no XMLHttpRequest
ok public/index.html has no googletagmanager
ok public/index.html has no google-analytics
ok public/index.html has no gtag(
ok public/index.html has no plausible.io
ok public/index.html has no fathom.js
ok public/index.html has no posthog
ok public/index.html has no mixpanel
ok public/index.html has no amplitude
ok public/index.html has no window.analytics
ok public/index.html has no hotjar
ok public/index.html has no clarity.ms
ok public/index.html has no fbq(
ok public/index.html has no connect.facebook.net
ok public/index.html has no toDataURL
ok public/index.html has no hardwareConcurrency
ok public/index.html has no deviceMemory
ok public/index.html has no navigator.plugins
ok public/index.html has no FingerprintJS
ok public/index.html has no window.fingerprint
ok public/contact/index.html has no document.cookie
ok public/contact/index.html has no localStorage
ok public/contact/index.html has no sessionStorage
ok public/contact/index.html has no navigator.sendBeacon
ok public/contact/index.html has no sendBeacon(
ok public/contact/index.html has no fetch(
ok public/contact/index.html has no XMLHttpRequest
ok public/contact/index.html has no googletagmanager
ok public/contact/index.html has no google-analytics
ok public/contact/index.html has no gtag(
ok public/contact/index.html has no plausible.io
ok public/contact/index.html has no fathom.js
ok public/contact/index.html has no posthog
ok public/contact/index.html has no mixpanel
ok public/contact/index.html has no amplitude
ok public/contact/index.html has no window.analytics
ok public/contact/index.html has no hotjar
ok public/contact/index.html has no clarity.ms
ok public/contact/index.html has no fbq(
ok public/contact/index.html has no connect.facebook.net
ok public/contact/index.html has no toDataURL
ok public/contact/index.html has no hardwareConcurrency
ok public/contact/index.html has no deviceMemory
ok public/contact/index.html has no navigator.plugins
ok public/contact/index.html has no FingerprintJS
ok public/contact/index.html has no window.fingerprint
ok public/privacy-choices/index.html has no document.cookie
ok public/privacy-choices/index.html has no localStorage
ok public/privacy-choices/index.html has no sessionStorage
ok public/privacy-choices/index.html has no navigator.sendBeacon
ok public/privacy-choices/index.html has no sendBeacon(
ok public/privacy-choices/index.html has no fetch(
ok public/privacy-choices/index.html has no XMLHttpRequest
ok public/privacy-choices/index.html has no googletagmanager
ok public/privacy-choices/index.html has no google-analytics
ok public/privacy-choices/index.html has no gtag(
ok public/privacy-choices/index.html has no plausible.io
ok public/privacy-choices/index.html has no fathom.js
ok public/privacy-choices/index.html has no posthog
ok public/privacy-choices/index.html has no mixpanel
ok public/privacy-choices/index.html has no amplitude
ok public/privacy-choices/index.html has no window.analytics
ok public/privacy-choices/index.html has no hotjar
ok public/privacy-choices/index.html has no clarity.ms
ok public/privacy-choices/index.html has no fbq(
ok public/privacy-choices/index.html has no connect.facebook.net
ok public/privacy-choices/index.html has no toDataURL
ok public/privacy-choices/index.html has no hardwareConcurrency
ok public/privacy-choices/index.html has no deviceMemory
ok public/privacy-choices/index.html has no navigator.plugins
ok public/privacy-choices/index.html has no FingerprintJS
ok public/privacy-choices/index.html has no window.fingerprint
F. npm test/ci wiring
ok npm test runs the public conversion signal test
ok npm run ci runs the public conversion signal test
126 checks, 0 failures
test-public-structured-data: JSON-LD structured data on public pages
A. public/contact/index.html
ok contact page has exactly one application/ld+json block
ok contact page JSON-LD block parses as valid JSON
ok contact page uses the schema.org context
ok contact page JSON-LD uses an @graph array
ok contact page page declares a canonical URL
ok contact page page declares a title
ok contact page page declares a description
ok contact page JSON-LD carries the stable Tiny Studio organization reference
ok contact page JSON-LD declares the page as ContactPage
ok contact page JSON-LD url matches the page canonical URL
ok contact page JSON-LD name matches the page title
ok contact page JSON-LD description matches the meta description
ok contact page JSON-LD page is part of the Tiny Studio website
ok contact page JSON-LD page is about the Tiny Studio organization
A. public/promptly/privacy/index.html
ok Promptly privacy policy page has exactly one application/ld+json block
ok Promptly privacy policy page JSON-LD block parses as valid JSON
ok Promptly privacy policy page uses the schema.org context
ok Promptly privacy policy page JSON-LD uses an @graph array
ok Promptly privacy policy page page declares a canonical URL
ok Promptly privacy policy page page declares a title
ok Promptly privacy policy page page declares a description
ok Promptly privacy policy page JSON-LD carries the stable Tiny Studio organization reference
ok Promptly privacy policy page JSON-LD declares the page as WebPage
ok Promptly privacy policy page JSON-LD url matches the page canonical URL
ok Promptly privacy policy page JSON-LD name matches the page title
ok Promptly privacy policy page JSON-LD description matches the meta description
ok Promptly privacy policy page JSON-LD page is part of the Tiny Studio website
ok Promptly privacy policy page JSON-LD page is about the Tiny Studio organization
B. npm test/ci wiring
ok npm test runs the public structured data test
ok npm run check delegates to npm test
ok npm run ci runs the public structured data test
31 checks, 0 failures
test-public-heading-hierarchy: card headings are semantic H2s with the former card scale
A. public/contact/index.html
ok page contains at least one heading
ok page has exactly one H1
ok the H1 is the first heading in the outline
ok the three card headings are H2s inside .info-card articles
ok card H2s plus the footer H2 keep a flat H2 band before the footer H3s
ok no heading-level jump greater than one (no H1 -> H3 skip)
A. public/promptly/index.html
ok page contains at least one heading
ok page has exactly one H1
ok the H1 is the first heading in the outline
ok the three card headings are H2s inside .info-card articles
ok card H2s plus the footer H2 keep a flat H2 band before the footer H3s
ok no heading-level jump greater than one (no H1 -> H3 skip)
A. public/promptly/privacy/index.html
ok page contains at least one heading
ok page has exactly one H1
ok the H1 is the first heading in the outline
ok the three card headings are H2s inside .info-card articles
ok card H2s plus the footer H2 keep a flat H2 band before the footer H3s
ok no heading-level jump greater than one (no H1 -> H3 skip)
A. public/drishti/index.html
ok page contains at least one heading
ok page has exactly one H1
ok the H1 is the first heading in the outline
ok the three card headings are H2s inside .info-card articles
ok card H2s plus the footer H2 keep a flat H2 band before the footer H3s
ok no heading-level jump greater than one (no H1 -> H3 skip)
A. public/drishti/support/index.html
ok page contains at least one heading
ok page has exactly one H1
ok the H1 is the first heading in the outline
ok the three card headings are H2s inside .info-card articles
ok card H2s plus the footer H2 keep a flat H2 band before the footer H3s
ok no heading-level jump greater than one (no H1 -> H3 skip)
A. public/privacy-choices/index.html
ok page contains at least one heading
ok page has exactly one H1
ok the H1 is the first heading in the outline
ok the three card headings are H2s inside .info-card articles
ok card H2s plus the footer H2 keep a flat H2 band before the footer H3s
ok no heading-level jump greater than one (no H1 -> H3 skip)
B. card-heading CSS pairing
ok styles.css defines .info-card :is(h2, h3) {
ok card rule keeps margin-top: 12px
ok card rule keeps font-size: clamp(1.65rem, 2vw, 2.35rem)
ok card rule keeps max-width: none
ok global h2 styling (12ch cap) is untouched
ok the old .info-card h3-only rule is replaced by the shared :is(h2, h3) rule
C. npm test/ci wiring
ok npm test runs the public heading hierarchy test
ok npm run ci runs the public heading hierarchy test
44 checks, 0 failures passed: 38 checks plus all downstream suites, including 44 heading checks.
Proof boundary
Summary by CodeRabbit