Documentation
¶
Index ¶
- Constants
- Variables
- func ChainBusObservers(observers ...protocol.BusObserver) protocol.BusObserver
- func CheckExplicitSourceCompanionConflict(explicitSource byte, selection *protocol.SourceAddressSelection, ...) bool
- func DefaultStartupAdmissionSourceSelectionConfig() protocol.SourceAddressSelectionConfig
- func EmitStartupResetWarn(logger func(format string, args ...interface{}))
- func EntryContainsAddress(entry registry.DeviceEntry, addr byte) bool
- func FormatStartupSourceSelectionExplicitLog(source byte) string
- func IsB524ResponseCoherent(responseData []byte, group byte, addr uint16) bool
- func NewRegisterDumpUploadHandler(outputDir string) http.Handler
- func NewSourceSelectionBusAdapter(reconstructor *PassiveTransactionReconstructor, name string, ...) (protocol.SourceAddressSelectionBus, error)
- func PassiveTransportSupported(cfg Config) bool
- func RejoinBackoffSchedule(attempt int, baseSeconds, maxSeconds int) time.Duration
- func RunSmoke(ctx context.Context, cfg smokeConfig, opts SmokeOptions) (runErr error)
- func RunSmokeFromEnv(ctx context.Context, opts SmokeOptions) error
- func ScanWithFullRangeGuard(ctx context.Context, bus registry.ScanBus, reg *registry.DeviceRegistry, ...) ([]registry.DeviceEntry, error)
- func SelectDefaultStartupSourceAddress(ctx context.Context) (protocol.SourceAddressSelection, error)
- func SnapshotContainsAddress(snap registry.DeviceEntrySnapshot, addr byte) bool
- func SnapshotTargetAddressForRouting(snap registry.DeviceEntrySnapshot) byte
- func StartupAdmissionConfigWithHint(hint byte, hintSet bool) protocol.SourceAddressSelectionConfig
- func StartupSourceSelectionExpvarNames() []string
- func TargetAddressForRouting(entry registry.DeviceEntry) byte
- func ValidateBaselineTopologySeed(seed []byte) error
- func ValidateSourceSelectionMode(v string) error
- func ValidateStartupAdmissionStability(stateMinStabilitySeconds int) error
- type ActivePassiveDeduplicator
- func (deduplicator *ActivePassiveDeduplicator) AttachReconstructor(ctx context.Context, reconstructor *PassiveTransactionReconstructor) error
- func (deduplicator *ActivePassiveDeduplicator) Budgets() dedupTimingBudgets
- func (deduplicator *ActivePassiveDeduplicator) Close() error
- func (deduplicator *ActivePassiveDeduplicator) LocalAddressSnapshot() LocalAddressSnapshot
- func (deduplicator *ActivePassiveDeduplicator) Observe(key WatchKey) WatchObservation
- func (deduplicator *ActivePassiveDeduplicator) OnBusEvent(event protocol.BusEvent) error
- func (deduplicator *ActivePassiveDeduplicator) OnPassiveClassifiedEvent(event PassiveClassifiedEvent)
- func (deduplicator *ActivePassiveDeduplicator) SetWatchObserver(observer WatchObserver)
- func (deduplicator *ActivePassiveDeduplicator) Subscribe(name string, priority DedupSubscriberPriority, buffer int) (*AdjudicatedPassiveSubscription, error)
- type ActiveTransactionFingerprint
- type AdaptermuxDiagSnapshot
- type AddressObservation
- type AddressSlot
- type AddressTable
- type AddressTableInserter
- func (i *AddressTableInserter) BackfillUnidentifiedAddresses()
- func (i *AddressTableInserter) OnPassiveClassifiedEvent(event PassiveClassifiedEvent)
- func (i *AddressTableInserter) SetEnrichmentIdentityProbeFn(fn func(addr byte))
- func (i *AddressTableInserter) SetEnrichmentRefreshFn(fn func())
- func (i *AddressTableInserter) SetRuntimeStateObserver(fn RuntimeStateObserver)
- type AdjudicatedPassiveEvent
- type AdjudicatedPassiveSubscription
- type AdmissionStabilityWindow
- type B509WatchKey
- type B516WatchKey
- type B524WatchKey
- type B555WatchKey
- type BroadcastListener
- func StartBroadcastListener(ctx context.Context, cfg Config, router *router.BusEventRouter) (*BroadcastListener, error)
- func StartBroadcastListenerWithReconstructor(ctx context.Context, router *router.BusEventRouter, ...) (*BroadcastListener, error)
- func StartBroadcastListenerWithTransport(ctx context.Context, cfg Config, router *router.BusEventRouter, ...) (*BroadcastListener, error)
- type BusAdmission
- type BusAdmissionActiveProbe
- type BusAdmissionRejectedCandidate
- type BusAdmissionSourceSelection
- type BusBusyAggregate
- type BusBusyWindow
- type BusErrorAggregate
- type BusFrameAggregate
- type BusMessageRecord
- type BusObservabilityBoundedList
- type BusObservabilityCapability
- type BusObservabilityCounters
- type BusObservabilityDegraded
- type BusObservabilitySnapshot
- type BusObservabilityStartup
- type BusObservabilityStatus
- type BusObservabilityStore
- func (store *BusObservabilityStore) AttachReconstructor(ctx context.Context, reconstructor *PassiveTransactionReconstructor) error
- func (store *BusObservabilityStore) Close() error
- func (store *BusObservabilityStore) EvidenceBuffer() *EvidenceBuffer
- func (store *BusObservabilityStore) MetricsHandler() http.Handler
- func (store *BusObservabilityStore) ObserveWatchDirectApply(event WatchEfficiencyDirectApplyEvent)
- func (store *BusObservabilityStore) ObserveWatchRead(event WatchEfficiencyReadEvent)
- func (store *BusObservabilityStore) OnBusEvent(event protocol.BusEvent) error
- func (store *BusObservabilityStore) OnPassiveClassifiedEvent(event PassiveClassifiedEvent)
- func (store *BusObservabilityStore) PeriodicitySnapshot() []BusPeriodicityEntry
- func (store *BusObservabilityStore) ProtocolSpecimens(family string) []ProtocolSpecimenExport
- func (store *BusObservabilityStore) RecentMessages(limit int) []BusMessageRecord
- func (store *BusObservabilityStore) RecordBusAdmissionTransition(state string, source, companionTarget byte, reason string) bool
- func (store *BusObservabilityStore) RenderPrometheus() string
- func (store *BusObservabilityStore) SetAdaptermuxDiagProvider(provider func() AdaptermuxDiagSnapshot)
- func (store *BusObservabilityStore) SetAdmissionStabilityWindow(window *AdmissionStabilityWindow)
- func (store *BusObservabilityStore) SetAdmittedSourceProvider(provider func() byte)
- func (store *BusObservabilityStore) SetEnergyFreshnessMetricsRefresher(refresher func(now time.Time, passiveState string))
- func (store *BusObservabilityStore) SetStartupSurfaceProvider(provider func() *BusObservabilityStartup)
- func (store *BusObservabilityStore) SetV8RolloutProvider(provider func() V8RolloutSnapshot)
- func (store *BusObservabilityStore) Snapshot() BusObservabilitySnapshot
- type BusObservabilitySummary
- type BusObservabilityTimingQuality
- type BusObservabilityWarmup
- type BusPeriodicityEntry
- type BusReconstructorAggregate
- type BusReconstructorRecovery
- type CanonicalAddressView
- type Config
- type DedupDisposition
- type DedupOutcomeClass
- type DedupResponseClass
- type DedupSubscriberPriority
- type DedupTransactionClass
- type DegradedModeAccumulator
- func (a *DegradedModeAccumulator) ClearLatch()
- func (a *DegradedModeAccumulator) CumulativeDegradedMs() uint64
- func (a *DegradedModeAccumulator) Escalated() bool
- func (a *DegradedModeAccumulator) RecordDegradedTick() bool
- func (a *DegradedModeAccumulator) RecordFailure() bool
- func (a *DegradedModeAccumulator) RecordSuccess()
- type DumpBus
- type EvidenceBuffer
- type EvidenceRecord
- type EvidenceStrength
- type ExtRegisterRequest
- type Gateway
- func (g *Gateway) AddRouterPlane(plane router.Plane)
- func (g *Gateway) Close() error
- func (g *Gateway) DumpUnknownDevices(ctx context.Context, entries []registry.DeviceEntry, ...) ([]UnknownDeviceDumpResult, error)
- func (g *Gateway) RefreshRouterPlanes() int
- func (g *Gateway) Start(ctx context.Context)
- type LocalAddressSnapshot
- type LocalBusAddressSnapshotter
- type ObserveFirstDirectApplyPolicy
- type ObserveFirstExternalWritePolicy
- type ObserveFirstFamily
- type ObserveFirstFamilyPolicy
- type ObserveFirstFeatureFlagNormalizationReason
- type ObserveFirstFeatureFlagState
- type ObserveFirstFeatureFlagView
- type ObserveFirstFeatureFlags
- func (flags ObserveFirstFeatureFlags) ExternalWritePolicy() ObserveFirstExternalWritePolicy
- func (flags ObserveFirstFeatureFlags) NormalizationReasons() []ObserveFirstFeatureFlagNormalizationReason
- func (flags ObserveFirstFeatureFlags) ObserveFirstEnabled() bool
- func (flags ObserveFirstFeatureFlags) PassiveConfigDirectApply() bool
- func (flags ObserveFirstFeatureFlags) PassiveStateDirectApply() bool
- func (flags ObserveFirstFeatureFlags) State() ObserveFirstFeatureFlagState
- func (flags ObserveFirstFeatureFlags) StateAt(updatedAt time.Time) ObserveFirstFeatureFlagState
- type ObserveFirstRequestIntent
- type ObserveFirstTrafficScope
- type PassiveACKCorrelation
- type PassiveACKCorrelator
- type PassiveACKPosition
- type PassiveAbandonReason
- type PassiveBusTap
- type PassiveClassifiedEvent
- type PassiveClassifiedEventKind
- type PassiveClassifiedSubscription
- type PassiveDiscontinuityReason
- type PassiveDiscoveryPromoter
- type PassiveDiscoveryPromoterOptions
- type PassiveDiscoveryPromoterSnapshot
- type PassiveEndpointState
- type PassiveReconstructorSnapshot
- type PassiveSubscriberPriority
- type PassiveTapConsumer
- type PassiveTapEvent
- type PassiveTapEventKind
- type PassiveTapStatus
- type PassiveTimingMarkers
- type PassiveTransactionFingerprint
- type PassiveTransactionReconstructor
- func (reconstructor *PassiveTransactionReconstructor) Close() error
- func (reconstructor *PassiveTransactionReconstructor) OnPassiveTapEvent(event PassiveTapEvent)
- func (reconstructor *PassiveTransactionReconstructor) SetLocalAddressSnapshotter(snapshotter LocalBusAddressSnapshotter)
- func (reconstructor *PassiveTransactionReconstructor) Snapshot() PassiveReconstructorSnapshot
- func (reconstructor *PassiveTransactionReconstructor) Subscribe(name string, priority PassiveSubscriberPriority, buffer int) (*PassiveClassifiedSubscription, error)
- type ProtocolSpecimenExport
- type RuntimeStateObserver
- type SemanticReadCircuitBreakerOptions
- type SemanticReadCircuitBreakerSuppression
- type SemanticReadCircuitBreakerTransition
- type SemanticReadCircuitState
- type SemanticReadExecutionStats
- type SemanticReadScheduler
- func (s *SemanticReadScheduler) Get(ctx context.Context, key string, maxAge time.Duration, ...) ([]byte, error)
- func (s *SemanticReadScheduler) GetWatch(ctx context.Context, key WatchKey, maxAge time.Duration, ...) ([]byte, error)
- func (s *SemanticReadScheduler) GetWatchWithStats(ctx context.Context, key WatchKey, maxAge time.Duration, ...) ([]byte, SemanticReadExecutionStats, error)
- func (s *SemanticReadScheduler) SetCircuitBreaker(options SemanticReadCircuitBreakerOptions)
- func (s *SemanticReadScheduler) SetShadowCache(cache *ShadowCache)
- type ShadowCache
- func (cache *ShadowCache) BootstrapRuntimeDescriptor(descriptor WatchDescriptor, sources ...WatchActivationSource) error
- func (cache *ShadowCache) CaptureGeneration(key WatchKey) uint64
- func (cache *ShadowCache) Close(ctx context.Context) error
- func (cache *ShadowCache) CompactOnce() time.Duration
- func (cache *ShadowCache) Entry(key WatchKey) (ShadowEntryView, bool)
- func (cache *ShadowCache) FeatureFlags() ObserveFirstFeatureFlags
- func (cache *ShadowCache) Invalidate(invalidation ShadowInvalidation) ShadowInvalidationResult
- func (cache *ShadowCache) Lookup(key WatchKey, maxAge time.Duration) ShadowLookupResult
- func (cache *ShadowCache) Observe(key WatchKey) WatchObservation
- func (cache *ShadowCache) RefreshActivations()
- func (cache *ShadowCache) RevalidatePinnedBudget() ShadowCacheSummary
- func (cache *ShadowCache) SnapshotEligibility(key WatchKey) ShadowEligibilitySnapshot
- func (cache *ShadowCache) StartCompactor()
- func (cache *ShadowCache) Summary() ShadowCacheSummary
- func (cache *ShadowCache) WatchSummary() WatchSummary
- func (cache *ShadowCache) Write(write ShadowWrite) ShadowWriteResult
- type ShadowCacheOptions
- type ShadowCacheSummary
- type ShadowConfidenceTier
- type ShadowEligibilitySnapshot
- type ShadowEntryState
- type ShadowEntryView
- type ShadowInvalidation
- type ShadowInvalidationReason
- type ShadowInvalidationResult
- type ShadowInvalidationSource
- type ShadowLookupResult
- type ShadowWrite
- type ShadowWriteRejectionReason
- type ShadowWriteResult
- type ShadowWriteSource
- type SmokeCheckResult
- type SmokeOptions
- type SourceSelectionArtifact
- type SourceSelectionArtifactAdmission
- type SourceSelectionArtifactBuilder
- func (b *SourceSelectionArtifactBuilder) Emit() (SourceSelectionArtifact, []byte, error)
- func (b *SourceSelectionArtifactBuilder) EmitToFile(path string) error
- func (b *SourceSelectionArtifactBuilder) RecordBaselineEvidence(address uint8, count int)
- func (b *SourceSelectionArtifactBuilder) RecordProbe(wireBytes int)
- func (b *SourceSelectionArtifactBuilder) ResetEmitOnce()
- func (b *SourceSelectionArtifactBuilder) SetActiveExplicitSource(source uint8)
- func (b *SourceSelectionArtifactBuilder) SetBaselineEvidenceProvider(provider func() map[string]int)
- func (b *SourceSelectionArtifactBuilder) SetDegraded(reason string)
- func (b *SourceSelectionArtifactBuilder) SetExplicitSource(source uint8)
- func (b *SourceSelectionArtifactBuilder) SetPostStartupSustainedRateProbesPer15s(rate float64)
- func (b *SourceSelectionArtifactBuilder) SetPromotedSuspects(n int)
- func (b *SourceSelectionArtifactBuilder) SetSourceSelection(source, companionTarget uint8, warmupDuration time.Duration)
- func (b *SourceSelectionArtifactBuilder) SetSourceSelectionActive()
- func (b *SourceSelectionArtifactBuilder) SetSourceSelectionMode(v string) error
- type SourceSelectionArtifactDiscovery
- type SourceSelectionArtifactSourceSelection
- type StartupSourceOverride
- type StartupSourceSelectionMetrics
- func (m *StartupSourceSelectionMetrics) MarkActive()
- func (m *StartupSourceSelectionMetrics) MarkDegraded(now time.Time)
- func (m *StartupSourceSelectionMetrics) MarkPending()
- func (m *StartupSourceSelectionMetrics) Publish()
- func (m *StartupSourceSelectionMetrics) RecordExplicitValidateOnly()
- func (m *StartupSourceSelectionMetrics) RecordWarmupEvent()
- func (m *StartupSourceSelectionMetrics) SetConsecutiveFailures(n int)
- func (m *StartupSourceSelectionMetrics) SetDegradedCumulativeMs(ms uint64)
- func (m *StartupSourceSelectionMetrics) SetDegradedEscalated(latched bool)
- func (m *StartupSourceSelectionMetrics) SetExplicitSourceActive(active bool)
- func (m *StartupSourceSelectionMetrics) SetExplicitSourceConflictDetected()
- func (m *StartupSourceSelectionMetrics) StartWarmupCycle() uint64
- type TransportAdmissionPath
- type TransportConfig
- type TransportProtocol
- type UnknownDeviceDumpOptions
- type UnknownDeviceDumpResult
- type V8RolloutSnapshot
- type WatchActivationSet
- func (set *WatchActivationSet) Activate(source WatchActivationSource, keys ...WatchKey) error
- func (set *WatchActivationSet) ActiveSources(key WatchKey) []WatchActivationSource
- func (set *WatchActivationSet) Deactivate(source WatchActivationSource, keys ...WatchKey)
- func (set *WatchActivationSet) Observe(key WatchKey) WatchObservation
- func (set *WatchActivationSet) Summary() WatchObservationSummary
- type WatchActivationSource
- type WatchCatalog
- type WatchCorrelationPolicy
- type WatchDescriptor
- type WatchDirectApplyPolicy
- type WatchEfficiencyDirectApplyEvent
- type WatchEfficiencyObserver
- type WatchEfficiencyReadEvent
- type WatchFamily
- type WatchFreshnessProfile
- type WatchKey
- type WatchObservation
- type WatchObservationState
- type WatchObservationSummary
- type WatchObserver
- type WatchSemanticClass
- type WatchSummary
- type WatchSummaryActivationCounts
- type WatchSummaryClassCount
- type WatchSummaryDegraded
- type WatchSummaryInventory
Constants ¶
const ( StartupAdmissionRejoinBackoffBaseSeconds = 5 StartupAdmissionRejoinBackoffMaxSeconds = 60 StartupAdmissionEscalationFailureCountThreshold = 5 StartupAdmissionEscalationDurationSeconds = 300 StartupAdmissionEscalationWindowSeconds = 900 )
const ( TransportENH TransportProtocol = "enh" TransportENS TransportProtocol = "ens" TransportUDPPlain TransportProtocol = "udp-plain" TransportTCPPlain TransportProtocol = "tcp-plain" TransportEbusdTCP TransportProtocol = "ebusd-tcp" TransportAdapterDirect TransportProtocol = "adapter-direct" DefaultSemanticZonePresenceMissThreshold = 3 DefaultSemanticZonePresenceHitThreshold = 2 DefaultSemanticDHWStaleTTL = 15 * time.Minute DefaultSemanticEnergyInterval = 5 * time.Minute DefaultSemanticRegulatorRecheckInterval = 60 * time.Second DefaultSemanticRegulatorAbsenceGrace = 5 * time.Minute DefaultMetricsPath = "/metrics" DefaultObserveFirstRecentMessageCapacity = 1024 DefaultObserveFirstPeriodicityCapacity = 256 DefaultObserveFirstPeriodicityStaleTTL = time.Hour DefaultObserveFirstSeriesBudget = 1024 DefaultObserveFirstWarmupConnectedWindow = 30 * time.Second DefaultObserveFirstWarmupCompletedTransactions = 20 DefaultObserveFirstWarmupPostResetWindow = 5 * time.Second DefaultObserveFirstWarmupPostResetTransactions = 10 DefaultObserveFirstWarmupOuterWindow = 5 * time.Minute // Default values for startup-admission escalation thresholds (frozen per // AD17 in startup-admission-discovery-w17-26.locked): // // The continuous_threshold_s value is frozen at 5 minutes (not // operator-tunable). The state_min_stability_s is operator-tunable but // bounded by AD22 invariant: state_min_stability_s * 5 <= continuous_threshold_s. StartupAdmissionContinuousThresholdSeconds = 300 StartupAdmissionStateMinStabilitySecondsDefault = 30 StartupAdmissionStateMinStabilitySecondsMin = 5 StartupAdmissionStateMinStabilitySecondsMax = 60 )
const ( DefaultSemanticReadFailureBudget = 2 DefaultSemanticReadOpenCooldown = 15 * time.Second DefaultSemanticReadHalfOpenProbeLimit = 1 )
const ( DefaultShadowCacheCapacity = 4096 DefaultShadowCachePinnedCapacity = 2048 DefaultShadowCacheWriteConfirmPinnedCap = 256 DefaultShadowCacheTombstoneRetainWindow = 15 * time.Minute DefaultShadowCacheTombstoneHardLifespan = 24 * time.Hour DefaultShadowCacheCompactorCadence = time.Minute DefaultShadowCacheCompactorBatchSize = 64 DefaultShadowCacheShutdownCompactorTimeout = time.Second )
const (
PassiveACKCorrelatorM2A = protocol.ACKCorrelatorM2A
)
const (
PassiveACKPositionRequestACK = protocol.ACKPositionRequestACK
)
Variables ¶
var ( ErrSemanticReadCircuitOpen = errors.New("semantic read circuit breaker open") ErrSemanticReadSupersededInFlight = errors.New("semantic read superseded while in flight") ErrSemanticReadRevalidationExhausted = errors.New("semantic read shadow revalidation exhausted") )
var ErrSourceSelectionBusInquiryUnsupported = errors.New("source address selection: inquiry not supported (InquiryEnabled=false)")
var ErrStartupAdmissionStabilityInvariant = errors.New("startup admission: state_min_stability_s * 5 must be <= continuous_threshold_s (AD22)")
ErrStartupAdmissionStabilityInvariant is returned when state_min_stability_s violates the AD22 5:1 invariant against continuous_threshold_s.
var VaillantBaselineTopologySeed = []byte{0x08, 0x15, 0x26, 0x04, 0xF6, 0xEC}
BaselineTopologySeed is the set of addresses protected from LRU eviction. Vaillant default: {0x08 BAI00, 0x15 BASV2, 0x26 VR_71, 0x04 NETX3-A, 0xF6 NETX3-B, 0xEC SOL00}. Operators MAY override via config; validation enforces responder-range [0x03, 0xFE] excluding 0xAA (SYN) and 0xFE (broadcast).
var VaillantStructuralStartupProbeTargets = []byte{0x08, 0x15, 0x26}
VaillantStructuralStartupProbeTargets is the bounded set of Vaillant device targets used as the structural startup-probe fallback when the source-address selector's passive warmup observed no probable targets.
Why this is narrower than VaillantBaselineTopologySeed: stealth slaves (0x04/0xF6 NETX3, 0xEC SOL00) are passive-only and do not respond to directed identity probes. The structural set is the active-probable subset {boiler, regulator, primary controller}.
These are TARGETS for active probes from the admitted source — never source addresses themselves.
Functions ¶
func ChainBusObservers ¶
func ChainBusObservers(observers ...protocol.BusObserver) protocol.BusObserver
func CheckExplicitSourceCompanionConflict ¶ added in v0.6.18
func CheckExplicitSourceCompanionConflict(explicitSource byte, selection *protocol.SourceAddressSelection, metrics *StartupSourceSelectionMetrics) bool
CheckExplicitSourceCompanionConflict compares the configured explicit source against the selector's selected source and emits advisory conflict observability when they disagree.
func DefaultStartupAdmissionSourceSelectionConfig ¶ added in v0.6.18
func DefaultStartupAdmissionSourceSelectionConfig() protocol.SourceAddressSelectionConfig
DefaultStartupAdmissionSourceSelectionConfig returns the SourceAddressSelectionConfig used by the startup-admission-discovery plan for source-selection-capable direct transports. See plan AD01/AD02/AD09 and helianthus-docs-ebus/architecture/startup-admission-and-discovery.md §2.2.3.
func EmitStartupResetWarn ¶ added in v0.6.18
func EmitStartupResetWarn(logger func(format string, args ...interface{}))
EmitStartupResetWarn is a package-level log helper for the AD17 restart-reset WARN line emitted once on process start. Callers use this immediately after NewStartupSourceSelectionMetrics to satisfy AD17's observability contract.
func EntryContainsAddress ¶ added in v0.6.18
func EntryContainsAddress(entry registry.DeviceEntry, addr byte) bool
EntryContainsAddress reports whether the entry's full address set (including aliases) contains addr. Use this for membership/lookup checks where any face on the entry should match — e.g. register dump target resolution and registry containment filters in passive discovery — instead of comparing only PrimaryDisplayAddress, which would miss the non-display side of an aliased canonical pair.
Phase C M-C6b helper.
func FormatStartupSourceSelectionExplicitLog ¶ added in v0.6.18
FormatStartupSourceSelectionExplicitLog returns the low-confidence explicit-validate-only log line emitted before the first active frame.
func IsB524ResponseCoherent ¶ added in v0.6.18
IsB524ResponseCoherent reports whether a B524 (Vaillant extended- register access) response payload is structurally coherent with the original request: the response echoes the request's group and register address in valid positions.
Two valid echo positions are accepted because B524 replies use two frame layouts depending on whether the opcode is preceded by a status / length prefix:
layout-a resp[1]=group, resp[2..3]=addr (LE) layout-b resp[2]=group, resp[3..4]=addr (LE)
A response that fails both checks is not a coherent reply — it may be a NACK, a fragment, or a passively-misclassified frame.
Used by:
- cmd/gateway/semantic_vaillant.go isB524ProbeCoherent (the active-probe acceptance check during discoverB524Root)
- bus_observability_store.go passiveResponseIsCoherentVaillantEvidence (the passive strong-evidence promotion gate)
Both call sites share a single source of truth for "what counts as a coherent B524 response" so that passive-evidence promotion uses the same acceptance criterion as active discovery.
func NewSourceSelectionBusAdapter ¶ added in v0.6.18
func NewSourceSelectionBusAdapter(reconstructor *PassiveTransactionReconstructor, name string, inquiryEnabled bool) (protocol.SourceAddressSelectionBus, error)
NewSourceSelectionBusAdapter returns a protocol.SourceAddressSelectionBus subscribed to the given reconstructor with priority=NonCritical and default buffer.
func RejoinBackoffSchedule ¶ added in v0.6.18
RejoinBackoffSchedule returns the nth attempt's backoff duration: Base * 2^(n-1), capped at Max. attempt=1 → Base; attempt=2 → 2*Base; etc.
func RunSmoke ¶
func RunSmoke(ctx context.Context, cfg smokeConfig, opts SmokeOptions) (runErr error)
func RunSmokeFromEnv ¶
func RunSmokeFromEnv(ctx context.Context, opts SmokeOptions) error
func ScanWithFullRangeGuard ¶ added in v0.6.18
func ScanWithFullRangeGuard(ctx context.Context, bus registry.ScanBus, reg *registry.DeviceRegistry, source byte, targets []byte, admissionPath TransportAdmissionPath, diagnosticFlag bool, evidenceHasVaillantRoot bool) ([]registry.DeviceEntry, error)
ScanWithFullRangeGuard applies the AD05 full-range retry guard before dispatching to the ebusreg scan implementation.
func SelectDefaultStartupSourceAddress ¶ added in v0.6.18
func SelectDefaultStartupSourceAddress(ctx context.Context) (protocol.SourceAddressSelection, error)
SelectDefaultStartupSourceAddress applies the docs-backed Helianthus source-selection policy without passive observations. This covers transports that cannot expose an observe-first lane: "auto" still means source selection, not source 0x00.
func SnapshotContainsAddress ¶ added in v0.6.18
func SnapshotContainsAddress(snap registry.DeviceEntrySnapshot, addr byte) bool
SnapshotContainsAddress is the value-typed counterpart of EntryContainsAddress for callers that have already taken a DeviceEntrySnapshot via LookupEntrySnapshot / IterateSnapshots.
P9.2 — race-free address-membership check. Pre-P9.2 callers had to take an EntryContainsAddress(entry, addr) on a live *deviceEntry pointer (entry.Addresses() reads through to mutable storage); this helper reads the snapshot's Addresses slice (already a value-typed copy taken under the registry's RLock).
func SnapshotTargetAddressForRouting ¶ added in v0.6.18
func SnapshotTargetAddressForRouting(snap registry.DeviceEntrySnapshot) byte
SnapshotTargetAddressForRouting is the value-typed counterpart of TargetAddressForRouting for callers iterating value-typed DeviceEntrySnapshot via IterateSnapshots / LookupEntrySnapshot.
P9.3 — closes the lock-free read race surface for B524 root candidate enumeration in the semantic Vaillant poller. Reads from the snapshot's Faces slice (already a value-typed copy taken under the registry's RLock) and falls back to the snapshot's PrimaryDisplayAddress.
func StartupAdmissionConfigWithHint ¶ added in v0.6.18
func StartupAdmissionConfigWithHint(hint byte, hintSet bool) protocol.SourceAddressSelectionConfig
StartupAdmissionConfigWithHint returns the default startup-admission selector config augmented with a hint candidate, when a hint is available. When hintSet is false the returned config is identical to DefaultStartupAdmissionSourceSelectionConfig (no hint biasing applied).
The hint is a HISTORICAL signal from a prior admission cycle (loaded from runtime_state.ebus.self.last_admitted_source per runtime-state-w19-26.locked M4_SOURCE_SELECTION_HINT). It biases candidate ordering so the cached source is tried first; the selector still validates the candidate against the live bus (AD24 — cache never bypasses warmup).
func StartupSourceSelectionExpvarNames ¶ added in v0.6.18
func StartupSourceSelectionExpvarNames() []string
func TargetAddressForRouting ¶ added in v0.6.18
func TargetAddressForRouting(entry registry.DeviceEntry) byte
TargetAddressForRouting returns the routing-correct target byte for an M2S write. Prefers AddressByRole(SlotRoleSlave) so an aliased canonical pair (e.g. BAI 0x03↔0x08) returns the target byte 0x08 rather than the alias-primary which may be the initiator. Falls back to PrimaryDisplayAddress only when no target-role face exists (single-initiator device, or a face with SlotRoleUnknown that the AddressClass-fallback in registry.AddressByRole cannot classify).
Phase C M-C6b helper. M-C7 will replace these per-callsite usages with explicit Frame.FrameType + Frame.Validate flow at the semantic API boundary.
func ValidateBaselineTopologySeed ¶ added in v0.6.18
ValidateBaselineTopologySeed checks the config-provided seed against the responder-address range.
func ValidateSourceSelectionMode ¶ added in v0.6.18
ValidateSourceSelectionMode returns nil if v is one of the four enum values the plan admits per AD23. Returns a FATAL-level error otherwise — callers should refuse to emit artifacts with an out-of- range value.
func ValidateStartupAdmissionStability ¶ added in v0.6.18
ValidateStartupAdmissionStability enforces AD22.
Types ¶
type ActivePassiveDeduplicator ¶
type ActivePassiveDeduplicator struct {
// contains filtered or unexported fields
}
func NewActivePassiveDeduplicator ¶
func NewActivePassiveDeduplicator(cfg Config) (*ActivePassiveDeduplicator, error)
func (*ActivePassiveDeduplicator) AttachReconstructor ¶
func (deduplicator *ActivePassiveDeduplicator) AttachReconstructor(ctx context.Context, reconstructor *PassiveTransactionReconstructor) error
func (*ActivePassiveDeduplicator) Budgets ¶
func (deduplicator *ActivePassiveDeduplicator) Budgets() dedupTimingBudgets
func (*ActivePassiveDeduplicator) Close ¶
func (deduplicator *ActivePassiveDeduplicator) Close() error
func (*ActivePassiveDeduplicator) LocalAddressSnapshot ¶
func (deduplicator *ActivePassiveDeduplicator) LocalAddressSnapshot() LocalAddressSnapshot
func (*ActivePassiveDeduplicator) Observe ¶
func (deduplicator *ActivePassiveDeduplicator) Observe(key WatchKey) WatchObservation
func (*ActivePassiveDeduplicator) OnBusEvent ¶
func (deduplicator *ActivePassiveDeduplicator) OnBusEvent(event protocol.BusEvent) error
func (*ActivePassiveDeduplicator) OnPassiveClassifiedEvent ¶
func (deduplicator *ActivePassiveDeduplicator) OnPassiveClassifiedEvent(event PassiveClassifiedEvent)
func (*ActivePassiveDeduplicator) SetWatchObserver ¶ added in v0.6.32
func (deduplicator *ActivePassiveDeduplicator) SetWatchObserver(observer WatchObserver)
func (*ActivePassiveDeduplicator) Subscribe ¶
func (deduplicator *ActivePassiveDeduplicator) Subscribe(name string, priority DedupSubscriberPriority, buffer int) (*AdjudicatedPassiveSubscription, error)
type ActiveTransactionFingerprint ¶
type ActiveTransactionFingerprint struct {
Epoch uint64
TransactionClass DedupTransactionClass
OutcomeClass DedupOutcomeClass
ResponseClass DedupResponseClass
FamilyPolicy ObserveFirstFamilyPolicy
Source byte
Target byte
RequestBytes []byte
ResponseBytes []byte
Hash [32]byte
ObservedAt time.Time
}
type AdaptermuxDiagSnapshot ¶ added in v0.6.18
type AdaptermuxDiagSnapshot struct {
// SynSuppressedPreEcho mirrors activeTxnDiag.synSuppressedPreEcho
// — total SYNs the existing P10.2 / pre-first-echo gate has
// suppressed. Provided for context alongside the new batch-21
// counters so an operator reading /metrics can compare the
// suppressed population to the gap populations below.
SynSuppressedPreEcho uint64
// SynSeenDuringGrantWindow counts SYNs observed during gateway
// ownership where gatewayTxnActive=false (Attack 1 — grant→first-
// write window).
SynSeenDuringGrantWindow uint64
// SynSeenWhileInterWriteEmpty counts SYNs observed during a
// gateway-owned active txn where the echo queue is empty AND at
// least one byte has been delivered to active (Attack 3 — inter-
// write queue-empty window).
SynSeenWhileInterWriteEmpty uint64
// SynSeenAfterTransportWindowExpired counts SYNs observed during
// gateway ownership where the upstream ENH transport's
// postGrantPreEcho window has closed via deadline-expiry in the
// current transaction (Attack 2 — batch-22 round-3). Forensic
// only; correlates with the residual pre_echo_syn rate
// unexplained by Attack 1 + Attack 3 instrumentation.
SynSeenAfterTransportWindowExpired uint64
// SynSuppressedBetweenWrites counts SYNs the betweenWritesSyn
// (queueJustDrained) gate suppressed — the Attack 3 (inter-write
// empty-queue) closure introduced in batch-26 round-7. Subset of
// SynSuppressedPreEcho. Operator dashboards: rate(SynSuppressedBetweenWrites)
// should rise after round-7 deploy while
// ebus_active_echo_mismatch_subclass_total{subclass="pre_echo_syn_raw"}
// drops.
SynSuppressedBetweenWrites uint64
}
AdaptermuxDiagSnapshot is the subset of adaptermux's activeTxnDiag snapshot exposed via the Prometheus surface for batch-21 forensic instrumentation. Field semantics match the originating counters in `internal/adaptermux/diag.go`. Plumbing through this small struct (rather than importing the full ActiveTxnSnapshot) keeps `bus_observability_store` decoupled from the adaptermux package.
type AddressObservation ¶ added in v0.6.18
type AddressObservation struct {
PositiveACKCount int
}
type AddressSlot ¶ added in v0.6.18
type AddressSlot struct {
Addr byte
Role string
DiscoverySource string
VerificationState string
// PriorityTier is the eBUS standard priority class (p0..p4) when
// Addr is a canonical source from sourceAddressTableV1, else "".
PriorityTier protocol.SourceAddressPriorityIndex
// FreeUse is true when Addr is a canonical source AND the eBUS
// standard table marks the row free-use (e.g. 0x07, 0x17, 0x7F,
// 0x1F/0x3F/0x7F/0xF7). False for non-canonical addresses or
// preallocated canonical sources.
FreeUse bool
RegistrySlot *registry.AddressSlot
}
type AddressTable ¶ added in v0.6.18
type AddressTable struct {
// contains filtered or unexported fields
}
func NewAddressTable ¶ added in v0.6.18
func NewAddressTable(regs ...*registry.DeviceRegistry) *AddressTable
func (*AddressTable) CanonicalAddressTableSnapshot ¶ added in v0.6.18
func (t *AddressTable) CanonicalAddressTableSnapshot() []CanonicalAddressView
CanonicalAddressTableSnapshot returns a snapshot of all 50 canonical eBUS addresses (25 sources + 25 companions per architecture/ebus_standard/12-source-address-table.md), with each row labelled by its current runtime observation state. Addresses present in the wrapped registry are marked Observed=true with their actual DiscoverySource; addresses not yet observed are marked Observed=false with DiscoverySource="never_observed".
func (*AddressTable) Lookup ¶ added in v0.6.18
func (t *AddressTable) Lookup(addr byte) (*AddressSlot, bool)
type AddressTableInserter ¶ added in v0.6.18
type AddressTableInserter struct {
// contains filtered or unexported fields
}
func NewAddressTableInserter ¶ added in v0.6.18
func NewAddressTableInserter(table *AddressTable, cfg Config) *AddressTableInserter
func (*AddressTableInserter) BackfillUnidentifiedAddresses ¶ added in v0.6.18
func (i *AddressTableInserter) BackfillUnidentifiedAddresses()
BackfillUnidentifiedAddresses iterates the registry's existing entries and invokes the wired enrichmentIdentityProbeFn for any address that looks unidentified (manufacturer empty OR Vaillant + serial empty). Used to close the race where a passive observation during the gateway's startup-admission window lands in the registry before SetEnrichmentIdentityProbeFn was wired.
Callers MUST defer the invocation until the gateway's startup barrier (admittedSource finalization) has closed — otherwise the probe submissions will race the startup directed scan and emit bus traffic during the admission validation window. See P5 round-3 finding (Codex P2 on PR #583, 2026-05-08).
The probe fn is idempotent (per-address sync.Map in EnqueueAddressIdentityProbe), so repeat calls are harmless.
func (*AddressTableInserter) OnPassiveClassifiedEvent ¶ added in v0.6.18
func (i *AddressTableInserter) OnPassiveClassifiedEvent(event PassiveClassifiedEvent)
func (*AddressTableInserter) SetEnrichmentIdentityProbeFn ¶ added in v0.6.18
func (i *AddressTableInserter) SetEnrichmentIdentityProbeFn(fn func(addr byte))
SetEnrichmentIdentityProbeFn wires the post-insertion per-address identity probe so new passive slots get a 0x07/0x04 + B5.09 ScanID read against them. See AddressTableInserter.enrichmentIdentityProbeFn.
Phase post-C P5 (live validation 2026-05-08): without this hook passive-observed entries (e.g. NETX3 0xF1↔0xF6) stay at empty manufacturer / deviceID / serialNumber forever, which prevents identity-merge from grouping aliased faces.
This setter is fire-only: it installs the fn pointer and returns without invoking it. Callers that need to backfill addresses inserted before the hook was wired should call BackfillUnidentifiedAddresses AFTER the gateway's startup barrier (semantic scheduler readiness) clears — see main.go for the wiring.
func (*AddressTableInserter) SetEnrichmentRefreshFn ¶ added in v0.6.18
func (i *AddressTableInserter) SetEnrichmentRefreshFn(fn func())
SetEnrichmentRefreshFn wires the post-insertion B524 root re-discovery trigger so the regulator surface populates without a gateway restart. See AddressTableInserter.enrichmentRefreshFn for semantics.
func (*AddressTableInserter) SetRuntimeStateObserver ¶ added in v0.6.18
func (i *AddressTableInserter) SetRuntimeStateObserver(fn RuntimeStateObserver)
SetRuntimeStateObserver wires the runtime-state Manager hook. The inserter calls fn once per passive observation (new insert OR refresh of an existing slot) so known_bus_members[] gets populated and LastSeenAt stays current as a basis for M5 revalidation ordering. Codex P2 follow-up on PR #615 — without this wiring, runtime_state.json's known_bus_members[] stays empty after a fresh install and M5 has nothing to revalidate.
type AdjudicatedPassiveEvent ¶
type AdjudicatedPassiveEvent struct {
Event PassiveClassifiedEvent
Fingerprint PassiveTransactionFingerprint
FamilyPolicy ObserveFirstFamilyPolicy
Disposition DedupDisposition
SuppressShadow bool
SuppressWatchEfficiency bool
ThirdPartyEligible bool
ObservabilityOnly bool
LocalParticipantInbound bool
MatchedActiveDuplicate bool
Epoch uint64
}
type AdjudicatedPassiveSubscription ¶
type AdjudicatedPassiveSubscription struct {
// contains filtered or unexported fields
}
func (*AdjudicatedPassiveSubscription) Close ¶
func (subscription *AdjudicatedPassiveSubscription) Close()
func (*AdjudicatedPassiveSubscription) Events ¶
func (subscription *AdjudicatedPassiveSubscription) Events() <-chan AdjudicatedPassiveEvent
type AdmissionStabilityWindow ¶ added in v0.6.18
type AdmissionStabilityWindow struct {
// contains filtered or unexported fields
}
AdmissionStabilityWindow gates emission of bus_admission state transitions through the configured state_min_stability_s window. A new state is admitted to the envelope body ONLY after it has been stable for the full window duration; transient flaps (state changes within the window) do not flip the envelope. Matches AD08 flap mitigation.
func NewAdmissionStabilityWindow ¶ added in v0.6.18
func NewAdmissionStabilityWindow(windowSeconds int) *AdmissionStabilityWindow
func (*AdmissionStabilityWindow) EmittedState ¶ added in v0.6.18
func (w *AdmissionStabilityWindow) EmittedState() string
EmittedState returns the state currently reflected in the envelope.
type B509WatchKey ¶
func NewB509WatchKey ¶
func NewB509WatchKey(target byte, registerAddress uint16) B509WatchKey
func (B509WatchKey) Canonical ¶
func (key B509WatchKey) Canonical() string
func (B509WatchKey) Family ¶
func (key B509WatchKey) Family() WatchFamily
func (B509WatchKey) String ¶
func (key B509WatchKey) String() string
type B516WatchKey ¶
func NewB516WatchKey ¶
func NewB516WatchKey(target, period, source, usage byte) B516WatchKey
func (B516WatchKey) Canonical ¶
func (key B516WatchKey) Canonical() string
func (B516WatchKey) Family ¶
func (key B516WatchKey) Family() WatchFamily
func (B516WatchKey) String ¶
func (key B516WatchKey) String() string
type B524WatchKey ¶
type B524WatchKey struct {
Target byte
Opcode byte
Group byte
Instance byte
RegisterAddress uint16
}
func NewB524WatchKey ¶
func NewB524WatchKey(target, opcode, group, instance byte, registerAddress uint16) B524WatchKey
func (B524WatchKey) Canonical ¶
func (key B524WatchKey) Canonical() string
func (B524WatchKey) Family ¶
func (key B524WatchKey) Family() WatchFamily
func (B524WatchKey) String ¶
func (key B524WatchKey) String() string
type B555WatchKey ¶
type B555WatchKey struct {
Target byte
Opcode byte
Zone byte
HC byte
Weekday byte
Slot byte
HasWeekday bool
HasSlot bool
}
func NewB555ProgramWatchKey ¶
func NewB555ProgramWatchKey(target, opcode, zone, hc byte) B555WatchKey
func NewB555WatchKey ¶
func NewB555WatchKey(target, opcode, zone, hc, weekday, slot byte) B555WatchKey
func (B555WatchKey) Canonical ¶
func (key B555WatchKey) Canonical() string
func (B555WatchKey) Family ¶
func (key B555WatchKey) Family() WatchFamily
func (B555WatchKey) String ¶
func (key B555WatchKey) String() string
type BroadcastListener ¶
type BroadcastListener struct {
// contains filtered or unexported fields
}
func StartBroadcastListener ¶
func StartBroadcastListener(ctx context.Context, cfg Config, router *router.BusEventRouter) (*BroadcastListener, error)
func StartBroadcastListenerWithReconstructor ¶
func StartBroadcastListenerWithReconstructor(ctx context.Context, router *router.BusEventRouter, reconstructor *PassiveTransactionReconstructor) (*BroadcastListener, error)
func StartBroadcastListenerWithTransport ¶
func StartBroadcastListenerWithTransport(ctx context.Context, cfg Config, router *router.BusEventRouter, wrap func(transport.RawTransport) transport.RawTransport) (*BroadcastListener, error)
func (*BroadcastListener) Close ¶
func (listener *BroadcastListener) Close() error
func (*BroadcastListener) Start ¶
func (listener *BroadcastListener) Start(ctx context.Context)
type BusAdmission ¶ added in v0.6.18
type BusAdmission struct {
State string `json:"state"`
Source uint8 `json:"source"`
CompanionTarget uint8 `json:"companion_target"`
Reason string `json:"reason,omitempty"`
SourceSelection *BusAdmissionSourceSelection `json:"source_selection,omitempty"`
}
BusAdmission is the additive data-body field surfaced in the ebus.v1.bus_observability envelope per AD08. It reflects the current admission state and associated metadata. State transitions are gated by the state-stability window (30s default); transient flaps do NOT flip this field nor the envelope's data_hash.
type BusAdmissionActiveProbe ¶ added in v0.6.18
type BusAdmissionRejectedCandidate ¶ added in v0.6.18
type BusAdmissionSourceSelection ¶ added in v0.6.18
type BusAdmissionSourceSelection struct {
State string `json:"state"`
Mode string `json:"mode,omitempty"`
Outcome string `json:"outcome,omitempty"`
Reason string `json:"reason,omitempty"`
SelectedSource *uint8 `json:"selected_source,omitempty"`
FailedSource *uint8 `json:"failed_source,omitempty"`
CompanionTarget *uint8 `json:"companion_target,omitempty"`
ActiveProbe *BusAdmissionActiveProbe `json:"active_probe,omitempty"`
Retryable bool `json:"retryable"`
NextAction string `json:"next_action,omitempty"`
LastSuccessfulSource *uint8 `json:"last_successful_source,omitempty"`
AutomaticRetryScheduled bool `json:"automatic_retry_scheduled"`
RejectedCandidates []BusAdmissionRejectedCandidate `json:"rejected_candidates,omitempty"`
}
type BusBusyAggregate ¶
type BusBusyAggregate struct {
TotalSeconds float64 `json:"total_seconds"`
Windows []BusBusyWindow `json:"windows"`
}
type BusBusyWindow ¶
type BusErrorAggregate ¶
type BusFrameAggregate ¶
type BusMessageRecord ¶
type BusObservabilityCapability ¶
type BusObservabilityCapability struct {
ActiveSupported bool `json:"active_supported"`
PassiveSupported bool `json:"passive_supported"`
BroadcastSupported bool `json:"broadcast_supported"`
PassiveAvailable bool `json:"passive_available"`
PassiveState string `json:"passive_state"`
PassiveReason string `json:"passive_reason,omitempty"`
EndpointState string `json:"endpoint_state"`
TapConnected bool `json:"tap_connected"`
}
type BusObservabilitySnapshot ¶
type BusObservabilitySnapshot struct {
Summary BusObservabilitySummary `json:"summary"`
Messages []BusMessageRecord `json:"messages,omitempty"`
Periodicity []BusPeriodicityEntry `json:"periodicity,omitempty"`
}
type BusObservabilityStartup ¶
type BusObservabilityStatus ¶
type BusObservabilityStatus struct {
LastUpdatedAt *time.Time `json:"last_updated_at,omitempty"`
TransportClass string `json:"transport_class"`
PublisherCadenceSec float64 `json:"publisher_cadence_sec"`
PublisherCadenceSource string `json:"publisher_cadence_source"`
Capability BusObservabilityCapability `json:"capability"`
Warmup BusObservabilityWarmup `json:"warmup"`
TimingQuality BusObservabilityTimingQuality `json:"timing_quality"`
Degraded BusObservabilityDegraded `json:"degraded"`
BusAdmission *BusAdmission `json:"bus_admission,omitempty"`
Startup *BusObservabilityStartup `json:"startup,omitempty"`
FeatureFlags ObserveFirstFeatureFlagState `json:"feature_flags"`
}
type BusObservabilityStore ¶
type BusObservabilityStore struct {
// contains filtered or unexported fields
}
func NewBusObservabilityStore ¶
func NewBusObservabilityStore(cfg Config) *BusObservabilityStore
func (*BusObservabilityStore) AttachReconstructor ¶
func (store *BusObservabilityStore) AttachReconstructor(ctx context.Context, reconstructor *PassiveTransactionReconstructor) error
func (*BusObservabilityStore) Close ¶
func (store *BusObservabilityStore) Close() error
func (*BusObservabilityStore) EvidenceBuffer ¶ added in v0.6.18
func (store *BusObservabilityStore) EvidenceBuffer() *EvidenceBuffer
EvidenceBuffer returns the runtime passive-evidence buffer used by the discovery promoter. Returns nil if the buffer was not constructed (e.g. invalid seed at startup); callers must nil-check.
func (*BusObservabilityStore) MetricsHandler ¶
func (store *BusObservabilityStore) MetricsHandler() http.Handler
func (*BusObservabilityStore) ObserveWatchDirectApply ¶
func (store *BusObservabilityStore) ObserveWatchDirectApply(event WatchEfficiencyDirectApplyEvent)
func (*BusObservabilityStore) ObserveWatchRead ¶
func (store *BusObservabilityStore) ObserveWatchRead(event WatchEfficiencyReadEvent)
func (*BusObservabilityStore) OnBusEvent ¶
func (store *BusObservabilityStore) OnBusEvent(event protocol.BusEvent) error
func (*BusObservabilityStore) OnPassiveClassifiedEvent ¶
func (store *BusObservabilityStore) OnPassiveClassifiedEvent(event PassiveClassifiedEvent)
func (*BusObservabilityStore) PeriodicitySnapshot ¶
func (store *BusObservabilityStore) PeriodicitySnapshot() []BusPeriodicityEntry
func (*BusObservabilityStore) ProtocolSpecimens ¶
func (store *BusObservabilityStore) ProtocolSpecimens(family string) []ProtocolSpecimenExport
func (*BusObservabilityStore) RecentMessages ¶
func (store *BusObservabilityStore) RecentMessages(limit int) []BusMessageRecord
func (*BusObservabilityStore) RecordBusAdmissionTransition ¶ added in v0.6.18
func (store *BusObservabilityStore) RecordBusAdmissionTransition(state string, source, companionTarget byte, reason string) bool
RecordBusAdmissionTransition is the production-side setter for the additive bus_admission field per AD08. The state argument MUST be one of {"pending", "active", "degraded"}; source/companionTarget are byte values from source-address selection or override; reason is non-empty only when state="degraded".
When an AdmissionStabilityWindow is installed (production path), the state observation is gated through it; transient flaps within the window do NOT flip the envelope nor data_hash. When no window is installed, the transition is applied immediately (test path).
Returns true if the envelope's bus_admission field actually changed as a result of this call (including stability-window-mediated flips).
func (*BusObservabilityStore) RenderPrometheus ¶
func (store *BusObservabilityStore) RenderPrometheus() string
func (*BusObservabilityStore) SetAdaptermuxDiagProvider ¶ added in v0.6.18
func (store *BusObservabilityStore) SetAdaptermuxDiagProvider(provider func() AdaptermuxDiagSnapshot)
SetAdaptermuxDiagProvider registers a snapshot provider callback for batch-21 forensic counters. Wired in cmd/gateway/main.go after the adaptermux is constructed; the callback closes over the mux and is invoked on each /metrics scrape. nil-store and nil-provider are no- ops (defensive — keeps test setup that does not exercise adaptermux from blowing up).
func (*BusObservabilityStore) SetAdmissionStabilityWindow ¶ added in v0.6.18
func (store *BusObservabilityStore) SetAdmissionStabilityWindow(window *AdmissionStabilityWindow)
SetAdmissionStabilityWindow installs the AD08 / AD22 flap-mitigation window on the store. When set, RecordBusAdmissionTransition will only flip the envelope's bus_admission field after the new state has been stable for state_min_stability_s. Caller (cmd/gateway/main.go) constructs the window from cfg.StateMinStabilitySeconds and passes it once at startup. If unset, RecordBusAdmissionTransition writes through immediately (legacy behavior; tests may use this mode).
func (*BusObservabilityStore) SetAdmittedSourceProvider ¶ added in v0.6.18
func (store *BusObservabilityStore) SetAdmittedSourceProvider(provider func() byte)
SetAdmittedSourceProvider installs the function the store uses to learn which address has been admitted as the gateway's source. This must be set after the source-address selection completes; the store uses it to filter self-source traffic out of evidence recording so the gateway never feeds its own probes back into the promotion pipeline. Nil-safe: when unset, all non-self-evident traffic flows to the buffer (legacy / test default).
func (*BusObservabilityStore) SetEnergyFreshnessMetricsRefresher ¶
func (store *BusObservabilityStore) SetEnergyFreshnessMetricsRefresher(refresher func(now time.Time, passiveState string))
func (*BusObservabilityStore) SetStartupSurfaceProvider ¶
func (store *BusObservabilityStore) SetStartupSurfaceProvider(provider func() *BusObservabilityStartup)
func (*BusObservabilityStore) SetV8RolloutProvider ¶ added in v0.6.32
func (store *BusObservabilityStore) SetV8RolloutProvider(provider func() V8RolloutSnapshot)
SetV8RolloutProvider registers a snapshot provider callback for the v8 frame-atomic-visibility rollout counters. Wired in cmd/gateway/main.go after the gateway's protocol.Bus and the adaptermux's v8 classifier are constructed; the callback closes over both. nil-store and nil-provider are no-ops so tests that do not exercise the v8 path are unaffected.
func (*BusObservabilityStore) Snapshot ¶
func (store *BusObservabilityStore) Snapshot() BusObservabilitySnapshot
type BusObservabilitySummary ¶
type BusObservabilitySummary struct {
LastUpdatedAt *time.Time `json:"last_updated_at,omitempty"`
Status BusObservabilityStatus `json:"status"`
Messages BusObservabilityBoundedList `json:"messages"`
Periodicity BusObservabilityBoundedList `json:"periodicity"`
Counters BusObservabilityCounters `json:"counters"`
Errors []BusErrorAggregate `json:"errors,omitempty"`
Frames []BusFrameAggregate `json:"frames,omitempty"`
Busy *BusBusyAggregate `json:"busy,omitempty"`
Reconstructor *BusReconstructorAggregate `json:"reconstructor,omitempty"`
SpecimenFamilies int `json:"specimen_families"`
SpecimenCount int `json:"specimen_count"`
}
type BusObservabilityWarmup ¶
type BusObservabilityWarmup struct {
State string `json:"state"`
Blocker string `json:"blocker,omitempty"`
ElapsedSeconds float64 `json:"elapsed_seconds,omitempty"`
CompletedTransactions int `json:"completed_transactions"`
RequiredTransactions int `json:"required_transactions"`
CompletionMode string `json:"completion_mode,omitempty"`
}
type BusPeriodicityEntry ¶
type BusPeriodicityEntry struct {
SourceBucket string
TargetBucket string
Primary byte
Secondary byte
Family string
State string
LastSeen time.Time
SampleCount int
LastInterval time.Duration
MeanInterval time.Duration
MinInterval time.Duration
MaxInterval time.Duration
// contains filtered or unexported fields
}
type BusReconstructorAggregate ¶
type BusReconstructorAggregate struct {
Recoveries []BusReconstructorRecovery `json:"recoveries"`
// PrefixResyncSkippedTotal — bytes dropped because the parser had
// not observed a SymbolSyn since the previous frame boundary
// (P6 Layer 1 inter-frame SYN gate). Operator canary for
// continuation-byte injection / startup resync.
PrefixResyncSkippedTotal uint64 `json:"prefix_resync_skipped_total"`
// InvalidSrcClassSkippedTotal — bytes rejected because the byte in
// source position was not initiator-class (P6 Layer 2 SRC
// AddressClass validation). Direct measure of operator-confirmed
// Mode B (upstream SRC byte loss in ENH StreamEventStarted
// handling / proxy STARTED-drop). Sustained non-zero rate after
// deploy is the signal to revisit P6.1 / P6.2 follow-ups.
InvalidSrcClassSkippedTotal uint64 `json:"invalid_src_class_skipped_total"`
}
type CanonicalAddressView ¶ added in v0.6.18
type CanonicalAddressView struct {
Address byte
Role string // "initiator" or "target"
PeerAddress byte
PriorityTier protocol.SourceAddressPriorityIndex
FreeUse bool
Description string
Observed bool
DiscoverySource string
VerificationState string
}
CanonicalAddressView is a snapshot of one canonical eBUS address as seen by the AddressTable: the eBUS standard table row metadata (tier, role, free-use, peer) combined with this address's runtime observation state.
Observation state distinguishes:
- "never_observed": the address is in the canonical table but no passive ACK / active scan has placed it in the registry.
- "passive_observed": placed by AD05 inserter from passive frames.
- "static_seed": placed by EnableStaticSeedTable.
- "active_confirmed": placed by startup scan / probe.
This view exists so MCP/GraphQL consumers can distinguish "this canonical address has not yet emitted traffic" from "this canonical address is not real on this bus" — important for A.7e audit + operator UX.
type Config ¶
type Config struct {
Transport transport.RawTransport
PassiveTransport transport.RawTransport // pre-configured passive transport (adapter-direct mode)
ProxyListenAddr string // TCP listen address for ENH proxy clients (empty disables)
TransportConfig TransportConfig
BusConfig protocol.BusConfig
QueueCapacity int
Providers []registry.PlaneProvider
ScanOnStart bool
ScanSource byte
ScanSourceAuto bool
StartupProbeTargets []byte
StartupCompanionTarget byte
ScanTimeout time.Duration
ScanRequestTimeout time.Duration
ScanInterval time.Duration
BackgroundScanInterval time.Duration
BootLiveTimeout time.Duration
StateMinStabilitySeconds int
StartupSource StartupSourceOverride
DiagnosticFullRangeRetry bool
// SemanticInterval is a legacy single-interval semantic polling configuration.
// Prefer SemanticDiscoveryInterval / SemanticConfigInterval / SemanticStateInterval.
SemanticInterval time.Duration
SemanticDiscoveryInterval time.Duration
SemanticConfigInterval time.Duration
SemanticStateInterval time.Duration
SemanticEnergyInterval time.Duration
SemanticRequestTimeout time.Duration
SemanticReadBreakerFailureBudget int
SemanticReadBreakerFailureBudgetSet bool
SemanticReadBreakerOpenCooldown time.Duration
SemanticReadBreakerHalfOpenProbeLimit int
SemanticZonePresenceMissThreshold int
SemanticZonePresenceHitThreshold int
SemanticDHWStaleTTL time.Duration
SemanticRegulatorRecheckInterval time.Duration
SemanticRegulatorAbsenceGrace time.Duration
SemanticCachePath string
BroadcastListen bool
PassiveAbsenceThreshold time.Duration
PassiveTransactionWatchdog time.Duration
PassiveReconnectInitialDelay time.Duration
PassiveReconnectMaxDelay time.Duration
PassiveDedupActivePublishBudget time.Duration
PassiveDedupPassiveDeliveryBudget time.Duration
PassiveDedupPendingGraceTimeout time.Duration
PassiveDedupActiveFingerprintRetention time.Duration
PassiveDedupPendingCapacity int
PassiveDedupRecoveryHysteresis time.Duration
PassiveDedupRecoveryEventThreshold int
LocalAddressSnapshotter LocalBusAddressSnapshotter
AdmittedSource func() byte
WatchObserver WatchObserver
WatchEfficiencyObserver WatchEfficiencyObserver
HTTPAddr string
MetricsPath string
GraphQLPath string
SnapshotPath string
SubscriptionPath string
MCPPath string
UIPath string
PortalPath string
MDNSAdvertise bool
MDNSInstance string
InstanceGUID string
// InstanceGUIDSource is the AD27 provenance tag passed by the
// add-on alongside InstanceGUID. One of: "runtime_state",
// "legacy_migrated", "generated", "cli-override". Empty when the
// flag wasn't supplied (older add-on, direct CLI invocation), in
// which case the Manager defaults to "cli-override" with a
// deprecation log.
InstanceGUIDSource string
// RuntimeStatePath overrides /data/runtime_state.json for tests +
// alternate deployments. Empty uses the runtimestate package default.
RuntimeStatePath string
DumpOutputDir string
DumpUploadPath string
DumpUploadURL string
DumpIncludePII bool
ObserveFirstEnabled bool
PassiveStateDirectApply bool
PassiveConfigDirectApply bool
ExternalWritePolicy ObserveFirstExternalWritePolicy
ObserveFirstFlags ObserveFirstFeatureFlags
ObserveFirstRecentMessageCapacity int
ObserveFirstPeriodicityCapacity int
ObserveFirstPeriodicityStaleTTL time.Duration
ObserveFirstSeriesBudget int
ObserveFirstWarmupConnectedWindow time.Duration
ObserveFirstWarmupCompletedTransactions int
ObserveFirstWarmupPostResetWindow time.Duration
ObserveFirstWarmupPostResetTransactions int
ObserveFirstWarmupOuterWindow time.Duration
// EnableStaticSeedTable, when true, plants the
// helianthus-ebusreg/vaillant/productids static seed entries
// into the registry at gateway startup. Used to deterministically
// surface Vaillant addresses that don't respond to active scan
// (e.g. NETX3 broadcast face 0x04 / 0xFF, SOL00 0xEC). Default
// false to preserve the strict observe-first AD05 contract;
// operators opt in via the addon config / CLI flag.
//
// Phase post-C P3 (live validation 2026-05-08): NETX3's 0x04
// face was absent from the registry because broadcast-source
// frames never carry an ACKCorrelation that would flow through
// the inserter. Static seed bypasses that gate.
EnableStaticSeedTable bool
// PhantomInitiatorRejectBytes is a comma-separated list of hex bytes
// (e.g. "0x71,0xFD") that the adapter-direct mux's IsKnownInitiatorByte
// predicate rejects as transient bit-arbitration AND-collision
// artifacts. When an external session's FAILED winner byte matches
// one of these values, the byte is suppressed instead of forwarded
// — preventing downstream consumers (ebusd's bus reconstructor)
// from mistaking the phantom for a real initiator and advancing
// their state machine into a stuck state.
//
// Default "0x71" preserves the live-HA test bus behavior observed
// in batch-27 iter7 (F-30): gateway 0x7F AND-collided with
// initiator 0xF1 yields 0x71, which is NOT a real initiator on
// that bus. Empty string disables filtering entirely on deployments
// where 0x71 IS a real initiator. Multi-byte CSV (e.g. "0x71,0xFD")
// extends rejection to additional phantoms — operators should set
// this explicitly when deploying onto a bus whose topology differs
// from the reference. Per Codex P2 thread on PR #634 (batch-24).
PhantomInitiatorRejectBytes string
}
func DefaultConfig ¶
func DefaultConfig() Config
type DedupDisposition ¶
type DedupDisposition string
const ( DedupDispositionUnmatchedThirdParty DedupDisposition = "unmatched_third_party" DedupDispositionMatchedActiveCopy DedupDisposition = "matched_active_duplicate" DedupDispositionLocalParticipantIn DedupDisposition = "local_participant_inbound" DedupDispositionObservabilityOnly DedupDisposition = "observability_only" DedupDispositionDiscontinuity DedupDisposition = "discontinuity" )
type DedupOutcomeClass ¶
type DedupOutcomeClass string
const ( DedupOutcomeSuccess DedupOutcomeClass = "success" DedupOutcomeNACK DedupOutcomeClass = "nack" DedupOutcomeTimeout DedupOutcomeClass = "timeout" DedupOutcomeCollision DedupOutcomeClass = "collision" DedupOutcomeTransportReset DedupOutcomeClass = "transport_reset" DedupOutcomeDecodeReset DedupOutcomeClass = "decode_reset" DedupOutcomeAbandoned DedupOutcomeClass = "abandoned" )
type DedupResponseClass ¶
type DedupResponseClass string
const ( DedupResponseValueBearing DedupResponseClass = "value_bearing" DedupResponseACKOnly DedupResponseClass = "ack_only" DedupResponseHeaderOnly DedupResponseClass = "header_only" DedupResponseErrorOrAmbiguous DedupResponseClass = "error_or_ambiguous" )
type DedupSubscriberPriority ¶
type DedupSubscriberPriority uint8
const ( DedupSubscriberCritical DedupSubscriberPriority = iota + 1 DedupSubscriberNonCritical )
type DedupTransactionClass ¶
type DedupTransactionClass string
const ( DedupTransactionClassInitiatorTarget DedupTransactionClass = "initiator_target" DedupTransactionClassInitiatorInitiator DedupTransactionClass = "initiator_initiator" DedupTransactionClassBroadcast DedupTransactionClass = "broadcast" DedupTransactionClassLocalParticipantIn DedupTransactionClass = "local_participant_inbound" DedupTransactionClassAbandonedPartial DedupTransactionClass = "abandoned_partial" )
type DegradedModeAccumulator ¶ added in v0.6.18
type DegradedModeAccumulator struct {
// contains filtered or unexported fields
}
DegradedModeAccumulator tracks both consecutive rejoin failures and a rolling-window cumulative degraded-duration counter. Escalation fires when EITHER threshold is reached. Per AD17, the accumulator is in-process only — no restart persistence.
func NewDegradedModeAccumulator ¶ added in v0.6.18
func NewDegradedModeAccumulator() *DegradedModeAccumulator
func (*DegradedModeAccumulator) ClearLatch ¶ added in v0.6.18
func (a *DegradedModeAccumulator) ClearLatch()
ClearLatch clears the escalated flag after state_min_stability_s of continuous active state. Caller is responsible for the stability timer; this method only flips the flag.
func (*DegradedModeAccumulator) CumulativeDegradedMs ¶ added in v0.6.18
func (a *DegradedModeAccumulator) CumulativeDegradedMs() uint64
CumulativeDegradedMs returns the sum of degraded-ms across all buckets in the rolling window.
func (*DegradedModeAccumulator) Escalated ¶ added in v0.6.18
func (a *DegradedModeAccumulator) Escalated() bool
Escalated reports whether the latch is currently set.
func (*DegradedModeAccumulator) RecordDegradedTick ¶ added in v0.6.18
func (a *DegradedModeAccumulator) RecordDegradedTick() bool
RecordDegradedTick advances the cumulative accumulator by one second of degraded-state occupancy. Called by a 1-second ticker in runtime when admission state is degraded. Returns true if the accumulator crossed the escalation threshold.
func (*DegradedModeAccumulator) RecordFailure ¶ added in v0.6.18
func (a *DegradedModeAccumulator) RecordFailure() bool
RecordFailure increments the consecutive failure counter and updates the accumulator with the failure moment. Returns true if the accumulator crossed the escalation threshold as a result of this call.
func (*DegradedModeAccumulator) RecordSuccess ¶ added in v0.6.18
func (a *DegradedModeAccumulator) RecordSuccess()
RecordSuccess clears the consecutive failure counter. Does NOT clear the rolling accumulator — flaps remain visible in the window. Latch clears only after state_min_stability_s of continuous active (caller handles the stability window separately).
type EvidenceBuffer ¶ added in v0.6.18
type EvidenceBuffer struct {
// contains filtered or unexported fields
}
EvidenceBuffer is a bounded, LRU-with-baseline-protection buffer of per-address observations. Its max capacity is max_entries=128 (per AD05). When the buffer is full and a new non-baseline address is observed, the oldest non-baseline entry is evicted. Baseline addresses are NEVER evicted — they may update in place but never leave the buffer.
func NewEvidenceBuffer ¶ added in v0.6.18
func NewEvidenceBuffer(maxEntries int, baseline []byte) (*EvidenceBuffer, error)
func (*EvidenceBuffer) Demote ¶ added in v0.6.18
func (b *EvidenceBuffer) Demote(addr byte) bool
Demote clears the promoted flag for an address and resets its observation counters, allowing the runtime promotion pipeline to give up on a candidate that has repeatedly failed active confirmation. The address remains in the buffer (so subsequent fresh evidence can re-promote it after threshold) but is no longer returned by PromotedAddresses.
Returns true iff the address was promoted before this call.
func (*EvidenceBuffer) Len ¶ added in v0.6.18
func (b *EvidenceBuffer) Len() int
Len returns the current count of stored entries.
func (*EvidenceBuffer) PromotedAddresses ¶ added in v0.6.18
func (b *EvidenceBuffer) PromotedAddresses() []byte
PromotedAddresses returns the sorted set of addresses that have crossed the promotion threshold. Caller uses this to build the directed probe target list for the ebusreg ScanDirected call.
func (*EvidenceBuffer) Record ¶ added in v0.6.18
func (b *EvidenceBuffer) Record(record EvidenceRecord) (promoted bool)
Record adds or updates evidence for an address. Returns whether the address crossed the promotion threshold as a result (≥2 weak/strong observations OR any strong observation).
EvidencePresenceOnly records a touch without contributing to the promotion threshold (`observations` and `strongObs` are NOT incremented). Used to keep an address fresh in the buffer without promoting it (see EvidencePresenceOnly docstring).
type EvidenceRecord ¶ added in v0.6.18
type EvidenceRecord struct {
Address byte
Strength EvidenceStrength
Observed time.Time
Kind string
}
EvidenceRecord is a single observation for a bus address.
type EvidenceStrength ¶ added in v0.6.18
type EvidenceStrength uint8
EvidenceStrength classifies an observation's contribution weight toward promoting a suspect to a confirmed-identity candidate.
const ( // EvidencePresenceOnly records that an address was observed on // the bus without contributing to promotion. Used for sign-of- // life broadcast sources (e.g. 0x07 0xFF), where the operator's // stated requirement is "consumed passively as presence // evidence, not used as a discovery probe target." EvidencePresenceOnly EvidenceStrength = iota + 1 // EvidenceWeak counts toward promotion (>=2 weak observations // promote). Initiator-class frames, request-target traffic without a // coherent B524 response. EvidenceWeak // EvidenceStrong promotes on a single observation. Only used // when the response payload demonstrably implements the // Vaillant extended-register protocol (passes the B524 probe // coherency check) or carries a B509 ScanID identity reply. EvidenceStrong )
type ExtRegisterRequest ¶
type Gateway ¶
type Gateway struct {
Transport transport.RawTransport
Bus *protocol.Bus
Registry *registry.DeviceRegistry
Router *router.BusEventRouter
// contains filtered or unexported fields
}
func (*Gateway) AddRouterPlane ¶
func (*Gateway) DumpUnknownDevices ¶
func (g *Gateway) DumpUnknownDevices(ctx context.Context, entries []registry.DeviceEntry, opts UnknownDeviceDumpOptions) ([]UnknownDeviceDumpResult, error)
func (*Gateway) RefreshRouterPlanes ¶
type LocalAddressSnapshot ¶
type LocalBusAddressSnapshotter ¶
type LocalBusAddressSnapshotter interface {
LocalAddressSnapshot() LocalAddressSnapshot
}
type ObserveFirstDirectApplyPolicy ¶
type ObserveFirstDirectApplyPolicy string
const ( ObserveFirstDirectApplyPolicyNever ObserveFirstDirectApplyPolicy = "never" ObserveFirstDirectApplyPolicyStateDefault ObserveFirstDirectApplyPolicy = "state_default" ObserveFirstDirectApplyPolicyConfigOptIn ObserveFirstDirectApplyPolicy = "config_opt_in" ObserveFirstDirectApplyPolicyEnergyMergeOnly ObserveFirstDirectApplyPolicy = "energy_merge_only" )
type ObserveFirstExternalWritePolicy ¶
type ObserveFirstExternalWritePolicy string
const ( ObserveFirstExternalWritePolicyInvalidateOnly ObserveFirstExternalWritePolicy = "invalidate_only" ObserveFirstExternalWritePolicyRecordOnly ObserveFirstExternalWritePolicy = "record_only" ObserveFirstExternalWritePolicyRecordAndInvalidate ObserveFirstExternalWritePolicy = "record_and_invalidate" )
func ParseObserveFirstExternalWritePolicy ¶
func ParseObserveFirstExternalWritePolicy(value string) (ObserveFirstExternalWritePolicy, error)
type ObserveFirstFamily ¶
type ObserveFirstFamily string
const ( ObserveFirstFamilyOther ObserveFirstFamily = "other" ObserveFirstFamilyB509 ObserveFirstFamily = "B509" ObserveFirstFamilyB516 ObserveFirstFamily = "B516" ObserveFirstFamilyB524 ObserveFirstFamily = "B524" ObserveFirstFamilyB555 ObserveFirstFamily = "B555" )
type ObserveFirstFamilyPolicy ¶
type ObserveFirstFamilyPolicy struct {
Family ObserveFirstFamily
RequestIntent ObserveFirstRequestIntent
ResponseClass DedupResponseClass
CorrelationPolicy WatchCorrelationPolicy
DirectApplyPolicy ObserveFirstDirectApplyPolicy
UsesRuntimeExternalWritePolicy bool
EffectiveExternalWritePolicy ObserveFirstExternalWritePolicy
}
type ObserveFirstFeatureFlagNormalizationReason ¶
type ObserveFirstFeatureFlagNormalizationReason string
const ( ObserveFirstFeatureFlagNormalizationReasonMasterOffClamp ObserveFirstFeatureFlagNormalizationReason = "master_off_clamp" ObserveFirstFeatureFlagNormalizationReasonConfigRequiresState ObserveFirstFeatureFlagNormalizationReason = "config_requires_state" ObserveFirstFeatureFlagNormalizationReasonConfigRequiresInvalidation ObserveFirstFeatureFlagNormalizationReason = "config_requires_invalidation" )
type ObserveFirstFeatureFlagState ¶
type ObserveFirstFeatureFlagState struct {
ObserveFirstEnabled bool `json:"observe_first_enabled"`
PassiveStateDirectApply bool `json:"passive_state_direct_apply"`
PassiveConfigDirectApply bool `json:"passive_config_direct_apply"`
ExternalWritePolicy ObserveFirstExternalWritePolicy `json:"external_write_policy"`
LastUpdatedAt *time.Time `json:"last_updated_at,omitempty"`
Normalizations []string `json:"normalizations,omitempty"`
}
type ObserveFirstFeatureFlagView ¶
type ObserveFirstFeatureFlagView interface {
ObserveFirstEnabled() bool
PassiveStateDirectApply() bool
PassiveConfigDirectApply() bool
ExternalWritePolicy() ObserveFirstExternalWritePolicy
}
type ObserveFirstFeatureFlags ¶
type ObserveFirstFeatureFlags struct {
// contains filtered or unexported fields
}
func DefaultObserveFirstFeatureFlags ¶
func DefaultObserveFirstFeatureFlags() ObserveFirstFeatureFlags
func NormalizeObserveFirstFeatureFlags ¶
func NormalizeObserveFirstFeatureFlags(enabled, stateDirect, configDirect bool, policy ObserveFirstExternalWritePolicy) ObserveFirstFeatureFlags
func NormalizeObserveFirstFeatureFlagsFromView ¶
func NormalizeObserveFirstFeatureFlagsFromView(view ObserveFirstFeatureFlagView) ObserveFirstFeatureFlags
func (ObserveFirstFeatureFlags) ExternalWritePolicy ¶
func (flags ObserveFirstFeatureFlags) ExternalWritePolicy() ObserveFirstExternalWritePolicy
func (ObserveFirstFeatureFlags) NormalizationReasons ¶
func (flags ObserveFirstFeatureFlags) NormalizationReasons() []ObserveFirstFeatureFlagNormalizationReason
func (ObserveFirstFeatureFlags) ObserveFirstEnabled ¶
func (flags ObserveFirstFeatureFlags) ObserveFirstEnabled() bool
func (ObserveFirstFeatureFlags) PassiveConfigDirectApply ¶
func (flags ObserveFirstFeatureFlags) PassiveConfigDirectApply() bool
func (ObserveFirstFeatureFlags) PassiveStateDirectApply ¶
func (flags ObserveFirstFeatureFlags) PassiveStateDirectApply() bool
func (ObserveFirstFeatureFlags) State ¶
func (flags ObserveFirstFeatureFlags) State() ObserveFirstFeatureFlagState
func (ObserveFirstFeatureFlags) StateAt ¶
func (flags ObserveFirstFeatureFlags) StateAt(updatedAt time.Time) ObserveFirstFeatureFlagState
type ObserveFirstRequestIntent ¶
type ObserveFirstRequestIntent string
const ( ObserveFirstRequestIntentUnknown ObserveFirstRequestIntent = "unknown" ObserveFirstRequestIntentRead ObserveFirstRequestIntent = "read" ObserveFirstRequestIntentWrite ObserveFirstRequestIntent = "write" ObserveFirstRequestIntentBroadcast ObserveFirstRequestIntent = "broadcast" )
type ObserveFirstTrafficScope ¶
type ObserveFirstTrafficScope string
const ( ObserveFirstTrafficScopeActive ObserveFirstTrafficScope = "active" ObserveFirstTrafficScopePassive ObserveFirstTrafficScope = "passive" )
type PassiveACKCorrelation ¶ added in v0.6.18
type PassiveACKCorrelation = protocol.ACKCorrelation
type PassiveACKCorrelator ¶ added in v0.6.18
type PassiveACKCorrelator = protocol.ACKCorrelator
type PassiveACKPosition ¶ added in v0.6.18
type PassiveACKPosition = protocol.ACKPosition
type PassiveAbandonReason ¶
type PassiveAbandonReason string
const ( PassiveAbandonReasonCorruptedRequest PassiveAbandonReason = "corrupted_request" PassiveAbandonReasonCorruptedTarget PassiveAbandonReason = "corrupted_target" PassiveAbandonReasonNACK PassiveAbandonReason = "nack" PassiveAbandonReasonNoResponse PassiveAbandonReason = "no_response" PassiveAbandonReasonNoProgress PassiveAbandonReason = "no_progress" PassiveAbandonReasonUnexpectedSYN PassiveAbandonReason = "unexpected_syn" PassiveAbandonReasonUnexpectedSymbol PassiveAbandonReason = "unexpected_symbol" PassiveAbandonReasonTransportReset PassiveAbandonReason = "transport_reset" PassiveAbandonReasonDecodeFault PassiveAbandonReason = "decode_fault" PassiveAbandonReasonDisconnected PassiveAbandonReason = "disconnected" PassiveAbandonReasonCRCMismatch PassiveAbandonReason = "crc_mismatch" PassiveAbandonReasonAmbiguousRetransmit PassiveAbandonReason = "ambiguous_retransmission" PassiveAbandonReasonShutdown PassiveAbandonReason = "shutdown" PassiveAbandonReasonScanTimeout PassiveAbandonReason = "scan_timeout" PassiveAbandonReasonScanCollision PassiveAbandonReason = "scan_collision" PassiveAbandonReasonArbitrationFragment PassiveAbandonReason = "arbitration_fragment" PassiveAbandonReasonSelfEcho PassiveAbandonReason = "self_echo" // F-19c (batch-16): defensive bound-check abandon reasons. These // fire at byte-observation time in handleRequestSymbolLocked / // handleResponseSymbolLocked when the candidate frame violates the // eBUS spec at a structural offset (QQ initiator-address rule, ZZ // non-SYN/non-ESC, NN_m / NN_s ≤ maxPassiveDataLen), before the // LEN-completion or SYN-trigger paths could mis-classify the // buffer. // // Spec references: // - OSI-7 Application Layer Spec V1.6.1 §2.3 (NN cap: 14 // mfr-specific, 10 standardised; codebase uses 16 per // industry folklore via maxPassiveDataLen). // - john30/ebusd symbol.h:39-66 + symbol.cpp:209-229 // (initiator-address nibble rule). // - Wikipedia OSI-2 / eBUS data-link layer reference for // escape encoding scope (QQ/ZZ never escape-encoded). PassiveAbandonReasonInvalidQQ PassiveAbandonReason = "invalid_qq" PassiveAbandonReasonInvalidZZ PassiveAbandonReason = "invalid_zz" PassiveAbandonReasonInvalidNNMaster PassiveAbandonReason = "invalid_nn_m" PassiveAbandonReasonInvalidNNSlave PassiveAbandonReason = "invalid_nn_s" PassiveAbandonReasonBufferOverflow PassiveAbandonReason = "buffer_overflow" )
type PassiveBusTap ¶
type PassiveBusTap struct {
// contains filtered or unexported fields
}
func StartPassiveBusTap ¶
func StartPassiveBusTap(ctx context.Context, cfg Config, consumer PassiveTapConsumer) (*PassiveBusTap, error)
func StartPassiveBusTapWithTransport ¶
func StartPassiveBusTapWithTransport(ctx context.Context, cfg Config, consumer PassiveTapConsumer, wrap func(transport.RawTransport) transport.RawTransport) (*PassiveBusTap, error)
func (*PassiveBusTap) Close ¶
func (tap *PassiveBusTap) Close() error
func (*PassiveBusTap) Snapshot ¶
func (tap *PassiveBusTap) Snapshot() PassiveTapStatus
type PassiveClassifiedEvent ¶
type PassiveClassifiedEvent struct {
Kind PassiveClassifiedEventKind
FrameType protocol.FrameType
Request protocol.Frame
Response protocol.Frame
HasRequest bool
HasResponse bool
Timing PassiveTimingMarkers
ObservedAt time.Time
AbandonReason PassiveAbandonReason
DiscontinuityReason PassiveDiscontinuityReason
ACKCorrelation PassiveACKCorrelation
Err error
Subscriber string
// OffendingSymbol is the raw observed byte that triggered the
// abandon at the moment abandonLocked was called. Populated for
// abandons whose cause is a single observed wire byte (e.g.
// UnexpectedSymbol, NACK, UnexpectedSYN, InvalidQQ/ZZ/NN, NN-bound
// overruns). Zero for lifecycle abandons that are not byte-driven
// (Shutdown, TransportReset, NoProgress watchdog) and for default
// frame-type defensive fall-throughs that cannot identify a single
// causal byte. F-19e (batch-18, 2026-05-13): added so the 0.7
// events/min `unexpected_symbol` rate observed post-F-19d becomes
// forensically diagnosable — the offending byte distribution
// reveals whether the cascade is dominated by wire SYN at
// unexpected phases, mid-frame data bytes, or escape-sequence
// fragments.
OffendingSymbol byte
// OffendingWasEscaped carries the upstream wasEscaped flag
// (F-19d) for the offending byte. Meaningful for phases that
// receive bytes from the unescape decoder (Request, Response);
// always false for phases that observe only structural bytes
// (Idle, ACK, FinalACK, Terminal) or for lifecycle abandons.
OffendingWasEscaped bool
}
type PassiveClassifiedEventKind ¶
type PassiveClassifiedEventKind uint8
const ( PassiveClassifiedEventBroadcastFrame PassiveClassifiedEventKind = iota + 1 PassiveClassifiedEventMasterFrame PassiveClassifiedEventTransaction PassiveClassifiedEventAbandonedTransaction PassiveClassifiedEventDiscontinuity )
type PassiveClassifiedSubscription ¶
type PassiveClassifiedSubscription struct {
// contains filtered or unexported fields
}
func (*PassiveClassifiedSubscription) Close ¶
func (subscription *PassiveClassifiedSubscription) Close()
func (*PassiveClassifiedSubscription) Events ¶
func (subscription *PassiveClassifiedSubscription) Events() <-chan PassiveClassifiedEvent
type PassiveDiscontinuityReason ¶
type PassiveDiscontinuityReason string
const ( PassiveDiscontinuityConnected PassiveDiscontinuityReason = "connected" PassiveDiscontinuityDisconnected PassiveDiscontinuityReason = "disconnected" PassiveDiscontinuityTransportReset PassiveDiscontinuityReason = "transport_reset" PassiveDiscontinuityDecodeFault PassiveDiscontinuityReason = "decode_fault" PassiveDiscontinuityReadTimeout PassiveDiscontinuityReason = "read_timeout" PassiveDiscontinuityShutdown PassiveDiscontinuityReason = "shutdown" PassiveDiscontinuityCriticalSubscriberFault PassiveDiscontinuityReason = "critical_subscriber_overflow" )
type PassiveDiscoveryPromoter ¶ added in v0.6.18
type PassiveDiscoveryPromoter struct {
// contains filtered or unexported fields
}
PassiveDiscoveryPromoter is the runtime-phase counterpart to the startup directed-probe scan. It bridges the gap where a Vaillant device — typically the regulator — boots after the gateway and therefore never appears in the directed startup probe target list.
Pipeline:
The bus_observability store records passive evidence per observed address into its EvidenceBuffer. Once an address crosses the buffer's promotion threshold (>=2 weak observations OR >=1 strong observation; strong = B524 / B509 ScanID response), it is exposed via PromotedAddresses().
The promoter periodically polls PromotedAddresses(), filters candidates already in the registry / equal to the admitted source / outside the responder range, and runs bounded active confirmation against each remaining candidate using the existing B524 capability probe.
On confirmation: a minimal Vaillant entry is registered, router planes are refreshed (so live event routing reflects the new device), and the semantic poller's discovery refresh is enqueued so the regulator surface populates without a gateway restart.
Source-address invariant: active confirmation always sources from the gateway's admitted source. The promoter never overrides the admitted source under any condition.
Rate limiting: per-address attempt counter with exponential backoff via RejoinBackoffSchedule. A failed confirmation schedules the next attempt at backoff(attempt) with a jittered floor; success clears the per-address state.
func NewPassiveDiscoveryPromoter ¶ added in v0.6.18
func NewPassiveDiscoveryPromoter(opts PassiveDiscoveryPromoterOptions) (*PassiveDiscoveryPromoter, error)
NewPassiveDiscoveryPromoter constructs a promoter. Returns an error if any required option is nil.
func (*PassiveDiscoveryPromoter) Run ¶ added in v0.6.18
func (p *PassiveDiscoveryPromoter) Run(ctx context.Context)
Run polls the evidence buffer at the configured tick interval and runs active confirmation on each promoted candidate not already in the registry. Returns when ctx is cancelled.
func (*PassiveDiscoveryPromoter) SetRegisterFn ¶ added in v0.6.18
func (p *PassiveDiscoveryPromoter) SetRegisterFn(fn func(target byte))
SetRegisterFn overrides the registry-write function. Used by tests to substitute a no-op or to capture the registered address. The production path uses the default registry.Register helper.
func (*PassiveDiscoveryPromoter) Snapshot ¶ added in v0.6.18
func (p *PassiveDiscoveryPromoter) Snapshot() PassiveDiscoveryPromoterSnapshot
Snapshot captures current promoter counters and per-address state for diagnostics and tests.
type PassiveDiscoveryPromoterOptions ¶ added in v0.6.18
type PassiveDiscoveryPromoterOptions struct {
// Registry is the gateway device registry — used to filter
// candidates already known and to register confirmed devices.
// Required.
Registry *registry.DeviceRegistry
// EvidenceBuffer feeds candidate addresses. Required.
EvidenceBuffer *EvidenceBuffer
// ConfirmFn runs the B524 capability coherency probe against the
// candidate target using the admitted source. Returns true on
// coherent response. Required.
ConfirmFn func(ctx context.Context, target byte) bool
// SemanticRefreshFn enqueues the semantic poller's discovery
// refresh after a successful registration so the regulator
// surface populates. Optional — promoter still registers and
// refreshes router planes when nil.
SemanticRefreshFn func()
// RouterRefreshFn refreshes router planes after a successful
// registration so live event routing reflects the new device.
// Optional.
RouterRefreshFn func()
// AdmittedSourceFn returns the gateway's admitted source. The
// promoter filters this address out of candidates so the gateway
// never confirms its own source. Required.
AdmittedSourceFn func() byte
// TickInterval bounds how often the promoter polls
// PromotedAddresses. Defaults to 30s if unset.
TickInterval time.Duration
// Now returns the current time. Defaults to time.Now if unset.
Now func() time.Time
}
PassiveDiscoveryPromoterOptions configures a new promoter.
type PassiveDiscoveryPromoterSnapshot ¶ added in v0.6.18
type PassiveDiscoveryPromoterSnapshot struct {
ConfirmedTotal uint64
RejectedTotal uint64
SkippedTotal uint64
PendingByAddr map[byte]int
}
Snapshot returns a point-in-time view of promoter state for diagnostics and tests.
func (PassiveDiscoveryPromoterSnapshot) String ¶ added in v0.6.18
func (s PassiveDiscoveryPromoterSnapshot) String() string
String renders the snapshot for log lines.
type PassiveEndpointState ¶
type PassiveEndpointState string
const ( PassiveEndpointStateUnknown PassiveEndpointState = "unknown" PassiveEndpointStateConnected PassiveEndpointState = "connected" PassiveEndpointStateTemporarilyDisconnected PassiveEndpointState = "temporarily_disconnected" PassiveEndpointStateUnsupportedOrMisconfigured PassiveEndpointState = "unsupported_or_misconfigured" PassiveEndpointStateClosed PassiveEndpointState = "closed" )
type PassiveReconstructorSnapshot ¶
type PassiveReconstructorSnapshot struct {
TapStatus PassiveTapStatus
FanoutOverflowTotal map[string]uint64
RecoveryTotal map[string]uint64
// AbandonsByReason counts how many transactions the reconstructor
// classified into each PassiveAbandonReason. Operators query this
// to determine if a specific (src, dst) pair is failing
// classification at unusual rates — e.g. live evidence of B503
// frames hitting unexpected_symbol despite Grafana ground truth
// showing positive ACKs on the wire (A.9 diagnostic surface).
AbandonsByReason map[string]uint64
// PrefixResyncSkippedTotal counts non-SYN bytes the parser dropped
// because no SymbolSyn was observed since the previous frame
// boundary (P6 Layer 1 — inter-frame SYN gate). Direct measure of
// continuation-byte / startup resync events; expected to spike at
// startup then plateau near zero on a clean bus.
PrefixResyncSkippedTotal uint64
// InvalidSrcClassSkippedTotal counts non-initiator-class bytes the
// parser rejected in source position (P6 Layer 2 — SRC AddressClass
// validation). Direct measure of upstream byte-loss frequency
// (operator-confirmed Mode B: "[SYN] [TGT] [PB=0xB5] [SB] [data]"
// signature where the actual SRC byte was eaten by the ENH
// transport's StreamEventStarted capture or by an analogous proxy
// drop). Sustained non-zero rate after deploy quantifies the
// cost-of-deferral for the upstream P6.1/P6.2 follow-ups.
InvalidSrcClassSkippedTotal uint64
}
type PassiveSubscriberPriority ¶
type PassiveSubscriberPriority uint8
const ( PassiveSubscriberCritical PassiveSubscriberPriority = iota + 1 PassiveSubscriberNonCritical )
type PassiveTapConsumer ¶
type PassiveTapConsumer interface {
OnPassiveTapEvent(PassiveTapEvent)
}
type PassiveTapEvent ¶
type PassiveTapEvent struct {
Kind PassiveTapEventKind
Symbol byte
ObservedAt time.Time
Err error
// WasEscaped is true iff Symbol was produced by the eBUS byte-
// stuffing decoder from a wire `0xA9 0x00` (→ logical 0xA9) or
// `0xA9 0x01` (→ logical 0xAA). False means EITHER (a) a raw
// passthrough byte that the local decoder saw on the wire, OR
// (b) an upstream-logical byte where the transport did not expose
// escape provenance. For F-23 transports that do expose
// transport.StreamEvent.WasEscaped, the passive tap preserves the
// upstream wire-side ground truth instead of hardcoding false.
//
// F-19d (_work_adaptermux_audit/EBUSD-VERIFICATION-2026-05-13-batch17.md):
// the passive transaction reconstructor uses this flag to
// disambiguate logical 0xAA bytes — escape-decoded data vs wire
// SYN frame-terminator — replacing the heuristic
// isMidRequestFrame() that mis-classified ~9 events/hour into
// next-frame cascades.
WasEscaped bool
}
type PassiveTapEventKind ¶
type PassiveTapEventKind uint8
const ( PassiveTapEventConnected PassiveTapEventKind = iota + 1 PassiveTapEventDisconnected PassiveTapEventSymbol PassiveTapEventReset PassiveTapEventDecodeFault PassiveTapEventReadTimeout )
type PassiveTapStatus ¶
type PassiveTapStatus struct {
Connected bool
EndpointState PassiveEndpointState
LastError string
ConnectAttemptCount uint64
ConnectCount uint64
ConnectFailureCount uint64
DisconnectCount uint64
ResetCount uint64
DecodeFaultCount uint64
ObservedSymbolCount uint64
LastConnectAt time.Time
LastDisconnectAt time.Time
LastObservedSymbol time.Time
}
type PassiveTimingMarkers ¶
type PassiveTransactionFingerprint ¶
type PassiveTransactionFingerprint struct {
Epoch uint64
TransactionClass DedupTransactionClass
OutcomeClass DedupOutcomeClass
ResponseClass DedupResponseClass
FamilyPolicy ObserveFirstFamilyPolicy
Source byte
Target byte
RequestBytes []byte
ResponseBytes []byte
Hash [32]byte
ObservedAt time.Time
}
type PassiveTransactionReconstructor ¶
type PassiveTransactionReconstructor struct {
// contains filtered or unexported fields
}
func StartPassiveTransactionReconstructor ¶
func StartPassiveTransactionReconstructor(ctx context.Context, cfg Config) (*PassiveTransactionReconstructor, error)
func StartPassiveTransactionReconstructorWithTransport ¶
func StartPassiveTransactionReconstructorWithTransport(ctx context.Context, cfg Config, wrap func(transport.RawTransport) transport.RawTransport) (*PassiveTransactionReconstructor, error)
func (*PassiveTransactionReconstructor) Close ¶
func (reconstructor *PassiveTransactionReconstructor) Close() error
func (*PassiveTransactionReconstructor) OnPassiveTapEvent ¶
func (reconstructor *PassiveTransactionReconstructor) OnPassiveTapEvent(event PassiveTapEvent)
func (*PassiveTransactionReconstructor) SetLocalAddressSnapshotter ¶
func (reconstructor *PassiveTransactionReconstructor) SetLocalAddressSnapshotter(snapshotter LocalBusAddressSnapshotter)
SetLocalAddressSnapshotter provides the reconstructor with a way to query the gateway's local bus address. The snapshotter is queried dynamically so the local address can be discovered at runtime (e.g. during the startup scan). Must be called before AttachReconstructor or at least before passive symbols start arriving; it is protected by stateMu.
func (*PassiveTransactionReconstructor) Snapshot ¶
func (reconstructor *PassiveTransactionReconstructor) Snapshot() PassiveReconstructorSnapshot
func (*PassiveTransactionReconstructor) Subscribe ¶
func (reconstructor *PassiveTransactionReconstructor) Subscribe(name string, priority PassiveSubscriberPriority, buffer int) (*PassiveClassifiedSubscription, error)
type ProtocolSpecimenExport ¶
type ProtocolSpecimenExport struct {
Family string `json:"family"`
Source byte `json:"source"`
Target byte `json:"target"`
FrameType string `json:"frame_type"`
RequestHex string `json:"request_hex"`
ResponseHex string `json:"response_hex,omitempty"`
RequestLen int `json:"request_len"`
ResponseLen int `json:"response_len"`
Outcome string `json:"outcome"`
FirstSeenAt time.Time `json:"first_seen_at"`
LastSeenAt time.Time `json:"last_seen_at"`
Count uint64 `json:"count"`
}
type RuntimeStateObserver ¶ added in v0.6.18
RuntimeStateObserver is the runtime-state cache notification hook. AddressTableInserter calls it once per passive observation (new insert OR refresh of an existing slot) so the runtimestate.Manager can populate/refresh known_bus_members[] for M5 revalidation.
observedAt is the bus-event timestamp; reportedSource is the runtimestate.LastSource string (e.g. "passive_observed").
Production wiring lives in cmd/gateway/main.go, calling runtimeStateMgr.UpsertKnownBusMember. The hook is fired synchronously inside maybeInsert; observers MUST be cheap (the Manager's UpsertKnownBusMember is a brief mu-guarded field swap and is safe to call at bus-event rate).
type SemanticReadCircuitBreakerOptions ¶
type SemanticReadCircuitBreakerOptions struct {
FailureBudget int
OpenCooldown time.Duration
HalfOpenProbeLimit int
OnTransition func(SemanticReadCircuitBreakerTransition)
OnSuppressed func(SemanticReadCircuitBreakerSuppression)
}
type SemanticReadCircuitBreakerSuppression ¶
type SemanticReadCircuitBreakerSuppression struct {
Key string
State SemanticReadCircuitState
SuppressedTotal uint64
RetryAfter time.Duration
}
type SemanticReadCircuitBreakerTransition ¶
type SemanticReadCircuitBreakerTransition struct {
Key string
From SemanticReadCircuitState
To SemanticReadCircuitState
ConsecutiveFailures int
}
type SemanticReadCircuitState ¶
type SemanticReadCircuitState string
const ( SemanticReadCircuitStateClosed SemanticReadCircuitState = "closed" SemanticReadCircuitStateOpen SemanticReadCircuitState = "open" SemanticReadCircuitStateHalfOpen SemanticReadCircuitState = "half-open" )
type SemanticReadScheduler ¶
type SemanticReadScheduler struct {
// contains filtered or unexported fields
}
SemanticReadScheduler coalesces identical semantic reads and provides a small in-memory cache to avoid multiplying eBUS traffic under multiple consumers.
It is intentionally generic: callers choose the key and the maxAge policy.
func NewSemanticReadScheduler ¶
func NewSemanticReadScheduler() *SemanticReadScheduler
func (*SemanticReadScheduler) Get ¶
func (s *SemanticReadScheduler) Get(ctx context.Context, key string, maxAge time.Duration, fetch func(context.Context) ([]byte, error)) ([]byte, error)
Get returns a cached value when it is fresh, otherwise it performs fetch once and shares the result with concurrent callers.
If fetch fails, the last successful value (if any) remains cached.
func (*SemanticReadScheduler) GetWatchWithStats ¶
func (*SemanticReadScheduler) SetCircuitBreaker ¶
func (s *SemanticReadScheduler) SetCircuitBreaker(options SemanticReadCircuitBreakerOptions)
func (*SemanticReadScheduler) SetShadowCache ¶
func (s *SemanticReadScheduler) SetShadowCache(cache *ShadowCache)
type ShadowCache ¶
type ShadowCache struct {
// contains filtered or unexported fields
}
func NewShadowCache ¶
func NewShadowCache(options ShadowCacheOptions) *ShadowCache
func (*ShadowCache) BootstrapRuntimeDescriptor ¶
func (cache *ShadowCache) BootstrapRuntimeDescriptor(descriptor WatchDescriptor, sources ...WatchActivationSource) error
BootstrapRuntimeDescriptor registers a descriptor/source pair into the runtime catalog+activation graph so shadow reads/writes can participate for keys that were discovered after cache construction.
func (*ShadowCache) CaptureGeneration ¶
func (cache *ShadowCache) CaptureGeneration(key WatchKey) uint64
func (*ShadowCache) CompactOnce ¶
func (cache *ShadowCache) CompactOnce() time.Duration
func (*ShadowCache) Entry ¶
func (cache *ShadowCache) Entry(key WatchKey) (ShadowEntryView, bool)
func (*ShadowCache) FeatureFlags ¶
func (cache *ShadowCache) FeatureFlags() ObserveFirstFeatureFlags
func (*ShadowCache) Invalidate ¶
func (cache *ShadowCache) Invalidate(invalidation ShadowInvalidation) ShadowInvalidationResult
func (*ShadowCache) Lookup ¶
func (cache *ShadowCache) Lookup(key WatchKey, maxAge time.Duration) ShadowLookupResult
func (*ShadowCache) Observe ¶ added in v0.6.32
func (cache *ShadowCache) Observe(key WatchKey) WatchObservation
func (*ShadowCache) RefreshActivations ¶
func (cache *ShadowCache) RefreshActivations()
func (*ShadowCache) RevalidatePinnedBudget ¶
func (cache *ShadowCache) RevalidatePinnedBudget() ShadowCacheSummary
func (*ShadowCache) SnapshotEligibility ¶
func (cache *ShadowCache) SnapshotEligibility(key WatchKey) ShadowEligibilitySnapshot
func (*ShadowCache) StartCompactor ¶
func (cache *ShadowCache) StartCompactor()
func (*ShadowCache) Summary ¶
func (cache *ShadowCache) Summary() ShadowCacheSummary
func (*ShadowCache) WatchSummary ¶
func (cache *ShadowCache) WatchSummary() WatchSummary
func (*ShadowCache) Write ¶
func (cache *ShadowCache) Write(write ShadowWrite) ShadowWriteResult
type ShadowCacheOptions ¶
type ShadowCacheOptions struct {
FeatureFlags ObserveFirstFeatureFlagView
Catalog *WatchCatalog
Activations *WatchActivationSet
Capacity int
PinnedCapacity int
WriteConfirmPinnedCap int
TombstoneRetainWindow time.Duration
TombstoneHardLifespan time.Duration
CompactorCadence time.Duration
CompactorBatchSize int
ShutdownCompactorTimeout time.Duration
Now func() time.Time
}
type ShadowCacheSummary ¶
type ShadowConfidenceTier ¶
type ShadowConfidenceTier string
const ( ShadowConfidenceHigh ShadowConfidenceTier = "high_confidence" ShadowConfidenceLimited ShadowConfidenceTier = "limited_confidence" ShadowConfidenceNone ShadowConfidenceTier = "no_confidence" )
type ShadowEntryState ¶
type ShadowEntryState string
const ( ShadowEntryStatePresent ShadowEntryState = "present" ShadowEntryStateInvalidated ShadowEntryState = "invalidated" ShadowEntryStateTombstone ShadowEntryState = "tombstone" )
type ShadowEntryView ¶
type ShadowEntryView struct {
CanonicalKey string
Descriptor WatchDescriptor
Source ShadowWriteSource
Confidence ShadowConfidenceTier
State ShadowEntryState
Value []byte
ObservedAt time.Time
ExpiresAt time.Time
Generation uint64
LastWriteGeneration uint64
InvalidationGeneration uint64
InvalidationReason ShadowInvalidationReason
InvalidationSource ShadowInvalidationSource
InvalidatedAt time.Time
Pinned bool
}
type ShadowInvalidation ¶
type ShadowInvalidation struct {
Key WatchKey
Reason ShadowInvalidationReason
Source ShadowInvalidationSource
InvalidatedAt time.Time
}
type ShadowInvalidationReason ¶
type ShadowInvalidationReason string
const ( ShadowInvalidationReasonExternalWrite ShadowInvalidationReason = "external_write" ShadowInvalidationReasonRollback ShadowInvalidationReason = "rollback" ShadowInvalidationReasonManual ShadowInvalidationReason = "manual" ShadowInvalidationReasonPolicyReject ShadowInvalidationReason = "policy_reject" )
type ShadowInvalidationResult ¶
type ShadowInvalidationResult struct {
Generation uint64
State ShadowEntryState
}
type ShadowInvalidationSource ¶
type ShadowInvalidationSource string
const ( ShadowInvalidationSourcePassive ShadowInvalidationSource = "passive" ShadowInvalidationSourceActive ShadowInvalidationSource = "active" ShadowInvalidationSourceOperator ShadowInvalidationSource = "operator" ShadowInvalidationSourceSystem ShadowInvalidationSource = "system" )
type ShadowLookupResult ¶
type ShadowLookupResult struct {
Entry ShadowEntryView
Found bool
Eligible bool
Descriptor WatchDescriptor
HasDescriptor bool
}
type ShadowWrite ¶
type ShadowWrite struct {
Key WatchKey
Source ShadowWriteSource
Confidence ShadowConfidenceTier
Value []byte
ObservedAt time.Time
StartGeneration uint64
}
type ShadowWriteRejectionReason ¶
type ShadowWriteRejectionReason string
const ( ShadowWriteRejectionReasonStaleTimestamp ShadowWriteRejectionReason = "stale_timestamp" ShadowWriteRejectionReasonSameTimestampConflict ShadowWriteRejectionReason = "same_timestamp_conflict" ShadowWriteRejectionReasonGenerationAdvanced ShadowWriteRejectionReason = "generation_advanced" ShadowWriteRejectionReasonPolicyReject ShadowWriteRejectionReason = "policy_reject" ShadowWriteRejectionReasonCapacity ShadowWriteRejectionReason = "capacity" )
type ShadowWriteResult ¶
type ShadowWriteResult struct {
Accepted bool
Generation uint64
LastWriteGeneration uint64
Reason ShadowWriteRejectionReason
}
type ShadowWriteSource ¶
type ShadowWriteSource string
const ( ShadowWriteSourcePassive ShadowWriteSource = "passive" ShadowWriteSourceActiveConfirmed ShadowWriteSource = "active_confirmed" )
type SmokeCheckResult ¶
type SmokeOptions ¶
type SmokeOptions struct {
RootDir string
Providers []registry.PlaneProvider
Logger *log.Logger
SourceAddress byte
OnGatewayReady func(ctx context.Context, gateway *Gateway, logger *log.Logger)
GraphQLCheck func(ctx context.Context, gateway *Gateway) SmokeCheckResult
MCPCheck func(ctx context.Context, gateway *Gateway) SmokeCheckResult
}
type SourceSelectionArtifact ¶ added in v0.6.18
type SourceSelectionArtifact struct {
Admission SourceSelectionArtifactAdmission `json:"admission"`
Discovery SourceSelectionArtifactDiscovery `json:"discovery"`
}
SourceSelectionArtifact is the machine-readable summary emitted at the end of the startup source-selection + discovery window per plan §M7.
type SourceSelectionArtifactAdmission ¶ added in v0.6.18
type SourceSelectionArtifactAdmission struct {
State string `json:"state"`
Source uint8 `json:"source"`
CompanionTarget uint8 `json:"companion_target"`
WarmupDurationS float64 `json:"warmup_duration_s"`
ReasonIfDegraded string `json:"reason_if_degraded"`
TransportKind string `json:"transport_kind"`
SourceSelection SourceSelectionArtifactSourceSelection `json:"source_selection"`
}
type SourceSelectionArtifactBuilder ¶ added in v0.6.18
type SourceSelectionArtifactBuilder struct {
// contains filtered or unexported fields
}
SourceSelectionArtifactBuilder aggregates runtime events over the startup window and produces the final SourceSelectionArtifact on Emit.
func NewSourceSelectionArtifactBuilder ¶ added in v0.6.18
func NewSourceSelectionArtifactBuilder(transportKind string) *SourceSelectionArtifactBuilder
func (*SourceSelectionArtifactBuilder) Emit ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) Emit() (SourceSelectionArtifact, []byte, error)
func (*SourceSelectionArtifactBuilder) EmitToFile ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) EmitToFile(path string) error
EmitToFile writes the artifact JSON to the given path. Once a snapshot is emitted (e.g. by the 60s startup-window goroutine), subsequent calls are no-ops via the emitOnce guard — this prevents the AD20-reviewer- flagged race where a defer-on-shutdown emit could overwrite the canonical 60s window snapshot with later state.
To re-arm the builder for a new window, call ResetEmitOnce.
func (*SourceSelectionArtifactBuilder) RecordBaselineEvidence ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) RecordBaselineEvidence(address uint8, count int)
func (*SourceSelectionArtifactBuilder) RecordProbe ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) RecordProbe(wireBytes int)
func (*SourceSelectionArtifactBuilder) ResetEmitOnce ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) ResetEmitOnce()
ResetEmitOnce re-arms EmitToFile so the next call will write again. Used by tests; production callers should not need this.
func (*SourceSelectionArtifactBuilder) SetActiveExplicitSource ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) SetActiveExplicitSource(source uint8)
SetActiveExplicitSource flips Admission.State to "active" and records the explicit Source used from the first active frame.
func (*SourceSelectionArtifactBuilder) SetBaselineEvidenceProvider ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) SetBaselineEvidenceProvider(provider func() map[string]int)
SetBaselineEvidenceProvider installs a callback that returns the per-baseline-address evidence counts at emit time. Called by Emit and EmitToFile under the builder's mutex; the provider must be safe for concurrent invocation. Resolves cruise-run #20 validation finding that per_baseline_address_evidence_counts was unconditionally empty in the emitted artifact even when the registry observed traffic to baseline addresses.
func (*SourceSelectionArtifactBuilder) SetDegraded ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) SetDegraded(reason string)
func (*SourceSelectionArtifactBuilder) SetExplicitSource ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) SetExplicitSource(source uint8)
func (*SourceSelectionArtifactBuilder) SetPostStartupSustainedRateProbesPer15s ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) SetPostStartupSustainedRateProbesPer15s(rate float64)
func (*SourceSelectionArtifactBuilder) SetPromotedSuspects ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) SetPromotedSuspects(n int)
func (*SourceSelectionArtifactBuilder) SetSourceSelection ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) SetSourceSelection(source, companionTarget uint8, warmupDuration time.Duration)
func (*SourceSelectionArtifactBuilder) SetSourceSelectionActive ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) SetSourceSelectionActive()
func (*SourceSelectionArtifactBuilder) SetSourceSelectionMode ¶ added in v0.6.18
func (b *SourceSelectionArtifactBuilder) SetSourceSelectionMode(v string) error
type SourceSelectionArtifactDiscovery ¶ added in v0.6.18
type SourceSelectionArtifactDiscovery struct {
WireBytes int `json:"wire_bytes"`
WindowS float64 `json:"window_s"`
StartupBurstPct float64 `json:"startup_burst_pct"`
PostStartupSustainedRateProbesPer15s float64 `json:"post_startup_sustained_rate_probes_per_15s"`
ProbeCount int `json:"probe_count"`
PromotedSuspectsWithoutIdentity int `json:"promoted_suspects_without_identity"`
PerBaselineAddressEvidenceCounts map[string]int `json:"per_baseline_address_evidence_counts"`
}
type SourceSelectionArtifactSourceSelection ¶ added in v0.6.18
type SourceSelectionArtifactSourceSelection struct {
Mode string `json:"mode"`
}
type StartupSourceOverride ¶ added in v0.6.18
type StartupSourceOverride struct {
// Source is the static source address to use for all Helianthus-
// originated active frames on source-selection-capable direct transports when
// this override is set. When nil, override is unset.
Source *uint8
// Validate, when true, runs the source-address selector in advisory-only mode in
// parallel with the override path so the companion-target conflict
// heuristic can still detect a mismatch and emit a WARN log. Does
// NOT gate active traffic (active frames fire immediately with the
// override source). Default: false.
Validate bool
}
StartupSourceOverride configures opt-in static-source admission on source-selection-capable direct transports per AD09. Default (unset) preserves the standard source-address selector warmup path.
type StartupSourceSelectionMetrics ¶ added in v0.6.18
type StartupSourceSelectionMetrics struct {
DegradedTotal *expvar.Int
State *expvar.Int
ExplicitSourceActive *expvar.Int
WarmupEventsSeen *expvar.Int
WarmupCyclesTotal *expvar.Int
ExplicitValidateOnlyTotal *expvar.Int
ExplicitSourceConflictDetected *expvar.Int
DegradedEscalated *expvar.Int
DegradedSinceMs *expvar.Int
ConsecutiveFailures *expvar.Int
DegradedCumulativeMs *expvar.Int
// contains filtered or unexported fields
}
StartupSourceSelectionMetrics bundles the 11 expvar surfaces exposed by the startup source-selection plan. Names and semantics match the plan exactly; callers publish this bundle via expvar.Publish at startup and update counters/gauges as runtime events occur.
func GetOrInitStartupSourceSelectionMetrics ¶ added in v0.6.18
func GetOrInitStartupSourceSelectionMetrics() *StartupSourceSelectionMetrics
GetOrInitStartupSourceSelectionMetrics returns the process-global StartupSourceSelectionMetrics instance, creating it and publishing its expvars on first call.
func NewStartupSourceSelectionMetrics ¶ added in v0.6.18
func NewStartupSourceSelectionMetrics() *StartupSourceSelectionMetrics
NewStartupSourceSelectionMetrics allocates the metric bundle. Caller decides whether to publish via expvar.Publish or keep per-instance (for tests).
func (*StartupSourceSelectionMetrics) MarkActive ¶ added in v0.6.18
func (m *StartupSourceSelectionMetrics) MarkActive()
MarkActive sets State=1 and clears DegradedSinceMs. Holds m.mu so the pair {State, DegradedSinceMs} updates atomically vs MarkDegraded / MarkPending — prevents the AD20-reviewer-flagged race where concurrent transitions could double-count DegradedTotal.
func (*StartupSourceSelectionMetrics) MarkDegraded ¶ added in v0.6.18
func (m *StartupSourceSelectionMetrics) MarkDegraded(now time.Time)
MarkDegraded sets State=2, increments DegradedTotal, records DegradedSinceMs if not already set.
func (*StartupSourceSelectionMetrics) MarkPending ¶ added in v0.6.18
func (m *StartupSourceSelectionMetrics) MarkPending()
MarkPending sets State=0. Holds m.mu (see MarkActive note).
func (*StartupSourceSelectionMetrics) Publish ¶ added in v0.6.18
func (m *StartupSourceSelectionMetrics) Publish()
Publish registers all expvars under the "startup_source_selection_" prefix. Idempotent-safe behavior: does NOT re-register if Publish was already called (expvar panics on duplicate publishes); caller must only call once per process. In tests, use metrics without publishing.
func (*StartupSourceSelectionMetrics) RecordExplicitValidateOnly ¶ added in v0.6.18
func (m *StartupSourceSelectionMetrics) RecordExplicitValidateOnly()
RecordExplicitValidateOnly increments ExplicitValidateOnlyTotal.
func (*StartupSourceSelectionMetrics) RecordWarmupEvent ¶ added in v0.6.18
func (m *StartupSourceSelectionMetrics) RecordWarmupEvent()
RecordWarmupEvent increments WarmupEventsSeen by 1.
func (*StartupSourceSelectionMetrics) SetConsecutiveFailures ¶ added in v0.6.18
func (m *StartupSourceSelectionMetrics) SetConsecutiveFailures(n int)
SetConsecutiveFailures records the current count.
func (*StartupSourceSelectionMetrics) SetDegradedCumulativeMs ¶ added in v0.6.18
func (m *StartupSourceSelectionMetrics) SetDegradedCumulativeMs(ms uint64)
SetDegradedCumulativeMs records the current rolling-window cumulative.
func (*StartupSourceSelectionMetrics) SetDegradedEscalated ¶ added in v0.6.18
func (m *StartupSourceSelectionMetrics) SetDegradedEscalated(latched bool)
SetDegradedEscalated sets the latch (0 or 1).
func (*StartupSourceSelectionMetrics) SetExplicitSourceActive ¶ added in v0.6.18
func (m *StartupSourceSelectionMetrics) SetExplicitSourceActive(active bool)
SetExplicitSourceActive(true) sets ExplicitSourceActive=1; false sets 0.
func (*StartupSourceSelectionMetrics) SetExplicitSourceConflictDetected ¶ added in v0.6.18
func (m *StartupSourceSelectionMetrics) SetExplicitSourceConflictDetected()
SetExplicitSourceConflictDetected flips ExplicitSourceConflictDetected to 1 (latching for the current run; a cycle reset would restart it).
func (*StartupSourceSelectionMetrics) StartWarmupCycle ¶ added in v0.6.18
func (m *StartupSourceSelectionMetrics) StartWarmupCycle() uint64
StartWarmupCycle resets WarmupEventsSeen to 0 and increments WarmupCyclesTotal. Returns the new cycle sequence number.
type TransportAdmissionPath ¶ added in v0.6.18
type TransportAdmissionPath uint8
TransportAdmissionPath is the source-selection dispatch decision for a given transport kind per the startup source-selection plan's transport capability matrix (see plan AD11 and helianthus-docs-ebus/architecture/startup-admission-and-discovery.md §10).
const ( // TransportAdmissionSourceSelectionCapable denotes a direct transport on which the // gateway runs the source-address selector warmup before any // non-explicit active frame. Applies to ENH, ENS, UDP-plain, TCP-plain. TransportAdmissionSourceSelectionCapable TransportAdmissionPath = iota + 1 // TransportAdmissionStaticFallback denotes the ebusd-tcp path, where the // gateway does NOT instantiate source-address selection and uses the configured // ScanSource on the ebusd-owned transport path per AD13. TransportAdmissionStaticFallback )
func ClassifyTransportAdmission ¶ added in v0.6.18
func ClassifyTransportAdmission(kind TransportProtocol) (TransportAdmissionPath, error)
ClassifyTransportAdmission returns the admission path dispatch for the given TransportProtocol per the startup-admission-discovery plan's transport capability matrix. Unknown or empty values return (zero, error).
func ResolveAdmissionPath ¶ added in v0.6.18
func ResolveAdmissionPath(kind TransportProtocol) (path TransportAdmissionPath, adapterDirectSpecialCase bool)
ResolveAdmissionPath returns the admission-path dispatch with adapter-direct special-cased to JoinCapable. Adapter-direct multiplexer mode always wraps a source-selection-capable underlying transport (ENH or ENS in practice; UDP/TCP-plain are not configurations the multiplexer is built for). The source-address selection bus adapter subscribes to the same PassiveTransactionReconstructor regardless of multiplexer presence, so adapter-direct deployments MUST run source-address selection.
This helper exists because ClassifyTransportAdmission is intentionally pure (one transport at a time, no multiplexer-context awareness) and rejects adapter-direct as needing inner-transport unwrap. Callers that have access to the full Config (and therefore know about the multiplexer wrapper) should use this helper instead of ClassifyTransportAdmission directly.
Returns the resolved admission path. The boolean indicates whether the adapter-direct special case fired (so the caller can log the multiplexer detection once, not twice). Empty/unknown protocols fall back to StaticFallback with the second return false.
Resolves cruise-run #20 validation finding: startup_scan.go had its own ClassifyTransportAdmission calls that took the static-fallback path on adapter-direct, contradicting main.go's special-case. Centralising the logic here keeps all call sites in agreement.
type TransportConfig ¶
type TransportProtocol ¶
type TransportProtocol string
func CanonicalTransportProtocol ¶ added in v0.6.18
func CanonicalTransportProtocol(protocol TransportProtocol) TransportProtocol
CanonicalTransportProtocol is the exported form of canonicalTransportProtocol. External callers (e.g. cmd/gateway's responder-capability provider) use it to normalise raw protocol strings to the enum literals used across the package.
Aliases handled: "ebusd" → "ebusd-tcp"; all forms are trimmed + lower-cased. Unknown strings pass through as the normalised TransportProtocol with no alias resolution (caller decides what to do with unknown values).
type UnknownDeviceDumpResult ¶
type UnknownDeviceDumpResult struct {
Address byte
BundlePath string
ManifestPath string
Uploaded bool
UploadURL string
UploadStatus string
UploadHTTPCode int
Error string
}
func DumpUnknownDevices ¶
func DumpUnknownDevices(ctx context.Context, bus DumpBus, entries []registry.DeviceEntry, opts UnknownDeviceDumpOptions) ([]UnknownDeviceDumpResult, error)
type V8RolloutSnapshot ¶ added in v0.6.32
type V8RolloutSnapshot struct {
// Round9AbsorbEntered counts transactions that entered the
// legacy pre-v8 round-9 absorb path in protocol.Bus.
// Published as helianthus_round9_absorb_entered_total.
//
// HelianthusRound9FiredUnderProxy alert fires on any growth:
// once the v8 frame-atomic-visibility path is fully deployed
// the round-9 fallback should never trigger. Growth indicates
// either an upstream regression or a corner case the v8 path
// does not yet cover.
Round9AbsorbEntered uint64
// PayloadAaAutoSynAbsorbed counts wire SYN bytes the round-9
// absorb path consumed during payload-0xAA writes.
// Published as helianthus_payload_aa_auto_syn_absorbed_total.
// Forensic — paired with Round9AbsorbEntered for severity
// dashboards (per-byte cost of legacy-fallback firings).
PayloadAaAutoSynAbsorbed uint64
// PayloadAaAutoSynRecovered counts transactions where the
// absorb path's drain successfully recovered to a clean
// terminator after consuming wire SYNs.
// Published as helianthus_payload_aa_auto_syn_recovered_total.
// Forensic — ratio recovered/entered shows how often the
// fallback actually rescued the transaction vs hit drain
// exhaustion.
PayloadAaAutoSynRecovered uint64
// PayloadAaAutoSynDrainExhausted counts transactions where the
// absorb path exhausted its drain budget without recovering.
// Published as helianthus_payload_aa_auto_syn_drain_exhausted_total.
// Forensic — non-zero indicates the round-9 fallback is
// running but failing to rescue; the transaction will surface
// as a bus error.
PayloadAaAutoSynDrainExhausted uint64
// V8ShadowWouldHaveDroppedTotal mirrors
// v8classifier.Classifier.ShadowWouldHaveDroppedTotal — bytes
// the v8 classifier WOULD have dropped under ModeEnforce but
// did NOT drop in ModeShadow. Published as
// helianthus_v8_shadow_would_have_dropped_total.
//
// HelianthusV8ShadowWouldHaveDroppedGrowing alert fires on
// rate > 0 in shadow mode — operators must assess enforce-
// mode safety before rolling out. ModeOff and ModeEnforce
// both report 0 here by design (see v8classifier.go:805).
V8ShadowWouldHaveDroppedTotal uint64
}
V8RolloutSnapshot is the per-scrape view of the frame-atomic-visibility v8 rollout counters. Three of the four payload_aa_* counters live on helianthus-ebusgo's *protocol.Bus (entered/recovered/exhausted), the Round9AbsorbEntered counter also lives there, and the shadow-mode would-have-dropped counter lives on the gateway's instance-local *v8classifier.Classifier. Snapshotting them into a single struct keeps bus_observability_store decoupled from both packages.
Field naming matches the Prometheus surface 1:1 (snake-case lowering of the Go field name with a leading "helianthus_" prefix) — see helianthus-docs-ebus/deployment/prometheus-alerts.md for the operator alerts that consume these counters.
type WatchActivationSet ¶
type WatchActivationSet struct {
// contains filtered or unexported fields
}
func NewWatchActivationSet ¶
func NewWatchActivationSet(catalog *WatchCatalog) *WatchActivationSet
func (*WatchActivationSet) Activate ¶
func (set *WatchActivationSet) Activate(source WatchActivationSource, keys ...WatchKey) error
Activate validates the full batch before mutating the immutable catalog-backed activation set.
func (*WatchActivationSet) ActiveSources ¶
func (set *WatchActivationSet) ActiveSources(key WatchKey) []WatchActivationSource
func (*WatchActivationSet) Deactivate ¶
func (set *WatchActivationSet) Deactivate(source WatchActivationSource, keys ...WatchKey)
func (*WatchActivationSet) Observe ¶
func (set *WatchActivationSet) Observe(key WatchKey) WatchObservation
func (*WatchActivationSet) Summary ¶
func (set *WatchActivationSet) Summary() WatchObservationSummary
type WatchActivationSource ¶
type WatchActivationSource string
const ( WatchActivationSourcePoller WatchActivationSource = "poller" WatchActivationSourceWriteConfirm WatchActivationSource = "write_confirm" WatchActivationSourceTooling WatchActivationSource = "tooling" WatchActivationSourceOperator WatchActivationSource = "operator" )
type WatchCatalog ¶
type WatchCatalog struct {
// contains filtered or unexported fields
}
func NewWatchCatalog ¶
func NewWatchCatalog(descriptors []WatchDescriptor) (*WatchCatalog, error)
func (*WatchCatalog) Descriptor ¶
func (catalog *WatchCatalog) Descriptor(key WatchKey) (WatchDescriptor, bool)
func (*WatchCatalog) DescriptorByCanonical ¶
func (catalog *WatchCatalog) DescriptorByCanonical(key string) (WatchDescriptor, bool)
func (*WatchCatalog) Descriptors ¶
func (catalog *WatchCatalog) Descriptors() []WatchDescriptor
func (*WatchCatalog) Len ¶
func (catalog *WatchCatalog) Len() int
type WatchCorrelationPolicy ¶
type WatchCorrelationPolicy string
const ( WatchCorrelationPolicyRequestResponse WatchCorrelationPolicy = "request_response" WatchCorrelationPolicyBroadcastSelector WatchCorrelationPolicy = "broadcast_selector" WatchCorrelationPolicyRecordInvalidate WatchCorrelationPolicy = "record_and_invalidate" WatchCorrelationPolicyRecordOnly WatchCorrelationPolicy = "record_only" WatchCorrelationPolicyInvalidateOnly WatchCorrelationPolicy = "invalidate_only" )
type WatchDescriptor ¶
type WatchDescriptor struct {
Key WatchKey
SemanticClass WatchSemanticClass
FreshnessProfile WatchFreshnessProfile
DecoderID string
CorrelationPolicy WatchCorrelationPolicy
DirectApplyPolicy WatchDirectApplyPolicy
FreshnessTTL *time.Duration
}
func (WatchDescriptor) CanonicalKey ¶
func (descriptor WatchDescriptor) CanonicalKey() string
func (WatchDescriptor) EffectiveFreshnessTTL ¶
func (descriptor WatchDescriptor) EffectiveFreshnessTTL() (time.Duration, error)
func (WatchDescriptor) Family ¶
func (descriptor WatchDescriptor) Family() WatchFamily
type WatchDirectApplyPolicy ¶
type WatchDirectApplyPolicy string
const ( WatchDirectApplyPolicyNever WatchDirectApplyPolicy = "never" WatchDirectApplyPolicyStateDefault WatchDirectApplyPolicy = "state_default" WatchDirectApplyPolicyConfigOptIn WatchDirectApplyPolicy = "config_opt_in" WatchDirectApplyPolicyEnergyMergeOnly WatchDirectApplyPolicy = "energy_merge_only" )
type WatchEfficiencyObserver ¶
type WatchEfficiencyObserver interface {
ObserveWatchRead(event WatchEfficiencyReadEvent)
ObserveWatchDirectApply(event WatchEfficiencyDirectApplyEvent)
}
type WatchEfficiencyReadEvent ¶
type WatchEfficiencyReadEvent struct {
Key WatchKey
Descriptor WatchDescriptor
HasDescriptor bool
MaxAge time.Duration
Stats SemanticReadExecutionStats
ObservedAt time.Time
}
type WatchFamily ¶
type WatchFamily string
const ( WatchFamilyB509 WatchFamily = "B509" WatchFamilyB516 WatchFamily = "B516" WatchFamilyB524 WatchFamily = "B524" WatchFamilyB555 WatchFamily = "B555" )
type WatchFreshnessProfile ¶
type WatchFreshnessProfile string
const ( WatchFreshnessProfileStateFast WatchFreshnessProfile = "state_fast" WatchFreshnessProfileStateSlow WatchFreshnessProfile = "state_slow" WatchFreshnessProfileConfig WatchFreshnessProfile = "config" WatchFreshnessProfileDiscovery WatchFreshnessProfile = "discovery" WatchFreshnessProfileDebug WatchFreshnessProfile = "debug" )
type WatchKey ¶
type WatchKey interface {
fmt.Stringer
Canonical() string
Family() WatchFamily
}
func PassiveWatchKeyFromEvent ¶
func PassiveWatchKeyFromEvent(event PassiveClassifiedEvent) (WatchKey, bool)
type WatchObservation ¶
type WatchObservation struct {
State WatchObservationState
Descriptor WatchDescriptor
HasDescriptor bool
Sources []WatchActivationSource
}
type WatchObservationState ¶
type WatchObservationState string
const ( WatchObservationStateActive WatchObservationState = "active" WatchObservationStateInactive WatchObservationState = "inactive" WatchObservationStateCatalogMiss WatchObservationState = "catalog_miss" )
type WatchObservationSummary ¶
type WatchObserver ¶
type WatchObserver interface {
Observe(key WatchKey) WatchObservation
}
type WatchSemanticClass ¶
type WatchSemanticClass string
const ( WatchSemanticClassState WatchSemanticClass = "state" WatchSemanticClassConfig WatchSemanticClass = "config" WatchSemanticClassDiscovery WatchSemanticClass = "discovery" WatchSemanticClassDebug WatchSemanticClass = "debug" )
type WatchSummary ¶
type WatchSummary struct {
LastUpdatedAt *time.Time `json:"last_updated_at,omitempty"`
Inventory WatchSummaryInventory `json:"inventory"`
ActivationCounts WatchSummaryActivationCounts `json:"activation_counts"`
FreshnessClasses []WatchSummaryClassCount `json:"freshness_classes"`
DirectApplyEligibilityClasses []WatchSummaryClassCount `json:"direct_apply_eligibility_classes"`
Degraded WatchSummaryDegraded `json:"degraded"`
}
type WatchSummaryActivationCounts ¶
type WatchSummaryActivationCounts struct {
CatalogDescriptors int `json:"catalog_descriptors"`
ActiveKeys int `json:"active_keys"`
SourceClasses []WatchSummaryClassCount `json:"source_classes"`
}
type WatchSummaryClassCount ¶
type WatchSummaryDegraded ¶
type WatchSummaryInventory ¶
type WatchSummaryInventory struct {
TotalEntries int `json:"total_entries"`
PinnedEntries int `json:"pinned_entries"`
EvictableEntries int `json:"evictable_entries"`
StaticPinnedFootprint int `json:"static_pinned_footprint"`
WriteConfirmPinnedActive int `json:"write_confirm_pinned_active"`
StateClasses []WatchSummaryClassCount `json:"state_classes"`
PinClasses []WatchSummaryClassCount `json:"pin_classes"`
}
Source Files
¶
- active_passive_deduplicator.go
- address_table.go
- address_table_inserter.go
- admission_artifact.go
- admission_envelope_stability.go
- admission_escalation.go
- admission_metrics.go
- admission_override_conflict.go
- b524_coherency.go
- broadcast_listener.go
- bus_observability_api.go
- bus_observability_store.go
- config.go
- device_info.go
- ebusgateway.go
- evidence_buffer.go
- full_range_guard.go
- gateway.go
- joinbus.go
- observe_first_family_policy.go
- observe_first_flags.go
- passive_bus_tap.go
- passive_discovery_promoter.go
- passive_reconstructor_f19c_helpers.go
- passive_transaction_reconstructor.go
- register_dump.go
- register_dump_upload.go
- semantic_read_scheduler.go
- shadow_cache.go
- smoke.go
- smoke_config.go
- target_address.go
- unknown_device_dump.go
- watch_catalog.go
- watch_efficiency.go
- watch_summary.go
- wire_log.go
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
ebusdscan
command
|
|
|
gateway
command
|
|
|
matrix-runner
command
|
|
|
smoke
command
|
|
|
internal
|
|
|
adaptermux
Package adaptermux embeds adapter multiplexing logic directly in the gateway, allowing a single ENH/ENS connection to the adapter hardware with demuxed active (owner) and passive (observer) paths.
|
Package adaptermux embeds adapter multiplexing logic directly in the gateway, allowing a single ENH/ENS connection to the adapter hardware with demuxed active (owner) and passive (observer) paths. |
|
adaptermux/v8classifier
Package v8classifier implements the frame-atomic-visibility v8 classifier surface for helianthus-ebusgateway's adapter multiplexer.
|
Package v8classifier implements the frame-atomic-visibility v8 classifier surface for helianthus-ebusgateway's adapter multiplexer. |
|
execution_policy
Package execution_policy is the single shared execution-policy module for the ebus_standard L7 surface.
|
Package execution_policy is the single shared execution-policy module for the ebus_standard L7 surface. |
|
nm_runtime
Package nm_runtime is the catalog-driven Network-Management emit path.
|
Package nm_runtime is the catalog-driven Network-Management emit path. |
|
rpc_source
Package rpc_source contains shared validation for caller-supplied RPC source bytes.
|
Package rpc_source contains shared validation for caller-supplied RPC source bytes. |
|
runtimestate
Package runtimestate is the gateway-owned loader/persister for /data/runtime_state.json.
|
Package runtimestate is the gateway-owned loader/persister for /data/runtime_state.json. |
|
vaillant/b503session
Package b503session implements the live-monitor session FSM for the Vaillant B503 extended-register protocol as specified in helianthus-docs-ebus/protocols/vaillant/ebus-vaillant-B503.md sections 6, 7.1.1, and 7.4.
|
Package b503session implements the live-monitor session FSM for the Vaillant B503 extended-register protocol as specified in helianthus-docs-ebus/protocols/vaillant/ebus-vaillant-B503.md sections 6, 7.1.1, and 7.4. |
|
ebus_standard
Package ebus_standard implements the gateway MCP surfaces for the ebus_standard L7 namespace (M4_GATEWAY_MCP).
|
Package ebus_standard implements the gateway MCP surfaces for the ebus_standard L7 namespace (M4_GATEWAY_MCP). |