fix(runtime-python): resolve QA findings RT-06/07/12/14 - #16
Merged
Conversation
Four confirmed runtime bugs from reports/python-runtime-qa-report.md, all reproduced end-to-end and covered by regression tests in tests/test_qa_fixes.py (9 tests). Full suite: 115 passed (was 106). - RT-12 (HIGH): thread the triggering Event through guard evaluation so `event.*` guards resolve against the payload instead of None. - RT-14 (MED): ordered comparisons (< > <= >=) fail closed on None/non-numeric operands instead of falling back to lexicographic string compare. RT-14 was masking RT-12, so the two are fixed together. - RT-06 (MED): run a state's on_entry before starting its invoked child (XState order) instead of dropping on_entry via an early return. - RT-07 (MED-HIGH): resume()/restore() rehydrate invoked child machines and active_invoke via _resume_children(), so a machine that crashed inside an invoke state is no longer permanently wedged. Sibling defs must be re-registered before resume; a missing sibling is skipped with a warning. Fixes documented in docs/runtime-python-production-hardening.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… mixed-operand guard test Addresses PR #16 review nits: - _resolve_variable docstring: state that ctx/context segments are skipped (ctx.amount and amount are equivalent). - _resume_children missing-sibling warning now names the exact register_machines({...}) call to make it actionable. - Add test_rt12_mixed_event_and_ctx_operands: a single comparison (event.amount > ctx.limit) that exercises both the event-payload and context resolution paths, guarding the resolution logic against regression. Suite: 116 passed (10 in test_qa_fixes.py). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the changeset that drives CI to bump the whole release train to v0.1.29 (the fixed npm group bumps together; CI then syncs pyproject.toml + server.json and tags v0.1.29, triggering the publish workflow). Also bumps the runtime-python __init__.__version__ to match and adds a root CHANGELOG entry for the GitHub release notes. Co-Authored-By: Claude Opus 4.8 (1M context) <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.
Summary
Fixes four confirmed runtime bugs in
packages/runtime-pythondocumented inreports/python-runtime-qa-report.md. Each was reproduced end-to-end throughparse_orca_md+OrcaMachinebefore fixing, and each is covered by a regression test.Eventthrough guard evaluation (_evaluate_guard → _eval_guard → _eval_compare/_eval_nullcheck → _resolve_variable). A path led byevent/payloadnow resolves against the event payload; everything else resolves against context as before. Previouslyevent.amount > 100resolved tocontext["event"]→None.< > <= >=) now require numeric operands (numeric strings still coerce);None/non-numeric operands fail closed (False) instead of falling back to lexicographicstr()compare.eq/neunchanged._execute_entry_actionsrunson_entryfirst, then starts the invoked child (XState order), instead of an earlyreturnthat droppedon_entry. Entry logic extracted to_run_on_entry._resume_children()rehydratesactive_invokeand re-instantiates/re-resumes each invoked child (completion handler factored into_make_child_done_handler). Wired into bothresume()andrestore(). A machine that crashed inside an invoke state is no longer permanently wedged.RT-12 + RT-14 were fixed together — RT-14 masked RT-12 (
str(None) > "100"wasTrue).Resume/persistence contract (RT-07)
Conservative version as proposed in the report: sibling defs (
register_machines) and action handlers must be re-registered beforeresume()/restore(); a child snapshot whose machine isn't a registered sibling is skipped with aUserWarning, not silently dropped or raised. Consistent with the existing start-path limitation.Testing
tests/test_qa_fixes.py(incl. an explicit "resumed machine is not wedged" test that drives a rehydrated child to completion and confirms the parent reacheson_done).Docs
docs/runtime-python-production-hardening.md— added "Runtime correctness fixes (RT-06/07/12/14)" section + summary-table rows.reports/python-runtime-qa-report.md— status updated to Fixed with a resolution note.Note
restore()also now rehydrates children (the report named bothresume()/restore(), though its repro targetedresume()). All pre-existing restore tests still pass — additive.🤖 Generated with Claude Code