Skip to content

feat(diff): add HTML formatter, side-by-side mode, analyzers, and security scoring - #245

Merged
unclesp1d3r merged 13 commits into
mainfrom
alert-fix-1
Feb 12, 2026
Merged

feat(diff): add HTML formatter, side-by-side mode, analyzers, and security scoring#245
unclesp1d3r merged 13 commits into
mainfrom
alert-fix-1

Conversation

@unclesp1d3r

@unclesp1d3r unclesp1d3r commented Feb 12, 2026

Copy link
Copy Markdown
Member

Summary

  • Formatter interface: Unified all formatters behind a shared Formatter interface with New() and NewWithMode() factory functions, replacing the switch statement in outputDiffResult()
  • HTML formatter: Self-contained HTML report output (--format html) using markdown-to-HTML conversion via goldmark, with embedded CSS, dark/light theme, collapsible sections, security badges, and print-friendly styles — fully offline, no CDN
  • Side-by-side display mode: Two-column terminal layout (--mode side-by-side) using golang.org/x/term for width detection, with automatic fallback to unified format on narrow terminals (<80 cols)
  • Semantic analyzers: New internal/diff/analyzers/ package with IP normalization (handles leading-zero octets), whitespace/port/protocol/path normalization (--normalize), and rule reorder detection (--detect-order)
  • Security impact scoring engine: New internal/diff/security/ package with pattern-based scoring (10 built-in patterns covering firewall, system, NAT, users, interfaces), aggregate risk summaries, and automatic augmentation of changes without existing security impact
  • Golden snapshot tests: Comprehensive goldie-based snapshot tests for HTML, Markdown, and JSON formatters with 3 scenarios each (no changes, single section, multi-section with security)
  • CLI wiring: New flags --format html, --mode unified|side-by-side, --normalize, --detect-order with validation, shell completions, and updated help text

New packages

  • internal/diff/formatters/Formatter interface, factory, HTML/side-by-side formatters
  • internal/diff/analyzers/ — Normalizer, OrderDetector
  • internal/diff/security/ — Scorer, Patterns, RiskSummary

Stats

  • 35 files changed, +2863 / -157 lines
  • 9 golden snapshot files for formatter regression testing
  • 0 lint issues, all tests pass

Test Plan

  • just ci-check passes (lint + all tests)
  • Golden snapshot tests for HTML, Markdown, and JSON formatters
  • Manual: opndossier diff old.xml new.xml -f html -o report.html produces valid self-contained HTML
  • Manual: opndossier diff old.xml new.xml -m side-by-side renders two-column layout
  • Manual: opndossier diff old.xml new.xml --normalize --detect-order reduces noise
  • Manual: Security badges appear in all output formats (terminal, markdown, json, html)
  • Verify narrow terminal (<80 cols) falls back to unified mode

🤖 Generated with Claude Code

- Implemented SideBySideFormatter to display diff results in a two-column layout.
- Added fallback to unified format for narrow terminals.
- Included detailed formatting for changes, including security impact badges.
- Created tests for the new formatter to ensure correct functionality.

feat(security): introduce security impact scoring system

- Added Pattern struct to define security impact matching rules.
- Implemented Scorer to evaluate security impacts based on configuration changes.
- Introduced RiskSummary and RiskItem to aggregate and report security risks.
- Added default patterns for common security risks in configurations.
- Created tests for scoring logic and pattern matching.

fix(diff): enhance section filtering and change type handling

- Added ChangeReordered type to track reordered elements.
- Improved section inclusion checks to be case-insensitive.
- Updated Result struct to include RiskSummary for comprehensive reporting.

refactor(report): streamline markdown report generation

- Refactored report generation to use a fluent interface for markdown building.
- Consolidated statistics and findings sections for better readability.
- Improved overall structure and formatting of the report output.

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Copilot AI review requested due to automatic review settings February 12, 2026 00:25
@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Feb 12, 2026
@coderabbitai

coderabbitai Bot commented Feb 12, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Summary by CodeRabbit

Release Notes

  • New Features

    • Added HTML output format for configuration diff reports
    • Added side-by-side display mode for terminal diffs
    • Added configuration value normalization (IP addresses, ports, protocols, paths) to reduce cosmetic differences
    • Added firewall rule reorder detection with new display option
    • Enhanced security impact analysis with pattern-based scoring across firewall rules, system settings, and network configurations
  • Documentation

    • Updated help text and examples to showcase new output formats and normalization options

Walkthrough

Adds HTML output and a side‑by‑side terminal formatter, a formatter factory, normalization and reorder-detection analyzers, pattern-based security scoring with RiskSummary, engine wiring to apply normalization/reorder detection/scoring, and extensive formatter/analyzer/golden tests and CLI flags.

Changes

Cohort / File(s) Summary
CLI / Command
cmd/diff.go
Adds html format, -m/--mode (unified
Formatter Factory & Types
internal/diff/formatters/formatter.go, internal/diff/formatters/formatter_test.go
Introduces Formatter interface, format constants (terminal,markdown,json,html), mode constants, and factory New/NewWithMode.
HTML Formatter & Tests
internal/diff/formatters/html.go, internal/diff/formatters/html_test.go
New HTMLFormatter that renders Markdown→HTML and emits a self-contained HTML document; tests validate structure, badges, and self-contained output.
Terminal Side‑by‑Side & Tests
internal/diff/formatters/terminal_sidebyside.go, .../terminal_sidebyside_test.go
Adds SideBySideFormatter with width detection, unified fallback, truncation/padding, two-column rendering and security badge support; tests cover layout, truncation, and badge rendering.
Markdown/Terminal Formatters
internal/diff/formatters/markdown.go
Emits Reordered summary count and symbol mapping for reordered changes; uses scorer-friendly security labels.
Formatter Golden Tests & Fixtures
internal/diff/formatters/golden_test.go, internal/diff/formatters/testdata/golden/*
Golden-file tests added for HTML/Markdown/JSON outputs with deterministic builders and fixtures.
Normalizer Analyzer & Tests
internal/diff/analyzers/normalizer.go, .../normalizer_test.go
New Normalizer with methods for IP, whitespace, port, protocol, and path normalization; comprehensive unit tests.
Order Detector & Tests
internal/diff/analyzers/order_detector.go, .../order_detector_test.go
New OrderDetector detecting reorders between ID lists; tests for various reorder scenarios.
Security Patterns & Scoring
internal/diff/security/patterns.go, internal/diff/security/scorer.go, internal/diff/security/risk.go, ..._test.go
Adds Pattern model and DefaultPatterns, Scorer with Score/ScoreAll, RiskSummary/RiskItem model and aggregation logic; tests validate matching and scoring.
Engine Integration & Tests
internal/diff/engine.go, internal/diff/engine_test.go
Wires scorer, normalizer, orderDetector into Engine; applies normalization, augments SecurityImpact via patterns, detects firewall reorders, computes RiskSummary; tests for normalization, reorder detection, and risk summary.
Core Diff Types & Tests
internal/diff/types.go, internal/diff/types_test.go
Adds ChangeReordered, Summary.Reordered, Result.RiskSummary, NewResult, Options.Mode/Normalize/DetectOrder, ChangesBySection, HasChanges, and case-insensitive section matching.
Analyzer Performance
internal/diff/analyzer.go
Replaced O(n) slice lookups with O(1) set lookups and capacity tuning for interface and DHCP comparisons.
Processor Markdown Builder
internal/processor/report.go
Refactored Markdown emission to a fluent/chained builder style and consolidated section rendering.
Markdown Rendering
internal/markdown/formatters.go
Enables Goldmark table extension and permits raw HTML in renderer (html.WithUnsafe).
Misc / Manifest / Docs
go.mod, internal/audit/plugin.go, LICENSE, AGENTS.md
Promotes golang.org/x/term to direct dependency; minor comment/license/agent docs updates.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as Diff CLI
    participant Engine as Diff Engine
    participant Normal as Normalizer
    participant OrderDet as OrderDetector
    participant Scorer as Security Scorer
    participant Factory as Formatter Factory
    participant Formatter as Concrete Formatter
    participant Writer as Output Writer

    CLI->>Engine: Compare(options, oldCfg, newCfg)
    alt DetectOrder enabled
        Engine->>OrderDet: DetectReorders(oldRuleIDs, newRuleIDs)
        OrderDet-->>Engine: []OrderChange
    end
    loop per change
        alt Normalize enabled
            Engine->>Normal: NormalizeValue(old/new)
            Normal-->>Engine: normalized value
        end
        Engine->>Scorer: Score(change) // preserves explicit SecurityImpact or matches patterns
        Scorer-->>Engine: SecurityImpact
    end
    Engine->>Scorer: ScoreAll(changes)
    Scorer-->>Engine: RiskSummary
    Engine->>Factory: NewWithMode(format, mode, Writer)
    Factory-->>Formatter: ConcreteFormatter
    Engine->>Formatter: Format(result)
    Formatter->>Writer: Write(output)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

✨ Columns split the old and new in tidy light,
Normalizers hush the noise so diffs read right.
Orders found, patterns score the riskiest thing,
HTML blooms, side‑by‑side makes changes sing.
Secure, auditable—small tools doing big things.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.75% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed Title follows conventional commit format with 'feat(diff):' prefix and clearly describes the main additions: HTML formatter, side-by-side mode, analyzers, and security scoring.
Description check ✅ Passed Description provides a clear summary, lists new packages, documents test plan outcomes, and includes statistics. Most template sections are present or reasonably addressed through the structured summary format.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch alert-fix-1

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 markdownlint-cli2 (0.20.0)
AGENTS.md

markdownlint-cli2 v0.20.0 (markdownlint v0.40.0)
Finding: AGENTS.md /*.md !CHANGELOG.md !.venv/ !/node_modules/ !/pycache/ !**/*.tpl.md
Linting: 72 file(s)
TypeError: Cannot read properties of undefined (reading 'slice')
at applyFix (file:///usr/local/lib/node_modules/markdownlint-cli2/node_modules/markdownlint/lib/markdownlint.mjs:1295:10)
at applyFixes (file:///usr/local/lib/node_modules/markdownlint-cli2/node_modules/markdownlint/lib/markdownlint.mjs:1369:26)
at file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2.mjs:817:31
at async Promise.all (index 0)
at async Promise.all (index 0)
at async main (file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2.mjs:1063:23)
at async file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2-bin.mjs:14:22


Comment @coderabbitai help to get the list of available commands and usage tips.

@dosubot dosubot Bot added component:display Issues related to display command and terminal output enhancement New feature or request security Security-related features and issues labels Feb 12, 2026
@coderabbitai coderabbitai Bot added audit Phase 4.3 tasks - Audit Report Generation documentation Improvements or additions to documentation go Pull requests that update go code priority:normal Normal priority issue testing Test infrastructure and test-related issues type:feature New feature implementation labels Feb 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds new diff output capabilities (HTML + side-by-side terminal) and introduces a security scoring subsystem intended to enrich diff results with risk summaries, fitting into the cmd/diffinternal/diff pipeline.

Changes:

  • Introduces a formatter factory + new HTML and side-by-side terminal formatters (with embedded static assets).
  • Adds new analyzer utilities (normalization + reorder detection) and a pattern-based security scoring engine with aggregated RiskSummary.
  • Extends diff CLI/options/types to support new flags, output mode, and risk summary metadata.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
internal/processor/report.go Refactors markdown generation to use chained builder calls; adjusts Summary() rendering.
internal/diff/types.go Adds ChangeReordered, risk summary types, and new diff options/behavior knobs.
internal/diff/types_test.go Extends section filtering tests for case-insensitive matches.
internal/diff/security/scorer.go Adds pattern-based scoring and aggregate risk computation.
internal/diff/security/scorer_test.go Adds unit tests for scorer behavior and aggregation.
internal/diff/security/risk.go Defines risk summary model and scoring weights for the security package.
internal/diff/security/patterns.go Defines built-in risk scoring patterns.
internal/diff/security/patterns_test.go Tests for default pattern integrity/uniqueness.
internal/diff/formatters/formatter.go Adds Formatter interface and factory (New, NewWithMode).
internal/diff/formatters/formatter_test.go Tests factory behavior and interface compliance.
internal/diff/formatters/html.go Adds self-contained HTML report formatter (template + embedded assets).
internal/diff/formatters/html_test.go Tests HTML output structure, embedding, and risk/security badge rendering.
internal/diff/formatters/terminal_sidebyside.go Adds side-by-side terminal formatter with width detection + unified fallback.
internal/diff/formatters/terminal_sidebyside_test.go Tests side-by-side formatting behavior and fallback paths.
internal/diff/formatters/static/styles.css Adds embedded CSS for HTML report (dark/light + print).
internal/diff/formatters/static/scripts.js Adds embedded JS for HTML interactivity (toggle/filter).
internal/diff/formatters/static/report.html.tmpl Adds embedded HTML template for diff reports and risk summary section.
internal/diff/formatters/markdown.go Updates security badge mapping to use diff.SecurityImpact* constants.
internal/diff/engine.go Wires in security scoring + aggregate risk summary population.
internal/diff/analyzers/normalizer.go Adds normalization helpers (IP/whitespace/port/protocol/path).
internal/diff/analyzers/normalizer_test.go Unit tests for normalizer behaviors.
internal/diff/analyzers/order_detector.go Adds reorder detection helper for ordered ID lists.
internal/diff/analyzers/order_detector_test.go Unit tests for reorder detection behavior.
cmd/diff.go Adds new CLI flags/completions/help text and uses formatter factory.
internal/audit/plugin.go Collapses package comment formatting.
go.mod Adds golang.org/x/term dependency for terminal sizing.

Comment thread cmd/diff.go Outdated
Comment thread cmd/diff.go
Comment thread internal/diff/formatters/html.go Outdated
Comment thread internal/diff/types.go
Comment thread internal/processor/report.go Outdated
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
- Fix help text: side-by-side mode is terminal-only, not HTML
- Wire --normalize and --detect-order flags into diff engine
- Fix non-deterministic HTML template iteration by using ordered slice
- Add Reordered counter to Summary struct for ChangeReordered tracking
- Include error context in report Summary() failure message
Copilot AI review requested due to automatic review settings February 12, 2026 01:55
@coderabbitai coderabbitai Bot added the dependencies Pull requests that update a dependency file label Feb 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 5 comments.

Comment thread internal/diff/formatters/terminal_sidebyside.go Outdated
Comment thread internal/diff/engine.go Outdated
Comment thread internal/diff/security/risk.go
Comment thread internal/diff/formatters/terminal_sidebyside.go
Comment thread internal/diff/formatters/formatter.go
- Add Reordered count to side-by-side terminal summary line
- Apply security scoring and SecurityOnly filtering to reorder changes
- Validate --mode side-by-side only works with --format terminal
- Document detectTerminalWidth stdout behavior
coderabbitai[bot]
coderabbitai Bot previously approved these changes Feb 12, 2026
- Replace O(n*m) slices.Contains loops with O(1) map lookups in
  CompareInterfaces and CompareDHCP
- Add capacity hints to DHCP name slice allocations
- Cache parsed HTML template at package level instead of per-Format call
- Add early exit in scorer when highest impact ("high") is reached
- Consolidate port normalization to single-pass separator detection
- Deduplicate badge text formatting in side-by-side formatter
Copilot AI review requested due to automatic review settings February 12, 2026 02:53
@coderabbitai coderabbitai Bot added the performance Performance optimization and improvements label Feb 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 6 comments.

Comment thread internal/diff/analyzers/order_detector.go
Comment thread internal/diff/security/scorer.go
Comment thread internal/diff/engine.go Outdated
Comment thread internal/diff/engine.go
Comment thread internal/diff/formatters/terminal_sidebyside.go
Comment thread internal/diff/engine.go
Replace the standalone HTML template/CSS/JS approach with a pipeline
that generates markdown via MarkdownFormatter, converts to HTML via
goldmark (already a dependency), and wraps in a minimal HTML shell.

This eliminates 3 static asset files (template, CSS, JS), removes the
go:embed dependency, and ensures HTML output stays consistent with
markdown output since it's derived from the same source.
Copilot AI review requested due to automatic review settings February 12, 2026 03:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated 4 comments.

Comment thread internal/diff/security/scorer.go Outdated
Comment thread internal/diff/types.go Outdated
Comment thread internal/diff/formatters/html.go
Comment thread internal/diff/formatters/terminal_sidebyside.go
…rmatters

Adds goldie-based snapshot tests covering all diff formatters with three
scenarios: no changes, single section, and multi-section with security
badges. Includes consistency and structural validation tests for HTML.
Replace duplicate RiskSummary/RiskItem structs with type aliases to
security package, eliminating field-by-field copy in computeRiskSummary.
Remove redundant golden tests (trivial determinism, structure checks
already covered by snapshots) and consolidate interface compliance tests.
Copilot AI review requested due to automatic review settings February 12, 2026 03:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 34 out of 34 changed files in this pull request and generated 3 comments.

Comment thread internal/diff/formatters/html.go
Comment thread internal/diff/engine.go Outdated
Comment thread cmd/diff.go
- Add nil receiver guard to RiskSummary.HasRisks()
- Wrap HTML formatter write error with context
- Add ChangeReordered to side-by-side style switch
- Use rune-based truncation to prevent UTF-8 garbling
- Fix global state leakage in diffSections normalization
- Enable goldmark table extension for proper HTML table rendering
- Pre-compile regex patterns to package-level variables
- Document TopRisks tier-based prioritization strategy
- Add IPv6 and invalid CIDR test cases for normalizer
- Use require.False/ErrorContains for stronger test assertions
- Add t.Parallel() to stateless table-driven tests
- Regenerate golden files with proper HTML table elements
Copilot AI review requested due to automatic review settings February 12, 2026 04:56
@unclesp1d3r unclesp1d3r self-assigned this Feb 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 37 out of 37 changed files in this pull request and generated 2 comments.

Comment thread internal/diff/security/scorer.go
Comment thread internal/diff/formatters/golden_test.go
coderabbitai[bot]
coderabbitai Bot previously approved these changes Feb 12, 2026
- Sort DetectReorders output by ID for deterministic results (partial #243)
- Make NormalizePort safe for non-port strings (validate input is numeric)
- Fix ANSI escape sequence column misalignment in side-by-side formatter
- Enable goldmark unsafe HTML to preserve <details> sections in HTML output
- Filter duplicate reorder/modified changes for same firewall rule
- Fix misleading --normalize flag description (display normalization, not comparison)
- Update ChangeInput.Type comment to include "reordered"
- Add 5 engine integration tests for DetectOrder, Normalize, and RiskSummary
- Regenerate golden files for HTML formatter
@unclesp1d3r

Copy link
Copy Markdown
Member Author

Addressed all unresolved Copilot review findings in commit 1787694:

Code fixes:

  • order_detector.go:47 - Sorted DetectReorders output by ID for deterministic results (also partial fix for Implement deterministic ordering for map-based configuration elements #243)
  • scorer.go:101/100 - TopRisks already uses tier-based prioritization: medium items are only appended when summary.High == 0. This prevents medium items from crowding out high items.
  • engine.go (normalize) - Fixed misleading --normalize description to "Normalize displayed values". Also added skip logic for changes where normalized values are equal.
  • engine.go:214 (detect-order) - Reorder detection now runs AFTER section comparison and filters out UUIDs that already have content changes.
  • terminal_sidebyside.go:66 - By design: queries os.Stdout since side-by-side is only for interactive terminals. Falls back to unified when width < 80.
  • engine.go:161 - NormalizePort now validates input is numeric before processing, preventing damage to non-port strings.
  • scorer.go:24 - Updated ChangeInput.Type comment to include "reordered".
  • terminal_sidebyside.go:130 - Replaced %-*s with padRight() using lipgloss.Width() for ANSI-safe alignment.
  • html.go:82 - Added html.WithUnsafe() to goldmark renderer to preserve <details> sections.
  • engine_test.go - Added 5 engine integration tests for DetectOrder, Normalize, and RiskSummary.
  • cmd/diff.go:76 - Fixed flag help text.

Low priority/deferred:

  • golden_test.go:141 - RiskSummary in golden tests: Scoring is tested separately in security/scorer_test.go. Adding scorer integration to golden tests would tightly couple formatter and scorer tests.

When --normalize is enabled, skip modified changes where normalized
old and new values are equal (e.g., IP with different leading zeros).
This makes normalize actually reduce noise rather than just reformatting
display values. Also extract repeated test path to constant.
Copilot AI review requested due to automatic review settings February 12, 2026 05:16
@unclesp1d3r
unclesp1d3r merged commit 2697020 into main Feb 12, 2026
20 of 24 checks passed
@unclesp1d3r
unclesp1d3r deleted the alert-fix-1 branch February 12, 2026 05:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 38 out of 38 changed files in this pull request and generated no new comments.

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

Labels

audit Phase 4.3 tasks - Audit Report Generation component:display Issues related to display command and terminal output dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation enhancement New feature or request go Pull requests that update go code performance Performance optimization and improvements priority:normal Normal priority issue security Security-related features and issues size:XXL This PR changes 1000+ lines, ignoring generated files. testing Test infrastructure and test-related issues type:feature New feature implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants