Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions pkg/parser/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -686,30 +686,38 @@ func Hash(h string) string {
return base58.Encode(hash[:])
}

// HashRule to provide a unique stable identity for the rule. It can be used for dupe detection.
// The hash is based on the rule's content, excluding metadata that is not semantically important.
// HashRule to provide a unique identity for the rule.
// The hash is based on the rule's content, excluding previous hash calculations.
Copy link

Copilot AI May 28, 2025

Choose a reason for hiding this comment

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

[nitpick] The phrase "excluding previous hash calculations" can be clearer; consider specifying "excluding the existing rule.Metadata.Hash field" so readers understand exactly which metadata is omitted.

Copilot uses AI. Check for mistakes.

func HashRule(rule ParseRuleT) (string, error) {
rule.Metadata.Hash = "" // Hash is what we are generating here, not semantically important
return _hashRule(rule)
}

// StableHash to provide a unique stable identity for the rule. It can be used for dupe detection.
// The hash is based on the rule's content, excluding metadata that is not semantically important.

// Strip out versioning metadata before calculating the hash.
func StableHash(rule ParseRuleT) (string, error) {

// Strip out versioning metadata before calculating the stable hash.
// The versioning metadata is not semantically important for the rule's content,
// so we can safely ignore it for the purpose of hashing.
// This is important to ensure that the hash remains consistent across changes
// that do not affect the rule's content, such as version bumps or metadata changes.

// The field rule.Metadata.Id is considered part of the rules identity and should be included in the hash.
// The field rule.Metadata.Id is considered part of the rules identity and should be included in the stable hash.
// Rules can change over time having the following properties:
// - Metadata.Id: Unique identifier for the rule, which is immutable for the lifetime of the rule.
// - Metadata.Hash: A hash of the rule's content, which is regenerated on every semantic change.
// - Metadata.Version: A version string that *should* be incremented on changes, but is not semantically important.
// - Metadata.Gen: A generation counter that is incremented on every change, but is not semantically important.

// NOTE: Modify 'rule' is acceptable because parameter passed by value.

rule.Metadata.Gen = 0 // Gen is bumped on every semantic change, so we don't want it in the hash
rule.Metadata.Hash = "" // Hash is what we are generating here, not semantically important
rule.Metadata.Version = "" // Version may be bumped on change, also not semantically important
return HashRule(rule)
}

func _hashRule(rule ParseRuleT) (string, error) {
// json.Marshal to produce deterministic output
jsonBytes, err := json.Marshal(rule)
if err != nil {
Expand Down