Skip to content
threada Docs

Integration Store Launch

This runbook owns Threada’s path to public integration-store listings. It keeps store claims aligned with executable product wiring and gives product, engineering, security, and launch owners one checklist to drive from build to approval.

Slack Marketplace remains the prerequisite listing because Threada already has live Slack intake wiring and the customer value is narrow enough to review safely: turn Slack requests into governed WorkItems with evidence, approvals, and an audit trail.

The active post-Slack public listing wave is now the full marketplace distribution program:

  1. Zapier public integration.
  2. Microsoft Teams Store.
  3. Google Workspace Marketplace.
  4. Atlassian Marketplace for Jira.
  5. Zendesk Marketplace.
  6. HubSpot App Marketplace.
  7. Salesforce AppExchange.
  8. Intercom App Store.
  9. Okta Integration Network.
  10. Freshworks Marketplace for Freshdesk.
  11. GitHub Marketplace.
  12. Notion Marketplace.
  13. Asana App Directory.
  14. monday.com Marketplace.
  15. AWS Marketplace.
  16. Microsoft Marketplace.
  17. Google Cloud Marketplace.
  18. Oracle Cloud Marketplace.
  19. Datadog Marketplace.
  20. PagerDuty Integrations directory.
  21. Discord App Directory.

ServiceNow Store and Shopify App Store remain documented adjacent marketplace paths from earlier planning, but they are not part of the active user-selected full distribution program unless a launch owner explicitly adds them back to the priority sequence.

Zapier goes first in the post-Slack wave because the public API already supports tenant-scoped WorkItem intake and follow-up. Teams and Google Workspace come next because they reuse the channel-to-WorkItem pattern. Jira, Zendesk, HubSpot, Salesforce, Intercom, Okta, and Freshworks follow because they cover the most common support, CRM, identity, and IT workflows. GitHub, Notion, Asana, and monday.com extend the work-management path. AWS, Microsoft, Google Cloud, and Oracle Cloud marketplaces are commercial procurement paths. Their internal BillingService procurement ingestion and signed public BFF procurement callbacks are live, but public launch still requires seller/partner account, fulfillment-adapter callback configuration, entitlement verification, buyer onboarding, reviewer smoke evidence, and approval before they can be treated as publicly available. Datadog, PagerDuty, and Discord close the current active sequence with observability, incident, and community intake surfaces.

Regenerate the local roadmap after meaningful Slack evidence changes:

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

This writes .deploy-evidence/integration-store-roadmap.json and .deploy-evidence/integration-store-roadmap.md. The roadmap is an operator coordination artifact, not submission evidence; it derives Slack gates from the current marketplace:slack evidence-status result and keeps Zapier, Teams, Google Workspace, Atlassian, Zendesk, HubSpot, Salesforce, Intercom, Okta, Freshworks, GitHub, Notion, Asana, monday.com, AWS, Microsoft commercial, Google Cloud, Oracle Cloud, Datadog, PagerDuty, and Discord sequencing honest about account, package, runtime, evidence, and approval gaps while keeping ServiceNow and Shopify visible as documented adjacent paths.

After the roadmap identifies the current wave, seed the gitignored marketplace evidence file before the first launch-control pass:

task marketplace:program -- evidence-status \
  --evidence .deploy-evidence/marketplace-program-evidence.json \
  --seed-out .deploy-evidence/marketplace-program-evidence.json \
  --no-json \
  --no-markdown

The seed starts every lifecycle gate as missing and refuses to overwrite an existing evidence file. Then generate the owner-routed marketplace owner seed if the program owner is known but marketplace-specific role owners are not assigned yet:

task marketplace:program -- owner-assignments \
  --owners .deploy-evidence/marketplace-program-owner-assignments.json \
  --evidence .deploy-evidence/marketplace-program-evidence.json \
  --seed-out .deploy-evidence/marketplace-program-owner-assignments.json \
  --program-owner-name "<name>" \
  --program-owner-email "<name>@threada.ai" \
  --program-owner-team "Marketplace Launch" \
  --no-json \
  --no-markdown

Then generate the owner-routed marketplace work queue:

task marketplace:program -- work-queue \
  --owners .deploy-evidence/marketplace-program-owner-assignments.json \
  --evidence .deploy-evidence/marketplace-program-evidence.json \
  --json-out .deploy-evidence/marketplace-program-work-queue.json \
  --markdown-out .deploy-evidence/marketplace-program-work-queue.md

Use the generated queue for assignment and follow-up. It composes the current program evidence status, safe evidence requests, runtime-binding blockers, and owner-assignment status into stable tasks routed to owner roles. It is not public launch proof; release readiness remains the launch authority.

Status

