Skip to main content

function_identity_id

Function function_identity_id 

Source
pub fn function_identity_id(file: &str, name: &str, start_line: u32) -> String
Expand description

Compute the deterministic FunctionIdentity::stable_id for a function.

Emits fallow:fn:<hash> where <hash> is the first 16 hex characters (first 8 bytes) of SHA-256(file \0 name \0 start_line). The preimage is NUL-delimited: the three fields joined by single 0x00 bytes, with start_line rendered as its decimal ASCII string. There is no trailing salt; the fallow:fn: prefix namespaces the value against the per-surface helpers.

§Why columns are NOT in the hash

The canonical hash inputs intentionally exclude column / span / source hash metadata. Two producers observing the same function with different positional fidelity (V8 dumps that lack columns vs Istanbul fnMap that has them, vs oxc spans that have byte-accurate positions) MUST produce the same stable_id so the cross-surface join holds. Columns survive on the wire (see FunctionIdentity::start_column) for display and same-line disambiguation, but are NOT part of the hash.

§Why NUL-delimited and 16 hex (0.8.0)

The 0.8.0 recipe reconciles this helper with the cloud aggregation store, which was authored NUL-delimited and 64-bit first. NUL delimiters prevent preimage ambiguity (unseparated file + name lets ("ab","c") collide with ("a","bc")); producers MUST reject NUL bytes in file / name so a delimiter cannot be smuggled into the input. The 16-hex (64-bit) truncation keeps the birthday-collision bound safe for large monorepos aggregated over time, where 8 hex (32-bit) becomes risky past ~65k functions in one partition.

§Why there is no kind parameter

Unlike finding_id / hot_path_id / blast_radius_id / importance_id, which are per-surface stable IDs, this helper produces ONE canonical ID per function across every surface the function appears on (findings, hot paths, blast radius, importance, static inventory). That is the whole point of the cross-surface join.

The canonical preimage, delimiter, and truncation are part of the wire contract. Changing any of them breaks ID stability across runs and invalidates any consumer that persists IDs (CI deduplication, suppression files, agent cross-references) and is therefore always a major bump. See function_identity_id_v1 for the pre-0.8.0 recipe kept for the upgrade grace window.

Added in protocol 0.6.0; recipe reconciled in 0.8.0.