- ABI stabilization and documentation
- C++ bindings (header-only,
bindings/cpp/) - Python bindings
- Correctness tests: installation unit tests, fuzzing (package JSON, dep constraints)
- pkg-config and CMake find module
- Drop the gpgme (OpenPGP) signing backend entirely; libsodium (Ed25519) becomes the only one
Additive only: existing dep_graph_resolve() / dep_graph_resolve_parallel()
keep their current behavior and ABI. This ships as a new, separate resolve
entry point; it does not touch .apg, struct package, or
struct package_metadata.
-
dep_graphtoday maps one name to exactly one node (node_map,alias_map); it cannot represent multiple candidate versions/providers for the same name. Needs a parallel candidate-set representation usable by the solver without disturbing the existing single-candidate graph used by the current resolvers. - Constraint model: turn each package's
dependencies(name + version op) andconflictsinto SAT clauses over candidate selection variables. - Provider/alias handling: a
provides/replacesalias can be satisfied by any of several candidates — needs "at least one of" clauses instead of today's single deterministic pick. Falls out of the unifiedcandidate_setmodel (aprovidesname and a real package name share the same lookup) — no separate handling needed, verified with a multi-provider dependency clause.replacesis not covered yet. - Solver core: pick and implement an actual SAT (or CDCL-lite/PubGrub-style
incremental) algorithm; decide on backtracking strategy and a search
budget/timeout for pathological inputs. Shipped as a plain DPLL solver
(unit propagation + backtracking, first-unassigned-variable decision
order, decision-count budget) in
src/graph/sat_solve.c. No clause learning (not CDCL) — a reasonable first cut, not the final version. Note:sat_model_build()alone doesn't force any package to be installed — the caller must add a unit clause for each root package it actually wants, same as the[app forced]case used to verify this. - Conflict reporting: on UNSAT, produce a human-readable explanation (which constraints clashed), not just an error code.
- New public API surface (new header declarations, new exported
symbols) — additive,
APG_API, no changes to existing signatures. - Threading: decide whether/how this interacts with the existing
pthread-parallel resolve path, or whether the solver stays single-threaded initially. - Tests: unit tests for satisfiable/unsatisfiable cases, fuzzing over randomly generated constraint sets, and a perf benchmark against the current resolver on typical (non-pathological) dependency sets.
- Atomic installation: all-or-nothing semantics