Skip to content

finding(gate): check:node-esm-load says it "refuses to grade artifacts it did not produce", but its build leg replays turbo cache entries produced in a different worktree #7276

Description

@yinlianghui

Observed by the dev seat implementing #6291 while running the derived gate family. Unassigned, finding — recording a measurement, not proposing a fix.

What the gate promises

check:node-esm-load builds every published package before grading, and says why:

Building every published package (the load leg refuses to grade artifacts it did not produce)…

What it actually did

On a container running several agents in sibling worktrees, the build leg logged cache hits whose replayed output names another worktree's path:

@object-ui/example-byo-backend-console:build: cache hit, replaying logs 5f31ed4a4acd0299
@object-ui/example-byo-backend-console:build: > @object-ui/example-byo-backend-console@0.1.0 build /home/user/objectui-issue-6606/examples/byo-backend-console

The run was in /home/user/objectui-issue-6291. /home/user/objectui-issue-6606 is a different agent's worktree, on a different branch. turbo's cache is keyed by input hash and lives outside the worktree, so a sibling's artifacts satisfy the build leg — the gate then grades artifacts it did not produce, which is the one thing its own banner says it will not do.

It then reported:

Load leg: 33 of 39 published ESM entries imported and evaluated.
✗ @object-ui/console: no-build-output — ./plugin.js does not exist after the build

Why this is worth a card

The failure mode is silent in the direction that matters. A green run tells you nothing about your tree if the artifacts came from someone else's, and a red run — like the one above — reads as "your change broke the build" when the change under test was two files under scripts/ and zero under packages/. An agent reading that verdict has no way to tell the two apart from the exit code, and the honest reading is NOT MEASURED, which is not one of the gate's outputs.

This is adjacent to but not the same as #1760 (an app-shell tsc failure masked by turbo cache): that one is about the cache hiding a real failure in a single checkout; this one is about cache entries crossing worktree boundaries so the gate's produced-it-myself invariant does not hold at all.

CI runs on a clean single checkout, so this is a local-verification hazard rather than a CI defect — which is exactly why it is easy to leave un-filed.

Possible directions (not prescriptive)

  • Give the build leg its own turbo cache dir (or --force) so "I produced these" is true, at the cost of build time.
  • Or have it assert provenance: fail loudly when a replayed log names a path outside the current repo root, rather than grading the artifacts.
  • Or state the limitation in the banner, so the reading is at least honest.

Refs: #6291 (the run where it surfaced) · #1760 (the adjacent cache-masking case)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repofindingpriority:p2tooling

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions