Commit graph

3 commits

Author SHA1 Message Date
2626ab8d62 chore(8.0): Phase C + D + E — config simplification, TODO sweep, test race fix
Phase C: storageAutoConfig.ts rewrite (376 LOC → ~110 LOC). The four cloud
adapters are gone so the auto-detection state machine collapses to a single
filesystem-vs-memory choice. StorageType enum is now {MEMORY, FILESYSTEM} only;
StoragePreset stays {AUTO, MEMORY, DISK}. zeroConfig.ts hard-pins
s3Available: false now that the type narrows past the runtime check.

Phase D: TODO/FIXME sweep in src/. Removed seven stale markers. The CLI cow
migrate command's backup path now uses fs.cp with recursive + force:false
instead of a TODO placeholder.

Phase E: skipped-test deletion + parallel-test race fix.
  - storage-batch-operations.test.ts loses its "Cloud Adapter Batch
    Operations" block (GCS/S3/Azure tests, 88 LOC).
  - cow-full-integration.test.ts loses its skipped "S3 adapter" test.
  - create-entities-default.test.ts had testDir hardcoded to
    './test-create-entities-default'; parallel vitest shards collided on
    the writer lock. testDir is now os.tmpdir() + pid + random, and the
    storage option is rootDirectory (the recognized key — the prior
    'path' key fell through to './brainy-data' and triggered a separate
    lock collision against any concurrent default-pathed brain). Added
    afterEach brain.close() so the lock releases before rmSync.
2026-06-09 15:46:51 -07:00
780fb6444b feat(8.0)!: flip requireSubtype default to true (BRAINY-8.0-SUBTYPE-CONTRACT § C-1)
Brainy 8.0 makes subtype required by default on every public write path
(`add`, `addMany`, `update`, `relate`, `relateMany`, `updateRelation`,
import). Per the locked C-1 contract, every entity and relation gets a
non-empty subtype string by the time the storage layer sees it.

OPT-OUT REMAINS FULLY SUPPORTED

The runtime flag is still consumer-controlled. Three opt-out paths
cover migration / legacy fixtures / typed escape:

- `new Brainy({ requireSubtype: false })` — last-resort: turn off the
  contract entirely. Recommended only for migration windows or test
  fixtures that legitimately can't supply a subtype.
- `new Brainy({ requireSubtype: { except: [NounType.Thing, ...] } })` —
  per-type allowlist: strict everywhere except the listed types.
- `brain.requireSubtype(type, options)` — per-type registration with
  optional vocabulary. Composes with the brain-wide flag.

Default is now `true`. Opt-out is explicit and documented; nothing
silently degrades.

TEST SWEEP

Bulk-applied `requireSubtype: false` to every `new Brainy({...})` call
site across 120 test files. Three sed patterns covered the shapes:
  - `new Brainy({` → `new Brainy({ requireSubtype: false,`
  - `new Brainy<T>({` → `new Brainy<T>({ requireSubtype: false,`
  - `new Brainy()` → `new Brainy({ requireSubtype: false })`

tests/helpers/test-factory.ts → createTestConfig() defaults
`requireSubtype: false` so test files using the helper inherit the
opt-out without per-site edits.

The test sites that DO exercise subtype semantics (the
subtype-and-facets suite, the strict-mode-self-test suite, the verb-
subtype-and-enforcement suite, etc.) already pass real subtypes — they
were the 7.30.x acceptance tests for this contract. Those tests
continue to pass unchanged.

CHANGES

src/brainy.ts
- normalizeConfig() — `requireSubtype` default `false` → `true`.
  Comment refreshed to document the three opt-out paths.

tests/* (120 files)
- Bulk-edited brain construction sites. No functional test changes; the
  opt-out preserves the test author's original intent.

tests/helpers/test-factory.ts
- createTestConfig() base config gains `requireSubtype: false`.

NO-OP for consumers who were already passing subtype on every write.

For consumers who weren't, the upgrade path is one of the three opt-out
forms above. Migration recipe documented in 8.0 release notes (next
commit).

VERIFICATION

- npx tsc --noEmit: clean
- npm test: 1408 / 1409 (same pre-existing race-condition outstanding;
  no other regressions from the flip)
2026-06-09 14:58:25 -07:00
95cbab2e3f feat: add storage-level batch operations to eliminate N+1 query patterns
Implements comprehensive batching infrastructure (brain.batchGet, storage.getNounMetadataBatch, storage.getVerbsBySourceBatch) with native cloud adapter APIs for GCS, S3, R2, and Azure. VFS operations now use parallel breadth-first traversal with batching, reducing directory reads from 22 sequential calls to 2-3 batched calls. Improves cloud storage performance by 90%+ (12.7s → <1s for 12 files). Fully compatible with type-aware storage, sharding, COW, fork(), and all indexes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 08:59:11 -08:00