Implemented

  • Slack, Teams, web, email, API, and custom are documented channel labels.
  • Runtime webhooks can ingest Slack events into WorkItems when a tenant-scoped channel installation and integration are already configured.
  • Slack request signing is verified before Slack webhook payloads are ingested.
  • Public BFF routes exist for Slack slash commands, OAuth start/callback with signed state, Events API URL verification, and app_uninstalled disablement.
  • Command-only Slack OAuth records non-secret install metadata in runtime integration records and intentionally does not persist raw Slack OAuth tokens.
  • Studio connector readiness can launch Slack OAuth for a selected pack, show returned Slack workspace installs, and bind an OAuth-created Slack runtime integration to the current pack without losing Slack metadata.
  • Studio runtime channels can map a Slack channel ID to the pack-bound Slack integration as an enabled Slack social channel, which is the channel record the Slack command router resolves before creating a WorkItem.
  • Accepted Slack slash commands return acknowledgement text with a Work shell link to the created WorkItem.
  • Slack slash-command outcomes after signature verification return reviewer-visible plain text for setup-required runtime responses, not-authorized failures, invalid command text, and retry-later runtime failures.
  • Runtime automation can execute governed Slack channel post actions through Slack Web API chat.postMessage when the tenant Slack integration has a bot-token secret and recorded slack_bot_token_granted_scopes metadata containing chat:write; command-only OAuth install scopes are recorded as slack_install_granted_bot_scopes and do not satisfy the post-message action requirement. Successful post-message actions persist the returned Slack channel and ts as the external action reference; integrations without that action requirement fail closed before Secret Manager reads or outbound HTTP, and Slack responses without channel or ts fail closed instead of recording an unauditable success.
  • Public Slack setup and support documentation covers install, channel mapping, slash-command use, disconnect, uninstall, data handling, and support/security contacts.
  • Slack submission pack documents the Marketplace copy, app manifest controls, asset shot list, reviewer test notes, and external evidence still required before submission.
  • The current Slack Marketplace evidence bundle validates production Secret Manager presence, production service-account secret access, the live public install page, public distribution, collaborator proof, install-flow evidence, and signed Slack review smoke evidence for the submitted app.
  • Public API WorkItem create, update, read, list, and message append are live.
  • The private action-only Zapier Platform scaffold exists at packages/zapier-platform-app for Create WorkItem, Append WorkItem Message, and Update WorkItem.
  • The private Microsoft Teams Store app package scaffold exists at packages/teams-store-app for bot-command and message-extension WorkItem intake.
  • The private Google Workspace Marketplace configuration scaffold exists at packages/google-workspace-marketplace-app for Google Chat slash-command and Help quick-command WorkItem intake.
  • The private Atlassian Marketplace Forge manifest scaffold exists at packages/atlassian-marketplace-app for a Jira issue-panel WorkItem intake posture.
  • Public Atlassian setup/support guidance exists at docs/integrations/atlassian-setup.md.
  • Public Zendesk setup/support guidance exists at docs/integrations/zendesk-setup.md.
  • The private HubSpot App Marketplace OAuth app scaffold exists at packages/hubspot-marketplace-app for governed contact upsert, including portal identity shared-data disclosure.
  • Public HubSpot setup/support guidance exists at docs/integrations/hubspot-setup.md.
  • The private Salesforce AppExchange API integration scaffold exists at packages/salesforce-appexchange-app for governed Contact upsert.
  • Public Salesforce setup/support guidance exists at docs/integrations/salesforce-setup.md.
  • The private ServiceNow Store app scaffold exists at packages/servicenow-store-app for governed Incident creation.
  • Public ServiceNow setup/support guidance exists at docs/integrations/servicenow-setup.md.
  • The private GitHub Marketplace launch-control scaffold exists at packages/github-marketplace-app for a public GitHub App, read-only permissions, app and Marketplace webhooks, listing metadata, setup-guide metadata, reviewer smoke notes, and fail-closed readiness evidence.
  • Shared marketplace scaffold primitives are Rust-owned through deploy-tool marketplace-package; descriptor coverage and runtime bindings are checked against proto/runtime_automation/runtime_automation.proto so package submission readiness cannot be satisfied by env vars alone. Every existing launch-control scaffold must set threada.marketplaceLaunchControl: true and keep marketplace.descriptor.json in sync with its package.json.
  • Side-effecting actions remain policy-gated through governed proposal flows; direct public REST action execution is intentionally disabled.

Missing for Slack Marketplace submission

  • Proof that the submitted Slack app has at least five active workspaces over Slack’s 28-day activity window. After confirming the count from Slack reporting or an approved evidence source, run task marketplace:slack -- active-workspaces-evidence to capture sanitized proof without raw workspace names, workspace IDs, user IDs, email addresses, Slack client IDs, secrets, tokens, cookies, or raw exports.
  • Legal, support, security, product, and engineering signoffs for the submitted Slack app. After the signoffs are recorded in the approved evidence system, run task marketplace:slack -- approvals-evidence to capture sanitized proof without raw approval packets, approver emails, personal identifiers, secrets, tokens, or cookies.
  • Final reviewer context values and the active-workspace count in reviewer context matching the final active-workspace evidence. The current asset manifest and review context are useful scaffolds, but marketplace:slack evidence-status must report them as implemented before final packaging.
  • Owner-confirmed company headquarters country for Slack dashboard section 3. Regenerate .deploy-evidence/slack-dashboard-fields.json and .md with task marketplace:slack -- dashboard-fields --headquarters-country <country> only after the launch owner confirms the value; do not infer it from timezone, founder location, cloud region, or subprocessor geography.
  • OAuth bot-token persistence, rotation, and revocation if the public Slack Marketplace app expands beyond commands into Web API scopes such as chat:write. The runtime post-message action currently depends on an explicit tenant-scoped bot-token secret plus recorded chat:write scope metadata rather than the command-only Slack OAuth metadata.

Blocked outside the repo

  • Slack dashboard active-workspace growth to the Marketplace threshold and an approved evidence source for the final count.
  • Approval packet replies or evidence records covering privacy policy, terms, subprocessors, data deletion language, support routing/SLA, security posture, product copy, and engineering launch readiness.
  • Owner-confirmed headquarters country.

Slack v1 package

The v1 Slack listing should sell one workflow:

Create a governed Threada WorkItem from Slack, route it to the right pack and queue, and keep the result auditable in Threada.

Do not claim Slack DM, channel-management, export, bulk delete, file access, historical search, or admin automation in the v1 listing. Do not claim Slack outbound channel posting in the public listing unless the submitted Slack app requests chat:write, persists/revokes its bot token through Secret Manager, and has reviewer smoke evidence for the post-message path. The runtime chat.postMessage action is live only for tenant integrations with an explicit bot-token secret.

Slack scopes

Start with the smallest scope set that can pass review:

ScopeRequiredUse
commandsYesInvoke Threada from /threada without reading channel history.
chat:writeNo for command-only v1Optional governed channel posting. Runtime Web API posting is implemented, but the public listing should not request this scope until the submitted Slack app has Secret Manager token persistence/revocation and reviewer smoke evidence for chat.postMessage.
app_mentions:readOptionalLet users mention Threada to create a WorkItem after event handling is implemented.
channels:readOptionalSupport channel picker/setup. Keep optional unless setup cannot work without it.

