Give a requester a per-rollout scratchpad, partitioned per account #197

Closed
opened 2026-08-12 22:51:24 +00:00 by coilyco-ops · 0 comments
Member

#155 chose the file verbs but recorded that the workspace behind them had to be declared first: where it mounts, whether it persists, and whether it is shared or partitioned. This issue is that declaration and its implementation.

Shape

Per rollout, not per turn and not persistent. The backing volume is an emptyDir, so the scratchpad lives exactly as long as the pod. Files survive across the turns of a conversation, and a rollout erases everything. No PVC, no claim to restore, and no eviction policy, because a rollout is the reset.

Partitioned per requester. Each account gets its own directory. One requester cannot list, read, or search another's files.

The partitioning is what matters most, because the demo guild is now users: all. A shared scratchpad would be a data path between arbitrary guild members, which is exactly the gap #155 flagged and which the access policy does not model.

Why this does not hit the execution guard

executionguard.go refuses execution once more than one account is admitted, because execution "carries no per-requester attribution". A guild is admitted now, so that objection applies to any shared write surface.

The scratchpad supplies the attribution rather than asking admission to narrow. A turn carrying no principal is refused outright.

Attribution reaches the tool layer through the turn context, which is the only per-turn seam a process-wide tool provider has. No tool interface changed.

Where it sits on #179's line

It reaches none of the five categories. No credential, no infrastructure mutation, no execution, no external publication, no third-party personal data. Worst case is a requester filling their own 4 MB and being told so.

The line it deliberately stays behind is item 3's writable path into a repository working tree. Adding a checkout would be a separate decision.

Bounds

  • Text only. UTF-8 validated on write and on read.
  • Files written 0600. The execute bit is denied by the mode, not discouraged by a description.
  • 256 KB per file, 4 MB per requester. Listing, search, and nesting all capped.
  • A parent segment is refused rather than normalized away, and the target is checked after symlinks are followed.

Off by default

No SIRENS_ECHO_SCRATCH means no tools at all, not tools that refuse. A deployment that has not mounted the volume pays nothing for the capability in its prompt, which keeps this from compounding the prefix question in #162.

That also means landing this on main changes no running behavior. It goes live only when deployment mounts the volume and sets the variable.

Not in scope

Web search from #155, which carries none of the filesystem questions and should land on its own. The per-turn upload file in #156, which should become an ingress path into this scratchpad rather than a second file concept with its own lifetime.

  • #155 - the tool set, and the workspace declaration this supplies
  • #156 - the per-turn upload, to be folded in as ingress
  • #168 - image reading, which waits on a file surface existing
  • #179 - the blast-radius line this is classified against
#155 chose the file verbs but recorded that the workspace behind them had to be declared first: where it mounts, whether it persists, and whether it is shared or partitioned. This issue is that declaration and its implementation. ## Shape **Per rollout, not per turn and not persistent.** The backing volume is an `emptyDir`, so the scratchpad lives exactly as long as the pod. Files survive across the turns of a conversation, and a rollout erases everything. No PVC, no claim to restore, and no eviction policy, because a rollout is the reset. **Partitioned per requester.** Each account gets its own directory. One requester cannot list, read, or search another's files. The partitioning is what matters most, because the demo guild is now `users: all`. A shared scratchpad would be a data path between arbitrary guild members, which is exactly the gap #155 flagged and which the access policy does not model. ## Why this does not hit the execution guard `executionguard.go` refuses execution once more than one account is admitted, because execution "carries no per-requester attribution". A guild is admitted now, so that objection applies to any shared write surface. The scratchpad supplies the attribution rather than asking admission to narrow. A turn carrying no principal is refused outright. Attribution reaches the tool layer through the turn context, which is the only per-turn seam a process-wide tool provider has. No tool interface changed. ## Where it sits on #179's line It reaches none of the five categories. No credential, no infrastructure mutation, no execution, no external publication, no third-party personal data. Worst case is a requester filling their own 4 MB and being told so. The line it deliberately stays behind is item 3's **writable path into a repository working tree**. Adding a checkout would be a separate decision. ## Bounds * Text only. UTF-8 validated on write and on read. * Files written `0600`. The execute bit is denied by the mode, not discouraged by a description. * 256 KB per file, 4 MB per requester. Listing, search, and nesting all capped. * A parent segment is refused rather than normalized away, and the target is checked after symlinks are followed. ## Off by default No `SIRENS_ECHO_SCRATCH` means **no tools at all**, not tools that refuse. A deployment that has not mounted the volume pays nothing for the capability in its prompt, which keeps this from compounding the prefix question in #162. That also means landing this on main changes no running behavior. It goes live only when deployment mounts the volume and sets the variable. ## Not in scope Web search from #155, which carries none of the filesystem questions and should land on its own. The per-turn upload file in #156, which should become an ingress path into this scratchpad rather than a second file concept with its own lifetime. ## Related * #155 - the tool set, and the workspace declaration this supplies * #156 - the per-turn upload, to be folded in as ingress * #168 - image reading, which waits on a file surface existing * #179 - the blast-radius line this is classified against
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-gaming/sirens-echo#197
No description provided.