Skip to content

feat(core): add TaskFileResolver primitive; refactor show target --check to use it#35583

Draft
polygraph-app[bot] wants to merge 3 commits intomasterfrom
feat/check-sandbox-report
Draft

feat(core): add TaskFileResolver primitive; refactor show target --check to use it#35583
polygraph-app[bot] wants to merge 3 commits intomasterfrom
feat/check-sandbox-report

Conversation

@polygraph-app
Copy link
Copy Markdown
Contributor

@polygraph-app polygraph-app Bot commented May 5, 2026

Summary

Adds a small generic TaskFileResolver primitive (exported from devkit-internals,
not devkit-exports) that lets callers ask whether a workspace-relative path is a
declared input or output of a given task. Refactors nx show target ... --check
(both inputs and outputs) to use it instead of duplicating the input/output
reconciliation logic.

This supersedes the earlier verifySandboxViolations API: that high-level helper
has been removed in favor of this lower-level primitive. Consumers (the nx-cloud
light client) own their own report schemas and call the primitive per file.

API

interface TaskFileResolver {
  isInput(taskId: string, file: string): boolean;
  isOutput(taskId: string, file: string): boolean;
  getInputs(taskId: string): string[];
  getRawInputs(taskId: string): HashInputs;
  getOutputs(taskId: string): string[];
  /**
   * Static validation for `dependentTasksOutputFiles` inputs: matches a path
   * against each declared dep-outputs glob ANDed with each upstream task's
   * declared outputs. Works without the upstream having actually run.
   */
  matchesDependentTaskOutputs(taskId: string, file: string): boolean;
}
function createTaskFileResolver(opts: {
  projectGraph: ProjectGraph;
  nxJson?: NxJsonConfiguration;
  workspaceRoot?: string;
}): Promise<TaskFileResolver>;

Exported from packages/nx/src/devkit-internals.ts.

isInput() accepts a path as an input if any of the following hold:

  1. Path is in HashInputs.files (resolved self-inputs).
  2. Path is in HashInputs.depOutputs (materialized — only populated after
    upstream tasks have run).
  3. Path matches a dependentTasksOutputFiles glob declared on the task AND
    lies inside the declared outputs of an upstream task in the task graph
    (honors transitive: true|false). This is the static check that lets
    sandbox-report verification work without first running the dependency.

Files

File Change
packages/nx/src/hasher/task-file-resolver.ts added — primitive impl
packages/nx/src/hasher/task-file-resolver.spec.ts added — unit tests
packages/nx/src/hasher/verify-sandbox-violations.ts deleted
packages/nx/src/hasher/verify-sandbox-violations.spec.ts deleted
packages/nx/src/devkit-internals.ts exposes createTaskFileResolver
packages/nx/src/devkit-exports.ts removes verifySandboxViolations exports
packages/nx/src/command-line/show/show-target/inputs.ts refactored — uses resolver
packages/nx/src/command-line/show/show-target/outputs.ts refactored — uses resolver

Test plan

  • Unit tests for the resolver primitive (23 tests passing locally — including
    6 new tests covering dependentTasksOutputFiles static validation).
  • Unit tests for show target inputs|outputs (25 tests passing locally).
  • CI build / lint / full jest suite.

Linked PR

Consumed by nrwl/ocean#11134, which owns the SandboxReport schema and
iterates the report calling resolver.isInput / resolver.isOutput per file.

…cking

Adds a programmatic API that lets external consumers verify whether
sandbox-violation file paths from a prior task run would be considered
legitimate inputs/outputs in the current workspace configuration.

The API mirrors the logic that powers nx show target --check:
inputs are reconciled via HashPlanInspector.inspectTaskInputs, outputs
via getOutputsForTargetAndConfiguration with glob matching.

HashPlanInspector and the new verifier are now exported from
devkit-exports for use by the nx-cloud light client.
@netlify
Copy link
Copy Markdown

netlify Bot commented May 5, 2026

Deploy Preview for nx-docs ready!

Name Link
🔨 Latest commit b90bdf7
🔍 Latest deploy log https://app.netlify.com/projects/nx-docs/deploys/69fbb7fa487cad00082be459
😎 Deploy Preview https://deploy-preview-35583--nx-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link
Copy Markdown

netlify Bot commented May 5, 2026

Deploy Preview for nx-dev ready!

Name Link
🔨 Latest commit b90bdf7
🔍 Latest deploy log https://app.netlify.com/projects/nx-dev/deploys/69fbb7face40d00008cd4f5c
😎 Deploy Preview https://deploy-preview-35583--nx-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@nx-cloud
Copy link
Copy Markdown
Contributor

nx-cloud Bot commented May 5, 2026

View your CI Pipeline Execution ↗ for commit b90bdf7

Command Status Duration Result
nx affected --targets=lint,test,build,e2e,e2e-c... ❌ Failed 36m 54s View ↗
nx run-many -t check-imports check-lock-files c... ✅ Succeeded 3s View ↗
nx-cloud record -- pnpm nx-cloud conformance:check ✅ Succeeded 17s View ↗
nx build workspace-plugin ✅ Succeeded <1s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded 24s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 6s View ↗

☁️ Nx Cloud last updated this comment at 2026-05-06 22:32:50 UTC

nx-cloud[bot]

This comment was marked as outdated.

…evkit-internals

Replaces the sandbox-report-aware verifySandboxViolations export with
a generic primitive. createTaskFileResolver returns a handle exposing
getInputs / getOutputs / isInput / isOutput per task — the cloud
light client owns the SandboxReport shape and the iteration loop.

Exposed via devkit-internals (not the public devkit-exports surface).

A follow-up commit will refactor nx show target --check to consume
this same resolver.
@AgentEnder AgentEnder force-pushed the feat/check-sandbox-report branch from 9ec92af to 8378d0e Compare May 6, 2026 20:51
@AgentEnder AgentEnder changed the title feat(core): expose verifySandboxViolations API for sandbox-report checking feat(core): add TaskFileResolver primitive; refactor show target --check to use it May 6, 2026
nx-cloud[bot]

This comment was marked as outdated.

…ally

Previously isInput() only matched against the materialized HashInputs.files
list — when an upstream task hadn't run yet, depOutputs was empty and any
file declared via { dependentTasksOutputFiles: '...', transitive?: bool }
was reported as not-an-input even when the path obviously matched both the
glob and a declared upstream output.

The new logic walks the task graph from the inspected task, pulls each
upstream's declared output globs, and reports the path as an input when
it matches the dependentTasksOutputFiles glob AND lies inside one of those
upstream outputs. Honors transitive: true/false. The check is exposed
separately as resolver.matchesDependentTaskOutputs so consumers (e.g. the
nx-cloud check-sandbox-report command) can reason about why a path was
considered an input.

Adds 6 unit tests covering: materialized depOutputs, static glob+output
match, glob-without-output mismatch, output-without-glob mismatch,
transitive=true walk, transitive=false short-walk, and the standalone
matchesDependentTaskOutputs accessor.
Copy link
Copy Markdown
Contributor

@nx-cloud nx-cloud Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nx Cloud is proposing a fix for your failed CI:

We removed five // eslint-disable-next-line import/order comments from task-file-resolver.spec.ts that were referencing an ESLint rule not registered in this project's configuration. Because eslint-plugin-import is not set up here, ESLint treats each disable comment as an error ("Definition for rule 'import/order' was not found"), causing the nx:lint task to fail. Dropping the comments resolves all five lint errors without altering any functional code or import logic.

Warning

We could not verify this fix.

diff --git a/packages/nx/src/hasher/task-file-resolver.spec.ts b/packages/nx/src/hasher/task-file-resolver.spec.ts
index 3b1a6f18..f138f70d 100644
--- a/packages/nx/src/hasher/task-file-resolver.spec.ts
+++ b/packages/nx/src/hasher/task-file-resolver.spec.ts
@@ -27,15 +27,10 @@ jest.mock('./task-hasher', () => ({
 
 // ── Imports (after mocks) ────────────────────────────────────────────────────
 
-// eslint-disable-next-line import/order
 import { HashPlanInspector } from './hash-plan-inspector';
-// eslint-disable-next-line import/order
 import { getOutputsForTargetAndConfiguration } from '../tasks-runner/utils';
-// eslint-disable-next-line import/order
 import { createTaskGraph } from '../tasks-runner/create-task-graph';
-// eslint-disable-next-line import/order
 import { getInputs as mockedGetInputs } from './task-hasher';
-// eslint-disable-next-line import/order
 import { createTaskFileResolver } from './task-file-resolver';
 
 const MockHashPlanInspector = jest.mocked(HashPlanInspector);

🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.

Apply fix via Nx Cloud  Reject fix via Nx Cloud


Or Apply changes locally with:

npx nx-cloud apply-locally mhOE-JwVl

Apply fix locally with your editor ↗   View interactive diff ↗



🎓 Learn more about Self-Healing CI on nx.dev

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant