feat(namespace): aggregation reads under the law + epoch 3 (the key-split rebuild) + THE ARMING COMMIT — the capability constant, the law module, and the typed refusals export from the package root; both engines' conformance suites light on this signal
Some checks are pending
CI / Node 22 (push) Waiting to run
CI / Node 24 (push) Waiting to run
CI / Bun (latest) (push) Waiting to run

This commit is contained in:
David Snelling 2026-08-03 15:53:13 -07:00
parent c2fb28a2f7
commit 7492b6cb59
7 changed files with 73 additions and 22 deletions

View file

@ -5619,7 +5619,7 @@ export class Brainy<T = any> implements BrainyInterface<T> {
this._aggregationIndex!.defineAggregate({
name: aggregateName,
source: {},
groupBy: perType ? [name, 'noun'] : [name],
groupBy: perType ? [name, 'system.type'] : [name],
metrics: { count: { op: 'count' } }
})
}
@ -5630,7 +5630,12 @@ export class Brainy<T = any> implements BrainyInterface<T> {
* and `counts.byField()` agree on the convention.
*/
private fieldCountsAggregateName(name: string): string {
return `__fieldCounts__${name}`
// v2 suffix: the per-type dimension moved from the legacy 'noun' alias to
// 'system.type' under the addressing law — a NEW name makes the ensure
// block re-define and BACKFILL from canonical instead of silently serving
// the old-dim definition (whose 'noun' key now reads user metadata and
// would drift). The v1 rows are derived state, superseded not lost.
return `__fieldCounts_v2__${name}`
}
/**
@ -11852,7 +11857,7 @@ export class Brainy<T = any> implements BrainyInterface<T> {
// don't have the tracked field at all (e.g. the VFS root) bucket under
// '__null__' and would otherwise pollute the count map.
if (value === undefined || value === null || value === '__null__') continue
if (options?.type !== undefined && row.groupKey?.['noun'] !== options.type) continue
if (options?.type !== undefined && row.groupKey?.['system.type'] !== options.type) continue
const key = String(value)
result[key] = (result[key] || 0) + (typeof row.metrics?.count === 'number' ? row.metrics.count : row.count)
}