From 3cbaf62e5288dc064fc7fa60923fce214c17ec72 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 16:17:42 +0000 Subject: [PATCH] CodeRabbit Generated Unit Tests: Generate Unit Tests for PR Changes --- tests/docs-status-updates.test.ts | 153 +++++++++++++++++++ tests/env-example-weak-or-relaxation.test.ts | 68 +++++++++ 2 files changed, 221 insertions(+) create mode 100644 tests/docs-status-updates.test.ts create mode 100644 tests/env-example-weak-or-relaxation.test.ts diff --git a/tests/docs-status-updates.test.ts b/tests/docs-status-updates.test.ts new file mode 100644 index 000000000..f733d45af --- /dev/null +++ b/tests/docs-status-updates.test.ts @@ -0,0 +1,153 @@ +import { existsSync, readFileSync, readdirSync } from "node:fs"; +import path from "node:path"; +import { describe, expect, it } from "vitest"; + +// Guards the 2026-07-17 status-refresh edits to three operator/audit-tracking +// docs. These docs are read by operators and future agents as the source of +// truth for what is done vs. still open, so a wrong status or a dangling file +// reference is a real regression, not just prose drift. + +const repoRoot = process.cwd(); +const docsDir = path.join(repoRoot, "docs"); +const migrationsDir = path.join(repoRoot, "supabase", "migrations"); + +function readDoc(name: string) { + return readFileSync(path.join(docsDir, name), "utf8"); +} + +function migrationExists(timestampPrefix: string) { + return readdirSync(migrationsDir).some((file) => file.startsWith(timestampPrefix)); +} + +/** Returns the single line of `doc` that contains `needle`, or undefined. */ +function lineContaining(doc: string, needle: string) { + return doc.split("\n").find((line) => line.includes(needle)); +} + +describe("docs/audit-remediation-plan-2026-07-14.md — 2026-07-17 reconciliation", () => { + const doc = readDoc("audit-remediation-plan-2026-07-14.md"); + + it("adds the reconciliation section for the memory-tasks review pass", () => { + expect(doc).toContain("Reconciliation"); + expect(doc).toContain("2026-07-17"); + expect(doc).toContain("claude/memory-tasks-review-glmntq"); + }); + + it("records F5 (.env.example weak-OR default) as done in code, matching src/lib/env.ts", () => { + expect(doc).toMatch(/F5[\s\S]{0,80}weak-OR[\s\S]{0,80}default corrected to `false`/); + expect(doc).toContain("src/lib/env.ts"); + }); + + it("references the in-flight draft PRs by number", () => { + expect(doc).toContain("#708"); + expect(doc).toContain("#710"); + }); + + it("links to a findings-handover doc that actually exists on disk", () => { + expect(doc).toContain("audit-handover-2026-07-14.md"); + expect(existsSync(path.join(docsDir, "audit-handover-2026-07-14.md"))).toBe(true); + }); + + it("still lists the OWNER:CODE cluster (D2, D3, E3, F1, F3, F6, H1-H5) as open", () => { + expect(doc).toContain("OWNER:CODE:"); + expect(doc).toContain("D2 (tenancy CI guard"); + expect(doc).toContain("E3 (wire `decideReindexGate`"); + expect(doc).toContain("API-contract hygiene"); + }); + + it("marks wave F2 as superseded rather than done or open", () => { + expect(doc).toContain("Superseded:"); + expect(doc).toContain("F2 (CI RAG-eval scope)"); + }); +}); + +describe("docs/ingestion-concurrency-fix-workorder.md — deep-memory scoping closed", () => { + const doc = readDoc("ingestion-concurrency-fix-workorder.md"); + + it("adds a 2026-07-17 status refresh declaring no open repository items", () => { + expect(doc).toContain("Status refresh 2026-07-17"); + expect(doc).toContain("no open repository items"); + }); + + it("replaces the 'Still open' entry with a resolved marker instead of the design-required line", () => { + const idx = doc.indexOf("## Still open (not merged or needs design)"); + expect(idx).toBeGreaterThan(-1); + const section = doc.slice(idx, idx + 400); + expect(section).toContain("_None._"); + expect(section).not.toContain("design required"); + }); + + it("strikes through the remaining-repo-work deep-memory scoping item as done", () => { + expect(doc).toContain("~~**deep-memory scoping**~~"); + expect(doc).toContain("DONE (2026-07-17)"); + }); + + it("references a producer-scoped migration that exists in supabase/migrations", () => { + const migrationName = "20260713030000_producer_scoped_deep_memory.sql"; + expect(doc).toContain(migrationName); + expect(existsSync(path.join(migrationsDir, migrationName))).toBe(true); + }); + + it("references the commit that reconciled the commit body", () => { + expect(doc).toContain("#569"); + }); + + it("retains the original 2026-07-15 status refresh and historical author-date content as provenance", () => { + expect(doc).toContain("Status refresh 2026-07-15"); + expect(doc).toContain("Author date: 2026-07-08"); + }); +}); + +describe("docs/operator-backlog.md — launch-gating table refresh", () => { + const doc = readDoc("operator-backlog.md"); + + it("flips the drift-codify migration row to done", () => { + const row = lineContaining(doc, "Apply drift-codify forward migration (step 1h)"); + expect(row).toBeDefined(); + expect(row).toContain("✅ done"); + expect(row).not.toContain("⏳ pending"); + }); + + it("adds a repo-ahead migrations verify row referencing the three pending migrations", () => { + const row = lineContaining(doc, "Apply repo-ahead migrations to live (post-2026-07-13)"); + expect(row).toBeDefined(); + expect(row).toContain("🔎 verify"); + for (const ts of ["20260713201542", "20260714110000", "20260717120000"]) { + expect(row).toContain(ts); + } + }); + + it("links the new verify row to a runbook doc that exists on disk", () => { + const row = lineContaining(doc, "Apply repo-ahead migrations to live (post-2026-07-13)"); + expect(row).toContain("[deploy-corrector-public-titles.md](deploy-corrector-public-titles.md)"); + expect(existsSync(path.join(docsDir, "deploy-corrector-public-titles.md"))).toBe(true); + }); + + it("links the drift-codify row to its forward-codify work-order doc that exists on disk", () => { + const row = lineContaining(doc, "Apply drift-codify forward migration (step 1h)"); + expect(row).toContain("[forward-codify-retrieval-rpcs-workorder.md](forward-codify-retrieval-rpcs-workorder.md)"); + expect(existsSync(path.join(docsDir, "forward-codify-retrieval-rpcs-workorder.md"))).toBe(true); + }); + + it("every migration timestamp referenced in the verify row corresponds to a real migration file", () => { + for (const ts of ["20260713201542", "20260714110000", "20260717120000"]) { + expect(migrationExists(ts)).toBe(true); + } + }); + + it("keeps the launch-gating table well-formed (every row has the same column count as the header)", () => { + const lines = doc.split("\n"); + const headerIndex = lines.findIndex((line) => line.startsWith("| Action")); + expect(headerIndex).toBeGreaterThan(-1); + const headerCols = lines[headerIndex].split("|").length; + + let i = headerIndex + 2; // skip the header and the `---` separator row + let rowCount = 0; + while (lines[i]?.startsWith("|")) { + expect(lines[i].split("|").length).toBe(headerCols); + i += 1; + rowCount += 1; + } + expect(rowCount).toBeGreaterThanOrEqual(6); + }); +}); \ No newline at end of file diff --git a/tests/env-example-weak-or-relaxation.test.ts b/tests/env-example-weak-or-relaxation.test.ts new file mode 100644 index 000000000..b6d6012d7 --- /dev/null +++ b/tests/env-example-weak-or-relaxation.test.ts @@ -0,0 +1,68 @@ +import { readFileSync } from "node:fs"; +import path from "node:path"; +import { afterEach, describe, expect, it, vi } from "vitest"; + +// RAG_TEXT_WEAK_OR_RELAXATION is an opt-in P8b experiment that is known to +// regress the golden retrieval eval when left on (see the comment above the +// field in src/lib/env.ts). .env.example previously committed the stale +// `true` value, which disagreed with the schema's actual `false` default; +// this PR corrects the committed default back to `false`. These tests guard +// against the two drifting apart again: the literal value committed in +// .env.example, and its parity with the env.ts zod schema default (which is +// the actual runtime behaviour whenever the var is left unset). + +const envExamplePath = path.join(process.cwd(), ".env.example"); + +function readEnvExampleValue(key: string): string | undefined { + const content = readFileSync(envExamplePath, "utf8"); + const match = content.match(new RegExp(`^${key}=(.*)$`, "m")); + return match?.[1]; +} + +async function loadEnvWith(value: string | undefined) { + vi.resetModules(); + vi.stubEnv("RAG_TEXT_WEAK_OR_RELAXATION", value); + return import("../src/lib/env"); +} + +afterEach(() => { + vi.unstubAllEnvs(); + vi.resetModules(); +}); + +describe(".env.example RAG_TEXT_WEAK_OR_RELAXATION", () => { + it("commits the safe default (false), not the regressive true", () => { + expect(readEnvExampleValue("RAG_TEXT_WEAK_OR_RELAXATION")).toBe("false"); + }); + + it("matches src/lib/env.ts's own schema default when the var is unset", async () => { + const { env } = await loadEnvWith(undefined); + expect(env.RAG_TEXT_WEAK_OR_RELAXATION).toBe(false); + expect(String(env.RAG_TEXT_WEAK_OR_RELAXATION)).toBe(readEnvExampleValue("RAG_TEXT_WEAK_OR_RELAXATION")); + }); + + it("resolves to the same boolean whether taken from env.ts's default or the literal .env.example value", async () => { + const exampleValue = readEnvExampleValue("RAG_TEXT_WEAK_OR_RELAXATION"); + expect(exampleValue).toBeDefined(); + + const { env: defaulted } = await loadEnvWith(undefined); + const { env: fromExample } = await loadEnvWith(exampleValue); + + expect(fromExample.RAG_TEXT_WEAK_OR_RELAXATION).toBe(defaulted.RAG_TEXT_WEAK_OR_RELAXATION); + }); + + it("still transforms an explicit true to true (regression guard: flag is not hard-disabled)", async () => { + const { env } = await loadEnvWith("true"); + expect(env.RAG_TEXT_WEAK_OR_RELAXATION).toBe(true); + }); + + it("documents the golden-eval regression and kill-switch semantics in the surrounding comment", () => { + const content = readFileSync(envExamplePath, "utf8"); + const idx = content.indexOf("RAG_TEXT_WEAK_OR_RELAXATION=false"); + expect(idx).toBeGreaterThan(-1); + const commentBlock = content.slice(Math.max(0, idx - 500), idx); + expect(commentBlock).toMatch(/OFF by default/i); + expect(commentBlock).toMatch(/golden retrieval eval/i); + expect(commentBlock).toMatch(/36\/36/); + }); +}); \ No newline at end of file