From dedd647cdef3fe30867e286ac076c7762e13be51 Mon Sep 17 00:00:00 2001 From: aaltshuler Date: Fri, 12 Jun 2026 13:21:03 +0300 Subject: [PATCH 1/2] release: bump workspace to 0.7.0 All six crate manifests + their path-dependency constraints, Cargo.lock, the regenerated openapi.json version metadata, AGENTS.md's surveyed version, and the v0.7.0 release notes (object-storage clusters, config-free --cluster serving, the operator config surface, keyed credentials, operator targeting/aliases, and the omnigraph.yaml deprecation stages). Co-Authored-By: Claude Fable 5 --- AGENTS.md | 12 ++-- Cargo.lock | 12 ++-- crates/omnigraph-cli/Cargo.toml | 12 ++-- crates/omnigraph-cluster/Cargo.toml | 6 +- crates/omnigraph-compiler/Cargo.toml | 2 +- crates/omnigraph-policy/Cargo.toml | 2 +- crates/omnigraph-server/Cargo.toml | 10 ++-- crates/omnigraph/Cargo.toml | 8 +-- docs/releases/v0.7.0.md | 90 ++++++++++++++++++++++++++++ openapi.json | 2 +- 10 files changed, 123 insertions(+), 33 deletions(-) create mode 100644 docs/releases/v0.7.0.md diff --git a/AGENTS.md b/AGENTS.md index b335955..87d6a46 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,7 +16,7 @@ Tools that support `@`-imports (Claude Code) auto-include all three files via th `CLAUDE.md` is a symlink to this file — there is exactly one source of truth. Edit `AGENTS.md`. -**Version surveyed:** 0.6.2 +**Version surveyed:** 0.7.0 **Workspace crates:** `omnigraph-compiler`, `omnigraph` (engine), `omnigraph-policy`, `omnigraph-cluster`, `omnigraph-cli`, `omnigraph-server` **Storage substrate:** Lance 6.x (columnar, versioned, branchable) **License:** MIT @@ -33,8 +33,8 @@ OmniGraph is a typed property-graph engine built as a coordination layer over ma - **Multi-modal querying**: vector ANN (`nearest`), full-text (`search`/`fuzzy`/`match_text`/`bm25`), Reciprocal Rank Fusion (`rrf`), and graph traversal (`Expand`, anti-join `not { … }`) in one runtime. - **Branches and commits across the whole graph**: Git-style — every successful publish appends to a commit DAG; merges are three-way at the row level. - **Atomic per-query writes**: `mutate_as` and `load` accumulate insert/update batches into an in-memory `MutationStaging.pending` per touched table; one `stage_*` + `commit_staged` per table runs at end-of-query, then `ManifestBatchPublisher::publish` commits the manifest atomically with per-table `expected_table_versions` CAS. A mid-query failure leaves Lance HEAD untouched on staged tables — no drift, no run state machine, no staging branches. Deletes still inline-commit; D₂ at parse time prevents inserts/updates and deletes from coexisting in one query. -- **HTTP server**: Axum + utoipa OpenAPI, bearer auth (SHA-256 hashed, optional AWS Secrets Manager). Cedar policy enforcement is engine-wide — every `_as` writer calls `Omnigraph::enforce(action, scope, actor)`, so HTTP, CLI, and embedded SDK consumers all hit the same gate. **Two modes** (v0.6.0+): single-graph (legacy flat routes) and multi-graph (`/graphs/{graph_id}/...` cluster routes + read-only `GET /graphs` enumeration). Per-graph + server-level Cedar policies. Runtime add/remove (`POST /graphs`, `DELETE /graphs/{id}`) is not exposed — operators edit `omnigraph.yaml` and restart. -- **CLI** driven by a single `omnigraph.yaml`; multi-format output (json/jsonl/csv/kv/table). +- **HTTP server**: Axum + utoipa OpenAPI, bearer auth (SHA-256 hashed, optional AWS Secrets Manager). Cedar policy enforcement is engine-wide — every `_as` writer calls `Omnigraph::enforce(action, scope, actor)`, so HTTP, CLI, and embedded SDK consumers all hit the same gate. **Two modes** (v0.6.0+): single-graph (legacy flat routes) and multi-graph (`/graphs/{graph_id}/...` cluster routes + read-only `GET /graphs` enumeration). Per-graph + server-level Cedar policies. Multi-graph mode boots from a cluster directory (`--cluster `, RFC-005) or the legacy `omnigraph.yaml` `graphs:` map. Runtime add/remove (`POST /graphs`, `DELETE /graphs/{id}`) is not exposed — operators run `cluster apply` (or edit the legacy file) and restart. +- **CLI** with two-surface config (RFC-008): the team-owned cluster directory (`cluster.yaml`) plus the per-operator `~/.omnigraph/config.yaml` (servers, credentials, actor, aliases). The legacy combined `omnigraph.yaml` still loads with per-key deprecation warnings — `config migrate` proposes the split, `OMNIGRAPH_NO_LEGACY_CONFIG=1` enforces strict mode. **Never extend `omnigraph.yaml`.** Multi-format output (json/jsonl/csv/kv/table). Throughout the docs, capabilities are split into **L1 — Inherited from Lance** vs **L2 — Added by OmniGraph**. @@ -90,7 +90,7 @@ Full diagram and concurrency model: [docs/dev/architecture.md](docs/dev/architec | Cedar policy actions, scopes, CLI | [docs/user/policy.md](docs/user/policy.md) | | HTTP server endpoints, auth, error model, body limits | [docs/user/server.md](docs/user/server.md) | | CLI quick-start | [docs/user/cli.md](docs/user/cli.md) | -| CLI command surface and `omnigraph.yaml` schema | [docs/user/cli-reference.md](docs/user/cli-reference.md) | +| CLI command surface and config schemas (`~/.omnigraph/config.yaml`, legacy `omnigraph.yaml`) | [docs/user/cli-reference.md](docs/user/cli-reference.md) | | Audit / actor tracking | [docs/user/audit.md](docs/user/audit.md) | | Error taxonomy and result serialization | [docs/user/errors.md](docs/user/errors.md) | | Install (binary / Homebrew / source / channels) | [docs/user/install.md](docs/user/install.md) | @@ -258,8 +258,8 @@ omnigraph policy explain --actor act-alice --action change --branch main | Three-way row-level merge | — | `OrderedTableCursor` + `StagedTableWriter`, structured `MergeConflictKind` | | Change feeds | — | `diff_between` / `diff_commits` with manifest fast path + ID streaming | | Cedar policy | — | Per-graph actions plus server-scoped actions (see [docs/user/policy.md](docs/user/policy.md) for the current list), branch / target_branch / protected scopes, validate/test/explain CLI. **Engine-wide enforcement** (MR-722): every `_as` writer (`apply_schema_as`, `mutate_as`, `load_as` — the deprecated `ingest_as` shims route through it — `branch_create_as` / `branch_create_from_as`, `branch_delete_as`, `branch_merge_as`) calls `Omnigraph::enforce(action, scope, actor)` — HTTP, CLI, embedded SDK all hit the same gate. | -| HTTP server | — | Axum, OpenAPI via utoipa, bearer auth (SHA-256, AWS Secrets Manager option), `authorize_request` at the HTTP boundary (resolves bearer→actor, applies admission control), NDJSON streaming export, **multi-graph mode (v0.6.0+) with cluster routes + read-only `GET /graphs` enumeration + per-graph + server-level Cedar policies. Add/remove graphs by editing `omnigraph.yaml` and restarting.** | -| CLI with config | — | `omnigraph.yaml`, aliases, multi-format output (json/jsonl/csv/kv/table) | +| HTTP server | — | Axum, OpenAPI via utoipa, bearer auth (SHA-256, AWS Secrets Manager option), `authorize_request` at the HTTP boundary (resolves bearer→actor, applies admission control), NDJSON streaming export, **multi-graph mode (v0.6.0+) with cluster routes + read-only `GET /graphs` enumeration + per-graph + server-level Cedar policies. Multi-graph boots from a cluster directory (`--cluster`) or the legacy `omnigraph.yaml`; add/remove graphs via `cluster apply` (or by editing the legacy file) and restarting.** | +| CLI with config | — | two-surface config (team `cluster.yaml` dir + per-operator `~/.omnigraph/config.yaml`; legacy `omnigraph.yaml` deprecated per RFC-008), aliases, multi-format output (json/jsonl/csv/kv/table) | | Audit / actor tracking | — | `_as` write APIs + actor map in commit graph | | Local RustFS bootstrap | — | `scripts/local-rustfs-bootstrap.sh` one-shot S3-backed dev environment | diff --git a/Cargo.lock b/Cargo.lock index b1cf0ef..2099055 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4543,7 +4543,7 @@ dependencies = [ [[package]] name = "omnigraph-cli" -version = "0.6.2" +version = "0.7.0" dependencies = [ "assert_cmd", "clap", @@ -4566,7 +4566,7 @@ dependencies = [ [[package]] name = "omnigraph-cluster" -version = "0.6.2" +version = "0.7.0" dependencies = [ "fail", "omnigraph-compiler", @@ -4584,7 +4584,7 @@ dependencies = [ [[package]] name = "omnigraph-compiler" -version = "0.6.2" +version = "0.7.0" dependencies = [ "ahash", "arrow-array", @@ -4605,7 +4605,7 @@ dependencies = [ [[package]] name = "omnigraph-engine" -version = "0.6.2" +version = "0.7.0" dependencies = [ "arc-swap", "arrow-array", @@ -4648,7 +4648,7 @@ dependencies = [ [[package]] name = "omnigraph-policy" -version = "0.6.2" +version = "0.7.0" dependencies = [ "cedar-policy", "clap", @@ -4661,7 +4661,7 @@ dependencies = [ [[package]] name = "omnigraph-server" -version = "0.6.2" +version = "0.7.0" dependencies = [ "arc-swap", "async-trait", diff --git a/crates/omnigraph-cli/Cargo.toml b/crates/omnigraph-cli/Cargo.toml index 901d69c..1670fb2 100644 --- a/crates/omnigraph-cli/Cargo.toml +++ b/crates/omnigraph-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "omnigraph-cli" -version = "0.6.2" +version = "0.7.0" edition = "2024" description = "CLI for the Omnigraph graph database." license = "MIT" @@ -13,11 +13,11 @@ name = "omnigraph" path = "src/main.rs" [dependencies] -omnigraph = { package = "omnigraph-engine", path = "../omnigraph", version = "0.6.2" } -omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.6.2" } -omnigraph-cluster = { path = "../omnigraph-cluster", version = "0.6.2" } -omnigraph-policy = { path = "../omnigraph-policy", version = "0.6.2" } -omnigraph-server = { path = "../omnigraph-server", version = "0.6.2" } +omnigraph = { package = "omnigraph-engine", path = "../omnigraph", version = "0.7.0" } +omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.7.0" } +omnigraph-cluster = { path = "../omnigraph-cluster", version = "0.7.0" } +omnigraph-policy = { path = "../omnigraph-policy", version = "0.7.0" } +omnigraph-server = { path = "../omnigraph-server", version = "0.7.0" } clap = { workspace = true } color-eyre = { workspace = true } serde = { workspace = true } diff --git a/crates/omnigraph-cluster/Cargo.toml b/crates/omnigraph-cluster/Cargo.toml index 973de6d..05a9308 100644 --- a/crates/omnigraph-cluster/Cargo.toml +++ b/crates/omnigraph-cluster/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "omnigraph-cluster" -version = "0.6.2" +version = "0.7.0" edition = "2024" description = "Cluster configuration validation, planning, and config-only apply for Omnigraph." license = "MIT" @@ -14,8 +14,8 @@ documentation = "https://docs.rs/omnigraph-cluster" failpoints = ["dep:fail", "fail/failpoints"] [dependencies] -omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.6.2" } -omnigraph = { package = "omnigraph-engine", path = "../omnigraph", version = "0.6.2" } +omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.7.0" } +omnigraph = { package = "omnigraph-engine", path = "../omnigraph", version = "0.7.0" } fail = { workspace = true, optional = true } serde = { workspace = true } serde_json = { workspace = true } diff --git a/crates/omnigraph-compiler/Cargo.toml b/crates/omnigraph-compiler/Cargo.toml index 8db46e6..bbf03f1 100644 --- a/crates/omnigraph-compiler/Cargo.toml +++ b/crates/omnigraph-compiler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "omnigraph-compiler" -version = "0.6.2" +version = "0.7.0" edition = "2024" description = "Schema/query compiler for Omnigraph. Zero Lance dependency." license = "MIT" diff --git a/crates/omnigraph-policy/Cargo.toml b/crates/omnigraph-policy/Cargo.toml index 0df2a12..907ce07 100644 --- a/crates/omnigraph-policy/Cargo.toml +++ b/crates/omnigraph-policy/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "omnigraph-policy" -version = "0.6.2" +version = "0.7.0" edition = "2024" description = "Policy / authorization layer for Omnigraph — Cedar-backed PolicyEngine, PolicyChecker trait, ResourceScope enum." license = "MIT" diff --git a/crates/omnigraph-server/Cargo.toml b/crates/omnigraph-server/Cargo.toml index 5393221..614711e 100644 --- a/crates/omnigraph-server/Cargo.toml +++ b/crates/omnigraph-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "omnigraph-server" -version = "0.6.2" +version = "0.7.0" edition = "2024" description = "HTTP server for the Omnigraph graph database." license = "MIT" @@ -19,10 +19,10 @@ default = [] aws = ["dep:aws-config", "dep:aws-sdk-secretsmanager"] [dependencies] -omnigraph = { package = "omnigraph-engine", path = "../omnigraph", version = "0.6.2" } -omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.6.2" } -omnigraph-policy = { path = "../omnigraph-policy", version = "0.6.2" } -omnigraph-cluster = { path = "../omnigraph-cluster", version = "0.6.2" } +omnigraph = { package = "omnigraph-engine", path = "../omnigraph", version = "0.7.0" } +omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.7.0" } +omnigraph-policy = { path = "../omnigraph-policy", version = "0.7.0" } +omnigraph-cluster = { path = "../omnigraph-cluster", version = "0.7.0" } axum = { workspace = true } clap = { workspace = true } color-eyre = { workspace = true } diff --git a/crates/omnigraph/Cargo.toml b/crates/omnigraph/Cargo.toml index a4a2fe0..7ee9bda 100644 --- a/crates/omnigraph/Cargo.toml +++ b/crates/omnigraph/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "omnigraph-engine" -version = "0.6.2" +version = "0.7.0" edition = "2024" description = "Runtime engine for the Omnigraph graph database." license = "MIT" @@ -16,8 +16,8 @@ default = [] failpoints = ["dep:fail", "fail/failpoints"] [dependencies] -omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.6.2" } -omnigraph-policy = { path = "../omnigraph-policy", version = "0.6.2" } +omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.7.0" } +omnigraph-policy = { path = "../omnigraph-policy", version = "0.7.0" } lance = { workspace = true } lance-datafusion = { workspace = true } datafusion = { workspace = true } @@ -52,7 +52,7 @@ chrono = { workspace = true } arc-swap = { workspace = true } [dev-dependencies] -omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.6.2" } +omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.7.0" } tokio = { workspace = true } lance-namespace-impls = { workspace = true } serial_test = "3" diff --git a/docs/releases/v0.7.0.md b/docs/releases/v0.7.0.md new file mode 100644 index 0000000..4048041 --- /dev/null +++ b/docs/releases/v0.7.0.md @@ -0,0 +1,90 @@ +# Omnigraph v0.7.0 + +v0.7.0 takes the cluster control plane to object storage and overhauls the +configuration architecture around two single-owner surfaces. A cluster — +state ledger, content-addressed catalog, and graph data — can now live +entirely on an S3-compatible bucket, and a server can boot from that bucket +with no local files at all. Operator identity, credentials, and personal +aliases move to a home-level config; the legacy combined `omnigraph.yaml` +enters a guided, staged deprecation. + +## Highlights + +- **Clusters on object storage (`storage:`).** `cluster.yaml` gains an + optional `storage: s3://bucket/prefix` root. Every stored byte — the + state ledger, lock, recovery sidecars, approval artifacts, catalog blobs, + and the derived graph roots (`/graphs/.omni`) — flows + through one storage layer, so `file://` (the default, byte-compatible + with existing clusters) and `s3://` are a single code path. The ledger's + compare-and-swap uses S3 conditional writes (`If-Match` / + `If-None-Match`), verified against AWS semantics, RustFS, and + Tigris-backed stores; the state lock is genuinely cross-machine on + object storage. +- **Config-free serving: `--cluster s3://bucket/prefix`.** The server + accepts a bare storage-root URI and boots from the applied revision on + the bucket — the ledger and catalog are the whole deployment artifact. + Policy bundles serve as digest-verified *content* from the catalog + (never re-read from disk), closing the last gap for fully remote + clusters. The preferred container shape becomes **bucket, no volume** + (see `docs/user/deployment.md`). +- **Per-operator configuration (`~/.omnigraph/`).** A home-level config + carries operator identity (`operator.actor`, the new last hop of the + `--as` chain), output defaults, named servers, and personal aliases. + `$OMNIGRAPH_HOME` relocates it; `$OMNIGRAPH_CONFIG` now stands in for + `--config` in both binaries. +- **Credentials keyed by server name.** `omnigraph login ` stores + a bearer token in `~/.omnigraph/credentials` (created `0600`; over- + permissive files are refused). Token resolution for a request whose URL + matches an operator-defined server: `OMNIGRAPH_TOKEN_` env → the + credentials file → the legacy `bearer_token_env` chain unchanged. A + token is only ever sent to the server it is keyed to. +- **Operator targeting and aliases.** `--server ` (with `--graph + ` for multi-graph servers) addresses operator-defined endpoints on + every remote-capable command. Operator aliases are pure *bindings* — + personal name → (server, graph, stored-query name, default params) — + invoking catalog-owned stored queries; they carry no query content. +- **`omnigraph.yaml` deprecation begins.** Loading the legacy file prints + a per-key notice naming each present key's new home + (`OMNIGRAPH_SUPPRESS_YAML_DEPRECATION=1` to silence in CI). + `omnigraph config migrate` proposes — and with `--write`, applies — the + split: team half to a ready-to-review `cluster.yaml`, personal half + merged into the operator config (existing entries always win). + `omnigraph init` no longer scaffolds the file. Migrated teams can set + `OMNIGRAPH_NO_LEGACY_CONFIG=1` to turn any legacy-file load into a hard + error. The file itself keeps working until its removal at the next + major version. + +## Breaking / behavior changes + +- `omnigraph init` no longer writes an `omnigraph.yaml` into the working + directory. Start cluster configs from the documentation templates, or + run `omnigraph config migrate` against an existing legacy file. +- Loading a legacy `omnigraph.yaml` now emits a deprecation block on + stderr (suppressible; see above). Output on stdout is unchanged. +- `ServingPolicy` (cluster crate API) carries verified policy *content* + instead of a blob path; `read_serving_snapshot` and several cluster + command entry points are now async. + +## Upgrade notes + +- Existing clusters need no migration: an absent `storage:` key keeps the + config-directory layout byte-for-byte. +- Existing `omnigraph.yaml` setups keep working through the deprecation + window; `omnigraph config migrate` produces the recommended split. +- Operator setup is three lines: + `mkdir -p ~/.omnigraph`, write `operator.actor` (and `servers:`) into + `~/.omnigraph/config.yaml`, then `echo $TOKEN | omnigraph login `. + +## Internals + +- The cluster, server, and CLI crates were modularized (the 7.9k-line + cluster `lib.rs` is now eight focused modules; the server and CLI test + monoliths split into per-area suites) — pure code movement, no behavior + change. +- New gated end-to-end suites run the full cluster lifecycle against a + real S3-compatible store in CI, including a lock-release regression and + a config-free server boot from a bare bucket URI. +- The deployment guide gains the bucket-no-volume container recipe for + AWS and Railway, validated against a live Railway deployment + (Railway buckets are S3-compatible and pass the conditional-write + contract test). diff --git a/openapi.json b/openapi.json index 85c5b8d..6e3dd03 100644 --- a/openapi.json +++ b/openapi.json @@ -7,7 +7,7 @@ "name": "MIT", "identifier": "MIT" }, - "version": "0.6.2" + "version": "0.7.0" }, "paths": { "/branches": { From 98c6147c38fe97e109acac96cd0d1fe59325834a Mon Sep 17 00:00:00 2001 From: aaltshuler Date: Fri, 12 Jun 2026 13:22:34 +0300 Subject: [PATCH 2/2] docs(testing): bring the test map up to release truth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lands an orphaned-but-accurate working-tree edit (the engine table rows for forbidden_apis.rs, lance_surface_guards.rs, traversal_indexed, proptest_equivalence, ordering, literal_filters, policy_engine_chassis — all real files; 21 -> 28 count) and replaces the stale pre-modularization crate rows: the CLI and server entries now describe the per-area suites (#192/#193 splits) plus this cycle's additions (RFC-008 deprecation coverage, keyed-credential auth, hermetic OMNIGRAPH_HOME harness, the bucket-gated s3 suites). Co-Authored-By: Claude Fable 5 --- docs/dev/testing.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/dev/testing.md b/docs/dev/testing.md index a817428..f2b33de 100644 --- a/docs/dev/testing.md +++ b/docs/dev/testing.md @@ -6,10 +6,10 @@ This file is the always-on map of the test surface. **Consult it before every ta | Crate | Path | Style | |---|---|---| -| `omnigraph` (engine) | `crates/omnigraph/tests/` | Integration tests (21 files), fixture-driven, share `tests/helpers/mod.rs` | -| `omnigraph-cli` | `crates/omnigraph-cli/tests/` | `cli.rs` (unit-ish; includes the `cluster_e2e_*` lifecycle compositions over the spawned binary — lost-state re-import recovery, out-of-band drift, graph-root destruction, multi-graph mixed-disposition convergence), `system_local.rs` (incl. the full-cycle cluster lifecycle with a spawned `--cluster` server — declare→serve→evolve→drift-heal→approved-delete — and applied-policy enforcement over HTTP), `system_remote.rs`, share `tests/support/mod.rs` | +| `omnigraph` (engine) | `crates/omnigraph/tests/` | Integration tests (28 files), fixture-driven, share `tests/helpers/mod.rs` | +| `omnigraph-cli` | `crates/omnigraph-cli/tests/` | Per-area suites (post-modularization): `cli_cluster.rs` (cluster command surface + operator-actor cascade), `cli_cluster_e2e.rs` (spawned-binary lifecycle compositions — lost-state re-import recovery, out-of-band drift, graph-root destruction, multi-graph mixed-disposition convergence), `cli_data.rs` (load/read/change/branch/commit/export/snapshot/policy/embed/maintenance + operator format cascade), `cli_schema_config.rs` (init/config, schema plan/apply, RFC-008 deprecation warnings + `config migrate` + strict mode), `cli_queries.rs`, `system_local.rs` (full-cycle cluster lifecycle with a spawned `--cluster` server, applied-policy enforcement over HTTP, keyed-credential auth, operator aliases), `system_remote.rs`; share `tests/support/mod.rs` (hermetic `OMNIGRAPH_HOME` by default) | | `omnigraph-cluster` | mostly in-source `#[cfg(test)] mod tests`; `tests/failpoints.rs` (feature-gated); `tests/s3_cluster.rs` (bucket-gated full lifecycle on object storage) | Cluster config parser, local JSON state diff, state CAS/lock handling/recovery, read-only validate/plan/status plus explicit refresh/import graph observations, config-only apply (content-addressed payload publish, disposition gating, composite-digest convergence, idempotent re-apply), catalog payload verification (status read-only, refresh drift + self-heal), failpoint crash-mid-apply / CAS-race coverage, Stage 4A graph creation (create executor, recovery sidecars + sweep rows, create crash windows), Stage 4B schema apply (migration previews in plan, schema executor, schema-apply sweep classification, schema crash windows), Stage 4C gated deletes (digest-bound approvals, delete executor + tombstones, delete sweep rows, delete crash windows), and 5A policy binding metadata (applies_to in the applied revision, binding-change diffing + convergence, pre-5A backfill), and the 5B serving-snapshot read API (converged read, refusal rows) | -| `omnigraph-server` | `crates/omnigraph-server/tests/` | `server.rs` (HTTP-level; incl. cluster-mode boot — converged-dir serving, policy binding wiring, boot refusals), `openapi.rs` (OpenAPI drift / regeneration) | +| `omnigraph-server` | `crates/omnigraph-server/tests/` | Per-area suites (post-modularization): `auth_policy.rs`, `data_routes.rs`, `schema_routes.rs`, `stored_queries.rs`, `multi_graph.rs` (cluster-mode boot — converged serving, policy binding wiring, boot refusals — + the concurrent branch-ops matrix), `boot_settings.rs` (mode inference, PolicySource), `s3.rs` (bucket-gated: single-graph serving + config-free `--cluster s3://` boot), `openapi.rs` (OpenAPI drift / regeneration); share `tests/support/mod.rs` | | `omnigraph-compiler` | mostly in-source `#[cfg(test)] mod tests` | Parser, type-checker, IR lowering, lint | The engine's `tests/` is the principal coverage surface; most graph-shaped behavior is exercised there. @@ -23,18 +23,25 @@ The engine's `tests/` is the principal coverage surface; most graph-shaped behav | `merge_truth_table.rs` | Merge-pair truth table (MR-786): all 9×9 `(left_op, right_op)` cells from `{noop, addNode, removeNode, addEdge, removeEdge, setProperty, dropProperty, addLabel, removeLabel}`. Adding a new op to `OpVariant` forces a compile error in `build_case` until the new row + column are dispositioned. 36 executable cells run through real `branch_merge` with a structured oracle (`MergeOutcome` / `MergeConflictKind` + graph-state assert); 45 cells involving `dropProperty`/`addLabel`/`removeLabel` are recorded as `Unsupported` until the mutation grammar grows. | | `writes.rs` | Direct-publish writes: cancellation, non-strict insert/merge rebase under the per-table queue, strict stale-write conflicts, multi-statement atomicity, MR-794 staged-write rewire (D₂ rejection, insert+update coalesce, multi-append coalesce, partial-failure recovery, load RI/cardinality recovery) | | `staged_writes.rs` | TableStore staged-write primitives (`stage_append`, `stage_merge_insert`, `commit_staged`, `scan_with_staged`, `count_rows_with_staged`) — primitive-level only; engine code uses the in-memory `MutationStaging` accumulator instead | +| `forbidden_apis.rs` | Defense-in-depth source-walk guard: engine code (`exec/`, `db/omnigraph/`, `loader/`, `changes/`) must not reach around the sealed storage trait to Lance inline-commit APIs; `// forbidden-api-allow: ` sentinel exempts reviewed lines | +| `lance_surface_guards.rs` | Pins the Lance API surfaces omnigraph depends on (named runtime + compile-only guards; see [lance.md](lance.md)) — the first smoke check on any Lance version bump; e.g. `compact_files_still_fails_on_blob_columns` turns red when the upstream blob-compaction fix lands | | `lifecycle.rs` | Graph lifecycle, schema state | | `point_in_time.rs` | Snapshots, time travel (`snapshot_at_version`, `entity_at`) | | `changes.rs` | `diff_between` / `diff_commits` | | `consistency.rs` | Cross-table snapshot isolation, atomic publish | | `schema_apply.rs` | Migration plan + apply, schema-apply lock | | `search.rs` | FTS / vector / hybrid (`bm25`, `nearest`, `rrf`) | -| `traversal.rs` | `Expand`, variable-length hops, anti-join | +| `traversal.rs` | `Expand`, variable-length hops, anti-join (CSR path — `OMNIGRAPH_TRAVERSAL_MODE` unset) | +| `traversal_indexed.rs` | BTREE-indexed Expand (`execute_expand_indexed`) forced via `OMNIGRAPH_TRAVERSAL_MODE`, asserted semantically equal to the CSR path; own binary, all `#[serial]` so env writes never race | +| `proptest_equivalence.rs` | Property-based query-correctness invariants over generated graphs (shared key alphabet forces cross-type id collisions, cycles, self-loops) — pins Expand-mode equivalence so a future fork divergence fails loudly instead of silently; `#[serial]` | +| `ordering.rs` | ORDER BY contract: descending, multi-key precedence, deterministic key-column tie-break (total order, so `ORDER … LIMIT` is deterministic), NULL placement (`nulls_first = !descending`) | +| `literal_filters.rs` | Execution goldens for non-string/non-integer scalar literal filters (F64/F32/Bool/Date/DateTime) across both the in-memory comparison arm and the Lance-pushdown arm | | `aggregation.rs` | `count`, `sum`, `avg`, `min`, `max` | | `export.rs` | NDJSON streaming export filters | | `s3_storage.rs` | S3-backed graph (skipped unless `OMNIGRAPH_S3_TEST_BUCKET` is set) | | `lance_version_columns.rs` | Per-row `_row_last_updated_at_version` behavior | | `validators.rs` | Schema constraint enforcement (enum, range, unique, cardinality) across JSONL, insert, update paths | +| `policy_engine_chassis.rs` | Engine-layer Cedar enforcement (MR-722): allow + deny through every `_as` writer via the SDK directly — no HTTP — proving embedded and CLI callers hit the same gate as the server, with action × scope shapes matching `authorize_request` | | `maintenance.rs` | `optimize` (compaction), `repair` (explicit uncovered-drift publish), and `cleanup` (version GC): empty/idempotent/no-op edges, policy validation, head preservation; `optimize` publishes its own compaction (`optimize_publishes_compaction_to_manifest_so_schema_apply_succeeds`), skips pre-existing uncovered drift (`optimize_skips_preexisting_manifest_head_drift`), and refuses to run while a `__recovery` sidecar is pending (`optimize_defers_when_recovery_sidecar_is_pending`); `repair` previews/heals verified maintenance drift, refuses raw semantic drift without `--force`, and forced repair publishes only by explicit operator choice | | `failpoints.rs` | Failure-injection coverage (gated on `failpoints` feature). Includes the five per-writer Phase B → recovery integration tests (`recovery_rolls_forward_after_finalize_publisher_failure`, `schema_apply_phase_b_failure_recovered_on_next_open`, `branch_merge_phase_b_failure_recovered_on_next_open`, `ensure_indices_phase_b_failure_recovered_on_next_open`, `optimize_phase_b_failure_recovered_on_next_open`). | | `recovery.rs` | Open-time recovery sweep — sidecar I/O, classifier dispatch (NoMovement / RolledPastExpected / UnexpectedAtP1 / UnexpectedMultistep / InvariantViolation), all-or-nothing decision, roll-forward via `ManifestBatchPublisher::publish`, roll-back via `Dataset::restore`, audit row in `_graph_commit_recoveries.lance`, `OpenMode::ReadOnly` skip path |