delegate-agent-cli 0.14.0__tar.gz → 0.15.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/CHANGELOG.md +41 -0
  2. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/PKG-INFO +10 -11
  3. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/README.md +9 -10
  4. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/docs/agent-setup.md +2 -2
  5. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/docs/cli-reference.md +37 -25
  6. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/docs/configuration.md +3 -2
  7. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/docs/security-model.md +13 -3
  8. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/docs/troubleshooting.md +16 -6
  9. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/docs/worktrees.md +9 -11
  10. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/pyproject.toml +1 -1
  11. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/__init__.py +1 -1
  12. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/argv_builders.py +12 -4
  13. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/cli.py +39 -2
  14. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/cli_parser.py +6 -1
  15. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/command_help.py +107 -47
  16. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/constants.py +13 -0
  17. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/describe_payload.py +37 -108
  18. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/inspection_commands.py +2 -5
  19. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/isolation.py +24 -25
  20. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/profiles.py +20 -0
  21. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/rendering.py +10 -5
  22. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/request_build.py +1 -0
  23. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/request_models.py +1 -0
  24. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/run_output_commands.py +6 -10
  25. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/run_registry.py +74 -1
  26. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/runner.py +464 -58
  27. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/safe_workspace.py +118 -60
  28. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/wait_cancel_commands.py +8 -4
  29. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/worktree_execution.py +104 -27
  30. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/worktree_remove.py +10 -1
  31. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent_cli.egg-info/PKG-INFO +10 -11
  32. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_codex_pure_sandbox.py +1 -0
  33. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_delegate_help_cli.py +47 -2
  34. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_delegate_isolation.py +56 -14
  35. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_delegate_parser.py +10 -0
  36. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_engine_argv.py +54 -37
  37. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_execution_argv_and_prompt.py +71 -0
  38. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_execution_worktree_failure_cleanup.py +19 -2
  39. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_execution_worktree_preflight.py +76 -187
  40. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_model_selection_wave1b.py +5 -3
  41. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_profiles.py +48 -1
  42. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_pure_call.py +7 -3
  43. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_run_registry.py +6 -0
  44. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_runner_capture.py +769 -0
  45. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_safe_workspace_isolation.py +95 -0
  46. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_slash_passthrough.py +8 -3
  47. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_snapshot_run_output.py +59 -0
  48. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_wait_cancel_commands.py +16 -0
  49. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_wave4_launch_features.py +157 -6
  50. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_worktree_remove.py +17 -0
  51. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/CONTRIBUTING.md +0 -0
  52. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/LICENSE +0 -0
  53. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/MANIFEST.in +0 -0
  54. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/SECURITY.md +0 -0
  55. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/bin/delegate-profile-shim +0 -0
  56. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/bin/delegate.py +0 -0
  57. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/config.example.json +0 -0
  58. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/docs/assets/delegate-agent-header.png +0 -0
  59. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/docs/development.md +0 -0
  60. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/docs/live-runtime.md +0 -0
  61. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/docs/publishing-checklist.md +0 -0
  62. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/examples/task.claude.json +0 -0
  63. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/examples/task.codex.json +0 -0
  64. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/examples/task.cursor.json +0 -0
  65. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/examples/task.droid.json +0 -0
  66. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/examples/task.grok.json +0 -0
  67. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/examples/task.judge.json +0 -0
  68. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/setup.cfg +0 -0
  69. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/archived_logs.py +0 -0
  70. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/argv_utils.py +0 -0
  71. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/bundled_models.py +0 -0
  72. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/capability_commands.py +0 -0
  73. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/command_errors.py +0 -0
  74. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/config.py +0 -0
  75. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/config_commands.py +0 -0
  76. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/errors.py +0 -0
  77. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/git_utils.py +0 -0
  78. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/harness_events.py +0 -0
  79. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/json_types.py +0 -0
  80. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/log_output.py +0 -0
  81. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/model_discovery.py +0 -0
  82. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/private_io.py +0 -0
  83. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/profile_commands.py +0 -0
  84. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/profile_guard.py +0 -0
  85. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/prompt_instructions.py +0 -0
  86. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/prompt_transport.py +0 -0
  87. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/reasoning.py +0 -0
  88. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/redaction.py +0 -0
  89. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/retention.py +0 -0
  90. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/run_metadata.py +0 -0
  91. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/run_status.py +0 -0
  92. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/seatbelt.py +0 -0
  93. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/snapshot_view.py +0 -0
  94. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/workflows/__init__.py +0 -0
  95. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/workflows/commands.py +0 -0
  96. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/workflows/registry.py +0 -0
  97. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/workflows/runtime.py +0 -0
  98. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/workflows/schema.py +0 -0
  99. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/workflows/script.py +0 -0
  100. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/worktree_commands.py +0 -0
  101. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/worktree_gc.py +0 -0
  102. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/worktree_mgmt.py +0 -0
  103. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/worktree_records.py +0 -0
  104. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/worktree_summary.py +0 -0
  105. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent/wsl.py +0 -0
  106. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent_cli.egg-info/SOURCES.txt +0 -0
  107. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent_cli.egg-info/dependency_links.txt +0 -0
  108. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent_cli.egg-info/entry_points.txt +0 -0
  109. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent_cli.egg-info/requires.txt +0 -0
  110. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/src/delegate_agent_cli.egg-info/top_level.txt +0 -0
  111. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_capability_commands.py +0 -0
  112. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_command_help.py +0 -0
  113. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_config_commands.py +0 -0
  114. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_delegate_validation.py +0 -0
  115. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_end_to_end_tracking.py +0 -0
  116. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_execution_dry_run.py +0 -0
  117. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_execution_worktree_run.py +0 -0
  118. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_harness_events.py +0 -0
  119. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_inspection_commands.py +0 -0
  120. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_kimi_commands.py +0 -0
  121. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_model_discovery.py +0 -0
  122. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_model_selection_wave1a.py +0 -0
  123. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_packaging.py +0 -0
  124. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_reasoning_capabilities.py +0 -0
  125. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_retention.py +0 -0
  126. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_snapshot_redaction.py +0 -0
  127. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_snapshot_rendering.py +0 -0
  128. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_snapshot_view.py +0 -0
  129. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_utility_modules.py +0 -0
  130. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_workflow_commands.py +0 -0
  131. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_worktree_list_show.py +0 -0
  132. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_worktree_prune_gc.py +0 -0
  133. {delegate_agent_cli-0.14.0 → delegate_agent_cli-0.15.0}/tests/test_wsl_guardrails.py +0 -0
