Skip to content

v0.20.4 feat: merge gbrain-jobs into minion-orchestrator — single unified minions skill#381

Merged
garrytan merged 15 commits intomasterfrom
feat/merge-minion-skills
Apr 24, 2026
Merged

v0.20.4 feat: merge gbrain-jobs into minion-orchestrator — single unified minions skill#381
garrytan merged 15 commits intomasterfrom
feat/merge-minion-skills

Conversation

@garrytan
Copy link
Copy Markdown
Owner

@garrytan garrytan commented Apr 24, 2026

Summary

Consolidates Minions (shell jobs + LLM subagents) into a single skill, corrects four content bugs a Codex cold-read surfaced, and adds structural tests so the corrected docs stay correct. Merged with master through v0.20.3 (queue resilience); this PR is now v0.20.4.

Minions skill consolidation (D1–D13)

  • skills/minion-orchestrator/SKILL.md rewritten to cover both shell-job and subagent lanes with a Preconditions block, real CLI examples, accurate MCP boundary, PGLite --follow path, and a pain_triggered pointer to skills/conventions/subagent-routing.md.
  • skills/RESOLVER.md narrowed "gbrain jobs""gbrain jobs submit" + "submit a gbrain job". The CLI namespace covers 9 subcommands; the bare trigger was a grab-bag.
  • Inline "replaces older gbrain-jobs routing intent" note in description + manifest.json, so stale references resolve at point-of-use.

Content corrections caught by review

  • Shell CLI examples used nonexistent --cmd/--argv/--cwd flags. Real form: --params '{"cmd":"...","cwd":"..."}'.
  • --tools "search,web_search" referenced a tool not in BRAIN_TOOL_ALLOWLIST. Swapped to search,query + added the full allowlist inline.
  • gbrain agent run flag list invented --queue/--priority/--max-attempts/--delay. Replaced with the real flag set.
  • Subagent examples referenced name="research" / name="orchestrate" handlers that don't exist. Replaced with gbrain agent run + real subagent / subagent_aggregator.
  • skills/conventions/subagent-routing.md stale get_job_stats reference fixed.
  • skills/query/SKILL.md + skills/maintain/SKILL.md + skills/smoke-test/SKILL.md frontmatter triggers closed gaps the new round-trip test surfaced.

New tests (D5 + D13 + T4)

  • test/resolver.test.ts D5 round-trip: every quoted RESOLVER.md trigger must match the target skill's frontmatter triggers:. Case- and punctuation-insensitive, /-split compounds.
  • test/resolver.test.ts D13 skill-example-name validator: every name="<word>" in any SKILL.md body must resolve to an op in src/core/operations.ts or a handler in PROTECTED_JOB_NAMES. Would have caught the research/orchestrate drift in CI.
  • test/e2e/minions-shell-pglite.test.ts: PGLite --follow inline path, previously documented but untested.

Test Coverage