Avoid *:history, files:read, admin.*, search:read, and broad user-token scopes for v1. If a future feature needs one, make that feature optional, update the store listing, and resubmit with a narrow justification.

Target install flow

  1. A tenant admin starts Slack setup from the Marketplace install/start URL, signs in to Studio, selects the receiving pack, and starts the Slack OAuth flow from the connector panel.
  2. Threada creates a signed install state containing tenant, requesting user, nonce, expiry, and return URL.
  3. The admin approves Slack OAuth.
  4. Threada exchanges the code server-side and stores non-secret installation metadata in runtime integration records. Command-only v1 does not persist raw Slack OAuth tokens.
  5. Studio returns to the selected pack and binds the Slack workspace install to that pack.
  6. The admin enters the Slack channel ID in Studio; Studio saves it as a Slack social runtime channel bound to the pack’s Slack integration.
  7. The admin confirms queue/routing rules for the pack.
  8. Submission readiness is complete only after public distribution is enabled, the app has at least five active workspaces, the reviewer install/start URL reaches Slack OAuth, a signed Slack request can be verified, and a test WorkItem can be created end to end in the reviewed deployment.

If a later version requests Web API scopes, update step 4 to store the Slack token in Secret Manager, record only the secret reference in runtime metadata, and revoke or delete that secret during disconnect/uninstall.

Target command flow

  1. User runs /threada <request> in Slack.
  2. Public BFF verifies Slack signing, timestamp freshness, and replay posture.
  3. BFF resolves Slack workspace/channel/user to a tenant ChannelInstallation.
  4. Runtime creates or appends a WorkItem with source channel slack.
  5. Threada responds within Slack’s timeout window with an acknowledgement and WorkItem link.
  6. WorkItem timeline records the Slack origin, normalized request, generated draft, approvals, and any later governed action.

If the installation is missing, disabled, unbound to a pack, or lacks tenant authorization, Slack should receive an explicit setup-required response instead of a silent success.

Submission package

Prepare these before pressing submit. The current control sheet is Slack Marketplace submission pack.

  • Public listing page for “Threada for Slack”.
  • Public setup guide with install, configure, use, disconnect, uninstall, and data-deletion sections.
  • Privacy policy and terms links.
  • Support URL and support email.
  • Security contact or vulnerability report path.
  • Short description focused on the Slack use case.
  • Long description that explains governed WorkItems, approval gates, evidence, and audit history without claiming unsupported automation.
  • Screenshots:
    • Slack command/acknowledgement.
    • Studio Slack workspace binding and channel mapping/readiness.
    • WorkItem in Work with source, evidence, and timeline.
    • Approval/governed-action view if demonstrated by a first-party live flow.
  • Optional demo video, 30-90 seconds if included:
    • Install through OAuth.
    • Configure one channel.
    • Run /threada.
    • Open the generated WorkItem.
    • Uninstall the Slack app and show the setup-required or disabled response.
  • Filled reviewer test notes with Threada credentials, tenant, install/start URL, public-distribution proof, expected outputs, and smoke-tested Slack workspace/channel evidence. Keep credentials out of the repo, and do not provide Threada-owned Slack workspace credentials to Slack reviewers.

Reviewer script

Use the filled reviewer notes from Slack Marketplace submission pack as the test script in the Slack submission. The minimum reviewer flow is:

  1. Sign in with the provided Threada admin account, open the install/start URL, and install Threada into a Slack workspace the reviewer controls.
  2. Return to Studio and confirm the workspace install is bound to the provided test pack, then map a Slack channel from the reviewer-controlled workspace to the provided queue.
  3. In Slack, run /threada Need vendor security review for ExampleCo before Friday.
  4. Confirm Slack returns a Threada acknowledgement with a WorkItem link.
  5. Open the WorkItem and confirm:
    • source channel is Slack,
    • original Slack text is preserved,
    • the WorkItem is assigned to the configured pack and queue,
    • the timeline shows the Slack intake event,
    • any generated draft is editable and evidence is visible where available.
  6. Disconnect or uninstall the app, then retry /threada test.
  7. Confirm Slack receives an explicit setup-required or app-disabled response and no new WorkItem is created.

Slack dashboard draft handoff

Before trying to work through Slack Marketplace sections 2-5, fill section 1, Your app listing, in the Slack app dashboard from .deploy-evidence/slack-dashboard-fields.md. Regenerate that artifact with task marketplace:slack -- dashboard-fields after changing any dashboard answer. The dashboard keeps the next step disabled when required listing controls are still empty or merely opened but not selected.

Use Productivity as the category, English (U.S.) as the supported language, https://docs.threada.ai/integrations/slack-setup/ for the installation and support URLs, https://threada.ai/legal/privacy/ for privacy, and support@threada.ai for support email. Leave the optional YouTube field empty unless a public demo URL exists, then paste only the final public YouTube URL with captions enabled and ads disabled. Preparing the dashboard draft is allowed before all evidence gates pass, but final submission is still blocked until the readiness checker is green and the launch owner approves the submit action.

For section 2, Scopes your app uses, use the scope justification from Slack Marketplace submission pack as rendered into .deploy-evidence/slack-dashboard-fields.md. For section 3, Security and compliance information, use the values in that generated artifact. The only current owner-supplied field is the company headquarters country; do not infer it from timezone, founder location, GCP region, or subprocessor location. If the public legal operating entity changes, update the submission pack, regenerate the dashboard fields, and update public legal docs before changing the Slack dashboard.

