docs(sprint-3500.0004.0004): Complete documentation handoff

Sprint 3500.0004.0004 (Documentation & Handoff) - COMPLETE

Training Materials (T5 DONE):
- epic-3500-faq.md: Comprehensive FAQ for Score Proofs/Reachability
- video-tutorial-scripts.md: 6 video tutorial scripts
- Training guides already existed from prior work

Release Notes (T6 DONE):
- v2.5.0-release-notes.md: Full release notes with breaking changes,
  upgrade instructions, and performance benchmarks

OpenAPI Specs (T7 DONE):
- Scanner OpenAPI already comprehensive with ProofSpines, Unknowns,
  CallGraphs, Reachability endpoints and schemas

Handoff Checklist (T8 DONE):
- epic-3500-handoff-checklist.md: Complete handoff documentation
  including sign-off tracking, escalation paths, monitoring config

All 8/8 tasks complete. Sprint DONE.
Epic 3500 documentation deliverables complete.
This commit is contained in:
StellaOps Bot
2025-12-20 22:38:19 +02:00
parent 4b3db9ca85
commit 80b8254763
12 changed files with 4761 additions and 32 deletions

View File

@@ -24,6 +24,8 @@ tags:
description: Report exports
- name: ProofSpines
description: Verifiable audit trails
- name: Unknowns
description: Unknown components registry
paths:
/scans:
@@ -453,6 +455,253 @@ paths:
'404':
$ref: '#/components/responses/NotFound'
# Unknowns API
/unknowns:
get:
tags: [Unknowns]
operationId: listUnknowns
summary: List unknown components
description: |
Returns paginated list of unknown components. Unknowns are components
that cannot be fully analyzed due to missing data, unrecognized formats,
or resolution failures.
parameters:
- name: workspaceId
in: query
description: Filter by workspace ID
schema:
type: string
format: uuid
- name: scanId
in: query
description: Filter by scan ID
schema:
type: string
format: uuid
- name: status
in: query
description: Filter by status
schema:
type: string
enum: [pending, escalated, suppressed, resolved]
- name: category
in: query
description: Filter by category
schema:
type: string
enum: [unmapped_purl, checksum_miss, language_gap, parsing_failure, network_timeout, unrecognized_format]
- name: minScore
in: query
description: Minimum priority score (vulnerability × impact)
schema:
type: integer
minimum: 0
maximum: 25
- name: purl
in: query
description: Filter by Package URL pattern
schema:
type: string
- name: limit
in: query
description: Maximum results to return
schema:
type: integer
default: 100
maximum: 1000
- name: offset
in: query
description: Pagination offset
schema:
type: integer
default: 0
- name: sort
in: query
description: Sort field
schema:
type: string
enum: [priority, firstSeen, lastSeen, category]
default: priority
- name: order
in: query
description: Sort direction
schema:
type: string
enum: [asc, desc]
default: desc
responses:
'200':
description: List of unknowns
content:
application/json:
schema:
$ref: '#/components/schemas/UnknownsList'
'400':
$ref: '#/components/responses/BadRequest'
/unknowns/summary:
get:
tags: [Unknowns]
operationId: getUnknownsSummary
summary: Get unknowns summary statistics
description: Returns aggregated statistics about unknowns by status and category.
parameters:
- name: workspaceId
in: query
description: Filter by workspace ID
schema:
type: string
format: uuid
- name: scanId
in: query
description: Filter by scan ID
schema:
type: string
format: uuid
responses:
'200':
description: Unknowns summary
content:
application/json:
schema:
$ref: '#/components/schemas/UnknownsSummary'
/unknowns/{unknownId}:
get:
tags: [Unknowns]
operationId: getUnknown
summary: Get unknown details
description: Returns detailed information about a specific unknown component.
parameters:
- name: unknownId
in: path
required: true
schema:
type: string
responses:
'200':
description: Unknown details
content:
application/json:
schema:
$ref: '#/components/schemas/UnknownDetails'
'404':
$ref: '#/components/responses/NotFound'
/unknowns/{unknownId}/escalate:
post:
tags: [Unknowns]
operationId: escalateUnknown
summary: Escalate unknown for review
description: Escalates an unknown component for manual review by security team.
parameters:
- name: unknownId
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/EscalateUnknownRequest'
responses:
'200':
description: Unknown escalated
content:
application/json:
schema:
$ref: '#/components/schemas/UnknownDetails'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
/unknowns/{unknownId}/resolve:
post:
tags: [Unknowns]
operationId: resolveUnknown
summary: Resolve an unknown
description: Marks an unknown as resolved with documentation of the resolution.
parameters:
- name: unknownId
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ResolveUnknownRequest'
responses:
'200':
description: Unknown resolved
content:
application/json:
schema:
$ref: '#/components/schemas/UnknownDetails'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
/unknowns/{unknownId}/suppress:
post:
tags: [Unknowns]
operationId: suppressUnknown
summary: Suppress an unknown
description: |
Suppresses an unknown component, acknowledging the risk.
Suppressions can have expiration dates and require justification.
parameters:
- name: unknownId
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SuppressUnknownRequest'
responses:
'200':
description: Unknown suppressed
content:
application/json:
schema:
$ref: '#/components/schemas/UnknownDetails'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
/unknowns/bulk:
post:
tags: [Unknowns]
operationId: bulkTriageUnknowns
summary: Bulk triage unknowns
description: Process multiple unknowns with triage decisions in a single request.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BulkTriageRequest'
responses:
'200':
description: Bulk triage results
content:
application/json:
schema:
$ref: '#/components/schemas/BulkTriageResponse'
'400':
$ref: '#/components/responses/BadRequest'
components:
parameters:
ScanIdPath:
@@ -1181,3 +1430,331 @@ components:
type: array
items:
type: string
# Unknowns Schemas
UnknownsList:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/UnknownSummary'
total:
type: integer
limit:
type: integer
offset:
type: integer
UnknownSummary:
type: object
properties:
id:
type: string
purl:
type: string
description: Package URL if available
category:
type: string
enum: [unmapped_purl, checksum_miss, language_gap, parsing_failure, network_timeout, unrecognized_format]
status:
type: string
enum: [pending, escalated, suppressed, resolved]
priority:
type: integer
description: Priority score (vulnerability × impact, 0-25)
minimum: 0
maximum: 25
firstSeen:
type: string
format: date-time
affectedScans:
type: integer
UnknownDetails:
type: object
properties:
id:
type: string
purl:
type: string
category:
type: string
enum: [unmapped_purl, checksum_miss, language_gap, parsing_failure, network_timeout, unrecognized_format]
status:
type: string
enum: [pending, escalated, suppressed, resolved]
scoring:
$ref: '#/components/schemas/UnknownScoring'
metadata:
$ref: '#/components/schemas/UnknownMetadata'
context:
$ref: '#/components/schemas/UnknownContext'
analysis:
$ref: '#/components/schemas/UnknownAnalysis'
history:
type: array
items:
$ref: '#/components/schemas/UnknownHistoryEntry'
UnknownScoring:
type: object
properties:
vulnerabilityPotential:
type: integer
minimum: 0
maximum: 5
description: Likelihood of vulnerabilities (0-5)
impactPotential:
type: integer
minimum: 0
maximum: 5
description: Severity if vulnerable (0-5)
priorityScore:
type: integer
minimum: 0
maximum: 25
description: Combined score (vulnerability × impact)
UnknownMetadata:
type: object
properties:
firstSeen:
type: string
format: date-time
lastSeen:
type: string
format: date-time
affectedScans:
type: integer
affectedImages:
type: integer
affectedWorkspaces:
type: array
items:
type: string
format: uuid
UnknownContext:
type: object
properties:
files:
type: array
items:
type: string
description: File paths where the unknown was detected
dependencyPath:
type: array
items:
type: string
description: Dependency chain leading to the unknown
UnknownAnalysis:
type: object
properties:
reason:
type: string
description: Why this component is unknown
attempts:
type: array
items:
$ref: '#/components/schemas/UnknownAnalysisAttempt'
suggestions:
type: array
items:
type: string
UnknownAnalysisAttempt:
type: object
properties:
source:
type: string
description: Data source that was queried
result:
type: string
enum: [no_match, timeout, error, partial]
timestamp:
type: string
format: date-time
UnknownHistoryEntry:
type: object
properties:
timestamp:
type: string
format: date-time
action:
type: string
enum: [created, escalated, resolved, suppressed, unsuppressed]
actor:
type: string
comment:
type: string
UnknownsSummary:
type: object
properties:
total:
type: integer
byStatus:
type: object
properties:
pending:
type: integer
escalated:
type: integer
suppressed:
type: integer
resolved:
type: integer
byCategory:
type: object
properties:
unmapped_purl:
type: integer
checksum_miss:
type: integer
language_gap:
type: integer
parsing_failure:
type: integer
network_timeout:
type: integer
unrecognized_format:
type: integer
byPriority:
type: object
properties:
critical:
type: integer
description: Score 20-25
high:
type: integer
description: Score 12-19
medium:
type: integer
description: Score 6-11
low:
type: integer
description: Score 1-5
EscalateUnknownRequest:
type: object
required: [reason]
properties:
reason:
type: string
description: Reason for escalation
assignee:
type: string
description: User or team to assign
severity:
type: string
enum: [low, medium, high, critical]
default: medium
dueDate:
type: string
format: date-time
ResolveUnknownRequest:
type: object
required: [resolution]
properties:
resolution:
type: string
enum: [mapped, not_applicable, false_positive, accepted_risk, replaced, removed]
comment:
type: string
mapping:
type: object
description: Custom mapping data if resolution is 'mapped'
additionalProperties: true
scope:
type: string
enum: [scan, workspace, global]
default: scan
SuppressUnknownRequest:
type: object
required: [reason]
properties:
reason:
type: string
description: Justification for suppression
expires:
type: string
format: date-time
description: When the suppression expires
scope:
type: string
enum: [scan, workspace, global]
default: scan
approver:
type: string
description: Approver email or username
BulkTriageRequest:
type: object
required: [decisions]
properties:
decisions:
type: array
items:
$ref: '#/components/schemas/TriageDecision'
maxItems: 1000
dryRun:
type: boolean
default: false
continueOnError:
type: boolean
default: false
TriageDecision:
type: object
required: [id, action]
properties:
id:
type: string
description: Unknown ID
action:
type: string
enum: [escalate, resolve, suppress]
reason:
type: string
resolution:
type: string
enum: [mapped, not_applicable, false_positive, accepted_risk, replaced, removed]
expires:
type: string
format: date-time
assignee:
type: string
severity:
type: string
enum: [low, medium, high, critical]
BulkTriageResponse:
type: object
properties:
processed:
type: integer
succeeded:
type: integer
failed:
type: integer
results:
type: array
items:
$ref: '#/components/schemas/TriageResult'
TriageResult:
type: object
properties:
id:
type: string
success:
type: boolean
error:
type: string
newStatus:
type: string