mirror of
https://github.com/garrytan/gbrain.git
synced 2026-08-14 08:53:22 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45c9dcbee3 | ||
|
|
869223f3b3 |
@@ -14,6 +14,55 @@
|
||||
most of #2112 but not its `checkSubagentCapability` fix (check explicit `models.subagent`
|
||||
before `models.tier.subagent`). Refile or cherry-pick; the rest of that PR is covered.
|
||||
|
||||
## v0.42.59.0 follow-ups (five-fix rollup #2735–#2739)
|
||||
|
||||
Filed as follow-ups from v0.42.59.0 (bootstrap probe for
|
||||
`timeline_entries.event_page_id`, migrate-engine source catalog + target-aware
|
||||
resume, entity-resolution quarantine, escape-aware fence cells, think gather
|
||||
source scope).
|
||||
|
||||
- [ ] **P2 — schema-bootstrap-coverage strip block never exercises `timeline_entries.event_page_id`.**
|
||||
The guard's pre-migration-brain simulation (the strip DDL in
|
||||
`test/schema-bootstrap-coverage.test.ts`) has no
|
||||
`ALTER TABLE timeline_entries DROP COLUMN IF EXISTS event_page_id` (or FK drop), so the
|
||||
coverage entry added for the v121 forward reference is vacuous — the probe never fires
|
||||
under that harness. The real regression guard lives in `test/bootstrap.test.ts` (which
|
||||
does drop → re-bootstrap → assert). Add the DROP statements to the strip block so the
|
||||
coverage test genuinely exercises its own entry.
|
||||
- [ ] **P2 — extract-facts reconcile still wipes-then-reinserts when the parse emitted MALFORMED warnings.**
|
||||
`runExtractFacts` (`src/core/cycle/extract-facts.ts`) deletes a page's facts and
|
||||
reinserts from the parsed fence even when `parseFactsFence` surfaced
|
||||
`FACTS_TABLE_MALFORMED` warnings — any future parse defect becomes a deletion vector
|
||||
(rows the parser failed to read get wiped with nothing to reinsert). Consider
|
||||
skip-wipe-on-warnings: treat a warning-bearing parse as non-authoritative for that page
|
||||
(skip the wipe, surface a warn), mirroring the empty-fence legacy-row guard's posture.
|
||||
- [ ] **P3 — bare-name resolution quarantines even on an exact unique match when prefix siblings exist.**
|
||||
With pages `companies/acme` + `companies/acme-labs`, a bare `"Acme"` yields two
|
||||
`findPrefixCandidates` rows, so `tryUnambiguousPrefixExpansion` declines — even though
|
||||
`companies/acme` is an exact `dir/token` slug match (and may be a unique exact title
|
||||
match). That's an unambiguity signal being wasted. Consider promoting an exact
|
||||
`dir/token` (or exact-title) hit above the sibling-count check in
|
||||
`src/core/entities/resolve.ts`.
|
||||
- [ ] **P2 — `scripts/run-verify-parallel.sh` no-gtimeout fallback reports the watchdog's exit code, not the check's.**
|
||||
In the fallback branch, `rc=$?` is captured after `wait "$cap_pid"` (the killed
|
||||
sleep-watchdog, rc=143) rather than after `wait "$pid"` (the actual check) — on a Mac
|
||||
without coreutils every check false-fails with rc=143. Capture `rc` from `wait "$pid"`
|
||||
first, then reap the watchdog.
|
||||
- [ ] **P3 — same-target migrate resume with `--force` still skips checkpointed pages after the wipe.**
|
||||
`gbrain migrate --to <engine> --force` wipes the target's pages, but the resume
|
||||
manifest's `completed_slugs` filter still applies, so previously-checkpointed pages are
|
||||
skipped against the now-empty target (pre-existing behavior; the v0.42.59.0 verification
|
||||
warns about it). `--force` should clear the manifest when it matches the same target.
|
||||
Where: `src/commands/migrate-engine.ts`.
|
||||
- [ ] **P2 — think residual scope gaps.** Two spots in `src/core/think/index.ts` don't yet
|
||||
inherit the caller's source scope the way the gather stage now does:
|
||||
`persistCitations` resolves citation slugs with an unscoped
|
||||
`SELECT id FROM pages WHERE slug = $1 LIMIT 1` (cross-source slug ambiguity can attach
|
||||
saved evidence to the wrong same-slug page), and the trajectory entity-resolution scalar
|
||||
is `opts.sourceId ?? 'default'` (a federated caller with `allowedSources` but no scalar
|
||||
resolves entities against `default` instead of its grant). Mirror the gather-stage
|
||||
precedence (federated array > scalar > default) at both sites.
|
||||
|
||||
## provider-agnostic follow-ups (filed v0.42.58.0)
|
||||
|
||||
Deferred from the provider-agnostic plumbing wave (#1249/#1250/#1292/#2271/#2209).
|
||||
|
||||
+4
-1
@@ -239,8 +239,11 @@ E2E tests live in `test/e2e/` and run against real Postgres+pgvector (require `D
|
||||
- `test/e2e/http-transport.test.ts` — `gbrain serve --http` end-to-end against real Postgres: bearer auth round-trip, `last_used_at` SQL-level debounce, `mcp_request_log` row insertion on success and auth_failed paths, `/health` DB-down → 503 (DB-probing health check), and the dispatch round-trip with a real operation. Skips without `DATABASE_URL`.
|
||||
- `test/e2e/serve-http-oauth.test.ts` — real-Postgres E2E against `gbrain serve --http` with full OAuth 2.1. Spawns a subprocess server, registers a client via the CLI, mints `client_credentials` tokens, exercises the `/mcp` JSON-RPC pipeline. Real DCR `/register` HTTP-level response-shape test (asserts `typeof body.client_id_issued_at === 'number'` over the wire, RFC 7591 §3.2.1); real CLI subprocess test for `revoke-client` (registers → mints token → revokes via `execSync` → asserts token rejected at `/mcp` → asserts re-run exits 1); server fixture flips on `--enable-dcr` so `/register` is reachable. **bun execSync env-inheritance contract:** bun's `execSync` does NOT inherit env mutations done via `process.env.X = ...`, only OS-level env from before bun started. helpers.ts loads `.env.testing` and sets `DATABASE_URL` via `process.env` mutation, which is invisible to subprocesses unless `env: { ...process.env }` is passed explicitly — every subprocess call in this file passes `env: { ...process.env }`. Reference fix for the same failure mode in sibling sync/cycle/dream/claw-test E2Es. `afterAll` cleanup is guarded on `clientId` (won't throw if `beforeAll` failed before registration); cleanup errors surface to stderr without throwing so real test failures aren't masked. Also covers the trust-boundary fix: an HTTP MCP `submit_job` for `name: "shell"` MUST reject with a permission error (request handler sets `remote: true` and `submit_job`'s protected-name guard fires), and the same guard rejects subagent submission. Skips without `DATABASE_URL`.
|
||||
- `test/e2e/sync-parallel.test.ts` — `DATABASE_URL`-gated. 60-file Postgres sync at concurrency=4 imports all + no connection leak (probes `pg_stat_activity` before/after to confirm worker engines disconnected). 120-file serial-vs-parallel benchmark prints `SYNC_PARALLEL_BENCH N files | serial=Xms | parallel(4)=Yms | speedup=Zx`. Asserts parallel ≤ serial × 1.5 (CI-noise tolerant; not a strict speedup gate).
|
||||
- `test/e2e/multi-source-bug-class.test.ts` — PGLite in-memory regression suite pinning every multi-source bug site: `listAllPageRefs` ordering by `(source_id, slug)`, `getPage` with sourceId picks the right `(source, slug)` row, `extract-takes` processes both overlapping `people/alice` rows independently, `listPages` filters correctly with `PageFilters.sourceId`, `addLinksBatch` with `from/to_source_id` targets the right rows, `validateSourceId` rejects path traversal, reverse-write disk layout uses `brainDir/.sources/<id>/<slug>.md` for non-default sources. No `DATABASE_URL` needed. Wired into `scripts/e2e-test-map.ts` so changes to extract-takes / patterns / synthesize / embed / extract / migrate-engine auto-trigger it.
|
||||
- `test/e2e/multi-source-bug-class.test.ts` — PGLite in-memory regression suite pinning every multi-source bug site: `listAllPageRefs` ordering by `(source_id, slug)`, `getPage` with sourceId picks the right `(source, slug)` row, `extract-takes` processes both overlapping `people/alice` rows independently, `listPages` filters correctly with `PageFilters.sourceId`, `addLinksBatch` with `from/to_source_id` targets the right rows, `validateSourceId` rejects path traversal, reverse-write disk layout uses `brainDir/.sources/<id>/<slug>.md` for non-default sources, `copyMigrationSources` lands source metadata before overlapping-slug pages. No `DATABASE_URL` needed. Wired into `scripts/e2e-test-map.ts` so changes to extract-takes / patterns / synthesize / embed / extract / migrate-engine auto-trigger it.
|
||||
- `test/e2e/migrate-engine-sources-postgres.test.ts` — `DATABASE_URL`-gated companion for `gbrain migrate --to`: migrates a PGLite brain carrying two non-default sources with overlapping slugs into real Postgres and asserts `copyMigrationSources` created every `sources` FK parent (config JSONB intact, not double-encoded) before any page write. Unit-level manifest identity (crash manifest resumes only against the SAME target; legacy engine-only manifests start fresh) is `test/migrate-engine-resume.test.ts`.
|
||||
- `test/e2e/facts-fence-reconcile-postgres.test.ts` — `DATABASE_URL`-gated round-trip for the escape-aware fence parser: renders a `## Facts` fence whose cells carry literal pipes, backslashes (Windows paths), and empty cells via `renderFactsTable`, runs the wipe-and-reinsert reconcile (`runExtractFacts`) on real Postgres, and asserts every cell survives byte-identically with no column shift.
|
||||
- `test/e2e/source-isolation-pglite.test.ts` — PGLite in-memory regression suite pinning the source-isolation seal at two layers. Engine layer: `searchKeyword` / `searchVector` / `searchKeywordChunks` / `listPages` / `getPage` / `traverseGraph` / `traversePaths` apply `sourceId` (scalar fast path) and `sourceIds` (array path) correctly across both engines. Op-handler layer: routes through `sourceScopeOpts(ctx)` so a `read+write`-scoped OAuth client bound to `--source dept-x` cannot see rows from neighboring sources via `search`, `query`, `list_pages`, `get_page`, or `find_experts`. Covers both `ctx.sourceId` (single-source clients) and `ctx.auth.allowedSources` (federated_read clients) precedence; federated array wins over scalar wins over nothing. No `DATABASE_URL` needed.
|
||||
- `test/e2e/think-source-isolation-pglite.test.ts` — PGLite in-memory suite pinning the `think` gather stage's source scope: seeds three sources with cross-source links and embedded takes, then asserts `runGather` under a federated `sourceIds` grant (and under a scalar `sourceId`) keeps every stream — hybrid retrieval, takes keyword + vector (`searchTakes`/`searchTakesVector`), and the `traversePaths` graph walk — inside the grant while still reaching authorized neighboring sources. No `DATABASE_URL` needed.
|
||||
- `test/e2e/skill-brain-first.test.ts` — doctor reports `skill_brain_first` check with structured issues; `--fix --dry-run` previews insertion without writing; `--fix` applies the canonical Convention callout idempotently; `brain_first: exempt` frontmatter resolves the warn; `brain_first_typo` surfaces a paste-ready hint; audit JSONL records `detected` / `resolved` / `fixed` transitions; stable brain emits 0 audit lines/run.
|
||||
- Tier 2 (`test/e2e/skills.test.ts`) requires OpenClaw + API keys, runs nightly in CI.
|
||||
- If `.env.testing` doesn't exist in this directory, check sibling worktrees: `find ../ -maxdepth 2 -name .env.testing -print -quit` and copy it here if found.
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user