Validation before submission

  • Unit and integration tests cover:
    • OAuth callback accepts valid signed state and rejects invalid, expired, and cross-tenant state.
    • Slash command accepts valid Slack signatures and rejects missing, stale, replayed, or malformed signatures.
    • Missing tenant/channel binding returns setup-required, not a 500.
    • Disabled installation does not create a WorkItem.
    • Successful command creates or appends the expected WorkItem.
    • Uninstall disables the runtime installation and preserves audit history.
    • Any future token-persisting scope revokes or deletes the Secret Manager token during disconnect/uninstall.
  • Changed-scope planner emits and passes the applicable docs, BFF, runtime, proto, adapter, and frontend checks.
  • task marketplace:slack -- review-smoke passes against the reviewer deployment for the mapped success channel, and again with SLACK_REVIEW_EXPECTED_RESULT=setup-required for an unmapped or disabled review channel.
  • task marketplace:slack -- review-smoke also passes with SLACK_REVIEW_SMOKE_MODE=uninstall-event, followed by setup-required command evidence for the same Slack workspace and review channel.
  • task marketplace:slack -- public-surface-check --out .deploy-evidence/slack-public-surface.json passes, proving the public setup guide, Marketplace page, security contact, privacy policy, and terms page are reachable over HTTPS without an obvious login wall. The evidence file must contain hashes and matched public markers, not page bodies or credentials. The docs build also consumes descriptor-declared marketplace public-docs contracts from marketplace.descriptor.json before publishing docs.threada.ai; Slack’s descriptor requires the rendered setup page to expose the Add to Slack CTA and Studio install URL, and to remain listed in the docs sitemap.
  • task marketplace:slack -- distribution-evidence --evidence-id <evidence-id> --evidence-owner <owner-team> --slack-app-id <app-id> --slack-client-id <client-id> --source-ref <proof-ref> --proof-file <proof-file> --out .deploy-evidence/slack-public-distribution.json writes sanitized proof that public distribution is enabled for the submitted Slack app. The evidence file must contain the Slack app ID, proof reference, proof hash, enabled flag, accountable evidence owner, immutable evidence ID, Slack client ID hash, and proof byte count when --proof-file is used, not raw Slack client IDs, dashboard screenshots, screenshot paths, client secrets, signing secrets, tokens, cookies, or dashboard dumps.
  • task marketplace:slack -- active-workspaces-evidence --evidence-id <evidence-id> --evidence-owner <owner-team> --slack-app-id <app-id> --slack-client-id <client-id> --active-workspace-count <count> --source-ref <proof-ref> --proof-file <proof-file> --out .deploy-evidence/slack-active-workspaces.json writes sanitized proof that the submitted Slack app has at least five active workspaces over Slack’s 28-day activity window. The evidence file must contain the Slack app ID, active workspace count, 28-day window, proof reference, proof hash, accountable evidence owner, immutable evidence ID, Slack client ID hash, and proof byte count when --proof-file is used, not raw workspace names, workspace IDs, team IDs, user IDs, email addresses, Slack client IDs, raw reports, report paths, screenshots, secrets, tokens, cookies, or dashboard dumps.
  • When Slack Manage Distribution still reports fewer than five active workspaces, record the current dashboard observation with task marketplace:slack -- active-workspaces-current --slack-app-id <app-id> --slack-client-id <client-id> --page-url <manage-distribution-url> --active-workspace-count <count> --active-user-count <count> --dashboard-text '<exact visible Slack count sentence>' --source-ref <operator-reference> --proof-file <proof-file> --out .deploy-evidence/slack-active-workspaces-current.json. This artifact is for operator handoff and owner-unblock packets only: final_submission_evidence must remain false, and it never replaces .deploy-evidence/slack-active-workspaces.json.
  • After checking the internal active-workspace outreach channel, record the current request target with task marketplace:slack -- active-workspace-outreach-current --channel-id <channel-id> --channel-name <channel-name> --page-url <slack-channel-url> --request-visible true --install-test-replies-observed <count> --source-message-permalink <original-request-permalink> --visible-runtime-signal '<sanitized signal>' --source-ref <operator-reference> --proof-file <proof-file> --out .deploy-evidence/slack-active-workspace-outreach-target-current.json. This artifact records where unsent active-workspace follow-up drafts should point. It must contain proof hashes and sanitized status only, not raw channel exports, screenshots, cookies, tokens, or private message bodies.
  • task marketplace:slack -- collaborators-evidence --evidence-id <evidence-id> --evidence-owner <owner-team> --slack-app-id <app-id> --slack-client-id <client-id> --added-collaborator-count <count> --source-ref <proof-ref> --proof-file <proof-file> --out .deploy-evidence/slack-collaborators.json writes sanitized proof that the submitted Slack app has at least one added collaborator. The evidence file must contain the Slack app ID, added collaborator count, threshold, proof reference, proof hash, accountable evidence owner, immutable evidence ID, Slack client ID hash, and proof byte count when --proof-file is used, not collaborator names, emails, user IDs, raw screenshots, screenshot paths, Slack client IDs, secrets, tokens, cookies, or dashboard dumps.
  • task marketplace:slack -- approvals-evidence --evidence-id <evidence-id> --evidence-owner <owner-team> --slack-app-id <app-id> --slack-client-id <client-id> --source-ref <proof-ref> --legal-approval-ref <ref> --legal-approval-owner <owner-role> --legal-approved-at <iso-timestamp> --support-approval-ref <ref> --support-approval-owner <owner-role> --support-approved-at <iso-timestamp> --security-approval-ref <ref> --security-approval-owner <owner-role> --security-approved-at <iso-timestamp> --product-approval-ref <ref> --product-approval-owner <owner-role> --product-approved-at <iso-timestamp> --engineering-approval-ref <ref> --engineering-approval-owner <owner-role> --engineering-approved-at <iso-timestamp> --proof-file <proof-file> --out .deploy-evidence/slack-approvals.json writes sanitized proof that legal, support, security, product, and engineering signoffs apply to the submitted Slack app. The evidence file must contain the Slack app ID, approval refs, approval owner role/team names, approval timestamps, proof reference, proof hash, accountable evidence owner, immutable evidence ID, Slack client ID hash, and proof byte count when --proof-file is used, not raw approval packets, packet paths, approver emails, personal identifiers, Slack client IDs, secrets, tokens, cookies, or dashboard dumps.
  • After sending the internal approval request, record the sent request with task marketplace:slack -- approval-request-sent --channel <#channel-name> --slack-channel-id <channel-id> --message-permalink <request-message-permalink> --body-verified-visible true --contains-current-blockers true --contains-reply-format true --approval-evidence-status <sanitized-status> --source-ref <operator-reference> --proof-file <proof-file> --out .deploy-evidence/slack-approval-request-sent.json. This artifact is not final approval evidence. It lets the handoff and follow-up generators preserve the original request thread while waiting for the five explicit signoffs.
  • When the approval request thread is still pending or only partially complete, record the current review-channel observation with task marketplace:slack -- review-channel-current --channel-id <channel-id> --channel-name <channel-name> --page-url <slack-channel-url> --approval-request-visible true --approval-replies-observed <count> --approval-areas <comma-separated-areas> --active-workspace-followup-visible <true-or-false> --visible-approval-activity '<sanitized summary>' --latest-visible-runtime-signal '<sanitized signal>' --source-ref <operator-reference> --proof-file <proof-file> --out .deploy-evidence/slack-review-channel-current.json. This artifact is for owner handoff only: it must keep final_submission_evidence set to false, and it never replaces .deploy-evidence/slack-approvals.json. Refresh the current active-workspace dashboard, outreach-channel, approval-request, and approval-thread artifacts within 24 hours before sending or acting on .deploy-evidence/slack-owner-unblock-request.md; the owner-unblock packet surfaces stale-observation warnings so launch owners do not chase outdated Slack counts or approval status. For a full marketplace-program submission or public launch release, run the release wrapper with program readiness enabled:
