Skip to content

Add live sessions and the Session panel - #4891

Open
TrueDoctor wants to merge 4 commits into
masterfrom
graph-storage-21-sessions
Open

TrueDoctor wants to merge 4 commits into
masterfrom
graph-storage-21-sessions

Conversation

@TrueDoctor

Copy link
Copy Markdown
Member

No description provided.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 35 files

Confidence score: 3/5

  • In persist.rs, a guest can treat an undo as successful even though no request was sent when there is no current host. Return a not-ready result or defer undo/redo bookkeeping until a host is available.
  • In identity.rs, anonymous users have only 64 possible labels, so peers can appear under the same name in the Session panel. Use a larger or compound deterministic name space.
  • In ingest_message_handler.rs, opening a demo through #demo/... can retain the archive’s session room because that path sends Open instead of OpenDemo. Route demo opens through OpenDemo or otherwise mark this path.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="document/format/src/persist.rs">

<violation number="1" location="document/format/src/persist.rs:450">
P2: A guest can report a retired undo as successful while no request was sent: `request_undo` returns `Ok(())` when there is no current host. Propagate a not-ready result (or defer the editor undo/redo bookkeeping) until a host is available; apply the same handling to the redo request.</violation>
</file>

<file name="editor/src/messages/portfolio/sync/identity.rs">

<violation number="1" location="editor/src/messages/portfolio/sync/identity.rs:12">
P2: This gives anonymous users only 64 possible labels, so distinct peers frequently appear under the same name in the Session panel and cannot be told apart. Use a larger or compound deterministic name space (for example, add a stable short identifier to the animal) so the stand-ins remain distinguishable.</violation>
</file>

<file name="editor/src/messages/portfolio/ingest/ingest_message_handler.rs">

<violation number="1" location="editor/src/messages/portfolio/ingest/ingest_message_handler.rs:52">
P2: Demos opened through the `#demo/...` URL bypass `fresh_identity` because that loader still sends `Open`, so copies retain the archive's session room. Route all demo opens through `OpenDemo` or otherwise mark this path as a fresh identity.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

replica.broadcast_head_move(moved)?;
}
} else if let Some(replica) = &mut self.network {
replica.request_undo(rev, false)?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: A guest can report a retired undo as successful while no request was sent: request_undo returns Ok(()) when there is no current host. Propagate a not-ready result (or defer the editor undo/redo bookkeeping) until a host is available; apply the same handling to the redo request.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At document/format/src/persist.rs, line 450:

<comment>A guest can report a retired undo as successful while no request was sent: `request_undo` returns `Ok(())` when there is no current host. Propagate a not-ready result (or defer the editor undo/redo bookkeeping) until a host is available; apply the same handling to the redo request.</comment>

<file context>
@@ -424,6 +424,58 @@ impl<L: Layout> Gdd<L> {
+				replica.broadcast_head_move(moved)?;
+			}
+		} else if let Some(replica) = &mut self.network {
+			replica.request_undo(rev, false)?;
+		}
+		Ok(())
</file context>

}

pub(crate) fn anonymous_name(user: UserId) -> String {
let index = (scramble(user) >> 40) as usize % ANONYMOUS_ANIMALS.len();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This gives anonymous users only 64 possible labels, so distinct peers frequently appear under the same name in the Session panel and cannot be told apart. Use a larger or compound deterministic name space (for example, add a stable short identifier to the animal) so the stand-ins remain distinguishable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At editor/src/messages/portfolio/sync/identity.rs, line 12:

<comment>This gives anonymous users only 64 possible labels, so distinct peers frequently appear under the same name in the Session panel and cannot be told apart. Use a larger or compound deterministic name space (for example, add a stable short identifier to the animal) so the stand-ins remain distinguishable.</comment>

<file context>
@@ -0,0 +1,81 @@
+}
+
+pub(crate) fn anonymous_name(user: UserId) -> String {
+	let index = (scramble(user) >> 40) as usize % ANONYMOUS_ANIMALS.len();
+	format!("Anonymous {}", ANONYMOUS_ANIMALS[index])
+}
</file context>

IngestMessage::Ingest { data, action, mime_type, path } => {
let data_type = DataType::detect(&data, &mime_type, path.as_deref());

let fresh_identity = matches!(action, IngestAction::OpenDemo);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Demos opened through the #demo/... URL bypass fresh_identity because that loader still sends Open, so copies retain the archive's session room. Route all demo opens through OpenDemo or otherwise mark this path as a fresh identity.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At editor/src/messages/portfolio/ingest/ingest_message_handler.rs, line 52:

<comment>Demos opened through the `#demo/...` URL bypass `fresh_identity` because that loader still sends `Open`, so copies retain the archive's session room. Route all demo opens through `OpenDemo` or otherwise mark this path as a fresh identity.</comment>

<file context>
@@ -49,6 +49,7 @@ impl MessageHandler<IngestMessage, IngestMessageContext> for IngestMessageHandle
 			IngestMessage::Ingest { data, action, mime_type, path } => {
 				let data_type = DataType::detect(&data, &mime_type, path.as_deref());
 
+				let fresh_identity = matches!(action, IngestAction::OpenDemo);
 				let placement = match action {
 					IngestAction::ResourceInput {
</file context>

@TrueDoctor
TrueDoctor added this pull request to stack #4897 November 1, 2026 11:29
@TrueDoctor
TrueDoctor force-pushed the graph-storage-21-sessions branch from 269ddd0 to 156721b Compare November 1, 2026 11:36
@TrueDoctor
TrueDoctor force-pushed the graph-storage-21-sessions branch from 156721b to 9df7d4f Compare November 1, 2026 14:34
@TrueDoctor
TrueDoctor force-pushed the graph-storage-21-sessions branch from 9df7d4f to f699efc Compare November 1, 2026 16:41
@TrueDoctor
TrueDoctor force-pushed the graph-storage-21-sessions branch from f699efc to 5b39740 Compare November 1, 2026 20:52
@TrueDoctor
TrueDoctor force-pushed the graph-storage-21-sessions branch from 5b39740 to 8d0f030 Compare November 1, 2026 21:03
@TrueDoctor
TrueDoctor force-pushed the graph-storage-21-sessions branch from 8d0f030 to f43bac2 Compare November 1, 2026 22:08
@TrueDoctor
TrueDoctor force-pushed the graph-storage-21-sessions branch from f43bac2 to cef0e5b Compare November 2, 2026 08:11
@TrueDoctor
TrueDoctor force-pushed the graph-storage-21-sessions branch from cef0e5b to 837bf98 Compare November 2, 2026 19:46
@TrueDoctor
TrueDoctor force-pushed the graph-storage-21-sessions branch from 837bf98 to b406d63 Compare November 2, 2026 21:53
Base automatically changed from graph-storage-20-reconcile to master November 3, 2026 11:35

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 existing issues remain and no new issues found across 38 files

Confidence score: 3/5

  • In document_history.rs, a dropped-step redo can fail while the legacy stacks have already advanced, leaving history out of sync. Return success only after storage redo succeeds, or restore the note and snapshot.
  • In identity.rs, anonymous peers can get the same displayed name and be indistinguishable in the Session panel. Use a larger name space or add a stable anonymous disambiguator while keeping the user ID.

Requires human review: Auto-approval blocked because this review re-detected 2 unresolved issues already reported by Cubic.

Re-trigger cubic

PortfolioMessage::LoadPersistedState { state } => {
if let Some(layout) = state.workspace_layout {
self.workspace.panel_layout = layout;
// Add the Session panel beside the Inspector, unless the user closed it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is not what we should do for migrating the state.
I suggest that we separately add a version to it that when incremented just discards the state or something.
or we do popper migrations like with the format.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, removing the version. It is probably fine to rely on the users to discover the new panel themselves

document_name: Option<String>,
document_path: Option<PathBuf>,
content: Vec<u8>,
fresh_identity: bool,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this a weird place to put this

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 10 files (changes from recent commits).

Confidence score: 2/5

  • In document_history.rs, a failed storage redo can remove the UndoNote while leaving its redo snapshot in legacy_redo_stack, so history bookkeeping no longer matches. Keep those updates consistent on failure.
  • In persist.rs, the equality guard can leave a guest permanently unable to undo if the host disconnects or applies the drop without broadcasting HeadMove. Make the guest able to recover when that response is missing.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="editor/src/messages/portfolio/document/document_history.rs">

<violation number="1" location="editor/src/messages/portfolio/document/document_history.rs:185">
P1: A failed storage redo leaves history bookkeeping inconsistent: this branch has already removed the `UndoNote`, while the redo snapshot remains in `legacy_redo_stack`. Storage can also advance before reporting a persistence error, so the non-session fallback may then restore an interface snapshot that disagrees with storage; preserve the note and reconcile partial storage failures before returning false.</violation>
</file>

<file name="document/format/src/persist.rs">

<violation number="1" location="document/format/src/persist.rs:431">
P1: This equality guard can permanently block a guest's undo after the request has no observable response: the host may disconnect and promote the guest, or may apply the drop but fail to broadcast its `HeadMove`. Because `undo_requested` is cleared only by `Gdd::disconnect`, the next undo returns `None` indefinitely until an unrelated head change; clear or invalidate the pending request on role changes and failed/unapplied responses, or add a retry path.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread document/format/src/persist.rs Resolved

impl WorkspacePanelLayout {
/// Raised when the default layout gains a panel.
pub const VERSION: u32 = 1;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think like this it will become a migration nightmare.

would you be fine with leaving this out for now and then addressing it later and for now relying on the reset workspace done by users?

This branch was successfully deployed

1 active deployment
graphite-dev (Preview) — af495cab Deployed Nov 3, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants