mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-29 16:39:15 +00:00
fix(verbs): green the 3 failing CI shards — 3-seg migration version, hermetic synthesize test, fresh llms
Three real CI-shard failures from the propagation commit + master merges: - migrations-registry (shard 10): v0_43_0 used a 4-segment version 0.43.0.0, but the registry enforces 3-segment semver (/^\d+\.\d+\.\d+$/). Changed the migration version to 0.43.0 (the RELEASE stays 0.43.0.0; migrations have always used 3-seg, e.g. 0.32.2). apply-migrations future-list fixtures updated to match. - synthesize conformance test (shard 5): asserted a successful answer via the chat seam, but runThink builds its client through a real-key check (not the seam), so CI (credential-free) took the NO_ANTHROPIC_API_KEY path → the verb's unavailable conversion → isError. Now wraps the call in withEnv with a fake key AND the chat seam, so it's deterministic regardless of ambient credentials. - build-llms (shard 8): the v0.42.44.0 master merge changed an inlined doc; regenerated llms.txt/llms-full.txt. Cathedral 1 CI fixes (#cathedral-1) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
49ee3a7e7c
commit
6820dbf0ff
+6
-1
@@ -3486,11 +3486,16 @@ for remote clients over OAuth 2.1.
|
||||
### Local stdio (zero setup)
|
||||
|
||||
```bash
|
||||
gbrain serve
|
||||
gbrain serve # full operation catalog (default)
|
||||
gbrain serve --surface verbs # just the 5 memory verbs (quickstart surface)
|
||||
```
|
||||
|
||||
Works with Claude Code, Cursor, Windsurf, and any MCP client that supports stdio.
|
||||
No server, no tunnel, no token needed. Works on both PGLite and Postgres engines.
|
||||
`--surface verbs` exposes exactly the five-verb memory protocol (`recall`,
|
||||
`remember`, `entity`, `synthesize`, `forget` —
|
||||
[MEMORY_VERBS v1](../protocol/MEMORY_VERBS_v1.md)) instead of the full catalog;
|
||||
omit the flag (default `full`) for every operation.
|
||||
|
||||
### Remote over OAuth 2.1 (recommended, v0.26.0+)
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ import type { Migration, OrchestratorOpts, OrchestratorResult } from './types.ts
|
||||
|
||||
async function orchestrator(_opts: OrchestratorOpts): Promise<OrchestratorResult> {
|
||||
// No schema/data work — MEMORY_VERBS v1 is a façade over existing tables.
|
||||
return { version: '0.43.0.0', status: 'complete', phases: [] };
|
||||
return { version: '0.43.0', status: 'complete', phases: [] };
|
||||
}
|
||||
|
||||
export const v0_43_0: Migration = {
|
||||
version: '0.43.0.0',
|
||||
version: '0.43.0',
|
||||
featurePitch: {
|
||||
headline:
|
||||
'Five memory verbs — recall, remember, entity, synthesize, forget — are now the agent-facing memory protocol (MEMORY_VERBS v1).',
|
||||
|
||||
@@ -108,7 +108,7 @@ describe('buildPlan — diff against completed + installed VERSION', () => {
|
||||
// autopilot cooperative, v0.16.0 = subagent runtime, v0.18.0 = multi-
|
||||
// source brains, v0.18.1 = RLS hardening, v0.21.0 = Cathedral II
|
||||
// (renumbered from v0.20.0 after master shipped v0.20.x in parallel).
|
||||
expect(plan.skippedFuture.map(m => m.version)).toEqual(['0.12.0', '0.12.2', '0.13.0', '0.13.1', '0.14.0', '0.16.0', '0.18.0', '0.18.1', '0.21.0', '0.22.4', '0.28.0', '0.29.1', '0.31.0', '0.32.2', '0.43.0.0']);
|
||||
expect(plan.skippedFuture.map(m => m.version)).toEqual(['0.12.0', '0.12.2', '0.13.0', '0.13.1', '0.14.0', '0.16.0', '0.18.0', '0.18.1', '0.21.0', '0.22.4', '0.28.0', '0.29.1', '0.31.0', '0.32.2', '0.43.0']);
|
||||
});
|
||||
|
||||
test('already applied → v0.11.0 lands in `applied` bucket, not pending', () => {
|
||||
@@ -148,7 +148,7 @@ describe('buildPlan — diff against completed + installed VERSION', () => {
|
||||
// v0.22.4, v0.28.0, v0.29.1, v0.31.0 were added later; installed=0.12.0
|
||||
// means they belong in skippedFuture, not pending. v0.11.0 and v0.12.0
|
||||
// stay pending despite being ≤ installed — that is the H9 invariant.
|
||||
expect(plan.skippedFuture.map(m => m.version)).toEqual(['0.12.2', '0.13.0', '0.13.1', '0.14.0', '0.16.0', '0.18.0', '0.18.1', '0.21.0', '0.22.4', '0.28.0', '0.29.1', '0.31.0', '0.32.2', '0.43.0.0']);
|
||||
expect(plan.skippedFuture.map(m => m.version)).toEqual(['0.12.2', '0.13.0', '0.13.1', '0.14.0', '0.16.0', '0.18.0', '0.18.1', '0.21.0', '0.22.4', '0.28.0', '0.29.1', '0.31.0', '0.32.2', '0.43.0']);
|
||||
});
|
||||
|
||||
test('--migration filter narrows to one version', () => {
|
||||
|
||||
@@ -44,6 +44,7 @@ import {
|
||||
__setEmbedTransportForTests,
|
||||
} from '../src/core/ai/gateway.ts';
|
||||
import { __setUsageLogPathForTests } from '../src/core/verbs/usage-log.ts';
|
||||
import { withEnv } from './helpers/with-env.ts';
|
||||
|
||||
let engine: PGLiteEngine;
|
||||
let home: string;
|
||||
@@ -295,11 +296,12 @@ describe('synthesize — marked expensive + unavailable conversion [c10]', () =>
|
||||
});
|
||||
|
||||
it('delegates to runThink and returns the frozen envelope with a priced cost block (chat seam — no real LLM)', async () => {
|
||||
// Hermetic: the chat transport seam answers deterministically. (The
|
||||
// keyless `unavailable` conversion [c10] is covered end-to-end by the CI
|
||||
// conformance step, which runs `protocol conformance --synthesize` in a
|
||||
// credential-free environment — a unit-level trigger here would depend on
|
||||
// the developer machine NOT having keys, the opposite of hermetic.)
|
||||
// Fully hermetic regardless of the dev/CI machine's ambient credentials:
|
||||
// runThink builds its client via a real-key check (hasAnthropicKey reads
|
||||
// process.env), NOT the gateway chat seam — so we must BOTH provide a fake
|
||||
// key via withEnv (so the client builds) AND install the chat seam (so no
|
||||
// real API call fires). Without the env key, CI (credential-free) takes the
|
||||
// NO_ANTHROPIC_API_KEY path → the verb's `unavailable` conversion → isError.
|
||||
__setChatTransportForTests(async () => ({
|
||||
text: JSON.stringify({ answer: 'Synthesized test answer.', citations: [], gaps: ['none'] }),
|
||||
blocks: [],
|
||||
@@ -308,7 +310,9 @@ describe('synthesize — marked expensive + unavailable conversion [c10]', () =>
|
||||
model: 'anthropic:claude-haiku-4-5-20251001',
|
||||
providerId: 'anthropic',
|
||||
}));
|
||||
const { isError, body } = await callRemote('synthesize', { question: 'what do we know?' });
|
||||
const { isError, body } = await withEnv({ ANTHROPIC_API_KEY: 'sk-test-hermetic' }, async () =>
|
||||
callRemote('synthesize', { question: 'what do we know?' }),
|
||||
);
|
||||
expect(isError).toBe(false);
|
||||
expect(body.answer).toBe('Synthesized test answer.');
|
||||
expect(body.protocol_version).toBe(1);
|
||||
|
||||
Reference in New Issue
Block a user