From 5328c91341210cab18bf80b5d83753a7d806f90e Mon Sep 17 00:00:00 2001 From: aaltshuler Date: Thu, 11 Jun 2026 23:45:18 +0300 Subject: [PATCH] =?UTF-8?q?refactor(cli):=20drop=20cluster=20init=20?= =?UTF-8?q?=E2=80=94=20no=20replacement=20scaffold?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Andrew's call, and the right one by the repo's own lens: a minimal cluster.yaml is five lines; a generator is a second copy of the schema to keep in sync forever, emitting a file that is unusable until hand-edited anyway (graphs: {} cannot apply or serve). Terraform has no config scaffolder either. New users copy from the cluster quick-start; migrants get a ready-to-review cluster.yaml from config migrate. RFC-008 stage 3 becomes purely subtractive. Co-Authored-By: Claude Fable 5 --- crates/omnigraph-cli/src/cli.rs | 17 -------- crates/omnigraph-cli/src/main.rs | 37 ---------------- crates/omnigraph-cli/tests/cli_cluster.rs | 46 -------------------- docs/dev/rfc-008-deprecate-omnigraph-yaml.md | 10 +++-- docs/user/cli-reference.md | 3 +- 5 files changed, 8 insertions(+), 105 deletions(-) diff --git a/crates/omnigraph-cli/src/cli.rs b/crates/omnigraph-cli/src/cli.rs index 6b89f0e..7b976b4 100644 --- a/crates/omnigraph-cli/src/cli.rs +++ b/crates/omnigraph-cli/src/cli.rs @@ -345,23 +345,6 @@ pub(crate) enum Command { #[derive(Debug, Subcommand)] pub(crate) enum ClusterCommand { - /// Scaffold a minimal cluster.yaml in the config directory (refuses - /// if one exists). The cluster checkout replaces the legacy - /// omnigraph.yaml scaffold (RFC-008 stage 3). - Init { - /// Directory to scaffold into (default: .) - #[arg(long, default_value = ".")] - config: PathBuf, - /// Optional deployment label (metadata.name) - #[arg(long)] - name: Option, - /// Optional storage root URI (s3://bucket/prefix); omit for the - /// config-dir layout - #[arg(long)] - storage: Option, - #[arg(long)] - json: bool, - }, /// Validate cluster.yaml and referenced schemas, queries, and policy files. Validate { /// Cluster config directory containing cluster.yaml. diff --git a/crates/omnigraph-cli/src/main.rs b/crates/omnigraph-cli/src/main.rs index 074ca25..8178e65 100644 --- a/crates/omnigraph-cli/src/main.rs +++ b/crates/omnigraph-cli/src/main.rs @@ -1217,43 +1217,6 @@ async fn main() -> Result<()> { } } Command::Cluster { command } => match command { - ClusterCommand::Init { - config, - name, - storage, - json, - } => { - let target = config.join("cluster.yaml"); - if target.exists() { - bail!( - "'{}' already exists — cluster init refuses to overwrite", - target.display() - ); - } - std::fs::create_dir_all(&config)?; - let mut scaffold = String::from("version: 1\n"); - if let Some(name) = &name { - scaffold.push_str(&format!("metadata:\n name: {name}\n")); - } - match &storage { - Some(root) => scaffold.push_str(&format!("storage: {root}\n")), - None => scaffold.push_str( - "# storage: s3://bucket/prefix # omit: this folder is the storage root\n", - ), - } - scaffold.push_str( - "graphs: {}\n# graphs:\n# knowledge:\n# schema: knowledge.pg\n# queries: queries/\n", - ); - std::fs::write(&target, scaffold)?; - if json { - print_json(&serde_json::json!({ "created": target.display().to_string() }))?; - } else { - println!( - "created {} — declare graphs, then `omnigraph cluster import` and `apply`", - target.display() - ); - } - } ClusterCommand::Validate { config, json } => { let output = validate_config_dir(config); finish_cluster_validate(&output, json)?; diff --git a/crates/omnigraph-cli/tests/cli_cluster.rs b/crates/omnigraph-cli/tests/cli_cluster.rs index 9f0326a..3b2eed3 100644 --- a/crates/omnigraph-cli/tests/cli_cluster.rs +++ b/crates/omnigraph-cli/tests/cli_cluster.rs @@ -950,49 +950,3 @@ graphs: assert!(!leaked.contains("phantom") && !leaked.contains("9999"), "{leaked}"); } -/// RFC-008 stage 3: `cluster init` scaffolds a minimal valid cluster.yaml -/// (the replacement for the retired omnigraph.yaml scaffold) and refuses -/// to overwrite. -#[test] -fn cluster_init_scaffolds_minimal_valid_config_and_refuses_overwrite() { - let temp = tempdir().unwrap(); - let output = cli() - .arg("cluster") - .arg("init") - .arg("--config") - .arg(temp.path()) - .arg("--name") - .arg("brain") - .output() - .unwrap(); - assert!(output.status.success(), "{output:?}"); - let text = fs::read_to_string(temp.path().join("cluster.yaml")).unwrap(); - assert!(text.contains("version: 1") && text.contains("name: brain"), "{text}"); - - // The scaffold validates clean. - let output = cli() - .arg("cluster") - .arg("validate") - .arg("--config") - .arg(temp.path()) - .arg("--json") - .output() - .unwrap(); - assert!(output.status.success(), "{output:?}"); - let payload: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap(); - assert_eq!(payload["ok"], true, "{payload}"); - - // Refuses a second run. - let output = cli() - .arg("cluster") - .arg("init") - .arg("--config") - .arg(temp.path()) - .output() - .unwrap(); - assert!(!output.status.success()); - assert!( - String::from_utf8_lossy(&output.stderr).contains("refuses to overwrite"), - "{output:?}" - ); -} diff --git a/docs/dev/rfc-008-deprecate-omnigraph-yaml.md b/docs/dev/rfc-008-deprecate-omnigraph-yaml.md index e9c37a9..a59be52 100644 --- a/docs/dev/rfc-008-deprecate-omnigraph-yaml.md +++ b/docs/dev/rfc-008-deprecate-omnigraph-yaml.md @@ -125,9 +125,13 @@ contract), retirement is staged, loud, and tooled: is the test of the migration map's completeness: any key it cannot place is a bug in this RFC. 3. **Stop scaffolding** *(landed)*. `omnigraph init` stops generating - `omnigraph.yaml` (it currently scaffolds one into cwd — the source of - the test-pollution bug). `omnigraph cluster init` (new, small) scaffolds - a minimal `cluster.yaml` instead. + `omnigraph.yaml` (it scaffolded one into cwd — the source of the + test-pollution bug). **No replacement scaffold**: a minimal + `cluster.yaml` is five lines; a generator would be a second copy of the + schema to keep in sync, producing a file that is unusable until + hand-edited anyway (Terraform has no config scaffolder either). New + users copy from the cluster quick-start; migrants get a ready-to-review + `cluster.yaml` from `config migrate`. 4. **Opt-in strict.** `OMNIGRAPH_NO_LEGACY_CONFIG=1` turns the warning into an error — for teams that finished migrating and want regressions caught. 5. **Remove at the next major.** Loading the file becomes an error pointing diff --git a/docs/user/cli-reference.md b/docs/user/cli-reference.md index e787ca2..62e3e0d 100644 --- a/docs/user/cli-reference.md +++ b/docs/user/cli-reference.md @@ -8,7 +8,7 @@ Top-level command families and subcommands. Graph-targeting commands accept a po | Command | Purpose | |---|---| -| `init` | `--schema ` → initialize a graph (no longer scaffolds `omnigraph.yaml` — RFC-008; use `cluster init` for a config scaffold) | +| `init` | `--schema ` → initialize a graph (no longer scaffolds `omnigraph.yaml` — RFC-008; start cluster configs from the [cluster.md](cluster.md) quick-start or `config migrate`) | | `load` | bulk load a branch, local or remote (`--mode overwrite\|append\|merge` is **required** — overwrite is destructive, so there is no default). Without `--from` the target branch must exist; `--from ` forks a missing `--branch` from `` first | | `ingest` | deprecated alias of `load --from ` (defaults: `--from main --mode merge`); prints a one-line warning to stderr | | `query` (alias: `read`) | run named read query; source via `--query `, `-e`/`--query-string `, or `--alias ` (exactly one). `read` is the deprecated previous name and prints a one-line warning to stderr | @@ -19,7 +19,6 @@ Top-level command families and subcommands. Graph-targeting commands accept a po | `commit list \| show` | inspect commit graph | | `schema plan \| apply \| show (alias: get)` | migrations | | `lint` (alias: `check`) | offline / graph-backed query validation. Replaces `query lint` / `query check`, which are kept as deprecated argv-level shims that print a one-line warning and rewrite to `omnigraph lint` | -| `cluster init` | scaffold a minimal `cluster.yaml` (`--name`, `--storage`); refuses to overwrite | | `config migrate` | propose (or `--write`: apply) the RFC-008 split of a legacy `omnigraph.yaml` — team half → ready-to-review `cluster.yaml`, personal half → `~/.omnigraph/config.yaml` (key-level merge, existing entries win), plus dropped-key reasons and manual steps | | `cluster validate \| plan \| apply \| approve \| status \| refresh \| import \| force-unlock` | declarative cluster control plane. `validate` checks a local `cluster.yaml` folder and referenced schema/query/policy files; `plan` diffs it against local JSON state at `__cluster/state.json`, annotates dispositions, and embeds real schema-migration previews; `apply` converges the cluster — stored-query/policy catalog writes (content-addressed under `__cluster/resources/`), graph creates, schema updates (soft drops only; `--as` records the actor), and graph deletes behind a digest-bound approval from `cluster approve --as ` (`apply`/`approve` default the actor from the per-operator `omnigraph.yaml`'s `cli.actor` when `--as` is omitted; nothing else in that file affects cluster commands); what apply converges is what an `omnigraph-server --cluster ` deployment serves on its next restart (omnigraph.yaml deployments are unaffected); `status` reads the state ledger; `refresh`/`import` explicitly update local JSON state from read-only graph observations; `force-unlock ` manually removes a held local state lock by exact id | | `optimize` | non-destructive Lance compaction (skips tables with `Blob` columns or uncovered drift; `--json` reports `skipped`) |