| name | cve-assessment |
| description | Use when assessing the impact of a CVE on any software project, component, or package. Optionally provide project_name and variant_name to auto-fetch variant context from VulnScout; otherwise supply platform context (package manager, build system, deployment environment) inline or rely on defaults. If the prompt explicitly requests a "strict assessment", the confidence gate becomes stricter (only HIGH confidence yields a definitive status; MEDIUM and LOW both submit under_investigation); by default, MEDIUM confidence can also yield a definitive status, while LOW confidence always submits under_investigation. |
CVE Assessment Skill
Overview
Guides a comprehensive security assessment of a CVE's impact on a software project. Given a CVE ID or GHSA ID plus platform context provided by the caller, the agent will:
- Research the vulnerability details from public databases (NVD, GitHub advisories)
- Analyze whether the affected component is installed in the target environment and at what version
- Assess whether the CVE compromises any of the project's defined security objectives
- Report a status (AFFECTED/EXPLOITABLE, FIXED/PATCHED, NOT APPLICABLE, or FALSE POSITIVE) with a concise impact summary
- Submit the assessment via the
vulnscout-write_assessment MCP tool — or, if an AI-generated assessment already exists and needs correcting (a stale duplicate found in Phase 5, or a mistake in the assessment this run just submitted), revise it via vulnscout-update_ai_assessment instead of creating a duplicate
Platform context (package manager, file paths, build system, deployment environment, runtime constraints) is resolved using a three-tier priority:
- MCP fetch — if
project_name is provided at invocation, resolve the variant context from VulnScout by chaining vulnscout-find_project_id → vulnscout-find_variant_id → vulnscout-get_merged_context; variant_name defaults to "default" if not specified
- Inline context — if platform context is described directly in the prompt, use it; skip MCP calls
- Default fallback — if neither is provided, proceed with
default.md objectives and no additional context
Workflow Overview
INPUT: CVE/GHSA ID + (project_name [+ variant_name]) OR inline platform context OR neither
↓
PHASE -1: Context Resolution → If project_name provided: chain vulnscout-find_project_id →
vulnscout-find_variant_id → vulnscout-get_merged_context (variant_name defaults to
"default"); store variant_id as resolved_variant_id for Phase 5;
if inline context provided: use it directly; otherwise: use defaults;
also resolve strict_mode from explicit prompt request (default: false)
↓
PHASE 0: Load Objectives File → Infer from threat_model / inline prompt; otherwise default.md
↓
PHASE 1: CVE Intelligence → Fetch NVD, resolve GHSA→CVE, extract details including affected component name and version ranges
↓
PHASE 2: Component Presence Analysis → Using environment from Phase -1 (or inline context), determine if affected component is installed, at what version, and in what scope (runtime vs. build-time)
↓
PHASE 3: Security Objectives Assessment → Evaluate if CVE compromises loaded security objectives; apply risks/other_info from Phase -1 as additional constraints
↓
PHASE 3.5: Confidence Score → Score assessment certainty HIGH/MEDIUM/LOW using defined rubric
↓
PHASE 4: Status Assignment → HIGH confidence: assign normal status; MEDIUM confidence: assign
normal status unless strict_mode is true (then under_investigation); LOW confidence:
always under_investigation
↓
PHASE 5: VulnScout Submission → Check has_ai_assessment for duplicates, then call vulnscout-write_assessment
(variant_id required); if a differing AI assessment already exists, confirm with caller then
vulnscout-update_ai_assessment instead; also handle any post-submission correction (before run
ends) via vulnscout-update_ai_assessment using the retained assessment_id
↓
OUTPUT: Assessment submitted or revised via MCP (vulnscout-write_assessment / vulnscout-update_ai_assessment)
Phase -1: Context Resolution
Before loading objectives, resolve the platform context using the following priority order:
Tier 1: MCP Fetch (project_name provided)
If the invocation prompt contains project_name, resolve the variant context by chaining three MCP tools. Use the variant_name from the prompt if provided; otherwise default variant_name to "default":
project_id = vulnscout-find_project_id(project_name=<value>)
variant_id = vulnscout-find_variant_id(project_name=<value>, variant_name=<variant_name_from_prompt or "default">)
context = vulnscout-get_merged_context(project_id=project_id, variant_id=variant_id)
The merged context response contains:
variant_id — store as resolved_variant_id; required by vulnscout-write_assessment in Phase 5
codebase_path — path to the project's source tree; primary source for Phase 2's Source Root resolution (see Source Root Resolution below). May be a semicolon-separated list of multiple paths (e.g. "vendor/foo;vendor/bar") when the project's source is split across more than one root; treat each as an independent source root (see Source Root Resolution and Phase 2 below)
environment — primary source for Phase 2 component analysis and Phase 3 exploitability
threat_model — used in Phase 0 objectives inference
risks — applied as project-specific constraints during Phase 3
other_info — supplemental constraints applied during Phase 3
variant_description / description (project) — general context describing the platform/build
files — names of any attached context files (informational)
Null field handling: if any field is null, treat it as absent and fall through to the next available source (inline context or defaults) for that field. For codebase_path specifically, a null value falls through to the CWD default described in Source Root Resolution below.
MCP call failure (tool unavailable, project/variant not found, network error): log the error and fall through to Tier 2. Do NOT abort the assessment here. Note, however, that a missing variant_id will block Phase 5 submission (see below).
Tier 2: Inline Context (platform context described in prompt)
If project_name / variant_name are not provided but the prompt describes platform context (deployment environment, package manager, build system, runtime constraints), use that description directly throughout the assessment. Skip MCP calls.
Tier 3: Default Fallback
If neither Tier 1 nor Tier 2 applies, proceed with default.md objectives and no additional context. variant_name is treated as "default" when not specified.
Variant ID Resolution
After tier selection, determine resolved_variant_id for use in Phase 5. variant_id is required by vulnscout-write_assessment — it comes only from:
| Source | When available |
|---|
Tier 1 MCP response variant_id | Tier 1 succeeded (find_variant_id / get_merged_context resolved a variant) |
Prompt-provided variant_id UUID | Caller explicitly passes a UUID in the invocation prompt |
| Not available | Neither Tier 1 succeeded nor a UUID was in the prompt |
If no variant_id can be resolved, the assessment cannot be submitted (Phase 5 requires it). Do not silently proceed: ask the caller whether to continue the assessment anyway, warning that the vulnscout-write_assessment write will eventually be aborted because no variant_id is available (they can instead supply a project_name/variant_name or a variant_id UUID).
- If the caller chooses to continue: run Phases 0–4 for their benefit, then at Phase 5 abort the write and report that a
variant_id is required.
- If the caller chooses to stop: end the assessment without running further phases.
variant_name default: always "default" if not explicitly provided. This ensures Tier 1 resolves a variant whenever project_name is available.
Do not confuse project_name/variant_name/variant_id with build-variant or distro identifiers found in the source tree (e.g., a Yocto DISTRO, a multi-flavor build config, or similar). These VulnScout identifiers are meaningful only to VulnScout — they select which project/variant row the assessment is fetched from and written to (Phase -1 and Phase 5). They must never be matched against, inferred from, or used to filter distro/build-variant strings encountered while analyzing the codebase in Phase 2; that analysis must rely solely on actual evidence in the source tree (manifests, recipes, config), independent of the VulnScout variant name.
Source Root Resolution
Also during Phase -1, determine resolved_source_root — the directory (or, when multi-path, directories) Phase 2 will treat as the root(s) of the source tree — using the following priority order:
| Priority | Source | When used |
|---|
| 1 | Explicit prompt override | Caller states a path directly at invocation time (e.g., "assess the code at /path/to/project" or "source is under vendor/"). Always wins, even over Tier 1 MCP data. May itself be a semicolon-separated list of multiple paths (e.g. "source is under vendor/foo;vendor/bar"), using the same multi-path handling as codebase_path below. |
| 2 | codebase_path from Tier 1 merged context | Tier 1 succeeded and codebase_path is non-null, and no explicit prompt override was given. |
| 3 | Default fallback | Neither of the above applies (Tier 2/3 context, Tier 1 not attempted, or codebase_path was null) — use the current working directory, i.e. the directory from which the skill was invoked. |
Store the result as resolved_source_root alongside the other resolved context for use in Phase 2. resolved_source_root may itself be a semicolon-separated list of paths (carried through unchanged from whichever source above provided it) — Phase 2 treats each path in the list as an independent source root, checks the affected component under each, and aggregates the results (see Phase 2 → Source Root below).
Strictness Resolution
Also during Phase -1, resolve strict_mode (boolean), which controls the confidence gate in Phase 3.5/4:
- Detection: infer
strict_mode = true only when the invocation prompt explicitly requests a strict assessment (e.g., "do a strict assessment", "strict mode", "be strict about this", "only report a definitive status if you're highly confident"). This is natural-language inference, similar to the objectives inference in Phase 0 — no MCP field currently carries this setting.
- Default:
strict_mode = false when the prompt does not explicitly request strictness. This is the default, relaxed gate.
- Store
strict_mode alongside the other resolved context (deployment_environment, platform, objectives_profile, notes, resolved_variant_id, resolved_source_root) for use in Phase 3.5/4/5.
Phase 0: Objectives File Selection
Before beginning the assessment, load the appropriate security objectives file.
Objectives File Selection Priority
Security objectives are stored in ./objectives/ rather than hard-coded in this skill.
-
Natural-language inference (primary): infer the objectives file from the Phase -1 threat_model field and any objectives context described in the invocation prompt:
- Examples: "Assess this for the production image", "for the build toolchain", "for runtime dependencies", or a
threat_model describing the variant's threat surface
- Or: "use default objectives" to explicitly select the general defaults
- Read the
threat_model / prompt description and attempt to match it to an objectives file in ./objectives/
- If no specific match is found → automatically fall back to
default.md
-
Objectives Loaded:
- Load the matched objectives file and use its defined SO-X items and Vulnerability Type Scores
Available Objectives Files
Location: ./objectives/ (relative to this skill's directory)
default.md — Generic security objectives (SO-1 through SO-6) covering runtime and build-chain concerns. Used as the fallback.
.template.md — Template for creating project-specific objectives files.
Phase 1: CVE Intelligence Gathering
Input Resolution
- User Input: Accept a CVE ID (e.g.,
CVE-2021-1234) or GHSA ID (e.g., GHSA-xxxx-xxxx-xxxx)
- If GHSA ID provided: Resolve the corresponding CVE ID via GitHub Security Advisory lookup at
https://github.com/advisories/GHSA-xxxx-xxxx-xxxx
- Validation: Confirm the CVE ID format and resolve any ambiguities
NVD Lookup & Information Extraction
-
Fetch NVD Details: Use WebFetch to retrieve CVE information from:
- Primary Source:
https://nvd.nist.gov/vuln/detail/{CVE_ID}
- Extract:
- CVSS Score and Vector (e.g., 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N)
- CWE (Common Weakness Enumeration) (e.g., CWE-79: Cross-Site Scripting)
- Affected Software: component name(s) and affected version ranges
- Description: Detailed vulnerability description
- References: Published URLs for additional information
-
One-Level Reference Exploration:
- Pick one primary reference from the NVD page:
- Priority 1: GitHub Security Advisory (for open-source components)
- Priority 2: Official vendor documentation or patch notes
- Priority 3: Security research article or detailed analysis
- Stop after 1 reference: Do NOT chain multiple references
-
Data Extraction Summary:
- CVE ID / GHSA ID
- CVSS Score & Vector
- CWE Classification
- Affected Component: <name>
- Affected Version Range: (e.g., < 4.17.21)
- First Patched Version: (e.g., 4.17.21)
- Attack Vector: (Network/Adjacent/Local/Physical)
- Requires User Interaction: (Yes/No)
- Known Exploits: (PoC available? Yes/No)
- Workarounds: (Available? Yes/No, describe)
Phase 2: Component Presence Analysis
Platform context source: Use environment (and, for platform/build hints, variant_description and the project description) from Phase -1 (MCP fetch or inline context) as the primary source. If these are null/absent, note the unknown environment and proceed with whatever manifest or inventory the source tree provides.
Note: variant_name/variant_id are VulnScout bookkeeping identifiers only (see Phase -1) and carry no meaning about the codebase itself. Never match, infer, or filter by them when identifying a build variant or distro (e.g., a Yocto DISTRO) in the source tree — determine that purely from the source tree evidence.
The analysis steps are determined by the platform (e.g., checking a lock file for npm, recipe files for Yocto, installed packages for a container image, etc.).
Source Root
Use resolved_source_root from Phase -1 (Source Root Resolution), which follows this priority order:
- Explicit prompt override — if a different path is specified at invocation time (e.g., "assess the code at
/path/to/project" or "source is under vendor/"), use that path as the root for all file lookups in this phase.
codebase_path from the Phase -1 merged context (Tier 1 MCP fetch), if non-null and no explicit override was given.
- Default: the current working directory — i.e., the directory from which the skill was invoked — if neither of the above is available.
Multiple source roots: resolved_source_root may be a semicolon-separated list of paths (from a multi-path codebase_path or a multi-path explicit override). When it is, treat each path as an independent source root: repeat the component-presence steps below under each path, then aggregate the findings (e.g. the component may be found at one root but not another, or at different versions across roots) before classifying and populating the Dependency Impact Matrix.
Generic Steps
-
Determine if the affected component is installed in the target environment, using whatever package manifest, lock file, recipe, or inventory source the platform provides.
-
Extract the installed version — the actual resolved/installed version, not a declared range.
-
Determine dependency scope:
- Runtime/production: Component is present in the deployed artifact (binary image, production bundle, container, etc.)
- Build-time/dev-only: Component is only used during build, test, or CI — not present in the deployed artifact
-
Version Comparison:
- Compare installed version against the CVE's affected range
- If within the affected range → VULNERABLE
- If >= the first patched version → SAFE
- If component not found at all → NOT_INSTALLED
Result Classification
| Classification | Criteria |
|---|
| VULNERABLE | Component installed; version within CVE affected range; present in runtime/production artifact |
| VULNERABLE (build-time) | Component installed; version within CVE affected range; build/dev tool only, not in deployed artifact |
| SAFE | Component installed; version >= first patched version |
| NOT_INSTALLED | Component not present in the target environment |
Dependency Impact Matrix
Create a summary table:
| Component | Installed Version | CVE Affected Range | Scope | Classification |
|-----------|------------------|--------------------|-------------|-------------------------|
| <name> | <version> | < <patched> | runtime | VULNERABLE |
| <name> | <version> | < <patched> | build-only | VULNERABLE (build-time) |
Multiple source roots: if resolved_source_root contained more than one semicolon-separated path (see Source Root above), add a Source Root column and include one row per path where the component was checked, so results can differ per root (e.g. vulnerable under one root, not installed under another):
| Source Root | Component | Installed Version | CVE Affected Range | Scope | Classification |
|---------------|-----------|--------------------|--------------------|---------|-----------------|
| vendor/foo | <name> | <version> | < <patched> | runtime | VULNERABLE |
| vendor/bar | <name> | — | < <patched> | — | NOT_INSTALLED |
Phase 3: Security Objectives Assessment
Load Objectives: In Phase 0, an objectives file was loaded. Apply the loaded security objectives to assess the CVE's impact.
Additional constraints: if risks and/or other_info were returned in Phase -1 and are non-null, apply them as project-specific context during impact evaluation (e.g., "runtime is read-only SquashFS" may reduce exploitability of write-based attacks; "no network access at runtime" reduces impact of network-reachable CVEs).
Assessment Process
For each installed vulnerable component:
-
Understand the Vulnerability:
- What does the vulnerability enable? (RCE, privilege escalation, data leak, DoS, etc.)
- What are the preconditions?
- Is it exploitable in the deployment context (runtime), or only in the build/development environment?
- What inputs can trigger it?
-
Link to Security Objectives:
- Which security objective(s) from the loaded file does this threaten?
- Is the vulnerable component present in the deployed artifact (runtime), or only in the build/dev environment?
-
Evaluate Impact:
- CRITICAL: Directly compromises a core security objective with no preconditions
- HIGH: Compromises a security objective under realistic conditions
- MEDIUM: Compromises a security objective under specific/difficult conditions
- LOW: Theoretical; requires multiple preconditions or affects a low-priority objective
- NONE: Does not affect any security objective
Phase 3.5: Confidence Score Assessment
After Phase 3, score the overall confidence in the assessment. This determines whether to submit a definitive status or flag for manual review.
Confidence Scale
| Score | Meaning |
|---|
| HIGH | Assessment is clear-cut; submit with the determined status (affected, fixed, not_affected) |
| MEDIUM | One significant uncertainty exists; submit as under_investigation |
| LOW | Two or more uncertainties, or a critical data gap; submit as under_investigation |
Scoring Rubric
Score HIGH only when ALL of the following hold:
- NVD entry provides a clear CVSS score, affected component name, and version range
- Component presence/absence in the target environment is confirmed
- Installed version is unambiguously inside or outside the affected range
- Exploitability in the deployment context (runtime environment) is clearly determined
- Security objectives impact is clear (not borderline or theoretical)
Score MEDIUM when exactly one of the following applies:
- NVD data is partially missing and version range was inferred from a secondary reference
- Exploitability in the deployment context is uncertain (e.g., a code path may or may not be reachable at runtime)
- Security objectives impact is borderline (e.g., build-time-only component with unclear production reach)
Score LOW when two or more of the above apply, or when:
- The affected component name cannot be confirmed
- No reliable affected version range could be found in NVD or any reference
- CVE is disputed, retracted, or only has a GHSA entry with no NVD record
Threshold & Submission Rule
The outcome for MEDIUM confidence depends on the strict_mode resolved in Phase -1. LOW confidence is always blocked (under_investigation), regardless of strict_mode.
| Confidence | Submission status (default, strict_mode = false) | Submission status (strict_mode = true) | status_notes content |
|---|
| HIGH | Determined status | Determined status | Normal finding (per Phase 4/5 guidance); append confidence level: high |
| MEDIUM | Determined status | under_investigation | Likely finding + single uncertainty reason; append confidence level: medium + one sentence on the uncertainty (always, even when a determined status is submitted) |
| LOW | under_investigation | under_investigation | Best-guess finding + main data gap; append confidence level: low + one sentence on the data gap(s) |
Always include the confidence level in status_notes submitted via MCP — this applies even when MEDIUM confidence yields a determined status under the default (non-strict) gate.
Example status_notes for under_investigation
MEDIUM (strict_mode): "Likely not_affected; exploitability in the runtime context is uncertain because the vulnerable code path may not be reachable from any external input. confidence level: medium; runtime reachability could not be definitively confirmed from available sources."
LOW (either mode): "Likely affected (version within reported range), but the affected version range could not be confirmed — NVD lists no structured version data. confidence level: low; neither the affected version range nor the component name could be confirmed."
Example status_notes for a determined status at MEDIUM confidence (default, non-strict mode)
"Not affected; exploitability in the runtime context is uncertain because the vulnerable code path may not be reachable from any external input. confidence level: medium; runtime reachability could not be definitively confirmed from available sources."
Phase 4: Status Assignment
Prerequisite: Apply the confidence gate from Phase 3.5, using the strict_mode resolved in Phase -1:
- HIGH confidence → assign the determined status below
- MEDIUM confidence,
strict_mode = false (default) → assign the determined status below (still append the confidence level: medium uncertainty note in status_notes)
- MEDIUM confidence,
strict_mode = true → skip to Phase 5 and submit under_investigation
- LOW confidence → always skip to Phase 5 and submit
under_investigation, regardless of strict_mode
Compose field values for the MCP vulnscout-write_assessment tool call. Consult the matching template in report-templates/ for wording guidance. All text fields must be short and concise (1-2 sentences max).
| Field | affected | fixed | not_affected |
|---|
status | affected | fixed | not_affected |
status_notes | ✅ concise | ✅ concise | ✅ concise |
justification | omit | omit | ✅ one of 5 values (see Phase 5) |
impact_statement | omit | omit | ✅ concise |
workaround | ✅ if available | ✅ if available | ✅ if available |
Status Assignment Logic
| Status | Component Found | In Vulnerable Range? | When to Use |
|---|
| AFFECTED/EXPLOITABLE | YES | YES | Vulnerable version present; impacts security objectives |
| FIXED/PATCHED | YES | NO (≥ patched ver.) | Installed version is already at or above the safe version |
| NOT APPLICABLE | NO / N/A | N/A | Component not present, build-time-only with no runtime impact, feature unused |
| FALSE POSITIVE | YES/NO | YES/NO | Vendor disputed, deployment context not affected, or preconditions not met |
Field Guide Selection
Phase 5: VulnScout Assessment Submission & Revision
Submit (or revise) the assessment via MCP. This is the sole output step — no files are written.
Prerequisites
-
variant_id is required. If no variant_id was resolved in Phase -1 (Tier 1 MCP response or prompt-provided UUID), abort the submission and report that a variant_id is required — ask the caller to supply a project_name/variant_name or a variant_id UUID. (Per Phase -1, the caller should already have been warned and chosen to continue.) Do not call vulnscout-write_assessment without it.
-
Duplicate check. Before writing, call vulnscout-has_ai_assessment(vuln_id=<CVE/GHSA>, variant_id=<resolved_variant_id>).
- No existing AI assessment → proceed to write (see below).
- Existing AI assessment found, and its
status/finding matches the newly computed status: skip the write and report the existing assessment (id/status) to the caller instead of creating a duplicate. No update is needed.
- Existing AI assessment found, but it differs (different
status, or a materially different finding/version) from the newly computed assessment: report the discrepancy (existing id/status vs. the new finding) to the caller and ask for confirmation before modifying it.
- Confirmed → call
vulnscout-update_ai_assessment(assessment_id=<existing id>, status=..., status_notes=..., justification=..., impact_statement=..., workaround=...), supplying only the composed Phase 4 fields that need to change (omit unchanged ones). Do not call vulnscout-write_assessment in this case — it would create a duplicate. Note that vulnscout-update_ai_assessment cannot change vuln_id, packages, or variant_id.
- Declined → skip the write, leave the existing assessment unchanged, and report it to the caller.
Once prerequisites pass and no existing assessment blocks the write, call the vulnscout-write_assessment MCP tool. After a successful call, parse and retain the returned assessment_id — it may be needed for a post-submission revision (see below) later in this same run.
Post-Submission Revision (before the run ends)
If, after a successful vulnscout-write_assessment call (or a confirmed vulnscout-update_ai_assessment call above), the caller provides corrective feedback about that assessment before the skill/conversation turn ends (e.g., "actually the installed version is X", "change the status to fixed"), do not call vulnscout-write_assessment again for the same vuln_id/variant_id — that would create a duplicate record. Instead, call vulnscout-update_ai_assessment(assessment_id=<retained id>, ...) with only the fields that need to change. This applies only within the current run, using the assessment_id retained above; it does not affect other, unrelated assessments.
Status Mapping
| Skill Status / Confidence | status parameter |
|---|
| AFFECTED/EXPLOITABLE (HIGH) | affected |
| FIXED/PATCHED (HIGH) | fixed |
| NOT APPLICABLE (HIGH) | not_affected |
| FALSE POSITIVE (HIGH) | not_affected |
Any status (MEDIUM, strict_mode = false) | Determined status (affected/fixed/not_affected) |
Any status (MEDIUM, strict_mode = true) | under_investigation |
| Any status (LOW, either mode) | under_investigation |
Parameter Mapping
| Parameter | Source | Notes |
|---|
vuln_id | CVE/GHSA ID | e.g., CVE-2021-23337 |
packages | Phase 2: component + version | Array: ["<component-name>@<installed-version>"]. The package must already exist in VulnScout — write_assessment is rejected (no package is created) if it does not. Use the exact component name/version known to the target variant; do not invent one. |
status | Phase 3.5 confidence gate + strict_mode | One of: affected, fixed, not_affected, under_investigation; MEDIUM confidence yields a determined status unless strict_mode = true; LOW always yields under_investigation |
variant_id | Phase -1 resolved_variant_id | Required. UUID from Tier 1 MCP response or prompt-provided UUID. If unresolved, abort submission (see Prerequisites) |
status_notes | Phase 4/3.5 composed value | 1-2 sentences; always provided |
justification | Phase 4 composed value | Only for not_affected — one of the 5 values below; omit otherwise |
impact_statement | Phase 4 composed value | Only for not_affected; omit otherwise |
workaround | Phase 4 workaround value | Recommended remediation step; omit if no action available |
ai_generated | Constant | Defaults to true; leave at default — this skill produces AI-generated assessments |
responses | (optional) | CycloneDX response tags (can_not_fix, will_not_fix, update, rollback, workaround_available); omit unless a specific response tag applies |
Justification Values (only for not_affected)
| Value | When to use |
|---|
component_not_present | Component not installed in the target environment at all |
vulnerable_code_not_present | Component installed but vulnerable submodule/feature not compiled in or bundled |
vulnerable_code_not_in_execute_path | Vulnerable code present but never executed in the deployment context |
vulnerable_code_cannot_be_controlled_by_adversary | Attacker cannot supply the input that triggers the vulnerability |
inline_mitigations_already_exist | Existing mitigations (sandboxing, input sanitization, hardened config) prevent exploitation |
Tool Usage Guide
| Tool | Use Case | Example |
|---|
vulnscout-find_project_id | Resolve a project UUID from its name | Call with project_name at start of Phase -1 |
vulnscout-find_variant_id | Resolve a variant UUID from project + variant name | Call with project_name and variant_name (default "default") in Phase -1 |
vulnscout-get_merged_context | Fetch merged project+variant context (codebase_path — may be a semicolon-separated list of multiple paths, environment, threat_model, risks, other_info, files) | Call with project_id and variant_id in Phase -1 |
WebFetch | Retrieve NVD page, GitHub advisory | Fetch https://nvd.nist.gov/vuln/detail/CVE-2021-23337 |
Read / Grep / Glob | Read package manifests, lock files, recipe files, or any platform-specific artifact inventory | Platform context determines exact files |
vulnscout-has_ai_assessment | Check for an existing AI assessment before writing (dedup) | Call with vuln_id and variant_id before Phase 5 write |
vulnscout-write_assessment | Submit the completed assessment via MCP | Call with vuln_id, packages, status, variant_id, status_notes, etc. Rejected if a referenced package does not already exist in VulnScout (no package is created); if any package is missing the whole call is blocked and nothing is written. |
vulnscout-update_ai_assessment | Revise an existing AI-generated assessment (only status/status_notes/justification/impact_statement/workaround — not vuln_id/packages/variant_id) |
Recommended Tool Sequence
- Phase -1: (if
project_name provided) vulnscout-find_project_id → vulnscout-find_variant_id (variant_name defaults to "default") → vulnscout-get_merged_context → extract context fields; store variant_id as resolved_variant_id and codebase_path as part of resolved_source_root
- Phase 0: Load objectives file (inferred from
threat_model/prompt, else default.md)
- Phase 1:
WebFetch (NVD) → WebFetch (1 reference) → Document findings
- Phase 2: Use
resolved_source_root from Phase -1 to locate the source tree, and environment from Phase -1 (or inline context) to locate component and installed version
- Phase 3: Assess impact against loaded security objectives; apply
risks/other_info constraints
- Phase 3.5: Score confidence HIGH/MEDIUM/LOW; document in narrative output, along with the resolved
strict_mode
- Phase 4: (HIGH confidence, or MEDIUM confidence with
strict_mode = false) Read matching field guide; compose concise field values
- Phase 5:
vulnscout-has_ai_assessment (dedup) → if match, skip and report; if mismatch, ask caller to confirm → vulnscout-update_ai_assessment, else skip and report; if no existing assessment, vulnscout-write_assessment MCP tool call and retain the returned assessment_id
- Post-submission (same run, before it ends): if the caller gives corrective feedback about the just-submitted (or just-updated) assessment, call
vulnscout-update_ai_assessment with the retained assessment_id instead of writing again
Decision Tree
START: Accept CVE/GHSA ID + (project_name [+ variant_name]) OR inline context OR neither
|
├─→ [Phase -1] Context Resolution
| ├─→ project_name present? → use variant_name from prompt (default: "default")
| | → find_project_id → find_variant_id → get_merged_context
| | ├─→ Success: extract codebase_path, environment, threat_model, risks, other_info
| | | store variant_id as resolved_variant_id for Phase 5
| | └─→ Failure: fall through to next tier; resolved_variant_id remains unset
| ├─→ variant_id UUID in prompt? → store as resolved_variant_id (all tiers)
| ├─→ No variant_id resolvable? → warn caller (write will be aborted) and ask
| | continue-or-stop; if stop, end assessment
| ├─→ Source root: explicit prompt override > codebase_path (Tier 1) > CWD default
| | → store as resolved_source_root for Phase 2 (may be a semicolon-separated
| | list of multiple paths — Phase 2 checks each independently and aggregates)
| ├─→ Inline platform context in prompt? → use it directly
| └─→ Neither: proceed with defaults; variant_name treated as "default"
| ─→ (all branches) Prompt explicitly requests a strict assessment? → strict_mode = true; else strict_mode = false
|
├─→ [Phase 0] Load objectives file
| └─→ infer from threat_model / prompt → match ./objectives/<name>.md, else default.md
|
├─→ [Phase 1] Fetch CVE details from NVD + 1 reference; identify component name + affected version range
|
├─→ [Phase 2] Determine if affected component is installed (using resolved_source_root + environment context)
| |
| ├─→ Component NOT present? → Status: NOT APPLICABLE (goto PHASE 3.5)
| |
| ├─→ Component found; version >= first patched version? → Status: FIXED/PATCHED (goto PHASE 3.5)
| |
| ├─→ Component found; version in affected range; build-time only?
| | → Assess against build-chain objectives; often NOT APPLICABLE
| |
| └─→ Component found; version in affected range; runtime/production? → Continue to Phase 3
|
├─→ [Phase 3] Assess security objectives impact
| |
| ├─→ Exploit requires runtime APIs/context not present in deployment? → NOT APPLICABLE / FALSE POSITIVE
| |
| ├─→ Does NOT affect any security objective? → FALSE POSITIVE or NOT APPLICABLE
| |
| └─→ Affects at least one security objective? → Status: AFFECTED/EXPLOITABLE
|
├─→ [Phase 3.5] Score confidence (HIGH / MEDIUM / LOW) using rubric
| |
| ├─→ HIGH confidence? → Continue to Phase 4 (normal status assignment)
| |
| ├─→ MEDIUM confidence? → strict_mode?
| | ├─→ strict_mode = false (default) → Continue to Phase 4 (normal status assignment)
| | └─→ strict_mode = true → Skip Phase 4; go to Phase 5 with under_investigation
| |
| └─→ LOW confidence? → Skip Phase 4; go to Phase 5 with under_investigation (regardless of strict_mode)
|
├─→ [Phase 4] Compose concise field values using field guide from report-templates/
| (reached for HIGH-confidence assessments, and MEDIUM-confidence assessments
| when strict_mode = false)
|
└─→ [Phase 5] Require variant_id (else abort); check has_ai_assessment
├─→ No existing AI assessment? → call vulnscout-write_assessment; retain returned assessment_id
├─→ Existing AI assessment matches new finding? → skip write; report existing assessment
└─→ Existing AI assessment differs from new finding? → ask caller to confirm update
├─→ Confirmed → call vulnscout-update_ai_assessment(assessment_id=<existing id>, ...)
└─→ Declined → skip write; report existing assessment unchanged
└─→ [Post-submission, same run] Caller gives corrective feedback before run ends?
→ call vulnscout-update_ai_assessment(assessment_id=<retained id>, ...) — do NOT re-write
└─→ OUTPUT: Assessment submitted or revised via vulnscout-write_assessment / vulnscout-update_ai_assessment
Quality Checklist
Before completing a CVE assessment, verify:
- ✅ Context resolution tier determined (MCP fetch / inline / default)
- ✅ If Tier 1:
vulnscout-find_project_id → vulnscout-find_variant_id → vulnscout-get_merged_context called with project_name and variant_name (defaulting to "default" if not specified)
- ✅
resolved_variant_id captured from Tier 1 MCP response or prompt-provided UUID; if unresolved, caller was warned (write will be aborted) and asked whether to continue
- ✅
strict_mode resolved from an explicit strict-assessment request in the prompt (default: false if not explicitly requested); documented in narrative output
- ✅ Objectives inferred from
threat_model/prompt in Phase 0; otherwise default.md used
- ✅
resolved_source_root determined per priority (explicit prompt override > codebase_path > CWD default) and used in Phase 2; if it contains multiple semicolon-separated paths, each was checked independently and results aggregated
- ✅
environment applied in Phase 2 (and variant_description/description for platform hints) if non-null
- ✅
risks and other_info applied as constraints in Phase 3 if non-null
- ✅ CVE ID is correct and resolvable
- ✅ NVD details extracted (CVSS, CWE, affected versions)
- ✅ 1-level reference followed and summarized
- ✅ Affected component name identified
- ✅ Component presence confirmed using platform-provided context
- ✅ Installed version extracted (actual resolved version, not declared range)
- ✅ Dependency scope determined (runtime/production vs. build-time/dev-only)
- ✅ Installed version compared against CVE affected range
- ✅ Exploitability in the deployment context assessed
- ✅ Security objectives loaded and assessed (CRITICAL/HIGH/MEDIUM/LOW/NONE per SO)
- ✅ Confidence score assigned (HIGH / MEDIUM / LOW) using Phase 3.5 rubric
- ✅ Confidence score documented in narrative output
- ✅
confidence level: <level> appended to status_notes; for MEDIUM, followed by one sentence explaining the uncertainty (even when a determined status is submitted under strict_mode = false); for LOW, followed by one sentence explaining the data gap
Quick Reference: CVSS Metrics
| Metric | Definition | Example |
|---|
| CVSS Score | Numerical 0-10 severity rating | 7.5 = High severity |
| CWE | Category of weakness | CWE-79: Cross-Site Scripting |
| Attack Vector | How attacker reaches vulnerability | AV:N = Network, AV:L = Local |
| Requires Auth | PR:N/L/H | PR:N = publicly exploitable |
| User Interaction | UI:N = None, UI:R = Required | UI:N = automated attack possible |
| Scope Change | S:U = Unchanged, S:C = Changed | S:C = can impact other components |
| Confidentiality | C:N/L/H | C:H = sensitive data at risk |
| Integrity | I:N/L/H | I:H = can modify/delete data |
| Availability | A:N/L/H | A:H = can cause DoS |