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.
Files changed (93) hide show
  1. aptitude_resolver-0.0.1/PKG-INFO +368 -0
  2. aptitude_resolver-0.0.1/README.md +344 -0
  3. aptitude_resolver-0.0.1/pyproject.toml +61 -0
  4. aptitude_resolver-0.0.1/src/aptitude/__init__.py +7 -0
  5. aptitude_resolver-0.0.1/src/aptitude/application/__init__.py +1 -0
  6. aptitude_resolver-0.0.1/src/aptitude/application/composition.py +341 -0
  7. aptitude_resolver-0.0.1/src/aptitude/application/dto/__init__.py +59 -0
  8. aptitude_resolver-0.0.1/src/aptitude/application/dto/install_dto.py +88 -0
  9. aptitude_resolver-0.0.1/src/aptitude/application/dto/resolve_request_dto.py +20 -0
  10. aptitude_resolver-0.0.1/src/aptitude/application/dto/resolve_result_dto.py +263 -0
  11. aptitude_resolver-0.0.1/src/aptitude/application/queries/__init__.py +13 -0
  12. aptitude_resolver-0.0.1/src/aptitude/application/queries/plan_skill_resolution.py +370 -0
  13. aptitude_resolver-0.0.1/src/aptitude/application/use_cases/__init__.py +13 -0
  14. aptitude_resolver-0.0.1/src/aptitude/application/use_cases/install_skill.py +139 -0
  15. aptitude_resolver-0.0.1/src/aptitude/application/use_cases/resolution_mapping.py +259 -0
  16. aptitude_resolver-0.0.1/src/aptitude/application/use_cases/resolve_skill_query.py +86 -0
  17. aptitude_resolver-0.0.1/src/aptitude/application/use_cases/sync_from_lock.py +100 -0
  18. aptitude_resolver-0.0.1/src/aptitude/cache/__init__.py +20 -0
  19. aptitude_resolver-0.0.1/src/aptitude/cache/keys.py +34 -0
  20. aptitude_resolver-0.0.1/src/aptitude/cache/store.py +61 -0
  21. aptitude_resolver-0.0.1/src/aptitude/discovery/__init__.py +13 -0
  22. aptitude_resolver-0.0.1/src/aptitude/discovery/candidate_discovery.py +155 -0
  23. aptitude_resolver-0.0.1/src/aptitude/discovery/intent/__init__.py +8 -0
  24. aptitude_resolver-0.0.1/src/aptitude/discovery/intent/parsing.py +63 -0
  25. aptitude_resolver-0.0.1/src/aptitude/discovery/query_builder/__init__.py +5 -0
  26. aptitude_resolver-0.0.1/src/aptitude/discovery/query_builder/build_query.py +17 -0
  27. aptitude_resolver-0.0.1/src/aptitude/discovery/reranking/__init__.py +5 -0
  28. aptitude_resolver-0.0.1/src/aptitude/discovery/reranking/candidate_reranker.py +584 -0
  29. aptitude_resolver-0.0.1/src/aptitude/domain/__init__.py +1 -0
  30. aptitude_resolver-0.0.1/src/aptitude/domain/errors/__init__.py +41 -0
  31. aptitude_resolver-0.0.1/src/aptitude/domain/errors/resolver_errors.py +188 -0
  32. aptitude_resolver-0.0.1/src/aptitude/domain/models/__init__.py +33 -0
  33. aptitude_resolver-0.0.1/src/aptitude/domain/models/dependency_spec.py +16 -0
  34. aptitude_resolver-0.0.1/src/aptitude/domain/models/discovered_skill.py +15 -0
  35. aptitude_resolver-0.0.1/src/aptitude/domain/models/discovery_candidate.py +26 -0
  36. aptitude_resolver-0.0.1/src/aptitude/domain/models/discovery_query.py +16 -0
  37. aptitude_resolver-0.0.1/src/aptitude/domain/models/resolution_graph.py +59 -0
  38. aptitude_resolver-0.0.1/src/aptitude/domain/models/search_intent.py +18 -0
  39. aptitude_resolver-0.0.1/src/aptitude/domain/models/skill_coordinate.py +13 -0
  40. aptitude_resolver-0.0.1/src/aptitude/domain/models/skill_identity.py +21 -0
  41. aptitude_resolver-0.0.1/src/aptitude/domain/models/skill_metadata.py +31 -0
  42. aptitude_resolver-0.0.1/src/aptitude/domain/models/version_summary.py +29 -0
  43. aptitude_resolver-0.0.1/src/aptitude/domain/policy/__init__.py +26 -0
  44. aptitude_resolver-0.0.1/src/aptitude/domain/policy/models.py +97 -0
  45. aptitude_resolver-0.0.1/src/aptitude/domain/policy/ranking.py +33 -0
  46. aptitude_resolver-0.0.1/src/aptitude/domain/policy/selection.py +40 -0
  47. aptitude_resolver-0.0.1/src/aptitude/domain/tracing/__init__.py +5 -0
  48. aptitude_resolver-0.0.1/src/aptitude/domain/tracing/models.py +15 -0
  49. aptitude_resolver-0.0.1/src/aptitude/execution/__init__.py +29 -0
  50. aptitude_resolver-0.0.1/src/aptitude/execution/debug_artifacts.py +107 -0
  51. aptitude_resolver-0.0.1/src/aptitude/execution/materialize.py +174 -0
  52. aptitude_resolver-0.0.1/src/aptitude/execution/plan.py +67 -0
  53. aptitude_resolver-0.0.1/src/aptitude/governance/__init__.py +8 -0
  54. aptitude_resolver-0.0.1/src/aptitude/governance/evaluator.py +304 -0
  55. aptitude_resolver-0.0.1/src/aptitude/interfaces/__init__.py +1 -0
  56. aptitude_resolver-0.0.1/src/aptitude/interfaces/cli/__init__.py +5 -0
  57. aptitude_resolver-0.0.1/src/aptitude/interfaces/cli/app.py +730 -0
  58. aptitude_resolver-0.0.1/src/aptitude/interfaces/cli/catalog.py +500 -0
  59. aptitude_resolver-0.0.1/src/aptitude/interfaces/cli/main.py +21 -0
  60. aptitude_resolver-0.0.1/src/aptitude/interfaces/cli/support.py +389 -0
  61. aptitude_resolver-0.0.1/src/aptitude/interfaces/cli/wizard.py +1101 -0
  62. aptitude_resolver-0.0.1/src/aptitude/interfaces/shared/__init__.py +9 -0
  63. aptitude_resolver-0.0.1/src/aptitude/interfaces/shared/install_workflow.py +233 -0
  64. aptitude_resolver-0.0.1/src/aptitude/lockfile/__init__.py +35 -0
  65. aptitude_resolver-0.0.1/src/aptitude/lockfile/model.py +97 -0
  66. aptitude_resolver-0.0.1/src/aptitude/lockfile/parser.py +247 -0
  67. aptitude_resolver-0.0.1/src/aptitude/lockfile/replay.py +91 -0
  68. aptitude_resolver-0.0.1/src/aptitude/lockfile/serializer.py +247 -0
  69. aptitude_resolver-0.0.1/src/aptitude/registry/__init__.py +5 -0
  70. aptitude_resolver-0.0.1/src/aptitude/registry/client.py +344 -0
  71. aptitude_resolver-0.0.1/src/aptitude/registry/mappers.py +108 -0
  72. aptitude_resolver-0.0.1/src/aptitude/registry/transport_models.py +125 -0
  73. aptitude_resolver-0.0.1/src/aptitude/resolution/__init__.py +1 -0
  74. aptitude_resolver-0.0.1/src/aptitude/resolution/conflict/__init__.py +7 -0
  75. aptitude_resolver-0.0.1/src/aptitude/resolution/conflict/conflict_rules.py +20 -0
  76. aptitude_resolver-0.0.1/src/aptitude/resolution/graph/__init__.py +7 -0
  77. aptitude_resolver-0.0.1/src/aptitude/resolution/graph/recursive_graph_resolver.py +246 -0
  78. aptitude_resolver-0.0.1/src/aptitude/resolution/normalizer/__init__.py +7 -0
  79. aptitude_resolver-0.0.1/src/aptitude/resolution/normalizer/dependency_normalizer.py +22 -0
  80. aptitude_resolver-0.0.1/src/aptitude/resolution/solver/__init__.py +19 -0
  81. aptitude_resolver-0.0.1/src/aptitude/resolution/solver/candidate_selection.py +92 -0
  82. aptitude_resolver-0.0.1/src/aptitude/resolution/solver/candidate_version_resolution.py +228 -0
  83. aptitude_resolver-0.0.1/src/aptitude/resolution/solver/version_selection.py +41 -0
  84. aptitude_resolver-0.0.1/src/aptitude/resolution/validation/__init__.py +7 -0
  85. aptitude_resolver-0.0.1/src/aptitude/resolution/validation/graph_validator.py +18 -0
  86. aptitude_resolver-0.0.1/src/aptitude/shared/__init__.py +1 -0
  87. aptitude_resolver-0.0.1/src/aptitude/shared/config/__init__.py +31 -0
  88. aptitude_resolver-0.0.1/src/aptitude/shared/config/aptitude_config.py +133 -0
  89. aptitude_resolver-0.0.1/src/aptitude/shared/config/settings.py +87 -0
  90. aptitude_resolver-0.0.1/src/aptitude/shared/logging/__init__.py +5 -0
  91. aptitude_resolver-0.0.1/src/aptitude/shared/logging/configure.py +27 -0
  92. aptitude_resolver-0.0.1/src/aptitude/telemetry/__init__.py +9 -0
  93. 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
