Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Roadmap

MOTIR-4147Done

(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.ts rather than hardcoded — the same mechanism the footer's LEGAL_* 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.ts already walks the real directory and is the natural home. The allowed shapes are: /legal/<slug> (this host), an absolute https?:// 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 grep above 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 carries target="_blank" + rel="noreferrer" (which the existing isExternal arm 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 · test pass.

Context refs

  • motir-marketing/content/legal/privacy.md:166 — the link
  • motir-marketing/app/legal/_components/MarkdownBody.tsx — the isExternal arm that decides target/rel and passes the href through
  • motir-marketing/lib/appOrigin.ts · lib/destinations.ts — how this repository already derives app-bound URLs
  • motir-marketing/tests/legal/legalReachability.test.ts — the totality guard over the real directory; the natural home for the new arm
  • motir-core/tests/e2e/data-subject-request-journey.spec.ts — the spec MOTIR-4015 narrowed, whose comment names this card
  • motir-core/lib/users/dataSubjectRequests.tsDATA_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.

Add a comment