omnigraph/docs/releases/v0.6.0.md
Ragnor Comerford 1aafbd9dc6
mr-668: fold multi-graph work into v0.6.0 (no separate v0.7.0 release)
The branch had bumped workspace versions to 0.7.0 and added a
dedicated `docs/releases/v0.7.0.md` for the multi-graph work.
Per scope decision: ship the graph-rename and the multi-graph
mode in one v0.6.0 release.

Changes:

* Workspace versions bumped 0.7.0 → 0.6.0 in every crate manifest
  (`omnigraph`, `omnigraph-compiler`, `omnigraph-policy`,
  `omnigraph-server`, `omnigraph-cli`) and their internal
  `path = ..., version = "..."` dependency constraints.
* `docs/releases/v0.7.0.md` content merged into
  `docs/releases/v0.6.0.md`, retargeted to a single coherent
  v0.6.0 release note covering both the graph terminology rename
  and the multi-graph server mode. The original v0.7.0.md is
  deleted.
* All `v0.7.0` / `0.7.0` doc and comment references throughout
  `crates/`, `docs/`, `AGENTS.md`, and `openapi.json` retargeted
  to `v0.6.0` / `0.6.0`. `Cargo.lock` regenerated to match.
* OpenAPI spec regenerated via `OMNIGRAPH_UPDATE_OPENAPI=1
  cargo test -p omnigraph-server --test openapi
  openapi_spec_is_up_to_date` — `"version": "0.6.0"` now.

Verification:

* `cargo build --workspace` — clean (6 pre-existing engine
  warnings only).
* `cargo test --workspace --locked` — zero failures across all
  39 test result groups.
* `bash scripts/check-agents-md.sh` — passes (34 links / 33 docs).
* `grep -rn "0\.7\.0\|v0\.7\.0" --include='*.rs' --include='*.md'
  --include='*.json' --include='*.toml' .` returns no workspace
  hits. The three remaining `0.7.0` strings in `Cargo.lock`
  belong to unrelated 3rd-party crates (`pem-rfc7468`, `radium`,
  `rand_xoshiro`).

The git tag and crates.io publish happen later — this commit
just consolidates the surface so the eventual release is one
coherent v0.6.0 covering all the work since v0.5.0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 11:39:50 +02:00

11 KiB
Raw Blame History

Omnigraph v0.6.0

Two pieces of work land in this release:

  1. The graph terminology rename (renamed RepoGraph across the Cedar resource model, policy API, and query-lint schema source).
  2. Multi-graph server mode (MR-668) — one omnigraph-server process can now serve 110 graphs concurrently behind cluster routes (/graphs/{graph_id}/...), with per-graph and server-level Cedar policy, read-only GET /graphs enumeration, and CLI parity (omnigraph graphs list).

