feat: guarded plugin auto-detection — installing @soulcraft/cor is the opt-in

With plugins unset (the default), init() probes for the first-party
accelerator: not installed means plain brainy with zero noise; installed and
healthy means it loads and announces itself; installed but broken (import
failure, invalid shape, failed activation, version mismatch) makes init()
THROW. An installed accelerator never silently vanishes behind the JS engines
- the anti-drift posture of the explicit list, applied to detection.

plugins: []/false stays a true opt-out (no probe); an explicit list keeps its
required-and-loud semantics. The import runs through an importPluginPackage
seam (variable specifier - bundlers cannot static-resolve the optional
package; tests simulate all outcomes without it installed).

Also: when a plugin activates but registers zero native providers (e.g. a
licensing gate declining to engage), the provider summary now warns loudly
instead of leaving every query silently on the JS engines.

Supersedes 8.0.8's explicit-opt-in wording; README/PLUGINS/types now document
the guarded contract. 7 new tests (tests/unit/plugin-autodetect.test.ts).
This commit is contained in:
David Snelling 2026-07-02 16:19:55 -07:00
parent b37359e097
commit 588267be7f
6 changed files with 265 additions and 26 deletions

View file

@ -23,20 +23,19 @@ Brainy's plugin system uses **named providers** — string keys mapped to implem
3. The plugin calls `context.registerProvider(key, implementation)` for each subsystem it provides
4. Brainy checks each provider key and wires the implementation into its internal pipeline
Plugins are **opt-in** — brainy never auto-imports packages. You must explicitly list plugins in the config:
Installing the first-party accelerator is the opt-in: with the default config, brainy probes for `@soulcraft/cor` and loads it when present. Everything except "not installed" fails **loud** — a present-but-broken accelerator makes `init()` throw rather than silently degrading to the JS engines.
```typescript
const brain = new Brainy({
plugins: ['@soulcraft/cor'] // explicitly load the native acceleration package
})
const brain = new Brainy() // @soulcraft/cor auto-detected when installed
const pinned = new Brainy({ plugins: ['@soulcraft/cor'] }) // or pin exactly what loads
const plain = new Brainy({ plugins: [] }) // or opt out of detection entirely
```
| `plugins` value | Behavior |
|---|---|
| `undefined` (default) | No plugins loaded |
| `false` | No plugins loaded |
| `[]` | No plugins loaded |
| `['@soulcraft/cor']` | Load only the listed packages |
| `undefined` (default) | Guarded auto-detection of `@soulcraft/cor`: not installed → no plugins, silently; installed → loads + announces; installed-but-broken → `init()` throws |
| `false` / `[]` | No plugins, no detection (explicit opt-out) |
| `['@soulcraft/cor']` | Load only the listed packages; a listed plugin that fails to load throws |
Plugins registered programmatically via `brain.use(plugin)` are always activated regardless of the `plugins` config.