docs: document libc taxonomy (none/musl/gnu/libc semantics)

none = static (no runtime dep, works everywhere)
musl = requires musl runtime (e.g. node-musl)
gnu  = requires glibc (crashes on Alpine)
libc = host UA value meaning "I have glibc"
This commit is contained in:
AJ ONeal
2026-03-11 02:33:16 -06:00
parent dcb092fa63
commit 1fff212d0b
2 changed files with 25 additions and 10 deletions

View File

@@ -46,14 +46,24 @@ The Go cache filters releases more aggressively than the old Node normalize.js:
- These are improvements — the filtered results better reflect what webi can
actually install.
### Libc Taxonomy
| Value | Meaning |
|--------|---------|
| `none` | Static build — no runtime libc dependency. Often built with musl but fully self-contained. Works everywhere. |
| `musl` | Requires musl C/C++ runtime at runtime (e.g. `node-musl`). NOT the same as a static musl build. |
| `gnu` | Requires glibc at runtime. Crashes on musl-only systems (Alpine). |
| `libc` | Host-reported UA value meaning "I have standard C library" (typically glibc). Not used in release metadata. |
### Known Issues Needing Resolution
- **WATERFALL libc vs gnu**: The Go cache correctly uses `libc='gnu'` for
glibc-linked Linux binaries (Rust projects like bat, rg; also node). The
build-classifier WATERFALL maps `libc` => `['none', 'libc']` but never tries
`gnu`, so Linux glibc hosts can't match these packages. Fix needed in
`host-targets.js`: `libc: ['none', 'gnu', 'libc']`. See QUESTIONS.md in the
Go agent worktree.
`host-targets.js`: `libc: ['none', 'gnu', 'libc']` (`none` first = prefer
static, `gnu` second = glibc host can run gnu-linked, `libc` last = fallback).
See QUESTIONS.md in the Go agent worktree.
- **Go cache `.git` source URLs (regression)**: The Go cache includes `.git`
source repo URLs as release assets. These get classified as
`ANYOS`/`ANYARCH` and match before platform-specific binaries because

View File

@@ -5,17 +5,22 @@ let Builds = require('./builds.js');
// Real User-Agent strings sent by webi bootstrap scripts.
//
// Known issues (not regressions from cache-only migration):
// Libc taxonomy:
// none = static build, no runtime libc dep (often built with musl, but self-contained)
// musl = requires musl C/C++ runtime at runtime (e.g. node-musl)
// gnu = requires glibc at runtime (crashes on musl-only/Alpine)
// libc = host UA value meaning "I have glibc" (not used in release metadata)
//
// Known issues:
//
// 1. WATERFALL libc vs gnu: The WATERFALL maps `libc` => ['none', 'libc']
// but packages with explicit gnu in filenames (Rust projects) get classified
// as libc='gnu'. A glibc host sending `libc` in the UA won't match `gnu`
// triplets. Needs a build-classifier submodule update.
// but never tries 'gnu'. Packages with glibc-linked builds (libc='gnu' in
// Go cache) won't match for hosts reporting 'libc'. Fix: update WATERFALL
// to `libc: ['none', 'gnu', 'libc']` in build-classifier submodule.
//
// 2. ANYOS/ANYARCH priority: The triplet enumeration tries ANYOS/ANYARCH
// before specific OS/arch. Packages whose Go cache includes source repo
// URLs (`.git`) as releases get matched to ANYOS before platform-specific
// binaries. The Go cache or selectPackage needs to handle this.
// 2. Go cache .git regression: The Go cache includes .git source repo URLs
// as releases, creating ANYOS/ANYARCH triplets. These match before
// platform-specific binaries. Fix: exclude .git from Go cache output.
let UA_CASES = [
// === macOS (no libc issue — darwin uses libc='none') ===