mixle.telemetry.core module

Event schema and local-first recorder for platform telemetry.

An Event is a typed, timestamped decision record containing the decision kind, the features used, the selected choice, and an optional outcome. A Telemetry recorder buffers events and can append them to a JSONL log for dashboards or learned policies.

kind is validated against EVENT_KINDS; the payload fields are not validated, filtered or redacted at all. See the package docstring (mixle.telemetry) for what that means for anything sensitive.

class Event(kind, features=<factory>, choice=None, outcome=<factory>, tags=<factory>, ts=0.0)[source]

Bases: object

One typed, timestamped decision record. Features/choice describe the decision; outcome scores it.

outcome is deliberately mutable after the fact – that is the documented “close the loop later” pattern Telemetry.record() describes. The event’s identity is not: kind and ts are re-validated on every assignment, not only at construction. Because a flush rewrites the whole log from the current field values, an event mutated into an invalid state would otherwise rewrite already-persisted history as something no reader can load back.

Parameters:
as_row()[source]

Return this event as a JSON-serializable row.

Return type:

dict[str, Any]

class Telemetry(path=None, *, flush_every=1)[source]

Bases: object

A local-first event recorder: buffer in memory, append to a JSONL log, read back for training.

record(kind, features=..., choice=..., outcome=..., tags=...) appends one Event. events(kind=...) yields the buffer (optionally filtered). training_rows(kind) yields the (features, choice, outcome) triples the learned-orchestration models consume.

Parameters:
  • path (str | None)

  • flush_every (int)

record(kind, *, features=None, choice=None, outcome=None, tags=None, when=None)[source]

Record one decision event; returns it (mutate .outcome later to close the loop).

The mutation updates this recorder’s in-memory buffer immediately and is captured by the next flush – an explicit flush() call, or the next automatic flush once flush_every more events have been recorded – because every flush rewrites the full buffered log rather than only appending whatever is new. Until that next flush, the JSONL file on disk (and any other reader with it open) still shows the pre-mutation value.

Parameters:
Return type:

Event

events(*, kind=None)[source]

Yield recorded events, optionally filtered by kind.

Parameters:

kind (str | None)

Return type:

Iterator[Event]

training_rows(kind)[source]

The (features, choice, outcome) triples for a decision kind.

Parameters:

kind (str)

Return type:

list[tuple[dict[str, Any], Any, dict[str, Any]]]

flush()[source]

Flush any buffered events to the configured JSONL log.

Return type:

None

get_default_recorder()[source]

The process-global recorder (a no-path in-memory buffer until one is configured).

Return type:

Telemetry

set_default_recorder(recorder)[source]

Install (or clear) the process-global recorder – e.g. point it at the user’s telemetry log.

Parameters:

recorder (Telemetry | None)

Return type:

None

record(kind, **kw)[source]

Record an event on the process-global recorder (see Telemetry.record()).

Parameters:
Return type:

Event