mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-07-06 02:52:11 +02:00
feat(cli)!: schema apply refuses a cluster-managed graph (RFC-011 D10) (#253)
`omnigraph schema apply` against a cluster-managed graph's storage root bypassed the cluster ledger/recovery/approvals. Mirror `init`'s refusal: on the embedded (direct-store) path, if the resolved URI is inside a cluster (`cluster_root_for_graph_uri`), bail and point at `cluster apply`. The served (`--server`) path is unaffected — it addresses a server, not a storage root. `schema plan`/`show` (read-only) are untouched. Two e2e tests injected "out-of-band drift" via this exact CLI path; since the CLI now refuses it, they inject drift via a direct engine `apply_schema` against the storage root instead — a faithful control-plane bypass, which is what out-of-band drift is. New regression: `schema_apply_refuses_a_cluster_managed_graph_and_signposts_cluster_apply`. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
4601e5f4bf
commit
d2340f19e9
5 changed files with 89 additions and 33 deletions
|
|
@ -1039,6 +1039,47 @@ fn init_refuses_a_cluster_managed_path_and_signposts_cluster_apply() {
|
|||
assert!(!temp.path().join("graphs").join("sneaky.omni").exists());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn schema_apply_refuses_a_cluster_managed_graph_and_signposts_cluster_apply() {
|
||||
// RFC-011 Decision 10: a direct `schema apply` against a cluster-managed
|
||||
// graph's storage root would bypass the ledger/recovery/approvals, so it is
|
||||
// refused and points at `cluster apply` (mirrors `init`'s refusal).
|
||||
let temp = applied_knowledge_cluster();
|
||||
// A schema that WOULD change the graph (adds `bio`) — so the no-mutation
|
||||
// assertion below is meaningful, not a no-op re-apply.
|
||||
fs::write(
|
||||
temp.path().join("people_v2.pg"),
|
||||
"node Person {\n name: String @key\n age: I32?\n bio: String?\n}\n",
|
||||
)
|
||||
.unwrap();
|
||||
let out = output_failure(
|
||||
cli()
|
||||
.arg("schema")
|
||||
.arg("apply")
|
||||
.arg("--schema")
|
||||
.arg(temp.path().join("people_v2.pg"))
|
||||
.arg("--store")
|
||||
.arg(temp.path().join("graphs").join("knowledge.omni")),
|
||||
);
|
||||
let stderr = String::from_utf8_lossy(&out.stderr);
|
||||
assert!(
|
||||
stderr.contains("cluster apply"),
|
||||
"schema apply against a cluster-managed graph should signpost `cluster apply`; got: {stderr}"
|
||||
);
|
||||
// And it bailed BEFORE mutating: the live schema still lacks `bio`.
|
||||
let show = output_success(
|
||||
cli()
|
||||
.arg("schema")
|
||||
.arg("show")
|
||||
.arg(temp.path().join("graphs").join("knowledge.omni")),
|
||||
);
|
||||
assert!(
|
||||
!stdout_string(&show).contains("bio"),
|
||||
"the refused apply must not have changed the live schema; got: {}",
|
||||
stdout_string(&show)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_outside_a_cluster_still_works() {
|
||||
// Regression guard: ordinary init (no cluster layout) is unaffected.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue