Skip to content
Autonomy
AGH RuntimeAutonomy

Task Execution Profiles

Typed task-owned overlays for coordinator guidance, worker selection, reviewer routing, participant policy, and sandbox mode at session start.

Audience
Operators running durable agent work
Focus
Autonomy guidance shaped for scanability, day-two clarity, and operator context.

A task execution profile is a typed, task-owned overlay that shapes how the runtime executes one task without giving the profile any new authority. Profiles steer coordinator guidance, narrow which workers and reviewers are eligible, bound participant routing, and pick the session sandbox. Task ownership, lease authority, terminal state, and review verdicts stay in task.Service exactly as described in Task Runs and Leases and Coordinator Handoff.

What a profile contains

Every task has at most one execution profile. The shape is fixed and persists through typed columns and selector side tables (no metadata_json):

{
  "task_id": "task-123",
  "coordinator": {
    "mode": "inherit",
    "agent_name": "",
    "provider": "",
    "model": "",
    "guidance": ""
  },
  "worker": {
    "mode": "inherit",
    "agent_name": "",
    "provider": "",
    "model": "",
    "allowed_agent_names": [],
    "preferred_agent_names": [],
    "required_capabilities": [],
    "preferred_capabilities": []
  },
  "review": {
    "agent_name": "",
    "provider": "",
    "model": "",
    "allowed_agent_names": [],
    "preferred_agent_names": [],
    "allowed_channel_ids": [],
    "preferred_channel_ids": [],
    "allowed_peer_ids": [],
    "preferred_peer_ids": [],
    "required_capabilities": [],
    "preferred_capabilities": []
  },
  "participants": {
    "allowed_channel_ids": [],
    "preferred_channel_ids": [],
    "allowed_peer_ids": [],
    "preferred_peer_ids": [],
    "allowed_agent_names": [],
    "preferred_agent_names": [],
    "required_capabilities": [],
    "preferred_capabilities": []
  },
  "sandbox": {
    "mode": "inherit",
    "sandbox_ref": ""
  }
}
BlockPurpose
coordinatorinherit keeps the workspace coordinator behavior. guided keeps the same daemon-managed coordinator but injects task-specific agent_name/provider/model/guidance.
workerinherit keeps workspace defaults. select narrows worker eligibility through allowed_agent_names, preferred_agent_names, and capability selectors.
reviewReviewer hints (agent/provider/model) plus reviewer routing selectors (channels, peers, agents, capabilities) consumed by the review gate.
participantsUpper-bound routing policy for coordination surfaces and review routing. Allowed lists narrow; preferred lists rank. Never a permission grant.
sandboxinherit falls through to workspace defaults. none skips sandbox startup when the runtime allows it. ref resolves a named [sandboxes.<name>] profile at session start.

Persistence and validation live in internal/task/profile.go and the typed selector tables in internal/store/globaldb; they ship as a numbered migration, not a JSON column.

Selector precedence and runtime selection

Effective behavior at runtime is the result of layering, not negotiation. The order is:

  1. Config defaults. [task.orchestration.profile] and [task.orchestration.review] define the default coordinator mode, default worker mode, default sandbox mode, provider-override gate, sandbox-none gate, and review policy defaults. See the config-toml reference.
  2. Persisted profile (write time). When an operator or agent calls task.Service.SetExecutionProfile, the service trims, deduplicates, and normalizes selectors, defaults missing modes to inherit, and validates the result against the config gates. The normalized profile is stored in task_execution_profiles plus the typed selector tables.
  3. Claim eligibility. ClaimNextRun consults the worker side of the persisted profile to filter eligible sessions: exact worker.agent_name, worker.allowed_agent_names, and required capabilities are enforced as store-level claim filters before a session is allowed to claim the run.
  4. Session start (load only). When task service starts a worker session it loads the persisted normalized profile (or the default inherit profile when none is stored) and passes it into StartTaskSession. The daemon session bridge then maps worker.agent_name, worker.provider, worker.model, and the sandbox policy into session.CreateOpts. Session start does not re-run profile validation; provider and model still flow through config.ResolveSessionAgentWithRuntime, so profile values never bypass provider authorization, credential slots, or session validation.
  5. Coordinator routing. The daemon ReviewRouter and coordinator runtime read review and participant policies to pick reviewer sessions. The original worker is excluded; persisted task.Service is the only authority that records routing diagnostics or no-route verdicts.
  6. Continuation runs. When a review rejects a run, the continuation run uses the task's current profile at enqueue time. Reviewed-run worker/participant fields are copied only when the new profile leaves the equivalent selector empty.

