You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit daa20a6
Browse filesBrowse the repository at this point in the historyBrowse files
fix(workbuddy): keep prompt hooks from stalling on scope reads (#1729)
* fix(workbuddy): keep prompt hooks from stalling on scope reads
WorkBuddy prompt submission should fail open within the scope binding HTTP budget even when a server response stalls after headers arrive.
Constraint: WorkBuddy enforces an outer UserPromptSubmit hook timeout
Scope-risk: narrow
Tested: uv run pytest tests/workbuddy_plugin/test_scope_binding.py -q
Tested: uv run ruff check integrations/workbuddy/plugins/powercontext/scripts/workspace_scope.py tests/workbuddy_plugin/conftest.py tests/workbuddy_plugin/test_scope_binding.py
Tested: uv run ruff format --check integrations/workbuddy/plugins/powercontext/scripts/workspace_scope.py tests/workbuddy_plugin/conftest.py tests/workbuddy_plugin/test_scope_binding.py
Co-authored-by: OmX <omx@oh-my-codex.dev>
* fix(workbuddy): bound hook response reads at every socket receive
f42a2bf added an absolute deadline around the scope resolver's response body,
but it still tightened urllib's socket timeout only once per 64 KiB block read.
http.client consumes many socket reads inside a single read call, so a server
that trickles a byte faster than that timeout keeps the caller inside one read
and past its deadline; the observed worst case is the host's 30s
UserPromptSubmit timeout, which is exactly what the change set out to remove.
Reuse the primitives the claude-code and codex scope modules already ship:
- open_bounded runs the request in a daemon worker, so connect and header
exchange stay inside the caller's budget.
- bind_response_deadline recomputes the remaining time before every receive,
framing included.
Both now cover the scope resolver and the hook's own recall, capture, and flush
reads. The hook shares them through the installed powercontext_scope_binding
shim instead of carrying its own opener, so the shim forwards them too.
_set_response_timeout reads the socket through a guarded getattr chain, so a
missing fp can no longer raise AttributeError outside the scope client's error
contract.
The deadline test replaces its fake socket with real loopback properties: body
drip, header drip, a large healthy response, an expired deadline, and the hook's
own recall read. The three drip cases fail on f42a2bf (3.19s, 3.17s, 3.20s
against a 1.0s assertion) and pass here.
---------
Co-authored-by: OmX <omx@oh-my-codex.dev>
0 commit comments