mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-06-15 01:55:13 +02:00
feat(cli): RFC-010 Slice 1 — declared plane capability surface + honest addressing (#217)
* feat(cli): declared plane capability surface + wrong-plane guard (RFC-010 Slice 1) New `planes.rs` is the single source of truth for which plane each subcommand belongs to (Data / Storage / Control / Session). `command_plane` is an exhaustive match — adding a `Command` variant is a compile error until its plane is declared, so the surface cannot silently drift from the command set. It descends into the nested enums where the plane differs per subcommand (`schema plan` is storage while `schema show/apply` are data; `queries validate` opens the graph while `queries list` reads only config). `guard_addressing` runs once in `main` before dispatch: the data-plane addressing flags `--server`/`--graph` on any non-data verb now fail with one declared, pinned error instead of being silently ignored (`optimize --server prod` previously dropped `--server`). `init`'s message drops the `--target` half since it takes only a positional URI today. Test: `cli_schema_config::schema_plan_with_server_flag_errors_wrong_plane` pins the per-subcommand label, proving the guard descends into the nested enum. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(cli): storage-plane verbs fail loudly on a remote target (RFC-010 Slice 1) `optimize`/`repair`/`cleanup` switch from `resolve_uri` to `resolve_local_uri`, so a `--target` (or positional URI) that resolves to a remote server now fails with a declared storage-plane message instead of whatever `Omnigraph::open` said about an `http(s)://` URI. The `resolve_local_graph` bail is reworded to that storage-plane message, so every storage verb already on the local resolver (`schema plan`, `queries validate`, `lint`) speaks with one voice. Net: `optimize --target knowledge` resolves to the graph's storage URI and runs embedded; `optimize --target prod` (remote) fails loudly; `optimize --server` is caught earlier by the guard. Positional-URI invocations are unchanged. Tests (pinned strings, per RFC-010's test plan): optimize happy path on a local graph, `optimize --server` wrong-plane error, `optimize <https>` storage-plane error; the existing `query_lint_rejects_http_targets_without_schema` assertion is updated to the new shared message. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
2ddb88fad9
commit
106356ab25
5 changed files with 232 additions and 6 deletions
|
|
@ -142,6 +142,47 @@ fn embed_seed_preserves_non_entity_rows() {
|
|||
assert_eq!(embedded[2]["to"], "dec-alpha");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn optimize_json_succeeds_on_local_graph() {
|
||||
// Happy path for the resolve_local_uri swap (RFC-010 Slice 1): a positional
|
||||
// local path still resolves and runs embedded.
|
||||
let temp = tempdir().unwrap();
|
||||
let graph = graph_path(temp.path());
|
||||
init_graph(&graph);
|
||||
load_fixture(&graph);
|
||||
|
||||
let output = output_success(cli().arg("optimize").arg("--json").arg(&graph));
|
||||
let payload: Value = serde_json::from_slice(&output.stdout).unwrap();
|
||||
assert!(payload["tables"].as_array().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn optimize_with_server_flag_errors_wrong_plane() {
|
||||
// RFC-010 Slice 1: --server is a data-plane addressing flag; on a
|
||||
// storage-plane verb the guard rejects it loudly (was: silently ignored).
|
||||
let output = output_failure(cli().arg("optimize").arg("--server").arg("prod"));
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
assert!(
|
||||
stderr.contains("`optimize` is a storage-plane command")
|
||||
&& stderr.contains("--server/--graph address the data plane and do not apply")
|
||||
&& stderr.contains("Use --target <name> or a storage URI."),
|
||||
"wrong-plane guard message not found; got: {stderr}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn optimize_with_remote_target_errors_storage_plane() {
|
||||
// RFC-010 Slice 1: a maintenance verb pointed at a remote URI fails loudly
|
||||
// and declaratively (was: whatever Omnigraph::open said about an https URI).
|
||||
let output = output_failure(cli().arg("optimize").arg("https://graph.example.invalid"));
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
assert!(
|
||||
stderr.contains("`optimize` is a storage-plane command and needs direct storage access")
|
||||
&& stderr.contains("remote server"),
|
||||
"storage-plane remote-target message not found; got: {stderr}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn repair_json_reports_noop_on_clean_graph() {
|
||||
let temp = tempdir().unwrap();
|
||||
|
|
@ -542,8 +583,12 @@ query list_people() {
|
|||
.arg("http://127.0.0.1:8080"),
|
||||
);
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
// RFC-010 Slice 1: the storage-plane verbs now share one declared message
|
||||
// (was: "query lint is only supported against local graph URIs …").
|
||||
assert!(
|
||||
stderr.contains("query lint is only supported against local graph URIs in this milestone")
|
||||
stderr.contains("`query lint` is a storage-plane command and needs direct storage access")
|
||||
&& stderr.contains("remote server"),
|
||||
"storage-plane remote-target message not found; got: {stderr}"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue