test: add failing test for multiple JSON output#559
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Make the legacy CLI just another SCAPlugin in the SBOM resolution path, collapsing the SBOM-vs-legacy fork in handleSBOMResolutionDI into a single plugin-agnostic loop. The replacement legacy plugin in pkg/ecosystems/legacy wraps the (tested) legacycli.HandleLegacyResolution path, so the existing legacy invocation behavior is preserved while the old untested resolver implementation is removed. Notable behavior changes: - The "no supported projects detected" error now fires whenever the combined results across all plugins are zero, replacing the old legacy-specific exit-code-3 trigger. Errored-but-empty legacy output (errNoDepGraphsFound) collapses into the same path. - uv (and other) plugin results are now returned even when legacy errors with errNoDepGraphsFound, where they used to be discarded. - With --fail-fast --all-projects, per-result errors from legacy now trigger fail-fast like any other plugin's errors. Previously they were silently demoted to warnings. - Excludes flow between plugins via opts.Global.Exclude rather than via live-config mutation; processed files from earlier plugins land in later plugins' options without applyProcessedFilesExclusions. Other moves and cleanups: - isExitCode3 / ExitCoder moved from pkg/depgraph to internal/legacycli so the legacy plugin (in pkg/ecosystems) can import them without a cycle. - InvokeLegacy extracted from HandleLegacyResolution so the plugin can consume parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity that workflow.Data metadata cannot carry). - The dead helpers executeLegacyWorkflow, processLegacyData, extractProblemResults and applyProcessedFilesExclusions are removed. - pkg/ecosystems/orchestrator now uses legacy.NewPlugin instead of the (now-deleted) legacy.NewLegacyResolver. - A per-result CLI error from the legacy CLI is no longer overwritten by a downstream depgraph unmarshal failure. The uv workspace-packages JSONL bundling — previously decided on a flag combination in handleSBOMResolutionDI — is now gated by a clearly named helper (isMonitorJSONLBridgeInvocation) on uv plugin identity plus the internal-uv-workspace-packages flag. The helper carries a comment explaining why the workaround exists (snyk monitor still calls our Go depgraph workflow from TS and parses stdout as JSONL; only the first workflow.Data reaches stdout per snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin in the SBOM resolution path, collapsing the SBOM-vs-legacy fork in handleSBOMResolutionDI into a single plugin-agnostic loop. The replacement legacy plugin in pkg/ecosystems/legacy wraps the (tested) legacycli.HandleLegacyResolution path, so the existing legacy invocation behavior is preserved while the old untested resolver implementation is removed. Notable behavior changes: - The "no supported projects detected" error now fires whenever the combined results across all plugins are zero, replacing the old legacy-specific exit-code-3 trigger. Errored-but-empty legacy output (errNoDepGraphsFound) collapses into the same path. - uv (and other) plugin results are now returned even when legacy errors with errNoDepGraphsFound, where they used to be discarded. - With --fail-fast --all-projects, per-result errors from legacy now trigger fail-fast like any other plugin's errors. Previously they were silently demoted to warnings. - Excludes flow between plugins via opts.Global.Exclude rather than via live-config mutation; processed files from earlier plugins land in later plugins' options without applyProcessedFilesExclusions. Other moves and cleanups: - isExitCode3 / ExitCoder moved from pkg/depgraph to internal/legacycli so the legacy plugin (in pkg/ecosystems) can import them without a cycle. - InvokeLegacy extracted from HandleLegacyResolution so the plugin can consume parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity that workflow.Data metadata cannot carry). - The dead helpers executeLegacyWorkflow, processLegacyData, extractProblemResults and applyProcessedFilesExclusions are removed. - pkg/ecosystems/orchestrator now uses legacy.NewPlugin instead of the (now-deleted) legacy.NewLegacyResolver. - A per-result CLI error from the legacy CLI is no longer overwritten by a downstream depgraph unmarshal failure. The uv workspace-packages JSONL bundling — previously decided on a flag combination in handleSBOMResolutionDI — is now gated by a clearly named helper (isMonitorJSONLBridgeInvocation) on uv plugin identity plus the internal-uv-workspace-packages flag. The helper carries a comment explaining why the workaround exists (snyk monitor still calls our Go depgraph workflow from TS and parses stdout as JSONL; only the first workflow.Data reaches stdout per snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin in the SBOM resolution path, collapsing the SBOM-vs-legacy fork in handleSBOMResolutionDI into a single plugin-agnostic loop. The replacement legacy plugin in pkg/ecosystems/legacy wraps the (tested) legacycli.HandleLegacyResolution path, so the existing legacy invocation behavior is preserved while the old untested resolver implementation is removed. Notable behavior changes: - The "no supported projects detected" error now fires whenever the combined results across all plugins are zero, replacing the old legacy-specific exit-code-3 trigger. Errored-but-empty legacy output (errNoDepGraphsFound) collapses into the same path. - uv (and other) plugin results are now returned even when legacy errors with errNoDepGraphsFound, where they used to be discarded. - With --fail-fast --all-projects, per-result errors from legacy now trigger fail-fast like any other plugin's errors. Previously they were silently demoted to warnings. - Excludes flow between plugins via opts.Global.Exclude rather than via live-config mutation; processed files from earlier plugins land in later plugins' options without applyProcessedFilesExclusions. Other moves and cleanups: - isExitCode3 / ExitCoder moved from pkg/depgraph to internal/legacycli so the legacy plugin (in pkg/ecosystems) can import them without a cycle. - InvokeLegacy extracted from HandleLegacyResolution so the plugin can consume parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity that workflow.Data metadata cannot carry). - The dead helpers executeLegacyWorkflow, processLegacyData, extractProblemResults and applyProcessedFilesExclusions are removed. - pkg/ecosystems/orchestrator now uses legacy.NewPlugin instead of the (now-deleted) legacy.NewLegacyResolver. - A per-result CLI error from the legacy CLI is no longer overwritten by a downstream depgraph unmarshal failure. The uv workspace-packages JSONL bundling — previously decided on a flag combination in handleSBOMResolutionDI — is now gated by a clearly named helper (isMonitorJSONLBridgeInvocation) on uv plugin identity plus the internal-uv-workspace-packages flag. The helper carries a comment explaining why the workaround exists (snyk monitor still calls our Go depgraph workflow from TS and parses stdout as JSONL; only the first workflow.Data reaches stdout per snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin in the SBOM resolution path, collapsing the SBOM-vs-legacy fork in handleSBOMResolutionDI into a single plugin-agnostic loop. The replacement legacy plugin in pkg/ecosystems/legacy wraps the (tested) legacycli.HandleLegacyResolution path, so the existing legacy invocation behavior is preserved while the old untested resolver implementation is removed. Notable behavior changes: - The "no supported projects detected" error now fires whenever the combined results across all plugins are zero, replacing the old legacy-specific exit-code-3 trigger. Errored-but-empty legacy output (errNoDepGraphsFound) collapses into the same path. - uv (and other) plugin results are now returned even when legacy errors with errNoDepGraphsFound, where they used to be discarded. - With --fail-fast --all-projects, per-result errors from legacy now trigger fail-fast like any other plugin's errors. Previously they were silently demoted to warnings. - Excludes flow between plugins via opts.Global.Exclude rather than via live-config mutation; processed files from earlier plugins land in later plugins' options without applyProcessedFilesExclusions. Other moves and cleanups: - isExitCode3 / ExitCoder moved from pkg/depgraph to internal/legacycli so the legacy plugin (in pkg/ecosystems) can import them without a cycle. - InvokeLegacy extracted from HandleLegacyResolution so the plugin can consume parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity that workflow.Data metadata cannot carry). - The dead helpers executeLegacyWorkflow, processLegacyData, extractProblemResults and applyProcessedFilesExclusions are removed. - pkg/ecosystems/orchestrator now uses legacy.NewPlugin instead of the (now-deleted) legacy.NewLegacyResolver. - A per-result CLI error from the legacy CLI is no longer overwritten by a downstream depgraph unmarshal failure. The uv workspace-packages JSONL bundling — previously decided on a flag combination in handleSBOMResolutionDI — is now gated by a clearly named helper (isMonitorJSONLBridgeInvocation) on uv plugin identity plus the internal-uv-workspace-packages flag. The helper carries a comment explaining why the workaround exists (snyk monitor still calls our Go depgraph workflow from TS and parses stdout as JSONL; only the first workflow.Data reaches stdout per snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin in the SBOM resolution path, collapsing the SBOM-vs-legacy fork in handleSBOMResolutionDI into a single plugin-agnostic loop. The replacement legacy plugin in pkg/ecosystems/legacy wraps the (tested) legacycli.HandleLegacyResolution path, so the existing legacy invocation behavior is preserved while the old untested resolver implementation is removed. Notable behavior changes: - The "no supported projects detected" error now fires whenever the combined results across all plugins are zero, replacing the old legacy-specific exit-code-3 trigger. Errored-but-empty legacy output (errNoDepGraphsFound) collapses into the same path. - uv (and other) plugin results are now returned even when legacy errors with errNoDepGraphsFound, where they used to be discarded. - With --fail-fast --all-projects, per-result errors from legacy now trigger fail-fast like any other plugin's errors. Previously they were silently demoted to warnings. - Excludes flow between plugins via opts.Global.Exclude rather than via live-config mutation; processed files from earlier plugins land in later plugins' options without applyProcessedFilesExclusions. Other moves and cleanups: - isExitCode3 / ExitCoder moved from pkg/depgraph to internal/legacycli so the legacy plugin (in pkg/ecosystems) can import them without a cycle. - InvokeLegacy extracted from HandleLegacyResolution so the plugin can consume parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity that workflow.Data metadata cannot carry). - The dead helpers executeLegacyWorkflow, processLegacyData, extractProblemResults and applyProcessedFilesExclusions are removed. - pkg/ecosystems/orchestrator now uses legacy.NewPlugin instead of the (now-deleted) legacy.NewLegacyResolver. - A per-result CLI error from the legacy CLI is no longer overwritten by a downstream depgraph unmarshal failure. The uv workspace-packages JSONL bundling — previously decided on a flag combination in handleSBOMResolutionDI — is now gated by a clearly named helper (isMonitorJSONLBridgeInvocation) on uv plugin identity plus the internal-uv-workspace-packages flag. The helper carries a comment explaining why the workaround exists (snyk monitor still calls our Go depgraph workflow from TS and parses stdout as JSONL; only the first workflow.Data reaches stdout per snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin in the SBOM resolution path, collapsing the SBOM-vs-legacy fork in handleSBOMResolutionDI into a single plugin-agnostic loop. The replacement legacy plugin in pkg/ecosystems/legacy wraps the (tested) legacycli.HandleLegacyResolution path, so the existing legacy invocation behavior is preserved while the old untested resolver implementation is removed. Notable behavior changes: - The "no supported projects detected" error now fires whenever the combined results across all plugins are zero, replacing the old legacy-specific exit-code-3 trigger. Errored-but-empty legacy output (errNoDepGraphsFound) collapses into the same path. - uv (and other) plugin results are now returned even when legacy errors with errNoDepGraphsFound, where they used to be discarded. - With --fail-fast --all-projects, per-result errors from legacy now trigger fail-fast like any other plugin's errors. Previously they were silently demoted to warnings. - Excludes flow between plugins via opts.Global.Exclude rather than via live-config mutation; processed files from earlier plugins land in later plugins' options without applyProcessedFilesExclusions. Other moves and cleanups: - isExitCode3 / ExitCoder moved from pkg/depgraph to internal/legacycli so the legacy plugin (in pkg/ecosystems) can import them without a cycle. - InvokeLegacy extracted from HandleLegacyResolution so the plugin can consume parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity that workflow.Data metadata cannot carry). - The dead helpers executeLegacyWorkflow, processLegacyData, extractProblemResults and applyProcessedFilesExclusions are removed. - pkg/ecosystems/orchestrator now uses legacy.NewPlugin instead of the (now-deleted) legacy.NewLegacyResolver. - A per-result CLI error from the legacy CLI is no longer overwritten by a downstream depgraph unmarshal failure. The uv workspace-packages JSONL bundling — previously decided on a flag combination in handleSBOMResolutionDI — is now gated by a clearly named helper (isMonitorJSONLBridgeInvocation) on uv plugin identity plus the internal-uv-workspace-packages flag. The helper carries a comment explaining why the workaround exists (snyk monitor still calls our Go depgraph workflow from TS and parses stdout as JSONL; only the first workflow.Data reaches stdout per snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin in the SBOM resolution path, collapsing the SBOM-vs-legacy fork in handleSBOMResolutionDI into a single plugin-agnostic loop. The replacement legacy plugin in pkg/ecosystems/legacy wraps the (tested) legacycli.HandleLegacyResolution path, so the existing legacy invocation behavior is preserved while the old untested resolver implementation is removed. Notable behavior changes: - The "no supported projects detected" error now fires whenever the combined results across all plugins are zero, replacing the old legacy-specific exit-code-3 trigger. Errored-but-empty legacy output (errNoDepGraphsFound) collapses into the same path. - uv (and other) plugin results are now returned even when legacy errors with errNoDepGraphsFound, where they used to be discarded. - With --fail-fast --all-projects, per-result errors from legacy now trigger fail-fast like any other plugin's errors. Previously they were silently demoted to warnings. - Excludes flow between plugins via opts.Global.Exclude rather than via live-config mutation; processed files from earlier plugins land in later plugins' options without applyProcessedFilesExclusions. Other moves and cleanups: - isExitCode3 / ExitCoder moved from pkg/depgraph to internal/legacycli so the legacy plugin (in pkg/ecosystems) can import them without a cycle. - InvokeLegacy extracted from HandleLegacyResolution so the plugin can consume parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity that workflow.Data metadata cannot carry). - The dead helpers executeLegacyWorkflow, processLegacyData, extractProblemResults and applyProcessedFilesExclusions are removed. - pkg/ecosystems/orchestrator now uses legacy.NewPlugin instead of the (now-deleted) legacy.NewLegacyResolver. - A per-result CLI error from the legacy CLI is no longer overwritten by a downstream depgraph unmarshal failure. The uv workspace-packages JSONL bundling — previously decided on a flag combination in handleSBOMResolutionDI — is now gated by a clearly named helper (isMonitorJSONLBridgeInvocation) on uv plugin identity plus the internal-uv-workspace-packages flag. The helper carries a comment explaining why the workaround exists (snyk monitor still calls our Go depgraph workflow from TS and parses stdout as JSONL; only the first workflow.Data reaches stdout per snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin in the SBOM resolution path, collapsing the SBOM-vs-legacy fork in handleSBOMResolutionDI into a single plugin-agnostic loop. The replacement legacy plugin in pkg/ecosystems/legacy wraps the (tested) legacycli.HandleLegacyResolution path, so the existing legacy invocation behavior is preserved while the old untested resolver implementation is removed. Notable behavior changes: - The "no supported projects detected" error now fires whenever the combined results across all plugins are zero, replacing the old legacy-specific exit-code-3 trigger. Errored-but-empty legacy output (errNoDepGraphsFound) collapses into the same path. - uv (and other) plugin results are now returned even when legacy errors with errNoDepGraphsFound, where they used to be discarded. - With --fail-fast --all-projects, per-result errors from legacy now trigger fail-fast like any other plugin's errors. Previously they were silently demoted to warnings. - Excludes flow between plugins via opts.Global.Exclude rather than via live-config mutation; processed files from earlier plugins land in later plugins' options without applyProcessedFilesExclusions. Other moves and cleanups: - isExitCode3 / ExitCoder moved from pkg/depgraph to internal/legacycli so the legacy plugin (in pkg/ecosystems) can import them without a cycle. - InvokeLegacy extracted from HandleLegacyResolution so the plugin can consume parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity that workflow.Data metadata cannot carry). - The dead helpers executeLegacyWorkflow, processLegacyData, extractProblemResults and applyProcessedFilesExclusions are removed. - pkg/ecosystems/orchestrator now uses legacy.NewPlugin instead of the (now-deleted) legacy.NewLegacyResolver. - A per-result CLI error from the legacy CLI is no longer overwritten by a downstream depgraph unmarshal failure. The uv workspace-packages JSONL bundling — previously decided on a flag combination in handleSBOMResolutionDI — is now gated by a clearly named helper (isMonitorJSONLBridgeInvocation) on uv plugin identity plus the internal-uv-workspace-packages flag. The helper carries a comment explaining why the workaround exists (snyk monitor still calls our Go depgraph workflow from TS and parses stdout as JSONL; only the first workflow.Data reaches stdout per snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin in the SBOM resolution path, collapsing the SBOM-vs-legacy fork in handleSBOMResolutionDI into a single plugin-agnostic loop. The replacement legacy plugin in pkg/ecosystems/legacy wraps the (tested) legacycli.HandleLegacyResolution path, so the existing legacy invocation behavior is preserved while the old untested resolver implementation is removed. Notable behavior changes: - The "no supported projects detected" error now fires whenever the combined results across all plugins are zero, replacing the old legacy-specific exit-code-3 trigger. Errored-but-empty legacy output (errNoDepGraphsFound) collapses into the same path. - uv (and other) plugin results are now returned even when legacy errors with errNoDepGraphsFound, where they used to be discarded. - With --fail-fast --all-projects, per-result errors from legacy now trigger fail-fast like any other plugin's errors. Previously they were silently demoted to warnings. - Excludes flow between plugins via opts.Global.Exclude rather than via live-config mutation; processed files from earlier plugins land in later plugins' options without applyProcessedFilesExclusions. Other moves and cleanups: - isExitCode3 / ExitCoder moved from pkg/depgraph to internal/legacycli so the legacy plugin (in pkg/ecosystems) can import them without a cycle. - InvokeLegacy extracted from HandleLegacyResolution so the plugin can consume parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity that workflow.Data metadata cannot carry). - The dead helpers executeLegacyWorkflow, processLegacyData, extractProblemResults and applyProcessedFilesExclusions are removed. - pkg/ecosystems/orchestrator now uses legacy.NewPlugin instead of the (now-deleted) legacy.NewLegacyResolver. - A per-result CLI error from the legacy CLI is no longer overwritten by a downstream depgraph unmarshal failure. The uv workspace-packages JSONL bundling — previously decided on a flag combination in handleSBOMResolutionDI — is now gated by a clearly named helper (isMonitorJSONLBridgeInvocation) on uv plugin identity plus the internal-uv-workspace-packages flag. The helper carries a comment explaining why the workaround exists (snyk monitor still calls our Go depgraph workflow from TS and parses stdout as JSONL; only the first workflow.Data reaches stdout per snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin in the SBOM resolution path, collapsing the SBOM-vs-legacy fork in handleSBOMResolutionDI into a single plugin-agnostic loop. The replacement legacy plugin in pkg/ecosystems/legacy wraps the (tested) legacycli.HandleLegacyResolution path, so the existing legacy invocation behavior is preserved while the old untested resolver implementation is removed. Notable behavior changes: - The "no supported projects detected" error now fires whenever the combined results across all plugins are zero, replacing the old legacy-specific exit-code-3 trigger. Errored-but-empty legacy output (errNoDepGraphsFound) collapses into the same path. - uv (and other) plugin results are now returned even when legacy errors with errNoDepGraphsFound, where they used to be discarded. - With --fail-fast --all-projects, per-result errors from legacy now trigger fail-fast like any other plugin's errors. Previously they were silently demoted to warnings. - Excludes flow between plugins via opts.Global.Exclude rather than via live-config mutation; processed files from earlier plugins land in later plugins' options without applyProcessedFilesExclusions. Other moves and cleanups: - isExitCode3 / ExitCoder moved from pkg/depgraph to internal/legacycli so the legacy plugin (in pkg/ecosystems) can import them without a cycle. - InvokeLegacy extracted from HandleLegacyResolution so the plugin can consume parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity that workflow.Data metadata cannot carry). - The dead helpers executeLegacyWorkflow, processLegacyData, extractProblemResults and applyProcessedFilesExclusions are removed. - pkg/ecosystems/orchestrator now uses legacy.NewPlugin instead of the (now-deleted) legacy.NewLegacyResolver. - A per-result CLI error from the legacy CLI is no longer overwritten by a downstream depgraph unmarshal failure. The uv workspace-packages JSONL bundling — previously decided on a flag combination in handleSBOMResolutionDI — is now gated by a clearly named helper (isMonitorJSONLBridgeInvocation) on uv plugin identity plus the internal-uv-workspace-packages flag. The helper carries a comment explaining why the workaround exists (snyk monitor still calls our Go depgraph workflow from TS and parses stdout as JSONL; only the first workflow.Data reaches stdout per snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin in the SBOM resolution path, collapsing the SBOM-vs-legacy fork in handleSBOMResolutionDI into a single plugin-agnostic loop. The replacement legacy plugin in pkg/ecosystems/legacy wraps the (tested) legacycli.HandleLegacyResolution path, so the existing legacy invocation behavior is preserved while the old untested resolver implementation is removed. Notable behavior changes: - The "no supported projects detected" error now fires whenever the combined results across all plugins are zero, replacing the old legacy-specific exit-code-3 trigger. Errored-but-empty legacy output (errNoDepGraphsFound) collapses into the same path. - uv (and other) plugin results are now returned even when legacy errors with errNoDepGraphsFound, where they used to be discarded. - With --fail-fast --all-projects, per-result errors from legacy now trigger fail-fast like any other plugin's errors. Previously they were silently demoted to warnings. - Excludes flow between plugins via opts.Global.Exclude rather than via live-config mutation; processed files from earlier plugins land in later plugins' options without applyProcessedFilesExclusions. Other moves and cleanups: - isExitCode3 / ExitCoder moved from pkg/depgraph to internal/legacycli so the legacy plugin (in pkg/ecosystems) can import them without a cycle. - InvokeLegacy extracted from HandleLegacyResolution so the plugin can consume parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity that workflow.Data metadata cannot carry). - The dead helpers executeLegacyWorkflow, processLegacyData, extractProblemResults and applyProcessedFilesExclusions are removed. - pkg/ecosystems/orchestrator now uses legacy.NewPlugin instead of the (now-deleted) legacy.NewLegacyResolver. - A per-result CLI error from the legacy CLI is no longer overwritten by a downstream depgraph unmarshal failure. The uv workspace-packages JSONL bundling — previously decided on a flag combination in handleSBOMResolutionDI — is now gated by a clearly named helper (isMonitorJSONLBridgeInvocation) on uv plugin identity plus the internal-uv-workspace-packages flag. The helper carries a comment explaining why the workaround exists (snyk monitor still calls our Go depgraph workflow from TS and parses stdout as JSONL; only the first workflow.Data reaches stdout per snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin in the SBOM resolution path, collapsing the SBOM-vs-legacy fork in handleSBOMResolutionDI into a single plugin-agnostic loop. The replacement legacy plugin in pkg/ecosystems/legacy wraps the (tested) legacycli.HandleLegacyResolution path, so the existing legacy invocation behavior is preserved while the old untested resolver implementation is removed. Notable behavior changes: - The "no supported projects detected" error now fires whenever the combined results across all plugins are zero, replacing the old legacy-specific exit-code-3 trigger. Errored-but-empty legacy output (errNoDepGraphsFound) collapses into the same path. - uv (and other) plugin results are now returned even when legacy errors with errNoDepGraphsFound, where they used to be discarded. - With --fail-fast --all-projects, per-result errors from legacy now trigger fail-fast like any other plugin's errors. Previously they were silently demoted to warnings. - Excludes flow between plugins via opts.Global.Exclude rather than via live-config mutation; processed files from earlier plugins land in later plugins' options without applyProcessedFilesExclusions. Other moves and cleanups: - isExitCode3 / ExitCoder moved from pkg/depgraph to internal/legacycli so the legacy plugin (in pkg/ecosystems) can import them without a cycle. - InvokeLegacy extracted from HandleLegacyResolution so the plugin can consume parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity that workflow.Data metadata cannot carry). - The dead helpers executeLegacyWorkflow, processLegacyData, extractProblemResults and applyProcessedFilesExclusions are removed. - pkg/ecosystems/orchestrator now uses legacy.NewPlugin instead of the (now-deleted) legacy.NewLegacyResolver. - A per-result CLI error from the legacy CLI is no longer overwritten by a downstream depgraph unmarshal failure. The uv workspace-packages JSONL bundling — previously decided on a flag combination in handleSBOMResolutionDI — is now gated by a clearly named helper (isMonitorJSONLBridgeInvocation) on uv plugin identity plus the internal-uv-workspace-packages flag. The helper carries a comment explaining why the workaround exists (snyk monitor still calls our Go depgraph workflow from TS and parses stdout as JSONL; only the first workflow.Data reaches stdout per snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
Make the legacy CLI just another SCAPlugin so the SBOM resolution path collapses into a plugin-agnostic loop. Identity.Legacy + ProjectDescriptor.GetTargetFileForPlugin() carry the legacy CLI's plugin.targetFile suppression semantic for npm-non-workspace, maven, sbt, rubygems and requirements.txt — fixing the registry 500s caused by always emitting MetaKeyTargetFileFromPlugin. Behavior changes: - "no supported projects detected" fires when combined results across all plugins are zero (was legacy-specific exit-code-3). - uv results are returned even when legacy errors with ErrNoDepGraphsFound (previously discarded). - --fail-fast --all-projects: legacy per-result errors now trigger fail-fast uniformly with other plugins (previously demoted to warnings). - A per-result legacy CLI error is no longer overwritten by a downstream depgraph unmarshal failure. Supporting moves: isExitCode3/ExitCoder relocate to internal/legacycli to break an import cycle; InvokeLegacy is extracted so the plugin consumes parsed []DepGraphOutput directly (preserving Workspace and TargetRuntime fidelity workflow.Data metadata cannot carry); the uv JSONL bundling for snyk monitor's TS-to-Go bridge is gated by isMonitorJSONLBridgeInvocation (snyk/go-application-framework#559).
| // Expected: both JSON payloads should be in the output | ||
| outputStr := setup.writer.String() | ||
| assert.Contains(t, outputStr, "first-project", "First JSON payload should be in output") | ||
| assert.Contains(t, outputStr, "second-project", "Second JSON payload should be in output (BUG: this fails)") |
There was a problem hiding this comment.
[Critical] This is an ungated failing test — go test ./pkg/local_workflows/ fails here today ("...first-project..." does not contain "second-project"), empirically confirmed. There's no t.Skip, build tag, or other gate, and CI runs this in required gates, so merging it alone turns main red for every subsequent pipeline.
The bug it documents is real and well-diagnosed: HandleContentTypeOther loops per item and useWriterWithOther → PopWritersByMimetype deletes the writer from the map after the first use (writer.go:58-62), so the second application/json item finds no writer and is dropped. Nice reproduction.
Resolution (one required before merge): (a) land the production fix in this same PR so the test goes green on commit (preferred — a failing test should accompany its fix), or (b) t.Skip("<TICKET>: multiple application/json items dropped by PopWritersByMimetype — un-skip when fixed") to keep CI green while preserving the repro.
— AI review
| output, err := outputWorkflowEntryPoint(setup.invocationContextMock, []workflow.Data{data1, data2}, setup.outputDestination) | ||
|
|
||
| assert.Nil(t, err) | ||
| assert.Equal(t, []workflow.Data{}, output) |
There was a problem hiding this comment.
[Should Fix] This assertion is a tautology that gives false confidence. outputWorkflowEntryPoint always returns the empty slice declared at output_workflow.go:39 and discards the input/leftover returned by the Handle* calls, so output is []workflow.Data{} regardless of how many items were dropped — it passes in both the buggy and fixed states. It reads as if it verifies 'no data left unprocessed', but the dropped second item is in fact neither written nor returned; this assertion hides that. Drop it, or replace with one that pins a real contract (assert the second item is written, or surfaced as unconsumed — currently it's neither).
— AI review
|
The bug diagnosis here is genuinely good — a precise, deterministic reproduction of a real [Suggestion] The — AI review |
| // This test demonstrates a bug: when multiple application/json items are passed with --json flag, | ||
| // only the first item is output. The PopWritersByMimetype function removes the writer after the | ||
| // first use, causing subsequent items to find no writer available. | ||
| t.Run("should output all application/json items when json flag is set", func(t *testing.T) { |
There was a problem hiding this comment.
Should-Fix: This adds a knowingly-failing test with no accompanying fix. Verified by running it: assert.Contains(outputStr, "second-project") fails — writer output is {"project":"first-project",...} only. That fails the parent Test_Output_outputWorkflowEntryPoint and makes go test ./pkg/local_workflows/... exit non-zero. If this branch merges to main on its own it red-lines CI for every consumer of the package until the fix lands.
The bug it demonstrates is real and the root cause is correctly identified: writerMapImpl.PopWritersByMimetype (output_workflow/writer.go) does delete(w.writers, mimeType), so the single JSON writer is consumed by the first item and the second finds none.
Before merge, either land the production fix in the same PR/stack (test turns green), or quarantine with t.Skip("<ticket>: multiple application/json items drop all but the first") referencing the bug, removed by the fix commit. If this PR is deliberately the RED step of a stack whose next commit carries the fix, this is acceptable — flagging so the decision is explicit.
— AI review
| output, err := outputWorkflowEntryPoint(setup.invocationContextMock, []workflow.Data{data1, data2}, setup.outputDestination) | ||
|
|
||
| assert.Nil(t, err) | ||
| assert.Equal(t, []workflow.Data{}, output) |
There was a problem hiding this comment.
Suggestion (non-blocking): assert.Equal(t, []workflow.Data{}, output) is vacuous here — outputWorkflowEntryPoint initializes output := []workflow.Data{} and returns it unchanged (handler results are assigned back into input, never output), so this passes for the same trivial reason in every existing test and cannot detect the multiple-JSON bug. The meaningful signal is the writer content asserted below.
— AI review
Reviewed Should-Fix
Suggestions
Security scan: nothing attributable to this test-only diff. — AI review |
Summary
This PR adds a failing test that demonstrates an issue where only the first
workflow.Dataitem is output when multiple items withapplication/jsoncontent type are passed to the output workflow with--jsonflag.Question for the team: Is this intended behavior, or should multiple JSON items be output?
Problem
When a workflow returns multiple
workflow.Dataitems (e.g., scanning multiple lock files), only the first JSON result is printed tostdout. All subsequent results are silently dropped.Expectation
When encountering multiple
workflow.Datathey should all be output with the correct renderer. In this case withapplication/jsonI would expect the output to be JSONL/NDJSON. One line per JSON separated by a\ncharacter.