Skip to content

Commit 25d4b83

Browse files
montfortclaude
andauthored
docs: add DevTrail documentation for release infrastructure session (#12)
Add 4 AILOGs (CI/metadata, cargo-dist, update subcommand, binary name fix), 1 AIDEC (CLI restructure and self_update crate selection), and 1 SBOM (self_update dependency and transitive dependencies). Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3d900fb commit 25d4b83

6 files changed

Lines changed: 374 additions & 0 deletions
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
id: SBOM-2026-04-03-001
3+
title: Addition of self_update dependency and transitive dependencies
4+
status: accepted
5+
created: 2026-04-03
6+
agent: claude-code-v1.0
7+
confidence: high
8+
review_required: false
9+
risk_level: low
10+
eu_ai_act_risk: not_applicable
11+
nist_genai_risks: [information_security]
12+
iso_42001_clause: [8]
13+
tags: [dependencies, sbom, self-update, security]
14+
related: [AILOG-2026-04-03-004]
15+
---
16+
17+
# SBOM: Addition of self_update dependency
18+
19+
## Summary
20+
21+
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.
22+
23+
## Direct Dependency Added
24+
25+
| Crate | Version | License | Purpose |
26+
|-------|---------|---------|---------|
27+
| `self_update` | 0.43.1 | MIT | Self-update from GitHub Releases |
28+
29+
### Features Enabled
30+
31+
- `archive-tar` — extract tar archives (Linux/macOS releases)
32+
- `archive-zip` — extract zip archives (Windows releases)
33+
- `compression-flate2` — decompress gzip/deflate
34+
35+
## Key Transitive Dependencies
36+
37+
| Crate | Version | Purpose | Risk Notes |
38+
|-------|---------|---------|------------|
39+
| `reqwest` | 0.12.28 | HTTP client for GitHub API | Well-maintained, widely used |
40+
| `native-tls` | 0.2.18 | TLS via OS library | Uses OpenSSL on Linux, Secure Transport on macOS, SChannel on Windows |
41+
| `tokio` | 1.51.0 | Async runtime (reqwest dependency) | Adds binary size but not used directly |
42+
| `self-replace` | 1.5.0 | Binary self-replacement | Core update mechanism |
43+
| `tar` | 0.4.45 | Tar archive extraction ||
44+
| `zip` | 6.0.0 | Zip archive extraction ||
45+
| `indicatif` | 0.18.4 | Progress bar display ||
46+
| `semver` | 1.0.28 | Version comparison ||
47+
48+
## Impact Assessment
49+
50+
- **Binary size**: Increases from ~5MB to ~8MB (debug), ~3MB to ~5MB (release with LTO) due to TLS and HTTP stack
51+
- **Compile time**: Increases by ~30s (first build) due to openssl-sys and reqwest
52+
- **Attack surface**: reqwest + native-tls are well-audited, widely-used crates. The update mechanism only contacts `api.github.com` over HTTPS.
53+
- **Supply chain**: All dependencies are from crates.io. No git dependencies.
54+
55+
## Mitigation
56+
57+
- TLS is handled by the OS native library (not rustls), reducing the cryptographic code compiled into the binary
58+
- Updates only download from the project's own GitHub Releases URL
59+
- Binary replacement uses `self-replace` which handles atomic replacement safely
60+
61+
---
62+
63+
<!-- Template: DevTrail | https://strangedays.tech -->
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
id: AILOG-2026-04-03-002
3+
title: Add CI workflow and crates.io publishing metadata
4+
status: accepted
5+
created: 2026-04-03
6+
agent: claude-code-v1.0
7+
confidence: high
8+
review_required: false
9+
risk_level: low
10+
eu_ai_act_risk: not_applicable
11+
nist_genai_risks: []
12+
iso_42001_clause: [8]
13+
lines_changed: 87
14+
files_modified: [Cargo.toml, .github/workflows/ci.yml, tests/cli/directory.rs, tests/cli/filtering.rs, tests/cli/output_formats.rs]
15+
observability_scope: none
16+
tags: [ci, github-actions, crates-io, publishing, infrastructure]
17+
related: [AILOG-2026-04-02-002]
18+
---
19+
20+
# AILOG: Add CI workflow and crates.io publishing metadata
21+
22+
## Summary
23+
24+
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.
25+
26+
## Context
27+
28+
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.
29+
30+
## Actions Performed
31+
32+
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
33+
2. Created `.github/workflows/ci.yml` with 3-OS matrix, cargo caching, and fmt/clippy/test steps
34+
3. Fixed pre-existing rustfmt issues in 3 test files
35+
4. Validated with `cargo publish --dry-run`
36+
37+
## Modified Files
38+
39+
| File | Lines Changed (+/-) | Change Description |
40+
|------|--------------------|--------------------|
41+
| `Cargo.toml` | +6/-0 | Added crates.io metadata fields |
42+
| `.github/workflows/ci.yml` | +46/-0 | New cross-platform CI workflow |
43+
| `tests/cli/directory.rs` | +17/-4 | rustfmt fixes |
44+
| `tests/cli/filtering.rs` | +13/-7 | rustfmt fixes |
45+
| `tests/cli/output_formats.rs` | +4/-1 | rustfmt fixes |
46+
47+
## Impact
48+
49+
- **Functionality**: N/A (infrastructure only)
50+
- **Performance**: N/A
51+
- **Security**: N/A
52+
- **Privacy**: N/A
53+
54+
## Verification
55+
56+
- [x] `cargo publish --dry-run` passes
57+
- [x] All 29 tests pass locally
58+
- [ ] CI workflow runs green on GitHub
59+
60+
---
61+
62+
<!-- Template: DevTrail | https://strangedays.tech -->
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
id: AILOG-2026-04-03-003
3+
title: Add cargo-dist release infrastructure
4+
status: accepted
5+
created: 2026-04-03
6+
agent: claude-code-v1.0
7+
confidence: high
8+
review_required: false
9+
risk_level: low
10+
eu_ai_act_risk: not_applicable
11+
nist_genai_risks: []
12+
iso_42001_clause: [8]
13+
lines_changed: 383
14+
files_modified: [Cargo.toml, dist-workspace.toml, .github/workflows/release.yml, RELEASING.md]
15+
observability_scope: none
16+
tags: [release, cargo-dist, github-actions, cross-platform, binaries, infrastructure]
17+
related: [AILOG-2026-04-03-002, AIDEC-2026-04-03-001]
18+
---
19+
20+
# AILOG: Add cargo-dist release infrastructure
21+
22+
## Summary
23+
24+
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.
25+
26+
## Context
27+
28+
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.
29+
30+
## Actions Performed
31+
32+
1. Ran `dist init --yes --ci=github --installer=shell --installer=powershell`
33+
2. Generated `dist-workspace.toml` with 5 target triples and installer config
34+
3. Generated `.github/workflows/release.yml` — multi-stage pipeline: plan → build-local → build-global → host → announce
35+
4. Added `[profile.dist]` to Cargo.toml (inherits release, LTO thin)
36+
5. Created `RELEASING.md` with step-by-step release procedure
37+
38+
## Modified Files
39+
40+
| File | Lines Changed (+/-) | Change Description |
41+
|------|--------------------|--------------------|
42+
| `Cargo.toml` | +5/-0 | Added `[profile.dist]` with LTO |
43+
| `dist-workspace.toml` | +17/-0 | cargo-dist configuration (targets, installers, CI) |
44+
| `.github/workflows/release.yml` | +296/-0 | Tag-triggered release workflow |
45+
| `RELEASING.md` | +65/-0 | Release procedure documentation |
46+
47+
## Decisions Made
48+
49+
- Selected cargo-dist over manual CI workflows for its opinionated, maintained approach and automatic installer generation.
50+
- Used `install-path = "CARGO_HOME"` so binaries install alongside cargo-managed tools.
51+
- Set `install-updater = false` because we implement self-update in-app (see AILOG-2026-04-03-004).
52+
53+
## Impact
54+
55+
- **Functionality**: Enables binary distribution for non-Rust users
56+
- **Performance**: Release binaries use LTO for smaller, faster output
57+
- **Security**: N/A
58+
- **Privacy**: N/A
59+
60+
## Verification
61+
62+
- [x] `dist plan` generates valid manifest
63+
- [x] All tests pass
64+
- [x] v0.1.0 and v0.1.1 releases built successfully via this workflow
65+
66+
---
67+
68+
<!-- Template: DevTrail | https://strangedays.tech -->
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
id: AILOG-2026-04-03-004
3+
title: Add arborist update subcommand for self-updating
4+
status: accepted
5+
created: 2026-04-03
6+
agent: claude-code-v1.0
7+
confidence: high
8+
review_required: false
9+
risk_level: low
10+
eu_ai_act_risk: not_applicable
11+
nist_genai_risks: []
12+
iso_42001_clause: [7, 8]
13+
lines_changed: 225
14+
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]
15+
observability_scope: none
16+
tags: [self-update, cli, subcommand, github-releases, feature]
17+
related: [AILOG-2026-04-03-003, AIDEC-2026-04-03-001]
18+
---
19+
20+
# AILOG: Add arborist update subcommand for self-updating
21+
22+
## Summary
23+
24+
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.
25+
26+
## Context
27+
28+
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.
29+
30+
## Actions Performed
31+
32+
1. Restructured `src/cli.rs`: `CliArgs``Cli` (Parser) + `Command` (Subcommand) + `AnalyzeArgs` (Args)
33+
2. Created `src/update.rs` (105 lines): GitHub Releases self-update with install method detection
34+
3. Updated `src/main.rs`: dispatch on `cli.command` variant
35+
4. Renamed all `CliArgs` references to `AnalyzeArgs` across `lib.rs`, `analysis.rs`, `output/mod.rs`, `output/table.rs`
36+
5. Added `self_update` dependency to `Cargo.toml`
37+
38+
## Modified Files
39+
40+
| File | Lines Changed (+/-) | Change Description |
41+
|------|--------------------|--------------------|
42+
| `src/update.rs` | +105/-0 | New self-update module |
43+
| `src/cli.rs` | +21/-2 | CLI restructure with optional subcommands |
44+
| `src/main.rs` | +11/-8 | Command dispatch logic |
45+
| `src/lib.rs` | +3/-2 | CliArgs → AnalyzeArgs, add update module |
46+
| `src/analysis.rs` | +4/-4 | CliArgs → AnalyzeArgs |
47+
| `src/output/mod.rs` | +2/-2 | CliArgs → AnalyzeArgs |
48+
| `src/output/table.rs` | +3/-3 | CliArgs → AnalyzeArgs |
49+
| `Cargo.toml` | +1/-0 | Added self_update dependency |
50+
51+
## Decisions Made
52+
53+
- Install method detection via heuristic: if binary path contains `.cargo/bin`, suggest `cargo install` instead of self-replace
54+
- `--check` flag for non-destructive version checking
55+
- `no_confirm(true)` for non-interactive update (suitable for CI/automation)
56+
57+
## Impact
58+
59+
- **Functionality**: Users can self-update with a single command
60+
- **Performance**: `self_update` adds ~2MB to binary size due to reqwest/TLS
61+
- **Security**: Updates are downloaded over HTTPS from GitHub Releases
62+
- **Privacy**: N/A (only contacts GitHub API for release info)
63+
64+
## Verification
65+
66+
- [x] `cargo test` — 29 tests pass (backward compatible)
67+
- [x] `arborist update --check` runs correctly (404 expected before first release)
68+
- [x] `arborist tests/fixtures/complex.rs` works as before
69+
70+
---
71+
72+
<!-- Template: DevTrail | https://strangedays.tech -->
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
id: AILOG-2026-04-03-005
3+
title: Fix binary name from arborist-cli to arborist
4+
status: accepted
5+
created: 2026-04-03
6+
agent: claude-code-v1.0
7+
confidence: high
8+
review_required: false
9+
risk_level: low
10+
eu_ai_act_risk: not_applicable
11+
nist_genai_risks: []
12+
iso_42001_clause: [8]
13+
lines_changed: 26
14+
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]
15+
observability_scope: none
16+
tags: [bugfix, binary-name, packaging, release]
17+
related: [AILOG-2026-04-03-004]
18+
---
19+
20+
# AILOG: Fix binary name from arborist-cli to arborist
21+
22+
## Summary
23+
24+
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.
25+
26+
## Context
27+
28+
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.
29+
30+
## Actions Performed
31+
32+
1. Added `[[bin]] name = "arborist" path = "src/main.rs"` to Cargo.toml
33+
2. Updated `src/update.rs`: `bin_name("arborist-cli")``bin_name("arborist")`
34+
3. Updated 7 test files: `cargo_bin("arborist-cli")``cargo_bin("arborist")`
35+
4. Bumped version to 0.1.1
36+
37+
## Impact
38+
39+
- **Functionality**: Binary now installs as `arborist` across all installation methods
40+
- **Performance**: N/A
41+
- **Security**: N/A
42+
43+
## Verification
44+
45+
- [x] `arborist --version` prints `arborist 0.1.1`
46+
- [x] All 29 tests pass
47+
- [x] Published to crates.io and GitHub Releases as v0.1.1
48+
49+
---
50+
51+
<!-- Template: DevTrail | https://strangedays.tech -->
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
id: AIDEC-2026-04-03-001
3+
title: CLI restructure to subcommands and self-update crate selection
4+
status: accepted
5+
created: 2026-04-03
6+
agent: claude-code-v1.0
7+
confidence: high
8+
review_required: false
9+
risk_level: low
10+
eu_ai_act_risk: not_applicable
11+
nist_genai_risks: []
12+
iso_42001_clause: [7]
13+
tags: [architecture, cli, self-update, decision]
14+
related: [AILOG-2026-04-03-004]
15+
---
16+
17+
# AIDEC: CLI restructure to subcommands and self-update crate selection
18+
19+
## Decision
20+
21+
Restructure the CLI from flat `CliArgs` to optional subcommands (`Cli` + `Command` + `AnalyzeArgs`) and use `self_update` crate for self-updating from GitHub Releases.
22+
23+
## Context
24+
25+
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).
26+
27+
## Alternatives Considered
28+
29+
### CLI Structure
30+
31+
| Alternative | Pros | Cons |
32+
|-------------|------|------|
33+
| **Optional subcommands (chosen)** | Full backward compatibility, `arborist src/` still works, clean separation of concerns | Potential ambiguity if a file is literally named "update" |
34+
| Mandatory subcommands (`arborist analyze src/`) | Cleaner architecture, no ambiguity | Breaking change, all existing usage and docs would need updating |
35+
| Flag-based (`arborist --update`) | No subcommand parsing issues | Conflates update with analysis flags, unclear UX |
36+
37+
### Self-Update Crate
38+
39+
| Alternative | Pros | Cons |
40+
|-------------|------|------|
41+
| **self_update (chosen)** | Works regardless of install method, queries GitHub API directly, mature (0.43.x) | Pulls in reqwest/TLS, adds ~2MB to binary |
42+
| axoupdater | Tight cargo-dist integration, lighter | Only works with cargo-dist install receipts, fails for cargo-install users |
43+
| Custom implementation | No extra deps | Significant effort for HTTP, archive extraction, binary replacement |
44+
45+
## Rationale
46+
47+
- **Optional subcommands**: Backward compatibility was non-negotiable. The positional args ambiguity is minimal (a file named "update" can be addressed as `./update`).
48+
- **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.
49+
50+
## Consequences
51+
52+
- The `CliArgs` type was renamed to `AnalyzeArgs` across 6 files — a one-time refactor
53+
- `self_update` adds reqwest as a transitive dependency, increasing compile time and binary size
54+
- Future subcommands (e.g., `arborist init`, `arborist config`) can be added trivially to the `Command` enum
55+
56+
---
57+
58+
<!-- Template: DevTrail | https://strangedays.tech -->

0 commit comments

Comments
 (0)