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-3877Done

Public project pages move to motir.co — rendered by motir-marketing over motir-core's public contract

Opened by Zhu Yue ·

⚠️ RE-SCOPED 2026-09-01 — the direction reversed, and this body is the correction

Everything below the line in the previous version of this card argued the REJECTED direction"the renderer stays where the data and the gates are, and the ADDRESS moves" — and its own comment of 2026-08-29 said so: "the card should not be run until its body says so." This is that rewrite. The four findings that conclusion rested on have each been settled since, on origin/main:

the card's findingwhat is true now
"there is no app/api/public/p/[identifier]/route.ts"ShippedMOTIR-3945
"six of those routes call getSession()"⚠️ CORRECTED 2026-09-02 (MOTIR-4166). Re-measured: ONE of ten is session-gated (follow, a write). That count was taken over app/api/public/p/* and stated about the whole public write surface. Over both app/api/public and app/api/public-requests it is FIVE of thirteen: follow, the request intake and its duplicate pre-check, and the two request writes. The /p/* READS are anonymous, which is the half that was right and is what this story depends on. See public-surface-hosts.md AMENDMENT 4 §A
"/api/public/* is not in the versioned contract"It isMOTIR-3946 gave it its own version, document and drift guard; MOTIR-3990 took it to totality
"/p/* is an application, not a page (~25 components)"Twelve files, one of them a Server Actions module — a real rebuild, not a second motir-core

The decision is docs/decisions/public-surface-hosts.md §2: motir.co serves every public page, from motir-marketing, over motir-core's public contract. motir-core ships no public rendering at all.


⚠️ AND THE PAGES ARE ALREADY GONE — this story is a restoration, not a migration

Measured on the live hosts, 2026-09-01:

  • https://app.motir.co/p/MOTIR404. MOTIR-3951 deleted app/(public)/p (12 files); proxy.ts 308s /p/* onto the public origin, but only once MOTIR_PUBLIC_SITE_URL is configured, which is the cutover's job.
  • https://motir.co/p/MOTIR404. Nothing serves it there yet. That is this story.
  • https://motir.co/explore200, rendering href="/p/MOTIR" on every card.

So the live directory links into a page no host answers for. Closing that window is this story, and it is why this card is highest. The interim disposition for those dead links is filed separately, under the epic.

What this story delivers

Seven screens on motir.co, four new endpoints on app.motir.co, and one decision that has to come first.

  • The decision. public-surface-hosts.md settled the host, the seam, the cookie and the cloud gate. It did not settle what happens to the affordances that read or require a session — follow, subscribe, roadmap vote, request upvote, request comment, submit request, in-place overview editing, and the top bar's account treatment — once the page is cross-origin from the session. §9 does not list it as deferred; it is simply open. AMENDMENT 2 closes it, per affordance, against what the mirrors do.
  • The four missing reads. MOTIR-3951's service sweep kept getBoard, getRoadmap, getWorkItemDetail, getRequestDetail and setPublicOverview precisely because "MOTIR-3877's motir-marketing /p/* pages will re-expose them through new API routes." Those routes are this story's. Two more are owed beside them: the changelog Atom feed, whose builder (lib/publicProjects/atomFeed.ts) has had no caller since the deletion, and a public-project index so motir.co's sitemap can enumerate what it advertises.
  • The pages, in motir-marketing, over that contract: the project shell and Overview, the five tabs, the two detail pages and the request intake, the act affordances, and the crawl surface.
  • The gates: a Vitest gate per repository, and a Playwright walk with an acceptance video — which this repository has no lane for yet, so building that lane is part of the story.

Scope

The ADR amendment; the four-plus-two public read routes and whatever the amendment needs on the motir-core side; the whole /p/* rendering surface in motir-marketing; its canonical / OpenGraph / JSON-LD / sitemap / Atom crawl surface on motir.co; and the assertion — not the assumption — that the Better-Auth session cookie stays host-only on app.motir.co.

Boundary

  • The app.motir.co/p/*motir.co redirect is ALREADY SHIPPED and is not this story's. MOTIR-3884 put p in proxy.ts's PUBLIC_REDIRECT_SEGMENTS and its matcher, and MOTIR-3886 asserts it. It fires when the cutover sets MOTIR_PUBLIC_SITE_URL. No card here re-owns it.
  • Ends at ONE Motir-owned host. Per-tenant subdomains and customer custom domains are MOTIR-3878's, and §4's reversal condition hands it the separate-registrable-domain question. Nothing here ships certificate-provisioning machinery. (The graph edge runs the other way — this story blocks 3878 — so the reference advisory raised on that name is CONTEXT, not a missing blocked_by; recorded here rather than left undisposed.)
  • Does not touch /explore, /docs or /legalMOTIR-3932 moved them.
  • Does not widen the session cookie. Not deferred — rejected (§4), and the condition the whole arrangement's residual exposure rests on.
  • /p/* is CLOUD-ONLY. The MOTIR_CLOUD gate is MOTIR-3908's and is shipped; every new route here inherits it, and none of them re-opens it.
  • Does not re-plan /p/*'s FEATURES. The tabs, changelog, follow and request intake are shipped behaviour being re-hosted, not redesigned.

⚠️ The trade this makes, which this story owns

The research that started this epic concluded that tenant-authored content belongs on a registrable domain of its own, because a cross-site-scripting hole in user content reaches whatever session shares its origin — GitHub's "Yummy cookies across domains", and the reason github.io, notion.site and vercel.app are on the Public Suffix List. motir.co achieves the primary goal: /p/* leaves the authenticated session's origin. It achieves it at lower isolation than the mirrors chose, because first-party and tenant content then share one origin, and that origin is the parent of the application's. That is acceptable only while the session cookie is host-only on app.motir.co — so this story asserts it in a test rather than intending it.

Verification recipe

  1. Open a public project at motir.co/p/<identifier> — the overview renders for a logged-out visitor.
  2. Move through Board, Items, Tree, Roadmap and Changelog; page one list and expand one tree level.
  3. Open a work item, and a feature request, from those lists.
  4. Submit a feature request — sign-in-to-act, not anonymous (⚠️ corrected 2026-09-02, MOTIR-4166: POST /api/public/projects/{projectId}/requests has always required a session). Follow the hand-off AMENDMENT 4 row 6 specifies: leave for app.motir.co, submit through the duplicate step there, and return to the project page, where the new request is visible.
  5. Follow the project, and exercise the vote / comment / overview-edit affordances as the amendment specifies them — including returning to the page you left.
  6. Subscribe to the project's changelog at motir.co/p/<identifier>/changelog.xml and get a valid Atom document.
  7. From a browser signed in to app.motir.co, load the public page and confirm the session cookie is not sent to motir.co.

Acceptance criteria

  • Every /p/* route — the project, its five tabs, the two detail pages, the request intake and the changelog feed — resolves on motir.co, rendered by motir-marketing, reading only motir-core's public contract.
  • Their canonical, og:url, JSON-LD @id and sitemap entries all name motir.co; a per-project OpenGraph card is served.
  • The Better-Auth session cookie is not sent to motir.co — asserted in a test — and no cookie's Domain was widened to achieve the split.
  • docs/decisions/public-surface-hosts.md AMENDMENT 2 names, per affordance, what happens to it once the page is cross-origin from the session, and which mirror's behaviour that follows.
  • No public-project rendering code is duplicated into a second repository, and motir-marketing gains no database client.
  • Every new app/api/public/* route carries a contract operation, the MOTIR_CLOUD gate and an anonymous-posture entry, with no exemption added to an existing guard.
  • The changelog Atom feed answers again, at the path proxy.ts's redirect produces.
  • motir-marketing has a Playwright lane gating its deploy, and this story's E2E publishes an acceptance video to this card.

Context refs

  • motir-core/docs/decisions/public-surface-hosts.md — §2 (the host table), §3 + AMENDMENT 1 (the contract), §4 (the cookie and its reversal condition), §5 (the cloud gate), §7 (this card's row), §8 (the costs), §9
  • motir-core/app/api/public/ — the twelve shipped operations, and the reads this story adds beside them
  • motir-core/lib/services/publicProjectsService.tsgetBoard · getRoadmap · getWorkItemDetail · getRequestDetail · setPublicOverview · listPublicForSitemap, kept by MOTIR-3951 for this story
  • motir-core/lib/publicProjects/atomFeed.ts — the builder with no caller
  • motir-core/proxy.tsPUBLIC_REDIRECT_SEGMENTS, and why /p/* is in it
  • motir-core/app/(public)/p/ @ 95a2d4468^ — the twelve deleted files, as prior art
  • motir-marketing/lib/explore.ts · app/explore/ — the shipped pattern for a surface fed by the public API
  • motir-marketing/.github/workflows/ci.yml — the lane that has no e2e job yet
  • motir-core/design/public-projects/ · design/public-site/ — the surface as it was, and motir.co's chrome

⚠️ ORDINAL CORRECTED AGAIN, 2026-09-02 — it is AMENDMENT 4. MOTIR-4139 (b615991c4) merged its own AMENDMENT 3 into public-surface-hosts.md — the subprocessor seam — while this story was in flight, so the affordance table is AMENDMENT 4. Every reference to AMENDMENT 2 or AMENDMENT 3 on this card and its siblings means that section. Twice in one day: an ADR ordinal is a serialized resource and nothing in the corpus says so — the amendment's own banner now does.

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