From a76618e176307fbb2b6d7372c693d66cd7d419af Mon Sep 17 00:00:00 2001 From: whyour Date: Mon, 31 Aug 2026 01:32:28 +0800 Subject: [PATCH] test(ql3): authorize read-only cutover probe boundary --- scripts/ql3-cluster-dependency-audit.cjs | 8 ++++ test/back/ql3ClusterDependencyAudit.test.cjs | 41 ++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/scripts/ql3-cluster-dependency-audit.cjs b/scripts/ql3-cluster-dependency-audit.cjs index 9d8acad2..1b573f41 100644 --- a/scripts/ql3-cluster-dependency-audit.cjs +++ b/scripts/ql3-cluster-dependency-audit.cjs @@ -2818,6 +2818,14 @@ function auditSourceImports(root, packagePath, findings) { ) { continue; } + if ( + packagePath === 'packages/ql3-local-application' && + path.relative(packageDirectory, filePath) === + 'src/production-process/cutoverProbeProcess.ts' && + specifier === '@qinglong/local-sqlite/readiness-inspection' + ) { + continue; + } if ( packagePath === 'packages/ql3-local-application' && path.relative(packageDirectory, filePath) === diff --git a/test/back/ql3ClusterDependencyAudit.test.cjs b/test/back/ql3ClusterDependencyAudit.test.cjs index c24daac2..faa2b36c 100644 --- a/test/back/ql3ClusterDependencyAudit.test.cjs +++ b/test/back/ql3ClusterDependencyAudit.test.cjs @@ -3293,6 +3293,47 @@ test('local application Profile subpaths stay in exact composition owners', (t) ); }); +test('cutover probe receives only the read-only SQLite readiness inspector', (t) => { + const root = fs.mkdtempSync( + path.join(os.tmpdir(), 'ql3-local-cutover-probe-boundary-'), + ); + const processDirectory = path.join( + root, + 'packages/ql3-local-application/src/production-process', + ); + fs.mkdirSync(processDirectory, { recursive: true }); + fs.writeFileSync( + path.join(processDirectory, 'cutoverProbeProcess.ts'), + [ + "import { inspect } from '@qinglong/local-sqlite/readiness-inspection';", + "import { mutate } from '@qinglong/local-sqlite/runtime';", + ].join('\n'), + ); + fs.writeFileSync( + path.join(processDirectory, 'neighbor.ts'), + "import { inspect } from '@qinglong/local-sqlite/readiness-inspection';", + ); + t.after(() => fs.rmSync(root, { recursive: true, force: true })); + + const findings = []; + auditSourceImports(root, 'packages/ql3-local-application', findings); + assert.deepEqual( + findings.map(({ code, file, specifier }) => ({ code, file, specifier })), + [ + { + code: 'FORBIDDEN_PACKAGE_SOURCE_IMPORT', + file: 'packages/ql3-local-application/src/production-process/cutoverProbeProcess.ts', + specifier: '@qinglong/local-sqlite/runtime', + }, + { + code: 'FORBIDDEN_PACKAGE_SOURCE_IMPORT', + file: 'packages/ql3-local-application/src/production-process/neighbor.ts', + specifier: '@qinglong/local-sqlite/readiness-inspection', + }, + ], + ); +}); + test('local process package remains SQLite, ORM and profile neutral', (t) => { const root = fixture( t,