# CompanyOS Routines read a Product's Sources and file evidence-backed Tasks

> Agno CompanyOS adds Sources and Routines to each Product. Declare them with `Product(sources=[...], routines=[...])`, and a scheduled or on-demand Routine reads those Sources and files Backlog Tasks backed by verified evidence.

- Published: 2026-10-19
- Author: Ashpreet Bedi
- Categories: Changelog
- Canonical: https://www.agno.com/blog/companyos-routines-read-a-products-sources-and-file-evidence-backed-tasks
- Markdown: https://www.agno.com/blog/companyos-routines-read-a-products-sources-and-file-evidence-backed-tasks.md

Agno's [CompanyOS](https://www.agno.com/blog/introducing-companyos) Products now take `sources` and `routines`, and each `Routine` you declare becomes an ordinary AgentOS schedule that `/company/routines` lists, edits, pauses and triggers. A Routine runs on its cron, or only when someone triggers it if you leave the cron out.

![Diagram of a CompanyOS Routine. A Source returns a link and content hash, a Routine runs a template or custom instructions, Intake verifies the evidence, a Backlog Task waits in a Project, and a person or an auto_accept policy moves it to Ready](https://www.agno.com/images/v3-1-5-company-routines.png)

A Source is a git repository, a markdown file or folder, or a single website page. Readers return a file index first, then one document at a time with a link and a SHA-256 hash of its content. The executor picks the evidence worth acting on and hands Intake a title, a brief and a stable `proposal_key`. Intake rereads those links, refuses changed content and keeps one Task per key, so the next scan of the same issue returns the Task it already filed. Agents can also save website Sources they discover through `add_company_source`, stamped with their agent and run ids.

Each Routine runs either a packaged template or your own `instructions`. `intake` proposes Tasks, `refresh` proposes Project completion and archives Done or Cancelled work older than `metadata.archive_window_days`, and `summary` writes `summary.md` and sends it to an interface such as Slack.

We declared a Documentation Product with a markdown Source, a weekday `intake` Routine and a custom `watch` Routine with no cron. A real Routine run would let an agent read the Source and call Intake. No model key was available, so the script made those calls through `CompanyManager` directly, as the release's `07_heartbeat.py` cookbook does. Real output:

```text
docs.intake  scheduled  cron=0 9 * * 1-5  template=intake  managed_by=company
docs.watch   on_demand  cron=None         template=None    managed_by=company
first scan:  'Document the new API' -> backlog
stale hash:  Proposal evidence changed; read the Source again before proposing work
repeat scan: same Task True, Tasks in Product 1
Product metadata: {'archive_window_days': 14, 'routine_ids': 2}
```

Routine Tasks wait in Backlog until a person accepts them, or until an `auto_accept` policy on the Routine does. The policy names one executor, must carry `limits.expires_at`, accepts one distinct Task by default and always runs at least one server-side check, such as `project_active`, `has_source_evidence` or `executor_registered`. With `scheduler=True`, a managed `Company automation` schedule checks every minute for Ready Tasks and authorized proposals. In the release's `06_execute_tasks.py` cookbook, run against an embedded Postgres queue, that tick accepted an Intake proposal with the reason "Authorized Routine proposal" and ran it to In review.

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/05_agent_os/30_company/07_heartbeat.py), and learn more about [recurring Routines](https://docs.agno.com/agent-platform/improve-agent#schedule-recurring-improvements) in the documentation.
