pub fn function_identity_id(file: &str, name: &str, start_line: u32) -> StringExpand 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.