Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 35 additions & 1 deletion crates/graphql-orm-ai/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Changelog"
kind: reference
status: active
owner: graphql-orm-ai-maintainers
last_reviewed: 2026-08-22
last_reviewed: 2026-08-23
review_by: 2027-02-01
supersedes: []
---
Expand All @@ -18,6 +18,40 @@ checkpoint facts. For the current workspace baseline and active gates, use the
[implementation status](docs/implementation-status.md) and the central
[AI production-readiness plan](../../docs/plans/active/ai-production-readiness/README.md).

## [0.93.0] - 2026-08-23

Persistent schema module: **0.63.0** (unchanged from 0.92.0).

### Added

- The Codex app-server launch profile now has a generic, default-disabled
`with_web_search(bool)` setting. An enabled profile removes only the
`standalone_web_search` process disable, advertises the reviewed web-search
capability, and projects request-authorized `PublicWeb` or allowed-domain
policy into the closed thread configuration.
- The strict protocol actor now admits correlated native `webSearch` item
start/completion lifecycles and exposes bounded typed actions, queries, call
identifiers, and structured result metadata. Consumers can count exact
lifecycles, settle completed-call pricing, and audit returned domains.

### Security

- Search remains off for every existing registration. Shell, Code Mode, MCP,
browser/computer control, files, plugins, collaboration, and other native
surfaces remain disabled when search is enabled.
- Allowed-domain results are independently checked for HTTPS URLs, matching
normalized hosts, subdomain scope, field/result byte ceilings, exact
lifecycle correlation, and the request's maximum call count. Native Codex
has no block-domain control, so `BlockedDomains` requests fail as
unsupported rather than silently broadening access.
- Search results enter provider model context before the completion lifecycle
reaches the consumer. Exposed result metadata supports downstream audit and
classification, but does not represent pre-context mediation or source
trust.

There is no schema, data, protected-payload, GraphQL SDL, backup or restore
migration in this release.

## [0.92.0] - 2026-08-23

Persistent schema module: **0.63.0** (unchanged from 0.91.1).
Expand Down
2 changes: 1 addition & 1 deletion crates/graphql-orm-ai/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "graphql-orm-ai"
version = "0.92.0"
version = "0.93.0"
edition = "2024"
authors = ["Toby Martin <toby@dastari.net>"]
description = "Project-agnostic AI agent runtime for graphql-orm applications"
Expand Down
32 changes: 31 additions & 1 deletion crates/graphql-orm-ai/MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Migration Guide"
kind: reference
status: active
owner: graphql-orm-ai-maintainers
last_reviewed: 2026-08-22
last_reviewed: 2026-08-23
review_by: 2027-02-01
supersedes: []
---
Expand All @@ -19,6 +19,36 @@ they describe. For the current workspace baseline and active delivery gates,
use [implementation status](docs/implementation-status.md) and the central
[AI production-readiness plan](../../docs/plans/active/ai-production-readiness/README.md).

## 0.92.0 to 0.93.0: opt-in Codex app-server native web search

Adopt `graphql-orm-ai` 0.93.0 from one reviewed full monorepo revision. The AI
schema module remains **0.63.0**. There is no database, data, table, column,
index, constraint, backfill, GraphQL SDL, protected-payload, backup or restore
migration.

Existing registrations remain search-disabled. A reviewed host opts in with
`AiCodexAppServerLaunchProfile::with_web_search(true)`, applies that exact
profile's `codex_arguments()`, and implements
`AiCodexAppServerRunProcess::create_empty_thread_with_web_search` for retained
threads. The default trait implementation accepts only `None` and preserves
existing disabled-search implementations.

Enabled requests must include exactly one `ModelBuiltinTool::WebSearch`, an
ordinary WebSearch egress proof, and `maximum_builtin_tool_calls`. `PublicWeb`
and `AllowedDomains` are supported. `BlockedDomains` remains unsupported
because the reviewed native app-server protocol exposes no exclusion filter.
The protocol actor emits `AiCodexAppServerInbound::WebSearchLifecycle` with
typed bounded result metadata; process implementations map those events to
the provider-neutral built-in start/completion stream used for usage and
pricing.

The app-server does not accept the built-in call ceiling as a wire setting.
The actor rejects a start beyond the host ceiling, but that over-limit native
operation may already have begun before its start notification is observed.
Search result bodies also enter model context before completion metadata is
delivered. Hosts must describe those limits honestly and must not present
post-result validation as pre-context classification.

