mirror of
https://github.com/garrytan/gbrain.git
synced 2026-08-15 01:12:20 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eeecc90968 |
File diff suppressed because one or more lines are too long
@@ -3823,7 +3823,7 @@ const whoami: Operation = {
|
||||
name: 'whoami',
|
||||
description:
|
||||
'Introspect the calling identity. Returns one of three transport shapes: ' +
|
||||
'{transport: "oauth", client_id, client_name, scopes, expires_at, source_id, federated_read}, ' +
|
||||
'{transport: "oauth", client_id, client_name, scopes, expires_at}, ' +
|
||||
'{transport: "legacy", token_name, scopes, expires_at: null}, or ' +
|
||||
'{transport: "local", scopes: []}, or {transport: "stdio", scopes: []} ' +
|
||||
'for the auth-less stdio MCP pipe. Throws unknown_transport when the ' +
|
||||
@@ -3865,10 +3865,6 @@ const whoami: Operation = {
|
||||
client_name: ctx.auth.clientName ?? ctx.auth.clientId,
|
||||
scopes: ctx.auth.scopes,
|
||||
expires_at: ctx.auth.expiresAt ?? null,
|
||||
// Read-only self-introspection of the token's source grants —
|
||||
// widens nothing; absent grants serialize fail-closed (null / []).
|
||||
source_id: ctx.auth.sourceId ?? null,
|
||||
federated_read: ctx.auth.allowedSources ?? [],
|
||||
};
|
||||
}
|
||||
return {
|
||||
|
||||
@@ -4835,11 +4835,11 @@ export class PGLiteEngine implements BrainEngine {
|
||||
const { rows } = await this.db.query(
|
||||
`SELECT t.id AS take_id, t.page_id, p.slug AS page_slug, t.row_num,
|
||||
t.claim, t.kind, t.holder, t.weight,
|
||||
similarity(t.claim, $1)::real AS score
|
||||
word_similarity($1, t.claim)::real AS score
|
||||
FROM takes t
|
||||
JOIN pages p ON p.id = t.page_id
|
||||
WHERE t.active
|
||||
AND t.claim % $1
|
||||
AND $1 <% t.claim
|
||||
AND ($2::text[] IS NULL OR t.holder = ANY($2::text[]))
|
||||
AND ($4::text[] IS NULL OR p.source_id = ANY($4::text[]))
|
||||
AND ($5::text IS NULL OR p.source_id = $5::text)
|
||||
|
||||
@@ -4962,11 +4962,11 @@ export class PostgresEngine implements BrainEngine {
|
||||
const rows = await sql`
|
||||
SELECT t.id AS take_id, t.page_id, p.slug AS page_slug, t.row_num,
|
||||
t.claim, t.kind, t.holder, t.weight,
|
||||
similarity(t.claim, ${query})::real AS score
|
||||
word_similarity(${query}, t.claim)::real AS score
|
||||
FROM takes t
|
||||
JOIN pages p ON p.id = t.page_id
|
||||
WHERE t.active
|
||||
AND t.claim % ${query}
|
||||
AND ${query} <% t.claim
|
||||
AND (
|
||||
${opts.takesHoldersAllowList ?? null}::text[] IS NULL
|
||||
OR t.holder = ANY(${opts.takesHoldersAllowList ?? null}::text[])
|
||||
|
||||
@@ -100,6 +100,22 @@ describe('searchTakes', () => {
|
||||
const worldHits = await engine.searchTakes('founder', { takesHoldersAllowList: ['world'] });
|
||||
expect(worldHits.every(h => h.holder === 'world')).toBe(true);
|
||||
});
|
||||
|
||||
// #3267: whole-string trigram % structurally can't match a short keyword
|
||||
// against a long claim (similarity between the full strings stays under the
|
||||
// 0.3 threshold). word_similarity (<%) matches the keyword against the
|
||||
// best-matching word span instead.
|
||||
test('single-word keyword matches a long claim containing it (#3267)', async () => {
|
||||
await engine.addTakesBatch([
|
||||
{
|
||||
page_id: acmePageId, row_num: 50,
|
||||
claim: 'Acme will consolidate the mid-market vertical SaaS landscape through disciplined acquisitions and a shared billing platform over the next five years',
|
||||
kind: 'bet', holder: 'garry', weight: 0.6,
|
||||
},
|
||||
]);
|
||||
const hits = await engine.searchTakes('consolidate');
|
||||
expect(hits.some(h => h.claim.includes('consolidate the mid-market'))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateTake', () => {
|
||||
|
||||
+6
-63
@@ -55,75 +55,23 @@ describe('whoami op contract', () => {
|
||||
expect(result.scopes).toEqual([]);
|
||||
});
|
||||
|
||||
test('oauth transport returns client identity and exact source grants', async () => {
|
||||
test('oauth transport returns full client identity', async () => {
|
||||
const auth: AuthInfo = {
|
||||
token: 'gbrain_at_xxx',
|
||||
clientId: 'gbrain_cl_abc',
|
||||
clientName: 'gstack-test',
|
||||
scopes: ['read', 'sources_admin'],
|
||||
expiresAt: 1234567890,
|
||||
sourceId: 'hot-memory',
|
||||
allowedSources: ['hot-memory', 'canonical-brain'],
|
||||
};
|
||||
const result = (await whoami.handler(
|
||||
ctxWith({ remote: true, sourceId: 'transport-fallback', auth }),
|
||||
{},
|
||||
)) as any;
|
||||
expect(result).toEqual({
|
||||
transport: 'oauth',
|
||||
client_id: 'gbrain_cl_abc',
|
||||
client_name: 'gstack-test',
|
||||
scopes: ['read', 'sources_admin'],
|
||||
expires_at: 1234567890,
|
||||
source_id: 'hot-memory',
|
||||
federated_read: ['hot-memory', 'canonical-brain'],
|
||||
});
|
||||
});
|
||||
|
||||
test('oauth transport uses fail-closed empty values when source grants are absent', async () => {
|
||||
const auth: AuthInfo = {
|
||||
token: 'gbrain_at_pre_migration',
|
||||
clientId: 'gbrain_cl_pre_migration',
|
||||
scopes: ['read'],
|
||||
};
|
||||
const result = (await whoami.handler(
|
||||
ctxWith({ remote: true, sourceId: 'transport-fallback', auth }),
|
||||
{},
|
||||
)) as any;
|
||||
expect(result.source_id).toBeNull();
|
||||
expect(result.federated_read).toEqual([]);
|
||||
});
|
||||
|
||||
test('oauth transport preserves an explicit empty federated grant', async () => {
|
||||
const auth: AuthInfo = {
|
||||
token: 'gbrain_at_empty',
|
||||
clientId: 'gbrain_cl_empty',
|
||||
scopes: ['read', 'write'],
|
||||
sourceId: 'hot-memory',
|
||||
allowedSources: [],
|
||||
};
|
||||
const result = (await whoami.handler(
|
||||
ctxWith({ remote: true, auth }),
|
||||
{},
|
||||
)) as any;
|
||||
expect(result.source_id).toBe('hot-memory');
|
||||
expect(result.federated_read).toEqual([]);
|
||||
});
|
||||
|
||||
test('oauth transport does not widen federated_read with the write source', async () => {
|
||||
const auth: AuthInfo = {
|
||||
token: 'gbrain_at_narrow',
|
||||
clientId: 'gbrain_cl_narrow',
|
||||
scopes: ['read', 'write'],
|
||||
sourceId: 'hot-memory',
|
||||
allowedSources: ['canonical-brain'],
|
||||
};
|
||||
const result = (await whoami.handler(
|
||||
ctxWith({ remote: true, auth }),
|
||||
{},
|
||||
)) as any;
|
||||
expect(result.source_id).toBe('hot-memory');
|
||||
expect(result.federated_read).toEqual(['canonical-brain']);
|
||||
expect(result.transport).toBe('oauth');
|
||||
expect(result.client_id).toBe('gbrain_cl_abc');
|
||||
expect(result.client_name).toBe('gstack-test');
|
||||
expect(result.scopes).toEqual(['read', 'sources_admin']);
|
||||
expect(result.expires_at).toBe(1234567890);
|
||||
});
|
||||
|
||||
test('legacy transport (token name as clientId, no gbrain_cl_ prefix)', async () => {
|
||||
@@ -202,11 +150,6 @@ describe('whoami op contract', () => {
|
||||
});
|
||||
|
||||
describe('whoami op metadata', () => {
|
||||
test('description documents OAuth source grant fields', () => {
|
||||
expect(whoami.description).toContain('source_id');
|
||||
expect(whoami.description).toContain('federated_read');
|
||||
});
|
||||
|
||||
test('scope is read (any authenticated caller can introspect itself)', () => {
|
||||
expect(whoami.scope).toBe('read');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user