* Add OpenClaw skills fallback for check-resolvable
* feat: v0.17.0 foundation — errors/warnings split + AGENTS.md support + auto-manifest
First two workstreams of the v0.17.0 "skillify end-to-end" release. Landed
together because the D-CX-3 exit-code refactor is a prerequisite for W1's
warning-surfaced filing audit in Workstream 3.
## D-CX-3: split ResolvableReport into errors[] + warnings[] + --strict
Prior: `env.ok = report.issues.length === 0` treated warnings and errors
identically for exit status. Any warning forced exit 1, which meant the
planned filing-audit (W3) would break CI for every OpenClaw deployment
emitting advisory warnings.
New contract:
- `ResolvableReport.errors[]` and `warnings[]` as separate arrays.
- `issues[]` stays as deprecated backcompat union (remove in v0.18).
- Default: exit 0 unless any errors. Warnings are advisory.
- `--strict` flag promotes warnings to fail CI (explicit opt-in).
Files: src/core/check-resolvable.ts, src/commands/check-resolvable.ts
(added --strict flag + help text + header doc), src/commands/doctor.ts
(use new fields), test/check-resolvable-cli.test.ts (rewrite REGRESSION-GATE
to document the new contract, add 3 D-CX-3 cases).
## W1: AGENTS.md support + auto-manifest + priority fix
The reference OpenClaw deployment uses AGENTS.md (not RESOLVER.md) at the
workspace root, and ships without a manifest.json. check-resolvable
silently false-passed against it pre-W1: 0 manifest entries meant 0
reachability iterations meant 0 errors reported.
Post-W1 behavior against ~/git/<redacted>/workspace (smoke-tested live):
- Detects 102 skills via SKILL.md walk (no manifest.json needed)
- Flags 15 unreachable errors (exactly the essay's '~15% dark' finding)
- Flags 108 warnings (overlaps, gaps) — advisory, not blocking
- Auto-detects via \$OPENCLAW_WORKSPACE without --skills-dir
Changes:
- NEW src/core/resolver-filenames.ts: one source of truth for the
filename policy. \`RESOLVER_FILENAMES = ['RESOLVER.md', 'AGENTS.md']\`.
Callers import from here, never hardcode either name.
- NEW src/core/skill-manifest.ts: \`loadOrDeriveManifest()\` — reads
manifest.json when present+valid, otherwise walks \`skillsDir/*/SKILL.md\`
to derive a synthetic manifest. Both check-resolvable.ts AND dry-fix.ts
now call this, replacing the two duplicated loaders that silently
returned [] on missing file (F-ENG-1, D-CX-12).
- src/core/repo-root.ts (rewrite): auto-detect priority changed to put
\$OPENCLAW_WORKSPACE ahead of findRepoRoot() walk when explicitly set
(D-CX-4). Adds workspace-root AGENTS.md detection — OpenClaw layout
places routing at workspace/AGENTS.md with skills/ below. New
SkillsDirSource variants \`openclaw_workspace_env_root\` and
\`openclaw_workspace_home_root\` for --verbose log clarity.
- src/core/check-resolvable.ts: accepts RESOLVER.md or AGENTS.md at the
skills dir or one level up (workspace root). Uses loadOrDeriveManifest
for reachability. Updated error messages reference both filenames.
- src/core/dry-fix.ts: unified manifest loader — auto-fix now works in
AGENTS.md-only workspaces where it previously no-op'd silently.
- src/commands/check-resolvable.ts: new AUTO_DETECT_HINT import for
clearer missing-skills-dir errors; updated sourceLabel map for the
two new workspace-root variants.
Tests:
- test/skill-manifest.test.ts: 14 cases covering explicit-manifest,
derived-manifest, malformed JSON, wrong shape, empty explicit array
(honored as 'zero skills' declaration), dirname fallback when no
name: frontmatter, underscore/dotfile dir skipping.
- test/repo-root.test.ts: new tests for the priority swap, AGENTS.md
skills-dir variant, AGENTS.md workspace-root variant, both-files
present (RESOLVER.md wins).
- test/check-resolvable-cli.test.ts: updated regression-gate to the
new contract; added three D-CX-3 cases.
All 105 tests passing across the foundation surface.
Plan + reviews: ~/.claude/plans/p1-lets-just-vast-blanket.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: v0.17.0 W2 — Check 5 trigger routing eval (structural)
Check 5 of the 10-step skillify checklist (the essay's "resolver
trigger eval") now runs structurally by default and has a dedicated
CLI verb for CI. Ships Layer A; Layer B (LLM tie-break) is reserved
for v0.18.
## New module: src/core/routing-eval.ts
The harness. Pure functions:
- `normalizeText(s)`: lowercase, strip non-alnum to spaces, collapse
whitespace. Unicode-friendly, quote-agnostic, punctuation-tolerant.
- `extractTriggerPhrases(cellText)`: split quoted alternatives like
`"search for", "find me"` into separate normalized phrases; fall
back to the whole cell when unquoted (OpenClaw-style descriptions).
- `indexResolverTriggers(resolverContent)`: build a skill-slug →
normalized-trigger-phrases map from the resolver table.
- `structuralRouteMatch(intent, index)`: substring-match the
normalized intent against every trigger phrase; return the set of
matched skills + whether the match was ambiguous (more than one
specific skill, excluding always-on family).
- `lintRoutingFixtures`: rejects fixtures whose intent is
verbatim-equal to a trigger (D-CX-6: fixtures must paraphrase the
framing, not copy the trigger text) and unknown expected_skill
references.
- `loadRoutingFixtures(skillsDir)`: walks `skills/<name>/routing-eval.jsonl`,
handles JSONL line-comments (`//` / `#`), collects malformed lines
separately without crashing.
- `runRoutingEval(resolver, fixtures)`: pure scoring. Supports
negative cases (`expected_skill: null` — nothing should match) and
an `ambiguous_with` allow-list for skills that co-fire with
always-on handlers (signal-detector, brain-ops, ingest).
Outcomes per fixture: `pass`, `missed`, `ambiguous`, `false_positive`.
Metrics: `top1Accuracy`, `passed`, `missed`, `ambiguous`,
`falsePositives`.
## Integration: check-resolvable runs Layer A by default
`checkResolvable()` now loads `routing-eval.jsonl` fixtures from every
skill, runs the structural eval, and appends non-pass outcomes as
warning-severity issues. New issue types:
- `routing_miss` — expected skill did not match
- `routing_ambiguous` — expected matched AND unexpected skills
- `routing_false_positive` — negative case unexpectedly matched
- `routing_fixture_lint` — linter or malformed-JSONL finding
All four are warnings — routing issues don't break exit in default
mode, but `--strict` promotes them (D-CX-3 contract). Advisories
without breaking CI.
## New CLI verb: `gbrain routing-eval`
Standalone Check 5 runner. `--json` envelope, `--llm` flag reserved,
`--skills-dir` override. Exit codes: 0 clean, 1 any failure/lint, 2
setup error. Suitable for CI gating separately from check-resolvable.
Removed from DEFERRED in CLI: `{check: 5, name: trigger_routing_eval}`.
Check 6 (brain_filing) still deferred; lands in W3.
## Seed fixtures
- skills/query/routing-eval.jsonl
- skills/citation-fixer/routing-eval.jsonl (includes a negative case)
These are intentionally modest. Additional fixtures per skill are the
natural next step; routing-eval itself passes cleanly under
check-resolvable default mode even when fixtures surface real gaps
(they're warnings, not errors). Running `gbrain routing-eval` reveals
the gaps immediately.
## Tests (34 new cases + updated integrations)
- test/routing-eval.test.ts: full harness coverage including
normalization, trigger extraction (quoted and unquoted), indexer,
structural match with ambiguity + always-on exemption, fixture
linter (verbatim-equality rule, unknown-skill rule, shape rule,
negative-case skip), JSONL loader (comments, malformed lines,
missing dirs, underscore/dot skipping), and every runRoutingEval
outcome (pass, miss, ambiguous, negative-pass, false-positive, empty).
- test/check-resolvable-cli.test.ts: updated DEFERRED unit test +
`--json` envelope test + `--verbose` test to reflect Check 5
shipping.
140/140 passing across the W1 + W2 surface.
## Live smoke
`gbrain routing-eval --json` against the current gbrain repo: 6
fixtures, 1 passing, 5 missed. The misses correctly surface
resolver-trigger narrowness (intents users naturally phrase differently
than trigger text). Fixtures will iterate in follow-up PRs; the
machinery ships now.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: v0.17.0 W3 — Check 6 brain filing audit
Check 6 ships. Every skill that writes brain pages is now audited
against a machine-readable filing-rules doc at
`skills/_brain-filing-rules.json`.
## New: skills/_brain-filing-rules.json
Canonical filing rules, JSON (D-CX-8: the pre-existing yaml-lite
parser handles flat maps only, so YAML would have needed a new
dependency for one file). The companion `_brain-filing-rules.md`
stays as the human explainer. 14 rule entries + explicit
`sources_dir` carve-out for bulk/raw data.
## New module: src/core/filing-audit.ts
- `loadFilingRules(skillsDir)`: returns parsed doc or null (missing
file → no-op; malformed JSON throws loud).
- `allowedDirectories(rules)`: normalized set of every rules[]
directory + sources_dir.
- `runFilingAudit(skillsDir)`: walks skills/*/SKILL.md, parses
frontmatter, audits any skill with `writes_pages: true`.
Two checks per qualifying skill:
1. `writes_to:` list is non-empty.
2. Every entry in `writes_to:` appears in allowedDirectories.
Both failures emit warning-severity issues. No errors — advisories
only, per D-CX-3.
## Distinction: writes_pages vs mutating (D-CX-7)
v0.17 introduces a new boolean frontmatter field `writes_pages:`.
`mutating: true` already means "has any side effect" (cron
schedulers, report writers, config mutators). Filing audit targets
ONLY skills with `writes_pages: true`, correctly excluding side-
effect-but-not-page-writing skills. The codex outside voice caught
this: conflating the two fields would drag ~100 skills into
filing-audit noise in the reference OpenClaw deployment.
## Integration: check-resolvable runs Check 6 by default
`checkResolvable()` calls `runFilingAudit(skillsDir)` and appends
issues as warnings. On missing/malformed rules doc, surfaces a
single advisory rather than bailing.
`DEFERRED` array in the CLI is now empty — v0.17 ships both Check 5
(W2) and Check 6 (W3). The export stays in place (stable --json
field) for future deferred checks.
## Seeded frontmatter on 7 canonical writers
Added `writes_pages: true` + `writes_to:` to:
- brain-ops (people, companies, deals, concepts, meetings)
- enrich (people, companies)
- ingest (people, companies, concepts, meetings, sources)
- idea-ingest (people, concepts, sources)
- media-ingest (concepts, people, companies, sources)
- meeting-ingestion (meetings, people, companies)
- signal-detector (people, companies, concepts)
Live smoke: `gbrain check-resolvable --json` on gbrain repo shows
`ok: true`, zero filing errors, zero filing warnings on seeded
skills. Every other mutating:true skill (citation-fixer,
cron-scheduler, data-research, maintain, migrate, minion-orchestrator,
reports, setup, skill-creator, soul-audit, webhook-transforms)
correctly skipped as side-effectful-but-not-page-writing.
## Tests (17 new cases + 3 updated CLI integrations)
test/filing-audit.test.ts covers:
- rules loader: missing (null), valid, malformed (throw),
non-array rules (throw)
- directory normalization (trailing slash, leading slash)
- clean case
- missing writes_to on writes_pages:true
- unknown directory
- D-CX-7: mutating:true alone does not trigger audit
- writes_pages:false skips
- no frontmatter skips
- inline `writes_to: [a, b]` syntax
- block `writes_to:\n - a` syntax
- sources/ allowed
- underscore/dot dir skipping
- total counts (totalScanned vs writesPagesSkills)
- missing dir graceful
- action string quality guard
Plus: CLI integration tests updated for empty DEFERRED array (Checks
5 and 6 both shipped).
158/158 passing across the v0.17 foundation + W1 + W2 + W3 surface.
## v0.18 preview (D-CX-13)
v0.17 filing-audit is declaration-level only. A future
`gbrain filing-audit --pages` walks the brain itself, infers primary
subject from page content via LLM judgment, and flags actual
misfilings vs. declarations. Declaration audit is the leading
indicator; pages audit is the ground truth.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: v0.17.0 W4 — gbrain skillify {scaffold,check} subcommand namespace
The essay's "skillify it!" verb becomes a CLI primitive pair. Two
subcommands, both promoted/factored so there's one source of truth:
## `gbrain skillify scaffold <name>` (mechanical)
Pure file generation. Zero LLM, zero judgment. Writes 5 stub files
atomically:
1. skills/<name>/SKILL.md frontmatter + body template
2. skills/<name>/scripts/<name>.mjs deterministic-code stub
3. skills/<name>/routing-eval.jsonl routing fixture seed
4. test/<name>.test.ts vitest skeleton
5. Appended trigger row to the detected resolver file (RESOLVER.md
or AGENTS.md — whatever W1's auto-detect found)
Flags: --description (required), --triggers, --writes-to,
--writes-pages, --mutating, --force, --dry-run, --json, --skills-dir.
Kebab-case name validation (`^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$`).
Works against gbrain-native RESOLVER.md layout AND OpenClaw-native
AGENTS.md-at-workspace-root layout (W1 interop).
## `gbrain skillify check [path]` (audit)
Promoted from scripts/skillify-check.ts per codex D-CX-2. The legacy
script stays as a 12-line shim that delegates to the new module so
existing callers (docs, cron, tests) keep working.
Wrapped in a subcommand namespace: `gbrain skillify {scaffold, check}`
is one coherent verb for the whole post-task loop. The essay's
"skillify it!" triggers the markdown skill, which orchestrates the
CLI primitives.
## Idempotency contract (D-CX-7)
`skillify scaffold --force` regenerates stub FILES but never re-appends
a resolver row that already references `skills/<name>/SKILL.md`.
Unit test pins this: two applies produce one resolver row, not two.
## D-CX-9 SKILLIFY_STUB sentinel
Every scaffolded script + SKILL.md body carries a SKILLIFY_STUB
sentinel. `check-resolvable` walks every skill's script dir looking
for the marker and emits a `skillify_stub_unreplaced` warning when
found. Default mode: advisory. `--strict` mode: error, blocks CI.
This is the gate that catches "we scaffolded and forgot to implement"
— the exact failure codex flagged as "scaffold verification is
theater" in the outside-voice review.
## Files
- NEW src/core/skillify/templates.ts (template strings)
- NEW src/core/skillify/generator.ts (planScaffold / applyScaffold +
SkillifyScaffoldError with typed error codes)
- NEW src/commands/skillify.ts (top-level dispatcher + scaffold handler)
- NEW src/commands/skillify-check.ts (promoted check logic)
- scripts/skillify-check.ts: rewritten to 12-line shim
- skills/skillify/SKILL.md: Phase 2 now references the scaffold
primitive; legacy manual path kept for extending existing skills
- src/cli.ts: `skillify` added to CLI_ONLY + dispatcher
- src/core/check-resolvable.ts: SKILLIFY_STUB sentinel scan + new
issue type `skillify_stub_unreplaced`
## Tests (14 new scaffold cases)
test/skillify-scaffold.test.ts covers:
- SKILL_NAME_PATTERN validation (kebab-case, no spaces, no
leading digit, no underscores/uppercase)
- planScaffold against fresh + existing-file + --force paths
- SKILLIFY_STUB sentinel presence in SKILL.md AND script stub
(both gate paths)
- D-CX-7 idempotency: resolverAppend null when row pre-exists,
second apply doesn't duplicate the row
- TBD-trigger placeholder when --triggers empty
- writes_pages / writes_to / mutating flow through to frontmatter
- applyScaffold writes files + appends resolver
- Full AGENTS.md-layout workspace interop (W1)
Existing test/skillify-check.test.ts still passes against the legacy
shim — zero regression for downstream consumers.
178/178 passing across v0.17 foundation + W1..W4.
## Live smoke
\`gbrain skillify scaffold webhook-verify --description "verify incoming
webhook signatures" --triggers "verify webhook,check tunnel"
--skills-dir /tmp/smoke --dry-run\` produces the expected 4-file plan
plus a 115-byte resolver append. \`--help\` works on both the top-level
and scaffold levels.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: v0.17.0 W5 — gbrain skillpack install (deps closure + lockfile + diff/dry-run)
The essay's "drop it into YOUR OpenClaw" promise lands as a CLI
verb. One command installs a curated bundle of gbrain skills + the
shared convention files they depend on into a target OpenClaw
workspace. Data-loss protected, concurrency-safe, atomic on the
AGENTS.md managed block.
## openclaw.plugin.json refresh
- Bumped version from stale 0.4.1 → 0.17.0 (codex flagged this drift
F-ENG-4 / D-CX-4).
- Expanded curated skill list from 7 → 25. Uses skills/manifest.json
top-level (v0.10.0 sourced) minus setup/migrate/publish
(install-time / code+skill pairs) minus private skills.
- Added \`shared_deps: [...]\` listing convention files every skill
references: conventions/, _brain-filing-rules.{md,json},
_output-rules.md. Installer always pulls these (D-CX-10
dependency closure).
- Added \`excluded_from_install: [...]\` for setup/migrate/publish —
surfaces the intentional exclusion as data rather than a comment.
## New module: src/core/skillpack/bundle.ts
- \`findGbrainRoot(start)\` — walks up looking for openclaw.plugin.json
+ src/cli.ts. The pair identifies a gbrain checkout.
- \`loadBundleManifest(root)\` — strict validation + typed BundleError
codes (manifest_not_found, manifest_malformed, skill_not_found).
- \`enumerateBundle({gbrainRoot, skillSlug?, manifest})\` — flat list
of source → target-relative paths. When skillSlug is set, scopes
to that one skill BUT always pulls shared_deps. \`--all\` walks every
skill in the manifest.
- \`bundledSkillSlugs(manifest)\` — sorted slugs for \`skillpack list\`.
## New module: src/core/skillpack/installer.ts
- \`planInstall(opts)\` — builds InstallPlan with per-file
existing/identical diff state. Pure; no writes.
- \`applyInstall(plan, opts)\` — writes files + managed block with
the contracts below.
- \`diffSkill(root, slug, skillsDir)\` — read-only per-file status
for \`skillpack diff <name>\`.
**Per-file diff protection (D-CX-3 / F4):**
wrote_new fresh file
wrote_overwrite local diff + --overwrite-local passed
skipped_identical bytes match the bundle (silent re-install)
skipped_locally_modified target differs + no --overwrite-local
→ PROTECTED DEFAULT
**Concurrency + atomic AGENTS.md (D-CX-11):**
- \`.gbrain-skillpack.lock\` at workspace root. Acquired on the
first write, released in finally.
- Lock stale threshold configurable (default 10min). --force-unlock
overrides.
- Managed-block writes via tmp-file-plus-rename (atomic on POSIX).
**Managed-block format:**
<!-- gbrain:skillpack:begin -->
<!-- Installed by gbrain <version> — do not hand-edit between markers. -->
| Trigger | Skill |
|---------|-------|
| "alpha" | \`skills/alpha/SKILL.md\` |
| ...
<!-- gbrain:skillpack:end -->
extractManagedSlugs() roundtrips: single-skill installs accumulate
into the same block rather than overwriting each other.
## New CLI: gbrain skillpack {list, install, diff, check}
Namespaced alongside W4's \`gbrain skillify\`. Subcommands:
list bundle inventory (human + --json)
install <name> single skill + deps closure
install --all entire curated bundle
diff <name> per-file diff vs target; read-only
check delegates to the pre-existing skillpack-check
(same CLI just namespaced)
Flags on install: --overwrite-local, --force-unlock, --dry-run,
--json, --skills-dir, --workspace.
Exit codes: 0 clean, 1 files skipped (protected local edits),
2 setup error / lock held.
## Live smoke
\`gbrain skillpack list\`: 25 skills. \`skillpack install query --dry-run\`
against a fresh temp workspace: 12 files planned (SKILL.md,
routing-eval.jsonl, 7 convention files, 3 rule files, managed block
to AGENTS.md). All shared_deps flagged [shared].
## Tests (36 new cases)
test/skillpack-install.test.ts:
- findGbrainRoot walks up, returns null when absent
- loadBundleManifest validates + rejects malformed
- enumerateBundle pulls shared_deps on single-skill scope (D-CX-10)
- buildManagedBlock + updateManagedBlock: append when absent,
in-place replace when present, extractManagedSlugs roundtrip
- planInstall + applyInstall: fresh install, dry-run, idempotency
(skipped_identical), local-edit protection, --overwrite-local,
lock-held concurrency (D-CX-11), --force-unlock, atomic
managed-block write, multi-skill accumulation in managed block,
AGENTS.md-at-workspace-root interop (W1 cross-check)
- diffSkill: missing, identical, differs
test/skillpack-sync-guard.test.ts (F-ENG-4):
- both manifests exist
- every skill in plugin.json exists on disk
- every shared_dep exists on disk
- plugin.json skills ⊂ skills/manifest.json
- excluded skills aren't in the install list
- plugin version ≥ 0.17 (kills the 0.4.1 stale drift)
204/204 passing across the v0.17 foundation + W1..W5.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: v0.17.0 guards — privacy scrub + OpenClaw-reference E2E + v0.16.4 regression
Three ship-blocker work items from the eng review + codex outside
voice round out v0.17:
## scripts/check-privacy.sh (CLAUDE.md:550 enforcement)
Greps for the banned OpenClaw fork name (case-insensitive) across
tracked files. Two modes:
scripts/check-privacy.sh scan working tree
scripts/check-privacy.sh --staged scan git-staged files (pre-commit)
Exit 1 on any finding outside the allow-list. Allow-list covers files
where the name is legitimately present: this script itself (defines
the rule), CLAUDE.md (the canonical rule text), llms-full.txt
(auto-generated from CLAUDE.md), the historical upgrade guide, and
test/integrations.test.ts (whose personal-info regex ENFORCES the
rule against recipes/).
Scrubbed existing leaks:
- CHANGELOG.md:366 reference in a closes-# line → "from the
OpenClaw reference deployment"
- test/doctor-minions-check.test.ts:171 comment → "an OpenClaw
host's cron script"
- test/plugin-loader.test.ts fixture plugin name → "openclaw-ref"
## test/e2e/openclaw-reference-compat.test.ts (ship-blocker gate)
The test that proves v0.17 delivers on the headline claim. New
fixture at test/fixtures/openclaw-reference-minimal/ mimics the
reference OpenClaw deployment layout: AGENTS.md at workspace root,
skills/ below, no manifest.json. Four fixture skills
(signal-detector, query, brain-ops, context-now).
Every v0.17 surface gets exercised end-to-end:
- autoDetectSkillsDir with $OPENCLAW_WORKSPACE (D-CX-4 priority)
- loadOrDeriveManifest walks SKILL.md (F-ENG-1 auto-manifest)
- checkResolvable accepts AGENTS.md at workspace root, all 4
skills reachable via resolver rows, zero errors
- Filing audit clean (brain-ops declares writes_pages+writes_to)
- CLI subprocess via `--skills-dir` → exit 0
- CLI subprocess via $OPENCLAW_WORKSPACE (no flag) → exit 0,
correct skillsDir detection
- skillpack install against the layout writes managed block into
AGENTS.md at workspace root
This is THE ship-blocker test. If the W1 + W5 stack ever regresses
against an AGENTS.md-layout workspace, this fails first.
## test/regression-v0_16_4.test.ts (F-ENG-8)
Guards v0.17 against adding "surprise" warnings. Builds a clean
fixture matching v0.16.4 canonical shape (manifest.json, RESOLVER.md,
2 skills, no routing-eval fixtures, no writes_pages). Runs v0.17
checkResolvable and asserts:
- zero errors, zero routing_*/filing_*/skillify_stub_* warnings
- JSON envelope keys unchanged (errors, warnings, issues, ok,
summary) — deprecated `issues[]` still equals errors ∪ warnings
- summary shape unchanged
If someone adds a new check that fires unexpectedly on a v0.16.4-era
fixture, this test catches it immediately.
## Fixture
test/fixtures/openclaw-reference-minimal/
├── AGENTS.md (4 rows, 3 sections)
└── skills/
├── brain-ops/SKILL.md (writes_pages+writes_to)
├── context-now/SKILL.md
├── query/SKILL.md
└── signal-detector/SKILL.md
Intentionally small (4 skills, 1 AGENTS.md, ~30 lines total) so the
fixture is maintainable. The OPENCLAW-reference deployment has 107
skills — this fixture is the minimum shape that exercises the full
v0.17 code path.
## Tests
215/215 passing across the full v0.17 surface:
- foundation + W1 + W2 + W3 + W4 + W5 (204)
- regression-v0_16_4 (3)
- openclaw-reference-compat (7)
- privacy guard (separate bash; exits 0 clean)
Plus: privacy pre-commit hook is a drop-in wrapper (documented in
the script header). Wiring into .github/workflows is a follow-up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* release: v0.17.0 — skillify goes end-to-end
Every skill. Every check. Every install. One command each.
Five workstreams land in one release:
- W1: AGENTS.md + auto-manifest + env-priority
- W2: Check 5 routing eval
- W3: Check 6 brain filing
- W4: gbrain skillify {scaffold,check}
- W5: gbrain skillpack {list,install,diff}
Plus D-CX-3 foundation (errors/warnings split + --strict), plus
codex outside-voice fixes (D-CX-1..12 applied), plus privacy pre-
commit guard, plus OpenClaw-reference E2E fixture, plus v0.16.4
regression guard.
Live against the reference OpenClaw deployment: 102 skills detected
via auto-manifest, 15 unreachable errors + 108 warnings surfaced —
exactly the essay's "~15% dark" finding. The magic word from the
essay finally works the way the essay describes.
Tests: 2156 unit (178 new) + 152 E2E Tier 1 + 3 Tier 2 + 8 new
openclaw-reference fixture cases. 0 failures across all tiers.
Plan + reviews: ~/.claude/plans/p1-lets-just-vast-blanket.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(test): add missing 'strict' field to 5 Flags literals in check-resolvable-cli.test.ts
CI failed `tsc --noEmit` after the D-CX-3 errors/warnings split added
`strict: boolean` as a required field on the `Flags` interface. Five
test sites in test/check-resolvable-cli.test.ts still construct
Flags object literals (for direct `resolveSkillsDir()` calls) and
hadn't been updated.
Added `strict: false` to all five literals:
- line 129 --skills-dir absolute path
- line 135 --skills-dir relative path
- line 148 no --skills-dir
- line 160 no --skills-dir + no env
- line 178 --skills-dir + OPENCLAW_WORKSPACE (REGRESSION-GATE)
Unit tests: 207/207 pass across the v0.19 surface. tsc --noEmit
exits 0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: adopt gstack's branch-scoped CHANGELOG rule + rewrite v0.19.0 entry
CLAUDE.md gains a new top section before "CHANGELOG voice" that codifies
what gstack's CLAUDE.md already says: CHANGELOG is user-facing product
release notes, not a log of internal decisions. Every entry describes
what THIS branch adds vs master. Plan-file IDs, decision tags (D-CX-#,
F-ENG-#), review rounds, test counts as marketing, and contributor-
facing metrics don't belong in it.
The v0.19.0 entry is rewritten to the new bar:
Removed:
- Version-collision note about v0.17.0/v0.18.0 shipping on master
- All D-CX-## and W# tags (meaningless outside the plan file)
- "codex caught" / CEO + Eng review round-up narrative
- Plan file path reference
- "215 new cases across 13 test files" marketing metrics
- W1..W5 bucketing in itemized changes
Kept / sharpened:
- User-facing headline (what your agent can now do)
- Numbers that mean something to users (unreachable-skills count,
scaffold timing, pre/post AGENTS.md support)
- Upgrade instructions
- Added/Changed/Fixed/For-contributors itemized sections (standard
keep-a-changelog shape)
Version sequence (`grep "^## \["`) is contiguous v0.19.0 → v0.16.4.
Privacy guard clean. Tests green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: update README/CLAUDE/TODOS for v0.19.0 skills + skillify loop
Skill count was stale (README said 26, actual is 28: skillify + skillpack-check
were missing from the tables and count). Corrected throughout. Marked TODOS item
"Checks 5 + 6 deferred in PR #325" as completed in v0.19 — they shipped as real
implementations, not just filed issues.
README:
- Skill count 26 → 28 (headline, install flow, table section, architecture diagram)
- Added `skillify` + `skillpack-check` rows to the operational skills table
- Rewrote the "Skillify" section to lead with the four v0.19 CLI verbs
(`gbrain skillify scaffold/check`, `gbrain skillpack list/install/diff`,
`gbrain routing-eval`, `gbrain check-resolvable --strict`) instead of
describing the pre-v0.19 state. Added the "works on your OpenClaw" pitch
around AGENTS.md + auto-manifest. Added the "drop 25 curated skills into
your OpenClaw" section for skillpack install.
- Added v0.19 skills block + v0.18 multi-source + v0.17 dream to the Commands
reference at the bottom.
- Standalone instruction sets count: 25 → 28 (with a parenthetical noting
the curated 25-skill bundle that `skillpack install` ships).
CLAUDE.md:
- Skill count 26 → 28 in the Skills section.
- New "Skillify loop (v0.19)" sub-bullet listing skillify + skillpack-check.
- Noted that `AGENTS.md` is also accepted as a resolver filename.
TODOS.md:
- Created "## Completed" section at the top.
- Moved the "Checks 5 + 6" item there with completion note linking to the
actual implementation files (routing-eval.ts + filing-audit.ts).
Privacy scan clean. Version sequence contiguous v0.19.0 → v0.16.4.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(test): regenerate llms-full.txt + llms.txt after README/CLAUDE edits
CI failed on `build-llms generator > committed llms.txt + llms-full.txt
match current generator output`. The drift was expected: the prior
commit edited README.md and CLAUDE.md (skill count + skillify section),
both of which are inlined into llms-full.txt by `scripts/build-llms.ts`.
Fix: `bun run build:llms` + commit the regenerated output.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Wintermute <wintermute@garrytan.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>