holon 0.14.1

A headless, event-driven runtime for long-lived agents
Documentation
# Command Execution And Task Model

This document defines the next-step design for command execution in Holon after
the tool-surface cutover to `exec_command`.

The goal is to keep the public command tool simple while making long-running
processes manageable inside the runtime.

## Problem

Holon currently has two tensions:

- `exec_command` should stay simple and aligned with Codex-style command
  execution.
- long-running commands such as dev servers, watchers, and long tests still
  need:
  - lifecycle tracking
  - status inspection
  - termination
  - possible follow-up continuation

Putting both modes into a single `background=true` flag makes the command tool
carry two different semantics at once:

- foreground synchronous execution
- background orchestrated task execution

That makes policy, transcript, stopping, and task ownership harder to reason
about.

## Design Principles

1. `exec_command` stays the foreground primitive.
2. Background work is modeled as a task, not as a command flag.
3. The runtime owns process lifecycle tracking.
4. The agent should not need to manually manage raw process ids.
5. Only tasks that have orchestration value should re-enter the main loop.

## Recommended Model

### 1. `exec_command`

`exec_command` is the public tool for:

- short verification commands
- diagnostics
- one-shot shell interactions

Its default contract should remain:

- start a command
- wait up to `yield_time_ms`
- if the process exits, return normal result output

It should not expose `background=true`.

### 2. `command_task`

Long-running non-interactive commands should be represented as:

- managed `command_task` records

This task kind is the runtime-level abstraction for:

- dev servers
- file watchers
- long-running test commands
- log-following helpers

Public creation paths:

- `exec_command` can promote long-running commands into managed `command_task`
- operator control surfaces may create managed `command_task` directly
- short waits should use `Sleep(duration_ms)` instead of a separate wait task

Suggested payload:

- `cmd`
- `workdir`
- `shell`
- `login`
- `tty`
- `yield_time_ms`
- `max_output_tokens`
- `summary`
- optional `continue_on_result`

### 3. Automatic Promotion

Holon should support this behavior for non-interactive commands:

1. `exec_command` starts the command.
2. If the process exits before `yield_time_ms`, return a normal result.
3. If the process is still running after `yield_time_ms`, the runtime promotes
   it into a `command_task`.
4. The tool result returns:
   - `task_id`
   - task status
   - initial output snippet

This keeps the model simple:

- short commands remain foreground
- long commands become managed tasks automatically

This promotion should only happen for non-interactive command flows. The first
version should not try to support mid-flight promotion of interactive PTY
sessions.

## Why Not `background=true`

`background=true` is attractive as a shortcut, but it has poor boundaries:

- it mixes process execution and orchestration in one tool contract
- it encourages the model to spawn long-lived processes without task metadata
- it makes stop/cleanup semantics awkward
- it creates a second background model next to managed `command_task`

Holon should avoid having both:

- background `exec_command`
- task-based background execution

The task model should be the only background model.

## Task Lifecycle

`command_task` should use the same task lifecycle as other runtime tasks:

- `queued`
- `running`
- `completed`
- `failed`
- `cancelled`

Runtime responsibilities:

- persist task records
- keep command ownership under the session
- emit `TaskStatus` and `TaskResult`
- support `TaskStop`
- record final exit status and output summary

## Agent Continuation

Task completion should not always wake the agent into another full reasoning
loop.

Recommended rule:

- `command_task`: default no automatic continuation
- `child_agent_task`: continue by default, with `workspace_mode` preserving
  inherited versus worktree-isolated delegation

If a `command_task` is specifically created to support the next reasoning step,
its metadata may set:

- `continue_on_result: true`

In that case the runtime may enqueue a follow-up after the `TaskResult`.

## Future Interactive Extension

If Holon later needs interactive shell sessions, that should be a separate
layer, not part of the first `command_task` implementation.

Two acceptable future directions:

1. Codex-style:
   - `exec_command` returns a session handle
   - `write_stdin` continues interaction

2. Task-wrapped interaction:
   - `command_task` owns an interactive session internally
   - later tools operate on `task_id` rather than a raw `session_id`

For Holon, the second option is likely more consistent with its task-oriented
runtime design, but it should come after the non-interactive `command_task`
path is stable.

## Recommended Implementation Order

1. Add `command_task` to the task model.
2. Add runtime execution for non-interactive command tasks.
3. Make `exec_command` auto-promote long-running non-interactive commands into
   `command_task`.
4. Extend `TaskStatus` and `TaskList` with command-task status and output summary.
5. Make `TaskStop` terminate `command_task` cleanly.
6. Re-evaluate whether interactive command sessions are still needed.

## Non-Goals For The First Pass

- no interactive PTY continuation
- no `write_stdin`
- no raw process-id exposure in the public contract
- no second background command model

## Summary

Holon should use:

- `exec_command` for foreground command execution
- `command_task` for managed background command execution

This keeps the public command tool simple, keeps background work visible and
stoppable, and aligns Holon more closely with Claude-style task orchestration
without giving up Codex-style command ergonomics.