DuoDuo docs

Install, use, and operate DuoDuo.

These docs cover durable files, event ordering, sessions, the scheduled subconscious, the intuition layer, and host operations.

Pick up conversations, switch models, and schedule work.

Use

Loops & Jobs

Ask DuoDuo to check again later—and report back.

Tell /loop what you want checked later. DuoDuo turns the request into a scheduled job, keeps your current conversation free, and brings each useful result back.

DuoDuo pulls a teal cord attached to a low lever on a large clock.

Plan before spending#

/loop check the staging deploy and tell me when something breaks

Before creating the job, DuoDuo proposes a plan with:

  • the cadence or wake strategy
  • the runtime and model
  • what gets delivered and where
  • the stop condition

Read the plan before you confirm it: this is where you decide what will run, how often it can spend a model turn, and when it should stop. You can explicitly ask DuoDuo to skip confirmation when the plan is already clear.

Three useful shapes#

Fixed cadence#

Use for digests, sweeps, and checks that should run on a stable calendar.

Delays and intervals accept composite durations—2h30m, 1d6h4m. An invalid cron string or a malformed duration is rejected when the job is created, rather than accepted and never fired.

Self-paced mission#

Use for “watch until done.” The job decides when to check again, can slow down when nothing is happening, and ends itself when the goal is complete.

A self-continuing loop judges progress by whether the gap it named actually closed, and stops when the work meets that bar—not when it runs out of turns.

Long-term tracker#

Use this when the answer should improve over weeks or months. One job keeps the thread while short-lived helpers can handle heavier research or analysis.

Manage a loop#

Talk to DuoDuo in plain language:

  • “show me my loops”
  • “stop staging-watch”
  • “make the release tracker daily instead”
  • “wake the market tracker back up”

Listing, reading, stopping, and interrupting a loop are also commands you can run yourself on the host:

duoduo job list
duoduo job read <id>
duoduo job archive <id>
duoduo job interrupt <id> -r "<reason>"
duoduo job reschedule <id> "@in 30m"
  • archive takes a loop off the schedule and moves its files out of the active set; a run already under way finishes. Nothing is deleted, so a stopped loop is still there to read.
  • interrupt ends the run in progress. The reason you give opens the loop's next run, so it learns why it was cut off instead of guessing.
  • reschedule adds one extra fire and leaves the cadence alone—the verb for “look once more tonight”, not for re-pacing.

Ending or re-timing a loop is an operator action, so it lives on the CLI. An agent can still create, list, and read jobs.

When a loop reports back#

A finished run's receipt reaches you as context on your next turn in the conversation that owns the loop; it does not start a turn of its own. A daemon restart delivers nothing by itself, so a loop never promises a follow-up it cannot keep.

Book one more turn#

A conversation can book its own next turn: DuoDuo sets a reminder that wakes this same session at a future time, with no job to name and no target to address. In a job session, it is one more fire of that job's own schedule. A pending reminder shows in the dashboard's job list with its owner, when it fires, and what it says; duoduo job archive <id> cancels it.

Give a job its own tool surface#

A job's frontmatter can configure the session it runs in, so a scheduled sweep is not stuck with the defaults of a live conversation:

prompt_mode: ...
allowedTools: [...]
disallowedTools: [...]
additionalDirectories: [...]
claude:
  tools: [...]

Host-wide defaults for all jobs live in kernel/config/job.md.

Cost rule#

Every scheduled wake can spend a real model turn. Match the cadence and model to the value of the check. If nothing needs judgment until new data arrives, let a script detect the change and wake DuoDuo only then.