## What changed
- Replace the single `category` and `score` fields in `SecurityRiskScore` with a
deterministic map of category names to scores.
- Validate the full Guardian V2 classifier response before storing it as one
thread extension value and, for non-ephemeral threads, one rollout item.
- Cover serialization and rollout loading with snapshots containing multiple
score categories.
GitOrigin-RevId: 24525de691f96bd34ccfe04acab2f01aca309837
## 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
- Replace the single byte limit with token-derived per-entry and separate message and tool transcript budgets.
- Preserve the first and latest user messages, then fill the remaining budgets with recent user, assistant, and tool context while limiting retained non-user entries.
- Truncate oversized entries in the middle without splitting UTF-8 characters, and report the approximate omitted token count.
- Exclude reasoning from the default transcript sources while retaining support when it is explicitly configured.
## Testing
- Cover oversized message and tool-result truncation, user-message retention, separate tool budgeting, configured reasoning, and the resulting Guardian sampling request.
GitOrigin-RevId: aaeaa5fb5d902b5a1581a8a819bf34724bde794b
## 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
- Parse and validate the structured risk scores returned for each classified tool call.
- Publish each score through thread extension data and persist it in rollout history for non-ephemeral threads.
- Report parsing, thread lookup, validation, and persistence failures through the extension warning sink.
## Testing
- Extend the Guardian V2 tool-classification test to verify that the sampled `action_risk` score is available from thread extension data and written to rollout history.
GitOrigin-RevId: 46614fe0d686736dfb1f09398c6fcd848c7d8b2c
## 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
## Why
Guardian V2 needs the requested action and its conversation context to assess
risk; a tool name and call ID alone do not describe what the tool will do.
## What changed
- Expose the original, pre-hook `ToolPayload` to tool lifecycle contributors.
- Build Guardian V2 classifier input from the bounded conversation transcript
and a structured planned-action object containing the tool name and arguments.
- Warn and skip classification if the planned action cannot be serialized.
## Testing
- Verify lifecycle contributors receive tool arguments.
- Verify Guardian V2 sends transcript history and planned-action JSON to the
classifier.
GitOrigin-RevId: 28266ef7c1d2267ba705fcfbd9be4ef48e64e104
## What changed
- Add a configurable renderer that converts conversation messages, agent
messages, tool calls and outputs, and reasoning into a numbered plaintext
transcript.
- Keep only relevant readable content, including manual-approval developer
messages, while omitting media payloads, encrypted content, and unsupported
response items.
- Limit transcripts to the most recent 320 KiB without splitting UTF-8
characters.
## Testing
- Cover source selection, content filtering, tool-name correlation, and bounded
UTF-8 truncation with unit tests.
GitOrigin-RevId: e2c6535f4a895862ca744258399fb36fc92e42c6
## What changed
- Register a tool lifecycle contributor when Guardian V2 is installed.
- On tool start, asynchronously ask the existing Luna sampler for a low-effort
`action_risk` score constrained to the range from `0.0` to `1.0`.
- Bound the tool metadata supplied to the classifier and treat it as untrusted
input.
- Emit an extension warning if classification sampling fails.
## Testing
Add an integration test that verifies the contributor reuses the configured
Luna pool and sends the expected model, attribution metadata, reasoning effort,
strict output schema, and tool-call context.
GitOrigin-RevId: 6b69fcc0443086544086849c38bcdd90560a291f
## 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
## What changed
- Add the `codex-guardian-v2` crate with an extension install entry point that does not register contributors yet.
- Register the crate in the Cargo workspace and add its Bazel target.
GitOrigin-RevId: 7c0c9479c6722d65f0f0dad9b0fd4a756e4649b3