Report a startup event to trace, off the main thread and with an opt-out - #26
Merged
Merged
Conversation
trace-client-python's single module is vendored as trace_client.py (unmodified apart from the vendoring note) together with its test. A new usage_reporting.py reads a usage_reporting block from settings.json in the working directory - enabled (default true), endpoint and key - writing the defaults and printing a one-line notice the first time the block is absent, then builds the client and reports one startup event tagged with the version from version.txt. main() calls it as its first line; the client is closed at interpreter exit. Nothing about the machine, the user, the grid size or the environments is sent. A missing or corrupt settings.json can never raise: an unreadable file yields a disabled client and a logged line. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WYoD9SsaRz8PjakTSHhmn6
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.
Summary
Usage reporting to trace is wired into Patchwork, the Preponderous-Software rollout counterpart of the Dans-Plugins one documented in
docs/CONSUMERS.mdthere.trace_client.pyis vendored from trace-client-python as a single standard-library-only module, unmodified apart from a vendoring note in its docstring; its test is vendored astests/test_trace_client.pywith one import adjusted.usage_reporting.pyis added. It reads theusage_reportingblock fromsettings.jsonin the working directory (the same placeenvironments.jsonis kept;*.jsonis already git-ignored), builds the client and reports onestartupevent tagged with the version read fromversion.txt. The client is closed at interpreter exit viaatexit.main()callsstartUsageReporting(log=log)as its first line — a two-line change tomain.py, kept deliberately small so that it composes with the open restructure in Make main.py importable and cap its render loop #23.The guarantees of the client are kept:
report()returns immediately (the HTTP call happens on one daemon thread), never raises, and queues at most 256 reports before dropping. A settings file that is missing, unwritable or corrupt cannot raise either — an unreadablesettings.jsonyields a disabled client and one logged line, and is not overwritten.What is sent, and what is not
One
startupevent per launch:{"application":"patchwork","name":"startup","tags":{"version":"0.2.0-SNAPSHOT-8-8-2026"}}. No username, hostname, IP, path, grid size, environment id or anything else about the machine or the person is included.Opt-out
Reporting is on by default. The first launch after this change prints exactly one line through the program's existing
log()channel —— and writes the block
{"usage_reporting": {"enabled": true, "endpoint": "https://trace.danielstephenson.dev", "key": "..."}}tosettings.json, so the notice is not shown again. Settingenabledtofalsedisables reporting entirely; keys already present in an existingsettings.jsonare preserved.Test plan
python3 -m unittest discover -s tests(Python 3.8.10, pygame 2.1.2 — the project's documented test command; the repository has no CI workflow): 9 tests OK before → 30 tests OK after (9RenderWindow, 11 vendored client, 10 newusage_reportingtests covering first-run write + notice, no notice on the second run, preservation of other settings, opt-out, corrupt-file handling, default fallbacks, the version source, and the startup body arriving at a loopback stub).python3 -c "import trace_client, usage_reporting"from the repository root succeeds; there is no packaging manifest to update (the project is run from a checkout).grep -c→ 1), never retyped.main.pywas run headless (SDL_VIDEODRIVER=dummy, Viron services stubbed,python main.py 5 --exit-after-create) with the endpoint pointed at a 10-line loopbackhttp.serverhandler. Run 1 (nosettings.json): the notice was printed once, the block was written, and the stub receivedPOST /api/metricswithAuthorization: Bearer <key>and body{"application":"patchwork","name":"startup","tags":{"version":"0.2.0-SNAPSHOT-8-8-2026"}}. Run 2 (block present): no notice, the same body arrived. Run 3 ("enabled": false): nothing arrived.🤖 Generated with Claude Code
https://claude.ai/code/session_01WYoD9SsaRz8PjakTSHhmn6
drafted by Claude on behalf of Daniel Stephenson