Skip to content

aprender-update: a 404 on a private repo's release listing reads as "up to date", and fetch::Http cannot authenticate #5055

Closed as not planned

Description

@noahgift

Second blocker for paiml/rmedia#717, alongside #5050.

Defect 1: a 404 on the release listing is reported as "up to date"

fetch::Http maps HTTP 404 to Ok(None). For the /releases?per_page=30 listing, that reads as "nothing published" and update --check prints <bin> X is up to date with exit 0.

On a private repository, GitHub answers 404 to an unauthenticated request whether or not the repository exists. paiml/rmedia is private. Measured 2026-10-10:

  • A build pinned to 0.4.9 printed rmedia 0.4.9 is up to date, exit 0.
  • v-rmedia-cli-0.5.0 was published at the time, with the matching tarball and .sha256.

That makes this a silent false negative: the user is told no update exists.

Proposed: a 404 on the listing is Err ("not found, or no access"), not Ok(None). A 404 on <asset>.sha256 can stay Ok(None), because the install already fails closed on a missing digest.

Defect 2: no credentials, so a private repository is unreachable

fetch::Http sends no Authorization header. A private repository's assets also need:

  • the API asset URL (/repos/O/R/releases/assets/<id>), not browser_download_url;
  • Accept: application/octet-stream.

The digest is fetched at <asset_url>.sha256, which has no API equivalent. It has to be resolved by asset name from the same listing.

Proposed:

  • An optional token, from GH_TOKEN, then GITHUB_TOKEN, then gh auth token.
  • Send it only to https://api.github.com/, and never forward it on a redirect: the asset download redirects to signed storage that needs none.
  • When a token is in use, Candidate::asset_url is the API URL, and the digest URL is the API URL of the asset named <name>.sha256.
  • With no token and a 404, the error says so: "no credentials; this repository may be private".

What rmedia does until this ships

crates/rmedia-types/src/update.rs (paiml/rmedia#717) implements both in an rmedia-side Net:

  • GithubNet: ureq 3, https_only, RedirectAuthHeaders::Never, refuses any non-api.github.com URL, and makes a 404 or a missing token an error.
  • TagBridge: rewrites the listing's asset URLs and resolves digests by name.

Tests cover the no-token case: exit 1, never "up to date". Verified live: a 0.4.9 build updated itself to the published 0.5.0, sha256-verified. The adapter is deleted when this ships.

How the decision was made

Planted quorum, degraded same-family (3 Sonnet 5.5 lanes; the author is Opus 5.5). It was unanimous for "rmedia-side authenticated Net now, plus this upstream issue". Making the releases public was rejected by all three lanes: rmedia is private IP.

Activity

  1. noahgift commented on Oct 14, 2026

    @noahgift
    ContributorAuthor

    Folded into #2876 as a checklist row (TRIAGE-100, 2026-10-14): the open-ticket cap is 100, so this ticket is now tracked on that master and closed as not planned. Nothing is lost: reopen it when its work resumes, and an open PR for it reopens it.

    Agent: aprender-clerk

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions