ascn-integrations
ASCN Integrations
Design and deliver missing ASCN capability as reusable integrations, then package as user-facing plugins.
When To Use
Use this skill when a workflow task cannot be completed with existing handlers/triggers/tools.
Typical triggers:
- missing handler for a required API/service
- missing trigger type for required event source
- schema/contract mismatch blocks reliable workflow composition
- required UI usability (
params_ui, options, conditional fields) are missing
Required Inputs
The integrator MUST collect:
- capability gap summary (what cannot be built today)
- target use-cases (at least one concrete workflow scenario)
- expected input/output contract (JSON-level)
- auth/secret requirements
- publish target (
userplugin first, system copy later)
If contract expectations are missing, stop and return input_validation_error.
Required Tool Surface
control.docs.getcontrol.registry.listcontrol.registry.detailscontrol.registry.resolve_optionscontrol.workflows.listcontrol.workflows.describecontrol.workflows.validatecontrol.workflows.createcontrol.workflows.patchcontrol.workflows.activatecontrol.tools.ensure_exportcontrol.tools.list_exportscontrol.plugins.create_plugincontrol.plugins.validate_definitioncontrol.plugins.update_plugincontrol.plugins.getcontrol.plugins.list
If required tools are unavailable, stop and return dependency_failure.
Delivery Modes
Mode A: Workflow-backed (default)
Use existing handlers to build a reusable workflow and export it through Trigger.Tool.
Mode B: Native integration (new handler/trigger code)
Use only when Mode A cannot satisfy latency, auth, determinism, or protocol constraints.
Native integrations MUST still be wrapped/published as plugins for user consumption.
Mode decision gate:
- choose Mode A first
- choose Mode B only with explicit constraint evidence
- if native code surfaces are unavailable in current context, return a native implementation proposal and stop before claiming implementation
Delivery Flow
- Discover existing capability (
control.registry.list,control.registry.details,control.tools.list_exports). - Produce contract draft:
- exact handler id (
Vendor.Action) params_schema(input object)returns_schema(output object)
- exact handler id (
- Choose delivery mode (
AorB) with explicit reason. - Implement integration.
- Validate workflow/config contract (
control.workflows.validate).- payload MUST be wrapped as
{ "workflow": { ... } }
- payload MUST be wrapped as
- Reconcile export (
control.tools.list_exports,control.tools.ensure_export). - Run plugin-definition preflight (
control.plugins.validate_definition). - Activate the final workflow (
control.workflows.activate). - Bundle handlers into plugin (
control.plugins.create_pluginthenupdate_pluginif needed). - Verify plugin visibility with
control.plugins.listand registry views (control.plugins.getfor deterministic reads). - Return output contract payload with verification evidence.
Plugin Packaging Rules
- Plugin name MUST be stable and vendor/domain-scoped (e.g.
StripeOps,CRMHubspot). - Handler names MUST be exact and collision-safe.
- One plugin MAY contain multiple handlers if they share domain and auth model.
- Plugin definitions SHOULD include UI metadata (
name,description,icon,tags) before handoff. - Unwrapped
Trigger.Toolexports MUST still be user-visible as flatUser.<Handler>entries. - Wrapped/published handlers MUST be rendered as first-class plugin cards/forms with plugin metadata (
name,description,icon) and handlerparams_ui.
Params UI Best Practices
params_ui MUST be human-usable and contract-aligned.
- Every key in
params_uiSHOULD exist inparams_schema.properties. - Localize labels/hints where possible (
en,ru). - Prefer explicit controls:
string,string_multiline,number,boolean,options,array,object,string_json
- Use conditional visibility for complex forms via
displayOptions.show. - Put dangerous/advanced options behind conditional toggles.
- Include safe defaults where predictable behavior is expected.
- Use
optionsonly for selectable values; usedisplayOptions.showonly for conditional visibility. - Keep field order identical to the execution mental model (auth -> target -> behavior -> advanced).
- For
options_sourcefields, resolve options viacontrol.registry.resolve_options(never via direct DB queries). - Reuse existing handler
params_uipatterns by readingcontrol.plugins.listwithinclude_definition=true.
Example conditional field pattern:
[
{
"key": "auth_mode",
"control": "options",
"label": {"en": "Auth mode"},
"options": [
{"value": "api_key", "label": {"en": "API key"}},
{"value": "oauth", "label": {"en": "OAuth"}}
]
},
{
"key": "api_key",
"control": "string",
"label": {"en": "API key"},
"displayOptions": {"show": {"auth_mode": ["api_key"]}}
}
]
Minimal params_ui field contract (recommended):
{
"key": "string",
"control": "string|string_multiline|number|boolean|options|array|object|string_json",
"label": {"en": "Field label"},
"hint": {"en": "Optional guidance"},
"required": false,
"default": null,
"options": [
{"value": "v1", "label": {"en": "Value 1"}}
],
"displayOptions": {"show": {"other_key": ["match_value"]}}
}
Rules for this contract:
optionsMUST exist only whencontrol=options.displayOptions.showMUST reference keys that exist in the sameparams_ui.required=truefields SHOULD be present inparams_schema.required.- Secret-bearing fields SHOULD use hints directing users to secrets, not literal defaults.
Conditional UI Recipes
Use these generic recipes as defaults for displayOptions.show.
They mirror stable patterns already used in current plugin definitions.
Recipe 1: Dropdown controls field visibility
[
{
"key": "mode",
"control": "options",
"label": {"en": "Mode"},
"required": true,
"options": [
{"value": "inline", "label": {"en": "Inline"}},
{"value": "file", "label": {"en": "File"}}
]
},
{
"key": "file_ref",
"control": "object",
"label": {"en": "File"},
"displayOptions": {"show": {"mode": ["file"]}}
}
]
Recipe 2: Boolean toggle controls section visibility
[
{
"key": "send_body",
"control": "boolean",
"label": {"en": "Send Body"}
},
{
"key": "body_format",
"control": "options",
"label": {"en": "Body Format"},
"displayOptions": {"show": {"send_body": [true]}},
"options": [
{"value": "json", "label": {"en": "JSON"}},
{"value": "raw", "label": {"en": "Raw"}}
]
}
]
Recipe 3: Multi-condition show (AND)
[
{
"key": "send_body",
"control": "boolean",
"label": {"en": "Send Body"}
},
{
"key": "body_format",
"control": "options",
"label": {"en": "Body Format"},
"options": [
{"value": "json", "label": {"en": "JSON"}},
{"value": "formdata", "label": {"en": "Form Data"}}
]
},
{
"key": "body",
"control": "string_json",
"label": {"en": "Body"},
"displayOptions": {
"show": {
"send_body": [true],
"body_format": ["json"]
}
}
}
]
Recipe 4: Filter dropdown options by another dropdown
[
{
"key": "provider",
"control": "options",
"label": {"en": "Provider"},
"options": [
{"value": "openai", "label": {"en": "OpenAI"}},
{"value": "azure", "label": {"en": "Azure"}}
]
},
{
"key": "model",
"control": "options",
"label": {"en": "Model"},
"options": [
{
"value": "gpt-4o-mini",
"label": {"en": "gpt-4o-mini"},
"displayOptions": {"show": {"provider": ["openai"]}}
},
{
"value": "azure/gpt-4o-mini",
"label": {"en": "azure/gpt-4o-mini"},
"displayOptions": {"show": {"provider": ["azure"]}}
}
]
}
]
Conditional UI Validation Checklist
Before publish/update, the integrator MUST verify:
- Every
displayOptions.showkey exists in the sameparams_ui. - Comparison values match the source field type (
trueas boolean, not"true"string). showcomparisons use optionvalue, not optionlabel.- Controller fields appear earlier than dependent fields in
params_uiorder. - Hidden-by-default advanced fields have safe defaults or are optional in schema.
- For option-level filtering, each option-level
displayOptions.showreferences an existing controller key.
Security & Secrets
- Credentials MUST come from secrets (
={{ $secrets.name }}), never literals. params_schemaSHOULD mark required secret-driven fields clearly.- Integration MUST document minimum secret set for successful invocation.
Stop And Retry Rules
- Retry only transient tool/runtime failures, max 3 attempts with exponential backoff.
- Do not auto-retry schema mismatch, validation errors, or missing capability.
- Do not claim completion if plugin visibility or activation checks are not executed.
Output Contract
Every completion MUST include:
{
"integration": {
"mode": "workflow|native|proposal_only",
"capability_status": "implemented|partially_implemented|blocked",
"handler_names": ["Vendor.Action"],
"workflow_id": "uuid-or-null",
"exported_tool_name": "string-or-null"
},
"plugin": {
"plugin_name": "VendorOps",
"created_or_updated": true,
"visible_in_plugins_list": true
},
"verification": {
"validated": true,
"activated": true,
"smoke_tested": true,
"latest_run_status": "COMPLETED|FAILED|RUNNING|UNKNOWN",
"run_id": "string-or-null"
},
"failure": {
"class": "none|input_validation_error|dependency_failure|schema_failure|runtime_failure|native_surface_unavailable",
"message": "string"
},
"open_items": [],
"next_action": "string"
}
Hand-off Back To ASCN Operator
After integration delivery:
- return exact handler/plugin identifiers
- return required secrets and minimal invocation payload
- instruct caller to resume lifecycle operations with
ascn-operator