Skip to content

Releases: rolling-codes/better-skill-creator

v3.7.1 — documentation and release metadata

Choose a tag to compare

@rolling-codes rolling-codes released this 25 Oct 22:07
f510f21

What's new

Added

  • Added a complete user guide, a v3.7.0 feature overview, and a decision record for maintainers.

Changed

  • Updated repository setup and agent guidance to reflect the published v3.7.0 release.

Fixed

  • Added coverage ensuring the pyproject.toml package version stays aligned with the CLI and plugin version.

This is a documentation and release-hygiene follow-up. It does not change runtime skill behavior. The v3.7.0 runtime features remain described in the v3.7.0 release notes.

v3.7.0 — near-miss candidates, model-aware compare, release hygiene

Choose a tag to compare

@rolling-codes rolling-codes released this 24 Oct 15:39
38b5347

v3.7.0 — near-miss candidates, model-aware compare, release hygiene

Released: 2026-10-24

This release is not a re-tag of 3.6.0. It ships the evaluation features from #78 and brings version metadata (README badge, bsc.VERSION, plugin/skill manifests) into lockstep with the GitHub Release.

What’s new vs 3.6.0

3.6.0 3.7.0
Focus Verification & failure-handling (doc-sync review cmds, reference containment, hollow-claim detection, atomic grading reports) Evaluation product features + release hygiene
Near-miss tests Not in tree as a reviewable workflow Offline adjacent-skill proposals → review → promote
Model compare Cross-model warnings on legacy raw files Exact model-identity baselines; unpooled models; preflight rejects bad metrics
CI canary — Bounded Haiku + Sonnet matrix on schedule / release/**
bsc.py doctor Python / PyYAML / claude --version Also checks required eval CLI flags (no auth / no model calls)
README badge v3.6.0 v3.7.0
Root LICENSE Nested under skill only Repo-root Apache-2.0 + packaged copy

Added

  • Reviewable near-miss candidates — python -m scripts.generate_tests <skill> --adjacent-skills <dir> writes tests/candidates/near_misses.yaml. Mark reviewed: true and should_trigger, then --promote-candidates. Stays out of measured evals until promoted.
  • Model-aware baseline comparisons — bsc.py compare and bsc.py eval … --baseline require aligned model identities for live/front-end envelopes; aliases warn in favor of pinned full IDs; sonnet[1m] / opus[1m] pass through.
  • Bounded Haiku/Sonnet trigger canary — five calls per model; missing credentials reported explicitly; reports downloadable as CI artifacts.
  • bsc.py doctor eval-flag checks — validates flags advertised by the installed Claude CLI without authentication or model calls.
  • Root LICENSE (Apache-2.0) for GitHub/clone discoverability.

Changed

  • SETUP.md — Python 3.12+ floor; skill-creator@skill-creator-local; prefer python bsc.py hooks install.
  • Packaged changelog / release-notes under skills/skill-creator/ are pointers to the root CHANGELOG.md (single source of truth).
  • Version lockstep: .claude-plugin/plugin.json, skills/skill-creator/skill.yaml, bsc.VERSION, README badge + “Current version”, pyproject.toml → 3.7.0.

Upgrade

Drop-in for 3.6.0 users. No skill-schema migration.

claude plugin marketplace add rolling-codes/better-skill-creator
claude plugin install skill-creator@skill-creator-local
python bsc.py doctor

Full changelog: https://github.com/rolling-codes/better-skill-creator/blob/main/CHANGELOG.md

v3.5.1 — repo-rename install fixes + design-analysis Complexity/Risk scales

Choose a tag to compare

@rolling-codes rolling-codes released this 19 Oct 18:53

A documentation and packaging-metadata patch. No code changes, no API or CLI changes, no behavior changes — every scripts.* import and invocation is identical to v3.5.0. The headline fix is that the install instructions actually work again after the repository was renamed.

Fixed

  • Broken install references after the rename to better-skill-creator. Several pointers still named the old rolling-codes/-the-better-skill-creator-skill-, which no longer resolves — so the documented install path failed end-to-end:
    • .claude-plugin/plugin.json repository field.
    • SETUP.md — the git clone URL, the cd target, and the /plugin marketplace add argument. These were non-working install steps; following the README/SETUP would fail before this release.
    • The repository URL inside CHANGELOG.md's existing version-compare links.

Changed

  • references/design-analysis.md — the scope-selection matrix now defines its Complexity and Risk criteria. Previously each was listed only as a one-line question with no scale. They now carry explicit low / moderate / high definitions, lined up with the activation criteria in references/independent-review.md §"When to run it" (the binary full-review-vs-recorded-skip decision), so the matrix and the review gate judge a skill the same way instead of drifting into two vocabularies:
    • High complexity ↔ a substantial new skill, an architecture or scope change, or multiple operating modes.
    • High risk ↔ handling external systems, permissions, or destructive actions — with authorization routed to the existing Entailment is not permission section.

How this was validated

The design-analysis change was taken through the skill's own full independent multi-agent review (outcome-analyst, scope-adversary, architecture-reviewer, practices-reviewer + completion-adversary). The review earned its keep:

  • Round 1 caught a blocking defect — an earlier draft cited rubric identifiers (external_mutation, permissioned_or_destructive, an ACTIVATION_RUBRIC) that do not exist in this repository (they had been copied from a different variant). The draft was rewritten to cite only the real prose criteria.
  • The release re-affirmation then caught two metadata inconsistencies — a README prose version line left at v3.5.0, and an over-broad CHANGELOG wording — both fixed before the completion-adversary returned complete.

skills/skill-creator/review.yaml records all findings, their dispositions, the synthesis, and the passed gate. Version is consistent across plugin.json, skill.yaml, bsc.py, and the README badge + prose. Local suite: 593 passed, 9 skipped; the on-main review gate passes.

Known limitation

The CHANGELOG.md compare-link footer is incomplete (it predates this release and recent versions already omit these links); the [3.5.1]/[3.5.0] headings render unlinked. Deferred to a future docs pass.

Full diff: v3.5.0...v3.5.1

v3.5.0 — bug-prevention phase 1

Choose a tag to compare

@rolling-codes rolling-codes released this 17 Oct 23:40
3b29b83

Bug-prevention phase 1 — source-level defect detectors and gate correctness, porting the gate-correctness patterns from the sibling longterm-ai project. No breaking changes; all existing scripts.* imports and CLI invocations are unchanged.

Added

  • scripts/source_rules.py — an AST linter over the toolkit's own Python that catches two recurring defect classes repo-wide:
    • H-ENCODING — text open()/read_text()/write_text() with no encoding= (a latent Windows bug; CI runs on windows-latest).
    • H-SWALLOW — an except body that is only pass (a silently swallowed error).
      Deliberately conservative / fail-closed (flags only provably builtin-open or pathlib receivers), CI-wired, with good/bad fixtures.
  • scripts/claims_check.py + claims.yaml — a behavioral-claim registry: every registered claim must resolve to an existing verifier test.
  • scripts/doc_sync.py — verifies documented commands, flags, modules, and links actually exist in the source.
  • Review-gate correctness (scripts/review_gate.py, scripts/finding_types.py) — a uniform 0/1/2 exit-code contract (0 = ok, 1 = blocking error, 2 = warnings-only) and a required-key check so a placeholder synthesis can no longer satisfy the gate.

Fixed

  • CI now tolerates a warnings-only exit (2) from doc_sync and claims_check (|| [ $? -eq 2 ]), matching the lint/static_analysis steps and the documented contract; only error findings (exit 1) block the build. (Found by the independent review of this release.)
  • Pinned eol=lf via .gitattributes so the independent-review source manifest hashes match on both the Linux and Windows CI jobs.

This release was validated through the full independent multi-agent review (outcome-analyst, scope-adversary, architecture-reviewer, practices-reviewer + completion-adversary, verdict complete); CI is green on ubuntu-latest and windows-latest, including the on-main review gate.

v3.4.1

Choose a tag to compare

@rolling-codes rolling-codes released this 14 Oct 16:51
7954d65

And make sure to update the README, because the README doesn't seem updated, even though we're on a new version and there's way more to the tool.

v3.4.1

Post-release patch for v3.4.0. Bug fixes and doc corrections only — no new public API, no breaking changes.

Fixes came from a CodeRabbit review of #61 after v3.4.0 shipped. Test portability failures on Windows CI were caught in #62.


run_eval.py — control query not counted in shared call budget

_check_infra used a private CallBudget(1) that the caller never saw. With --max-calls 15 you got 16 actual model calls.

# before
calls = len(eval_set) * runs_per_query * (max_retries + 1)
...
from scripts.call_budget import CallBudget as _CB
if not _check_infra(..., _CB(1), max_retries):

# after
calls = 1 + len(eval_set) * runs_per_query * (max_retries + 1)
...
if not _check_infra(..., budget, 0):

bsc.py eval pre-check updated to match: (1 + len(cases) * runs * (retries + 1)) * len(models).

New behavioral test added: test_run_eval_reports_infrastructure_failed_when_control_query_not_triggered — asserts infrastructure_failed: true and zero eval calls when the control query does not trigger.


bsc.py — hard-coded .git/hooks broken in worktrees and submodules

doctor() and _install_hooks() both used ROOT / ".git" / "hooks". In a git worktree the hooks directory lives at .git/worktrees/<name>/; in a submodule it lives inside the parent repo. Both cases silently broke hook install and the doctor check.

# before — two hard-coded call sites in doctor() and _install_hooks()
hook_dest = ROOT / ".git" / "hooks" / "pre-commit"
git_hooks = ROOT / ".git" / "hooks"

# after — shared resolver, fallback when git unavailable
def _hooks_dir():
    hooks = subprocess.check_output(
        ["git", "rev-parse", "--git-path", "hooks"], cwd=ROOT, text=True, ...
    ).strip()
    return (ROOT / hooks).resolve()

The hooks subcommand was also incorrectly picking up the path positional added to other subcommands, requiring a skill path it does not need:

# before
elif name not in ("doctor", "compare"):
    p.add_argument("path", type=Path)

# after
elif name not in ("doctor", "compare", "hooks"):
    p.add_argument("path", type=Path)

review_gate.py — wrong summary line in --release mode

In --release mode a review-skipped finding is promoted to an error. The if chain checked skipped_finding first, so the promoted error still printed "skipped — no review record" even though errors was non-empty.

# before
if skipped_finding:
    print("Review gate: skipped — no review record")
elif errors:
    print(f"Review gate: failed — {len(errors)} error(s)")

# after
if errors:
    print(f"Review gate: failed — {len(errors)} error(s)")
elif skipped_finding:
    print("Review gate: skipped — no review record")

Exit-code logic was already correct; only the printed summary was wrong.


validate.py — scoring exception swallowed, gate returned exit 0

# before — prints to stderr and continues; validate.py exits 0 with a broken score
except Exception as exc:
    print(f"Score: (error: {exc})", file=sys.stderr)

# after — appended as an error Finding; gate exits 1
except Exception as exc:
    findings.append(Finding(
        severity="error", rule="score-error", message=f"Scoring failed: {exc}",
    ))

.github/workflows/test.yml — canary used wrong invocation; review_gate escape let errors through

Canary was calling python -m scripts.run_eval from working-directory: skills/skill-creator with a hardcoded model version ID and ANTHROPIC_API_KEY only. Three problems: python -m scripts.run_eval bypasses bsc.py's sys.path setup; the hardcoded model ID claude-haiku-5-5 will rot; CLAUDE_CODE_OAUTH_TOKEN was missing so Claude Code's OAuth auth path failed silently.

# before
- name: Run trigger canary
  working-directory: skills/skill-creator
  env:
    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
  run: |
    python -m scripts.run_eval \
      --eval-set tests/should_trigger.yaml \
      --skill-path . \
      --model claude-haiku-5-5 \
      --max-calls 15

# after — runs from repo root via bsc.py, tier alias, OAuth token
- name: Run trigger canary
  env:
    CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
  run: |
    python bsc.py eval "$canary_dir" --live \
      --model haiku \
      --max-calls 15

review_gate escape: the step had || [ $? -eq 2 ], which passes CI whenever the exit code is 2 — but also silently eats errors. For lint and static_analysis this softening is intentional (warnings should not block PRs). For review_gate it is wrong: any non-zero exit is a hard failure. Removed. The step is also now conditioned on non-PR runs — PR branches may have a pending review in progress; main and scheduled runs must not.

# before — escape swallows errors on review_gate too
python -m scripts.review_gate . || [ $? -eq 2 ]

# after — hard fail; PR runs skip the step entirely
- name: Enforce review gate on main and scheduled runs
  if: github.event_name != 'pull_request'
  run: python -m scripts.review_gate .

CLAUDE.md — stale description of what CI runs

The file said CI runs validate.py (the unified gate) on every push. CI actually runs quick_validate, lint, static_analysis, and review_gate as separate steps — validate.py's score threshold and description-confidence checks are intentionally excluded from CI. Also corrected the pre-commit hook description (it also runs lint and review_gate, not only quick_validate).

# before
CI runs it on every push; the pre-commit hook runs `quick_validate` (faster, structural only).

# after
CI runs `quick_validate`, `lint`, `static_analysis`, and `review_gate` as separate checks;
it does not run the unified gate, its score threshold, or description-confidence checks.
The CI review gate blocks main pushes and scheduled runs; PR development can proceed
with a pending review. The pre-commit hook runs `quick_validate`, lint, and the review
gate, plus pyright when available.

README.md — bsc.py hooks install missing from Quick start; --model undocumented

The hooks install subcommand added in v3.4.0 was not in the Quick start. The old step 2 jumped straight to "Create or improve a skill" with no mention of the hook. New step 2, now in the README:

2. Install the pre-commit hook (optional but recommended):

python bsc.py hooks install

Runs quick_validate on every commit to catch structural errors before they reach CI.

Steps 2–5 renumbered to 3–6.

bsc.py eval --model / --models (also added in v3.4.0) were also absent. The eval section ended at --live with no indication that model selection was possible. Added immediately after the --live block, now in the README:

Pass --model haiku (or --models haiku,sonnet) to run against specific model tiers.


tests/test_readme.py — code block count off by one after README change

# before
assert len(_code_blocks(quick_start)) == 4, (
    "Install, validate, preview and live evaluation need code blocks"
)

# after
assert len(_code_blocks(quick_start)) == 5, (
    "Install, hooks, validate, preview and live evaluation need code blocks"
)

tests/test_bsc_hooks.py — execute-bit and submodule assertions fail on Windows CI

stat().st_mode & 0o111 is always 0 on Windows — chmod with execute bits is a no-op on NTFS. git submodule add with local file:// paths exits 128 on the Windows GitHub Actions runner.

# before — unconditional, fails on Windows
assert hook.stat().st_mode & 0o111

elif layout == "submodule":
    parent = tmp_path / "parent"
    ...

# after
if sys.platform != "win32":
    assert hook.stat().st_mode & 0o111

elif layout == "submodule":
    if sys.platform == "win32":
        pytest.skip("git submodule add with local paths is unreliable on Windows CI")
    ...

PRs: #61 · #62 · #63

v3.4.0 — token-economy & skill-composition guidance

Choose a tag to compare

@rolling-codes rolling-codes released this 06 Oct 17:02
107c76c

Covers three releases (v3.3.0, v3.3.1, v3.4.0) shipped between v3.2.1 and this tag. No breaking changes to scripts.* imports or CLI invocations.

What changed and why

Token-economy guidance (v3.4.0) — added references/token-economy.md to answer a recurring question: how do you structure a skill so it doesn't burn the model's context budget? The reference covers the three progressive-disclosure levers (metadata is always-on; SKILL.md is a <500-line index; references/ and scripts/ cost nothing until loaded), one-skill-vs-many composition, and a recommended development track (scoping-changes → implementing-features → validating-code → reviewing-changes). Wired into SKILL.md and skill.yaml so the orphan checker can't silently drop it. (#51)

Development-practices guidance (v3.3.0) — added references/development-practices.md for skills that write code, fix bugs, or author PRs. Converted patterns from 84 real fix: commits into reusable guidance so agents don't rediscover the same failure modes. (#48)

Dogfood fix: bsc.py check failed on its own skill (v3.3.1) — checks() called validate_skill() without claude_code=True, so python bsc.py check skills/skill-creator always reported the legitimate model: key as an error. Fixed; --strict flag added for upload/API compat validation. Runs/ directory also added to .gitignore to prevent accidental staging of report artifacts. (#50)

Generated-test discovery and dependency path containment — tests generated into tests/generated/ were not discovered by pytest; fixed the collection path. Dependency paths can no longer escape the skill directory via relative traversal. (#44, #49)

PRs

#44 · #48 · #49 · #50 · #51

v3.2.1 — post-release hardening

Choose a tag to compare

@rolling-codes rolling-codes released this 04 Oct 22:12
5134f19

Post-release hardening following the independent v3.2.0 audit and a CodeRabbit security review. 17 commits; no new features, no breaking changes.

What changed and why

Applied independent audit findings — the v3.2.0 review surfaced critical (C1), high (H1, H2), medium (M2, M4, M6, M8, M11), and low (L11) findings. C1 was a flag-shaped argument accepted as a positional skill name in the generator CLI — --flag passed as a skill name would silently create a broken skill. Promoted to error and rejected before execution. (#37)

Gate wiring into pre-commit hook — review_gate.py, pyright, and a version-consistency check were missing from the hook. Previously a commit could pass locally while blocking the package pipeline. The hook now runs quick-validate → lint → static-analysis → review-gate → pyright → version-check in order. (#39)

Security hardening — CodeRabbit's repository security review flagged six execution and packaging boundary issues: path traversal in skill loading, unsandboxed subprocess execution in skill_test, and missing input validation in the package compiler. Addressed in a dedicated security PR. (#40)

PRs

#37 · #39 · #40

v3.2.0 — Validation architecture overhaul and model-aware writing

Choose a tag to compare

@rolling-codes rolling-codes released this 03 Oct 22:49

Validation architecture overhaul, model-aware writing guidance, and silent-failure fixes. No breaking changes — existing python -m scripts.lint/static_analysis/review_gate invocations continue to work.

What changed and why

scripts/validate.py — unified validation gate — previously you had to run quick_validate, lint, static_analysis, and review_gate separately and manually interpret the combined output. validate.py chains them in order, short-circuits on structural errors, and emits a single sorted report with a score and description confidence at the end. Now the canonical pre-package check. (#33–#36 carried the README documentation; the script itself landed via direct commit)

scripts/types.py — shared types module — Finding, BLOCKING_SEVERITIES, DISPOSITIONS, and GATE_STATES had been duplicated across static_analysis.py, review.py, and their consumers. Any consumer that needed a type had to import from a module it had no other dependency on. Extracted to scripts/types.py; both source modules re-export for backwards compatibility.

metadata.lint_ignore — a skill can now suppress specific lint rules in its frontmatter with a justification comment, instead of requiring a global exemption added to analysis_config.py. Prevents the common pattern of disabling a rule globally because one skill legitimately needs an exception.

Model-aware writing guidance — references/model-guidance.md expanded from 90 to 350 lines. Added tier-specific density calibration: Haiku-class models need shorter, denser instructions than Fable/Opus; over-specified SKILL.md files that work on one tier can confuse a smaller one.

target_model field — metadata.target_model now takes a tier name (fable, opus, sonnet, haiku), not a model ID. A full model ID like claude-opus-4-8 triggers invalid-target-model. This decouples the skill from a specific version and lets the tier alias resolve at runtime.

PRs

#33 · #34 · #35 · #36

v3.1.0 — 2026 model guidance overhaul

Choose a tag to compare

@rolling-codes rolling-codes released this 02 Oct 21:00
a590deb

2026 model guidance overhaul. No breaking changes.

What changed and why

budget_tokens removed — Claude 4.7+ returns HTTP 400 when budget_tokens is set in the request. Any skill that used this field stopped working on current models. Replaced with output_config.effort. (#32)

references/model-guidance.md expanded 90 → 350 lines — the short existing guidance was insufficient for the Fable 5 / Opus 4 / Sonnet 4 / Haiku 4 generation. Added: what changed in 2026 for skill authors (over-specification now actively hurts; Fable 5 self-routes without rigid scaffolding), tier-specific instruction density calibration, and guidance on when to use extended thinking. (#32)

SKILL.md compressed 519 → ~415 lines — removed prescriptive boilerplate that told the model how to think instead of what done looks like. The compression came from replacing multi-step sequences with outcome descriptions. This is the "less is more" lesson from Fable 5 evaluation: rigid step sequences suppress the model's own reasoning and reduce quality on harder tasks.

Hedged language flagged — lint now flags phrases like "try to", "if possible", and "consider" as producing optional compliance. A skill instruction that says "try to validate input" is a suggestion, not a requirement. The linter treats these as warnings so authors can make the intent explicit.

PRs

#32

v3.0.1 — eval transport fix

Choose a tag to compare

@rolling-codes rolling-codes released this 02 Oct 20:11
17b6403

Patch release. Live trigger evals could not run against a current Claude Code install; this restores them.

What changed and why

eval --live fixed — native binary resolution — recent Claude Code releases ship a native bin/claude binary and no longer include the cli.js entry point that claude_process.claude_command was resolving to. On Windows the resolver rewrote the shim to node …/cli.js, which raised FileNotFoundError, got recorded as SUBPROCESS_CRASH, and surfaced as infrastructure_failed on every query. No model call was ever made, so trigger rates were silently wrong. The resolver now prefers the native binary and falls back to the legacy layout only when absent. All live paths share the same resolver: bsc.py eval --live, skill_test, run_eval, and the run_loop description optimizer. (#31)

schemaVersion moved under metadata — top-level schemaVersion is now rejected by quick_validate. This is a breaking schema change for skills written against the old layout; scripts/migrate_skill.py migrates them automatically: python -m scripts.migrate_skill /path/to/skill --to 1.

Scorer no longer rewards pre-approval grants — a skill that pre-approved all tools in its allowed-tools list was previously scored higher than one that didn't. Pre-approvals are a security-relevant decision, not a quality signal.

PRs

#31