# How Versioning Is Handled in the Humanizer Project: File Locations and Validation

> Discover how the Humanizer project manages versioning across SKILL.md README.md and plugin.json using a Python validation script for consistent releases.

- Repository: [Siqi Chen/humanizer](https://github.com/blader/humanizer)
- Tags: how-to-guide
- Published: 2026-09-11

---

**The Humanizer project stores its version number in three separate files—[`SKILL.md`](https://github.com/blader/humanizer/blob/main/SKILL.md), [`README.md`](https://github.com/blader/humanizer/blob/main/README.md), and [`.claude-plugin/plugin.json`](https://github.com/blader/humanizer/blob/main/.claude-plugin/plugin.json)—and enforces consistency through an automated Python validation script that prevents mismatched releases.**

The blader/humanizer repository uses a distributed versioning strategy that requires synchronization across metadata, documentation, and plugin configuration files. This approach ensures that the skill version, public changelog, and Claude plugin manifest always reflect the same release number, eliminating confusion for end users and Claude-compatible agents.

## Where Version Numbers Are Stored

Unlike single-file versioning systems, the Humanizer project maintains identical version strings across three distinct locations. Each file serves a specific purpose in the project's ecosystem.

### SKILL.md – The Canonical Source

The primary version definition resides in [`SKILL.md`](https://github.com/blader/humanizer/blob/main/SKILL.md) within the YAML front matter. This `metadata.version` field acts as the single source of truth for the skill itself.

```yaml
metadata:
  version: "3.0.0"

```

According to the blader/humanizer source code, this value follows strict **semantic versioning** (three-part version strings in the format `MAJOR.MINOR.PATCH`). The validation script specifically searches for this pattern using the regex `(?m)^\s+version:\s*["\']?([0-9]+\.[0-9]+\.[0-9]+)["\']?\s*$` to extract the canonical version from the YAML metadata block.

### README.md – Public Version History

The [`README.md`](https://github.com/blader/humanizer/blob/main/README.md) file contains a "Version history" section where the first bullet point must display the current release version. This serves as the public-facing changelog for users browsing the repository.

```markdown
- **3.0.0** - Rebuilt the skill around one account of why AI text sounds the way it does…

```

The validation logic requires that the version extracted from the first entry in this history block matches exactly with the version defined in [`SKILL.md`](https://github.com/blader/humanizer/blob/main/SKILL.md). Any discrepancy triggers a validation failure.

### .claude-plugin/plugin.json – Plugin Manifest

For Claude-compatible AI agents, the plugin manifest at [`.claude-plugin/plugin.json`](https://github.com/blader/humanizer/blob/main/.claude-plugin/plugin.json) contains a `version` field that must mirror the skill version.

```json
{
  "version": "3.0.0"
}

```

This JSON value ensures that Claude can correctly identify and load the appropriate version of the humanization skill. The validation script accesses this value via `PLUGIN.get("version", "")` and includes it in the consistency check.

## How Version Consistency Is Enforced

To prevent human error during version updates, the project includes a dedicated validation script at [`scripts/validate-package.py`](https://github.com/blader/humanizer/blob/main/scripts/validate-package.py). This Python utility programmatically extracts version strings from all three locations and raises an exception if they differ.

The script uses a helper function `require_match()` to apply regex patterns against each file:

```python
skill_version = require_match(
    re.search(r'(?m)^\s+version:\s*["\']?([0-9]+\.[0-9]+\.[0-9]+)["\']?\s*$', yaml_metadata),
    "Add metadata.version to SKILL.md as a three-part version",
)
readme_version = require_match(
    # ... regex extraction from README

)
package_versions = {skill_version, readme_version, str(PLUGIN.get("version", ""))}

if len(package_versions) != 1:
    raise Exception(f"Use one package version in all files: {sorted(package_versions)}")

```

When executed, the script creates a set containing all three extracted versions. If the set contains more than one unique value, the script aborts with an error message listing the mismatched versions. Successful validation outputs: `Humanizer package v{version} is valid`.

## Updating the Version Number

When preparing a new release, maintainers must update all three files simultaneously before running the validation script. The following workflow ensures consistency:

1. Edit [`SKILL.md`](https://github.com/blader/humanizer/blob/main/SKILL.md) and modify the `metadata.version` value
2. Edit [`README.md`](https://github.com/blader/humanizer/blob/main/README.md) to add a new bullet under "Version history" with the updated version
3. Edit [`.claude-plugin/plugin.json`](https://github.com/blader/humanizer/blob/main/.claude-plugin/plugin.json) to update the JSON version field

Example workflow for updating to version `4.1.0`:

```bash

# Edit SKILL.md: Change metadata.version to "4.1.0"

# Edit README.md: Add to Version history:

# - **4.1.0** - Brief description of the changes.

# Edit .claude-plugin/plugin.json: Set "version": "4.1.0"

# Validate the changes

python3 scripts/validate-package.py

# Expected output: Humanizer package v4.1.0 is valid

```

If any file retains the old version number, the validator will output an error indicating which files contain mismatched values, preventing an inconsistent release.

## Summary

- The Humanizer project stores version data in three locations: [`SKILL.md`](https://github.com/blader/humanizer/blob/main/SKILL.md) (YAML metadata), [`README.md`](https://github.com/blader/humanizer/blob/main/README.md) (changelog), and [`.claude-plugin/plugin.json`](https://github.com/blader/humanizer/blob/main/.claude-plugin/plugin.json) (plugin manifest)
- All three files must contain identical semantic version strings (e.g., `3.0.0`)
- The [`scripts/validate-package.py`](https://github.com/blader/humanizer/blob/main/scripts/validate-package.py) script enforces consistency by extracting versions using regex and comparing them as a set
- Validation failures raise an exception listing the mismatched versions, blocking releases until fixed
- Contributors must update all three files when bumping the version number

## Frequently Asked Questions

### What files contain version information in the Humanizer project?

The version number appears in [`SKILL.md`](https://github.com/blader/humanizer/blob/main/SKILL.md) (the canonical YAML metadata), [`README.md`](https://github.com/blader/humanizer/blob/main/README.md) (the public version history), and [`.claude-plugin/plugin.json`](https://github.com/blader/humanizer/blob/main/.claude-plugin/plugin.json) (the Claude plugin manifest). Each location serves a distinct purpose, from skill identification to plugin compatibility.

### How does the Humanizer project prevent version mismatches?

The project uses [`scripts/validate-package.py`](https://github.com/blader/humanizer/blob/main/scripts/validate-package.py), a Python script that reads all three version locations, extracts the values using regular expressions, and verifies they form a single unique set. If multiple versions are detected, the script raises an exception and aborts the validation process.

### What version format does the Humanizer project use?

The project follows semantic versioning with a three-part numeric format (`MAJOR.MINOR.PATCH`). The validation script explicitly searches for the pattern `[0-9]+\.[0-9]+\.[0-9]+` to ensure compliance with this standard.

### Where is the version validation script located?

The validation logic resides in [`scripts/validate-package.py`](https://github.com/blader/humanizer/blob/main/scripts/validate-package.py) at the repository root. This script contains the `require_match()` function and the consistency check logic that compares versions across the three required files.