Skip to content

thread-centric routing, spaces/profiles, registry/invites, and maintenance tooling#64

Open
deathbyknowledge wants to merge 6 commits intomainfrom
profiles
Open

thread-centric routing, spaces/profiles, registry/invites, and maintenance tooling#64
deathbyknowledge wants to merge 6 commits intomainfrom
profiles

Conversation

@deathbyknowledge
Copy link
Owner

Summary

This PR completes the thread-centric multi-tenant redesign for GSV and migrates routing from a session-key-centric model to explicit runtime identities:

  • principalId (who sent)
  • surfaceId (where it was sent)
  • spaceId (tenant/state/policy boundary)
  • agentId (persona/runtime)
  • threadId (logical thread identity)
  • stateId (execution identity / Session DO identity)

It adds a registry-backed router, membership-aware authorization, onboarding/invite flows, migration/repair tooling, CLI + UI support, and broad test coverage.

Why this change

sessionKey was carrying too many responsibilities (routing hint, state identity, and implicit tenant boundary). This created ambiguity and leakage risks in multi-user/group scenarios. This PR separates those concerns and makes routing + policy decisions explicit and enforceable.

What changed

1) Core routing and state model

  • Added thread-centric routing and state identity translation:
    • gateway/src/gateway/thread-routing.ts
    • gateway/src/gateway/thread-state.ts
  • Router now resolves inbound to (spaceId, agentId, threadId, stateId).
  • stateId supports both:
    • legacy sessions (legacySession:<sessionKey>) with no-fork legacy execution identity
    • new threads (thread:<threadId>)

2) Registry store and tenant bindings

  • Added registry abstraction + persisted maps:
    • gateway/src/gateway/registry-store.ts
  • Introduced runtime-managed records for:
    • principal profiles (home/default context)
    • space memberships (role per space)
    • conversation bindings (surface -> space/agent/mode)
    • thread routes/meta
    • legacy thread index
    • invites

3) Membership and authorization

  • Added capability and cross-space checks:
    • gateway/src/gateway/authz.ts
  • Enforced policy at dispatch boundaries (not just prompt shaping), including:
    • cross-space restrictions for gsv__SessionSend
    • scoped results for gsv__SessionsList

4) Onboarding + invite lifecycle

  • Added invite creation/claim/revoke/list:
    • gateway/src/gateway/invites.ts
  • Added pending binding flow + channel self-registration path (/claim <code>):
    • gateway/src/gateway/channel-inbound.ts

5) RPC surface updates

  • Added/expanded registry RPC methods in:
    • gateway/src/protocol/methods.ts
    • gateway/src/gateway/rpc-handlers/registry.ts
    • gateway/src/gateway/rpc-handlers/index.ts
    • gateway/src/gateway/rpc-registry.ts
  • Session/chat RPC targets now accept sessionKey | threadRef paths where applicable.

6) Migration + repair tooling

  • Added maintenance operations:
    • registry.backfill
    • registry.repair
  • Backend implementation:
    • gateway/src/gateway/registry-maintenance.ts

7) CLI support

  • Added registry management and maintenance commands:
    • gsv registry principal ...
    • gsv registry member ...
    • gsv registry conversation ...
    • gsv registry pending ...
    • gsv registry invite ...
    • gsv registry maintenance backfill
    • gsv registry maintenance repair
  • Files:
    • cli/src/main.rs
    • cli/src/commands.rs
    • cli/src/gateway_client.rs

8) UI support

  • Updated UI client/types/views to surface thread identities and registry/invite interactions:
    • gateway/ui/src/ui/gateway-client.ts
    • gateway/ui/src/ui/types.ts
    • gateway/ui/src/react/views/PairingView.tsx
    • gateway/ui/src/react/views/ChatView.tsx
    • gateway/ui/src/react/views/SessionsView.tsx
    • gateway/ui/src/react/state/store.ts

9) Tool schema compatibility fix

  • Adjusted gsv__SessionSend tool schema to remove top-level combinator usage rejected by OpenAI function schema validation.
  • Runtime still enforces sessionKey || threadRef requirement.

