You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Rework RTLO4f around an explicit graph-theoretic definition
Replace the seven-clause MUST-style spec with four: define a directed
graph G over parentReferences, return the *key-paths* corresponding
to G's simple paths from root to this LiveObject. The new term
*key-path* (matching PathObject's "path" concept) is used here to
distinguish from the graph-theoretical "simple path". Edge cases
(root, orphan, multi-key, multi-ancestor, cycles) fall out of the
definition.
There's a tension here: the most universal contract would just say
"returns the key-paths from root to this LiveObject" and leave the
mechanism to SDK implementers. But any SDK implementing
`getFullPaths` will probably want a `parentReferences`-equivalent
data structure, and keeping that structure consistent across the
many places where `LiveMap.data` is mutated (`MAP_SET`, `MAP_REMOVE`,
`MAP_CLEAR`, tombstone, sync rebuild) is the part SDKs are likely to
get wrong. The prescriptive `parentReferences`-based formulation
pays for itself by making those bookkeeping responsibilities
explicit at each mutation site. If we hadn't already specified
`parentReferences` and its maintenance, we might not have bothered
— but we have, so let's use it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: specifications/objects-features.md
+5-8Lines changed: 5 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -388,14 +388,11 @@ Objects feature enables clients to store shared data as "objects" on a channel.
388
388
-`(RTLO4e6)` Set `LiveObjectUpdate.tombstone` to `true` on the object computed in [RTLO4e5](#RTLO4e5)
389
389
-`(RTLO4e7)` Set `LiveObjectUpdate.objectMessage` on the object computed in [RTLO4e5](#RTLO4e5) to the `ObjectMessage` argument
390
390
-`(RTLO4e8)` Return the `LiveObjectUpdate` object computed in [RTLO4e5](#RTLO4e5)
391
-
-`(RTLO4f)` internal `getFullPaths` function - returns the list of distinct paths from the root `LiveMap` (objectId `root`) to this `LiveObject`, computed by traversing `parentReferences` upward. Each returned path is an ordered sequence of keys from `root` to this `LiveObject`.
392
-
-`(RTLO4f1)``getFullPaths` MUST be implemented as an enumeration of all *simple paths* from this `LiveObject` to the root `LiveMap` over the inverse of the `parentReferences` graph (i.e. walking child → parent). A *simple path* is a path along which no `LiveObject` appears more than once. This is the standard graph problem, typically solved by a depth-first traversal with path-local backtracking equivalent to NetworkX's `all_simple_paths`. Implementation should choose iterative DFS with explicit stack (easier to read and debugging).
393
-
-`(RTLO4f2)` If this `LiveObject` is the root `LiveMap` (objectId `root`), the returned list MUST contain exactly one path, and that path MUST be empty (zero key segments). This makes the root reachable from itself via the empty key sequence
394
-
-`(RTLO4f3)` If this `LiveObject` is not the root `LiveMap` and has no entries in its `parentReferences` at the time of the call (e.g. orphaned, or not yet reachable from root), the returned list MUST be empty
395
-
-`(RTLO4f4)` While traversing paths, suppress cyclic paths whenever a sibling branch had already revisited the same node. Reference behaviour on cyclic graphs is given by NetworkX's `all_simple_paths`, which implementations MAY consult for worked examples
396
-
-`(RTLO4f5)` When a single parent `LiveMap` references this `LiveObject` at multiple keys, the returned list MUST contain one distinct path per such key, each ending at the corresponding key
397
-
-`(RTLO4f6)` When this `LiveObject` is reachable via multiple distinct ancestor paths (either because it has multiple parents in `parentReferences`, or because any ancestor on the way to root itself has multiple paths to root), the returned list MUST contain one path per distinct ancestor path
398
-
-`(RTLO4f7)` The order of paths in the returned list is not mandatory. Implementations MAY return paths in any order; callers requiring a stable order MUST sort the result themselves
391
+
-`(RTLO4f)` internal `getFullPaths` function - returns the list of all key-paths from the root `LiveMap` (objectId `root`) to this `LiveObject`. A *key-path* is a list of zero or more keys (the same concept as "path" elsewhere in this spec, e.g. on `PathObject`); we use the term key-path in this clause specifically to distinguish it from the graph-theoretical "simple path" used in [RTLO4f2](#RTLO4f2)
392
+
-`(RTLO4f1)` Which key-paths are returned is determined via a directed graph G defined as follows. The nodes of G are the `LiveObject`s in the `ObjectsPool`. For each `(parent, key)` pair recorded in `child`'s `parentReferences` ([RTLO3f](#RTLO3f)), G has a directed edge from `parent` to `child` labelled `key`
393
+
-`(RTLO4f2)` A *simple path* in G is a sequence of edges visiting each node at most once. Each such path in G from `root` to this `LiveObject` contributes one key-path to the returned list: the list of its edge labels. The empty simple path (which exists only when this `LiveObject` is itself `root`) contributes the empty key-path `[]`
394
+
-`(RTLO4f3)` Each such key-path appears in the returned list exactly once. The order is unspecified
395
+
-`(RTLO4f4)` (non-normative) A typical approach is iterative DFS with an explicit stack: walk upward from this `LiveObject` toward `root` via `parentReferences`, collecting keys along the way and skipping branches that would revisit a node
399
396
-`(RTLO5)` An `OBJECT_DELETE` operation can be applied to a `LiveObject` in the following way:
0 commit comments