Skip to main content

Crate fallow_cov_protocol

Crate fallow_cov_protocol 

Source
Expand description

Versioned envelope types shared between the public fallow CLI and the closed-source fallow-cov production-coverage sidecar.

The public CLI builds a Request from its static analysis output, spawns the sidecar, writes the request to stdin, and reads a Response from stdout. Both sides depend on this crate to guarantee contract alignment.

§Versioning

The top-level protocol_version field is a full semver string. Major bumps indicate breaking changes; consumers MUST reject mismatched majors. Minor bumps add optional fields; consumers MUST forward-accept unknown fields and SHOULD map unknown enum variants to Feature::Unknown, ReportVerdict::Unknown, or Verdict::Unknown rather than erroring.

§0.2 overview

This is the first production-shaped contract. The top-level ReportVerdict (previously Verdict) is unchanged in meaning but was renamed to avoid colliding with per-finding Verdict. Each Finding and HotPath now carries a deterministic finding_id / hot_path_id hash, a full Evidence block, and — for findings — a per-function verdict and nullable invocation count. Confidence gained VeryHigh and None variants to match the decision table in .internal/spec-production-coverage.md.

StaticFunction::static_used and StaticFunction::test_covered are intentionally required (no #[serde(default)]) — a silent default would hide every safe_to_delete finding, so 0.1-shape requests must fail deserialization instead of parsing into a wrong answer.

§0.5 changes

  • HotPath gained an end_line field so consumers can match a hot path against a PR diff at line granularity, not just file granularity. The field is #[serde(default)] for forward-tolerance with 0.4-shape sidecars; readers MUST treat a 0 value as a single-line range (line..=line).
  • ReportVerdict::HotPathChangesNeeded was renamed to ReportVerdict::HotPathTouched. The wire string changes from hot-path-changes-needed to hot-path-touched. The verdict reads as a state observation rather than an action item; it is informational.

§0.6 changes

  • New FunctionIdentity type and optional identity field threaded through StaticFunction, Finding, HotPath, BlastRadiusEntry, and ImportanceEntry. Becomes the canonical join key between the CLI’s static function inventory, V8 / Istanbul runtime coverage, test coverage from oxc-coverage-instrument, source-map remapped findings, and fallow-cloud aggregation when present. Older 0.5-shape envelopes continue to deserialize with identity: None; consumers SHOULD prefer identity.stable_id as the join key when present and fall back to the legacy file + function + line triple otherwise.
  • New function_identity_id helper emitting fallow:fn:<8 hex> (this 0.6 recipe was reconciled to a NUL-delimited 16-hex digest in 0.8.0; see # 0.8 changes). The helper hashes only file + name + start_line + "function" (NOT columns) so producers with different positional fidelity (V8 byte offsets vs Istanbul UTF-16 columns vs oxc spans) agree on the join key for the same function. Columns survive on the wire as descriptive metadata for same-line disambiguation in display.
  • New IdentityResolution enum with Resolved / Fallback / Unresolved / Unknown variants. Lets cloud aggregation record per function whether the identity came from a source-map lookup, a line-only fallback, or remains unresolved.
  • StaticFunction, Finding, HotPath, BlastRadiusEntry, and ImportanceEntry are now #[non_exhaustive]. This is a one-time source-side break for downstream Rust consumers that constructed these via struct literals (the wire shape is unchanged and forward-compatible). Future field additions become pure additive changes; the CHANGELOG calls out the migration path.

§0.7 changes

  • FunctionIdentity::source_hash format is now pinned: the first 8 bytes of SHA-256(<canonical body bytes>) rendered as 16 lowercase hex characters. Compute via the new source_hash_for helper. Producers that cannot canonicalize the bytes the same way as their siblings MUST omit the field rather than emit a divergent format. Closes the cross-producer non-comparability gap that the 0.6.0 “producer-defined, opaque string” wording allowed.
  • New source_hash_for helper. Reuses the existing sha2 dependency. No new transitive deps. Anchor fixture (source_hash_for_anchor_fixture in the test module) pins a known input to a known output so producers can self-test.
  • Tightened rustdoc on FunctionIdentity::stable_id_computed documenting the method as a diagnostic helper, NOT a validation gate. Consumers MUST NOT reject payloads whose stable_id differs from the value returned by the helper.
  • Byte-level JSON-shape anchor fixtures added for FunctionIdentity (full + minimal) plus anchor fixtures for blast_radius_id and importance_id parallel to the existing function_identity_id fixture.
  • RiskBand and CoverageSource gain Unknown sentinel variants with #[serde(other)]. Future producers MAY add new variants as additive minor bumps; consumers map unseen variants to Unknown rather than failing deserialization.
  • 0.7.2 (docs only, no wire change): corrected the rustdoc and CHANGELOG claim that FunctionIdentity::stable_id is “stable across line moves”. It hashes start_line, so a moved function gets a new stable_id; it is the cross-surface + cross-producer join key, not a line-move-immune one. Line-move-tolerant matching belongs on the content-based FunctionIdentity::source_hash.

§0.8 changes

  • BREAKING: function_identity_id recipe reconciled. The stable_id preimage is now NUL-delimited (file \0 name \0 start_line) and truncated to 16 hex chars (64 bits) instead of the 0.7.x unseparated file + name + start_line + "function" truncated to 8 hex. This matches the cloud aggregation store’s recipe (authored NUL-delimited + 64-bit first) and keeps the column exclusion. Every fallow:fn: value changes; persisted ids (CI dedup, suppression files, cloud function_hits) reset and must be regenerated. function_identity_id_v1 retains the 0.7.x recipe for the upgrade grace window: consumers recompute both and match either until the next re-baseline.

Structs§

Action
Machine-readable next-step hint for AI agents.
BlastRadiusEntry
A function with meaningful static or traffic-weighted blast radius.
CaptureQuality
Capture-quality telemetry surfaced alongside the aggregate summary.
DiagnosticMessage
Error / warning surfaced by the sidecar.
Evidence
Supporting evidence for a Finding. Mirrors the rows of the decision table in .internal/spec-production-coverage.md so the CLI can render the “why” behind each verdict without re-deriving it.
Finding
A per-function finding combining static analysis and runtime coverage.
FunctionIdentity
Canonical, versioned identity for a function.
HotPath
A function the sidecar identified as a hot path in the current dump.
ImportanceEntry
A function ranked by runtime traffic, complexity, and ownership risk.
License
The license material the sidecar should validate.
Options
Runtime knobs. All fields are optional so new options can be added without a breaking change.
Request
Sent by the public CLI to the sidecar via stdin.
Response
Emitted by the sidecar to stdout.
StaticFile
Static analysis results for a single source file.
StaticFindings
Static analysis output the public CLI already produced.
StaticFunction
Static analysis results for a single function within a StaticFile.
Summary
Aggregate statistics describing the observed coverage dump.

Enums§

Confidence
Confidence the sidecar attaches to a Finding::verdict.
CoverageSource
A single coverage artifact on disk.
Feature
Feature flags present in the license JWT’s features claim.
IdentityResolution
How a FunctionIdentity was produced by the upstream coverage pipeline.
ReportVerdict
Top-level report verdict for a coverage analysis run.
RiskBand
Risk band for a blast-radius entry.
Verdict
Per-finding verdict. Replaces the 0.1 CallState enum.
Watermark
What to render in the human output when the license is in the grace window.

Constants§

PROTOCOL_VERSION
Current protocol version. Bumped per the semver rules above.

Functions§

blast_radius_id
Compute the deterministic BlastRadiusEntry::id for a blast-radius entry.
finding_id
Compute the deterministic Finding::id for a production-coverage finding.
function_identity_id
Compute the deterministic FunctionIdentity::stable_id for a function.
function_identity_id_v1Deprecated
Compute the pre-0.8.0 FunctionIdentity::stable_id recipe.
hot_path_id
Compute the deterministic HotPath::id for a hot-path finding. Uses the same canonical order as finding_id with kind "hot", emitting fallow:hot:<hash>.
importance_id
Compute the deterministic ImportanceEntry::id for an importance entry.
source_hash_for
Compute the canonical FunctionIdentity::source_hash for the given canonical body bytes.