You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add repository-authored recurring agent work based on the public Eve schedules model, but call the OpenBot product concept a Routine.
Tilde already supports cron-triggered agent invocations, so Tilde—not Vercel, Electron, control-service, or a process-local timer—must own production scheduling and signed delivery. OpenBot discovers and validates routine source, reconciles it through the public Tilde API, and presents execution status without duplicating the scheduler.
Terminology and supported subset
Routine is the OpenBot product, UI, API, and authored-source term.
Cron schedule is the provider-level cadence supplied to Tilde.
A routine run is an ordinary signed Tilde invocation of the selected primary agent, with routine trigger metadata.
Do not expose a second user-facing “Schedule” resource.
The first slice supports Eve's recurring prompt/task form, not its channel-handoff handler form. Eve handlers use to(channel, target) and waitUntil(...); OpenBot does not own channel adapters because Tilde owns ChatKit ingress, delivery, and history. If a future public Tilde contract supports a durable handler workflow, add it through a separate decision rather than emulating channels locally.
Routines are root-agent only. configuration/agent/subagents/<id>/routines/ is rejected; a routine invokes the primary agent, which can delegate to a subagent through #15.
The path-relative filename is the stable routine slug: routines/maintenance/cleanup.ts becomes maintenance/cleanup.
Authored contract
Support two equivalent forms:
import{defineRoutine}from"@openbot/agent-service-provider/routines";exportdefaultdefineRoutine({cron: "0 9 * * 1-5",prompt: "Review outstanding work and prepare the weekday digest.",});
---cron: "0 9 * * 1-5"---
Review outstanding work and prepare the weekday digest.
defineRoutine is a typed pass-through and accepts exactly one recurring prompt.
Cron uses a validated standard five-field expression with minute granularity and UTC semantics for the first release.
Prompt bodies are repository source and must not contain credentials, one-time links, or raw PII.
TypeScript routines are declarative. Do not execute arbitrary module code during discovery or deployment planning.
Discovery is recursive, deterministic, path-contained, and rejects duplicate/unsafe slugs, symlinks, invalid cron, empty prompts, unsupported fields, and subagent routines.
Include routine files and the normalized desired-state manifest in agent/deployment content digests.
Do not support both schedules/ and routines/ indefinitely. If an Eve-shaped schedules/ directory is found, fail with a migration message explaining OpenBot's deliberate Routine terminology and Tilde ownership.
Architecture
1. One normalized routine model
The agent-service package owns a provider-neutral RoutineDefinition containing only OpenBot domain data:
stable agent ID and routine slug;
cron expression and explicit timezone semantics;
bounded prompt content or content digest;
enabled state;
optional non-secret labels;
deterministic desired-state digest.
Markdown and TypeScript inputs normalize to the same model. Control-service, deployment planning, documentation, and tests consume that model instead of re-parsing source.
2. Tilde owns scheduling and invocation
Extend the narrow Tilde resource provisioner in #26 to reconcile each normalized routine against Tilde's public cron-job agent-invocation API using the generated client/SDK contract. Do not guess routes or handwrite fetch calls.
Tilde remains authoritative for:
cron evaluation and next-run calculation;
enabled/disabled runtime state;
signed invocation delivery;
invocation identity, retries, and run status;
creation or selection of the ChatKit session used for the run.
OpenBot stores only the source mapping, remote resource ID, last-applied digest, and non-secret status needed for planning, drift reporting, and reconciliation.
Do not generate Vercel Cron entries. Local and Vercel agent-service artifacts expose the same ordinary signed agent endpoint; Tilde invokes whichever deployed endpoint is registered for the agent.
3. Invocation contract
A routine invocation must enter the same authenticated agent path as any other Tilde run and carry validated metadata such as routine ID/slug, scheduled time, invocation ID, attempt, and trigger kind. Provider-specific wire fields stay inside the Tilde adapter.
Verify the Tilde signature before loading history, tools, prompts, or secrets.
Expose a safe runtime trigger descriptor such as transport.kind = "tilde-routine"; do not fabricate a channel.
Run the normal prompt, tools, hooks, usage accounting, cancellation, and terminal-event flow.
Record enough non-secret correlation metadata to trace one scheduled tick through invocation, agent turn, tool work, and terminal status.
4. Delivery, concurrency, and idempotency
Treat scheduler delivery as at least once unless the public Tilde contract guarantees otherwise.
Use Tilde's stable invocation ID as the turn idempotency key so a retry cannot start duplicate model work or external side effects.
Apply the registered agent's concurrency policy (queue, interrupt, or queue_and_batch) rather than inventing a second routine-specific queue.
Define misfire behavior for delayed ticks and overlapping executions. The first release should not backfill an unbounded number of missed runs.
A changed cron/prompt updates the existing remote routine by stable ownership identity instead of creating a duplicate.
Deletion is ownership-safe and explicit; retain remote jobs not provably owned by the installation.
5. Sessions and output
Default each routine run to a new Tilde ChatKit session so independent runs do not accumulate unbounded conversational history. Preserve stable routine and invocation metadata for cross-run audit and memory lookup.
The routine is fire-and-forget from the owner's perspective, but its output remains a canonical Tilde run result and can use tools, update memory, write to the Computer, or explicitly send messages through Tilde-provided tools. It cannot park waiting for a human, CAPTCHA, OAuth, WebAuthn, or another interactive handoff in the first slice; those cases should fail with a clear status and link to #21 where applicable.
Do not silently post every routine result into an arbitrary chat channel. Delivery to an owner or external system must be an explicit tool/action available to the agent.
6. Owner experience and operations
Add an owner-facing Routines view backed by control-service/Tilde status APIs:
routine name, agent, normalized cadence, and UTC indication;
enabled/reconciled/drifted/error state;
next scheduled run and last terminal run;
redacted error summary and correlation ID;
explicit Run now for testing, using an authenticated Tilde invocation rather than a local dev-only route.
Repository source remains authoritative for cadence, prompt, and enabled state. The first UI is inspect/run-now only; editing or pausing should update source through the code-forge workflow in #14 rather than creating silent remote drift.
7. Local development
Provide a CLI command such as openbot routine run <slug> that:
discovers and validates the same normalized routine;
requires an initialized target agent;
asks Tilde to invoke it once through the authenticated production-equivalent path;
returns session/turn correlation IDs and optionally follows terminal status.
Do not run a background cron daemon in openbot dev. This keeps local behavior deterministic and avoids double firing while Tilde is active.
Delivery slices
Record Routine terminology, Tilde scheduler ownership, root-only scope, session semantics, and the unsupported handler/channel form in ADR-0011.
Add openbot routine list, openbot routine run <slug>, and focused operator diagnostics.
Add the inspect/run-now Routines UI after the control contract is stable.
Update scaffolds, AGENTS.md, agent docs, deployment docs, and focused test skills.
Acceptance criteria
Nested .ts and .md routines normalize to deterministic slugs and the same typed model.
Invalid cron, empty prompts, unsafe paths, symlinks, unsupported handler/channel fields, schedules/, and subagent routines fail with actionable errors.
Deploy dry-run reports create/update/no-op/retain/delete without mutation or prompt/secret leakage.
Repeated deployment is idempotent and a changed definition updates one Tilde cron job rather than creating another.
No Vercel Cron or process-local scheduler is generated.
A scheduled tick reaches the signed primary-agent endpoint, runs the authored prompt, and produces one traceable terminal Tilde run.
Duplicate delivery does not create duplicate model turns or external side effects under the documented idempotency contract.
Agent concurrency, delayed/missed ticks, overlapping runs, endpoint failure, timeout, cancellation, and retry behavior have focused integration tests.
Each run uses the documented session strategy and does not silently publish output to a channel.
Hooks identify a routine trigger without receiving a fabricated channel context.
openbot routine run <slug> and the UI's Run now action exercise the same authenticated path as production scheduling.
Runtime secrets, webhook keys, raw tool output, and sensitive prompt content are absent from plan output, control state, logs, and routine status APIs.
Whether Tilde's public API exposes an immutable invocation idempotency key and explicit misfire policy, or whether OpenBot must supply them through the generated client contract.
Whether a future routine may opt into a stable session key for longitudinal work, with explicit history bounds.
Whether repository-owned enabled: false is needed in the first schema or deletion alone is sufficient.
Whether dynamic/user-created routines belong in a later control-state feature rather than this source-authored contract.
Outcome
Add repository-authored recurring agent work based on the public Eve schedules model, but call the OpenBot product concept a Routine.
Tilde already supports cron-triggered agent invocations, so Tilde—not Vercel, Electron, control-service, or a process-local timer—must own production scheduling and signed delivery. OpenBot discovers and validates routine source, reconciles it through the public Tilde API, and presents execution status without duplicating the scheduler.
Terminology and supported subset
The first slice supports Eve's recurring prompt/task form, not its channel-handoff handler form. Eve handlers use
to(channel, target)andwaitUntil(...); OpenBot does not own channel adapters because Tilde owns ChatKit ingress, delivery, and history. If a future public Tilde contract supports a durable handler workflow, add it through a separate decision rather than emulating channels locally.Target layout
After #19:
Routines are root-agent only.
configuration/agent/subagents/<id>/routines/is rejected; a routine invokes the primary agent, which can delegate to a subagent through #15.The path-relative filename is the stable routine slug:
routines/maintenance/cleanup.tsbecomesmaintenance/cleanup.Authored contract
Support two equivalent forms:
defineRoutineis a typed pass-through and accepts exactly one recurring prompt.Do not support both
schedules/androutines/indefinitely. If an Eve-shapedschedules/directory is found, fail with a migration message explaining OpenBot's deliberate Routine terminology and Tilde ownership.Architecture
1. One normalized routine model
The agent-service package owns a provider-neutral
RoutineDefinitioncontaining only OpenBot domain data:Markdown and TypeScript inputs normalize to the same model. Control-service, deployment planning, documentation, and tests consume that model instead of re-parsing source.
2. Tilde owns scheduling and invocation
Extend the narrow Tilde resource provisioner in #26 to reconcile each normalized routine against Tilde's public cron-job agent-invocation API using the generated client/SDK contract. Do not guess routes or handwrite fetch calls.
Tilde remains authoritative for:
OpenBot stores only the source mapping, remote resource ID, last-applied digest, and non-secret status needed for planning, drift reporting, and reconciliation.
Do not generate Vercel Cron entries. Local and Vercel agent-service artifacts expose the same ordinary signed agent endpoint; Tilde invokes whichever deployed endpoint is registered for the agent.
3. Invocation contract
A routine invocation must enter the same authenticated agent path as any other Tilde run and carry validated metadata such as routine ID/slug, scheduled time, invocation ID, attempt, and trigger kind. Provider-specific wire fields stay inside the Tilde adapter.
transport.kind = "tilde-routine"; do not fabricate a channel.4. Delivery, concurrency, and idempotency
queue,interrupt, orqueue_and_batch) rather than inventing a second routine-specific queue.5. Sessions and output
Default each routine run to a new Tilde ChatKit session so independent runs do not accumulate unbounded conversational history. Preserve stable routine and invocation metadata for cross-run audit and memory lookup.
The routine is fire-and-forget from the owner's perspective, but its output remains a canonical Tilde run result and can use tools, update memory, write to the Computer, or explicitly send messages through Tilde-provided tools. It cannot park waiting for a human, CAPTCHA, OAuth, WebAuthn, or another interactive handoff in the first slice; those cases should fail with a clear status and link to #21 where applicable.
Do not silently post every routine result into an arbitrary chat channel. Delivery to an owner or external system must be an explicit tool/action available to the agent.
6. Owner experience and operations
Add an owner-facing Routines view backed by control-service/Tilde status APIs:
Repository source remains authoritative for cadence, prompt, and enabled state. The first UI is inspect/run-now only; editing or pausing should update source through the code-forge workflow in #14 rather than creating silent remote drift.
7. Local development
Provide a CLI command such as
openbot routine run <slug>that:Do not run a background cron daemon in
openbot dev. This keeps local behavior deterministic and avoids double firing while Tilde is active.Delivery slices
defineRoutine, Markdown parsing, recursive discovery, normalization, validation, and content digests.openbot routine list,openbot routine run <slug>, and focused operator diagnostics.AGENTS.md, agent docs, deployment docs, and focused test skills.Acceptance criteria
.tsand.mdroutines normalize to deterministic slugs and the same typed model.schedules/, and subagent routines fail with actionable errors.openbot routine run <slug>and the UI's Run now action exercise the same authenticated path as production scheduling.Dependencies
Open decisions
enabled: falseis needed in the first schema or deletion alone is sufficient.