diff --git a/.devtrail/07-ai-audit/SBOM-2026-04-03-001-self-update-dependency.md b/.devtrail/07-ai-audit/SBOM-2026-04-03-001-self-update-dependency.md new file mode 100644 index 0000000..fd08b10 --- /dev/null +++ b/.devtrail/07-ai-audit/SBOM-2026-04-03-001-self-update-dependency.md @@ -0,0 +1,63 @@ +--- +id: SBOM-2026-04-03-001 +title: Addition of self_update dependency and transitive dependencies +status: accepted +created: 2026-04-03 +agent: claude-code-v1.0 +confidence: high +review_required: false +risk_level: low +eu_ai_act_risk: not_applicable +nist_genai_risks: [information_security] +iso_42001_clause: [8] +tags: [dependencies, sbom, self-update, security] +related: [AILOG-2026-04-03-004] +--- + +# SBOM: Addition of self_update dependency + +## Summary + +Added `self_update v0.43.1` as a direct dependency for the `arborist update` subcommand. This introduces a significant number of transitive dependencies (~197 new packages in Cargo.lock), primarily from the reqwest HTTP client and TLS stack. + +## Direct Dependency Added + +| Crate | Version | License | Purpose | +|-------|---------|---------|---------| +| `self_update` | 0.43.1 | MIT | Self-update from GitHub Releases | + +### Features Enabled + +- `archive-tar` — extract tar archives (Linux/macOS releases) +- `archive-zip` — extract zip archives (Windows releases) +- `compression-flate2` — decompress gzip/deflate + +## Key Transitive Dependencies + +| Crate | Version | Purpose | Risk Notes | +|-------|---------|---------|------------| +| `reqwest` | 0.12.28 | HTTP client for GitHub API | Well-maintained, widely used | +| `native-tls` | 0.2.18 | TLS via OS library | Uses OpenSSL on Linux, Secure Transport on macOS, SChannel on Windows | +| `tokio` | 1.51.0 | Async runtime (reqwest dependency) | Adds binary size but not used directly | +| `self-replace` | 1.5.0 | Binary self-replacement | Core update mechanism | +| `tar` | 0.4.45 | Tar archive extraction | — | +| `zip` | 6.0.0 | Zip archive extraction | — | +| `indicatif` | 0.18.4 | Progress bar display | — | +| `semver` | 1.0.28 | Version comparison | — | + +## Impact Assessment + +- **Binary size**: Increases from ~5MB to ~8MB (debug), ~3MB to ~5MB (release with LTO) due to TLS and HTTP stack +- **Compile time**: Increases by ~30s (first build) due to openssl-sys and reqwest +- **Attack surface**: reqwest + native-tls are well-audited, widely-used crates. The update mechanism only contacts `api.github.com` over HTTPS. +- **Supply chain**: All dependencies are from crates.io. No git dependencies. + +## Mitigation + +- TLS is handled by the OS native library (not rustls), reducing the cryptographic code compiled into the binary +- Updates only download from the project's own GitHub Releases URL +- Binary replacement uses `self-replace` which handles atomic replacement safely + +--- + + diff --git a/.devtrail/07-ai-audit/agent-logs/AILOG-2026-04-03-002-ci-workflow-and-crates-metadata.md b/.devtrail/07-ai-audit/agent-logs/AILOG-2026-04-03-002-ci-workflow-and-crates-metadata.md new file mode 100644 index 0000000..839f009 --- /dev/null +++ b/.devtrail/07-ai-audit/agent-logs/AILOG-2026-04-03-002-ci-workflow-and-crates-metadata.md @@ -0,0 +1,62 @@ +--- +id: AILOG-2026-04-03-002 +title: Add CI workflow and crates.io publishing metadata +status: accepted +created: 2026-04-03 +agent: claude-code-v1.0 +confidence: high +review_required: false +risk_level: low +eu_ai_act_risk: not_applicable +nist_genai_risks: [] +iso_42001_clause: [8] +lines_changed: 87 +files_modified: [Cargo.toml, .github/workflows/ci.yml, tests/cli/directory.rs, tests/cli/filtering.rs, tests/cli/output_formats.rs] +observability_scope: none +tags: [ci, github-actions, crates-io, publishing, infrastructure] +related: [AILOG-2026-04-02-002] +--- + +# AILOG: Add CI workflow and crates.io publishing metadata + +## Summary + +Added cross-platform CI workflow (GitHub Actions) running on ubuntu, macos, and windows with `cargo fmt --check`, `cargo clippy -- -D warnings`, and `cargo test`. Added all required metadata fields to Cargo.toml for crates.io publishing: repository, homepage, readme, keywords, categories, and exclude patterns. + +## Context + +The project had no automated CI and was missing crates.io metadata, blocking both quality assurance and public distribution. This was the first step in a 4-phase plan to enable full release infrastructure. + +## Actions Performed + +1. Added crates.io metadata to `Cargo.toml`: repository, homepage, readme, keywords (`complexity`, `metrics`, `cognitive`, `cyclomatic`, `cli`), categories (`command-line-utilities`, `development-tools`), and exclude patterns for non-essential directories +2. Created `.github/workflows/ci.yml` with 3-OS matrix, cargo caching, and fmt/clippy/test steps +3. Fixed pre-existing rustfmt issues in 3 test files +4. Validated with `cargo publish --dry-run` + +## Modified Files + +| File | Lines Changed (+/-) | Change Description | +|------|--------------------|--------------------| +| `Cargo.toml` | +6/-0 | Added crates.io metadata fields | +| `.github/workflows/ci.yml` | +46/-0 | New cross-platform CI workflow | +| `tests/cli/directory.rs` | +17/-4 | rustfmt fixes | +| `tests/cli/filtering.rs` | +13/-7 | rustfmt fixes | +| `tests/cli/output_formats.rs` | +4/-1 | rustfmt fixes | + +## Impact + +- **Functionality**: N/A (infrastructure only) +- **Performance**: N/A +- **Security**: N/A +- **Privacy**: N/A + +## Verification + +- [x] `cargo publish --dry-run` passes +- [x] All 29 tests pass locally +- [ ] CI workflow runs green on GitHub + +--- + + diff --git a/.devtrail/07-ai-audit/agent-logs/AILOG-2026-04-03-003-cargo-dist-release-infrastructure.md b/.devtrail/07-ai-audit/agent-logs/AILOG-2026-04-03-003-cargo-dist-release-infrastructure.md new file mode 100644 index 0000000..e926afc --- /dev/null +++ b/.devtrail/07-ai-audit/agent-logs/AILOG-2026-04-03-003-cargo-dist-release-infrastructure.md @@ -0,0 +1,68 @@ +--- +id: AILOG-2026-04-03-003 +title: Add cargo-dist release infrastructure +status: accepted +created: 2026-04-03 +agent: claude-code-v1.0 +confidence: high +review_required: false +risk_level: low +eu_ai_act_risk: not_applicable +nist_genai_risks: [] +iso_42001_clause: [8] +lines_changed: 383 +files_modified: [Cargo.toml, dist-workspace.toml, .github/workflows/release.yml, RELEASING.md] +observability_scope: none +tags: [release, cargo-dist, github-actions, cross-platform, binaries, infrastructure] +related: [AILOG-2026-04-03-002, AIDEC-2026-04-03-001] +--- + +# AILOG: Add cargo-dist release infrastructure + +## Summary + +Configured cargo-dist v0.31.0 for automated cross-platform binary builds. Tag-triggered GitHub Actions workflow builds release binaries for 5 targets (Linux x86_64/aarch64, macOS Intel/Apple Silicon, Windows x86_64) with shell and PowerShell installers. Added `RELEASING.md` documenting the release procedure. + +## Context + +Users needed pre-compiled binaries to install without a Rust toolchain. cargo-dist was chosen as the standard Rust ecosystem tool for this purpose, generating optimized builds with LTO and platform-specific installers. + +## Actions Performed + +1. Ran `dist init --yes --ci=github --installer=shell --installer=powershell` +2. Generated `dist-workspace.toml` with 5 target triples and installer config +3. Generated `.github/workflows/release.yml` — multi-stage pipeline: plan → build-local → build-global → host → announce +4. Added `[profile.dist]` to Cargo.toml (inherits release, LTO thin) +5. Created `RELEASING.md` with step-by-step release procedure + +## Modified Files + +| File | Lines Changed (+/-) | Change Description | +|------|--------------------|--------------------| +| `Cargo.toml` | +5/-0 | Added `[profile.dist]` with LTO | +| `dist-workspace.toml` | +17/-0 | cargo-dist configuration (targets, installers, CI) | +| `.github/workflows/release.yml` | +296/-0 | Tag-triggered release workflow | +| `RELEASING.md` | +65/-0 | Release procedure documentation | + +## Decisions Made + +- Selected cargo-dist over manual CI workflows for its opinionated, maintained approach and automatic installer generation. +- Used `install-path = "CARGO_HOME"` so binaries install alongside cargo-managed tools. +- Set `install-updater = false` because we implement self-update in-app (see AILOG-2026-04-03-004). + +## Impact + +- **Functionality**: Enables binary distribution for non-Rust users +- **Performance**: Release binaries use LTO for smaller, faster output +- **Security**: N/A +- **Privacy**: N/A + +## Verification + +- [x] `dist plan` generates valid manifest +- [x] All tests pass +- [x] v0.1.0 and v0.1.1 releases built successfully via this workflow + +--- + + diff --git a/.devtrail/07-ai-audit/agent-logs/AILOG-2026-04-03-004-update-subcommand.md b/.devtrail/07-ai-audit/agent-logs/AILOG-2026-04-03-004-update-subcommand.md new file mode 100644 index 0000000..30920cd --- /dev/null +++ b/.devtrail/07-ai-audit/agent-logs/AILOG-2026-04-03-004-update-subcommand.md @@ -0,0 +1,72 @@ +--- +id: AILOG-2026-04-03-004 +title: Add arborist update subcommand for self-updating +status: accepted +created: 2026-04-03 +agent: claude-code-v1.0 +confidence: high +review_required: false +risk_level: low +eu_ai_act_risk: not_applicable +nist_genai_risks: [] +iso_42001_clause: [7, 8] +lines_changed: 225 +files_modified: [Cargo.toml, src/cli.rs, src/main.rs, src/lib.rs, src/analysis.rs, src/update.rs, src/output/mod.rs, src/output/table.rs] +observability_scope: none +tags: [self-update, cli, subcommand, github-releases, feature] +related: [AILOG-2026-04-03-003, AIDEC-2026-04-03-001] +--- + +# AILOG: Add arborist update subcommand for self-updating + +## Summary + +Added `arborist update` subcommand that self-updates the binary from GitHub Releases using the `self_update` crate, and `arborist update --check` to check for new versions without installing. Restructured the CLI from flat `CliArgs` to `Cli` + `Command` + `AnalyzeArgs` with optional subcommands while maintaining full backward compatibility. + +## Context + +Users who install via shell/PowerShell installers or direct binary download needed a way to update without manual steps. The `self_update` crate was chosen over `axoupdater` for its flexibility across install methods (see AIDEC-2026-04-03-001). The CLI restructure was necessary to support subcommands alongside the existing flat argument interface. + +## Actions Performed + +1. Restructured `src/cli.rs`: `CliArgs` → `Cli` (Parser) + `Command` (Subcommand) + `AnalyzeArgs` (Args) +2. Created `src/update.rs` (105 lines): GitHub Releases self-update with install method detection +3. Updated `src/main.rs`: dispatch on `cli.command` variant +4. Renamed all `CliArgs` references to `AnalyzeArgs` across `lib.rs`, `analysis.rs`, `output/mod.rs`, `output/table.rs` +5. Added `self_update` dependency to `Cargo.toml` + +## Modified Files + +| File | Lines Changed (+/-) | Change Description | +|------|--------------------|--------------------| +| `src/update.rs` | +105/-0 | New self-update module | +| `src/cli.rs` | +21/-2 | CLI restructure with optional subcommands | +| `src/main.rs` | +11/-8 | Command dispatch logic | +| `src/lib.rs` | +3/-2 | CliArgs → AnalyzeArgs, add update module | +| `src/analysis.rs` | +4/-4 | CliArgs → AnalyzeArgs | +| `src/output/mod.rs` | +2/-2 | CliArgs → AnalyzeArgs | +| `src/output/table.rs` | +3/-3 | CliArgs → AnalyzeArgs | +| `Cargo.toml` | +1/-0 | Added self_update dependency | + +## Decisions Made + +- Install method detection via heuristic: if binary path contains `.cargo/bin`, suggest `cargo install` instead of self-replace +- `--check` flag for non-destructive version checking +- `no_confirm(true)` for non-interactive update (suitable for CI/automation) + +## Impact + +- **Functionality**: Users can self-update with a single command +- **Performance**: `self_update` adds ~2MB to binary size due to reqwest/TLS +- **Security**: Updates are downloaded over HTTPS from GitHub Releases +- **Privacy**: N/A (only contacts GitHub API for release info) + +## Verification + +- [x] `cargo test` — 29 tests pass (backward compatible) +- [x] `arborist update --check` runs correctly (404 expected before first release) +- [x] `arborist tests/fixtures/complex.rs` works as before + +--- + + diff --git a/.devtrail/07-ai-audit/agent-logs/AILOG-2026-04-03-005-fix-binary-name.md b/.devtrail/07-ai-audit/agent-logs/AILOG-2026-04-03-005-fix-binary-name.md new file mode 100644 index 0000000..08c7e73 --- /dev/null +++ b/.devtrail/07-ai-audit/agent-logs/AILOG-2026-04-03-005-fix-binary-name.md @@ -0,0 +1,51 @@ +--- +id: AILOG-2026-04-03-005 +title: Fix binary name from arborist-cli to arborist +status: accepted +created: 2026-04-03 +agent: claude-code-v1.0 +confidence: high +review_required: false +risk_level: low +eu_ai_act_risk: not_applicable +nist_genai_risks: [] +iso_42001_clause: [8] +lines_changed: 26 +files_modified: [Cargo.toml, src/update.rs, tests/cli/directory.rs, tests/cli/exit_codes.rs, tests/cli/filtering.rs, tests/cli/multi_input.rs, tests/cli/output_formats.rs, tests/cli/single_file.rs, tests/cli/stdin.rs] +observability_scope: none +tags: [bugfix, binary-name, packaging, release] +related: [AILOG-2026-04-03-004] +--- + +# AILOG: Fix binary name from arborist-cli to arborist + +## Summary + +Added `[[bin]] name = "arborist"` to Cargo.toml so the installed binary is `arborist` instead of `arborist-cli` (the package name default). Updated `self_update` bin_name and all test references to match. Released as v0.1.1. + +## Context + +After publishing v0.1.0, users installing via `cargo binstall arborist-cli` got a binary named `arborist-cli`, but the CLI was designed to be invoked as `arborist` (matching the clap `name` field). Without the `[[bin]]` section, Cargo defaults the binary name to the package name. + +## Actions Performed + +1. Added `[[bin]] name = "arborist" path = "src/main.rs"` to Cargo.toml +2. Updated `src/update.rs`: `bin_name("arborist-cli")` → `bin_name("arborist")` +3. Updated 7 test files: `cargo_bin("arborist-cli")` → `cargo_bin("arborist")` +4. Bumped version to 0.1.1 + +## Impact + +- **Functionality**: Binary now installs as `arborist` across all installation methods +- **Performance**: N/A +- **Security**: N/A + +## Verification + +- [x] `arborist --version` prints `arborist 0.1.1` +- [x] All 29 tests pass +- [x] Published to crates.io and GitHub Releases as v0.1.1 + +--- + + diff --git a/.devtrail/07-ai-audit/decisions/AIDEC-2026-04-03-001-cli-restructure-and-self-update-strategy.md b/.devtrail/07-ai-audit/decisions/AIDEC-2026-04-03-001-cli-restructure-and-self-update-strategy.md new file mode 100644 index 0000000..067cd9c --- /dev/null +++ b/.devtrail/07-ai-audit/decisions/AIDEC-2026-04-03-001-cli-restructure-and-self-update-strategy.md @@ -0,0 +1,58 @@ +--- +id: AIDEC-2026-04-03-001 +title: CLI restructure to subcommands and self-update crate selection +status: accepted +created: 2026-04-03 +agent: claude-code-v1.0 +confidence: high +review_required: false +risk_level: low +eu_ai_act_risk: not_applicable +nist_genai_risks: [] +iso_42001_clause: [7] +tags: [architecture, cli, self-update, decision] +related: [AILOG-2026-04-03-004] +--- + +# AIDEC: CLI restructure to subcommands and self-update crate selection + +## Decision + +Restructure the CLI from flat `CliArgs` to optional subcommands (`Cli` + `Command` + `AnalyzeArgs`) and use `self_update` crate for self-updating from GitHub Releases. + +## Context + +Adding an `arborist update` command required introducing subcommands to a CLI that previously used only flat positional arguments and flags. Additionally, two crates were available for self-updating: `axoupdater` (cargo-dist companion) and `self_update` (general-purpose). + +## Alternatives Considered + +### CLI Structure + +| Alternative | Pros | Cons | +|-------------|------|------| +| **Optional subcommands (chosen)** | Full backward compatibility, `arborist src/` still works, clean separation of concerns | Potential ambiguity if a file is literally named "update" | +| Mandatory subcommands (`arborist analyze src/`) | Cleaner architecture, no ambiguity | Breaking change, all existing usage and docs would need updating | +| Flag-based (`arborist --update`) | No subcommand parsing issues | Conflates update with analysis flags, unclear UX | + +### Self-Update Crate + +| Alternative | Pros | Cons | +|-------------|------|------| +| **self_update (chosen)** | Works regardless of install method, queries GitHub API directly, mature (0.43.x) | Pulls in reqwest/TLS, adds ~2MB to binary | +| axoupdater | Tight cargo-dist integration, lighter | Only works with cargo-dist install receipts, fails for cargo-install users | +| Custom implementation | No extra deps | Significant effort for HTTP, archive extraction, binary replacement | + +## Rationale + +- **Optional subcommands**: Backward compatibility was non-negotiable. The positional args ambiguity is minimal (a file named "update" can be addressed as `./update`). +- **self_update**: Users install via multiple channels (cargo install, cargo binstall, shell installer, direct download). `axoupdater` only works for the shell installer path, while `self_update` works for all GitHub Release downloads. The binary size increase is acceptable for a developer tool. + +## Consequences + +- The `CliArgs` type was renamed to `AnalyzeArgs` across 6 files — a one-time refactor +- `self_update` adds reqwest as a transitive dependency, increasing compile time and binary size +- Future subcommands (e.g., `arborist init`, `arborist config`) can be added trivially to the `Command` enum + +--- + +