Backward compatibility and migration

  • Existing legacy sessions continue to resolve to existing Session DO identity (no-fork behavior).
  • Legacy sessionKey targeting remains supported.
  • New thread-centric routing coexists with legacy data.
  • Operators can migrate/repair incrementally via CLI:
gsv registry maintenance backfill --dry-run true
gsv registry maintenance repair --dry-run true

gsv registry maintenance backfill --dry-run false
gsv registry maintenance repair --dry-run false

Reviewer guide (recommended order)

A. Architecture and intent

  1. SPEC.md
  2. TODOS.md

B. Core runtime model

  1. gateway/src/gateway/registry-store.ts
  2. gateway/src/gateway/thread-state.ts
  3. gateway/src/gateway/thread-routing.ts
  4. gateway/src/gateway/do.ts

C. Policy and execution safety

  1. gateway/src/gateway/authz.ts
  2. gateway/src/gateway/tool-executors.ts
  3. gateway/src/agents/tools/sessions.ts

D. API layer

  1. gateway/src/protocol/methods.ts
  2. gateway/src/gateway/rpc-handlers/registry.ts
  3. gateway/src/gateway/rpc-handlers/session-target.ts
  4. gateway/src/gateway/rpc-handlers/session.ts
  5. gateway/src/gateway/rpc-handlers/chat.ts

E. Operator surface

  1. cli/src/main.rs
  2. cli/src/commands.rs
  3. cli/src/gateway_client.rs

F. UI surface

  1. gateway/ui/src/react/views/PairingView.tsx
  2. gateway/ui/src/react/views/SessionsView.tsx
  3. gateway/ui/src/react/views/ChatView.tsx

G. Tests

  1. gateway/src/gateway/thread-routing.test.ts
  2. gateway/src/gateway/registry-maintenance.test.ts
  3. gateway/src/gateway/authz.test.ts
  4. gateway/src/gateway/invites.test.ts
  5. gateway/src/gateway/rpc-handlers/session-target.test.ts

Validation run

Executed during this branch development:

  • gateway: bunx tsc --noEmit
  • gateway: targeted Vitest suites for authz/tools/invites/session-target/routing/maintenance
  • cli: cargo check
  • cli: cargo fmt --check
  • gateway/ui: npm run check
  • gateway e2e: npm run test:e2e -- --filter "Channel Mode"
    • Result on run: 61 pass, 0 fail

Commit map

For reviewers preferring incremental history:

  1. a67a227 fix session send tool schema compatibility
  2. a8dd3f6 add registry maintenance rpc methods
  3. c28886b add registry maintenance cli commands
  4. 4bf6842 add routing and registry maintenance coverage
  5. ff7a7c1 complete thread-centric profile and routing implementation

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ff7a7c1233

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +217 to +222
if (params.modeHint === "me") {
return "per-user";
}
if (params.peerKind === "dm") {
return params.dmDefaultMode;
}

Choose a reason for hiding this comment

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

P2 Badge Honor /group mode override when resolving thread mode

parseModeHint recognizes /group, but determineThreadMode only branches on "me", so a /group message never changes routing and just falls back to the bound/default mode. In conversations configured as per-user-in-group (or any future non-shared default), users cannot force a shared thread despite the explicit override path being wired in parseModeHint, which makes the new routing controls inconsistent.

Useful? React with 👍 / 👎.

Comment on lines +134 to +136
if (!threadId) {
threadId = crypto.randomUUID();
migrated += 1;

Choose a reason for hiding this comment

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

P1 Badge Preserve thread ID when backfilling thread-scoped sessions

When backfilling an entry whose state identity is already thread:<id> but threadId is missing, this branch generates a fresh random threadId instead of reusing <id>. That breaks the expected 1:1 mapping between stateId and thread identity, and can leave existing metadata/routes keyed by the original thread ID unreachable (for example threadRef=id:<id> lookups after migration).

Useful? React with 👍 / 👎.

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