From a612584841a998d3ecf43a417e552f3db7d4ffdf Mon Sep 17 00:00:00 2001 From: jedarden Date: Mon, 6 Jul 2026 17:00:58 -0400 Subject: [PATCH] feat(bf-5151): add canonical identity fields to blob creation types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the three new canonical identity fields — PersonName, AssignedColor, IdentityResolved — to the four primary tracked-blob struct types that are constructed at the blob-creation sites catalogued in bf-1q3m: - signal.TrackedBlob (internal/signal/processor.go) — canonical type; api.TrackedBlob is a type alias of it - tracker.Blob (3D) (internal/tracker/tracker.go) - tracking.Blob (2D) (internal/tracking/tracker.go) - automation.TrackedBlob (internal/automation/engine.go) The camelCase JSON keys (personName, assignedColor, identityResolved) match the dashboard Blob interface in dashboard/types/spaxel.d.ts, which viz3d.js reads directly. The legacy snake_case PersonLabel/PersonColor fields are retained as deprecated aliases for backward compatibility. Per the task, the fields are left at their zero values for existing blobs: empty strings and a nil *bool all carry omitempty, so they serialize as omitted (undefined in JS). A follow-up bead populates them from the BLE identity sidecar. IdentityResolved is *bool to faithfully represent the tri-state semantics (nil=unattempted, &true=resolved, &false=failed). fusion.Blob is intentionally untouched: it is the pre-identity Fresnel peak type ({X,Y,Z,Confidence} only) and is out of scope for identity per bf-1q3m. Verified: gofmt clean, go vet ./... clean, go test ./... passes; marshaling check confirms zero-value blobs omit the fields (undefined) while set blobs emit the camelCase keys. Co-Authored-By: Claude --- mothership/internal/automation/engine.go | 8 ++++++++ mothership/internal/signal/processor.go | 9 +++++++++ mothership/internal/tracker/tracker.go | 8 ++++++++ mothership/internal/tracking/tracker.go | 8 ++++++++ 4 files changed, 33 insertions(+) diff --git a/mothership/internal/automation/engine.go b/mothership/internal/automation/engine.go index db76136..03f02d7 100644 --- a/mothership/internal/automation/engine.go +++ b/mothership/internal/automation/engine.go @@ -1339,6 +1339,14 @@ type TrackedBlob struct { X, Y, Z float64 VX, VY, VZ float64 Confidence float64 + + // Canonical identity fields (bf-5151). camelCase JSON keys match the dashboard + // Blob type in dashboard/types/spaxel.d.ts. Left at zero values (undefined) for + // existing blobs — a follow-up bead populates them from the BLE identity sidecar + // so person-aware automations ("when Alice enters…") can fire. + PersonName string `json:"personName,omitempty"` + AssignedColor string `json:"assignedColor,omitempty"` + IdentityResolved *bool `json:"identityResolved,omitempty"` // tri-state: nil=unattempted, &true=resolved, &false=failed } // Evaluate processes tracked blobs and triggers automations based on zone/volume crossings. diff --git a/mothership/internal/signal/processor.go b/mothership/internal/signal/processor.go index b83e7cb..20f4282 100644 --- a/mothership/internal/signal/processor.go +++ b/mothership/internal/signal/processor.go @@ -596,6 +596,15 @@ type TrackedBlob struct { IdentityConfidence float64 `json:"identity_confidence,omitempty"` IdentitySource string `json:"identity_source,omitempty"` Posture string `json:"posture,omitempty"` + + // Canonical identity fields (bf-5151). camelCase JSON keys match the dashboard + // Blob type in dashboard/types/spaxel.d.ts; the snake_case PersonLabel/PersonColor + // above are retained as deprecated aliases for backward compatibility. Left at + // their zero values here (undefined) — a follow-up bead populates them from the + // BLE identity sidecar. + PersonName string `json:"personName,omitempty"` + AssignedColor string `json:"assignedColor,omitempty"` + IdentityResolved *bool `json:"identityResolved,omitempty"` // tri-state: nil=unattempted, &true=resolved, &false=failed } // SetTrackedBlobs stores the latest tracked blobs from the fusion engine. diff --git a/mothership/internal/tracker/tracker.go b/mothership/internal/tracker/tracker.go index 74ed6bc..1e62ec6 100644 --- a/mothership/internal/tracker/tracker.go +++ b/mothership/internal/tracker/tracker.go @@ -51,6 +51,14 @@ type Blob struct { IdentitySource string `json:"identity_source,omitempty"` // "ble_triangulation", "ble_only", or "" IdentityLastSeen time.Time `json:"-"` // Last time identity was confirmed + // Canonical identity fields (bf-5151). camelCase JSON keys match the dashboard + // Blob type in dashboard/types/spaxel.d.ts; the snake_case fields above are + // retained as deprecated aliases. Left at zero values (undefined) for existing + // blobs — populated later from the BLE identity sidecar. + PersonName string `json:"personName,omitempty"` + AssignedColor string `json:"assignedColor,omitempty"` + IdentityResolved *bool `json:"identityResolved,omitempty"` // tri-state: nil=unattempted, &true=resolved, &false=failed + ukf *UKF // internal — nil in copies returned to callers } diff --git a/mothership/internal/tracking/tracker.go b/mothership/internal/tracking/tracker.go index 4e30fb9..1df5ab1 100644 --- a/mothership/internal/tracking/tracker.go +++ b/mothership/internal/tracking/tracker.go @@ -37,6 +37,14 @@ type Blob struct { IdentitySource string `json:"identity_source,omitempty"` // "ble_triangulation", "ble_only", or "" IdentityLastSeen time.Time `json:"-"` // Last time identity was confirmed Posture Posture `json:"posture,omitempty"` // Estimated body posture + + // Canonical identity fields (bf-5151). camelCase JSON keys match the dashboard + // Blob type in dashboard/types/spaxel.d.ts; the snake_case fields above are + // retained as deprecated aliases. Left at zero values (undefined) for existing + // blobs — populated later from the BLE identity sidecar. + PersonName string `json:"personName,omitempty"` + AssignedColor string `json:"assignedColor,omitempty"` + IdentityResolved *bool `json:"identityResolved,omitempty"` // tri-state: nil=unattempted, &true=resolved, &false=failed } // TrailMaxLen is the maximum number of trail points kept per blob.