mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 12:42:38 +00:00
579291272e
V2 tracker / Backend-register-session race could land SessionStarted after ESP/Tracker signals had already advanced Stage past SessionStarted. The HandleSessionStartedV1 dead-end-Wache then swallowed the registry-derived profile facts (enrollmentType + isHybridJoin), leaving JoinMode=Unknown on every affected enrollment_complete payload (Session 10c8e0bf). Root cause was a concept mix in SessionStarted: a lifecycle anchor doing double duty as a static-facts seed. Split into two signals: - SessionStarted: pure lifecycle anchor (Stage / ClassifierTick / step). - EnrollmentFactsObserved: stage-agnostic, idempotent, monotonic facts carrier. New reducer handler delegates to ApplyEnrollmentFactsObserved (renamed from ApplySessionStarted, with set-once reason for v1 to honour the documented idempotency contract). AwaitEnrollment is transparently covered: AgentBootstrap blocks until the MDM cert exists, so the registry is guaranteed populated by the time PostEnrollmentFactsObserved runs; a single post per agent run suffices. Tests: - DecisionCore: 234/234 (4 new fact-handler tests + idempotency + monotonicity) - Agent.V2.Core: 771/771 (3 new producer tests, 1 reshaped) - Agent.Core (V1): 507/507 sanity-check unchanged Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>