
Distill
Reverse-engineer an Allium specification from existing Python or TypeScript implementations using worked extraction examples.
Overview
distill is an agent skill most often used in Validate (also Build) that extracts Allium specifications from existing Python and TypeScript implementations.
Install
npx skills add https://github.com/juxt/allium --skill distillWhat is this skill?
- Worked Example 1: password reset flow from Flask/Python models and tokens
- Shows how implementation details map into Allium specification structure
- Pairs Python (SQLAlchemy-style models) patterns with spec extraction steps
- Useful when legacy code exists but no single source-of-truth spec
- Teaches reading code for entities, status, lockout, and token lifecycle
- Includes worked Example 1: Password Reset (Python/Flask)
Adoption & trust: 1.3k installs on skills.sh; 390 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You have working code but no authoritative spec, so agents and future you cannot safely extend or refactor the behavior.
Who is it for?
Solo builders adopting Allium who need to document legacy Flask, ORM, or TS services before redesign or agent-assisted refactors.
Skip if: Greenfield projects with no code to read, or teams not using Allium who only want generic OpenAPI stubs.
When should I use this skill?
Turning existing implementations into Allium specifications using worked code-to-spec examples.
What do I get? / Deliverables
You produce an Allium-aligned specification that captures entities, rules, and flows distilled from concrete implementations.
- Allium specification draft derived from code
- Documented entities, states, and token or lifecycle rules
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Distilling code into a spec clarifies scope and behavior before you commit to refactors or agent-generated changes. Password-reset style walkthroughs formalize domain rules, entities, and flows—the heart of validation-grade scoping.
Where it fits
Map User, lockout, and PasswordResetToken models into an Allium spec before changing reset email flows.
Publish a spec file alongside the repo so agents implement new endpoints against documented rules.
Compare two implementation variants and distill the minimal shared behavior into one spec.
How it compares
Spec-from-code methodology for Allium—not a one-shot OpenAPI generator or runtime testing skill.
Common Questions / FAQ
Who is distill for?
Developers formalizing behavior with Allium who start from existing Python or TypeScript code rather than a blank requirements doc.
When should I use distill?
In validate when scoping auth or domain flows from legacy code; in build docs when creating the spec artifact agents should follow.
Is distill safe to install?
It guides spec extraction only; review Security Audits on this Prism page and avoid pasting production secrets into example walks.
SKILL.md
READMESKILL.md - Distill
# Worked examples: from code to spec These examples show real implementations in Python and TypeScript, then walk through extracting the Allium specification. ## Example 1: Password Reset (Python/Flask) **The implementation:** ```python # models.py from datetime import datetime, timedelta from werkzeug.security import generate_password_hash, check_password_hash import secrets class User(db.Model): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(120), unique=True, nullable=False) password_hash = db.Column(db.String(256), nullable=False) status = db.Column(db.String(20), default='active') failed_attempts = db.Column(db.Integer, default=0) locked_until = db.Column(db.DateTime, nullable=True) def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password) def is_locked(self): return (self.status == 'locked' and self.locked_until and self.locked_until > datetime.utcnow()) class PasswordResetToken(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) token = db.Column(db.String(64), unique=True, nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow) expires_at = db.Column(db.DateTime, nullable=False) used = db.Column(db.Boolean, default=False) user = db.relationship('User', backref='reset_tokens') @staticmethod def generate_token(): return secrets.token_urlsafe(32) def is_valid(self): return (not self.used and self.expires_at > datetime.utcnow()) # routes.py from flask import request, jsonify from flask_mail import Message RESET_TOKEN_EXPIRY_HOURS = 1 MAX_FAILED_ATTEMPTS = 5 LOCKOUT_MINUTES = 15 @app.route('/api/auth/request-reset', methods=['POST']) def request_password_reset(): data = request.get_json() email = data.get('email') user = User.query.filter_by(email=email).first() if not user: # Return success anyway to prevent email enumeration return jsonify({'message': 'If account exists, reset email sent'}), 200 if user.status == 'deactivated': return jsonify({'message': 'If account exists, reset email sent'}), 200 # Invalidate existing tokens PasswordResetToken.query.filter_by( user_id=user.id, used=False ).update({'used': True}) # Create new token token = PasswordResetToken( user_id=user.id, token=PasswordResetToken.generate_token(), expires_at=datetime.utcnow() + timedelta(hours=RESET_TOKEN_EXPIRY_HOURS) ) db.session.add(token) db.session.commit() # Send email reset_url = f"{app.config['FRONTEND_URL']}/reset-password?token={token.token}" msg = Message( 'Password Reset Request', recipients=[user.email], html=render_template('emails/password_reset.html', user=user, reset_url=reset_url) ) mail.send(msg) return jsonify({'message': 'If account exists, reset email sent'}), 200 @app.route('/api/auth/reset-password', methods=['POST']) def reset_password(): data = request.get_json() token_string = data.get('token') new_password = data.get('password') if len(new_password) < 12: return jsonify({'error': 'Password must be at least 12 characters'}), 400 token = PasswordResetToken.query.filter_by(token=token_string).first() if not token or not token.is_valid(): return jsonify({'error': 'Invalid or expired token'}), 400 user = token.user # Mark token as used token.used = True # Update password user.set_password(new_password) user.status = 'active' user.failed_attempts = 0 user.locked_until = None # Invalidate all sessions (ass