content/legal/ LEAVES motir-core — the live-gate confirmation, the deletion and its 84-file sweep, and the guards that assert the absence
Created 2026-09-01 by the re-plan that refused motir run MOTIR-3909 at step 0. This story is the POST-DEPLOY half of MOTIR-3909, carved out because that story's own criteria implied two merges separated by a deployment — and a container is completed by ONE merge per repository (plan-rules/kind-container.md, COUNT THE MERGES A CONTAINER'S OWN CRITERIA IMPLY).
motir-core reaches this story already reading its legal documents from a configured manifest, with the hosted deployment provisioned and the reader live. What is left is to take moooon B.V.'s contract text out of the tree — and to prove it is gone rather than merely unread.
Why this is a story of its own — the DEPLOY BOUNDARY
MOTIR-3910 already states the rule this story is an instance of: "every card whose acceptance criteria read a deployed environment has no legal position inside a container whose own merge produces that deployment: its pull request will not open while such a child is un-landed, and the child cannot be done until it merges."
MOTIR-3909 held all of it — the manifest reader AND a card confirming the gate live on app.motir.co AND a deletion blocked_by that confirmation. No ordering of those children finished the story. The line is drawn here instead: MOTIR-3909 merges and deploys; this story opens by reading that deployment, and only then deletes the fallback.
The order, and why the deletion is not first
- Confirm the gate is LIVE on the deployed application — the manifest set by MOTIR-3909's provisioning card is actually what holds a reader, and a fresh sign-up records an acceptance against it. Until that is observed, the seven files in
content/legal/are still the working fallback for nothing, and removing them is removing a safety net that has not been replaced in fact, only in code. - Delete
content/legal/andapp/(public)/legal/, and sweep the 84-file referrer population. - Assert the absence — a repository guard that no module reads
content/legal/any more, and a browser walk proving/legalis gone from the application host while the configured legal journey still works.
Step 1 is what makes step 2 safe, and it is a reading of a running system rather than of this repository — which is precisely why it sits at the head of this container instead of inside the one that produced the deployment.
Boundary
- It does not build the manifest reader, the link surfaces or the subprocessor split. All three are MOTIR-3909's, discharged before this story starts.
- It does not SET the hosted manifest. MOTIR-4012 does, inside MOTIR-3909, before that story's pull request opens. This story only reads back what that card set, from the running application rather than from the platform.
- It does not build
motir.co/legal. MOTIR-3932 did; it isdone. - It does not issue the 301. MOTIR-3884 did, under MOTIR-3932 — so
/legalon the app host is already redirected, and this story removes what was behind it. - It does not touch the rest of
app/(public). MOTIR-3951 removed the other 69 files; its own table nameslegalas MOTIR-3909's, and that ownership travels here with the deletion card. - It does not touch the re-consent machinery, the
LegalAcceptancetable or its migration. Those STAY, and this story's guards are what prove they still work with nothing incontent/. - It does not widen the
MOTIR_CLOUDgate.
Ordering — ONE story edge
This story is blocked_by MOTIR-3909, and that single edge carries every cross-story constraint its children used to carry individually: the manifest reader ships, the link surfaces render from configuration, the subprocessor evidence is re-homed and the hosted manifest is set — and only then does anything here read the deployment or delete a file. Every leaf edge beneath this story is in-subtree.
MOTIR-3910 is blocked_by this story as well as MOTIR-3909: the cutover's smoke of the live journey is not honest while the app host still carries the documents.
Verification recipe
- On
app.motir.co, sign in as a reader whose accepted version is materially behind: you are held at/re-consent, each row links tomotir.co/legal/<slug>, and Agree and continue returns you to where you were going. - Sign up a fresh account and confirm the acceptance rows were written against the manifest's versions.
- Request
app.motir.co/legalandapp.motir.co/legal/terms— neither serves a document from this repository any more. git ls-tree origin/main content/returns nothing, andgit grep -n "content/legal" origin/main -- ':!docs/decisions'returns only re-pointed citations.git grep -n "moooon" origin/main -- ':!docs' ':!CLA.md' ':!README.md' ':!.github' ':!design'returns only the configuration seam and its tests.
Acceptance criteria
- Every child is
done. The repository set ismotir-corealone — themotir-marketingpage-side assertion is MOTIR-4011's, in MOTIR-3909. - The hosted gate was observed LIVE over the manifest before anything was deleted, and the observation is recorded on the card that made it — not inferred from a merged pull request.
- The seven documents and their renderer are gone from
motir-core, and no module in that repository readscontent/legal/any more — asserted as an ABSENCE, with the guard shown red against a deliberately re-introduced filesystem read. - The abandoned route is deleted, not left unreferenced, and the sweep for leftovers is recorded with its re-run population quoted.
- The PR body carries the full re-run
grepresult for every reader of the legal routes and content, with a per-hit disposition — changed here, or a named sibling card. - The re-consent gate still works with nothing in
content/— a material version bump holds a signed-in reader, a patch bump does not — asserted through the whole seam against real Postgres. app.motir.co/legalno longer serves a document, asserted in a browser on the status code rather than on a rendered page.
Context refs
motir-core/content/legal/·app/(public)/legal/— the population being removedmotir-core/lib/legal/{documents,consent,reconsentGate}.ts·lib/services/legalAcceptanceService.ts— the machinery that STAYS and that this story's guards prove still worksmotir-core/.github/workflows/ci.yml·tests/ci-changed-paths-gate.test.ts— thecontent/*arm and the defect it exists formotir-core/messages/en.json·messages/zh.json— thelegal.*namespace to split- MOTIR-3909 — the manifest half;
blocked_by, and the edge that carries this story's whole ordering - MOTIR-4012 — sets the hosted manifest, inside MOTIR-3909; this story reads it back from the running application
- MOTIR-3910 — the cutover, which this story
blocks motir-meta/prompts/plan-rules/kind-container.md— the merge-count check this story exists to satisfy