(motir-marketing) The Privacy Policy's §7 data-rights link is a RELATIVE path — on motir.co it is a 404, so the export/deletion promise leads nowhere
Opened by Zhu Yue ·
Type: code · Executor: coding_agent · Repo: motir-marketing · ONE PR.
content/legal/privacy.md §7 tells a reader how to exercise their data rights and links them to the place they do it. That link is a RELATIVE path, written when the document lived on app.motir.co. It now lives on motir.co, where the path resolves to a page that does not exist.
The Privacy Policy currently makes a GDPR Art. 15/17 promise and points at a 404.
Reproduction — three facts, each read rather than inferred
Measured on motir-marketing origin/main (fetched 2026-09-02).
1. The link is relative. content/legal/privacy.md:166:
**The product provides these directly.** [In your account settings](/settings/account/data) you
grep -rn '](/' content/legal/ | grep -v '](/legal' returns that ONE line — it is the only cross-host relative link in the seven documents, so the fix has exactly one site.
2. The renderer passes the href through verbatim. app/legal/_components/MarkdownBody.tsx:
const isExternal = (href: string) => /^https?:\/\//.test(href)
// ...
a: ({ href, ...props }) => (
<a {...props} href={href}
{...(href && isExternal(href) ? { target: '_blank', rel: 'noreferrer' } : {})}
... />
),
isExternal decides only target/rel. A relative href is emitted unchanged, as a same-origin link.
3. There is no such route on this host. find app -type d -name 'settings*' in motir-marketing returns nothing; the whole app tree is _brand, _components, design, docs, explore, legal. So motir.co/settings/account/data is a 404.
Where it was found, and what it is NOT
Found while sweeping the referrers for MOTIR-4015, on branch parent/MOTIR-3909-legal-manifest. It is not caused by that branch — the three facts above are all on motir-marketing origin/main. It arrived with MOTIR-4009's byte-for-byte port, which is exactly the discipline that card asked for: the documents were not to be edited on the way across, and this link needed editing precisely because the host changed under it. The port did the right thing and left this behind.
motir-core's tests/e2e/data-subject-request-journey.spec.ts used to assert this link by reading the rendered document. It cannot any more — the document is not in that repository — so MOTIR-4015 narrowed it to the half motir-core still owns (the pane the link names answers 200 and renders) and named this bug in the spec's own comment. Both halves are needed and only one has a home; this card is the other.
What to do
- Point §7 at the ABSOLUTE app URL, derived from
lib/appOrigin.ts/lib/destinations.tsrather than hardcoded — the same mechanism the footer'sLEGAL_*and the rest of this repository's app-bound doors already use, so a change of app origin moves it.- ⚠️ It is a change to a published legal document. The prose does not change, only the target it always meant; say so in the PR body, and do not renumber, retitle or re-version the file while you are in it.
- Then make the class unrepeatable, because one fixed link says nothing about the next document: add a guard over
content/legal/**asserting that no Markdown link is a bare same-origin path outside the set this host actually serves.tests/legal/legalReachability.test.tsalready walks the real directory and is the natural home. The allowed shapes are:/legal/<slug>(this host), an absolutehttps?://URL, and an in-page#anchor. Anything else is a link this site cannot serve. - Sweep the other six documents with that guard before assuming §7 is the only one — the
grepabove says it is TODAY, and a guard is what keeps that true.
Acceptance criteria
content/legal/privacy.md§7 links to the data-and-privacy pane on the APP origin, derived rather than hardcoded, and the rendered anchor carriestarget="_blank"+rel="noreferrer"(which the existingisExternalarm gives it for free once the href is absolute).- A guard over the real
content/legal/directory fails on ANY bare same-origin path that is not/legal/<slug>or an#anchor— and it is shown to fail by reintroducing the old link, not merely asserted to pass. - The PR body records that a published document changed, what changed (a link target, not prose), and why.
pnpm lint · format:check · typecheck · build · testpass.
Context refs
motir-marketing/content/legal/privacy.md:166— the linkmotir-marketing/app/legal/_components/MarkdownBody.tsx— theisExternalarm that decidestarget/reland passes the href throughmotir-marketing/lib/appOrigin.ts·lib/destinations.ts— how this repository already derives app-bound URLsmotir-marketing/tests/legal/legalReachability.test.ts— the totality guard over the real directory; the natural home for the new armmotir-core/tests/e2e/data-subject-request-journey.spec.ts— the spec MOTIR-4015 narrowed, whose comment names this cardmotir-core/lib/users/dataSubjectRequests.ts—DATA_PRIVACY_PANE_PATH, the path §7 means
Discussion
No comments yet.
Adding to this discussion signs you in on app.motir.co and brings you back to this request.