# CompanyOS Tasks run on sandboxed Claude and Codex agents pinned to one commit

> Agno CompanyOS can now accept a Task for a sandboxed `ClaudeAgent` or `CodexAgent`. The first successful run records the repository commit in `metadata.checkout`, and every later attempt reuses that session and commit.

- Published: 2026-10-19
- Author: Ashpreet Bedi
- Categories: Changelog
- Canonical: https://www.agno.com/blog/companyos-tasks-run-on-sandboxed-claude-and-codex-agents-pinned-to-one-commit
- Markdown: https://www.agno.com/blog/companyos-tasks-run-on-sandboxed-claude-and-codex-agents-pinned-to-one-commit.md

Agno's [CompanyOS](https://www.agno.com/blog/introducing-companyos) now accepts a Task for a `ClaudeAgent` or `CodexAgent` that has a `sandbox` and a `repository`, and the Task response reports `sandboxed: true`. The Product needs a git Source for the same repository, and the first successful run writes the exact commit it worked on to `metadata.checkout`.

Later attempts reuse that session and send the pinned commit back to the sandbox. A run that reports any other commit fails the attempt, and the Task stays In progress with the error. A pinned Task can only move to another sandboxed executor. The inert `engineering` executor type is gone.

There was no model key or Docker for this check, so we used the release's own test doubles. `FixtureAgent`, Agno's credential-free harness double, stood in for `ClaudeAgent` and `CodexAgent` with a `DockerSandbox` that never started. A scripted run output stood in for the harness turn, the queue ran on an embedded Postgres with fakeredis coordination, and the routes ran for real. Real output:

```text
accept without git Source: 409 Sandboxed executor requires a Product git Source matching repository URL https://github.com/octocat/Hello-World
accept engineer: 200 sandboxed = True status = ready
POST runs attempt 1: 202 {'status': 'PENDING'}
after attempt 1: in_review | result: COMPLETED README says: Hello World!
metadata.checkout: {"source_id": "1a7d572e-ab93-45b5-a5b7-afa269d9cc1e", "url": "https://github.com/octocat/Hello-World", "branch": "master", "commit": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
POST runs attempt 2 (revision): 202
after attempt 2 on another commit: in_progress | result: ERROR Sandboxed run repository pin does not match the Task checkout
same session: True
reassign pinned Task to plain agent: 409 Task checkout is already pinned and requires a sandboxed executor; create a new Task
```

Each Task also keeps one session owner across attempts, `task.user_id`. Company checks the run permission of whoever presses start, then runs the attempt in the owner's session and records the starter as `started_by`. With the release's `09_task_session_ownership.py` cookbook, Alice started a local workflow Task and Bob asked for the revision:

```text
Bob requests attempt 2: 202
same session: True | task.user_id: alice
started_by: ['alice', 'bob']
run owners: ['alice', 'alice']
```

Recovery after a restart reconciles existing reservations before it checks the current Routine policy, and it never queues new work. Repeated automatic dispatch failures for the same Task and reason now share one failed history row, with a count in `/company/attention` under `automation_failures`. Refresh deletes completed automation history after `CompanyConfig.automation_history_retention_days`, 30 days by default.

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/05_agent_os/30_company/09_sandboxed_engineers.py), and learn more about [sandboxes and checkpoints](https://docs.agno.com/agent-platform/production#sandboxes-and-checkpoints) in the documentation.
