Repository navigation
fix: route a kernel request on the target PolicyGate admitted - #1889
Conversation
…dmitted PolicyGate decides whether a request may be routed by its stripped ``target_agent`` (`policy/gate.py`), and the router then dispatched on the raw one. A request naming `" kernel_agent"` therefore passed admission and fell through to the unknown-target refusal: the agent it named was enabled, had a handler and was allowed to serve it. The router now reads the field the way the gate read it, so the two agree on the name. The reply kind is deliberately left as sent: the requester awaits ``<kind>_done`` built from its own string, so normalising that would answer on a key nobody is listening to. Observable effect: a kernel request whose ``target_agent`` carries surrounding whitespace now runs its handler instead of coming back failed with ``unknown_target_agent``. An operator saw the request refused and recorded in the session's failure ledger for naming an agent that does exist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Code metrics gate: PASSEDJudged: the 2 files this change touches. Files it does not touch never fail it; anything found there is listed under Outside this change for information.
Already over at the base (backlog, not this change's): 3
85 findings in files this change does not touchOutside this change (informational): 85
...and 60 more; the job log lists every row.
Thresholds and sources: |
chaojhou
left a comment
There was a problem hiding this comment.
PR #1889 -- fix: route a kernel request on the target PolicyGate admitted
What it does: PolicyGate admits a REQUEST on its whitespace-stripped target_agent, but IntentRouter._handle_request routed on the raw value, so a padded " kernel_agent " passed admission and was refused as unknown_target_agent. The router now strips the name the same way, so the gate, the dispatcher's sequence check and the router agree on the target.
Blocking issues: none
SKIPPED: V4 -- #1869, #1675 and #1276 change more than 100 files and only their first 100 were compared; overlap there is unchecked.
Checked: src/hyperloom/orchestrator/loop/intent_router.py _handle_request, handle_intent, _auto_reject; src/hyperloom/orchestrator/policy/gate.py _validate_request; src/hyperloom/orchestrator/loop/dispatcher.py sequence_denial_for_request; tree-wide sweep for every non-test reader of target_agent | Ran: git grep/git show at head and base; gh pr diff 1888 for overlap | Base: 190604f | Head: d9a01f6
LGTM
Follow-up to review feedback on #1881 (finding 4,
description-claim). The reviewer found that #1881's description was wrong aboutunknown_target_agentbeing unreachable, and the reason it was wrong is a bug.PolicyGate decides whether a request may be routed by its stripped
target_agent(policy/gate.py:target = str(payload.get("target_agent", "")).strip()), and_handle_requestthen dispatched on the raw one. So a request naming" kernel_agent "passed admission and fell straight through to the unknown-target refusal - the agent it named was enabled, had a registered handler, and was allowed to serve it.The router now reads the field the way the gate read it, so the two agree on the name.
The reply kind is deliberately left as sent. The requester awaits
<kind>_donebuilt from its own string, so normalising that would answer on a key nobody is listening to. A paddedkindtherefore still comes backunknown_kernel_kind; that half belongs at the boundary - the gate should refuse a name it has to normalise before it recognises it - and is not in this PR.Review feedback on #1881.
test_a_padded_target_agent_reaches_its_handlersends" kernel_agent "and asserts the request reaches the kernel-agent arm - refused for its kind, not for its target. It fails onmainwithunknown_target_agentand passes here.Run locally:
pytestovertest_profile_and_kernel_handlers.py,test_policy_gate.py,test_agent_roles_and_policy.py,test_lifecycle_wiring.py,test_regression_locks.py- 257 passed; the one failure is a missing optionalTraceLensimport in the local environment and reproduces onmain.None. One line changes and every measured value for
_handle_requestand the module is unchanged.Not a refactor - a correctness fix. It removes a second reading of one value: the gate and the router now resolve
target_agentthe same way.A kernel request whose
target_agentcarries surrounding whitespace now runs its handler instead of coming back failed withunknown_target_agent. An operator previously saw the request refused, and recorded in the session's failure ledger, for naming an agent that does exist and was ready to serve it.Breaking changes: no
PR addresses single concern: yes
Root cause is upstream: no