Skip to content

pgw#1346 K11: the eager tier gets a runtime binding, so inst.tuned exists - #930

Open
PaulFidika wants to merge 1 commit into
masterfrom
1346-w1b3a-eager-binding
Open

pgw#1346 K11: the eager tier gets a runtime binding, so inst.tuned exists#930
PaulFidika wants to merge 1 commit into
masterfrom
1346-w1b3a-eager-binding

Conversation

@PaulFidika

Copy link
Copy Markdown
Contributor

Unblocks K11 (B3b) and the ctx.defaults migration for every eager endpoint.

The gap

B5 landed the declaration half — render_eager emits a real Model subclass for a model with no graph classes. What no code did was build one on the serving path: residency.instance_for refused any model with neither an eager module nor an armed cell, and a runner-less model has neither by construction.

So every eager model was unconstructible, inst.tuned was unreachable, and since inst.tuned is the entire replacement for ctx.defaults, that one refusal gated anima (5 defaults reads), hidream (14), the auxiliary-model class, and all 11 weight-bearing boundary endpoints at once.

The fix

  • A model that declares no runners is now complete with a ref and its tuned values.
  • The refusal stays for a model that declares a graph and has nothing to run it — still a pod-level failure, and handing back an instance would move the error somewhere useless.
  • NoGraphBacking names that state instead of reusing an empty EagerBacking, whose refusal would read "no eager module bound for runner 'x'; it has []" and send the reader hunting for a registration that was never supposed to happen. "Nothing to arm, by declaration" and "not armed yet" are different answers; only one is a defect.

The eager tier's serving surface

inst.path and inst.pipeline, the way a typed runner call is a graph model's. B5's measurement: 8 of 11 weight-bearing boundary endpoints hand a local path to an external binary or a custom loader; 3 use an object the worker constructed.

Both refuse by name rather than returning an empty path or None — a handler that shells out to llama-server with "" fails somewhere far away and confusingly. The executor materializes the path through the same store.ensure_local call that already served slot-path injection, so the two routes cannot disagree.

This is also the shape F0(b)'s path-kind would need, so it is deliberately expressed on the instance — it works whichever way Paul rules F0.

Verification

  • 9 new tests in tests/test_eager_binding_pgw1346.py
  • 198 green across the eager/injection/axes/SDK/flux/v2 suites
  • mypy src/gen_worker tests tests_v2Success: no issues found in 913 source files; ruff clean
  • lint_serve_role_closure (both roles), lint_serving_process_compiles, lint_unreached_surface, lint_fence_symbols, check_registry_contract, check_model_bindings, lint_retired_sdk_spellings, assemble_changelog --check — green

🤖 Generated with Claude Code

…ists

B5 landed the declaration half — `render_eager` emits a real `Model`
subclass for a model with no graph classes. What no code did was BUILD one
on the serving path: `residency.instance_for` refused any model with
neither an eager module nor an armed cell, and a runner-less model has
neither by construction.

So every eager model was unconstructible, `inst.tuned` was unreachable,
and since `inst.tuned` is the entire replacement for `ctx.defaults`, that
one refusal gated anima (5 defaults reads), hidream (14), the auxiliary
model class, and all 11 weight-bearing boundary endpoints at once.

A model that declares no runners is now complete with a ref and its tuned
values. The refusal stays for a model that DECLARES a graph and has
nothing to run it — that is still a pod-level failure, and handing back an
instance would move the error somewhere useless.

`NoGraphBacking` gives the state its own name rather than reusing an empty
`EagerBacking`, whose refusal would read "no eager module bound for runner
'x'; it has []" and send the reader hunting for a registration that was
never supposed to happen. "Nothing to arm, by declaration" and "not armed
yet" are different answers and only one of them is a defect.

`inst.path` and `inst.pipeline` are the tier's serving surface, the way a
typed runner call is a graph model's. Measured across the boundary batch:
8 of 11 hand a local path to an external binary or a custom loader, 3 use
an object the worker built. Both refuse by name instead of returning an
empty path or None — a handler that shells out with "" fails somewhere far
away and confusingly. The executor materializes the path through the SAME
`store.ensure_local` call that already served slot-path injection, so the
two routes cannot disagree.

9 new tests; mypy clean over 913 files; ruff clean; serve-role closure,
unreached surface, fence symbols, registry contract and the binding gate
all green.
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