@@ -380,6 +380,16 @@ let CHECK_ONLY = false
380380const staleArtifacts: string[] = []
381381const emittedByPath = new Map<string, string>()
382382
383+ /**
384+ * Deletion candidates recorded by cleanup in check mode. Judged at the end of
385+ * the run, not at cleanup time: generate mode deletes a non-canonical page and
386+ * lets the trigger pass recreate it in the same run, so a candidate that was
387+ * re-emitted this run is that delete-then-recreate dance — content drift (if
388+ * any) is already covered by the overlay comparison — while a candidate nothing
389+ * re-emitted is a genuinely stale page regeneration would remove.
390+ */
391+ const wouldDeletePaths: string[] = []
392+
383393/** Writes a generated artifact, or in check mode records its final content for the end-of-run comparison. */
384394function emitGeneratedFile(filePath: string, content: string): void {
385395 if (CHECK_ONLY) {
@@ -3355,9 +3365,7 @@ function cleanupStaleToolDocs(validToolDocs: Set<string>): void {
33553365 }
33563366
33573367 if (CHECK_ONLY) {
3358- staleArtifacts.push(
3359- `${path.relative(rootDir, docPath)} (stale page — regeneration would delete it)`
3360- )
3368+ wouldDeletePaths.push(docPath)
33613369 continue
33623370 }
33633371
@@ -3997,7 +4005,13 @@ if (import.meta.main) {
39974005 process.exit(1)
39984006 }
39994007 if (CHECK_ONLY) {
4000- const stale = [...collectStaleEmissions(), ...staleArtifacts]
4008+ const genuinelyDeleted = wouldDeletePaths
4009+ .filter((docPath) => !emittedByPath.has(docPath))
4010+ .map(
4011+ (docPath) =>
4012+ `${path.relative(rootDir, docPath)} (stale page — regeneration would delete it)`
4013+ )
4014+ const stale = [...collectStaleEmissions(), ...staleArtifacts, ...genuinelyDeleted]
40014015 if (stale.length > 0) {
40024016 console.error(
40034017 `Generated integration docs are stale:\n- ${stale.join('\n- ')}\n` +
0 commit comments