task.Service rejects profile mutation while tasks.current_run_id is set. Profile edits are control-plane changes; they must not rewrite an active execution.

Sandbox mode behavior

ModeEffect at session start
inheritThe session keeps the workspace/global sandbox path. No task-level override is applied.
noneThe session starts with no sandbox. The gate is enforced at profile write time when task.orchestration.profile.allow_task_sandbox_none = false. Tool policy, approval policy, provider authorization, and session authorization still run.
refsandbox.sandbox_ref resolves through workspace [sandboxes.<name>] validation. Unknown or invalid refs fail with a typed validation error before session start.

Sandbox selection never bypasses tool allowlists, approval policy, or provider authorization. It only chooses which sandbox profile (if any) the session boots with.

Worker runtime selection

The worker block resolves at session start as follows:

  • agent_name (when set and allowed) becomes the session agent.
  • provider and model overlay the agent definition. The task.orchestration.profile.allow_task_provider_override gate is enforced at profile write time; if the gate is false, task.Service rejects any profile that sets a non-empty provider or model on the coordinator, worker, or review block. Persisted overrides flow through config.ResolveSessionAgentWithRuntime at session start so provider authorization, credential slots, and session validation apply unchanged.
  • allowed_agent_names and capability selectors filter ClaimNextRun candidates so an agent/session that does not match cannot claim the run.

If the resulting selector matches no eligible session, the run stays queued. The runtime exposes the state through dashboard, scheduler health, and active-run diagnostics rather than auto-relaxing the profile.

Manage a profile from the CLI

The agh task profile command group operates against a single task id and shares its UDS surface with the matching HTTP endpoints. Every subcommand supports -o json|jsonl|toon for agent consumption.

agh task profile inspect task-123 -o json
agh task profile update  task-123 --profile "$(cat profile.json)" -o json
agh task profile delete  task-123 -o json

Generated reference for each verb:

Update is a full replace, not a patch. The request body must carry the entire profile; any section that is omitted, sent as {}, or sent with an empty selector list normalizes to its default (missing modes become inherit, missing selector arrays become empty). To preserve a previously persisted selector, re-send it in the new body. Service-level normalization trims fields, deduplicates selectors, sorts them deterministically, and rejects values outside the [task.orchestration] gates with a typed validation error.

Manage a profile through HTTP and UDS

Both transports mount the same shared core handlers, so HTTP and UDS responses are identical and refer to the same authority.

MethodPathPurpose
GET/api/tasks/{id}/execution-profileRead the persisted profile or the default inherit profile if none is stored.
PUT/api/tasks/{id}/execution-profileReplace the profile. Body must satisfy task_execution_profile.task_id == {id} (or omit the field). Omitted blocks normalize to defaults; PUT does not patch fields.
DELETE/api/tasks/{id}/execution-profileRemove the profile. The task falls back to the default inherit profile.

Operation IDs in openapi/agh.json: getTaskExecutionProfile, setTaskExecutionProfile, and deleteTaskExecutionProfile. The OpenAPI document is the source of truth for request/response shapes; do not paraphrase fields. Generated TypeScript types live under web/src/generated/agh-openapi.d.ts.

PUT and DELETE return 409 Conflict when the task has an active run (tasks.current_run_id is set). Resolve or release the active run before retrying.

Native tools for in-session agents

Worker, coordinator, and reviewer sessions can manage profiles through the task toolset. The model-facing names live in the tasks toolset; AGH registers them internally with the agh__ prefix so toolset routing can hide them when policy denies the call.

Model-facing nameInternal idAuthority
task_execution_profile_getagh__task_execution_profile_getReads the profile through task.Service. Read-risk, hidden when off.
task_execution_profile_setagh__task_execution_profile_setUpdates the profile through task.Service. Mutating, active-run guard.
task_execution_profile_deleteagh__task_execution_profile_deleteDeletes the profile through task.Service. Destructive, active-run guard.

