Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
4762d8a
docs: prepare telemetry for upload
gmemuriuki Sep 2, 2026
e0c24fc
Move telemetry into its own module directory
gmemuriuki Sep 2, 2026
d6af4d6
Add telemetry row identifiers
gmemuriuki Sep 2, 2026
1de6354
Define telemetry dates and versions
gmemuriuki Sep 2, 2026
19dc861
Define the storage limit telemetry row
gmemuriuki Sep 2, 2026
0e3f15c
Distinguish unknown telemetry schemas
gmemuriuki Sep 3, 2026
ea709f2
Add typed telemetry identifiers
gmemuriuki Sep 9, 2026
dd0acae
Define the telemetry identifier wire format
gmemuriuki Sep 10, 2026
fa8513c
Derive telemetry identifiers from framed inputs
gmemuriuki Sep 10, 2026
b78a97d
Generate telemetry identity keys securely
gmemuriuki Sep 10, 2026
7d8fd74
Define private telemetry identity state
gmemuriuki Sep 10, 2026
e84dd1f
Add telemetry identity state construction
gmemuriuki Sep 10, 2026
40f02ed
Define telemetry return cohorts
gmemuriuki Sep 10, 2026
a988390
Advance telemetry identity windows with session state
gmemuriuki Sep 10, 2026
5e3c9e3
Add telemetry identifier reset
gmemuriuki Sep 10, 2026
fbee999
Move telemetry state into a module directory
gmemuriuki Sep 10, 2026
e4260bc
Separate telemetry state lifecycle
gmemuriuki Sep 10, 2026
cfeba87
Move telemetry schema into a module directory
gmemuriuki Sep 10, 2026
b46a62e
Define agent telemetry values
gmemuriuki Sep 10, 2026
9db395d
Add session start telemetry rows
gmemuriuki Sep 10, 2026
8e1c821
Define configuration telemetry agents
gmemuriuki Sep 10, 2026
79cc0b2
Define agent configuration rows
gmemuriuki Sep 10, 2026
6bc19c1
Read agent configuration rows
gmemuriuki Sep 10, 2026
d577413
Keep agent telemetry names aligned
gmemuriuki Sep 11, 2026
27e981e
Define resolution telemetry vocabulary
gmemuriuki Sep 11, 2026
32890dd
Validate resolution summary telemetry
gmemuriuki Sep 11, 2026
18dc2db
Read resolution summaries through the classifier
gmemuriuki Sep 11, 2026
24aef51
Define package resolution vocabulary
gmemuriuki Sep 11, 2026
7b84afb
pacify merciless fmt
gmemuriuki Sep 11, 2026
f21e90f
Validate session start dates during decoding
gmemuriuki Sep 12, 2026
3e4c9f0
Define validated public package coordinates
gmemuriuki Sep 11, 2026
8460afe
Derive package identities from validated coordinates
gmemuriuki Sep 11, 2026
ff51a6a
Define package resolution telemetry rows
gmemuriuki Sep 11, 2026
a047ac0
Read package resolution telemetry rows
gmemuriuki Sep 11, 2026
6788792
Define tagged identity dimensions
gmemuriuki Sep 11, 2026
67f138c
Define public extension telemetry vocabulary
gmemuriuki Sep 11, 2026
682e92d
Generate validated telemetry name types
gmemuriuki Sep 11, 2026
e418e1a
Bind telemetry subjects to their identity anchors
gmemuriuki Sep 11, 2026
1e0e5fe
Define public extension coordinates
gmemuriuki Sep 11, 2026
3e5549b
Define extension resolution path nodes
gmemuriuki Sep 11, 2026
328069d
Validate extension resolution paths
gmemuriuki Sep 11, 2026
731ff16
Derive stable extension subjects from resolution paths
gmemuriuki Sep 11, 2026
4345b99
Add extension resolution row construction
gmemuriuki Sep 12, 2026
00724aa
Support extension resolution rows in the schema reader
gmemuriuki Sep 12, 2026
4371e4a
Derive agent subjects during row construction
gmemuriuki Sep 12, 2026
e093274
Define session identity derivation inputs
gmemuriuki Sep 12, 2026
546b838
Bind session transitions to current identity state
gmemuriuki Sep 12, 2026
86eee8b
Derive session identity from agent input
gmemuriuki Sep 12, 2026
644f656
Bind session rows to one completion timestamp
gmemuriuki Sep 13, 2026
925d97a
Define eligible command coordinates
gmemuriuki Sep 13, 2026
3fdbbdc
Test session timing at UTC midnight
gmemuriuki Sep 13, 2026
933992d
Derive command subjects from typed coordinates
gmemuriuki Sep 13, 2026
8d03fb0
Rotate identifiers for every recording operation
gmemuriuki Sep 13, 2026
6a4f83a
Add command telemetry event schema
gmemuriuki Sep 13, 2026
5f19dd2
Bind agent configuration to recording state
gmemuriuki Sep 13, 2026
4e1d700
Bind telemetry rows to recording state
gmemuriuki Sep 13, 2026
d7d8030
Refactor strict telemetry row deserialization
gmemuriuki Sep 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ dialoguer = "0.12.0"
toml_edit = "0.25.11"
url = "2.5.8"
symposium-install = { version = "0.1.0", path = "symposium-install", features = ["clap"] }
uuid = { version = "1.26.0", features = ["v4", "serde"] }
hmac = "0.12.1"
getrandom = "0.4.2"


[dev-dependencies]
Expand Down
4 changes: 3 additions & 1 deletion md/design/module-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,12 @@ Builtin dispatch currently only acts on `SessionStart`, where `handle_session_st

Manages `state.toml` in the config directory. Deserializes through `RawState` and validates into the runtime `State`. Tracks the semver of the binary that last touched the directory (for future migration hooks) and the timestamp of the last update check (to throttle crates.io queries to once per 24 hours). `ensure_current()` is called on startup to silently stamp the current version. `should_check_for_update()` / `record_update_check()` gate the auto-update flow.

### `telemetry.rs` — opt-in usage telemetry
### `telemetry/` — opt-in usage telemetry

Implements the local, opt-in [telemetry](./telemetry.md) event log under `<config-dir>/telemetry/`, one JSONL file per UTC day. Off by default; gated by `[telemetry] enabled`. A `TelemetryEvent` is an `at` timestamp plus a kind-tagged `EventKind` (`session_start` / `user_prompt` / `tool_use`), serialized one per line. `record` / `record_kind` append an event; `roll_off` deletes files older than `RETENTION_DAYS` (30); `read_events` / `recent_events` read them back; `usage` + `status_text` back `telemetry status`; `recent_events` backs `telemetry show`. Events are anonymous by construction — no prompt text, command lines, or file paths. Every write path is best-effort — failures are logged and swallowed so a hook is never broken. The recording entry points are not yet called from the hook pipeline, so no events are produced today even when telemetry is enabled.

The replacement recording contract is being built behind private `schema`, `identity`, and `state` submodules before it is connected to production callers. Within `schema`, `mod.rs` owns shared row primitives and version dispatch, `macros.rs` owns strict versioned-row boilerplate while each row module keeps its validation rules, `name.rs` owns validation shared by public name types, `agent.rs` owns agent vocabulary and agent-originated rows, `command.rs` owns eligible built-in and public plugin-command coordinates and exhaustively maps parsed CLI commands into the recorded built-in set, `extension.rs` owns validated public extension coordinates and vocabulary shared across event kinds, and `resolution.rs` owns resolution summaries and shared resolution vocabulary. Package-resolution vocabulary and validated public coordinates live in `resolution/package.rs`; `resolution/extension.rs` owns the strict recursive node vocabulary, the validated path wrapper that enforces whole-path depth, leaf-count, and encoded-size limits, and the versioned row that derives `extension_subject` from its target and path. Timestamped rows validate during deserialization that `day` is the UTC calendar day containing `at`; the later archive reader separately validates that the row belongs to its daily file. Private state binds its key and identifier-window or return-cohort anchor into distinct identity scopes. Each identifier domain accepts only its contract-selected scope. Row constructors take a bound recording context, derive identifiers from their own source fields, and take their day from the context: package resolution derives `package_subject` from its coordinate, agent configuration derives `agent_subject` from its agent, command derives `command_subject` from its coordinate, and a full resolution reuses one context for its summary, package, and extension rows. Session start extends that context with a return-cohort scope and derives its timestamp, both subjects, and `cohort_day` from one bound session transition. Within `state`, `mod.rs` owns the versioned private-state file shape, while `state/lifecycle.rs` owns the identifier-window transition for every recording plus return-cohort and identifier-reset transitions. A completed recording transition is a single-use value; a session transition extends it with the return-cohort selection. Binding either transition against unchanged anchors exposes only the identity scopes valid for that operation. The persistence layer will require a successful-write token for that binding so the contract's persist-before-derive order is structural rather than only documented. Their tests remain beside the responsibility they exercise.

### `report.rs` — structured report layer

Provides user-facing output for all commands via a custom tracing layer. Commands emit `tracing::info!` or `tracing::debug!` events with a `report = %ReportEvent::Variant { ... }` field; the `ReportLayer` intercepts these and renders them based on mode:
Expand Down
Loading
Loading