## Why
Guardian sampling uses a pool of WebSockets, while the bridge routes each
connection by thread ID. Each socket therefore needs its own identity instead
of reusing the source thread ID across the pool.
## What changed
- Generate a classifier thread ID for every pooled connection and use it for
request, window, and subagent attribution.
- Preserve the originating thread ID in turn metadata alongside the Guardian
classifier request kind.
- Build request metadata after leasing a connection so retries use the identity
of the socket that carries the request.
## Testing
- Cover unique identities across pooled and replacement connections.
- Verify classifier attribution metadata for extension requests and retries.
GitOrigin-RevId: 1c36207125157ff05cab9487a2fa37bf85e5fdd8
## Why
Guardian sampling WebSockets authenticate when the connection is opened. Reusing
a pooled connection after credentials change can therefore keep using the old
authorization.
## What changed
- Track authentication changes on each pooled sampling connection.
- Discard stale connections after an auth change and reject connections whose
authentication changes while the handshake is in progress.
## Testing
- Verify the sampler reconnects with the refreshed bearer token instead of
reusing its existing connection.
- Verify the installed Guardian extension reconnects after an external auth
refresh.
GitOrigin-RevId: 6d2e7df776fd21c78be0928f71162f5419a8b8f0
## Why
Guardian sampling can encounter temporary connection or service failures while
opening a WebSocket, starting a request, or consuming its response stream.
## What changed
- Retry transient transport, streaming, rate-limit, and server failures up to
two times across the full sampling flow.
- Recover from unauthorized responses through the configured auth manager and
discard pooled connections that may contain stale credentials.
- Allow sampler initialization to continue when its initial WebSocket prewarm
fails, so the first sample can establish a fresh connection.
## Testing
Added coverage for recovery after prewarm failures and `503` responses, and for
stopping once the transient retry budget is exhausted.
GitOrigin-RevId: af74c2df95c4241184ca641ef4418db6aa4ab695
## What changed
- Add the `features.guardianv2.transcript.include_images` opt-in setting.
- Include recent images from user and assistant messages and configured tool outputs in Guardian v2 sampling requests.
- Bound image context to the four most recent images and 8 MiB total, and omit image detail hints when constructing the sampling request.
## Testing
- Cover configuration parsing and image forwarding from messages and tool outputs.
GitOrigin-RevId: b0ae6b6182535fd084ea103ed01dc3c803d7d1f7
## What changed
- Expand the Guardian sampling pool from 8 to 16 WebSocket connections.
- When the pool is full, supersede the oldest request that has already produced a score before replacing an unfinished classification. Treat superseded classifications as a no-op in the extension.
- Stop response WebSocket work when its event consumer is dropped, including while waiting for the connection lock or draining a completed sample.
- Allow retries across both initially warmed connections for retryable stream failures.
## Testing
- Add a concurrent sampler test that fills the pool and verifies scored drains are replaced before an unfinished classification.
GitOrigin-RevId: 9e4df7b01516094726ff3e11878f8ca742d21b03
## Why
Guardian V2 classification requests should retain compacted conversation context only when the parent and classifier model configurations can share the encrypted compaction.
## What changed
- Resolve the classifier model's compaction compatibility hash when initializing its sampler.
- Add the latest encrypted parent compaction to classification input when both models have the same non-empty compatibility hash.
- Ignore missing, empty, or unidentified compactions, and omit parent context when compatibility cannot be established.
## Testing
- Cover latest-compaction selection and invalid compaction data.
- Cover matching, mismatched, missing, empty, and changed compatibility hashes.
GitOrigin-RevId: f0fcb09fd028cd2f397fdbc3d541b4bc464b0beb
## What changed
- Represent Guardian sampling input as an ordered list of text entries.
- Send each transcript entry and approval-request delimiter as a separate input
content item while preserving the existing transcript byte limit.
## Testing
- Update transcript and sampler tests to verify entry boundaries, multi-item
request serialization, and bounded transcript behavior.
GitOrigin-RevId: 433e2e6ca18ce9288025715f5956295bfe852e98
## What changed
- Register Guardian V2 for thread startup as well as tool-call lifecycle events.
- When `guardianv2` is enabled, create and store a thread-local Luna sampler using the thread's model provider, authentication policy, session metadata, originator, and service tier.
- Emit a warning if sampler initialization fails, and skip tool classification when the thread has no sampler.
## Testing
- Update the extension test to enable `guardianv2`, run thread startup, and verify tool-call sampling through the initialized connection.
GitOrigin-RevId: 5ab732e85c9827495c67f57117eb5be450a7f90e
## What changed
- Opt Guardian V2 Luna sampler WebSocket connections into responses lite.
- Send `reasoning.context` as `all_turns` on sampling requests.
## Testing
- Extend sampler and extension tests to verify the connection header and reasoning context.
GitOrigin-RevId: 4b0263c01b8259ed5268c222dcf7559912baba8c
## What changed
- Prewarm two Responses WebSocket connections and grow the pool on demand, up to eight connections, so overlapping samples can run concurrently.
- Lease each connection to a single sample and return healthy connections to the idle pool after completion.
- Replace closed or 55-minute-old connections and retry a sample once after a retryable or stream error.
- Keep the sampler available when the second prewarm connection cannot be opened.
## Testing
- Cover connection reuse, partial prewarm success, concurrent pool growth, and retrying an expired connection on another warm connection.
GitOrigin-RevId: 3ee7b05adc00a2135ba7cb35f6e4455199bf3784
## Why
Structured output can be complete before the Responses stream emits its terminal
events. Waiting for those events unnecessarily delays the sampler and can leave it
waiting after usable output has arrived.
## What changed
- Return a Luna sample as soon as accumulated text deltas parse as a complete JSON
object.
- Continue draining the remaining response events in the background so the
authenticated WebSocket stays reusable for subsequent samples.
- Enforce the output-size limit while accumulating deltas on the early-return path.
## Testing
- Cover returning complete JSON without terminal response events.
- Verify that early return still allows the authenticated WebSocket to be reused.
GitOrigin-RevId: 80c9963f1540f7862356aaad3503e3071a8fb92a
## What changed
- Add a `LunaSampler` that opens an authenticated Responses WebSocket and reuses it for structured, tool-free `gpt-5.6-luna` requests.
- Carry the host's provider, authentication, proxy, attribution, and service-tier configuration into the connection and requests.
- Require strict JSON schemas, preserve per-request reasoning effort and turn metadata, and reject missing or oversized output.
## Testing
- Add a WebSocket test covering authentication and attribution headers, connection reuse, structured request fields, per-turn metadata, reasoning effort, and returned output.
GitOrigin-RevId: aef85fd8ddcfcb7c76a9ede0d3191e3a0321656b