Skip to content

Navigation Menu

Sign in
Sign up

fix: don't flag an in-flight parallel duplicate as crashed - #443

Open
AmirF194 wants to merge 1 commit into
CraftOS-dev:dev from
AmirF194:fix/activity-log-parallel-intent-conflation
Open

fix: don't flag an in-flight parallel duplicate as crashed #443
AmirF194 wants to merge 1 commit into
CraftOS-dev:dev from
AmirF194:fix/activity-log-parallel-intent-conflation

Conversation

@AmirF194

@AmirF194 AmirF194 commented Sep 5, 2026
edited
Loading

Copy link
Copy Markdown

What

  • ActivityLogGuard now tracks idem_keys with an INTENT it recorded but hasn't complete()'d yet.
  • begin()'s stale-INTENT branch checks that set before treating a row as a crashed prior attempt.

Why

execute_parallel dispatches every call in a batch before any of them completes, so two identical irreversible calls land two begin() calls back to back with no complete() in between. The second call saw the first's INTENT row and treated it as an interrupted (crashed) attempt, downgrading it to FAILED and telling the LLM the action "may have already happened," even though the first call was still genuinely running. Repro and details in #442.

Closes #442

Age alone can't fix this: an immediate crash-then-restart produces the exact same young INTENT row, and that case still needs the "may have happened" warning (there's a test for it). Tracking in-flight keys per guard instance handles both correctly, since a restart creates a fresh guard with an empty set.

How to test

  • python3 -m pytest tests/test_activity_log.py -q: 12 passed. The new test fails on dev and passes on this branch.
  • python3 -m pytest tests -q (skipping tests/e2e, tests/llm/golden, and two other files with pre-existing collection errors unrelated to this change, missing mss, a relative import bug): 944 passed, 29 skipped, 0 failed.
  • ruff format --check and ruff check clean on both changed files.
  • python -m compileall -q app agent_core agents decorators skills

One thing I didn't add a fallback for: if something throws between begin() and complete() and complete() never runs, that idem_key stays in the in-flight set until the process restarts, so a genuinely stuck duplicate would keep reading as "already running" instead of eventually getting flagged as a possible crash. The ledger row was already stuck at INTENT in that same case before this change, so it's not a new risk, just not one this closes.

Screenshots / Logs

Not UI-facing.

...ashed
ActivityLogGuard.begin() had no way to tell a batch mate still running
(execute_parallel dispatches all calls before any of them completes)
apart from a row that survived a crash and restart. Track in-flight
idem_keys per guard instance: a restart creates a fresh, empty set, so
the crash-recovery path still fires exactly as before.
Signed-off-by: Amir Fathi <amirfathi.me@gmail.com>

zfoong commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Is this still a work in progress? @AmirF194

AmirF194 marked this pull request as ready for review September 7, 2026 18:06

AmirF194 commented Sep 7, 2026

Copy link
Copy Markdown
Author

Ready for review, not WIP, sorry for the confusion. Marked it ready. Reproduced the false crash-flag twice (a standalone script driving ActivityLogGuard directly, plus a new regression test in tests/test_activity_log.py), and ruff/pytest are clean on the branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

2 participants

AltStyle によって変換されたページ (->オリジナル) /