# Limits and guardrails



<Info>
  This is a **public, customer-installed** Slack app running on your own data.
  Every limit below exists because of that, not because of a missing feature.
</Info>

## Tenancy [#tenancy]

* Your Slack workspace is connected to exactly **one** Surface environment,
  chosen at connect time by someone who can log into Surface.
* Every tool SAM has reads that environment. There is no tenant argument
  it could pass, and no path to another customer's data.
* Approval clicks are checked against the workspace that owns the pending
  action. A click from elsewhere reads as *not found*, not *forbidden*. A
  distinct answer would confirm the row exists to someone who shouldn't know.
* In [Slack Connect channels](/docs/sam/shared-channels) the gate is
  on **who is asking**, per channel.

## Permissions [#permissions]

| Control                  | Who sets it                           | Effect                                                                                                                   |
| ------------------------ | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Capability modules       | Surface admin                         | A tool outside an enabled module is never shown to the model, so it cannot be called. Structural, not a line in a prompt |
| Writes enabled           | Surface admin **and** the OAuth grant | Both must agree. Off means fully read-only, and it says so instead of pretending                                         |
| Daily question limit     | Surface admin                         | 200 by default, rolling 24 hours                                                                                         |
| Who can approve a change | Fixed                                 | The person who asked, or any Slack workspace admin                                                                       |

Three tools are **never** exposed to a customer whatever the configuration:
creating environments, inviting members, and filing feedback tickets.

## The approval gate [#the-approval-gate]

Anything not explicitly marked read-only parks behind an Approve/Cancel card.
The gate reads the tool's own annotation rather than a hand-maintained list of
dangerous operations, so a brand-new tool defaults to *needs approval*.

* The card carries the **finished** change. A placeholder or half-filled payload
  is bounced before any card is posted.
* The database row, not the card, is the source of truth. A double-click can't
  run a change twice; a lost card can't strand a half-done write.
* Editing published content edits the draft. Publishing is a second approval.
* **One shortcut, deliberately:** the **Save in Vault** button *is* the approval
  and there's no second card. It only ever creates a new dated document under
  `slack/` and can't overwrite or delete anything.

## Stopping mid-flight [#stopping-mid-flight]

Every status line carries a **Stop** button while SAM is working. A
stopped turn changes nothing, because writes were already parked behind approval cards,
so there's nothing half-done to unwind. Background jobs carry the same button on
their progress card.

## Budgets [#budgets]

| Budget                       | Value                                                                      |
| ---------------------------- | -------------------------------------------------------------------------- |
| Questions per workspace      | 200 / rolling 24h                                                          |
| Spend per question           | $5 ceiling, including generated images                                     |
| Reasoning steps per question | 15, with 4 lookups per step                                                |
| Background jobs              | 20 / rolling 24h · 2 concurrent · $12 and \~18 minutes each · 12 items max |
| Web searches / page reads    | 3 each per question; 10 / 20 per background job                            |
| Images in / out              | 8 read per message (5 MB each), 4 generated per request                    |
| Text files                   | 50,000 characters                                                          |
| Schedules                    | 10 per workspace                                                           |

Hitting a cap always produces a message (&#x2A;"that question got too big for one
go, try narrowing it down"*), never silence.

## Reaching the outside world [#reaching-the-outside-world]

Page fetching is `https` only, follows at most 3 redirects, caps at 2 MB and 10
seconds, and re-checks the resolved IP on **every** hop against private and
link-local ranges. It cannot be talked into reading an internal address.

## What is stored [#what-is-stored]

| Stored                                                                   | Where and why                                                                                                                                                                                                                                               |
| ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The question, the answer, status, tools used, cost, tokens, URLs fetched | One row per question, which powers the daily cap, the usage tool and our dashboards. Question and answer text also ride along on the product-analytics event, both cut at 4,000 characters. Tool results, meaning your Surface data in bulk, are never sent |
| Memory documents                                                         | Per workspace or channel. Fully visible and deletable in App Home                                                                                                                                                                                           |
| Schedules                                                                | Prompt, cadence, slot, target channel                                                                                                                                                                                                                       |
| Pending changes                                                          | Until approved or cancelled                                                                                                                                                                                                                                 |
| Slack bot token, Surface OAuth grant                                     | Encrypted. `/surface disconnect` revokes the Surface grant immediately                                                                                                                                                                                      |

Uninstalling tombstones the workspace rather than deleting it, so install
history survives for support. SAM reads the workspace as gone and stops
responding.
