Skip to content

[Status] Aspire CLI acquisition coherence — install/update/self-update across all 5 routes #29

@radical

Description

@radical

Aspire CLI Acquisition Coherence — Status Tracker

Master status issue. Mirrors / pairs with microsoft/aspire#15949 but lives on this fork because most of the work is research, decisions, and runbooks rather than mainline code.

Why

Aspire CLI now ships through 5 acquisition routes:

  1. get-aspire-cli.{sh,ps1} (release / staging / dev) → ~/.aspire/bin
  2. get-aspire-cli-pr.{sh,ps1} (PR dogfood, hive-isolated) → ~/.aspire/bin + ~/.aspire/hives/pr-N/
  3. winget (Microsoft.Aspire, stable; Microsoft.Aspire.Prerelease infrastructure exists but disabled)
  4. Homebrew (aspire cask, stable only)
  5. dotnet-tool (Aspire.Cli, native-AOT post-Embed distribution channel in CLI binary instead of relying on aspire.config.json microsoft/aspire#15947)

These routes share ~/.aspire/ for config, hives, caches, bundles, sdks. They have independent update mechanisms but mutate shared state. aspire update --self is route-aware only for dotnet-tool — for all other routes it silently clobbers the on-disk binary, often corrupting the package manager's view of what's installed.

The 36-scenario Windows playbook (gist bae142…) confirmed cross-contamination is a real, reproducible bug today — the most severe being W34/W35 where a winget binary silently inherits a removed PR install's channel + hive.

Goal

Every cell in the user-scenarios matrix green or knowingly deferred, validated by a mix of unit tests, E2E tests, and manual runbooks. No silent clobber. No cross-contamination. Clean uninstall. Predictable update flow per route.

Approach — three tracks

  • Track A — Research. Document current behavior, state-sharing, and pipeline shape. Mostly done.
  • Track B — Implementation. Make the CLI install-route aware (InstallRoute enum + detector), fix --self per route, ship aspire uninstall, scope channel + bundle correctly.
  • Track C — Validation. Automated tests + manual runbooks for every cell of the user-scenarios matrix.

Track A — Research deliverables (✅ done)

Stored under docs/specs/cli-acquisition/ on this fork (or in the linked session files until promoted). Headlines:

  • behavior-matrix.md — 5 routes × 7 actions; 7 gaps cited. Top: --self redirect only fires for dotnet-tool path-shape; winget/brew silently overwrite.
  • aspire-home-map.md — 23 paths in ~/.aspire/ classified for cross-route safety. Critical hazard: bundle/<version>/ is keyed on process path, not install identity — two installs at the same version race the same dir.
  • pkgmgr-pipelines.md — winget has prerelease infra (disabled); Homebrew doesn't. winget cask uses UpgradeBehavior: uninstallPrevious.
  • reparse-flip-risk.md — Windows bundle/ flip is not atomic (RemoveIfExists+Move); Unix uses atomic rename(2). 6 risks total incl. legacy managed/ migration hard-failure if dir is in use.

Track B — Implementation tracker

# Task Status Issue
B0 InstallRoute enum + detector design ready #33
B1 Install-route sentinel writers per route depends on B0 #38
B2 aspire update --self per-route dispatch depends on B0/B1 #39
B3 Channel write scope (no longer global) depends on Q3 decision #40
B4 aspire uninstall --self + --state-only depends on B0 + Q5 #41
B5 Bundle <install-id> scoping + Windows atomic flip depends on Q2 #42

Track B work is intended to land upstream in microsoft/aspire as PRs against microsoft#15949.

Track C — Validation tracker

See user-scenarios.md. 9 categories, ~40 scenarios. Per-category test issues filed with track-c-validation label:

# Task Issue
C1 Install-route detection test fixture #43
C2 Channel-contention test #44
C3 Bundle-flip-while-running test #45
C-rb-winget Manual runbook: winget #46
C-rb-brew Manual runbook: brew #47
C-rb-sxs Manual runbook: Windows SxS #48

Decisions (Q1–Q7)

Q Topic Recommendation Issue
Q1 Should pkg mgrs publish prereleases? winget yes (infra exists), Homebrew no #30
Q2 Bundle directory scoping for SxS bundle/<install-id>/<ver>/, kill shared symlink #31
Q3 Channel state — global vs per-route needs team input (lean: hybrid) #34
Q4 Hive sharing model needs team input (lean: stay shared) #35
Q5 aspire uninstall command surface route-aware refusal + --state-only #32
Q6 Running-CLI vs --self guarantees needs team input (lean: best-effort) #36
Q7 --self --channel X from pkg-mgr install needs team input (lean: refuse + --break-install escape hatch) #37

Each "recommend" decision has a draft writeup; team sign-off required before implementation lands.

User-scenarios

The acceptance matrix lives in user-scenarios.md. Categories:

Every Track-B implementation issue lists which S-IDs it advances. Every Track-C issue maps to specific S-IDs.

Linked upstream issues

How to read this issue

  1. Scroll to Track A — Research deliverables: read those 4 markdowns first.
  2. Read user-scenarios.md — that's the goal-state.
  3. Pick a Track B or Track C issue from the labelled list and start.

Status updates

I'll update the checkbox tracker below and post comments at milestone boundaries.

Track A — Research

  • Behavior matrix
  • ~/.aspire/ map
  • Package manager pipelines audit
  • Reparse-flip risk audit

Track B — Implementation (gated on decisions)

Track C — Validation

Metadata

Metadata

Assignees

No one assigned

    Labels

    acquisitionAspire CLI acquisition coherence workstatus-issueMaster tracker / status issue

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions