docs: drop ./ path prefixes; document query discovery

Paths in cluster.yaml and command examples are relative to one explicit
config folder (Terraform-shaped) — the ./ prefixes were noise and are gone
across the user docs (109 instances; ../ links and ./scripts executables
untouched). The cluster docs now present directory discovery as the primary
queries form with the list and map forms documented alongside.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
aaltshuler 2026-06-11 00:46:21 +03:00
parent 677320ceec
commit 44b5866516
7 changed files with 118 additions and 101 deletions

View file

@ -54,7 +54,7 @@ cli:
query:
roots: [<dir>, …] # search path for .gq files
auth:
env_file: ./.env.omni
env_file: .env.omni
aliases:
<alias>:
# accepted values: `read` / `query` (read alias), `change` / `mutate`
@ -70,20 +70,20 @@ aliases:
queries: # top-level registry — applies only to a bare-URI (anonymous) graph; a graph served by name uses its `graphs.<id>.queries`. Mirrors top-level `policy`.
<query-name>: { file: <path-to-.gq> } # mcp.expose defaults to true
policy:
file: ./policy.yaml
file: policy.yaml
```
## Cluster config preview
```bash
omnigraph cluster validate --config ./company-brain
omnigraph cluster plan --config ./company-brain --json
omnigraph cluster apply --config ./company-brain --json
omnigraph cluster approve graph.<id> --config ./company-brain --as <actor>
omnigraph cluster status --config ./company-brain --json
omnigraph cluster refresh --config ./company-brain --json
omnigraph cluster import --config ./company-brain --json
omnigraph cluster force-unlock <LOCK_ID> --config ./company-brain --json
omnigraph cluster validate --config company-brain
omnigraph cluster plan --config company-brain --json
omnigraph cluster apply --config company-brain --json
omnigraph cluster approve graph.<id> --config company-brain --as <actor>
omnigraph cluster status --config company-brain --json
omnigraph cluster refresh --config company-brain --json
omnigraph cluster import --config company-brain --json
omnigraph cluster force-unlock <LOCK_ID> --config company-brain --json
```
`--config` is a directory containing `cluster.yaml`; it defaults to `.`.

View file

@ -3,11 +3,11 @@
## Core Graph Flow
```bash
omnigraph init --schema ./schema.pg ./graph.omni
omnigraph load --data ./data.jsonl --mode overwrite ./graph.omni
omnigraph snapshot ./graph.omni --branch main --json
omnigraph query --uri ./graph.omni --query ./queries.gq --name get_person --params '{"name":"Alice"}'
omnigraph mutate --uri ./graph.omni --query ./queries.gq --name insert_person --params '{"name":"Mina","age":28}'
omnigraph init --schema schema.pg graph.omni
omnigraph load --data data.jsonl --mode overwrite graph.omni
omnigraph snapshot graph.omni --branch main --json
omnigraph query --uri graph.omni --query queries.gq --name get_person --params '{"name":"Alice"}'
omnigraph mutate --uri graph.omni --query queries.gq --name insert_person --params '{"name":"Mina","age":28}'
```
`omnigraph query` is the canonical read command (pairs with `POST /query`);
@ -21,11 +21,11 @@ For ad-hoc reads and mutations (REPLs, AI agents, one-off scripts), pass the
GQ source inline with `-e` / `--query-string` instead of a file path:
```bash
omnigraph query --uri ./graph.omni \
omnigraph query --uri graph.omni \
-e 'query find($name: String) { match { $p: Person { name: $name } } return { $p.name, $p.age } }' \
--params '{"name":"Alice"}'
omnigraph mutate --uri ./graph.omni \
omnigraph mutate --uri graph.omni \
-e 'query add($name: String, $age: I32) { insert Person { name: $name, age: $age } }' \
--params '{"name":"Inline","age":42}'
```
@ -38,14 +38,14 @@ only the source loader changes.
## Branching And Reviewable Data Flows
```bash
omnigraph branch create --uri ./graph.omni --from main feature-x
omnigraph branch list --uri ./graph.omni
omnigraph branch merge --uri ./graph.omni feature-x --into main
omnigraph branch create --uri graph.omni --from main feature-x
omnigraph branch list --uri graph.omni
omnigraph branch merge --uri graph.omni feature-x --into main
omnigraph ingest --data ./batch.jsonl --branch review/import-2026-04-09 ./graph.omni
omnigraph export ./graph.omni --branch main --type Person > people.jsonl
omnigraph commit list ./graph.omni --branch main --json
omnigraph commit show --uri ./graph.omni <commit-id> --json
omnigraph ingest --data batch.jsonl --branch review/import-2026-04-09 graph.omni
omnigraph export graph.omni --branch main --type Person > people.jsonl
omnigraph commit list graph.omni --branch main --json
omnigraph commit show --uri graph.omni <commit-id> --json
```
## Remote Server Mode
@ -53,7 +53,7 @@ omnigraph commit show --uri ./graph.omni <commit-id> --json
Serve a graph:
```bash
omnigraph-server ./graph.omni --bind 127.0.0.1:8080
omnigraph-server graph.omni --bind 127.0.0.1:8080
```
Read through the HTTP API:
@ -61,7 +61,7 @@ Read through the HTTP API:
```bash
omnigraph query \
--target http://127.0.0.1:8080 \
--query ./queries.gq \
--query queries.gq \
--name get_person \
--params '{"name":"Alice"}'
```
@ -87,23 +87,23 @@ Runtime add/remove is **not** in v0.6.0. To add a graph, stop the server, add a
Per-graph URLs: hit a graph's cluster route from any subcommand by pointing `--uri` at it:
```bash
omnigraph read --uri http://server.example.com/graphs/beta --query ./q.gq ...
omnigraph read --uri http://server.example.com/graphs/beta --query q.gq ...
```
## Runs, Policy, And Diagnostics
```bash
omnigraph lint --query ./queries.gq --schema ./schema.pg --json
omnigraph check --query ./queries.gq ./graph.omni --json
omnigraph lint --query queries.gq --schema schema.pg --json
omnigraph check --query queries.gq graph.omni --json
omnigraph schema plan --schema ./next.pg ./graph.omni --json
omnigraph schema apply --schema ./next.pg ./graph.omni --json
omnigraph policy validate --config ./omnigraph.yaml
omnigraph policy test --config ./omnigraph.yaml
omnigraph policy explain --config ./omnigraph.yaml --actor act-alice --action read --branch main
omnigraph schema plan --schema next.pg graph.omni --json
omnigraph schema apply --schema next.pg graph.omni --json
omnigraph policy validate --config omnigraph.yaml
omnigraph policy test --config omnigraph.yaml
omnigraph policy explain --config omnigraph.yaml --actor act-alice --action read --branch main
omnigraph commit list ./graph.omni --json
omnigraph commit show --uri ./graph.omni <commit-id> --json
omnigraph commit list graph.omni --json
omnigraph commit show --uri graph.omni <commit-id> --json
```
(The legacy `omnigraph run list/show/publish/abort` subcommands were removed in MR-771; mutations and loads publish atomically and the commit graph (`omnigraph commit list`) is the audit surface.)
@ -120,7 +120,7 @@ query roots:
```yaml
graphs:
local:
uri: ./demo.omni
uri: demo.omni
dev:
uri: http://127.0.0.1:8080
bearer_token_env: OMNIGRAPH_BEARER_TOKEN

