*** title: Plugin Go-Live Checklist position: 4 excerpt: Best practices to review before launching your plugin to production. deprecated: false hidden: false metadata: title: Plugin Go-Live Checklist description: >- A practical, artifact-by-artifact guide to reviewing your Agent Studio plugin before launching it to production. robots: index ------------- 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`). * **Compound actions wait for completion.** If an activity calls a compound action, ensure "Wait for this action to fully complete" is checked — otherwise the output will be empty when downstream steps try to use it. Uncheck only for fire-and-forget side effects (e.g., logging) where no output is needed. This setting does not apply to HTTP, Script, or Built-in actions, which are synchronous by default. * **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](/agent-studio/plugins/conversational-plugins/citations-1) 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.