Repository navigation
Add a read-only status command for the event queue file - #88
Merged
Merged
Conversation
Each run's upload state, reason and undelivered events as JSON, read without changing the file; exit 8 without a file and 9 for one it cannot use (microcosm-emitter#87). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`microcosm-emitter status` prints each run's upload state, reason and undelivered events as JSON, reading `--event-queue-file` or the file the emitter itself uses in SQLite's read-only mode. It exits 8 without a file and 9 for one it cannot use, catching only database and operating-system errors (microcosm-emitter#87). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A run whose registration JSON is not an object is still printed, and a known revision without the telemetry tables gets the message that names SQLite's error code. The default-path test is named for what it checks: the default path for the environment status runs in (review round 1). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
status selects the five columns it prints, so it no longer decodes a run's registration JSON. Each Problem's value is its message, so none can lack one. The README, the fragment and the docstrings now say that pruning also deletes undelivered events, that the default path is the one for the environment status runs in, and that a WAL-mode file gets -wal and -shm files; the README no longer says Microcosm's runner already runs status (review round 1). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Fixes #87
Summary
This adds
microcosm-emitter status, a read-only command that prints each run in an emitter's event queue file. It brings back only the read-only status part of the closed #36. Microcosm's Modal runner is to run it in the container after a build (Microcosm task 1a · 5, not yet written). It will record in the stage receipt how many events each run left undelivered, without reading the file itself.--event-queue-file PATH, optional. Without it,statusreads the default path for the environment it runs in. That is the interface'sdefault_spool_path():$XDG_CACHE_HOME/microcosm/telemetry/events.sqlite3, or~/.cache/microcosm/telemetry/events.sqlite3whenXDG_CACHE_HOMEis unset or blank.statusruns with the same environment.{"runs": [{"run_id", "producer_id", "upload_state", "reason", "undelivered_events"}]}.reasonis the run'slocal_only_reasoncolumn, ornull.undelivered_eventscounts the run's events the file still holds. The emitter deletes an event once the collector acknowledges it, but its pruning also deletes undelivered events older than 7 days or beyond 100 MiB. So 0 means none are held, not that every event was delivered.mode=ro) through the newcore.database.create_read_only_engine. It is never opened through the class the emitter's own modules use, which would create a missing file, make the file and its directory private to this user, migrate it, and prune events older than 7 days.statusmakes no network connection, and doesn't deliver, prune, migrate, create, or change any file, directory or permission.-waland-shmfiles beside it when the directory is writable.Exit codes
Each failure prints one line on standard error naming the path, and nothing on standard output.
telemetry-token's codes 3 to 7 are unchanged; #36's renumbering into oneExitCodetable is left out.How errors are handled
telemetry/service/run_status.pycatches onlySQLAlchemyErrorandOSError, and turns them intoUnusableEventQueueFileErrorwith aProblem.cli.statuscatches only that error andMissingEventQueueFileError. There is no catch-all, so any other error is a defect and ends with Python's traceback.statusholds no credential, so a traceback can't print one.Problemmember's value is its line for standard error, so no problem can lack a message.sqlite_errorname(SQLITE_READONLY_ROLLBACK,SQLITE_NOTADB), so no module imports the driver (tests/test_boundaries.py).core.migrationsgains two helpers:recorded_revisions, which reads the version table;known_revisions, which lists the packaged event queue history.No new suppression
This PR adds no inline suppression, so
rules/baselines/noqa-comments.txtis unchanged at 140 entries (146 lines, including its 6-line header).cli.statusimportsmicrocosm_emitter.telemetry.service.run_statusinside the function, so thathost,versionandtelemetry-tokenstill load no database code.banned-module-level-importsinpyproject.toml, as Fix Ruff's typing-only import, annotation and in-function import findings (TC, ANN, PLC) #65 addedmicrocosm_emitter.host.__main__for the same kind of deferred import incli. Ruff then forbids importing it at module level (TID253), and its PLC0415 accepts the function-level import without a# noqa.Environment variables
There are no new variables. Without
--event-queue-file,statusreadsXDG_CACHE_HOME, andHOMEthroughPath.home(), from the process that runs it, through the interface's existingdefault_spool_path(). A relativeXDG_CACHE_HOMEresolves against that process's working directory.The emitter host reads neither variable: it opens the path the build sends it. Microcosm's runner (1a · 5) will run
statuswith the build's environment. Nothing else is read: no credential, collector token or collector origin.Tests
tests/telemetry/test_status_command.pyis new. Each test was run locally on macOS with Python 3.14.6, selected by node ID from an explicit list. Node IDs below are undertests/telemetry/test_status_command.py::.test_status_prints_each_run_and_changes_nothingassert 2 == 0test_status_reads_the_default_path_for_its_environment(3 cases; renamed in round 1)XDG_CACHE_HOMEset, blank, or unset withHOMEassert 2 == 0test_status_exits_8_without_an_event_queue_file(2 cases)assert 2 == 8test_status_exits_9_for_a_file_it_cannot_use(8 cases)cannot be read (SQLITE_ERROR). Each: exit 9, the matching message with the path, and the directory unchangedassert 2 == 9. The round-1 case passed at 9debc93 already; with the fallback message's wording changed temporarily, it failed, and the change was revertedtest_status_prints_a_run_whose_registration_is_not_an_object(round 1)assert 1 == 0(aValueErrortraceback from decoding the registration)test_status_help_names_the_event_queue_filestatus --helpnames--event-queue-fileand the event queue fileassert 2 == 0ruff format --checkandruff checkpassed on the changed Python files only.Review round 1
The review found no bugs. These changes come from its code-quality points:
Problem;status;create_read_only_engine's docstring;Not verified
status.Release
The fragment is
added, so merging this releases 0.13.0 of both distributions to PyPI throughpush.yaml.🤖 Generated with Claude Code