+ ![Python](https://img.shields.io/badge/python-3.9%2B-3776AB?style=for-the-badge&logo=python&logoColor=white)
28
+ ![uv](https://img.shields.io/badge/uv-managed-6E56CF?style=for-the-badge&logo=uv&logoColor=white)
29
+ ![Pydantic](https://img.shields.io/badge/pydantic-E92063?style=for-the-badge&logo=pydantic&logoColor=white)
30
+ ![pytest](https://img.shields.io/badge/pytest-0A9EDC?style=for-the-badge&logo=pytest&logoColor=white)
31
+ ![Ruff](https://img.shields.io/badge/ruff-D7FF64?style=for-the-badge&logo=ruff&logoColor=111111)
32
+ [![DeepWiki](https://img.shields.io/badge/Ask-DeepWiki-0A66C2?style=for-the-badge&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAsVBMVEVHcEwmWMYZy38Akt0gwZoSaFIbYssUmr4gwJkBlN4WbNE4acofwZkBj9k4aMkBk94WgM0bsIM4aMkewJc2ZMM3Z8cbvIwYpHsewJYAftgBkt0fvpgBkt0cv44cv5wzYckAjtsCk90pasUboXsgwJkfwpYfwJg4aMoct44yXswAkd0BkN84Z8cBktwduZIjcO85lM4hwZo5acoBleA6a88iyaABmOQ8b9QhxZ0CnOoizaOW4DOvAAAAMHRSTlMAKCfW%2FAgWA%2F7%2FDfvMc9j7MU%2Frj3XBcRW%2FJMbe7kUxjI%2FlUzzz6tPQkJ%2BjVmW1oeulmmslAAAByUlEQVQ4y32Tia6jIBSGUVFcqliXtlq73rm3d50ERNC%2B%2F4PNQetoptMeE0PgC%2F9%2FFhCaBSH9Hz2J%2BONgPDl2DolSUWY%2FPL8oEQRCfPxHpFc3Ah5wHoiI6I05NXgjAOgQF3Jn1Dlo4XMPDDes09UE2d%2BREvl3lijBg4CrHNmrbcM2u9u5nwsRcAFfFHFY5sZ607Yua3GqpQiKE6G9cZHZThblZ4T2mLnMxde3ATASMUj72o0Pbs1fADDcLHqAjEDugJ3lC%2BztMGYTADcoLaFyH%2B02DP9%2BWS4ahrXE4laALFKcq8vZfscNY8312mxfr27bLJZjnsYhSDIHmUxLu9h9N%2Fep%2B7pazwoZQw%2B1Nwi33epu7c2p8RooeqCdAHMGoOJIq3CUwIMEniRIaHVe3ZVnO2Vgsh1MstEkQUXVUc%2BjXfk3zbemxS6%2BpQmlPtUeALJ8VKj4JHvAelBqFFdSS3h1SPzQKr%2F%2BaRa0%2B0cCIWtJLauG5U%2FfbgyG01uiNqQhyzA8ddKj1OvK28AsZyN3DKE4X6AEWrU1jJx9N7RFpdPxpHU%2FtMOQG9SjfTp3Yz8KgRVKpfx88Dqhpseq606h%2F%2Bzxfh6LJ8eEDKWbxx9XEDwqzP1SVgAAAABJRU5ErkJggg%3D%3D)](https://deepwiki.com/y0ncha/aptitude-client)
33
+ ![Last Commit](https://img.shields.io/github/last-commit/aptitude-stack/resolver?style=for-the-badge)
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
+ ![Python](https://img.shields.io/badge/python-3.9%2B-3776AB?style=for-the-badge&logo=python&logoColor=white)
4
+ ![uv](https://img.shields.io/badge/uv-managed-6E56CF?style=for-the-badge&logo=uv&logoColor=white)
5
+ ![Pydantic](https://img.shields.io/badge/pydantic-E92063?style=for-the-badge&logo=pydantic&logoColor=white)
6
+ ![pytest](https://img.shields.io/badge/pytest-0A9EDC?style=for-the-badge&logo=pytest&logoColor=white)
7
+ ![Ruff](https://img.shields.io/badge/ruff-D7FF64?style=for-the-badge&logo=ruff&logoColor=111111)
8
+ [![DeepWiki](https://img.shields.io/badge/Ask-DeepWiki-0A66C2?style=for-the-badge&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAsVBMVEVHcEwmWMYZy38Akt0gwZoSaFIbYssUmr4gwJkBlN4WbNE4acofwZkBj9k4aMkBk94WgM0bsIM4aMkewJc2ZMM3Z8cbvIwYpHsewJYAftgBkt0fvpgBkt0cv44cv5wzYckAjtsCk90pasUboXsgwJkfwpYfwJg4aMoct44yXswAkd0BkN84Z8cBktwduZIjcO85lM4hwZo5acoBleA6a88iyaABmOQ8b9QhxZ0CnOoizaOW4DOvAAAAMHRSTlMAKCfW%2FAgWA%2F7%2FDfvMc9j7MU%2Frj3XBcRW%2FJMbe7kUxjI%2FlUzzz6tPQkJ%2BjVmW1oeulmmslAAAByUlEQVQ4y32Tia6jIBSGUVFcqliXtlq73rm3d50ERNC%2B%2F4PNQetoptMeE0PgC%2F9%2FFhCaBSH9Hz2J%2BONgPDl2DolSUWY%2FPL8oEQRCfPxHpFc3Ah5wHoiI6I05NXgjAOgQF3Jn1Dlo4XMPDDes09UE2d%2BREvl3lijBg4CrHNmrbcM2u9u5nwsRcAFfFHFY5sZ607Yua3GqpQiKE6G9cZHZThblZ4T2mLnMxde3ATASMUj72o0Pbs1fADDcLHqAjEDugJ3lC%2BztMGYTADcoLaFyH%2B02DP9%2BWS4ahrXE4laALFKcq8vZfscNY8312mxfr27bLJZjnsYhSDIHmUxLu9h9N%2Fep%2B7pazwoZQw%2B1Nwi33epu7c2p8RooeqCdAHMGoOJIq3CUwIMEniRIaHVe3ZVnO2Vgsh1MstEkQUXVUc%2BjXfk3zbemxS6%2BpQmlPtUeALJ8VKj4JHvAelBqFFdSS3h1SPzQKr%2F%2BaRa0%2B0cCIWtJLauG5U%2FfbgyG01uiNqQhyzA8ddKj1OvK28AsZyN3DKE4X6AEWrU1jJx9N7RFpdPxpHU%2FtMOQG9SjfTp3Yz8KgRVKpfx88Dqhpseq606h%2F%2Bzxfh6LJ8eEDKWbxx9XEDwqzP1SVgAAAABJRU5ErkJggg%3D%3D)](https://deepwiki.com/y0ncha/aptitude-client)
9
+ ![Last Commit](https://img.shields.io/github/last-commit/aptitude-stack/resolver?style=for-the-badge)
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.