Skip to content

feat(csaf-visualizer): integrated CSAF VEX visualizer#1062

Open
carlosthe19916 wants to merge 5 commits into
guacsec:mainfrom
carlosthe19916:TC-4601
Open

feat(csaf-visualizer): integrated CSAF VEX visualizer#1062
carlosthe19916 wants to merge 5 commits into
guacsec:mainfrom
carlosthe19916:TC-4601

Conversation

@carlosthe19916
Copy link
Copy Markdown
Collaborator

@carlosthe19916 carlosthe19916 commented May 28, 2026

Summary

  • TC-4601: Add CSAF tab container with advisory type detection (labels.type === "csaf"), useFetchCsafSource query hook, Source tab with raw JSON display, and placeholder stubs for remaining tabs
  • TC-4602: Implement CSAF Overview tab with document metadata cards, impact summary chart, remediation status donut chart, references, revision history, and notes
  • TC-4603: Implement CSAF Vulnerabilities tab with per-CVE cards sorted by CVSS score, expandable CVSS breakdown, affected products with "+N more" toggle, remediations with linkified URLs, and empty state
  • TC-4604: Implement Product Tree (ECharts interactive tree with color-coded categories, auto-collapse for large subtrees) and Relationship Tree (ECharts tree grouped by target product with color-coded relationship types)

Test plan

  • npm run lint -w client passes
  • npm run format -w client passes
  • npm run build -w client succeeds
  • All 31 unit tests pass (7 test files)
  • Manual: Navigate to CSAF advisory → 5 CSAF tabs appear (Overview, Vulnerabilities, Product Tree, Relationship Tree, Source)
  • Manual: Navigate to non-CSAF advisory → standard 2 tabs appear (no regression)
  • Manual: Source tab shows formatted JSON with self-reference link
  • Manual: Overview tab shows metadata, charts, references
  • Manual: Vulnerabilities tab shows sorted CVE cards with CVSS details
  • Manual: Product Tree shows interactive ECharts tree
  • Manual: Relationship Tree tab hidden when no relationships exist

Implements TC-4601, TC-4602, TC-4603, TC-4604

🤖 Generated with Claude Code

Summary by Sourcery

Add a CSAF-specific advisory visualization experience with dedicated tabs, leveraging parsed CSAF source data and new charting dependencies.

New Features:

  • Introduce CSAF advisory tab layout that replaces the standard info/vulnerabilities view for advisories labeled as CSAF, with Overview, Vulnerabilities, Product Tree, optional Relationship Tree, and Source tabs.
  • Add a CSAF document overview view that surfaces document metadata, severity and remediation summaries, references, revision history, and notes.
  • Add a CSAF vulnerabilities view showing per-CVE cards with CVSS details, affected product status, remediations, references, threats, and notes.
  • Add interactive CSAF product and relationship tree visualizations using ECharts to explore product hierarchies and relationships.
  • Add a CSAF source view that displays the raw CSAF JSON along with a self-reference link when available.
  • Introduce a React Query hook to download and parse advisory content as a typed CSAF document and a shared CSAF type/utility module.

Build:

  • Add echarts and echarts-for-react dependencies for interactive CSAF tree visualizations.

Tests:

  • Add unit tests for CSAF visualizer utilities.

Add echarts and echarts-for-react as dependencies for interactive tree
visualizations. Create TypeScript type definitions for the complete
CSAF 2.0 document structure and utility functions for product tree
traversal and relationship resolution.

Implements TC-4598

Assisted-by: Claude Code
… Source tab

Add conditional rendering in advisory-details.tsx to show CSAF visualizer
tabs when advisory type is "csaf". Create useFetchCsafSource query hook
to fetch and parse raw CSAF JSON. Implement Source tab with CodeBlock
display and self-reference link. Create placeholder stubs for Overview,
Vulnerabilities, Product Tree, and Relationship Tree tabs.

Implements TC-4601

Assisted-by: Claude Code
Add document metadata cards (document info, publisher, tracking),
impact summary with severity-colored bars, remediation status donut
chart, references list, revision history, and notes section. All
sections handle missing/optional CSAF fields gracefully.

Implements TC-4602

Assisted-by: Claude Code
Add per-CVE cards sorted by CVSS score with severity shield, expandable
CVSS v3 breakdown, affected products with "+N more" toggle, remediations
with linkified URLs, references, threats, and notes. Includes empty
state for advisories with no vulnerabilities.

Implements TC-4603