@@ -5,6 +5,46 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.15.0] - 2026-07-16
9
+
10
+ ### Added
11
+
12
+ - Work-mode worktree isolation now automatically carries tracked edits and
13
+ untracked, non-ignored files into the new worktree, with tracked/untracked
14
+ counts in human and JSON warnings and fail-clean teardown on sync errors.
15
+ - Child environments expose authoritative source/execution root metadata, and
16
+ Delegate-managed snapshot and worktree cleanup refuses targets that are or
17
+ contain the source workspace.
18
+ - Empty successful safe and read-only call results retry once when the prompt
19
+ can be safely extended; tracked runs retain both attempts and envelopes report
20
+ `emptyRetry` only when a retry was attempted.
21
+ - Bare Harness resolution in Snapshot, run-output, and wait now reports the
22
+ resolved Run, Alias, workspace, and age, with a stale-resolution warning after
23
+ 24 hours.
24
+
25
+ ### Changed
26
+
27
+ - `run-output --tail N` now selects stdout when no output stream or Completion
28
+ Report was requested; stderr remains opt-in.
29
+ - Devin safe mode now fails during preflight with `unsupported_mode` rather than
30
+ launching without an enforceable read-only boundary.
31
+ - Call children use their throwaway cwd as `DELEGATE_SOURCE_ROOT`; the
32
+ Registry/config workspace is not disclosed to a stateless call.
33
+
34
+ ### Fixed
35
+
36
+ - Empty-result retries now preserve cumulative duration, byte counts, usage,
37
+ truncation, stdin diagnostics, timeout budgets, and tracked launch-failure
38
+ state across primary, authentication-fallback, and retry attempts.
39
+ - Source-root cleanup guards now handle relative, symlinked, case-variant,
40
+ unresolved, and malformed paths conservatively without blocking safe cleanup
41
+ of source descendants.
42
+ - Dirty worktree sync preserves arbitrary filename bytes, rejects unsyncable
43
+ dirty submodules with escaped diagnostics, and documents the same behavior
44
+ consistently across the CLI reference and worktree guidance.
45
+ - Devin help and discovery surfaces now derive supported modes consistently and
46
+ reject unknown modes before constructing executable arguments.
47
+
8
48
  ## [0.14.0] - 2026-07-15
9
49
 
10
50
  ### Added
@@ -350,6 +390,7 @@ Usage-audit fix wave: 82 sessions and 1,241 delegate invocations from one week o
350
390
 
351
391
  - Releases before 0.1.3 predate this changelog.
352
392
 
393
+ [0.15.0]: https://github.com/treygoff24/delegate-agent/compare/v0.14.0...v0.15.0
353
394
  [0.14.0]: https://github.com/treygoff24/delegate-agent/compare/v0.13.1...v0.14.0
354
395
  [0.13.1]: https://github.com/treygoff24/delegate-agent/compare/v0.13.0...v0.13.1
355
396
  [0.13.0]: https://github.com/treygoff24/delegate-agent/compare/v0.12.0...v0.13.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: delegate-agent-cli
3
- Version: 0.14.0
3
+ Version: 0.15.0
4
4
  Summary: A tiny CLI for delegating bounded agent tasks to Cursor, Droid, OpenAI Codex, Claude Code, Grok Build, or Kimi Code runtimes.
5
5
  Author: Trey Goff
6
6
  License-Expression: MIT
@@ -163,7 +163,6 @@ Run a read-only review in an isolated throwaway workspace:
163
163
  delegate codex safe "Review this repository for correctness risks. Do not edit files."
164
164
  delegate claude safe "Review this repository for correctness risks. Do not edit files."
165
165
  delegate grok safe "Review this repository for correctness risks. Do not edit files."
166
- delegate devin safe "Review this repository for correctness risks. Do not edit files."
167
166
  delegate opencode safe "Review this repository for correctness risks. Do not edit files."
168
167
  delegate cursor safe "Review the current diff for regressions. Do not edit files."
169
168
  delegate kimi safe "Review this repository for regressions. Do not edit files."
@@ -191,7 +190,7 @@ raw model ID passed through verbatim). Droid still accepts a positional alias;
191
190
  `--model` works on every engine, including Droid:
192
191
 
193
192
  ```bash
194
- delegate devin safe --model claude-fable-5 "Review this repository. Do not edit files."
193
+ delegate devin work --model implementer "Implement the scoped change and report it."
195
194
  delegate droid work --model custom:my-model "Implement the scoped change."
196
195
  delegate --json dry-run codex safe --model fast "Review this repository. Do not edit files."
197
196
  ```
@@ -327,9 +326,9 @@ Delegate separates three ideas:
327
326
 
328
327
  Defaults are intentionally conservative for review paths:
329
328
 
330
- - `delegate cursor safe`, `delegate codex safe`, `delegate claude safe`, `delegate grok safe`, `delegate devin safe`, `delegate opencode safe`, `delegate droid ALIAS safe`, and `delegate kimi safe` run in an isolated throwaway workspace. Safe mode reviews your **current working tree** — uncommitted tracked edits and untracked, non-ignored files are mirrored into an isolated throwaway copy (only gitignored paths are excluded), so you can review local changes without committing first or pasting a diff.
329
+ - `delegate cursor safe`, `delegate codex safe`, `delegate claude safe`, `delegate grok safe`, `delegate opencode safe`, `delegate droid ALIAS safe`, and `delegate kimi safe` run in an isolated throwaway workspace. Safe mode reviews your **current working tree** — uncommitted tracked edits and untracked, non-ignored files are mirrored into an isolated throwaway copy (only gitignored paths are excluded), so you can review local changes without committing first or pasting a diff.
331
330
  - Grok safe mode uses Delegate isolated copy plus Grok read-only sandbox/permission controls (`--sandbox read-only`, `--permission-mode dontAsk` by default). It does not use Grok `plan` mode. Prompts are delivered via Grok `--prompt-file` from a Delegate temp file.
332
- - Devin safe mode uses Delegate isolated copy plus a Delegate-generated `--agent-config` deny-list for edit/write/exec and `mcp__*`, with Devin `--permission-mode auto`. Work mode uses Devin `--permission-mode dangerous` because Devin print mode rejects unapproved edit/exec tools.
331
+ - Devin safe mode is unsupported: Devin may implement filesystem surveys through the generic `exec` tool, which Delegate cannot permit without weakening the read-only boundary. Use another safe Harness for filesystem review. Devin work mode uses `--permission-mode dangerous` because Devin print mode rejects unapproved edit/exec tools.
333
332
  - OpenCode safe mode uses Delegate's isolated copy plus an `OPENCODE_CONFIG_CONTENT` permission lockdown that allows only read, glob, and grep operations. OpenCode merges this override last, so repository configuration cannot restore write-capable tools. `opencode call --read-only` uses the same lockdown; plain `call` does not.
334
333
  - Claude safe mode invokes `claude -p` with prompt text on stdin, `--permission-mode plan`, `--strict-mcp-config`, Read/Grep/Glob plus selected read-only Bash tools, and `--no-session-persistence` by default. Delegate does not currently prove that Claude Code hooks, plugins, user settings, or other non-MCP customization surfaces are disabled.
335
334
  - `work` mode can edit. By default it runs in the real workspace for backward compatibility.
@@ -352,12 +351,12 @@ child where that summary is available. `--forbid-commit` fails the run if
352
351
  commits remain ahead of the creation base when the child exits, and it now
