@@ -19,6 +19,14 @@ import { run } from "../../src/index.js";
1919// test/integration/ -> cli -> packages -> typescript -> server -> repo root
2020const SHOWCASE = resolve ( import . meta. dirname , "../../../../../../examples/showcase" ) ;
2121
22+ // The docs root, taken from the CONFIG default rather than a `--out` flag — because the
23+ // gate reads the config and `--out` does not survive the run. The test used to pass
24+ // `--out <dir>/docs` while `verify --docs` resolved the default, and it only agreed
25+ // because the two happened to be the same string. When the default moved to
26+ // `docs/generated`, that coincidence ended and every case here failed at once: the two
27+ // doors onto one directory were never actually being compared.
28+ const DOCS_ROOT = join ( "docs" , "generated" ) ;
29+
2230/** A throwaway copy of the showcase with a freshly generated docs tree. */
2331function project ( ) : string {
2432 const dir = mkdtempSync ( join ( tmpdir ( ) , "verify-docs-" ) ) ;
@@ -27,7 +35,7 @@ function project(): string {
2735}
2836
2937async function generateDocs ( dir : string ) : Promise < void > {
30- expect ( await run ( [ "docs" , dir , "--out" , join ( dir , "docs" ) ] ) ) . toBe ( 0 ) ;
38+ expect ( await run ( [ "docs" , dir ] ) ) . toBe ( 0 ) ;
3139}
3240
3341describe ( "meta verify --docs" , ( ) => {
@@ -38,12 +46,17 @@ describe("meta verify --docs", () => {
3846 // The agent surface materialises only with a loadable gen config, which the
3947 // showcase has. Assert the pages exist before asserting the gate is green, so a
4048 // green result cannot come from the surface having silently emitted nothing.
41- expect ( existsSync ( join ( dir , "docs" , "agent" , "schema.md" ) ) ) . toBe ( true ) ;
42- expect ( existsSync ( join ( dir , "docs" , "agent" , "ui.md" ) ) ) . toBe ( true ) ;
43- expect ( existsSync ( join ( dir , "docs" , "agent" , "requirements.md" ) ) ) . toBe ( true ) ;
49+ expect ( existsSync ( join ( dir , DOCS_ROOT , "agent" , "schema.md" ) ) ) . toBe ( true ) ;
50+ expect ( existsSync ( join ( dir , DOCS_ROOT , "agent" , "requirements.md" ) ) ) . toBe ( true ) ;
51+ // NO ui.md, and that is the assertion. The showcase wires entity/queries/routes/
52+ // prompt generators and not one UI generator, so nothing here emits a form, a hook
53+ // or a grid — the page's metadata predicate (`servesReadApi`) said otherwise and
54+ // produced a control table for forms that do not exist plus endpoints for a client
55+ // that was never generated. Whether the tier exists is a GENERATOR fact.
56+ expect ( existsSync ( join ( dir , DOCS_ROOT , "agent" , "ui.md" ) ) ) . toBe ( false ) ;
4457 // Built from the REAL migrate-ts snapshot: the dialect comes from the project's
4558 // own config, not from `meta docs`'s neutral "sqlite" placeholder.
46- const schema = readFileSync ( join ( dir , "docs" , "agent" , "schema.md" ) , "utf8" ) ;
59+ const schema = readFileSync ( join ( dir , DOCS_ROOT , "agent" , "schema.md" ) , "utf8" ) ;
4760 expect ( schema ) . toContain ( "`subscribers`" ) ;
4861 expect ( schema ) . toContain ( "Declared by `acme::Subscriber`." ) ;
4962
@@ -57,7 +70,7 @@ describe("meta verify --docs", () => {
5770 const dir = project ( ) ;
5871 try {
5972 await generateDocs ( dir ) ;
60- const page = join ( dir , "docs" , "agent" , "schema.md" ) ;
73+ const page = join ( dir , DOCS_ROOT , "agent" , "schema.md" ) ;
6174 writeFileSync ( page , readFileSync ( page , "utf8" ) . replace ( "subscribers" , "subscribersRENAMED" ) ) ;
6275 expect ( await run ( [ "verify" , "--cwd" , dir , "--docs" ] ) ) . toBe ( 1 ) ;
6376 } finally {
@@ -69,7 +82,8 @@ describe("meta verify --docs", () => {
6982 const dir = project ( ) ;
7083 try {
7184 await generateDocs ( dir ) ;
72- rmSync ( join ( dir , "docs" , "agent" , "ui.md" ) ) ;
85+ // A page the showcase DOES emit — ui.md is not one of them (no UI generator).
86+ rmSync ( join ( dir , DOCS_ROOT , "agent" , "schema.md" ) ) ;
7387 expect ( await run ( [ "verify" , "--cwd" , dir , "--docs" ] ) ) . toBe ( 1 ) ;
7488 } finally {
7589 rmSync ( dir , { recursive : true , force : true } ) ;
@@ -98,10 +112,10 @@ describe("meta verify --docs", () => {
98112 // hand-written documentation. Convicting those is the jurisdiction mistake
99113 // `verify --codegen`'s orphan branch was corrected for; with no manifest to appeal
100114 // to, this gate must never make it.
101- writeFileSync ( join ( dir , "docs" , "ARCHITECTURE.md" ) , "# Ours, not MetaObjects'.\n" ) ;
115+ writeFileSync ( join ( dir , DOCS_ROOT , "ARCHITECTURE.md" ) , "# Ours, not MetaObjects'.\n" ) ;
102116 // Inside `agent/` too: the gate convicts a STALE GENERATED page there, and it tells
103117 // the two apart by the `@generated` marker rather than by the directory alone.
104- writeFileSync ( join ( dir , "docs" , "agent" , "NOTES.md" ) , "# Also ours.\n" ) ;
118+ writeFileSync ( join ( dir , DOCS_ROOT , "agent" , "NOTES.md" ) , "# Also ours.\n" ) ;
105119 expect ( await run ( [ "verify" , "--cwd" , dir , "--docs" ] ) ) . toBe ( 0 ) ;
106120 } finally {
107121 rmSync ( dir , { recursive : true , force : true } ) ;
@@ -121,8 +135,8 @@ describe("meta verify --docs", () => {
121135 // Simulated by copying a generated page to a name no run emits: same shape, one
122136 // condition — a committed file carrying our marker that a fresh run does not
123137 // produce — without needing to break the project to reach it.
124- const stale = readFileSync ( join ( dir , "docs" , "agent" , "schema.md" ) , "utf8" ) ;
125- writeFileSync ( join ( dir , "docs" , "agent" , "schema.postgres.md" ) , stale ) ;
138+ const stale = readFileSync ( join ( dir , DOCS_ROOT , "agent" , "schema.md" ) , "utf8" ) ;
139+ writeFileSync ( join ( dir , DOCS_ROOT , "agent" , "schema.postgres.md" ) , stale ) ;
126140 expect ( await run ( [ "verify" , "--cwd" , dir , "--docs" ] ) ) . toBe ( 1 ) ;
127141 } finally {
128142 rmSync ( dir , { recursive : true , force : true } ) ;
@@ -137,7 +151,7 @@ describe("meta verify --docs", () => {
137151 // repository's `docs/` may hold a symlink to a build output absent on CI. `statSync`
138152 // follows it and throws ENOENT, which the caller reports as "regeneration failed" —
139153 // the gate going red, blaming the fresh run, for a dangling link it did not create.
140- symlinkSync ( join ( dir , "docs" , "nowhere-at-all" ) , join ( dir , "docs" , "dangling.md" ) ) ;
154+ symlinkSync ( join ( dir , DOCS_ROOT , "nowhere-at-all" ) , join ( dir , DOCS_ROOT , "dangling.md" ) ) ;
141155 expect ( await run ( [ "verify" , "--cwd" , dir , "--docs" ] ) ) . toBe ( 0 ) ;
142156 } finally {
143157 rmSync ( dir , { recursive : true , force : true } ) ;
@@ -202,10 +216,10 @@ async function runCapturingStderr(args: string[]): Promise<{ exit: number; out:
202216
203217describe ( "meta verify --docs — a git-ignored page is not drift" , ( ) => {
204218 test ( "the F27 reproduction: generate all, commit two, gate is clean" , async ( ) => {
205- const dir = gitProject ( "docs/*\n!docs/requirements.md\n!docs/requirements.toon\n" ) ;
219+ const dir = gitProject ( "docs/generated/ *\n!docs/generated/ requirements.md\n!docs/generated /requirements.toon\n" ) ;
206220 try {
207221 await generateDocs ( dir ) ;
208- git ( dir , "add" , "-f" , ".gitignore" , "docs/requirements.md" , "docs/requirements.toon" ) ;
222+ git ( dir , "add" , "-f" , ".gitignore" , "docs/generated/ requirements.md" , "docs/generated /requirements.toon" ) ;
209223 git ( dir , "commit" , "-qm" , "docs" ) ;
210224
211225 const { exit, out } = await runCapturingStderr ( [ "verify" , "--cwd" , dir , "--docs" ] ) ;
@@ -218,12 +232,12 @@ describe("meta verify --docs — a git-ignored page is not drift", () => {
218232
219233 test ( "...and a REAL edit to one of the two committed pages still convicts" , async ( ) => {
220234 // The other half. A rule that exempts everything is not a fix, it is a mute button.
221- const dir = gitProject ( "docs/*\n!docs/requirements.md\n!docs/requirements.toon\n" ) ;
235+ const dir = gitProject ( "docs/generated/ *\n!docs/generated/ requirements.md\n!docs/generated /requirements.toon\n" ) ;
222236 try {
223237 await generateDocs ( dir ) ;
224- git ( dir , "add" , "-f" , ".gitignore" , "docs/requirements.md" , "docs/requirements.toon" ) ;
238+ git ( dir , "add" , "-f" , ".gitignore" , "docs/generated/ requirements.md" , "docs/generated /requirements.toon" ) ;
225239 git ( dir , "commit" , "-qm" , "docs" ) ;
226- writeFileSync ( join ( dir , "docs" , "requirements.md" ) , "hand-edited\n" ) ;
240+ writeFileSync ( join ( dir , DOCS_ROOT , "requirements.md" ) , "hand-edited\n" ) ;
227241
228242 const { exit, out } = await runCapturingStderr ( [ "verify" , "--cwd" , dir , "--docs" ] ) ;
229243 expect ( exit ) . toBe ( 1 ) ;
@@ -238,12 +252,12 @@ describe("meta verify --docs — a git-ignored page is not drift", () => {
238252 test ( "a TRACKED page is compared even when a pattern would ignore it" , async ( ) => {
239253 // The property the whole design rests on: git never reports a tracked path as
240254 // ignored. So this rule can never be used to hide a page the project commits.
241- const dir = gitProject ( "docs/\n" ) ;
255+ const dir = gitProject ( "docs/generated/ \n" ) ;
242256 try {
243257 await generateDocs ( dir ) ;
244- git ( dir , "add" , "-f" , ".gitignore" , "docs/agent/schema.md" ) ;
258+ git ( dir , "add" , "-f" , ".gitignore" , "docs/generated/ agent/schema.md" ) ;
245259 git ( dir , "commit" , "-qm" , "docs" ) ;
246- writeFileSync ( join ( dir , "docs" , "agent" , "schema.md" ) , "hand-edited\n" ) ;
260+ writeFileSync ( join ( dir , DOCS_ROOT , "agent" , "schema.md" ) , "hand-edited\n" ) ;
247261
248262 const { exit, out } = await runCapturingStderr ( [ "verify" , "--cwd" , dir , "--docs" ] ) ;
249263 expect ( exit ) . toBe ( 1 ) ;
@@ -255,7 +269,7 @@ describe("meta verify --docs — a git-ignored page is not drift", () => {
255269
256270 test ( "ignoring EVERYTHING is refused, not reported clean" , async ( ) => {
257271 // A gate asked to check pages that could check none must not answer "no drift".
258- const dir = gitProject ( "docs/\n" ) ;
272+ const dir = gitProject ( "docs/generated/ \n" ) ;
259273 try {
260274 await generateDocs ( dir ) ;
261275 git ( dir , "add" , "-f" , ".gitignore" ) ;
@@ -277,7 +291,7 @@ describe("meta verify --docs — a git-ignored page is not drift", () => {
277291 await generateDocs ( dir ) ;
278292 git ( dir , "add" , "-f" , "docs" ) ;
279293 git ( dir , "commit" , "-qm" , "docs" ) ;
280- rmSync ( join ( dir , "docs" , "README.md" ) ) ;
294+ rmSync ( join ( dir , DOCS_ROOT , "README.md" ) ) ;
281295
282296 const { exit, out } = await runCapturingStderr ( [ "verify" , "--cwd" , dir , "--docs" ] ) ;
283297 expect ( exit ) . toBe ( 1 ) ;
@@ -300,14 +314,14 @@ describe("meta verify --docs — a git-ignored page is not drift", () => {
300314 // Untracked on purpose: git never reports a TRACKED path as ignored (the test
301315 // above), so the only way to reach this branch is the real-world shape — a leftover
302316 // generated page on a machine that has run `meta docs`, under an ignored path.
303- const dir = gitProject ( "docs/agent/stale-page.md\n" ) ;
317+ const dir = gitProject ( "docs/generated/ agent/stale-page.md\n" ) ;
304318 try {
305319 await generateDocs ( dir ) ;
306320 git ( dir , "add" , "-f" , ".gitignore" , "docs" ) ;
307321 git ( dir , "commit" , "-qm" , "docs" ) ;
308322 // Ours by both halves of `isOurs`: under `agent/`, carrying the generated marker.
309323 writeFileSync (
310- join ( dir , "docs" , "agent" , "stale-page.md" ) ,
324+ join ( dir , DOCS_ROOT , "agent" , "stale-page.md" ) ,
311325 "<!-- @generated by meta docs -->\n\nA page a fresh run no longer emits.\n" ,
312326 ) ;
313327
@@ -330,13 +344,13 @@ describe("meta verify --docs — a git-ignored page is not drift", () => {
330344 // Stated as a CONTRAST on one fixture, because that is the only form that proves
331345 // the exemption is what produced the clean run: the same project, the same missing
332346 // page, exempt when git can answer and convicted when it cannot.
333- const dir = gitProject ( "docs/*\n!docs/requirements.md\n!docs/requirements.toon\n" ) ;
347+ const dir = gitProject ( "docs/generated/ *\n!docs/generated/ requirements.md\n!docs/generated /requirements.toon\n" ) ;
334348 try {
335349 await generateDocs ( dir ) ;
336- git ( dir , "add" , "-f" , ".gitignore" , "docs/requirements.md" , "docs/requirements.toon" ) ;
350+ git ( dir , "add" , "-f" , ".gitignore" , "docs/generated/ requirements.md" , "docs/generated /requirements.toon" ) ;
337351 git ( dir , "commit" , "-qm" , "docs" ) ;
338352 // An ignored page that is NOT on disk — the fresh-clone shape.
339- rmSync ( join ( dir , "docs" , "README.md" ) ) ;
353+ rmSync ( join ( dir , DOCS_ROOT , "README.md" ) ) ;
340354
341355 const withGit = await runCapturingStderr ( [ "verify" , "--cwd" , dir , "--docs" ] ) ;
342356 expect ( withGit . exit ) . toBe ( 0 ) ;
@@ -361,18 +375,18 @@ describe("meta verify --docs — a git-ignored page is not drift", () => {
361375 // The exemption is computed over the fresh set BY NAME, on disk or not. Deciding
362376 // per-file-existence would have made `checked` a property of the machine: a dev box
363377 // that has run `meta docs` has all 589 pages present and a CI runner has two.
364- const body = "docs/*\n!docs/requirements.md\n!docs/requirements.toon\n" ;
378+ const body = "docs/generated/ *\n!docs/generated/ requirements.md\n!docs/generated /requirements.toon\n" ;
365379 const withPages = gitProject ( body ) ;
366380 const withoutPages = gitProject ( body ) ;
367381 try {
368382 for ( const dir of [ withPages , withoutPages ] ) {
369383 await generateDocs ( dir ) ;
370- git ( dir , "add" , "-f" , ".gitignore" , "docs/requirements.md" , "docs/requirements.toon" ) ;
384+ git ( dir , "add" , "-f" , ".gitignore" , "docs/generated/ requirements.md" , "docs/generated /requirements.toon" ) ;
371385 git ( dir , "commit" , "-qm" , "docs" ) ;
372386 }
373387 // One machine keeps every locally generated page; the other is a fresh clone.
374- rmSync ( join ( withoutPages , "docs" , "README.md" ) ) ;
375- rmSync ( join ( withoutPages , "docs" , "agent" ) , { recursive : true , force : true } ) ;
388+ rmSync ( join ( withoutPages , DOCS_ROOT , "README.md" ) ) ;
389+ rmSync ( join ( withoutPages , DOCS_ROOT , "agent" ) , { recursive : true , force : true } ) ;
376390
377391 const a = await runCapturingStderr ( [ "verify" , "--cwd" , withPages , "--docs" ] ) ;
378392 const b = await runCapturingStderr ( [ "verify" , "--cwd" , withoutPages , "--docs" ] ) ;
0 commit comments