Repository navigation
fix: make a static pod's tap set visible, and refuse a bad steer with a 400 - #228
Merged
Merged
Conversation
Which sites a pod declared decided whether a request would be served, and was not written down anywhere a human reads at startup. It took a 500 mid-stream to find out that a pod's tap set and its axis layers disagreed. Both banners now say so, and they answer different questions. The config banner prints before the SAEs load, so `sae` has no address list yet and says that rather than an empty set that would read as "nothing declared". The ready banner is the same question after resolution and after the extras merge in, read off the loaded model. Collapsed to ranges because the honest list is unreadable: `auto` on this 70B pod declares 80 addresses per direction, which is `resid_post.0-79` here. One token per point name, layers grouped inside it, so `mlp_out_post.0-25 resid_mid.0-25` is a whole gemmascope set. Co-authored-by: Cursor <cursoragent@cursor.com>
…stream The read-side twin of this landed in #227 and left the write side asymmetric: an axis reading an undeclared layer got a 400 naming the layer, while a steer WRITING to one still died inside generate_steered, several hundred tokens into a StreamingResponse that had already returned 200. `assert_steering_available` did not catch it because it asks whether the pod declared any write site at all, which is the generation-only case. What bites is writes declared, at other layers: a projection cap writes wherever the vector it caps was fitted, so on the assistant-axis endpoint the pod declared 40 for the readout and was asked to write 32. An uploaded vector can name any layer, so the set is not one a pod can enumerate at startup. Both checks now match sites the way the engine does, through the `resid_pre[L]` == `resid_post[L-1]` alias, so a pod that declared one spelling is not refused for the other. They lean permissive on anything they do not recognize: an unrecognized site is one the engine refuses for itself, which is the failure they replace, where a false refusal would break a request the pod could serve. `steer_write_layers` shares `steer_layer_for_hook` with the spec that does the writing, since computing the layer twice is how a check passes for one layer and the engine fails at another. It runs only on a pod whose taps are fixed -- resolving those layers reads each feature's hook out of the SAE manager, and a check that cannot refuse anything should not be able to raise on the way to saying so. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #227. Two changes, both about the same thing: which sites a pod
declared decides whether a request is served, and that was neither visible at
startup nor reported cleanly when it went wrong.
1. The declared tap set is in both startup banners
Config banner, before the SAEs load:
Ready banner, read off the loaded model after resolution:
Two lines because they answer two questions.
saehas no address list until theSAEs load, so the first says that rather than printing an empty set that would
read as "nothing declared"; the second is the truth after the extras merge in. A
pod missing a layer its axes need is now visible at startup rather than on the
first request that needs it.
Ranges because the literal list is unreadable —
autoon the 70B pod is 80addresses per direction. One token per point name with layers grouped inside it,
so a gemmascope set reads
mlp_out_post.0-25 resid_mid.0-25.2. A steer at an undeclared layer is a 400, not a 500 mid-stream
#227 fixed the read side and left the write side asymmetric. An axis reading an
undeclared layer got a 400 naming the layer; a steer writing to one still died
inside
generate_steered, well into aStreamingResponsethat had alreadyreturned 200:
assert_steering_availablemisses this because it asks whether the pod declaredany write site, which is the generation-only case. What bites is writes
declared, at other layers: a projection cap writes wherever the vector it caps
was fitted, so the pod declared 40 for the readout and was asked to write 32. An
uploaded vector can name any layer, so this is not a set a pod can enumerate.
Both checks now match sites the way the engine does, through the
resid_pre[L]==resid_post[L-1]alias, so a pod that declared one spelling isnot refused for the other — the read check in #227 compared literal names and was
stricter than the engine. They lean permissive on anything unrecognized, since
that degrades to the engine's own refusal (the failure they replace) where a
false refusal would break a request the pod could serve.
Deploy note
The pod that prompted #227 no longer uses
STATIC_POINTS_EXTRA: capping writes atlayers no list can enumerate, so it runs
STATIC_POINTS=auto— priced atutil 0.90 with the prefill chunk pinned to 2048, which leaves KV at ~47,000
tokens. That lives in gitignored
local_scripts/pods.yaml, so it is not in thisdiff.
STATIC_POINTS_EXTRAstays as the lever for a pod that cannot affordautoand whose axis layers are a closed set; it now has no user.
Test plan
ruff check+ruff format --checkrepeats, and a layerless address
STATIC_POINTSshape, including a regression testthat a named mode is not iterated character by character
STATIC_POINTS=auto, read andwrite sets asked separately, alias match, and the hooked-pod gate
a fully-installed venv — this checkout's
apps/inference/.venvis partialand cannot load
conftest.pyare only proven by relaunching the 70B pod on this build
Made with Cursor