brainy/tests/unit/boundary-no-native.test.ts
David Snelling a52dba2168 refactor(8.0): API-surface + quality polish from the readiness audit
- find() search-mode: collapsed the two overlapping options to one canonical
  `searchMode: SearchMode` (the redundant `mode` alias was silently ignored on
  the primary find() path while honored on the historical path — a footgun) and
  removed the unwired `explain?` FindParams field (never read by find()).
- Documentation accuracy on the public type surface: entity ids documented as
  UUID v7 (auto) / v5 (natural key), not v4; dropped the stale "Brainy 3.0"
  banners and "backward compatibility" hedging on the fresh-8.0 Result type;
  documented the via/type alias; removed the dead GraphConstraints.bidirectional;
  fixed the no-op `EmbeddedGraphVerb = Omit<GraphVerb,'source'>` to omit the real
  sourceId; corrected the GraphIndexProvider.isInitialized JSDoc; documented
  removeMany's per-chunk generation granularity; JSDoc'd the public VFS surface.
- Honest perf comments in source: removed unmeasured billion-scale figures from
  the LSMTree / graphAdjacencyIndex headers (the JS fallback is in-memory after
  open; native is the scale path).
- Robustness: getVerbMetadata propagates read errors symmetrically with
  getNounMetadata; the find() egress integrity-guard keeps a row when the JS
  matcher doesn't implement an operator the provider already matched on; hardened
  the boundary-no-native CI guard to catch side-effect imports + re-exports.
- Tests: de-theatricalized a relateMany test to assert the real contract; fixed
  a stale Model-B header.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 10:04:19 -07:00

99 lines
4.9 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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*|export\s[^'"]*from\s*|import\s*\(\s*|require\s*\(\s*|import\s*)['"]@soulcraft\/cor(?:tex)?(?:\/[^'"]*)?['"]/
describe('open/proprietary boundary — public repo must not depend on @soulcraft/cor', () => {
it('the detector catches every static-dependency form (incl. side-effect imports + re-exports)', () => {
// Each of these creates a hard dependency on the proprietary package and MUST
// be caught (the prior regex missed the bare side-effect import and re-export forms).
for (const form of [
`import cor from '@soulcraft/cor'`,
`import { x } from '@soulcraft/cor'`,
`import '@soulcraft/cor'`,
`import '@soulcraft/cor/native'`,
`export { x } from '@soulcraft/cor'`,
`export * from '@soulcraft/cor'`,
`const x = require('@soulcraft/cor')`,
`const x = await import('@soulcraft/cor')`,
`import x from '@soulcraft/cortex'`
]) {
expect(NATIVE_MODULE.test(form), `should detect: ${form}`).toBe(true)
}
// A different package whose name merely starts with the same prefix is NOT a match.
for (const ok of [`import x from '@soulcraft/core'`, `// see @soulcraft/cor docs`]) {
expect(NATIVE_MODULE.test(ok), `should NOT match: ${ok}`).toBe(false)
}
})
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([])
})
})