## 0.91.1 to 0.92.0: owner-authorized tool arguments and safe failures

Adopt `graphql-orm-ai` 0.92.0 from one reviewed full monorepo revision. The AI
Expand Down
18 changes: 11 additions & 7 deletions crates/graphql-orm-ai/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ for AI, ORM, storage, backup, and tool-profile packages:

```toml
[dependencies]
graphql-orm-ai = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.92.0", default-features = false, features = ["sqlite"] }
graphql-orm-ai = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.93.0", default-features = false, features = ["sqlite"] }
```

Exactly one persistence backend is required: `sqlite` (default), `postgres`,
Expand Down Expand Up @@ -154,14 +154,18 @@ for `codex-cli 0.148.0` with `gpt-5.4`; reverify it before upgrading Codex. Any
missing proof continues through the disclosed cleanup-and-rebind path.

The retained dynamic-tool launch profile is version-observed on Codex 0.148.0.
It disables Code Mode, Code Mode-only routing, shell, files, MCP, browser,
hosted search, and every other native item surface. Its sole process-level
exception is `code_mode_host`: `--disable code_mode_host` suppresses direct
It disables Code Mode, Code Mode-only routing, shell, files, MCP, browser, and
every other native item surface by default. Native web search has a separate
default-off `with_web_search(bool)` profile setting and still requires an exact
request built-in, egress proof, supported PublicWeb/allow-domain policy, and
call ceiling. Its other sole process-level exception is `code_mode_host`:
`--disable code_mode_host` suppresses direct
`dynamicToolCall` delivery on that Codex version, so the launch arguments omit
only that flag while the per-thread configuration still sets the feature
false. The protocol actor rejects any native item that is nevertheless
emitted. Reverify both direct delivery and the negative native-item matrix
before upgrading Codex.
false. When native search is enabled, the actor admits only its exact bounded
item lifecycle and exposes structured result metadata for host accounting and
audit; results enter model context before that completion event. Reverify both
direct delivery and the negative native-item matrix before upgrading Codex.

The Codex schema projector preserves bounded nullable scalar `type` arrays in
the crate-authored FixedBroker definitions. It does not pass through arbitrary
Expand Down
8 changes: 5 additions & 3 deletions crates/graphql-orm-ai/docs/local-harness.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ The separate `provider-codex-app-server` feature adds a second local boundary:
one strictly allowlisted process may be retained for an exact claimed run, and
an explicitly planned turn may resume one protected provider-thread cursor.
Experimental app-server dynamic tools are default-off and use only the
ordinary coordinator-owned registered GraphQL tool path. Structured output,
hosted web, files, images, shell, MCP, browser control, and generic JSON-RPC
remain unavailable. Its construction and exact limitations are in
ordinary coordinator-owned registered GraphQL tool path. Native web search is
separately default-off and may be enabled by an immutable launch profile plus
an exact request built-in, egress proof, supported domain policy, and call
ceiling. Structured output, files, images, shell, MCP, browser control, and
generic JSON-RPC remain unavailable. Its construction and exact limitations are in
[provider sessions, hosted search, and visible activity](provider-sessions-and-hosted-activity.md).

## Authority split
Expand Down
49 changes: 39 additions & 10 deletions crates/graphql-orm-ai/docs/provider-sessions-and-hosted-activity.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ operation whose resolver makes the final authorization decision.
| Contract | Default | Durable provider state | Application tools |
| --- | --- | --- | --- |
| JSONL `local-harness` | disabled | none | exact stateless replay supported |
| Codex app-server v2 | disabled | run process plus optional protected thread cursor | default-off experimental dynamic tools through the coordinator |
| Codex app-server v2 | disabled | run process plus optional protected thread cursor | default-off dynamic tools and independently default-off native web search |
| Native OpenAI hosted search | absent from each request | Responses continuation only when selected | mixed retained continuation supported |
| Visible reasoning summary | disabled | protected activity/final blocks | authority-neutral |
| Reasoning effort | provider/registration default | exact request, budget, checkpoint, and retained-session fingerprint | authority-neutral |
Expand Down Expand Up @@ -211,19 +211,20 @@ containing no project config or MCP servers, an empty working directory, and
the registered operating-system sandbox. The actor additionally sends empty
thread/turn environments and a closed thread config that disables shell,
unified execution, Code Mode, utility tools, connectors, plugins,
collaboration, images, browser/computer use, and hosted search. This is defense
in depth: the process sandbox remains authoritative if a provider version
ignores a feature toggle.
collaboration, images, browser/computer use, and, by default, hosted search.
This is defense in depth: the process sandbox remains authoritative if a
provider version ignores a feature toggle.

