A development report on SessionDock, based on the project state of September 5, 2026. SessionDock is not yet a released, end-to-end application.
Two agents are supposed to work on two projects in parallel. Each needs a browser with a prepared login. If its assigned workspace is busy, neither agent should silently switch to another profile or browser.
Separate browser profiles solve only one part of this problem: they separate browser data. We also need to know which project a workspace belongs to, who may control it at any given moment, and what should happen to a delayed action after control changes hands.
SessionDock is our attempt to answer those questions in software. We are developing a local Linux environment for prepared Chromium workspaces that a person will eventually be able to delegate to an agent for a limited time. The main state-management and scheduler components are implemented and tested. The path from the user to a real browser action is not yet complete.
A profile does not identify who owns an action
If all you need is to keep two logins apart, you do not automatically need another tool. Our starting point is also a separate Chromium user-data directory. A launch script can open two browsers with different directories and assign matching download paths.
The additional requirements appear when a workspace no longer belongs to one person alone, but is used by different actors at different times.
Consider a simple example. A person signs in to an administration interface and then delegates a limited task to an agent. During the task, the person needs to inspect something and takes control back. A browser action prepared by the agent arrives late.
The browser data may still be perfectly separate. One question remains: Is the agent still allowed to execute that action?
A directory structure cannot answer this. The system needs an authoritative record of who currently controls the workspace.
Treating the browser workspace as a managed resource
SessionDock calls a prepared browser workspace with its own assignment and local data a slot.
In the current workspace code, each slot receives a complete Chromium user-data directory, a download directory, and separate XDG and D-Bus paths. The graphical design uses a private Weston desktop. The packaged browser is Chromium, not Google Chrome.
The scheduler adds a fixed binding to this technical separation. The data model includes the project, worktree, environment, expected account, and expected tenant. An agent run receives permission for a specific binding; it should not be free to select an arbitrary environment on every request.
The word “expected” matters. A stored account name does not prove that the website is actually signed in with that account. The full login, confirmation, and delegation flow has not been integrated yet.
Likewise, a worktree assignment is currently a data-model concept in the tested core. It does not mean that SessionDock can already discover every Git worktree and open the appropriate interface automatically.
A lease controls access; an epoch fences a handover
A person and an agent should not write to the same slot at the same time. The scheduler therefore uses exclusive, time-limited access rights: leases.
A lease epoch complements that model. It is a monotonically increasing generation number for control authorization. When control changes hands, the previous generation becomes invalid.
A simplified example:
Agent A controls the slot at epoch 41.
The person takes control back.
The current epoch is now 42.
A delayed action from A arrives with epoch 41.
The authorization check rejects it as stale.
Before dispatch, the state machine checks whether the agent still has control, whether the session is ready, and whether the expected lease epoch matches the current one. This core logic is covered by unit tests.
That does not yet prove an end-to-end protected browser action. The check must sit at the correct point in the complete execution path, and that integration remains open.
Nor can such a check undo an action that has already reached the website. If a web service has accepted a change, a local handover does not reverse it. Unknown outcomes, recovery, and quarantine therefore remain part of the design.
Separate browsers can still change the same resource
The scheduler can allocate independent slots in parallel. This does not make their work independent at the application level.
Two separate browsers can use the same account to modify the same server-side resource. Two agents might, for example, edit the same product record at the same time. Separate cookies and download directories do not prevent that conflict.
The scheduler therefore also supports conflict keys. They can coordinate known shared resources, provided the conflict has been described correctly. SessionDock does not automatically understand the business logic of an arbitrary website.
This distinction matters to the data model. Local browser separation, permission to control a workspace, and conflicts over application data are three different concerns.
Running a browser and displaying it are different jobs
The graphical environment adds another requirement. A person should be able to sign in to a real Chromium workspace without giving the agent their passwords or TOTP seeds. At the same time, the browser should not constantly appear as a regular window on the person’s desktop.
The workspace prototype therefore separates browser execution from display on the host. Chromium is intended to run on a private Weston desktop. A viewer opens separately, and only after an explicit action by the person.
This is an architectural decision, not a demonstrated guarantee about focus handling or two-factor authentication. On the investigation host, the real Chromium launch failed because namespaces were blocked. The login and focus test matrix is also still open. USB security keys and smartphone passkeys are explicitly blocked in the current prototype.
SessionDock does not import existing sessions from the user’s normal desktop Chrome installation either. The intended flow is a manual login inside each slot. The persistent profile path is designed to preserve that login across restarts, but this has not yet been demonstrated with a real authentication-and-restart test.
One authority, but not yet a complete execution path
The repository contains a Go daemon with a local API, SQLite persistence, a scheduler, and a state machine. It also contains a separate workspace prototype and parts of a Chromium extension using Native Messaging.
Their responsibilities are deliberately different. The daemon is intended to remain the authoritative source for permissions and state. Browser components should not replace that authority with their own potentially stale decisions.
These parts are not yet connected into a usable product. The regular CLI does not control the daemon; in practice, only help and version output are usable there. The MCP server, agent adapters, and complete action executor are missing. The workspace prototype is not yet wired to the scheduler.
A passing scheduler test is therefore not a successfully completed agent run. Likewise, prepared slot directories do not demonstrate two browsers operating concurrently. Both provide useful evidence for individual components, but not for the complete user flow.
The security boundary this architecture does not create
Separate profiles are not a security boundary against every local process.
The slots still live on the same host and ultimately belong to the same host user. Chromium shares the host’s network access. Hard isolation between an agent and every other host file it might reach has not been implemented.
If an agent has broad file access outside SessionDock, an API permission model alone cannot stop it from taking another route. Any future security claim will have to account for that boundary.
What the current design tells us
The design therefore centers on controlled access to a prepared workspace, not on the browser window itself.
Responsibilities are divided across several components. The slot owns the local browser data, the binding describes the work context, and the lease grants current control. The epoch makes stale permissions detectable, while conflict keys coordinate known shared resources.
The core model is currently further along than the visible application. The next meaningful proof is not another architecture diagram but a complete flow: prepare a test workspace, sign in manually, delegate it for a limited time, observe a real action, and take control back.
Until that flow works and has been tested, SessionDock remains a development project. The underlying problem is already clear, though: a browser agent needs more than a browser. It needs an unambiguous workspace and a verifiable, limited right to act within it.
Top comments (1)
The epoch fencing at the action dispatcher is the cleanest part of this design. In human-agent handoffs, delayed event dispatch is where state corruption usually happens. An agent prepares a click three seconds before the operator grabs focus, and the action fires into whatever page the human just navigated to. Checking a monotonic epoch number right before the CDP event dispatches turns that race condition into a deterministic drop.
The edge that gets messy in practice with headless slots is in-flight requests that cleared the browser before the epoch bumped. The click was authorized when sent, but the server response and subsequent redirect land after the lease expired. If the agent loop watches DOM mutations to plan its next move, canceling pending fetch channels or tearing down the network listener on lease handover saves a lot of phantom state errors.