Repository navigation
feat(usage): opt-in local observability — usage events, health surfacing, effectiveness measurement - #482
Conversation
…surfacing, effectiveness)
…by, index age Line cap 512B→1KiB: measured real events (cwd+facts+query) exceed 512; O_APPEND atomicity on regular files does not depend on PIPE_BUF.
…e counters, heartbeat, queries_served
… absence, feedback, health
…last_error (ungated)
…deleted eval index
Code review responseFour parallel reviewers (usage package core / CLI taps+verbs / watch daemon / config+eval+docs) reviewed Critical (fixed)
Important (all fixed)
Minors fixed: Acknowledged, not changed (noted for the record): Full suite after fixes: 1 failure — |
What
Opt-in, strictly-local observability for jrag so the owner can answer three questions that were previously unanswerable: how is jrag being used (by autonomous agents), was it useful, and were there problems.
One switch gates the whole layer —
usage.enabled(default off; envJAVA_CODEBASE_RAG_USAGE_ENABLEDor YAMLusage.enabled). Disabled, jrag is byte-identical to today: no files, no extra state, noevent_idon envelopes.docs/superpowers/specs/active/2026-09-13-local-observability-design.md· Plan:docs/superpowers/plans/active/2026-09-13-local-observability.mdThe pieces
usage/package (paths,events,writer,summarize): versioned surface-neutral event schema (v1), day-sharded capped JSONL in a durable per-project state dir (never the index dir —jrag erasecan't wipe history), single-os.writeO_APPENDappends (synchronous: bothmain()pathsos._exit()past buffered flushes), 30-day retention, 5 MiB/day cap with drop accounting, swallow-everything guard — telemetry never changes stdout/stderr/exit codes.main()funnel (per-invocation event: verb, capped query, duration, rc, envelope facts,index_age_s,served_byhot/cold, ppid+cwd for sessions; error + usage-error paths record too), operator-CLI mirror, watch-daemon_record(reindex lifecycle with stderr tails,consecutive_errors/ per-phase last-success / heartbeat / livequeries_served).jrag usage [--days N]— summary rollup: per-verb calls/outcome mix/latency split hot-vs-cold, miss rate binned by index age, sessions, struggle signals (repeats, reformulations, abandoned), absence-term mining, watch health, feedback labels, storage status. Zero-states when disabled/empty (rc 0,prime-style never-nag).jrag feedback <event_id> --good|--bad [--note]— sparse owner labels anchored to the 10-charevent_idenvelopes carry while telemetry is on; joined injrag usagewith orphan reporting.jrag statusdaemon-health node + warnings (dead / failing ≥3 / heartbeat >120s),jrag prime"running, reindex failing since X". Ungated:jrag watch --statusrenders the already-recordedlast_error(previously persisted but never shown anywhere).eval --reuse-index: measure the live index without a rebuild (cron-friendly nightly recall/MRR); snapshotsgraph.meta()intoreport.jsonso index health and recall are jointly analyzable.usage/to stdlib non-network roots; "What jrag records locally" table indocs/CONFIGURATION.md§6; identifiers and outcomes only — never file contents.Design decisions worth reviewing
llmCLI's unbounded SQLite log is the cautionary tale).watch --statuslast_errorand eval mode stay ungated (display of existing state / explicit operator action).O_APPENDatomicity on regular files doesn't depend on PIPE_BUF.Tests
tests/usage/(paths, schema, writer caps/retention/swallow, pure aggregation, taps incl. error paths, verbs, gating, health renders, import lint) +tests/eval/test_reuse_index.py.test_detach_stale_socket_cleaned_before_bind, an intermittent load-timing flake of a real-subprocess readiness wait: passes standalone 4/4 and in 3/3 watch-suite runs; the telemetry-off daemon path is unchanged code.INDEX_DIR/SOURCE_ROOTper-test (tests/usage/conftest.py) — the full-suite order otherwise inherits anos.environwriterun_evalnever restores.Notes
origin/master(ced115f, fix(cli): clean usage-error envelope; flow/outline accept FQN roots (#473 #474 #475) #481) — the usage-error envelope refactor and this PR's tap touch adjacent code injrag.py::main; rebased cleanly, overlap zone re-verified.masterhas diverged fromorigin/masterby one local commit (091cfbd, the.agents/worktrees/gitignore chore) vs origin'sced115f— left unpushed for the owner to reconcile.