Skip to content

Commit 27385bb

Browse files
committed
Introduced source-aware, bounded recovery strategies.
1 parent 9633404 commit 27385bb

18 files changed

Lines changed: 2338 additions & 72 deletions

.codex

Whitespace-only changes.

README.md

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ manifest of the current system state (installed packages with source), build
66
update plans from fresh sources, apply repo/AUR/app/firmware updates
77
selectively, and produce detailed logs for review.
88

9+
Syn-Syu is source-aware and tool-aware. Different channels may use different
10+
bounded recovery strategies; pacman mirror failover is not treated as a generic
11+
solution for AUR helpers, PKGBUILD sources, Flatpak, or fwupd.
12+
913
## Features
1014

1115
- Coordinates pacman and AUR helpers with explicit include/exclude filters.
@@ -17,6 +21,9 @@ selectively, and produce detailed logs for review.
1721
- Configurable logging level with time and size-based log retention policies.
1822
- Validates download, build, and install footprint before updates, applying a
1923
configurable free-space buffer.
24+
- Applies source-aware bounded acquisition policy: pacman repos use mirror
25+
failover, AUR RPC/helper paths use transient retry where safe, and other
26+
channels remain tool-owned unless explicitly implemented.
2027
- Optional application updates for Flatpak and firmware (fwupd) with dedicated
2128
commands or opt-in flags that now also seed the manifest and plan.
2229
- Supports guided or advanced install workflows through optional tooling.
@@ -62,9 +69,8 @@ and copy binaries and libraries into a prefix you choose. An accompanying
6269

6370
Syn-Syu looks for configuration at `~/.config/syn-syu/config.toml`. An example
6471
file is provided at `examples/config.toml`. You can view the merged
65-
configuration (defaults + file) via `synsyu config --show [--json]
66-
synsyu logs --prune # apply retention policy via synsyu_core`. Key
67-
options include:
72+
configuration with `synsyu_core config [--json]`; log retention pruning is
73+
available through `synsyu_core logs --prune`. Key options include:
6874

6975
- `core.manifest_path` – output path for the generated manifest.
7076
- `space.min_free_gb` – reserved buffer that must remain free after updates.
@@ -77,6 +83,23 @@ options include:
7783
- `helpers.priority` – ordered list of AUR helpers to try.
7884
- `aur.max_parallel_requests` / `aur.max_kib_per_sec` – control how many AUR
7985
RPC calls run concurrently and optionally throttle each request in KiB/s.
86+
- `mirrors.enabled` – enables mirror-aware repo acquisition failover.
87+
- `mirrors.mirrorlist_path` / `mirrors.pacman_conf_path` – inputs used to read
88+
mirror candidates and build temporary pacman configs without editing system
89+
files.
90+
- `mirrors.probe`, `mirrors.probe_timeout_seconds`, `mirrors.max_candidates`,
91+
and `mirrors.max_sync_age_hours` – bound mirror probing and stale-mirror
92+
filtering.
93+
- `mirrors.cache_ttl_hours` / `mirrors.cache_path` – keep last-known probe
94+
outcomes so the next rebuild can choose better first candidates before it
95+
probes again.
96+
- `mirrors.max_failovers` / `mirrors.retry_delay_seconds` – bound repo
97+
acquisition retries; attempts are limited to `max_failovers + 1`.
98+
- `acquisition.aur_rpc.*` – bounded transient retry for direct AUR RPC calls
99+
used by `synsyu_core`.
100+
- `acquisition.aur_helper.*` – bounded transient retry around AUR helper
101+
acquisition failures; build, dependency, signature, checksum, and PKGBUILD
102+
failures are terminal.
80103
- `applications.flatpak` / `applications.fwupd` – defaults for including
81104
application/firmware updates in both manifest generation and `sync` (also
82105
exposed as commands and `--with-*` flags).
@@ -85,7 +108,27 @@ options include:
85108
define additional safety margin before installs proceed.
86109

87110
CLI flags such as `--config`, `--include`, `--exclude`, `--dry-run`,
88-
`--no-aur`, `--no-repo`, and `--min-free-gb` override configuration on demand.
111+
`--no-aur`, `--no-repo`, `--mirrors`, `--no-mirrors`, and `--min-free-gb`
112+
override configuration on demand.
113+
114+
Mirror failover does not replace pacman trust, signature, dependency, or
115+
transaction checks. Syn-Syu only cycles mirrors after retrieval-style failures
116+
such as timeouts or failed downloads. Signature, integrity, keyring, dependency,
117+
lock, disk, and conflict errors stop the mirror loop and are surfaced as final
118+
failures. Known-fresh mirrors are ranked ahead of mirrors whose freshness cannot
119+
be checked; stale mirrors are excluded from failover candidates. Syn-Syu creates
120+
temporary pacman config files for each attempt and does not permanently modify
121+
your system mirrorlist. Mirror status output includes a short outcome code such
122+
as `ready`, `stale`, `timeout`, `connect_failed`, or `http_error`.
123+
124+
Syn-Syu is source-aware and tool-aware. Pacman mirror failover is pacman-specific.
125+
AUR RPC retry covers transient HTTP/network failures in Rust state generation.
126+
AUR helper retry covers clearly transient helper fetch/clone/download failures
127+
in Bash execution. PKGBUILD upstream source fallback, Flatpak retry policy, and
128+
fwupd retry policy are not implemented as Syn-Syu strategies yet; those channels
129+
remain separate future extension points or tool-owned behavior.
130+
For AUR RPC, `[acquisition.aur_rpc].max_retries` wins when set; legacy
131+
`[aur].max_retries` is used only when the new acquisition key is absent.
89132

90133
## Usage
91134

@@ -107,6 +150,8 @@ synsyu fwupd # Apply firmware updates via fwupdmgr
107150
synsyu sync --with-flatpak --with-fwupd # include app/firmware updates in one sweep
108151
synsyu helpers # List detected AUR helpers
109152
synsyu helper <name> # Set helper for this session (or persist with helpers.sh)
153+
synsyu mirrors # Show ranked mirror candidates recorded in the manifest
154+
synsyu acquisition # Show source-aware bounded acquisition policy
110155
synsyu config # Show config path info
111156
synsyu groups-edit # Open groups.toml in $EDITOR
112157
synsyu log # Show log directory/retention info
@@ -122,6 +167,7 @@ The Rust binary is also available directly:
122167
```bash
123168
synsyu_core --manifest ~/.config/syn-syu/manifest.json --with-fwupd --offline
124169
synsyu_core plan --manifest ~/.config/syn-syu/manifest.json --plan ~/.config/syn-syu/plan.json --json --strict
170+
synsyu_core mirrors --no-probe --json
125171
```
126172

127173
## Development

docs/Syn-Syu_Overview.md

Lines changed: 146 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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
5481
they 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
143219
flatpak = false
144220
fwupd = 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]
147248
enabled = false
148249
pre_command = "sudo snapper create --description 'Syn-Syu pre-update'"
@@ -169,6 +270,47 @@ operations; CLI flags `--with-flatpak` and `--with-fwupd` override the defaults.
169270
Flatpak metadata is appended by the Bash layer after `synsyu_core` runs; the
170271
core 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+
172314
The `[space]` section defines `min_free_gb`, a buffer that must remain free on
173315
disk before updates proceed, and `mode`, which controls behaviour when the
174316
buffer is not met. `mode = "warn"` (default) emits a warning; `mode = "enforce"`

0 commit comments

Comments
 (0)