diff --git a/strix/tools/finish/tool.py b/strix/tools/finish/tool.py index 9484a453..e3dcb7ae 100644 --- a/strix/tools/finish/tool.py +++ b/strix/tools/finish/tool.py @@ -238,12 +238,17 @@ async def finish_scan( remediation steps. End with retest/validation guidance. - **Formatting — use markdown in every field.** These fields may be - rendered into generated reports, so structure them clearly: lead - each section with a short ``# Heading``, use ``**bold**`` for labels/emphasis, - ``inline code`` for identifiers/paths/parameters, bullet or - numbered lists for enumerations, and fenced code blocks - (```` ```language ````) for any code/payload excerpts. Never emit - one flat wall of prose or leave code unformatted. + rendered into generated reports, so structure them clearly: use + ``**bold**`` for labels/emphasis, ``inline code`` for + identifiers/paths/parameters, bullet or numbered lists for + enumerations, and fenced code blocks (```` ```language ````) for + any code/payload excerpts. Never emit one flat wall of prose or + leave code unformatted. + - **Each field is a section body, not a document.** The report adds + the section title ("Executive Summary", "Methodology", ...) itself, + so do NOT start a field with a heading such as ``# Executive + Summary`` — it would print twice. Sub-headings (``##``) inside a + field are fine. - If **zero** vulnerabilities were found, say so plainly and characterize the posture positively; ``technical_analysis`` should summarize the areas tested and confirm no issues, and @@ -252,8 +257,6 @@ async def finish_scan( Example (abbreviated — mirror this structure, not the wording):: executive_summary: - # Executive Summary - An external assessment of the **Acme Customer Portal** identified multiple weaknesses that could lead to unauthorized access to customer data. @@ -269,8 +272,6 @@ async def finish_scan( - Potential exposure of customer records across tenants. methodology: - # Methodology - Conducted per the **OWASP WSTG**. **Engagement type:** Gray-box external test. @@ -280,8 +281,6 @@ async def finish_scan( and tenant-isolation testing, input/SSRF testing. technical_analysis: - # Technical Analysis - **Severity model** reflects exploitability x impact. 1. **SSRF in URL preview** (Critical) — insufficient @@ -293,8 +292,6 @@ async def finish_scan( no deny-by-default egress policy. recommendations: - # Recommendations - **Immediate** 1. Remediate SSRF: enforce a destination allowlist, deny-by-default, re-validate on every redirect hop. diff --git a/tests/test_reporting_fields.py b/tests/test_reporting_fields.py index 46d55af3..86e90d62 100644 --- a/tests/test_reporting_fields.py +++ b/tests/test_reporting_fields.py @@ -1085,7 +1085,9 @@ def test_tool_descriptions_include_formatting_guidance() -> None: finish_desc = finish_scan.description assert "markdown" in finish_desc.lower() - assert "# Executive Summary" in finish_desc + assert "section body" in finish_desc.lower() + assert "do not start a field with a heading" in finish_desc.lower() + assert "\n # Executive Summary" not in finish_desc dep_desc = create_dependency_report.description assert "cve" in dep_desc.lower()