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: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -707,13 +707,15 @@ jobs:
# These real CLI/server/proxy journeys must execute in the ordinary
# workspace gate. A removed, filtered or re-ignored owner is not green.
for test_name in \
cluster_e2e_live_apply_changes_schema_queries_and_adds_graph_without_restart \
remote_server_and_cli_end_to_end_flow \
remote_schema_apply_refuses_additive_change_for_cluster_backed_graph \
remote_schema_apply_refuses_incompatible_change_for_cluster_backed_graph \
remote_schema_apply_refuses_branched_cluster_backed_graph \
remote_read_preserves_projection_order_in_json_and_csv \
remote_branch_create_list_merge_flow \
remote_merge_delivery_loss_never_replays_committed_effect \
remote_deployment_delivery_loss_preserves_owned_completion \
remote_branch_delete_removes_branch \
remote_export_round_trips_full_branch_graph \
remote_ingest_creates_review_branch_and_keeps_it_readable \
Expand Down
5 changes: 5 additions & 0 deletions changelog.d/canonical-data-interfaces.breaking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- Removed deprecated HTTP `/read`, `/change`, and `/ingest` routes and CLI `read`, `change`, `ingest`, `check`, `query lint`, and `query check` spellings. Use `query`, `mutate`, `load`, and `lint`; HTTP query and mutation bodies accept only `query` and `name` rather than their old aliases. Export always emits JSONL and no longer accepts `--jsonl`; see the [CLI reference][canonical-data-cli].
- Removed the unused HTTP `/schema/apply` endpoint. `schema apply` now accepts only standalone storage; deploy served schema changes with `cluster apply --server URL --config DIR`.
- Managed `cluster token` now issues only version-2 identity credentials; `--actions` and version-1 restricted caches/tokens are refused. Run `cluster token` to replace an old local credential explicitly; permissions remain owned by applied Cedar policy.

[canonical-data-cli]: ../docs/user/cli/reference.md
3 changes: 3 additions & 0 deletions changelog.d/cluster-lifecycle-completion.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Cluster apply supports policy grants/revocations and rebinding, embedding-provider changes, and external-Blob rules on existing graphs without restarting the server. Plan performs the same effect-free checks as apply without taking writer admission, and unrelated unavailable graphs do not block independent changes. Removing a graph declaration uses the same deployment and physically deletes its managed root and retained history after affected work drains. Deletion recovery accepts older manifests from the same graph lifetime while refusing replacements. A fresh creation can reuse verified empty local directories left by abandoned creation cleanup. Adoption, missing-root recreation and repair overrides are unsupported. See [cluster operations][cluster-lifecycle-completion].

[cluster-lifecycle-completion]: ../docs/user/clusters/index.md
1 change: 1 addition & 0 deletions changelog.d/deployment-observation-retries.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Served deployment observation retries truncated HTTP response bodies within the caller's wait budget, without resubmitting the deployment. Malformed receipts still fail immediately. Managed wait timeouts now point to `cluster status --managed` for recovery.
3 changes: 3 additions & 0 deletions changelog.d/explicit-managed-cli.breaking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Managed service commands now require `omnigraph cluster <command> --managed`; without that flag, cluster commands ignore managed folder context. Use `cluster operation --managed ID` for service lifecycle observation and `cluster status --managed [RUN_ID]` for run status. The top-level `managed` command is removed; data-command context and credential behavior are unchanged. See the [CLI reference][explicit-managed-cli].

[explicit-managed-cli]: ../docs/user/cli/reference.md#managed-cluster-commands
4 changes: 2 additions & 2 deletions changelog.d/release.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "v0.12.0",
"base": "refs/tags/v0.11.0",
"version": "v0.12.1",
"base": "refs/tags/v0.12.0",
"legacy": null
}
3 changes: 3 additions & 0 deletions changelog.d/served-deployment-observation.breaking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Served cluster deployment now supports `cluster plan --server`, durable acceptance with `apply --no-wait`, and bounded waiting through `apply --timeout` or `status --deployment-id ID --wait`. Plans show graph-root deletion without closing serving admission. Caller timeout preserves the original ID and never cancels or replays server work. An authenticated initiator can observe its exact receipt after a management-policy handoff. Exact lookup now returns `{deployment, active, in_progress}`; aggregate status retains `{status, active, in_progress}`. Update API consumers with the server. See [cluster deployment][served-deployment-observation].

[served-deployment-observation]: ../docs/user/clusters/index.md
23 changes: 23 additions & 0 deletions changelog.d/server-deployment-simplification.breaking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
- Cluster plan now always observes without taking the writer lock, and migration
previews use the same captured preparation as apply. The removed `--observe`,
`--lifecycle` and `--schema-correction` flags are rejected. Apply supports graph
creation, physical graph deletion and configuration changes. Removing a graph
declaration and applying deletes its managed storage and retained history;
interrupted deletion resumes through the original deployment ID. There is no
unregister mode. Adoption, missing-root recreation, drift acceptance and catalog
repair are no longer apply modes.

- Deployment activation is reported from the current process runtime snapshot,
without a second ledger write after activation. Durable results no longer store
`activation` or `restart_required`. Finish outstanding deployments with their
originating build and run the stopped-ledger upgrade before starting the new
build on a ledger containing those completed-result fields. Conversion preserves
graph data and exact achieved receipts. Normal reads identify qualified old
receipts with `ledger_upgrade_required` and the stopped-upgrade command.
Unrelated blocked graphs no longer invalidate activation of an independent
deployment. The drain timeout bounds admitted-request drainage; owned deployment
preparation and completion continue under the process shutdown boundary.

- The CLI also rejects the obsolete `repair --confirm` and `repair --force`
controls. Repair continues diagnosing foreign linear table commits without
adopting them.
89 changes: 6 additions & 83 deletions crates/omnigraph-api-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,6 @@ pub mod branch_statement_refusals {
pub const NAME_OR_PARAMS: &str = "a branch statement takes no name and no parameters";
/// An expected head beside a statement.
pub const COMMIT_PRECONDITION: &str = "a branch statement takes no commit precondition";
/// Any branch statement sent to a deprecated route.
pub const DEPRECATED_ROUTE: &str =
"branch statements are not served on deprecated routes; use POST /mutate or POST /query";
/// An `explain` statement sent to a deprecated route.
pub const EXPLAIN_DEPRECATED_ROUTE: &str =
"the explain statement is not served on deprecated routes; use POST /query";

/// Fill the `{statement}` placeholder of the two door refusals.
pub fn with_statement(template: &str, statement: &str) -> String {
template.replace("{statement}", statement)
Expand All @@ -87,10 +80,6 @@ pub mod query_file_refusals {
/// step, refused at every HTTP route and CLI verb since nothing follows
/// the prefix in the same request.
pub const ONLY_SETTINGS: &str = "a file of only settings lines carries no statement";
/// Either carrier — the `settings` field or a `set`/`reset` prefix in the
/// source — at either deprecated route, which serve their legacy bodies
/// under the process defaults alone.
pub const SETTINGS_AT_DEPRECATED_ROUTE: &str = "the deprecated /read and /change routes take no settings, neither a settings field nor a set or reset prefix; use POST /query or POST /mutate";
}

/// The `settings` field of a request: one optional value per `request`-scope
Expand Down Expand Up @@ -471,32 +460,6 @@ pub struct ReadOutput {
pub graph_commit_id: Option<String>,
}

/// Indefinitely byte-stable envelope of the deprecated `POST /read` route; cell
/// spelling follows the JSON writer. The canonical [`ReadOutput`] may grow
/// additive fields; this legacy envelope deliberately cannot carry them.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct LegacyReadOutput {
pub query_name: String,
pub target: ReadTargetOutput,
pub row_count: usize,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub columns: Vec<String>,
#[schema(value_type = Value)]
pub rows: Box<RawValue>,
}

impl From<ReadOutput> for LegacyReadOutput {
fn from(value: ReadOutput) -> Self {
Self {
query_name: value.query_name,
target: value.target,
row_count: value.row_count,
columns: value.columns,
rows: value.rows,
}
}
}

/// The effect of a branch statement sent to `POST /mutate`, tagged by `kind`.
/// A merge conflict has no kind: it is the 409 `POST /branches/merge` answers.
/// The statement grammar is `BranchStmt` in `omnigraph-compiler`.
Expand Down Expand Up @@ -896,43 +859,17 @@ pub struct ChangeErrorOutput {
pub change_diff_refusal: Option<ChangeDiffRefusalOutput>,
}

#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ReadRequest {
/// GQ query source. May declare one or more named queries; pick one with
/// `query_name` if there is more than one.
#[schema(
example = "query get_person($name: String) {\n match {\n $p: Person { name: $name }\n }\n return { $p.name, $p.age }\n}"
)]
pub query_source: String,
/// Name of the query to run when `query_source` declares multiple. Optional
/// when only one query is declared.
pub query_name: Option<String>,
/// JSON object whose keys match the query's declared parameters.
pub params: Option<Value>,
/// Branch to read from. Mutually exclusive with `snapshot`. Defaults to `main`.
pub branch: Option<String>,
/// Snapshot id to read from. Mutually exclusive with `branch`.
pub snapshot: Option<String>,
/// Refused when present: the deprecated route runs under the process
/// defaults. Typed as raw JSON so the refusal names the field instead of
/// a deserialization error.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub settings: Option<Value>,
}

