Spawn: inherit WithObserve boundaries via GetObservers(k) (scheduler-spawn-drops-observer-boundary) - #478
Closed
proboscis wants to merge 2 commits into
Closed
Conversation
Spawn inherits inner handlers but silently drops WithObserve boundaries, so observers inside scheduled() never see spawned-task effects. 4 tests fail at HEAD (inside-scheduler, nested, cancel, GetObservers intrinsic); 2 pass as regression guards (outside-scheduler, sibling scope). Spec section documents the decided semantics. Issue: scheduler-spawn-drops-observer-boundary Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rs(k)
Spawn captured inner handlers (GetHandlers) but dropped observer
boundaries, so observers installed inside scheduled() silently missed
all effects performed by spawned tasks.
- doeff-vm-core: DetachedFiberChain::observer_callables +
Continuation::observer_callables; DoCtrl::GetObservers { from } +
observers_in_caller_chain (symmetric to GetHandlers).
- doeff-vm: PyGetObservers pyclass, eager classify path
(continuation_observers_value), module registration, stub.
- doeff: export GetObservers; handler_utils.get_inner_observers.
- scheduler: Spawn captures inner observers and reinstalls them with
WithObserve around the child program; released with the task in
_release_task_refs. Inheritance recurses across nested Spawn.
Observer semantics stay fiber-chain-scoped at the VM level; the
scheduler opts in, mirroring handler inheritance. Spec updated
(SPEC-SCHED-001 Observer inheritance).
Issue: scheduler-spawn-drops-observer-boundary
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
|
Superseded by #479 (merged): same issue implemented and verified via GetBoundaries(k). This branch came from a run that was stopped mid-flight. |
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.
Issue
scheduler-spawn-drops-observer-boundary— Spawn は inner handler を継承するのに intercept/observer 境界を落とすため、scheduled()の内側に置いたWithObserveが Spawn した子タスクの効果を一切観測できない(silent drop)。設計判断(issue の論点 1–3 への回答)
論点 2 の機構で論点 1 の結果を実現した:
GetObservers(k)を新設:GetHandlers(k)の observer 版。継続の detached fiber chain(perform サイト→捕捉ハンドラ)上の intercept 境界の observer callable を innermost 順で返す。非消費(one-shot 継続に影響なし)。get_inner_observers(k)で捕捉し、タスク初回実行時にWithObserveで子プログラムを再ラップ。handler 継承と完全に対称。_release_task_refsで解放される。継承ハンドラと同一のライフサイクルで、cancel の特別扱いは不要。multi-shot は本 VM に存在しない(SPEC-VM-021 one-shot)、かつ捕捉は read-only。仕様は
specs/vm/SPEC-SCHED-001-cooperative-scheduling.mdの Observer inheritance 節に明文化した。変更内容
doeff-vm-coreDetachedFiberChain::observer_callables/Continuation::observer_callables、DoCtrl::GetObservers { from }+observers_in_caller_chain(GetHandlersと対称)doeff-vm(PyO3)PyGetObserverspyclass、classify の eager 変換continuation_observers_value、モジュール登録、__init__.py/.pyidoeffGetObserversre-export、handler_utils.get_inner_observersdoeff-core-effects/scheduleralloc_task(inner_observers=…)→ 初回実行時にWithObserve再ラップ、_release_task_refsで解放TDD 順守: commit 89cb8fa で失敗するテストを先にコミット(4 failed / 2 passed のガード)、次コミットで実装。
Verification(1:1 マッピング)
Issue に形式的な
## Verification節は無いため、issue の再現スクリプトの期待値と論点を基準にマップする:scheduled(WithObserve(obs, …))で child-effect が観測されるtests/test_spawn_observer_inheritance.py::test_observer_inside_scheduler_sees_spawned_task_effectstests/test_spawn_observer_inheritance.py::test_observer_outside_scheduler_sees_spawned_task_effectstests/test_spawn_observer_inheritance.py::test_observer_inside_scheduler_sees_nested_spawn_effectstests/test_spawn_observer_inheritance.py::test_observer_scoped_below_spawn_site_is_not_inheritedtests/test_spawn_observer_inheritance.py::test_cancelled_child_effects_before_cancel_are_observedGetObservers(k)intrinsic 単体tests/test_spawn_observer_inheritance.py::test_get_inner_observers_returns_observer_callablesIssue 再現スクリプト実行結果(修正後)
追加のランタイム検証(public API 経由の probe)
テスト / lint
uv run pytest全体: 959 passed, 1 failed — 唯一の failuretests/architecture/test_no_public_withhandler_shim.py::test_public_withhandler_shim_imports_are_goneは base cacc4b8 でも失敗する既存問題(packages/doeff-adr/tests/test_defadr_macros.pyを検出。本 PR と無関係)。cargo test(doeff-vm-core): passed。make lint-pyright: 0 errors。ruff: 本 PR の変更ファイルは clean(doeff/program.pyの SIM108 は base から存在する既存指摘)。semgrep/doeff-linter: 本 PR 変更ファイルの指摘件数は base と同一(新規指摘ゼロ; scheduler.py は before/after ともに 5 errors / 43 warnings / 39 info)。リポジトリ全体には既存指摘が多数あり本 PR のスコープ外。Verification deviations
🤖 Generated with Claude Code