Capture correctness: one collector, away spans, document boundaries, honest health - #102
Merged
Merged
Conversation
…honest health - One collector per data folder via an OS advisory lock; the supervisor backs off instead of respawning a blocked worker every second. - Away spans after 5 minutes without input (OS input clock) or when the screen locks; duration_seconds keeps its wall-clock meaning; away spans never sync to a Gateway. - Debounced, noise-normalized document boundaries within the same app (new default; "application" follows it, "application_only" keeps the old behavior); title privacy modes respected. - capture_health only for real degradation and permission changes; routine counters move to diagnostics. - macOS Accessibility/Input Monitoring preflight: blocked sensors are stated in startup output, heartbeat, capture health and the Recording pill. - Claude Code UserPromptSubmit/Stop as turn boundaries keyed by prompt_id; outdated OpenWorkGraph hook entries refreshed at launch when Observe is on. - Per-channel agent telemetry diagnostics (counts and reason codes only). - Lease-gated, bounded agent spool: hooks spool only while OpenWorkGraph is running and recording; flushed through normal ingest rules.
…nt; make pause-window test independent of Windows clock resolution
…, not a turn or subagent finishing
…ses SIGTERM before finally/atexit) and never re-issue it after stop
Owner
Author
|
Follow-up from end-to-end verification (isolated full stack on macOS: real launcher, collector supervisor, hook processes, config writes):
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release 1 of the capture audit: fixes where OpenWorkGraph's own evidence was misleading. It changes no schema, no field meaning and no sharing rule, and it adds no new organizational signal.
Why
On a real install (21,852 events, Sep 15–28):
capture_healthrows caused by routine checkpoints.What changes
One collector per data folder
flock/msvcrt.locking) on<data>/.collector.lock, held for the collector's lifetime. It is released on exit or crash, with no stale PID file.data/liveanddata/demoare separate.Away spans (not a new meaning for
duration_seconds)away_after_seconds(default 300, minimum 60) with no input, or when the screen locks. The rest becomesaway_span(app "Away").CGEventSourceSecondsSinceLastEventType/GetLastInputInfo). It needs no permission and never sees keys. The collector's own sensors are a fallback only when they can see input.away_spanis dropped inprepare_event_for_gatewayregardless of org policy, since sharing it would be presence monitoring. Analytics already count app time fromfocus_spanonly.Debounced same-app document boundaries
application_and_document. A materially different title must persist for 2 polls. The boundary is backdated to when the new title first appeared.none: no title information is used.hash: normalizes before comparing.config.jsonwas created from the example with"application", so that value now follows the default."application_only"is the explicit opt-out.capture_health = degradation
diagnostics.Truthful macOS permissions
AXIsProcessTrustedandIOHIDCheckAccesspreflight, which never prompt, rechecked every minute.permissionsand a truthfulkeyboard_sensor, capture health records missing permissions, and the Recording pill says "macOS … permission missing".Claude Code turn boundaries
UserPromptSubmit→run_startedandStop→run_finished/success, keyed byprompt_id(shared with Claude's tool hooks and OTel).SessionStart/SessionEndstill bound the session.prompt_id: the turn hook is ignored, never confused with the session.enterprise_runneronly when Claude Code Observe is on and OpenWorkGraph's hooks already exist. A backup is written, and user hooks and env are kept. It is deliberately not done at app startup, so tests never touch a real~/.claude.PreCompact: deferred. It needs a new agent operation, which older Gateways would reject on sync.Agent telemetry diagnostics
GET /v1/agent-telemetry/diagnostics(API/dashboard auth) plus a line in the Connections rows.Lease-gated agent spool
data/auth/agent_spool. A 4xx is never spooled.Tests
tests/test_capture_correctness_v098.py(16) drives the real collector loop with a scripted clock, window and OS idle clock.tests/test_agent_delivery_v098.py(12) covers the lease, flush, client, diagnostics, hook refresh and status.tests/js/capture_correctness.test.mjs(2).check_injected_dashboard_js.pypasses.Not in this PR (release 2)
osascript, Windows UWP, Linux/Wayland).run_id, so they are grouped into the parent turn rather than linked as children.