event

package
v0.0.0-...-65b0da1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 20, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package event implements the event model of §5.1, equation (3).

Equation (3) defines an event as a partial function

e : F ⇀ ⋃_f D_f,  with e(f) ∈ D_f where defined

so an event is exactly a set of (field path, value) pairs together with the designated entity ε(e) and timestamp. The set of fields an event carries is dom(e), which §11 identifies with the mask M of the conformal missing-data literature.

Determinism (R4)

This package is where Go's map-iteration randomisation would otherwise leak into scores. Two structural choices prevent it rather than relying on care at each call site:

  1. The value map is unexported and is never returned. The only way to enumerate an event's fields is Event.All, which yields them in sorted field-path order. Iterating in nondeterministic order is therefore not expressible.
  2. Float accumulation over fields (equations (5), (18), and the (9) grid) is consequently always performed in the same order, so sums are bit-identical across runs. E8 asserts this.

Timestamps are event time, never wall-clock time. No function in this package, or in any package reachable from the scoring path, may call time.Now; decay in §6.2 and §7.2 is driven by the event timestamp and the state row's own last-observed timestamp. An architecture test enforces the prohibition.

Index

Constants

View Source
const (
	Microsecond Timestamp = 1
	Millisecond           = 1000 * Microsecond
	Second                = 1000 * Millisecond
	Minute                = 60 * Second
	Hour                  = 60 * Minute
	Day                   = 24 * Hour
)

Microseconds, and the derived units used by the decay factors of §6.2 and §7.2.

Variables

This section is empty.

Functions

This section is empty.

Types

type EntityID

type EntityID string

EntityID identifies the entity ε(e) that an event concerns.

Which field yields the entity is configuration, not code (§5.1: "A designated field yields the entity ε(e)"). For enterprise authentication telemetry the entity is the individual user account, so that a verdict answers whether this person acted out of character against their own persisted history. A user who habitually departs from the population norm is not thereby anomalous; §7.6 makes that argument for timing specifically, and §6 for categorical attributes. Population-scope structure lives in §8 instead, where role and peer similarity are discovered as block structure.

type Event

type Event struct {
	// contains filtered or unexported fields
}

Event is an immutable realisation of equation (3).

Construct one with New. The zero Event carries no fields and is not scoreable.

func New

func New(source SourceID, entity EntityID, occurredAt Timestamp, fields map[FieldPath]Value, offset int64) Event

New builds an event from its fields.

The supplied map is copied, so later mutation by the caller cannot alter the event. Field paths are sorted once here, fixing the canonical order used by every subsequent traversal and every float accumulation.

func (*Event) All

func (e *Event) All() iter.Seq2[FieldPath, Value]

All yields the event's fields in sorted field-path order.

This is the only enumeration this package offers, which is what makes nondeterministic traversal inexpressible rather than merely discouraged.

func (*Event) Entity

func (e *Event) Entity() EntityID

Entity returns ε(e).

func (*Event) Get

func (e *Event) Get(f FieldPath) (Value, bool)

Get returns the value of f and whether f ∈ dom(e).

func (*Event) Has

func (e *Event) Has(f FieldPath) bool

Has reports whether f ∈ dom(e).

func (*Event) ID

func (e *Event) ID() ID

ID returns the content-derived identifier.

func (*Event) Len

func (e *Event) Len() int

Len returns |dom(e)|, the number of fields the event carries.

func (*Event) Mask

func (e *Event) Mask() []FieldPath

Mask returns dom(e) in sorted order: the set of fields the event carries, which §11 identifies with the mask M. The returned slice is a copy, so a caller cannot disturb the canonical order.

func (*Event) OccurredAt

func (e *Event) OccurredAt() Timestamp

OccurredAt returns the event timestamp, which is the only clock the scoring path is permitted to consult.

func (*Event) Offset

func (e *Event) Offset() int64

Offset returns the reader's corpus position. Provenance and replay only; it is not part of the content digest and must not reach a score.

func (*Event) Source

func (e *Event) Source() SourceID

Source returns the telemetry source that produced the event.

func (*Event) With

func (e *Event) With(extra map[FieldPath]Value) Event

With returns a copy of the event carrying additional fields.

It exists for derived fields: structure inferred inside a value, such as the /24 of an address or the parent domain of a hostname, is registered as a field beside the original so that every detector scores it unchanged and none of them learns that derivation happened.

The copy carries its OWN identifier, because the identifier is a digest of content and the added fields are content. Two events differing in their fields must not claim to be the same event; a caller wanting the original's identity should keep the original.

An added path that already exists is ignored rather than overwriting: derivation may only add to an event, never restate what a source said. Returning a copy keeps the receiver immutable, so an event already handed to a detector cannot change underneath it (R4).

type FieldPath

type FieldPath string

FieldPath identifies a field. §5.1: F is a countable set of field paths whose members are not known at design time. Paths are opaque to every detector; a detector that named a field would violate R2.

type ID

type ID [32]byte

ID is a content-derived event identifier.

It is a digest of the event's semantic content and nothing else: not of arrival order, not of the batch the event appeared in, and not of wall-clock time. Two byte-identical events therefore carry the same ID however they are batched, which is what lets E8 assert byte-identical scores across differing batch compositions. Corpora containing exact duplicate rows (LANL's redteam.txt has 34) legitimately produce repeated IDs.

func (ID) String

func (id ID) String() string

String returns the hex encoding of the identifier.

type SourceID

type SourceID string

SourceID identifies the telemetry source. Field registries, calibration sets (§10.1) and co-occurrence graphs (§8.2) are all scoped per source, because neither score distributions nor block structure transfer across sources.

type Timestamp

type Timestamp int64

Timestamp is event time in microseconds, on the corpus's own epoch.

It is deliberately a distinct type from any wall-clock representation so that a stray time.Now cannot be assigned to it. LANL's epoch starts at 1 with one-second resolution; the reader multiplies into microseconds so that corpora of finer resolution need no schema change.

type Value

type Value struct {
	// contains filtered or unexported fields
}

Value is an immutable field value.

Corpus readers emit values as text; the field registry of §5.1 infers the kind (categorical, boolean, discrete, continuous, identifier, excluded, unknown). This ordering is what discharges R2: nothing in the ingest path needs advance knowledge of a field's type, cardinality, or value set.

The text is never converted to the inferred type. A kind selects how a value is *scored*, not what it is stored as, and the registry's package documentation records why: converting would make the reading depend on the batch (R1), would merge values a source distinguishes, and would commit before the evidence is in.

A value may be present but not interpretable. LANL encodes this as a literal "?" (see DATA.md). §5.3 distinguishes that case from absence: an absent field is not in dom(e) at all, whereas a present-but-uninterpretable field is in dom(e) and yields status abstained_unusable. Collapsing the two would lose the distinction the four-valued status exists to preserve.

func NewValue

func NewValue(text string) Value

NewValue returns a usable text value.

func UnusableValue

func UnusableValue(text string) Value

UnusableValue returns a value that is present in dom(e) but not scoreable. The text is retained so that evidence can report what was actually observed (R5).

func (Value) IsEmpty

func (v Value) IsEmpty() bool

IsEmpty reports whether the value carries no text at all.

func (Value) IsUsable

func (v Value) IsUsable() bool

IsUsable reports whether the value can be scored. A false result must produce an abstained_unusable verdict, never a neutral score (R3).

func (Value) Text

func (v Value) Text() string

Text returns the value's canonical text representation. It is the identity used for equality throughout the framework, so that no detector needs to know a field's type in order to compare values.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL