mirror of
https://github.com/garrytan/gbrain.git
synced 2026-08-14 08:53:22 +00:00
* feat: v0.19.0 — skillify loop + AGENTS.md compat + brain-first convention This is the v0.19.0 release. The branch ships four new CLI commands, a refactor to check-resolvable, and an expansion of the brain-first convention for sub-agent tool discovery. The original commit message described only the convention expansion, undercounting the scope by ~5x; this amend captures the full release. NEW COMMANDS - gbrain skillify scaffold <name> — 4 stub files + idempotent resolver row - gbrain skillify check [path] — 10-item post-task audit (promoted) - gbrain skillpack list / install — curated 25-skill bundle, atomic install - gbrain skillpack diff <name> — per-file diff preview - gbrain routing-eval — dedicated CI verb for Check 5 fixtures CHECK-RESOLVABLE REFACTOR - Accepts AGENTS.md as a resolver file alongside RESOLVER.md, at either the skills directory or one level up (workspace root layout). - Auto-derives the skill manifest by walking skills/*/SKILL.md when manifest.json is missing. - Splits ResolvableReport into errors[] + warnings[] so advisory checks (filing audit, routing gaps, DRY violations) don't break CI by default. - New --strict opt-in flag promotes warnings to exit 1. BRAIN-FIRST CONVENTION - skills/conventions/brain-first.md expanded from 5-step lookup guide to full sub-agent reference: tool inventory, lookup chain, score thresholds, authority hierarchy, sync rules, entity page conventions, sub-agent propagation rule. PRODUCTION-READINESS HARDENING (this branch's review pass) - routing-eval --llm: emits stderr placeholder notice + runs structural layer only. README, CHANGELOG, CLI help all rewritten consistently. Was a silent no-op against documented contract. - skillpack installer: receipt comment in fence (cumulative-slugs="...") preserves single-skill-install accumulation while letting install --all prune removed bundle skills cleanly. Unknown rows preserved + stderr warning for the operating agent. Pre-v0.19 fences upgrade silently. - skillify scaffold: resolver-row regex broadened to detect backticked, quoted, and bare path forms. No duplicate row on --force after the user normalizes formatting. - scripts/check-privacy.sh: now wired into package.json test chain so the wintermute-ban rule is actually enforced. New regression test. - E2E Tier 2 (LLM skills) promoted from schedule-only to required per-PR CI. Local Tier 1 + Tier 2 verified clean. - Stale v0.17/v0.18 version labels rewritten across new files. TESTS - test/routing-eval-cli.test.ts: 4 cases covering --llm warn semantics - test/privacy-script-wired.test.ts: regression guard for CI wiring - test/skillpack-install.test.ts: 4 new cases for receipt + cumulative + unknown-row preserve+warn + pre-v0.19 upgrade path - test/skillify-scaffold.test.ts: 4 new cases for broadened regex VERIFICATION - bun test: 2237 pass / 18 known PGLite-contention flakes (CI green; documented as P3 dev-experience in TODOS.md) - bun run typecheck: clean - bun run test:e2e: 18/19 files green (1 pre-existing flake on master, not caused by this branch — verified via git stash) - llms.txt + llms-full.txt regenerated to match README + CHANGELOG Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: scrub banned fork name from public artifacts The privacy guard wired into the test chain in this branch caught 5 pre-existing references to the banned OpenClaw fork name in CHANGELOG.md (2x), skills/migrations/v0.19.0.md (1x), src/cli.ts (1x), and src/commands/sync.ts (1x). All originated in master's v0.19.0 release notes and migration doc when the privacy script existed but wasn't wired into CI yet. Replacements per CLAUDE.md privacy mapping: - Origin-story copy (CHANGELOG layer narratives, code comments naming the production deployment that drove the feature) → "Garry's OpenClaw" - Reader-facing migration step → "your OpenClaw" No code semantics changed. Comments + headings only. Verification: scripts/check-privacy.sh exits 0, full CI guard chain green (privacy + jsonb + progress + wasm + typecheck). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: bump VERSION to 0.24.0 + new CHANGELOG entry Bump branch version above master's v0.21.0 per CLAUDE.md "CHANGELOG + VERSION are branch-scoped" rule. The new v0.24.0 entry at the top of CHANGELOG covers what THIS branch adds vs master: - routing-eval --llm honesty pass (4-surface contract drift fix) - skillpack installer cumulative-receipt + unknown-row preserve+warn (the Codex-caught regression that would have shipped in master if the original v0.19.0 had landed without this branch's review pass) - skillify scaffold resolver-row regex broadening (backtick + quoted + bare forms; idempotency contract preserved under hand-editing) - 5 banned-name leaks scrubbed from public artifacts - check-privacy.sh wired into CI test chain + regression guard test - 7 stale v0.17/v0.18 version labels rewritten across 5 files - Tier 2 (LLM-skills E2E) promoted from schedule-only to required per-PR VERSION 0.21.0 → 0.24.0 package.json version field synced. llms.txt + llms-full.txt regenerated (no content drift; sizes match). Test suite: 62/62 green across the 5 test files this branch added or extended (routing-eval-cli, privacy-script-wired, skillpack-install, skillify-scaffold, build-llms). CI guards: privacy + jsonb + progress + wasm + typecheck all clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: update project documentation for v0.24.0 Auto-discovered drift via /document-release after the v0.24.0 hardening pass landed. All factual corrections clearly warranted by the diff. CLAUDE.md: - Skillpack installer: documented the cumulative-slugs receipt comment, install --all prune semantics, unknown-row preserve+warn behavior, and pre-v0.24 silent upgrade. Was previously vague about "tracks a skill manifest so install --update diffs cleanly" without explaining what the receipt is or why it matters. - routing-eval: replaced the false claim that --llm "opts into a Haiku tie-break layer for CI." Now correctly describes the placeholder semantic landed in v0.24.0 (stderr notice + structural-only run). README.md: - Skillpack section: added one paragraph on the receipt comment + the user-visible stderr message for hand-added rows. Connects the safe rerun promise to the v0.24.0 implementation that actually enforces it. CONTRIBUTING.md: - Running tests section: now recommends `bun run test` (full CI guard chain + typecheck + tests) before pushing. Names each guard so new contributors understand what catches what. The privacy guard (newly wired in v0.24.0) is one of these — without `bun run test` you'd skip it locally and find out from CI. llms-full.txt: regenerated to reflect CLAUDE.md changes. Verification: full guard chain green locally (privacy + jsonb + progress + wasm + typecheck). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Garry Tan <garry@ycombinator.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
117 lines
3.6 KiB
TypeScript
117 lines
3.6 KiB
TypeScript
/**
|
|
* Source-Type Boost Map
|
|
*
|
|
* Multiplies into ts_rank / vector cosine score at SQL build time so that
|
|
* curated content (originals/, concepts/, writing/) outranks bulk content
|
|
* (openclaw/chat/, daily/, media/x/) for non-temporal queries.
|
|
*
|
|
* Keyed by slug prefix. Longest-prefix-match wins (sorted at lookup time
|
|
* inside sql-ranking.ts). Defaults grounded in the composition of the
|
|
* canonical brain at ~/git/brain/.
|
|
*
|
|
* Override via env: GBRAIN_SOURCE_BOOST="originals/:1.8,openclaw/chat/:0.3"
|
|
* Hard-exclude via env: GBRAIN_SEARCH_EXCLUDE="test/,scratch/"
|
|
*/
|
|
|
|
export const DEFAULT_SOURCE_BOOSTS: Record<string, number> = {
|
|
// Curated, opinionated, high-signal — Garry's own writing
|
|
'originals/': 1.5,
|
|
// Reusable knowledge frameworks
|
|
'concepts/': 1.3,
|
|
// Long-form essays / articles
|
|
'writing/': 1.4,
|
|
// Entity pages
|
|
'people/': 1.2,
|
|
'companies/': 1.2,
|
|
'deals/': 1.2,
|
|
// Notes from real meetings
|
|
'meetings/': 1.1,
|
|
// Ingested third-party content
|
|
'media/articles/': 1.1,
|
|
'media/repos/': 1.1,
|
|
// Neutral baselines (explicit for clarity)
|
|
'yc/': 1.0,
|
|
'civic/': 1.0,
|
|
// Bulk / noisy
|
|
'daily/': 0.8,
|
|
'media/x/': 0.7,
|
|
// Chat transcripts — massive, noisy, swamp keyword queries
|
|
'openclaw/chat/': 0.5,
|
|
};
|
|
|
|
/**
|
|
* Hard-excludes — slug prefixes that should never enter search results
|
|
* (unless explicitly opted-in via include_slug_prefixes).
|
|
*/
|
|
export const DEFAULT_HARD_EXCLUDES: string[] = [
|
|
'test/',
|
|
'archive/',
|
|
'attachments/',
|
|
'.raw/',
|
|
];
|
|
|
|
/**
|
|
* Parse GBRAIN_SOURCE_BOOST env var.
|
|
* Format: comma-separated prefix:factor pairs.
|
|
* Example: "originals/:1.8,openclaw/chat/:0.3"
|
|
*
|
|
* Malformed entries are skipped silently. Returns empty object if env is
|
|
* unset or unparseable in its entirety.
|
|
*/
|
|
export function parseSourceBoostEnv(env: string | undefined): Record<string, number> {
|
|
if (!env) return {};
|
|
const out: Record<string, number> = {};
|
|
for (const pair of env.split(',')) {
|
|
const idx = pair.lastIndexOf(':');
|
|
if (idx <= 0) continue;
|
|
const prefix = pair.slice(0, idx).trim();
|
|
const factor = Number.parseFloat(pair.slice(idx + 1).trim());
|
|
if (!prefix || !Number.isFinite(factor) || factor < 0) continue;
|
|
out[prefix] = factor;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Parse GBRAIN_SEARCH_EXCLUDE env var.
|
|
* Format: comma-separated slug prefixes.
|
|
* Example: "test/,scratch/,private/"
|
|
*
|
|
* Blank entries skipped. Returns empty array if env is unset.
|
|
*/
|
|
export function parseHardExcludesEnv(env: string | undefined): string[] {
|
|
if (!env) return [];
|
|
return env.split(',').map(s => s.trim()).filter(s => s.length > 0);
|
|
}
|
|
|
|
/**
|
|
* Resolve the effective boost map by merging defaults with env override.
|
|
* Env entries override defaults (shallow merge); env-only entries are added.
|
|
*/
|
|
export function resolveBoostMap(
|
|
envValue: string | undefined = process.env.GBRAIN_SOURCE_BOOST,
|
|
): Record<string, number> {
|
|
const override = parseSourceBoostEnv(envValue);
|
|
return { ...DEFAULT_SOURCE_BOOSTS, ...override };
|
|
}
|
|
|
|
/**
|
|
* Resolve the effective hard-exclude prefix list.
|
|
*
|
|
* - Defaults union with env-supplied excludes
|
|
* - Subtract any caller-supplied include_slug_prefixes (opt-back-in)
|
|
* - Caller-supplied exclude_slug_prefixes adds to the union
|
|
*/
|
|
export function resolveHardExcludes(
|
|
excludeOpt?: string[],
|
|
includeOpt?: string[],
|
|
envValue: string | undefined = process.env.GBRAIN_SEARCH_EXCLUDE,
|
|
): string[] {
|
|
const envExcludes = parseHardExcludesEnv(envValue);
|
|
const union = new Set<string>([...DEFAULT_HARD_EXCLUDES, ...envExcludes, ...(excludeOpt ?? [])]);
|
|
if (includeOpt?.length) {
|
|
for (const p of includeOpt) union.delete(p);
|
|
}
|
|
return Array.from(union);
|
|
}
|