Senses and muscles: resident pi session, wake queue, telegram, ZAI tools.
One resident AgentSession per process; never replace it per wake.
Subscriptions stay bound; session history persists on the agent volume.
The deterministic runtime owns transport: telegram cursors, dedup,
authorization, at-least-once outbox, deterministic /hide. The model never
manages cursors.
Wake policy: failure > chat FIFO > one coalesced heartbeat; chat never
steers an active turn; heartbeat at most once per UTC hour, no backfill.
Every agent event hits the durable spool before side effects; the spool
drains idempotently into the service.
Curated ZAI tools only: stable will-owned names and schemas, no dynamic MCP
passthrough; MCP packages stay lockfile-pinned (no npx @latest).
Budget: externally configured daily cap plus a small recovery reserve;
model failures get three attempts, then the wake defers.
The worktree is the editing source; operational resources load from the
immutable image (WILL_RESOURCE_DIR), never from the worktree.
Testing: the wake engine, queue, spool, telegram runtime, and ZAI tools are
pi-free and tested with fakes (engine.test.ts, *.int.test.ts). Real
pi-session behavior is smoke-gated behind WILL_PI_SMOKE=1.
# AGENTS.md — src/agent
Senses and muscles: resident pi session, wake queue, telegram, ZAI tools.
- One resident `AgentSession` per process; never replace it per wake.
Subscriptions stay bound; session history persists on the agent volume.
- The deterministic runtime owns transport: telegram cursors, dedup,
authorization, at-least-once outbox, deterministic `/hide`. The model never
manages cursors.
- Wake policy: failure > chat FIFO > one coalesced heartbeat; chat never
steers an active turn; heartbeat at most once per UTC hour, no backfill.
- Every agent event hits the durable spool before side effects; the spool
drains idempotently into the service.
- Curated ZAI tools only: stable will-owned names and schemas, no dynamic MCP
passthrough; MCP packages stay lockfile-pinned (no `npx @latest`).
- Budget: externally configured daily cap plus a small recovery reserve;
model failures get three attempts, then the wake defers.
- The worktree is the editing source; operational resources load from the
immutable image (`WILL_RESOURCE_DIR`), never from the worktree.
- Testing: the wake engine, queue, spool, telegram runtime, and ZAI tools are
pi-free and tested with fakes (`engine.test.ts`, `*.int.test.ts`). Real
pi-session behavior is smoke-gated behind `WILL_PI_SMOKE=1`.