task deploy:release -- --yes --marketplace-program-readiness

This deploys dev and prod through the normal release path, then writes the canonical release-owned marketplace program readiness artifact to .deploy-evidence/releases/<release-short>/marketplace-program-readiness.json and refreshes .deploy-evidence/marketplace-program-release-readiness-latest.json only after all marketplace lifecycle gates, descriptor readiness evidence, and runtime bindings are ready and every marketplace has accountable owner assignments for account access, technical work, evidence, submission, and post-approval maintenance.

For the Slack Marketplace handoff specifically, run the release wrapper with Slack readiness enabled after refreshing the current Slack observations:

task deploy:release -- --yes --slack-marketplace-readiness

This deploys dev and prod through the normal release path, then writes the canonical release-owned Slack readiness artifact to .deploy-evidence/releases/<release-short>/slack-integration-readiness.json and refreshes .deploy-evidence/slack-release-readiness-latest.json only when the release is ready for Marketplace packaging. Then generate the marketplace handoff from the commit-scoped release snapshot:

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

The handoff command consumes the release readiness artifact instead of rerunning deployment or install-page checks, then regenerates the readiness summary, action plan, roadmap, unsent follow-up drafts, owner-unblock packet, ready-subset directory, ZIP, and ready-subset validation receipt under .deploy-evidence/slack-marketplace/runs/<release-short>/ from one release snapshot. It updates .deploy-evidence/slack-marketplace/latest-run.json last, so operators never consume a mixed-generation handoff. The owner packet also reconciles the outputs from marketplace:slack approval-request-sent and marketplace:slack active-workspace-outreach-current, so launch owners can distinguish original sends from prepared follow-up drafts and final approval or active-workspace evidence. When debugging only the drafts, regenerate them directly with the lower-level draft generator:

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 direct command writes sanitized draft copy only; it does not send Slack messages and must remain not_sent_waiting_for_explicit_user_confirmation until the launch owner confirms the exact destination and body. Use the owner-unblock packet’s Action Order section as the execution queue: start the Can start now actions in parallel, wait on any named owner decision or external-evidence dependency before running a blocked action’s evidence command, and run final package commands only after all listed dependencies are complete and the observations are freshly regenerated.

  • 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 passes, proving the submitted public setup page is reachable and exposes the Add to Slack CTA to Studio’s Slack install route. If using Slack Direct Install instead, run task marketplace:slack -- install-flow-check --mode direct-install --url <direct-install-url> --out .deploy-evidence/slack-install-flow.json and prove the URL returns HTTP 302 to Slack OAuth. The evidence file must contain hashes and sanitized link or redirect metadata, not page bodies, raw redirect URLs, raw Slack client IDs, OAuth state, OAuth code, cookies, or tokens.
  • The filled .deploy-evidence/slack-review-context.json includes a non-placeholder public distribution reference, active-workspace proof source, approval refs that match approval evidence, HTTPS install/start URL, and install flow proof for the reviewed app.
  • task deploy:release -- --yes --slack-marketplace-readiness has completed and written the commit-scoped release artifact under .deploy-evidence/releases/. Treat any non-empty missing or blocked section in that release artifact as a launch stop. The .deploy-evidence/slack-release-readiness-latest.json alias advances only after a ready release.
  • For the full distribution program, task deploy:release -- --yes --marketplace-program-readiness has completed and written .deploy-evidence/releases/<release-short>/marketplace-program-readiness.json. Treat any marketplace status other than ready, any incomplete descriptor evidence, any runtime-binding blocker, or any incomplete owner assignment as a public-launch stop. The .deploy-evidence/marketplace-program-release-readiness-latest.json alias advances only after the full program is ready.
  • For debugging only, task marketplace:slack -- evidence-status --check-deploy --check-install-page --deploy-env prod --deploy-project threada-prod --json-out .deploy-evidence/slack-readiness-latest-check-summary.json can rerun the readiness checks outside the release wrapper. This status path also reads .deploy-evidence/slack-dashboard-fields.json and reports a dashboard owner-value blocker when the artifact is missing or still needs the confirmed headquarters country. Do not use this ad hoc output as the authority when a release readiness artifact exists.
  • task marketplace:slack -- action-plan --check-deploy --check-install-page --deploy-env prod --deploy-project threada-prod writes .deploy-evidence/slack-action-plan.json and .deploy-evidence/slack-action-plan.md from the current readiness state for sanitized operator handoff after each evidence-status pass, including the same dashboard missing/blocked status reported by readiness.
  • task marketplace:program -- store-roadmap --check-deploy --check-install-page --deploy-env prod --deploy-project threada-prod writes .deploy-evidence/integration-store-roadmap.json and .deploy-evidence/integration-store-roadmap.md from the current Slack readiness state, the dashboard-fields owner-value gate, and the recommended follow-on store sequence. Treat it as an operator roadmap, not final submission proof.
  • task marketplace:program -- evidence-status --evidence .deploy-evidence/marketplace-program-evidence.json --json-out .deploy-evidence/marketplace-program-status.json --markdown-out .deploy-evidence/marketplace-program-status.md writes the full distribution evidence and approval tracker. Use --seed-out .deploy-evidence/marketplace-program-evidence.json --no-json --no-markdown to bootstrap the gitignored evidence file exactly once, or --template-out .deploy-evidence/marketplace-program-evidence-template.json --no-json --no-markdown to generate a disposable reference template. Record only sanitized references for provider accounts, production app IDs, install flows, Secret Manager resource names, tenant mapping, setup docs, smoke tests, evidence bundles, submission materials, and approval status. Required non-Slack marketplaces remain blocked until a launch-control package descriptor exists and the runtime binding checker sees a real IntegrationType or WebhookProvider plus the descriptor’s sanitized *_RUNTIME_BINDING_REF deployment/smoke proof requirement.
  • task marketplace:program -- owner-assignments --owners .deploy-evidence/marketplace-program-owner-assignments.json --evidence .deploy-evidence/marketplace-program-evidence.json --json-out .deploy-evidence/marketplace-program-owner-assignments-status.json --markdown-out .deploy-evidence/marketplace-program-owner-assignments-status.md writes the accountable owner coverage gate. Use --template-out .deploy-evidence/marketplace-program-owner-assignments-template.json --no-json --no-markdown to generate the fill-in template from descriptors, then fill the gitignored assignments file with Threada accountability addresses before requesting a public-launch release.
  • task marketplace:slack -- dashboard-fields --json-out .deploy-evidence/slack-dashboard-fields.json --markdown-out .deploy-evidence/slack-dashboard-fields.md writes a recoverable Slack Marketplace dashboard copy/paste artifact for sections 1-3. Pass --headquarters-country <country> only after the company headquarters country is confirmed by the launch owner; otherwise the artifact remains explicitly blocked and non-final.
  • Add new Slack Marketplace automation as a subcommand of task marketplace:slack -- <subcommand>, not as a separate package script or standalone operator entrypoint, so generated handoffs and release readiness keep a single command surface.
  • task marketplace:slack -- submission-check passes after smoke evidence and Marketplace assets are present, using .deploy-evidence/slack-submission-assets.json as the asset manifest, and rejects evidence files that point at different Slack app/client IDs.
  • task marketplace:slack -- submission-package writes .deploy-evidence/slack-submission-package.md from the live review context without placeholders, secrets, missing approval references, or active workspace-count gaps.
  • task marketplace:slack -- ready-subset writes .deploy-evidence/slack-submission-ready-subset and .deploy-evidence/slack-submission-ready-subset.zip for non-final operator coordination while active-workspace or approval evidence is still pending. It includes the optional demo-video recording board and YouTube metadata draft, generated action plan, active-workspace and approval evidence helper scripts, unsent follow-up drafts, submission-field drafts, current browser-observation summaries, the integration-store roadmap, and missing optional operator handoff records in the bundle manifest, but does not replace a passing marketplace:slack submission-package run.
  • slack-submission-ready-subset-validation.json is generated inside the immutable marketplace:slack refresh-handoff run directory after checksum verification and must have the same timestamp as the refreshed readiness summary, owner packet, and ready-subset manifest.
  • Browser review covers Studio setup/readiness and WorkItem source/timeline states if UI changed.
  • Security review confirms no Slack tokens, signing secrets, raw Slack bodies, cookies, or PII are logged.

