Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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

---

<!-- Template: DevTrail | https://strangedays.tech -->
Original file line number Diff line number Diff line change
@@ -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

---

<!-- Template: DevTrail | https://strangedays.tech -->
Original file line number Diff line number Diff line change
@@ -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

---

<!-- Template: DevTrail | https://strangedays.tech -->
Original file line number Diff line number Diff line change
@@ -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

---

<!-- Template: DevTrail | https://strangedays.tech -->
Original file line number Diff line number Diff line change
@@ -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

---

<!-- Template: DevTrail | https://strangedays.tech -->
Original file line number Diff line number Diff line change
@@ -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

---

<!-- Template: DevTrail | https://strangedays.tech -->
Loading