mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-27 22:15:33 +00:00
* feat(engine): listEnrichCandidates source-aware candidate selection (#1700) One SQL query per engine: thin-filter + per-page source-correct inbound-link count (to_page_id = p.id, mentions excluded) + enriched_at recency guard + whitelisted ORDER BY (ENRICH_ORDER_SQL) + LIMIT, returning a lightweight projection (no page bodies). EnrichCandidate/EnrichCandidatesOpts types. pg + pglite parity, pinned by engine-parity.test.ts. * feat(enrich): gbrain enrich --thin brain-internal grounded synthesis (#1700) Develops stub pages at scale by consolidating scattered brain knowledge (search + backlinks + facts + raw_data) into one grounded gateway.chat call per page. Resumable (op-checkpoint), budget-capped (best-effort under --workers), per-page advisory lock, put_page write-through. CLI + thin-client refuse + Minion handler. Includes codex-review fixes: sanitizeContext neutralizes the <context> envelope delimiters (P1 injection escape); background fan-out idempotency key carries the run fingerprint (P1); post-hoc budget-overage flag via new BudgetTracker.cap getter (P1); checkpoint flush on budget exhaustion (P2). Accepts the documented best-effort in-flight-cancel limitation (D5) with an explicit code note. * feat(cycle): enrich_thin opt-in autopilot phase (#1700) Default-OFF trickle around runEnrichCore: develops a few thin pages per source per tick so the brain compounds over time. Per-source cap enforced as min(per-source, brain-wide remaining) with brain-wide total + walltime caps (P2 fix: per-source max_cost_usd was parsed but never enforced). Wired into CyclePhase / ALL_PHASES / PHASE_SCOPE / NEEDS_LOCK + dispatch. * chore: bump version and changelog (v0.42.6.0) gbrain enrich --thin batch enrichment (#1700) + codex-review fixes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
67 lines
2.7 KiB
TypeScript
67 lines
2.7 KiB
TypeScript
/**
|
|
* v0.38 PHASE_SCOPE coverage regression.
|
|
*
|
|
* The phase-scope taxonomy in `src/core/cycle.ts` is documentation, not
|
|
* runtime enforcement (deferred TODO per plan). This test guards the
|
|
* static contract:
|
|
*
|
|
* 1. Every `ALL_PHASES` entry has a `PHASE_SCOPE` entry. New phases
|
|
* added without taxonomy declaration fail this test.
|
|
* 2. No extra `PHASE_SCOPE` entries beyond `ALL_PHASES`. Stale entries
|
|
* from removed phases fail this test.
|
|
* 3. Every value is one of 'source' | 'global' | 'mixed' (type check).
|
|
*
|
|
* Future fan-out wave consumes PHASE_SCOPE directly; this test makes
|
|
* the contract enforceable at the unit-test layer.
|
|
*/
|
|
import { describe, test, expect } from 'bun:test';
|
|
import { ALL_PHASES, PHASE_SCOPE, type PhaseScope } from '../src/core/cycle.ts';
|
|
|
|
const VALID_SCOPES: ReadonlyArray<PhaseScope> = ['source', 'global', 'mixed'];
|
|
|
|
describe('PHASE_SCOPE coverage', () => {
|
|
test('every ALL_PHASES entry has a PHASE_SCOPE entry', () => {
|
|
const missing = ALL_PHASES.filter(p => !(p in PHASE_SCOPE));
|
|
expect(missing).toEqual([]);
|
|
});
|
|
|
|
test('no extra PHASE_SCOPE entries beyond ALL_PHASES', () => {
|
|
const all = new Set<string>(ALL_PHASES);
|
|
const extra = Object.keys(PHASE_SCOPE).filter(p => !all.has(p));
|
|
expect(extra).toEqual([]);
|
|
});
|
|
|
|
test('every PHASE_SCOPE value is source | global | mixed', () => {
|
|
const invalid: string[] = [];
|
|
for (const [phase, scope] of Object.entries(PHASE_SCOPE)) {
|
|
if (!VALID_SCOPES.includes(scope)) {
|
|
invalid.push(`${phase}: ${scope}`);
|
|
}
|
|
}
|
|
expect(invalid).toEqual([]);
|
|
});
|
|
|
|
test('all 22 phases covered (regression on accidental omission)', () => {
|
|
// Pin the count so a future PR that adds a phase to ALL_PHASES
|
|
// without updating PHASE_SCOPE notices here too. The v0.39.1.0
|
|
// master merge brought in the 17th phase (`schema-suggest`); v0.41
|
|
// adds 'extract_atoms' + 'synthesize_concepts' (T9 lens packs) +
|
|
// 'conversation_facts_backfill' (v0.41.11.0) for 20; v0.41.39 (#1700)
|
|
// adds 'enrich_thin' and v0.42.0.0 adds 'skillopt' for a total of 22.
|
|
expect(ALL_PHASES.length).toBe(22);
|
|
expect(Object.keys(PHASE_SCOPE).length).toBe(22);
|
|
});
|
|
|
|
test('embed remains global (the headline brain-wide phase)', () => {
|
|
// Pin embed specifically — codex r1 P0-1 called this out as the
|
|
// canonical reason per-source locks aren't sufficient for true
|
|
// fan-out. If future code makes embed source-scopable, this fails
|
|
// and forces a corresponding lift in the fan-out wave.
|
|
expect(PHASE_SCOPE.embed).toBe('global');
|
|
});
|
|
|
|
test('sync remains source-scoped (the headline per-source phase)', () => {
|
|
expect(PHASE_SCOPE.sync).toBe('source');
|
|
});
|
|
});
|