Zapier follow-on

Zapier can launch after the Slack work is underway because it can use the existing public API contract. Use Zapier Public Integration as the launch-control document.

The enterprise-safe path is actions first:

  • Create WorkItem.
  • Append WorkItem message.
  • Update WorkItem status, queue, or assignee.

The private Zapier Platform scaffold for those actions lives at packages/zapier-platform-app. Keep that package as the source of truth for the reviewable Zapier action implementation and use this runbook plus the Zapier launch-control doc for submission gates.

The public setup and support URL for reviewer testing is https://docs.threada.ai/integrations/zapier-setup/, generated from Zapier setup and support.

Keep New WorkItem and Updated WorkItem triggers blocked until the public API has stable recency/cursor behavior for Zapier polling or a Zapier-compatible webhook trigger. Do not publish polling triggers that could miss updates or create noisy duplicates.

Do not expose direct external action execution in Zapier. Threada action execution remains governed by proposal, policy, approval, idempotency, and audit controls.

Do not submit to Zapier until package tests, authenticated zapier validate, private Zap Editor smoke testing, reviewer credential handoff, public setup documentation review, and the Zapier validation/review path all pass.

Teams follow-on

Teams Store work should start after Slack and the Zapier scaffold because the same tenant-installation model can be reused, while Store packaging is a separate review path from runtime relay intake. The launch-control design lives in Microsoft Teams Store.

The enterprise-safe v1 path is Teams-to-WorkItem intake through a first-class Teams app package. The private package scaffold lives at packages/teams-store-app and currently covers the manifest template, generated color and outline icons, package zip generation, and local validation checks for the bot command plus message-extension WorkItem intake surface. Teams still needs real Microsoft app and bot IDs, Bot Framework and Microsoft Entra setup where required, tenant install/mapping behavior, setup-required responses, Store listing copy, reviewer test notes, Developer Portal validation, custom-app self-test, Partner Center submission, and desktop/web/mobile validation. The existing relay-style signed webhook support is not by itself a Teams Store app.

