feat(namespace): conformance green 19/19 — data-aware did-you-mean on unindexed bare addresses, ordering contract on the column top-K path (never drop, nulls last, ties by id), shape-complete addressed reads (entity views AND raw storage shapes, shadow-proof both scopes), per-key source matching for dotted addresses; refusal classes unified under UnresolvableFieldError
Some checks failed
CI / Node 22 (push) Has been cancelled
CI / Node 24 (push) Has been cancelled
CI / Bun (latest) (push) Has been cancelled

This commit is contained in:
David Snelling 2026-08-03 16:01:02 -07:00
parent 7492b6cb59
commit 8e962dabda
4 changed files with 134 additions and 61 deletions

View file

@ -167,10 +167,39 @@ export function readEntityFieldAddress(
entity: HNSWNounWithMetadata,
address: FieldAddress
): unknown {
const rec = entity as unknown as Record<string, unknown>
const bag =
rec.metadata && typeof rec.metadata === 'object'
? (rec.metadata as Record<string, unknown>)
: null
if (address.scope === 'system') {
return (entity as unknown as Record<string, unknown>)[address.field]
// Entity views carry system scalars top-level; raw storage shapes carry
// them inside the stored metadata record (where `type` is spelled `noun`).
// Read top-level first, then the record — never the user's namespace.
const top = rec[address.field]
if (top !== undefined) return top
if (bag) {
if (address.field === 'type') return bag.type ?? bag.noun
return bag[address.field]
}
return undefined
}
return entity.metadata?.[address.field]
// User scope. The write-path remap guarantees the user can never OWN a
// field named like a system scalar (those lift top-level at write), so a
// bare system name reads as ABSENT — reading the stored record's reserved
// key here would re-create the shadow this module exists to kill. Same for
// plumbing and the legacy 'noun' spelling.
if (
SYSTEM_ENTITY_SCALARS.has(address.field) ||
PLUMBING_FIELDS.has(address.field) ||
address.field === 'noun'
) {
return undefined
}
if (bag) return bag[address.field]
return rec[address.field]
}
/**
@ -222,29 +251,6 @@ export function buildUnresolvableMessage(
)
}
/**
* @description Refusal for a malformed or out-of-map field ADDRESS
* `system.<anything-not-in-the-map>` (including all plumbing), an empty
* name, or a bare `metadata.` prefix. The message carries the full valid
* system map so the fix never needs a docs lookup.
*/
export class InvalidFieldAddressError extends Error {
public readonly raw: string
public readonly kind: FieldAddressKind
constructor(raw: string, kind: FieldAddressKind, systemMap: ReadonlySet<string>) {
const valid = [...systemMap].map((f) => `system.${f}`).join(', ')
super(
`'${raw}' is not an addressable ${kind} field. Bare names address your own ` +
`metadata fields; engine fields are exactly: ${valid}. Engine plumbing ` +
`(vector, connections, level, data, _rev) is not part of the query surface.`
)
this.name = 'InvalidFieldAddressError'
this.raw = raw
this.kind = kind
}
}
/**
* @description Refusal for a syntactically valid address that resolves to
* NOTHING a bare name no user field carries. Carries the did-you-mean
@ -256,14 +262,35 @@ export class UnresolvableFieldError extends Error {
public readonly raw: string
public readonly kind: FieldAddressKind
constructor(raw: string, kind: FieldAddressKind) {
super(buildUnresolvableMessage(raw, kind))
constructor(raw: string, kind: FieldAddressKind, messageOverride?: string) {
super(messageOverride ?? buildUnresolvableMessage(raw, kind))
this.name = 'UnresolvableFieldError'
this.raw = raw
this.kind = kind
}
}
/**
* @description Refusal for a malformed or out-of-map field ADDRESS
* `system.<anything-not-in-the-map>` (including all plumbing), an empty
* name, or a bare `metadata.` prefix. The message carries the full valid
* system map so the fix never needs a docs lookup.
*/
export class InvalidFieldAddressError extends UnresolvableFieldError {
constructor(raw: string, kind: FieldAddressKind, systemMap: ReadonlySet<string>) {
const valid = [...systemMap].map((f) => `system.${f}`).join(', ')
super(
raw,
kind,
`'${raw}' is not an addressable ${kind} field. Bare names address your own ` +
`metadata fields; engine fields are exactly: ${valid}. Engine plumbing ` +
`(vector, connections, level, data, _rev) is not part of the query surface.`
)
this.name = 'InvalidFieldAddressError'
}
}
/**
* @description Refusal for a find() option that is accepted by the type
* surface but NOT implemented an accepted option must work or refuse;