The sole process-level exception is measured on Codex 0.148.0: adding
The always-present process-level exception is measured on Codex 0.148.0: adding
`--disable code_mode_host` to this otherwise identical profile made a retained
GPT-5.6 Luna turn complete without issuing its offered tool, while omitting
that one argument produced the direct `dynamicToolCall` / `item/tool/call`.
`codex_arguments()` therefore omits only that disable. The actor still sends
`features.code_mode_host=false`, `features.code_mode=false`, and
`features.code_mode_only=false` per thread; shell, file, MCP, browser, web, and
every other native item remain unavailable and are rejected by the protocol
actor if emitted. Re-run the direct-tool readiness probe and negative native-
`features.code_mode_only=false` per thread; shell, file, MCP, browser, and every
other native item remain unavailable and are rejected by the protocol actor if
emitted. A registration may separately opt into only native web search as
described below. Re-run the direct-tool readiness probe and negative native-
item suite before adopting another Codex version.

Only a reviewed `Direct` model-tool declaration can construct this profile.
Expand All @@ -243,8 +244,9 @@ server sends it anyway. The actor admits only initialization, exact thread
start/resume/delete, turn start/interruption, correlated responses, the closed
visible-event allowlist, and—only for an experimental registration—the exact
documented `item/tool/call` server request. Commands, shell, files, patches,
MCP, collaboration, images, hosted web search, browser control, raw reasoning,
and arbitrary methods remain forbidden.
MCP, collaboration, images, browser control, raw reasoning, and arbitrary
methods remain forbidden. Native web-search items are admitted only for an
enabled profile and exact request configuration.

Codex may emit the documented generic `warning` while a turn is open. The
actor accepts only the exact positive-timestamp envelope, an optional thread ID
Expand Down Expand Up @@ -390,6 +392,33 @@ completed search usage across protected checkpoints, so a continuation cannot
reset it. Provider start without completion is not billable completion
evidence and leaves uncertain transport to the existing recovery path.

The Codex app-server profile is independently default-off through
`with_web_search(false)`. Setting it to `true` changes the immutable
registration identity and removes only the process-level
`--disable standalone_web_search`; the closed per-thread configuration still
turns search on only when the current `ModelRequest` contains the authorized
built-in. `PublicWeb` and `AllowedDomains` are supported. Allowed domains are
sent as `tools.web_search.allowed_domains` and every returned HTTPS result is
checked again against the same exact domain/subdomain policy. `BlockedDomains`
fails as unsupported because the reviewed app-server configuration has no
native exclusion list.

Codex reports each native operation as a correlated `webSearch` item start and
completion. The strict actor exposes a typed call ID, action, query, and
bounded result records containing domain, HTTPS URL, title, snippet, and
provider reference. This gives a process implementation exact lifecycle
counts, completed-call pricing evidence, and observed-domain audit data. The
actor rejects starts beyond `maximum_builtin_tool_calls`; because app-server
does not accept that ceiling on the wire, an over-limit native operation may
have begun before its start notification reaches the host.

Native results are provider-hosted: they enter model context before the
completion event reaches the consumer. Result validation and downstream
classification are therefore post-result audit, not pre-context mediation.
The request's WebSearch egress proof still governs whether the capability is
offered at all, and surfaced result metadata is provider-authored rather than
source-trust evidence.

Native OpenAI Responses can offer hosted search and reviewed application tools
in the same `ProviderRetained` request. Application calls still return to the
coordinator, which rehydrates the principal, reapplies tool policy, issues
Expand Down
2 changes: 1 addition & 1 deletion crates/graphql-orm-ai/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,7 @@ fn serialized_bytes(value: &impl Serialize) -> Option<u64> {
.and_then(|encoded| u64::try_from(encoded.len()).ok())
}

fn valid_web_domain(value: &str) -> bool {
pub(crate) fn valid_web_domain(value: &str) -> bool {
let value = value.strip_prefix("*.").unwrap_or(value);
!value.is_empty()
&& value.len() <= 253
Expand Down
Loading