The public setup and support URL for reviewer testing is https://docs.threada.ai/integrations/microsoft-teams-setup/, generated from Microsoft Teams setup and support.

Do not expose proactive messages, Graph reads, calendar/file access, or direct external action execution in the Teams Store listing unless the corresponding permissions, runtime path, tenant scoping, tests, and review evidence exist.

Google Workspace follow-on

Google Workspace Marketplace work should start after Slack, the Zapier scaffold, and Teams scoping because the public package must choose a real Google app integration before the listing can be reviewable. The launch-control design lives in Google Workspace Marketplace.

The enterprise-safe first package is Google Chat-to-WorkItem intake. It reuses the same governed WorkItem posture as Slack and Teams while avoiding broad Gmail, Drive, Calendar, or domain-wide scopes. The private configuration scaffold lives at packages/google-workspace-marketplace-app and currently covers the Google Chat app configuration draft, Marketplace listing draft inputs, zero-scope v1 OAuth posture, and local validation checks for the slash-command plus Help quick-command WorkItem intake surface. Google Workspace still needs real Google Cloud project/listing values, Chat API and Marketplace SDK configuration, production endpoint validation, tenant/domain/space mapping behavior, setup-required responses, Store listing copy, reviewer test notes, OAuth consent evidence, Chat install/behavior self-test evidence, and Google Marketplace review. The existing Gmail runtime intake, governed Gmail draft payload, and Google Chat notification plumbing are not by themselves a Google Workspace Marketplace app.

The public setup and support URL for reviewer testing is https://docs.threada.ai/integrations/google-workspace-setup/, generated from Google Workspace setup and support.

Do not expose Gmail/Drive/Calendar/Admin SDK scopes, direct external action execution, or a generic Google Workspace automation claim unless the corresponding Google app integration, OAuth consent, least-privilege scopes, verification/security-assessment evidence where required, tenant scoping, tests, and Google review evidence exist.

Atlassian follow-on

Atlassian Marketplace work should continue after the Google Workspace package is scoped because Jira needs a first-class Forge app package and an Atlassian review path. The launch-control design lives in Atlassian Marketplace, and public Jira setup/support guidance lives in Atlassian setup and support.

The enterprise-safe first package is the committed private Forge manifest scaffold at packages/atlassian-marketplace-app. It generates a Jira jira:issuePanel manifest posture with read:jira-work, one explicit Threada API backend egress URL, one explicit hosted icon URL, Marketplace listing inputs, and submission-readiness blockers. The existing governed jira_create_issue and jira_update_issue action payloads are useful implementation evidence, but they are not by themselves an Atlassian Marketplace app.

Do not expose unmanaged direct Jira writes, broad Jira admin scopes, packaged Jira knowledge sync, or a generic Jira automation claim unless the corresponding Forge app package, manifest scopes, install mapping, security/privacy evidence, tenant scoping, tests, and Atlassian review evidence exist. The remaining Atlassian blockers are a real Forge app ID, Forge lint/precheck evidence, production Forge deployment, enabled distribution/share path, fresh Jira test site install evidence, deployed resolver/UI, Atlassian site/project-to-Threada tenant mapping, Marketplace listing link, Forge Remote invocation and egress security evidence, Privacy and Security tab evidence, reviewer setup, and Atlassian review approval.

Zendesk follow-on

Zendesk Marketplace work now has a private integration-app package scaffold at packages/zendesk-marketplace-app. The public listing still needs a real Zendesk Marketplace organization/profile/listing, global OAuth client for multi-customer server-side Zendesk API access, Zendesk Marketplace request headers, real brand assets, a source ZIP, Zendesk automated checks, reviewer setup, and Zendesk review. The launch-control design lives in Zendesk Marketplace, and public Zendesk setup/support guidance lives in Zendesk setup and support.

The enterprise-safe first package is the committed marketingOnly: true integration-app scaffold for governed Zendesk ticket creation from a Threada WorkItem or customer request. The existing governed zendesk_create_ticket and zendesk_update_ticket payloads are useful implementation evidence, but they are not by themselves a Zendesk Marketplace approval. Use a Zendesk Support app later only if the first reviewable flow needs a Zendesk Agent Workspace surface.

Do not expose customer API tokens, regular OAuth tokens, unmanaged direct Zendesk writes, broad ticket/user/org/help center scopes, autonomous AI ticketing-agent claims, macros, bulk updates, packaged Zendesk knowledge sync, or a generic Zendesk automation claim unless the corresponding Zendesk app or integration package, global OAuth posture, request headers, tenant mapping, field allowlists, production URLs, OAuth disconnect/revocation handling, tests, Zendesk review, and listing approval evidence exist.

HubSpot follow-on

HubSpot App Marketplace work should start after the Zendesk package is scoped because the public listing needs a first-class HubSpot public app, OAuth install flow, least-privilege CRM scopes, three active unique production installs, and HubSpot review path. The launch-control design lives in HubSpot App Marketplace, and public HubSpot setup/support guidance lives in HubSpot setup and support.

The enterprise-safe first package is the committed OAuth-installed governed HubSpot contact upsert scaffold at packages/hubspot-marketplace-app. The shared Marketplace OAuth callback now exchanges HubSpot authorization codes, discovers the authorized portal through HubSpot token introspection, stores tenant-scoped credentials in Secret Manager, and binds runtime execution to the discovered portal with a hubspot_upsert_contact allowlist. The existing governed hubspot_upsert_contact, hubspot_upsert_deal, and hubspot_update_ticket payloads are useful implementation evidence, but they are not by themselves a HubSpot App Marketplace app.

