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.
Recommended sequence
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:
- Zapier public integration.
- Microsoft Teams Store.
- Google Workspace Marketplace.
- Atlassian Marketplace for Jira.
- Zendesk Marketplace.
- HubSpot App Marketplace.
- Salesforce AppExchange.
- Intercom App Store.
- Okta Integration Network.
- Freshworks Marketplace for Freshdesk.
- GitHub Marketplace.
- Notion Marketplace.
- Asana App Directory.
- monday.com Marketplace.
- AWS Marketplace.
- Microsoft Marketplace.
- Google Cloud Marketplace.
- Oracle Cloud Marketplace.
- Datadog Marketplace.
- PagerDuty Integrations directory.
- 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_uninstalleddisablement. - 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.postMessagewhen the tenant Slack integration has a bot-token secret and recordedslack_bot_token_granted_scopesmetadata containingchat:write; command-only OAuth install scopes are recorded asslack_install_granted_bot_scopesand do not satisfy the post-message action requirement. Successful post-message actions persist the returned Slackchannelandtsas the external action reference; integrations without that action requirement fail closed before Secret Manager reads or outbound HTTP, and Slack responses withoutchannelortsfail 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-appfor Create WorkItem, Append WorkItem Message, and Update WorkItem. - The private Microsoft Teams Store app package scaffold exists at
packages/teams-store-appfor bot-command and message-extension WorkItem intake. - The private Google Workspace Marketplace configuration scaffold exists at
packages/google-workspace-marketplace-appfor Google Chat slash-command and Help quick-command WorkItem intake. - The private Atlassian Marketplace Forge manifest scaffold exists at
packages/atlassian-marketplace-appfor 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-appfor 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-appfor 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-appfor 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-appfor 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 againstproto/runtime_automation/runtime_automation.protoso package submission readiness cannot be satisfied by env vars alone. Every existing launch-control scaffold must setthreada.marketplaceLaunchControl: trueand keepmarketplace.descriptor.jsonin sync with itspackage.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-evidenceto 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-evidenceto 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-statusmust report them as implemented before final packaging. - Owner-confirmed company headquarters country for Slack dashboard section 3.
Regenerate
.deploy-evidence/slack-dashboard-fields.jsonand.mdwithtask 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
commandsinto Web API scopes such aschat:write. The runtime post-message action currently depends on an explicit tenant-scoped bot-token secret plus recordedchat:writescope 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:
| Scope | Required | Use |
|---|---|---|
commands | Yes | Invoke Threada from /threada without reading channel history. |
chat:write | No for command-only v1 | Optional 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:read | Optional | Let users mention Threada to create a WorkItem after event handling is implemented. |
channels:read | Optional | Support 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
- 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.
- Threada creates a signed install state containing tenant, requesting user, nonce, expiry, and return URL.
- The admin approves Slack OAuth.
- 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.
- Studio returns to the selected pack and binds the Slack workspace install to that pack.
- 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.
- The admin confirms queue/routing rules for the pack.
- 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
- User runs
/threada <request>in Slack. - Public BFF verifies Slack signing, timestamp freshness, and replay posture.
- BFF resolves Slack workspace/channel/user to a tenant ChannelInstallation.
- Runtime creates or appends a WorkItem with source channel
slack. - Threada responds within Slack’s timeout window with an acknowledgement and WorkItem link.
- 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:
- Sign in with the provided Threada admin account, open the install/start URL, and install Threada into a Slack workspace the reviewer controls.
- 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.
- In Slack, run
/threada Need vendor security review for ExampleCo before Friday. - Confirm Slack returns a Threada acknowledgement with a WorkItem link.
- 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.
- Disconnect or uninstall the app, then retry
/threada test. - 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-smokepasses against the reviewer deployment for the mapped success channel, and again withSLACK_REVIEW_EXPECTED_RESULT=setup-requiredfor an unmapped or disabled review channel.task marketplace:slack -- review-smokealso passes withSLACK_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.jsonpasses, 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 frommarketplace.descriptor.jsonbefore publishingdocs.threada.ai; Slack’s descriptor requires the rendered setup page to expose theAdd to SlackCTA 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.jsonwrites 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-fileis 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.jsonwrites 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-fileis 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_evidencemust remainfalse, 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.jsonwrites 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-fileis 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.jsonwrites 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-fileis 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 keepfinal_submission_evidenceset tofalse, 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.jsonpasses, 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, runtask marketplace:slack -- install-flow-check --mode direct-install --url <direct-install-url> --out .deploy-evidence/slack-install-flow.jsonand 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.jsonincludes 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-readinesshas completed and written the commit-scoped release artifact under.deploy-evidence/releases/. Treat any non-emptymissingorblockedsection in that release artifact as a launch stop. The.deploy-evidence/slack-release-readiness-latest.jsonalias advances only after a ready release.- For the full distribution program,
task deploy:release -- --yes --marketplace-program-readinesshas 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.jsonalias 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.jsoncan rerun the readiness checks outside the release wrapper. This status path also reads.deploy-evidence/slack-dashboard-fields.jsonand 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-prodwrites.deploy-evidence/slack-action-plan.jsonand.deploy-evidence/slack-action-plan.mdfrom 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-prodwrites.deploy-evidence/integration-store-roadmap.jsonand.deploy-evidence/integration-store-roadmap.mdfrom 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.mdwrites the full distribution evidence and approval tracker. Use--seed-out .deploy-evidence/marketplace-program-evidence.json --no-json --no-markdownto bootstrap the gitignored evidence file exactly once, or--template-out .deploy-evidence/marketplace-program-evidence-template.json --no-json --no-markdownto 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 realIntegrationTypeorWebhookProviderplus the descriptor’s sanitized*_RUNTIME_BINDING_REFdeployment/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.mdwrites the accountable owner coverage gate. Use--template-out .deploy-evidence/marketplace-program-owner-assignments-template.json --no-json --no-markdownto 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.mdwrites 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-checkpasses after smoke evidence and Marketplace assets are present, using.deploy-evidence/slack-submission-assets.jsonas the asset manifest, and rejects evidence files that point at different Slack app/client IDs.task marketplace:slack -- submission-packagewrites.deploy-evidence/slack-submission-package.mdfrom the live review context without placeholders, secrets, missing approval references, or active workspace-count gaps.task marketplace:slack -- ready-subsetwrites.deploy-evidence/slack-submission-ready-subsetand.deploy-evidence/slack-submission-ready-subset.zipfor 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 passingmarketplace:slack submission-packagerun.slack-submission-ready-subset-validation.jsonis generated inside the immutablemarketplace:slack refresh-handoffrun 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.