Skip to content

fix(ship): runtime_roles.paths duplicates the publisher workflow's on.push.paths — read the workflow, or drift-check it #2341

Description

@hdkiller

Found in the cold review of #2337 (WM-1104), polish item 13. Not blocking that PR; filed separately per the discovered-work rule.

Problem

config/repos.yaml runtime_roles[].paths is documented — in docs/ship.md, in config/repos.example.yaml, and now enforced as required by loadShipConfig — as mirroring the publisher workflow's own on.push.paths. That is not a convention but the definition of stale the check uses: the publisher rebuilds when those paths move, so a pin older than a change to one of them is stale by the publisher's own rule.

Mirroring means the two copies can drift, and nothing notices. legalease's case_agent role lists four paths; .github/workflows/case-agent-image.yml has its own on.push.paths. If someone adds a fifth path to the workflow, the publisher starts rebuilding on it while ship-preflight keeps reporting the pin fresh — a silent false PASS on the release gate, in the one direction that matters.

The WM-1104 fix round made a missing paths a hard config error, which closes the "check that can never fail" hole. It does nothing about the "check that reads the wrong definition of stale" hole.

Two options

  1. Read the workflow file (preferred): drop paths from the config for roles whose publisher lives in the same repo and parse on.push.paths out of .github/workflows/<publisher_workflow> at the tip being shipped. Single source of truth, drift impossible. Cost: the module has to read a file out of the target checkout (git show <tip>:.github/workflows/<wf>, which is the honest read — the paths that applied at that commit) and parse YAML. It also has to decide what to do when the workflow has no on.push.paths at all (answer: FAIL, same as today's missing-paths case).
  2. Drift-check: keep paths in config but add a check that compares it against the workflow's on.push.paths and FAILs pre-flight when they differ. Cheaper, keeps the config self-documenting, but keeps the duplication.

Option 1 also removes a required config key from every repo that adopts ship-preflight, which is the larger win.

Acceptance

  • Adding a path to the publisher workflow without touching config/repos.yaml changes the runtime-pin:<role> verdict (option 1) or FAILs pre-flight with a drift message naming both lists (option 2).
  • A publisher workflow with no on.push.paths is a FAIL with a clear message, not a SKIP or a PASS.
  • docs/ship.md and config/repos.example.yaml stop telling operators to hand-mirror a list, or say explicitly that the drift check exists.

Owned paths

  • orchestrator/ship.mjs
  • orchestrator/ship.test.mjs
  • config/repos.example.yaml
  • docs/ship.md

Activity

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions