Plugin Go-Live Checklist

Best practices to review before launching your plugin to production.
View as Markdown

Before launching a plugin to production, walk through each artifact and verify it meets these best practices. Not every item applies to every plugin — use your judgment based on your use case.

Plugin

  • Description is clear and specific. Users and the AI assistant both rely on the description to understand what the plugin does. Vague descriptions lead to poor triggering and confused users.
  • Log redaction is enabled. Strict log redaction should be on by default to prevent sensitive data from appearing in logs.
  • No internal data in trigger examples. Trigger utterances should not contain real employee names, internal org names, or customer-specific references.
  • No junk triggers. Remove any test triggers (“test”, “asdf”, “hello”) before going live.

Listeners

  • Webhooks are secured. Ensure inbound webhooks are validated using signature verification or credentials — never accept unauthenticated webhook payloads.
  • Filter events at source. If your Listener receives events from a third-party system, configure the webhook on the source side to send only the events you care about, rather than filtering in Moveworks.

Conversation Process

Slots

  • Slots are well-described. Each slot description should explain what the value represents and what format is expected. Avoid prompt-engineering instructions in descriptions (e.g. “Ask the user for this”) — use inference policies instead.
  • Don’t ask for information the system already has. If the user’s email, name, or ID is available from meta_info, don’t ask for it as a slot. This creates unnecessary friction.
  • Slot inference is enabled where possible. Avoid setting slots to “Always explicitly ask” unless truly necessary. Letting the AI infer slot values from the user’s initial message makes the experience faster.
  • Use appropriate data types. Numeric values should use a numeric type, not string. Mismatched types can cause parsing issues and confuse validation.
  • Use validation policies over prompt tuning. When a slot needs validation (e.g. a date must be in the future), implement it as a validation rule (e.g. $PARSE_TIME(value) >= $TIME()) rather than adding instructions to the slot description.
  • References to business objects use data-type-based resolvers over inline resolvers where available.

Activities & Decision Policies

  • Prefer compound actions over multi-activity processes. If your plugin chains multiple API calls, consolidate them into a single compound action rather than multiple sequential activities. This is more maintainable and often faster.
  • Confirmation is required for destructive actions. Any activity that modifies, creates, or deletes business records should have consent enabled (needs_confirmation).
  • Wait for completion is enabled. Activities should use the blocking behavior so the user gets a response after the action completes, not before.
  • Output is trimmed to what matters. Don’t return the raw API response to the user. Trim unnecessary fields (internal IDs, API metadata, system timestamps) to reduce latency, lower token usage, and avoid exposing irrelevant data.
    • Replace API links (e.g. https://api.vendor.com/v2/tickets/123) with user-facing links (https://vendor.com/tickets/123).
    • Consider using citation format for structured results.
  • Use display instructions to control output presentation. If you need to control how results from an action activity are presented to the user, use display instructions for the model rather than adding a content activity or LLM action after it. The reasoning engine already generates a response from the action output — adding an extra LLM step doubles the latency for no benefit.

Data Types

  • Name data types with system awareness. Include the source system in the name (e.g. u_JiraTask not u_Task, u_SalesforceAccount not u_Account). This prevents naming collisions and makes it clear where the data comes from.
  • Schema accurately reflects the business object. The data type should contain the fields that the API actually returns, with correct types.

Compound Actions

  • No internal data in input arg examples. Example values should not reference internal teams, employee names, or org-specific terminology.
  • Parallelize where possible. Any code that can safely run in parallel should be made parallel.
  • Avoid LLM actions in user-facing compound actions. If the compound action is invoked by a conversational plugin, adding an LLM action inside it doubles latency — the LLM runs once inside the compound action, then the reasoning engine runs again to generate the user-facing response. Return structured data from the compound action and let the reasoning engine handle presentation.
  • Don’t use notify expressions as progress updates. Notify expressions are designed to send messages to users or channels — not to show intermediate status.
  • Return data in citation structure where possible, so results render cleanly in the conversation.

Script Actions

  • Code is documented. Functions should have docstrings explaining what they do, what they accept, and what they return.

HTTP Actions

Request Safety

  • Use {{{triple brackets}}} for template parameters. In HTTP action paths and request bodies, use {{{param}}} (triple brackets) instead of {{param}} (double brackets). Double brackets apply URL/HTML encoding which can corrupt values like emails, dates, and JSON.
  • HTTP filtering handles null values safely. If an HTTP action filters by a user-provided value (e.g. /approvals?email={{email}}), ensure that an empty or null value does not bypass permissions and return all records.
  • Remove dead parameters from request bodies. If a parameter in the HTTP body is not actually used, remove it to avoid accidentally writing empty or null values to the target system.
  • Action works on test. Before publishing, test each HTTP action to verify it returns the expected response.

Authentication & Security

  • Use User Consent Auth when available. If the connector supports OAuth 2.0 Authorization Code grants, use User Consent Auth so actions run as the requesting user rather than a service account.
  • Audit trail for write actions. If User Consent Auth is not available and your plugin modifies business records, include an audit comment identifying who made the change:
    "Created via Moveworks on behalf of {{meta_info.user.email_addr}} on {{NOW()}}"
  • No sensitive data in auth headers. Auth headers should not contain client_id, client_secret, cookies, or other credentials that belong in the connector configuration.
  • No internal data in configuration. Input arg descriptions, example values, and URL paths should not contain real employee names, internal org names, customer data, or partner-specific URLs.

Schema & Documentation

  • HTTP actions have a response schema. Define a response schema so the platform can validate responses and provide better error handling.
  • Input arguments are well-documented. Each input arg should have a clear description and, where relevant, a link back to the source API documentation. Example values should match the expected format (e.g. ISO-8601 for timestamps, not yyyy/mm/dd).

General

  • Minimize unnecessary API calls. Design your plugin to avoid extra round-trips. For example, if a plugin has separate paths for “request for self” vs. “request for others,” don’t make a preliminary API call to fetch direct reports if it’s not needed on the current path.
  • Use user identity for system IDs where available. When the target system can resolve the current user’s identity, use it directly rather than making a separate lookup call.
  • The API does not expose capabilities beyond what the user can already do in the UI. Plugins should mirror what’s possible through normal product usage, not bypass access controls.