Skip to content

endpoint.extra_body: refuse a field jevify sets when the backend is built - #4

Merged
fidecastro merged 1 commit into
mainfrom
extra-body-refused-at-build
Sep 28, 2026
Merged

fidecastro merged 1 commit into
mainfrom
extra-body-refused-at-build

Conversation

@fidecastro

Copy link
Copy Markdown
Owner

The problem

Follow-up to #3. The extra_body clash check ran per request, so a key jevify sets on only one path was refused only when that path ran. logit_bias is set by the equal-bias rung and the probe: a recipe with extra_body: {logit_bias: ...} passed ask and eval (warm and top-k readout never set it) and failed inside probe. Which command failed depended on which request happened to set the key first.

The change

  • RESERVED_REQUEST_FIELDS in jevify/adapters/endpoint/client.py: every top-level request field jevify sets, across the readout requests of every dialect and rung, the probe, the tokenize and apply-template routes, and the rerank and embeddings bodies.
  • The client refuses a reserved key when it is built, so probe, ask, eval and serve fail the same way, before any request. build_backend is the one path all four take.
  • The per-request check from endpoint.extra_body: top-level request fields, so Ollama can turn thinking off #3 stays as the backstop for a field the registry does not know yet.
  • Docs: SKILL.md (when the refusal happens; the fields also reach the tokenize and template routes) and the ADR-0004 D2 row.

Tests

  • tests/guards/test_request_fields.py: a ratchet guard in the style of the other structure guards. It drives every adapter kind and dialect through the fakes the way an operator does (probe, apply_probe, warm, evaluate each question type) and fails naming any request field the registry lacks. It caught top_n in the rerank body on its first run, a field my read of the adapters had missed.
  • test_extra_body_naming_a_field_jevify_sets_is_refused_before_any_request, parametrized over max_tokens (set on every request) and logit_bias (the case above). Replaces the per-request test from endpoint.extra_body: top-level request fields, so Ollama can turn thinking off #3, whose scenario it covers. Both cases were red before the change.
  • The fake records tokenize and apply-template bodies in template_requests, apart from requests, so request counts in existing tests are unchanged.

Evidence

  • uv run pytest -m "not live and not encoder": 138 passed (137 before).
  • ruff check and ruff format --check: clean.
  • mypy jevify: 20 errors, the same 20 as on main.
  • Removing top_n from the registry makes the guard fail naming top_n and the rerank recipe.
  • jevify probe on a recipe with extra_body: {logit_bias: ...} and an unreachable base_url prints endpoint.extra_body may not set logit_bias: jevify sets it and never connects.

Not exercised

  • No live server. The registry was verified against the fakes, which cover every route the adapters call; a field a real server would see that the fakes do not is still caught by the per-request backstop.
  • Encoder-kind recipes have no endpoint, so nothing to check.

🤖 Generated with Claude Code

…uilt

The clash check in #3 ran per request, so a key set only by one path
(`logit_bias` by the equal-bias rung and the probe) passed warm and
evaluate and failed inside probe. The refusal now comes from one registry,
RESERVED_REQUEST_FIELDS in the endpoint client, checked when the client is
built: probe, ask, eval and serve fail the same way, before any request.
The per-request check stays as the backstop.

A hand-kept registry drifts, so tests/guards/test_request_fields.py drives
every adapter kind and dialect through the fakes (probe, apply the probe,
warm, evaluate) and fails naming any request field the registry lacks. It
already caught one the first time it ran: `top_n` in the rerank body. The
fake records its tokenize and apply-template bodies apart from the scoring
ones so request counts in existing tests stay as they were.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@fidecastro
fidecastro merged commit 2eace09 into main Sep 28, 2026
5 checks passed
haohao3k pushed a commit to haohao3k/jevify that referenced this pull request Oct 6, 2026
Conflicts with endpoint.extra_body (fidecastro#3, fidecastro#4):
- SKILL.md: keep both recipe notes.
- tests/test_recipes.py: keep the extra_body tests and the frozen-hash canary.
- tests/fakes/fake_openai_server.py: keep main's template_requests log and
  drop the branch's tokenize_requests; test_probe reads /tokenize bodies from
  template_requests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant