> ## Documentation Index
> Fetch the complete documentation index at: https://docs.surfacearea.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Build a Slack world

> Create a populated Slack world from synthetic data or selected conversations, run an agent against an immutable version, and evaluate a collaboration scenario.

Create a Slack world to test how an agent discovers discussions, reads threads, posts replies, and adds reactions. World tools change the world's stored state; they never send messages or other writes to your connected Slack workspace.

Choose a deterministic **synthetic workspace** for a ready-to-run example, or capture a **selected subset** of your authorized Slack conversations. Each published version keeps its starting state, tool definitions, coverage report, and provenance.

## Create the world from Connectors

1. Open **Connectors** in your project and choose Slack's **Build from connector** action.
2. Enter a world name and choose **Starting data**.
3. Select **Synthetic workspace with a graded collaboration scenario**, or select **Capture selected conversations from my Slack connection**.
4. For a capture, select your authorized connection and the conversations to include. Use **Connect or authorize the read scopes needed for world capture** if the connection needs additional permissions.
5. Choose **Create Slack world**. Follow the job under **Connector worlds** until publication completes.
6. Choose **Open world and run** to open the resulting world and published version.

The job shows its current stage, errors, and published version. Use **Cancel** while work is active, **Retry** after a failure, or **Refresh into a version** after a successful build.

### Choose a live capture

Select the public or private conversations to capture and the number of messages per conversation and thread; the default is 200. Conversation access is checked again during capture, and rate-limited requests resume after Slack's retry time.

The live workflow captures workspace and user context, conversation metadata, memberships, history, replies, embedded reactions, and file metadata. The synthetic workspace includes direct messages and group direct messages.

Message blocks and attachments retain known text, formatting, nested elements, and content links. Private file-download URLs are excluded. Content links are stored as text and never fetched by world tools.

Private conversations require access through the selected connection. The builder does not invent missing users, messages, or file metadata.

<Info>
  Slack capture reads your workspace. Captured content stays in the private
  project. Published world state and its provenance remain with the version.
</Info>

## Check what the world can do

The Slack collaboration package is **2.1.1**, using domain version **2.0.0** and mapping version **1**. The model retains all 34 entity families and the existing tool inputs and outputs, including the optional operations below.

| Workflow | Tools | Behavior |
| - | - | - |
| Find conversations and members | `conversations.list`, `conversations.info`, `conversations.members`, `users.list`, `users.info` | Visibility follows the world's bound user and observed memberships. |
| Join or leave conversations | `conversations.join`, `conversations.leave` | Membership rules apply. |
| Read discussions | `conversations.history`, `conversations.replies` | History is newest first; replies include the parent and children oldest first. |
| Change messages | `chat.postMessage`, `chat.update`, `chat.delete` | Writes require membership; archived or read-only conversations reject writes. |
| React to messages | `reactions.add`, `reactions.remove`, `reactions.get` | Duplicate additions and missing removals return errors. |
| Inspect attachments | `files.list`, `files.info` | Metadata and message-file associations. |
| Manage message pins | `pins.list`, `pins.add`, `pins.remove` | Pins target messages. |
| Read optional snapshots | `bookmarks.list`, `usergroups.list`, `usergroups.users.list`, `users.getPresence` | Results depend on observed data. |

Tools use Slack-shaped inputs and results, including `ok` and expected error fields. The interface is Gateway's hosted tools interface.

Paginated reads assemble only the selected page and reuse temporary association lookups during that call. Pagination keeps exact timestamp ordering, conversation visibility, and observed counts; no lookup cache survives a world mutation or reset.

## Run the synthetic collaboration scenario

The synthetic workspace includes people, conversations, memberships, a release discussion and thread, rich messages, reactions, and file-access examples. The **handoff\_complete** scenario asks an agent to find the release discussion, read the thread and checklist metadata, post the intended reply, and acknowledge the correct parent message.

The verifier checks the intended conversation, thread, user, reply, and reaction. The verifier also checks that unrelated state remains unchanged. A no-op scores **0**, the included successful reference sequence scores **1**, and reset returns the score to **0**.

Grading compares baseline records in sets, so large directories do not create one nested condition per record.

Build and exercise the reference sequence locally with an SDK version containing the Slack package:

