From b198281ce1383c4957a536c986c5d4dc88771d3c Mon Sep 17 00:00:00 2001 From: David Snelling Date: Fri, 19 Jun 2026 09:03:54 -0700 Subject: [PATCH] =?UTF-8?q?test(8.0):=20boundary=20guard=20forbids=20@soul?= =?UTF-8?q?craft/cor=20too=20(cortex=E2=86=92cor=20rename)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The open/closed separation test now forbids the proprietary native package under BOTH names (@soulcraft/cor + legacy @soulcraft/cortex) — in any dependency field and any static import under src/ or tests/. Renamed boundary-no-cortex → boundary-no-native. This is load-bearing for the lockstep model: because brainy cannot depend on cor, the combined brainy-8.0 × cor-3.0 integration matrix lives in the cor repo (which devDeps brainy), not here. --- tests/unit/boundary-no-cortex.test.ts | 56 ------------------- tests/unit/boundary-no-native.test.ts | 77 +++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 56 deletions(-) delete mode 100644 tests/unit/boundary-no-cortex.test.ts create mode 100644 tests/unit/boundary-no-native.test.ts diff --git a/tests/unit/boundary-no-cortex.test.ts b/tests/unit/boundary-no-cortex.test.ts deleted file mode 100644 index 4785d4ab..00000000 --- a/tests/unit/boundary-no-cortex.test.ts +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @module tests/unit/boundary-no-cortex - * @description Enforces the open-source / proprietary boundary in CI: the public - * MIT Brainy repo must never DEPEND ON the proprietary `@soulcraft/cortex` - * package to build or test. Cortex is the one product Brainy may NAME (docs say - * `npm install @soulcraft/cortex`, error messages point at its `idSpace:'u64'` - * mode), and registering it through the public plugin API is the supported path — - * but nothing in `src/` or `tests/` may statically `import`/`require` it, and it - * must not appear in any dependency field. This guards against someone turning an - * optional integration into a hard coupling that silently makes green CI depend - * on a private build. See the perf-comparison boundary decision (handoff AJ/AK). - */ -import { describe, it, expect } from 'vitest' -import * as fs from 'node:fs' -import * as path from 'node:path' -import { fileURLToPath } from 'node:url' - -const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..') -const SELF = fileURLToPath(import.meta.url) - -/** Recursively collect .ts/.js/.mjs/.cjs files under a directory. */ -function sourceFiles(dir: string): string[] { - const out: string[] = [] - for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { - if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name.startsWith('.')) continue - const full = path.join(dir, entry.name) - if (entry.isDirectory()) out.push(...sourceFiles(full)) - else if (/\.(ts|js|mjs|cjs)$/.test(entry.name) && full !== SELF) out.push(full) - } - return out -} - -// Matches a real module specifier for cortex in an import/require/dynamic-import — -// NOT a bare string mention (docs/JSDoc/error-message/mock-name are allowed). -const CORTEX_MODULE = /(?:import\s[^'"]*from\s*|import\s*\(\s*|require\s*\(\s*)['"]@soulcraft\/cortex(?:\/[^'"]*)?['"]/ - -describe('open/proprietary boundary — public repo must not depend on @soulcraft/cortex', () => { - it('no src/ or tests/ file imports or requires @soulcraft/cortex', () => { - const offenders: string[] = [] - for (const dir of ['src', 'tests']) { - for (const file of sourceFiles(path.join(repoRoot, dir))) { - if (CORTEX_MODULE.test(fs.readFileSync(file, 'utf8'))) { - offenders.push(path.relative(repoRoot, file)) - } - } - } - expect(offenders, `These files statically depend on the proprietary package — use the public plugin API at runtime instead:\n${offenders.join('\n')}`).toEqual([]) - }) - - it('@soulcraft/cortex is in no dependency field of package.json', () => { - const pkg = JSON.parse(fs.readFileSync(path.join(repoRoot, 'package.json'), 'utf8')) - const fields = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'] as const - const present = fields.filter((f) => pkg[f] && Object.prototype.hasOwnProperty.call(pkg[f], '@soulcraft/cortex')) - expect(present, `@soulcraft/cortex must not be a dependency (public CI must pass with it absent); found in: ${present.join(', ')}`).toEqual([]) - }) -}) diff --git a/tests/unit/boundary-no-native.test.ts b/tests/unit/boundary-no-native.test.ts new file mode 100644 index 00000000..20acc6e0 --- /dev/null +++ b/tests/unit/boundary-no-native.test.ts @@ -0,0 +1,77 @@ +/** + * @module tests/unit/boundary-no-native + * @description Enforces the open-source / proprietary boundary in CI: the public + * MIT Brainy repo must never DEPEND ON the proprietary native-acceleration + * package to build or test. That package is **`@soulcraft/cor`** (formerly + * `@soulcraft/cortex` — both names are guarded here through the rename + * transition). Brainy may NAME it (docs say `npm install @soulcraft/cor`, error + * messages point at its `idSpace:'u64'` mode) and registering it through the + * public plugin API is the supported runtime path — but nothing in `src/` or + * `tests/` may statically `import`/`require` it, and it must not appear in any + * dependency field. + * + * This is load-bearing for the lockstep release model: because brainy cannot + * depend on `@soulcraft/cor`, the combined brainy-8.0 × cor-3.0 integration + * matrix (the "every code path proven with both engines" proof) lives in the + * **cor** repo, which devDeps brainy — NOT here. See handoff LOCKSTEP-VERIFY. + * If this test ever needs `@soulcraft/cor` to go green, the boundary has been + * violated and an optional integration became a hard coupling on a private build. + */ +import { describe, it, expect } from 'vitest' +import * as fs from 'node:fs' +import * as path from 'node:path' +import { fileURLToPath } from 'node:url' + +const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..') +const SELF = fileURLToPath(import.meta.url) + +/** The proprietary native package, across the cortex→cor rename. */ +const NATIVE_PACKAGES = ['@soulcraft/cor', '@soulcraft/cortex'] as const + +/** Recursively collect .ts/.js/.mjs/.cjs files under a directory. */ +function sourceFiles(dir: string): string[] { + const out: string[] = [] + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name.startsWith('.')) continue + const full = path.join(dir, entry.name) + if (entry.isDirectory()) out.push(...sourceFiles(full)) + else if (/\.(ts|js|mjs|cjs)$/.test(entry.name) && full !== SELF) out.push(full) + } + return out +} + +// Matches a real module specifier for the native package in an +// import/require/dynamic-import — NOT a bare string mention (docs / JSDoc / +// error-message / mock-name are allowed). `@soulcraft/cor` and +// `@soulcraft/cortex` both match; `@soulcraft/core` (a different name) does not, +// because the package must be followed by a subpath separator or the closing quote. +const NATIVE_MODULE = + /(?:import\s[^'"]*from\s*|import\s*\(\s*|require\s*\(\s*)['"]@soulcraft\/cor(?:tex)?(?:\/[^'"]*)?['"]/ + +describe('open/proprietary boundary — public repo must not depend on @soulcraft/cor', () => { + it('no src/ or tests/ file imports or requires the native package', () => { + const offenders: string[] = [] + for (const dir of ['src', 'tests']) { + for (const file of sourceFiles(path.join(repoRoot, dir))) { + if (NATIVE_MODULE.test(fs.readFileSync(file, 'utf8'))) { + offenders.push(path.relative(repoRoot, file)) + } + } + } + expect(offenders, `These files statically depend on the proprietary package — use the public plugin API at runtime instead:\n${offenders.join('\n')}`).toEqual([]) + }) + + it('the native package is in no dependency field of package.json', () => { + const pkg = JSON.parse(fs.readFileSync(path.join(repoRoot, 'package.json'), 'utf8')) + const fields = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'] as const + const present: string[] = [] + for (const field of fields) { + for (const native of NATIVE_PACKAGES) { + if (pkg[field] && Object.prototype.hasOwnProperty.call(pkg[field], native)) { + present.push(`${field}:${native}`) + } + } + } + expect(present, `The proprietary native package must not be a dependency (public CI must pass with it absent); found in: ${present.join(', ')}`).toEqual([]) + }) +})