Defines the optional native graph-acceleration provider (cor 3.0) that
brainy feature-detects and routes brain.graph.* / related({node}) /
find({connected}) to, falling back to pure-TS adjacency when absent. This is
the published seam cor wires its native build against (mirrors the existing
VersionedIndexProvider pattern: defined in plugin.ts, exported from index.ts,
implemented externally, feature-detected at runtime).
Contract (locked cross-team in the design thread):
- GraphAccelerationProvider: traverse, edgesForNode, graphCursorOpen/Next/Close,
pageRank, connectedComponents, shortestPath, neighborhoodSample, topByDegree.
Every read op is generation-aware (optional trailing generation?: bigint) so
db.asOf(g).graph.* resolves historically; omitted = now.
- Subgraph: columnar wire format (BigInt64Array node/edge columns, Uint16Array
edgeTypes, optional Uint8Array nodeDepth, truncated flag) — parallel typed
arrays, never array-of-objects; brainy maps u64<->UUID lazily for rendered rows.
- OpaqueIdSet: a find() universe forwarded opaquely into traverse/search for the
zero-crossing query->expand fusion (brainy never inspects it; the provider
version-tags + validates the envelope).
- VectorIndexProvider.search gains allowedIds?: OpaqueIdSet | ReadonlySet<string>
(predicate pushdown — recovers filtered recall lost to post-filtering).
- EntityIdMapperProvider gains entityIntsToUuids(BigInt64Array) — the bigint batch
reverse resolver for Subgraph.nodes; implemented on the JS mapper (TS fallback).
All new public types exported from index.ts. Test: entityIntsToUuids round-trip
+ order-preservation + empty-int sentinel.
- id-normalization (#18): `brain.newId()` (UUID v7) + v7 default ids; non-UUID string ids are
transparently normalized to a stable UUID v5 on creation AND every lookup — get/update/remove,
relate(from,to), related, find({connected}), getMany, removeMany, the transact op-handler, and
db.with() overlays — with the caller's original key preserved under `_originalId`. The engine only
ever sees a UUID; real UUIDs pass through untouched. universal/uuid.ts gains v5/v7/isUUID +
BRAINY_ID_NAMESPACE; new utils/idNormalization.ts (coerceNewEntityId / resolveEntityId).
- aggregation min/max delete-safety: `queryAggregate` no longer leaves a stale min/max after
deleting the current extreme — min/max now track a value multiset and recompute in-memory (no
entity scan; that scan was the prior delete-then-hang a consumer reported). Other metrics were
already exact across deletes. Regression test proves resolve-after-delete + correct new min/max.
- release.sh RC-safe: explicit version arg, prerelease detection (npm `--tag rc` + GitHub
`--prerelease`), full `test:ci` gate (unit + integration), current-branch push, npm-access
verification after publish.
- native-engine references point at `@soulcraft/cor` (8.0's partner) in user-facing strings/docs.
Unit 1461/0 · integration 599/0 · tsc clean.
The JS fallback EntityIdMapper caps at u32::MAX to match the metadata
index's Roaring32 bitmap width. Before this guard, a brain past 4.29 B
entities would silently widen `nextId` into JS's safe-integer range,
truncating ints inside the bitmaps and zeroing query results — the
same silent under-count cortex 3.0's Piece 10 just closed on the
native path. Brainy 8.0 surfaces the overflow loudly instead.
When `nextId` would exceed `U32_ENTITY_ID_MAX`, `getOrAssign` throws
`EntityIdSpaceExceeded` with a message pointing at the cortex 3.0
binary mapper's `idSpace: 'u64'` mode as the migration path (mmap-
backed extendible-hash KV, persists the full u64 range losslessly).
The existing-UUID lookup path bypasses the guard — only fresh
allocations can overflow.
Surfaces via `@soulcraft/brainy/internals`:
- `EntityIdMapper` (already exported, behavior gated)
- `EntityIdSpaceExceeded` (new)
- `U32_ENTITY_ID_MAX` (new constant, = 0xFFFF_FFFF)
This is the lockstep half of cortex 3.0 / Piece 10 / Step 15. Cortex's
`NativeBinaryEntityIdMapperWrapper` ships the U64 binary mapper that
takes over above this ceiling; brainy ships the bright-line failure
that points consumers at it.
New test: tests/unit/utils/entity-id-mapper-u32-ceiling.test.ts (6
assertions covering the constant, the error shape, normal
allocations, the boundary case at exactly u32::MAX, the overflow
throw, and the existing-uuid lookup bypass).