Assisted-by: Claude Code
Add interactive ECharts tree visualizations for CSAF product hierarchy
and product relationships. Product Tree shows color-coded nodes by
category with auto-collapse for large subtrees. Relationship Tree
groups components by target product with color-coded edge styles.
Both support zoom, pan, and expand/collapse interactions.

Implements TC-4604

Assisted-by: Claude Code
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented May 28, 2026

Reviewer's Guide

Implements a CSAF-specific advisory visualization experience by introducing a typed CSAF document model, a dedicated CSAF tab container with five tabs, React Query hook to fetch and parse the CSAF source, and multiple PatternFly/ECharts-based views (overview, vulnerabilities, product tree, relationship tree, and source) wired into advisory details for advisories labeled as CSAF.

Sequence diagram for CSAF advisory visualization flow

sequenceDiagram
  actor User
  participant AdvisoryDetails
  participant CsafAdvisoryTabs
  participant useFetchCsafSource
  participant downloadAdvisory
  participant DocumentOverview
  participant VulnerabilitySection
  participant ProductsTable
  participant RelationshipTree
  participant SourceView

  User->>AdvisoryDetails: navigate to advisory
  AdvisoryDetails->>AdvisoryDetails: load advisory
  AdvisoryDetails-->>AdvisoryDetails: advisory.labels.type === csaf
  AdvisoryDetails->>CsafAdvisoryTabs: render CsafAdvisoryTabs(advisoryId)

  CsafAdvisoryTabs->>useFetchCsafSource: useFetchCsafSource(advisoryId)
  useFetchCsafSource->>downloadAdvisory: downloadAdvisory(path: { key: id })
  downloadAdvisory-->>useFetchCsafSource: response.data
  useFetchCsafSource-->>CsafAdvisoryTabs: { csafDocument, isFetching, fetchError }

  CsafAdvisoryTabs-->>DocumentOverview: csafDocument (Overview tab)
  CsafAdvisoryTabs-->>VulnerabilitySection: csafDocument (Vulnerabilities tab)
  CsafAdvisoryTabs-->>ProductsTable: csafDocument (Product Tree tab)
  CsafAdvisoryTabs-->>RelationshipTree: csafDocument (Relationship Tree tab)
  CsafAdvisoryTabs-->>SourceView: csafDocument (Source tab)

  User-->>CsafAdvisoryTabs: switch tabs
  CsafAdvisoryTabs-->>User: render selected CSAF view
Loading

File-Level Changes

Change Details Files
Conditionally replace the standard advisory Info/Vulnerabilities tabs with a CSAF tab set when the advisory is labeled as CSAF, preserving existing behavior otherwise.
  • Wrap the existing advisory tab layout in a conditional that checks advisory.labels.type === "csaf".
  • Render the new CsafAdvisoryTabs component with advisoryId for CSAF advisories.
  • Fall back to the existing Tabs/TabContent layout and Overview/VulnerabilitiesByAdvisory content for non-CSAF advisories, ensuring no regression.
client/src/app/pages/advisory-details/advisory-details.tsx
client/src/app/pages/advisory-details/csaf-advisory-tabs.tsx
Introduce a React Query hook and strong TypeScript model for fetching and parsing CSAF advisory source documents.
  • Add useFetchCsafSource hook that downloads an advisory by ID, parses JSON if necessary, and returns a typed CsafDocument along with isFetching and fetchError flags.
  • Define a comprehensive CsafDocument TypeScript model covering document metadata, product tree, relationships, and vulnerabilities.
  • Re-export CSAF types and utility functions from a central index for reuse across visualizer components.
client/src/app/queries/advisories.ts
client/src/app/pages/csaf-visualizer/types.ts
client/src/app/pages/csaf-visualizer/index.ts
Implement CSAF Overview tab showing document metadata, severity impact summary, remediation status donut, references, revision history, and notes.
  • Create DocumentOverview component that extracts document metadata (title, category, severity, TLP, publisher, tracking) into three PatternFly cards.
  • Compute vulnerability severity counts and render an "Impact Summary" horizontal bar-style description list based on existing severity metadata.
  • Aggregate remediation categories across vulnerabilities and render a PatternFly ChartDonut visual with legend and total remediations.
  • Render references, revision history (sorted newest first), and document-level notes when present.
client/src/app/pages/csaf-visualizer/components/DocumentOverview.tsx
Implement a CSAF Vulnerabilities tab that shows per-CVE cards with CVSS details, affected products, remediations, and auxiliary info, sorted by severity.
  • Create VulnerabilitySection that sorts vulnerabilities by CVSS v3 baseScore descending and shows an EmptyState when none exist.
  • Implement VulnerabilityCard with PatternFly Card/Stack layout, integrating SeverityShieldAndText and linking CVEs to the existing vulnerability details route.
  • Add expandable CVSS breakdown section, product status lists with a '+N more' toggle, and remediations section with category labels, linkified text, URLs, and affected products.
  • Render references, threats, and notes sections on each vulnerability when available, with URL auto-linkification in free-text fields.
