adnv 1.5.1

CLI that tracks, checks and auto-updates infrastructure dependency versions across Terraform, Helm, Docker, Git and npm
Documentation
# Roadmap

This roadmap is organized by priority, informed by the security audit and code quality review.

## Phase 1: Security Hardening (Critical)

### Fix tar slip vulnerability
The archive extraction in `ops/run/codegen/source/archive.rs` does not validate entry paths, allowing path traversal attacks from malicious archives. Each tar entry must be validated to resolve within the destination directory.

### Validate action paths
The `output`, `copy`, and `local` actions accept user-provided paths without validation. Reject absolute paths and `..` traversals. The `output` action's `remove_dir_all` on user-provided paths is particularly dangerous.

### Restrict environment variable expansion
Template variables prefixed with `$` expand all environment variables, including secrets. Implement an allowlist or require explicit opt-in for env var access.

### Support secrets from environment variables
Notification backend credentials (Mattermost API key, Matrix password, SMTP password) are currently stored in plaintext YAML. Add support for `$ENV_VAR` expansion in credential fields.

## Phase 2: Dependency Modernization

### Replace deprecated crates

| Crate | Replacement | Reason |
|-------|-------------|--------|
| `tempdir` | `tempfile::TempDir` | Deprecated, security concerns |
| `serde_yaml` | `serde_yml` | Unmaintained |
| `once_cell` | `std::sync::OnceLock` | In std since Rust 1.80 |
| `void` | `std::convert::Infallible` | In std |

### Remove unused dependencies
- `async-recursion`: No `#[async_recursion]` usage found
- `void`: No usage found in source files

### Enforce HTTPS
Add `.https_only(true)` to all `reqwest::Client` instances (currently only Docker Hub enforces this).

## Phase 3: Code Quality

### Unify outdated and update modules
`ops/outdated/mod.rs` and `ops/update/mod.rs` share identical `run()` functions and `Options` structs. Extract a shared pipeline with an optional apply step.

### Unify display modules
`outdated/display.rs` and `update/display.rs` have near-identical table rendering logic. Extract a shared table builder.

### Extract shared constants
`DEFAULT_MESSAGE_TEMPLATE` is duplicated across three notification backends. Move to `output/mod.rs`.

### Extract filter logic
The `since` check + `FilterWhileAction` pattern is copy-pasted across 4+ list implementations. Create a method on `ListOptions`.

### Wrap blocking I/O in spawn_blocking
`dircpy::CopyBuilder::run()` and `git2::RepoBuilder::clone()` block the Tokio runtime. Wrap in `tokio::task::spawn_blocking()`.

### Fix Docker Hub double-fetch
`sources/list/docker/docker_io.rs` fetches the first page but discards results before re-fetching in the loop.

## Phase 4: Robustness

### Replace panicking code
Multiple `.expect()` and `.unwrap()` calls on external API data should return proper errors:
- `sources/list/docker/gitlab.rs:38,41`
- `ops/check/output/mail.rs:104`
- `commands/assist.rs:22`
- `ops/check/process.rs:22`

### Limit concurrent requests
`futures::future::join_all` creates unbounded parallelism. Use `buffer_unordered(N)` to limit concurrency and avoid rate limiting.

### Add test coverage
Priority areas with zero tests:
- Notification output modules (mattermost, element, mail)
- Codegen actions and sources (entire `ops/run/codegen/`)
- File editing utilities (`util/edit.rs`)
- Date utilities (`util/date.rs`)

### Remove dead code
- `commands/debug.rs`: Empty command
- `commands/assist.rs`: Deprecated, duplicates `run`
- `sources/fetch/mod.rs`: Contains only `todo!()`

## Phase 5: Feature Suggestions

### Dry-run mode for update
`adnv update --dry-run` to preview changes without modifying files. Show a diff of what would change.

### JSON/YAML output format
`adnv outdated --format json` for programmatic consumption in CI pipelines.

### Version pinning / ignore rules
Allow ignoring specific dependencies or pinning to current versions:
```yaml
# .adnv-ignore
gitlab.com/org/legacy-module  # skip this module
hashicorp/aws < 6.0.0         # don't suggest 6.x
```

### Slack notification backend
Add Slack webhook or Bot API support alongside existing Mattermost/Matrix/Email.

### OpenTofu support
Explicit support for OpenTofu registry and version formats, as the ecosystem diverges from Terraform.

### Multi-config file support
Support splitting config across multiple files or using includes:
```yaml
version: 1
include:
  - check-sources.yml
  - workflows/*.yml
```

### Webhook output backend
Generic webhook output for integration with arbitrary systems:
```yaml
outputs:
  webhook: !Webhook
    url: https://hooks.example.com/adnv
    method: POST
    headers:
      Authorization: "Bearer $TOKEN"
```

### Lockfile generation
Generate a lockfile recording resolved versions, enabling reproducible builds and detecting drift:
```
adnv lock          # generate adnv.lock
adnv check-lock    # verify current state matches lock
```

### Diff output for update
Show a unified diff of changes after `adnv update`, similar to `terraform plan`:
```
~ module "vpc" {
-   version = "1.0.0"
+   version = "1.2.0"
  }
```

### SBOM generation
Generate Software Bill of Materials from scanned dependencies for compliance and supply chain security.