Skip to content

fleet-sync: designed, deliberately not built — the evidence, so the option keeps its cost at zero #24

Description

@bdelanghe

The dependabot.yml fan-out (#10) took 57 repos, one at a time: add_repo → clone → branch → PR → merge, in batches of five to ten. That is exactly the shape that should be a workflow, and the question came up mid-sweep. Recording the design and the reasons it was not built, so choosing it later costs a decision rather than a rediscovery.

The design

An org-var-driven sync lane in ci-workflows:

  • desired statetemplates/* (already true)
  • target set — an org variable (FLEET_REPOS), or derived dynamically from the caller-pins census, which already computes "repos containing .github/workflows/deps.yml"
  • actuator — a workflow that pushes a branch and opens a PR per repo where the file differs
  • credential — a new pinned GH_APPS broker entry

Same OpenTofu decomposition as caller-pins (desired / plan / apply), one layer up: instead of converging pins, it converges files.

What's already in place — this is smaller than it looks

Everything except the entry itself exists:

  • vars.CF_BROKER_URL is an org variable, visible to every repo.
  • .github/actions/broker-gh-token is a reusable composite action that mints a scoped App token from it, with a require: scope assertion that fails loudly rather than 403-ing a step later (.github#87, #93).
  • bounded-systems-front-desk (appId 4072076) is installed on all repos, deliberately.
  • front-desk-pin is an existing broker entry at exactly contents:write, pull_requests:write, metadata:read, pinned by workflowRef to .github's org-defaults.yml — the precedent, doing the identical push-a-branch-and-open-a-PR job for one repo.

So the build is one wrangler.jsonc entry through the reviewer-gated broker-deploy lane, plus the workflow. No new App, no standing PAT, no new secret.

The boundary that decides how useful it is

.github/dependabot.yml is not a workflow file, so distributing it needs only contents:write. But templates/deps.yml is, and GitHub rejects pushes touching .github/workflows/* from tokens lacking the workflows permission. So fleet-sync is either:

  • narrow — non-workflow files only (dependabot configs, community-health files). Cheap, safe, and less useful than it sounds.
  • broad — includes workflow files, which needs the workflows escalation and makes this repo's main able to mint org-wide write. That is the posture change SHA pins exist to prevent, and it was declined once already (#10).

That fork is the actual decision. It is not answerable by "would automation be nice".

Why it wasn't built tonight

  1. The arithmetic didn't favour it. 25 repos remained when the question was asked — fewer than the build plus a broker deploy plus a review cycle. It only pays off on the next fleet file, and that frequency is unmeasured. Three appeared this week because the org is mid-buildout; steady state might be quarterly.
  2. It is the bespoke actor we declined twice. The stated criterion is automation, config-as-code, nothing to maintain later. Dependabot is now the org's only standing actuator, which is a clean property to keep.
  3. The manual pass was the requirements-gathering. Each thing the sweep found would have been a bot bug shipped to 57 repos:
    • deps: PR titles are rejected by semantic-PR gates; ci: is required.
    • guest-room and prx already had dependabot.ymlprx with bun + docker + github-actions ecosystems. A blind copy would have destroyed all three; the append-vs-clobber guard skipped both correctly.
    • Dependabot resolves via tags, so the untagged ci-workflows was invisible to the applier — found only by inspecting a live Dependabot PR (release-tag: name the desired state — Dependabot cannot see an untagged repo #23), and fixed by release-tag.yml.
    • Three repos ci-workflows#2 recorded as empty (gh-action-brand-checks, -contracts, -node-uniqueness) are populated and carry current callers.

When to build it

When a third fleet file needs distributing, or when a template bump needs to reach callers faster than Dependabot's weekly cycle. Until then this issue is the whole cost.

Verified end state of the fan-out

.github/dependabot.yml present on 58/58 — 55 merged tonight, guest-room and prx already configured, plus ci-workflows self-adopted.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions