Skip to content

chore: release 0.5.0 - #173

Merged
wjduenow merged 2 commits into
mainfrom
release/0.5.0
May 30, 2026
Merged

chore: release 0.5.0#173
wjduenow merged 2 commits into
mainfrom
release/0.5.0

Conversation

@wjduenow

@wjduenow wjduenow commented May 30, 2026

Copy link
Copy Markdown
Owner

Cuts v0.5.0 to PyPI.

Scope: #141 only — the bundled SignalForge Claude Code skill + install-skill subcommand + SKILL ↔ CLI parity gate + docs/skills.md.

Why this is small: main's v0.4.0 release squash-merge (#167) already contained all the #135/#136/#137/#155/#159 content — main and dev are content-equivalent there, dev just has the granular commit history. The only post-v0.4.0 change on dev is #141 (709f147), so v0.5.0's honest delta is the skill stuff alone.

Branch shape: release/0.5.0 is based on main + git cherry-pick 709f147. The cherry-pick reproduces dev's tree modulo this release commit (verified: git diff release/0.5.0 origin/dev shows only CHANGELOG.md + init.py — both my edits).

Pre-flight:

  • uv sync --dev && uv run ruff check . && uv run ruff format --check . && uv run pyright && uv run pytest — all PASS (2753 passed, 97.75% coverage)
  • uv build + uvx twine check — PASSED on wheel and sdist
  • Skill metadata version strings bumped 0.5.0.dev0 → 0.5.0 (SKILL.md frontmatter + assets/SKILL.eval.json) to match the release

Follow-up: after merge, tag main HEAD v0.5.0, create non-prerelease GitHub Release with the curated [0.5.0] section, monitor publish-pypi, verify on PyPI, then open the combined dev PR (bump to 0.6.0.dev0 + backmerge main → dev).

Replaces: #172 (closed — had stale-Unreleased CHANGELOG bookkeeping bug that duplicated v0.4.0 content into [0.5.0]).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added signalforge install-skill command to deploy the bundled Claude Code skill into dbt projects.
    • Skill enables end-to-end AI-driven test generation workflow with demo paths.
  • Documentation

    • Added comprehensive skill user guide and installation instructions.
    • Updated CLI operations documentation and README with skill setup guidance.
  • Chores

    • Bumped version to 0.5.0.
    • Added evaluation badge to README.

Review Change Stack

wjduenow and others added 2 commits May 30, 2026 15:46
* #141: SignalForge skill + install-skill (plan)

Phase 4 detailing complete. 24 decisions locked across:
- skill source path (`src/signalforge/skills/signalforge/` package-data tree;
  `src/signalforge/skill/` Python lib)
- destination policy (always overwrite SKILL.md, preserve siblings, no --force)
- symlink/cycle defence (mirrors copy_demo verbatim)
- error hierarchy (SkillError base + 3 concretes; spans tiers 1+2 → excluded base)
- wheel packaging + wheel_smoke gate
- AST scan #7 bump (12→13)
- SKILL ↔ CLI parity gate (new test scans live argparse + key demo commands)
- 5-surface parity for install-skill
- self-grade ops (pre-release manual; pinned in eval.json + README badge)
- e2e demo paths (zero-cred default + opt-in live)
- skill-parity.md rule + cli-layer.md update (orchestrator-only)

