How to Promote an Approved Candidate Version in Distilly
To promote an approved candidate version in Distilly, run distilly version promote <candidate-id> to convert the staged candidate into a stable release, which validates the approval flag, moves the directory to a permanent version path, and updates the version manifest.
Distilly, an open-source skill generation framework maintained at titanwings/distilly, manages skill releases through a lightweight version-manager system defined in tools/version_manager.py. Before agents can install a skill, new versions must pass through a candidate staging phase and undergo a formal promotion process. Understanding how to promote an approved candidate version ensures your skills transition safely from testing to production availability.
Understanding Candidate Versions and Approval
What is a Candidate Version?
When you generate a new skill using distilly create, the system writes the output to a candidate version directory following the naming pattern v0.0.0-candidate-<hash>. These directories reside under .distilly/versions/ and serve as isolated sandboxes for testing. The candidate naming convention distinguishes experimental builds from stable releases that production agents consume.
The Approval Gate
Before promotion can occur, a candidate must be explicitly marked approved. The approval mechanism writes "approved": true into the candidate’s meta.json metadata file, typically triggered by distilly test <candidate-id> or manual review of the generated SKILL.md. The VersionManager class in tools/version_manager.py treats this flag as a mandatory prerequisite; any call to promote_candidate() without this metadata entry will fail validation.
How to Promote an Approved Candidate
Using the Distilly CLI
The standard method to promote an approved candidate version in Distilly is the distilly version promote command. If only one approved candidate exists, you may omit the ID; otherwise, specify the full candidate identifier.
Follow this complete workflow:
- Generate the candidate:
distilly create --name my-skill --family colleague
- Run tests to mark the candidate approved:
distilly test v0.0.0-candidate-abc123
- Promote to stable:
distilly version promote v0.0.0-candidate-abc123
- Verify the new stable version:
distilly version list
After promotion, distilly install my-skill automatically resolves to the new stable version without requiring version specifiers.
Programmatic Promotion
For CI/CD pipelines or custom automation, instantiate VersionManager and invoke promote_candidate() directly:
from tools.version_manager import VersionManager
vm = VersionManager()
candidate_id = "v0.0.0-candidate-abc123"
if vm.is_approved(candidate_id):
vm.promote_candidate(candidate_id) # Moves candidate → stable version
print(f"Successfully promoted {candidate_id}")
This approach allows you to embed promotion logic into larger workflows defined in tools/skill_writer.py or external orchestrators.
Internal Promotion Mechanics
The VersionManager.promote_candidate() function in tools/version_manager.py executes three atomic operations to ensure consistency.
First, it performs strict validation by checking that the candidate’s meta.json contains approved = true. If this flag is missing or false, the function raises a validation error and aborts.
Second, it physically moves the candidate directory from its temporary path (e.g., .distilly/versions/v0.0.0-candidate-abc123) to the stable version path (e.g., .distilly/versions/v1.2.3). This rename operation makes the skill immediately discoverable by agents requesting the latest stable release.
Third, it updates .distilly/versions.json to record the new current stable version and archives the previous stable version entry. This manifest update ensures that version listings reflect the promotion instantly.
Summary
- Distilly stages new skills as candidate versions using the format
v0.0.0-candidate-<hash>inside.distilly/versions/. - Approval requires
"approved": truein the candidate’smeta.json, typically set viadistilly test. - Execute
distilly version promote <candidate-id>to trigger promotion through the CLI. - The
VersionManager.promote_candidate()method intools/version_manager.pyhandles validation, directory moves, and manifest updates atomically. - After promotion, the skill becomes the default target for
distilly installoperations.
Frequently Asked Questions
How does Distilly verify a candidate is approved before promotion?
The VersionManager.promote_candidate() function explicitly checks the candidate’s metadata file for "approved": true. This validation occurs in tools/version_manager.py and raises an error if the flag is absent, preventing accidental promotion of untested skills.
Can I promote a candidate without using the CLI?
Yes. Import VersionManager from tools/version_manager.py and call promote_candidate(candidate_id) programmatically. This method is tested in tests/test_cli_lifecycle.py and performs the same validation and file operations as the CLI equivalent.
What happens to previous stable versions after promotion?
Distilly archives the previous stable version within .distilly/versions.json while updating the current pointer to the newly promoted version. The old version files remain in .distilly/versions/ but are no longer served as the default installation target for agents.
Where does Distilly store the current stable version information?
The .distilly/versions.json file acts as the source of truth for version metadata. During promotion, VersionManager updates this file to reflect the new stable release, ensuring that distilly version list and installation commands resolve correctly.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →