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
146
planned
1,367
shipped

Motir · Roadmap

MOTIR-3881Done

The public origin motir-core EMITS — the follow-digest links, and what app/sitemap.ts contains once nothing public is served

Opened by Zhu Yue ·

Type: code · Executor: coding_agent · Repo: motir-core · ONE PR.

⚠️ RE-SCOPED 2026-08-30 — the premise was measured and most of it is about to be deleted

This card was authored as "publicSiteOrigin() stops delegating to MOTIR_BASE_URL", on the reasoning that canonicals, og:url, JSON-LD @id and sitemap entries would need a second origin. Nearly all of those live in app/(public), which leaves this repository entirely. Measured on the branch, every reader of publicSiteOrigin() / publicProjectUrl():

readerafter app/(public) is deleted
app/(public)/p/[identifier]/{layout,changelog/page,changelog.xml/route}, explore/(square)/page, explore/topic/[slug]/page, _components/PublicProjectJsonLd, explore/_components/ExploreJsonLdgone — 7 files, the whole canonical/JSON-LD population
app/sitemap.tssurvives, with nothing public left to list
lib/rootMetadata.tssurvives, and is not this card'smetadataBase answers where is the application, which stays MOTIR_BASE_URL
lib/services/publicFollowDigestService.tssurvives, and is the real subject of this card

So the split is still owed and its purpose has changed. It is not about the pages this application renders — it will render none. It is about the absolute links this application EMITS into the world for a host it does not serve: the follow-digest email points a reader at a public project page on motir.co.

⚠️ And the second stale framing: there is no inert window to protect

The earlier body said the fallback arm was load-bearing because the public origin would be unconfigured until a cutover. motir.co already resolves to the motir-marketing Fly app — the apex does not move (docs/decisions/public-surface-hosts.md §7, MOTIR-3910). The public origin is knowable and configurable today, so the interesting case is a MISSING configuration in a self-hosted or local build, not a window in production.

What this card decides and ships

  1. publicSiteOrigin() resolves its own configured variable, no longer delegating to resolveBaseUrlTrimmed(). lib/baseUrl.ts keeps the application-origin question and its comment names which consumers moved.
  2. The follow digest emits links to the public site. publicFollowDigestService is the one shipped consumer that outlives the page deletion, and its links must resolve for a reader who clicks them from an inbox.
  3. ⚠️ app/sitemap.ts — DECIDE, do not leave it. It currently emits the square, its rank variants, every topic page and every public project against one origin. When this application serves none of them, a sitemap that still lists them is a crawl directive pointing at another host's URLs from this host's file. Say what it contains: the application host's own indexable surface, or nothing at all — and if nothing, whether the route is deleted or kept empty, consistently with app/robots.ts, which names it (MOTIR-3726).
  4. ⚠️ /follow/confirm and /follow/unsubscribe are NOT the reading surface and have no owner. Two pages under app/(public) reached from transactional email, not from the public site. They are the deletion card's to dispose of; this card must not assume they leave, because the digest it configures links to them.

Boundary

  • It deletes no page and issues no redirect. Both belong with the story that lands the replacements.
  • It does not touch lib/rootMetadata.ts. metadataBase is the application's own origin and is unaffected.
  • It does not decide where the public site is hosted — the ADR did.

Acceptance criteria

  • publicSiteOrigin() resolves from its own configured variable; lib/baseUrl.ts no longer serves the public question, and its precedence comment names the split.
  • Exactly ONE module reads each variable, asserted by a tree grep in the shape tests/hosting/appUrlSeam.test.ts already uses.
  • The follow digest's links resolve to the public site, asserted on the rendered email — the one consumer that outlives the page deletion, so it is the one the test must actually exercise.
  • An unset public-site origin has a stated, tested behaviour for a local or self-hosted build. Whatever it is, it may not silently emit localhost into an email that leaves the building.
  • app/sitemap.ts's contents are decided and recorded on this card, and a test asserts it lists nothing served by another host.
  • /follow/* is named on this card as the deletion card's to dispose of, with the digest's dependency on it stated.
  • ≥90% coverage on the files this PR touches.

Context refs

  • motir-core/lib/publicProjects/urls.tspublicSiteOrigin(), publicProjectUrl()
  • motir-core/lib/baseUrl.ts — the precedence contract and its single-reader rule
  • motir-core/lib/services/publicFollowDigestService.ts — the surviving consumer
  • motir-core/app/sitemap.ts · app/robots.ts — the crawl pair, and MOTIR-3726's decision that robots names the sitemap
  • motir-core/docs/decisions/public-surface-hosts.md §7 — the apex does not move
  • motir-core/tests/hosting/appUrlSeam.test.ts — the single-reader idiom

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