/// Inline read-query request for `POST /query`.
///
/// Friendlier-named alternative to [`ReadRequest`] for ad-hoc reads and
/// AI-agent integration. Mutations are rejected with 400 — use `POST
/// /mutate` (or its deprecated alias `POST /change`) for write queries.
/// Mutations are rejected with 400 — use `POST /mutate` for write queries.
/// Field names are deliberately short (`query`, `name`) to match the GQ
/// keyword and the CLI `-e` flag.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
#[serde(deny_unknown_fields)]
pub struct QueryRequest {
/// GQ read-query source. May declare one or more named queries; pick one
/// with `name` when more than one is declared. Mutations
/// (`insert`/`update`/`delete`) get 400 — use `POST /mutate` (or its
/// deprecated alias `POST /change`) instead. May instead be the branch
/// (`insert`/`update`/`delete`) get 400 — use `POST /mutate` instead. May be the branch
/// statement `branch list`, sent with no `name`, `params`, `branch`, or
/// `snapshot`; or one `explain` statement (`explain query …`), which
/// answers the v2 plan instead of
Expand Down Expand Up @@ -1091,22 +1028,18 @@ impl BlobStatOutput {
}

#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
#[serde(deny_unknown_fields)]
pub struct ChangeRequest {
/// GQ mutation source containing `insert`, `update`, or `delete` statements.
/// May declare multiple named mutations; pick one with `name`. May instead
/// be one branch statement (grammar: `BranchStmt` in `omnigraph-compiler`),
/// sent with no `name`, `params`, or `branch`.
///
/// Accepts the legacy field name `query_source` as a deserialization alias.
#[schema(
example = "query insert_person($name: String, $age: I32) {\n insert Person { name: $name, age: $age }\n}"
)]
#[serde(alias = "query_source")]
pub query: String,
/// Name of the mutation to run when `query` declares multiple.
///
/// Accepts the legacy field name `query_name` as a deserialization alias.
#[serde(default, alias = "query_name")]
#[serde(default)]
pub name: Option<String>,
/// JSON object whose keys match the mutation's declared parameters.
#[serde(default)]
Expand Down Expand Up @@ -1269,16 +1202,6 @@ pub fn param_descriptor(param: &Param) -> ParamDescriptor {
}
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, ToSchema)]
pub struct SchemaApplyRequest {
/// Project schema in `.pg` source form. The diff against the current
/// schema produces the migration steps that will be applied.
#[schema(
example = "node Person {\n name: String @key\n age: I32?\n}\n\nedge Knows: Person -> Person"
)]
pub schema_source: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct SchemaApplyOutput {
pub uri: String,
Expand Down Expand Up @@ -2206,7 +2129,7 @@ pub enum GraphAvailabilityAction {
None,
WaitForStartup,
WaitForTransition,
RestartAfterCorrection,
ApplyCorrectionOrRestart,
WaitForRestart,
}

Expand Down
Loading
Loading