Native tools delegate every read and mutation to the task service. They do not bypass active-run mutation rejection, normalization, audit events, default-profile behavior, or claim-token fencing. Reviewer-bound submission of a verdict still uses the dedicated reviewer tool described in the review-gate documentation; the profile tools never assert reviewer authority.

Inspect and edit from the operator web UI

Open a task on the web UI and switch to the Orchestration tab. The tab is rendered by TasksDetailOrchestrationPanel and is wired against the task 26 data layer in web/src/systems/tasks.

The tab surfaces:

  • Execution Profile. Shows the effective profile (or the default state when none is persisted). The JSON edit dialog calls the same PUT /api/tasks/{id}/execution-profile endpoint as the CLI and the native task_execution_profile_set tool. Edit and Delete buttons are disabled while the task has an active run; the UI mirrors the runtime's mutation guard rather than inventing a parallel rule.
  • Reviews. Read-only list of persisted task-run reviews (status, outcome, missing work, next round guidance). Verdict authority remains the reviewer-bound submit_run_review tool; the card surfaces a permanent disclaimer reinforcing that operator sessions cannot submit a verdict from the web UI.
  • Bridge Notifications. Cursor diagnostics for terminal task notifications, including a zero state when no delivery has happened.
  • Stream Resume. latest_event_seq and connection state for cursor-seeded SSE.

Server rejections (validation errors, active-run guard, missing task) surface as toasts. The web UI does not infer authority locally; it reflects what task.Service returns.

Config lifecycle

Defaults and gates live under [task.orchestration]. The complete reference is in config.toml; the relevant subset for profiles is:

[task.orchestration.profile]
default_coordinator_mode    = "inherit"   # inherit | guided
default_worker_mode         = "inherit"   # inherit only
default_sandbox_mode        = "inherit"   # inherit | none
allow_task_provider_override = true       # gates worker.provider/model and review.provider/model
allow_task_sandbox_none      = true       # required when default_sandbox_mode = "none" or task.sandbox.mode = "none"

Behavior to keep in mind:

  • Unknown TOML keys are errors. The config loader rejects typos at startup; profiles inherit the same strictness.
  • <workspace>/.agh/config.toml overlays the global file. Workspace overlays can flip allow_task_provider_override or allow_task_sandbox_none for one workspace.
  • task.orchestration.profile.* paths are agent-mutable through the existing config tool surface (agh config set and the agh__config_* native tools). Secret-shaped paths and trust-rooted sections remain off-limits; see the config tool surface invariants in config.toml.
  • Sandbox none is rejected at validation time when allow_task_sandbox_none = false, even if a task explicitly sets sandbox.mode = "none".
  • Provider/model overrides set on the profile are rejected at validation time when allow_task_provider_override = false. The same gate applies to coordinator, worker, and review blocks.

The review-policy defaults under [task.orchestration.review] are documented with the review gate; they shape task.review_policy and the reviewer routing applied through ReviewProfile.

Authority boundary

Profiles are configuration and selection input. They never become authority on their own:

  • task_runs remains the only durable execution queue and ownership source.
  • ClaimNextRun is the only authoritative claim primitive. Profile selectors narrow it; they cannot grant a claim that lease/scope rules would deny.
  • task.Service owns task/run transitions, profile validation, terminal state, review verdicts, and continuation-run creation.
  • ParticipantPolicy constrains routing only. Channel membership, peer authorization, and tool policy are still enforced by the network, bridge, tool, and review subsystems.
  • SandboxPolicy selects a sandbox; it never bypasses approval policy, tool allowlists, provider authorization, or session authorization.
  • CoordinatorProfile.mode = "guided" keeps the daemon-managed workspace coordinator and respects max_active_per_workspace. There is no dedicated per-task coordinator in this MVP.
  • Task Runs and Leases explains the claim/lease contract that profile selectors narrow.
  • Coordinator Handoff explains coordinator bootstrap and how guided mode injects task-specific guidance.
  • Coordination Channels explains why channels carry conversation but never own task state.
  • config.toml lists every [task.orchestration] field, default, and validation rule.
  • agh task profile is the generated CLI reference for the profile commands.

On this page