mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-30 19:49:14 +00:00
73bbbde01dcdf5da4bca9fa57be44a5cd8ebd60d
17
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
805814451e |
v0.42.26.0 docs(supabase): update connection-string setup to new UI + Transaction pooler (#1848) (#1875)
* docs(supabase): update connection-string setup to new UI + Transaction pooler Supabase moved the connection string under "Connect" in the top nav and now shows three options (Direct, Transaction pooler, Session pooler). Update the tutorial, gbrain init prompts, the setup skill, the verify runbook, and the live-sync guide to recommend the Transaction pooler (port 6543) — which gbrain is tuned for (prepared statements disabled, DDL/locks routed to a derived direct connection). Document the IPv4 footgun: the derived direct connection is IPv6-only, so on IPv4-only hosts reads work but sync silently skips pages. Tutorial 7c now leads with the free fix (GBRAIN_DIRECT_DATABASE_URL -> Session pooler, port 5432) and keeps the IPv4 add-on as the paid alternative. Removes stale "transaction mode breaks sync (.begin() is not a function)" warnings and the port-6543 "Session pooler" mislabels. Extends PR #1848 by @FilipHarald. * chore: bump version and changelog (v0.42.26.0) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
a57d98b813 |
v0.42.12.0 feat: self-upgrading gbrain — invocation-riding update check + opt-in auto-upgrade (#1798)
* feat(self-upgrade): decision/cache/snooze foundation + atomic binary self-update Pure decideSelfUpgrade (invocation + autopilot channels), atomic untrusted cache + escalating snooze + shared marker grammar (forged-marker rejection), semver helpers, and real darwin-arm64/linux-x64 binary self-update (download -> fsync -> smoke -> atomic rename; failure leaves old binary intact). Tests incl. real-HTTP-server swap E2E. * feat(self-upgrade): check-update cache/markers, self-upgrade command, CLI heartbeat hook check-update gains gstack-style cache/snooze/markers + refreshUpdateCache + exported fetchLatestRelease. New 'gbrain self-upgrade' command. cli.ts emits the update marker on every invocation (cache-read-only hot path, detached single-flight refresh, skip-set + recursion guard + NODE_ENV=test gate). * feat(self-upgrade): autopilot silent channel, doctor check, runPostUpgrade setup, config + identity marker autopilot opt-in silent channel (auto+quiet+idle, swap-only+breadcrumb+exit-relaunch) + installSystemd Restart=always + migrateSystemdUnitToRestartAlways. doctor self_upgrade_health. runPostUpgrade applySelfUpgradeSetup (one-time consent + systemd rewrite). init defaults mode=notify. config self_upgrade plane + KNOWN_CONFIG_KEYS. get_brain_identity carries update marker. * docs(self-upgrade): gbrain-upgrade agent skill, RESOLVER/manifest, auto-update doc reversal, HEARTBEAT New skills/gbrain-upgrade agent flow (mirror gstack-upgrade) wired into RESOLVER + manifest. upgrades-auto-update.md reversed to document opt-in auto + conservative gates. HEARTBEAT self-upgrade --check-only line. llms-full regenerated. * chore: bump version and changelog (v0.42.12.0) Self-upgrading gbrain: invocation-riding update marker + opt-in autopilot silent channel + real atomic binary self-update. Mirrors gstack's mechanism. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(self-upgrade): write just-upgraded-from breadcrumb + clear stale cache after upgrade Codex ship-review P3: the CLI startup hook reads just-upgraded-from to print the one-time JUST_UPGRADED confirmation, but nothing wrote it — dead path. runUpgrade now writes the breadcrumb (covers full + --swap-only) and clears the update-check cache + snooze so a now-applied 'upgrade available' marker stops nudging. * feat(self-upgrade): surface what's-new in notify + wire agent integration (AGENTS.md, HEARTBEAT) + e2e - self-upgrade --check-only --json now includes changelog_diff + release_url (export fetchChangelog); the gbrain-upgrade skill shows 3-5 what's-new bullets before the 4-option prompt instead of just version numbers. - setup injects a self-upgrade marker protocol into AGENTS.md so interactive agents (Claude Code, Codex) act on the UPGRADE_AVAILABLE stderr marker — the piece that makes notify actually fire for them. - HEARTBEAT daily beat routes through the gbrain-upgrade skill (OpenClaw/Hermes cron cadence); auto-mode daemons ride the autopilot tick. - e2e: real subprocess invocation proves the marker fires (notify emits; off/snooze/up-to-date silent; JUST_UPGRADED fires+clears; --quiet suppresses). Serial test: --check-only surfaces the changelog. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
54a0629745 |
v0.37.8.0 feat: voyage-code-3 discoverability + reindex-code cost-preview fix (#1267)
* v0.37.6.0 feat: voyage-code-3 discoverability + reindex-code cost-preview fix For agents indexing source code with gbrain, the right embedding model is now obvious — and the brain tells you so out loud. Decision tree + Topology 3 doc + Topology 3 setup-skill pointer + runtime stderr nudge from `gbrain reindex --code` against non-code-tuned models. Same diff fixes the stale hardcoded `text-embedding-3-large` in the cost preview that would have made the nudge land badly. Tests: 3 new files (recipe regression, nudge logic + CLI integration, cost-preview IRON-RULE regression). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * todos: file pre-existing doctor-report-remote score regression (#1215 follow-up) Noticed during /ship of v0.37.6.0. The skill_brain_first check added in v0.37.3.0 (#1215) appears to tank the doctor health score on fresh PGLite test brains, causing test/doctor-report-remote.test.ts:65 to fail with health_score: 50 (expects >=70). Pre-existing on master; not in this branch's touch surface. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
cb5bf1d332 |
v0.31.10 feat: add cold-start and ask-user skills (#802)
* feat: add cold-start and ask-user skills cold-start: Day-one brain bootstrapping that sequences the highest-leverage data sources (contacts, calendar, email, conversations, social, archives) to go from empty brain to useful brain. Recommends ClawVisor for credential safety. Each phase is independently valuable and gated on user consent. Includes resume protocol for interrupted sessions. ask-user: Platform-agnostic choice-gate pattern for presenting users with 2-4 options and stopping execution until they respond. Works with Telegram inline buttons, Discord, CLI, or Hermes clarify tool. Adapted from the Wintermute ask-user pattern for the general gbrain ecosystem. Also: - Updated manifest.json with both new skills - Updated RESOLVER.md with cold-start triggers and ask-user convention - Updated setup/SKILL.md to point to cold-start as natural next step - Updated GBRAIN_SKILLPACK.md with Getting Started section * fix: make cold-start the automatic next step after setup - Add Phase J to setup skill — transitions directly into cold-start after verification passes, not as a 'next steps' bullet - Agent MUST offer cold-start, not just mention it - Add anti-pattern: 'ending setup without offering cold-start' - Update output format to flow into cold-start prompt - Track deferred state if user declines * safety: make ClawVisor required for API access, not optional Phase 0 is now 'ClawVisor Setup (Required for API Access)' — not 'Credential Gateway Setup' with three options. The framing changed: - ClawVisor is the safe path. Direct OAuth is not offered as an alternative. - If user declines ClawVisor, agent skips to offline-only imports (markdown, conversation exports, Twitter archive, file archives). - Explicitly: 'Do NOT offer direct OAuth as an alternative.' - Safety boundary callout explains why: raw OAuth tokens + AI agent = uncontrolled attack surface (prompt injection → full Google account). - Anti-pattern #1 is now 'Giving the agent raw OAuth tokens.' - Revocation advantage highlighted: disable access in one click. The contract, description, manifest, and skillpack doc all updated to say 'uses' not 'recommends'. * fix: PR #802 ask-user/cold-start clear repo test gates Four contributor bugs in PR #802 fail existing test gates: - ask-user/SKILL.md missing required Contract / Anti-Patterns / Output Format sections (test/skills-conformance.test.ts). - cold-start/SKILL.md description references trigger phrase "now what?" but the triggers: list omits it (test/resolver.test.ts round-trip). - ask-user is in skills/manifest.json but has no trigger row in RESOLVER.md, breaking manifest reachability (test/resolver.test.ts). - cold-start/SKILL.md writes_to: declares daily/, media/, conversations/ which aren't in skills/_brain-filing-rules.json, failing test/check-resolvable.test.ts. Adds the missing skill sections, the missing trigger entries, and three filing-rules entries to legitimize cold-start's writes_to. The filing-rules additions describe daily/ as date-keyed (calendar + daily notes), media/ as format-prefixed for source-format ingest (media/x/{handle}/), and conversations/ for chat exports. Test surface: - bun test test/skills-conformance.test.ts → was 207 pass / 3 fail, now 209 pass / 0 fail. - bun test test/resolver.test.ts → was 82 pass / 2 fail, now 84 pass / 0 fail. - bun test test/check-resolvable.test.ts → was 24 pass / 1 fail, now 25 pass / 0 fail. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: scrub 'Hermes Agent' references from PR #802-introduced files CLAUDE.md privacy doctrine forbids naming private agent forks (Wintermute, Hermes, Neuromancer) in any public artifact: skills, README, CHANGELOG, PR titles, commit messages, comments. The canonical phrasing is "OpenClaw" or "your OpenClaw". PR #802 introduced three sites that violated the rule: - skills/ask-user/SKILL.md:79 section heading "With the `clarify` tool (Hermes Agent)". - skills/ask-user/SKILL.md:80 body line "Hermes agents have a built-in `clarify` tool". - skills/manifest.json ask-user description listed "Hermes clarify tool" alongside Telegram / Discord / CLI. Scrub is narrow: only the three PR-introduced sites. Pre-existing "Hermes" references elsewhere in the repo (README.md links to NousResearch/hermes-agent, docs/integrations/credential-gateway.md, docs/guides/cron-schedule.md, etc.) are intentional public-project references to the open-source Hermes Agent and stay in place. scripts/check-privacy.sh enforces the wintermute layer of the rule on every push; the Hermes / Neuromancer doctrine layer is doctrinal only. Future hardening (extending the script to also ban Hermes / Neuromancer in a precise allow-listed way) is filed as TODOS.md P8. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * v0.31.10 feat: cold-start + ask-user skills PR #802 ships the cold-start skill (day-one brain bootstrapping across 8 phases) and the ask-user skill (choice-gate pattern). Setup skill's Phase J auto-launches cold-start when verification passes, closing the "now what?" gap that every new gbrain user hits. Cold-start orchestrates existing recipes (email-to-brain, calendar-to-brain, x-to-brain) and skills (meeting-ingestion); it does not reinvent ingestion logic. State persists across agent crashes via ~/.gbrain/cold-start-state.json, matching the existing update-state.json convention. Trigger phrases include "cold start", "fill my brain", "now what?", "bootstrap", "import my data". Known limitations explicitly flagged in CHANGELOG: - ClawVisor required for API-backed phases (Contacts / Calendar / Gmail). v0.32 will restore the dual A / B pattern that recipes/email-to-brain.md and recipes/calendar-to-brain.md already document. - Phase-level resume granularity. Mid-phase failure restarts the phase from item 1; idempotent slug writes prevent duplicates. Per-item resume lands with the gbrain cold-start CLI counterpart in v0.32. CHANGELOG entry follows the canonical release-summary spec from CLAUDE.md:930: bold headline, 3-5 sentence lead, "What you can now do" section, "How it works under the hood", "Known limitations", "To take advantage of v0.31.10" block, "For contributors". Version bumps from 0.31.2 (branch base) past master's 0.31.3 to 0.31.10. Slots 0.31.4 through 0.31.9 are reserved for in-flight work; the gap is deliberate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Neuromancer <neuromancer@garryslist.org> Co-authored-by: Garry Tan <garrytan@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
8392d434a9 |
v0.29.2 feat: thin-client mode (gbrain init --mcp-only + gbrain remote ping/doctor + topologies) (#732)
* feat(config): add remote_mcp field + isThinClient() helper Adds a top-level optional remote_mcp config block to GBrainConfig (issuer_url, mcp_url, oauth_client_id, oauth_client_secret) for thin-client installs that consume a remote `gbrain serve --http` over MCP instead of running a local engine. isThinClient(config) returns true when remote_mcp is set; used by the CLI dispatch guard, doctor branch, and init re-run guard. The engine field stays as today (postgres|pglite); thin-client mode is a separate config field, NOT an engine kind extension (codex outside-voice review flagged the engine='remote' extension as overreach). GBRAIN_REMOTE_CLIENT_SECRET env var overrides the config-file value at load time so the secret can stay out of disk for headless agents. Foundation commit for multi-topology v1; no behavior change yet. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(probe): outbound OAuth + MCP smoke probes Adds three pure async functions over the standard fetch API: - discoverOAuth(issuerUrl): GET /.well-known/oauth-authorization-server - mintClientCredentialsToken(tokenEndpoint, id, secret): POST /token - smokeTestMcp(mcpUrl, accessToken): POST /mcp initialize Discriminated 'ok=true' / 'ok=false + reason' return shapes so callers render error messages consistently. No SDK dependency to keep init's setup-flow scope tight; Lane B's mcp-client.ts will pull in the official @modelcontextprotocol/sdk Client for full session semantics. Used by both 'gbrain init --mcp-only' (Lane A's setup smoke) and runRemoteDoctor (Lane A's thin-client doctor checks). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(init): --mcp-only branch + re-run guard Adds 'gbrain init --mcp-only' for thin-client setup. Required flags (or env vars): --issuer-url OAuth root (e.g. https://host:3001) --mcp-url MCP tool dispatch path (e.g. https://host:3001/mcp) --oauth-client-id, --oauth-client-secret Pre-flight runs three smoke probes (discovery, token round-trip, MCP initialize) BEFORE writing the config — fail-fast on bad URL beats fail-late on bad credentials. On success, writes ~/.gbrain/config.json with remote_mcp set and NO local DB created. Re-run guard (A8): when ~/.gbrain/config.json already has remote_mcp, 'gbrain init' (any flag set) refuses without --force. Catches the scripted-setup-loop friction from the user-reported scenario where re-running setup-gbrain on a thin-client machine kept trying to re-create a local DB. Two URLs in config (issuer + mcp) instead of one because OAuth discovery + /token live at the issuer root while tool dispatch is at /mcp — they compose from a common base in practice but reverse-proxy setups need them explicit (codex review #2). Tests: 15 cases covering happy path, env-var-supplied secret stays out of disk, all four required-flag missing-error paths, three smoke-failure paths, network-unreachable path, and the four re-run guard variants (default/--pglite/--mcp-only without --force / with --force). Uses async Bun.spawn (NOT execFileSync) — sync exec deadlocks against in-process HTTP fixtures because the parent's event loop can't accept connections while sync-blocked on a child. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(doctor): runRemoteDoctor for thin-client mode Replaces every DB-bound check from runDoctor() with a tighter set scoped to 'is the remote MCP we configured actually reachable?'. Five checks: - config_integrity (URL fields well-formed) - oauth_credentials (secret resolvable from env or config file) - oauth_discovery (GET /.well-known/oauth-authorization-server) - oauth_token (POST /token client_credentials) - mcp_smoke (POST /mcp initialize) Output shape matches the local doctor's Check surface so JSON consumers can union the two without conditional logic. schema_version is 2 (matches local doctor). collectRemoteDoctorReport() is the pure data collector; runRemoteDoctor() is the print/exit wrapper. Tests pin the data collector so we don't have to intercept stdout / process.exit. Tests: 12 cases over a tiny in-process HTTP fixture covering happy path, every probe failure mode (404/parse/auth/network/server-error), malformed-URL config integrity, missing-secret short-circuit, and the env-var-overrides-config-file secret resolution. withEnv() helper used for env mutations to satisfy the test-isolation lint. Module is added but not yet wired into the CLI doctor branch; the wiring lands in the next commit (cli dispatch guard + doctor routing). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(cli): thin-client dispatch guard + doctor routing Adds a single canonical refusal at the top of handleCliOnly() for the 9 DB-bound commands when ~/.gbrain/config.json has remote_mcp set: sync, embed, extract, migrate, apply-migrations, repair-jsonb, orphans, integrity, serve Single dispatch check (not 9 sprinkled assertLocalEngine calls per codex review #1) — avoids the blast radius of letting commands enter connectEngine before the check fires. Refused commands exit 1 with a canonical error naming the remote mcp_url. doctor branch routes to runRemoteDoctor when isThinClient(config) returns true; falls through to the existing local-doctor flow otherwise. Wires the module added in the previous commit into the user-facing CLI surface. Safe commands (init, auth, --version, --help, etc.) still work in thin-client mode and are NOT in the refused set. Tests: 14 cases — 9 refused commands × 1 each, 2 safe commands, 1 doctor-routing assertion (fingerprints the thin-client output by 'mode:"thin-client"' in JSON), 2 regression tests asserting local config still passes through normally. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(topologies): multi-topology architecture guide + setup skill Phase A.5 New docs/architecture/topologies.md covering three deployment shapes: 1. Single brain (today's default) 2. Cross-machine thin client (consume a remote brain over MCP) 3. Split-engine per-worktree (Conductor users with per-worktree code engines + shared remote artifacts brain) Each topology gets an ASCII diagram, when-it-fits guidance, and concrete setup recipes. Topology 3's alias-level routing footgun (wrong alias = silent wrong-brain writes) is called out explicitly per codex review #6. Topology 3 needs zero gbrain code changes — GBRAIN_HOME already overrides ~/.gbrain and 'gbrain serve --http --port N' already runs on any port. gstack composes these primitives on its side. skills/setup/SKILL.md gets Phase A.5 BEFORE the local-engine phases. Asks the user which topology fits, walks thin-client setup through 'gbrain init --mcp-only', skips Phases B/C/C.5/H entirely for thin clients (host's autopilot handles sync/extract/embed). README.md gets a one-line link to the topology doc from the Architecture section. llms-full.txt regenerated to include the new doc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(e2e): thin-client end-to-end skeleton Spins up 'gbrain serve --http' against real Postgres, registers a client with read,write,admin scope, runs 'gbrain init --mcp-only' from a separate tempdir GBRAIN_HOME, exercises the canonical thin-client flows: - init --mcp-only succeeds against the live host - doctor reports mode: thin-client + all checks green - sync is refused with the canonical thin-client error - re-running init refuses without --force Tier B flows (gbrain remote ping / doctor) will be added alongside their Lane B implementation. Skips when DATABASE_URL unset (matches the e2e gate convention used across the suite). Async Bun.spawn (NOT execFileSync) so the test event loop stays responsive — execFileSync deadlocks against in-process HTTP fixtures because the parent's event loop can't accept connections while sync-blocked on a child process. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(doctor): doctorReportRemote core for thin-client + run_doctor op Adds three new exports to src/commands/doctor.ts that the run_doctor MCP op + gbrain remote doctor CLI both consume: - DoctorReport interface schema_version=2 stable shape - computeDoctorReport(checks) status + health_score math - doctorReportRemote(engine) focused 5-check thin-client surface doctorReportRemote runs: 1. connection (engine reachable + page count via getStats) 2. schema_version (engine.getConfig('version') vs LATEST_VERSION) 3. brain_score (the 5-component composite) 4. sync_failures (file-plane JSONL count from gbrainPath('sync-failures.jsonl')) 5. queue_health (Postgres-only: stalled active jobs > 1h) Engine-agnostic: works on both Postgres and PGLite via engine.executeRaw + engine.getConfig + engine.getHealth — no reliance on db.getConnection() which is Postgres-only. Deliberately a focused subset of the local doctor surface, NOT a full mirror. Generalizing to lint/integrity/orphans is filed as follow-up pending demand. Local doctor (runDoctor) is unchanged; operators on the host machine still get the full check set. schema_version=2 matches the local doctor's --json output schema, so JSON consumers can union the two without conditional logic. Tests: 11 unit cases against PGLite covering the 5-check happy path, schema version reporting (latest), PGLite-specific queue_health informational message, and the score+status math via computeDoctorReport. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(mcp-client): outbound HTTP MCP client over @modelcontextprotocol/sdk New src/core/mcp-client.ts wraps the official SDK's Client + StreamableHTTPClientTransport with OAuth client_credentials minting, in-process token caching with expires_at, and refresh-on-401 retry. Public surface: - callRemoteTool(config, toolName, args) tool call w/ auto-refresh - unpackToolResult(res) parse content[0].text JSON - RemoteMcpError discriminated by `reason` Token cache: module-level Map keyed by mcp_url. CLI processes are short-lived; the cache amortizes when one invocation makes multiple calls (gbrain remote ping submits then polls). Persisting to disk would be a credential-on-disk surface for marginal benefit since /token round-trip is sub-100ms. 401 retry: ONLY for mid-session token rotation (initial good token → stale → 401). If the FIRST mint fails auth, surface immediately as RemoteMcpError(auth) — retry won't help when credentials are wrong from the start. If a fresh-mint-after-401 still 401s, surface as RemoteMcpError(auth_after_refresh) which the CLI renders with a hint pointing the operator at gbrain auth register-client. Used by gbrain remote ping (submit_job + get_job poll) and gbrain remote doctor (run_doctor). Test-only _clearMcpClientTokenCache export for fixture isolation. Tests: 13 unit cases over an in-process HTTP fixture mimicking gbrain serve --http (OAuth discovery + /token + /mcp JSON-RPC handshake). Covers happy path, token cache reuse + force-refresh, args passthrough, config-error paths (no remote_mcp / no secret), token mint 401, network unreachable, tool isError envelope, and unpackToolResult parse failures. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(operations): add run_doctor MCP op (admin scope, HTTP-reachable) New op in src/core/operations.ts wraps doctorReportRemote() and returns the structured DoctorReport JSON over MCP. scope: 'admin' (system-state read; not for routine consumers) localOnly: false (reachable over HTTP) mutating: false (safe to call repeatedly) params: {} (no caller arguments needed) First read-only diagnostic op exposed over HTTP MCP. Used by gbrain remote doctor — the matching client-side renderer lives in src/commands/remote.ts. Precedent: doctor only. Generalizing run_lint / run_integrity / run_orphans to MCP is filed as follow-up work pending demand. Local doctor stays unchanged; this op is the operator-friendly subset for remote callers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(remote): gbrain remote ping + gbrain remote doctor Two thin-client convenience commands that round-trip through the host's HTTP MCP endpoint: - gbrain remote ping submit_job(autopilot-cycle) → poll get_job → exit when terminal. The "I just wrote markdown, tell the host to re-index" affordance. - gbrain remote doctor run_doctor MCP op → render the host's DoctorReport → exit 0/1 based on status. Both require a thin-client install (~/.gbrain/config.json with remote_mcp). Local installs get a clear error pointing at the local equivalents. Polling backoff (ping): 1s × 30s, then 5s × 5min, then 10s. Default cap 15min, configurable via `--timeout`. Without backoff, a 5-min cycle would burn 300 round-trips against the host's rate limiter. Payload uses `data: {phases: [...]}`, NOT `params:` — the submit_job op shape takes `data`. Codex review #8 catch. NO `repo` arg passed to autopilot-cycle — uses the server's configured brain repo. This sidesteps TODO #1144 (sync_brain repo-path validation for caller-controlled paths) entirely. src/cli.ts wires the `remote` subcommand into CLI_ONLY + the dispatch. Help (`gbrain remote --help`) and unknown-subcommand handling included. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(e2e): thin-client Tier B + scope-mismatch regression Extends the existing test/e2e/thin-client.test.ts with three new cases: 1. gbrain remote doctor returns the host's DoctorReport — pins the run_doctor MCP op round-trip. Asserts schema_version=2, all 5 check names present, connection + schema_version ok against a fresh host. 2. gbrain remote ping triggers autopilot-cycle and returns terminal state — pins the submit_job → poll → terminal wire path. Accepts any terminal state (success / failed / dead / cancelled / timeout) because autopilot on an empty no-repo brain may fail-fast in the sync phase. What this test pins is the JSON shape (job_id present, state populated), NOT cycle success on a no-repo fixture. 3. read+write client cannot call run_doctor — codex review #7 regression guard. Registers a separate client with `--scopes "read write"` (no admin), runs `gbrain remote doctor` against it, asserts exit 1 with auth/auth_after_refresh/tool_error reason. Keeps the verification flow honest: the canonical setup MUST require admin scope. `gbrain auth register-client` doesn't have --json, so the test parses the human output for "Client ID:" and "Client Secret:" lines via a helper. Test-level timeout bumped 60s → 120s for the ping wait + auth/init overhead. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: bump version and changelog (v0.29.2) v0.29.2 ships thin-client mode: gbrain init --mcp-only, gbrain remote ping/doctor, run_doctor MCP op, and the docs/architecture/topologies.md deployment guide. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
35967645f3 | fix: doctor --fix — 7 DRY violations resolved (inline Iron Law → convention reference) | ||
|
|
81b3f7afac |
feat: knowledge graph layer — auto-link, typed relationships, graph-query (v0.10.3) (#188)
* feat(schema): graph layer migrations v5/v6/v7 + GraphPath/health types
Schema foundation for v0.10.3 knowledge graph layer:
- v5: links UNIQUE constraint widened to (from, to, link_type) so the same
person can both works_at AND advises the same company as separate rows.
Idempotent for fresh + upgrade (drops both old constraint names first).
- v6: timeline_entries gets UNIQUE index on (page_id, date, summary) for
ON CONFLICT DO NOTHING idempotency at DB level.
- v7: drops trg_timeline_search_vector trigger. Structured timeline entries
are now graph data, not search text. Markdown timeline still feeds search
via the pages trigger. Side benefit: extraction pagination is no longer
self-invalidating (trigger used to bump pages.updated_at on every insert).
Types: new GraphPath (edge-based traversal result), PageFilters.updated_after,
BrainHealth gets link_coverage / timeline_coverage / most_connected. Postgres
schema regenerated via build:schema.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(graph): auto-link on put_page + extract --source db + security hardening
Core graph layer wired into the operation surface:
- New src/core/link-extraction.ts: extractEntityRefs (canonical extractor used
by both backlinks.ts and the new graph code), extractPageLinks (combines
markdown refs + bare-slug scan + frontmatter source, dedups within-page),
inferLinkType (deterministic regex heuristics for attended/works_at/
invested_in/founded/advises/source/mentions), parseTimelineEntries (parses
multiple date format variants from page content), isAutoLinkEnabled
(engine config flag, defaults true, accepts false/0/no/off case-insensitive).
- put_page operation auto-link post-hook: extracts entity refs from freshly
written content, reconciles links table (adds new, removes stale). Returns
auto_links: { created, removed, errors } in response so MCP callers see
outcomes. Runs in a transaction so concurrent put_page on same slug can't
race the reconciliation. Default on; opt out with auto_link=false config.
- traverse_graph operation extended with link_type and direction params.
Returns GraphPath[] (edges) when filters set, GraphNode[] (nodes) for
backwards compat. Depth hard-capped at TRAVERSE_DEPTH_CAP=10 for remote
callers; without this, depth=1e6 from MCP burns memory on the recursive CTE.
- gbrain extract <links|timeline|all> --source db: walks pages from the
engine instead of from disk. Works for live brains with no local checkout
(MCP-driven Wintermute / OpenClaw). Filesystem mode (--source fs) is
unchanged. New --type and --since filters with date validation upfront
(invalid --since used to silently no-op the filter and reprocess everything).
- Security: auto-link skipped for ctx.remote=true (MCP). Bare-slug regex
matches `people/X` anywhere in page text including code fences and quoted
strings. Without this gate an untrusted MCP caller could plant arbitrary
outbound links by writing pages with intentional slug references; combined
with the new backlink boost, attacker-placed targets would surface higher
in search.
- Postgres orphan_pages aligned to PGLite definition (no inbound AND no
outbound). Comment used to claim alignment but code disagreed; engines
drifted silently when users migrated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(cli): graph-query command + skill updates + v0.10.3 migration file
Agent-facing surface for the graph layer:
- New `gbrain graph-query <slug>` command with --type, --depth, --direction
in|out|both. Maps to traverse_graph operation with the new filters. Renders
the result as an indented edge tree.
- skills/migrations/v0.10.3.md: agent runs this post-upgrade to discover the
graph layer. Tells the agent to run `gbrain extract links --source db`,
then timeline, verify with stats, try graph-query, and lists the inferred
link types so they can be used in subsequent traversals.
- skills/brain-ops/SKILL.md Phase 2.5: documents that put_page now auto-links.
No more manual add_link calls in the Iron Law back-linking path.
- skills/maintain/SKILL.md: graph population phase. Shows the right command
to backfill links + timeline from existing pages.
- cli.ts: register graph-query in CLI_ONLY + handleCliOnly switch. Update help
text to describe `gbrain extract --source fs|db` and the new graph-query.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(graph): unit + e2e + 80-page A/B/C benchmark for graph layer
Coverage for the v0.10.3 graph layer (260+ new test assertions):
- test/link-extraction.test.ts (46 tests): extractEntityRefs both formats,
extractPageLinks dedup + frontmatter source, inferLinkType heuristics
(meeting/CEO/invested/founded/advises/default), parseTimelineEntries
multiple date formats + invalid date rejection, isAutoLinkEnabled
case-insensitive truthy/falsy parsing.
- test/extract-db.test.ts (12 tests): `gbrain extract <links|timeline|all>
--source db` happy paths, --type filter, --dry-run JSON output,
idempotency via DB constraint, type inference from CEO context.
- test/graph-query.test.ts (5 tests): direction in/out/both, type filter,
non-existent slug, indented tree output.
- test/pglite-engine.test.ts (+26 tests): getAllSlugs, listPages
updated_after filter, multi-type links via v5 migration, removeLink with
and without linkType, addTimelineEntry skipExistenceCheck flag,
getBacklinkCounts for hybrid search boost, traversePaths in/out/both with
cycle prevention via visited array, getHealth graph metrics
(link_coverage / timeline_coverage / most_connected).
- test/e2e/graph-quality.test.ts (6 tests): full pipeline against PGLite
in-memory. Auto-link via put_page operation handler. Reconciliation
removes stale links on edit. auto_link=false config skip.
- test/benchmark-graph-quality.ts: A/B/C comparison on 80 fictional pages,
35 queries across 7 categories. Hard thresholds: link_recall > 90%,
link_precision > 95%, timeline_recall > 85%, type_accuracy > 80%,
relational_recall > 80%. Currently passing all 9.
Built test-first: benchmark caught WORKS_AT_RE matching "founder" inside
slug names (frank-founder), "worked at" past-tense missing from regex,
PGLite Date object vs ISO string comparison bug. All fixed before merge.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: bump version and changelog (v0.10.3)
CHANGELOG: knowledge graph layer headline. Auto-link on every page write.
Typed relationships (works_at, attended, invested_in, founded, advises).
gbrain extract --source db. graph-query CLI. Backlink boost in hybrid search.
Schema migrations v5/v6/v7 applied automatically.
Security hardening caught during /ship adversarial review: traverse_graph
depth capped at 10 from MCP, auto-link skipped for ctx.remote=true, runAutoLink
reconciliation in transaction, --since validates dates upfront.
TODOS.md: 2 P2 follow-ups (auto-link redundant SQL on skipped writes;
extract --source db not gated on auto_link config).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: sync CLAUDE.md with v0.10.3 graph layer
Updated key files list (extract.ts now describes --source fs|db, added
graph-query.ts and link-extraction.ts), test inventory (extract-db,
link-extraction, graph-query unit tests; e2e/graph-quality), and
test count (51 unit + 7 e2e, 1151 + 105 assertions).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(v0.10.3): wire graph layer into install flow + README + benchmark
Existing brains upgrading to v0.10.3 had no clear path to backfill the new
links/timeline tables. New installs had no instruction to run extract --source db
after import. This wires the knowledge graph into every install touchpoint so the
v0.10.3 features actually reach the user.
- README: headline now sells self-wiring graph + 94% benchmark numbers; new
Knowledge Graph section between Knowledge Model and Search; LINKS+GRAPH command
block expanded; Benchmarks docs group added
- INSTALL_FOR_AGENTS.md: new Step 4.5 (graph backfill) + Upgrade section now runs
gbrain init + post-upgrade and points to migrations/v<N>.md
- skills/setup/SKILL.md Phase C: new step 5 for graph backfill (idempotent,
skip-if-empty); existing file migration becomes step 6
- src/commands/init.ts: post-init hint detects existing brain (page_count > 0)
and prints extract commands for both PGLite and Postgres engines
- docs/GBRAIN_VERIFY.md: new Check #7 (knowledge graph wired) with backfill
fallback + graph-query smoke test
- docs/benchmarks/2026-04-18-graph-quality.md: checked-in benchmark report
matching the existing search-quality format (94% recall, 100% precision,
100% relational recall, idempotent both ways)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(claude): require PR descriptions to cover the whole branch
Adds a rule to CLAUDE.md so future PR bodies always cover the full diff
against the base branch, not just the most recent commit. Includes the
git log + gh pr view incantation to check what's actually in a PR.
This is a reaction to PR #189 being created with a body that described
only the last commit instead of the 7 commits it actually contained.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(upgrade): post-upgrade prints full body + --execute mode + downstream skill upgrade doc
PR #188 review caught two install-flow gaps that this commit closes:
1. `gbrain post-upgrade` only printed the migration headline + description
from YAML frontmatter, never the markdown body that contains the
step-by-step backfill instructions. Agents saw "Knowledge graph layer —
your brain now wires itself" and had no idea to run `gbrain extract
links --source db`. Now prints the full body after the headline.
2. New `--execute` flag reads a structured `auto_execute:` list from
migration frontmatter and runs the safe commands sequentially. Without
`--yes` it prints the plan only (preview mode). With `--yes` it actually
runs them. Stops on first failure with a clear error.
3. Downstream agents (Wintermute etc.) keep local skill forks that gbrain
can't push updates to. New `docs/UPGRADING_DOWNSTREAM_AGENTS.md` lists
the exact diffs each release needs applied to those forks. v0.10.3
diffs for brain-ops, meeting-ingestion, signal-detector, enrich.
Changes:
- src/commands/upgrade.ts:
- runPostUpgrade(args) accepts flags
- Prints full body via extractBody()
- Parses auto_execute: list via extractAutoExecute() (hand-rolled, no yaml dep)
- --execute previews, --execute --yes runs
- Fix cosmetic bug: `recipe: null` no longer prints "show null" message
- src/cli.ts: pass args to runPostUpgrade
- skills/migrations/v0.10.3.md:
- Add auto_execute: list (gbrain init + extract links/timeline + stats)
- Fix typo: completion record version was 0.10.1, now 0.10.3
- test/upgrade.test.ts: 5 new tests covering body printing, plan preview,
actual execution, no-auto_execute case, and --help output
- docs/UPGRADING_DOWNSTREAM_AGENTS.md: NEW
- CLAUDE.md: key files list updated
Test: 13 upgrade tests pass (was 8, +5 new). Full unit suite: 1078 pass,
zero regressions, 32 expected E2E skips (no DATABASE_URL).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* bench(graph): add Configuration A baseline (no graph) vs C comparison
Previous benchmark showed C numbers only (94.4% link recall, 100% relational
recall, etc.) but never quantified what a pre-v0.10.3 brain actually loses.
Reviewer caught this gap.
Adds measureBaselineRelational() that simulates a no-graph fallback:
- Outgoing queries: regex-extract entity refs from the seed page content
- Incoming queries: grep-style scan of all pages for the seed slug
This is what an agent without the structured links table can do today.
Honest result on the 5 relational queries in the benchmark:
- Recall: 100% A vs 100% C (+0%) — markdown contains the refs either way
- Precision: 58.8% A vs 100.0% C (+70%) — without typed links, you get the
right answers buried in 41% noise
Per-query breakdown shows the divergence is concentrated in INCOMING queries:
"Who works at startup-0?" returns 5 candidates without graph (2 employees +
3 noise pages that mention startup-0) vs exactly 2 with graph. For an LLM
agent, that's ~3x less reading work per relational question.
Also documented what the benchmark deliberately doesn't test (multi-hop,
search ranking with backlink boost, aggregate queries, type-disagreement
queries) so future benchmark work has a roadmap.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* bench(graph): add 4 missing categories — multi-hop, aggregate, type-disagreement, ranking
The previous benchmark commit (
|
||
|
|
d8613366a5 |
Minions v7 + v0.11.1 canonical migration + skillify (#130)
* feat: add minion_jobs schema, migration v5, and executeRaw to BrainEngine Foundation for the Minions job queue system. Adds: - minion_jobs table (20 columns) with CHECK constraints, partial indexes, and RLS. Inspired by BullMQ's job model, adapted for Postgres. - Migration v5 creates the table for existing databases. - executeRaw<T>() method on BrainEngine interface for raw SQL access, needed by the Minions module for claim queries (FOR UPDATE SKIP LOCKED), token-fenced writes, and atomic stall detection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: Minions job queue — queue, worker, backoff, types BullMQ-inspired Postgres-native job queue built into GBrain. No Redis. No external dependencies. Postgres transactions replace Lua scripts. - MinionQueue: submit, claim (FOR UPDATE SKIP LOCKED), complete/fail (token-fenced), atomic stall detection (CTE), delayed promotion, parent-child resolution, prune, stats - MinionWorker: handler registry, lock renewal, graceful SIGTERM, exponential backoff with jitter, UnrecoverableError bypass - MinionJobContext: updateProgress(), log(), isActive() for handlers - 8-state machine: waiting/active/completed/failed/delayed/dead/ cancelled/waiting-children Patterns stolen from: BullMQ (lock tokens, stall detection, flows), Sidekiq (dead set, backoff formula), Inngest (checkpoint/resume). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: 43 tests for Minions job queue Full coverage of the Minions module against PGLite in-memory: - Queue CRUD (9): submit, get, list, remove, cancel, retry, duplicate - State machine (6): waiting→active→completed/failed, retry→delayed→waiting - Backoff (4): exponential, fixed, jitter range, attempts_made=0 edge - Stall detection (3): detect stalled, counter increment, max→dead - Dependencies (5): parent waits, fail_parent, continue, remove_dep, orphan - Worker lifecycle (5): register, start-without-handlers, claim+execute, non-Error throws, UnrecoverableError bypass - Lock management (3): renewal, token mismatch, claim sets lock fields - Claim mechanics (4): empty queue, priority ordering, name filtering, delayed promotion timing - Cancel & retry (2): cancel active, retry dead Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: Minions CLI commands and MCP operations Wire Minions into the GBrain CLI and MCP layer: CLI (gbrain jobs): submit <name> [--params JSON] [--follow] [--dry-run] list [--status S] [--queue Q] [--limit N] get <id> — detailed view with attempt history cancel/retry/delete <id> prune [--older-than 30d] stats — job health dashboard work [--queue Q] [--concurrency N] — Postgres-only worker daemon 6 MCP operations (contract-first, auto-exposed via MCP server): submit_job, get_job, list_jobs, cancel_job, retry_job, get_job_progress Built-in handlers: sync, embed, lint, import. --follow runs inline. Worker daemon blocked on PGLite (exclusive file lock). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: update project documentation for Minions job queue CLAUDE.md: added Minions files to key files, updated operation count (36), BrainEngine method count (38), test file count (45), added jobs CLI commands. CHANGELOG.md: added Minions entry to v0.10.0 (background jobs, retry, stall detection, worker daemon). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: Minions v2 — agent orchestration primitives (pause/resume, inbox, tokens, replay) Adds the foundation for Minions as universal agent orchestration infrastructure. GBrain's Postgres-native job queue now supports durable, observable, steerable background agents. The OpenClaw plugin (separate repo) will consume these via library import, not MCP, for zero-latency local integration. ## New capabilities - **Concurrent worker** — Promise pool replaces sequential loop. Per-job AbortController for cooperative cancellation. Graceful shutdown waits for all in-flight jobs via Promise.allSettled. - **Pause/resume** — pauseJob clears the lock and fires AbortSignal on active jobs. Handlers check ctx.signal.aborted and exit cleanly. resumeJob returns paused jobs to waiting. Catch block skips failJob when signal.aborted. - **Inbox (separate table)** — minion_inbox table for sidechannel messages. sendMessage with sender validation (parent job or admin). readInbox is token-fenced and marks read_at atomically. Separate table avoids row bloat from rewriting JSONB on every send. - **Token accounting** — tokens_input/tokens_output/tokens_cache_read columns. updateTokens accumulates; completeJob rolls child tokens up to parent. USD cost computed at read time (no cost_usd column — pricing too volatile). - **Job replay** — replayJob clones a terminal job with optional data overrides. New job, fresh attempts, no parent link. ## Handler contract additions MinionJobContext now provides: - `signal: AbortSignal` — cooperative cancellation - `updateTokens(tokens)` — accumulate token usage - `readInbox()` — check for sidechannel messages - `log()` — now accepts string or TranscriptEntry ## MCP operations added pause_job, resume_job, replay_job, send_job_message — all auto-generate CLI commands and MCP server endpoints. ## Library exports package.json exports map adds ./minions and ./engine-factory paths so plugins can `import { MinionQueue } from 'gbrain/minions'` for direct library use. ## Instruction layer (the teaching) - skills/minion-orchestrator/SKILL.md — when/how to use Minions, decision matrix, lifecycle management, anti-patterns - skills/conventions/subagent-routing.md — cross-cutting rule: all background work goes through Minions - RESOLVER.md — trigger entries for agent orchestration - manifest.json — registered ## Schema migration v6 Additive: 3 token columns, paused status, minion_inbox table with unread index. Full Postgres + PGLite support. No backfill needed. ## Tests 65 tests (was 43): pause/resume (5), inbox (6), tokens (4), replay (4), concurrent worker context (3), plus all existing coverage. ## What's NOT in this commit Deferred to follow-up PRs: - LISTEN/NOTIFY subscribe (needs real Postgres E2E) - Resource governor (depends on concurrent worker stress testing) - Routing eval harness (needs API keys + benchmark data) - OpenClaw plugin (separate @gbrain/openclaw-minions-plugin repo) See docs/designs/MINIONS_AGENT_ORCHESTRATION.md for full CEO-approved design. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(minions): migration v7 — agent_parity_layer schema Adds columns on minion_jobs (depth, max_children, timeout_ms, timeout_at, remove_on_complete, remove_on_fail, idempotency_key) plus the new minion_attachments table. Three partial indexes for bounded scans: idx_minion_jobs_timeout, idx_minion_jobs_parent_status, and uniq_minion_jobs_idempotency. Check constraints enforce non-negative depth and positive child cap / timeout. Additive migration — existing installs pick it up via ensureSchema on next use. No user action required. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(minions): extend types for v7 parity layer Extends MinionJob with depth/max_children/timeout_ms/timeout_at/ remove_on_complete/remove_on_fail/idempotency_key. Extends MinionJobInput with the same options plus max_spawn_depth override. Adds MinionQueueOpts (maxSpawnDepth default 5, maxAttachmentBytes default 5 MiB). Adds AttachmentInput/Attachment shapes and ChildDoneMessage in the InboxMessage union. rowToMinionJob updated to pick up the new columns. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(minions): attachments validator New module validateAttachment() gates every attachment write. Rejects empty filenames, path traversal (.., /, \), null bytes, oversized content (5 MiB default, per-queue override), invalid base64, and implausible content_type headers. Returns normalized { filename, content_type, content (Buffer), sha256, size } on success. The DB also enforces UNIQUE (job_id, filename) as defense-in-depth for concurrent addAttachment races — JS-only checks are not sufficient. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(minions): queue v7 — depth, child cap, timeouts, cascade, idempotency, child_done Wraps completeJob and failJob in engine.transaction() so parent hook invocations (resolveParent, failParent, removeChildDependency) fold into the same transaction as the child update. A process crash between child and parent can't strand the parent in waiting-children anymore. Adds v7 behaviors: - Depth tracking. add() computes depth = parent.depth + 1 and rejects past maxSpawnDepth (default 5). - Per-parent child cap. add() takes SELECT ... FOR UPDATE on the parent, counts non-terminal children, rejects when count >= max_children. NULL max_children = no cap. - Per-job wall-clock timeout. claim() populates timeout_at when timeout_ms is set. New handleTimeouts() dead-letters expired rows with error_text='timeout exceeded'. Terminal — no retry. - Cascade cancel. cancelJob() walks descendants via recursive CTE with depth-100 runaway cap. Returns the root row. Re-parented descendants (parent_job_id NULL) are naturally excluded. - Idempotency. add() uses INSERT ... ON CONFLICT (idempotency_key) DO NOTHING RETURNING; falls back to SELECT when RETURNING is empty. Same key always yields the same job id. - child_done inbox. completeJob inserts {type:'child_done', child_id, job_name, result} into the parent's inbox in the same transaction as the token rollup, guarded by EXISTS so terminal/deleted parents skip without FK violation. New readChildCompletions(parent_id, lock_token, since?) helper; token-fenced like readInbox. - removeOnComplete / removeOnFail. Deletes the row after the parent hook fires, so parent policy sees consistent state. - Attachment methods. addAttachment validates via validateAttachment then INSERTs; UNIQUE (job_id, filename) backs the JS dup check. listAttachments, getAttachment, deleteAttachment round out the API. Fixes pre-existing inverted status bug: add() now puts children in waiting/delayed (not waiting-children) and atomically flips the parent to waiting-children in the same transaction. Tests no longer need manual UPDATE workarounds. Two correctness fixes: - Sibling completion race. Under READ COMMITTED, two grandchildren completing concurrently each saw the other as still-active in the pre-commit snapshot and neither flipped the parent. Fixed by taking SELECT ... FOR UPDATE on the parent row at the start of completeJob and failJob transactions, serializing siblings on the parent lock. - JSONB double-encode. postgres.js conn.unsafe(sql, params) auto- JSON-encodes parameters. Calling JSON.stringify(obj) first stored a JSON string literal (jsonb_typeof=string) and broke payload->>'key' queries silently. Removed JSON.stringify from three call sites (child_done inbox post, updateProgress, sendMessage). PGLite tolerated both forms so unit tests missed it — real-PG E2E caught it. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(minions): worker — timeout safety net + handleTimeouts tick Worker tick now calls handleStalled() first, then handleTimeouts() — stall requeue wins over timeout dead-letter when both could fire in the same cycle. handleTimeouts() guards on lock_until > now() so stalled jobs take the retryable path. launchJob schedules a per-job setTimeout(timeout_ms) that fires ctx.signal as a best-effort handler interrupt. The timer is always cleared in .finally so process exit isn't delayed by a dangling timer. Handlers that respect AbortSignal stop cleanly; handlers that ignore it still get dead-lettered by the DB-side handleTimeouts. Removed post-completeJob and post-failJob parent-hook calls from the worker — those are now inside the queue method transactions. Worker becomes simpler and crash-safer. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test(minions): 33 new unit tests for v7 parity layer Covers depth cap, per-parent child cap, timeout dead-letter, cascade cancel (including the re-parent edge case), removeOnComplete / removeOnFail, idempotency (single + concurrent), child_done inbox (posted in txn + survives child removeOnComplete + since cursor), attachment validation (oversize, path traversal, null byte, duplicates, base64), AbortSignal firing on pause mid-handler, catch-block skipping failJob when aborted, worker in-flight bookkeeping, token-rollup guard when parent already terminal, and setTimeout safety-net cleanup. Existing tests updated to remove the inverted-status manual UPDATE workarounds that the add() fix made obsolete. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test(e2e): Minions v7 concurrency + OpenClaw resilience coverage minions-concurrency.test.ts spins two MinionWorker instances against the test Postgres, submits 20 jobs, and asserts zero double-claims (every job runs exactly once). This is the only test that actually proves FOR UPDATE SKIP LOCKED under real concurrency — PGLite runs on a single connection and can't exercise the race. minions-resilience.test.ts covers the six OpenClaw daily pains: 1. Spawn storm caps enforce under concurrent submit. 2. Agent stall → handleStalled() requeues; handleTimeouts() skips (lock_until guard). 3. Forgotten dispatches recoverable via child_done inbox. 4. Cascade cancel stops grandchildren mid-flight. 5. Deep tree fan-in (parent → 3 children → 2 grandchildren each) completes with the full inbox chain. 6. Parent crash/recovery resumes from persisted state. helpers.ts extends ALL_TABLES with minion_attachments, minion_inbox, and minion_jobs (FK dependents first) so E2E teardown doesn't leak rows between runs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore: release v0.11.0 — Minions v7 agent orchestration primitives Bumps VERSION / package.json to 0.11.0. Adds CHANGELOG entry covering depth tracking, max_children, per-job timeouts, cascade cancel, idempotency keys, child_done inbox, removeOnComplete/Fail, attachments, migration v7, plus the two correctness fixes (sibling completion race and JSONB double-encode). TODOS.md captures the four v7 follow-ups: per-queue rate limiting, repeat/cron scheduler, worker event emitter, and waitForChildren convenience helpers. 1066 unit + 105 E2E = 1171 tests passing. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(minions): unify JSONB inserts, tighten nullish coalescing Three non-blocker cleanups from post-ship review of v0.11.0: - queue.ts add() and completeJob(): pre-stringifying with JSON.stringify while other sites pass raw objects with $n::jsonb casts. postgres.js double-encodes if you stringify first — works on PGLite (text→JSONB auto-cast), fails silently on real PG. Unify on raw object + explicit $n::jsonb cast. - queue.ts readChildCompletions: since clause used sent_at > $2 relying on PG's implicit text→TIMESTAMPTZ coercion. Explicit $2::timestamptz is safer and clearer. - types.ts rowToMinionJob: parent_job_id used || which coerces 0 to null. Harmless today (SERIAL IDs start at 1) but ?? is semantically correct. All 110 unit tests pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(minions): updateProgress missed $1::jsonb cast in unification Residual from |
||
|
|
e5a9f0126a |
feat: GStackBrain — 16 new skills, resolver, conventions, identity layer (v0.10.0) (#120)
* feat: migrate 8 existing skills to conformance format Add YAML frontmatter (name, version, description, triggers, tools, mutating), Contract, Anti-Patterns, and Output Format sections to all existing skills. Rename Workflow to Phases. Ingest becomes thin router delegating to specialized ingestion skills (Phase 2). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add RESOLVER.md, conventions directory, and output rules RESOLVER.md is the skill dispatcher modeled on Wintermute's AGENTS.md. Categorized routing table: Always-on, Brain ops, Ingestion, Thinking, Operational, Setup, Identity. Conventions directory extracts cross-cutting rules (quality, brain-first lookup, model routing, test-before-bulk). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: add skills conformance and resolver validation tests skills-conformance.test.ts validates every skill has YAML frontmatter with required fields, Contract, Anti-Patterns, and Output Format sections, and manifest.json coverage. resolver.test.ts validates routing table categories, skill path existence, and manifest-to-resolver coverage. 50 new tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add 9 brain skills from Wintermute (Phase 2) Generalized from Wintermute's battle-tested skills: - signal-detector: always-on idea+entity capture on every message - brain-ops: brain-first lookup, read-enrich-write loop, source attribution - idea-ingest: links/articles/tweets with author people page mandatory - media-ingest: video/audio/PDF/book with entity extraction (absorbs video/youtube/book) - meeting-ingestion: transcripts with attendee enrichment chaining - citation-fixer: audit and fix citation formatting - repo-architecture: filing rules by primary subject - skill-creator: create skills with conformance standard + MECE check - daily-task-manager: task lifecycle with priority levels All Garry-specific references generalized. Core workflows preserved. Updated RESOLVER.md and manifest.json. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add operational infrastructure + identity layer (Phase 3) Operational skills: - daily-task-prep: morning prep with calendar context and open threads - cross-modal-review: quality gate via second model with refusal routing - cron-scheduler: schedule staggering, quiet hours, wake-up override, idempotency - reports: timestamped reports with keyword routing - testing: skill validation framework (conformance checks) - soul-audit: 6-phase interview generating SOUL.md, USER.md, ACCESS_POLICY.md, HEARTBEAT.md - webhook-transforms: external events to brain signals with dead-letter queue Identity layer: - SOUL.md template (agent identity, generated by soul-audit) - USER.md template (user profile, generated by soul-audit) - ACCESS_POLICY.md template (4-tier access control) - HEARTBEAT.md template (operational cadence) - cross-modal.yaml convention (review pairs, refusal routing chain) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: update CLAUDE.md with 24 skills, RESOLVER.md, conventions, templates GBrain is now a GStack mod for agent platforms. Updated architecture description, key files listing (16 new skill files, RESOLVER.md, conventions, templates), skills section (24 skills organized by resolver categories), and testing section (new conformance and resolver tests). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add GStack detection + mod status to gbrain init (Phase 4) After brain initialization, gbrain init now reports: - Number of skills loaded (from manifest.json) - GStack detection (checks known host paths, uses gstack-global-discover if available) - GStack install instructions if not found - Resolver and soul-audit pointers Also adds installDefaultTemplates() for SOUL.md/USER.md/ACCESS_POLICY.md/HEARTBEAT.md deployment, and detectGStack() using gstack-global-discover with fallback to known paths (DRY: doesn't reimplement GStack's host detection logic). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: v0.10.0 release documentation - CHANGELOG: 24 skills, signal detector, RESOLVER.md, soul-audit, access control, conventions, conformance standard, GStack detection in init - README: updated skill section with 24 skills, resolver, conventions - TODOS: added runtime MCP access control (P1) - VERSION: 0.9.2 → 0.10.0 - package.json + manifest.json version bumped Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add skill table to CHANGELOG v0.10.0 16-row table detailing every new skill, what it does, and why it matters. Written to sell the upgrade, not document the implementation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: restore package.json version after merge conflict resolution Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: zero-based README rewrite for GStackBrain v0.10.0 Lead with GStack mod identity. 24 skills table organized by category. Install block references RESOLVER.md and soul-audit. GBrain+GStack relationship explained. Removed redundancy (733 -> 406 lines). All essential content preserved: install, recipes, architecture, search, commands, engines, voice, knowledge model. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: extract install block to INSTALL_FOR_AGENTS.md, simplify README The 30-line copy-paste install block becomes one line: "Retrieve and follow INSTALL_FOR_AGENTS.md" Benefits: agent always gets latest instructions (no stale copy-paste), README stays clean, install details live where agents read them. README now leads with what GBrain does ("gives your agent a brain") instead of GStack relationship. Removed "requires frontier model" note. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: 3 bugs in init.ts from merge conflict resolution 1. llstatSync typo (merge corruption) → lstatSync 2. __dirname undefined in ESM module → fileURLToPath polyfill 3. require('fs') in ESM → use imported readFileSync All three would crash gbrain init at runtime. Caught by /review. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add checkResolvable shared core function for resolver validation Shared function at src/core/check-resolvable.ts validates that all skills are reachable from RESOLVER.md, detects MECE overlaps (with whitelist for always-on/router skills), finds gaps in frontmatter triggers, and scans for DRY violations. Returns structured ResolvableIssue objects with machine-parseable fix objects alongside human-readable action strings. Three call sites: bun test, gbrain doctor, skill-creator skill. Cleans up test/resolver.test.ts: removes stale 9-line skip list, imports from production check-resolvable.ts instead of reimplementing parsing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: expand doctor with resolver validation, filesystem-first architecture Doctor now runs filesystem checks (resolver health, skill conformance) before connecting to DB. New --fast flag skips DB checks. Falls back to filesystem-only when DB is unavailable. Adds schema_version: 2 to JSON output, composite health score (0-100), and structured issues array with action strings for agent parsing. Resolver health check calls checkResolvable() and surfaces actionable fix instructions. Link integrity check uses engine.getHealth() dead_links count. CLI routing split: doctor dispatched before connectEngine() so filesystem checks always run. Fixes Codex-identified blocker where doctor required DB. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add adaptive load-aware throttling and fail-improve loop backoff.ts: System load checking (CPU via os.loadavg, memory via os.freemem), exponential backoff with 20-attempt max guard, active hours multiplier (2x slower during waking hours), concurrent process limit (max 2). Windows-safe: defaults to "proceed" when os.loadavg returns zeros. fail-improve.ts: Deterministic-first, LLM-fallback pattern with JSONL failure logging. Cascade failure handling: when both paths fail, throws LLM error and logs both. Log rotation at 1000 entries. Call count tracking for deterministic hit rate metrics. Auto-generates test cases from successful LLM fallbacks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add transcription service and enrichment-as-a-service transcription.ts: Groq Whisper (default) with OpenAI fallback. Files >25MB segmented via ffmpeg. Provider auto-detection from env vars. Clear error messages for missing API keys and unsupported formats. enrichment-service.ts: Global enrichment service callable from any ingest pathway. Entity slug generation (people/jane-doe, companies/acme-corp), mention counting via searchKeyword, tier auto-escalation (Tier 3→2→1 based on mention frequency and source diversity), batch enrichment with backoff throttling, regex-based entity extraction from text. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add data-research skill with recipe system, extraction, dedup, tracker New skill: data-research — one parameterized pipeline for any email-to- structured-data workflow (investor updates, donations, company metrics). 7-phase pipeline: define recipe, search, classify, extract (with extraction integrity rule), archive, deduplicate, update tracker. data-research.ts: Recipe validation, MRR/ARR/runway/headcount regex extraction (battle-tested patterns), dedup with configurable tolerance, markdown tracker parsing/appending, quarterly/monthly date windowing, 6-phase HTML email stripping with 500KB ReDoS cap. Registers data-research in manifest.json (25th skill) and RESOLVER.md. Fixes backoff test robustness for high-load systems. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: update project documentation for v0.10.0 infrastructure additions CLAUDE.md: added 6 new core files (check-resolvable, backoff, fail-improve, transcription, enrichment-service, data-research), 6 new test files, updated skill count to 25, test file count to 34. README.md: updated skill count to 25, added data-research to skills table. CHANGELOG.md: added Infrastructure section documenting resolver validation, doctor expansion, adaptive throttling, fail-improve loop, voice transcription, enrichment service, and data-research skill. TODOS.md: anonymized personal references. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: doctor.ts use ES module imports, harden backoff test Replace require('fs') with ES module import in doctor.ts for consistency with the rest of the file. Backoff test made resilient to parallel test execution leaking module-level state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: README rewrite with production brain stats, sample output, new infrastructure Lead with the flex: 17,888 pages, 4,383 people, 723 companies, 526 meeting transcripts built in 12 days. Show sample query output so readers see what they'll get. Document self-improving infrastructure (tier auto-escalation, fail-improve loop, doctor trajectory). Add data-research recipes to Getting Data In. Update commands section with doctor --fix, transcribe, research init/list. Fix stale "24" references to "25". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: README lead with YC President origin and production agent deployments Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: README lead with skill philosophy and link to Thin Harness Fat Skills Skills section now explains: skill files are code, they encode entire workflows, they call deterministic TypeScript for the parts that shouldn't be LLM judgment. Links to the tweet and the architecture essay. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: link GStack repo, add 70K stars and 30K daily users Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: remove meeting transcript count from README (sensitive) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: README lead with YC President origin and production agent deployments Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: rename political-donations recipe to expense-tracker (sensitivity) Renamed the built-in data-research recipe from political-donations to expense-tracker across README, CHANGELOG, SKILL.md, and reports routing. Same extraction patterns (amounts, dates, recipients), neutral framing. Also renamed social-radar keyword route to social-mentions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
baf3517868 |
feat: v0.9.0 -- smart file storage, publish, production-grade skills (#62)
* feat: battle-tested skill patterns from production deployment Backport production-learned brain-operations patterns: - Iron Law of Back-Linking (mandatory bidirectional linking) - Brain filing rules (file by primary subject, not format) - Enrichment protocol (7-step pipeline, 3-tier system, person/company templates) - Media ingest workflows (articles, videos, podcasts, PDFs, screenshots) - Citation requirements (mandatory [Source: ...] on every fact) - Test Before Bulk operating principle - Voice recipe: unicode crash fix, PII scrub, identity-first prompt, DIY STT+LLM+TTS - X-to-Brain recipe: image OCR, Filtered Stream, tweet rating rubric, cron stagger * chore: bump version and changelog (v0.8.1) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add _brain-filing-rules.md to CLAUDE.md key files * feat: smart file upload with TUS resumable and .redirect.yaml pointers - Supabase Storage auto-selects upload method by file size: < 100 MB standard POST, >= 100 MB TUS resumable (6 MB chunks + retry) - Signed URL generation for private bucket access (1-hour expiry) - New `upload-raw` command with size routing: small text stays in git, large/media files go to cloud with .redirect.yaml pointer - New `signed-url` command for generating access links - File resolver supports both .redirect.yaml (v0.9+) and .redirect (legacy) - Redirect format upgraded: 10 fields with full metadata - All migration commands (mirror, redirect, restore, clean) handle both formats * feat: skills reference actual gbrain file commands - Filing rules document upload-raw, signed-url, and .redirect.yaml format - Ingest skill uses gbrain files upload-raw for raw source preservation - Maintain skill adds file storage health checks - Setup skill adds storage configuration phase with migration guidance - Voice recipe uses upload-raw for call audio storage - Migration v0.9.0 with complete storage setup instructions * chore: bump version and changelog (v0.9.0) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: gbrain publish -- shareable HTML with password protection First code+skill pair: deterministic code does the work (strip private data, encrypt with AES-256-GCM, generate self-contained HTML), the skill tells the agent when and how to use it. 34 new tests. See: https://x.com/garrytan/status/2042925773300908103 * feat: backlinks check/fix, page lint, and report commands Three new deterministic tools (zero LLM calls): - gbrain backlinks check/fix -- scans brain for entity mentions without back-links, creates them. Enforces the Iron Law from the skills. - gbrain lint [--fix] -- catches LLM preambles, code fence wrapping, placeholder dates, missing frontmatter, broken citations, empty sections. --fix auto-strips fixable artifacts. - gbrain report --type <name> -- saves timestamped reports to brain/reports/{type}/YYYY-MM-DD-HHMM.md for audit trails. 33 new tests (409 total, 0 fail). * feat: v0.9.0 migration tells agents to swap scripts for built-in commands Migration file now: - Lists all 5 new deterministic commands with usage examples - Includes a script-to-command replacement table (old -> new) - Tells the agent to find custom script references in AGENTS.md, skills, and cron jobs and replace with gbrain commands - Adds recommended cron jobs for daily backlink fix + weekly lint - References the Thin Harness, Fat Skills thread * fix: CLI routing bugs found during DX review - Fixed subArgs reference error in handleCliOnly (used wrong variable name) - Renamed gbrain backlinks check/fix to gbrain check-backlinks to avoid conflict with existing backlinks operation (per-page incoming links) - Added TOOLS section to --help output showing publish, check-backlinks, lint, report - Added upload-raw and signed-url to FILES section in --help - Updated all docs/migration references to use check-backlinks * fix: security hardening from adversarial review - XSS: sanitize marked.parse() output (strip script/iframe/on* attrs) - Path traversal: validate report --type against [a-z0-9-] pattern - TUS: HEAD request before retry to get server's actual offset (TUS spec) - Pointer: upload-raw now includes pointer content in JSON output - Symlinks: use lstatSync in all walkers to prevent directory escape --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
e9f3c9c24d |
docs: live sync setup + verification runbook + API key loading (#24)
* docs: add SKILLPACK Section 18 — Live Sync (MUST ADD) Contract-first guide for keeping the vector DB in sync with the brain repo. Documents the pooler prerequisite (Session mode required for transactions), sync + embed primitives, four example approaches (cron, --watch, webhook, git hook), isSyncable exclusions, silent skip warning, and OpenClaw/Hermes cron registration examples. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add GBRAIN_VERIFY.md installation verification runbook Six-check runbook: schema (doctor), skillpack loaded, auto-update, live sync (coverage check + embed check + end-to-end push-and-search test), embedding coverage, brain-first lookup protocol. Emphasizes "sync ran" != "sync worked" — the real test is searching for corrected text after a push. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add setup Phases H (Live Sync) and I (Verification) Phase H: MUST ADD live sync setup — pooler prerequisite check, automatic sync configuration (agent picks approach), sync+embed chaining, coverage verification. Phase I: run GBRAIN_VERIFY.md end-to-end before declaring setup complete. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add install steps 8-9 (live sync + verification) Step 8: set up automatic sync with SKILLPACK Section 18 reference. Step 9: run GBRAIN_VERIFY.md runbook. Add GBRAIN_VERIFY.md to docs section. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add API key loading instructions to CLAUDE.md Source ~/.zshrc before running Tier 2 tests so OPENAI_API_KEY and ANTHROPIC_API_KEY are available. Without this, embedding and skills tests skip silently. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: bump version to v0.5.0 Live sync, verification runbook, API key loading instructions. Version markers updated in SKILLPACK and RECOMMENDED_SCHEMA. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add anti-hand-roll rule to skill routing in CLAUDE.md Explicitly prohibit manually running git commit + push + gh pr create when /ship is available. /ship handles VERSION, CHANGELOG, document-release, reviews, and coverage audit. Hand-rolling skips all of these. Added "commit and ship" / "push and ship" variants to the ship routing rule. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: changelog voice rule + rewrite 0.5.0 changelog to sell the upgrade CLAUDE.md: add changelog voice guidance — lead with benefits, not implementation details. Make users want to upgrade. CHANGELOG: rewrite 0.5.0 entries from dry feature descriptions to capability-focused bullets ("your brain never falls behind" not "SKILLPACK Section 18 added"). SKILLPACK Section 17: update the auto-update message template to instruct agents to sell the upgrade, not just summarize the diff. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add v0.5.0 migration directive for live sync + verification Agents upgrading from v0.4.x will automatically: check their pooler connection string, set up automatic sync, and run the verification runbook. Without this migration file, upgrading agents would learn about live sync (by re-reading Section 18) but wouldn't set it up. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: sharpen migration file guidance in CLAUDE.md Replace vague "requires agent action" with concrete trigger list: new setup steps existing users don't have, MUST ADD skillpack sections, schema changes, deprecated commands, new verification steps, new crons. Add the key test: "if an existing user upgrades and does nothing else, will their brain work worse?" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: make Section 17 upgrade flow work for direct user requests Section 17 was structured as a cron-initiated flow only. An agent handling "upgrade gbrain" might just run the command and stop, missing the post-upgrade steps where the value is (re-read skills, run migrations, schema sync). Added explicit entry point for direct upgrade requests. Made Steps 2-4 more concrete about where to find files and why migrations can't be skipped. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: add E2E sync tests — git-to-DB pipeline (11 tests) Tests the full sync lifecycle against real Postgres+pgvector: - First sync imports all pages from a git repo - Second sync with no changes returns up_to_date - Incremental sync picks up new files (add → commit → sync → verify) - Incremental sync picks up modifications — THE CRITICAL TEST: corrected text appears in DB and keyword search after sync - Incremental sync handles deletes - Non-syncable files are excluded (README, .raw/, ops/) - Sync state (last_commit, last_run) persisted to config - Sync logged to ingest_log - --full reimports everything - --dry-run shows changes without applying Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: strengthen CLAUDE.md to always run ALL test tiers Replace passive "source zshrc" suggestion with ALWAYS directive. Explicitly state that "run all tests" means ALL tiers including Tier 2 with API keys. Do not skip Tier 2 just because keys need loading. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: Tier 2 E2E tests — correct openclaw CLI invocation The tests used `openclaw -p` which doesn't exist. The correct command is `openclaw agent --local --agent <id> --message <prompt>`. Also fixed JSON output parsing (structured JSON goes to stderr, not stdout — use non-JSON mode instead). Fixed ingest test to assert on agent response text rather than test DB state (the agent writes to its own configured DB, not the ephemeral test DB). 82 tests pass, 0 fail, 0 skip across all 5 E2E files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
57d2cd384a |
docs: add Hermes Agent alongside OpenClaw
GBrain install instructions and skills work with both OpenClaw and Hermes Agent. First mention in each file says OpenClaw/Hermes, subsequent references say OpenClaw. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
3ef38e8f5c |
docs: update Supabase connection string instructions
New flow: Get Connected > Direct Connection String > Session Pooler > copy Shared Pooler. The old gear icon > Project Settings path is stale. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
f541f045d2 |
feat: add gbrain check-update command and auto-update agent workflow (#15)
* feat: add `gbrain check-update` command for auto-update notifications Deterministic collector that checks GitHub Releases for new versions, compares semver (minor+ only, skips patches), and fetches changelog diffs. Exports `detectInstallMethod()` from upgrade.ts for reuse. Includes 15 unit tests covering version comparison, CLI wiring, and error handling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: add E2E upgrade tests against real GitHub API Exercises check-update CLI end-to-end: valid JSON output, human-readable mode, help text, graceful no-releases handling, and version comparison wiring. Skips gracefully when network is unavailable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add SKILLPACK Section 17 — auto-update notifications Full agent playbook for the update lifecycle: check, notify, consent, upgrade, skills refresh, schema sync, report. Includes standalone self-update for skillpack-only users via version markers and raw GitHub URL fetching. Adds version markers to both SKILLPACK and RECOMMENDED_SCHEMA headers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add auto-update step 7 to install paste, setup Phase G, migrations dir Adds step 7 to the OpenClaw install paste (default-on update checks). Setup skill gets Phase G (conditional offer for manual installs) and schema state tracking via ~/.gbrain/update-state.json. Creates skills/migrations/ directory for version-specific upgrade directives. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: update CLAUDE.md with E2E test DB lifecycle, migration conventions Adds E2E test DB lifecycle instructions (spin up, run, tear down). Documents version migration convention (skills/migrations/v[version].md) and schema state tracking (~/.gbrain/update-state.json). Updates test file counts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: broken semver comparison in extractChangelogBetween The version range check compared minor versions without guarding on major being equal, causing incorrect changelog entries to be captured (e.g., v0.5.0 would match when upgrading from v1.2.0). Extracted semverGt/semverLte helpers for correct comparisons. Added 5 tests for extractChangelogBetween covering cross-major, same-version, and malformed input cases. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: bump version and changelog (v0.4.1) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
95eda98e27 |
feat: surface GBRAIN_SKILLPACK.md during setup and init
- gbrain init success message now prints the skillpack path - Setup skill adds Phase E: load the production agent guide - Agents are instructed to read and inject key SKILLPACK patterns Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
912a321cfa |
GBrain v0.4.0 — production agent documentation + reference architecture (#10)
* fix: widen validateSlug to accept any filename characters Git is the system of record. Slugs are lowercased repo-relative paths. The restrictive regex rejected spaces, parens, and special chars, blocking 5,861 Apple Notes files from importing. Now only rejects empty slugs, path traversal (..), and leading slash. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: enable RLS on all tables with BYPASSRLS safety check Without RLS, the Supabase anon key gives full read access to the DB. Enable RLS on all 10 tables with no policies — the postgres role (used by gbrain via pooler) has BYPASSRLS and is unaffected. Only enables if the current role actually has BYPASSRLS privilege to avoid locking ourselves out on non-Supabase setups. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: import resilience — 5MB limit, error suppression, structured progress Raise MAX_FILE_SIZE from 1MB to 5MB for Apple Notes with attachments. Track error patterns and suppress after 5 identical errors to prevent 5,861 identical warnings from killing the agent process. Replace \r progress bar with structured log lines (rate, ETA) for agent parsing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: init detects IPv6-only Supabase URLs, adds pgvector check Detect db.*.supabase.co direct URLs and warn about IPv6 failure. On ECONNREFUSED/ETIMEDOUT to Supabase, suggest the Session pooler connection string with exact dashboard click path. Check for pgvector extension after connecting and fail with clear instructions if missing. Update wizard hints to show pooler URL format. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add pre-ship requirement for E2E tests E2E tests against real Postgres+pgvector must pass before /ship or /review. Adds the requirement to CLAUDE.md so all agents enforce it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: parallel import with per-worker engine instances Refactor PostgresEngine to support instance-level DB connections instead of only the module-global singleton. Each worker gets its own connection with poolSize:2 (vs 10 for the main engine), so 8 workers = 16 connections. Add --workers N flag to gbrain import. Workers pull from a shared queue and use independent engine instances — no transaction context corruption. The bottleneck is network round-trips to Supabase (one per page upsert). Parallel workers cut import time proportionally. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: automatic schema migration runner Migrations are embedded as string constants in migrate.ts (survives Bun --compile). Each migration runs in a transaction for clean rollback on failure. Runs automatically on initSchema() — no manual step needed when a user updates the gbrain binary against an older DB. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: pluggable storage backend (S3 + Supabase Storage + local) Add StorageBackend interface with three implementations: - S3Storage: works with AWS S3, Cloudflare R2, MinIO (any S3-compatible) - SupabaseStorage: uses Supabase Storage REST API with service role key - LocalStorage: filesystem-based, for testing Add file-resolver.ts with fallback chain: local file → .redirect breadcrumb → .supabase marker → storage backend. Supports the three-stage migration (mirror → redirect → clean). Add yaml-lite.ts for parsing marker and breadcrumb files without adding a YAML dependency. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: gbrain doctor command — health checks with --json output Checks: connection, pgvector extension, RLS on all tables, schema version, embedding coverage. Outputs structured JSON with --json flag for agent parsing. Exit code 0 if healthy, 1 if issues found. Agents should run gbrain doctor --json when any command fails. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: rewrite setup skill + README for agent-first DX Setup skill: add Why Supabase, step-by-step project creation, explicit agent instructions (nohup for large imports, doctor on failure, don't ask for anon key), available init flags, file migration offer after first import. Remove ClawHub references. README: simplify to single OpenClaw install path, remove ClawHub, fix squatted npm name to github:garrytan/gbrain, add Supabase settings note about Session pooler. Add Apple Notes test fixtures with spaces and parens in filenames for E2E testing of the slug fix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add RLS verification, schema health, and nohup hints to maintain skill Maintenance skill now checks RLS status and schema version as part of periodic health checks. Adds nohup pattern for large embedding refreshes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: import resume checkpoint + Supabase smart URL parsing Import resume: saves checkpoint every 100 files to ~/.gbrain/import-checkpoint.json. On restart with same directory and file count, skips already-processed files. Use --fresh to ignore checkpoint and start over. Cleared on successful completion. Supabase admin: extractProjectRef() parses any Supabase URL format (dashboard, direct, pooler, project URL) to extract the project ref. discoverPoolerUrl() uses the Management API to find the correct pooler connection string (including the exact region prefix). checkRls() verifies RLS status via the API. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: add 56 unit tests for all new code 8 new test files covering every feature added in this branch: - slug-validation.test.ts: spaces, parens, unicode, path traversal (10 tests) - yaml-lite.test.ts: parse + stringify, marker/redirect formats (9 tests) - supabase-admin.test.ts: extractProjectRef for 4 URL formats (7 tests) - migrate.test.ts: version export, runMigrations callable (2 tests) - storage.test.ts: LocalStorage CRUD + createStorage factory (14 tests) - file-resolver.test.ts: fallback chain, redirect, marker parsing (6 tests) - import-resume.test.ts: checkpoint save/load/resume/fresh (6 tests) - doctor.test.ts: module export, CLI registration (3 tests) Total: 184 pass, 0 fail (up from 128). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: bulk chunk INSERT + E2E tests for all new features Bulk INSERT: upsertChunks now builds a multi-row VALUES query instead of inserting chunks one-by-one. Reduces DB round-trips by ~50x per page. E2E tests added to mechanical.test.ts: - Slug with special chars: import Apple Notes fixtures with spaces/parens, verify search finds them, verify idempotency - RLS verification: check pg_tables.rowsecurity on all tables, verify current user has BYPASSRLS - Doctor command: verify exit 0 on healthy DB, --json produces valid JSON with check structure - Parallel import: --workers 2 produces same page count as sequential Unit tests added: - setup-branching.test.ts: IPv6 detection, defaultWorkers auto-tuning, smart URL parsing across all Supabase URL formats Fixtures added: - large/big-file.md (2.1MB) for testing raised file size limit - apple-notes/ fixtures already existed Total: 200 pass, 0 fail (up from 184). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: --json on init/import, file migration CLI, lifecycle tests --json flag: init and import now support --json for structured output. Agents get parseable JSON instead of human-readable text. File migration CLI: implement mirror, unmirror, redirect, restore, clean, and status subcommands for the three-stage file migration lifecycle (local → mirrored → redirected → cloud-only). File migration tests: full lifecycle test covering every transition in the state machine (LOCAL → MIRROR → UNMIRROR → REDIRECT → RESTORE → CLEAN), including edge cases and file resolver at each stage. Bulk chunk INSERT: upsertChunks now builds multi-row parameterized VALUES query, reducing round-trips per page from ~50 to 1. Total: 207 pass, 0 fail. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: thorough E2E tests for parallel import concurrency Replace the weak single-comparison parallel import test with 7 tests: - Sequential baseline: capture page count, chunk count, and all slugs - --workers 2: verify page count matches sequential - Chunk count matches (no duplicates from concurrent writes) - Page slugs match exactly - No duplicate pages (SQL GROUP BY HAVING count > 1) - No duplicate chunks (SQL GROUP BY page_id, chunk_index) - --workers 4: also works correctly - Re-import with workers is idempotent These tests catch the exact bug Codex found (db.ts singleton causing concurrent transaction corruption) by verifying data integrity after parallel writes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add batch embedding queue as P1 TODO Deferred during eng review (per-worker embedding is good enough for now). Revisit after profiling real imports to confirm embedding is the bottleneck. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: E2E test failures — fixture counts, arg parsing, doctor exit code Fix fixture count assertions: 13 → 16 pages (added apple-notes + large file), companies 2 → 3 (ohmygreen), concepts 3 → 5 (notes, big-file). Fix --workers arg parsing: the worker count value (e.g. "2") was being picked up as the directory arg. Skip flag values when finding the dir. Fix doctor exit code: warnings (like missing embeddings) should exit 0, only actual failures exit 1. E2E tests import with --no-embed, so embeddings are always WARN. Fix E2E CLI tests: add initCli() before doctor and parallel import tests so ~/.gbrain/config.json exists for the subprocess. All E2E tests pass: 63 pass, 0 fail. All unit tests pass: 207 pass, 0 fail. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: update project documentation for v0.4.0 New CHANGELOG entry for all post-0.3.0 features (doctor, storage backends, parallel import, resume checkpoints, RLS, schema migrations, --json output). Version bumped 0.3.0 → 0.4.0 across all manifests. CLAUDE.md: test count 9→19, skill count 8→7, added key files. CONTRIBUTING.md: fixture count 13→16, added missing source files. README.md: added gbrain doctor to commands, fixed stale welcome PRs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add GBRAIN_SKILLPACK.md reference architecture Production agent patterns from a real deployment with 14,700+ brain files. Covers: entity detection on every message, brain-first lookup protocol, 7-step enrichment pipeline with tiered API spend, compiled truth + timeline, source attribution with mandatory citations, meeting ingestion with entity propagation, cron schedule with quiet hours and travel-aware timezone, YouTube/media ingestion via Diarize.io, integration guides for ClawVisor, Circleback webhooks, and Quo/OpenPhone SMS. Opens with the Vannevar Bush memex framing and the originals folder for capturing intellectual capital. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: rewrite README opener with memex pitch and production architecture Replace code-first opener with mimetic-desire pitch: Vannevar Bush memex tagline, production brain numbers (10K+ files, 3K+ people, 13 years of calendar), "ask it anything" examples, compounding thesis. New sections: The Compounding Thesis (read-write loop), Architecture (three-column diagram), What a Production Agent Looks Like (SKILLPACK reference), How gbrain fits with OpenClaw (three-layer complement). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: update skills with brain-first lookup, entity detection, heartbeat setup: Phase D rewritten with brain-first lookup protocol (gbrain search → query → get → grep fallback), sync-after-write rule, memory_search complement table. query: token-budget awareness (chunks not full pages), source precedence hierarchy (user > compiled truth > timeline > external). ingest: entity detection on every message (scan, check brain, create or enrich, commit and sync). maintain: heartbeat integration (doctor, embed --stale, sync verification, stale compiled truth detection). briefing: gbrain-native context loading (search attendees before meetings, search sender before email, daily deal/meeting/commitment queries). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add OpenClaw positioning to README opener Make it clear up top that GBrain is built for OpenClaw agents and works with any OpenClaw deployment. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: credit Karpathy's Knowledge LLM vision, add origin story GBrain started as Karpathy's LLM wiki idea built for real. Worked great until the brain hit thousands of files and grep fell apart. GBrain is the search layer that had to exist once the brain outgrew grep. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
a86f995883 |
feat: GBrain v0.3.0 — contract-first architecture + ClawHub plugin (#7)
* feat: contract-first operations.ts with OperationError, dry_run, importFromContent 30 shared operations as single source of truth for CLI and MCP. - OperationError with typed error codes (page_not_found, invalid_params, etc.) - dry_run support on all mutating operations - importFromContent split from importFile with transaction wrapping - Idempotency hash now includes ALL fields (title, type, frontmatter, tags) - Config env var fallback: GBRAIN_DATABASE_URL > DATABASE_URL > config file Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: rewrite MCP server + CLI + tools-json from operations server.ts: 233 -> ~80 lines. Tool definitions and dispatch generated from operations[]. cli.ts: shared operations auto-registered, CLI-only commands kept as manual dispatch. tools-json: generated FROM operations[], eliminating the third contract surface. Parity test verifies structural contract between operations, CLI, and MCP. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: delete 12 command files migrated to operations.ts Handler logic for get, put, delete, list, search, query, health, stats, tags, link, timeline, and version now lives in operations.ts. Kept: init, upgrade, import, export, files, embed, sync, serve, call, config. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: init --non-interactive, upgrade verification, schema migration - gbrain init --non-interactive --url <url> for plugin mode (no TTY required) - Post-upgrade version verification in gbrain upgrade - Drop storage_url from files table (storage_path is the only identifier) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: tool-agnostic skills + new setup skill All 7 skills rewritten with intent-based language instead of CLI commands. Works with both CLI and MCP plugin contexts. New setup skill replaces install: auto-provision Supabase via CLI, AGENTS.md injection, target TTHW < 2 min. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: ClawHub bundle plugin, CI workflows, v0.3.0 - openclaw.plugin.json with configSchema, MCP server config, skill listing - GitHub Actions: test on push/PR, multi-platform release (macOS arm64 + Linux x64) - Version bump 0.3.0, CHANGELOG, README ClawHub section, CLAUDE.md updated Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: idempotency hash mismatch + MCP dry_run passthrough importFromContent now passes its all-fields hash through putPage via content_hash on PageInput, so the stored hash matches the computed hash. Previously the skip-if-unchanged check never fired because the hash formulas differed. MCP server now passes dry_run from tool params to OperationContext. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: bump version and changelog (v0.3.0.0) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: schema loader handles PL/pgSQL $$ blocks Delete the semicolon-based SQL splitter in db.ts which broke on PL/pgSQL trigger functions containing semicolons inside $$ delimiter blocks. Use single conn.unsafe(schemaSql) call instead — the postgres driver handles multi-statement SQL natively. schema.sql already uses IF NOT EXISTS / CREATE OR REPLACE for idempotency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: E2E test infrastructure + realistic brain fixtures Add test infrastructure for running E2E tests against real Postgres+pgvector. Includes: - test/e2e/helpers.ts: DB lifecycle, fixture import, timing, diagnostics - 13 fixture files as a miniature realistic brain (people, companies, deals, meetings, concepts, projects, sources) following the compiled truth + timeline format from GBRAIN_RECOMMENDED_SCHEMA.md - docker-compose.test.yml: local pgvector convenience (port 5433) - .env.testing.example: template for test credentials - package.json: add test:e2e script Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: E2E test suites + CI workflow Tier 1 (mechanical.test.ts): 14 test suites covering all operations against real Postgres — page CRUD, search with quality scoring, links, tags, timeline, versions, admin, chunks, resolution, ingest log, raw data, files, idempotency stress, setup journey (full CLI flow), init edge cases, schema idempotency, schema diff guard, performance baselines. Tier 1 (mcp.test.ts): MCP protocol test — spawns server, sends JSON-RPC, verifies tools/list matches operations count. Tier 2 (skills.test.ts): OpenClaw skill tests — ingest, query, health. Skips gracefully when dependencies missing. CI (.github/workflows/e2e.yml): Tier 1 on every PR (pgvector service), Tier 2 nightly/manual with API key secrets. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: E2E test fixes + traverseGraph jsonb cast - Fix traverseGraph query: cast json_agg to jsonb_agg so SELECT DISTINCT works - Fix put_page tests to use importFromContent with noEmbed (no OpenAI key in Tier 1) - Fix get_health assertion (page_count not total_pages) - Fix raw_data test to handle JSONB string/object return - Simplify MCP test to verify tool generation directly - Add timeouts to CLI subprocess tests - Use port 5434 for docker-compose (5433 often in use) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: update all project docs for E2E test suite - CLAUDE.md: updated test count (9 unit + 3 E2E), added E2E test instructions, fixed skill count to 8 - CONTRIBUTING.md: updated project structure with test/e2e/, added E2E test instructions, rewrote "Adding a new command" to reflect contract-first architecture (add to operations.ts, done) - README.md: fixed table count (10 not 9), added recommended schema doc to Docs section, added E2E instructions to Contributing section - CHANGELOG.md: added E2E test suite, docker-compose, schema loader fix, and traverseGraph jsonb fix to v0.3.0 entry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |