$npx -y skills add zakelfassi/skills-driven-development --skill breaking-change-auditAudit shipctl's public interface before a release — compare flags, exit codes, and output formats against the previous tag to catch accidental breaking changes. Use when preparing a release, when asked to "check for breaking changes", or as a gate before tagging a new version.
| 1 | # Breaking-Change Audit |
| 2 | |
| 3 | Compare the current public interface against the previous release tag to surface accidental breaking changes before publishing. |
| 4 | |
| 5 | ## Inputs |
| 6 | - Previous tag (defaults to the most recent git tag: `git describe --tags --abbrev=0`) |
| 7 | - Current version (defaults to HEAD) |
| 8 | - Scope: `flags` | `exit-codes` | `output-format` | `all` (default) |
| 9 | |
| 10 | ## Steps |
| 11 | |
| 12 | 1. **Build both versions** |
| 13 | ```bash |
| 14 | # Build HEAD |
| 15 | cargo build --release |
| 16 | cp target/release/shipctl /tmp/shipctl-next |
| 17 | |
| 18 | # Build the previous tag |
| 19 | git stash |
| 20 | git checkout {prev-tag} |
| 21 | cargo build --release |
| 22 | cp target/release/shipctl /tmp/shipctl-prev |
| 23 | git checkout - |
| 24 | git stash pop |
| 25 | ``` |
| 26 | |
| 27 | 2. **Diff public flags** |
| 28 | Capture help output for every command and subcommand: |
| 29 | ```bash |
| 30 | /tmp/shipctl-prev --help > /tmp/flags-prev.txt |
| 31 | /tmp/shipctl-prev release --help >> /tmp/flags-prev.txt |
| 32 | # ... repeat for all subcommands |
| 33 | |
| 34 | /tmp/shipctl-next --help > /tmp/flags-next.txt |
| 35 | /tmp/shipctl-next release --help >> /tmp/flags-next.txt |
| 36 | |
| 37 | diff /tmp/flags-prev.txt /tmp/flags-next.txt |
| 38 | ``` |
| 39 | Lines prefixed with `-` in the diff represent removed flags or changed defaults. |
| 40 | |
| 41 | 3. **Check exit codes** |
| 42 | Run a battery of known invocations and compare exit codes: |
| 43 | ```bash |
| 44 | # Example: unknown flag should exit 2 |
| 45 | /tmp/shipctl-prev --unknown-flag 2>&1; echo "prev exit: $?" |
| 46 | /tmp/shipctl-next --unknown-flag 2>&1; echo "next exit: $?" |
| 47 | ``` |
| 48 | Document any changes; a changed exit code for a common error case is a breaking change. |
| 49 | |
| 50 | 4. **Check output format** (JSON / machine-readable outputs) |
| 51 | ```bash |
| 52 | /tmp/shipctl-prev release --dry-run --json > /tmp/out-prev.json |
| 53 | /tmp/shipctl-next release --dry-run --json > /tmp/out-next.json |
| 54 | diff /tmp/out-prev.json /tmp/out-next.json |
| 55 | ``` |
| 56 | Removed JSON keys, renamed fields, or type changes are breaking. |
| 57 | |
| 58 | 5. **Classify findings** |
| 59 | | Type | Breaking? | Action | |
| 60 | |------|-----------|--------| |
| 61 | | New flag added | No | Note in changelog under Added | |
| 62 | | Flag removed | **Yes** | Requires `BREAKING CHANGE:` in commit | |
| 63 | | Flag renamed | **Yes** | Requires `BREAKING CHANGE:`; add alias for one release cycle | |
| 64 | | Default changed | **Yes** | Requires `BREAKING CHANGE:` | |
| 65 | | Exit code changed | **Yes** | Requires `BREAKING CHANGE:` | |
| 66 | | New JSON key added | No | Note under Added | |
| 67 | | JSON key removed/renamed | **Yes** | Requires `BREAKING CHANGE:` | |
| 68 | |
| 69 | 6. **Decide** |
| 70 | - If no breaking changes: proceed with the release. |
| 71 | - If breaking changes are intentional: bump the major version; add `BREAKING CHANGE:` to the commit footer; document a migration path in the changelog. |
| 72 | - If breaking changes are accidental: revert or fix before cutting the release. |
| 73 | |
| 74 | ## Conventions |
| 75 | - This audit runs before every `release-cut` invocation (step 3 in that skill) |
| 76 | - Breaking changes require a major version bump per semver |
| 77 | - A one-release deprecation alias is preferred over immediate removal |
| 78 | - All findings are appended to `AUDIT.md` for record-keeping |
| 79 | |
| 80 | ## Edge Cases |
| 81 | - **Previous tag doesn't build:** Note the failure, skip that check, document in the audit log that the previous baseline was unavailable. |
| 82 | - **Subcommand added:** New subcommands are non-breaking; still document under Added. |
| 83 | - **Output format is not machine-readable:** Treat human-readable output changes as non-breaking unless documented otherwise. |
| 84 | - **Environment-dependent output:** Use `--dry-run` or a controlled fixture to get deterministic output for diff. |