feat: visibility tier (public/internal/system) on nouns + verbs
Adds a reserved, top-level `visibility` field (mirrors the subtype rollout): 'public' (default, surfaced) | 'internal' (a consumer's app-internal data — hidden from default find()/getRelations()/counts/stats, opt-in via includeInternal) | 'system' (Brainy plumbing, library-set only; the add()/relate() param narrows to 'public' | 'internal'). Fixes a real leak: the VFS root entity counted in getNounCount() and appeared in find() (a fresh brain reported 1 entity). It is now visibility:'system' → excluded from every user-facing surface (fresh brain reports 0). - Reserved (STANDARD_ENTITY_FIELDS / STANDARD_VERB_FIELDS) — surfaced top-level on reads, never in the custom metadata bag; a 'public'/'internal' value smuggled through metadata is lifted to the field, 'system' dropped with a one-shot warning. - Threaded through add/relate/update/updateRelation + their internal mirrors; stored only when not 'public' so the common case stays lean. - Default exclusion in counts (baseStorage, isCountedVisibility), find()/getRelations() (hard candidate filter via excludeVisibility — keeps top-K/limit/offset correct), and rebuildCounts; includeInternal/includeSystem opt-ins. - VFS root marked 'system'. Same on-disk shape as the 8.0 line, so it carries forward unchanged. Backward-compatible: absent === 'public', so all existing data stays counted + returned. Tests: tests/unit/brainy/visibility.test.ts 17/17 (fresh-brain getNounCount()===0, internal hidden + opt-in, verb symmetry, top-level surfacing, metadata-spoof rejection). 1522 unit green; count-synchronization integration green.
This commit is contained in:
parent
c53dd61f96
commit
3a62445465
8 changed files with 778 additions and 36 deletions
|
|
@ -75,6 +75,11 @@ export async function rebuildCounts(storage: BaseStorage): Promise<RebuildCounts
|
|||
for (const noun of result.items) {
|
||||
const metadata = await storage.getNounMetadata(noun.id)
|
||||
if (metadata?.noun) {
|
||||
// 8.0 visibility: the user-facing counts only include public entities.
|
||||
// Internal/system entities (e.g. the VFS root) are excluded — keeping this
|
||||
// rebuild consistent with the incremental gating in baseStorage.
|
||||
const visibility = metadata.visibility
|
||||
if (visibility === 'internal' || visibility === 'system') continue
|
||||
const entityType = metadata.noun
|
||||
entityCounts.set(entityType, (entityCounts.get(entityType) || 0) + 1)
|
||||
totalNouns++
|
||||
|
|
@ -105,6 +110,8 @@ export async function rebuildCounts(storage: BaseStorage): Promise<RebuildCounts
|
|||
|
||||
for (const verb of result.items) {
|
||||
if (verb.verb) {
|
||||
// 8.0 visibility: exclude internal/system edges from the user-facing counts.
|
||||
if (verb.visibility === 'internal' || verb.visibility === 'system') continue
|
||||
const verbType = verb.verb
|
||||
verbCounts.set(verbType, (verbCounts.get(verbType) || 0) + 1)
|
||||
totalVerbs++
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue