334 lines
No EOL
13 KiB
Markdown
334 lines
No EOL
13 KiB
Markdown
# Source And Provider Expansion Implementation Plan
|
|
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
|
|
**Goal:** Make GitLab and SourceForge real repository-backed install sources, preserve direct URL as a first-class exact-resolution source, and keep zsync as update metadata rather than an install provider.
|
|
|
|
**Architecture:** Normalize the source taxonomy first, then add a capability-shaped resolver layer that distinguishes repository-backed sources from exact artifact sources. Preserve truthful install origin data in the registry and let update planning attach richer metadata without rewriting source identity.
|
|
|
|
**Tech Stack:** Rust, Cargo workspace, `aim-core` source and adapter modules, existing fixture-backed integration tests in `crates/aim-core/tests`, CLI end-to-end tests in `crates/aim-cli/tests`, existing registry and update planning code.
|
|
|
|
## Follow-up Status
|
|
|
|
Task 1 hit a classification ambiguity blocker after the initial rollout. The follow-up design and execution live in `.plans/007-source-provider-expansion/2026-03-20-task-1-ambiguity-handoff-addendum.md`.
|
|
|
|
Current state on this branch:
|
|
|
|
- ambiguous GitLab deep paths and one SourceForge nested download path are now preserved as provider-owned candidate kinds during classification
|
|
- the first GitLab candidate slice now resolves as a concrete repository-backed install source at the adapter layer
|
|
- the SourceForge `files/releases/stable/download` candidate slice now resolves as a concrete latest-download install source at the adapter layer
|
|
- the SourceForge `files/releases/v*/download` slice is now preserved as a provider-owned candidate and reports `NoInstallableArtifact`
|
|
- unsupported queries remain distinct from provider-owned no-artifact outcomes
|
|
|
|
Classifier policy for follow-up work:
|
|
|
|
- accept explicit concrete shapes
|
|
- accept explicit provider-candidate shapes
|
|
- reject everything else
|
|
|
|
Future changes should expand the allowlist deliberately rather than adding broad negative-rule coverage for every unsupported provider page family.
|
|
|
|
---
|
|
|
|
### Task 1: Lock down source taxonomy with failing classification tests
|
|
|
|
**Files:**
|
|
- Modify: `crates/aim-core/tests/query_resolution.rs`
|
|
- Modify: `crates/aim-core/src/source/input.rs`
|
|
- Modify: `crates/aim-core/src/domain/source.rs`
|
|
|
|
**Step 1: Write the failing tests**
|
|
|
|
Add classification tests that cover:
|
|
- GitLab repository and release-like URL forms that should classify as `GitLab`
|
|
- supported SourceForge URL forms that should classify as `SourceForge`
|
|
- direct URLs that must remain `DirectUrl`
|
|
- malformed provider URLs that must fail as unsupported
|
|
|
|
**Step 2: Run test to verify it fails**
|
|
|
|
Run: `cargo test --package aim-core --test query_resolution`
|
|
Expected: FAIL because SourceForge is not yet part of the public source taxonomy and current classification rules are too narrow.
|
|
|
|
**Step 3: Write minimal classification changes**
|
|
|
|
Update the source domain and classifier so the public source taxonomy includes the approved source kinds and supported input forms without introducing zsync as an install source.
|
|
|
|
**Step 4: Run test to verify it passes**
|
|
|
|
Run: `cargo test --package aim-core --test query_resolution`
|
|
Expected: PASS.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git add crates/aim-core/tests/query_resolution.rs crates/aim-core/src/source/input.rs crates/aim-core/src/domain/source.rs
|
|
git commit -m "test: cover expanded source taxonomy"
|
|
```
|
|
|
|
### Task 2: Add a shared resolver contract for source capabilities
|
|
|
|
**Files:**
|
|
- Modify: `crates/aim-core/src/adapters/traits.rs`
|
|
- Modify: `crates/aim-core/src/adapters/mod.rs`
|
|
- Modify: `crates/aim-core/tests/adapter_contract.rs`
|
|
- Modify: `crates/aim-core/src/app/query.rs`
|
|
|
|
**Step 1: Write the failing tests**
|
|
|
|
Add contract tests that assert:
|
|
- repository-backed resolvers accept only their own source kinds
|
|
- exact-resolution resolvers accept only exact artifact kinds
|
|
- resolvers can return structured “no installable artifact” outcomes rather than collapsing to unsupported
|
|
|
|
**Step 2: Run test to verify it fails**
|
|
|
|
Run: `cargo test --package aim-core --test adapter_contract`
|
|
Expected: FAIL because the current adapter trait does not distinguish source capability outcomes cleanly enough.
|
|
|
|
**Step 3: Write minimal resolver contract changes**
|
|
|
|
Refine the shared adapter or resolver contract to represent:
|
|
- unsupported source kind
|
|
- supported source with successful artifact resolution
|
|
- supported source with no installable artifact found
|
|
|
|
Keep the API small and do not add terminal concerns.
|
|
|
|
**Step 4: Run test to verify it passes**
|
|
|
|
Run: `cargo test --package aim-core --test adapter_contract`
|
|
Expected: PASS.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git add crates/aim-core/src/adapters/traits.rs crates/aim-core/src/adapters/mod.rs crates/aim-core/tests/adapter_contract.rs crates/aim-core/src/app/query.rs
|
|
git commit -m "feat: add capability-shaped resolver contract"
|
|
```
|
|
|
|
### Task 3: Make GitLab a real repository-backed install source
|
|
|
|
**Files:**
|
|
- Modify: `crates/aim-core/src/adapters/gitlab.rs`
|
|
- Modify: `crates/aim-core/src/app/add.rs`
|
|
- Modify: `crates/aim-core/tests/adapter_contract.rs`
|
|
- Modify: `crates/aim-core/tests/install_integration.rs`
|
|
- Modify: `crates/aim-cli/tests/end_to_end_cli.rs`
|
|
|
|
**Step 1: Write the failing tests**
|
|
|
|
Add tests that assert:
|
|
- a GitLab source resolves to a concrete install candidate
|
|
- install flow persists a truthful GitLab install origin
|
|
- CLI integration can install a fixture-backed GitLab source end to end
|
|
|
|
**Step 2: Run test to verify it fails**
|
|
|
|
Run: `cargo test --package aim-core --test install_integration`
|
|
Expected: FAIL because GitLab resolution is currently placeholder-level and not wired into the add flow meaningfully.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Implement GitLab-specific repository-backed resolution using the new resolver contract and thread the result through the add flow without changing direct URL or zsync semantics.
|
|
|
|
**Step 4: Run test to verify it passes**
|
|
|
|
Run: `cargo test --package aim-core --test install_integration`
|
|
Expected: PASS.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git add crates/aim-core/src/adapters/gitlab.rs crates/aim-core/src/app/add.rs crates/aim-core/tests/adapter_contract.rs crates/aim-core/tests/install_integration.rs crates/aim-cli/tests/end_to_end_cli.rs
|
|
git commit -m "feat: add gitlab install source resolution"
|
|
```
|
|
|
|
### Task 4: Preserve direct URL as an exact-resolution source
|
|
|
|
**Files:**
|
|
- Modify: `crates/aim-core/src/adapters/direct_url.rs`
|
|
- Modify: `crates/aim-core/src/app/add.rs`
|
|
- Modify: `crates/aim-core/tests/install_integration.rs`
|
|
- Modify: `crates/aim-cli/tests/end_to_end_cli.rs`
|
|
|
|
**Step 1: Write the failing tests**
|
|
|
|
Add tests that assert:
|
|
- direct URL installs continue to resolve exactly to the provided artifact
|
|
- registry persistence keeps the original direct URL source kind and locator
|
|
- no provider-like reclassification occurs after install
|
|
|
|
**Step 2: Run test to verify it fails**
|
|
|
|
Run: `cargo test --package aim-core --test install_integration`
|
|
Expected: FAIL if the new resolver contract or registry changes accidentally regress exact-resolution behavior.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Adjust the direct URL path to use the new resolver interfaces while preserving exact-resolution semantics and best-effort metadata only.
|
|
|
|
**Step 4: Run test to verify it passes**
|
|
|
|
Run: `cargo test --package aim-core --test install_integration`
|
|
Expected: PASS.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git add crates/aim-core/src/adapters/direct_url.rs crates/aim-core/src/app/add.rs crates/aim-core/tests/install_integration.rs crates/aim-cli/tests/end_to_end_cli.rs
|
|
git commit -m "feat: preserve direct url exact resolution semantics"
|
|
```
|
|
|
|
### Task 5: Add SourceForge as a repository-backed source for supported project forms
|
|
|
|
**Files:**
|
|
- Modify: `crates/aim-core/src/adapters/sourceforge.rs`
|
|
- Modify: `crates/aim-core/src/source/input.rs`
|
|
- Modify: `crates/aim-core/src/app/add.rs`
|
|
- Modify: `crates/aim-core/tests/adapter_contract.rs`
|
|
- Modify: `crates/aim-core/tests/install_integration.rs`
|
|
- Modify: `crates/aim-cli/tests/end_to_end_cli.rs`
|
|
|
|
**Step 1: Write the failing tests**
|
|
|
|
Add tests that assert:
|
|
- supported SourceForge URL or project forms classify correctly
|
|
- SourceForge resolution can produce a concrete install candidate
|
|
- SourceForge installs persist truthful origin data
|
|
|
|
**Step 2: Run test to verify it fails**
|
|
|
|
Run: `cargo test --package aim-core --test adapter_contract`
|
|
Expected: FAIL because SourceForge currently returns unsupported from its adapter.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Implement only the supported SourceForge project or download forms needed for exact current-product scope. Return structured no-artifact failures for valid-but-non-installable projects.
|
|
|
|
**Step 4: Run test to verify it passes**
|
|
|
|
Run: `cargo test --package aim-core --test adapter_contract`
|
|
Expected: PASS.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git add crates/aim-core/src/adapters/sourceforge.rs crates/aim-core/src/source/input.rs crates/aim-core/src/app/add.rs crates/aim-core/tests/adapter_contract.rs crates/aim-core/tests/install_integration.rs crates/aim-cli/tests/end_to_end_cli.rs
|
|
git commit -m "feat: add sourceforge install source resolution"
|
|
```
|
|
|
|
### Task 6: Keep registry origin truthful and update metadata additive
|
|
|
|
**Files:**
|
|
- Modify: `crates/aim-core/src/registry/model.rs`
|
|
- Modify: `crates/aim-core/src/app/add.rs`
|
|
- Modify: `crates/aim-core/src/app/update.rs`
|
|
- Modify: `crates/aim-core/src/update/channels.rs`
|
|
- Modify: `crates/aim-core/tests/update_planning.rs`
|
|
- Modify: `crates/aim-core/tests/registry_roundtrip.rs`
|
|
|
|
**Step 1: Write the failing tests**
|
|
|
|
Add tests that assert:
|
|
- GitLab and SourceForge installs preserve original source kind and locator after roundtrip persistence
|
|
- direct URL installs remain direct URL installs after metadata inspection
|
|
- discovered update channels augment stored state without rewriting source identity
|
|
- zsync remains update metadata only
|
|
|
|
**Step 2: Run test to verify it fails**
|
|
|
|
Run: `cargo test --package aim-core --test update_planning`
|
|
Expected: FAIL because update planning and registry expectations do not yet fully encode the approved source-versus-update split.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Adjust registry and update planning logic so install origin remains canonical and update channels remain additive metadata.
|
|
|
|
**Step 4: Run test to verify it passes**
|
|
|
|
Run: `cargo test --package aim-core --test update_planning`
|
|
Expected: PASS.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git add crates/aim-core/src/registry/model.rs crates/aim-core/src/app/add.rs crates/aim-core/src/app/update.rs crates/aim-core/src/update/channels.rs crates/aim-core/tests/update_planning.rs crates/aim-core/tests/registry_roundtrip.rs
|
|
git commit -m "feat: preserve source identity through update planning"
|
|
```
|
|
|
|
### Task 7: Improve provider-aware error reporting without changing CLI shape
|
|
|
|
**Files:**
|
|
- Modify: `crates/aim-core/src/adapters/traits.rs`
|
|
- Modify: `crates/aim-core/src/app/add.rs`
|
|
- Modify: `crates/aim-cli/src/lib.rs`
|
|
- Modify: `crates/aim-core/tests/install_failures.rs`
|
|
- Modify: `crates/aim-cli/tests/end_to_end_cli.rs`
|
|
|
|
**Step 1: Write the failing tests**
|
|
|
|
Add tests that distinguish:
|
|
- unsupported source semantics
|
|
- supported source with no installable artifact
|
|
- transport or integration failure
|
|
|
|
**Step 2: Run test to verify it fails**
|
|
|
|
Run: `cargo test --package aim-core --test install_failures`
|
|
Expected: FAIL because failure reasons are not yet structured enough to preserve those distinctions.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Introduce explicit failure categories and thread them through the add flow so the CLI can render clearer provider-aware messages without changing the progress UI architecture.
|
|
|
|
**Step 4: Run test to verify it passes**
|
|
|
|
Run: `cargo test --package aim-core --test install_failures`
|
|
Expected: PASS.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git add crates/aim-core/src/adapters/traits.rs crates/aim-core/src/app/add.rs crates/aim-cli/src/lib.rs crates/aim-core/tests/install_failures.rs crates/aim-cli/tests/end_to_end_cli.rs
|
|
git commit -m "feat: clarify provider-aware source resolution failures"
|
|
```
|
|
|
|
### Task 8: Full verification
|
|
|
|
**Files:**
|
|
- Modify: `README.md`
|
|
- Modify: `crates/aim-core/tests/github_source_discovery.rs`
|
|
- Modify: `crates/aim-core/tests/query_resolution.rs`
|
|
- Modify: `crates/aim-core/tests/install_integration.rs`
|
|
- Modify: `crates/aim-core/tests/update_planning.rs`
|
|
- Modify: `crates/aim-cli/tests/end_to_end_cli.rs`
|
|
|
|
**Step 1: Tighten any stale expectations**
|
|
|
|
Update docs and tests so the product contract matches the approved design:
|
|
- GitLab and SourceForge are install sources
|
|
- direct URL remains exact-resolution
|
|
- zsync remains update metadata
|
|
|
|
**Step 2: Run focused workspace verification**
|
|
|
|
Run: `cargo test --package aim-core --test query_resolution --test adapter_contract --test install_integration --test update_planning --test install_failures`
|
|
Expected: PASS.
|
|
|
|
**Step 3: Run CLI verification**
|
|
|
|
Run: `cargo test --package aim-cli --test end_to_end_cli`
|
|
Expected: PASS.
|
|
|
|
**Step 4: Run full workspace verification**
|
|
|
|
Run: `cargo fmt --all && cargo test --workspace`
|
|
Expected: PASS.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git add README.md crates/aim-core/tests/github_source_discovery.rs crates/aim-core/tests/query_resolution.rs crates/aim-core/tests/install_integration.rs crates/aim-core/tests/update_planning.rs crates/aim-core/tests/install_failures.rs crates/aim-cli/tests/end_to_end_cli.rs
|
|
git commit -m "docs: align source provider contract and tests"
|
|
``` |