InsightWorker Logo
  • contact@verticalserve.com
Docs / Apps & scheduling / Dry-run before enabling

Dry-running apps

Dry-run executes the full agent loop without performing writes. Use it to:

  • Verify a new skill before enabling it
  • Validate a cron schedule fires at the expected time
  • Estimate token cost before committing to a run
  • Debug an app that's failing in production without touching the live system

Skill dry-run

insightworker skill run my-skill --dry-run

What this does:

  • Runs the agent loop with the skill's prompt
  • Read tools (file reads, JIRA search, SharePoint list/read) execute normally — the agent needs to see state to plan correctly
  • Write tools are intercepted — the agent's intent is logged but no mutation happens
  • Output includes a "would have done" summary

Sample output:

[dry-run] Skill: gather-incident-data
  Read tools (executed):
    sharepoint_search "incident response" → 12 results
    jira_search "project = OPS AND created >= -7d" → 8 issues

  Write tools (intercepted):
    edit_file path=reports/weekly-incidents.md
      diff (40 lines, 2 sections added/updated)
    graph_send_email to="oncall@example.com" subject="Weekly Incident Digest"
      body length: 1240 chars

  Token use: 18,234 in / 4,891 out
  Estimated cost: $0.18 (Sonnet 4.6 pricing)

The intercepted writes show the exact parameters that would have been sent. You can paste those parameters into a real run to validate.

Schedule dry-run

insightworker schedule dry-run morning-digest

What this does:

  • Parses the cron expression and reports the next N fires
  • Does not run the skill itself
  • Use this purely to validate the cron expression
Next 5 fires for "morning-digest":
  2026-05-04 09:00:00 America/New_York
  2026-05-05 09:00:00 America/New_York
  ...

To dry-run the skill that the schedule will invoke (full agent loop, no writes):

insightworker schedule dry-run morning-digest --execute

This combines schedule resolution + skill dry-run.

What read vs write means here

InsightWorker classifies each tool as read or write in its metadata:

Read (executes during dry-run)Write (intercepted)
read_file, list_files, grep, globedit_file, write_file
jira_search, jira_issuejira_create_issue, jira_comment
sharepoint_list, sharepoint_search, sharepoint_readsharepoint_write (when enabled)
perplexity_search, web_fetchgraph_send_email
bash (with safe: true)bash (default, treated as write)

bash defaults to write because shell can do anything. In a dry-run, all bash calls are intercepted and reported; if you need a specific bash call to execute (e.g. read-only git log), tag it with safe: true in the skill's tool config.

Limits of dry-run

  • State drift after read: read tools see live state; if you dry-run at 09:00 and run-for-real at 10:00, the state may have changed
  • Side effects via APIs that don't support a dry mode: e.g. some external services don't have a "preview" — InsightWorker can't preview what it can't preview
  • Cascading effects: if Tool A's output drives Tool B's params, intercepting Tool A means Tool B gets a synthetic placeholder. The plan still validates, but the params for B are approximate.

For high-stakes apps, dry-run + a manual review of the "would have done" output before promoting to a real run.

See also


Source: docs/workflows-and-scheduling/dry-run.md in the public repo. Open a PR with corrections.