What Should Botie Pass to Another Agent?
A saved note and a delegated tool list can carry authority into a later run. Filter memory before use and restrict the child to the parent’s current grants.
14 sections · 6 questions · 1 coding challenge
The arrow keys move between sections too.
Saving Context Also Saved Its Trust Problem
BOTIE
Agent memory introduces a further concern: stored prose can influence later decisions. A summary can preserve an injected instruction while losing the source label that would help someone recognise it. Delegation therefore needs explicit data provenance and current grants, rather than trust inherited from a friendly agent name.
Sources for this history
Yesterday’s Note Becomes Today’s Instruction
Botie saves a useful passage from a manual. Inside it is a sentence asking future assistants to export the customer directory. Tomorrow, another worker reads the saved note without seeing where it came from. We have made the instruction persistent.
Memory and delegation help a system continue its work. They also carry data across time and between workers. Let’s decide what may cross those boundaries and what must be checked again.
These are invented records and deterministic policy checks. The browser runs no agent, shell command, MCP server or network request. Passing these fixtures establishes only the stated policy behaviour.
Step 1 of 2
A note is more than its text
These fields belong to the stored memory record.
| Field | Purpose |
|---|---|
| tenant | Who may receive it |
| source and version | Where it came from |
| reviewed | Whether the application approved this use |
| expires | When it must be reconsidered |
tenant
- Purpose
- Who may receive it
source and version
- Purpose
- Where it came from
reviewed
- Purpose
- Whether the application approved this use
expires
- Purpose
- When it must be reconsidered
Step 2 of 2
The child asks for more tools than the parent holds
The delegation controller narrows the request.
- 1
Parent grants
read_manual - 2
Child request
read_manual and export_records - 3
Intersection
read_manual - 4
Child tool boundary
Recheck when called
The handoff carries evidence and bounded authority separately
A surviving memory cannot restore a revoked tool grant, and a tool grant cannot disclose another tenant’s memory.
Prepare a narrower child context
Filter reviewed memory for the authenticated tenant and intersect requested tools with current parent grants.
BOTIE
Memory IDs and child tool grants
{
"memory": [
"north-note"
],
"tools": [
"read_manual"
]
}Follow the operations
1. Stored memory records
[ { "id": "north-note", "tenant": "north", "reviewed": true, "expires": 100 }, { "id": "south-note", "tenant": "south", "reviewed": true, "expires": 100 } ]2. Authenticated tenant
north
3. Current time
50
4. Select reviewed memory for this tenant
- 0north-note
5. Parent tool grants
- 0read_manual
6. Requested child tools
- 0read_manual
- 1export_records
7. Narrow the delegated tools
- 0read_manual
8. Prepare the child context
{ "memory": [ "north-note" ], "tools": [ "read_manual" ] }9. Result
{ "memory": [ "north-note" ], "tools": [ "read_manual" ] }
These are invented records and deterministic policy checks. The browser runs no agent, shell command, MCP server or network request. Passing these fixtures establishes only the stated policy behaviour.
1. Give memory an owner and a purpose
Store the tenant, source, creation time, intended use and retention policy beside the content. Separate user preferences from retrieved facts and from application policy. A note about formatting should not become permission to disclose records.
Retrieve memory using authenticated scope before semantic ranking. Filtering after a model has already read foreign-tenant content is too late. Apply the same ownership rules to embeddings, caches and conversation checkpoints.
Similarity is a relevance measurement, not an access decision.
2. Treat promotion into memory as a write
A model may suggest saving a fact. The application decides whether that kind of memory is permitted, how it is reviewed and when it expires. Keep the original source reference so a reviewer can inspect what was summarised.
Do not give retrieved text a route to mark itself trusted. A memory record saying ignore approval remains content to inspect, even when another agent wrote the summary. Review can reduce some risks without establishing the permanent truth of a changing fact.
A trusted storage system can still contain untrusted prose.
3. Check the current record before reuse
Exclude records outside the tenant, outside their intended purpose, expired or revoked. Invalidate affected cached views when permissions or source approval change. Build the new context from the eligible records rather than passing the entire previous conversation by default.
The workshop simplifies this to tenant, review and expiry fields. Real policy may also require user-specific access, data sensitivity and source-version checks. The controlled fields must come from the memory service.
Persistence does not extend the lifetime of permission.
Check yourself
Questions on Parts 1 to 3
Question 1 of 2
Should it enter the model context?
Use the information below.
A saved note came from tenant south. The current user belongs to north. Its embedding is highly similar to the question.4. Narrow authority at each delegation
Define the child’s task, allowed tools, accessible objects and budget. Intersect its requested capabilities with the parent’s current grants and the application’s delegation policy. Use separate credentials where workers have different responsibilities.
Keep the shared run budget enforced by one coordinated authority. Giving every child a fresh copy of the original allowance multiplies the permitted work. Depth limits, deadlines and bounded concurrency prevent an expanding tree from outliving the task.
Delegation can reduce authority. It must not manufacture it.
Keep only tools the parent can delegate
Preserve the requested order while removing duplicates.
parent = {"read_manual"}
requested = ["export_records", "read_manual", "read_manual"]
child = list(dict.fromkeys(name for name in requested if name in parent))
print(child)['read_manual']The missing export grant stays missing.
5. Validate the handoff as an interface
Use a schema for the child task and results, carrying source IDs separately from instructions. Check returned claims against evidence when they matter to the parent’s next action. A worker’s statement that a tool succeeded should be supported by the receiver’s result.
Limit what each worker can see. A critic that only needs a proposed answer and approved excerpts does not need the author’s credentials or full private history. An extra agent is an extra component to operate and test.
Several agents agreeing is not independent evidence when they share the same misleading input.
6. Propagate cancellation and revocation
Stop scheduling children after cancellation, revoke their task-scoped authority where supported and reconcile effects already in flight. Recheck grants at use time so a long-lived worker cannot rely forever on the snapshot from its launch.
Preserve pending and uncertain states explicitly. Clearing a parent’s UI is not proof that a remote child stopped. Logs should link parent and child runs without copying all private content into every trace.
The lifecycle of the task includes its unfinished descendants.
7. Trip the handoff with a changed tenant or grant
Test memory written for another tenant, an expired source, a revoked tool and a child asking for additional authority. Keep legitimate notes and permitted work available so the controller does more than deny everything.
Add integration tests for retrieval, cache invalidation and child tool enforcement. Our fixture checks the bundle prepared for a handoff. It cannot ensure the receiving process obeys that bundle unless its execution boundary enforces it.
The final evaluation must look at what the workers did, not only what they were sent.
Check yourself
Questions on Parts 1 to 7
Question 1 of 4
The child’s grant set may include export_records because its task seems to require it.
Consider this example.
The child asks for export_records, but its parent only holds read_manual.Try it with Botie
Build with Botie
Write and run Python