Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions docs/measurement/public-conversion-signal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Public conversion signal contract (The Website Correction application route)

Scope: read-only measurement of which public page pointed a visitor to The
Website Correction application route. This layer does not deploy, send, or
collect anything. It does not change pricing or legal copy, does not touch
auth, payments, or leads, and does not depend on PR #10's public copy.

## Signal source

A Website Correction CTA is any public link that routes to the application
route (the contact page application section or the application email route)
or carries a `data-measure-source` marker. Every such CTA must carry an
explicit stable source tag naming its placement.
Comment on lines +10 to +13

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Define the direct application link as an exception.

Lines 10-13 require every application-endpoint link to carry data-measure-source. However, public/contact/index.html line 98 is the direct application link and intentionally has no marker. This makes the contract false for the current flow.

Define source CTAs as inbound placement links, or explicitly exempt the contact-page application link.

🤖 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 `@docs/measurement/public-conversion-signal.md` around lines 10 - 13, Update
the CTA contract in the documentation to define source CTAs as inbound placement
links, or explicitly exempt the direct contact-page application link from the
data-measure-source requirement. Preserve the requirement for stable source tags
on all other qualifying placement links.


Canonical stable source names:

| Name | Placement | State in this checkout |
| --- | --- | --- |
| `homepage-hero` | Website Correction CTA in the homepage hero rail | Defined; no live CTA (PR #10 copy not merged) |
| `homepage-service` | Website Correction CTA in the homepage managed-service section | Defined; no live CTA (PR #10 copy not merged) |
Comment on lines +19 to +20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Mark the newly wired homepage sources as live

This checkout adds active homepage-hero and homepage-service CTAs in public/index.html, but the signal contract still labels both dormant and states that PR #10 is not merged. Since this table is the documented registry operators are told to update when placements change, it now gives the opposite state from the deployed markup and can mislead future attribution maintenance.

Useful? React with 👍 / 👎.

| `homepage-footer` | Website Correction CTA in the homepage footer | Defined; no live CTA |

Names are used only when they correspond to a real Website Correction CTA;
a name with no live CTA is dormant, not attached to unrelated links. In this
checkout the homepage has no Website Correction CTA: the "Ask about 0509" and
footer "0509" links are product CTAs (0509 is a product, not The Website
Correction) and must never carry a Website Correction source name. Any new
placement needs a new registered name, added here, to the allowlist in
`public/contact/index.html`, and to `scripts/test-public-conversion-signal.mjs`.

## Offer naming

The application route names the offer exactly as the public copy does:
The Website Correction. It is never presented as a generic "reviewed
service"; the human-reviewed nature of the offer is described in words
("reviewed by a human"), not used as a substitute offer name. The application
Comment on lines +33 to +36

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove the validator-forbidden phrase.

Line 34 contains reviewed service. scripts/test-public-conversion-signal.mjs line 70 requires that the documentation does not contain this text. Therefore, npm test and npm run ci fail on this checkout.

Reword the negative policy without that exact phrase.

🤖 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 `@docs/measurement/public-conversion-signal.md` around lines 33 - 36, Update
the documentation paragraph around “The Website Correction” to remove the exact
validator-forbidden phrase “reviewed service,” while preserving the intended
distinction between the offer name and its human-reviewed description.

subject line is the operator-visible measurement signal: it names The
Website Correction and, when a marker is present, the source tag, so the
operator reads the signal directly in the received application email. The
default subject is exactly `The Website Correction application`; with a
marker present it becomes `The Website Correction application — from <name>
(internal measurement marker)`.

## Marker mechanics

- CTA side: `data-measure-source="<name>"` on the anchor, routing to
`/contact/?source=<name>` or to the application mailto route with the
source name visible in the subject line.
- Endpoint side: `public/contact/index.html` reads the `?source=` parameter,
accepts only registered names, and prefills the application email subject
as `The Website Correction application — from <name> (internal measurement
marker)`. The prefilled subject is the human-readable, manual measurement
signal; it is visible in the email client before sending, and the visitor
can edit or remove it.
- Nothing auto-sends or auto-submits: the route is a plain `mailto:` link the
visitor opens and sends themselves. There is no form, no hidden field, no
script-triggered navigation.

## Owner

The Tiny Studio operator (the repo operator) owns this signal contract and is
the only reader of the measurement signal. Interpretation happens only during
manual review of received application emails; no automation reads, tallies, or
acts on the signal.

## Retention

The static site stores nothing: this layer adds no cookie, no server log, no
client-side storage, and no third-party request. The only retention is what an
applicant voluntarily includes in the subject line of the email they send to
`support@tinystudio.in`; that email is governed by the studio inbox policy and
is not processed automatically.

## Privacy boundary

- No analytics provider, no cookies, no fingerprinting, no hidden fields, no
message-content collection.
- The marker is a first-party URL parameter and email subject prefill the
visitor can see, edit, or remove before sending. Removing it never blocks
the application.
- The disclosure about the marker sits on the contact page next to the
application route, where the visitor actually encounters the marker, and
states that it is for internal measurement only and that nothing is sent
until the visitor sends the email themselves.
- `public/privacy-choices/index.html` needs no change: this layer collects
nothing and offers no data choices, so there is nothing to opt out of there.
The privacy-choices page documents app-related data requests; this layer
does not create app data or choices, and the contact-page disclosure already
covers the only visitor-visible behavior this layer introduces.

## Honesty

Static-site source tagging is not proof of completed applications; only received human messages count as completion evidence.
A tag being present or a link being opened proves nothing about completion.

## Falsifiable decision rules

1. The tag pipeline is falsified iff any Website Correction CTA exists on the
public homepage without a registered `data-measure-source` tag, or the
contact endpoint fails to propagate an accepted source into the visible
prefilled subject line. `scripts/test-public-conversion-signal.mjs`
enforces this rule deterministically and fails when it breaks.
2. A completed application is counted only when a received human message
arrives in the studio inbox. If an application email arrives whose subject
carries no registered source name, the propagation rule is falsified and
the contact wiring must be re-verified before any conversion conclusion is
drawn. Under this rule, "no tagged clicks" and "no applications" are both
observable, and either direction can be disproven by a single counterexample.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@
"product:truth": "node scripts/check-product-truth.mjs",
"mobbin:run": "node scripts/run-design-system-proving-lab.mjs",
"mobbin:check": "node scripts/run-design-system-proving-lab.mjs --dry-run",
"ci": "node scripts/test-service-engine.mjs && node scripts/test-sales-intake-contract.mjs && node scripts/test-active-offer-projection.mjs && node scripts/test-active-operator-surfaces.mjs && node scripts/test-client-readiness-contract.mjs && node scripts/test-validated-service-client.mjs && node scripts/test-client-acceptance-gates.mjs && node scripts/check-product-truth.mjs && node scripts/check-human-service-kit.mjs && node scripts/test-design-system-proving-lab.mjs && node scripts/check-retention-automation.mjs && node scripts/test-retention-automation.mjs && node scripts/check-agency-defaults.mjs && node scripts/check-outbound-claim-safety.mjs && node scripts/check-outbound-send-readiness.mjs && node scripts/test-outbound-send-readiness.mjs && find scripts -name '*.mjs' -print0 | xargs -0 -n1 node --check",
"test": "node scripts/test-service-engine.mjs && node scripts/test-sales-intake-contract.mjs && node scripts/test-active-offer-projection.mjs && node scripts/test-active-operator-surfaces.mjs && node scripts/test-client-readiness-contract.mjs && node scripts/test-validated-service-client.mjs && node scripts/test-client-acceptance-gates.mjs && node scripts/check-product-truth.mjs && node scripts/check-human-service-kit.mjs && node scripts/test-design-system-proving-lab.mjs && node scripts/check-retention-automation.mjs && node scripts/test-retention-automation.mjs && node scripts/check-agency-defaults.mjs && node scripts/check-outbound-claim-safety.mjs && node scripts/check-outbound-send-readiness.mjs && node scripts/test-outbound-send-readiness.mjs && find scripts -name '*.mjs' -print0 | xargs -0 -n1 node --check"
"ci": "node scripts/test-service-engine.mjs && node scripts/test-sales-intake-contract.mjs && node scripts/test-active-offer-projection.mjs && node scripts/test-active-operator-surfaces.mjs && node scripts/test-client-readiness-contract.mjs && node scripts/test-validated-service-client.mjs && node scripts/test-client-acceptance-gates.mjs && node scripts/check-product-truth.mjs && node scripts/check-human-service-kit.mjs && node scripts/test-design-system-proving-lab.mjs && node scripts/check-retention-automation.mjs && node scripts/test-retention-automation.mjs && node scripts/check-agency-defaults.mjs && node scripts/check-outbound-claim-safety.mjs && node scripts/check-outbound-send-readiness.mjs && node scripts/test-outbound-send-readiness.mjs && node scripts/test-public-conversion-signal.mjs && find scripts -name '*.mjs' -print0 | xargs -0 -n1 node --check",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Run the conversion check before the known failure

In the checked .github/workflows/codex-ci.yml, CI invokes npm run ci, but this && chain places the new conversion test after test-active-operator-surfaces.mjs. The commit explicitly records that the earlier test fails on clean main, so shell short-circuiting prevents CI from ever executing the new 120-check gate (and the subsequent syntax checks); move this gate ahead of the known failure or repair the baseline so it is actually enforced.

Useful? React with 👍 / 👎.

"test": "node scripts/test-service-engine.mjs && node scripts/test-sales-intake-contract.mjs && node scripts/test-active-offer-projection.mjs && node scripts/test-active-operator-surfaces.mjs && node scripts/test-client-readiness-contract.mjs && node scripts/test-validated-service-client.mjs && node scripts/test-client-acceptance-gates.mjs && node scripts/check-product-truth.mjs && node scripts/check-human-service-kit.mjs && node scripts/test-design-system-proving-lab.mjs && node scripts/check-retention-automation.mjs && node scripts/test-retention-automation.mjs && node scripts/check-agency-defaults.mjs && node scripts/check-outbound-claim-safety.mjs && node scripts/check-outbound-send-readiness.mjs && node scripts/test-outbound-send-readiness.mjs && node scripts/test-public-conversion-signal.mjs && find scripts -name '*.mjs' -print0 | xargs -0 -n1 node --check"
},
"engines": {
"node": ">=20"
Expand Down
44 changes: 43 additions & 1 deletion public/contact/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,54 @@ <h3>The Website Correction</h3>
before any work starts.
</p>
<div class="action-row">
<a class="button" href="mailto:support@tinystudio.in?subject=Website%20Correction">Apply for The Website Correction</a>
<a class="button" href="#website-correction-application">Apply for The Website Correction</a>
<a class="ghost-button" href="mailto:support@tinystudio.in">Plain email to the studio inbox</a>
</div>
</div>
</section>

<section class="app-strip reveal delay-1" id="website-correction-application" aria-labelledby="website-correction-title">
<div class="app-strip-grid">
<article>
<p class="eyebrow">The Website Correction</p>
<h3 id="website-correction-title">Apply by email, with a visible measurement marker.</h3>
<p class="section-copy">
If you arrived from a Tiny Studio page, the link may have
carried an internal measurement marker (for example
<code>?source=homepage-hero</code>) so the studio can learn
which page pointed you here. The marker is for internal
measurement only: there is no analytics provider, no cookie,
and nothing is sent until you press send in your own email
app. You can remove the marker before sending.
</p>
<div class="action-row">
<a class="button" id="website-correction-apply" href="mailto:support@tinystudio.in?subject=The%20Website%20Correction%20application">Apply to The Website Correction</a>
</div>
</article>
<article>
<p class="eyebrow">What the marker contains</p>
<p class="section-copy">
Only a stable page name from the measurement contract, never
any text you type and never anything from your device. When a
marker is present it appears in the email subject line, so it
stays visible to you before you send. Without a marker the
email opens with a plain subject and the application works
the same.
</p>
</article>
</div>
<script>
(function () {
var REGISTRY = ["homepage-hero", "homepage-service", "homepage-footer"];
var link = document.getElementById("website-correction-apply");
var source = new URLSearchParams(window.location.search).get("source");
if (link && source && REGISTRY.indexOf(source) !== -1) {
link.href = "mailto:support@tinystudio.in?subject=" + encodeURIComponent("The Website Correction application — from " + source + " (internal measurement marker)");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve source attribution when scripts are unavailable

When JavaScript is disabled or blocked, this assignment never runs and the static mailto at line 117 retains the untagged default subject even after a visitor follows either tagged homepage URL. Because the page provides a <noscript> stylesheet fallback and the application itself remains usable, these visitors silently lose the conversion signal; provide a non-JavaScript propagation fallback or explicitly narrow the signal contract to JavaScript-enabled visits.

Useful? React with 👍 / 👎.

}
})();
</script>
</section>

<section class="card-grid">
<article class="info-card reveal delay-1">
<p class="eyebrow">Support</p>
Expand Down
12 changes: 6 additions & 6 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ <h1>Products for people. One sharper system for teams.</h1>

<article class="rail-item">
<span class="rail-label">Managed service</span>
<strong><a href="mailto:support@tinystudio.in?subject=Website%20Correction">The Website Correction</a></strong>
<strong><a data-measure-source="homepage-hero" href="/contact/?source=homepage-hero#website-correction-application">The Website Correction</a></strong>
<p>One human-reviewed correction pass for founders, by email.</p>
</article>
</aside>
Expand Down Expand Up @@ -290,13 +290,13 @@ <h2 id="managed-service-title">The Website Correction.</h2>
<p class="team-mark">Website Correction</p>
<h4>Fit and scope are reviewed by a human first.</h4>
<p>
Email the studio inbox with the subject "Website Correction",
share your site and the page that matters most, and a person
reviews whether it fits and what the correction covers. Work
starts only after that review.
Apply through the contact page's application route, share your
site and the page that matters most, and a person reviews
whether it fits and what the correction covers. Work starts
only after that review.
</p>
<div class="action-row action-row-compact">
<a class="button" href="mailto:support@tinystudio.in?subject=Website%20Correction">Apply by email</a>
<a class="button" data-measure-source="homepage-service" href="/contact/?source=homepage-service#website-correction-application">Apply by email</a>
<a class="text-link" href="/contact/">See the contact page</a>
</div>
</div>
Expand Down
Loading