Skip to content

[finding] an .objectui-sha diff derives NO pin-critical gate — the gates a pin bump most needs are the ones structurally excluded from path derivation, and one of them shipped a red on PR #12955 #12956

Description

@os-elon

Observation-class finding, recorded while bumping the objectui pin on #12687 (PR #12955). Sharpened after a second instance turned up as a real CI red on that PR — the original filing understated this as a single-gate gap.

The claim

An .objectui-sha diff derives no pin-critical gate at all. This is not one unreachable gate; it is a class, and the class is characterised by something worse than an oversight: the gates a pin bump most needs are the ones that cannot be path-filtered, and path derivation is blind to exactly that.

Two instances, two different mechanisms, same consequence.

Instance 1 — Console Pin Gate, filtered one indirection away

It selects itself on a dorny/paths-filter job output, not a workflow-level pull_request: paths: filter:

# .github/workflows/ci.yml
console:
  - '.objectui-sha'
  - 'scripts/build-console.sh'
  
---
  name: Console Pin Gate
  needs: filter
  if: ${{ !cancelled() && needs.filter.outputs.console != 'false' }}

The population is real, correct, and sitting in the workflow file — just expressed one hop from where the derivation reads.

Instance 2 — check:objectui-pin-citations, deliberately UNFILTERED (this is the sharp one)

pnpm --filter @objectstack/spec check:objectui-pin-citations, run in Type Check · source gates (lint.yml:3701). It declares no path population on purpose, and the step's own comment says why:

Reads src/ and the root pin file only — no build — so it belongs in this pre-build source-audit group. Unfiltered and required: a paths filter on packages/spec/** would go dormant on exactly the PR that moves .objectui-sha, which is the PR this exists to catch.

That is the whole finding in one sentence. The gate is unfiltered because filtering it would break it — and being unfiltered is precisely what makes it invisible to a derivation that works from declared paths. The correctness requirement and the derivability requirement are in direct opposition here.

Measured, on PR #12955

diff families derived pin gates named
.objectui-sha + .changeset/…md (2 files) 8 none — all 8 matched via the changeset file; .objectui-sha matched nothing
after adding 3 × packages/spec/src/** (5 files) 33 still none

The second row is the damning one: the diff now edits the very files check:objectui-pin-citations scans and the pin file it compares them against, the family grew from 8 to 33 — and the gate is still not named.

Residue placement (--residue), which is why a dev skips them:

  • check:objectui-pin-citationsUndetermined ("source names no path at all — NOT known irrelevant"), 34 families
  • check:console-shaUndetermined, same bucket
  • check:console-injectionSilent ("source names paths, none of which cover yours — the weakest verdict"), 111 families

All three sit in the two buckets whose own labels say they are not clearances — and which, at 34 + 111 families, no one reads.

It is not hypothetical — it shipped a red

PR #12955 ran every derived gate green locally, plus the console pair by hand (read out of ci.yml, because the derivation would not name them). check:objectui-pin-citations was neither derived nor guessed, and CI went red:

✗ 8 spec source(s) assert an objectui pin this repo does NOT build against.
  .objectui-sha = 9602dc820450dda956843c6cfe5b329bcf88c757
    packages/spec/src/data/api-methods-batch-conformance.test.ts:64  cites `190fbd01d`
    packages/spec/src/ui/component.test.ts:281 / :366 / :2437         cites `190fbd01d`
    packages/spec/src/ui/component.zod.ts:642 / :1649 / :1825 / :2393 cites `190fbd01d`

Type Check · source gates (job 98826433330) failed; the required TypeScript Type Check context went red purely as its rollup (verified from the aggregator's own OS_NEEDS: one lane failure, three success).

Note the shape: this gate exists specifically to fire on pin bumps and is required — so the one card it was built for is the one card whose dev is not told to run it.

Why a pin bump makes this expensive

A pin bump's entire risk is the console build and the cross-repo records that describe it. The failure is not "a gate went red" but the cost of the round trip: re-measuring 8 records against a 359-commit objectui range is real work, and check:objectui-pin-citations refuses a mechanical fix by design (no gen:, NO_GENERATOR in the check:generated ledger) — it demands a human/agent re-derivation. Learning that from CI rather than from the dispatch list costs a full patch round every time.

Not proposing the fix

Two candidate directions, both wider than a special case, neither costed here:

  1. Follow needs.<job>.outputs.<name> back to the dorny/paths-filter block that defines it — covers instance 1 and every other filtered job in ci.yml at once.
  2. Give deliberately-unfiltered-but-path-relevant gates a way to declare a derivation population distinct from their execution filter — the point being that a gate can be correct to run always and still know which diffs make it interesting. That is instance 2, and the ROOT_DIR_WATCH_HINTS marker idiom the residue output already mentions looks like the nearest existing seam.

Filed unassigned.

Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions