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 · Work items

MOTIR-4104Blocked

Vitest gate (motir-core) — the absence of every content/legal reader, the catalogue split, and the CI content arm's disposition

Type: test · Executor: coding_agent · Repo: motir-core · ONE PR. This story's per-repo coverage + integration gate. It runs LAST, after the deletion card has merged, because it measures that card's real, merged effect. Real Postgres, not mocks.

Every assertion here is about an ABSENCE, or about what SURVIVED an absence. That is what makes it a separate gate from MOTIR-4014, which measures the manifest seam under MOTIR-3909: a manifest that works proves the new path and says nothing whatever about whether the old one is gone. The clauses below were cut from MOTIR-4014 in the same plan that created this card, so nothing is asserted twice and nothing was dropped.

Its three jobs at run time — not a plan-time case list

  1. Coverage floor. Run coverage over this story's changed surface in this repository and write whatever is missing to reach the project's per-file gate (≥90% branch/fn/line, motir-core/CLAUDE.md), plus the five files vitest.config.ts pins at their own thresholds — lib/legal/{consent,documents,reconsentGate}.ts, lib/repositories/legalAcceptanceRepository.ts, lib/services/legalAcceptanceService.ts. Those five are untouched by the deletion and must not drop when the suites around them are removed.
  2. The integration seam that must SURVIVE the deletion — the manifest wire end to end with nothing in content/: a configured manifest → documents.tsconsent.tslegalAcceptanceService → the LegalAcceptance rows → resolveOutstanding → the rendered row's href. MOTIR-4014 drove this wire with the files still in the tree; this drives it after they are gone, which is the only run in which a surviving filesystem read would be visible.
  3. The contract guards coverage cannot see — below.

The guards

  • ⚠️ NOTHING IN THIS REPOSITORY READS content/legal/ ANY MORE. The structural guard, and the one this whole story turns on: no node:fs / fs import under lib/legal/, and no content/legal path reference outside re-pointed prose citations. Assert the ABSENCE of the reader, and show the guard RED against a deliberately re-introduced filesystem read — a negative assertion nobody has watched fail is a test that passes because it cannot see.
  • content/ itself is empty, and the guard says so as a SET rather than as a maximum. git ls-tree the directory and assert the population, not that a particular file has gone (core.md gate 2's coverage-is-a-set limb).
  • The materiality rule survives with nothing in the tree. Over the manifest alone: a MINOR or MAJOR bump on one of the three re-consent slugs HOLDS the reader; a PATCH bump does not. Asserted through the seam, not in isolation.
  • The unconfigured arm still behaves, on BOTH sides. With no manifest AND no content/legal/: recordAcceptance writes zero rows and does not throw; resolveOutstanding answers []; a signed-in request is not held. Assert each behaviour, not "nothing errored" — every one is a deliberate empty-set arm, and silently correct is this story's whole failure mode.
  • Catalogue parity after the legal.* split. Every en key has its zh twin, no key a SURVIVING surface reads was removed, and no orphan key nothing reads was left behind. The orphan direction is the quiet one: a catalogue key nothing reads is invisible to every other check.
  • The CI content/* arm is consistent with whatever the deletion card chose. tests/ci-changed-paths-gate.test.ts asserts that arm's ordering in three places; no assertion may cite a path that no longer exists, and if the arm was KEPT its test's rationale names the defect it still guards rather than the directory it used to name.
  • tests/seo/robots.test.ts no longer asserts /legal is crawlable on this host, and the suite still asserts whatever replaced it rather than simply losing the case.

⚠️ Read the lane's own configuration before writing a line in it

The manifest is a server-side, process-wide value: a spec that needs it CONFIGURED has no per-test override and no client seam a request stub can reach. Name the exact mechanism this suite uses to set it, and confirm the runner reaches it, before writing the assertions — a guard in a lane that cannot reach the asserted state passes on unfixed code and stays green for ever. Where an arm cannot be reached from this suite at all, say so and put it in the E2E card rather than asserting the harness.

⚠️ What this card may NOT assert

  • Nothing about the manifest seam that MOTIR-3909 already gated. MOTIR-4014 owns the configured-arm seam, the malformed-manifest guard and the tenancy fixture. This card re-drives the seam only to prove it survives the deletion, and says so in the spec's own comment.
  • Nothing about motir-marketing. MOTIR-4011's.
  • Nothing about the redirect. MOTIR-3884's.
  • Nothing about the deployed manifest. The live-gate confirmation reads that from the running application; a repository suite cannot.

Acceptance criteria

  • Coverage over this story's changed surface in motir-core meets the per-file gate, and the five pinned files stay at their configured thresholds; the PR body shows the run.
  • The no-content/legal-reader guard exists, and the PR shows it going RED against a deliberately re-introduced filesystem read — the red run is quoted, not described.
  • The content/ population guard asserts the directory's contents as a SET, and the PR body quotes the git ls-tree it was derived from.
  • The manifest seam is driven end to end against real Postgres with content/legal/ absent, in one test, and the spec's comment states that this is the post-deletion re-drive rather than a copy of MOTIR-4014's.
  • The materiality guard asserts both directions — a MINOR bump holds, a PATCH bump does not — through the seam.
  • All three unconfigured assertions are present, each about a specific behaviour rather than about the absence of an exception.
  • Catalogue parity passes in BOTH directions: no missing twin, and no orphan key.
  • tests/ci-changed-paths-gate.test.ts is consistent with the arm's chosen disposition, and no assertion in this repository cites content/legal as a live path.
  • The mechanism this suite uses to configure the manifest is named in the spec's own comment, and the PR body confirms the runner reaches it — or names which arm moved to the E2E lane and why.
  • No test is deleted because its subject moved: anything re-pointed is re-pointed to a shipped symbol, and the PR body maps every assertion to one.

Context refs

  • motir-core/vitest.config.ts — the per-file thresholds on the five legal files
  • motir-core/lib/legal/documents.ts · consent.ts · reconsentGate.ts — the seam's upper half, all of which STAY
  • motir-core/lib/services/legalAcceptanceService.ts · lib/repositories/legalAcceptanceRepository.ts — its lower half
  • motir-core/tests/legal/ — the surviving suites this composes with
  • motir-core/tests/ci-changed-paths-gate.test.ts · .github/workflows/ci.yml — the content/* arm and the defect it exists for
  • motir-core/tests/seo/robots.test.ts — the crawlable-allow list
  • motir-core/messages/en.json · messages/zh.json — the parity subject
  • motir-core/CLAUDE.md — the coverage gate and the real-Postgres discipline
  • the deletion card — what this measures; blocked_by
  • MOTIR-4014 — the manifest-seam gate under MOTIR-3909, whose absence clauses were cut and landed here

Advisory dispositions

  • Any reference advisory naming MOTIR-4014, MOTIR-4011 or the cards under MOTIR-3909: NOT an owed leaf edge. They sit in another container, and this story is blocked_by that container; the edge belongs BETWEEN the stories and already exists (core.md gate 4's cross-parent limb; gate 7).
  • The remaining reference advisories name cards this one's What this card may NOT assert list excludes. Naming the owner is what makes the exclusion checkable, so the reference is deliberate and no edge is owed.