Runtime add/remove (POST /graphs, DELETE /graphs/{id}, omnigraph graphs create) is not in v0.6.0. Operators add or remove graphs by editing omnigraph.yaml and restarting. The first cut of POST /graphs shipped behind an atomic-YAML-rewrite design that we pulled before release once its concurrency guarantees were challenged (flock-on-renamed-inode race, duplicate-check outside the critical section, and an init-cleanup path that could destroy an existing graph's schema on re-init). The correct fix is a Lance-style cluster catalog (reserve → init → publish with recovery sidecars); that work is deferred.

Breaking Changes

Graph terminology rename

  • Renamed the Cedar resource entity from Omnigraph::Repo to Omnigraph::Graph.
  • Renamed policy API terminology from repo_id to graph_id on PolicyCompiler::compile (and on the new PolicyEngine::load_graph / PolicyEngine::load_server loaders described below).
  • Renamed query-lint schema source JSON from "repo" to "graph" for schema_source.kind.

Multi-graph server mode

  • Multi-graph deployments lose flat routes. Single-graph invocation (omnigraph-server <URI>) is unchanged — same flat /snapshot, /read, /branches, etc. Multi-graph deployments serve those routes under /graphs/{graph_id}/...; bare flat paths return 404 in multi mode.
  • ServerConfig shape change (programmatic embedders only): ServerConfig { uri, policy_file } is replaced by ServerConfig { mode: ServerConfigMode }, where ServerConfigMode = Single { uri, policy_file } | Multi { graphs, config_path, server_policy_file }. Callers that use load_server_settings are unaffected; callers that construct ServerConfig directly need to wrap their fields in ServerConfigMode::Single.
  • AppState's routing surface is AppState::routing() -> &GraphRouting, where GraphRouting = Single { handle } | Multi { registry, config_path }. The previous AppState::uri(), AppState::mode(), AppState::registry() accessors and the ServerMode enum are gone — embedders read state.routing() and match on the arm they need. Per-graph URIs live on handle.uri.
  • AppState::new_multi is the new multi-graph constructor. Single-mode new_* / open_* constructors are unchanged.
  • AuthenticatedActor(Arc<str>)ResolvedActor { actor_id, tenant_id, scopes, source } (programmatic embedders only). The struct shape changes, but the HTTP contract — bearer auth, MR-731 spoof defense — is unchanged. Cluster-mode call sites construct with tenant_id: None, scopes: vec![Scope::Full], source: AuthSource::Static. Forward-compat for Cloud mode (RFC 0003) and OAuth provider (RFC 0004).
  • PolicyEngine::load(path, graph_id) removed in favor of two kind-typed loaders: PolicyEngine::load_graph(path, graph_id) for per-graph policies and PolicyEngine::load_server(path) for server-level policies. Each loader rejects rules whose action resource_kind() doesn't match the engine kind — operators who put a graph_list rule in a per-graph file (or a read rule in a server file) now get a load-time error instead of a silently-never-matching rule.
  • PolicyRequest::actor_id field removed. Actor identity is now a separate parameter on PolicyEngine::authorize(actor_id, &request). The type system enforces MR-731's server-authoritative-actor invariant — handlers cannot smuggle identity through the request body.
  • Omnigraph::init is strict by default. Initialization at a URI that already holds schema files now errors with OmniError::AlreadyInitialized instead of silently overwriting. Operators who actually want to overwrite use InitOptions { force: true } (CLI: omnigraph init --force). Closes the destructive-cleanup footgun where a failed re-init would delete an existing graph's schema files.

New

  • Multi-graph mode. Invoke with omnigraph-server --config omnigraph.yaml where the YAML has a non-empty graphs: map and no single-mode selector (no server.graph, no CLI <URI> or --target). At startup the server opens every configured graph in parallel (bounded concurrency, fail-fast).
  • GET /graphs. Lists every registered graph, sorted alphabetically by graph_id. Auth-required when bearer tokens are configured; Cedar-gated by PolicyAction::GraphList against Omnigraph::Server::"root". Returns 405 in single mode. Server-scoped actions require an explicit server.policy.file in every runtime state — the management surface is closed by default even in --unauthenticated mode so that server topology is never exposed without operator opt-in.
  • CLI omnigraph graphs list. Mirrors the HTTP surface. Rejects local URI targets with a clear message — for remote multi-graph servers only.
  • CLI omnigraph init --force. Bypasses the strict-init preflight when an operator deliberately wants to recover from orphan schema files. Does NOT purge existing Lance datasets; recursive deletion needs StorageAdapter::delete_prefix (deferred — see below).
  • Per-graph Cedar policy. Each entry in the graphs: map can carry a policy.file path, loaded at startup via PolicyEngine::load_graph. Cedar's Omnigraph::Graph::"<graph_id>" resource is per-graph; the new Omnigraph::Server::"root" resource governs server-level actions.
  • Server-level Cedar policy. server.policy.file in the config governs the graph_list action on Omnigraph::Server::"root". Required to expose GET /graphs once bearer tokens are configured (MR-723 default-deny otherwise rejects graph_list as non-read).
  • Cedar action vocabulary: graph_list (server-scoped). Runtime graph_create / graph_delete are reserved but not shipped — see "Deferred."
  • Startup invariant: policy requires tokens. Configuring any policy file (per-graph or server-level) without bearer tokens now refuses to boot — serve() would otherwise start a server that 401s every request. The check lives in classify_server_runtime_state and applies uniformly to single and multi mode.

Configuration

omnigraph.yaml schema additions (all optional, single-mode unaffected):

server:
  bind: 0.0.0.0:8080
  policy:
    file: ./server-policy.yaml          # server-level Cedar (graph_list)

graphs:
  alpha:
    uri: s3://tenant-bucket/alpha
    policy:
      file: ./policies/alpha.yaml       # per-graph Cedar
  beta:
    uri: s3://tenant-bucket/beta
    # no per-graph policy → engine-layer enforcement is a no-op

Deferred

  • POST /graphs runtime graph creation and CLI omnigraph graphs create. Pulled before release after the YAML-rewrite design's correctness story didn't survive review. A future release will add a managed cluster catalog (Lance-backed reserve → init → publish with recovery sidecars) and re-expose runtime creation on top of it. Until then, operators add graphs by editing omnigraph.yaml and restarting.
  • DELETE /graphs/{id}. Never shipped in v0.6.0; deferred with the same cluster-catalog work.
  • StorageAdapter::delete_prefix. The substrate primitive a managed catalog would need. Will land alongside runtime mutation.
  • omnigraph init --force purging Lance state. Today --force only bypasses the schema-file preflight; recursive deletion of existing Lance datasets needs delete_prefix.
  • X-Actor-Id service delegation forwarding. Needs durable both-actor audit on _graph_commits.lance — out of scope.
  • Hot policy reload. Restart is cheap at N≤10 graphs.

User Impact

  • No on-disk migration is required. Existing .omni graphs from v0.5.0 (and earlier) open cleanly under v0.6.0 — Lance datasets, __manifest, _schema.pg, _schema.ir.json, __schema_state.json, _graph_commits.lance, _graph_commit_recoveries.lance all use unchanged formats. No conversion step.
  • Existing single-graph deployments upgrade with zero changes. omnigraph-server <URI> with v0.5.0 config keeps working identically.
  • Multi-graph adoption is opt-in. Add a graphs: map to omnigraph.yaml (and remove server.graph) to switch a deployment to multi mode.
  • Cluster routes are breaking for client SDKs targeting multi mode. Generated clients from previous v0.5.0 OpenAPI specs will hit 404 on flat paths against a multi-mode server. Regenerate against the v0.6.0 openapi.json.
  • Supported YAML policy authoring is unchanged. The Cedar Omnigraph::Graph and Omnigraph::Server entities are internally generated by compile_policy_source — operator YAML only references actions and groups.
  • Operators with unsupported raw Cedar policy files should update Omnigraph::Repo resource references to Omnigraph::Graph.

Migration: single → multi

# Before (v0.5.0 single-mode invocation)
server:
  graph: my-graph
graphs:
  my-graph:
    uri: /var/lib/omnigraph/my-graph
policy:
  file: ./policy.yaml
# After (v0.6.0 multi-mode — drop `server.graph` and the top-level `policy`)
server:
  policy:
    file: ./server-policy.yaml      # NEW: governs GET /graphs
graphs:
  my-graph:
    uri: /var/lib/omnigraph/my-graph
    policy:
      file: ./policy.yaml           # MOVED: was top-level

Same omnigraph.yaml file; restart the server. Clients targeting the old flat routes (/snapshot, /read, …) must update to /graphs/my-graph/snapshot, etc.

To add a new graph after rollout: stop the server, append a new graphs.<id> entry, restart.

Documentation

  • Public docs, CLI help, examples, server docs, and test helpers now consistently use "graph" for the OmniGraph data artifact.
  • GitHub/source repository terminology remains spelled out as "repository" where needed.
  • New: docs/user/cli.md documents omnigraph graphs list; docs/user/server.md documents the multi-graph mode and the cluster route convention; docs/user/policy.md documents the per-graph vs server-scoped action distinction.

Test coverage

  • GraphId newtype validation, registry race tests, init failpoints (still reachable from omnigraph init CLI).
  • Mode-inference four-rule matrix, parallel multi-graph startup, cluster routing.
  • Cedar Server resource refactor, backwards-compat for graph-only policies, kind-alignment rejection (server actions in graph files / vice versa).
  • GET /graphs enumeration, 405-in-single-mode, 403-in-Open-mode-without-server-policy, Cedar admin/viewer authorization.
  • Cluster routes with inner path params (/branches/{branch}, /commits/{commit_id}) deserialize correctly under axum 0.8 nested routing.
  • Policy-requires-tokens startup invariant enforced uniformly across single and multi mode.
  • MR-731 spoof regression test stays green across the entire refactor.