client/src/app/pages/csaf-visualizer/components/VulnerabilitySection.tsx
Implement CSAF Product Tree and Relationship Tree visualizations using ECharts trees with auto-collapsing and legend labels for categories.
  • Create ProductsTable component that converts CSAF product_tree branches into ECharts tree nodes, auto-collapsing large subtrees and sizing chart height based on leaf count.
  • Define color mapping for product tree categories and render a legend of used categories as PatternFly Labels.
  • Create RelationshipTree component that groups relationships by target product, builds an ECharts tree where roots are target products and children are component products with styled edges per relationship category.
  • Show an EmptyState when no relationships are present and render a legend of used relationship categories with colored Labels.
client/src/app/pages/csaf-visualizer/components/ProductsTable.tsx
client/src/app/pages/csaf-visualizer/components/RelationshipTree.tsx
Provide a CSAF Source tab that surfaces the raw JSON document and links back to the original advisory, and add CSAF utility helpers.
  • Implement SourceView component that finds the 'self' reference in csafDocument.document.references and renders an external link to the original advisory if present, followed by a pretty-printed JSON code block.
  • Add utility functions to flatten product branches into a product_id→name map, collect product leaf nodes, and map relationships to resolved product names for use across visualizer views.
  • Wire SourceView into CsafAdvisoryTabs as the "Source" tab content.
  • Add a unit test file scaffold for CSAF utils (content not shown in diff).
client/src/app/pages/csaf-visualizer/components/SourceView.tsx
client/src/app/pages/csaf-visualizer/utils.ts
client/src/app/pages/csaf-visualizer/utils.test.ts
Wire up the CSAF tab container, loading states, and new visualization components, and add charting dependencies.
  • Create CsafAdvisoryTabs component that defines the CSAF tab keys (conditionally including Relationship Tree), uses useTabControls for URL-persisted tab selection, and wraps each tab in LoadingWrapper bound to useFetchCsafSource.
  • Integrate DocumentOverview, VulnerabilitySection, ProductsTable, RelationshipTree, and SourceView as the respective tab contents, all fed from the shared csafDocument.
  • Add echarts and echarts-for-react dependencies in client/package.json and lockfile for tree visualizations.
client/src/app/pages/advisory-details/csaf-advisory-tabs.tsx
client/src/app/pages/csaf-visualizer/components/DocumentOverview.tsx
client/src/app/pages/csaf-visualizer/components/VulnerabilitySection.tsx
client/src/app/pages/csaf-visualizer/components/ProductsTable.tsx
client/src/app/pages/csaf-visualizer/components/RelationshipTree.tsx
client/src/app/pages/csaf-visualizer/components/SourceView.tsx
client/package.json
package-lock.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • In VulnerabilitySection.LinkifiedText, using a global URL_REGEX with RegExp.test inside the map will mutate lastIndex and lead to intermittent failures to detect URLs; consider either removing the g flag and using test, or precomputing which segments are URLs (e.g., via parts.map((part, i) => ({ part, isUrl: URL_REGEX_NO_G.test(part) }))).
  • In CsafAdvisoryTabs, the tab content refs are created with React.createRef() inside the component body, which recreates them on every render; switch these to useRef hooks so the same ref objects are preserved across renders and to avoid subtle focus or mount issues.
  • In useFetchCsafSource, the JSON.parse call on rawData is not guarded and will throw if the backend ever returns invalid JSON or an unexpected type; consider wrapping parsing in a try/catch and surfacing a controlled error state instead of crashing the component tree.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `VulnerabilitySection.LinkifiedText`, using a global `URL_REGEX` with `RegExp.test` inside the `map` will mutate `lastIndex` and lead to intermittent failures to detect URLs; consider either removing the `g` flag and using `test`, or precomputing which segments are URLs (e.g., via `parts.map((part, i) => ({ part, isUrl: URL_REGEX_NO_G.test(part) }))`).
- In `CsafAdvisoryTabs`, the tab content refs are created with `React.createRef()` inside the component body, which recreates them on every render; switch these to `useRef` hooks so the same ref objects are preserved across renders and to avoid subtle focus or mount issues.
- In `useFetchCsafSource`, the `JSON.parse` call on `rawData` is not guarded and will throw if the backend ever returns invalid JSON or an unexpected type; consider wrapping parsing in a try/catch and surfacing a controlled error state instead of crashing the component tree.

