Conversation
Five robustness gaps where one malformed value in the user's own client logs or ledger could abort a whole read/import (or misattribute evidence) instead of skipping the affected row. Each keeps byte-identical behavior for normal inputs and adds a regression test. - rate_limits: skip a plan-usage sample whose `org` is unhashable (list/dict) rather than aborting every org's snapshot. (#222) - client_usage: guard `_timestamp_seconds`/`_optional_float` against non-finite (NaN/Infinity) values so one bad log line no longer aborts the whole usage refresh, matching the existing cursor-usage guard. (#223) - api: key mechanical-check session linking by (client, session id) so a passing hook check is not credited across clients in a merged Task and a step is not falsely marked independently checked. (#224) - task_outcome/receipt: key left-behind session identity by (client, session id) so two clients reusing one session-id string no longer suppress the inactive / mostly-done downgrade. (#225) - event_log: coerce `created_at` fail-soft (catch OverflowError, reject non-finite) so an oversized timestamp is mirrored verbatim with an empty index column instead of aborting reconcile / store open. (#226)
This was referenced Sep 15, 2026
Open
…ng-222-226 # Conflicts: # CHANGELOG.md
# Conflicts: # CHANGELOG.md # src/agentacct/event_log.py
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
Five fail-soft / evidence-integrity gaps reported as #222–#226, each verified by reproducing the exact failure against
mainbefore fixing. In every case one malformed value in the user's own client logs or event ledger — or a session-id collision across clients — could abort a whole read/import or misattribute evidence, instead of skipping the affected row. All fixes are minimal and additive, preserve byte-identical behavior for normal inputs, and ship with a regression test.Fixes
rate_limits—read_claude_plan_usage_latest()used the raworgas a dict key before normalizing, so a sample with a list/dictorgraisedTypeError: unhashable typeand dropped every org's snapshot. Now such samples are skipped, mirroring the existing non-Mapping skip.client_usage—_timestamp_seconds()/_optional_float()had no finite check; aNaN/Infinitytoken (whichjson.loadsaccepts) crashed the parser, and the exception escaped the top-level per-clientexcept(read/OS/sqlite only), aborting the entire usage refresh. Both now treat non-finite as absent, matching the existing_cursor_timestamp_secondsguard.api—_link_mechanical_checks_by_session_time()keyed check→step linking onclient_session_idalone, so within one explicitly-merged cross-client Task two clients reusing a raw id (e.g. an MCPdefault) could credit one client's passing hook check to the other's step, falsely lifting it toindependently_checked. Now keyed by(client, session id)on both sides.task_outcome/receipt— the left-behind inference keyed session identity on the raw id string while the rest of the ledger uses(client, client_session_id); two clients reusing an id suppressed the inactive/mostly-done downgrade. All three functions now key on the(client, session id)pair.event_log—_extract_columns()did a barefloat(created_at); an out-of-range integer (e.g.10**400) raisedOverflowError(not caught by thejson.loadsguard) and one poison line abortedreconcile_from_file()/ store open. A small coercion now catches overflow and rejects non-finite, keeping the raw line mirrored verbatim with an empty index column.Testing
test_rate_limits,test_client_usage,test_mechanical_capture,test_task_outcome,test_event_log.test_opencode_actionswas corrected to carry theclienta real opencode projection stamps (the check now attaches only within the same client).PYTHONPATH=src .venv/bin/python -m pytest -q).Fixes #222
Fixes #223
Fixes #224
Fixes #225
Fixes #226