353
352
  implies `--isolation worktree`.
354
353
 
355
- To carry uncommitted local work into the worktree instead of stashing it, add
356
- `--include-dirty`: it syncs tracked edits and untracked, non-ignored files into
357
- the worktree through the same snapshot primitives as safe mode, and tears the
358
- worktree down before launching the child if that sync fails.
354
+ Work-mode worktree runs automatically sync tracked edits and untracked,
355
+ non-ignored files from a dirty source checkout before launch, report the counts
356
+ in a `dirty_source_auto_included` warning, and tear down the worktree if syncing
357
+ fails. `--include-dirty` remains an explicit, harmless no-op on a clean source.
359
358
 
360
- Safe isolation and `--include-dirty` recreate an untracked symlink only when it is relative, resolves inside the source workspace, and its target is not gitignored; any symlink that fails those checks — an absolute target, an escape out of the tree, or a target that is itself a gitignored secret — is replaced with an inert placeholder file, failing closed on any ambiguity. Delegate reports a warning listing the symlink paths it blocked. In Git repositories with no commits yet, Cursor/Codex/Claude/Droid/Grok/Devin/OpenCode/Kimi safe isolation falls back to a directory copy because Git cannot create a detached worktree from an unborn `HEAD`.
359
+ Safe isolation and `--include-dirty` recreate an untracked symlink only when it is relative, resolves inside the source workspace, and its target is not gitignored; any symlink that fails those checks — an absolute target, an escape out of the tree, or a target that is itself a gitignored secret — is replaced with an inert placeholder file, failing closed on any ambiguity. Delegate reports a warning listing the symlink paths it blocked. In Git repositories with no commits yet, Cursor/Codex/Claude/Droid/Grok/OpenCode/Kimi safe isolation falls back to a directory copy because Git cannot create a detached worktree from an unborn `HEAD`.
361
360
 
362
361
  Snapshots and `run-output` redact common credential shapes by default, including authorization headers, bearer/basic tokens, JWT-like strings, and common `token=` / `api_key=` / `password=` values. Use `--no-redact` only when exact output is necessary and safe to display.
363
362
 
@@ -399,6 +398,6 @@ AI_PROFILE delegate ...` uses the base config, or set
399
398
 
400
399
  - Delegate is an alpha CLI wrapper. Child runtimes can change their own flags or behavior.
401
400
  - Safe mode is a policy and isolation pattern, not a guarantee that a runtime cannot perform side effects outside its execution workspace.
402
- - Persistent worktrees require a Git repository with a valid `HEAD`; work-mode worktree runs require a clean source checkout.
401
+ - Persistent worktrees require a Git repository with a valid `HEAD`.
403
402
  - `--pass-through` is incompatible with `--json` and with persistent worktree runs.
404
403
  - Delegate stores local run metadata under `.delegate/`; do not commit that directory.
@@ -130,7 +130,6 @@ Run a read-only review in an isolated throwaway workspace:
130
130
  delegate codex safe "Review this repository for correctness risks. Do not edit files."
131
131
  delegate claude safe "Review this repository for correctness risks. Do not edit files."
132
132
  delegate grok safe "Review this repository for correctness risks. Do not edit files."
133
- delegate devin safe "Review this repository for correctness risks. Do not edit files."
134
133
  delegate opencode safe "Review this repository for correctness risks. Do not edit files."
135
134
  delegate cursor safe "Review the current diff for regressions. Do not edit files."
136
135
  delegate kimi safe "Review this repository for regressions. Do not edit files."
@@ -158,7 +157,7 @@ raw model ID passed through verbatim). Droid still accepts a positional alias;
158
157
  `--model` works on every engine, including Droid:
159
158
 
160
159
  ```bash
161
- delegate devin safe --model claude-fable-5 "Review this repository. Do not edit files."
160
+ delegate devin work --model implementer "Implement the scoped change and report it."
162
161
  delegate droid work --model custom:my-model "Implement the scoped change."
163
162
  delegate --json dry-run codex safe --model fast "Review this repository. Do not edit files."
164
163
  ```
@@ -294,9 +293,9 @@ Delegate separates three ideas:
294
293
 
295
294
  Defaults are intentionally conservative for review paths:
296
295
 
297
- - `delegate cursor safe`, `delegate codex safe`, `delegate claude safe`, `delegate grok safe`, `delegate devin safe`, `delegate opencode safe`, `delegate droid ALIAS safe`, and `delegate kimi safe` run in an isolated throwaway workspace. Safe mode reviews your **current working tree** — uncommitted tracked edits and untracked, non-ignored files are mirrored into an isolated throwaway copy (only gitignored paths are excluded), so you can review local changes without committing first or pasting a diff.
296
+ - `delegate cursor safe`, `delegate codex safe`, `delegate claude safe`, `delegate grok safe`, `delegate opencode safe`, `delegate droid ALIAS safe`, and `delegate kimi safe` run in an isolated throwaway workspace. Safe mode reviews your **current working tree** — uncommitted tracked edits and untracked, non-ignored files are mirrored into an isolated throwaway copy (only gitignored paths are excluded), so you can review local changes without committing first or pasting a diff.
298
297
  - Grok safe mode uses Delegate isolated copy plus Grok read-only sandbox/permission controls (`--sandbox read-only`, `--permission-mode dontAsk` by default). It does not use Grok `plan` mode. Prompts are delivered via Grok `--prompt-file` from a Delegate temp file.
299
- - Devin safe mode uses Delegate isolated copy plus a Delegate-generated `--agent-config` deny-list for edit/write/exec and `mcp__*`, with Devin `--permission-mode auto`. Work mode uses Devin `--permission-mode dangerous` because Devin print mode rejects unapproved edit/exec tools.
298
+ - Devin safe mode is unsupported: Devin may implement filesystem surveys through the generic `exec` tool, which Delegate cannot permit without weakening the read-only boundary. Use another safe Harness for filesystem review. Devin work mode uses `--permission-mode dangerous` because Devin print mode rejects unapproved edit/exec tools.
300
299
  - OpenCode safe mode uses Delegate's isolated copy plus an `OPENCODE_CONFIG_CONTENT` permission lockdown that allows only read, glob, and grep operations. OpenCode merges this override last, so repository configuration cannot restore write-capable tools. `opencode call --read-only` uses the same lockdown; plain `call` does not.
301
300
  - Claude safe mode invokes `claude -p` with prompt text on stdin, `--permission-mode plan`, `--strict-mcp-config`, Read/Grep/Glob plus selected read-only Bash tools, and `--no-session-persistence` by default. Delegate does not currently prove that Claude Code hooks, plugins, user settings, or other non-MCP customization surfaces are disabled.
302
301
  - `work` mode can edit. By default it runs in the real workspace for backward compatibility.
@@ -319,12 +318,12 @@ child where that summary is available. `--forbid-commit` fails the run if
319
318
  commits remain ahead of the creation base when the child exits, and it now
320
319
  implies `--isolation worktree`.
321
320
 
322
- To carry uncommitted local work into the worktree instead of stashing it, add
323
- `--include-dirty`: it syncs tracked edits and untracked, non-ignored files into
324
- the worktree through the same snapshot primitives as safe mode, and tears the
325
- worktree down before launching the child if that sync fails.
321
+ Work-mode worktree runs automatically sync tracked edits and untracked,
322
+ non-ignored files from a dirty source checkout before launch, report the counts
323
+ in a `dirty_source_auto_included` warning, and tear down the worktree if syncing
324
+ fails. `--include-dirty` remains an explicit, harmless no-op on a clean source.
326
325
 
327
- Safe isolation and `--include-dirty` recreate an untracked symlink only when it is relative, resolves inside the source workspace, and its target is not gitignored; any symlink that fails those checks — an absolute target, an escape out of the tree, or a target that is itself a gitignored secret — is replaced with an inert placeholder file, failing closed on any ambiguity. Delegate reports a warning listing the symlink paths it blocked. In Git repositories with no commits yet, Cursor/Codex/Claude/Droid/Grok/Devin/OpenCode/Kimi safe isolation falls back to a directory copy because Git cannot create a detached worktree from an unborn `HEAD`.
326
+ Safe isolation and `--include-dirty` recreate an untracked symlink only when it is relative, resolves inside the source workspace, and its target is not gitignored; any symlink that fails those checks — an absolute target, an escape out of the tree, or a target that is itself a gitignored secret — is replaced with an inert placeholder file, failing closed on any ambiguity. Delegate reports a warning listing the symlink paths it blocked. In Git repositories with no commits yet, Cursor/Codex/Claude/Droid/Grok/OpenCode/Kimi safe isolation falls back to a directory copy because Git cannot create a detached worktree from an unborn `HEAD`.
328
327
 
329
328
  Snapshots and `run-output` redact common credential shapes by default, including authorization headers, bearer/basic tokens, JWT-like strings, and common `token=` / `api_key=` / `password=` values. Use `--no-redact` only when exact output is necessary and safe to display.
330
329
 
@@ -366,6 +365,6 @@ AI_PROFILE delegate ...` uses the base config, or set
366
365
 