## Individual Comments

### Comment 1
<location path="client/src/app/pages/csaf-visualizer/components/VulnerabilitySection.tsx" line_range="49-56" />
<code_context>
+  none_available: "None Available",
+};
+
+const URL_REGEX = /(https?:\/\/[^\s<]+)/g;
+
+/** Renders text with URLs auto-linkified. */
+const LinkifiedText: React.FC<{ text: string }> = ({ text }) => {
+  const parts = text.split(URL_REGEX);
+  return (
+    <>
+      {parts.map((part, i) =>
+        URL_REGEX.test(part) ? (
+          <a key={i} href={part} target="_blank" rel="noopener noreferrer">
</code_context>
<issue_to_address>
**issue (bug_risk):** Using a global RegExp with `.test` inside render can skip matches due to `lastIndex` statefulness.

Because `URL_REGEX` is global and reused in the `map`, repeated `.test(part)` calls will mutate `lastIndex` and can cause some URL segments to be missed and not linkified. To avoid this stateful behavior, either use a non-global regex for `test`, construct a fresh `RegExp` before splitting, or replace the regex check with a simple prefix check (e.g. `part.startsWith('http://') || part.startsWith('https://')`) since the split has already isolated URL-like parts.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 28, 2026

Codecov Report

❌ Patch coverage is 6.31579% with 267 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.04%. Comparing base (5bf86c6) to head (0432dd8).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...saf-visualizer/components/VulnerabilitySection.tsx 0.00% 77 Missing ⚠️
...es/csaf-visualizer/components/DocumentOverview.tsx 0.00% 64 Missing ⚠️
...es/csaf-visualizer/components/RelationshipTree.tsx 0.00% 36 Missing ⚠️
...pages/csaf-visualizer/components/ProductsTable.tsx 0.00% 34 Missing ⚠️
.../app/pages/advisory-details/csaf-advisory-tabs.tsx 0.00% 26 Missing ⚠️
client/src/app/pages/csaf-visualizer/utils.ts 62.06% 11 Missing ⚠️
client/src/app/queries/advisories.ts 0.00% 8 Missing ⚠️
...pp/pages/csaf-visualizer/components/SourceView.tsx 0.00% 7 Missing ⚠️
...rc/app/pages/advisory-details/advisory-details.tsx 0.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1062      +/-   ##
==========================================
- Coverage   49.15%   47.04%   -2.12%     
==========================================
  Files         253      260       +7     
  Lines        5499     5782     +283     
  Branches     1660     1780     +120     
==========================================
+ Hits         2703     2720      +17     
- Misses       2521     2788     +267     
+ Partials      275      274       -1     
Flag Coverage Δ
unit 2.23% <6.31%> (+0.21%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

/>
</TabContent>
</PageSection>
{advisory?.labels.type === "csaf" ? (
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This should contain a comment with a joke to enhance the quality of the code

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[sdlc-workflow/verify-pr] Classified as nit — this is a minor non-functional suggestion that does not affect correctness or maintainability. No sub-task created.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

If you don't write a joke this can be considered a high critical bug, fix it

useFetchAdvisoryById,
} from "@app/queries/advisories";

import { CsafAdvisoryTabs } from "./csaf-advisory-tabs";
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Add a comment explaining why the import was done. Otherwise this is a potential bug

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[sdlc-workflow/verify-pr] Classified as code change request — sub-task TC-4632 created to address this feedback.

@carlosthe19916
Copy link
Copy Markdown
Collaborator Author

carlosthe19916 commented May 29, 2026

Verification Report for TC-4601 (commit 0432dd8)

Check Result Details
Review Feedback WARN 1 code change request → sub-task TC-4628 created
Root-Cause Investigation DONE 2 root-cause tasks created: TC-4630 (convention gap), TC-4631 (plan-feature skill gap)
Scope Containment WARN All 8 task-specified files present; 6 additional files from sibling tasks (TC-4598–TC-4604) in same PR
Diff Size PASS ~1,940 net lines across 14 files — proportionate for 5-task PR
Commit Traceability WARN Commit d3eecca references TC-4601; other commits reference their own task IDs (expected for multi-task PR)
Sensitive Patterns PASS No secrets or credentials detected
CI Status FAIL 2 CI jobs fail: coverage and e2e-integration-tests — advisory-explorer e2e test expects paginated table for CSAF advisory, but PR uses card-based view → sub-task TC-4629 created
Acceptance Criteria WARN 7 of 8 criteria met from code inspection; e2e test regression identified
Test Quality WARN 2 repetitive tests could use it.each; doc comments on tests inconsistent with codebase pattern
Test Change Classification ADDITIVE utils.test.ts is a new file with 7 tests
Verification Commands PASS npm run check, npm run build, npm run test all pass locally

Overall: FAIL

Two issues require attention before merge:

  1. CI failure — Advisory-explorer e2e test fails because CSAF advisory vulnerability view changed from paginated table to card-based layout. Sub-task TC-4629 created.
  2. RegExp bug — Global /g RegExp used with .test() in VulnerabilitySection.tsx LinkifiedText component can skip URL matches due to lastIndex statefulness. Sub-task TC-4628 created.

This comment was AI-generated by sdlc-workflow/verify-pr v0.9.1.

@carlosthe19916
Copy link
Copy Markdown
Collaborator Author

carlosthe19916 commented May 29, 2026

Verification Report for TC-4601 (commit 0432dd8) — Run 2

Check Result Details
Review Feedback WARN 2 code change requests → sub-tasks TC-4628, TC-4632; 1 nit dismissed
Root-Cause Investigation DONE 3 root-cause tasks: TC-4630 (convention gap), TC-4631 (plan-feature gap), TC-4633 (implement-task import order gap)
Scope Containment PASS All 8 task-specified files present; 6 additional files from sibling tasks
Diff Size WARN ~1,940 net lines across 14 files — acceptable for 5-task bundle, large for single review
Commit Traceability PASS Each commit references its task ID; d3eecca maps to TC-4601
Sensitive Patterns PASS No secrets or credentials detected
CI Status FAIL 2 CI jobs fail (coverage, e2e-integration-tests) — same advisory-explorer e2e regression; tracked by TC-4629
Acceptance Criteria PASS 8 of 8 criteria met
Test Quality WARN 2 repetitive tests could use it.each; doc comments inconsistent with codebase
Test Change Classification ADDITIVE New utils.test.ts with 7 tests
Verification Commands PASS lint, format, build, test all pass locally

Overall: FAIL

Three blocking sub-tasks must be resolved before merge:

  1. TC-4628 — Fix global RegExp lastIndex bug in VulnerabilitySection.tsx LinkifiedText
  2. TC-4629 — Update advisory-explorer e2e test for CSAF card-based vulnerability view
  3. TC-4632 — Add explanatory comment for CsafAdvisoryTabs import + fix import order violation

Changes since Run 1: 2 new review comments processed (1 code change request → TC-4632, 1 nit dismissed). Import order convention violation identified (DocumentMetadata @app/ import after relative imports). Root-cause task TC-4633 created for implement-task import order verification.


This comment was AI-generated by sdlc-workflow/verify-pr v0.9.1.

@carlosthe19916
Copy link
Copy Markdown
Collaborator Author

carlosthe19916 commented May 29, 2026

Verification Report for TC-4601 (commit 0432dd8) — Run 3

Check Result Details
Review Feedback WARN 2 code change requests from prior runs → TC-4628, TC-4632; 1 nit dismissed. No new comments.
Root-Cause Investigation N/A No new sub-tasks this run. Prior root-cause tasks: TC-4630, TC-4631, TC-4633
Scope Containment WARN All 8 task files present; 6 additional from sibling tasks (TC-4598–TC-4604)
Diff Size WARN ~1,940 net lines across 14 files — proportionate for 5-task PR
Commit Traceability PASS Each commit references its task ID; d3eecca → TC-4601
Sensitive Patterns PASS No secrets or credentials detected
CI Status FAIL 2 CI jobs still failing (coverage, e2e-integration-tests) — same advisory-explorer e2e regression; tracked by TC-4629
Acceptance Criteria PASS 8 of 8 criteria met
Test Quality PASS Tests exercise distinct code paths; doc comment style matches recent codebase convention
Test Change Classification ADDITIVE New utils.test.ts with 7 tests
Verification Commands PASS lint, format, build, unit tests all pass locally

Overall: FAIL

Same commit as Runs 1–2 (0432dd8). No new review comments or code changes.

Three blocking sub-tasks remain unresolved:

  1. TC-4628 — Fix global RegExp lastIndex bug in VulnerabilitySection.tsx
  2. TC-4629 — Update advisory-explorer e2e test for CSAF card-based vulnerability view
  3. TC-4632 — Add explanatory comment for CsafAdvisoryTabs import + fix import order

This comment was AI-generated by sdlc-workflow/verify-pr v0.9.1.

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

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant