Repository navigation
rfc: graph access and cross-process writes - #1017
Conversation
Draft RFC for issue ModernRelay#980: `omnigraph serve` local sessions with session records, a thin `omnigraph studio` launcher, `omnigraph mcp` for agents, and `omnigraph credential` for static tokens. Wider-blast-radius changes are listed in Appendix A with their filed issues.
1d35a97 to
71e280b
Compare
aaltshuler
left a comment
There was a problem hiding this comment.
Reviewed the RFC against current main and RFC 0059. The inline comments identify seven design gaps in session election, destination/actor binding, Studio transitions, and MCP behavior. These are specification findings; this PR contains no runtime implementation.
…e the target writer
Rename the session to a local server and --session to --via-server. Move server records from /tmp, which macOS ages out after three days, to per-user directories resolved from the account, with the machine they belong to. Never write a token to a terminal, list live local servers in targets --json, give each agent context one write path, add platform coverage, and gather every refusal code in one table.
…-process writes Rewrite the RFC from first principles: name the target, never the path; correctness in the engine across processes; one set of operations on three surfaces; one serving concept with explicit audiences, folding the omnigraph-server binary into omnigraph serve; --as as a declaration or an assertion; one outcome model and exit table; and introspection through target list and access. Bring cross-process writer safety and the access route into scope, with the engine design on the __manifest version CAS, and land the interfaces before the engine phase. Rename the file to match the new title.
… storage-uncertainty fix
…ep set The review of ef44175 recommended merging, with four optional corrections: read-back has three results; a caller settles a control fact from the fact, since the head does not move; cleanup candidates still pass protected_manifest_branches and retained_merge_bases; a crash loses the attempt id, so only delete and drop converge after one. A not-ready branch's listing fields come from its registration.
|
All four optional corrections are in eca33ef:
The #1093 log sentence now names the publication id (013877f). |
|
Hold the merge. One blocking hole is open. The four optional corrections from the review of Why this shape is rightA person names a target. The ordinary cluster server is the only HTTP server. Writer safety stays on the Earlier findings, at
|
Storage outcomes per operation dropped its pending-publication registry: an unknown publication is recorded nowhere and blocks nothing, and its version key fences it. A control fact follows the same fence, and the one-branch service_unavailable row goes. Read-back follows ModernRelay#1092's split, a not-ready branch's absent listing fields are named, and the access evidence uses RFC 0059's target kinds.
|
Addressed at 78eb27f. Blocking: the version-key fence. A control fact now follows #1093's §5. An ambiguous request is recorded nowhere and blocks nothing; the chain's next publication either loads it or takes its version first. A read of the registration, tombstone or drop record is final only after the chain moves past the attempted version. The attempt id stays on the fact, in the log and in Optional
|
|
Non-blocking alignment note from the actor views RFC (#951, now at 5f14b1b). It adopts this RFC's model as revised today.
|
|
Aligned with the actor views note at 298515b:
The six refusal codes and the serving rule belong to #951 and need no text here. The registry already takes them as |
|
Hold the merge. The pending-publication record is gone, and that is the right cut. One settlement rule still waits one version too long, and the linear fence is stated for every write. Reviewed head Why, what, how, impactAn unknown manifest request must not grow a second record. The version key already decides a linear overwrite. This delta drops the one-branch The new sentences say a read is final only after the chain moves past the attempted version. A read is final when that version is readable. The same sentences give every unsettled write the linear fence. A detached proposal and an unattached snapshot do not use that fence. The extra wait stalls a control-fact create. Its next step writes a ref. It does not publish another manifest version. A detached write settled from the linear head can report the wrong result. Earlier findings
The actor-views sentences match #951 at Blocking1. A readable attempted version is already finalUse this rule for a linear overwrite:
#1093 §5 at This text says the read is final only after the chain moves past the attempted version. That wait is one version too long. The read-back bullet says a version that holds this attempt id landed. The unknown-outcomes bullet says that read is not final yet. An implementer cannot follow both. A create's follow-up writes the ref, so the chain can remain on the registration. Keep the detached case on #1093 §5. A proposal and an unattached snapshot publish with Change these sentences: "later writes to its branch proceed"; "The outcome is final once the branch moves past the attempted version"; the unknown-outcomes bullet; the catalog evidence bullet "stays unknown until the chain moves past it". Optional
Tradeoff and liabilityThe version key removes the pending record. That record made a rerun fail, which is why #1093 dropped it. One attempt id remains the witness for every control fact. The common write stays on the reload path. The extra wait adds a stall to every control fact whose follow-up is not a publication. Five more facts of this kind would copy that stall. A detached write judged from the linear head adds a false result. The readable-version rule removes both. It adds no new row and no new record. The client half is unchanged. One server, one target resolver, and one failure object still remove liability. That stays safe while Validation
RecommendationRequest changes. Hold the merge until the finality sentences match #1093 §5. Inline
Blocking. This sentence gives every unsettled write the linear fence. #1093 §5 limits that fence to a linear overwrite. A proposal and an unattached snapshot publish with
Blocking. A read of the attempted version is final when that version is readable. It landed when the version holds this attempt id. It lost when the version holds another fact and this attempt was not acknowledged. It stays unknown while the version is absent, until some commit holds that version. #1093 §5 says the next publication loads the late commit or creates that version. It does not wait for a later version. The read-back bullet above already says a version that holds this attempt id landed. This sentence says that read is not final yet. An implementer cannot follow both. A create's follow-up writes the ref. It does not publish the next manifest version, so the chain can remain on the registration. Use the readable-version rule here, in "The outcome is final once the branch moves past the attempted version", and in the catalog evidence bullet "stays unknown until the chain moves past it".
Optional. When the store acknowledged this attempt and the version holds another fact, the attempt stays unknown. |
|
Addressed at 33ba294. Blocking: a readable attempted version is final. The read-back bullet, the unknown-outcomes bullet,
Nothing waits for a later version, so a create whose follow-up writes only the ref settles at the registration. Blocking: the linear fence. Rule 6 now points at §5. A linear publication's version key fences it. A detached proposal or unattached snapshot settles as §5 says, not by the next linear version. The unknown-outcomes bullet states that every control fact is a linear publication on its chain. Optional. A refused request is a loss beside a never-sent one: The decision log records the change. |
|
Merge this RFC. The settlement holes from the review of Why, what, how, impactAn unknown manifest write becomes definite when its attempted version is readable. The version holds this attempt: the write landed. The version holds another fact, and the store did not acknowledge this attempt: the write lost. The version is absent: the write stays unknown until some commit holds that version. A linear publication uses that version key. The next publication loads the late commit, or it creates the version first. A detached proposal and an unattached snapshot settle as §5 of #1093 says. The next linear version does not fence them. A create whose follow-up writes only the ref settles at the registration. The chain can stay on that version. Earlier findings
Optional
Tradeoff and liabilityThe readable-version rule removes the extra wait. A control fact whose follow-up is a ref, a deregistration, or a tag release can settle on its own publication. The version key stays the one fence for a linear overwrite. This delta adds no row and no pending record. The in-doubt result after an acknowledgement stays on the attempt that holds the request record. A later check that required that bit would leave a taken version unknown. Five more control facts use the same attempt id and the same version key. The client half is unchanged. One server, one target resolver, and one failure object still remove liability. That stays safe while Validation
RecommendationMerge. Inline
Optional. This check is a later read. Its fields are the branch, the publication id, and the head before the write. #1093 records an unresolved request nowhere. Once this version holds another commit, §5 says the write is not committed. A create-if-absent cannot land after the version is held. State that loss here. Keep the in-doubt result on the read-back bullet in the engine section. An acknowledged attempt whose version holds another fact stays unknown. The catalog bullet already names both results. This paragraph names the loss only when the store did not acknowledge the attempt, and a later check cannot know that. |
This draft covers graph access and cross-process writes while retaining one
ordinary cluster-backed server model on localhost and remote hosts.
The second serving model is discontinued. #1075, #1077 and #1083 are closed
without merging, and #980 is closed as not planned. This RFC no longer proposes
standalone/local serving APIs, generated local policy and credentials, server
records, election/reuse, automatic Studio or MCP hosting, or retirement of
omnigraph-serveras part of that design.Independent scope remains:
outcomes and exit semantics remain separate proposals.
useful MCP adapter logic may be selectively reused later in a separate PR
for an explicit existing server target, without the cancelled serving stack.
not lift the existing single-writer support boundary.
longer depends on
AppState::local.Accepted 2026-10-20 (maintainer decision): the remaining storage, identity,
HTTP, MCP and outcome changes. Appendix A's items stay separate decisions. No
serving implementation from the cancelled stack reached
main.Validation: documentation and RFC registry checks, spelling, and
git diff --check. This is a documentation-only scope correction; no runtime behavior ortest qualification is claimed.