367
366
  - Delegate is an alpha CLI wrapper. Child runtimes can change their own flags or behavior.
368
367
  - Safe mode is a policy and isolation pattern, not a guarantee that a runtime cannot perform side effects outside its execution workspace.
369
- - Persistent worktrees require a Git repository with a valid `HEAD`; work-mode worktree runs require a clean source checkout.
368
+ - Persistent worktrees require a Git repository with a valid `HEAD`.
370
369
  - `--pass-through` is incompatible with `--json` and with persistent worktree runs.
371
370
  - Delegate stores local run metadata under `.delegate/`; do not commit that directory.
@@ -96,7 +96,7 @@ When running on Windows through WSL, treat Delegate as a Linux CLI:
96
96
  delegate --json dry-run claude safe --reasoning-effort high "Review only. Do not edit files."
97
97
  delegate --json dry-run grok safe "Review only. Do not edit files."
98
98
  delegate --json dry-run grok safe --reasoning-effort high "Review only. Do not edit files."
99
- delegate --json dry-run devin safe "Review only. Do not edit files."
99
+ delegate --json dry-run devin work "Describe the planned work invocation."
100
100
  delegate --json dry-run opencode safe "Review only. Do not edit files."
101
101
  delegate --json dry-run opencode safe --reasoning-effort high "Review only. Do not edit files."
102
102
  delegate --json dry-run cursor safe "Review only. Do not edit files."
@@ -104,7 +104,7 @@ When running on Windows through WSL, treat Delegate as a Linux CLI:
104
104
  delegate --json dry-run kimi safe "Review only. Do not edit files."
105
105
  ```
106
106
 
107
- The Codex, Claude, Grok, Devin, OpenCode, Cursor, and Kimi dry-runs succeed with the unedited example config when no reasoning effort is requested. Explicit Codex reasoning-effort dry-runs can target the harness default model when no default model is configured. Claude and Grok reasoning effort map to native `--effort` flags; OpenCode reasoning effort maps to `--variant` without model validation. The Droid dry-run validates the alias, so it returns `unconfigured_model` until you replace the `reviewer` placeholder in `config.json` with a real model ID.
107
+ The Codex, Claude, Grok, Devin work, OpenCode, Cursor, and Kimi dry-runs succeed with the unedited example config when no reasoning effort is requested. Devin safe mode is intentionally rejected because filesystem surveys may require generic `exec`, which cannot be allowed without weakening the read-only boundary. Explicit Codex reasoning-effort dry-runs can target the harness default model when no default model is configured. Claude and Grok reasoning effort map to native `--effort` flags; OpenCode reasoning effort maps to `--variant` without model validation. The Droid dry-run validates the alias, so it returns `unconfigured_model` until you replace the `reviewer` placeholder in `config.json` with a real model ID.
108
108
 
109
109
  ### OpenCode
110
110
 
@@ -103,12 +103,13 @@ warning plus suggested review commands, but does not fail solely because commits
103
103
  exist. Validation rejects `--forbid-commit` outside `work` mode, and explicit
104
104
  `--isolation none --forbid-commit` remains invalid.
105
105
 
106
- `--include-dirty` is an opt-in launch flag for `work` mode with persistent
107
- worktree isolation. It copies uncommitted tracked changes and untracked
108
- non-ignored files from the source checkout into the new persistent worktree
109
- before the child starts. Gitignored files remain excluded, and external symlinks
110
- are blocked with the same protections used by safe-mode workspace sync. Without
111
- the flag, persistent worktree launches still require a clean source checkout.
106
+ Work-mode persistent worktrees automatically copy uncommitted tracked changes
107
+ and untracked non-ignored files from a dirty source checkout before the child
108
+ starts. Gitignored files remain excluded, and external symlinks are blocked with
109
+ the same protections used by safe-mode workspace sync. Automatic sync emits a
110
+ `dirty_source_auto_included` warning with tracked-modified and untracked counts.
111
+ `--include-dirty` remains an explicit launch flag and is a no-op when the source
112
+ is already clean.
112
113
  JSON and text completion output report `includeDirty: true` / `syncedFiles`.
113
114
  `run --input-json` accepts the equivalent boolean field `includeDirty`.
114
115
 
@@ -118,11 +119,9 @@ A few boundaries are worth stating explicitly:
118
119
  repo history but also matched by a `.gitignore` rule is part of the repository
119
120
  and is synced like any other tracked file; `--include-dirty` excludes only
120
121
  untracked gitignored paths, not tracked ones.
121
- - **`--include-dirty` skips the submodule-cleanliness portion of the clean
122
- check.** Without the flag, the preflight requires a clean source checkout
123
- including submodule state; with the flag, the entire clean-source check is
124
- skipped, so dirty submodules do not block the launch and submodule
125
- working-tree state is not mirrored.
122
+ - **Dirty submodules fail preflight.** Delegate auto-syncs ordinary tracked and
123
+ untracked non-ignored source changes, but cannot safely reproduce dirty
124
+ submodule state, so it refuses the launch until that submodule is clean.
126
125
  - **Keep secrets out of hardlinks.** A hardlink at a non-ignored path to
127
126
  gitignored content is indistinguishable from a regular file and will sync by
128
127
  content; `--include-dirty` trusts every non-ignored path. Path-based exclusion
@@ -166,7 +165,7 @@ Examples:
166
165
 
167
166
  ```bash
