fix: per-action write state so one write failure doesn't block the rest#20
Merged
Merged
Conversation
A single successful, skipped, or denied write set a request-wide flag (`write_executed` / `write_decision`) that blocked every subsequent write in the same turn. Creating two jobs in one interaction, or retrying after a skip, failed with "Request already fulfilled" or "User skipped this action". Track write state per distinct action instead, keyed on a stable signature of the tool name plus its arguments: - `executed_writes`: set of completed action signatures — only an identical repeat is suppressed (still guards accidental double-sends). - `write_decisions`: per-signature approval/skip/deny decisions — reused only for the identical action, so a skip/deny never leaks onto a different write. Distinct writes (e.g. scheduling several reminders) now each run and prompt independently. Fixes #8.
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
Fixes #8 — a write failure (or skip/deny, or even a successful write) in
manage_jobsblocked every subsequent write action in the same turn.Root cause
_execute_tooltracked write actions with two request-wide values inrequest_state:write_executed(a single bool) — setTrueafter the first successful write.write_decision(a single value) — set to the first write's approve/skip/deny outcome.Because both are global to the turn, the guards at the top of
_execute_toolrejected any later write once one write had completed ("Request already fulfilled") or been skipped/denied ("User skipped this action") — even a completely different action. Scheduling two reminders in one interaction, or retrying after a skip, failed.Fix
Track write state per distinct action, keyed on a stable signature of the tool name + its arguments (
_write_signature, order-insensitive):executed_writes— a set of completed action signatures. Only an identical repeat is suppressed, preserving the original guard against accidental double-sends.write_decisions— per-signature approval decisions, reused only for the identical action, so a skip/deny never leaks onto a different write.Read-action approval caching (per
match_key, with persistedALWAYSrules) is unchanged.Tests
Added regression tests in
tests/test_tools.py:Full suite: 310 passed.
ruff check/ruff formatclean.