aptitude-resolver 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aptitude_resolver-0.0.1/PKG-INFO +368 -0
- aptitude_resolver-0.0.1/README.md +344 -0
- aptitude_resolver-0.0.1/pyproject.toml +61 -0
- aptitude_resolver-0.0.1/src/aptitude/__init__.py +7 -0
- aptitude_resolver-0.0.1/src/aptitude/application/__init__.py +1 -0
- aptitude_resolver-0.0.1/src/aptitude/application/composition.py +341 -0
- aptitude_resolver-0.0.1/src/aptitude/application/dto/__init__.py +59 -0
- aptitude_resolver-0.0.1/src/aptitude/application/dto/install_dto.py +88 -0
- aptitude_resolver-0.0.1/src/aptitude/application/dto/resolve_request_dto.py +20 -0
- aptitude_resolver-0.0.1/src/aptitude/application/dto/resolve_result_dto.py +263 -0
- aptitude_resolver-0.0.1/src/aptitude/application/queries/__init__.py +13 -0
- aptitude_resolver-0.0.1/src/aptitude/application/queries/plan_skill_resolution.py +370 -0
- aptitude_resolver-0.0.1/src/aptitude/application/use_cases/__init__.py +13 -0
- aptitude_resolver-0.0.1/src/aptitude/application/use_cases/install_skill.py +139 -0
- aptitude_resolver-0.0.1/src/aptitude/application/use_cases/resolution_mapping.py +259 -0
- aptitude_resolver-0.0.1/src/aptitude/application/use_cases/resolve_skill_query.py +86 -0
- aptitude_resolver-0.0.1/src/aptitude/application/use_cases/sync_from_lock.py +100 -0
- aptitude_resolver-0.0.1/src/aptitude/cache/__init__.py +20 -0
- aptitude_resolver-0.0.1/src/aptitude/cache/keys.py +34 -0
- aptitude_resolver-0.0.1/src/aptitude/cache/store.py +61 -0
- aptitude_resolver-0.0.1/src/aptitude/discovery/__init__.py +13 -0
- aptitude_resolver-0.0.1/src/aptitude/discovery/candidate_discovery.py +155 -0
- aptitude_resolver-0.0.1/src/aptitude/discovery/intent/__init__.py +8 -0
- aptitude_resolver-0.0.1/src/aptitude/discovery/intent/parsing.py +63 -0
- aptitude_resolver-0.0.1/src/aptitude/discovery/query_builder/__init__.py +5 -0
- aptitude_resolver-0.0.1/src/aptitude/discovery/query_builder/build_query.py +17 -0
- aptitude_resolver-0.0.1/src/aptitude/discovery/reranking/__init__.py +5 -0
- aptitude_resolver-0.0.1/src/aptitude/discovery/reranking/candidate_reranker.py +584 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/__init__.py +1 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/errors/__init__.py +41 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/errors/resolver_errors.py +188 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/models/__init__.py +33 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/models/dependency_spec.py +16 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/models/discovered_skill.py +15 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/models/discovery_candidate.py +26 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/models/discovery_query.py +16 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/models/resolution_graph.py +59 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/models/search_intent.py +18 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/models/skill_coordinate.py +13 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/models/skill_identity.py +21 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/models/skill_metadata.py +31 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/models/version_summary.py +29 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/policy/__init__.py +26 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/policy/models.py +97 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/policy/ranking.py +33 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/policy/selection.py +40 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/tracing/__init__.py +5 -0
- aptitude_resolver-0.0.1/src/aptitude/domain/tracing/models.py +15 -0
- aptitude_resolver-0.0.1/src/aptitude/execution/__init__.py +29 -0
- aptitude_resolver-0.0.1/src/aptitude/execution/debug_artifacts.py +107 -0
- aptitude_resolver-0.0.1/src/aptitude/execution/materialize.py +174 -0
- aptitude_resolver-0.0.1/src/aptitude/execution/plan.py +67 -0
- aptitude_resolver-0.0.1/src/aptitude/governance/__init__.py +8 -0
- aptitude_resolver-0.0.1/src/aptitude/governance/evaluator.py +304 -0
- aptitude_resolver-0.0.1/src/aptitude/interfaces/__init__.py +1 -0
- aptitude_resolver-0.0.1/src/aptitude/interfaces/cli/__init__.py +5 -0
- aptitude_resolver-0.0.1/src/aptitude/interfaces/cli/app.py +730 -0
- aptitude_resolver-0.0.1/src/aptitude/interfaces/cli/catalog.py +500 -0
- aptitude_resolver-0.0.1/src/aptitude/interfaces/cli/main.py +21 -0
- aptitude_resolver-0.0.1/src/aptitude/interfaces/cli/support.py +389 -0
- aptitude_resolver-0.0.1/src/aptitude/interfaces/cli/wizard.py +1101 -0
- aptitude_resolver-0.0.1/src/aptitude/interfaces/shared/__init__.py +9 -0
- aptitude_resolver-0.0.1/src/aptitude/interfaces/shared/install_workflow.py +233 -0
- aptitude_resolver-0.0.1/src/aptitude/lockfile/__init__.py +35 -0
- aptitude_resolver-0.0.1/src/aptitude/lockfile/model.py +97 -0
- aptitude_resolver-0.0.1/src/aptitude/lockfile/parser.py +247 -0
- aptitude_resolver-0.0.1/src/aptitude/lockfile/replay.py +91 -0
- aptitude_resolver-0.0.1/src/aptitude/lockfile/serializer.py +247 -0
- aptitude_resolver-0.0.1/src/aptitude/registry/__init__.py +5 -0
- aptitude_resolver-0.0.1/src/aptitude/registry/client.py +344 -0
- aptitude_resolver-0.0.1/src/aptitude/registry/mappers.py +108 -0
- aptitude_resolver-0.0.1/src/aptitude/registry/transport_models.py +125 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/__init__.py +1 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/conflict/__init__.py +7 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/conflict/conflict_rules.py +20 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/graph/__init__.py +7 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/graph/recursive_graph_resolver.py +246 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/normalizer/__init__.py +7 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/normalizer/dependency_normalizer.py +22 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/solver/__init__.py +19 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/solver/candidate_selection.py +92 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/solver/candidate_version_resolution.py +228 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/solver/version_selection.py +41 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/validation/__init__.py +7 -0
- aptitude_resolver-0.0.1/src/aptitude/resolution/validation/graph_validator.py +18 -0
- aptitude_resolver-0.0.1/src/aptitude/shared/__init__.py +1 -0
- aptitude_resolver-0.0.1/src/aptitude/shared/config/__init__.py +31 -0
- aptitude_resolver-0.0.1/src/aptitude/shared/config/aptitude_config.py +133 -0
- aptitude_resolver-0.0.1/src/aptitude/shared/config/settings.py +87 -0
- aptitude_resolver-0.0.1/src/aptitude/shared/logging/__init__.py +5 -0
- aptitude_resolver-0.0.1/src/aptitude/shared/logging/configure.py +27 -0
- aptitude_resolver-0.0.1/src/aptitude/telemetry/__init__.py +9 -0
- aptitude_resolver-0.0.1/src/aptitude/telemetry/metrics.py +61 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: aptitude-resolver
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Deterministic package-manager-style resolver for AI skills
|
|
5
|
+
Requires-Dist: diskcache>=5.6
|
|
6
|
+
Requires-Dist: httpx>=0.27
|
|
7
|
+
Requires-Dist: packaging>=24.0
|
|
8
|
+
Requires-Dist: prompt-toolkit>=3.0
|
|
9
|
+
Requires-Dist: pydantic>=2.0
|
|
10
|
+
Requires-Dist: pydantic-settings>=2.0
|
|
11
|
+
Requires-Dist: rich>=13.0
|
|
12
|
+
Requires-Dist: ruff==0.15.9
|
|
13
|
+
Requires-Dist: structlog>=25.0
|
|
14
|
+
Requires-Dist: tenacity>=9.0
|
|
15
|
+
Requires-Dist: tomli>=2.0 ; python_full_version < '3.11'
|
|
16
|
+
Requires-Dist: typer>=0.12
|
|
17
|
+
Requires-Dist: mypy>=1.0 ; extra == 'dev'
|
|
18
|
+
Requires-Dist: pytest>=8.0 ; extra == 'dev'
|
|
19
|
+
Requires-Dist: pytest-cov>=6.0 ; extra == 'dev'
|
|
20
|
+
Requires-Dist: ruff>=0.0.1 ; extra == 'dev'
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# Aptitude Resolver
|
|
26
|
+
|
|
27
|
+

