G findings4 watchman: a finding's id keeps the safe key parts its condition's key had

Builds: design 47 G §689, A-14
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
2026-11-11 21:56:38 +01:00
parent 8cbb86dfbd
commit 7310af36e6
@@ -66,15 +66,29 @@ func (f Finding) Key() string {
return FindingKey(f.Scope, f.ID, token)
}
// KeyID is an id as the parts of a key: each dot-separated part made safe for a bus key, as the key of a condition is
// (mcc.Key), so the finding's key keeps the shape its condition had.
func KeyID(id string) string {
parts := strings.Split(id, ".")
for i, p := range parts {
p = unsafeKey.ReplaceAllString(strings.TrimSpace(p), "_")
if p == "" {
p = "_"
}
parts[i] = p
}
return strings.Join(parts, ".")
}
// Contract is f as the seat mesh-conditions' generated finding (design 47 G §686, §689): a ref, where the finding has a
// token other than its kind, goes into the id as `<id>.<ref>` (A-14), and is kept in `ref` so the finding reads back as
// it was written. The resolved words are not a field of the seat (A-22), and its `at` is its `since`, so the same thing
// observed again writes the same bytes.
func (f Finding) Contract() condseat.Finding {
id, ref := f.ID, ""
id, ref := KeyID(f.ID), ""
if f.Token != "" && f.Token != f.Kind {
ref = f.Token
id = f.ID + "." + ref
id = id + "." + KeyID(ref)
}
v := condseat.Finding{Scope: f.Scope, ID: id, Kind: f.Kind, Ref: ref, Severity: f.Severity, Summary: f.Summary,
Headline: f.Headline, Explanation: f.Explanation, Needs: f.Needs, Source: f.Source, Observer: Observer,