View file

@ -20,14 +20,14 @@ or serve anything it applies: the server still boots from `omnigraph.yaml`.
## Commands
```bash
omnigraph cluster validate --config ./company-brain
omnigraph cluster plan --config ./company-brain --json
omnigraph cluster apply --config ./company-brain --json
omnigraph cluster approve graph.<id> --config ./company-brain --as <actor>
omnigraph cluster status --config ./company-brain --json
omnigraph cluster refresh --config ./company-brain --json
omnigraph cluster import --config ./company-brain --json
omnigraph cluster force-unlock <LOCK_ID> --config ./company-brain --json
omnigraph cluster validate --config company-brain
omnigraph cluster plan --config company-brain --json
omnigraph cluster apply --config company-brain --json
omnigraph cluster approve graph.<id> --config company-brain --as <actor>
omnigraph cluster status --config company-brain --json
omnigraph cluster refresh --config company-brain --json
omnigraph cluster import --config company-brain --json
omnigraph cluster force-unlock <LOCK_ID> --config company-brain --json
```
`--config` points at a directory, not a file. The directory must contain
@ -54,7 +54,7 @@ The exact contract:
cluster state XOR `omnigraph.yaml`, never a merge.
- **The other direction is ergonomics, not coupling**: a per-operator
`omnigraph.yaml` may point `graphs.<name>.uri` at a cluster's derived root
(`./company-brain/graphs/knowledge.omni`) so data-plane commands can use
(`company-brain/graphs/knowledge.omni`) so data-plane commands can use
`--target <name>` — an ordinary local path, no special handling.
## Supported `cluster.yaml`
@ -72,17 +72,35 @@ state:
graphs:
knowledge:
schema: ./knowledge.pg
queries:
find_experts:
file: ./knowledge.gq
schema: knowledge.pg
queries: queries/ # discover every `query <name>` in queries/*.gq
policies:
base:
file: ./base.policy.yaml
file: base.policy.yaml
applies_to: [knowledge]
```
`queries` is Terraform-shaped — the `.gq` files are the declaration. Three
forms:
```yaml
queries: queries/ # directory: top-level *.gq, sorted; every declaration registers
queries: [people.gq, extra/a.gq] # explicit files; every declaration in each
queries: # fine-grained name -> file map
find_experts:
file: knowledge.gq
```
Discovery is loud: an unreadable or unparseable `.gq`, or the same query name
declared in two files, fails validation (`query_parse_error`,
`duplicate_query_name`). Each discovered query is still an individually
addressed resource (`query.<graph>.<name>`) with its own plan/apply lifecycle;
the digest is the containing file's hash, so editing a multi-query file
updates all of its queries together. Paths are relative to the config
directory — the cluster is one explicit folder, so no `./` prefixes are
needed.
`metadata.name` is a display label. `state.backend` may be omitted or set to
`cluster`; external state backends are reserved for a later stage. `state.lock`
defaults to `true`. When enabled, `cluster plan`, `cluster apply`,
@ -324,7 +342,7 @@ without graph movement.
## Serving from the cluster (the mode switch)
```bash
omnigraph-server --cluster ./company-brain --bind 0.0.0.0:8080
omnigraph-server --cluster company-brain --bind 0.0.0.0:8080
```
`--cluster <dir>` is an **exclusive boot source** (axiom 15): it cannot

View file

@ -32,7 +32,8 @@ Lay out a config directory:
company-brain/
├── cluster.yaml
├── people.pg # schema for the "knowledge" graph
├── people.gq # a stored query
├── queries/ # stored queries — the .gq files ARE the declaration
│ └── people.gq
└── base.policy.yaml # a Cedar policy bundle
```
@ -43,27 +44,25 @@ metadata:
name: company-brain
graphs:
knowledge:
schema: ./people.pg
queries:
find_person:
file: ./people.gq
schema: people.pg
queries: queries/ # every `query <name>` in queries/*.gq registers
policies:
base:
file: ./base.policy.yaml
file: base.policy.yaml
applies_to: [knowledge] # graph-bound; use [cluster] for server-level
```
Bring it to life:
```bash
omnigraph cluster validate --config ./company-brain # parse + typecheck everything
omnigraph cluster import --config ./company-brain # create the state ledger
omnigraph cluster plan --config ./company-brain # preview: what would apply do?
omnigraph cluster apply --config ./company-brain # converge
omnigraph cluster validate --config company-brain # parse + typecheck everything
omnigraph cluster import --config company-brain # create the state ledger
omnigraph cluster plan --config company-brain # preview: what would apply do?
omnigraph cluster apply --config company-brain # converge
```
That single `apply` **creates the graph** (at the derived root
`./company-brain/graphs/knowledge.omni`), applies its schema, and publishes
`company-brain/graphs/knowledge.omni`), applies its schema, and publishes
the query and policy into the content-addressed catalog
(`__cluster/resources/…`). The output lists every change with its
disposition; `converged: true` means there is nothing left to do — re-running
@ -73,14 +72,14 @@ Load data through the normal graph plane (the control plane manages
*definitions*, not rows):
```bash
omnigraph load --data ./seed.jsonl ./company-brain/graphs/knowledge.omni
omnigraph load --data seed.jsonl company-brain/graphs/knowledge.omni
```
Serve it:
```bash
OMNIGRAPH_SERVER_BEARER_TOKENS_JSON='{"act-reader":"s3cret"}' \
omnigraph-server --cluster ./company-brain --bind 0.0.0.0:8080
omnigraph-server --cluster company-brain --bind 0.0.0.0:8080
```
`--cluster` is an **exclusive boot source**: it cannot be combined with a
@ -103,8 +102,8 @@ Every change follows the same loop, whatever its kind:
```bash
$EDITOR company-brain/people.pg # or any .gq / policy / cluster.yaml edit
omnigraph cluster plan --config ./company-brain
omnigraph cluster apply --config ./company-brain --as andrew
omnigraph cluster plan --config company-brain
omnigraph cluster apply --config company-brain --as andrew
# restart cluster-booted servers to pick it up
```
@ -142,8 +141,8 @@ anything runs.
## 3. Inspect: status, refresh, drift
```bash
omnigraph cluster status --config ./company-brain --json # ledger only, read-only
omnigraph cluster refresh --config ./company-brain # re-observe live graphs
omnigraph cluster status --config company-brain --json # ledger only, read-only
omnigraph cluster refresh --config company-brain # re-observe live graphs
```
`status` never touches the graphs; `refresh` opens them read-only and
@ -164,13 +163,13 @@ converges the ledger.
Removing a graph from `cluster.yaml` never executes silently:
```bash
omnigraph cluster apply --config ./company-brain
omnigraph cluster apply --config company-brain
# Delete graph.scratch [Blocked: approval_required]
omnigraph cluster approve graph.scratch --config ./company-brain --as andrew
omnigraph cluster approve graph.scratch --config company-brain --as andrew
# cluster approve: delete graph.scratch approved by andrew (approval 01KT…)
omnigraph cluster apply --config ./company-brain --as andrew
omnigraph cluster apply --config company-brain --as andrew
# Delete graph.scratch [Applied] ← root removed, subtree tombstoned
```
@ -196,8 +195,8 @@ again**.
**A held lock** (a crashed process left `__cluster/lock.json`):
```bash
omnigraph cluster status --config ./company-brain # shows the lock holder + id
omnigraph cluster force-unlock <LOCK_ID> --config ./company-brain
omnigraph cluster status --config company-brain # shows the lock holder + id
omnigraph cluster force-unlock <LOCK_ID> --config company-brain
```
Force-unlock requires the exact lock id (from status) — there is no blind
@ -240,7 +239,7 @@ with an in-flight apply.
- **`omnigraph.yaml` still has a job**: per-operator settings — your
`cli.actor` default for `--as`, CLI defaults, credentials, and data-plane
ergonomics (point `graphs.<name>.uri` at a derived root like
`./company-brain/graphs/knowledge.omni` to use `--target <name>` for
`company-brain/graphs/knowledge.omni` to use `--target <name>` for
loads). It just no longer describes the deployment — a server boots from
one source or the other, never a merge of both.

View file

@ -33,7 +33,7 @@ On Windows, the binaries are `omnigraph.exe` and `omnigraph-server.exe`.
Run against a local graph:
```bash
omnigraph-server ./graph.omni --bind 0.0.0.0:8080
omnigraph-server graph.omni --bind 0.0.0.0:8080
```
Run against an object-store-backed graph:
@ -208,7 +208,7 @@ docker run --rm -p 8080:8080 \
-e OMNIGRAPH_CONFIG="/etc/omnigraph/omnigraph.yaml" \
-v "$PWD/config:/etc/omnigraph:ro" \
omnigraph-server:local
# /etc/omnigraph/omnigraph.yaml contains `policy: { file: ./policy.yaml }`;
# /etc/omnigraph/omnigraph.yaml contains `policy: { file: policy.yaml }`;
# policy.yaml (+ optional policy.tests.yaml) sit beside it in the mount.
```

