Files
gbrain/test/skill-catalog-block-scalar.test.ts
T
1eb430a2df v0.42.37.0 fix(security,ingest): source-isolation grant enforcement + non-string frontmatter guard + papercuts (#1999)
* fix(security): scope cross-source reads to the caller grant; close get_page exact-path leak

One shared resolveRequestedScope() routes every source-scoped read op
(query, code_callers/callees, search_by_image, code_blast/flow, get_page)
through a single fail-closed trust+grant ladder: a remote caller's __all__
collapses to its granted sources (never the whole brain) and an explicit
out-of-grant source_id is rejected. get_page's exact-match path now honors a
federated grant via getPage(sourceIds[]) in both engines. Legacy bearer tokens
carry their stored permissions.source_id grant (bounded, never widened). Also
retries getConfig on transient connection loss.

Closes #1924, #1371, #1393, #1336, #1603.

* fix(ingest): non-string frontmatter no longer aborts lint/sync; embed/hook/catalog papercuts

Parser coerces a non-string title to a string and falls back to inference for
slug/type (never fabricating a "123" slug), with a lint NON_STRING_FIELD finding
surfacing the malformed frontmatter; a defensive guard in content-sanity stops a
non-string title from crashing the whole lint/sync run brain-wide. Plus: embed
--catch-up no longer arms the overflowed 32-bit budget timer (and surfaces
unembeddable chunks); the frontmatter pre-commit hook ships a correct .md/.mdx
regex; and the skill catalog parses YAML block-scalar descriptions.

Closes #1883, #1658, #1556, #1948, #1946, #1840, #1711.

* v0.42.37.0 fix(security,ingest): source-isolation grant enforcement + non-string frontmatter guard + papercuts

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs: add NON_STRING_FIELD frontmatter validation class to docs for v0.42.37.0

The v0.42.37.0 non-string-frontmatter fix added an eighth validation
class (NON_STRING_FIELD / lint code frontmatter-non-string-field). Update
the two current-state docs that enumerate the validation classes:
- skills/frontmatter-guard/SKILL.md (seven->eight + table row)
- docs/integrations/pre-commit.md (seven->eight + table row)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 21:19:25 -07:00

50 lines
2.3 KiB
TypeScript

/**
* #1711 — skill catalog parses YAML block-scalar `description:` fields.
*
* Pre-fix `parseDescriptionField` matched `description: |` with a greedy regex
* and captured the bare block indicator (`|` / `>`) as the description, so a
* skill written with `description: |` showed a literal "|" in the catalog
* instead of its text.
*/
import { describe, test, expect } from 'bun:test';
import { oneLineDescription } from '../src/core/skill-catalog.ts';
describe('oneLineDescription — block scalars', () => {
test('literal block scalar (|) folds indented lines into the description', () => {
const raw = ['name: demo', 'description: |', ' First line of the description.', ' Second line continues it.'].join('\n');
const out = oneLineDescription(raw, 'body fallback');
expect(out).toBe('First line of the description. Second line continues it.');
expect(out).not.toContain('|');
});
test('folded block scalar (>) is parsed too', () => {
const raw = ['description: >', ' Folded description', ' across two lines.'].join('\n');
expect(oneLineDescription(raw, 'fallback')).toBe('Folded description across two lines.');
});
test('chomping/indent indicators (|-, >+, |2) are recognized', () => {
const raw = ['description: |-', ' Trimmed block scalar.'].join('\n');
expect(oneLineDescription(raw, 'fallback')).toBe('Trimmed block scalar.');
});
test('block scalar with no indented continuation falls back to body prose', () => {
const raw = ['description: |', 'name: next-key'].join('\n');
expect(oneLineDescription(raw, 'Body prose line')).toBe('Body prose line');
});
});
describe('oneLineDescription — inline scalars still work', () => {
test('plain inline description', () => {
expect(oneLineDescription('description: A plain one-liner', 'fallback')).toBe('A plain one-liner');
});
test('quoted inline description strips surrounding quotes', () => {
expect(oneLineDescription('description: "Quoted desc"', 'fallback')).toBe('Quoted desc');
expect(oneLineDescription("description: 'Single quoted'", 'fallback')).toBe('Single quoted');
});
test('absent description falls back to first prose line', () => {
expect(oneLineDescription('name: x', 'The first prose line.')).toBe('The first prose line.');
});
});