Skip to content

claude-code-chat-browser: Simplify predicate-ordered tool dispatch selection #118

Description

@clean6378-max-it

Calendar Day

Thursday, July 9, 2026 (PR 2 of 3)

Planned Effort

3 story points (Medium) — sprint item #6

Depends on: Wednesday PR 2 (adversarial fixtures #4) merged; Thursday PR 1 (MessageDict #5) merged or stacked.

Companion PR: Thursday PR 3 (session decorator #7) — independent.

Problem

_TOOL_RESULT_DISPATCH in utils/tool_dispatch.py (15 entries) is a first-match-wins table where insertion order is load-bearing and deliberately not “specific before generic.” A contributor adding a tool type must understand the whole table plus intentional broad-before-narrow exceptions (is_task_message_tool_result before retrieval/completed/async).

Ordering intent is enforced only positionally (4 ORDERING_INVARIANTS in tests/test_tool_dispatch_ordering.py). Week 1 PR #104 unified the tool-name registry but did not simplify this selection mechanism — it remains the project's most subtle correctness mechanism and fragile extension point.

Goal

One merged PR that refactors dispatch classification so adding a tool type no longer requires reasoning about the entire tuple order, while preserving all existing classification results and passing structural + adversarial tests.

Scope

Approach (pick one or combine)

  1. Discriminant-based lookup — once MessageDict carries role/shape discriminant (Thursday PR 1), collapse overlap into direct keying where possible.
  2. Explicit specificity — if full keying isn't feasible, annotate predicates with priority/score instead of implicit tuple position; document each broad-before-narrow exception.

Touch points

  • utils/tool_dispatch.py — refactor _TOOL_RESULT_DISPATCH / _parse_tool_result selection.
  • docs/architecture.md — update “Dispatch table” section with unambiguous selection rule.
  • Module docstring — document new rule; preserve comments on intentional broad-before-narrow cases.

Guards (must still pass)

  • All 4 ORDERING_INVARIANTS in test_tool_dispatch_ordering.py.
  • Adversarial fixtures from test_tool_dispatch_adversarial.py (Wednesday PR 2).
  • tests/test_real_session_fixtures.py, tests/test_jsonl_parser.py — no classification change.

Out of scope

Acceptance Criteria

  • Adding a tool type no longer requires reasoning about entire implicit tuple ordering.
  • All ordering invariants and adversarial fixtures pass.
  • Module docstring and docs/architecture.md “Dispatch table” updated.
  • No change to classification for existing real-session fixtures.
  • Full pytest, mypy --strict, and ruff pass.
  • PR approved by at least 1 reviewer.

Verification

cd C:\Users\Jasen\CppAliance\claude-code-chat-browser
.\.venv\Scripts\Activate.ps1
pytest tests/test_tool_dispatch_ordering.py tests/test_tool_dispatch_adversarial.py -v
pytest tests/test_real_session_fixtures.py tests/test_jsonl_parser.py tests/test_tool_dispatch_sync.py -q
pytest -q
mypy .
ruff check .

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions