Morning Routine¶
Configurable morning routine that coordinates journal, tasks, contracts, calendar, and metacognition into a single briefing-first flow. Collect everything, then synthesize and act.
Workflow name: morning-routine
Execution: main
Steps¶
| # | ID | Name | Type | Depends on |
|---|---|---|---|---|
| 1 | load-config |
Load morning config | code |
|
| 2 | resolve-phases |
Resolve enabled phases | code |
load-config |
| 3 | context-snapshot |
Collect fresh context snapshot | code |
resolve-phases |
| 4 | sign-in |
Morning sign-in conversation | reasoning |
context-snapshot |
| 5 | yesterday-close |
Close out yesterday's journal | reasoning |
context-snapshot |
| 6 | calendar-today |
Fetch today's calendar schedule | code |
context-snapshot |
| 7 | task-briefing |
Get task status summary | code |
context-snapshot |
| 8 | contract-check |
Check contract health and constraints | code |
context-snapshot |
| 9 | blindspot-scan |
Scan yesterday's work for blindspot patterns | reasoning |
context-snapshot |
| 10 | synthesize |
Synthesize morning briefing | reasoning |
sign-in, yesterday-close, calendar-today, task-briefing, contract-check, blindspot-scan |
| 11 | propose-mits |
Propose MITs, review with user, and create tasks | reasoning |
synthesize |
| 12 | persist-briefing |
Write morning briefing to journal | reasoning |
propose-mits |
| 13 | day-planner |
Generate Day Planner schedule | reasoning |
propose-mits, calendar-today |
Step instructions¶
context-snapshot¶
Purpose: Gather fresh context from all tracked systems. This is always the first step — everything downstream depends on it.
Phase gate: Always enabled (core). No skip check needed.
Procedure:
-
Ensure today's journal exists. Call
mcp__work-buddy__wb_run("journal_state", {"target": "today"})— if the result showsexists: false, the journal needs creating via Obsidian. -
Get the configured lookback window:
hours = step_results["load-config"].get("morning", {}).get("context_hours", 24)(default: 24). -
Run the context bundle collector:
`mcp__work-buddy__wb_run("context_bundle", {"hours": <hours>})` -
Read the resulting pack files from the bundle path returned in the result. Priority files:
git_summary.md,tasks_summary.md,projects_summary.md,obsidian_summary.md,messages_summary.md,chat_summary.md,calendar_summary.md,wellness_summary.md. -
Condense into a structured activity digest — not the raw pack, but a ~20 line summary of: what repos had activity, what journal entries exist, outstanding tasks, recent conversations, messages.
Result: Condensed activity digest string.
sign-in¶
Purpose: Brief morning check-in that fills the journal Sign-In fields. Always enabled.
Agentic step. The agent conducts a conversational check-in and writes responses to the journal. Behavioral instructions (conversation tone, what to ask, how to use wellness data) are in the slash command, not here.
Procedure:
-
Read current sign-in state and wellness trends:
Returns`mcp__work-buddy__wb_run("journal_sign_in")`{sign_in: {sleep, energy, mood, check_in, motto, all_filled}, wellness: "..."}. -
If
sign_in.all_filled: Return{"summary": "Sign-in already complete. Sleep: X, Energy: X, Mood: X", "wellness_context": wellness}. -
If NOT all filled: Conduct check-in conversation for missing fields.
-
Write responses to the journal:
This is consent-gated — on`mcp__work-buddy__wb_run("journal_sign_in", {"write_fields": "{\"sleep\": 7, \"energy\": 8, \"mood\": 7, \"check_in\": \"...\", \"motto\": \"...\"}"})`consent_requiredresponse, follow the standard consent flow. -
Return
{"summary": "...", "wellness_context": wellness}for downstream steps.
Result: Sign-in summary with wellness context.
yesterday-close¶
Purpose: Close out yesterday's journal by filling Log gaps.
Agentic step. The agent checks yesterday's journal and auto-fills gaps. Behavioral instructions (interaction rules) are in the slash command, not here.
Phase gate: Check step_results["resolve-phases"]["yesterday-close"]. If false, skip.
Procedure:
-
Read yesterday's journal state:
`mcp__work-buddy__wb_run("journal_state", {"target": "yesterday"})` -
If
error: Log the error and skip:{"skipped": true, "reason": error}. -
If
ambiguous: Log a warning and skip. -
If NOT
exists: Return{"skipped": true, "reason": "no journal for {date}"}. -
If
exists: Check the journal content. If the Log section has 3+ entries, return{"summary": "Yesterday ({date}) has N log entries. Last: HH:MM AM/PM."}. -
If the Log is sparse (< 3 entries): Delegate to
update-journalworkflow:mcp__work-buddy__wb_run("update-journal", {"target": "yesterday"})and advance to completion. Return the summary.
Result: Brief summary string describing yesterday's state.
calendar-today¶
Purpose: Fetch today's Google Calendar schedule.
Phase gate: Check step_results["resolve-phases"]["calendar-today"]. If false, skip.
Procedure:
-
Fetch today's calendar (includes readiness check):
`mcp__work-buddy__wb_run("context_calendar")` -
If the result indicates unavailability, return
{"available": false, "reason": "Calendar not available"}. Do NOT fail — graceful degradation. -
Otherwise return the calendar data.
Result: Calendar data or unavailability notice.
task-briefing¶
Purpose: Get current task status.
Phase gate: Check step_results["resolve-phases"]["task-briefing"]. If false, skip.
Procedure:
`mcp__work-buddy__wb_run("task_briefing")`
Result: Task briefing data dict.
contract-check¶
Purpose: Check contract health, active constraints, and deadlines.
Phase gate: Check step_results["resolve-phases"]["contract-check"]. If false, skip.
Procedure:
mcp__work-buddy__wb_run("contract_constraints")— active contracts with bottleneck constraints.mcp__work-buddy__wb_run("contract_health")— health check report.- Combine into a single result dict with
active_count,constraints,health,top_constraint,has_paper_contract. - If no active contracts exist, note it explicitly.
Result: Combined contract data dict.
blindspot-scan¶
Purpose: Check yesterday's work against metacognition patterns.
Phase gate: Check step_results["resolve-phases"]["blindspot-scan"]. If false, skip.
Procedure depends on step_results["load-config"]["morning"]["blindspot_depth"]:
Light mode (default)¶
Agentic step. The agent scans for HIGH-severity patterns using context-snapshot and yesterday-close data. Behavioral instructions (pattern list, what to look for) are in the slash command, not here.
Return a brief summary: either "None detected" or a list of pattern names with one-line evidence.
Full mode¶
Delegate to the detect-blindspots workflow: mcp__work-buddy__wb_run("detect-blindspots"). Return the full result.
Result: Pattern summary string or full blindspot report.
synthesize¶
Purpose: Combine all collected data into a concise morning briefing.
Agentic step. The agent builds a briefing from all prior step results and presents it. Behavioral instructions (tone, synthesis rules, follow-up offers, presentation style) are in the slash command, not here.
Procedure:
-
Read each prior step from
step_results.<step_id>:sign-in,yesterday-close,calendar-today,task-briefing,contract-check,blindspot-scan. For skipped/failed steps the entry will beNoneor{"skipped": true}— handle gracefully. -
Synthesize a briefing from those step results. The briefing covers: yesterday summary, calendar, tasks, contracts, projects, blindspots. Tone and format rules are in the slash command.
-
Present the briefing and offer follow-ups.
-
Return
{"briefing_md": briefing_md}only. Downstream steps read the underlying data directly fromstep_results.<upstream_id>— do not echo the upstream results back under aresultsbundle, that just round-trips data already in the response.
Result: Briefing markdown.
propose-mits¶
Purpose: Propose today's Most Important Tasks, present for user review, create tasks, and set them to focused state.
Phase gate: None -- always runs.
Procedure:
-
Using
step_results["synthesize"]["briefing_md"]for the briefing narrative and reading underlying data directly from each upstream step'sstep_resultsentry (step_results["task-briefing"],step_results["contract-check"],step_results["blindspot-scan"],step_results["yesterday-close"]), propose up tostep_results["load-config"]["morning"]["max_mits"]MITs. Behavioral instructions (MIT quality rules, user review, presentation) are in the slash command, not here. -
Present the proposed MITs to the user for review. Wait for confirmation or adjustments.
-
Complete any old MITs. If the task briefing shows previously-focused MITs that are now done, mark them complete:
`mcp__work-buddy__wb_run("task_toggle", {"task_id": "<id>", "done": true})` -
Create MIT tasks in the master task list. Include
#tasker/state/focusedin the task_text (interim workaround for Dataview visibility -- see t-abe6ea4b):Then also set each created task to focused via the state API:`mcp__work-buddy__wb_run("task_create", {"task_text": "MIT: <task text> #tasker/state/focused", "urgency": "high", "project": "...", "due_date": "...", "contract": "..."})``mcp__work-buddy__wb_run("task_change_state", {"task_id": "<id>", "state": "focused"})`
Result: {"mits_created": [{"id": "t-...", "text": "...", "due": "..."}], "old_mits_completed": ["t-..."]}
persist-briefing¶
Purpose: Write the morning briefing to the journal. Consent-gated.
Phase gate: Check step_results["load-config"]["morning"]["persist_briefing"]. If false, return {"persisted": false, "reason": "disabled by config"}.
Procedure:
-
Compose the briefing markdown from
step_results["synthesize"]["briefing_md"], incorporating the MIT list fromstep_results["propose-mits"]["mits_created"]. -
Placement: The briefing callout goes in the Sign-In section, after the Motto field and before
# **Tasks & Objectives**. Thejournal_writecapability handles placement automatically. The callout header includes the generation timestamp.This is consent-gated -- on`mcp__work-buddy__wb_run("journal_write", {"mode": "briefing", "briefing_md": "<briefing markdown>"})`consent_requiredresponse, follow the standard consent flow.
Result: {"persisted": true, "path": "..."} or {"persisted": false, "reason": "..."}
day-planner¶
Purpose: Check Day Planner plugin readiness, generate a schedule from calendar events and focused tasks, and write to journal.
Phase gate: Check step_results["load-config"]["morning"]["day_planner"]["enabled"]. If false, return {"generated": false, "skipped_reason": "disabled by config"}.
Procedure -- follow ALL five sub-steps in order:
Sub-step 1 -- Status check:
status = `mcp__work-buddy__wb_run("day_planner", {"action": "status"})`
{"generated": false, "skipped_reason": "plugin not ready: <reason>"}.
Sub-step 2 -- Read existing plan:
existing = `mcp__work-buddy__wb_run("day_planner", {"action": "read"})`
entry_count > 0, return {"generated": false, "skipped_reason": "user already has a plan with N entries"}. Do not clobber user edits.
Sub-step 3 -- Gather inputs:
- Calendar events: Build from
step_results["calendar-today"]. The rawcontext_calendarresult is a pre-formatted markdown string, not a structured list — you must extract events from it and pass them in one of the accepted shapes below. If calendar was skipped/unavailable, use[].
Accepted shapes (see day_planner capability docstring for full spec):
- Flat (easier when constructing by hand):
[{"start": "13:00", "end": "13:30", "summary": "Team sync"}]
start/end accept "HH:MM" or ISO datetime. Label key may be summary, description, or text. Set past: true to exclude.
- Google Calendar API (raw from Calendar API):
[{"start": {"dateTime": "2026-04-16T13:00:00-04:00"}, "end": {"dateTime": "2026-04-16T13:30:00-04:00"}, "summary": "...", "timeStatus": "future"}]
- Focused tasks: MITs from
step_results["propose-mits"]["mits_created"]plus any pre-existing focused tasks fromstep_results["task-briefing"]. Each task accepts: descriptionortext(required): task labelduration(optional, int minutes): overrides config defaulttime_start(optional,"HH:MM"): pin task to a specific start time; conflicts fall to unscheduled
Example:
[{"description": "MIT 1: Ship LLM-judge eval", "duration": 90},
{"description": "MIT 2: Draft paper contract", "duration": 30, "time_start": "14:00"}]
-
Calendar duplication guard: If
hasRemoteCalendarsistruein the status from sub-step 1, setinclude_calendar_events: falsein config overrides to avoid duplication. -
Past-time protection:
clamp_to_nowistrueby default — unpinned tasks will not be placed before the current local time. Pinned tasks (time_start) bypass this clamp; pin intentionally for retrospective blocks.
Sub-step 4 -- Generate and write:
`mcp__work-buddy__wb_run("day_planner", {"action": "generate_and_write", "calendar_events": "<json>", "focused_tasks": "<json>"})`
Sub-step 5 -- Present summary: Show the user a brief summary of the generated timed blocks for the day.
Result: {"generated": true, "entries": [...]} or {"generated": false, "skipped_reason": "..."}