A manifest input whose development home lacks the ref breaks every consumer, and says nothing about fastlane #14

Closed
opened 2026-08-10 08:14:56 +00:00 by agent.teyla · 0 comments
Contributor

Source: the midgard/jostoph-rs correction on #11, 2026-08-10.

.fastlane.just's assemble appends ?ref={{ref}} to every manifest input, unconditionally — there is no per-input ref and no existence check. So the manifest silently assumes every listed repo carries a fastlane branch.

That assumption is not free-standing: some repos are main-only by design (owner, 2026-08-10 — jostoph-rs is consumed as published, not co-developed branch-for-branch). The manifest has no way to express one, so the rule is "leave it out" — an implicit rule, written down nowhere, enforced by nothing.

When the rule is broken the failure is maximally unhelpful. Measured, not assumed:

error: Failed to fetch git repository '…'
       … while updating the flake input 'jostoph-rs'
  • It does not degrade — the entire nix evaluation fails, not just that override.
  • It hits every repo that declares the input, not the repo that made the mistake.
  • It names neither fastlane, nor the manifest, nor the branch that is missing. Nothing in that message points at the file you have to edit.

The file's own header explains that an undeclared input is inert ("nix warns on an unknown --override-input, it does not fail"), which invites the reasonable and wrong inference that a bad input is inert too.

This is the shape of drift the steward exists to catch: a hand-edited setting, correct today, that breaks things far from where it was written.

In scope

  • At manifest-refresh time, probe each input's development home for the ref branch and warn, on stderr, naming the input, the repo, and the missing branch.
  • Recording the constraint in the file's own header, beside the "inert" note it currently contradicts.

Out of scope

  • Raising. A hard error would take out every repo that fetches the manifest — strictly worse than today's blast radius, which is limited to repos declaring the offending input. Warn, never raise.
  • Probing on the hot path. flake_override runs the seam on every just invocation in a wired repo. Per-invocation network probes would tax every command to catch a once-in-a-while steward typo. The refresh already pays a network cost once a day; the probe belongs there and nowhere else.
  • Teaching the manifest to express a main-only input (a per-input ref, a [published] section). No input wants it: a repo consumed as published simply is not a development home, so the right entry is no entry. Building the schema for a case with no instances is inventing work.
  • Skipping or rewriting a bad input. Routing around a broken manifest line hides it; the line is wrong and someone must fix it.

Boundary

This adds git to what the seam assumes. It has assumed only nu and just, deliberately, because it ships to every repo in the estate. Mitigated by making the probe entirely best-effort: no git, no key, no network — the probe says nothing and assemble behaves exactly as before. It may only ever add a warning, never change a flag or an exit status.

The distinction that makes this safe is that git ls-remote --exit-code separates the two failures: exit 2 is "connected fine, no such branch" — a fact about the manifest, worth saying. Exit 128 is unreachable or unauthenticated — a fact about the machine, and none of this file's business. Only exit 2 warns.

The probe validates the default ref. just ref=<other> assemble is unvalidated and still fails the old way; validating every possible ref is not a thing a cache can do.

Acceptance

  • A manifest listing a repo with no fastlane branch produces a stderr warning naming the input, the repo and the branch — and assemble still prints its flags and exits 0.
  • The four real inputs produce no warning.
  • The emitted flags are byte-identical to before, for the same manifest.
  • With git absent from PATH, assemble still works and warns about nothing.
  • An unreachable or unauthenticated remote (exit 128) produces no warning — it is not a manifest fault.
  • A cached, fresh manifest does no probing at all: no network calls on the hot path.

Context

  • #6 — the manifest and the seam.
  • #11 — where this was measured, and the main-only-by-design ruling that motivates it.
  • #10 — the doctor step that installs this seam into every repo, which is what gives a bad manifest line its reach.
Source: the `midgard/jostoph-rs` correction on #11, 2026-08-10. `.fastlane.just`'s `assemble` appends `?ref={{ref}}` to **every** manifest input, unconditionally — there is no per-input ref and no existence check. So the manifest silently assumes every listed repo carries a `fastlane` branch. That assumption is not free-standing: some repos are `main`-only **by design** (owner, 2026-08-10 — `jostoph-rs` is consumed as published, not co-developed branch-for-branch). The manifest has no way to express one, so the rule is "leave it out" — an implicit rule, written down nowhere, enforced by nothing. When the rule is broken the failure is maximally unhelpful. Measured, not assumed: ``` error: Failed to fetch git repository '…' … while updating the flake input 'jostoph-rs' ``` - It does not **degrade** — the entire nix evaluation fails, not just that override. - It hits **every repo that declares the input**, not the repo that made the mistake. - It names neither `fastlane`, nor the manifest, nor the branch that is missing. Nothing in that message points at the file you have to edit. The file's own header explains that an *undeclared* input is inert ("nix warns on an unknown `--override-input`, it does not fail"), which invites the reasonable and wrong inference that a *bad* input is inert too. This is the shape of drift the steward exists to catch: a hand-edited setting, correct today, that breaks things far from where it was written. ## In scope - At manifest-refresh time, probe each input's development home for the `ref` branch and **warn**, on stderr, naming the input, the repo, and the missing branch. - Recording the constraint in the file's own header, beside the "inert" note it currently contradicts. ## Out of scope - **Raising.** A hard error would take out every repo that fetches the manifest — strictly worse than today's blast radius, which is limited to repos declaring the offending input. Warn, never raise. - **Probing on the hot path.** `flake_override` runs the seam on *every* `just` invocation in a wired repo. Per-invocation network probes would tax every command to catch a once-in-a-while steward typo. The refresh already pays a network cost once a day; the probe belongs there and nowhere else. - **Teaching the manifest to express a main-only input** (a per-input `ref`, a `[published]` section). No input wants it: a repo consumed as published simply is not a development home, so the right entry is no entry. Building the schema for a case with no instances is inventing work. - **Skipping or rewriting a bad input.** Routing around a broken manifest line hides it; the line is wrong and someone must fix it. ## Boundary This adds `git` to what the seam assumes. It has assumed only `nu` and `just`, deliberately, because it ships to every repo in the estate. Mitigated by making the probe entirely best-effort: no `git`, no key, no network — the probe says nothing and `assemble` behaves exactly as before. It may only ever *add* a warning, never change a flag or an exit status. The distinction that makes this safe is that `git ls-remote --exit-code` separates the two failures: **exit 2** is "connected fine, no such branch" — a fact about the manifest, worth saying. **Exit 128** is unreachable or unauthenticated — a fact about the machine, and none of this file's business. Only exit 2 warns. The probe validates the *default* `ref`. `just ref=<other> assemble` is unvalidated and still fails the old way; validating every possible ref is not a thing a cache can do. ## Acceptance - A manifest listing a repo with no `fastlane` branch produces a stderr warning naming the input, the repo and the branch — and `assemble` still prints its flags and exits 0. - The four real inputs produce no warning. - The emitted flags are byte-identical to before, for the same manifest. - With `git` absent from PATH, `assemble` still works and warns about nothing. - An unreachable or unauthenticated remote (exit 128) produces no warning — it is not a manifest fault. - A cached, fresh manifest does no probing at all: no network calls on the hot path. ## Context - #6 — the manifest and the seam. - #11 — where this was measured, and the main-only-by-design ruling that motivates it. - #10 — the doctor step that installs this seam into every repo, which is what gives a bad manifest line its reach.
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#14
No description provided.