View file

@ -35,13 +35,13 @@ In multi mode (`omnigraph.yaml` with a non-empty `graphs:` map), policy files at
```yaml
server:
policy:
file: ./server-policy.yaml # server-level: graph_list
file: server-policy.yaml # server-level: graph_list
graphs:
alpha:
uri: s3://tenant-bucket/alpha
policy:
file: ./policies/alpha.yaml # per-graph: read, change, branch_*, schema_apply
file: policies/alpha.yaml # per-graph: read, change, branch_*, schema_apply
beta:
uri: s3://tenant-bucket/beta
# no per-graph policy → no engine-layer Cedar enforcement on beta
@ -78,8 +78,8 @@ rules:
```yaml
policy:
file: ./policy.yaml # Cedar rules + groups
tests: ./policy.tests.yaml # declarative test cases
file: policy.yaml # Cedar rules + groups
tests: policy.tests.yaml # declarative test cases
cli:
actor: act-andrew # default actor for CLI direct-engine writes

View file

@ -47,8 +47,8 @@ query register_employee_with_team($name: String, $age: I32, $team: String) {
```
```bash
omnigraph change --query ./mutations.gq --name register_employee_with_team \
--params '{"name":"Alice","age":30,"team":"Acme"}' ./graph.omni
omnigraph change --query mutations.gq --name register_employee_with_team \
--params '{"name":"Alice","age":30,"team":"Acme"}' graph.omni
```
If the second statement fails (e.g. `Acme` doesn't exist), the publisher never publishes; `Alice` is not in the database. Atomic.
@ -57,10 +57,10 @@ If the second statement fails (e.g. `Acme` doesn't exist), the publisher never p
```bash
# Query 1
omnigraph change --query ./mutations.gq --name register_employee --params '{"name":"Alice","age":30}' ./graph.omni
omnigraph change --query mutations.gq --name register_employee --params '{"name":"Alice","age":30}' graph.omni
# Query 2 — runs after Query 1 has already published
omnigraph change --query ./mutations.gq --name link_to_team --params '{"name":"Alice","team":"Acme"}' ./graph.omni
omnigraph change --query mutations.gq --name link_to_team --params '{"name":"Alice","team":"Acme"}' graph.omni
```
These are **two publishes** on `main`. If Query 2 fails, Query 1's effects are already visible. There is no `ROLLBACK` for Query 1.
@ -75,32 +75,32 @@ The pattern when you need to run multiple queries — possibly across multiple c
```bash
# Fork a working branch from main.
omnigraph branch create --from main onboarding/2026-04-25 ./graph.omni
omnigraph branch create --from main onboarding/2026-04-25 graph.omni
# Run any number of mutations on the branch — each one is its own publish on the branch.
# Concurrent reads of `main` are unaffected.
omnigraph change --branch onboarding/2026-04-25 \
--query ./mutations.gq --name register_employee \
--params '{"name":"Alice","age":30}' ./graph.omni
--query mutations.gq --name register_employee \
--params '{"name":"Alice","age":30}' graph.omni
omnigraph change --branch onboarding/2026-04-25 \
--query ./mutations.gq --name register_employee \
--params '{"name":"Bob","age":25}' ./graph.omni
--query mutations.gq --name register_employee \
--params '{"name":"Bob","age":25}' graph.omni
omnigraph change --branch onboarding/2026-04-25 \
--query ./mutations.gq --name link_to_team \
--params '{"name":"Alice","team":"Acme"}' ./graph.omni
--query mutations.gq --name link_to_team \
--params '{"name":"Alice","team":"Acme"}' graph.omni
# Inspect the branch — read queries work just like on main.
omnigraph read --branch onboarding/2026-04-25 \
--query ./queries.gq --name list_employees ./graph.omni
--query queries.gq --name list_employees graph.omni
# Happy with what's on the branch? Merge it. This is one atomic publish:
# `main` flips to include every commit on the branch.
omnigraph branch merge onboarding/2026-04-25 --into main ./graph.omni
omnigraph branch merge onboarding/2026-04-25 --into main graph.omni
# OR: not happy? Throw it away. `main` is untouched.
# omnigraph branch delete onboarding/2026-04-25 ./graph.omni
# omnigraph branch delete onboarding/2026-04-25 graph.omni
```
Properties:
@ -115,16 +115,16 @@ Two agents writing to the same graph independently:
```bash
# Agent A
omnigraph branch create --from main agent-a/work ./graph.omni
omnigraph change --branch agent-a/work … ./graph.omni
omnigraph branch create --from main agent-a/work graph.omni
omnigraph change --branch agent-a/work … graph.omni
# … many mutations …
omnigraph branch merge agent-a/work --into main ./graph.omni
omnigraph branch merge agent-a/work --into main graph.omni
# Agent B (running concurrently)
omnigraph branch create --from main agent-b/work ./graph.omni
omnigraph change --branch agent-b/work … ./graph.omni
omnigraph branch create --from main agent-b/work graph.omni
omnigraph change --branch agent-b/work … graph.omni
# … many mutations …
omnigraph branch merge agent-b/work --into main ./graph.omni
omnigraph branch merge agent-b/work --into main graph.omni
```
Each agent sees a consistent snapshot of `main` at the time it forked. The first merge to `main` lands as a fast-forward (or a no-op if no concurrent change). The second merge runs three-way: rows touched by both branches surface as `MergeConflict`s for the caller to resolve.