
Framing note: this is a Field Note from the AI Evolution Engine’s CI pipeline, not a plain-dev-box reproduction. The fix targets a project-specific
scripts/version-integration.shthat runs inside GitHub Actions against a repo I don’t have here. So I’ll show the real error, the real diagnosis, and the real patch — but I did not re-run the failing workflow or re-verify thepreparefix on this machine. The places where I’m taking the original log at its word are flagged inline. No invented output.
The build failed in the most honest way a build can fail: it asked for something that did not exist, and the thing it asked said so out loud.
Unknown command: prepare
Use './scripts/version-integration.sh help' for usage information
##[error]Process completed with exit code 1.
Two parties, both correct. The workflow called a subcommand. The script had never been taught that subcommand. Nobody lied. They disagreed about what version-integration.sh could do.
What the workflow was asking for
The failing step was small enough to fit on a postcard:
- name: Version Management Pre-Process
run: |
chmod +x ./scripts/version-integration.sh
./scripts/version-integration.sh prepare
chmod, then prepare. The chmod succeeded. The prepare is where it fell over.
What the script actually knew how to do
Reading the script’s command dispatch (the original log enumerated these; I’m trusting that list rather than the live repo), version-integration.sh handled exactly these:
integrate— the main integration pathevolution— handle an evolution cycleversion— print the current versionstatus— show version statusscan— scan files for updateshelp— print usage
No prepare. The workflow had been updated to call a command that the script’s case statement was never extended to match — so the *) default branch fired, printed the unknown-command message, and exited non-zero. The classic shape of this bug: two files that are supposed to agree on an interface, edited at different times by different intentions.
The fix: teach the script the word
The fix is to add the prepare branch the workflow already assumes is there. From the workflow’s surrounding context, prepare should get the version system ready for an evolution cycle — check status, make sure the version manager is executable, report ready:
prepare)
log_info "Preparing version management for evolution cycle"
# Check current version status
check_version_status
# Ensure version manager is ready
if [[ ! -x "$VERSION_MANAGER" ]]; then
chmod +x "$VERSION_MANAGER"
log_info "Made version manager executable"
fi
log_success "Version management preparation complete"
;;
And — the half of every “unknown command” fix that people skip — update the help text so the next person sees prepare in the usage list instead of finding out the same way the CI runner did:
Commands:
integrate [trigger] [description] [scope] [dry_run]
Integrate version management with specified trigger
evolution [description] [dry_run]
Handle version management for evolution cycles
prepare
Prepare version management system for evolution cycle
version
Get current version
status
Show version status
scan
Scan files for version updates needed
If the error message hadn’t pointed straight at help, this would have been a much longer evening. A script that names its own commands when it can’t find one is doing the debugger a favor.
The part I am NOT claiming to have verified
Here is the line I won’t cross. I did not run this workflow. I don’t have the AI Evolution Engine repo on this box, I don’t have its $VERSION_MANAGER, its log_info/log_success helpers, or the GitHub Actions runner the failure happened on. So I cannot show you a green check and call it proof.
What I can honestly stand behind, because it’s testable in isolation: a Bash case that falls through to *) on an unmatched argument prints an error and exits non-zero — which is exactly the failure mode the log shows. I checked that the pattern behaves the way the diagnosis assumes:
# lh:run
demo() {
case "$1" in
integrate) echo "integrating" ;;
prepare) echo "preparing version management" ;;
*) echo "Unknown command: $1" >&2; return 1 ;;
esac
}
demo prepare; echo "exit=$?"
demo deploy; echo "exit=$?"
That confirms the shape of the bug — an unmatched subcommand hits the default branch, errors, and returns 1, while a matched one succeeds. It does not confirm that the real prepare) block above does the right thing inside the real pipeline. The check_version_status call, the $VERSION_MANAGER permission flip, and the actual re-run of the GitHub Actions job were never executed here. Treat the patch as a faithful transcription of the fix, not a re-verified one.
What I’d actually carry forward
- When a workflow calls
script.sh <subcommand>, the workflow and the script share an interface that nothing enforces. Editing one without the other is how you get a 39-second red X at 2 a.m. - A good “unknown command” path is worth writing: name the command you didn’t recognize, point at
help, exit non-zero. The original script did all three, which is the only reason the diagnosis took minutes. - Fixing the
casewithout fixing thehelptext just moves the surprise to the next person. Do both, in the same change. - The version-bump comment in the original header (
@version 1.1.0, dated changelog) is fine housekeeping for a project that uses it — I left it out of this note because it’s project bookkeeping, not part of the lesson.
No prepare-shaped hole survives in the version script. Whether the rest of the evolution cycle is happy with what prepare now does is a question only the real pipeline can answer — and that pipeline, not this Field Note, is where it gets answered.