Deterministic package-manager-style resolver for AI skills
Project description
Aptitude Resolver
Aptitude is a deterministic, package-manager-style resolver for AI skills.
The system is intentionally split in two:
- Aptitude Server owns registry data, metadata, immutable artifacts, and discovery indexes
- Aptitude owns intent interpretation, candidate selection, dependency resolution, governance, lock generation, and execution planning
Current CLI
Primary commands:
aptitude install "<query>"aptitude sync --lock aptitude.lock.jsonaptitude manifest
Internal preview command:
aptitude resolve "<query>"
Running aptitude with no arguments launches the install-first wizard. install and sync stay as the promoted task commands, while manifest exposes the complete command and flag surface. resolve still exists for preview, debugging, and CI, but it is hidden from normal CLI help.
How To Install
Install the resolver and its development dependencies with uv:
uv sync --extra dev
This creates the local environment from pyproject.toml and makes the published CLI available through uv run or an activated environment.
Packaging And Publishing
This project builds and publishes as a normal Python package. uv is the build and publish tool, and the release registry is PyPI. There is no separate special "uv registry" format.
The packaging metadata lives in pyproject.toml:
[project]defines the package name, version, dependencies, and console entry point[project.scripts]exposes bothaptitude-resolverandaptitude, both mapped toaptitude_resolver.interfaces.cli.main:main[build-system]tellsuvto build the package withuv_build
Build the package artifacts locally:
make build
make build runs uv build --no-sources and creates:
dist/*.whl
dist/*.tar.gz
The wheel is the main installable artifact. It contains the aptitude_resolver package, its dependency metadata, and both console scripts.
For a local manual publish with a PyPI API token:
export PYPI_API_TOKEN=your-pypi-token
make build-publish
make build-publish:
- requires
PYPI_API_TOKEN - builds fresh artifacts into
.build-publish-dist/ - publishes with
uv publish - defaults to the production PyPI upload endpoint
To rehearse the local flow against TestPyPI instead of production PyPI:
export PYPI_API_TOKEN=your-testpypi-token
make build-publish REPOSITORY=testpypi
For the normal release path, publish to PyPI through GitHub Actions trusted publishing:
uv version --bump patch
git tag v$(uv version --short)
git push origin v$(uv version --short)
The release workflow lives at .github/workflows/publish.yml and:
- triggers on tags matching
v* - builds the wheel and sdist with
uv build --no-sources - publishes with
pypa/gh-action-pypi-publish - authenticates to PyPI with GitHub OIDC trusted publishing
- does not use PyPI API tokens or repository secrets for the CI release path
The publish job uses the GitHub Environment pypi. That is not required by PyPI itself, but it is recommended because it gives releases a dedicated protection boundary in GitHub.
Install and run after publishing:
uv tool install aptitude-resolver
aptitude --help
For one-off execution without a persistent install:
uvx aptitude-resolver --help
Use this mental model:
make buildbuilds the distributable artifactsmake build-publishperforms a local token-based publish to PyPI or TestPyPI- pushing a
v*tag triggers the trusted publishing workflow uv tool install aptitude-resolverinstalls the published packageuvx aptitude-resolver ...runs the published package ephemerallyaptitude ...is the command end users run after installation
How To Use
For repo-local development, typical usage starts with one of these commands:
PYTHONPATH=src .venv/bin/python -m aptitude_resolver
PYTHONPATH=src .venv/bin/python -m aptitude_resolver --help
PYTHONPATH=src .venv/bin/python -m aptitude_resolver install "Postman Primary Skill"
PYTHONPATH=src .venv/bin/python -m aptitude_resolver sync --lock aptitude.lock.json
PYTHONPATH=src .venv/bin/python -m aptitude_resolver manifest
The no-args entrypoint launches the install-first wizard. Use install for fresh planning from a query, sync --lock for replaying an existing lockfile, and manifest for the full capability map. For development, python -m aptitude_resolver is the canonical module entrypoint.
For published usage, prefer the installed CLI:
aptitude --help
aptitude install "Postman Primary Skill"
aptitude sync --lock aptitude.lock.json
aptitude manifest
For one-off published usage without installation:
uvx aptitude-resolver
uvx aptitude-resolver install "Postman Primary Skill"
uvx aptitude-resolver sync
What Works Today
- discovery-backed query resolution from human-readable input
- resolver-owned candidate version selection
- deterministic recursive dependency graph resolution
- candidate-policy filtering and graph governance before lock generation
- workspace policy loading from
aptitude.toml - hard policy CLI overrides for fresh planning
- rich lockfile generation, serialization, parsing, and replay
- lock-driven execution plan generation
- local materialization from either a fresh plan or an existing lockfile
sync --lockas the lock-replay equivalent ofuv sync- registry caching and bounded transient retry
- additive telemetry for planning and materialization stages
- deterministic lockfiles for identical logical inputs
- trace output for discovery, selection, resolver, lock, and execution steps
What Is Still Incomplete
- organization-managed policy loading is not implemented yet
- broader organization-specific rules are not implemented yet
- winner-vs-runner-up explanation still derives from parallel explanation logic instead of directly from reranker output
plugins/extensibility is not implemented yet- MCP and SDK interfaces are not implemented yet
Selection, Governance, And Integrity Direction
The canonical architecture now defines these required semantics:
- server provides immutable metadata such as lifecycle, trust, token, size, and checksum facts
- resolver owns policy and candidate selection
- governance is split into:
- candidate-policy filtering before final ranking and final root selection
- full graph governance after resolution and before lock generation
- ranking compares only policy-compliant candidates
- phase 1 checksum verification uses server-published
sha256checksum metadata and fails fast on mismatch
Current code now implements Governance Phase 1, profile-aware ranking, and explainability snapshots. The canonical source of truth for remaining evolution lives under docs/README.md.
Current User Flows
Fresh planning and install:
install query
-> discovery
-> resolver
-> governance
-> lockfile
-> execution plan
-> materialization
Lock replay:
sync --lock aptitude.lock.json
-> lockfile parse
-> lock replay
-> execution plan
-> materialization
Example Commands
Install from a query:
aptitude install "Postman Primary Skill"
Install as JSON for automation:
aptitude install "Postman Primary Skill" --json
Inspect the complete CLI surface:
aptitude manifest
Sync from an existing lockfile:
aptitude sync --lock aptitude.lock.json
Preview the resolved graph, lock, and execution plan without materializing:
uv run python -m aptitude_resolver resolve "Postman Primary Skill"
Current Package Map
src/aptitude_resolver/
application/
dto/
queries/
use_cases/
cache/
discovery/
intent/
query_builder/
reranking/
domain/
errors/
models/
policy/
tracing/
execution/
governance/
interfaces/
cli/
lockfile/
registry/
resolution/
conflict/
graph/
normalizer/
solver/
validation/
shared/
config/
logging/
telemetry/
Current Registry Contract Used By The Resolver
The resolver currently talks to the live registry through registry/ using these runtime paths:
POST /discoveryGET /skills/{slug}GET /skills/{slug}/{version}GET /resolution/{slug}/{version}GET /skills/{slug}/{version}/content
The resolver treats the server as a source of immutable facts and candidate generation only. Final ranking, version choice, solving, policy enforcement, lock generation, and execution planning remain resolver-owned.
Development
Requirements:
- Python
>=3.9
Run the CLI:
PYTHONPATH=src .venv/bin/python -m aptitude_resolver --help
PYTHONPATH=src .venv/bin/python -m aptitude_resolver install "Postman Primary Skill"
PYTHONPATH=src .venv/bin/python -m aptitude_resolver sync --lock aptitude.lock.json
Or via Python:
PYTHONPATH=src .venv/bin/python -m aptitude_resolver --help
Developer workflow:
make help
make format
make format-check
make lint
make typecheck
make test
make test-cov
make check
Source Of Truth Docs
Start with the docs index:
The canonical architecture pair for future implementation work is:
Before any non-trivial implementation or refactor, read both.
Supporting docs:
The docs/reference/openapi/ directory is kept as raw server reference material, not as the sole source of truth for runtime behavior.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aptitude_resolver-0.0.9.tar.gz.
File metadata
- Download URL: aptitude_resolver-0.0.9.tar.gz
- Upload date:
- Size: 66.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb9336e7ca7f24119647c68181236995c5a5ccd250fed766769e49331516e5e5
|
|
| MD5 |
93a27e39b50b55ae9edb221c0b5247eb
|
|
| BLAKE2b-256 |
beee6a4980389389941b6f7fe768567a02e406e931aed45ad1d01b4096acfaa1
|
File details
Details for the file aptitude_resolver-0.0.9-py3-none-any.whl.
File metadata
- Download URL: aptitude_resolver-0.0.9-py3-none-any.whl
- Upload date:
- Size: 106.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9e1d1f2d1bef53f968cecce3f8bafbe5a24282cd999be0f5ac2569c9e4ee8b4
|
|
| MD5 |
06b409402bfcfa63ef0dc0d8c74c6d4f
|
|
| BLAKE2b-256 |
5bd0ba0e23fd1b8f9dca6f426087535c3e4e547a8cb9e7e2bef8a68cd9b39596
|