Do not expose private app tokens, unmanaged direct HubSpot writes, broad CRM or marketing scopes, packaged HubSpot knowledge sync, or a generic HubSpot automation claim unless the corresponding public app, OAuth install flow, least-privilege scopes, tenant mapping, field allowlists, disconnect/uninstall handling, active-install evidence, tests, and HubSpot review evidence exist.

Salesforce follow-on

Salesforce AppExchange work should start after the HubSpot package is scoped because the public listing needs a first-class Salesforce package or API integration, External Client App or approved/existing Connected App install flow, least-privilege CRM scopes, Partner Console listing path, AppExchange partner OAuth controls, Security Review, and listing approval. The launch-control design lives in Salesforce AppExchange, and public Salesforce setup/support guidance lives in Salesforce setup and support.

The enterprise-safe first package is the committed AppExchange API integration scaffold at packages/salesforce-appexchange-app for OAuth-installed governed Salesforce Contact upsert from a Threada WorkItem or lead record. The existing governed salesforce_upsert_contact and salesforce_upsert_opportunity payloads are useful implementation evidence, but they are not by themselves a Salesforce AppExchange app.

Do not expose username/password flows, session ID reuse, private connected-app secrets, unmanaged direct Salesforce writes, broad CRM/metadata/Apex/Flow scopes, packaged Salesforce knowledge sync, or a generic Salesforce automation claim unless the corresponding public app or package, OAuth install flow, PKCE, refresh-token rotation, refresh-token idle timeout, refresh-token IP allowlist, least-privilege scopes, tenant mapping, tests, Salesforce Security Review, and listing approval evidence exist.

ServiceNow adjacent path

ServiceNow Store work now has a committed private app scaffold at packages/servicenow-store-app and public setup/support guidance at ServiceNow setup and support. The public listing still needs the external ServiceNow partner/vendor path: Technology Partner Program or Build Partner readiness, vendor instance, private-scope app upload, certification documentation, Store Publisher Portal submission, App Review, Listing Review, and ServiceNow approval. The launch-control design lives in ServiceNow Store.

The enterprise-safe first package is the scaffolded governed ServiceNow Incident creation posture from a Threada WorkItem or ITSM request. The existing governed service_now_create_incident payload is useful implementation evidence, but it is not by itself a ServiceNow Store approval.

Do not expose global-scope apps, update-set-only delivery, personal developer instance artifacts, manually provisioned admin credentials, unmanaged direct ServiceNow writes, broad incident/request/change/problem/catalog/CMDB/user/admin scopes, packaged ServiceNow knowledge sync, or a generic ServiceNow automation claim unless the corresponding private-scope app or certified integration package, approved credential posture, tenant mapping, tests, ServiceNow certification, and listing approval evidence exist.

Shopify adjacent path

Shopify App Store work remains a documented adjacent path outside the active full distribution program because the public listing needs a first-class embedded Shopify public app, Shopify-owned install path, least-privilege order scopes, GraphQL Admin API implementation, protected customer data posture, and Shopify App Review. The launch-control design lives in Shopify App Store.

The enterprise-safe first package is a governed Shopify order note/tag update from a Threada WorkItem. The existing governed shopify_update_order and shopify_refund payloads are useful implementation evidence, but they are not by themselves a Shopify App Store app.

Do not expose custom app install links, private app tokens, REST Admin API implementation for a new public app, unmanaged direct Shopify writes, broad order/customer/product/fulfillment/checkout/payment scopes, refund capability, packaged Shopify knowledge sync, or a generic Shopify automation claim unless the corresponding embedded public app, managed install or approved OAuth flow, GraphQL Admin API implementation, protected customer data handling, tenant mapping, tests, Shopify App Review, and listing approval evidence exist.

Freshworks Marketplace for Freshdesk

Freshworks Marketplace for Freshdesk is part of the active full distribution program. A private launch-control package now exists at packages/freshworks-marketplace-app, with generated Freshworks CLI source, a packed app ZIP, and a signed public-BFF callback for tenant-bound Freshdesk ticket creation. The public listing still needs a Freshworks Developer Portal Public App entry, real module and product selection, real FDK run/validate/pack evidence, Marketplace media and support details, privacy/security questionnaire, reviewer install evidence, and Freshworks review. The launch-control design lives in Freshworks Marketplace for Freshdesk, and program-level launch rules live in Marketplace distribution program. Runtime/source wiring comes before launch checks: submission readiness must remain blocked until real production URLs, structured evidence references, Freshworks CLI validation/pack evidence, reviewer-safe install evidence, and Freshworks review evidence exist. Threada request signing and mapping-token verification stay server-side; the Freshworks request template may inject only the opaque tenant mapping token into X-Threada-Freshworks-Mapping. Do not put Secret Manager resource names or verifier secret values in Freshworks request template headers or uploaded app code.

The enterprise-safe first package is governed Freshdesk ticket creation from a Threada WorkItem or customer request. The generated Freshworks app calls Threada through /api/v1/integrations/freshworks/freshdesk/actions/create-ticket with an opaque tenant mapping token injected by the Freshworks request template from a secure app setting; the BFF verifies that token with FRESHWORKS_MARKETPLACE_MAPPING_TOKEN_SECRET and dispatches the existing FreshdeskCreateTicket runtime action.

Do not expose Custom App uploads, private install links, manually provisioned Freshdesk API keys, unmanaged direct Freshdesk writes, broad ticket, contact, company, agent, or admin scopes, ticket update or conversation claims, packaged Freshdesk knowledge sync, or a generic Freshdesk automation claim unless the corresponding Freshworks App package, current platform manifest, request templates or server-side API path, tenant mapping, tests, Freshworks review, and listing approval evidence exist.

Maintenance after approval

  • Keep the listing, docs, screenshots, support contact, and privacy links current.
  • Resubmit before shipping substantial scope, endpoint, or behavior changes.
  • Monitor install success, command latency, Slack error responses, WorkItem creation failure rate, and support volume.
  • Rotate secrets through the normal Secret Manager flow.
  • Delist or disable the app if Threada cannot keep the integration maintained and supportable.

References