* feat(skillpack): extract copyArtifacts shared helper (T1) Pure file-copy primitive for scaffold (gbrain→host) and harvest (host→gbrain). Atomic-refusal contract: symlink-reject + canonical-path containment validate every item before any write. Used by both directions of the v0.33 loop. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(skillpack): scaffold subcommand + SKILL.md frontmatter sources (T2) New scaffold.ts replaces the managed-block installer. One-time additive copy into the user's repo via copyArtifacts; refuses to overwrite existing files (user owns them). Partial-state policy: copies missing paired sources even when the skill dir already exists. bundle.ts extended with loadSkillSources + enumerateScaffoldEntries — paired source files declared in each SKILL.md's frontmatter sources: array, not in openclaw.plugin.json. Single source of truth, co-located with the skill. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(skillpack): reference command + apply-clean-hunks (T4 + T15) reference is the read-only diff lens with an agent-readable framing line. Pure-JS unified-diff producer + parser + applier (no patch(1) dependency). Two-way merge with documented limitation: without scaffold-time base tracking, applied hunks align everything to gbrain. The agent dry-runs reference first, then decides. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(skillpack): migrate-fence + scrub-legacy-fence-rows (T5 + T16) migrate-fence is the one-shot transition from the pre-v0.36 managed-block model. Strips begin/end markers and the cumulative-slugs receipt comment; preserves fence rows verbatim as user-owned routing during the transition to frontmatter discovery. Receipt-then-row fallback (F-CDX-8) covers stale/missing receipts. scrub-legacy-fence-rows is the opt-in cleanup after migrate-fence. Two-condition gate: removes a row only when skills/<slug>/ exists AND that skill's frontmatter declares non-empty triggers (proof frontmatter discovery covers it). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(skillpack): harvest + privacy linter (T6 + T7) The inverse loop: lift a proven skill from a host repo (~/git/wintermute, etc.) back into gbrain so other clients can scaffold it. --from <host-repo-root> is symmetric with scaffold's --workspace. Security: symlink rejection + canonical-path containment (mirrors validateUploadPath). Privacy: default-on linter scans harvested files against ~/.gbrain/harvest-private-patterns.txt plus built-in defaults (Wintermute, email, Slack channel patterns). Any match rolls back the copy and exits non-zero. --no-lint bypasses for the editorial workflow after a manual scrub. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(repo-root): cwd_walk_up tier for non-OpenClaw hosts (T9 + D3) autoDetectSkillsDir now walks up from cwd looking for any skills/ directory, ahead of the implicit ~/.openclaw/workspace fallback. cd ~/git/wintermute && gbrain skillpack scaffold ... finds wintermute automatically without requiring a RESOLVER.md/AGENTS.md to exist yet. R5 regression preserved: $OPENCLAW_WORKSPACE still wins when explicitly set. +5 test cases in test/repo-root.test.ts pin the new tier order and the R5 guard. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(skillpack): rewrite CLI dispatch, drop install + uninstall (T3 + T10) skillpack.ts dispatcher rewritten for the v0.36 contract: scaffold, reference (+ --apply-clean-hunks), migrate-fence, scrub-legacy-fence-rows, harvest, plus the existing list / diff / check. install and uninstall are gone — both exit non-zero with a hint pointing at scaffold / migrate-fence. Clean break, no deprecated alias. skillpack-check gains --strict for CI gating. When invoked as the subcommand `gbrain skillpack check`, default is informational (exit 0 even with drift); --strict opts back into the cron-friendly exit-1-on-issues behavior. Top-level gbrain skillpack-check preserves its existing exit semantics for backwards compat. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(skills): skillpack-harvest editorial workflow + resolver wiring (T8) The companion editorial skill for the gbrain skillpack harvest CLI. Walks the genericization checklist (scrub fork names, generalize triggers, lift fork- specific conventions to references) before the CLI runs. Routing-eval fixtures use paraphrased intents to avoid the intent_copies_trigger lint. Wires the new slug into openclaw.plugin.json#skills, skills/manifest.json, and skills/RESOLVER.md. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test(skillpack): 9-case real-subprocess E2E flow (T11) Spawns gbrain as a subprocess against tempdir workspaces. Covers: scaffold first-run + re-run no-op, reference diff + --apply-clean-hunks, migrate-fence, scrub-legacy-fence-rows, harvest privacy-lint catch + --no-lint bypass, and the install removed-error path. No DATABASE_URL needed — skillpack is filesystem-only. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore: docs + VERSION + CHANGELOG for v0.36.0.0 (T13 + T14) Skillpacks as scaffolding, not amber. v0.36 retires the managed-block install model. Six new subcommands replace install + uninstall: scaffold, reference (with --apply-clean-hunks), migrate-fence, scrub-legacy-fence-rows, harvest, plus the existing list / diff / check (check gains --strict for CI gating). Routing comes from each skill's frontmatter triggers — gbrain does not touch your RESOLVER.md or AGENTS.md. Companion editorial skill skillpack-harvest drives the genericization checklist; default-on privacy linter catches Wintermute / email / Slack references before they leak into gbrain core. New docs guide at docs/guides/skillpacks-as-scaffolding.md walks the model and the migration path for pre-v0.36 installs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(ci): privacy checks — allow-list harvest-lint tests, scrub user-facing fork-name references CI's check-privacy.sh and check-test-real-names.sh both flagged the literal fork name across the v0.36 skillpack diff. Two failure modes, two fixes: 1. **Meta-rule-enforcement files** added to both allow-lists. The harvest privacy linter's whole job is to catch the banned literal leaking into gbrain; its source has the regex pattern, its tests verify the linter fires by feeding it the banned string, and the skill markdown documents the substitution policy. Same exception status as check-privacy.sh and check-proposal-pii.sh themselves. Files allow-listed: - src/core/skillpack/harvest-lint.ts - test/skillpack-harvest-lint.test.ts - test/skillpack-harvest.test.ts - test/e2e/skillpack-flow.test.ts - skills/skillpack-harvest/SKILL.md 2. **User-facing references** swapped for canonical phrasing per CLAUDE.md's responsible-disclosure rule. README + new docs guide + 4 src docstrings + 1 test now say 'your OpenClaw' / 'host agent repo' / 'agentRepo' var name. Behavior unchanged — only documentation strings touched. Verify gate (the script CI runs) passes locally: EXIT=0. Tests still pass: 60/60 across the affected files. llms-full.txt regenerated. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(test): update check-resolvable-cli expectation for cwd_walk_up tier Sister fix to the test/repo-root.test.ts update in commit a31418e3. The new v0.33 cwd_walk_up tier fires before repo_root when running from inside the gbrain repo — same skills/ dir matched, different source label. Behavior unchanged; the legacy repo_root tier is now functionally subsumed (kept in the type union for back-compat). CI shard 3 failure: test/check-resolvable-cli.test.ts:171. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(test): pin clock in sync_freshness boundary tests (CI flake) The 24h and 72h exact-boundary tests scheduled last_sync_at relative to Date.now() at construction time, then let the check call Date.now() again internally. CI scheduler jitter between the two reads pushed ageMs past the strict > thresholds by microseconds, dropping the 72h-boundary case into the fail branch instead of warn. Fix: add an optional `opts.now` test seam to checkSyncFreshness. The two boundary tests now capture t0 once and pass it both to the timestamp constructor and to the check, making ageMs deterministically equal to the boundary. The non-boundary tests (4d, 30h, 2h, etc.) don't need pinning — they're comfortably away from the > comparison. CI shard 1 flake: test/doctor.test.ts:479. Locally 48/48 doctor tests pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(skillpack): agent-onboarding readme + next-action hints on every CLI surface (DX review) DX audit of the v0.36 scaffold model surfaced one structural gap and four output gaps. When scaffolded files land on a downstream agent's disk, the agent had no agent-facing manifest telling it what to do — no routing contract, no upgrade flow, no two-way merge warning at the right surface. Fixes: 1. **New shared dep: skills/_AGENT_README.md.** Lands on every scaffold + migrate-fence alongside the existing _brain-filing-rules.md and _output-rules.md. Short, agent-readable contract: walk *.SKILL.md frontmatter triggers: for routing, gbrain is reference not law on upgrade, no managed-block fence anymore, two-way merge has known limitations. Single source of truth for the agent operating contract. 2. **scaffold stdout** prints a next-action hint pointing at the readme (with absolute path) and the reference --all upgrade-sweep command. 3. **reference stdout** adds per-category decision policy: - missing → scaffold again - differs → was edit intentional? keep it. Accidental? patch by hand or apply-clean-hunks after reading the two-way warning. 4. **reference --apply-clean-hunks** prints the two-way merge WARNING BEFORE the apply (to stderr, survives stdout redirect). Spells out that gbrain has no scaffold-time base and local edits in differing sections WILL be aligned to gbrain. Skipped in --json mode for machine consumers. On conflicts, prints how to inspect and patch. 5. **migrate-fence stdout** tells the agent its routing model just changed (fence gone, walk frontmatter now) and points at scrub-legacy-fence-rows as the eventual cleanup. References the new _AGENT_README for fresh-install agents. Smoke verified end-to-end: 16 files land (was 15, +1 for _AGENT_README), hint prints with absolute path, readme lands on disk. Tests + verify gate pass clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(skillpack): upgrade-time reference sweep + reference --since version filter (DX deferred items) Closes the last two DX gaps from the v0.36 audit: 1. **Post-upgrade reference sweep.** New `postUpgradeReferenceSweep` helper called at the end of `gbrain post-upgrade`. After migrations apply, auto-runs `reference --all` against the detected host workspace and prints a one-line-per-skill summary of drift. Five gates: GBRAIN_SKIP_REFERENCE_SWEEP env-var bypass, no detected workspace (silent), workspace IS gbrain repo (dev-mode silent), zero drift (silent), and pure-missing skills the host never scaffolded are filtered out as noise. All errors swallowed — never blocks post-upgrade. Helper accepts test-seam opts (gbrainRoot, targetWorkspace) for unit testability. 2. **`reference --all --since <version>`.** Filters the sweep to skills whose source actually changed in gbrain between <version> and HEAD, using a new `changedSlugsSinceVersion` helper in bundle.ts. Pure-JS git wrapper (spawnSync), no deps. Accepts bare '0.X.Y.Z' or 'v0.X.Y.Z' or commit SHA. Falls back loudly to full sweep when git can't resolve the ref (tarball install, missing tag). Test coverage added — total +32 new test cases: UNIT (15 cases): - test/skillpack-changed-since-version.test.ts (9 cases): git-aware filter against a fixture git repo. Covers null on non-repo, null on bad tag, empty array on no changes, single + multi-slug drift (deduped + sorted), bare + v-prefix version forms, non- skills/ path filtering, SHA-prefix ref form. - test/upgrade-reference-sweep.test.ts (6 cases): gate logic. Covers env-var bypass, zero drift, empty-host suppression, drift-detected output shape, dev-mode workspace==gbrain guard, error-swallowing contract. E2E (8 new cases in test/e2e/skillpack-flow.test.ts): - 10: scaffold lands skills/_AGENT_README.md - 11: scaffold stdout prints the Next: hint - 12: scaffold re-run (skipped-existing) suppresses the hint - 13: reference stdout prints per-category decision policy - 14: --apply-clean-hunks WARNING on stderr, not stdout - 15: --apply-clean-hunks --json suppresses the WARNING (bug fix surfaced here: code originally printed unconditionally, now gated on !json) - 16: migrate-fence stdout points at the new routing model - 17: --since with a bad tag falls back to full sweep with warn Local sweep: 579/579 pass across 18 affected test files, verify gate EXIT=0, llms regenerated. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(README): zero-base rewrite — 921 → 422 lines, refreshed catalog, MECE structure The README had drifted into a changelog dumping ground. Four 'New in vX.Y' paragraphs competed for the lead, 16 version tags scattered through headings, the production-numbers hook (17,888 pages, 4,383 people) was six months stale, and skills were described in three places (Skills section, Commands section, inline marketing prose). Zero-based rewrite: **Refreshed catalog** (surveyed live brain + live agent fork, broad strokes per CLAUDE.md privacy rules): - ~100K total brain items (was 17,888 in the old README — 6x stale) - ~16K people (was 4,383) - ~5K companies (was 723) - ~8K concepts, ~4K originals, ~3.5K daily notes - ~31K media (30K tweets, 179 books, papers/films/games/interviews) - 108 cron jobs running (was 21) - 273 skills in the live agent fork (35 bundled + 238 user-built) **Structure** — MECE, single source of truth per concept: 1. Hook + at-a-glance table (refreshed numbers) 2. Install (3 paths, terse) 3. What it does (5 capability areas — replaces 12 scattered sections) 4. Skills (categorized one-liners — 35 lines, was ~200) 5. How it works (one coherent flow — replaces 4 overlapping sections: Architecture, Knowledge Model, Knowledge Graph, Search, Why It Works) 6. Commands (terse cheatsheet — every command, one line each) 7. Docs (link map — points to docs/ for the heavy stuff) 8. Origin / Contributing / License **Cut entirely** (moved or deleted): - 4 'New in vX.Y' leads (→ CHANGELOG.md is the changelog) - 16 (vX.Y) version tags in section headings - Minions stats subsection (subsumed into hook + 'durable background work') - Voice section (was 12 lines of brand prose) - Engine Architecture detail (→ docs/architecture/) - File Storage section (→ docs/guides/storage-tiering.md) - Per-skill marketing prose (one-liner per skill in the table) The README is no longer the changelog. Future releases append to CHANGELOG.md; the README only changes when a structural capability does. llms-full.txt regenerated. Privacy check + verify gate pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(README): fix line-start '+' rendering bug + lead with eval evidence Two fixes in one: 1. **Markdown bug fix.** The OAuth 2.1 paragraph had `+ PKCE,` on a line start (column 1), which GitHub-flavored markdown interprets as a list marker — the line break before it broke the paragraph and rendered as an orphan first line followed by a bullet. Rewrote the OAuth 2.1 capabilities as inline-comma-separated, escaped the `+` semantics. Swept the whole file for the same bug class — no other instances. 2. **Maximum-sell mode for evals.** Surveyed every published benchmark in both this repo and ~/git/gbrain-evals. Strongest evidence pulled to the top: - **97.60% R@5 on the public LongMemEval _s (500 questions).** No LLM in the retrieval loop. $0.50 per 1000 queries. Beats MemPalace raw by a point on the same dataset, beats every academic dense retriever (Stella, Contriever, BM25). Mastra/Supermemory measure a different metric (QA accuracy with LLM judge) — flagged honestly. - **+31.4 points P@5 from the self-wiring knowledge graph** on BrainBench v0.20.0 (240-page rich-prose corpus, 145 relational gold queries). Separable, measured, load-bearing. Zero retrieval regression across seven releases (v0.16 → v0.20). New '## Benchmarks' section after Install: - Public benchmark table with cross-system comparison - In-house BrainBench scorecard with per-adapter Δ vs gbrain - Source-swamp resistance result (93.3% top-1 vs 80% grep-only) - Skill/prompt compression: 25KB → 13KB AGENTS.md, +13-17pp accuracy across Opus 4.7 / Sonnet 4.6 / Haiku 4.5 - 'Run your own evals' subsection with copy-pasteable commands for every eval surface (longmemeval, cross-modal, eval capture/replay, BrainBench) Tightened the lead's cost-comparison claim to what's defensible per the underlying eval doc (MemPal LLM-rerank $0.001/q vs gbrain $0.0005/q; dropped the overstated '6x' I'd written initially). Privacy + verify gate + build-llms test all pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(README): integrate the eval story into the lead, move jargon into 'Receipts on the evals' Previous lead dumped metric acronyms (R@5, P@5, P@5 deltas, MemPalace, Stella, Contriever, BM25) before the reader knew what gbrain does. A 'somewhat technical' reader hits the wall of jargon and bounces. Rewritten: **Lead (jargon-free, 3 paragraphs)** — describes the value in plain English, with two anchor numbers: - 'right answer in top 5 results 97.6% of the time' (not 'R@5 97.60%') - 'roughly 4x more relevant than plain vector RAG' (not '+31.4 pts P@5') - 'better than every comparable system that doesn't pay for a language- model call on every retrieval' (the load-bearing honest framing, without naming the competitors mid-hook) - ends with '[Receipts on the evals →]' linking down **'## Benchmarks' renamed '## Receipts on the evals'** with a glossary at the top defining R@5, P@5, and 'no LLM in the loop' in one line each. Then the full tables: LongMemEval cross-system (with the metric-mismatch flag for Mastra/Supermemory), in-house BrainBench scorecard, source-swamp resistance, and prompt compression. The competitor names + metrics stay here where readers who want the receipts can find them, with the glossary so the acronyms don't tax cold readers. Net: lead reads as 'here's what it does and the proof' instead of 'here are the benchmark numbers, figure out what they mean.' Comparison facts unchanged. Privacy + verify gate + build-llms test all pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(README): name LongMemEval explicitly + first-person voice in lead Two specific edits from user feedback: 1. 'the standard public benchmark for AI memory systems' → 'LongMemEval' (linked to the HuggingFace dataset). The benchmark has a name; use it. 2. 'Built by the President and CEO of Y Combinator to run his own AI agents' (passive third-person) → 'I'm the President and CEO of Y Combinator, and I use this 16 hours a day' (active first-person). Carried the voice change through the rest of the README — the downstream 'Garry's personal agent' line and the Origin section's 'Garry Tan needed... he'd ever drafted... so he built one' all flip to first person ('my personal agent', 'I needed', 'I'd ever drafted', 'so I built one'). The README is now consistently first-person from the author's voice instead of a hagiographic third-person framing. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(README): add Multi-player and company brains section Three deployment patterns documented: 1. Single GBrain server + thin MCP clients (recommended). Tailscale private networking, OAuth scope, source-scoped clients, exhaustive what-clients-can/cannot-do lists. 2. Local PGLite + GStack for per-worktree code search. 3. Federated repos (advanced) — multiple servers indexing the same brain repo. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(README): tighten install path + add tech-orientation block + visceral query example Self-eval as a cold reader surfaced four gaps blocking a 10/10 first read: 1. Lead never says WHAT it is technically — CLI? service? cloud? local? Added a "What it is, technically" block right after the hook: open-source MIT, Bun CLI + MCP server, local-first, data stays on disk, MCP-native. 2. Install path optimized for committed users not evaluators. The old "recommended" path (deploy OpenClaw on Render, 8GB RAM) blocked anyone trying gbrain for the first time. Reordered into 3 paths by commitment: 60-second standalone CLI first, MCP for Claude Code / Cursor second, full agentic install third. 3. No example output showing what success looks like. Added a real sample `gbrain query` invocation with the hybrid-search result format so a reader can feel the experience before they install. 4. Privacy / data-locality unaddressed in lead. Now stated up front: embedding calls only hit external APIs if you configure them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
265 lines
10 KiB
Markdown
265 lines
10 KiB
Markdown
---
|
|
name: skillpack-harvest
|
|
version: 0.33.0
|
|
description: |
|
|
Lift a proven skill from a host repo (e.g. your OpenClaw fork) back into
|
|
gbrain's bundle so other clients can scaffold it. Editorial workflow:
|
|
the CLI does the file copy + privacy lint; this skill drives the
|
|
judgment-heavy genericization (scrub real names, generalize triggers,
|
|
lift fork-specific conventions to references).
|
|
triggers:
|
|
- "harvest this skill into gbrain"
|
|
- "publish this skill to gbrain"
|
|
- "lift this skill upstream"
|
|
- "share this skill with other gbrain clients"
|
|
- "promote my skill to gbrain"
|
|
mutating: true
|
|
writes_pages: false
|
|
writes_to:
|
|
- skills/<harvested-slug>/
|
|
- openclaw.plugin.json
|
|
---
|
|
|
|
# skillpack-harvest — Editorial workflow for lifting host skills into gbrain
|
|
|
|
> **Convention:** see [_brain-filing-rules.md](../_brain-filing-rules.md) for
|
|
> file placement rules. This skill writes into gbrain's own tree, not the
|
|
> brain repo's notes.
|
|
|
|
This skill is the inverse of `gbrain skillpack scaffold`. Scaffold ships
|
|
skills downstream (gbrain → host). Harvest lifts proven patterns
|
|
upstream (host → gbrain) so they become references every other client
|
|
can scaffold.
|
|
|
|
## Contract
|
|
|
|
A harvest is "properly done" when:
|
|
|
|
1. The host skill is mature (used in production, recent routing-eval
|
|
cases pass).
|
|
2. The editorial genericization in Phase 3 has scrubbed every
|
|
fork-specific reference (names, real entities, internal channels).
|
|
3. `gbrain skillpack harvest --dry-run` previewed the file set.
|
|
4. The real `gbrain skillpack harvest <slug> --from <host>` succeeded
|
|
with `status: harvested` (no privacy-lint hits).
|
|
5. `bun test test/skills-conformance.test.ts` passes on the new
|
|
`skills/<slug>/SKILL.md`.
|
|
6. The user has reviewed the diff in gbrain and explicitly approved
|
|
the commit.
|
|
|
|
If any of these is incomplete, the skill is NOT yet harvested — the
|
|
files may sit in gbrain's working tree, but they're not landed.
|
|
|
|
## Output Format
|
|
|
|
This skill produces three artifacts in gbrain's working tree:
|
|
|
|
1. `skills/<harvested-slug>/SKILL.md` (and any sibling files like
|
|
`routing-eval.jsonl`)
|
|
2. Paired source files at their mirror paths (e.g.
|
|
`src/commands/<slug>.ts`) when the host SKILL.md declared them
|
|
in frontmatter `sources:`
|
|
3. An updated `openclaw.plugin.json` with the new slug added to
|
|
`skills:` (sorted)
|
|
|
|
The session output to the user is a one-line success summary plus
|
|
a list of files written. JSON mode (`--json`) returns the full
|
|
`HarvestResult` shape for machine consumption.
|
|
|
|
## Anti-Patterns
|
|
|
|
- **Skipping the dry-run.** Always preview first. Files land in
|
|
gbrain's working tree; cleanup is a `git checkout` away, but you
|
|
shouldn't need to.
|
|
- **Trusting the linter alone.** The default regex set catches the
|
|
common cases. It doesn't catch every proper noun. Phase 3 (the
|
|
editorial pass) is the primary defense.
|
|
- **Harvesting `--no-lint` without justification.** The lint exists
|
|
for a reason. If you bypass it, document why in the commit.
|
|
- **Harvesting a skill that's still in flux.** Wait until the host
|
|
version stabilizes. Otherwise you'll harvest, then re-harvest,
|
|
then re-harvest, and that churns gbrain's bundle for no benefit.
|
|
- **Moving files instead of copying.** Harvest is a copy. The host
|
|
retains its skill. Don't `rm -rf` the source after harvesting.
|
|
- **Harvesting batch (multiple skills at once).** Not supported, and
|
|
for good reason — the editorial review per skill is real work.
|
|
|
|
## When to invoke
|
|
|
|
- The user developed a skill in their host fork (Wintermute, Neuromancer,
|
|
Zion, etc.) and wants other gbrain clients to be able to use it
|
|
- A skill has proven itself in production and is ready to generalize
|
|
- The user explicitly asks to "harvest" or "publish" a skill upstream
|
|
|
|
Do NOT invoke when:
|
|
- The skill is still in flux locally — let it stabilize first
|
|
- The skill references private content that can't be generalized
|
|
- The user just wants to share a one-off draft (use a gist instead)
|
|
|
|
## Preconditions
|
|
|
|
Before running this skill, confirm:
|
|
|
|
1. **The skill is mature.** Recent `routing-eval.jsonl` cases pass; the
|
|
skill has been used in production at least a few times.
|
|
|
|
2. **The skill is generalizable.** Strip-test in your head: replace
|
|
every fork-specific name. Does it still make sense as a skill?
|
|
|
|
3. **The user owns the gbrain checkout.** The harvest writes into
|
|
gbrain's working tree. They'll review and commit. Don't harvest
|
|
into a checkout the user doesn't intend to commit from.
|
|
|
|
## Workflow
|
|
|
|
### Phase 1 — Plan
|
|
|
|
Ask the user:
|
|
- What slug should the harvested skill have? (Slugs must be kebab-case,
|
|
globally unique in the gbrain bundle.)
|
|
- Which host repo is the source? (Path to repo root, not to the skill
|
|
directory — e.g. `~/git/wintermute`, not `~/git/wintermute/skills/foo`.)
|
|
- Should paired source files come along? (Check the host SKILL.md's
|
|
frontmatter `sources:` array.)
|
|
|
|
### Phase 2 — Dry-run + privacy-lint preview
|
|
|
|
Run the CLI with `--dry-run`:
|
|
|
|
```bash
|
|
gbrain skillpack harvest <slug> --from <host-repo-root> --dry-run
|
|
```
|
|
|
|
The output shows:
|
|
- Which files would land in gbrain's tree
|
|
- Whether paired sources are included
|
|
- (Implicit) The skill's frontmatter triggers — read them and check
|
|
they generalize
|
|
|
|
Do **not** skip the dry-run. The privacy linter only runs on a real
|
|
harvest, but the dry-run preview lets you see the files before they
|
|
land. Spot-check the SKILL.md and any paired source for things the
|
|
linter might miss (proper nouns, internal project names, etc.).
|
|
|
|
### Phase 3 — Genericization checklist (the editorial pass)
|
|
|
|
Before running the real harvest, walk the host's `skills/<slug>/`
|
|
files and apply this checklist. If anything matches, edit the host
|
|
file FIRST, then run harvest.
|
|
|
|
1. **Fork-specific names → generic phrasing**
|
|
- `Wintermute` → `your OpenClaw` (or `OpenClaw deployment`)
|
|
- `Neuromancer`, `Zion`, `<personal-fork-name>` → same treatment
|
|
- Personal first names (`garry`, `jane`, etc.) → `the user` /
|
|
`you` / a generic placeholder
|
|
|
|
2. **Real entities → placeholders**
|
|
- Real people, companies, deals, funds → placeholder slugs
|
|
(`alice-example`, `acme-example`, `fund-a`, etc.)
|
|
- Email addresses → strip entirely OR use `example@example.com`
|
|
- Internal Slack channels → `#some-channel` or strip
|
|
- Specific tracker IDs / Linear ticket numbers → strip
|
|
|
|
3. **Fork-specific conventions → references**
|
|
- Mentions of `<host-repo>/docs/...` files → either lift the doc
|
|
into gbrain OR replace with a generic placeholder explanation
|
|
- Mentions of `<host-repo>/skills/<other-fork-only-skill>` → either
|
|
decide to harvest that one too, or replace with a generic
|
|
pattern reference
|
|
|
|
4. **Triggers array generalizes**
|
|
- Read every entry in frontmatter `triggers:`. None should
|
|
reference the user's name, fork name, or internal tools.
|
|
- "Have garry sign off on it" → "have the user sign off on it"
|
|
|
|
5. **routing-eval.jsonl examples are scrubbed**
|
|
- Open `skills/<slug>/routing-eval.jsonl`. Every `intent` field
|
|
gets the same scrub as `triggers:`.
|
|
|
|
6. **Code comments + log strings**
|
|
- If a paired source is going to be harvested, walk it for the
|
|
same private-pattern leaks. Comments are the most common
|
|
hiding spot.
|
|
|
|
### Phase 4 — Real harvest
|
|
|
|
Once Phase 3 is complete, run the real harvest:
|
|
|
|
```bash
|
|
gbrain skillpack harvest <slug> --from <host-repo-root>
|
|
```
|
|
|
|
Default behavior:
|
|
- Path-confinement + symlink rejection at file copy
|
|
- Privacy linter runs against `~/.gbrain/harvest-private-patterns.txt`
|
|
(plus built-in defaults: `\bWintermute\b`, email, Slack channels)
|
|
- On any match → rollback (delete the harvested files) + exit non-zero
|
|
- `openclaw.plugin.json` updated to add the slug, sorted
|
|
|
|
Outcomes:
|
|
- `harvested` — success, manifest updated, files in gbrain's tree
|
|
- `lint_failed` — privacy linter caught something. Go back to Phase 3,
|
|
scrub the host file, retry.
|
|
- `slug_collision` — gbrain already has a skill at that slug. Either
|
|
use a different slug, or pass `--overwrite-local` if you really
|
|
mean to replace.
|
|
|
|
### Phase 5 — Verify in gbrain
|
|
|
|
After a successful harvest:
|
|
|
|
1. `bun test test/skills-conformance.test.ts` — confirms the new
|
|
SKILL.md meets the frontmatter contract.
|
|
2. `gbrain skillpack check --strict` — confirms no drift between
|
|
bundle and gbrain's own checkout.
|
|
3. `gbrain skillpack list` — confirms the slug shows up in the bundle.
|
|
4. Review the diff: `cd <gbrainRoot> && git diff -- skills/<slug>/`
|
|
5. Commit the additions in gbrain (do NOT commit any leftover files
|
|
in the host repo — harvest is a copy, not a move).
|
|
|
|
### Phase 6 — Downstream announcement (optional)
|
|
|
|
If other gbrain clients should pick up the new skill:
|
|
- Note it in `CHANGELOG.md` under "Skills added" for the next release
|
|
- Tag the user / contributor in the PR if the skill came from
|
|
someone outside the core team
|
|
|
|
## Bypass: `--no-lint`
|
|
|
|
The privacy linter is the safety net. The editorial pass is the
|
|
primary defense. If you've completed Phase 3 thoroughly and the
|
|
linter is still firing on a false positive, use `--no-lint`:
|
|
|
|
```bash
|
|
gbrain skillpack harvest <slug> --from <host-repo-root> --no-lint
|
|
```
|
|
|
|
**Document the bypass in the commit message.** Future maintainers
|
|
should be able to see WHY the lint was bypassed (e.g. "Wintermute
|
|
appears in a citation, not a real reference — verified manually").
|
|
|
|
Never bypass the linter on a casual basis. The whole point of the
|
|
default-on lint is that real names occasionally slip through the
|
|
editorial pass.
|
|
|
|
## What harvest does NOT do
|
|
|
|
- It does NOT move files (it copies). The host's `skills/<slug>/`
|
|
stays in place.
|
|
- It does NOT auto-scrub names. The editorial pass is human-driven.
|
|
- It does NOT publish to npm or a remote bundle. It writes to
|
|
gbrain's working tree; the user commits + ships via the normal
|
|
gbrain release process.
|
|
- It does NOT support `--all` (no batch harvest). One skill at a
|
|
time keeps the editorial review tractable.
|
|
|
|
## Files this skill touches
|
|
|
|
- gbrain's `skills/<slug>/` — every file in the host skill dir
|
|
(copy)
|
|
- gbrain's mirror path for declared paired sources
|
|
(e.g. `src/commands/<slug>.ts` if the host SKILL.md declares it
|
|
in frontmatter)
|
|
- gbrain's `openclaw.plugin.json` — adds the slug to `skills:`
|
|
array, sorted alphabetically
|