|
|
28
|
+

|
|
29
|
+

|
|
30
|
+

|
|
31
|
+

|
|
32
|
+
[](https://deepwiki.com/y0ncha/aptitude-client)
|
|
33
|
+

|
|
34
|
+
|
|
35
|
+
Aptitude is a deterministic, package-manager-style resolver for AI skills.
|
|
36
|
+
|
|
37
|
+
The system is intentionally split in two:
|
|
38
|
+
|
|
39
|
+
- Aptitude Server owns registry data, metadata, immutable artifacts, and discovery indexes
|
|
40
|
+
- Aptitude owns intent interpretation, candidate selection, dependency resolution, governance, lock generation, and execution planning
|
|
41
|
+
|
|
42
|
+
## Current CLI
|
|
43
|
+
|
|
44
|
+
Primary commands:
|
|
45
|
+
|
|
46
|
+
- `aptitude install "<query>"`
|
|
47
|
+
- `aptitude sync --lock aptitude.lock.json`
|
|
48
|
+
- `aptitude manifest`
|
|
49
|
+
|
|
50
|
+
Internal preview command:
|
|
51
|
+
|
|
52
|
+
- `aptitude resolve "<query>"`
|
|
53
|
+
|
|
54
|
+
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.
|
|
55
|
+
|
|
56
|
+
## How To Install
|
|
57
|
+
|
|
58
|
+
Install the resolver and its development dependencies with `uv`:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv sync --extra dev
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
This creates the local environment from `pyproject.toml` and makes the `aptitude` entrypoint available through `uv run` or an activated environment.
|
|
65
|
+
|
|
66
|
+
## Packaging And Publishing
|
|
67
|
+
|
|
68
|
+
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.
|
|
69
|
+
|
|
70
|
+
The packaging metadata lives in `pyproject.toml`:
|
|
71
|
+
|
|
72
|
+
- `[project]` defines the package name, version, dependencies, and console entry point
|
|
73
|
+
- `[project.scripts]` maps the installed `aptitude` command to `aptitude.interfaces.cli.main:main`
|
|
74
|
+
- `[build-system]` tells `uv` to build the package with `uv_build`
|
|
75
|
+
|
|
76
|
+
Build the package artifacts locally:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
make package
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`make package` runs `uv build --no-sources` and creates:
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
dist/*.whl
|
|
86
|
+
dist/*.tar.gz
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The wheel is the main installable artifact. It contains the `aptitude` package, its dependency metadata, and the `aptitude` console script.
|
|
90
|
+
|
|
91
|
+
For a local manual publish with a PyPI API token:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
export PYPI_API_TOKEN=your-pypi-token
|
|
95
|
+
make build-publish
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`make build-publish`:
|
|
99
|
+
|
|
100
|
+
- requires `PYPI_API_TOKEN`
|
|
101
|
+
- builds fresh artifacts into `.build-publish-dist/`
|
|
102
|
+
- publishes with `uv publish`
|
|
103
|
+
- defaults to the production PyPI upload endpoint
|
|
104
|
+
|
|
105
|
+
To rehearse the local flow against TestPyPI instead of production PyPI:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
export PYPI_API_TOKEN=your-testpypi-token
|
|
109
|
+
make build-publish REPOSITORY=testpypi
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
For the normal release path, publish to PyPI through GitHub Actions trusted publishing:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
git tag v0.0.1
|
|
116
|
+
git push origin v0.0.1
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The release workflow lives at `.github/workflows/publish.yml` and:
|
|
120
|
+
|
|
121
|
+
- triggers on tags matching `v*`
|
|
122
|
+
- builds the wheel and sdist with `uv build --no-sources`
|
|
123
|
+
- publishes with `pypa/gh-action-pypi-publish`
|
|
124
|
+
- authenticates to PyPI with GitHub OIDC trusted publishing
|
|
125
|
+
- does not use PyPI API tokens or repository secrets for the CI release path
|
|
126
|
+
|
|
127
|
+
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.
|
|
128
|
+
|
|
129
|
+
Install and run after publishing:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
uv tool install aptitude
|
|
133
|
+
aptitude --help
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
For one-off execution without a persistent install:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
uvx aptitude --help
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Use this mental model:
|
|
143
|
+
|
|
144
|
+
- `make package` builds the distributable artifacts
|
|
145
|
+
- `make build-publish` performs a local token-based publish to PyPI or TestPyPI
|
|
146
|
+
- pushing a `v*` tag triggers the trusted publishing workflow
|
|
147
|
+
- `uv tool install aptitude` installs the published CLI
|
|
148
|
+
- `aptitude ...` is the command end users run after installation
|
|
149
|
+
|
|
150
|
+
## How To Use
|
|
151
|
+
|
|
152
|
+
For repo-local development, typical usage starts with one of these commands:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main
|
|
156
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main --help
|
|
157
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main install "Postman Primary Skill"
|
|
158
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main sync --lock aptitude.lock.json
|
|
159
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main manifest
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
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. The help text and examples still use the logical `aptitude` command name, but the verified repo-local entrypoint is the module invocation above.
|
|
163
|
+
|
|
164
|
+
For published usage, prefer the installed CLI:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
aptitude --help
|
|
168
|
+
aptitude install "Postman Primary Skill"
|
|
169
|
+
aptitude sync --lock aptitude.lock.json
|
|
170
|
+
aptitude manifest
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## What Works Today
|
|
174
|
+
|
|
175
|
+
- discovery-backed query resolution from human-readable input
|
|
176
|
+
- resolver-owned candidate version selection
|
|
177
|
+
- deterministic recursive dependency graph resolution
|
|
178
|
+
- candidate-policy filtering and graph governance before lock generation
|
|
179
|
+
- workspace policy loading from `aptitude.toml`
|
|
180
|
+
- hard policy CLI overrides for fresh planning
|
|
181
|
+
- rich lockfile generation, serialization, parsing, and replay
|
|
182
|
+
- lock-driven execution plan generation
|
|
183
|
+
- local materialization from either a fresh plan or an existing lockfile
|
|
184
|
+
- `sync --lock` as the lock-replay equivalent of `uv sync`
|
|
185
|
+
- registry caching and bounded transient retry
|
|
186
|
+
- additive telemetry for planning and materialization stages
|
|
187
|
+
- deterministic lockfiles for identical logical inputs
|
|
188
|
+
- trace output for discovery, selection, resolver, lock, and execution steps
|
|
189
|
+
|
|
190
|
+
## What Is Still Incomplete
|
|
191
|
+
|
|
192
|
+
- organization-managed policy loading is not implemented yet
|
|
193
|
+
- broader organization-specific rules are not implemented yet
|
|
194
|
+
- winner-vs-runner-up explanation still derives from parallel explanation logic instead of directly from reranker output
|
|
195
|
+
- `plugins/` extensibility is not implemented yet
|
|
196
|
+
- MCP and SDK interfaces are not implemented yet
|
|
197
|
+
|
|
198
|
+
## Selection, Governance, And Integrity Direction
|
|
199
|
+
|
|
200
|
+
The canonical architecture now defines these required semantics:
|
|
201
|
+
|
|
202
|
+
- server provides immutable metadata such as lifecycle, trust, token, size, and checksum facts
|
|
203
|
+
- resolver owns policy and candidate selection
|
|
204
|
+
- governance is split into:
|
|
205
|
+
- candidate-policy filtering before final ranking and final root selection
|
|
206
|
+
- full graph governance after resolution and before lock generation
|
|
207
|
+
- ranking compares only policy-compliant candidates
|
|
208
|
+
- phase 1 checksum verification uses server-published `sha256` checksum metadata and fails fast on mismatch
|
|
209
|
+
|
|
210
|
+
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](docs/README.md).
|
|
211
|
+
|
|
212
|
+
## Current User Flows
|
|
213
|
+
|
|
214
|
+
Fresh planning and install:
|
|
215
|
+
|
|
216
|
+
```text
|
|
217
|
+
install query
|
|
218
|
+
-> discovery
|
|
219
|
+
-> resolver
|
|
220
|
+
-> governance
|
|
221
|
+
-> lockfile
|
|
222
|
+
-> execution plan
|
|
223
|
+
-> materialization
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Lock replay:
|
|
227
|
+
|
|
228
|
+
```text
|
|
229
|
+
sync --lock aptitude.lock.json
|
|
230
|
+
-> lockfile parse
|
|
231
|
+
-> lock replay
|
|
232
|
+
-> execution plan
|
|
233
|
+
-> materialization
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Example Commands
|
|
237
|
+
|
|
238
|
+
Install from a query:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
aptitude install "Postman Primary Skill"
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Install as JSON for automation:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
aptitude install "Postman Primary Skill" --json
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Inspect the complete CLI surface:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
aptitude manifest
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Sync from an existing lockfile:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
aptitude sync --lock aptitude.lock.json
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Preview the resolved graph, lock, and execution plan without materializing:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
uv run python -m aptitude.interfaces.cli.main resolve "Postman Primary Skill"
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Current Package Map
|
|
269
|
+
|
|
270
|
+
```text
|
|
271
|
+
src/aptitude/
|
|
272
|
+
application/
|
|
273
|
+
dto/
|
|
274
|
+
queries/
|
|
275
|
+
use_cases/
|
|
276
|
+
cache/
|
|
277
|
+
discovery/
|
|
278
|
+
intent/
|
|
279
|
+
query_builder/
|
|
280
|
+
reranking/
|
|
281
|
+
domain/
|
|
282
|
+
errors/
|
|
283
|
+
models/
|
|
284
|
+
policy/
|
|
285
|
+
tracing/
|
|
286
|
+
execution/
|
|
287
|
+
governance/
|
|
288
|
+
interfaces/
|
|
289
|
+
cli/
|
|
290
|
+
lockfile/
|
|
291
|
+
registry/
|
|
292
|
+
resolution/
|
|
293
|
+
conflict/
|
|
294
|
+
graph/
|
|
295
|
+
normalizer/
|
|
296
|
+
solver/
|
|
297
|
+
validation/
|
|
298
|
+
shared/
|
|
299
|
+
config/
|
|
300
|
+
logging/
|
|
301
|
+
telemetry/
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Current Registry Contract Used By The Resolver
|
|
305
|
+
|
|
306
|
+
The resolver currently talks to the live registry through `registry/` using these runtime paths:
|
|
307
|
+
|
|
308
|
+
- `POST /discovery`
|
|
309
|
+
- `GET /skills/{slug}`
|
|
310
|
+
- `GET /skills/{slug}/{version}`
|
|
311
|
+
- `GET /resolution/{slug}/{version}`
|
|
312
|
+
- `GET /skills/{slug}/{version}/content`
|
|
313
|
+
|
|
314
|
+
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.
|
|
315
|
+
|
|
316
|
+
## Development
|
|
317
|
+
|
|
318
|
+
Requirements:
|
|
319
|
+
|
|
320
|
+
- Python `>=3.9`
|
|
321
|
+
|
|
322
|
+
Run the CLI:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main --help
|
|
326
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main install "Postman Primary Skill"
|
|
327
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main sync --lock aptitude.lock.json
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Or via Python:
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main --help
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Developer workflow:
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
make help
|
|
340
|
+
make format
|
|
341
|
+
make format-check
|
|
342
|
+
make lint
|
|
343
|
+
make typecheck
|
|
344
|
+
make test
|
|
345
|
+
make test-cov
|
|
346
|
+
make check
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Source Of Truth Docs
|
|
350
|
+
|
|
351
|
+
Start with the docs index:
|
|
352
|
+
|
|
353
|
+
- [docs/README.md](docs/README.md)
|
|
354
|
+
|
|
355
|
+
The canonical architecture pair for future implementation work is:
|
|
356
|
+
|
|
357
|
+
- [docs/architecture/system-overview.md](docs/architecture/system-overview.md)
|
|
358
|
+
- [docs/architecture/decision-rules.md](docs/architecture/decision-rules.md)
|
|
359
|
+
|
|
360
|
+
Before any non-trivial implementation or refactor, read both.
|
|
361
|
+
|
|
362
|
+
Supporting docs:
|
|
363
|
+
|
|
364
|
+
- [docs/contributors/README.md](docs/contributors/README.md)
|
|
365
|
+
- [docs/reference/recommended-libraries.md](docs/reference/recommended-libraries.md)
|
|
366
|
+
- [docs/roadmap/README.md](docs/roadmap/README.md)
|
|
367
|
+
|
|
368
|
+
The `docs/reference/openapi/` directory is kept as raw server reference material, not as the sole source of truth for runtime behavior.
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# Aptitude Resolver
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
[](https://deepwiki.com/y0ncha/aptitude-client)
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
Aptitude is a deterministic, package-manager-style resolver for AI skills.
|
|
12
|
+
|
|
13
|
+
The system is intentionally split in two:
|
|
14
|
+
|
|
15
|
+
- Aptitude Server owns registry data, metadata, immutable artifacts, and discovery indexes
|
|
16
|
+
- Aptitude owns intent interpretation, candidate selection, dependency resolution, governance, lock generation, and execution planning
|
|
17
|
+
|
|
18
|
+
## Current CLI
|
|
19
|
+
|
|
20
|
+
Primary commands:
|
|
21
|
+
|
|
22
|
+
- `aptitude install "<query>"`
|
|
23
|
+
- `aptitude sync --lock aptitude.lock.json`
|
|
24
|
+
- `aptitude manifest`
|
|
25
|
+
|
|
26
|
+
Internal preview command:
|
|
27
|
+
|
|
28
|
+
- `aptitude resolve "<query>"`
|
|
29
|
+
|
|
30
|
+
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.
|
|
31
|
+
|
|
32
|
+
## How To Install
|
|
33
|
+
|
|
34
|
+
Install the resolver and its development dependencies with `uv`:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
uv sync --extra dev
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This creates the local environment from `pyproject.toml` and makes the `aptitude` entrypoint available through `uv run` or an activated environment.
|
|
41
|
+
|
|
42
|
+
## Packaging And Publishing
|
|
43
|
+
|
|
44
|
+
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.
|
|
45
|
+
|
|
46
|
+
The packaging metadata lives in `pyproject.toml`:
|
|
47
|
+
|
|
48
|
+
- `[project]` defines the package name, version, dependencies, and console entry point
|
|
49
|
+
- `[project.scripts]` maps the installed `aptitude` command to `aptitude.interfaces.cli.main:main`
|
|
50
|
+
- `[build-system]` tells `uv` to build the package with `uv_build`
|
|
51
|
+
|
|
52
|
+
Build the package artifacts locally:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
make package
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`make package` runs `uv build --no-sources` and creates:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
dist/*.whl
|
|
62
|
+
dist/*.tar.gz
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The wheel is the main installable artifact. It contains the `aptitude` package, its dependency metadata, and the `aptitude` console script.
|
|
66
|
+
|
|
67
|
+
For a local manual publish with a PyPI API token:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
export PYPI_API_TOKEN=your-pypi-token
|
|
71
|
+
make build-publish
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`make build-publish`:
|
|
75
|
+
|
|
76
|
+
- requires `PYPI_API_TOKEN`
|
|
77
|
+
- builds fresh artifacts into `.build-publish-dist/`
|
|
78
|
+
- publishes with `uv publish`
|
|
79
|
+
- defaults to the production PyPI upload endpoint
|
|
80
|
+
|
|
81
|
+
To rehearse the local flow against TestPyPI instead of production PyPI:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
export PYPI_API_TOKEN=your-testpypi-token
|
|
85
|
+
make build-publish REPOSITORY=testpypi
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
For the normal release path, publish to PyPI through GitHub Actions trusted publishing:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
git tag v0.0.1
|
|
92
|
+
git push origin v0.0.1
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The release workflow lives at `.github/workflows/publish.yml` and:
|
|
96
|
+
|
|
97
|
+
- triggers on tags matching `v*`
|
|
98
|
+
- builds the wheel and sdist with `uv build --no-sources`
|
|
99
|
+
- publishes with `pypa/gh-action-pypi-publish`
|
|
100
|
+
- authenticates to PyPI with GitHub OIDC trusted publishing
|
|
101
|
+
- does not use PyPI API tokens or repository secrets for the CI release path
|
|
102
|
+
|
|
103
|
+
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.
|
|
104
|
+
|
|
105
|
+
Install and run after publishing:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
uv tool install aptitude
|
|
109
|
+
aptitude --help
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
For one-off execution without a persistent install:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
uvx aptitude --help
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Use this mental model:
|
|
119
|
+
|
|
120
|
+
- `make package` builds the distributable artifacts
|
|
121
|
+
- `make build-publish` performs a local token-based publish to PyPI or TestPyPI
|
|
122
|
+
- pushing a `v*` tag triggers the trusted publishing workflow
|
|
123
|
+
- `uv tool install aptitude` installs the published CLI
|
|
124
|
+
- `aptitude ...` is the command end users run after installation
|
|
125
|
+
|
|
126
|
+
## How To Use
|
|
127
|
+
|
|
128
|
+
For repo-local development, typical usage starts with one of these commands:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main
|
|
132
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main --help
|
|
133
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main install "Postman Primary Skill"
|
|
134
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main sync --lock aptitude.lock.json
|
|
135
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main manifest
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
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. The help text and examples still use the logical `aptitude` command name, but the verified repo-local entrypoint is the module invocation above.
|
|
139
|
+
|
|
140
|
+
For published usage, prefer the installed CLI:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
aptitude --help
|
|
144
|
+
aptitude install "Postman Primary Skill"
|
|
145
|
+
aptitude sync --lock aptitude.lock.json
|
|
146
|
+
aptitude manifest
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## What Works Today
|
|
150
|
+
|
|
151
|
+
- discovery-backed query resolution from human-readable input
|
|
152
|
+
- resolver-owned candidate version selection
|
|
153
|
+
- deterministic recursive dependency graph resolution
|
|
154
|
+
- candidate-policy filtering and graph governance before lock generation
|
|
155
|
+
- workspace policy loading from `aptitude.toml`
|
|
156
|
+
- hard policy CLI overrides for fresh planning
|
|
157
|
+
- rich lockfile generation, serialization, parsing, and replay
|
|
158
|
+
- lock-driven execution plan generation
|
|
159
|
+
- local materialization from either a fresh plan or an existing lockfile
|
|
160
|
+
- `sync --lock` as the lock-replay equivalent of `uv sync`
|
|
161
|
+
- registry caching and bounded transient retry
|
|
162
|
+
- additive telemetry for planning and materialization stages
|
|
163
|
+
- deterministic lockfiles for identical logical inputs
|
|
164
|
+
- trace output for discovery, selection, resolver, lock, and execution steps
|
|
165
|
+
|
|
166
|
+
## What Is Still Incomplete
|
|
167
|
+
|
|
168
|
+
- organization-managed policy loading is not implemented yet
|
|
169
|
+
- broader organization-specific rules are not implemented yet
|
|
170
|
+
- winner-vs-runner-up explanation still derives from parallel explanation logic instead of directly from reranker output
|
|
171
|
+
- `plugins/` extensibility is not implemented yet
|
|
172
|
+
- MCP and SDK interfaces are not implemented yet
|
|
173
|
+
|
|
174
|
+
## Selection, Governance, And Integrity Direction
|
|
175
|
+
|
|
176
|
+
The canonical architecture now defines these required semantics:
|
|
177
|
+
|
|
178
|
+
- server provides immutable metadata such as lifecycle, trust, token, size, and checksum facts
|
|
179
|
+
- resolver owns policy and candidate selection
|
|
180
|
+
- governance is split into:
|
|
181
|
+
- candidate-policy filtering before final ranking and final root selection
|
|
182
|
+
- full graph governance after resolution and before lock generation
|
|
183
|
+
- ranking compares only policy-compliant candidates
|
|
184
|
+
- phase 1 checksum verification uses server-published `sha256` checksum metadata and fails fast on mismatch
|
|
185
|
+
|
|
186
|
+
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](docs/README.md).
|
|
187
|
+
|
|
188
|
+
## Current User Flows
|
|
189
|
+
|
|
190
|
+
Fresh planning and install:
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
install query
|
|
194
|
+
-> discovery
|
|
195
|
+
-> resolver
|
|
196
|
+
-> governance
|
|
197
|
+
-> lockfile
|
|
198
|
+
-> execution plan
|
|
199
|
+
-> materialization
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Lock replay:
|
|
203
|
+
|
|
204
|
+
```text
|
|
205
|
+
sync --lock aptitude.lock.json
|
|
206
|
+
-> lockfile parse
|
|
207
|
+
-> lock replay
|
|
208
|
+
-> execution plan
|
|
209
|
+
-> materialization
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Example Commands
|
|
213
|
+
|
|
214
|
+
Install from a query:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
aptitude install "Postman Primary Skill"
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Install as JSON for automation:
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
aptitude install "Postman Primary Skill" --json
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Inspect the complete CLI surface:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
aptitude manifest
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Sync from an existing lockfile:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
aptitude sync --lock aptitude.lock.json
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Preview the resolved graph, lock, and execution plan without materializing:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
uv run python -m aptitude.interfaces.cli.main resolve "Postman Primary Skill"
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Current Package Map
|
|
245
|
+
|
|
246
|
+
```text
|
|
247
|
+
src/aptitude/
|
|
248
|
+
application/
|
|
249
|
+
dto/
|
|
250
|
+
queries/
|
|
251
|
+
use_cases/
|
|
252
|
+
cache/
|
|
253
|
+
discovery/
|
|
254
|
+
intent/
|
|
255
|
+
query_builder/
|
|
256
|
+
reranking/
|
|
257
|
+
domain/
|
|
258
|
+
errors/
|
|
259
|
+
models/
|
|
260
|
+
policy/
|
|
261
|
+
tracing/
|
|
262
|
+
execution/
|
|
263
|
+
governance/
|
|
264
|
+
interfaces/
|
|
265
|
+
cli/
|
|
266
|
+
lockfile/
|
|
267
|
+
registry/
|
|
268
|
+
resolution/
|
|
269
|
+
conflict/
|
|
270
|
+
graph/
|
|
271
|
+
normalizer/
|
|
272
|
+
solver/
|
|
273
|
+
validation/
|
|
274
|
+
shared/
|
|
275
|
+
config/
|
|
276
|
+
logging/
|
|
277
|
+
telemetry/
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Current Registry Contract Used By The Resolver
|
|
281
|
+
|
|
282
|
+
The resolver currently talks to the live registry through `registry/` using these runtime paths:
|
|
283
|
+
|
|
284
|
+
- `POST /discovery`
|
|
285
|
+
- `GET /skills/{slug}`
|
|
286
|
+
- `GET /skills/{slug}/{version}`
|
|
287
|
+
- `GET /resolution/{slug}/{version}`
|
|
288
|
+
- `GET /skills/{slug}/{version}/content`
|
|
289
|
+
|
|
290
|
+
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.
|
|
291
|
+
|
|
292
|
+
## Development
|
|
293
|
+
|
|
294
|
+
Requirements:
|
|
295
|
+
|
|
296
|
+
- Python `>=3.9`
|
|
297
|
+
|
|
298
|
+
Run the CLI:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main --help
|
|
302
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main install "Postman Primary Skill"
|
|
303
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main sync --lock aptitude.lock.json
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Or via Python:
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
PYTHONPATH=src .venv/bin/python -m aptitude.interfaces.cli.main --help
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Developer workflow:
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
make help
|
|
316
|
+
make format
|
|
317
|
+
make format-check
|
|
318
|
+
make lint
|
|
319
|
+
make typecheck
|
|
320
|
+
make test
|
|
321
|
+
make test-cov
|
|
322
|
+
make check
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Source Of Truth Docs
|
|
326
|
+
|
|
327
|
+
Start with the docs index:
|
|
328
|
+
|
|
329
|
+
- [docs/README.md](docs/README.md)
|
|
330
|
+
|
|
331
|
+
The canonical architecture pair for future implementation work is:
|
|
332
|
+
|
|
333
|
+
- [docs/architecture/system-overview.md](docs/architecture/system-overview.md)
|
|
334
|
+
- [docs/architecture/decision-rules.md](docs/architecture/decision-rules.md)
|
|
335
|
+
|
|
336
|
+
Before any non-trivial implementation or refactor, read both.
|
|
337
|
+
|
|
338
|
+
Supporting docs:
|
|
339
|
+
|
|
340
|
+
- [docs/contributors/README.md](docs/contributors/README.md)
|
|
341
|
+
- [docs/reference/recommended-libraries.md](docs/reference/recommended-libraries.md)
|
|
342
|
+
- [docs/roadmap/README.md](docs/roadmap/README.md)
|
|
343
|
+
|
|
344
|
+
The `docs/reference/openapi/` directory is kept as raw server reference material, not as the sole source of truth for runtime behavior.
|