Diff: 8 files, ~460 lines (pre-merge scope; merged with master's v0.20.1-0.20.3)

AUTOMATED (via new tests):
[★★★] RESOLVER.md ↔ frontmatter trigger drift → D5 round-trip (59 assertions)
[★★★] Skill refs to nonexistent handler/op names → D13 validator
[★★★] PGLite --follow shell-job execution → test/e2e/minions-shell-pglite.test.ts
[★★★] MCP shell-submit rejection → test/e2e/minions-shell.test.ts:103 (existing)

MANUAL: 3 prose surfaces (natural-language, not machine-testable)

Coverage: 6/8 surfaces automated (75%) — prose surfaces are appropriate manual coverage for a doc rewrite.

Pre-Landing Review

Multi-pass review via specialist subagents. Three fix commits (344cc0a, 622f0c5, 7b50988) addressed 10 findings total across first/second/adversarial passes. Every finding was either auto-fix (clear correct answer) or surfaced a pre-existing drift case that got closed as bonus (query/maintain/smoke-test trigger frontmatters).

Adversarial Review

  • Claude subagent: FIXABLE findings applied, INVESTIGATE findings deferred with documentation (D13 regex false-positive surface, PGLite E2E env-var race).
  • Codex outside-voice pass ran during /plan-ceo-review and caught T1–T4 before implementation.

Plan Completion

All 13 decisions (D1–D13) from ~/.claude/plans/lets-check-it-out-jaunty-coral.md complete. D4 (VERSION + CHANGELOG) handled by /ship (now v0.20.4).

Documentation

  • README.md: skill count updated to reflect consolidated minion-orchestrator + v0.19.1 smoke-test.
  • CLAUDE.md: key-files entry for skills/minion-orchestrator/SKILL.md describes the v0.20.4 consolidation; test inventory picks up new tests.
  • CHANGELOG.md: v0.20.4 entry in user voice, above master's v0.20.3 (queue resilience) entry.
  • VERSION + package.json: 0.20.3 → 0.20.4.

TODOS

No new TODOs added; gbrain jobs stats --orphaned remains a pre-existing deferred operational tool.

Test plan

  • bun test test/resolver.test.ts — 57/57 pass on merged tree (v0.20.4)
  • bun test test/e2e/minions-shell-pglite.test.ts — passes (earlier ship pass)
  • Full E2E suite passed on prior ship pass (191/191 tests, 20 files)
  • gbrain check-resolvable --jsonok: true, all skills reachable

🤖 Generated with Claude Code

root and others added 11 commits April 24, 2026 03:27
…mes, PGLite path

The initial merge commit a51c737 documented `submit_job name="shell"` as
agent-callable, but src/core/operations.ts:1106 rejects protected names
from MCP callers (shell is in src/core/minions/protected-names.ts:16) —
shell-job submission is CLI-only. Subagent examples referenced non-existent
handler names (`research`, `orchestrate`) instead of the real `subagent` /
`subagent_aggregator` handlers. PGLite section wrongly told users to
migrate to Supabase when `gbrain jobs submit ... --follow` inline mode
works per docs/guides/minions-shell-jobs.md:15. Contract section canonized
"every task through Minions" against the `pain_triggered` default in
skills/conventions/subagent-routing.md:16,27.

Rewrite addresses all four:
- Shell Jobs section is explicit about CLI-only submission; agents observe
  via get_job / list_jobs / get_job_progress (non-protected).
- Subagent examples route through `gbrain agent run` (user-facing CLI)
  with raw handler names documented as the power-user path.
- PGLite gets --follow inline execution, not migration friction.
- Contract softened to point at subagent-routing.md convention.

Also adds a Preconditions block for Shell Jobs (env gate, RCE warning,
execution-mode choice, verification command), narrows the frontmatter
"gbrain jobs" trigger to "gbrain jobs submit" + "submit a gbrain job"
(bare was too broad — CLI namespace covers 9 subcommands), inlines a
"replaces older gbrain-jobs routing intent" note in the description, and
removes non-existent `get_job_stats` from the tools list (CLI is
`gbrain jobs stats`; no MCP equivalent).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace bare "gbrain jobs" in the routing table with "gbrain jobs submit"
+ "submit a gbrain job". The bare phrase was too broad — the CLI namespace
covers 9 subcommands (submit, list, get, retry, delete, prune, stats,
smoke, work). Users asking about stats/prune/retry now fall through to
`gbrain --help` instead of getting misrouted to minion-orchestrator, which
only documents shell execution and subagent orchestration.

Matches the frontmatter trigger narrow in minion-orchestrator/SKILL.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two new assertion blocks in test/resolver.test.ts:

1. RESOLVER.md trigger round-trip: every quoted phrase in a routing-table
   row has a fuzzy match in the target skill's frontmatter `triggers:` list.
   Catches RESOLVER ↔ frontmatter drift that checkResolvable's reachability
   check doesn't. Fuzzy match is case-insensitive, trailing-punctuation-
   insensitive, and splits on "/" for compound phrases like
   "pause/resume agent" — accommodates RESOLVER.md's natural-language
   summary style without allowing real drift through.

2. Skill example-name validator: every `name="<word>"` reference in any
   SKILL.md body must resolve to either a declared operation in
   src/core/operations.ts or a known Minions handler in
   PROTECTED_JOB_NAMES. Would have caught the `name="research"` /
   `name="orchestrate"` drift that slipped through the first review
   — nothing in CI caught those handler names referencing non-existent
   handlers until a Codex cold-read found them. This test closes that
   class of regression gap.

51 / 51 tests pass locally. Full E2E suite (bun run test:e2e) still
passes 197 / 197 across 19 files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes the T4 coverage gap surfaced during PR #381 eng review. The sibling
test/e2e/minions-shell.test.ts covers Postgres + persistent-daemon; this
file covers the PGLite + --follow path the minion-orchestrator skill now
documents.

Two assertions:

1. submit → registerBuiltinHandlers → worker.start → shell runs → completes
   with exit_code 0 and stdout_tail "hello\n". Exercises the exact dispatch
   path src/commands/jobs.ts:207 takes when --follow is set, including the
   GBRAIN_ALLOW_SHELL_JOBS=1 gate.

2. With GBRAIN_ALLOW_SHELL_JOBS unset, registerBuiltinHandlers leaves the
   shell handler unregistered. Confirms the env gate from
   src/commands/jobs.ts:611 works.

Runs in-memory against PGLiteEngine — no DATABASE_URL, no Docker, runs in
CI unconditionally. Completes in ~1.2s.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pre-landing review caught 4 doc bugs + 2 test fragilities + 2 pre-existing
drift cases. All auto-fix category (clear correct answer, single obvious fix).

minion-orchestrator/SKILL.md:
- Shell submit examples used nonexistent `--cmd`/`--argv`/`--cwd` flags. Real
  CLI takes `--params '{"cmd":"...","cwd":"..."}'` (src/commands/jobs.ts:55-85).
  Examples now match `gbrain jobs submit --help` output.
- `--tools "search,web_search"` referenced `web_search` which isn't in
  BRAIN_TOOL_ALLOWLIST (src/core/minions/tools/brain-allowlist.ts:47-59).
  Swapped to `search,query`. Added a full allowlist enumeration so
  readers don't have to grep.
- `gbrain agent run` flags section listed `--queue`, `--priority`,
  `--max-attempts`, `--delay` — none of these exist on that command
  (src/commands/agent.ts:105-129). Replaced with the real flag set
  (`--subagent-def`, `--model`, `--max-turns`, `--tools`, `--timeout-ms`,
  `--fanout-manifest`, `--follow`, `--no-follow`, `--detach`) and a note
  about using `gbrain jobs submit` for queue tuning.
- MCP boundary claim "returns permission_denied" was imprecise. Reworded:
  throws an OperationError with code permission_denied.

test/resolver.test.ts:
- D5/C row regex required the backtick-quoted skill path to be followed
  immediately by `|`, silently skipping rows with trailing parentheticals
  (e.g., `` `skills/maintain/SKILL.md` (extraction sections) |``). Broadened
  to `[^|]*\|` so every row gets audited.

test/e2e/minions-shell-pglite.test.ts:
- Shared engine across both tests with no per-test reset. Future test
  additions would hit order-dependency. Added beforeEach TRUNCATE on
  minion_jobs / minion_inbox / minion_attachments, matching the Postgres
  sibling at test/e2e/minions-shell.test.ts:55-58.

skills/query/SKILL.md:
- Added 4 triggers RESOLVER.md routes to this skill but the frontmatter
  never declared: "who knows who", "relationship between", "connections",
  "graph query". Pre-existing drift — the broadened D5/C regex surfaced it.

skills/maintain/SKILL.md:
- Added 6 triggers with the same pre-existing drift: "extract links",
  "build link graph", "populate timeline", "populate links", "backfill graph",
  "extract timeline entries".

57/57 tests pass on the fixed tree.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two more stale references caught by specialist re-dispatch on the fixed tree:

skills/minion-orchestrator/SKILL.md:72 — Routing table row described shell
  jobs as taking `--cmd` or `--argv` as CLI flags. Same class of bug as M1
  from the prior fix commit but in a different location. Now says `--params`
  with `cmd` or `argv`, matching the corrected submit examples (lines 112-120).

skills/conventions/subagent-routing.md:82 — "Check `get_job_stats`
  queue_health.active" referenced an MCP operation that doesn't exist in
  src/core/operations.ts. The new minion-orchestrator skill cross-references
  this convention file, so agents following the routing pointer would hit a
  non-existent op. Replaced with the real ops: `list_jobs --status active`
  (MCP) or `gbrain jobs stats` (CLI).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Claude adversarial subagent caught two last consistency gaps:

skills/manifest.json:135 — Skill description still read "Manage background
  agents via Minions job queue" (subagent-only framing), out of sync with
  the reframed SKILL.md frontmatter. Manifest is what the skill registry
  indexes; leaving this stale meant shell-job-intent routers would miss it.
  Updated to match the unified wording.

skills/minion-orchestrator/SKILL.md:288 — Anti-pattern line "Don't use
  sessions_spawn with runtime: subagent when Minions is available" was
  subagent-lane-specific inside the now-consolidated skill, reading like
  the one rule in the skill but only addressing one lane. Scoped to
  "For subagent work" and pointed at `gbrain agent run` so the rule
  doesn't confuse shell-job readers.

Two investigate-class items deferred to follow-up:
- D13 regex could false-positive on future skills with unrelated `name="..."`
  usage. Today clean; scope to backtick-fenced snippets if it bites.
- PGLite E2E env-var race if bun:test ever goes file-parallel. Today isolated
  per file; add helper + comment when needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Skill count 28 -> 29 across README and CLAUDE.md (adds smoke-test from
  v0.19.1 to the Skills section, closes a prior drift).
- README minion-orchestrator row rewritten to name both lanes (shell jobs
  via `gbrain jobs submit shell`, LLM subagents via `gbrain agent run`)
  so the surface matches the consolidated skill file.
- README Operational table gains a smoke-test row.
- CLAUDE.md key-files entry for minion-orchestrator now describes the
  v0.19.2 consolidation, trust boundary (MCP permission_denied on
  protected names), and the narrowed trigger set.
- CLAUDE.md Skills section notes the consolidation and the new v0.19.1
  smoke-test skill.
- CLAUDE.md test inventory picks up `test/e2e/minions-shell-pglite.test.ts`
  and the v0.19.2 round-trip + name-validator additions in
  `test/resolver.test.ts`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@garrytan garrytan changed the title feat: merge gbrain-jobs into minion-orchestrator — single unified minions skill v0.19.2 feat: merge gbrain-jobs into minion-orchestrator — single unified minions skill Apr 24, 2026
…kills

# Conflicts:
#	CHANGELOG.md
#	CLAUDE.md
#	VERSION
#	package.json
@garrytan garrytan changed the title v0.19.2 feat: merge gbrain-jobs into minion-orchestrator — single unified minions skill v0.20.4 feat: merge gbrain-jobs into minion-orchestrator — single unified minions skill Apr 24, 2026
garrytan and others added 2 commits April 24, 2026 01:28
…ms-full.txt

CI caught two issues:

1. `test/e2e/minions-shell-pglite.test.ts` — the "GBRAIN_ALLOW_SHELL_JOBS
   unset → shell handler not registered" test was written against pre-v0.20.3
   `registerBuiltinHandlers` behavior (env gate at registration time). Master's
   queue-resilience merge moved the gate from registration to execution:
   shell handler is now always registered so claimed jobs emit a clear rejection
   log, and `shellHandler` itself throws UnrecoverableError when
   GBRAIN_ALLOW_SHELL_JOBS != '1' (see src/core/minions/handlers/shell.ts:210).
   Updated the test to invoke shellHandler directly with a minimal ctx and
   assert the throw. Preserves the test's intent (prove the guard works) under
   the new control flow.

2. `llms-full.txt` drift — README.md + CLAUDE.md updates in v0.19.2 and v0.20.4
   updated the skill count to 29 and rewrote the minion-orchestrator
   description, but the committed `llms-full.txt` bundle still reflected the
   pre-consolidation content. Regenerated via `bun run build:llms`.

The third CI failure (`planInstall + applyInstall D-CX-11`) passes cleanly
locally (26/26 in test/skillpack-install.test.ts). The 1ms runtime in CI
suggests a filesystem-mtime flake, not a real regression from this branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
D-CX-11 ("--force-unlock overrides a stale lock") flaked in CI with a 1ms
runtime. Root cause: on fast CI filesystems (ext4 with high-resolution
mtimes on GitHub runners), `writeFileSync` can set a lock's mtime a few
microseconds ahead of the subsequent `Date.now()`, making `age` negative.

Old logic:
  const stale = age >= staleMs;

With `staleMs: 0` and `age = -0.3ms`: `-0.3 >= 0` is false → NOT stale →
the `!stale` branch throws `lock_held` before reaching the force-unlock
path. Test failed at the first ms, never exercised the actual unlock logic.

Fix (src/core/skillpack/installer.ts:189):
  const stale = age < 0 || age >= staleMs;

Treats negative age (future mtime) as stale. Safe: if the lock's mtime is
in the future, either the filesystem clock just jumped forward or the
lock was written by a racing process; either way it's not a live,
healthy lock and the stale path is the correct branch.

Passes locally (26/26 in test/skillpack-install.test.ts).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@garrytan garrytan merged commit 11abb24 into master Apr 24, 2026
4 checks passed
garrytan added a commit that referenced this pull request Apr 24, 2026
Pulls upstream v0.20.4 (#381): merge gbrain-jobs into minion-orchestrator —
single unified minions skill.

Conflicts resolved:
- VERSION — kept 0.21.0; upstream is 0.20.4
- package.json — v0.21.0 wins
- CHANGELOG.md — v0.21.0 preserved above upstream's v0.20.4

Build clean: 0.21.0 binary runs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ChenyqThu pushed a commit to ChenyqThu/jarvis-knowledge-os-v2 that referenced this pull request Apr 27, 2026
Merge upstream/master (commit 11abb24, gbrain v0.20.4) into KOS v2 fork.

Six upstream commits land:
- v0.19.0 check-resolvable OpenClaw fallback (garrytan#326)
- v0.19.1 smoke-test skillpack (garrytan#369)
- v0.20.0 BrainBench extracted to sibling repo (garrytan#195)
- v0.20.2 jobs supervisor (garrytan#364) — Postgres-only, PGLite skips
- v0.20.3 queue resilience + queue_health doctor (garrytan#379) — Postgres-only
- v0.20.4 minion-orchestrator skill consolidation (garrytan#381)

Conflicts resolved (2 real, 5 auto):
- .gitignore: union both fork (.omc/, kos-jarvis log globs) and upstream
  (eval/data/world-v1/world.html, amara-life-v1 cache) entries.
- skills/manifest.json: append upstream's smoke-test skill plus retain
  the 9 kos-jarvis fork skills (39 total).
- CLAUDE.md / README.md / package.json (0.20.4) / skills/RESOLVER.md /
  src/cli.ts (mode 0755) auto-merged cleanly.

Fork-local patches preserved (verified post-merge):
- src/core/pglite-schema.ts:65 — idx_pages_source_id commented out
  (upstream garrytan#370 still open, fix retained).
- src/core/pglite-engine.ts:87 — pg_switch_wal() before close()
  (WAL durability patch, no upstream issue filed yet).
- src/cli.ts mode 100755 — bun shim executable bit.

Issue garrytan#332 (v0_13_0 process.execPath) fixed upstream in v0.19.0 ...
running gbrain apply-migrations --yes will clear the partial-ledger
remainder that has been stuck in doctor since the v0.13 sync.

v0.20's headline features (jobs supervisor, queue_health, wedge-rescue,
backpressure-audit) are Postgres-only and skip on our PGLite engine.
Sync is preventive ... keeps the fork mergeable rather than buying new
runtime capability.

Pre-merge baseline (HEAD 170876f):
- pages 1988, chunks 3750 (100% embedded), links 8522, timeline 10881
- doctor health 60/100 (failed: minions_migration partial 0.13.0)
- brain_score 86/100

Rollback: git tag pre-sync-v0.20-1777105378
PGLite snapshot: ~/.gbrain/brain.pglite.pre-sync-v0.20-1777105391 (416M)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant