parlov-output 0.8.0

Output formatters for parlov: SARIF, terminal table, and raw JSON.
Documentation

parlov-output

Output formatters for parlov. Renders oracle results as terminal tables, structured JSON, or SARIF v2.1.0.

table

use parlov_output::{render_table, render_scan_table, render_endpoint_verdict_table};

let one = render_table(&result);                                  // single OracleResult
let many = render_scan_table(&findings);                          // Vec<ScanFinding>
let endpoint = render_endpoint_verdict_table(&verdict, &findings); // EndpointVerdict summary + per-finding rows

ANSI-colored by verdict (red = Confirmed, yellow = Likely, green = NotPresent) and severity (red = High, yellow = Medium, cyan = Low). Shows confidence score and impact class. Label, Leaks, and RFC Basis rows appear when the classifier provides metadata; omitted for NotPresent results. The endpoint renderer appends a verdict summary block (verdict, posterior, severity, strategies run/total, stop reason, first-confirm + final-confirming strategy), plus Observability and Action rows when the endpoint status is not EvidenceObserved. A Probe: row under each non-NotPresent finding shows the actual wire URL pair, a Chain: row appears when the finding came from a Phase-2 chained spec, and a verbose section dumps filtered headers and body samples when --verbose was set on the scan.

Table rendering is gated to native targets. On wasm32-unknown-unknown the render_*_table exports do not exist — Cloudflare Workers consumers emit JSON or SARIF only.

json

use parlov_output::{render_json, render_scan_json, render_endpoint_verdict_json};

let one = render_json(target_url, &result, strategy_id, strategy_name, method)?;
let many = render_scan_json(target_url, &findings)?;
let endpoint = render_endpoint_verdict_json(target_url, &verdict, &findings)?;

v1.2.0 schema. Each ScanFinding carries always-present probe (baseline_url, probe_url, method) and exchange (baseline_status, probe_status) blocks; an optional chain_provenance for findings produced by generate_dag_chained_plan; optional repro curls when --repro was set; and optional verbose exchange.headers + exchange.body_samples when --verbose was set. The endpoint envelope adds observability_status (string) and an optional block_summary (expected_observation_opportunities, blocked_before_oracle_layer, blocked_fraction, dominant_block_family, dominant_block_reasons, operator_action) for non-EvidenceObserved endpoints, plus a block_family string on each Inapplicable contributing finding. Deterministic finding IDs (finding_id) for cross-run deduplication.

sarif

use parlov_output::{render_sarif, render_scan_sarif, render_endpoint_verdict_sarif};

let one = render_sarif(target_url, &result, strategy_id, method)?;
let many = render_scan_sarif(target_url, &findings)?;
let endpoint = render_endpoint_verdict_sarif(target_url, &verdict, &findings)?;

SARIF v2.1.0 with one rule per technique, security-severity derived from confidence, signals as relatedLocations, and deterministic fingerprints for cross-run deduplication. Per-result properties carry probe, exchange, and (when set) chain_provenance objects under the spec-blessed extension point. Run properties on the endpoint renderer carry endpoint posterior, contributing-finding attribution, observability_status, and operator_action.

repro curls and verbose context

use parlov_output::{build_curl, ReproInfo, ProbeContext, ExchangeContext, wire};

// build_curl renders a single reproducible curl invocation per ProbeDefinition
let curl = build_curl(&probe_definition);

// wire helpers for downstream consumers building their own contexts
let filtered = wire::filter_security_headers(&headers);
let sample = wire::truncate_body_sample(&body);

build_curl is the primitive behind --repro: emits curl -X METHOD -H 'Name: Value' ... URL with body as --data or --data-binary based on content. Headers are NOT redacted — the curls are designed to copy-paste for hand verification. wire::filter_security_headers reduces a HeaderMap to a security-relevant allowlist (Authorization, If-*, Range, Accept, Accept-Language, Content-Type, WWW-Authenticate, Cookie, Set-Cookie, and any X-*); wire::truncate_body_sample produces a 256-byte UTF-8-safe sample.

license

MIT OR Apache-2.0