check: the git credential row is missing, and default-branch hides why it matters #97

Closed
opened 2026-08-28 20:23:52 +00:00 by larandar · 0 comments
Owner

Proposal

Three defects found by chasing one warning that had been dismissed as background noise across five consecutive doctor runs.

The chain

ting:default-branch reported could not read HEAD from <url> on every run. It was read as an unreachable-forge / network condition. It was not — it was an auth failure, and two separate bugs conspired to hide that.

1. check's git credential row does not exist

check carries a 38-line comment explaining, in detail, why the forge needs a credential.https://<forge>.helper row: HTTPS speaks Basic auth, not bearer; without it git falls through to an interactive askpass and fails outright (found live 2026-08-09). The settings table contains no git row at all — only four jj ones.

The proof it was lost rather than never written: config-get and config-set both implement a "git" scope, and nothing uses it. Dead code with a paragraph of rationale above it.

A comment describing a check that is not in the table is worse than no comment, because it reads as coverage.

2. default-branch threw the real error away

if $symref.exit_code != 0 {
  gum log --level warn $"⚠ default-branch: could not read HEAD from ($source)"

$symref.stderr — which says fatal: Authentication failed — was discarded. An auth failure and an unreachable forge rendered identically.

Its comment also claimed git ls-remote needs no token because HEAD "is public information on a public repo". True for a public repo; most of the estate is not public, so it goes through the credential helper.

3. The helper is inert without an exported token

The row reads $FORGEJO_ACCESS_TOKEN from the environment (correctly — no secret in git config). But an unexported token makes it answer with an empty password, which Forgejo reports as "Credentials are incorrect or have expired" — a wrong token, not a missing one. That one word is what sent the diagnosis down the wrong path.

Specification Delta

  • ADDED to check's settings table: [git, 'credential.https://jo.et0.pw.helper', ...], reviving the dead "git" scope.
  • ADDED ting:token: warns when FORGEJO_ACCESS_TOKEN is unset, naming the misleading "expired" symptom. Reports length only, never the value.
  • CHANGED ting:default-branch: carries the last non-empty line of stderr into the warning; comment corrected.
  • CHANGED chain order: config -> token -> remotes.

Verification

Against lar.ad/flake-ops, with the module as a path: input.

Token unset:

WARN ⚠ token — FORGEJO_ACCESS_TOKEN is unset; the credential helper will answer with an
     empty password and every HTTPS forge operation will report EXPIRED credentials
WARN ⚠ default-branch: could not read HEAD from https://jo.et0.pw/lar.ad/flake-ops.git
     — fatal: Authentication failed for 'https://jo.et0.pw/lar.ad/flake-ops.git/'

Token present:

INFO ✅ git credential.https://jo.et0.pw.helper
INFO ✅ token — FORGEJO_ACCESS_TOKEN present (40 chars)
INFO ✅ default-branch — fastlane

default-branch has never been green before this change.

## Proposal Three defects found by chasing one warning that had been dismissed as background noise across five consecutive doctor runs. ## The chain `ting:default-branch` reported `could not read HEAD from <url>` on every run. It was read as an unreachable-forge / network condition. It was not — it was an auth failure, and two separate bugs conspired to hide that. ### 1. `check`'s git credential row does not exist `check` carries a 38-line comment explaining, in detail, why the forge needs a `credential.https://<forge>.helper` row: HTTPS speaks Basic auth, not bearer; without it git falls through to an interactive askpass and fails outright (found live 2026-08-09). The **settings table contains no git row at all** — only four `jj` ones. The proof it was lost rather than never written: `config-get` and `config-set` both implement a `"git"` scope, and **nothing uses it**. Dead code with a paragraph of rationale above it. A comment describing a check that is not in the table is worse than no comment, because it reads as coverage. ### 2. `default-branch` threw the real error away ```nu if $symref.exit_code != 0 { gum log --level warn $"⚠ default-branch: could not read HEAD from ($source)" ``` `$symref.stderr` — which says `fatal: Authentication failed` — was discarded. An auth failure and an unreachable forge rendered identically. Its comment also claimed `git ls-remote` needs no token because HEAD "is public information on a public repo". True for a public repo; **most of the estate is not public**, so it goes through the credential helper. ### 3. The helper is inert without an exported token The row reads `$FORGEJO_ACCESS_TOKEN` from the environment (correctly — no secret in git config). But an unexported token makes it answer with an **empty password**, which Forgejo reports as *"Credentials are incorrect or have expired"* — a wrong token, not a missing one. That one word is what sent the diagnosis down the wrong path. ## Specification Delta - **ADDED** to `check`'s settings table: `[git, 'credential.https://jo.et0.pw.helper', ...]`, reviving the dead `"git"` scope. - **ADDED** `ting:token`: warns when `FORGEJO_ACCESS_TOKEN` is unset, naming the misleading "expired" symptom. Reports **length only**, never the value. - **CHANGED** `ting:default-branch`: carries the last non-empty line of stderr into the warning; comment corrected. - **CHANGED** chain order: `config -> token -> remotes`. ## Verification Against `lar.ad/flake-ops`, with the module as a `path:` input. Token unset: ``` WARN ⚠ token — FORGEJO_ACCESS_TOKEN is unset; the credential helper will answer with an empty password and every HTTPS forge operation will report EXPIRED credentials WARN ⚠ default-branch: could not read HEAD from https://jo.et0.pw/lar.ad/flake-ops.git — fatal: Authentication failed for 'https://jo.et0.pw/lar.ad/flake-ops.git/' ``` Token present: ``` INFO ✅ git credential.https://jo.et0.pw.helper INFO ✅ token — FORGEJO_ACCESS_TOKEN present (40 chars) INFO ✅ default-branch — fastlane ``` `default-branch` has never been green before this change.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Ting/Jostoph#97
No description provided.