@@ -8,10 +8,15 @@ updates across official repositories and the Arch User Repository.
88
99- ** synsyu_core** – Rust binary that enumerates installed packages and emits a
1010 structured JSON manifest at ` ~/.config/syn-syu/manifest.json ` (configurable)
11- describing the current state: what is installed and which source it came from.
11+ describing the current state: what is installed, which source it came from,
12+ direct AUR RPC source classification, and bounded network state such as
13+ ranked pacman mirror candidates.
1214- ** syn-syu** – Bash CLI that parses the manifest, builds update plans, selects
13- helpers, and executes updates per user intent. Logging follows the Synavera
14- Script Etiquette and is kept under ` ~/.local/share/syn-syu/ ` by default.
15+ helpers, applies source-aware bounded acquisition policy, and executes updates
16+ per user intent. Pacman repos, AUR RPC, and AUR helper acquisition use
17+ different recovery strategies because their transports and failure modes are
18+ different. Logging follows the Synavera Script Etiquette and is kept under
19+ ` ~/.local/share/syn-syu/ ` by default.
1520- ** syn-syu plan** – Builds an update plan from fresh sources (pacman, AUR,
1621 Flatpak, fwupd when enabled), writes it to ` ~/.config/syn-syu/plan.json ` , and
1722 prints a concise summary (with optional strict/JSON modes).
@@ -42,6 +47,28 @@ the Syn-Syu config directory (not under `/tmp`).
4247 "install_date" : " 2024-11-01T12:00:00Z" ,
4348 "validated_by" : " Signature"
4449 }
50+ },
51+ "network" : {
52+ "mirrors" : {
53+ "enabled" : true ,
54+ "status" : " ready" ,
55+ "source" : " mirrorlist" ,
56+ "source_path" : " /etc/pacman.d/mirrorlist" ,
57+ "max_failovers" : 2 ,
58+ "candidate_count" : 6 ,
59+ "usable_count" : 3 ,
60+ "candidates" : [
61+ {
62+ "rank" : 1 ,
63+ "server" : " https://mirror.example/archlinux/$repo/os/$arch" ,
64+ "status" : " ready" ,
65+ "outcome" : " ready" ,
66+ "freshness" : " fresh" ,
67+ "usable" : true ,
68+ "latency_ms" : 94
69+ }
70+ ]
71+ }
4572 }
4673}
4774```
@@ -53,6 +80,25 @@ When Flatpak or firmware updates are requested, the manifest also includes an
5380` applications ` block capturing the chosen sources (` flatpak ` / ` fwupd ` ), whether
5481they were enabled during manifest generation, and any discovered updates.
5582
83+ When mirror probing is enabled, ` synsyu_core ` also records ` network.mirrors ` .
84+ The Bash layer treats that state as advisory input for repo acquisition only.
85+ It does not rewrite ` /etc/pacman.d/mirrorlist ` ; for each attempt it creates a
86+ temporary pacman config that points the existing mirrorlist include at a
87+ one-line temporary mirrorlist. Pacman still performs repository, package,
88+ signature, dependency, and transaction validation.
89+
90+ Operationally: when repo downloads fail because a mirror is unreachable, slow,
91+ or stale, Syn-Syu can try a bounded number of alternate mirrors. It does not
92+ retry integrity or trust failures. It does not modify your system mirrorlist
93+ permanently.
94+
95+ For AUR operations, Syn-Syu does not pretend that every failure is a mirror
96+ problem. Direct AUR RPC calls in ` synsyu_core ` use bounded retry with the
97+ configured fixed delay for transient HTTP or network failures. AUR helper
98+ execution in Bash may retry clearly transient helper fetch/clone/download
99+ failures. PKGBUILD, checksum, signature, dependency, conflict, and build
100+ failures stop immediately.
101+
56102## CLI Sketch
57103
58104| Command | Purpose |
@@ -73,6 +119,8 @@ they were enabled during manifest generation, and any discovered updates.
73119| ` syn-syu export ` | Export repo/AUR package lists for replication. |
74120| ` syn-syu helpers ` | List detected AUR helpers. |
75121| ` syn-syu helper <name> ` | Set helper for this session (persist with helpers.sh). |
122+ | ` syn-syu mirrors ` | Show ranked pacman mirror candidates recorded in the manifest. |
123+ | ` syn-syu acquisition ` | Show source-aware bounded acquisition policies by channel. |
76124| ` syn-syu config ` | Show config path info. |
77125| ` syn-syu groups-edit ` | Open groups file in ` $EDITOR ` . |
78126| ` syn-syu log ` | Show log directory/retention info. |
@@ -82,7 +130,8 @@ Use `syn-syu --help` for the full flag list.
82130
83131### Power-user Flags
84132
85- - ` --json ` – machine-readable output for ` check ` and ` inspect ` .
133+ - ` --json ` – machine-readable output where supported, including ` check ` ,
134+ ` inspect ` , ` mirrors ` , and ` acquisition ` .
86135- ` --quiet ` /` -q ` – suppress non-essential output; logs still written.
87136- ` --confirm ` /` --noconfirm ` – toggle interactive confirmations passed to helpers
88137 and pacman (default is non-interactive).
@@ -91,6 +140,8 @@ Use `syn-syu --help` for the full flag list.
91140 ` sync ` (both flags repeatable; evaluated as Bash regex).
92141- ` --batch <N> ` – repo package batch size; defaults to ` core.batch_size ` from
93142 config or ` 10 ` .
143+ - ` --mirrors ` / ` --no-mirrors ` – enable or disable repo mirror failover for the
144+ current run without changing config.
94145- ` --with-flatpak ` / ` --with-fwupd ` – opt into Flatpak and firmware updates
95146 during manifest generation and ` sync ` (also available as standalone commands).
96147- ` plan ` flags: ` --json ` , ` --strict ` , ` --offline ` , ` --no-aur ` , ` --no-repo ` ,
@@ -108,6 +159,31 @@ Use `syn-syu --help` for the full flag list.
108159- ** pacnew detection** – after successful updates, Syn-Syu scans for
109160 ` .pacnew/.pacsave ` files (using ` pacdiff ` when available) and surfaces them in
110161 logs/console so you can merge configuration changes promptly.
162+ - ** Source-aware acquisition policy** – Syn-Syu treats each source/channel
163+ separately. Pacman repo downloads use mirror failover. AUR RPC uses bounded
164+ HTTP/network retry in Rust. AUR helper execution uses bounded retry only for
165+ transient helper acquisition failures. PKGBUILD upstream source fallback,
166+ Flatpak retry policy, and fwupd retry policy are explicit future/tool-owned
167+ channels, not hidden pacman-style behavior.
168+ - ** Mirror-aware repo acquisition** – when enabled, ` synsyu_core ` reads active
169+ pacman ` Server = ` entries from the configured mirrorlist or from explicit
170+ ` [mirrors].servers ` , probes a small bounded set, ranks usable mirrors by
171+ freshness first and response latency second, and marks mirrors stale when
172+ ` lastsync ` is older than ` max_sync_age_hours ` . Mirrors with unknown freshness
173+ remain usable but sort after known-fresh mirrors. The Bash layer retries repo
174+ batches against at most ` max_failovers + 1 ` usable mirrors and stops when the
175+ budget is exhausted. It only retries retrieval-style failures such as failed
176+ downloads, DNS errors, timeouts, and connection resets. Signature, integrity,
177+ keyring, dependency, lock, disk, and conflict errors are not mirror-retryable
178+ and remain final. Status output includes a compact outcome code such as
179+ ` ready ` , ` stale ` , ` timeout ` , ` connect_failed ` , or ` http_error ` so a failed
180+ candidate can be diagnosed without reading the full probe message first.
181+ - ** AUR bounded acquisition** – direct AUR RPC calls retry transient HTTP
182+ failures such as 429, timeout, and 5xx responses within the configured retry
183+ budget. AUR helper execution retries only clear transport/fetch failures such
184+ as DNS failure, timeout, TLS/connect failure, or transient Git transport
185+ errors. PKGBUILD, checksum, signature, dependency, conflict, and build
186+ failures are terminal and are not retried by Syn-Syu.
111187- ** Application updates** – opt into Flatpak and firmware (fwupd) updates via
112188 config (` [applications] ` ) or on-demand commands ` syn-syu flatpak ` /
113189 ` syn-syu fwupd ` , or include them in both the manifest and ` sync ` with
@@ -143,6 +219,31 @@ max_kib_per_sec = 0
143219flatpak = false
144220fwupd = false
145221
222+ [mirrors ]
223+ enabled = true
224+ mirrorlist_path = " /etc/pacman.d/mirrorlist"
225+ pacman_conf_path = " /etc/pacman.conf"
226+ probe = true
227+ probe_timeout_seconds = 3
228+ max_candidates = 6
229+ max_failovers = 2
230+ retry_delay_seconds = 2
231+ max_sync_age_hours = 48
232+ cache_ttl_hours = 168
233+ # cache_path = "~/.cache/syn-syu/mirror-probes.json"
234+ # Optional explicit candidates; when non-empty these replace mirrorlist discovery.
235+ # servers = ["https://mirror.example/archlinux/$repo/os/$arch"]
236+
237+ [acquisition .aur_rpc ]
238+ enabled = true
239+ max_retries = 2
240+ retry_delay_seconds = 2
241+
242+ [acquisition .aur_helper ]
243+ enabled = true
244+ max_retries = 1
245+ retry_delay_seconds = 3
246+
146247[snapshots ]
147248enabled = false
148249pre_command = " sudo snapper create --description 'Syn-Syu pre-update'"
@@ -169,6 +270,47 @@ operations; CLI flags `--with-flatpak` and `--with-fwupd` override the defaults.
169270Flatpak metadata is appended by the Bash layer after ` synsyu_core ` runs; the
170271core binary itself only supports ` --with-fwupd ` .
171272
273+ The ` [mirrors] ` section controls repo mirror failover. ` enabled = true ` records
274+ mirror state in the manifest and allows the Bash layer to cycle official repo
275+ package acquisition through usable candidates. ` max_candidates ` limits how many
276+ servers are considered from the source list. ` probe_timeout_seconds ` limits
277+ each HTTP probe. ` max_sync_age_hours ` controls freshness: stale mirrors are
278+ excluded, known-fresh mirrors rank ahead of freshness-unknown mirrors, and
279+ latency is used within those groups. ` max_failovers ` means additional mirrors
280+ after the first attempt, so the maximum attempts for a repo batch are
281+ ` max_failovers + 1 ` , further capped by the number of usable candidates.
282+ ` retry_delay_seconds ` inserts a short pause between retryable failures.
283+ ` cache_ttl_hours ` keeps last-known probe outcomes for a bounded time so the next
284+ manifest rebuild can choose better first candidates before it probes again. The
285+ cache is only an ordering hint; fresh probe results still replace cached results,
286+ and retry bounds do not change.
287+
288+ This feature is aimed at standard Arch-style repository layouts where official
289+ repos share the configured mirrorlist include and mirror URLs contain ` $repo `
290+ and ` $arch ` . Syn-Syu replaces matching ` Include = mirrorlist_path ` lines only in
291+ a temporary pacman config for the current attempt. Custom repositories that use
292+ the same include path should be reviewed before enabling mirror failover. This
293+ feature does not guarantee successful downloads whenever internet access exists;
294+ it only gives Syn-Syu a bounded way to move past clearly unreliable mirrors
295+ without hiding serious pacman errors.
296+
297+ The ` [acquisition.aur_rpc] ` section controls direct AUR RPC retry used by the
298+ Rust backend for source classification and state gathering. ` max_retries ` means
299+ additional tries after the first request, and ` retry_delay_seconds ` is a fixed
300+ pause between retryable failures. ` [acquisition.aur_rpc].max_retries ` has
301+ precedence when set; legacy ` [aur].max_retries ` is used only when the new
302+ acquisition key is absent. ` synsyu_core config ` and ` syn-syu acquisition ` show
303+ the effective value. Retryable conditions are transient HTTP/network failures,
304+ not malformed package metadata or local policy failures.
305+
306+ The ` [acquisition.aur_helper] ` section controls Bash-layer retry around helper
307+ execution for AUR packages. It is deliberately conservative: Syn-Syu retries
308+ helper transport/fetch failures, but stops immediately for PKGBUILD,
309+ dependency, checksum, signature, conflict, and build failures. PKGBUILD
310+ upstream source fallback is a separate future problem because safe handling
311+ depends on makepkg/helper semantics and upstream source arrays, not pacman
312+ mirrors.
313+
172314The ` [space] ` section defines ` min_free_gb ` , a buffer that must remain free on
173315disk before updates proceed, and ` mode ` , which controls behaviour when the
174316buffer is not met. ` mode = "warn" ` (default) emits a warning; ` mode = "enforce" `
0 commit comments