11 stories laid out: US-001…US-009 implementation + US-010 Quality Gate + US-011
Patterns & Memory.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* #141: mark plan phase=published, link PR #166

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(#141): add skill-parity rule documenting CLI/skill parity gate

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* #141: devolved to beads (epic bd_1-scaffolding-ezn, 11 tasks)

Approved + devolved. US-001 is at the front of the ready queue.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* bd_1-scaffolding-ezn.1: US-001 bootstrap skills tree + wheel packaging

Lays down src/signalforge/skills/signalforge/{SKILL.md,assets/SKILL.eval.json}
as structural placeholders. Wires [tool.hatch.build.targets.wheel].include for
the skills tree. Extends wheel_smoke with _EXPECTED_SKILL_FILES (positive) and
a negative assertion that no .claude/skills/* paths appear in the wheel.

Plan: plans/super/141-claude-skill-install.md US-001 / DEC-001, 010, 011, 022.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* bd_1-scaffolding-ezn.2: US-002 signalforge.skill lib + typed errors + AST scan #7 bump

Adds signalforge.skill subpackage with install_skill(dest) -> Path and the
three-class typed-error hierarchy (SkillDestPathError tier 1, SkillDestUnsafeError
tier 2, SkillPackageDataMissingError tier 1). Mirrors signalforge.demo.copy_demo
verbatim for symlink-cycle defence and importlib.resources lookup; never rmtree.

Registers the three lib concretes in _EXCEPTION_TO_EXIT_CODE; adds SkillError to
_EXCEPTION_MAPPING_EXCLUDED_BASES; bumps AST scan #7 count 12 -> 13.

Plan: plans/super/141-claude-skill-install.md US-002 / DEC-002, 003, 005, 006, 007, 008, 009.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* bd_1-scaffolding-ezn.3: US-003 CLI install-skill subcommand + handler + exit-code mapping + subprocess smoke

Adds 'signalforge install-skill [<dest>]' wired via add_parser/cmd_install_skill
mirroring init_demo shape. Three CliInstallSkill*Error wrappers (Path/DestUnsafe/
PackageDataMissing) registered in _EXCEPTION_TO_EXIT_CODE (tier 1/2/1). Stdout
success line + (replaced existing SKILL.md) on overwrite per DEC-017. Subprocess
--help smoke under cli_subprocess marker. Per-class construction branches added
to test_exit_codes.py for the three new wrappers.

Plan: plans/super/141-claude-skill-install.md US-003 / DEC-002, 003, 004, 008, 009, 017, 024.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* bd_1-scaffolding-ezn.7: US-007 author SKILL.md prose (frontmatter + 7 body sections)

Replaces the US-001 placeholder with the real user-facing workflow per DEC-020
(frontmatter) and DEC-021 (seven sections). Body teaches the full pipeline:
point-at-project, zero-cred demo, real draft+prune, prune-existing,
diff-reading, gated live e2e, troubleshooting. Contains every canonical token
the US-004 parity gate scans for (subcommand names + demo command lines +
install-skill bootstrap).

Plan: plans/super/141-claude-skill-install.md US-007 / DEC-012, 013, 020, 021.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* bd_1-scaffolding-ezn.4: US-004 SKILL ↔ CLI parity gate

NEW tests/cli/test_skill_cli_parity.py scans src/signalforge/skills/signalforge/
SKILL.md for three token categories per DEC-015:
1. Every subcommand name from the live argparse parser (auto-grows)
2. Four canonical demo command lines (signalforge init-demo / generate <model>
   --write / prune-existing <model> --schema <path> / install-skill)
3. The install-skill bootstrap line (covered by category 2's fourth entry)

Plain substring match; no normalisation. Planted-violation self-check proves
the gate can fail loud — per testing-signal.md AST-source-scan-gate philosophy.

The gate runs inside the canonical VALIDATE_CMD (uv run pytest) so /ralph-run
keeps the skill current automatically without relying on the model remembering.

Plan: plans/super/141-claude-skill-install.md US-004 / DEC-015, 016, 019.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* bd_1-scaffolding-ezn.9: US-009 skill-parity.md + cli-layer.md update

Replaces the anticipatory skill-parity.md with the post-implementation
contract: names the actual shipped artefacts (src/signalforge/skill/,
src/signalforge/skills/signalforge/SKILL.md, signalforge install-skill,
tests/cli/test_skill_cli_parity.py), documents the two-name convention
(skills/ plural for package-data vs skill/ singular for the Python lib),
the planted-violation self-check, and the wheel exclusion defence for
maintainer-only .claude/skills/.

cli-layer.md § Multi-surface parity gains a paragraph naming the bundled
skill as the 6th parity surface, cross-linking to skill-parity.md and the
test_skill_cli_parity.py gate.

ORCHESTRATOR-ONLY commit per ralph-worker-claude-dir-perms memory —
workers cannot Write under .claude/ in worktrees.

Plan: plans/super/141-claude-skill-install.md US-009 / DEC-018, 019.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* bd_1-scaffolding-ezn.6: US-006 docs (skills.md + mkdocs nav + cli-ops + README pointer)

NEW docs/skills.md catalog page describing the bundled SignalForge skill, the
install-skill subcommand, the two demo paths (zero-cred default + opt-in live
e2e), the parity gate, and the maintainer-only-skill exclusion. mkdocs.yml nav
gains 'Claude Code Skill' entry. docs/cli-ops.md gains the install-skill
subcommand entry with stderr shapes + exit codes. README Quick start gains a
one-sentence pointer after pip install.

clauditor badge intentionally NOT added here — US-008 owns that surface.

Plan: plans/super/141-claude-skill-install.md US-006 / DEC-021, 023.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* bd_1-scaffolding-ezn.5: US-005 5-surface parity test for install-skill

Mirrors tests/cli/test_5_surface_parity_init_demo.py for the install-skill
subcommand. v0.1 canonical token: 'install-skill' (no flags). Pins the token
across argparse help, handler docstring, docs/cli-ops.md, plan document, and
the test docstring itself.

Orthogonal to test_skill_cli_parity.py (US-004): that scans the FULL CLI
surface against ONE skill body; this pins ONE subcommand across FIVE surfaces.

Plan: plans/super/141-claude-skill-install.md US-005 / DEC-024.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* bd_1-scaffolding-ezn.8: US-008 clauditor self-grade + README badge

Adds clauditor-eval to [dependency-groups].dev (PyPI dist name; provides
the 'clauditor' CLI entry point — the upstream LLM-as-judge framework
SignalForge's own grading layer shares its methodology with). Grade
pending — clauditor-eval installs cleanly and 'uv run clauditor grade'
runs, but a meaningful score requires a maintainer-crafted EvalSpec
(SignalForge-specific assertions + grading criteria); the auto-scaffolded
'clauditor init' template is generic boilerplate that would grade
noise-against-noise. Refined assets/SKILL.eval.json to a
'pending-first-grade' shape that pins the current signalforge.__version__,
names the grader and regen command, and explains why the maintainer must
hand-tune an EvalSpec before the first real grade. README shields.io
badge surfaces the pending state ('clauditor: pending', lightgrey). New
'Self-grade' section in docs/skills.md documents the regen flow for the
maintainer's pre-release workflow per DEC-014.

VALIDATE_CMD green: 2745 passed, all four checks. wheel_smoke + cli_subprocess
gated markers also green.

Plan: plans/super/141-claude-skill-install.md US-008 / DEC-014.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* bd_1-scaffolding-ezn.10: Quality Gate — fix bugs from code review

Four code-review passes surfaced 8 real findings; this commit addresses them.

CORRECTNESS
- src/signalforge/__init__.py: revert __version__ from 0.4.0.dev0 back to
  0.5.0.dev0 — the dev branch is the 0.5.0 development line; the previous
  value was a stale-rebase artifact (Review 1).
- src/signalforge/skill/__init__.py: extend symlink defence (DEC-005) to
  cover every install-tree ancestor (.claude/, .claude/skills/,
  .claude/skills/signalforge/) — not just SKILL.md itself. A symlinked
  ancestor dir would otherwise smuggle writes through copytree (Review 1).
- tests/skill/test_install.py: new test_install_skill_refuses_when_install_dir_ancestor_is_symlink
  pins the ancestor-symlink defence with a concrete attacker-elsewhere
  repro.

SKILL.md PROSE (drift between skill and live CLI surface)
- Remove the "--force" example (DEC-003 explicitly forbids the flag;
  re-running install-skill overwrites SKILL.md by default and preserves
  siblings).
- Frontmatter signalforge-version: "0.X.Y" → "0.5.0.dev0" (matches
  __version__; was a literal placeholder shipped to operators).
- Section 2: "no warehouse, no API keys, no dbt profile" was misleading
  — the drafter always calls Anthropic. Reword to "no dbt profile / no
  warehouse credentials of your own" + name the ANTHROPIC_API_KEY
  requirement.
- LLMCacheTooLargeError mis-labelled tier-3 → corrected to tier-2 (the
  cache-too-large check is a pre-LLM-call input-validation gate per
  cli-layer.md's four-tier taxonomy).

docs/skills.md DRIFT
- Canonical-commands list said "signalforge --version" — DEC-015's
  hardcoded list is init-demo / generate <model> --write /
  prune-existing <model> --schema <path> / install-skill (no --version
  variant; the parity gate scans for `version` subcommand separately
  via category 1).
- "signalforge --version is the first thing it runs" → "signalforge
  version (the subcommand)" — flag vs subcommand mismatch.

PARITY GATE EXTENSION (the gate would have caught the --force bug)
- tests/cli/test_skill_cli_parity.py: add fourth category that scans
  SKILL.md for `signalforge <subcommand> --<flag>` patterns and
  asserts each flag exists on the live subparser. Pinned with the
  same planted-violation philosophy (verified manually:
  reinstating --force fails the gate loud). Closes the "skill prose
  teaches a flag that doesn't exist" failure mode the original gate
  could not catch.

Validation:
- uv run ruff check . — clean
- uv run ruff format --check . — clean
- uv run pyright — 0 errors
- uv run pytest — 2747 passed (was 2745 baseline; +2 new tests)
- uv run pytest -m wheel_smoke --no-cov — 5/5
- uv run pytest -m cli_subprocess --no-cov — 8/8

Plan: plans/super/141-claude-skill-install.md US-010.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* #141: plan phase=implemented; record Ralph run completion + QG findings

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* #141: close codecov patch-coverage gaps (5 lines, 3 files → 100%)

codecov flagged 5 missed lines in the PR diff:
- src/signalforge/cli/install_skill.py:177-178 — except OSError around the
  existed_before probe (silently downgrades on probe failure; the install
  should still proceed)
- src/signalforge/skill/__init__.py:150 — resolve(strict=False) fallback
  for a dest that doesn't exist yet (the common fresh-project case)
- src/signalforge/skill/__init__.py:157 — non-ELOOP OSError raw re-raise
  (narrow ELOOP-only routing is load-bearing — a PermissionError must
  NOT be mis-attributed as a symlink cycle)
- src/signalforge/skill/errors.py:66 — SkillError.__str__'s no-footer
  branch (when neither remediation kwarg nor default_remediation is set)

Per the qg-pass-3-defer-defensive-tests-fails-codecov memory, codecov
holds patch coverage to project standard regardless of "is this a real
bug today" — defensive branches need test coverage even when they're
fallbacks.

Adds 4 tests:
- test_skill_error_str_omits_footer_when_remediation_is_none (errors.py:66)
- test_install_skill_propagates_non_eloop_oserror_unchanged (skill:157)
- test_install_skill_resolves_nonexistent_dest_via_strict_false_fallback (skill:150)
- test_install_skill_handles_oserror_in_existed_before_probe (cli:177-178)

Coverage: install_skill.py 95% → 100%, skill/__init__.py 95% → 100%,
skill/errors.py 95% → 100%. Full pytest: 2751 passed (was 2747).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* #141: address CodeRabbit + Copilot PR review (13 threads)

Trivial:
- assets/SKILL.eval.json: version 0.4.0.dev0 → 0.5.0.dev0 (matches the
  __version__ revert in the previous QG commit; flagged by both reviewers).
- SKILL.md fenced ASCII pipeline diagram: add `text` language tag (MD040).
- plans/super/141: drop the leftover duplicate "_Pending Phase 3/4._"
  placeholders at the end of the doc.

Substantive — symlink defence broadened to EVERY bundled path:
- src/signalforge/skill/__init__.py: the symlink defence used to cover
  only `<dest>/.claude/skills/signalforge/SKILL.md`. A symlinked
  `assets/SKILL.eval.json` (or symlinked `assets/` directory) would
  smuggle writes through copytree. Now enumerates every relative path
  under the bundled source tree via `rglob` and refuses to overwrite any
  of them through a symlink. Pinned by
  `test_install_skill_refuses_when_assets_dir_is_symlink`.
- Also wrap `mkdir(parents=True)` in try/except NotADirectoryError →
  raise SkillDestUnsafeError so a non-dir component along the install
  chain (e.g. `<dest>/.claude` is a regular file) yields a typed
  remediation-bearing message instead of a raw OSError. Pinned by
  `test_install_skill_wraps_notadirectoryerror_from_mkdir_chain`.

Substantive — CLI existed_before probe:
- src/signalforge/cli/install_skill.py: probe was `.exists()` which
  follows symlinks AND returns False for broken symlinks. The DEC-017
  contract says "True for files and symlinks (both shapes are replaced
  from the operator's POV)" — a broken symlink is a third shape that
  the probe silently downgrades. Probe now OR's `.is_symlink()` to
  catch the broken-symlink case (semantics stay honest even though
  the lib seam then raises SkillDestUnsafeError on the same path).

Substantive — SKILL.md ADC contradiction:
- The frontmatter `compatibility:` field and Section 2 body claimed
  "zero-credential demo (no warehouse needed)" while simultaneously
  describing the demo as sampling a public BigQuery dataset under ADC
  (which requires `gcloud auth application-default login` +
  GOOGLE_CLOUD_PROJECT). Both surfaces rewritten to honestly describe
  the demo's real posture: removes the dbt-project setup cost, but
  needs ANTHROPIC_API_KEY + ADC + GOOGLE_CLOUD_PROJECT. Section 2 also
  surfaces `signalforge lint --model <name>` as the truly-offline
  fallback (manifest-only, no LLM, no warehouse).

Substantive — dbt parse invocation:
- SKILL.md Section 1 suggested running `dbt parse` but the
  `allowed-tools` frontmatter does NOT include `Bash(dbt *)`. Reworded
  to "ask the user to run dbt parse themselves" rather than implying
  the skill runs it — preserves the narrow tool grant.

Substantive — parity gate (`test_skill_cli_parity.py`):
- Broaden `_SKILL_FLAG_USAGE_RE` to match `signalforge <subcommand>
  [<positional> ...] --<flag>` so canonical shapes like `generate
  <model> --write` and `prune-existing <model> --schema <path>` are no
  longer skipped (CodeRabbit + Copilot). Constrain to same-line
  `[ \t]` (not `\s`) so the match cannot span newlines — without
  this, prose like "signalforge installed (pip install ...)" plus
  "signalforge lint --model" two paragraphs later yields a spurious
  `installed --model` capture (caught during validation).
- Unknown-subcommand branch now FAILS instead of skipping (Copilot).
  A typo like `signalforge instal-skill --force` would previously
  skip silently; now it surfaces in the assertion message.
- Verified via planted-violation: `signalforge generate <model>
  --xyzbogus` injection trips the gate; restoring SKILL.md returns
  the gate to green.

Validation:
- uv run ruff check . — clean
- uv run ruff format --check . — clean
- uv run pyright — 0 errors
- uv run pytest — 2753 passed (was 2751; +2 new tests)
- uv run pytest -m wheel_smoke --no-cov — 5/5
- Patch coverage: install_skill.py 100%, skill/__init__.py 100%,
  skill/errors.py 100% — codecov-clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cuts v0.5.0 to PyPI. Bumps version 0.4.0 → 0.5.0 and adds a new [0.5.0]
CHANGELOG section honestly scoped to #141 (the SignalForge Claude Code
skill + install-skill subcommand). Also bumps the SKILL.md frontmatter
and assets/SKILL.eval.json version strings 0.5.0.dev0 → 0.5.0 so the
shipped skill metadata matches the release.

Branch shape: release/0.5.0 is based on main + cherry-pick of 709f147
(#141's squash-merge commit on dev). Main's content-equivalence to dev
means the cherry-pick reproduces dev's tree modulo this commit; no
intervening dev work is lost.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Implements bundled Claude Code skill installation feature by adding a new signalforge install-skill CLI subcommand and underlying signalforge.skill library. Includes comprehensive path safety (symlink cycle detection, ancestor checks), wheel packaging updates, complete skill documentation with parity enforcement against live CLI, and extensive test coverage (unit, CLI, parity gates, wheel validation).

Changes

Bundled Claude Code Skill Installation

Layer / File(s) Summary
Version bump and wheel packaging
src/signalforge/__init__.py, pyproject.toml
Updates package version to 0.5.0 and configures Hatchling wheel to bundle src/signalforge/skills/ asset directory alongside _demo. Adds clauditor-eval>=0.1,<1 development dependency for pre-release self-grading via clauditor CLI.
Skill error types
src/signalforge/skill/errors.py
Defines typed exception hierarchy with SkillError base (includes optional remediation, cause, and __str__ formatter), plus three concrete subclasses: SkillDestPathError (destination canonicalization failures), SkillDestUnsafeError (unsafe destination shapes), SkillPackageDataMissingError (missing bundled assets). Each includes sensible default remediation text.
Skill library API
src/signalforge/skill/__init__.py, tests/skill/test_install.py
Implements public install_skill(dest) function with symlink-cycle-safe path resolution (including strict→non-strict fallback), symlink-ancestor checks, bundled asset enumeration, refusal to overwrite symlink targets, destination directory creation, and shutil.copytree with dirs_exist_ok=True. Returns resolved absolute SKILL.md path. Unit tests validate happy path, overwrite semantics, symlink safety across SKILL.md/ancestors/assets, cycle detection with cause verification, missing data errors, file destination rejection, error class inheritance, remediation rendering, non-ELOOP OSError propagation, and nonexistent destination handling.
CLI error wrappers and exit-code mapping
src/signalforge/cli/errors.py, src/signalforge/cli/_helpers.py
Defines three CLI wrapper exceptions (CliInstallSkillPathError, CliInstallSkillDestUnsafeError, CliInstallSkillPackageDataMissingError) that extend existing CLI error base classes and provide CLI-specific remediation. Extends _EXCEPTION_TO_EXIT_CODE mapping with Tier 1 (load-time: exits 1) and Tier 2 (input-validation: exit 2) mappings for both underlying skill and CLI wrapper errors.
Install-skill CLI subcommand
src/signalforge/cli/__init__.py, src/signalforge/cli/install_skill.py, tests/cli/test_install_skill.py
Registers new install-skill subcommand with optional DEST positional (defaults to CWD), implements cmd_install_skill handler that: probes pre-install existence of SKILL.md (with OSError resilience), calls install_skill(raw_dest), catches three specific library exceptions and maps to CLI wrappers with appropriate exit codes, preserves KeyboardInterrupt/SystemExit, includes generic panic handler for unmapped exceptions, prints single-line stdout info with optional "(replaced existing SKILL.md)" suffix. CLI test suite covers success path, overwrite behavior, input validation (file vs directory, symlink cycles), missing data, default destination, exit-code table membership, help output, forward-compatibility exception routing without traceback leaks, and keyboard interrupt propagation.
Skill documentation assets
src/signalforge/skills/signalforge/SKILL.md, src/signalforge/skills/signalforge/assets/SKILL.eval.json
Adds comprehensive SKILL.md with frontmatter (name, version, allowed tools), end-to-end workflow documentation covering: installation steps, pointing to dbt projects via lint, bundled demo flow with GCP/ADC setup, real project generation with safety modes, pruning existing tests, interpreting diff tiers, optional live e2e test with explicit user confirmation, and troubleshooting guide with error mappings and exit-code taxonomy. Adds SKILL.eval.json with pending-first-grade status, version reference, and pre-release manual grading notes.
User-facing documentation
README.md, docs/skills.md, docs/cli-ops.md, mkdocs.yml
Adds clauditor-graded badge and signalforge install-skill quick-start to README. Creates comprehensive docs/skills.md covering skill purpose, install command with destination/overwrite behavior, workflow steps (draft→prune→grade→diff), demo paths (zero-credential default and opt-in live e2e), parity gate mechanism, self-grading via clauditor with badge generation, and maintainer-only skills exclusion. Updates docs/cli-ops.md with new install-skill subcommand section documenting path handling, safety bypass semantics, exit-code tiers, and example invocation. Adds "Claude Code Skill" navigation entry to mkdocs.yml.
Parity and integration tests
tests/cli/test_5_surface_parity_install_skill.py, tests/cli/test_skill_cli_parity.py, tests/cli/test_subprocess_smoke.py, tests/cli/test_exit_codes.py, tests/test_wheel_packaging.py, tests/test_audit_completeness.py
Enforces 5-surface parity for install-skill token across argparse help, handler/module docstrings, docs/cli-ops.md, and plan document with aggregate consistency check. Implements skill↔CLI parity gate that introspects live parser to verify every subcommand name and four canonical demo command lines appear in SKILL.md, includes planted self-check, and validates all referenced --flags exist on live subparsers. Adds subprocess smoke test for install-skill --help. Extends exception constructor factory in exit-code tests. Adds wheel smoke tests for bundled skill files presence and maintainer-only skill exclusion. Excludes SkillError as abstract base from error audit and updates expected per-stage errors.py count to 13.
Planning and rules documentation
plans/super/141-claude-skill-install.md, .claude/rules/cli-layer.md, .claude/rules/skill-parity.md, CHANGELOG.md
Adds comprehensive plan document with acceptance criteria, discovery seams, scoping decisions (no --force flag, demo paths, self-grade model), architecture review (security, API design, packaging, observability, testing), detailed refinement log with error hierarchies and symlink defenses, and 11 implementation stories. Updates cli-layer.md to declare SKILL.md as sixth parity surface with test enforcement. Adds skill-parity.md codifying artifact placement (src/signalforge/skills/ for shipped, .claude/skills/ for maintainer-only), naming convention (skills/ package data vs skill/ Python module), and scope limitations. Updates CHANGELOG with v0.5.0 release entry covering bundled skill, install-skill, parity gate, and symlink defense fixes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • wjduenow/SignalForge#141: This PR implements the exact bundled Claude Code skill, install-skill subcommand, library API, parity gate, and wheel packaging features requested in this issue.

Possibly related PRs

  • wjduenow/SignalForge#168: Both PRs update src/signalforge/__init__.py __version__ constant as part of release version management (main: 0.4.00.5.0).
  • wjduenow/SignalForge#166: Both PRs implement skill↔CLI parity gate enforcement via tests/cli/test_skill_cli_parity.py scanning against src/signalforge/skills/signalforge/SKILL.md to prevent drift from live CLI.
  • wjduenow/SignalForge#162: Both PRs extend the CLI's shared exception-to-exit-code mapping machinery in src/signalforge/cli/_helpers.py and tests/cli/test_exit_codes.py by registering new exception types for CLI subcommands.

Poem

🐰 A skill hops into the package, all bundled tight,
install-skill plants it deep where Claude can write,
Symlinks beware—this rabbit checks every link,
Parity gates ensure the docs don't drift in a blink,
Five surfaces synced, tests guard the seams,
A skill-filled wheel now rolls through the streams! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.46% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'chore: release 0.5.0' clearly and concisely describes the main change: cutting a new version release.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@wjduenow
wjduenow merged commit 1f96c8a into main May 30, 2026
10 of 11 checks passed
@wjduenow
wjduenow deleted the release/0.5.0 branch May 31, 2026 17:56
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.

2 participants