168
167
  delegate codex safe "Review this repo for regressions; report file/line/severity."
169
- delegate codex safe --model gpt-5.5 "Review this repo for regressions; report file/line/severity."
168
+ delegate codex safe --model reviewer "Review this repo for regressions; report file/line/severity."
170
169
  delegate codex safe --model my-alias --reasoning-effort medium --fast "Explore likely causes."
171
170
  delegate codex work "Implement the scoped task; report changed files and tests."
172
171
  delegate codex call "Summarize this context in three bullets."
@@ -195,7 +194,7 @@ Examples:
195
194
 
196
195
  ```bash
197
196
  delegate claude safe "Review this repo for regressions; report file/line/severity."
198
- delegate claude work --model claude-opus-4-6 "Implement the scoped task; report changed files and tests."
197
+ delegate claude work --model implementer "Implement the scoped task; report changed files and tests."
199
198
  delegate claude call "Summarize this context in three bullets."
200
199
  delegate --isolation worktree claude work "Implement the feature in a persistent worktree."
201
200
  ```
@@ -251,9 +250,9 @@ delegate [--json] opencode call [--read-only] [--model <alias-or-model>] [--reas
251
250
  {
252
251
  "opencode": {
253
252
  "models": {
254
- "sonnet": "anthropic/claude-sonnet-4-5",
255
- "sonnet-high": {
256
- "model": "anthropic/claude-sonnet-4-5",
253
+ "reviewer": "provider/model",
254
+ "reviewer-high": {
255
+ "model": "provider/model",
257
256
  "variant": "high"
258
257
  }
259
258
  }
@@ -280,7 +279,7 @@ Examples:
280
279
  ```bash
281
280
  delegate opencode safe "Review this repo for regressions; report file/line/severity."
282
281
  delegate opencode work --agent build "Implement the scoped task; report changed files and tests."
283
- delegate opencode call --read-only --model anthropic/claude-sonnet-4-5 --prompt-file rubric.md
282
+ delegate opencode call --read-only --model reviewer --prompt-file rubric.md
284
283
  delegate --isolation worktree opencode work "Implement the feature in a persistent worktree."
285
284
  ```
286
285
 
@@ -436,7 +435,9 @@ On expiry Delegate terminates the whole child process group and returns
436
435
  `call_timeout` with exit code 1.
437
436
 
438
437
  `--read-only`, `--pure`, and `--timeout` apply only to `call`; passing them with
439
- `safe`/`work` is rejected.
438
+ `safe`/`work` is rejected. Empty-result retry applies to safe runs and read-only
439
+ calls when the prompt can be safely extended; write-capable, pure, and verbatim
440
+ calls are not retried.
440
441
  Because the child call is stateless, `--isolation`, `--pass-through`,
441
442
  `--progress`, `--forbid-commit`, and markdown completion reports are rejected.
442
443
  An ordinary call also rejects `--cwd`.
@@ -451,7 +452,7 @@ delegate --cwd /path/to/project --group wf_0123abcdef45 codex call "Summarize th
451
452
  ```
452
453
 
453
454
  The child still executes in an empty temporary cwd; `--cwd` does not give it the
454
- project tree. Dry-run accepts the same combination for faithful planning but
455
+ project tree or leak it through Delegate root metadata. Dry-run accepts the same combination for faithful planning but
455
456
  creates no run entry. Use `safe` or `work` when the child should see the project
456
457
  tree.
457
458
 
@@ -499,7 +500,7 @@ Typical dry-run JSON fields:
499
500
 
500
501
  When a profile is active, dry-run and completion payloads add `authProfile` (the resolved profile name) and, when a Codex fallback profile is configured, `fallbackProfile`. Dry-run also adds `profileEnv` (the injected env map, with values redacted). These keys are omitted when no profile is active.
501
502
 
502
- For Cursor, Claude, Grok, Devin, OpenCode, Droid, and Kimi safe mode, an explicit `--isolation none`
503
+ For Cursor, Claude, Grok, OpenCode, Droid, and Kimi safe mode, an explicit `--isolation none`
503
504
  is normalized to `auto` with a warning because those safe contracts depend on
504
505
  the temporary workspace/config boundary. Codex safe can use `none` because Codex
505
506
  still runs with its read-only sandbox.
@@ -585,9 +586,10 @@ Supported input keys:
585
586
 
586
587
  - `engine`: `cursor`, `droid`, `codex`, `claude`, `grok`, `devin`, `opencode`, or `kimi`.
587
588
  - `mode`: `safe`, `work`, or `call`.
589
+ - The `devin` engine rejects `safe` with `unsupported_mode` during preflight. Devin filesystem surveys may require generic `exec`, which Delegate cannot allow without weakening the read-only boundary; use another safe Harness for filesystem review.
588
590
  - `model`: optional alias-or-id for every engine. Resolved against `<engine>.models` when it matches an alias; otherwise passed through as a raw model ID. For Droid, a positional alias remains alias-only/strict; JSON/`--model` is alias-or-id. Cursor honors an explicit model even when it differs from `cursor.defaultModel`.
589
591
  - `cwd`: optional workspace path. Git directories resolve to the repo root. Omit it for `mode: "call"`, which always uses an empty temporary cwd.
590
- - `isolation`: optional `auto`, `none`, or `worktree`. `null` is invalid. `mode: "call"` rejects isolation. For Cursor, Claude, Grok, Devin, OpenCode, Droid, and Kimi safe mode, `none` is normalized to `auto` with a warning.
592
+ - `isolation`: optional `auto`, `none`, or `worktree`. `null` is invalid. `mode: "call"` rejects isolation. For Cursor, Claude, Grok, OpenCode, Droid, and Kimi safe mode, `none` is normalized to `auto` with a warning.
591
593
  - `reasoningEffort`: optional non-empty effort string. It overrides provider `defaultReasoningEffort` for that JSON run.
592
594
  - `fast`: optional Codex-only boolean or `null`. `true` requests Fast, `false` explicitly requests Standard, and `null`/omission inherits Codex configuration.
593
595
  - `progress`: optional boolean. `true` enables parent progress heartbeats on stderr; `false` disables them even when `progress.enabled` is true in config. When omitted, config `progress.enabled` applies (default `false`). `mode: "call"` rejects progress.
@@ -763,7 +765,7 @@ Codex usage-limit fallback fires, the completion payload also includes
763
765
  `codexAuthFallback` metadata (reason, the primary and fallback profile names,
764
766
  both exit codes, and a redacted primary stderr tail).
765
767
 
766
- Snapshot JSON uses schema `delegate.snapshot.v1` and includes fields such as `alias`, `runId`, `harness`, `status`, `rawStatus`, `effectiveStatus`, `staleReason`, `nextActions`, `cwd`, `executionCwd`, `assistantText`, `recentEvents`, `warnings`, `exitCode`, reasoning metadata, terminal metadata, and isolation/worktree metadata when applicable. Inspection commands do not rewrite a stale run's recorded state; they expose the raw recorded status plus the effective status computed from the current PID check. Run-output and worktree show output include `requestedHandle`, `resolvedHandle`, and `resolutionKind` (`literal`, `latest`, or `latest_model`) when a handle resolves indirectly.
768
+ Snapshot JSON uses schema `delegate.snapshot.v1` and includes fields such as `alias`, `runId`, `harness`, `status`, `rawStatus`, `effectiveStatus`, `staleReason`, `nextActions`, `cwd`, `executionCwd`, `assistantText`, `recentEvents`, `warnings`, `exitCode`, reasoning metadata, terminal metadata, and isolation/worktree metadata when applicable. Inspection commands do not rewrite a stale run's recorded state; they expose the raw recorded status plus the effective status computed from the current PID check. Run-output and worktree show output include `requestedHandle`, `resolvedHandle`, and `resolutionKind` (`literal`, `latest`, or `latest_model`) when a handle resolves indirectly. For bare harness handles, snapshot, run-output, and wait also report `resolvedRunId`, `resolvedAlias`, `resolvedWorkspace`, `resolvedAge`, and `resolvedAgeSeconds`. Resolutions older than 24 hours add a `bare_handle_stale` warning suggesting `--cwd` or an explicit handle.
767
769
 
768
770
  Tracked run envelopes include `completionReportWritten`, `completionReportSource`
769
771
  (`child`, `delegate_synthesized`, `stdout_recovery`, or `null`), and
@@ -773,6 +775,15 @@ exit-code-derived status.
773
775
 
774
776
  Run-output JSON uses schema `delegate.run-output.v1` and returns selected completion report, stdout, and/or stderr content. By default, secret-like strings are redacted unless `--no-redact` is supplied. Tracked runs finish in one of the terminal statuses `succeeded`, `failed`, or `cancelled`; explicit harness cancellation/error terminal events override an exit-zero child status.
775
777
 
778
+ Safe runs and read-only call runs that exit successfully with `resultQuality=empty`
779
+ retry once with the original prompt plus a plain-text final-answer instruction.
780
+ Pure and slash pass-through prompts, and write-capable calls, do not retry. Retried
781
+ envelopes add `emptyRetry: {attempted, resolved}`; runs that do not retry omit the
782
+ field. If the second attempt is also empty, the run remains successful and honest
783
+ with `resultQuality=empty`, and emits an
784
+ `empty_success_retry` warning. Tracked safe runs retain both attempts in their
785
+ stdout/stderr logs.
786
+
776
787
  `delegate wait` blocks until every selected run reaches terminal state. Defaults:
777
788
  `--interval 3`, minimum interval `1`, and `--timeout 3600`. Exit codes are `0`
778
789
  when all runs succeeded, `1` when any run failed or was cancelled, and `124` on
@@ -819,9 +830,10 @@ selectors are preserved. `--stdout` or `--stderr` without `--tail` or `--raw`
819
830
  defaults to a bounded `--tail 80` and a character cap (default 60000); use
820
831
  `--max-chars N` to override the cap. `--raw` returns the full stream with no
821
832
  line or character bounds, includes `rawOutputBytes` in JSON metadata, and cannot
822
- be combined with `--tail` or `--max-chars`. `--tail` and `--max-chars` require
823
- `--stdout` or `--stderr`; Delegate rejects them when only `--completion-report`
824
- is selected.
833
+ be combined with `--tail` or `--max-chars`. A bare `--tail N` implies
834
+ `--stdout` when no output selector is supplied; it never includes stderr.
835
+ `--max-chars` still requires `--stdout` or `--stderr`, and Delegate rejects
836
+ either bound when only `--completion-report` is selected.
825
837
 
826
838
  When `completion-report.md` is absent, `run-output --completion-report` makes a
827
839
  bounded best-effort attempt to recover an explicit final response from the
@@ -386,6 +386,7 @@ Controls local run recording.
386
386
  - `models`: optional map of local aliases to Devin model IDs for `--model` / JSON `model`. Alias keys must not collide with mode names, equal the engine's own name, or start with `-`.
387
387
  - `defaultReasoningEffort`: not supported in v1; must be `null`.
388
388
  - Discover live Devin model IDs with `delegate models devin --live`.
389
+ - Devin safe mode is rejected during preflight because filesystem surveys may require generic `exec`, which Delegate cannot permit without weakening the read-only boundary. Use another safe Harness for filesystem review.
389
390
 
390
391
  ### `opencode`
391
392
 
@@ -491,7 +492,7 @@ Supported boolean policy keys: `networkAccess`, `webSearch`, `bypassApprovalsAnd
491
492
  ```
492
493
 
493
494
  Allowed values are `auto`, `none`, and `worktree`. For Cursor, Claude, Grok,
494
- Devin, OpenCode, Droid, and Kimi safe mode, an effective value of `none` is normalized to `auto`
495
+ OpenCode, Droid, and Kimi safe mode, an effective value of `none` is normalized to `auto`
495
496
  because those safe contracts depend on Delegate's temporary workspace/config
496
497
  boundary. Explicit per-run CLI/JSON `none` requests also emit a warning; a
497
498
  config default is normalized without a separate per-run warning. Codex safe can
@@ -499,7 +500,7 @@ use `none` because the Codex read-only sandbox remains active.
499
500
 
500
501
  Embedded defaults:
501
502
 
502
- - `safe`: `auto`. Cursor, Claude, Grok, Devin, OpenCode, Droid, Codex, and Kimi safe use temporary workspace isolation by default.
503
+ - `safe`: `auto`. Cursor, Claude, Grok, OpenCode, Droid, Codex, and Kimi safe use temporary workspace isolation by default. Devin safe is unsupported.
503
504
  - `work`: `none`. Work mode runs in the real workspace unless you opt into worktree isolation.
504
505
 
505
506
  ### `worktrees`
@@ -27,15 +27,16 @@ Delegate does not control:
27
27
 
28
28
  Safe mode is for review and investigation.
29
29
 
30
- - Cursor safe, Droid safe, Codex safe, Claude safe, Grok safe, Devin safe, OpenCode safe, and Kimi safe run in an isolated throwaway workspace by default, with your current working tree mirrored into that copy (see [What safe review can and cannot see](#what-safe-review-can-and-cannot-see) below).
30
+ - Cursor safe, Droid safe, Codex safe, Claude safe, Grok safe, OpenCode safe, and Kimi safe run in an isolated throwaway workspace by default, with your current working tree mirrored into that copy (see [What safe review can and cannot see](#what-safe-review-can-and-cannot-see) below).
31
31
  - Cursor safe also writes a read-oriented `.cursor/cli.json` in the isolated workspace only.
32
32
  - Codex safe uses `--ask-for-approval never exec --sandbox read-only`.
33
33
  - Claude safe uses `claude -p` with stdin prompt transport, `--permission-mode plan`, `--strict-mcp-config`, Read/Grep/Glob, and selected read-only Bash tools. Delegate does not currently prove that Claude Code hooks, plugins, user settings, or other non-MCP customization surfaces are disabled.
34
34
  - Droid safe uses Delegate's read-only safety prompt, does not add Droid work-mode unsafe flags, and uses the isolated temporary workspace as a defense-in-depth boundary.
35
35
  - Kimi safe uses Delegate's read-only safety prompt and does not enable Kimi `--plan`. Kimi prompt mode auto-approves tool actions, so there is no runtime read-only enforcement for Kimi safe; the isolated temporary workspace is the effective boundary and the safety prompt is advisory.
36
36
  - Grok safe uses Delegate's read-only safety prompt plus Grok `--sandbox read-only` and `--permission-mode dontAsk`. Delegate does not use Grok `plan` mode for safe review. Prompts are delivered via Grok `--prompt-file`.
37
+ - Devin safe is rejected during preflight. Devin may implement filesystem surveys through generic `exec`, which Delegate cannot permit without weakening the read-only boundary; use another safe Harness for filesystem review.
37
38
  - OpenCode safe uses `--pure` plus environment-injected runtime enforcement. `OPENCODE_CONFIG_CONTENT` merges after repository config, disables sharing and autoupdate, applies deny-all-but-read/glob/grep permissions globally and to the selected agent, and creates a synthetic `delegate-read-only` agent when none is selected. `OPENCODE_PERMISSION` applies the same tool policy. Delegate re-applies these protected settings after profile resolution. `--pure` also disables repository-local plugins that could otherwise execute code during a safe run.
38
- - Explicit `--isolation none` is normalized to `auto` with a warning for Cursor, Claude, Grok, Devin, OpenCode, Droid, and Kimi safe mode because it would remove the isolation/config boundary those safe contracts rely on. Codex safe may opt out of Delegate workspace isolation because the Codex read-only sandbox remains active.
39
+ - Explicit `--isolation none` is normalized to `auto` with a warning for Cursor, Claude, Grok, OpenCode, Droid, and Kimi safe mode because it would remove the isolation/config boundary those safe contracts rely on. Codex safe may opt out of Delegate workspace isolation because the Codex read-only sandbox remains active.
39
40
 
40
41
  Safe mode is not a proof of zero side effects. Treat it as a defensive default plus prompt/runtime policy. A runtime could still read available files, use configured credentials, load its own customizations, or perform actions allowed by its own permissions.
41
42
 
@@ -159,7 +160,7 @@ security control.
159
160
 
160
161
  ### Temporary safe isolation
161
162
 
162
- Cursor safe, Droid safe, Codex safe, Claude safe, Grok safe, Devin safe, OpenCode safe, and Kimi safe normally run in a temporary Git worktree or directory copy, with uncommitted tracked edits and untracked, non-ignored files synced from the source working tree (gitignored paths excluded). This protects the source checkout from ordinary relative-path edits made inside the execution workspace. Delegate may still write `.delegate/` metadata in the source workspace for tracked runs.
163
+ Cursor safe, Droid safe, Codex safe, Claude safe, Grok safe, OpenCode safe, and Kimi safe normally run in a temporary Git worktree or directory copy, with uncommitted tracked edits and untracked, non-ignored files synced from the source working tree (gitignored paths excluded). This protects the source checkout from ordinary relative-path edits made inside the execution workspace. Delegate may still write `.delegate/` metadata in the source workspace for tracked runs.
163
164
 
164
165
  Git repositories with commits use a detached temporary Git worktree. Non-Git directories use a temporary directory copy. Git repositories with no commits fall back to a temporary directory copy because Git cannot create a detached worktree from an unborn `HEAD`; Delegate reports that fallback in run metadata.
165
166
 
@@ -171,6 +172,15 @@ This closes a leak where an untracked symlink whose absolute target pointed at t
171
172
 
172
173
  `--isolation worktree` with `work` mode creates a preserved Git worktree and local branch. The child edits that worktree, not the source checkout. The orchestrator can inspect and integrate the diff later.
173
174
 
175
+ Workspace-backed children receive `DELEGATE_SOURCE_ROOT` with the resolved source
176
+ workspace root. Isolated children also receive `DELEGATE_EXECUTION_ROOT`. Call
177
+ mode has no source checkout: its throwaway cwd is `DELEGATE_SOURCE_ROOT`, and the
178
+ Registry/config workspace is not exposed to the child. Delegate's own worktree
179
+ removal, pruning, and temporary snapshot teardown paths refuse a target that is
180
+ or contains the source root, including through relative or symlinked paths.
181
+ Harness-side hook enforcement is separate machine configuration and is not
182
+ provided by this repository.
183
+
174
184
  Persistent worktree isolation is not a security sandbox. It does not prevent:
175
185
 
176
186
  - Use of secrets available in environment variables, config files, credential stores, or runtime sessions.
@@ -240,9 +240,17 @@ delegate --json droid reviewer call --prompt-file prompt.md
240
240
  Call mode returns captured assistant text in JSON `text` when available. Use
241
241
  `safe` or `work` for project-aware review/implementation and tracked output.
242
242
 
243
+ ## Devin safe reports `unsupported_mode`
244
+
245
+ Devin may implement a read-only filesystem survey through the generic `exec`
246
+ tool. Delegate cannot permit that tool in safe mode without weakening the
247
+ read-only boundary, so `delegate devin safe` is rejected before launch. Use
248
+ another safe Harness for filesystem review; Devin work and call modes remain
249
+ available.
250
+
243
251
  ## Safe-mode isolation fails
244
252
 
245
- Cursor, Droid, Codex, Claude, Grok, Devin, OpenCode, and Kimi safe create an
253
+ Cursor, Droid, Codex, Claude, Grok, OpenCode, and Kimi safe create an
246
254
  isolated throwaway workspace by default. Safe mode reviews your **current working tree**,
247
255
  uncommitted tracked edits and untracked, non-ignored files are mirrored into
248
256
  that copy (only gitignored paths are excluded), so you do **not** need to
@@ -250,7 +258,7 @@ commit or stash before a safe review. In Git repositories, Delegate first tries
250
258
  a detached worktree and syncs the dirty tree into it; for non-Git directories
251
259
  and some Git fallback cases, it uses a directory copy. Codex safe is the only
252
260
  safe harness that may opt out with `--isolation none`, because Codex still
253
- keeps its read-only sandbox active. Cursor, Droid, Claude, Grok, Devin,
261
+ keeps its read-only sandbox active. Cursor, Droid, Claude, Grok,
254
262
  OpenCode, and Kimi safe
255
263
  normalize `--isolation none` back to `auto` with a warning because their safe
256
264
  contracts depend on Delegate's temporary workspace boundary.
@@ -270,7 +278,9 @@ python3 bin/delegate.py codex safe "Review my uncommitted changes. Do not edit."
270
278
 
271
279
  ## Persistent worktree run refused
272
280
 
273
- Work-mode persistent worktrees require a Git repository with a valid `HEAD` and a clean source checkout.
281
+ Work-mode persistent worktrees require a Git repository with a valid `HEAD`.
282
+ Dirty tracked and untracked non-ignored files are synced automatically; sync
283
+ failures abort and tear down the new worktree before child launch.
274
284
 
275
285
  ```bash
276
286
  git status --short
@@ -279,9 +289,9 @@ delegate --json --isolation worktree dry-run cursor work "Implement only."
279
289
  ```
280
290
 
281
291
  Detached `HEAD` is valid; an unborn repository with no commit is not. Dry-run
282
- shows the planned branch/path but does not run the full launch preflight. If the
283
- source checkout is dirty, commit, stash, or choose a different isolation mode
284
- before launching.
292
+ shows the planned branch/path but does not run the full launch preflight. Ordinary
293
+ tracked and untracked source changes auto-sync; commit or stash dirty submodules,
294
+ or choose a different isolation mode, before launching.
285
295
 
286
296
  ## Persistent worktree run failed with `commit_policy_violated`
287
297
 
@@ -10,7 +10,7 @@ Use persistent worktree isolation when:
10
10
  - You want to review, cherry-pick, or merge the child work later.
11
11
  - You want Delegate to keep run metadata tied to a branch and worktree path.
12
12
 
13
- Use the real workspace instead when the task depends on uncommitted local files that you do not want to commit or mirror into a worktree. If you do want a persistent worktree that starts from your current dirty checkout, use `--include-dirty`.
13
+ Use the real workspace instead when the task depends on uncommitted local files that you do not want mirrored into a worktree. Work-mode worktree runs automatically mirror a dirty checkout.
14
14
 
15
15
  For grouped feature waves, commit between waves when they share the real
16
16
  workspace. If each feature needs its own review or commit, use one persistent
@@ -29,8 +29,10 @@ delegate --isolation worktree droid implementer work "Implement the scoped chang
29
29
  delegate --isolation worktree kimi work "Implement the scoped change and report changed files."
30
30
  ```
31
31
 
32
- Add `--include-dirty` when the new persistent worktree should start with the
33
- source checkout's uncommitted tracked edits and untracked non-ignored files:
32
+ Dirty source checkouts automatically seed the new persistent worktree with
33
+ uncommitted tracked edits and untracked non-ignored files. Delegate emits a
34
+ `dirty_source_auto_included` warning with both counts. `--include-dirty` remains
35
+ available as an explicit request and is a no-op when the source is clean:
34
36
 
35
37
  ```bash
36
38
  delegate --isolation worktree cursor work --include-dirty "Implement using my local edits."
@@ -47,13 +49,9 @@ A few boundaries are worth stating explicitly:
47
49
  was committed before being added to `.gitignore`) is part of the repository
48
50
  and is synced like any other tracked file. `--include-dirty` excludes only
49
51
  untracked gitignored paths, not tracked ones.
50
- - **`--include-dirty` skips the submodule-cleanliness portion of the clean
51
- check.** Without the flag, the preflight requires a clean source checkout
52
- including submodule state (`git status --ignore-submodules=none`). With the
53
- flag, the entire clean-source check is skipped, so dirty submodules do not
54
- block the launch and submodule working-tree state is not mirrored into the
55
- new worktree (only the source checkout's tracked diff and untracked
56
- non-ignored files are).
52
+ - **Dirty submodules fail preflight.** Delegate auto-syncs ordinary tracked and
53
+ untracked non-ignored source changes, but cannot safely reproduce dirty
54
+ submodule state, so it refuses the launch until that submodule is clean.
57
55
  - **Keep secrets out of hardlinks.** A hardlink at a non-ignored path to
58
56
  gitignored content is indistinguishable from a regular file to Delegate's
59
57
  path-based sync: it is a non-ignored path, so `--include-dirty` syncs it by
@@ -91,7 +89,7 @@ Persistent worktree work-mode runs require:
91
89
 
92
90
  - A Git workspace.
93
91
  - A valid `HEAD` commit.
94
- - A clean source checkout: no staged, unstaged, or untracked files, unless the launch uses `--include-dirty`.
92
+ - A source checkout whose tracked edits and untracked non-ignored files can be synced.
95
93
  - No `--pass-through`.
96
94
 
97
95
  Dry-run previews the plan without creating anything:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "delegate-agent-cli"
7
- version = "0.14.0"
7
+ version = "0.15.0"
8
8
  description = "A tiny CLI for delegating bounded agent tasks to Cursor, Droid, OpenAI Codex, Claude Code, Grok Build, or Kimi Code runtimes."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,5 +1,5 @@
1
1
  """Delegate Agent CLI package."""
2
2
 
3
- VERSION = "0.14.0"
3
+ VERSION = "0.15.0"
4
4
 
5
5
  __all__ = ["VERSION"]
@@ -397,10 +397,20 @@ def build_devin_argv(
397
397
  pure: bool = False,
398
398
  ) -> list[str]:
399
399
  _reject_pure("devin", mode, pure)
400
+ if mode == MODE_SAFE:
401
+ raise DelegateError(
402
+ "unsupported_mode",
403
+ "Devin safe mode is unsupported: Devin may perform read-only filesystem "
404
+ "surveys through the generic exec tool, which Delegate cannot allow without "
405
+ "weakening the read-only boundary. Use another harness in safe mode for "
406
+ "filesystem review.",
407
+ )
408
+ if mode not in (MODE_WORK, MODE_CALL):
409
+ validate_mode(mode)
400
410
  argv = [str(devin["binary"])]
401
411
  if model:
402
412
  argv.extend(["--model", model])
403
- read_only = mode == MODE_SAFE or (mode == MODE_CALL and call_read_only)
413
+ read_only = mode == MODE_CALL and call_read_only
404
414
  if read_only:
405
415
  argv.extend(
406
416
  [
@@ -410,10 +420,8 @@ def build_devin_argv(
410
420
  "auto",
411
421
  ]
412
422
  )
413
- elif mode in (MODE_WORK, MODE_CALL):
414
- argv.extend(["--permission-mode", "dangerous"])
415
423
  else:
416
- validate_mode(mode)
424
+ argv.extend(["--permission-mode", "dangerous"])
417
425
  if prompt_transport != PROMPT_TRANSPORT_FILE:
418
426
  raise DelegateError(
419
427
  "invalid_prompt_transport",