feat(8.0): reserved-field enforcement — reservedFieldPolicy defaults to throw
An untyped (JS) caller that smuggles a Brainy-reserved field (confidence, weight, subtype, visibility, service, createdBy, noun/verb, data, createdAt, updatedAt, _rev) inside a write-path metadata bag previously got a silent remap-or-drop — a class of bug where confidence-evolution writes no-oped for weeks before being caught on read-back. 8.0 closes this with no silent failures. - New BrainyConfig.reservedFieldPolicy: 'throw' | 'warn' | 'remap' (default 'throw'). 'throw' rejects the write naming every offending key + its correct write path; 'warn' remaps with a one-shot per-key warning; 'remap' is the legacy silent path. - Central enforceReservedPolicy gate wired into all four remap methods (add, update, relate, updateRelation) so live calls AND their transact()/with() mirrors honor it. Single-source reservedWritePath guidance shared by throw+warn. - 'warn' now warns for EVERY reserved key (closes the gap where only system-managed fields warned). Dead warnDropped* helpers removed. - Import pipeline migrated to route reserved values (confidence/weight/subtype) through dedicated params and strip reserved keys from extractor/customMetadata bags via the canonical split*MetadataRecord helpers — imports no longer trip the default throw. - Tests: new reservedFieldPolicy matrix (throw/warn/remap across every write path + transact); remap-correctness suite reframed as opt-in 'remap'; shared test-factory no longer emits reserved keys in custom metadata.
This commit is contained in:
parent
ae3fe82fd9
commit
54c7c39669
12 changed files with 605 additions and 190 deletions
|
|
@ -10,13 +10,19 @@
|
|||
* consumer's confidence-evolution writes no-oped for weeks before being
|
||||
* caught by reading values back.
|
||||
*
|
||||
* 8.0 contract under test (every write path, entities AND relationships):
|
||||
* These tests pin the LEGACY REMAP behavior, which in 8.0 is opt-in via
|
||||
* `reservedFieldPolicy: 'remap'` (the default is `'throw'` — see the policy
|
||||
* matrix in tests/unit/brainy/reserved-field-policy.test.ts). The brain in
|
||||
* every test below is constructed with `reservedFieldPolicy: 'remap'` so these
|
||||
* deep correctness assertions about the remap path stay exercised.
|
||||
*
|
||||
* Remap contract under test (every write path, entities AND relationships):
|
||||
* - user-mutable reserved fields (`confidence`, `weight`, `subtype` — plus
|
||||
* `service`/`createdBy` at add()/relate() time) remap from the metadata
|
||||
* bag to their dedicated top-level param, with top-level winning when both
|
||||
* are present;
|
||||
* - system-managed reserved fields (`createdAt`, `_rev`, `noun`/`verb`,
|
||||
* `data`, …) are dropped from the bag (one-shot warning);
|
||||
* `data`, …) are dropped from the bag;
|
||||
* - the same normalization applies to `transact()` operations and `with()`
|
||||
* speculative views;
|
||||
* - reads NEVER echo a reserved field inside `metadata`.
|
||||
|
|
@ -32,11 +38,12 @@ import { Brainy } from '../../../src/index.js'
|
|||
import { NounType, VerbType } from '../../../src/types/graphTypes.js'
|
||||
import { createTestConfig } from '../../helpers/test-factory.js'
|
||||
|
||||
describe('reserved-field metadata remap (8.0 contract)', () => {
|
||||
describe('reserved-field metadata remap (8.0 legacy remap path)', () => {
|
||||
let brain: Brainy
|
||||
|
||||
beforeEach(async () => {
|
||||
brain = new Brainy(createTestConfig())
|
||||
// The remap path is opt-in in 8.0 (default policy is 'throw').
|
||||
brain = new Brainy(createTestConfig({ reservedFieldPolicy: 'remap' }))
|
||||
await brain.init()
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue