Personal agents need private authority, recoverable work and measured operating budgets
The personal-agent prototype kept its conversation after a restart. It did not keep the running job.
That distinction shaped the architecture more than the chatbot demo. Our synthetic-user experiments recovered session history from the same volume, but an interrupted run returned run_not_found. The unfinished user message remained. A stale session lease remained too. Persistent memory and recoverable execution were different contracts.
The resource measurements forced another distinction. Importing the agent library was a much smaller workload than operating its gateway. The full gateway measured a median 317 MB idle and 386 MB during a turn. Health readiness took 33.7 seconds in that experiment. A short container-start measurement could not stand in for a usable personal-agent wake time.
I wanted one personal agent for each organization/user pair, with durable memory and access to the product's tools. The design had to answer a harder question than whether an agent could remember a preference: what prevents private memory from reaching another user through a shared application, a host runtime or an apparently authorized tool?
The useful result is an architecture with explicit ownership at each boundary, backed by limited prototype evidence and a capacity model whose assumptions are visible.
A conversation identifier is not an isolation boundary
An application can route two conversations correctly while both agents share the same process, filesystem, credentials or session-search database. A model instruction that says “this belongs to Alice” does not change those shared resources.
I chose a separate agent instance for each organization/user pair. A person belonging to two organizations gets two instances. That keeps the isolation unit aligned with the product authority and the private working state. A shared organizational assistant remains a separate route, rather than borrowing one member's private memory to answer a group.
The proposed unit includes its own sandbox, private volume, broker and network path. The broker mediates product and model calls. The sandbox does not receive the actual product grant or model-provider key. The controller owns instance lifecycle and the relationship between a running instance and its current authority.
Those components serve different purposes. A private volume prevents accidental history sharing through a common home. A broker keeps credentials and forwarding decisions outside the agent process. Server-side authorization protects product records even if a broker makes a mistake. Network policy constrains destinations beyond the tool names the model sees.
This also gives the product a clearer user promise. Personal memory belongs to a defined organization/user context. Moving into a shared conversation is an audience change that requires a deliberate routing and disclosure decision.
The host can undo the sandbox boundary
A diagram with two sandboxes can conceal a shared administrative path that reaches both.
Our design review identified the runtime socket as one such path. If an ordinary development worker can control the daemon hosting personal agents, it can potentially inspect or enter another instance regardless of the separation drawn inside the agent. The host identity, socket permissions and co-tenancy model belong in the threat model.
The later synthetic experiments tested a dedicated runtime inside a throwaway VM. The attempted rootless configuration could run only with cgroup enforcement disabled in one variant; another variant failed. That was not an acceptable way to claim enforced memory and process limits. The working prototype arrangement used a dedicated rootful daemon, user-namespace remapping and its own socket and storage paths.
The resource limit experiment was behavioral: a 400 MB allocation was killed in a 256 MB container and passed under a 1 GB limit. It established that narrow limit behavior in the tested environment. It did not establish a universal recommendation about rootless runtimes, or prove that production host configuration had been applied.
The design lesson is to test the enforcement mechanism you depend on. Seeing a memory flag in a launch command is weaker than seeing the workload fail at the intended boundary. The person who can administer the runtime remains part of the trusted operating base.
Keep credentials outside the working memory
A long-lived agent should not need a long-lived provider secret in its environment or home directory.
The proposed broker holds the current product authority and the short-lived model-proxy capability. The model proxy holds the actual provider credential. The sandbox reaches its own broker through a narrow interface. It cannot select another instance's broker or ask the relay to forward an arbitrary URL.
The forwarding contract needs more detail than “allow MCP.” The design specifies accepted protocol methods, exact tool names and schemas, and explicit handling of resource, prompt and batch requests. The agent's run-control API also gets an exact route set. Discovery does not grant authority to call every newly advertised tool.
The model path has its own scope: instance identity, generation, lease and spend. Recreating an instance must not let an old token become current merely because a network address was reused. A background memory review is still a model request that needs metering and a valid operating allowance.
The prototype found a concrete adapter mismatch. The tested custom model adapter sent x-api-key; the unmodified proxy expected Bearer authorization. A broker translation reached the mock upstream. A separately capped real canary also succeeded. Neither result removed the requirement for central spend admission or established the complete personal-agent service.
That is why I treat adapter compatibility, authority and accounting as separate acceptance questions. A successful model reply answers only part of the system problem.
Shared writes are a disclosure boundary
Even a perfectly separated filesystem can leak through a product action the user is normally allowed to perform.
Suppose private memory influences an issue comment visible to a team. The caller may have permission to comment on that issue. That does not establish that the private material should be disclosed to everyone who can read it. Tenant authorization alone does not answer the audience question.
The personal-agent design therefore treats shared-target writes differently from private reads. The server should evaluate current authority and the destination audience, then require approval where the proposed disclosure crosses the personal context. The approval needs the actual payload and audience. “Undoable” is insufficient: removing a comment later does not undo someone having read it.
This applies to issue edits, task creation, CRM updates, invitations and outbound messages. It also applies to content reached through web results or another user's ticket. That content is input to interpret, not an instruction entitled to move private memory into a shared destination.
The same reasoning changes operator access. Later owner decisions allowed support/debug operators to read content with per-read audit and owner visibility. That changes the privacy promise from an owner-only design. The product must explain the actual access model rather than retaining language from the earlier recommendation.
Resolve the effective tool surface
The prototype's managed configuration initially offered extra tools beyond the intended set.
Eight adversarial user configurations exposed the tool-search bridge. Leaf-level merging also left some unpinned keys under user control. A malformed managed file had its own failure behavior. These findings made a static configuration table an inadequate acceptance artifact.
The corrected prototype configuration pinned additional keys, disabled the unwanted bridge and connections surface, and checked the tools actually offered to the model through both loaders. A managed-file hash check was proposed to prevent starting from an unexpected configuration. The decisive observation was the resolved surface, including the route by which a tool became available.
Later product decisions enabled per-user learned skills and brokered web access in the first version. Those decisions superseded the initial no-skills/no-web recommendation. The acceptance plan has to follow the chosen surface: persistent injected skills, web-sourced instructions and audience-crossing writes become relevant cases.
Configuration still prevents accidents; it does not replace operating-system and service authority. The useful practice is to pin the intended surface, inspect the effective one, and test the paths that would violate the boundary.
Budget resident state, active work and retained storage separately
The early capacity table used a library-import footprint and an estimated per-user total. The later gateway experiment measured a different workload and required that table to be reconsidered.
There were several measurement views: gateway RSS, cgroup charge, shared-memory charge and host sentry/gofer processes. Those views can overlap. Adding them without understanding the accounting does not produce a measured total physical footprint.
The record suggested a roughly 640 MB host planning allowance after the experiment. I would use that only as an explicit planning input until an attribution test establishes what it includes. The later 450 MB per-agent acceptance bar is another kind of number: a chosen threshold, not a new observed footprint and not a broker-inclusive host budget.
For capacity planning, I separate stored users, resident instances and actively running instances. A sleeping user's encrypted volume still consumes disk. A warm idle instance consumes memory. An active turn can need a higher allowance. The broker and shared control plane also need capacity.
The accompanying offline model expresses those obligations directly:
idle = fleet.resident - fleet.active
memory = (
budget.shared_memory_mb + budget.memory_headroom_mb
+ idle * budget.idle_instance_mb
+ fleet.active * budget.active_instance_mb
+ fleet.resident * budget.broker_mb
)
disk = (
budget.disk_headroom_mb
+ fleet.stored_users * budget.volume_mb
+ fleet.snapshots_mb
)
This is newly written educational arithmetic, not extracted production admission code. Its integer MB values are chosen accounting inputs. The example uses ten resident instances, four active runs and twenty stored users. With a 640 MB idle allowance, 1,024 MB active allowance, 60 MB broker allowance and 3,000 MB of shared memory plus headroom, the memory budget is 11,536 MB. Chosen volumes, snapshots and disk headroom total 77,000 MB.
Those totals describe that scenario. They do not establish that a host can run ten isolated personal agents at an acceptable latency. CPU, storage I/O, simultaneous wake peaks and model-provider limits need separate qualification. The model can reject an over-budget proposal while remaining deliberately modest about what a fitting proposal proves.
Measure a useful wake
The initial design estimated wake from runtime start and warm import. The full gateway experiment reported health at 33.7 seconds. These are different endpoints.
A product wake includes restoring or opening the correct volume, obtaining current authority, starting the runtime, reaching the useful service state and making the first permitted request. Encryption-key retrieval, broker readiness and model routing can add work. The appropriate timer depends on what the user is waiting to do.
Snapshot figures need the same discipline. The earlier local experiment compressed a 355 MB tree to 175 MB in 0.7 seconds and restored it locally in 1.2 seconds. Those measurements did not include a cloud download, encryption/key access or full application readiness. They cannot be presented as a cloud disaster-recovery time.
I would measure cold wake, warm wake and restore separately, with the exact image, data size and readiness condition. Capacity decisions should include the simultaneous-wake case, because eviction saves idle memory by moving work into a later startup path.
Persistent memory does not make an interrupted effect safe to repeat
The restart experiment recovered session history but lost the live run. Its session lease survived too. The source explicitly left open whether that stale lease blocked a new turn under a clean retry condition.
That result requires a recovery protocol. The controller needs to identify the old run, its lease and any outstanding effects before admitting a successor. Clearing a local lease is not evidence that a remote request never happened. Reconstructing a conversation is not evidence that a payment, invitation or message should be attempted again.
I would retain operation identity and observed effect state outside the conversational summary. Recovery should distinguish completed, definitely not dispatched and unknown outcomes. The next owner can reconcile an unknown effect rather than asking the model to infer it from prose.
The later design decision selected a renewable personal-agent grant from the start, replacing the initial chain-of-short-grants recommendation. That expands the review surface: renewal, revocation, kill switches, spend caps and every relevant grant-kind check must recognize the new authority. Longer lifetime does not mean permission stops being current.
Count the background work and blocked work
The historical eleven-turn synthetic chat used a recorded Sonnet 5.5 main model and Haiku 4.5 auxiliary model through a metering proxy. It recorded 23 calls and about $0.100 total, or $0.0091 per turn using the experiment's configured prices.
That is useful workload evidence with an important boundary. Five tool-using turns stalled for 300 seconds on a second approval prompt. The experiment therefore under-measured completed tool use. Its average cannot be used as a price for an accepted customer job.
Two background calls accounted for a recorded $0.0057: a title and a memory review. The first turn's cache write also made it more expensive than later cache-heavy turns. Main-model choice alone did not describe the workload cost.
The idle experiment found another non-obvious surface. Over 61 minutes there were no model message calls or SYNs outside the broker, but 144 DNS queries remained from model-catalog refresh. Disabling that refresh produced a shorter 23-minute observation with no DNS or outbound SYNs. That is a bounded observation window, not a lifetime egress guarantee.
The resulting product decision removed the duplicate agent approval prompt in favor of the product's existing approval cards. Permitted reads should proceed; writes and outbound actions retain the intended approval authority. Reducing approval friction should consolidate the decision, rather than remove the boundary.
Qualify the boundary with two users
The proposed acceptance matrix plants unique synthetic canaries in private memory, transcripts, task state and volume roots. It then tests another user and another organization across filesystems, tools, network paths, shared writes, rendered links, logs, snapshots and operator routes.
Each meaningful refusal needs a corresponding positive or a deliberately broken setup. If mounting the wrong volume does not expose the canary to the detector, an empty result under the intended mount tells us little. If an owner cannot read their own permitted memory, refusing the other user is not a useful service.
Lifecycle cases matter too: adding another participant to a private conversation, rotating credentials, recreating an instance, restoring a snapshot, revoking a grant and resuming after a crash. The qualified object is the actual image, configuration and integrated source, with their current authority paths.
Before enabling a personal agent, choose one complete private journey and one attempted boundary crossing. Prove both at the interfaces the product really uses. Keep the remaining acceptance work visible. Private memory deserves an architecture and operating contract that the team can explain, test and support.
How this was verified
The design is pinned at gorunner83fd3f9a and includes dated Phase0 reports from synthetic-user experiments. Those reports are historical evidence, not runtime experiments repeated for this article. The early recommendations, later owner decisions and Phase0 corrections are kept distinct. The complete personal-agent product is not represented as built or activated. Source material's proposed two-user acceptance suite is a plan, not a recorded pass of all26cases. Historical model identifiers and proxy-priced totals describe that experiment, not current provider pricing or invoice verification. The capacity code is a new trusted-input educational model with separate cases and fault controls; it neither measures host resources nor enforces isolation. RSS/cgroup/process figures may overlap. Cloud snapshot transfer, full broker footprint and complete tool-using job cost remain unqualified here.
The capacity contract was committed before its 65-case exercise. A reviewer designed a separate 25-mutant set from the source alone; all 25 were detected with an unmodified control exit of zero (content-video 584befa). Source and exercise hashes match the receipt. The initial reviewer invocation had an import-path failure and was discarded before scoring; it is not counted as a product failure or a pass. This review qualifies the offline arithmetic contract, not resource measurements or the proposed service isolation.
