mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-28 14:59:47 +00:00
* feat(migrate): provider-agnostic embedding migration service — the path off ZeroEntropy (#3390) - gbrain migrate embeddings --to <provider:model> (alias: retrieval-upgrade): plan + cost preflight, consent gate (--yes / TTY confirm / non-TTY exit 2), live probe against the target provider before any mutation, env-override gate, schema dimension transition via the shared runSchemaTransition, dual-plane config write, NULL-signature-inclusive invalidation, query-cache purge, resumable re-embed through the standard embed pipeline (single-flight locks, backoff, pacing, stderr progress). Killed runs resume by re-running the same command; the NULL-embedding column is the checkpoint. - #3391 root-cause fix (both engines): countStaleChunks / sumStaleChunkChars / invalidateStaleSignatureEmbeddings accept includeNullSignature to lift the v108 grandfather clause; embed --stale warns loudly when a model swap leaves NULL-signature pages in the old embedding space, and --include-null-signature re-embeds them. Default sweep behavior unchanged. - knobs_hash v=12 → v=13 (prov=default legacy callers must not be served pre-migration cache rows). - migrate_embeddings op: scope admin, localOnly, hidden cliHints, hard remote refusal, needs_confirmation without yes=true. - One-shot post-upgrade ZE-sunset banner (ze_sunset_notice_shown) for brains resolving to a zeroentropyai:* embedding model or reranker. - doctor's dimension-mismatch repair hint now names the real command. - Docs: docs/guides/embedding-migration.md, KEY_FILES entries, spend-controls gate row. Tests: PGLite unit + full-lifecycle flow (interrupted-run resume), real-Postgres e2e (pgvector DDL path + #3391 predicate parity). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(test): satisfy check:test-isolation + bump the remaining knobs_hash pins - test/migrate-embeddings-flow.test.ts → .serial.test.ts: the file holds a temp GBRAIN_HOME + an installed fake embed transport for its whole lifecycle (beforeAll → afterAll), which withEnv() can't wrap. This also fixes the CI shard-pollution failure in test/ai/recipes-existing-regression.test.ts (that file passes solo on both master and this branch; the flow test's configureGateway + provider-key deletion was leaking into it inside the same shard process). - test/embedding-migration.test.ts: env-override case now uses withEnv(). - Bump the three remaining KNOBS_HASH_VERSION pins to 13 (cross-modal-phase1, search-alias-resolved-boost, search/knobs-hash-reranker). - Docs + llms bundles follow the test rename. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(test): wire the new Postgres e2e into the smart e2e selector map Changes to embed.ts / embedding-migration.ts / retrieval-upgrade-planner.ts / postgres-engine.ts now trigger test/e2e/migrate-embeddings-postgres.test.ts — the #3391 stale predicates and runSchemaTransition's DDL path behave differently on real pgvector than on PGLite, so the smart selector has to know. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(migrate): consult spend.posture in the embedding-migration consent gate The brief asked the gate to honor spend.posture; it previously didn't read it at all. Now it does — but deliberately does NOT bypass on tokenmax: posture waives the spend CEILING, and this gate also guards a destructive schema rebuild (existing vectors dropped, retrieval degraded until the re-embed finishes). Under tokenmax the dollar figure is marked informational on stderr and the confirmation is still asked; --yes stays the single scripted bypass. Pinned by a new case in the flow test so a later refactor can't quietly turn posture into a bypass. Guide + spend-controls table updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * wip: blocker fixes --------- Co-authored-by: Garry Tan <garrytan@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
122 lines
5.7 KiB
TypeScript
122 lines
5.7 KiB
TypeScript
// scripts/e2e-test-map.ts
|
|
//
|
|
// Path-glob -> E2E test files map. Used by scripts/select-e2e.ts.
|
|
//
|
|
// CONTRACT: This map can ONLY narrow from "all". When a changed src/ path
|
|
// matches no glob here, the selector falls back to "run all E2E" (fail-closed).
|
|
// You can safely add narrowing entries; you cannot break correctness by missing
|
|
// one. Tune as misses surface (i.e., when ci:local:diff ran more than necessary
|
|
// and you'd like to narrow that surface area).
|
|
//
|
|
// Glob syntax is the minimal subset implemented in select-e2e.ts:
|
|
// - "**" matches any sequence of path segments (including zero)
|
|
// - "*" matches any characters within a single path segment
|
|
// - everything else is literal
|
|
// No brace expansion, no ?, no [ ].
|
|
|
|
export const E2E_TEST_MAP: Record<string, string[]> = {
|
|
// Source-aware ranking, hybrid search, intent classification.
|
|
"src/core/search/**": [
|
|
"test/e2e/search-quality.test.ts",
|
|
"test/e2e/search-exclude.test.ts",
|
|
"test/e2e/search-swamp.test.ts",
|
|
],
|
|
// Tree-sitter chunkers feed code-indexing E2E.
|
|
"src/core/chunkers/**": ["test/e2e/code-indexing.test.ts"],
|
|
// OpenClaw context-engine plugin: engine + entry feed the plugin-shape E2E
|
|
// (mocked SDK) AND the real-loader Tier 2 E2E that spawns openclaw and
|
|
// actually installs the plugin into an isolated --profile.
|
|
"src/core/context-engine.ts": [
|
|
"test/e2e/openclaw-context-engine-plugin.test.ts",
|
|
"test/e2e/openclaw-plugin-load-real.test.ts",
|
|
],
|
|
"src/openclaw-context-engine.ts": [
|
|
"test/e2e/openclaw-context-engine-plugin.test.ts",
|
|
"test/e2e/openclaw-plugin-load-real.test.ts",
|
|
],
|
|
// dream.ts is a thin alias over runCycle in cycle.ts.
|
|
"src/core/cycle.ts": ["test/e2e/cycle.test.ts", "test/e2e/dream.test.ts"],
|
|
// Multi-source sync writes share the per-source bookmark anchor.
|
|
"src/core/sync.ts": ["test/e2e/sync.test.ts", "test/e2e/multi-source.test.ts"],
|
|
// v0.32.8 multi-source bug class regression suite — fires on any cycle
|
|
// phase, extract, integrity, embed, or migrate-engine change.
|
|
"src/core/cycle/extract-takes.ts": ["test/e2e/multi-source-bug-class.test.ts"],
|
|
"src/core/cycle/patterns.ts": ["test/e2e/multi-source-bug-class.test.ts"],
|
|
"src/core/cycle/synthesize.ts": [
|
|
"test/e2e/multi-source-bug-class.test.ts",
|
|
"test/e2e/synthesize-bigint-job-id-postgres.test.ts",
|
|
],
|
|
"src/commands/embed.ts": [
|
|
"test/e2e/multi-source-bug-class.test.ts",
|
|
// #3391: the NULL-signature stale predicates differ per engine.
|
|
"test/e2e/migrate-embeddings-postgres.test.ts",
|
|
],
|
|
// #3390: runSchemaTransition's DDL path + the stale predicates behave
|
|
// differently on real pgvector than on PGLite.
|
|
"src/core/embedding-migration.ts": ["test/e2e/migrate-embeddings-postgres.test.ts"],
|
|
"src/core/retrieval-upgrade-planner.ts": ["test/e2e/migrate-embeddings-postgres.test.ts"],
|
|
"src/commands/extract.ts": ["test/e2e/multi-source-bug-class.test.ts"],
|
|
"src/commands/migrate-engine.ts": ["test/e2e/multi-source-bug-class.test.ts"],
|
|
// Any minions queue/worker/handler change exercises all minion E2E.
|
|
"src/core/minions/**": [
|
|
"test/e2e/minions-concurrency.test.ts",
|
|
"test/e2e/minions-resilience.test.ts",
|
|
"test/e2e/minions-shell.test.ts",
|
|
"test/e2e/minions-shell-pglite.test.ts",
|
|
"test/e2e/worker-abort-recovery.test.ts",
|
|
],
|
|
// postgres.js bind paths + JSONB shapes + parity vs PGLite.
|
|
"src/core/postgres-engine.ts": [
|
|
"test/e2e/postgres-bootstrap.test.ts",
|
|
"test/e2e/postgres-jsonb.test.ts",
|
|
"test/e2e/jsonb-roundtrip.test.ts",
|
|
"test/e2e/engine-parity.test.ts",
|
|
"test/e2e/schema-drift.test.ts",
|
|
// #3391: includeNullSignature stale predicates (engine parity).
|
|
"test/e2e/migrate-embeddings-postgres.test.ts",
|
|
],
|
|
// PGLite bootstrap path + parity guard.
|
|
"src/core/pglite-engine.ts": [
|
|
"test/e2e/postgres-bootstrap.test.ts",
|
|
"test/e2e/engine-parity.test.ts",
|
|
"test/e2e/schema-drift.test.ts",
|
|
],
|
|
// Schema source of truth: any change must pass the cross-engine drift gate.
|
|
"src/schema.sql": ["test/e2e/schema-drift.test.ts"],
|
|
"src/core/pglite-schema.ts": ["test/e2e/schema-drift.test.ts"],
|
|
"src/core/migrate.ts": ["test/e2e/schema-drift.test.ts", "test/e2e/migrate-chain.test.ts"],
|
|
// MCP stdio + HTTP transports share dispatch.
|
|
"src/mcp/**": ["test/e2e/mcp.test.ts", "test/e2e/http-transport.test.ts"],
|
|
// Integrity batch-load fast path.
|
|
"src/commands/integrity.ts": ["test/e2e/integrity-batch.test.ts"],
|
|
// gbrain connect — raw-bearer MCP smoke probe exercised end-to-end against
|
|
// a real serve --http (PGLite), so changes to either feed it.
|
|
"src/commands/connect.ts": ["test/e2e/connect-bearer.test.ts"],
|
|
"src/core/connect-probe.ts": ["test/e2e/connect-bearer.test.ts"],
|
|
// Upgrade chains migration ledger; touches both runners.
|
|
"src/commands/upgrade.ts": [
|
|
"test/e2e/upgrade.test.ts",
|
|
"test/e2e/migrate-chain.test.ts",
|
|
"test/e2e/migration-flow.test.ts",
|
|
],
|
|
"src/commands/doctor.ts": ["test/e2e/doctor-progress.test.ts"],
|
|
// Knowledge graph layer feeds graph-quality.
|
|
"src/core/link-extraction.ts": ["test/e2e/graph-quality.test.ts"],
|
|
// v0.38 ingestion substrate. POST /ingest lives inside serve-http.ts
|
|
// (per the plan-eng-review E1 decision); the daemon + built-in sources
|
|
// + ingest_capture Minion handler all feed the in-process roundtrip
|
|
// E2E AND the HTTP contract E2E for the webhook route.
|
|
"src/commands/serve-http.ts": [
|
|
"test/e2e/serve-http-ingest-webhook.test.ts",
|
|
"test/e2e/serve-http-oauth.test.ts",
|
|
],
|
|
"src/core/ingestion/**": [
|
|
"test/e2e/ingestion-roundtrip.test.ts",
|
|
"test/e2e/serve-http-ingest-webhook.test.ts",
|
|
],
|
|
"src/core/minions/handlers/ingest-capture.ts": [
|
|
"test/e2e/ingestion-roundtrip.test.ts",
|
|
"test/e2e/serve-http-ingest-webhook.test.ts",
|
|
],
|
|
};
|