@volter/twin-slack
Slack
Local Slack messages, channels, OAuth installation and incoming webhooks over a synthetic workspace. No real Slack messages or invitation emails are sent.
Your World stack
Set up these twins together
In your app’s folder, install the exact choices with the current starter tools:
For a new World, select just these vendors and publishers:
Review the generated bindings and keep each source version in agreement with your manifest and lockfile. An existing World keeps its state and configuration; follow the update guide to change it. Check each release’s Node and kernel requirements before installing.
Your choices stay in this browser. Use several twins together
Mirror UI
Local twin screens with synthetic data · @volter/twin-slack 3.0.9
Setup gives the current installation instructions for @volter/twin-slack 3.0.9. Open the published README for credentials, seeds, supported operations and limits.
This release declares 179 unsupported HTTP operations. Check operation support in Evidence.
README shipped with @volter/twin-slack 3.0.9
These instructions were published with this package. Their tool versions may differ from the current starter cohort. Use Setup to install this version.
Slack's Web API, workspace invitations and member pages, app configuration and OAuth install pages, incoming webhooks and signed app deliveries. The pinned API and corrections are in spec/; provenance is spec/SOURCE.md. The current product callers, operation decisions and customer story are in journeys/.
Use with an existing app
Use Node 22.6 or newer.
In an app that already uses Slack, install the product CLI and this exact twin release:
npm install --save-dev --save-exact @volter/world@3.0.165 @volter/world-core@3.0.155 @volter/twin-slack@3.0.9
./node_modules/.bin/volter world init --name my-app --twins slack --source slack=@volter/twin-slack
Run the local executable from this app’s folder; if it is missing, complete the installation here before continuing.
Review the detected vendor and bindings before booting. The World issues throwaway bot, Socket Mode and signing credentials using the names listed below. Run the app's own command inside the World:
./node_modules/.bin/volter world up
./node_modules/.bin/volter world run -- npm test
./node_modules/.bin/volter world log
./node_modules/.bin/volter world down
Replace npm test with your app or test command. down retains state and a later up resumes it.
Publisher and catalog contribution instructions: the public publisher guide.
The pack models an ordinary workspace with people, channels, timestamped messages and threads, files, normal workspace
user groups, apps and their scoped grants. Its APIs keep Slack's ok/error envelope, cursor paging and caller visibility.
OAuth codes and grants have their own secrets, expiry and revocation. File bytes use the kernel blob seam. Scheduled
messages use the World clock.
Conversation workspace identity uses Slack's context_team_id, including channel visibility after vendor refresh
and shared-World cloning. Existing local rows that carry team_id remain readable.
A person creates the workspace at slack.com/get-started and joins through invitation mail and the Join page. Workspace
admins manage members and invitation requests at slack.com/admin. Developers configure their app at api.slack.com/apps;
installation uses slack.com/oauth/v2/authorize and oauth.v2.access. Program calls use their own issued tokens; a person's
synthetic client session is xoxp-<user-id>. Real credentials are never needed.
In a named World browser, an existing member enters OAuth consent through slack.com/signin: their email,
the confirmation code in the twin's /_twin/mail inbox, then the browser session. The consent page shows the
requested bot/user scopes and the eligible channel for an incoming webhook. Apple/Google, SSO, passkeys and
multi-workspace switching are outside that screen's scope. This flow sends no real email.
Fresh local Worlds seed a synthetic workspace named World with its owner and #general through that signup flow.
The default seed is copied into the application's .volter/seeds/ by init and remains editable there. Use the CLI and core versions pinned above for this release.
The conversation mirror opens at app.slack.com/client/<workspace-id>/<conversation-id>, or /client
at the World's Slack address. Sign in with an existing synthetic member's email and the confirmation code in
/_twin/mail?to=<email>; the opaque browser session acts as that active member. The sidebar lists joined
channels and existing individual or group DMs. Public channels outside the member's sidebar are available
under Browse channels, with Join Channel using conversations.join. New message opens or resumes a DM
through conversations.open.
The opaque browser session authenticates API calls only from an original same-origin POST. Opening an API URL as a link does not borrow that session. Explicit API tokens retain Slack's GET/POST method compatibility and take precedence over the browser cookie.
The client displays actual stored messages in time order, sender names, text, Slack links and mentions,
section/rich-text content from blocks, attachments, file names, edit markers, reaction counts and thread reply counts. Reply in thread
opens the original message and its replies alongside the channel. Send now and thread replies call
chat.postMessage, including thread_ts and the optional reply_broadcast. The existing API supplies
timestamps, stored writes and app events. A successful call opens a fresh stored view; a refusal preserves
the draft and displays the API's error. Archived channels retain readable history and have no composer.
Missing or inaccessible conversations and missing threads refuse without disclosing their messages.
The administration, app settings and OAuth screens remain separate.
The composer sends with Enter; Shift-Enter inserts a line break. Synthetic member/app avatars and rail icons use the public brand.volter.ai service, which must be reachable. No vendor avatar is downloaded. Section fields and rich-text lists, quotes, preformatted text and styles are read from the stored blocks. Section mrkdwn displays bold, italic, strikethrough, inline code and fenced code while retaining existing links and visible mentions. Plain-text fields remain literal; advanced formatting combinations are not claimed. Unsupported block elements remain text-only or explicitly unavailable; their controls do not pretend to act.
The client is a basic conversation mirror. Message editing, adding/removing reactions, file upload/download, rich composer
formatting, search, notification/activity feeds, huddles, canvases and lists have no client controls here.
Reading existing conversations works without JavaScript; automatic return to the conversation and inline
API errors require it. A native form submission receives the API's JSON answer.
Thread selection uses the mirror's thread_ts query parameter. Message times are displayed in UTC.
The local sign-in page also answers on the client host so its World-scoped session remains on the
same browser origin. Appearance follows Slack Support's public quick-start channel, sidebar and composer
references; no Slack page, avatar asset or DOM is captured or copied into the pack.
World doors represent acts the API does not perform: an externally developed distributed app (/_twin/apps), a client
slash command, Home opening, link share or action (/_twin/client/*), and observation of app deliveries or invitation mail
(/_twin/deliveries and /_twin/mail). The application's own credentials come from /_twin/app-credentials, which the
World asks at every boot: its own app, installed in its workspace, with a bot token (SLACK_BOT_TOKEN), an app-level
Socket Mode token (SLACK_APP_TOKEN) and the app's signing secret. It is subscribed to every event the twin sends (link_shared
aside: it names no unfurl domain) and receives them over Socket Mode (it has no Request URL); its bot holds every scope Slack's methods name. Stored vendor mutations still use the API or vendor pages.
Its callers are journeys/demand.json's: RH2's Slack app and channel bridge, Volter Harness's Slack platform (the Chat SDK in Socket Mode), Twin's on-call recipe, Dub's Slack integration and Postiz's Slack channel. Enterprise Grid administration, SCIM provisioning and legacy OAuth are outside the modeled slate. Every Web API operation no demand, life step or refresh reaches answers the gap (unknown_method), files.upload among them. The upload flow is files.getUploadURLExternal, its returned byte-upload URL and files.completeUploadExternal.
Publishing and catalog process: the public publisher guide. Standing is the Protocol 3 grade and score-pack report, recorded after the whole slate is written. No result here asserts that the final walk or independent review has run.
Dub priority support can create a channel and send a recipient-specific Slack Connect email invitation. The stored pending invitation is read through conversations.listConnectInvites with count/cursor pagination and retained in the local mail outbox. Receiving-workspace acceptance, approval, user-id recipients and join links are outside this workflow; the twin sends no real invitation mail. Targeted invitation responses disclose no shareable URL.
Install a selected release
Choose the implementation and exact package version in the Slack catalog.
Use that release's Setup tab for installation instructions. Use a catalog twin
explains selection and setup. Keep the selected package version, your app's lockfile and the World service's
source.package and source.version in agreement.
Set up this release
Use a Node version matching >=22.3. Install this exact starter cohort in your app folder:
npm install --save-dev --save-exact @volter/world@3.0.165 @volter/world-core@3.0.155 @volter/world-runtime@3.0.163 @volter/world-console@3.0.151 @volter/world-ui@1.0.155 @volter/twin-slack@3.0.9In your app’s folder, initialize a World with this implementation:
./node_modules/.bin/volter world init --name my-app --twins slack --source slack=@volter/twin-slackReview the detected vendor and retain the generated bindings. The slack service’s source must select this version:
{
"source": {
"package": "@volter/twin-slack",
"version": "3.0.9"
}
}This is the source field, not a complete config. Keep the installed version, lockfile and generated service source in agreement. Use the release README for throwaway SDK credentials, seeds and limits.
The assessment records its own earlier tool versions under Measurements. This setup uses the current starter cohort.
Run your app’s own test command inside the World:
./node_modules/.bin/volter world up
./node_modules/.bin/volter world run -- npm test
./node_modules/.bin/volter world log
./node_modules/.bin/volter world downdown stops compute and retains state.
Versions and implementations
| Package / version | Publisher | Status | First use |
|---|---|---|---|
| @volter/twin-slack3.0.9 | volter-ai | Selected default | Passed |
| @volter/twin-slack3.0.8 | volter-ai | live | Passed |
| @volter/twin-slack3.0.7 | volter-ai | live | Passed |
| @volter/twin-slack3.0.6 | volter-ai | live | Passed |
| @volter/twin-slack3.0.5 | volter-ai | live | Passed |
| @volter/twin-slack3.0.4 | volter-ai | live | Not measured |
| @volter/twin-slack3.0.3 | volter-ai | live | Not measured |
Evidence for 3.0.9
Declared unsupported HTTP operations · 179
This release declares these operations unmodeled. They answer the vendor’s unknown-request error. Journey coverage is measured separately.
slack:admin_analytics_getFileslack:admin_apps_activities_listslack:admin_apps_approveslack:admin_apps_approved_listslack:admin_apps_config_lookupslack:admin_apps_config_setslack:admin_apps_requests_cancelslack:admin_apps_requests_listslack:admin_apps_restrictslack:admin_apps_restricted_listslack:admin_audit_anomaly_allow_getItemslack:admin_audit_anomaly_allow_updateItemslack:admin_auth_policy_assignEntitiesslack:admin_auth_policy_getEntitiesslack:admin_auth_policy_removeEntitiesslack:admin_barriers_createslack:admin_barriers_deleteslack:admin_barriers_listslack:admin_barriers_updateslack:admin_conversations_archiveslack:admin_conversations_convertToPrivateslack:admin_conversations_createslack:admin_conversations_deleteslack:admin_conversations_disconnectSharedslack:admin_conversations_ekm_listOriginalConnectedChannelInfoslack:admin_conversations_getConversationPrefsslack:admin_conversations_getCustomRetentionslack:admin_conversations_getTeamsslack:admin_conversations_inviteslack:admin_conversations_removeCustomRetentionslack:admin_conversations_renameslack:admin_conversations_restrictAccess_addGroupslack:admin_conversations_restrictAccess_listGroupsslack:admin_conversations_restrictAccess_removeGroupslack:admin_conversations_searchslack:admin_conversations_setConversationPrefsslack:admin_conversations_setCustomRetentionslack:admin_conversations_setTeamsslack:admin_conversations_unarchiveslack:admin_emoji_addslack:admin_emoji_addAliasslack:admin_emoji_listslack:admin_emoji_removeslack:admin_emoji_renameslack:admin_functions_listslack:admin_functions_permissions_lookupslack:admin_functions_permissions_setslack:admin_inviteRequests_approveslack:admin_inviteRequests_approved_listslack:admin_inviteRequests_denied_listslack:admin_inviteRequests_denyslack:admin_inviteRequests_listslack:admin_roles_addAssignmentsslack:admin_roles_listAssignmentsslack:admin_roles_removeAssignmentsslack:admin_teams_admins_listslack:admin_teams_createslack:admin_teams_listslack:admin_teams_owners_listslack:admin_teams_settings_infoslack:admin_teams_settings_setDefaultChannelsslack:admin_teams_settings_setDescriptionslack:admin_teams_settings_setDiscoverabilityslack:admin_teams_settings_setIconslack:admin_teams_settings_setNameslack:admin_usergroups_addChannelsslack:admin_usergroups_addTeamsslack:admin_usergroups_listChannelsslack:admin_usergroups_removeChannelsslack:admin_users_assignslack:admin_users_inviteslack:admin_users_listslack:admin_users_removeslack:admin_users_session_clearSettingsslack:admin_users_session_getSettingsslack:admin_users_session_invalidateslack:admin_users_session_listslack:admin_users_session_resetslack:admin_users_session_resetBulkslack:admin_users_session_setSettingsslack:admin_users_setAdminslack:admin_users_setExpirationslack:admin_users_setOwnerslack:admin_users_setRegularslack:admin_users_unsupportedVersions_exportslack:admin_workflows_collaborators_addslack:admin_workflows_collaborators_removeslack:admin_workflows_permissions_lookupslack:admin_workflows_searchslack:admin_workflows_unpublishslack:api_testslack:apps_event_authorizations_listslack:apps_permissions_infoslack:apps_permissions_requestslack:apps_permissions_resources_listslack:apps_permissions_scopes_listslack:apps_permissions_users_listslack:apps_permissions_users_requestslack:audit_v1_actionsslack:audit_v1_logsslack:audit_v1_schemasslack:bookmarks_addslack:bookmarks_editslack:bookmarks_listslack:bookmarks_removeslack:bots_infoslack:calls_addslack:calls_endslack:calls_infoslack:calls_participants_addslack:calls_participants_removeslack:calls_updateslack:canvases_access_deleteslack:canvases_access_setslack:canvases_createslack:canvases_deleteslack:canvases_editslack:canvases_sections_lookupslack:conversations_canvases_createslack:conversations_closeslack:conversations_externalInvitePermissions_setslack:conversations_kickslack:dialog_openslack:dnd_endDndslack:dnd_infoslack:dnd_teamInfoslack:files_comments_addslack:files_comments_deleteslack:files_comments_listslack:files_infoslack:files_remote_addslack:files_remote_infoslack:files_remote_listslack:files_remote_removeslack:files_remote_shareslack:files_remote_updateslack:files_revokePublicURLslack:files_sharedPublicURLslack:files_uploadslack:functions_completeErrorslack:functions_completeSuccessslack:migration_exchangeslack:oauth_accessslack:oauth_tokenslack:openid_connect_tokenslack:openid_connect_userInfoslack:reactions_listslack:reminders_addslack:reminders_completeslack:reminders_deleteslack:reminders_infoslack:reminders_listslack:rtm_connectslack:search_allslack:search_filesslack:search_messagesslack:stars_addslack:stars_listslack:stars_removeslack:team_accessLogsslack:team_billableInfoslack:team_integrationLogsslack:team_preferences_listslack:team_profile_getslack:users_deletePhotoslack:users_identityslack:users_lookupByEmailslack:users_setActiveslack:users_setPhotoslack:views_openslack:views_pushslack:views_updateslack:workflows_stepCompletedslack:workflows_stepFailedslack:workflows_triggers_createslack:workflows_triggers_deleteslack:workflows_triggers_listslack:workflows_triggers_updateslack:workflows_updateStep
Installed first use · Passed
- Installed first use
- Passed
- Fresh app installation
- Verified
- Workflow scope
- Exact installed artifact; normal CLI initialization, unchanged SDK, result assertions and retained-state read-only resume where applicable
- Customer SDK versions
@slack/web-api@7.19.0- CLI, kernel and runtime versions
@volter/world@3.0.165·@volter/world-core@3.0.155·@volter/world-runtime@3.0.163- World clock
- {"mode":"wall"}
- Retained-state readback
- Verified
- Stopped compute
- Verified
- Customer journey failures
- 0
API coverage, replay and browser measurements
Counts describe the declared HTTP surface, not separate command tables or other protocols. Consult the release README for those workflows.
- Assessment scope
- packaged-customer-journey; in-process
- Declared HTTP surface
- 68 served · 179 gaps · 247 declared operations
- Exercised HTTP operation coverage
- 59 / 247 declared operations (23.9%)
- Journey steps
- 221 answered / 246 steps
- Replay
- Equal across 2 runs
- Journey failures
- 0
- Browser target
- Not measured
- HTTP operations exercised through Chromium
- Not measured
- Chromium journey replay
- Not measured
- Browser response observation
- Not recorded
- Application-origin CORS coverage
- Not measured
- Native cookie-jar coverage
- Not measured
- DOM coverage
- Not measured
- Source code coverage
- Not measured
- State transition coverage
- Not measured
Operations not exercised · measurement only
An operation not exercised by this journey may be served or unsupported. Check the separate declared unsupported operations above.
slack:admin_analytics_getFileslack:admin_apps_activities_listslack:admin_apps_approveslack:admin_apps_approved_listslack:admin_apps_config_lookupslack:admin_apps_config_setslack:admin_apps_requests_cancelslack:admin_apps_requests_listslack:admin_apps_restrictslack:admin_apps_restricted_listslack:admin_audit_anomaly_allow_getItemslack:admin_audit_anomaly_allow_updateItemslack:admin_auth_policy_assignEntitiesslack:admin_auth_policy_getEntitiesslack:admin_auth_policy_removeEntitiesslack:admin_barriers_createslack:admin_barriers_deleteslack:admin_barriers_listslack:admin_barriers_updateslack:admin_conversations_archiveslack:admin_conversations_convertToPrivateslack:admin_conversations_createslack:admin_conversations_deleteslack:admin_conversations_disconnectSharedslack:admin_conversations_ekm_listOriginalConnectedChannelInfoslack:admin_conversations_getConversationPrefsslack:admin_conversations_getCustomRetentionslack:admin_conversations_getTeamsslack:admin_conversations_inviteslack:admin_conversations_removeCustomRetentionslack:admin_conversations_renameslack:admin_conversations_restrictAccess_addGroupslack:admin_conversations_restrictAccess_listGroupsslack:admin_conversations_restrictAccess_removeGroupslack:admin_conversations_searchslack:admin_conversations_setConversationPrefsslack:admin_conversations_setCustomRetentionslack:admin_conversations_setTeamsslack:admin_conversations_unarchiveslack:admin_emoji_addslack:admin_emoji_addAliasslack:admin_emoji_listslack:admin_emoji_removeslack:admin_emoji_renameslack:admin_functions_listslack:admin_functions_permissions_lookupslack:admin_functions_permissions_setslack:admin_inviteRequests_approveslack:admin_inviteRequests_approved_listslack:admin_inviteRequests_denied_listslack:admin_inviteRequests_denyslack:admin_inviteRequests_listslack:admin_roles_addAssignmentsslack:admin_roles_listAssignmentsslack:admin_roles_removeAssignmentsslack:admin_teams_admins_listslack:admin_teams_createslack:admin_teams_listslack:admin_teams_owners_listslack:admin_teams_settings_infoslack:admin_teams_settings_setDefaultChannelsslack:admin_teams_settings_setDescriptionslack:admin_teams_settings_setDiscoverabilityslack:admin_teams_settings_setIconslack:admin_teams_settings_setNameslack:admin_usergroups_addChannelsslack:admin_usergroups_addTeamsslack:admin_usergroups_listChannelsslack:admin_usergroups_removeChannelsslack:admin_users_assignslack:admin_users_inviteslack:admin_users_listslack:admin_users_removeslack:admin_users_session_clearSettingsslack:admin_users_session_getSettingsslack:admin_users_session_invalidateslack:admin_users_session_listslack:admin_users_session_resetslack:admin_users_session_resetBulkslack:admin_users_session_setSettingsslack:admin_users_setAdminslack:admin_users_setExpirationslack:admin_users_setOwnerslack:admin_users_setRegularslack:admin_users_unsupportedVersions_exportslack:admin_workflows_collaborators_addslack:admin_workflows_collaborators_removeslack:admin_workflows_permissions_lookupslack:admin_workflows_searchslack:admin_workflows_unpublishslack:api_testslack:apps_event_authorizations_listslack:apps_permissions_infoslack:apps_permissions_requestslack:apps_permissions_resources_listslack:apps_permissions_scopes_listslack:apps_permissions_users_listslack:apps_permissions_users_requestslack:audit_v1_actionsslack:audit_v1_logsslack:audit_v1_schemasslack:bookmarks_addslack:bookmarks_editslack:bookmarks_listslack:bookmarks_removeslack:bots_infoslack:calls_addslack:calls_endslack:calls_infoslack:calls_participants_addslack:calls_participants_removeslack:calls_updateslack:canvases_access_deleteslack:canvases_access_setslack:canvases_createslack:canvases_deleteslack:canvases_editslack:canvases_sections_lookupslack:chat_scheduledMessages_listslack:conversations_canvases_createslack:conversations_closeslack:conversations_externalInvitePermissions_setslack:conversations_kickslack:conversations_membersslack:dialog_openslack:dnd_endDndslack:dnd_infoslack:dnd_teamInfoslack:files_comments_addslack:files_comments_deleteslack:files_comments_listslack:files_infoslack:files_listslack:files_remote_addslack:files_remote_infoslack:files_remote_listslack:files_remote_removeslack:files_remote_shareslack:files_remote_updateslack:files_revokePublicURLslack:files_sharedPublicURLslack:files_uploadslack:functions_completeErrorslack:functions_completeSuccessslack:migration_exchangeslack:oauth_accessslack:oauth_tokenslack:openid_connect_tokenslack:openid_connect_userInfoslack:pins_listslack:reactions_getslack:reactions_listslack:reminders_addslack:reminders_completeslack:reminders_deleteslack:reminders_infoslack:reminders_listslack:rtm_connectslack:search_allslack:search_filesslack:search_messagesslack:stars_addslack:stars_listslack:stars_removeslack:team_accessLogsslack:team_billableInfoslack:team_integrationLogsslack:team_preferences_listslack:team_profile_getslack:usergroups_listslack:usergroups_users_listslack:users_deletePhotoslack:users_identityslack:users_infoslack:users_listslack:users_lookupByEmailslack:users_setActiveslack:users_setPhotoslack:views_openslack:views_pushslack:views_updateslack:workflows_stepCompletedslack:workflows_stepFailedslack:workflows_triggers_createslack:workflows_triggers_deleteslack:workflows_triggers_listslack:workflows_triggers_updateslack:workflows_updateStep
Conformance results
- decided: 0 failures · every served operation is decided with its demand; every demanded and every refreshed operation is served
- published: 0 failures · what a release publishes holds every unit: its manifest, its spec and its journeys
- cited: 0 failures · every vendor fact cited is recorded as a page that answered, each quote found on it
- refresh: 0 failures · every stored resource of a vendor-backed unit declares how it is read back, and a unit that sends events ingests the vendor's
- registered: 0 failures · a vendor-backed unit, lane or not, reaches the registered pack's state system
- allowance: 0 failures · a rate budget above the fallback rests on the vendor's documented allowance, cited in its manifest
- client: 0 failures · driven by the vendor's own client (its official SDK), served as a World runs it, the vendor's documented behaviour holds · 2 case(s) through the vendor's client
- life: 0 failures · the life walked over HTTP against the pack served as a World runs it, with its scenario: every check held
- standalone: 0 failures · served by its server.ts as a World runs it, the pack answers HTTP and the boot probe, and each declared socket upgrades
Publisher, admission and provenance
- Publisher
- volter-ai/twin-packs-open
- Source commit
- b828301d8954cedd90491525860fa03090897081
- Catalog record commit
- ccced73d6aff1c841514572b17161b9f4a365e7e
- Package integrity
sha512-m7LWrT6yU4cBdrzzSOaKaH4z+sdZehf6GlDng0YN5+v03xP3UTdkRLXzrWizsh6SNzs844v4RhfJGowH4bNcmQ==- Admission mode
- Trusted internal publisher · maintainer merge
- Catalog assessment
- Bundled report checksum verified
- Assessed at
- Not recorded
- Assessment input head
- ccced73d6aff1c841514572b17161b9f4a365e7e
- Evidence
- Assessment and admission
Catalog snapshot · @volter/twin-catalog@0.2.71
- Source commit
943891bdf6d9c7c912371d09abad928343448492- Catalog digest
97b49ec4477102b96f048169aba62b310c39b8bf49c3a910a24c9ef43ac6e36b- Installer integrity
sha512-Uny2d1umJ/a8y6XyMi05K4/t9HBHPIJmTHe0zrrJ+CdyqsKt8E99it8BEXslfC07xN42ttNCYyDgW6ZWBou4vg==
