mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-27 22:15:33 +00:00
* feat: brainstorm + lsd (v0.37 wave, pre-merge snapshot) Brainstorm + LSD bisociation idea generator. Will rebase + bump after master merge. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs: CHANGELOG voice tightening — strip meta-content from v0.37.1.0 entry CLAUDE.md gains an IRON RULE for CHANGELOG entries: the changelog describes what the user gets, not how the work happened. No mentions of review processes, plan files, decision tags, migration version drama, or 'what we caught and fixed before merging.' If a fact only exists because of the development workflow, it does not belong in release notes. Rewrite v0.37.1.0 entry to comply: cut the 'what we caught' section (architectural review drama), the 'plan + reviews' bullet, and the migration-renumbering aside. Entry shrinks 67 → 56 lines, every sentence now answers 'what can I do / how do I use it / what should I watch for.' Regenerated llms-full.txt to absorb the CLAUDE.md voice update. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
66 lines
2.2 KiB
TypeScript
66 lines
2.2 KiB
TypeScript
/**
|
|
* v0.37.0 — domain-bank distance normalization (D6 + codex r2 #9).
|
|
*
|
|
* Pinned cases from the codex-r2 fix: same-vector → 0, orthogonal → 0.5,
|
|
* opposite → 1, missing-vector → caller responsibility (skipped at retrieval).
|
|
*/
|
|
|
|
import { describe, test, expect } from 'bun:test';
|
|
import { normalizedCosineDistance } from '../../src/core/brainstorm/domain-bank.ts';
|
|
|
|
function v(...nums: number[]): Float32Array {
|
|
return new Float32Array(nums);
|
|
}
|
|
|
|
describe('normalizedCosineDistance — codex r2 #9 pinned cases', () => {
|
|
test('same vector → distance 0 (identical)', () => {
|
|
const a = v(0.6, 0.8, 0.0);
|
|
expect(normalizedCosineDistance(a, a)).toBeCloseTo(0, 6);
|
|
});
|
|
|
|
test('orthogonal unit vectors → distance 0.5 (neutral)', () => {
|
|
const x = v(1, 0, 0);
|
|
const y = v(0, 1, 0);
|
|
expect(normalizedCosineDistance(x, y)).toBeCloseTo(0.5, 6);
|
|
});
|
|
|
|
test('opposite unit vectors → distance 1 (maximally far)', () => {
|
|
const x = v(1, 0, 0);
|
|
const y = v(-1, 0, 0);
|
|
expect(normalizedCosineDistance(x, y)).toBeCloseTo(1, 6);
|
|
});
|
|
|
|
test('45-degree separation lands between 0 and 0.5', () => {
|
|
// cos(45°) ≈ 0.707, so cosDist ≈ 0.293, halved → 0.146
|
|
const x = v(1, 0);
|
|
const y = v(Math.sqrt(0.5), Math.sqrt(0.5));
|
|
const d = normalizedCosineDistance(x, y);
|
|
expect(d).toBeGreaterThan(0.1);
|
|
expect(d).toBeLessThan(0.2);
|
|
});
|
|
|
|
test('zero-vector edge → 0.5 (neutral, no division-by-zero)', () => {
|
|
const z = v(0, 0, 0);
|
|
const a = v(1, 1, 1);
|
|
expect(normalizedCosineDistance(z, a)).toBeCloseTo(0.5, 6);
|
|
});
|
|
|
|
test('dimension mismatch throws', () => {
|
|
expect(() => normalizedCosineDistance(v(1, 0), v(1, 0, 0))).toThrow(/dim mismatch/);
|
|
});
|
|
|
|
test('result is symmetric: d(a,b) === d(b,a)', () => {
|
|
const a = v(0.3, 0.4, 0.5);
|
|
const b = v(0.7, 0.1, 0.2);
|
|
expect(normalizedCosineDistance(a, b)).toBeCloseTo(normalizedCosineDistance(b, a), 6);
|
|
});
|
|
|
|
test('result is bounded [0, 1] even on non-unit vectors', () => {
|
|
const a = v(10, 0, 0);
|
|
const b = v(0, 5, 0);
|
|
const d = normalizedCosineDistance(a, b);
|
|
expect(d).toBeGreaterThanOrEqual(0);
|
|
expect(d).toBeLessThanOrEqual(1);
|
|
});
|
|
});
|