## Context Current implementation in `pkg/pacman/pacman.go` spawns shell processes for pacman queries: 1. **`ValidatePackage`**: Calls `pacman -Qip` then `pacman -Sip` (2 processes per package) to check if package exists in sync databases 2. **`MarkExplicit`**: Calls `pacman -D --explicit ` individually per package (N processes for N packages) 3. **AUR**: Called individually per package not found in pacman databases Performance issues scale with package count. No caching of package queries across calls. ## Goals / Non-Goals **Goals:** - Use Jguer/dyalpm library to query pacman databases without spawning processes - Add in-memory cache for ALL package query results (pacman + AUR), valid for entire job duration - Batch `pacman -D --explicit` calls to single process for multiple packages - Batch AUR HTTP queries to single request for all packages not found in pacman **Non-Goals:** - Refactor AUR handling (already uses HTTP API - will batch it) - Add persistent cache (only job-duration in-memory) - Change other pacman operations (sync, cleanup) ## Decisions 1. **dyalpm over go-alpm**: dyalpm uses purego (no cgo), cleaner cross-compilation - Alternative: go-alpm (cgo-based) - rejected for compilation complexity 2. **Unified cache in Pac struct**: Single cache map replaces separate aurCache - Alternative: keep separate caches - rejected, unnecessary complexity - Cache key: package name, value: PackageInfo struct 3. **Batch MarkExplicit**: Accept `[]string` packages, pass all to single `pacman -D --explicit` call - Note: pacman -D accepts multiple packages in single call 4. **Batch query strategy**: - Query all packages against dyalpm local DB → returns found[] - Query not-found against dyalpm sync DBs → returns found[] - Query remaining not-found against AUR HTTP (single batched request) - Current: pacman -Qip → pacman -Sip → AUR (per-package) - New: Batch dyalpm local → Batch dyalpm sync → Batch AUR 5. **Fallback for dyalpm unavailable**: If dyalpm init fails, fall back to: - pacman -Qip for all packages (single process, capture all) - pacman -Sip for remaining (single process, capture all) - AUR HTTP batch for remaining (already batched) ## Risks / Trade-offs - **Risk**: dyalpm requires libalpm.so.15 on system - Mitigation: Check at runtime, fallback to process spawn if missing - **Risk**: Cache invalidation edge cases (e.g., package installed during job) - Mitigation: Acceptable for declpac use case; user runs sync after config changes - **Risk**: AUR API batch size limits - Mitigation: Chunk large batches if AUR has limits (TBD in implementation) ## Migration Plan 1. Add dyalpm dependency to go.mod 2. Refactor Pac struct: replace aurCache with unified pkgCache map 3. Change ValidatePackage to ValidatePackages (slice input, batch processing) 4. Update MarkExplicit to accept slice 5. Batch AUR HTTP calls in ensureAURCache 6. Update call sites in Sync(), categorizePackages, DryRun() 7. Test with existing test suite