From 34ed2435ecf45938bb88829da25c3a8352fee5d7 Mon Sep 17 00:00:00 2001 From: aaltshuler Date: Tue, 27 Oct 2026 13:04:41 +0200 Subject: [PATCH 1/3] docs(rfc): propose served optimization with minimal native orchestration --- docs/rfcs/2026-10-25-served-optimization.md | 358 ++++++++++++++++++++ docs/rfcs/README.md | 1 + 2 files changed, 359 insertions(+) create mode 100644 docs/rfcs/2026-10-25-served-optimization.md diff --git a/docs/rfcs/2026-10-25-served-optimization.md b/docs/rfcs/2026-10-25-served-optimization.md new file mode 100644 index 000000000..a25cf5a04 --- /dev/null +++ b/docs/rfcs/2026-10-25-served-optimization.md @@ -0,0 +1,358 @@ +--- +rfc: "2026-10-25-served-optimization" +title: "Served optimization" +track: maintainer +status: draft +implementation: in-progress +authors: + - aaltshuler +created: 2026-10-25 +updated: 2026-10-27 +discussion: https://github.com/ModernRelay/omnigraph/pull/1177 +supersedes: [] +superseded_by: [] +blocked_on: + - "Align the implementation with the synchronous execution contract and qualify disconnect, publication and shutdown outcomes." + - "Qualify finite native work bounds and the supported deployment resource envelope before enabling execution." + - "Before managed enablement: amend LCY-04.2 and DEC-08-76 and qualify native enforcement of control-plane capacity allocation." +--- + +# RFC: Served optimization + +## In plain language + +**Purpose:** let an operator optimize a graph while its server stays running. + +**The problem:** as data changes, its storage can become fragmented. +`optimize` reorganizes data files and maintains supported indexes so the engine +can read them more efficiently, while preserving the graph's data. Today the +command opens storage itself. Running it beside a server would introduce a +second writer that the server does not control. + +**The proposed solution:** send the request to the server that already manages +the graph. That server checks permission and available capacity, runs the +existing engine operation, and returns a report of what happened. The command +waits for that report. Reads can continue; writes may wait while optimization +holds the resources it needs. + +**Key design decisions:** + +- **Keep management in the control plane.** For managed clusters, it decides + when to request work and keeps scheduling records, operational history and + collected logs. The server checks each request and owns its execution; the + engine performs the storage changes safely. A self-hosted operator can call + the server directly without a control plane. +- **Keep the server interface small.** One request optimizes one graph's + `main` branch and returns its result. The server does not gain a persistent + jobs database, automatic scheduler or maintenance recovery command. Looking + up an individual operation after disconnect is outside this first slice. +- **Reuse the existing safety rules.** The engine makes the optimized graph + visible as one complete change. The server enforces permissions and work + limits, and admits only one optimization at a time per cluster. Optimization + still consumes server resources; this proposal does not move the computation + to the control plane or promise maintenance without impact on other work. +- **Be honest when the answer is lost.** Losing the connection does not cancel + the work. If the caller never receives the result, the outcome is unknown; + neither the CLI nor the control plane automatically submits it again. The + server does not promise to recover that request's report after a restart. + +**The tradeoff:** this gives operators a safe way to request optimization with +little new server machinery. It deliberately gives up guaranteed recovery of +every request's result after a crash. The control plane can keep a history of +what it requested and observed, but cannot turn a missing answer into proof +that the work succeeded or failed. + +## Summary + +Expose `optimize` through the server that already owns the cluster. The server +owns safe execution and returns the exact result it observes. The control plane +owns scheduling, delivery, operational history and collected logs. The engine +keeps its existing snapshot, staging and graph-publication contract. + +The first slice is one synchronous request for one graph's `main`. It adds no +durable maintenance journal, scheduler, restart lookup or recovery command. +A lost response leaves the caller's outcome unknown; it never authorizes an +automatic retry. This is a deliberate limit on the execution contract. + +The implementation in [#1177](https://github.com/ModernRelay/omnigraph/pull/1177) +currently includes a stronger durable invocation protocol. It must be reduced +to this revised design before it can claim conformance. This document changes +the proposal; it does not claim the implementation already matches it. + +## Motivation + +The existing direct `optimize` opens graph storage. A running cluster already +owns that storage, so an independent process cannot safely optimize beside it. +Operators need to run the existing operation through that owner. + +Durable job tracking is a separate requirement. Making receipt retention a +prerequisite for serving creates an availability dependency unrelated to whether +the graph is safe. A manual operation does not need its own sequence ledger, +publication-witness protocol or offline recovery workflow to be useful. + +## User and operational behavior + +For a configured server target, the proposed command is: + +```bash +omnigraph optimize --target prod --graph knowledge +omnigraph optimize --target prod --graph knowledge --json +``` + +The command waits for this attempt's result. It reports the accepted input +commit, its resulting commit or unchanged commit, table statistics, skips, +deferred indexes and any optional-work failures. It may block writes while +holding existing gates; admitted reads retain their snapshots. + +The existing direct command remains available under normal exclusive native +ownership. A remote refusal never falls back to direct storage. Existing +target selection, actor assertion and result-output conventions apply. There +are no new `--no-wait`, `--operation-id` or `--writers-stopped` modes. + +| Observation | Meaning and caller action | +|---|---| +| Definitive refusal before effects | This request did not optimize. Correct the reported cause before making another request. | +| Completed result | Use this attempt's exact report, including no-work and optional-work outcomes. | +| Lost response or observation timeout | Execution may still be running or may have completed. Record unknown; do not automatically resubmit. | +| Native failure | Preserve its typed effect and settlement evidence; an error alone does not prove that nothing published. | + +A later explicitly requested optimization is a new attempt against a fresh +accepted snapshot, after native admission permits it. It may perform additional +work or publish another commit. It is not replay, recovery or proof that the +previous attempt failed. A changed graph head or equal logical data does not +identify the old attempt's result. + +## Design + +### Responsibility boundary + +| Owner | Responsibility | +|---|---| +| Control plane | Scheduling, fleet capacity allocation, delivery policy, durable workflow history, log collection/retention and operator presentation. | +| Server | Authentication, local admission, ownership of execution through disconnect, bounded execution status and exact responses. | +| Engine | Authorization at the native entry point, accepted snapshot, physical optimization, graph publication and typed storage outcomes. | + +The control plane records intent, delivery attempts and responses it actually +observed. Its records are authoritative for its workflow, not native acceptance +or publication. An unobserved result remains unknown. Self-hosted callers can +use the same native endpoint without deploying a control plane. + +The server emits ordinary correlated diagnostic events and metrics through the +existing observability facilities. It does not persist a second operational +history or manage log delivery. Loss of an observational record is neither +proof of safety nor a reason to close otherwise valid native admission. +This minimizes management overhead; physical optimization still runs in the +engine. Moving that computation to independent workers is out of scope. + +### Native execution and outcomes + +Add the graph policy action `optimize`, scoped to `main`. Installed policies +must explicitly grant it; `admin`, configuration management and membership do +not imply it. HTTP resolves the bearer to an actor; cluster admission checks +current applied policy and the engine checks the same action before effects. +Keep normal access discovery and the existing `--as` credential-actor assertion. +An assertion never supplies a trusted actor. Do not retain bearer bytes. + +Reuse the existing cluster admission, owned-operation runtime and deployment +gate. Admit at most one optimization per cluster and serialize it with +configuration deployment. Refuse another optimization while that slot or the +deployment gate is busy; ordinary writes keep their existing gate behavior. +Accepted work remains owned after its HTTP waiter exits. Disconnect and +observation deadlines end waiting, not native execution. + +The engine retains its schema, branch and sorted-table gates, one coherent +accepted snapshot, detached staging and single graph-manifest publication. +Capture the exact before/after commits as part of that attempt, while the +relevant gates are held; never infer the result from a later head read. +Direct and served entry points share these semantics. Resource limits constrain +work; their presence must not select a different publication or error protocol. + +Separate known graph publication from optional derived-artifact work. A settled +artifact failure is reported explicitly without relabeling a known commit as +unknown. Genuine uncertain I/O, including a possibly accepted write to a mutable +cache object, still needs the existing settlement and containment rules. Never +discard that uncertainty merely because the data is derived. +Key-scoped storage uncertainty does not itself close process admission; +containment remains limited to the cases defined by the existing storage-outcome +contract, rather than every failure after acceptance. + +Shutdown and successor admission follow the existing +[owned-operation](2026-09-30-owned-server-operations.md) and +[storage-outcome](2026-10-19-storage-outcomes-and-restartable-ownership.md) +contracts. A dropped future does not exclude accepted I/O or a predecessor. +There is no additional startup blocker for a missing maintenance receipt, no +neutral graph commit solely to settle one, and no maintenance-specific unlock. + +### HTTP, receipts and status + +Add `POST /graphs/{graph_id}/optimize` through the shared operation registry, +typed API and [HTTP conventions](2026-10-19-http-api-conventions.md). The graph +is addressed once, in the path. The initial operation uses the existing optimize +behavior without new request options; clients do not copy server ceilings into +a maintenance envelope. +Return the exact completed report after durable publication, or the typed +failure. A no-work result names the unchanged commit. Do not return `202` as a +promise of durable acceptance. + +Here, a receipt means the completed response observed by the caller. It is not +a server-persisted record. The first slice exposes completion through that +response and keeps execution status in the existing owned-operation runtime; +it adds no per-invocation lookup endpoint. A request correlation ID supplies +identification only, not idempotency, deduplication or restart recovery. +Clients and control-plane delivery code must disable automatic POST retries +after ambiguous dispatch. Native status may be lost at restart. + +MCP exposure and asynchronous lookup are deferred. If reconnect lookup becomes +necessary, a separate bounded, process-local extension can retain active and +terminal statuses scoped to the server incarnation. Missing, evicted or old +statuses must mean unknown, never not-executed, and lookup must never execute +work. That extension must define its limits and authorization before shipping; +this RFC does not require a generic jobs API to expose optimize. + +### Bounds and enablement + +Execution is disabled until explicitly configured and qualified. Keep typed +limits under the server's existing configuration/builder ownership, without a +maintenance-only YAML file or parser. The server selects finite ceilings for +tables, fragments, physical rows, source bytes and file references; callers +cannot raise them. Start with one dataset and one compaction task in flight. +Bound metadata enumeration and result construction as well as physical work. + +Validate the complete accepted source inventory before the first rewrite, +including dropped-column materialization, catalog work, table manifests, +index files, deletion files and managed Blob payloads. External Blob references +remain references; their payloads are not fetched. Count before exceeding the +limit, rather than materializing an unbounded inventory and checking afterwards. +Unknown sizes or unsupported layouts refuse. Preserve the current full-text +rebuild boundary; index/statistics/storage errors must not masquerade as +insufficient vector training data. Do not add historical-prefix scans or output +truncation. + +Finite source ceilings and concurrency do not establish hard memory, CPU, +scratch-space or I/O-rate guarantees. Native work and completion resources need +measured limits and process/platform isolation for the supported envelope, +including competition with foreground requests. Existing request-count and +request-byte admission is not a substitute. Ordinary bounded result delivery +remains necessary; the durable-journal report reservation and recovery-envelope +machinery are not part of this contract. + +Managed execution additionally requires native enforcement of control-plane +capacity allocation on every entry point, including direct remote CLI calls. +A proxy check alone is insufficient. State support through explicit deployment +capability and resource admission, not an inference from static-token, signed +token or OIDC authentication. Until qualified, managed execution stays disabled. + +## Invariants + +The [architectural invariants](../dev/invariants.md) remain unchanged: one +accepted snapshot, detached pre-publication effects, one graph publication, +engine authorization, bounded work and typed uncertain outcomes. Derived indexes +and caches affect cost, never logical correctness. Existing ownership and I/O +settlement remain necessary even when observational status is missing. + +There is no second storage writer, manifest-derived job queue, custom WAL, +shadow publication authority, implicit retry, or inline content-write rebuild. +The control plane cannot bypass native policy, resource admission or fencing. +Cleanup, repair, history deletion and isolated workers remain outside this RFC. + +## Compatibility and reversibility + +This design adds no graph format or durable maintenance object. Adding the +`optimize` action requires policy and access-discovery updates for direct and +served callers. Removing the endpoint later leaves ordinary graph commits and +detached output governed by existing retention and cleanup rules. + +The candidate in #1177 has not established a supported wire or disk contract. +Remove its maintenance journal, sequence protocol, lookup/recovery routes, +receipt-only admission blocks and recovery CLI flags before shipping. Do not +silently delete an outstanding journal in an experimental deployment: exclude +its owner and settle its native work using the candidate's recovery procedure +before switching binaries. Migration of such experimental roots is not supplied +by this documentation change. + +The control-plane specifications +[LCY-04.2](https://github.com/ModernRelay/og-control-plane/blob/58a29d6dd4ea00cef84829f03181ffe740d01974/specs/08-LCY-Lifecycle.md#L702) +and [DEC-08-76](https://github.com/ModernRelay/og-control-plane/blob/58a29d6dd4ea00cef84829f03181ffe740d01974/specs/02-DEC-Decisions.md#L3601) +currently require durable native invocation identity, acceptance, results and +original-ID reconciliation. Amend those requirements before claiming managed +compatibility with this weaker observation contract. Moving the same guarantees +into control-plane bookkeeping would not satisfy them. + +## Alternatives + +- **Keep direct-only optimization:** requires stopping the owner for routine + physical maintenance; does not solve the operational problem. +- **Durable native invocation journal:** supports original-ID lookup and + publication reconciliation across crashes, with unresolved or partial outcomes + when evidence is insufficient. It adds persistent identities, retention, + recovery and an availability dependency on receipt settlement. Defer until a + concrete use case requires that stronger guarantee. +- **Reuse the deployment ledger:** couples configuration convergence to physical + optimization without removing durable invocation complexity. +- **Control-plane-only execution receipts:** cannot prove native publication + when a response was lost. Keep workflow history there and preserve unknowns. +- **Process-local asynchronous status:** useful for reconnecting observers, but + adds retention, authorization and incarnation semantics. Defer until the + synchronous slice demonstrates that need. + +## Evidence and tests + +Extend the existing engine `integration/maintenance.rs`, policy, cluster +admission, server operation/runtime and CLI maintenance owners. Prove: + +- Denied actors, unsupported deployments, exhausted bounds and competing work + refuse before physical effects; direct calls cannot bypass engine policy. +- Disconnect and timeout leave execution owned, with no client resubmission. + Shutdown and predecessor exclusion preserve native I/O settlement. +- Success reports this attempt's exact commit; no-work reports the unchanged + commit. Lost responses and crashes never become inferred success or failure. +- Known publication plus settled optional failure preserves both facts; + uncertain publication or optional I/O retains the required native fencing. +- Rows, schema, Blob values, index behavior, retained history and live branches + are preserved. Use GQT for expressible logical assertions; retain Rust owners + for physical mechanisms, concurrency and faults. + +Update the registry, OpenAPI, CLI contracts and DST storage-cost golden with +implementation changes. Verify that no receipt lookup, journal write or +maintenance-specific startup gate remains. Qualify resource and live-cloud +settlement separately; local correctness tests cannot establish those limits. +Measure large Blob rows, wide/high-dimensional rows, many small fragments and +index rebuilds under the intended allocation. Publish the tested limits. + +The candidate's source accounting was inspected against unmodified Lance +13.0.0: [compaction planning/execution](https://docs.rs/crate/lance/13.0.0/source/src/dataset/optimize.rs), +[fragment metadata](https://docs.rs/crate/lance-table/13.0.0/source/src/format/fragment.rs), +[index inventories](https://docs.rs/crate/lance-table/13.0.0/source/src/format/index.rs) +and [object-store sizing](https://docs.rs/crate/lance-io/13.0.0/source/src/object_store.rs). +Lance's compaction byte option alone excludes Blob-v2 payload accounting and +does not bound all optimization work. Reuse qualified native mechanisms rather +than introducing another transaction or recovery protocol. Tests of the prior +journal design are not evidence that this revised contract is implemented. + +## Rollout + +1. Review this reduced contract and align #1177's code, tests, OpenAPI and user + documentation. Keep execution disabled during qualification. +2. Enable the synchronous self-hosted slice only for the measured supported + resource envelope. Preserve explicit unknown outcomes and existing shutdown + behavior; publish the policy change and limits with the implementation. +3. Amend the control-plane specifications and qualify native capacity admission + before enabling managed calls. Keep scheduling and operational history in + the control plane. This phase does not gate the self-hosted slice. + +## Unresolved questions + +No additional design decision is required for the synchronous scope. The +implementation, resource and managed-integration evidence gates are listed in +`blocked_on`. Durable receipts, asynchronous lookup and worker offload require +separate justification and are not implied follow-on commitments. + +## Decision log + +- **2026-10-27:** Narrow the initial candidate to safe execution through the + existing owner. Replace durable invocation/lookup and offline recovery with + synchronous exact results and explicit unknown outcomes. Assign orchestration, + history and log collection to the control plane; retain native authorization, + resource admission, publication and settlement. Record the control-plane + specification changes needed before managed enablement. The implementation + still needs to be aligned; this revision does not accept its earlier protocol. diff --git a/docs/rfcs/README.md b/docs/rfcs/README.md index 5b8afb7a7..60c56421b 100644 --- a/docs/rfcs/README.md +++ b/docs/rfcs/README.md @@ -254,3 +254,4 @@ then dated RFCs by date. | [2026-10-19](2026-10-19-http-api-conventions.md) | HTTP API conventions | maintainer | accepted | complete | | [2026-10-19](2026-10-19-storage-outcomes-and-restartable-ownership.md) | Storage outcomes per operation and restartable ownership | maintainer | accepted | in-progress | | [2026-10-20](2026-10-20-operator-connections-and-credential-providers.md) | Operator profiles and credential providers | maintainer | draft | in-progress | +| [2026-10-25](2026-10-25-served-optimization.md) | Served optimization | maintainer | draft | in-progress | From 3087f7dd3535c122352d7989fbf5e56ab1de2d1c Mon Sep 17 00:00:00 2001 From: aaltshuler Date: Tue, 27 Oct 2026 13:05:25 +0200 Subject: [PATCH 2/3] docs(rfc): link independent served optimization review --- docs/rfcs/2026-10-25-served-optimization.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/rfcs/2026-10-25-served-optimization.md b/docs/rfcs/2026-10-25-served-optimization.md index a25cf5a04..c8d90b589 100644 --- a/docs/rfcs/2026-10-25-served-optimization.md +++ b/docs/rfcs/2026-10-25-served-optimization.md @@ -8,7 +8,7 @@ authors: - aaltshuler created: 2026-10-25 updated: 2026-10-27 -discussion: https://github.com/ModernRelay/omnigraph/pull/1177 +discussion: https://github.com/ModernRelay/omnigraph/pull/1186 supersedes: [] superseded_by: [] blocked_on: @@ -356,3 +356,7 @@ separate justification and are not implied follow-on commitments. resource admission, publication and settlement. Record the control-plane specification changes needed before managed enablement. The implementation still needs to be aligned; this revision does not accept its earlier protocol. +- **2026-10-27:** Move design review to + [#1186](https://github.com/ModernRelay/omnigraph/pull/1186), independently of + the implementation in #1177. The proposal and its qualification gates are + unchanged by the split. From 5d5bf01ee04a327a4116c8ae6524a5e1d8bd50f3 Mon Sep 17 00:00:00 2001 From: aaltshuler Date: Tue, 27 Oct 2026 13:15:56 +0200 Subject: [PATCH 3/3] docs(rfc): explain optimization decisions and tradeoffs independently --- docs/rfcs/2026-10-25-served-optimization.md | 689 +++++++++++--------- 1 file changed, 393 insertions(+), 296 deletions(-) diff --git a/docs/rfcs/2026-10-25-served-optimization.md b/docs/rfcs/2026-10-25-served-optimization.md index c8d90b589..228761ad4 100644 --- a/docs/rfcs/2026-10-25-served-optimization.md +++ b/docs/rfcs/2026-10-25-served-optimization.md @@ -12,351 +12,448 @@ discussion: https://github.com/ModernRelay/omnigraph/pull/1186 supersedes: [] superseded_by: [] blocked_on: - - "Align the implementation with the synchronous execution contract and qualify disconnect, publication and shutdown outcomes." - - "Qualify finite native work bounds and the supported deployment resource envelope before enabling execution." - - "Before managed enablement: amend LCY-04.2 and DEC-08-76 and qualify native enforcement of control-plane capacity allocation." + - "Implement and verify the request, disconnect, publication and shutdown behavior specified here." + - "Measure and enforce finite work limits within a supported deployment resource allocation before enabling execution." + - "Before managed enablement: amend the control-plane requirements for durable operation results and verify capacity enforcement at every native entry point." --- # RFC: Served optimization -## In plain language - -**Purpose:** let an operator optimize a graph while its server stays running. - -**The problem:** as data changes, its storage can become fragmented. -`optimize` reorganizes data files and maintains supported indexes so the engine -can read them more efficiently, while preserving the graph's data. Today the -command opens storage itself. Running it beside a server would introduce a -second writer that the server does not control. - -**The proposed solution:** send the request to the server that already manages -the graph. That server checks permission and available capacity, runs the -existing engine operation, and returns a report of what happened. The command -waits for that report. Reads can continue; writes may wait while optimization -holds the resources it needs. - -**Key design decisions:** - -- **Keep management in the control plane.** For managed clusters, it decides - when to request work and keeps scheduling records, operational history and - collected logs. The server checks each request and owns its execution; the - engine performs the storage changes safely. A self-hosted operator can call - the server directly without a control plane. -- **Keep the server interface small.** One request optimizes one graph's - `main` branch and returns its result. The server does not gain a persistent - jobs database, automatic scheduler or maintenance recovery command. Looking - up an individual operation after disconnect is outside this first slice. -- **Reuse the existing safety rules.** The engine makes the optimized graph - visible as one complete change. The server enforces permissions and work - limits, and admits only one optimization at a time per cluster. Optimization - still consumes server resources; this proposal does not move the computation - to the control plane or promise maintenance without impact on other work. -- **Be honest when the answer is lost.** Losing the connection does not cancel - the work. If the caller never receives the result, the outcome is unknown; - neither the CLI nor the control plane automatically submits it again. The - server does not promise to recover that request's report after a restart. - -**The tradeoff:** this gives operators a safe way to request optimization with -little new server machinery. It deliberately gives up guaranteed recovery of -every request's result after a crash. The control plane can keep a history of -what it requested and observed, but cannot turn a missing answer into proof -that the work succeeded or failed. - ## Summary -Expose `optimize` through the server that already owns the cluster. The server -owns safe execution and returns the exact result it observes. The control plane -owns scheduling, delivery, operational history and collected logs. The engine -keeps its existing snapshot, staging and graph-publication contract. - -The first slice is one synchronous request for one graph's `main`. It adds no -durable maintenance journal, scheduler, restart lookup or recovery command. -A lost response leaves the caller's outcome unknown; it never authorizes an -automatic retry. This is a deliberate limit on the execution contract. - -The implementation in [#1177](https://github.com/ModernRelay/omnigraph/pull/1177) -currently includes a stronger durable invocation protocol. It must be reduced -to this revised design before it can claim conformance. This document changes -the proposal; it does not claim the implementation already matches it. +### In plain language + +This RFC proposes running `optimize` through a graph's running server. +Optimization reorganizes data files and maintains supported indexes to improve +storage and read efficiency while preserving the graph's logical data. + +Today, the CLI performs optimization by opening storage itself. That is suitable +when no server owns the graph. While a server is running, maintenance must go +through that server so it can coordinate the work with other requests. The +proposed command sends one request and waits for a report of what happened. + +The server checks permission, limits the work and runs it through the engine, +which is the database code responsible for storage. The control plane, when +used, is the separate service that manages clusters: it schedules requests, +allocates resources and keeps operational history and collected logs. A +self-hosted operator can call the server without a control plane. + +The main design choices are: + +- **Use the existing server and engine.** This keeps optimization under the same + ownership and data-safety rules as other writes. The work still consumes + server resources and can delay ordinary writes. +- **Start with one request that waits for completion.** There is no separate + background-job API or later result lookup. This keeps the server's management + work small, but callers need to keep the connection open to receive the report. +- **Keep graph durability separate from report recovery.** A completed graph + change is saved in storage and survives a server restart, even if the caller + loses the response. This proposal + does not store reports for retrieval after a restart. If an answer is lost, + the caller records an unknown outcome and does not automatically repeat the + request. The failure example below explains why. + +The initial workflow is operator-requested optimization of one graph's `main` +branch. A control plane can schedule requests using the same execution contract +once the managed-enablement requirements below are met. Building that scheduler, +separate compute workers, cleanup of old data, repair and deletion of graph +history are outside this proposal. ## Motivation -The existing direct `optimize` opens graph storage. A running cluster already -owns that storage, so an independent process cannot safely optimize beside it. -Operators need to run the existing operation through that owner. +Repeated writes can leave many small data fragments or indexes that would +benefit from maintenance. An operator should be able to request that work +without stopping the server and handing its storage to a separate process. -Durable job tracking is a separate requirement. Making receipt retention a -prerequisite for serving creates an availability dependency unrelated to whether -the graph is safe. A manual operation does not need its own sequence ledger, -publication-witness protocol or offline recovery workflow to be useful. +The running server already coordinates changes to graph data and configuration. +A CLI process that independently opens the same storage would bypass that +coordination. Sending the request to the server solves this ownership problem; +adding another writer would require a different concurrency design. + +The initial workload is occasional, operator-requested maintenance with a +bounded amount of work. It can tolerate waiting and some interference with +ordinary writes. It does not require an audit system that can reconstruct every +maintenance request after a crash. Those assumptions motivate the execution +and result-retention choices below; they are limits of this proposal, not +claims that all future maintenance workloads will have the same needs. ## User and operational behavior -For a configured server target, the proposed command is: +With `prod` configured as a server target and `knowledge` as a graph on it: ```bash omnigraph optimize --target prod --graph knowledge omnigraph optimize --target prod --graph knowledge --json ``` -The command waits for this attempt's result. It reports the accepted input -commit, its resulting commit or unchanged commit, table statistics, skips, -deferred indexes and any optional-work failures. It may block writes while -holding existing gates; admitted reads retain their snapshots. - -The existing direct command remains available under normal exclusive native -ownership. A remote refusal never falls back to direct storage. Existing -target selection, actor assertion and result-output conventions apply. There -are no new `--no-wait`, `--operation-id` or `--writers-stopped` modes. - -| Observation | Meaning and caller action | -|---|---| -| Definitive refusal before effects | This request did not optimize. Correct the reported cause before making another request. | -| Completed result | Use this attempt's exact report, including no-work and optional-work outcomes. | -| Lost response or observation timeout | Execution may still be running or may have completed. Record unknown; do not automatically resubmit. | -| Native failure | Preserve its typed effect and settlement evidence; an error alone does not prove that nothing published. | - -A later explicitly requested optimization is a new attempt against a fresh -accepted snapshot, after native admission permits it. It may perform additional -work or publish another commit. It is not replay, recovery or proof that the -previous attempt failed. A changed graph head or equal logical data does not -identify the old attempt's result. +Both commands wait for the same result; `--json` selects machine-readable output. +The report identifies the input graph commit, the resulting or unchanged commit, +per-table work, deliberate skips, deferred indexes and optional-work failures. +An optimization can create a new commit because the stored layout changed even +though the graph's logical data did not. A no-work result identifies the +unchanged commit. + +| What the caller receives | What it establishes | What to do next | +|---|---|---| +| Explicit refusal before effects | This request performed no optimization writes. | Address the permission, capacity or other reported cause before requesting work again. | +| Completed report | This attempt's reported graph result is known; inspect any skips or optional-work failures too. | Keep the report if operational history is needed. | +| Connection loss or timeout without a definitive result | The request may not have started, may still be running, or may have finished. | Record unknown; do not automatically resend it. | +| Engine/storage error | Only the effects and uncertainty stated by that error are known. An error is not proof that nothing changed. | Follow the reported storage outcome; do not infer permission to replay. | + +For example, the server can finish optimization, make its graph commit durable, +and then lose the connection before the report reaches the CLI. The graph is +safe, but the CLI cannot know the result. Repeating the command could perform +more work and create another commit. A later head read also cannot prove what +this particular request did: other requests can advance the graph too. + +After an unknown outcome, an operator may deliberately request a new +optimization once the server can safely admit it. That request uses the graph +state accepted at that time. It does not recover or classify the old request, +and may repeat its cost. The CLI and control plane must not silently make that +decision on the operator's behalf. + +The direct-storage command remains available under exclusive storage ownership. +Remote errors never cause a fallback to direct storage, because that would +bypass the running owner's coordination. ## Design -### Responsibility boundary - -| Owner | Responsibility | -|---|---| -| Control plane | Scheduling, fleet capacity allocation, delivery policy, durable workflow history, log collection/retention and operator presentation. | -| Server | Authentication, local admission, ownership of execution through disconnect, bounded execution status and exact responses. | -| Engine | Authorization at the native entry point, accepted snapshot, physical optimization, graph publication and typed storage outcomes. | - -The control plane records intent, delivery attempts and responses it actually -observed. Its records are authoritative for its workflow, not native acceptance -or publication. An unobserved result remains unknown. Self-hosted callers can -use the same native endpoint without deploying a control plane. - -The server emits ordinary correlated diagnostic events and metrics through the -existing observability facilities. It does not persist a second operational -history or manage log delivery. Loss of an observational record is neither -proof of safety nor a reason to close otherwise valid native admission. -This minimizes management overhead; physical optimization still runs in the -engine. Moving that computation to independent workers is out of scope. - -### Native execution and outcomes - -Add the graph policy action `optimize`, scoped to `main`. Installed policies -must explicitly grant it; `admin`, configuration management and membership do -not imply it. HTTP resolves the bearer to an actor; cluster admission checks -current applied policy and the engine checks the same action before effects. -Keep normal access discovery and the existing `--as` credential-actor assertion. -An assertion never supplies a trusted actor. Do not retain bearer bytes. - -Reuse the existing cluster admission, owned-operation runtime and deployment -gate. Admit at most one optimization per cluster and serialize it with -configuration deployment. Refuse another optimization while that slot or the -deployment gate is busy; ordinary writes keep their existing gate behavior. -Accepted work remains owned after its HTTP waiter exits. Disconnect and -observation deadlines end waiting, not native execution. - -The engine retains its schema, branch and sorted-table gates, one coherent -accepted snapshot, detached staging and single graph-manifest publication. -Capture the exact before/after commits as part of that attempt, while the -relevant gates are held; never infer the result from a later head read. -Direct and served entry points share these semantics. Resource limits constrain -work; their presence must not select a different publication or error protocol. - -Separate known graph publication from optional derived-artifact work. A settled -artifact failure is reported explicitly without relabeling a known commit as -unknown. Genuine uncertain I/O, including a possibly accepted write to a mutable -cache object, still needs the existing settlement and containment rules. Never -discard that uncertainty merely because the data is derived. -Key-scoped storage uncertainty does not itself close process admission; -containment remains limited to the cases defined by the existing storage-outcome -contract, rather than every failure after acceptance. - -Shutdown and successor admission follow the existing -[owned-operation](2026-09-30-owned-server-operations.md) and +### Responsibilities and why they are separated + +| Component | Responsibility | Reason | +|---|---|---| +| Control plane | Decide when managed maintenance should run, allocate fleet resources, deliver requests, retain workflow history and collect logs. | It has the view across clusters and owns operator workflows. Each database server should not duplicate that management system. | +| Server | Authenticate callers, check whether work can start, own its lifetime and return the observed result. | It knows the active graph and configuration, current local work and storage ownership. A scheduler's approval alone cannot make execution safe. | +| Engine | Enforce graph policy, choose a consistent input version, optimize storage and make the graph change visible. | The same data-safety contract must hold for HTTP, direct CLI and embedded callers. | + +In this document, **native** means the OmniGraph server/engine boundary, as +distinct from the external control plane. Control-plane records prove what it +requested or observed. If the server's answer never arrived, a record saying +"request sent" cannot prove that optimization succeeded. Ordinary diagnostic +logs and request correlation IDs help investigation; they are not a guaranteed +result-recovery protocol. + +The server emits diagnostic events and metrics through its existing facilities. +Collection, long-term retention and presentation belong to the surrounding +operational system. Losing a log or report must not by itself make a safe graph +unavailable. This division reduces management overhead; it does not offload the +CPU, memory or storage traffic of optimization. + +### Admission, authorization and concurrency + +Add the policy action `optimize` on the selected graph's `main` branch. Installed +policies must grant it explicitly: permission to manage configuration or +membership does not imply permission to run expensive maintenance. The reserved +`admin` action does not grant it either. HTTP resolves the credential to an +actor, and the engine checks the action as well so direct calls cannot bypass +policy. Do not retain bearer credentials in logs or results. + +Use normal access discovery and the existing `--as` behavior. On HTTP, `--as` +asserts that the credential resolves to the expected actor; it never supplies +a trusted identity. Keeping this assertion avoids a special authentication +rule for optimization. + +The server admits at most one optimization per cluster, and none concurrently +with configuration deployment. A conflicting optimization request is refused +rather than queued. This bounds maintenance concurrency and keeps graph/policy +configuration stable during the operation. The cost is that different graphs +in one cluster cannot optimize in parallel. Restricting the initial operation +to `main` similarly avoids adding branch selection and branch-maintenance +coordination to the first supported surface. + +Ordinary writes retain the engine's existing coordination and may wait for +optimization. Already admitted readers retain their consistent graph versions, +but shared CPU and storage bandwidth can still affect their latency. This is +not a promise of maintenance without performance impact. + +These local coordination gates do not prevent an independent process from +writing storage. Existing cluster ownership and exclusion of previous writers +remain responsible for that boundary. + +### One attempt and one graph publication + +The engine carries out one attempt in this order: + +1. Hold the existing schema, branch and table coordination gates and capture one + coherent graph version: schema, branch and all participating table versions. + Revalidate that the captured authority still permits the operation before + effects, and check the complete supported workload against its limits. +2. Prepare replacement table versions without making them visible to readers. + These are detached staged changes; an incomplete preparation must not expose + a partly optimized graph. +3. When graph changes need publication, publish the selected versions together + through the existing commit mechanism. This is the point at which the new + layout becomes visible. Report that publication as successful only after it + is durable. A no-work attempt skips publication and keeps its input commit. +4. Report this attempt's input and output commits and exact work outcomes. + Capture those identities while the relevant gates still protect them; + reading the latest commit later could attribute another request's work to + this one. + +Skips and deferred indexes remain explicit. The operation preserves logical +data and supported query guarantees; it does not promise every index is rebuilt +or that approximate-search results are identical after a physical index change. +Direct and served entry points use the same publication and failure semantics. +A resource limit can restrict admission or concurrency, but must not silently +select another correctness protocol. + +### Request lifetime and truthful failure reporting + +**Synchronous** describes the interface: the caller waits for the final answer. +It does not mean that closing the connection cancels storage work. The server's +existing owned-operation runtime keeps accepted work and its resource +reservations alive after the HTTP waiter disappears. An observation timeout +ends waiting; it does not establish that the engine stopped. + +Three different situations must remain distinct: + +| Situation | Required behavior | Why | +|---|---|---| +| The client loses a report after a known successful publication. | The caller records unknown; the server does not treat response loss alone as a storage failure. | The missing information is at the client, not necessarily in the database. | +| Publication succeeds, then optional derived-cache work fails with a known outcome. | Preserve the successful commit and report the optional failure separately. | A cache that can be rebuilt must not erase a known graph result. | +| A storage request may still take effect, or the process loses reliable ownership of work. | Apply native storage settlement and any required restrictions on further writes or shutdown. | Releasing ownership too early could allow a delayed write to interfere with later work. | + +Here, **settled** means the storage request's outcome is known or its possible +late effect has been made safe. **Containment** means stopping admission or +terminating a process that can no longer safely own its work. Uncertainty +confined to particular files or object names follows the existing per-key rules; it +does not automatically close the entire process. Uncertain writes to an +optional mutable cache still need those rules: being derived does not make a +late overwrite harmless. + +Shutdown and replacement servers keep the existing +[operation-ownership](2026-09-30-owned-server-operations.md) and [storage-outcome](2026-10-19-storage-outcomes-and-restartable-ownership.md) -contracts. A dropped future does not exclude accepted I/O or a predecessor. -There is no additional startup blocker for a missing maintenance receipt, no -neutral graph commit solely to settle one, and no maintenance-specific unlock. +requirements. Dropping a future or seeing no response does not prove that a +previous writer and its accepted I/O are excluded. Conversely, a missing +maintenance report adds no new startup blocker. Graph safety and the ability +to recover a report are separate obligations. -### HTTP, receipts and status +### HTTP and result retention -Add `POST /graphs/{graph_id}/optimize` through the shared operation registry, +Add `POST /graphs/{graph_id}/optimize` using the shared operation registry, typed API and [HTTP conventions](2026-10-19-http-api-conventions.md). The graph -is addressed once, in the path. The initial operation uses the existing optimize -behavior without new request options; clients do not copy server ceilings into -a maintenance envelope. -Return the exact completed report after durable publication, or the typed -failure. A no-work result names the unchanged commit. Do not return `202` as a -promise of durable acceptance. - -Here, a receipt means the completed response observed by the caller. It is not -a server-persisted record. The first slice exposes completion through that -response and keeps execution status in the existing owned-operation runtime; -it adds no per-invocation lookup endpoint. A request correlation ID supplies -identification only, not idempotency, deduplication or restart recovery. -Clients and control-plane delivery code must disable automatic POST retries -after ambiguous dispatch. Native status may be lost at restart. - -MCP exposure and asynchronous lookup are deferred. If reconnect lookup becomes -necessary, a separate bounded, process-local extension can retain active and -terminal statuses scoped to the server incarnation. Missing, evicted or old -statuses must mean unknown, never not-executed, and lookup must never execute -work. That extension must define its limits and authorization before shipping; -this RFC does not require a generic jobs API to expose optimize. - -### Bounds and enablement - -Execution is disabled until explicitly configured and qualified. Keep typed -limits under the server's existing configuration/builder ownership, without a -maintenance-only YAML file or parser. The server selects finite ceilings for -tables, fragments, physical rows, source bytes and file references; callers -cannot raise them. Start with one dataset and one compaction task in flight. -Bound metadata enumeration and result construction as well as physical work. - -Validate the complete accepted source inventory before the first rewrite, -including dropped-column materialization, catalog work, table manifests, -index files, deletion files and managed Blob payloads. External Blob references -remain references; their payloads are not fetched. Count before exceeding the -limit, rather than materializing an unbounded inventory and checking afterwards. -Unknown sizes or unsupported layouts refuse. Preserve the current full-text -rebuild boundary; index/statistics/storage errors must not masquerade as -insufficient vector training data. Do not add historical-prefix scans or output -truncation. - -Finite source ceilings and concurrency do not establish hard memory, CPU, -scratch-space or I/O-rate guarantees. Native work and completion resources need -measured limits and process/platform isolation for the supported envelope, -including competition with foreground requests. Existing request-count and -request-byte admission is not a substitute. Ordinary bounded result delivery -remains necessary; the durable-journal report reservation and recovery-envelope -machinery are not part of this contract. - -Managed execution additionally requires native enforcement of control-plane -capacity allocation on every entry point, including direct remote CLI calls. -A proxy check alone is insufficient. State support through explicit deployment -capability and resource admission, not an inference from static-token, signed -token or OIDC authentication. Until qualified, managed execution stays disabled. +is specified once, in the path. No new request options or caller-supplied +resource ceilings are needed for the initial operation. + +Return the completed report or a typed failure on that request. There is no +initial `202` job-acceptance response, persistent operation record, polling +endpoint or restart-resume promise. A request correlation ID is for diagnosis, +not a key that makes repeated requests execute once. Clients and control-plane +delivery code must disable automatic POST retries after ambiguous dispatch. + +A caller can retain a received report as its operational record. The server +does not guarantee later retrieval if that response is lost or the process +restarts. The benefit and cost of this choice are explained under Alternatives. +MCP exposure is outside the initial HTTP/CLI contract. + +### Work limits and enablement + +An optimization request can be small while the work it triggers is large. +Request-count and request-byte limits therefore cannot protect the server on +their own. Before any rewrite, inspect the accepted input and enforce finite +ceilings on tables, fragments, physical rows, source bytes and file references. +Stop counting when a limit is exceeded; checking only after an unbounded +inventory has been collected would defeat the limit. + +Account for the complete supported work: catalog and table manifests, data, +deletion and index files, and managed Blob payloads. A small Blob descriptor +can refer to a large payload, and rewriting a table can read those bytes. +External Blob references remain references; their payloads are not fetched. +Include rewriting needed to physically remove dropped columns and index work, +even when ordinary compaction alone would select less data. Unknown sizes or +unsupported layouts refuse before effects, rather than enabling an unbounded +fallback or silently optimizing only a prefix. + +Start with one dataset and one compaction task in flight. This reduces competing +allocations, but one task or one Blob row can still be large. Source ceilings +are not hard limits on peak memory, CPU, temporary space or I/O rate. Enabling +execution requires measured limits within the deployment's process/platform +resource allocation, including contention with foreground requests. Metadata +enumeration, result construction and completion also need bounded resources. +No report may silently truncate work outcomes to fit a response. + +Configure these limits through the existing server configuration/builder owner +so operators have one settings authority. Execution is off until explicitly +enabled within a qualified allocation; callers cannot raise its ceilings. +The endpoint exposes existing optimization behavior: it does not expand that +behavior into full-text rebuilding, which has a separate explicit operation. +A vector column with no non-null values may legitimately leave index work +pending. A failed read or index build does not prove that the column is empty; +index, statistics and storage errors must remain errors. + +For managed clusters, the control plane allocates capacity and the server must +enforce it at every execution entry point. Otherwise, a direct remote CLI call +could bypass the scheduler's limits. Authentication proves identity, not +available resources: static tokens, signed tokens and OIDC are not capacity +policies. Managed execution remains disabled until native enforcement is +qualified, even if self-hosted execution is available. ## Invariants -The [architectural invariants](../dev/invariants.md) remain unchanged: one -accepted snapshot, detached pre-publication effects, one graph publication, -engine authorization, bounded work and typed uncertain outcomes. Derived indexes -and caches affect cost, never logical correctness. Existing ownership and I/O -settlement remain necessary even when observational status is missing. +The [architectural invariants](../dev/invariants.md) continue to govern every +entry point: one coherent input snapshot, unreachable preparation work, one +graph publication, native policy enforcement and bounded observable failures. +Indexes and caches may affect cost but cannot silently weaken logical +correctness. No second storage writer or graph-publication authority is added. +Process-local gates do not replace storage ownership, and recording a request +in the control plane does not authorize a write or prove its completion. + +## Alternatives -There is no second storage writer, manifest-derived job queue, custom WAL, -shadow publication authority, implicit retry, or inline content-write rebuild. -The control plane cannot bypass native policy, resource admission or fencing. -Cleanup, repair, history deletion and isolated workers remain outside this RFC. +### Require operators to stop the server -## Compatibility and reversibility +Keeping direct-only optimization avoids adding an HTTP operation. It also +requires an outage and a storage-ownership handoff for routine maintenance. +Execution through the existing owner avoids that handoff while retaining its +coordination rules, at the cost of competing with foreground work. -This design adds no graph format or durable maintenance object. Adding the -`optimize` action requires policy and access-discovery updates for direct and -served callers. Removing the endpoint later leaves ordinary graph commits and -detached output governed by existing retention and cleanup rules. +### Store durable jobs and results in the server -The candidate in #1177 has not established a supported wire or disk contract. -Remove its maintenance journal, sequence protocol, lookup/recovery routes, -receipt-only admission blocks and recovery CLI flags before shipping. Do not -silently delete an outstanding journal in an experimental deployment: exclude -its owner and settle its native work using the candidate's recovery procedure -before switching binaries. Migration of such experimental roots is not supplied -by this documentation change. +A durable job system could let callers reconnect and retrieve the result using +an operation ID. It would need to record acceptance before work, bind the ID to +one request, retain results, authorize their retrieval and define expiration. +It must also handle a crash after the graph commit but before the result record: +otherwise it still cannot say what happened to that request. -The control-plane specifications -[LCY-04.2](https://github.com/ModernRelay/og-control-plane/blob/58a29d6dd4ea00cef84829f03181ffe740d01974/specs/08-LCY-Lifecycle.md#L702) -and [DEC-08-76](https://github.com/ModernRelay/og-control-plane/blob/58a29d6dd4ea00cef84829f03181ffe740d01974/specs/02-DEC-Decisions.md#L3601) -currently require durable native invocation identity, acceptance, results and -original-ID reconciliation. Amend those requirements before claiming managed -compatibility with this weaker observation contract. Moving the same guarantees -into control-plane bookkeeping would not satisfy them. +Those responsibilities add storage writes, recovery logic and retention rules +to every participating server. Reusing the configuration-deployment ledger +would still require these rules and couple physical maintenance to configuration +management. Gating normal serving on unresolved job records would also make +result recovery a database-availability dependency. -## Alternatives +This proposal chooses the smaller contract because its workload is occasional +manual optimization. Graph durability is retained; guaranteed result retrieval +after disconnect or restart is not. The concrete cost is that an operator may +never learn the exact outcome of one request. If that is unacceptable for a +workload, durable result recovery needs a separate design before supporting it. + +### Keep temporary results in server memory -- **Keep direct-only optimization:** requires stopping the owner for routine - physical maintenance; does not solve the operational problem. -- **Durable native invocation journal:** supports original-ID lookup and - publication reconciliation across crashes, with unresolved or partial outcomes - when evidence is insufficient. It adds persistent identities, retention, - recovery and an availability dependency on receipt settlement. Defer until a - concrete use case requires that stronger guarantee. -- **Reuse the deployment ledger:** couples configuration convergence to physical - optimization without removing durable invocation complexity. -- **Control-plane-only execution receipts:** cannot prove native publication - when a response was lost. Keep workflow history there and preserve unknowns. -- **Process-local asynchronous status:** useful for reconnecting observers, but - adds retention, authorization and incarnation semantics. Defer until the - synchronous slice demonstrates that need. +A bounded in-memory status cache could support reconnection while the same +process remains alive. It avoids durable writes but still needs lookup +authorization, memory/retention bounds and a way to distinguish process +instances. Restart or eviction would again leave unknown outcomes; a missing +entry could not safely mean "never executed." Defer this interface until the +need to reconnect justifies those extra lifecycle rules. + +### Let the control plane guarantee completion history + +The control plane can durably record requests and responses it receives. It +cannot close the example's gap between a native commit and a lost response: +its own "sent" record does not establish completion. Treating that record as +success would invent evidence; treating it as failure and resending could +repeat work. The chosen boundary keeps workflow history there and preserves +unknown results unless native evidence establishes more. + +### Move optimization to separate workers + +Separate workers could reduce competition with the serving process. They would +need stable input versions, constrained storage permissions, bounded resources +and validation of their output before the owning engine publishes it. That is +an additional execution architecture. The initial proposal accepts shared +server load and possible write delays to reuse the existing execution path. + +## Compatibility and reversibility + +The new HTTP operation and policy action require API, CLI and access-discovery +updates. Installed policies must explicitly grant `optimize`, including for +direct callers. Existing target selection and actor assertion stay unchanged; +no additional submit, observe or recover command is needed. The graph format +is unchanged. Removing the endpoint later leaves graph commits and staged +output governed by ordinary retention and cleanup. + +### Coordination with existing specifications and prototypes + +Managed-service specifications currently require a stronger contract than the +one proposed here: native operation identities and results retained for lookup +and reconciliation after interruption. Those requirements appear in +[LCY-04.2](https://github.com/ModernRelay/og-control-plane/blob/58a29d6dd4ea00cef84829f03181ffe740d01974/specs/08-LCY-Lifecycle.md#L702) +and [DEC-08-76](https://github.com/ModernRelay/og-control-plane/blob/58a29d6dd4ea00cef84829f03181ffe740d01974/specs/02-DEC-Decisions.md#L3601). +They must explicitly permit unknown, unrecoverable request results before +managed enablement. Control-plane bookkeeping cannot substitute for the native +proof those documents currently require. This dependency does not block an +independently qualified self-hosted implementation. + +The unmerged prototype in +[#1177](https://github.com/ModernRelay/omnigraph/pull/1177) implements durable +operation records and offline reconciliation. It is not an implementation of +this document's complete contract. Its job journal, sequence protocol, lookup +and recovery interfaces, report-retention machinery and startup restrictions +caused solely by a missing operation report must be removed or replaced when +aligning the code. + +An experimental root used with that prototype may contain an unfinished +operation. Before changing binaries, exclude the previous writer and resolve +its accepted work using that prototype's recovery procedure. Deleting its +record would discard evidence without proving the work is safe. This RFC does +not supply a migration for such experimental roots. ## Evidence and tests Extend the existing engine `integration/maintenance.rs`, policy, cluster -admission, server operation/runtime and CLI maintenance owners. Prove: - -- Denied actors, unsupported deployments, exhausted bounds and competing work - refuse before physical effects; direct calls cannot bypass engine policy. -- Disconnect and timeout leave execution owned, with no client resubmission. - Shutdown and predecessor exclusion preserve native I/O settlement. -- Success reports this attempt's exact commit; no-work reports the unchanged - commit. Lost responses and crashes never become inferred success or failure. -- Known publication plus settled optional failure preserves both facts; - uncertain publication or optional I/O retains the required native fencing. -- Rows, schema, Blob values, index behavior, retained history and live branches - are preserved. Use GQT for expressible logical assertions; retain Rust owners - for physical mechanisms, concurrency and faults. - -Update the registry, OpenAPI, CLI contracts and DST storage-cost golden with -implementation changes. Verify that no receipt lookup, journal write or -maintenance-specific startup gate remains. Qualify resource and live-cloud -settlement separately; local correctness tests cannot establish those limits. -Measure large Blob rows, wide/high-dimensional rows, many small fragments and -index rebuilds under the intended allocation. Publish the tested limits. - -The candidate's source accounting was inspected against unmodified Lance -13.0.0: [compaction planning/execution](https://docs.rs/crate/lance/13.0.0/source/src/dataset/optimize.rs), +admission, server operation/runtime and CLI maintenance test owners. Cover the +observable contract rather than treating prototype test results as proof: + +- Refusals for policy, capacity, unsupported layouts and competing maintenance + happen before physical effects; direct calls still enforce engine policy. +- Disconnects and timeouts do not cancel accepted work, release its capacity + early or trigger client resubmission. Shutdown preserves storage ownership. +- Reports identify the exact attempt's commits, including unchanged no-work + results; response loss never becomes inferred success or failure. +- Known publication and settled optional failure are reported separately; + uncertain storage requests and ownership failures retain their specific + restrictions without blanket process shutdown for every error. +- Logical data, schema, Blob values, retained history, live branches and + supported index/query behavior survive optimization. Use GQT for expressible + logical assertions and existing Rust owners for mechanisms, concurrency and + faults. + +Update the operation registry, OpenAPI, CLI contracts and DST storage-cost +golden with the implementation. Verify there are no persistent job-record +writes or result-history prerequisites for startup. Measure large Blob rows, +wide/high-dimensional rows, many small fragments and index rebuilds alongside +foreground requests. Publish the tested allocation and limits; local tests do +not establish live-cloud settlement or a production resource envelope. + +The resource analysis uses unmodified Lance 13.0.0 +[compaction planning/execution](https://docs.rs/crate/lance/13.0.0/source/src/dataset/optimize.rs), [fragment metadata](https://docs.rs/crate/lance-table/13.0.0/source/src/format/fragment.rs), [index inventories](https://docs.rs/crate/lance-table/13.0.0/source/src/format/index.rs) and [object-store sizing](https://docs.rs/crate/lance-io/13.0.0/source/src/object_store.rs). -Lance's compaction byte option alone excludes Blob-v2 payload accounting and -does not bound all optimization work. Reuse qualified native mechanisms rather -than introducing another transaction or recovery protocol. Tests of the prior -journal design are not evidence that this revised contract is implemented. +Lance's compaction byte option excludes Blob-v2 payload accounting and does not +cover all graph optimization work, which is why the complete-work checks above +are required. This source analysis is not a measurement of resource limits. ## Rollout -1. Review this reduced contract and align #1177's code, tests, OpenAPI and user - documentation. Keep execution disabled during qualification. -2. Enable the synchronous self-hosted slice only for the measured supported - resource envelope. Preserve explicit unknown outcomes and existing shutdown - behavior; publish the policy change and limits with the implementation. -3. Amend the control-plane specifications and qualify native capacity admission - before enabling managed calls. Keep scheduling and operational history in - the control plane. This phase does not gate the self-hosted slice. +1. Implement the specified HTTP/CLI, policy, ownership and failure contract; + align prototype code and user documentation. Keep execution disabled while + its behavior and resource limits are qualified. +2. Enable self-hosted execution only for a measured supported allocation. + Publish its limits, policy migration and lost-response behavior with it. +3. Amend the managed-service result guarantees and verify native capacity + enforcement before enabling managed calls. Scheduling, history and log + collection remain control-plane responsibilities. ## Unresolved questions -No additional design decision is required for the synchronous scope. The -implementation, resource and managed-integration evidence gates are listed in -`blocked_on`. Durable receipts, asynchronous lookup and worker offload require -separate justification and are not implied follow-on commitments. +No additional design choice is required for this bounded synchronous scope. +Implementation and qualification gates are listed in `blocked_on`; numerical +deployment limits require measurements, not assumptions. Reconnect lookup, +durable results and worker offload are possible separate proposals, not promises +made by this RFC. ## Decision log -- **2026-10-27:** Narrow the initial candidate to safe execution through the - existing owner. Replace durable invocation/lookup and offline recovery with - synchronous exact results and explicit unknown outcomes. Assign orchestration, - history and log collection to the control plane; retain native authorization, - resource admission, publication and settlement. Record the control-plane - specification changes needed before managed enablement. The implementation - still needs to be aligned; this revision does not accept its earlier protocol. -- **2026-10-27:** Move design review to - [#1186](https://github.com/ModernRelay/omnigraph/pull/1186), independently of - the implementation in #1177. The proposal and its qualification gates are - unchanged by the split. +- **2026-10-27:** Choose synchronous execution through the existing owner, + explicit unknown outcomes and control-plane orchestration/history. A prior + prototype included durable invocation lookup and offline result recovery; + those guarantees are outside the selected contract. Native authorization, + resource admission, graph publication and storage settlement remain required. +- **2026-10-27:** Separate design review in + [#1186](https://github.com/ModernRelay/omnigraph/pull/1186) from the + implementation prototype in #1177. +- **2026-10-27:** Rewrite the proposal as a standalone contract. Explain the + request lifecycle, lost-response example, component responsibilities and the + benefit and cost of each alternative without requiring prototype history.