7.2 KiB
Source And Provider Expansion Design
Goal
Expand install-source coverage beyond the current GitHub-centric path without collapsing providers, exact artifact sources, and update metadata into one abstraction.
Problem Statement
The current codebase has a real mismatch between what the domain and adapter layers suggest is possible and what the end-to-end install pipeline actually treats as first-class:
- the domain source model already includes GitHub, GitLab, direct URL, and file
- the adapter layer also advertises SourceForge and zsync shapes
- the public source pipeline and most end-to-end behavior are still effectively GitHub-shaped
That creates two problems:
- adding new install origins risks becoming a copy of the GitHub path with provider-specific exceptions bolted on later
zsyncis at risk of being modeled as a provider even though the current code treats it primarily as update metadata
Design Goals
- make
GitLaba real repository-backed install source - make
SourceForgea real repository-backed install source - preserve
direct-urlas a first-class exact-resolution source - keep install origin semantics truthful in the registry
- allow provider-native update re-resolution where it fits naturally
- keep
zsyncas update metadata rather than forcing it into the install-source model
Non-Goals
- generic search UX across all providers
- full behavioral parity across every provider in the first slice
- rewriting the CLI presentation layer
- promoting
zsyncinto a first-class install source - inventing a universal provider abstraction that erases real capability differences
Architectural Decision
Separate three concerns explicitly:
source kind: how the user identified the install originresolution strategy: how the system turns that origin into a concrete installable artifactupdate channel: how an installed application later discovers newer payloads
Under this model:
GitHub,GitLab, andSourceForgeare repository-backed source kindsdirect-urlis an exact artifact source kindfileremains a local artifact source kindzsyncremains an update-channel and metadata mechanism
This keeps install and update semantics aligned without pretending every source type has provider-like behavior.
Source Taxonomy
The input classification layer should classify user queries into a small, stable taxonomy:
- repository-backed sources
- GitHub
- GitLab
- SourceForge
- exact artifact sources
- direct URL
- local artifact sources
- file
Classification should answer only:
- what kind of source the user provided
- what canonical locator can be derived
- whether release or asset hints are present
- whether the origin is inherently trackable
Classification should not try to encode provider-specific release discovery beyond those normalized hints.
Resolution Model
After classification, a resolver layer should convert a SourceRef into an installable release candidate.
Repository-backed sources
Repository-backed resolution should:
- accept a canonical repository or project locator
- discover release or download candidates using provider-specific logic
- select a concrete AppImage payload when confidence is sufficient
- return explicit structured failures when the repository exists but no installable AppImage is available
This applies to:
- GitHub
- GitLab
- SourceForge
Exact artifact sources
Exact-resolution sources should:
- treat the user-provided locator as the concrete payload origin
- derive best-effort metadata without pretending release discovery exists
- remain installable even when rich update tracking is unavailable
This applies to:
- direct URL
- file
Registry Semantics
Registry persistence should preserve the truth about where the install came from.
Each installed record should continue to store:
- original source kind
- original source locator
- canonical locator when one exists
- installed version
- installed file metadata
The key rule is:
- install origin remains the origin the user chose
- update mechanisms are additive metadata, not a replacement source identity
That means a direct URL install remains a direct URL install even if metadata later yields a richer update channel. A GitLab install remains a GitLab install even if update planning later uses provider-specific release rediscovery.
Update Strategy
Update planning should use the install origin as the primary re-entry point.
For repository-backed sources:
- prefer provider-native re-resolution using the canonical locator
- attach update channels discovered during metadata inspection as additional evidence
For exact-resolution sources:
- keep update support weak by default unless post-install metadata offers something stronger
For zsync:
- keep it as discovered metadata and update-channel input
- do not rewrite the install source as
zsync - do not require
zsyncinstall-source tests in this phase
This preserves a clean distinction between install origin and update mechanism.
Error Handling
The design should distinguish unsupported semantics from runtime failure.
Unsupported source semantics
Examples:
- malformed provider URL shapes
- a project URL form we do not support yet
- a provider source kind sent to the wrong resolver
These should fail early during classification or resolver selection with provider-aware messages.
Resolvable source, but no installable artifact
Examples:
- repository exists but has no AppImage asset
- release metadata is present but incomplete
- multiple assets exist but none match install heuristics confidently
These should be structured resolution failures rather than generic unsupported errors.
Transport or integration failure
Examples:
- HTTP download failures
- metadata fetch failures
- local staging or desktop integration failures
These remain operational failures in the existing install and update flow.
Testing Strategy
Testing should expand along capability lines rather than provider-specific copy-paste.
Classification tests
Add coverage for:
- GitLab source forms
- SourceForge source forms
- direct URL edge cases
- unsupported or malformed provider inputs
Resolver contract tests
Each resolver should satisfy a shared contract:
- accepts valid source refs for its own kind
- rejects source refs for other kinds
- returns a concrete install candidate or a structured no-artifact result
End-to-end flow tests
Add focused flow coverage for:
- install from GitLab source
- install from direct URL
- install from SourceForge source
- truthful registry origin persistence
- update planning that uses install origin plus additive metadata
Non-goal tests
Do not force zsync into install-source tests for this phase.
Rollout
Recommended rollout order:
- normalize the source taxonomy and resolver interfaces
- wire GitLab and direct URL cleanly through install and registry persistence
- add SourceForge using the same resolver contract, limited to supported URL and project forms
- extend update planning only where the source kind supports provider-native re-resolution naturally
- leave
zsyncunchanged except to ensure it remains additive update metadata
This keeps the product honest: each added source gets explicit semantics instead of being forced through a renamed GitHub pathway.