Skip to content

JVNAUTOSCI-2689: Recover stale multi-org tabs after restart - #474

Merged
witbrock merged 1 commit into
mainfrom
codex/JVNAUTOSCI-2689-stale-tab-recovery
Aug 27, 2026
Merged

JVNAUTOSCI-2689: Recover stale multi-org tabs after restart#474
witbrock merged 1 commit into
mainfrom
codex/JVNAUTOSCI-2689-stale-tab-recovery

Conversation

@witbrock

@witbrock witbrock commented Aug 27, 2026

Copy link
Copy Markdown
Member

User outcome

An authenticated user can keep simultaneous tabs in Personal, Org A, and Org B across a one-server process restart. An already-open pre-upgrade tab can recover from its exact actor-owned conversation and submit once, without inheriting another tab's organisation or losing/duplicating the prompt.

Jira: JVNAUTOSCI-2689

Causal repair

  • Persist only a hashed window selector, canonical actor, and Personal/organisation selection with TTL; rederive namespace and role from current represented membership.
  • Re-read the durable binding on strict requests so worker-local caches cannot preserve another worker's switch or a revoked membership.
  • Coordinate recovery and membership mutation by exact actor/organisation pair; unrelated users and organisations do not share a global request barrier.
  • Recover old tabs only from exact authenticated conversation metadata and current membership. Unknown or other-actor selectors remain fail closed.
  • Rendezvous the two uncorrelated halves of the pre-JVNAUTOSCI-916: concurrent scoped turns and multi-org tabs #473 queue/generate wire protocol with a content-free bounded key, preserving per-conversation admission and idempotence.
  • Pass the exact actor/org/namespace scope key to live-progress lookup and report typed locator retrieval failures instead of the misleading catch-all status.

Validation

  • 198 affected backend tests passed, including cold restart, two-org plus Personal isolation, cross-worker invalidation/switching, exact-scope coordination, pre-upgrade browser-wire arrival orders, duplicate-key races, actor/org/window non-disclosure, and locator scope/failure status.
  • 271 affected frontend tests passed, including the full chatTab suite and diagnostic-copy status projections.
  • Focused Ruff checks, new-file Ruff formatting, Python compilation, frontend static lint, and git diff whitespace checks passed.
  • One existing Google GenAI Python 3.14 deprecation warning remains.

Delivery decision

Merge decision does not change: the candidate satisfies the issue's bounded recovery and isolation claim and no stop-ship condition is demonstrated.

This does not quantify live Atlas capacity for tens of simultaneous users. Strict window-bound requests add one indexed durable binding lookup, and same actor/org cold recovery may wait up to three seconds for an in-flight membership change. Those are non-blocking measurements for operational load testing, not evidence of a correctness regression.

No deployment, runtime restart, or Sol-family model request is included.


def load_owned(
self, window_session_id: str, user_id: str
) -> PersistedWindowSessionBinding | None: ...

def load_for_mutation(
self, window_session_id: str
) -> PersistedWindowSessionBinding | None: ...
user_id: str,
organisation_concept_id: str | None,
scope_kind: str,
) -> PersistedWindowSessionBinding: ...
scope_kind: str,
) -> PersistedWindowSessionBinding: ...

def touch_owned(self, window_session_id: str, user_id: str) -> bool: ...

def touch_owned(self, window_session_id: str, user_id: str) -> bool: ...

def delete_owned(self, window_session_id: str, user_id: str) -> bool: ...

def delete_owned_for_organisation(
self, user_id: str, organisation_concept_id: str
) -> int: ...
self, user_id: str, organisation_concept_id: str
) -> int: ...

def delete_all_owned(self, user_id: str) -> int: ...
token = _SCOPE_COORDINATION_STACK.set((*stack, resource_key))
try:
yield
except BaseException as exc:
@witbrock
witbrock merged commit 0707d1f into main Aug 27, 2026
4 checks passed
@witbrock
witbrock deleted the codex/JVNAUTOSCI-2689-stale-tab-recovery branch August 27, 2026 19:34
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.

1 participant