avelino / avelino/dotagent

Concurrency control — multiple instances of the same agent

Open
#28 0 comments 0 reactions 0 assignees View on GitHub
area: manifest area: runner type: feature
Dominant language
Rust
Stars
3
Forks
1
Avg merge
4h 50m
Merged PRs (30d)
1

Description

Today an agent runs at most once at a time per `(agent, schedule)`. That is the right default for cron-style work. But some agents are stateless processors — say, a fan-out worker that pulls from a queue — where running 4 in parallel is exactly what you want.

There is no knob to express that.

## Proposal

A new `concurrency` field on `[[schedules]]` (default 1, preserving today's behavior):

```toml
[[schedules]]
id = "worker"
type = "interval"
interval_minutes = 1
concurrency = 4 # up to 4 simultaneous instances
```

When the schedule fires and N instances are already running where N < concurrency, the daemon spawns another. If N == concurrency, the fire is skipped (logged as `concurrency_capped`, audit event emitted).

Each instance gets a unique heartbeat slug (e.g. `worker-0`, `worker-1`) so state files don't collide.

## Acceptance criteria

- [ ] `concurrency = 1` (default) preserves today's behavior bit-for-bit.
- [ ] `concurrency > 1` allows parallel instances with separate heartbeats.
- [ ] Hitting the cap emits an audit event and skips the fire (not queues).
- [ ] `dotagent status` and `dotagent why` reflect "N of M instances running".
- [ ] [`agent-spec.md`](docs/reference/agent-spec.md) updated.

## Where to start

- `crates/dotagent-core/src/manifest.rs` — schema.
- `crates/dotagent/src/commands/daemon.rs` — tick loop where the spawn decision happens.
- `crates/dotagent-state/src/lib.rs` — slug generation.

## Non-goals

- Distributed coordination across machines. Single-host only.
- Work-queue semantics. dotagent stays a scheduler, not a queue runner.

Contributor guide

Open the contributing guide

Research direction

Start by reading the schema in crates/dotagent-core/src/manifest.rs, then trace the spawn decision in crates/dotagent/src/commands/daemon.rs and slug generation in crates/dotagent-state/src/lib.rs. Done means the default remains unchanged, parallel instances have separate heartbeats, capped fires are audited and skipped, status and why show N of M, and docs/reference/agent-spec.md is updated.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.