Slack Marketplace submission pack
Use this pack as the working control sheet for the first public Threada Slack Marketplace submission. It is not approval evidence by itself. Before submitting, replace every placeholder with live deployment values and attach the runtime proof described below.
Submission stance
Submit the v1 app as a narrow slash-command integration:
- Users run
/threada <request>in a mapped Slack channel. - Threada creates a governed WorkItem in the configured pack and queue.
- Slack receives an acknowledgement with a WorkItem link.
- Review, evidence, approvals, proposals, actions, and audit history continue in Threada.
Do not claim Slack message history, file access, private-channel access, direct messages, App Home, Slack outbound posting, channel administration, workspace export, bulk actions, or automated execution from Slack for v1.
Slack app configuration
Use docs/integrations/slack-app-manifest.example.json as the import template,
then verify each field in Slack app settings before review.
| Setting | Value |
|---|---|
| App name | Threada |
| Slash command | /threada |
| Slash command request URL | https://api.threada.ai/api/v1/integrations/slack/commands |
| OAuth redirect URL | https://api.threada.ai/api/v1/integrations/slack/oauth/callback |
| Events API request URL | https://api.threada.ai/api/v1/integrations/slack/events |
| Event subscriptions | app_uninstalled only |
| Bot scopes | commands only |
| Socket Mode | Disabled |
| Org-wide deployment | Disabled for v1 unless Enterprise Grid behavior has been explicitly validated |
| Slack public distribution | Enabled before Marketplace review |
| Marketplace install path | Public setup page recorded in reviewer context. Use Slack Direct Install only after Threada supports an accountless OAuth handoff; if Direct Install is enabled, Slack’s dashboard must accept the URL’s 302 redirect to Slack OAuth. |
Before pressing submit, confirm the Slack app has been distributed publicly, the Marketplace install path can take a reviewer to Slack OAuth, the app has at least five active workspaces, the Events API request URL is verified, and the production slash-command endpoint is reachable over HTTPS from Slack.
Marketplace listing fields
Use this copy unless product or legal changes it before submission.
App name:
Threada
Short description:
Create governed Threada WorkItems from Slack requests.
Long description:
Threada helps teams turn operational requests into governed work. Use Threada from Slack to capture a request, route it to the right pack and queue, and continue review in Threada with drafts, evidence, approvals, and audit history.
Run /threada in a mapped Slack channel with the request you want to capture. Threada verifies the Slack request, creates a tenant-scoped WorkItem, and returns a link so your team can continue in Threada.
The v1 Slack app uses the commands scope only. It does not read Slack channel history, files, private channels, direct messages, or workspace exports.
Primary category:
Productivity
Pricing:
Included with service subscription
Marketing page URL:
https://docs.threada.ai/integrations/slack-setup/
Support URL:
https://docs.threada.ai/integrations/slack-setup/
Support email:
support@threada.ai
Support response:
Within 2 business days
Privacy policy URL:
https://threada.ai/legal/privacy/
Terms URL:
https://threada.ai/legal/terms/
Security overview URL:
https://docs.threada.ai/security/
Privacy and security contacts:
privacy@threada.ai
security@threada.ai
Scope and event justification
Use this table when Slack asks why each requested surface is needed. The v1
listing should request only the commands bot scope and the app_uninstalled
event subscription.
| Requested surface | Why Threada needs it | Data access boundary |
|---|---|---|
Bot scope commands | Receives /threada slash-command invocations so a user can create a governed WorkItem from Slack. | Slash-command payload for the invoking workspace/channel/user and submitted command text only; no channel history, files, private channels, direct messages, search, exports, admin APIs, or user-token scopes. |
Event subscription app_uninstalled | Detects Slack app uninstallation so Threada can revoke or disable the tenant workspace install mapping. | Slack Events API lifecycle envelope for the submitted app/workspace only; no message content or channel history. |
Reviewer environment
Fill this table with the exact Threada reviewer values and smoke-test evidence references Slack needs. Slack reviewers install the app into a Slack workspace they control; do not provide Threada-owned Slack workspace credentials. The Slack workspace and channel fields below are smoke-test evidence references for the same production app, not login material for Slack reviewers. Do not commit secrets, passwords, Slack signing secrets, OAuth client secrets, or customer PII.
| Field | Review value | Evidence owner |
|---|---|---|
| Threada deployment commit | TODO | Engineering |
| API base URL | https://api.threada.ai | Platform |
| Studio URL | TODO | Product |
| Work URL | https://work.threada.ai | Product |
| Reviewer tenant | TODO | Product |
| Reviewer admin account | TODO - provide through Slack submission notes, not this repo | Product |
| Reviewer credential handoff path | TODO - provide through Slack submission notes, not this repo | Product |
| Slack public distribution proof | TODO - Slack Manage Distribution reference | Integrations |
| Slack install/start URL | TODO - HTTPS install page or Direct Install URL | Product |
| Slack install flow proof | TODO - evidence the setup page exposes Add to Slack, or that Direct Install reaches Slack OAuth | Integrations |
| Slack app ID | TODO | Integrations |
| Slack client ID | TODO | Integrations |
| Smoke-tested Slack workspace name | TODO | Product |
| Smoke-tested Slack workspace URL | TODO | Product |
| Smoke-tested Slack reviewer user | TODO | Product |
| Smoke-tested Slack mapped channel name | TODO | Product |
| Smoke-tested Slack mapped channel ID | TODO | Product |
| Threada pack | TODO | Product |
| Threada queue or routing policy | TODO | Product |
| Expected success response | TODO - acknowledgement with WorkItem link | Engineering |
| Expected setup-required response | TODO - response text from unmapped or disabled test | Engineering |
Reviewer test notes
Paste this into the Slack submission after replacing placeholders with live values.
Use the provided Threada reviewer account to sign in to Studio:
Studio URL: TODO
Tenant: TODO
Pack: TODO
Slack install/start URL: TODO
Slack public distribution proof: TODO
Slack install flow proof: TODO
Do not use Threada-owned Slack workspace credentials. Install the app into a
Slack workspace you control during Marketplace review. The smoke-tested
workspace/channel values in the evidence package prove Threada tested the same
production app; they are not Slack credentials.
1. Sign in to Studio, then open the Slack install/start URL above.
2. Start the Slack install flow and approve the Threada app in the Slack workspace you use for Marketplace review.
3. After Slack redirects back to Studio, confirm the workspace install is shown and bound to the pack.
4. In Studio runtime channel settings, map the Slack channel you use for review to the same pack and queue.
5. In that Slack channel, run:
/threada Need vendor security review for ExampleCo before Friday
6. Expected result: Slack returns a Threada acknowledgement with a WorkItem link.
7. Open the WorkItem link and confirm the WorkItem is in the configured pack and queue, with Slack as the source channel and the original command text preserved.
8. Disable the Slack channel mapping in Studio or uninstall the app from Slack, then run /threada test again.
9. Expected result: Slack returns an explicit setup-required or disabled response, and no new WorkItem is created.
The v1 app requests only the commands scope. It does not read message history, files, private channels, direct messages, or workspace exports.
Support: support@threada.ai
Security: security@threada.ai
Privacy: privacy@threada.ai
Asset shot list
Capture production or reviewer-environment behavior only. The app icon must be a 512px by 512px PNG or JPG file. Screenshots should be 1600px by 1000px in PNG or JPG format and under 21 MB. Each listing image should show the Slack integration context; when showing Threada Studio or Work, pair it with the Slack command, Slack acknowledgement, or the post-click WorkItem destination from Slack. Avoid secrets, internal admin-only URLs, customer data, personal email addresses, and tokens.
| Asset | Required content | Status |
|---|---|---|
| App icon | 512x512 Threada app icon suitable for Slack Marketplace | TODO |
| Screenshot 1 | Slack channel showing /threada command and acknowledgement with WorkItem link | TODO |
| Screenshot 2 | Slack install result paired with Studio workspace install bound to the reviewer pack | TODO |
| Screenshot 3 | Slack mapped channel paired with Studio channel mapping for the reviewer queue | TODO |
| Screenshot 4 | Slack acknowledgement paired with the WorkItem showing Slack source, original request, and timeline | TODO |
| Optional screenshot 5 | Approval or governed action proposal view, only if the shown flow is live in the reviewer tenant | TODO |
| Optional demo video | 30-90 second public YouTube video with captions, ads disabled, install/OAuth, setup, end-to-end use, and uninstall shown if Threada chooses to include a video | OPTIONAL |
Use .deploy-evidence/slack-demo-video-review-cut.mp4 only as a local,
non-final pacing and copy review artifact. It must not be uploaded as the Slack
Marketplace demo while its companion manifest status remains
non_final_review_cut_not_for_youtube_submission or while
reviewer_safe_for_internal_bundle is not true; replace every placeholder
scene with live install/OAuth, setup-required, and uninstall/disconnect capture
before uploading any final public YouTube video. Keep the local review cut under
25 MiB so the non-final ready-subset ZIP remains an operator handoff, not a
large media archive.
Recommended video flow:
- Start from Studio with the reviewer pack selected.
- Install Slack through OAuth.
- Confirm the workspace install and channel mapping.
- Run
/threadain Slack. - Open the generated WorkItem in Threada.
- Uninstall the app from Slack and show the setup-required or disabled response.
Evidence bundle
Attach or retain this evidence before submitting:
- Slack app settings screenshot showing only the
commandsscope for v1. - Slack app settings screenshot showing the slash-command URL, OAuth redirect URL, and Events API request URL.
- Slack Manage Distribution screenshot or audit reference showing public
distribution enabled for the app being submitted. Generate structured public
distribution evidence with
task marketplace:slack -- distribution-evidence, retained as.deploy-evidence/slack-public-distribution.json. - Install/start URL proof showing the reviewer can start from the public setup
page and use the Add to Slack CTA to reach Studio’s Slack install route. If
using Slack Direct Install, retain the dashboard save/validation reference for
the 302 redirect. Generate structured install evidence with
task marketplace:slack -- install-flow-check, retained as.deploy-evidence/slack-install-flow.json. - Deployment commit SHA and deployment environment for the reviewed app.
- Output or CI links for the changed-scope validation that covers Slack BFF, runtime, Studio setup, Work link behavior, and docs.
- Signed
/threadasuccess test with timestamp, Slack workspace, channel ID, returned WorkItem ID, and redacted logs showing no secrets or raw tokens. Generate this withtask marketplace:slack -- review-smokeagainst the review deployment after filling the environment variables below. - Setup-required or disabled-command test showing no WorkItem was created.
Generate this with the same command and
SLACK_REVIEW_EXPECTED_RESULT=setup-required. app_uninstalledevent test showing the runtime installation becomes disabled and audit history remains available. Generate the signed event acceptance evidence with the same command andSLACK_REVIEW_SMOKE_MODE=uninstall-event, then run the setup-required smoke against the same workspace/channel to prove commands no longer create WorkItems.- Public surface evidence from
task marketplace:slack -- public-surface-check, retained as.deploy-evidence/slack-public-surface.json. - Approval evidence from
task marketplace:slack -- approvals-evidence, retained as.deploy-evidence/slack-approvals.json, covering legal, support, security, product, and engineering signoffs for the exact submitted Slack app. - Active-workspace evidence from
task marketplace:slack -- active-workspaces-evidence, retained as.deploy-evidence/slack-active-workspaces.json, proving the app has at least five active workspaces over Slack’s 28-day activity window. If the Slack Manage Distribution page is still below five active workspaces, record the current blocker snapshot withtask marketplace:slack -- active-workspaces-current; retain it as.deploy-evidence/slack-active-workspaces-current.jsonfor owner handoff only. That snapshot must keepfinal_submission_evidenceset tofalseand does not replace final active-workspace evidence. - Collaborator evidence from
task marketplace:slack -- collaborators-evidence, retained as.deploy-evidence/slack-collaborators.json, proving the Slack app has the app creator plus at least one added collaborator without storing collaborator names or emails.
Deployment smoke command
Before collecting live smoke evidence for a fresh or rotated Slack app, seed the
production Slack Secret Manager values from a clean operator shell. Use the
exact Slack app values from Slack’s app settings; the state secret is generated
automatically as a non-placeholder 32-byte random value unless
SLACK_OAUTH_STATE_SECRET is set. If
marketplace:slack evidence-status --check-deploy or the latest release
readiness artifact already reports production Slack secret presence and
service-account access as implemented, do not rerun this step unless rotating
Slack credentials.
export SLACK_COMMAND_SIGNING_SECRET='<from Slack app Basic Information>'
export SLACK_OAUTH_CLIENT_ID='<from Slack app Basic Information>'
export SLACK_OAUTH_CLIENT_SECRET='<from Slack app Basic Information>'
task marketplace:slack -- seed-secrets \
--env prod \
--project threada-prod \
--dry-run
task marketplace:slack -- seed-secrets \
--env prod \
--project threada-prod
The seed command creates missing Secret Manager containers, adds missing secret
versions, skips existing versions by default, and never prints secret values. Use
--rotate-existing only for an intentional Slack credential rotation.
After seeding, run the standard production services deploy so public-bff starts
a new revision with the mounted Slack secret values and production OAuth redirect
URL before collecting smoke evidence.
Run the smoke command from a clean checkout after the reviewer tenant, Slack workspace, pack, queue, and channel mapping are live. Provide the signing secret through the operator shell or secret manager tooling; do not commit it.
This simulates Slack’s signed slash-command POST to prove the deployed endpoint, signature verification, routing, and WorkItem link behavior. It does not replace the reviewer walkthrough from the Slack client.
SLACK_REVIEW_API_BASE_URL=https://api.threada.ai \
SLACK_REVIEW_SIGNING_SECRET="$SLACK_COMMAND_SIGNING_SECRET" \
SLACK_REVIEW_TEAM_ID=T0123456789 \
SLACK_REVIEW_CHANNEL_ID=C0123456789 \
SLACK_REVIEW_USER_ID=U0123456789 \
SLACK_REVIEW_COMMAND_TEXT="Need vendor security review for ExampleCo before Friday" \
SLACK_REVIEW_OUTPUT_FILE=.deploy-evidence/slack-review-success.json \
task marketplace:slack -- review-smoke
For setup-required evidence, use an unmapped or disabled review channel and set:
SLACK_REVIEW_EXPECTED_RESULT=setup-required
For app_uninstalled lifecycle evidence, send a signed Events API payload:
SLACK_REVIEW_API_BASE_URL=https://api.threada.ai \
SLACK_REVIEW_SIGNING_SECRET="$SLACK_COMMAND_SIGNING_SECRET" \
SLACK_REVIEW_TEAM_ID=T0123456789 \
SLACK_REVIEW_API_APP_ID=A0123456789 \
SLACK_REVIEW_SMOKE_MODE=uninstall-event \
SLACK_REVIEW_OUTPUT_FILE=.deploy-evidence/slack-review-uninstall-event.json \
task marketplace:slack -- review-smoke
Then run the setup-required smoke for the same workspace and review channel to prove commands no longer create WorkItems.
Command-mode JSON evidence includes the checked URL, Slack team/channel/user IDs, command text hash, HTTP status, content type, response body hash, response body, WorkItem URL, and WorkItem ID. Uninstall-event JSON evidence includes the checked Events API URL, Slack team ID, Slack app ID when provided, event type, HTTP status, content type, and response hash/body. Neither mode includes the Slack signing secret, request signature, or raw request body.
Public distribution evidence
After enabling public distribution in Slack’s Manage Distribution dashboard, retain a screenshot or audit artifact outside the repo and generate sanitized metadata for the readiness gate:
task marketplace:slack -- distribution-evidence \
--evidence-id GRC-2026-06-17-slack-public-distribution \
--evidence-owner "Integrations" \
--slack-app-id A0123456789 \
--slack-client-id 123456789.987654321 \
--source-ref "Slack Manage Distribution screenshot 2026-06-17" \
--proof-file path/to/slack-manage-distribution.png \
--out .deploy-evidence/slack-public-distribution.json
The generated evidence stores only the evidence ID, evidence owner, Slack app
ID, Slack client ID hash, proof reference, proof SHA-256, timestamp, enabled
flag, and proof byte count when --proof-file is used. It does not store the
raw Slack client ID, dashboard screenshot, screenshot path, Slack client secret,
signing secret, OAuth tokens, cookies, or dashboard dump. If the proof artifact
is already hashed by an external evidence system, use --proof-sha256 instead
of --proof-file.
Active workspace evidence
Slack expects submitted Marketplace apps to be installed on at least five active workspaces. Active means used within the past 28 days. After confirming the count from Slack reporting or an approved evidence source, retain the raw report outside the repo and generate sanitized metadata for the readiness gate:
task marketplace:slack -- active-workspaces-evidence \
--evidence-id GRC-2026-06-17-slack-active-workspaces \
--evidence-owner "Integrations" \
--slack-app-id A0123456789 \
--slack-client-id 123456789.987654321 \
--active-workspace-count 7 \
--source-ref "Slack Marketplace active workspace export 2026-06-17" \
--proof-file path/to/slack-active-workspaces.csv \
--out .deploy-evidence/slack-active-workspaces.json
The generated evidence stores only the active workspace count, 28-day window,
threshold, evidence ID, evidence owner, Slack app ID, Slack client ID hash,
proof reference, proof SHA-256, timestamp, and proof byte count when
--proof-file is used. It does not store workspace names, workspace IDs, team
IDs, user IDs, email addresses, raw reports, report paths, screenshots, Slack
client secrets, signing secrets, OAuth tokens, cookies, or dashboard dumps. If
the proof artifact is already hashed by an external evidence system, use
--proof-sha256 instead of --proof-file.
Collaborator evidence
Slack’s Marketplace maintenance requirements say submitted apps must have an app collaborator so more than one person can access the app configuration. After confirming the Slack app has at least one added collaborator, retain the raw Collaborators page proof outside the repo and generate sanitized metadata for the readiness gate:
task marketplace:slack -- collaborators-evidence \
--evidence-id GRC-2026-06-17-slack-collaborators \
--evidence-owner "Integrations" \
--slack-app-id A0123456789 \
--slack-client-id 123456789.987654321 \
--added-collaborator-count 1 \
--source-ref "Slack app Collaborators page 2026-06-17" \
--proof-file path/to/slack-collaborators.png \
--out .deploy-evidence/slack-collaborators.json
The generated evidence stores only the added collaborator count, threshold,
evidence ID, evidence owner, Slack app ID, Slack client ID hash, proof
reference, proof SHA-256, timestamp, and proof byte count when --proof-file
is used. It does not store collaborator names, emails, user IDs, raw
screenshots, screenshot paths, Slack client secrets, signing secrets, OAuth
tokens, cookies, or dashboard dumps. If the proof artifact is already hashed by
an external evidence system, use --proof-sha256 instead of --proof-file.
Approval evidence
After legal, support, security, product, and engineering owners sign off on the submitted Slack app, retain the raw approval packet outside the repo and generate sanitized metadata for the readiness gate:
task marketplace:slack -- approvals-evidence \
--evidence-id GRC-2026-06-17-slack-approvals \
--evidence-owner "Marketplace Launch" \
--slack-app-id A0123456789 \
--slack-client-id 123456789.987654321 \
--source-ref "Slack Marketplace approval packet 2026-06-17" \
--legal-approval-ref LEGAL-2026-06-17 \
--legal-approval-owner "Legal" \
--legal-approved-at 2026-06-17T01:02:03.000Z \
--support-approval-ref SUPPORT-2026-06-17 \
--support-approval-owner "Support" \
--support-approved-at 2026-06-17T01:02:03.000Z \
--security-approval-ref SEC-2026-06-17 \
--security-approval-owner "Security" \
--security-approved-at 2026-06-17T01:02:03.000Z \
--product-approval-ref PROD-2026-06-17 \
--product-approval-owner "Product" \
--product-approved-at 2026-06-17T01:02:03.000Z \
--engineering-approval-ref ENG-2026-06-17 \
--engineering-approval-owner "Engineering" \
--engineering-approved-at 2026-06-17T01:02:03.000Z \
--proof-file path/to/slack-marketplace-approvals.pdf \
--out .deploy-evidence/slack-approvals.json
The generated evidence stores only the evidence ID, evidence owner, Slack app
ID, Slack client ID hash, proof reference, proof SHA-256, timestamp, approval
area refs, approval owner role/team names, approval timestamps, and proof byte
count when --proof-file is used. It does not store approval packet contents,
approval packet paths, approver emails, personal identifiers, Slack client
secrets, signing secrets, OAuth tokens, cookies, or dashboard dumps. If the
approval packet is already hashed by an external evidence system, use
--proof-sha256 instead of --proof-file.
Public surface check
Before running the final readiness check, verify that the public setup, Marketplace, security, privacy, and terms pages are reachable without login:
task marketplace:slack -- public-surface-check \
--out .deploy-evidence/slack-public-surface.json
The checker validates HTTPS public URLs, HTTP 200-399 responses, text/HTML content, required page markers, and obvious login-wall redirects or password forms. The generated evidence stores URL metadata, status, content type, response hashes, and matched public markers only. It does not store page bodies, cookies, request credentials, or secrets.
Install/start flow check
Threada’s v1 Slack install is tenant-scoped: a tenant admin signs in to Studio, selects the receiving pack, and starts OAuth from the Slack connector panel. Use the standard public install-page flow for Marketplace review until the product supports an accountless Direct Install handoff. Verify that the public setup page is reachable and exposes the Add to Slack CTA to Studio’s Slack install route:
task marketplace:slack -- install-flow-check \
--mode install-page \
--url https://docs.threada.ai/integrations/slack-setup/ \
--install-link-url https://studio.threada.ai/integrations/slack/install \
--out .deploy-evidence/slack-install-flow.json
The checker requires HTTP 200 HTML, the expected setup markers including
Add to Slack, and a sanitized link to Studio’s Slack install route. The
generated evidence stores the source URL, status, content type, matched marker
names, a SHA-256 hash of the page body, and sanitized link metadata. It does not
store page bodies, cookies, tokens, passwords, Slack signing secrets, raw OAuth
URLs, OAuth state, OAuth code, or raw Slack client IDs.
If the submitted app later enables Slack Direct Install, switch to direct mode and use the exact dashboard URL:
task marketplace:slack -- install-flow-check \
--mode direct-install \
--url https://<direct-install-url> \
--out .deploy-evidence/slack-install-flow.json
Direct mode requires HTTP 302 to https://slack.com/oauth/v2/authorize with the
expected OAuth query keys and stores only hashes plus redirect host/path/query
key names.
Submission readiness check
After the success, setup-required, uninstall, public-surface,
public-distribution, active-workspace, collaborator, approval, and install-flow
evidence files exist, create local scaffolds for the Marketplace asset manifest
and reviewer context. With the default paths, the scaffold command writes
gitignored files under .deploy-evidence, refuses to overwrite existing files
unless --force is supplied, and only copies non-secret values that can be
inferred from the generated smoke, public-distribution, active-workspace,
approval, and install-flow evidence. It validates collaborator evidence for
warnings, but does not copy collaborator names, emails, or proof details into
the generated review context. It also warns if the public-distribution,
active-workspace, collaborator, approval, direct-install, and uninstall-smoke
evidence do not refer to the same Slack app/client ID. If you pass custom
--assets or --context paths, keep them out of git or confirm they are
ignored before filling them.
task marketplace:slack -- submission-scaffold \
--evidence-dir .deploy-evidence \
--assets .deploy-evidence/slack-submission-assets.json \
--context .deploy-evidence/slack-review-context.json
Then replace every placeholder in the generated files and add the referenced asset files. Paths are relative to the asset manifest file. Do not commit the generated evidence, review context, package output, or working asset inventory. The generated review context intentionally requires non-secret public distribution, active-workspace, collaborator, approval, and install/start URL proof before the readiness status can pass.
Slack dashboard listing draft
Slack’s Marketplace wizard keeps sections 2-5 effectively blocked until
section 1, Your app listing, has the required listing fields filled in the
Slack dashboard. Use the local
.deploy-evidence/slack-dashboard-fields.md copy/paste sheet for the
dashboard values, then verify the Next: Scopes Your App Uses button is
enabled before moving on. Regenerate it with task marketplace:slack -- dashboard-fields
after changing any dashboard answer.
For the current Threada v1 listing, section 1 should use:
- App name:
Threada. - Short description:
Create governed Threada WorkItems from Slack requests. - Long description: use the prepared long description from the local dashboard fields sheet.
- Category:
Productivity. - Installation landing page URL:
https://docs.threada.ai/integrations/slack-setup/. - Privacy policy URL:
https://threada.ai/legal/privacy/. - App support URL:
https://docs.threada.ai/integrations/slack-setup/. - Support email:
support@threada.ai. - Supported language:
English (U.S.). - Pricing: choose the Slack dashboard option that matches Threada’s included
service-subscription model; keep the local field recorded as
Included with service subscription.
Keep the optional YouTube video field empty unless a final public YouTube URL exists, and paste the final URL only after the demo video evidence gate passes. The dashboard draft can be prepared before final active-workspace and approval evidence exists, but do not click the final Slack submission button until the readiness checker is green and the launch owner explicitly approves submission.
Section 2, Scopes your app uses, should use this reason for the commands
scope:
Threada uses the commands scope only to receive /threada slash-command
invocations so a user can create a governed WorkItem from Slack. Threada
receives the slash-command payload for the invoking workspace, channel, user,
and submitted command text; it does not read channel history, files, private
channels, direct messages, search results, workspace exports, admin APIs, or
user-token scopes.
Section 3, Security and compliance information, should use only claims that are already present in the public legal, privacy, subprocessor, and security docs. The current dashboard draft values are:
- Company/developer name:
Threada. - Company headquarters location: owner-provided value required; do not guess it from timezone, founder location, or infrastructure region.
- Terms of service URL:
https://threada.ai/legal/terms/. - Data retention policy:
Default retention is 90 days for work history logs and analytics and 365 days for configuration and audit records, unless a customer agreement or tenant setting defines a shorter or approved longer retention period. - Data archival/removal policy:
Customer data is deleted or returned according to tenant settings, the applicable agreement, and authenticated deletion requests. On termination, access ceases and customer content is deleted or returned per retention policy. - Data storage policy:
Customer data is stored in managed cloud services with HTTPS/TLS in transit, encryption at rest, tenant isolation, role-based access control, GCP Secret Manager for secrets, and audit logging. - How data is hosted:
Cloud hosted on Google Cloud Platform. The default workload region is us-central1 in the United States, with plan-gated residency options for Business/Enterprise plans. - Data host company:
Google Cloud Platform; MongoDB Atlas for managed database storage. - Subprocessors:
Yes. - Guidelines for subprocessors URL:
https://threada.ai/legal/subprocessors/. - App exposes an LLM to customers:
Yes. - LLM models being used:
OpenAI and Google (Gemini) for language model inference and embeddings. - LLM data tenancy policy:
Customer content is processed within tenant-scoped workflows and retrieval indexes. Threada does not train foundation models with Customer Content or use one customer's content to inform another customer's results. - LLM data residency policy:
Current model subprocessors are listed as United States on the published subprocessors page. Threada's default workload region is us-central1, with plan-gated residency options for Business/Enterprise plans. - LLM retention settings:
Threada retention remains governed by workspace retention settings and applicable agreements. Customer Content is indexed for retrieval, not model training; on termination customer data is deleted within the applicable retention period unless law requires longer retention. - SOC, ISO, FedRAMP, CSA STAR, COPPA, and Privacy Shield URLs: leave blank unless Threada publishes those attestations.
- HIPAA compliant:
No. - GDPR commitment URL:
https://threada.ai/legal/dpa/. - Data deletion procedure:
Deletion requests are authenticated and handled through privacy/support channels. Threada deletes or returns Customer Content according to tenant settings, the applicable agreement, and the DPA; on contract termination customer data is deleted within 90 days unless a longer period is required by law. - SSO support:
Yes. - SAML support:
Yes. - SSO providers:
Customer-managed identity providers using IdP-initiated SAML, such as Okta, Microsoft Entra ID, Google Workspace, or OneLogin. - Dedicated security team:
Nountil a public owner-approved security-team claim exists. - Vulnerability disclosure programme:
Nountil a public disclosure programme page exists. - Bug bounty programme:
Nountil a public bounty programme exists. - Third-party auths/connections required for the app to function:
No. - Security contact:
security@threada.ai. - Third-party services:
Google Cloud Platform, MongoDB Atlas, OpenAI, Google (Gemini), Stripe, and Google Workspace/Gmail API where enabled.
{
"icon": {
"path": "assets/slack-icon.png"
},
"screenshots": [
{
"id": "slack-command-ack",
"path": "assets/slack-command-ack.png",
"showsSlackContext": true
},
{
"id": "studio-workspace-binding",
"path": "assets/studio-workspace-binding.png",
"showsSlackContext": true
},
{
"id": "studio-channel-mapping",
"path": "assets/studio-channel-mapping.png",
"showsSlackContext": true
},
{
"id": "workitem-from-slack",
"path": "assets/workitem-from-slack.png",
"showsSlackContext": true
}
],
"video": {
"url": "",
"durationSeconds": 60,
"captionsEnabled": true,
"adsDisabled": true,
"showsSlackContext": true,
"showsInstallOauthFlow": true,
"showsSetupProcess": true,
"showsEndToEndFunctionality": true,
"showsUninstallFlow": true
}
}
The icon must be a 512x512 PNG or JPG file. Screenshots must be 1600x1000 PNG
or JPG files under 21 MB and show the Slack context for the workflow being
reviewed. The demo video object is optional; leave video.url empty when no
public demo is being submitted. If a video is provided, it must be a public
YouTube video, 30 to 90 seconds long, with captions enabled, ads disabled, and
Slack context visible. It must show the full install/OAuth flow, setup process,
end-to-end /threada functionality, and Slack app uninstallation.
Run the midstream evidence status report whenever the submission inputs are partially assembled:
task marketplace:slack -- evidence-status \
--manifest docs/integrations/slack-app-manifest.example.json \
--evidence-dir .deploy-evidence \
--assets .deploy-evidence/slack-submission-assets.json \
--context .deploy-evidence/slack-review-context.json \
--dashboard-fields .deploy-evidence/slack-dashboard-fields.json \
--check-deploy \
--check-install-page \
--deploy-env prod \
--deploy-project threada-prod
The status report prints explicit implemented, missing, blocked, and
next actions sections. The generated next actions are the launch worklist:
each action names the status item it unblocks, the expected owner, and the
sanitized command template to run next. Asset and reviewer-context actions also
repeat the Slack-context media requirements and credential-handoff constraints
so the generated handoff can be used directly by the submission operator. Pass
--json when the launch owner needs the same data as machine-readable
next_actions. The command exits non-zero until every required evidence file,
asset, reviewer context value, dashboard-fields owner value, deployment secret
prerequisite, service-account secret-access grant, and live-smoke prerequisite
is present. It only reports required environment variable names, placeholders,
and Secret Manager IDs; keep Slack signing secrets, OAuth client secrets,
tokens, passwords, raw request bodies, and cookies out of repo files and
command output.
The --check-install-page flag also runs a no-write preflight against the live
public setup page and reports deploy lag, missing install links, or content drift
before the operator runs the evidence-writing install-flow command.
For release readiness, prefer the release wrapper over ad hoc marketplace checks:
task deploy:release -- --yes --slack-marketplace-readiness
The optional Slack readiness stage runs after the normal dev and prod release
deploys. It writes
.deploy-evidence/releases/<release-short>/slack-integration-readiness.json
and updates .deploy-evidence/slack-release-readiness-latest.json only when the
release is ready for Marketplace packaging. The commit-scoped release artifact
is always the canonical source of truth for deploy readiness, Secret Manager
checks, service-account secret access, public install-page preflight,
dashboard-field owner-value status, and Marketplace evidence status.
For operator handoff, refresh every derived .deploy-evidence handoff artifact
from the release readiness artifact:
task marketplace:slack -- refresh-handoff \
--release-readiness .deploy-evidence/releases/<release-short>/slack-integration-readiness.json \
--manifest docs/integrations/slack-app-manifest.example.json \
--evidence-dir .deploy-evidence \
--assets .deploy-evidence/slack-submission-assets.json \
--context .deploy-evidence/slack-review-context.json \
--dashboard-fields .deploy-evidence/slack-dashboard-fields.json \
--active-workspaces-current .deploy-evidence/slack-active-workspaces-current.json \
--active-workspace-outreach-target-current .deploy-evidence/slack-active-workspace-outreach-target-current.json \
--approval-request-sent .deploy-evidence/slack-approval-request-sent.json \
--review-channel-current .deploy-evidence/slack-review-channel-current.json \
--followup-drafts .deploy-evidence/slack-marketplace-followup-drafts.json
This writes one immutable handoff run under
.deploy-evidence/slack-marketplace/runs/<release-short>/, including the
readiness summary, action plan, integration-store roadmap, regenerated
follow-up drafts, owner-unblock request, ready-subset directory, ready-subset
ZIP, and checksum validation receipt. It then updates
.deploy-evidence/slack-marketplace/latest-run.json last. Prefer this command
for launch-owner handoffs so the readiness summary, owner packet, roadmap, and
ready-subset validation receipt cannot drift across different generations. Use
the lower-level commands below only when debugging a specific generator or when
a release artifact does not exist yet.
All Slack Marketplace operations live under the single
task marketplace:slack -- <subcommand> CLI. Do not add one-off Slack
Marketplace package scripts for new launch steps; add a registry-backed
subcommand so generated handoffs, release readiness, and operator docs stay on
the same surface.
The action-plan generator writes the same status-derived worklist to local
.deploy-evidence artifacts:
task marketplace:slack -- action-plan \
--manifest docs/integrations/slack-app-manifest.example.json \
--evidence-dir .deploy-evidence \
--assets .deploy-evidence/slack-submission-assets.json \
--context .deploy-evidence/slack-review-context.json \
--check-deploy \
--check-install-page \
--deploy-env prod \
--deploy-project threada-prod \
--json-out .deploy-evidence/slack-action-plan.json \
--markdown-out .deploy-evidence/slack-action-plan.md
This command does not fabricate missing evidence and does not treat an
incomplete status as success. It writes a sanitized JSON and Markdown handoff
with current owners, commands, missing items, blocked items, and implemented
items, while keeping raw Slack dashboard exports, credentials, tokens, request
bodies, and screenshots outside the repo.
It also reads .deploy-evidence/slack-dashboard-fields.json: if the artifact is
missing, or if it still needs the owner-provided headquarters country, the action
plan adds a dashboard-specific missing/blocked item and next action. Do not infer
the headquarters country from timezone, founder location, GCP region, or
subprocessor location.
Before generating follow-up drafts, keep all current Slack observations produced
through the single Marketplace CLI. Record the active-workspace outreach target
with task marketplace:slack -- active-workspace-outreach-current, record
the original approval request with
task marketplace:slack -- approval-request-sent, record the Slack Manage
Distribution count with task marketplace:slack -- active-workspaces-current,
and record the approval-thread state with
task marketplace:slack -- review-channel-current. These artifacts are
operator handoff inputs only; they preserve proof hashes, message permalinks,
and sanitized status without becoming final active-workspace or approval
evidence.
When the latest Slack observations show that the active-workspace or approval thread blockers are still open, regenerate the unsent follow-up drafts from those current observations:
task marketplace:slack -- followup-drafts \
--active-workspaces-current .deploy-evidence/slack-active-workspaces-current.json \
--active-workspace-outreach-target-current .deploy-evidence/slack-active-workspace-outreach-target-current.json \
--approval-request-sent .deploy-evidence/slack-approval-request-sent.json \
--review-channel-current .deploy-evidence/slack-review-channel-current.json \
--json-out .deploy-evidence/slack-marketplace-followup-drafts.json \
--markdown-out .deploy-evidence/slack-marketplace-followup-drafts.md
The generated drafts are not sent evidence. They are sanitized operator copy and
carry not_sent_waiting_for_explicit_user_confirmation until the launch owner
confirms the exact Slack destination and body.
When the remaining work depends on launch-owner action outside the repo, generate the single owner-facing unblock packet from the same sanitized evidence:
task marketplace:slack -- owner-unblocker \
--action-plan .deploy-evidence/slack-action-plan.json \
--active-workspaces-current .deploy-evidence/slack-active-workspaces-current.json \
--active-workspace-outreach-target-current .deploy-evidence/slack-active-workspace-outreach-target-current.json \
--approval-request-sent .deploy-evidence/slack-approval-request-sent.json \
--assets .deploy-evidence/slack-submission-assets.json \
--context .deploy-evidence/slack-review-context.json \
--dashboard-fields .deploy-evidence/slack-dashboard-fields.json \
--followup-drafts .deploy-evidence/slack-marketplace-followup-drafts.json \
--review-channel-current .deploy-evidence/slack-review-channel-current.json \
--json-out .deploy-evidence/slack-owner-unblock-request.json \
--markdown-out .deploy-evidence/slack-owner-unblock-request.md
The owner-unblock packet lists only the external decisions and actions still
needed for Marketplace submission, including the five active workspaces, five
approval replies, reviewer-context active-workspace
count, and owner-confirmed headquarters country. It also reconciles the outputs
from marketplace:slack approval-request-sent and
marketplace:slack active-workspace-outreach-current so the operator can tell
the difference between “original request sent”, “follow-up draft prepared”, and
“final evidence collected”. It references sanitized draft hashes and commands,
but must not include credentials, cookies, raw Slack dashboard exports,
screenshots, request bodies, or private video links.
Use the packet’s Action Order section before assigning work. Items listed as
Can start now can run in parallel; items waiting for owner decisions or
external evidence must not run their evidence command until the named decision
or action IDs are complete. The final package commands are valid only after
every listed action and decision is complete and the current Slack observations
have been refreshed.
When reviewer context validation fails, the packet carries the exact
reviewer-context failure details so the launch owner can remove BLOCKED
placeholders, raw proof references, and active-workspace mismatches before
rerunning the final package command.
Regenerate .deploy-evidence/slack-active-workspaces-current.json with
task marketplace:slack -- active-workspaces-current after each Slack dashboard check so
the packet reflects the current active-workspace blocker without weakening the
final evidence gate.
Regenerate
.deploy-evidence/slack-active-workspace-outreach-target-current.json with
task marketplace:slack -- active-workspace-outreach-current after each
read-only outreach-channel check so follow-up drafts keep pointing at the
visible original request.
Regenerate .deploy-evidence/slack-approval-request-sent.json with
task marketplace:slack -- approval-request-sent after the approval-request
thread is created or re-verified, then regenerate
.deploy-evidence/slack-review-channel-current.json with
task marketplace:slack -- review-channel-current after each read-only approval-thread
check so the packet reflects the current reply count without weakening the final
approval-evidence gate.
The owner-unblock packet marks these current-observation inputs stale after 24
hours; refresh them before sending or acting on the packet because Slack updates
the active-workspace count daily and approval replies can change at any time.
For cross-store launch coordination, regenerate the local integration-store roadmap from the same Slack readiness inputs:
task marketplace:program -- store-roadmap \
--manifest docs/integrations/slack-app-manifest.example.json \
--evidence-dir .deploy-evidence \
--assets .deploy-evidence/slack-submission-assets.json \
--context .deploy-evidence/slack-review-context.json \
--check-deploy \
--check-install-page \
--deploy-env prod \
--deploy-project threada-prod \
--json-out .deploy-evidence/integration-store-roadmap.json \
--markdown-out .deploy-evidence/integration-store-roadmap.md
The roadmap is an operator artifact, not Slack submission evidence. It derives
the Slack gates from the current marketplace:slack evidence-status result plus the
dashboard-fields owner-value gate, and keeps Zapier, Teams, Google Workspace,
Atlassian, Zendesk, HubSpot, Salesforce, and ServiceNow work sequenced around
packaged, reviewable surfaces.
To regenerate the Slack dashboard copy/paste artifact for Marketplace sections 1-3, run:
task marketplace:slack -- dashboard-fields \
--json-out .deploy-evidence/slack-dashboard-fields.json \
--markdown-out .deploy-evidence/slack-dashboard-fields.md
Add --headquarters-country <country> only after the company headquarters
country is confirmed by the launch owner. Without that value, the generated
artifact stays explicitly blocked and must not be treated as final submission
evidence.
Run the local pre-submit checker:
task marketplace:slack -- submission-check \
--manifest docs/integrations/slack-app-manifest.example.json \
--evidence-dir .deploy-evidence \
--assets .deploy-evidence/slack-submission-assets.json
The checker validates the narrow v1 Slack manifest, the three generated smoke evidence files, public surface evidence, public distribution evidence, active-workspace evidence, collaborator evidence, approval evidence, install/start evidence, and the asset manifest metadata. It also fails if the manual evidence, direct-install evidence when present, or uninstall-smoke evidence point at different Slack app/client IDs. It does not submit the app to Slack or replace the live reviewer walkthrough.
Generated reviewer package
After task marketplace:slack -- submission-check passes, create a local review context
file with only non-secret submission values. Do not include passwords, Slack
signing secrets, OAuth client secrets, Slack tokens, raw request bodies, or
cookies. Provide reviewer credentials through Slack’s submission fields or an
approved secure channel instead.
{
"deploymentCommit": "<reviewed-deployment-git-sha>",
"apiBaseUrl": "https://api.threada.ai",
"studioUrl": "https://studio.threada.ai",
"workUrl": "https://work.threada.ai",
"reviewerTenant": "<reviewer-tenant-name>",
"reviewerAdminAccount": "<reviewer-account-identifier>",
"reviewerAccessInstructions": "<credential-handoff-instructions>",
"slackPublicDistributionRef": "<slack-public-distribution-proof-reference>",
"slackInstallFlowUrl": "https://<install-page-or-direct-install-url>",
"slackInstallFlowEvidence": "<install-flow-test-reference>",
"slackAppId": "<slack-app-id>",
"slackClientId": "<slack-client-id>",
"slackWorkspaceName": "<smoke-tested-workspace-name>",
"slackWorkspaceUrl": "https://<smoke-tested-workspace>.slack.com",
"slackReviewerUser": "<smoke-tested-slack-user>",
"slackMappedChannelName": "#marketplace-review",
"slackMappedChannelId": "<slack-channel-id>",
"threadaPack": "<pack-key>",
"threadaQueue": "<queue-or-routing-policy>",
"expectedSuccessResponse": "<Slack acknowledgement text with WorkItem link>",
"expectedSetupRequiredResponse": "<setup-required or disabled response>",
"activeWorkspaceCount": 5,
"activeWorkspaceEvidence": "<active-workspace-count-source>",
"legalApprovalRef": "<legal-approval-reference>",
"supportApprovalRef": "<support-approval-reference>",
"securityApprovalRef": "<security-approval-reference>",
"productApprovalRef": "<product-approval-reference>",
"engineeringApprovalRef": "<engineering-approval-reference>",
"submissionNotes": "<optional reviewer-safe notes>"
}
Then generate the local package to use while filling Slack’s submission flow:
Use sanitized evidence references in the review context. Do not leave BLOCKED
markers, local .deploy-evidence/... paths, workstation paths, or raw screenshot
and dashboard proof filenames in reviewer-visible fields.
task marketplace:slack -- submission-package \
--context .deploy-evidence/slack-review-context.json \
--manifest docs/integrations/slack-app-manifest.example.json \
--evidence-dir .deploy-evidence \
--assets .deploy-evidence/slack-submission-assets.json \
--out .deploy-evidence/slack-submission-package.md
The generator performs final local validation against the current evidence files, rejects placeholder or secret-like review context, cross-checks the active workspace count against the sanitized evidence, cross-checks approval refs against the sanitized approval evidence, and writes a sanitized Markdown package with listing copy, reviewer notes, a reviewer-access handoff, smoke, public-surface, public-distribution, active-workspace, approval, and install-flow evidence hashes, asset inventory, and approval references. The access handoff names the Threada reviewer tenant, account identifier, secure credential delivery path, install/start URL, and Slack workspace boundary; it must not contain actual credentials. Treat the generated package as local launch evidence; do not commit it.
If final active-workspace or approval evidence is still pending, generate a non-final operator bundle instead:
task marketplace:slack -- ready-subset \
--manifest docs/integrations/slack-app-manifest.example.json \
--evidence-dir .deploy-evidence \
--assets .deploy-evidence/slack-submission-assets.json \
--context .deploy-evidence/slack-review-context.json \
--out-dir .deploy-evidence/slack-submission-ready-subset \
--zip-out .deploy-evidence/slack-submission-ready-subset.zip
The ready-subset bundle copies the valid manifest, current asset inventory,
ready evidence, generated action plan, operator handoffs, active-workspace and
approval evidence helper scripts, current browser-observation summaries,
owner-unblock request, demo-video recording board, YouTube metadata draft,
optional non-final demo-video review cut with its manifest and notes, unsent
follow-up drafts, submission-field drafts, Slack dashboard-field drafts, the
integration-store roadmap, and checksum file into a local directory and ZIP
archive. If the local review-cut MP4 is present, the
generator requires its
companion manifest to stay marked
non_final_review_cut_not_for_youtube_submission, carry
reviewer_safe_for_internal_bundle: true, list replacement targets, and remain
under the ready-subset size cap. It is
intentionally marked
not_final_submission_ready; use it for internal launch coordination only, not
as a substitute for a passing
marketplace:slack submission-package run. Do not treat this bundle as a final submission
gate; regenerate the formal package after the active-workspace and approval
evidence blockers clear, and after the dashboard-fields artifact has no missing
owner-provided values.
Its manifest uses the same reviewer-context validator as the final submission
package, so reviewer-context placeholders and evidence mismatches appear in
final_submission_blockers. Unsafe local or raw proof references inside copied
JSON or text artifacts fail bundle generation before they can be copied into the
ZIP.
The bundle manifest records only repo-relative or input:<filename> source
references so the ZIP does not expose operator workstation paths.
Copied JSON and text artifacts are also scanned for secrets, workstation paths,
non-HTTPS proof URLs, raw proof filenames, proof file/path fields, and raw proof
ref/path fields. Keep only sanitized source labels plus hashes and byte counts
in operator artifacts that enter the bundle.
If an optional operator handoff is absent, the bundle manifest records it under
missing_operator_sources and the CLI prints a warning.
The preferred marketplace:slack refresh-handoff wrapper also writes
slack-submission-ready-subset-validation.json inside the immutable run
directory after verifying SHA256SUMS; that validation receipt records the
bundle timestamp, checksum count, ZIP or directory-only status, helper scripts,
and final-submission blockers. When passed --release-readiness, the wrapper
consumes the release readiness snapshot instead of rerunning deploy and
install-page checks.
Final gate
Do not submit to Slack until every item below is true:
- Production Slack app exists with production client ID, client secret, signing
secret, and callback URLs configured through
slack-oauth-client-id-prod,slack-oauth-client-secret-prod,slack-oauth-state-secret-prod,slack-command-signing-secret-prod, and the deployment-derivedSLACK_OAUTH_REDIRECT_URL. - The public setup guide, support path, privacy path, and security contact are reachable without login.
- Slack public distribution is enabled, and the reviewer-safe install/start URL reaches Slack OAuth for the production app being reviewed.
- The reviewer tenant and Threada test account are live; the smoke-tested Slack workspace/channel evidence proves the submitted app was tested before review.
- The reviewer script succeeds end to end in the same deployment Slack will review.
- The screenshots and video show that same behavior.
task marketplace:slack -- public-surface-checkpasses and writes sanitized evidence for the public setup, Marketplace, security, privacy, and terms pages.task marketplace:slack -- distribution-evidencewrites sanitized public distribution evidence for the submitted Slack app.task marketplace:slack -- active-workspaces-evidencewrites sanitized proof that the submitted Slack app has at least five active workspaces over Slack’s 28-day activity window.task marketplace:slack -- collaborators-evidencewrites sanitized proof that the submitted Slack app has at least one added collaborator.task marketplace:slack -- approvals-evidencewrites sanitized proof that legal, support, security, product, and engineering signoffs apply to the submitted Slack app.task marketplace:slack -- install-flow-checkpasses and writes sanitized install/start evidence for either the standard public install page or a validated Slack Direct Install URL.task marketplace:slack -- action-planwrites.deploy-evidence/slack-action-plan.jsonand.deploy-evidence/slack-action-plan.mdafter every readiness pass so the launch owner has an owner-assigned, sanitized handoff for any remainingmissingorblockeditems.task marketplace:slack -- owner-unblockerwrites.deploy-evidence/slack-owner-unblock-request.jsonand.deploy-evidence/slack-owner-unblock-request.mdwhenever external owner action remains, so the ready-subset bundle has one launch-owner packet with no secrets or private dashboard exports.task marketplace:slack -- submission-checkpasses against the smoke evidence and asset manifest for the submission package.task marketplace:slack -- submission-packagewrites a sanitized package from the live review context and does not report placeholders, secrets, or missing approval references.- The app still requests only
commandsfor v1. - No listing copy claims unsupported Slack surfaces or data access.
- Legal, security, support, product, and engineering owners have signed off.