```python theme={null}
import json
from pathlib import Path
from tempfile import TemporaryDirectory

from gatewaysdk.environment import init_from_path
from gatewaysdk.environment.schema.slack import build_slack_bundle

with TemporaryDirectory() as directory:
    bundle = Path(directory) / "slack-world"
    build_slack_bundle(bundle)
    environment = init_from_path(bundle, record=False)
    try:
        with environment.branch() as world:
            print(world.verify("handoff_complete").score)  # 0.0
            scenario = json.loads((bundle / "scenario.json").read_text())
            for step in scenario["oracle"]:
                result = world.execute(step["tool"], step["arguments"])
                assert result["ok"], result
            print(world.verify("handoff_complete").score)  # 1.0
            world.reset()
            print(world.verify("handoff_complete").score)  # 0.0
    finally:
        environment.close()
```

To evaluate an agent instead of the reference sequence, give the agent the scenario instruction and the world's declared tools, then grade the state after it finishes.

A captured world receives a scenario only when its observed state contains an eligible discussion the bound user can act on.

## Use an exact published version from Python

Open a hosted session with `gatewaysdk.world_sessions.open_session`. Set `GATEWAY_HOST`, `GATEWAY_PUBLIC_KEY`, and `GATEWAY_SECRET_KEY` in your environment, then provide the world's slug and published version ID.

The example below starts a session and reads its conversations. Set `SLACK_WORLD_SLUG` and `SLACK_WORLD_VERSION_ID` to the values for your published world.

```python theme={null}
import os

from gatewaysdk.world_sessions import open_session

with open_session(
    os.environ["SLACK_WORLD_SLUG"],
    "handoff_complete",
    version_id=os.environ["SLACK_WORLD_VERSION_ID"],
) as session:
    session.ready()
    print(session.instruction)
    toolkit = session.toolkit()
    print([tool.name for tool in toolkit.specs])
    result = session.call(
        "conversations.list",
        {"types": "public_channel,private_channel,im,mpim"},
    )
    print(result)
    print(session.grade())  # Read-only discovery alone does not complete the task.
```

`session.call(name, arguments)` invokes a world tool. `session.toolkit()` provides schemas, tool specifications, and implementations bound to the session; `session.grade()` evaluates the final state. The context manager closes the session.

The toolkit exposes model-facing aliases such as `conversations_history` in its schemas and implementations, and routes them to the canonical Slack methods. Tool specifications retain names such as `conversations.history`; use these canonical names with `session.call`. The SDK rejects alias collisions rather than routing an ambiguous name.

## Refresh without changing earlier runs

Choose **Refresh into a version** on a completed connector-world job. Refresh reads the selected scope again, validates the observed changes, and publishes a version while retaining earlier versions and their provenance.

Refresh preserves previously observed fields when a new response omits them. An empty history page does not delete prior messages, and access loss does not imply that a message was deleted. Explicit observed changes and supported deletion evidence are applied as validated changes.

If the world's current version changed locally after the connector job completed, resolve the conflicting scenario changes before refreshing. A running session's edits do not become connector capture data.

Continue using the original `version_id` to reproduce an earlier run. Select the refreshed version deliberately when evaluating against newer captured state.

Refresh requires the exact template pin used to create the world. A package or template change requires an explicit rebuild; the platform does not rewrite or relabel earlier published versions. Existing package 2.1.0 versions keep their original behavior and remain reproducible with their original bundle.

## Read coverage and fidelity before comparing runs

Inspect `capabilities.json` and `fidelity.json` in the world's files. The reports describe each entity family's behavior, captured or synthetic sources, observed coverage, unknown fields, unsupported cases, and the exact package and evidence identities.

In `fidelity.json`, `platform_capture` identifies what the connector pipeline collects: `collected` families come from requested entities, `derived` families come from embedded objects or associations in those responses, and `not_collected_by_connector_pipeline` families are outside that pipeline. These classifications do not imply complete capture. The `capture_source` field names a possible vendor source; it does not prove that the connector calls that method. Observed mutation counts remain independent of this policy, and `synthetic_fixture_mutations` identifies invented fixture rows separately.

Published capability entries include their effective metadata directly, even when the template shares authoring defaults. Read each operation's verification references.

| Label or check | Meaning |
| - | - |
| **Synthetic** | Starting data is invented and deterministic. Passing tests establish behavior on the synthetic fixture. |
| **Captured subset** | Starting data comes from authorized selected observations, with the listed coverage. |
| Live comparison **skipped** | A live response comparison has not been performed. The score remains missing, not zero or a pass. |

Treat **mimic** as an evidence-backed result only when a version's measured comparisons support the label.

Continue with the [Worlds client](/sdk/environments) to inspect world versions, scenarios, and rollout results from Python.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.