protocol: reuse-feedback-obs, SPEC 10.1 - feature negotiation, and each observation sent once - #11
Merged
Merged
Conversation
…the checker sees what a client does with each action and how it handles closes The passive checker watched one connection and could not tell chunk-summed reward, terminal observations, time-major order, metadata-first, the close reasons or text frames from their violations. With --probe the client runs a probe env whose observation counts steps and echoes the applied action, and the checker drives the connection: it speaks late, sends a 2 MiB metadata frame, closes for a resync, stops the run, and answers with a text frame. raw_client.py implements the probe env, and its --bug option breaks each clause in turn; tests/test_conformance_probe.py checks that each is named.
…fter Found by the probe checker itself, on Linux, in about one run in two of the resync scenario: when the server's resync close arrived while the feedback was being sent, the send raised, the reset after it never ran, and env 0 carried its finished episode onto the next connection (t = 7, 11, 15 for an episode of 3). The packed feedback already holds the terminal observation, so resetting first changes nothing the server sees.
…ed in CI in every scenario `plugrl_client --probe host port batch` runs the probe environment, executes each chunk time-major and flushes it at the terminal step, and handles the section 7 close reasons: it reconnects after plugrl-server-resync with nothing resent, exits 0 on plugrl-server-stop, and exits 2 on a text frame. A close now raises ServerClosed with its code and reason, and a text frame TextFrame, instead of one generic error. Passive mode is unchanged.
…s a 7.6 violation; raw_client --bug stale-chunk plugrl-env-client failed the resync scenario this way: after reconnecting it fed back chunks answered on the old connection, which the checker reported under 4.3. On a reconnected connection, feedback for an env that was never given an action there is now named for the clause it breaks. The new stale-chunk bug does exactly that, and the test expects the 7.6 clause.
… 8.2), and examples/reference_server.py is one written against SPEC alone A client that drives a server the way SPEC lets a client behave - ragged batches, a feedback set unlike the infer's, large frames, three kinds of malformed message, two connections sharing env 0, and the end of the run - and checks the action layout and env_ids, the resync closes, that the server survives a bad client, and the stop reason. The reference server trains nothing and passes; its --bug option breaks each server clause in turn. plugrl-server main passes; its version before #108 fails two checks.
…e - each observation crosses the link once Every observation crossed the link twice: in the feedback that ends a chunk, and again in the next infer as the state the new chunk starts from. That second copy is the factor of two in E43's cost model. A server now lists the features it implements in its metadata's `features`, and with this one an infer marks in `reuse` the rows whose observation the server already holds from that env's last feedback on the connection, and sends only the others. - SPEC: 5.1 `features`, 5.2 `reuse`, section 10 says what a feature is (an addition a server offers and a client uses only when offered, so old and new versions talk both ways), 10.1 the feature itself, and a line in each checklist. - plugrl_protocol.reuse.ObservationCache is the server's half: it keeps each env's last feedback observation, or that its episode ended, and completes an infer from it, raising ReuseError on a reuse SPEC forbids. - plugrl-conformance --features reuse-feedback-obs offers the feature to a client and checks that it reuses only what the server holds; without the flag nothing changes. - plugrl-conformance-server exercises it when the server lists it: partial and full reuse are answered, and a reuse after a terminal feedback, or with no feedback on the connection, closes for a resync. A server that does not list it gets one note. - raw_client.py uses it when offered (--no-reuse turns it off), and reference_server.py offers it. The bugs reuse-unoffered, reuse-after-reset and lenient-reuse show each clause is checked.
… ObservationCache Merging rows whose text was None produced the strings "None". Only the end-to-end checker tests covered reuse.py, and their clients always send text, so nothing caught it. tests/test_reuse.py now checks the cache on its own: row order, every row reused, the latest feedback wins, no reuse after terminated or truncated or with no feedback, malformed reuse and data, and text in each form a client may send it.
…s its envs not reusable A server feeds every feedback to the cache, from clients that use the feature and clients that do not. on_feedback raised ReuseError on an observation it could not split by env, such as one with no text key, so a version 1 client whose feedback the server had always accepted would have been closed for a resync. Now the envs of such a feedback are only marked as not reusable, with the reason, and a later reuse of one raises in complete. Validating a feedback stays the server's business: reference_server.py and the client checker no longer treat the cache as a validator.
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.
Every observation crosses the link twice: once in the feedback that ends a chunk, and again in the next infer as the state the new chunk starts from. The two differ only after a reset. That second copy is the factor of two in E43's cost model (2.8 ms + 2 × observation bytes / bandwidth). This removes it, and adds the negotiation it needs to stay compatible both ways. Stacked on #10 (and #9, #8): merge those first. The three commits after the merge of #8's branch are new.
Negotiation (SPEC 10).
metadata'sfeatures.So a new client works with an old server, and an old client with a new one.
protocol_versionstays 1. A change that cannot be made this way is the one that would move it to 2.reuse-feedback-obs(SPEC 10.1). An infer may carryreuse, a bool array with one entry per row:obsof that env's last feedback on this connection.datais batched to the rows that are not reused.What is in it:
plugrl_protocol.reuse.ObservationCache: the server's half, one per connection.on_feedbackstores each env's row, or marks that its episode ended.completerebuilds the full observation of an infer and raisesReuseErroron a forbidden reuse.on_feedbacknever raises. A server feeds it every feedback, from clients that never reuse too, so a feedback it cannot split (notextkey, say) only makes those envs not reusable.plugrl-conformance --features reuse-feedback-obs: offers the feature to a client. The probe checks still see the full observation, so every other clause is graded as before. A client that reuses something the server does not hold fails 10.1. A client that is offered the feature and never uses it gets a note. Without the flag nothing changes, and a client that sendsreuseanyway fails.plugrl-conformance-server: a newreusephase, which runs when the server lists the feature. It checks four things:databatch) is answered;A server that does not list the feature gets one note.
Reference implementations:
raw_client.pyuses the feature when offered (--no-reuseturns it off), andreference_server.pyoffers it.Bugs that show each clause is checked:
reuse-unofferedandreuse-after-reseton the client,lenient-reuseon the server.Checks:
tests/test_reuse.py, which unit-tests the cache on its own. ruff 0.14.2 is clean.Before this commit, the branch merges in #8's last commit (the 7.6 refinement), so that #10's branch carries all of #8.
Users:
ObservationCache. A reusing client trains the same weights bit for bit.