Remove the scan information section

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
alexanderandClaude Opus 5.5 committed 2026-09-24 21:14:14 +02:00
1 parent b380c736c9
commit 9d78e9edf4
5 files changed
+6 -184

No files matched your search

+4 -5
View File
@@ -39,8 +39,8 @@ report_generator from-folder --artifacts ./sample [--path <file-or-directory>]
whose metadata is gone.
The inputs are one SARIF file (`merged.sarif`, with one run per tool) and the vulnerability report
(`vdr.json`); either is enough on its own. `metadata.json` is optional, and without it the scan and
project pages are left out. The report has these parts:
(`vdr.json`); either is enough on its own. `metadata.json` is optional, and without it the project
page is left out. The report has these parts:
1. the cover and a table of contents,
2. a summary and the most critical issues across all sources,
@@ -98,9 +98,8 @@ vectors by `persistent_storage.utils.cvss_utils`.
### What it cannot fill in
A field the artifacts do not answer is written as `<xxx>`, never guessed or quietly dropped. Today
that is the manufacturer (unless given with `--manufacturer`), the analysed lines of code, the language
breakdown, and the tools and profile of each pipeline stage — the metadata records that a stage ran
and how long it took, not what it ran.
that is the manufacturer (unless given with `--manufacturer`), the analysed lines of code and the language
breakdown.
A measured zero survives: `0 filtered` is a reading, and a blank is a gap.
+2 -64
View File
@@ -79,9 +79,8 @@ def build_context(
"sections": [_tool_section(name, report) for name, report in tools],
}
# Without the pipeline's metadata these two pages would be nothing but gaps.
# Without the pipeline's metadata this page would be nothing but gaps.
if metadata:
context["scan"] = _scan(sources, metadata)
context["project"] = _project(metadata, project)
critical = _critical(tools, sca)
@@ -142,7 +141,7 @@ def _tool_name(run: dict[str, Any]) -> str:
def _contents(context: dict[str, Any]) -> list[dict[str, str]]:
"""The table of contents: every top-level part of the report that is actually in it."""
parts = [context[key] for key in ("scan", "project", "summary", "critical") if key in context]
parts = [context[key] for key in ("project", "summary", "critical") if key in context]
return [{"id": part["id"], "title": part["title"]} for part in [*parts, *context["sections"]]]
@@ -224,46 +223,6 @@ def _severity_ledger(tools: list[tuple[str, SarifReport]], sca: VdrReport | None
return {"title": "True issues by severity", "rows": rows}
def _scan(sources: ReportSources, metadata: dict[str, Any]) -> dict[str, Any]:
"""What the pipeline did, stage by stage."""
stages = [stage for stage in metadata.get("stages") or [] if isinstance(stage, dict)]
failed = [stage["label"] for stage in stages if stage.get("status") not in ("success", None)]
return {
"id": "scan",
"title": "CipherCell Scan Information",
"overview": [
_fact("Scan started at", _moment(metadata.get("pipeline_start_iso"))),
_fact("Scan duration", _duration(metadata.get("pipeline_duration_seconds"))),
_fact("Scan completed at", _moment(metadata.get("pipeline_end_iso"))),
_fact(
"Pipeline Steps", ", ".join(_stated(stage.get("label") or stage.get("key")) for stage in stages) or None
),
_fact("Errors Detected", ", ".join(failed) if failed else "None" if stages else None),
],
"stages": [_stage(stage, sources) for stage in stages],
}
def _stage(stage: dict[str, Any], sources: ReportSources) -> dict[str, Any]:
"""One stage of the pipeline.
The tools a stage ran and the profile it ran them under are not recorded in the metadata, so
they are left unstated. What is recorded is when it ran, how it ended, and -- indirectly -- what
it produced, which is read off the names of the files the scan stored.
"""
return {
"title": stage.get("label") or stage.get("key") or UNKNOWN,
"rows": [
_fact("Selected Tools", None),
_fact("Profile", None),
_fact("Duration", _duration(stage.get("duration_seconds"))),
_fact("Created Artifacts", ", ".join(sorted(sources.files)) or None, kind="mono"),
_fact("Errors Detected", "None" if stage.get("status") == "success" else stage.get("status")),
],
}
def _version(metadata: dict[str, Any]) -> str | None:
"""What version of the project was scanned: the stated one, else the commit the SBOM was uploaded for.
@@ -772,24 +731,3 @@ def _percent(share: float | None) -> str | None:
return None
return f"{share * 100:.2f} %" if share < 0.01 else f"{share * 100:.1f} %"
def _moment(stated: Any) -> str | None: # noqa: ANN401
"""An ISO timestamp as the report writes it, or nothing where it cannot be read."""
if not isinstance(stated, str):
return None
try:
return datetime.fromisoformat(stated).strftime("%A, %B %d, %Y %H:%M:%S (%Z)").replace("()", "").strip()
except ValueError:
return None
def _duration(seconds: Any) -> str | None: # noqa: ANN401
"""A number of seconds as ``HH:MM:SS``."""
if not isinstance(seconds, (int, float)) or isinstance(seconds, bool):
return None
whole = int(seconds)
return f"{whole // 3600:02d}:{whole % 3600 // 60:02d}:{whole % 60:02d}"
-1
View File
@@ -32,7 +32,6 @@ AUTHOR = "CipherCell"
# shorter report rather than one full of empty tables.
CONTEXT = {
"cover": "scan_id, footer_date, logo, title, identity[], severity_ledger{title, rows[]}",
"scan": "title, overview[], stages[{title, rows[], table?}]",
"project": "title, overview[], languages{title, rows[]}",
"summary": "title, overview[], distributions[{title, rows[], legend}]",
"critical": "title, table{columns[], rows[]}",
-103
View File
@@ -97,108 +97,6 @@ def _cover() -> dict[str, Any]:
}
def _scan() -> dict[str, Any]:
"""What the pipeline did, stage by stage, and what each stage was configured with."""
return {
"title": "CipherCell Scan Information",
"overview": [
_fact("Scan started at", "Wednesday, September 16, 2026 05:43:14 (UTC)"),
_fact("Scan duration", "07:30:38"),
_fact("Scan completed at", "Wednesday, September 16, 2026 13:13:52 (UTC)"),
_fact(
"Pipeline Steps",
"Preanalysis, SAST, SBOM Dependency Tracking, SBOM Reachability, AI FP Detection, AI Ranking",
),
_fact("Errors Detected", "None (2 warnings, see SBOM Reachability)"),
],
"stages": [
{
"title": "Pre-Analysis Settings",
"rows": [
_fact("Selected Tools", "Propylon v0.9.4"),
_fact("Profile", "deterministic"),
_fact("Errors Detected", "None"),
],
},
{
"title": "SAST Settings",
"rows": [
_fact("Selected Tools", "ruff v0.14.4, bandit v1.8.6, cppcheck v2.18.0, semgrep v1.145.0"),
_fact("Language Coverage", "C (cppcheck, semgrep), Python (ruff, bandit, semgrep)"),
_fact("Rule Profile", "security — ruleset ciphercell-sec-2026.03, sha256 8f2b41c6…d97a"),
_fact("Deduplication Method", "Deterministic"),
_fact("Created Artifacts", "sast_combined.sarif", kind="mono"),
_fact("Errors Detected", "None"),
],
},
{
"title": "SBOM Dependency Tracking Settings",
"rows": [
_fact("Selected Tools", "syft v1.33.0, cdxgen v11.10.0, deptrace v0.7.2"),
_fact("Profile", "Standard SBOM"),
_fact("SBOM Format", "CycloneDX 1.6"),
_fact("Advisory Sources", "NVD, OSV.dev, GitHub Advisory Database, Sonatype OSS Index"),
_fact("Created Artifacts", "sbom.cdx.json, sbom.vdr.json", kind="mono"),
_fact("Errors Detected", "None"),
],
},
{
"title": "SBOM Reachability",
"rows": [
_fact("Selected Tools", "CodeQL v2.24.1, Joern v4.0.312"),
_fact("Profile", "Default Taint Analysis"),
_fact("Created Artifacts", "sbom_annotated.vdr.json", kind="mono"),
_fact("Errors Detected", "2 warnings"),
],
"table": {
"columns": ["ID", "Stage", "Warning"],
"rows": [
{
"cells": [
"W-01",
"Joern, JavaScript",
"2 of 148 entry points could not be resolved (dynamic require() in "
"server/plugins/loader.js:41). The 6 findings depending on these entry points "
"were escalated and are reported conservatively as true issues.",
]
},
{
"cells": [
"W-02",
"CodeQL, C",
"Database build skipped for vendored sources under third_party/; excluded by "
"scan scope, no reachability verdict is claimed for those paths.",
]
},
],
},
},
{
"title": "AI FP Detection",
"rows": [
_fact("Selected Tools", "Polygraph v1.6.2"),
_fact("Profile", "static and escalation agent"),
_fact("AI Model", "Qwen3-32B, digest sha256:4ab1…c70f"),
_fact("Inference", "On-premise, CipherCell inference cluster"),
_fact("Reasoning Effort", "Default (classification), Default (escalation)"),
_fact("Response Cache", "Enabled"),
_fact("Context Enrichment", "Static (50 lines before, 50 lines after)"),
_fact("Errors Detected", "None"),
],
},
{
"title": "Ranking",
"rows": [
_fact("Selected Tools", "Prism v0.4.1"),
_fact("Effort", "Standard"),
_fact("Context Size", "Minimal"),
_fact("Errors Detected", "None"),
],
},
],
}
def _project() -> dict[str, Any]:
"""What was scanned, and what it is written in."""
return {
@@ -517,7 +415,6 @@ def sample_context() -> dict[str, Any]:
"""A complete context, covering every section the template can draw."""
return {
"cover": _cover(),
"scan": _scan(),
"project": _project(),
"summary": _summary(),
"critical": _critical(),
-11
View File
@@ -130,17 +130,6 @@
</ol>
{% endif %}
{% if scan %}
<h1 id="{{ scan.id }}" style="break-before: page">{{ scan.title }}</h1>
{{ facts(scan.overview, wide=true) }}
{% for stage in scan.stages %}
<h3>{{ stage.title }}</h3>
{{ facts(stage.rows, wide=true) }}
{% if stage.table %}{{ grid(stage.table) }}{% endif %}
{% endfor %}
{% endif %}
{% if project %}
<h1 id="{{ project.id }}" style="break-before: page">{{ project.title }}</h1>
{{ facts(project.overview, wide=true) }}