The Router Pattern Across Domains
March 2026
The router sits between a scheduler and an executor. It decides what work should happen next, compiles the relevant context into one bounded prompt, and hands it off. The executor — agent, script, or human — simply does what the router prepared.
This separation is deliberately boring. The router doesn't execute. It doesn't have opinions about LLMs or tool interfaces. It owns one job: transform vague recurring work into specific wake-sized tasks.
The pattern emerged from agent orchestration, but the architecture transfers. A personal assistant, a project manager, a product development pipeline — all face the same problem: what should I work on next, and what do I need to know to do it?
The Core Pattern
The router's vocabulary is small:
project → lane → request → job → playbook → compiled prompt
Project — A routed unit of work. Has identity, configuration, and state. Points at an external target workspace.
Lane — A recurring category: research, maintenance, writing, interactive. Each has a cadence (interval, manual, always), a playbook, and artifacts to read.
Request — An explicit queued item. Has identity, status (pending, selected, completed), priority, and optional notes. Durable and auditable.
Job — The concrete thing selected for one wake. May come from a request, be derived from lane state, or be synthesized from a signal scan.
Playbook — Reusable instructions for how to do that kind of work. Not just a prompt fragment — defines expected inputs, outputs, and operational framing.
Compiled Prompt — The final handoff: project context, lane context, task, stopping condition, and playbook instructions in one human-readable document.
The router resolves this chain every time it's invoked:
1. Pick project (round-robin by staleness)
2. Reset stale requests (cleanup)
3. Select lane (requests > overdue > priority > alphabetical)
4. Select job within lane
5. Resolve playbook
6. Compile prompt
7. Write outputs
Crucially: the decision is inspectable. You can read latest-decision.json and see exactly why a job was chosen. You can read runs.jsonl and audit weeks of decisions.
What Makes This Work
Three properties distinguish the router from ad-hoc scheduling:
1. Bounded Prompts
Every compiled prompt includes a ## Stop When section. The task isn't "work on research" — it's "read the next two files in the reading list and update state.md with findings."
This respects budget. An agent or executor has limited turns. The router is responsible for scoping work to fit.
2. Explicit State Files
State lives in files, not hidden runtime. The state.md, hints.md, devlog.md, and lane caches are all readable, diffable, and manually editable. Recovery means "read the files and understand where we are."
3. Scan-Derived Requests
The scan command reads project state files, detects actionable signals, and enqueues requests. "Active investigation status: ready to publish" becomes a request automatically. This closes the loop: the executor updates state, and the router surfaces the next step.
Domain Applications
Personal Assistant
The problem: An inbox, a todo list, a calendar, and reminders all compete for attention. The assistant must prioritize, but also respect user intent, time of day, and relationships between items.
The router fit: Define each input as a lane:
| Lane | Cadence | Artifacts | Scan Pattern |
|---|---|---|---|
| inbox | interval | inbox/state.md | emails older than 2 days → "Review stale email" |
| todos | manual | todos/state.md | status: ready items → "Complete ready todo" |
| reminders | always | reminders/state.md | items with due: in next 24h → high priority |
| calendar | interval | calendar/state.md | events in next 3 days → "Prepare for upcoming events" |
Playbooks:
inbox-triage— read subject lines, decide defer/delete/respond, update statetodo-complete— read item, execute, mark donereminder-notify— surface reminder with context
Key insight: The router solves priority resolution. "What should I do next?" becomes "requests > overdue lanes > priority." The assistant stops thrashing.
Project Management
The problem: A project has issues, milestones, reviews, and maintenance. Some are urgent, some can wait. Work must be visible and recoverable.
The router fit: Define lanes per workflow:
| Lane | Cadence | Artifacts | Scan Pattern |
|---|---|---|---|
| triage | always | issues/state.md | new issues → "Triage new issue" |
| milestones | manual | milestones/state.md | milestones with approaching deadlines |
| review | interval | reviews/state.md | PRs awaiting review |
| maintenance | interval | maintenance/state.md | stale dependencies, scheduled cleanup |
Key insight: The router provides auditable decision history. Every routing decision is logged. "Why did we work on that?" has an answer.
Product Development
The problem: A product backlog, an interactive pipeline, and a roadmap compete for development attention. Product leaders need visibility into what's being worked on.
| Lane | Cadence | Artifacts | Scan Pattern |
|---|---|---|---|
| features | manual | features/state.md | features with status: ready |
| interactive | interval | interactive/state.md | active interactive piece → "Advance interactive piece" |
| roadmap | interval | roadmap/state.md | upcoming themes → review |
| feedback | interval | feedback/state.md | untriaged feedback |
Key insight: The router surfaces stale work. An interactive piece that hasn't advanced in a week? That's visible as an overdue lane.
Content Studio
The problem: An editorial calendar, draft pipeline, review queue, and publication schedule. Content is time-sensitive. Deadlines matter.
| Lane | Cadence | Artifacts | Scan Pattern |
|---|---|---|---|
| draft | manual | drafts/state.md | status: ready drafts → "Publish ready draft" |
| review | interval | review/state.md | drafts awaiting feedback |
| editorial | interval | calendar/state.md | upcoming deadlines |
| distribution | manual | distribution/state.md | published content awaiting promotion |
Key insight: Content work is often phase-based. The router tracks phases explicitly in state files. Scan patterns detect phase transitions.
Research Labs
The problem: Investigations are long-running, findings accumulate, writing is deferred. Labs need to track "what are we investigating?" across multiple parallel threads.
| Lane | Cadence | Artifacts | Scan Pattern |
|---|---|---|---|
| investigation | manual | research/state.md | investigations with complete findings |
| writing | manual | writing/state.md | investigations ready to write up |
| review | interval | review/state.md | peer review queue |
| grants | interval | grants/state.md | approaching deadlines |
Key insight: Research has inherently long work items. The router's job is to break them into wake-sized pieces and track progress.
What Transfers
The pattern works because it separates concerns:
The router owns:
- Priority resolution (what should happen next)
- Context compilation (what the executor needs to know)
- State continuity (where we are, what's next)
- Audit logging (why we did what we did)
The executor owns:
- Execution (doing the work)
- Tool interfaces (talking to systems)
- Error handling (what to do when things break)
The scheduler owns:
- Timing (when to wake)
- Retry policies (what to do on failure)
- Invocation (calling the router)
This separation works across domains because every domain has the same coordination problem. Project managers ask "what should I work on?" Personal assistants ask "what should I surface?" Content editors ask "what should we publish?"
The router answers the same question in each case.
What Adapts
The router's core logic is domain-agnostic. What changes across domains:
Scan Patterns — Each domain has its own signals. A writing lane detects status: ready; an inbox lane detects age > 2 days. The scan function is domain-specific — the scan command is generic.
Playbooks — Each domain defines its own operational framing. A content studio's draft-advance playbook looks different from a research lab's investigation-advance. The concept is reusable; the concrete text is custom.
Artifacts — What the router reads depends on the domain. A project manager reads issues/state.md; a personal assistant reads inbox/state.md. The artifact resolution system is generic; the paths are configured.
Profiles — A generic profile seeds sensible defaults. A website profile seeds writing and maintenance lanes. A research profile seeds investigation and writing lanes. The profile system is the extension point for domain-specific scaffolding.
Evolution Opportunities
Weighted Selection — Currently, the router uses deterministic priority: requests > overdue > alphabetical. Weighted scoring would allow lanes to "heat up" based on time since last completion or importance metrics.
Dependency Graphs — Jobs could declare dependencies. "Run interactive piece" depends on "draft interactive spec." The router would traverse the graph instead of selecting independently.
Multi-Router Coordination — Multiple router instances (personal, work, project-specific) could share a global priority layer. "What should I work on across all contexts?"
Outcome-Aware Priority — Currently, complete records outcome but doesn't affect future selection. A job that fails repeatedly could be demoted. A job that succeeds could boost similar future work.
Agent Integration — Rather than shell invocation, the router could expose a tool interface. The agent calls router_next and receives the compiled prompt directly. This closes the loop without intermediary scripts.
Conclusion
The router pattern externalizes coordination. Instead of embedding "what should I do next?" inside the executor, it becomes a first-class system. An agent or human receives a bounded prompt and executes. A scheduler invokes at intervals. The router decides.
This works for agents. It also works for project managers, personal assistants, editorial calendars, and research labs. Any domain with recurring work, competing priorities, and state continuity benefits from the same architecture.
The key insight: files are enough. State in readable text, decisions in append-only logs, prompts as human-readable markdown. No hidden runtime state, no opaque databases. The router is debuggable because everything is inspectable.
If you're building something that needs to decide "what next" across multiple recurring workstreams, consider whether a router-shaped system would fit. The pattern is simple, the implementation is lightweight, and the separation of concerns pays dividends in observability and recovery.