feat(8.0): brain.fillSubtypes migration helper + pre-RC1 gap closure
- brain.fillSubtypes(rules): idempotent subtype back-fill for pre-8.0 data.
One rule per NounType/VerbType (literal default or per-entry function);
fills only entries still missing a subtype through the public update()/
updateRelation() paths; returns { scanned, filled, skipped, errors, byType }.
Full unit suite in tests/unit/brainy/fill-subtypes.test.ts.
- Fix getNouns/getVerbs pagination hasMore (peek one past the window) —
was permanently false, silently truncating every multi-page walk.
- find({ near }) without near.id now throws a teaching error instead of an
opaque storage sharding failure; CLI --threshold without --near applies a
plain score floor.
- CLI init/close audit: every one-shot command init()s, close()s, and exits
explicitly; delete the unmaintained interactive REPL; replace the cloud-era
storage subcommands with status/batch-delete; new types/validate commands.
- requireSubtype JSDoc now documents the 8.0 default-on contract; audit()
recommendation points at fillSubtypes.
- Docs: data-storage-architecture rewritten to the real 8.0 on-disk layout;
README storage section reflects filesystem+memory and snapshots; eli5 and
SEMANTIC_VFS /as-of/ semantics corrected; internal tracker IDs and
.strategy references scrubbed from published files.
This commit is contained in:
parent
9b0f4acd5b
commit
c44678390e
30 changed files with 1517 additions and 3226 deletions
|
|
@ -132,6 +132,7 @@ export const coreCommands = {
|
|||
|
||||
const spinner = ora('Adding to neural database...').start()
|
||||
const brain = getBrainy()
|
||||
await brain.init()
|
||||
|
||||
let metadata: any = {}
|
||||
if (options.metadata) {
|
||||
|
|
@ -204,6 +205,12 @@ export const coreCommands = {
|
|||
} else {
|
||||
formatOutput({ id: result, metadata, confidence: addParams.confidence, weight: addParams.weight }, options)
|
||||
}
|
||||
|
||||
// close() releases the writer lock and indexes, but global timers
|
||||
// (UnifiedCache bookkeeping, PathResolver stats) keep the event loop
|
||||
// alive. CLI commands are one-shot — exit explicitly.
|
||||
await brain.close()
|
||||
process.exit(0)
|
||||
} catch (error: any) {
|
||||
if (spinner) spinner.fail('Failed to add data')
|
||||
console.error(chalk.red('Failed to add data:', error.message))
|
||||
|
|
@ -280,6 +287,7 @@ export const coreCommands = {
|
|||
|
||||
const spinner = ora('Searching with Triple Intelligence™...').start()
|
||||
const brain = getBrainy()
|
||||
await brain.init()
|
||||
|
||||
// Build comprehensive search params
|
||||
const searchParams: any = {
|
||||
|
|
@ -292,11 +300,6 @@ export const coreCommands = {
|
|||
searchParams.offset = parseInt(options.offset)
|
||||
}
|
||||
|
||||
// Vector Intelligence - similarity threshold
|
||||
if (options.threshold) {
|
||||
searchParams.near = { threshold: parseFloat(options.threshold) }
|
||||
}
|
||||
|
||||
// Metadata Intelligence - type filtering
|
||||
if (options.type) {
|
||||
const types = options.type.split(',').map(t => t.trim())
|
||||
|
|
@ -314,7 +317,9 @@ export const coreCommands = {
|
|||
}
|
||||
}
|
||||
|
||||
// Vector Intelligence - proximity search
|
||||
// Vector Intelligence - proximity search around an anchor entity.
|
||||
// `near` requires an id; a bare --threshold (no --near) is applied as a
|
||||
// plain score floor on the fused results after find() returns.
|
||||
if (options.near) {
|
||||
searchParams.near = {
|
||||
id: options.near,
|
||||
|
|
@ -371,7 +376,14 @@ export const coreCommands = {
|
|||
}
|
||||
}
|
||||
|
||||
const results = await brain.find(searchParams)
|
||||
let results = await brain.find(searchParams)
|
||||
|
||||
// Without --near there is no proximity anchor; apply --threshold as a
|
||||
// minimum-score filter on the fused results instead.
|
||||
if (!options.near && options.threshold) {
|
||||
const minScore = parseFloat(options.threshold)
|
||||
results = results.filter((r) => r.score === undefined || r.score >= minScore)
|
||||
}
|
||||
|
||||
spinner.succeed(`Found ${results.length} results`)
|
||||
|
||||
|
|
@ -457,6 +469,10 @@ export const coreCommands = {
|
|||
} else {
|
||||
formatOutput(results, options)
|
||||
}
|
||||
|
||||
// One-shot command — see add() for why the explicit close + exit.
|
||||
await brain.close()
|
||||
process.exit(0)
|
||||
} catch (error: any) {
|
||||
if (spinner) spinner.fail('Search failed')
|
||||
console.error(chalk.red('Search failed:', error.message))
|
||||
|
|
@ -496,6 +512,7 @@ export const coreCommands = {
|
|||
|
||||
const spinner = ora('Fetching item...').start()
|
||||
const brain = getBrainy()
|
||||
await brain.init()
|
||||
|
||||
// Try to get the item
|
||||
const item = await brain.get(id)
|
||||
|
|
@ -529,6 +546,10 @@ export const coreCommands = {
|
|||
} else {
|
||||
formatOutput(item, options)
|
||||
}
|
||||
|
||||
// One-shot command — see add() for why the explicit close + exit.
|
||||
await brain.close()
|
||||
process.exit(0)
|
||||
} catch (error: any) {
|
||||
if (spinner) spinner.fail('Failed to get item')
|
||||
console.error(chalk.red('Failed to get item:', error.message))
|
||||
|
|
@ -589,6 +610,7 @@ export const coreCommands = {
|
|||
|
||||
const spinner = ora('Creating relationship...').start()
|
||||
const brain = getBrainy()
|
||||
await brain.init()
|
||||
|
||||
let metadata: any = {}
|
||||
if (options.metadata) {
|
||||
|
|
@ -627,6 +649,10 @@ export const coreCommands = {
|
|||
} else {
|
||||
formatOutput({ id: result, source, verb, target, metadata }, options)
|
||||
}
|
||||
|
||||
// One-shot command — see add() for why the explicit close + exit.
|
||||
await brain.close()
|
||||
process.exit(0)
|
||||
} catch (error: any) {
|
||||
if (spinner) spinner.fail('Failed to create relationship')
|
||||
console.error(chalk.red('Failed to create relationship:', error.message))
|
||||
|
|
@ -683,6 +709,7 @@ export const coreCommands = {
|
|||
|
||||
spinner = ora('Updating entity...').start()
|
||||
const brain = getBrainy()
|
||||
await brain.init()
|
||||
|
||||
// Get existing entity first
|
||||
const existing = await brain.get(id)
|
||||
|
|
@ -731,6 +758,10 @@ export const coreCommands = {
|
|||
} else {
|
||||
formatOutput({ id, updated: true }, options)
|
||||
}
|
||||
|
||||
// One-shot command — see add() for why the explicit close + exit.
|
||||
await brain.close()
|
||||
process.exit(0)
|
||||
} catch (error: any) {
|
||||
if (spinner) spinner.fail('Failed to update entity')
|
||||
console.error(chalk.red('Update failed:', error.message))
|
||||
|
|
@ -784,6 +815,7 @@ export const coreCommands = {
|
|||
|
||||
spinner = ora('Deleting entity...').start()
|
||||
const brain = getBrainy()
|
||||
await brain.init()
|
||||
|
||||
await brain.delete(id)
|
||||
|
||||
|
|
@ -794,6 +826,10 @@ export const coreCommands = {
|
|||
} else {
|
||||
formatOutput({ id, deleted: true }, options)
|
||||
}
|
||||
|
||||
// One-shot command — see add() for why the explicit close + exit.
|
||||
await brain.close()
|
||||
process.exit(0)
|
||||
} catch (error: any) {
|
||||
if (spinner) spinner.fail('Failed to delete entity')
|
||||
console.error(chalk.red('Delete failed:', error.message))
|
||||
|
|
@ -846,6 +882,7 @@ export const coreCommands = {
|
|||
|
||||
spinner = ora('Removing relationship...').start()
|
||||
const brain = getBrainy()
|
||||
await brain.init()
|
||||
|
||||
await brain.unrelate(id)
|
||||
|
||||
|
|
@ -856,6 +893,10 @@ export const coreCommands = {
|
|||
} else {
|
||||
formatOutput({ id, removed: true }, options)
|
||||
}
|
||||
|
||||
// One-shot command — see add() for why the explicit close + exit.
|
||||
await brain.close()
|
||||
process.exit(0)
|
||||
} catch (error: any) {
|
||||
if (spinner) spinner.fail('Failed to remove relationship')
|
||||
console.error(chalk.red('Unrelate failed:', error.message))
|
||||
|
|
@ -875,7 +916,9 @@ export const coreCommands = {
|
|||
|
||||
if (options.json) {
|
||||
formatOutput(diag, options)
|
||||
return
|
||||
// One-shot command — see add() for why the explicit close + exit.
|
||||
await brain.close()
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
console.log(chalk.bold('\nBrainy Diagnostics'))
|
||||
|
|
@ -907,6 +950,10 @@ export const coreCommands = {
|
|||
console.log(` Metadata: ${diag.indexes.metadata.type} (initialized: ${diag.indexes.metadata.initialized})`)
|
||||
console.log(` Graph: ${diag.indexes.graph.type} (initialized: ${diag.indexes.graph.initialized}, wired: ${diag.indexes.graph.wiredToStorage})`)
|
||||
console.log()
|
||||
|
||||
// One-shot command — see add() for why the explicit close + exit.
|
||||
await brain.close()
|
||||
process.exit(0)
|
||||
} catch (error: any) {
|
||||
console.error(chalk.red('Diagnostics failed: ' + error.message))
|
||||
process.exit(1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue