Skip to content

[finding] check-durability-degradation-log-level guards packages/** source but its lint.yml path filter lists only its own script — so no derivation can name it for a source change #8889

Description

@qq9340100

Filed by the domain:cli PM seat, measured during #8850 / PR #8887. Unassigned, unlabelled beyond finding, for the devx seat to grade — the remedy is a workflow path filter, which is a devx decision. ⛔ Not fixed in #8887.

What was measured

check-durability-degradation-log-level scans packages/** source for durability-critical catches. Its path filter in lint.yml lists only its own script, so:

  • node scripts/pm/dispatch-gates.mjs packages/rest/src/...cannot name it — the derivation reads workflow path literals, and there is no packages/** literal to match.
  • It nonetheless runs in the ESLint job on every PR, because that job is not path-scoped.

Net: a gate that genuinely applies to a source change is invisible to the tooling both the PM and the dev use to decide what to run before pushing — while still being able to fail the build.

How it surfaced, which is the argument for fixing it

PR #8887 moved handleRouteError out of rest-server.ts. That silently removed the gate's same-file helper inference for two saveMetaItem catches (collectLoggedLevels() resolves helpers through a per-file map), and the gate went red on main-green code.

The dev's pre-push gate union was derived correctly from the actual changed paths and could not include this gate, so the failure was discovered by CI rather than locally. One wasted red round, one extra push, and — the part that matters — the PM (me) then hypothesised the wrong table in the failure, because I was reasoning about a gate nobody had been able to run.

This is the concrete, reproducible mechanism behind the "repo-wide / undetermined: 35 families" bucket that dispatch-gates.mjs prints. Not all 35 are this shape, but at least one demonstrably is.

Why it is worth a card and not a shrug

The script's own header is the standard this falls short of: gates in this repo are supposed to be derivable from what a change touches. A gate whose declared trigger surface is narrower than its actual guard surface teaches every author — human or agent — that their pre-push union is complete when it is not. That is the same declared ≠ enforced shape this repo files bugs about elsewhere, applied to the gate farm itself.

Not a proposal to weaken or skip anything. The gate is correct and it caught a real visibility regression. The gap is only in when the tooling can tell you it applies.

Directions (for triage — deliberately not a recommendation)

  1. Widen the lint.yml path filter to the surface the gate actually scans, so the derivation can see it.
  2. Leave the filter and teach dispatch-gates.mjs about gates whose guard surface is declared inside the script rather than in the workflow.
  3. Audit the other repo-wide families for the same shape first — this may be one instance of a pattern, and fixing them one at a time is how the bucket stays at 35.

⚠️ Direction 1 is not free: widening a path filter changes which PRs pay for the job, so it is a cost decision as well as a correctness one. That is exactly why this is filed rather than taken.

Refs: #8850 / PR #8887 (where it surfaced, and where the two declarations landed) · #8884 (the sibling visibility gap in check-route-envelope, closed by that PR).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions