mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-31 04:07:52 +00:00
Atom-extraction page discovery hardcoded EXTRACTABLE_PAGE_TYPES and ignored the active pack's `extractable: true` flags, so a type declared extractable in the manifest (e.g. `note`) never actually extracted. Closes the D2 TODO the code already flagged (extract-atoms.ts: 'future pack-aware refactor ... pull from the active pack manifest'). Resolve the allowlist as: legacy hardcoded floor UNION the pack's extractable types, MINUS synthesis outputs (atom, concept — extracting from these would loop, since concepts are synthesized from atoms). Mirrors facts/eligibility.ts, which excludes concept the same way. Back-compat: gbrain-base brains keep every legacy target via the union; fail-soft falls back to the legacy floor if the pack can't load. - pure unionExtractableTypes() policy, unit-tested - discoverExtractablePages + countExtractAtomsBacklog resolve from the pack - page-discovery fixture updated (note now extracts; concept stays excluded) Co-authored-by: Paolo Belcastro <p3ob7o@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
40 lines
1.7 KiB
TypeScript
40 lines
1.7 KiB
TypeScript
/**
|
|
* Pack-driven extractable-type allowlist (unionExtractableTypes): honors the
|
|
* schema-pack manifest's `extractable: true` flags while preserving the legacy
|
|
* hardcoded floor and excluding synthesis outputs. Closes the D2 TODO in
|
|
* extract-atoms.ts (page discovery was ignoring the pack's extractable flag, so
|
|
* a type declared extractable — e.g. `note` — never actually extracted).
|
|
*/
|
|
import { describe, test, expect } from 'bun:test';
|
|
import { unionExtractableTypes } from '../src/core/cycle/extract-atoms.ts';
|
|
|
|
const LEGACY = ['meeting', 'source', 'article', 'video', 'book', 'original'];
|
|
|
|
describe('unionExtractableTypes', () => {
|
|
test('legacy floor is always present (back-compat)', () => {
|
|
const r = unionExtractableTypes([]);
|
|
for (const t of LEGACY) expect(r).toContain(t);
|
|
});
|
|
|
|
test('pack-declared extractable types are added (e.g. note)', () => {
|
|
const r = unionExtractableTypes(['note', 'writing']);
|
|
expect(r).toContain('note');
|
|
expect(r).toContain('writing');
|
|
for (const t of LEGACY) expect(r).toContain(t);
|
|
});
|
|
|
|
test('synthesis outputs are excluded even when the pack marks them extractable', () => {
|
|
// gbrain-base declares `concept` extractable:true, but extracting atoms FROM
|
|
// concepts would loop (concepts are synthesized from atoms).
|
|
const r = unionExtractableTypes(['note', 'concept', 'atom']);
|
|
expect(r).toContain('note');
|
|
expect(r).not.toContain('concept');
|
|
expect(r).not.toContain('atom');
|
|
});
|
|
|
|
test('no duplicates when the pack repeats a legacy type', () => {
|
|
const r = unionExtractableTypes(['meeting', 'source']);
|
|
expect(r.filter((t) => t === 'meeting')).toHaveLength(1);
|
|
});
|
|
});
|