aboutsummaryrefslogtreecommitdiff
path: root/.ai/workflows/daily-prep.org
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-06 21:59:52 -0500
committerCraig Jennings <c@cjennings.net>2026-05-06 21:59:52 -0500
commitd81b23ad6b6e437dfe3c338a00a4be39bc555146 (patch)
tree2d4b0d7890fd1fc70d81282b81fed2808c28a106 /.ai/workflows/daily-prep.org
parent201377f57430ef28d02e703a2191434bbee55c75 (diff)
downloadrulesets-d81b23ad6b6e437dfe3c338a00a4be39bc555146.tar.gz
rulesets-d81b23ad6b6e437dfe3c338a00a4be39bc555146.zip
chore(ai): initialize project notes and Claude tooling surfaces
Replace the seed notes.org with project-specific context (layout, install modes, task tracker location, recent inflection point). Bring in the synced template surfaces (protocols, workflows, scripts, references, retrospectives, someday-maybe) as tracked content for this content/documentation project.
Diffstat (limited to '.ai/workflows/daily-prep.org')
-rw-r--r--.ai/workflows/daily-prep.org767
1 files changed, 767 insertions, 0 deletions
diff --git a/.ai/workflows/daily-prep.org b/.ai/workflows/daily-prep.org
new file mode 100644
index 0000000..1d5da0f
--- /dev/null
+++ b/.ai/workflows/daily-prep.org
@@ -0,0 +1,767 @@
+#+TITLE: Daily Prep Workflow
+#+AUTHOR: Craig Jennings & Claude
+#+DATE: 2026-02-23
+
+* Overview
+
+This workflow prepares Craig for the next workday by reviewing scheduled meetings, identifying priorities, and blocking time on the calendar. It ensures Craig walks into every meeting prepared and has a plan for the day's focused work.
+
+This is typically run the evening before or morning of the workday in question.
+
+* Problem We're Solving
+
+Without daily prep, Craig risks:
+- Walking into meetings without the right context loaded
+- Missing opportunities to drive key decisions or raise important points
+- Losing track of action items owed to or from specific people
+- Not having focused work time protected on the calendar
+- Reactive instead of proactive days
+
+*Impact:* Unprepared meetings waste everyone's time. Unplanned days let urgent displace important.
+
+* Exit Criteria
+
+- All meetings for the day are reviewed with prep notes
+- 1:1 meetings have talking points drawn from todo.org and session history
+- Day's priorities are identified and confirmed by Craig
+- Time blocks are placed on the calendar for focused work
+- Any quick tasks (< 5 min) are done during prep itself
+- Craig feels ready for the day
+
+* When to Use This Workflow
+
+- When Craig says "let's prep for tomorrow" or "daily prep" or similar
+- During evening wrap-up if there are meetings the next day
+- Morning of a workday before meetings start
+- When Craig asks for the standup brief alone ("what's my standup report", "let's do the daily standup report", "give me the standup brief") — see Standup-only mode below
+
+* Modes
+
+The workflow runs in one of two modes based on the trigger phrase. Pick the mode at workflow start. Don't switch mid-run.
+
+** Full-prep mode (default)
+
+Trigger: "let's prep for tomorrow", "daily prep", or any general prep-cycle phrase.
+
+Runs Phase A → Phases 1-5 → Phase 6 (only if a standup is on the calendar) → Phase 7 → Phase 8 → Phase 9.
+
+** Standup-only mode
+
+Trigger: "what's my standup report", "let's do the daily standup report", "give me the standup brief", or similar standup-specific phrasing.
+
+Runs *only* a slim Phase A + Phase 6 + a conditional Phase 8 + Phase 9. Skip Phases 1-5 and Phase 7 entirely.
+
+*** Slim Phase A (standup-only)
+
+Fetch only what Phase 6 needs:
+
+1. =todo.org= — for WAITING items (blockers) and DONE-since-cutoff (completed work).
+2. Previous prep doc — anchor for the lookback (check =inbox/= then =daily-prep/=, take most recent).
+3. Most recent =.ai/sessions/= summary — for the "what did I do" question.
+
+Skip the calendar fetches, the Proton grep, and the [#A]/[#B] todo pull. Phase 6 Step 1's sweep handles the rest.
+
+*** Where the brief lands
+
+- If a prep doc for today already exists at =inbox/YYYY-MM-DD-daily-prep.org=, append or replace its =* Standup Brief= section.
+- If no prep doc for today exists, create =inbox/YYYY-MM-DD-daily-prep.org= with only the =* Standup Brief= section populated. Full prep can be added later by re-running in full-prep mode.
+
+*** Phase 8 in standup-only mode
+
+Only run if a stale prep doc exists in =inbox/= that's older than yesterday. Otherwise skip — there's nothing to archive.
+
+Use standup-only mode when Craig wants the brief fast (e.g., right before standup) without rebuilding the day's plan.
+
+* Prep Doc Structure
+
+The prep doc has a fixed set of top-level sections. Don't invent new ones. If substantive content surfaces that doesn't fit one of these headings, mention it in chat after the workflow finishes rather than adding it to the prep doc.
+
+Canonical sections (full-prep mode produces all; standup-only produces just =* Standup Briefs=):
+
+| Section | Phase that writes it | Purpose |
+|----------------------------------+----------------------+----------------------------------------------------------------------------|
+| =* Heads-up= | Phase 7 | Substantial situational context that changes Craig's frame for the day |
+| =* Day's Priorities= | Phase 3 | Actionable items for today (with Email/Slack/Linear Response sub-sections) |
+| =* Meetings / Work Blocks= | Phase 4 | Chronological schedule for the day (meetings + work blocks interleaved) |
+| =* Standup Briefs= | Phase 6 | Yesterday / Today / Blockers content for the standup meeting |
+| =* Upcoming Deadlines= | Phase 7 | Next 4-6 weeks of relevant deadlines, briefly |
+| =* [Next day]'s Anchor Tasks= | Phase 7 | Explicit forward commitments for tomorrow. Phase 2 of next-day's prep reads this |
+
+Order in the prep doc follows the table top-to-bottom: Heads-up first (frame-setter), Day's Priorities next (action surface), then schedule, then standup, then deadlines, then forward-commitment.
+
+* Approach: How We Work Together
+
+** Continuous flow (no mid-phase gates)
+
+Phases A through 7 run continuously. Don't stop between phases for Craig's input or confirmation. Information surfaced in later phases (especially Phase 3 email/Slack/Linear scans) frequently reframes what Craig wants from earlier phases — meeting goals, carry-forward decisions, priority order, time blocking. Stopping at Phase 1 to ask "what do you want from this meeting?" means asking Craig to react with stale context, before scans surface the email that might change his answer.
+
+Build all phases through Phase 7, then present the assembled draft and surface every question and proposed adjustment at the final review.
+
+Exception: stop only if a scan turns up something that *blocks* further building. Examples: a meeting was canceled and the whole day's structure changes; a security or compliance issue Craig must adjudicate before email triage proceeds. Otherwise keep going.
+
+This rule applies to all phases including Phase 1's "collaborative review" line and Phase 2's planned-vs-actual review. Both are framed as collaborative in their phase descriptions; the collaboration happens once, at the end, against the assembled prep doc.
+
+** Phase A: Data Gathering (one parallel batch)
+
+Before any synthesis or interaction, pull every source the prep doc needs in a *single batch of parallel tool calls*. These reads are all independent — issue them in one message, not as a sequential round-trip per source:
+
+1. =mcp__google-calendar__list-events= for the *personal* account, scoped to the day being prepped.
+2. =mcp__google-calendar__list-events= for the *work* account, same scope.
+3. Grep =~/.emacs.d/data/pcal.org= for items on that day. This is the Proton Calendar export (=pcal= = personal calendar). The same directory has =gcal.org= and =dcal.org= for Google personal + DeepSat, but those are already covered by the MCP queries in steps 1 and 2 — only =pcal.org= adds non-redundant items.
+4. Read =todo.org= — collect [#A] and [#B] tasks plus anything with DEADLINE: or SCHEDULED: touching the day.
+5. List + read the *previous* prep doc. Check =inbox/= first (active prep docs not yet archived), then =daily-prep/= (the archive). Take the most recent file by date — usually yesterday's, but may be older if Craig was off (PTO, weekend, missed days). The lookback for the standup brief is anchored on this file's date, so accuracy matters.
+6. Read the most recent =.ai/sessions/= summary file (for the standup brief's "What did I do since last standup?" question).
+
+Phases 1-5 below all work from this in-memory snapshot. *Do NOT re-query the calendars in Phase 4* — the time-blocking pass uses the same data Phase A fetched. A typical daily-prep used to run 4-5 sequential round-trips just for data gathering; this collapses to one.
+
+** Phase 1: Meeting Review
+
+Working from the Phase A calendar snapshot, present each meeting with:
+
+1. *Time and duration*
+2. *Meeting name*
+3. *Owner* (who scheduled/owns the meeting)
+4. *Official agenda* (from calendar description)
+5. *What Craig needs from this meeting* -- decisions to drive, points to make, information to convey, people to persuade
+
+For the last item, Claude may not know Craig's goals for the meeting. Present what's known and Craig will clarify during review.
+
+*** 1:1 Meeting Prep
+
+1:1 meetings get deeper preparation:
+
+1. Check todo.org for tasks tagged with or related to the person
+2. Review session histories since the last 1:1 with that person for relevant events, decisions, and context
+ - Default lookback: since the last 1:1 with that person
+ - Craig may ask to go further back for long-running items
+3. Identify:
+ - Status updates Craig should share (progress on things they care about)
+ - Questions Craig needs to ask
+ - Decisions that need their input
+ - Action items owed to or from them
+
+Capture the meeting list with what's known about each (time, owner, official agenda, who's accepted vs declined, what Craig might need). Don't stop here for Craig's input. Bring questions about meeting goals to the final review at the end of Phase 7, when the cross-source picture from Phase 3 is in hand. The collaborative review of the meeting list happens once, against the assembled prep doc, not as a mid-flow gate.
+
+** Phase 2: Planned vs. Actual Review
+
+Before setting tomorrow's priorities, review what was planned for today against what actually happened. This catches work that slipped and prevents it from silently disappearing.
+
+1. Pull the current day's prep doc (if one exists). If it has a populated =* [Today]'s Anchor Tasks= section (written by yesterday's Phase 7 as the explicit handoff), use that as the canonical carry-forward list. Otherwise fall back to inferring carry-forward by listing the day's planned work blocks.
+2. For each block, note: completed, partially done, or not started
+3. For items that didn't happen, identify why (took longer than expected, blocked, deprioritized, meetings ran over)
+4. Carry forward anything that still matters into the priority list for the next day, with updated time estimates based on what we learned today
+5. Add all carried-forward items as =TODO= entries in the new prep doc's Day's Priorities section — don't just note them in the Planned vs Actual table. Unfinished tasks from yesterday become today's tasks automatically unless Craig cuts them.
+
+This step keeps the daily prep honest. If a 1-hour task consistently takes 3 hours, the estimates need to change. If work keeps getting bumped by meetings, that's a pattern worth raising.
+
+** Phase 3: Day's Priorities
+
+Assemble priorities automatically from multiple sources. No interactive confirmation. Craig reviews the prep doc as a whole when it's done.
+
+Write the assembled list as =TODO= entries under the prep doc's =* Day's Priorities= section. Order by urgency — most time-sensitive or blocking first. If Craig wants to add or remove a priority, he edits the prep doc directly.
+
+Sources contributing to Day's Priorities: todo.org, email, Slack, Linear.
+
+*Don't create empty response sub-section headers.* Only emit =** Email Response=, =** Slack Response=, or =** Linear Response= when there's at least one item to put under it. The =# Sources checked:= footer at the top of the prep doc shows which sources were scanned (✓ = ran, ✗ = skipped) — Craig already knows from the footer that Slack and Linear were checked even when those subsections aren't in the doc. Empty headers add visual noise and imply something was missed.
+
+*Linear digest / notification emails don't get their own TODO.* If sub-step 3b returns a Linear digest email saying "you have N unread notifications," that's not an Action item — Linear notifications surface either via 3e (the direct Linear query) or via the underlying per-notification emails Linear sends. Classify the digest as Noise-keep (or Noise-trash if the per-notification emails are also flowing through) and don't add a separate "Linear notifications check" entry to Day's Priorities.
+
+*** Recommended Approach Pattern (used by sub-steps 3b, 3d, 3e)
+
+When an item involves a non-trivial decision or judgment that benefits from analysis, include a =recommended approach= subheader before the response draft. The approach is the executor's analysis — situation, options, recommendation with rationale, considerations Craig should weigh — so Craig can evaluate the recommendation itself, not just the wording.
+
+Skip the approach subheader for routine acknowledgments, simple status replies, or "yep, looks good" approvals.
+
+Source-specific examples of when to *include* the approach subheader:
+
+- *Email:* decisions like grant applications, partnership replies, public-facing or sensitive responses
+- *Slack:* @mentions with explicit asks, items where someone is blocked waiting on Craig
+- *Linear:* @mentions requesting input, Blocked tickets Craig owns, Needs-Review items where the call isn't trivially obvious
+
+Format (consistent across all three sources):
+
+#+begin_example
+***** YYYY-MM-DD Day @ HH:MM:SS -ZZZZ recommended approach
+<situation, options, recommendation with rationale, considerations>
+***** YYYY-MM-DD Day @ HH:MM:SS -ZZZZ recommended response
+<draft response text, OR proposed action like a state change>
+#+end_example
+
+Generate timestamps with =date "+%Y-%m-%d %a @ %H:%M:%S %z"= so they're accurate, not estimated.
+
+*** Sub-step 3a: From todo.org
+
+1. Pull all [#A] tasks from todo.org.
+2. Add time-sensitive items (DEADLINE: or SCHEDULED: touching the day).
+3. Carry forward unfinished items surfaced by Phase 2 — but skip any item already added by step 1 or 2 above. A task that was [#A] yesterday and didn't finish gets carried forward by Phase 2 and would also re-appear in step 1's [#A] pull. Dedupe by org-mode heading text or =:ID:= property if present.
+
+Priorities typically include:
+- Messages to send (Slack, email)
+- Meetings to schedule
+- Documents to send out for review
+- Follow-ups to make
+- Prep work needed before a meeting
+
+*** Sub-step 3b: From email
+
+Scan email since the prior prep doc's *mtime* (when the file was last written, not the date in its filename or title) — both accounts, unread or unanswered, with the =summarize-emails=-style noise filter (=NOT flag:list=, addressed-to-Craig). Express the cutoff to Gmail as =after:YYYY/MM/DD HH:MM:SS= so messages dated *between the prior prep's write time and now* land in scope. Anchoring on filename date or Gmail's day-granular =after:= operator drifts when a prep doc is generated late at night for the next day — the wrong window catches a full extra calendar day or misses several hours.
+
+*Track every message path returned by the scan* (Action, FYI, and Noise alike). Sub-step 3c uses this list to mark-read only the emails actually processed, avoiding a race condition with emails arriving mid-workflow.
+
+For each email, classify:
+
+- *Action* — explicit ask, deadline, request for decision, or Craig is the bottleneck
+- *FYI* — informational, no action required (note in session-context.org if substantive, otherwise drop)
+- *Noise-keep* — automated/CC-only with no expected response, but has residual value (mark read; keep in inbox archive)
+- *Noise-trash* — automated/CC-only with no expected response AND no residual value (trash it; see criterion below)
+
+*Trash criterion.* Trash if both are true:
+
+1. No transactional / financial / security record value (would I ever search for this in 6 months?)
+2. Not direct human-to-human correspondence
+
+Otherwise mark-read but keep.
+
+*Per-account bias.* DeepSat work account biases toward keeping — defense engineering audit-trail value, storage is free. Personal Gmail biases toward trashing — high volume, low residual value, search clutter.
+
+Common *Noise-trash* patterns:
+- Newsletter / blog digest content (Substack subscriptions you don't actually read, daily/weekly roundups)
+- Retail / SaaS / EDC marketing promos
+- Social-network engagement bait (LinkedIn social digests, Instagram followers, Bandcamp DMs)
+- Aggregate notification digests redundant with their source app (Linear digest emails, Notion/Miro daily/weekly engagement pings)
+- Wrong-recipient mail (mailing-list typo addressed to a different person)
+- Past-event calendar artifacts (cancellations/updates for events that already happened)
+- Stock-tip teasers, deal alerts, review-request prompts (Hotels.com / Airbnb "rate your stay")
+
+Common *Noise-keep* patterns:
+- Financial: dividend statements, monthly statements, payment confirmations, invoices (paid or unpaid)
+- Account security: new-login alerts, new payment method added, password reset, OAuth grants
+- Domain / registrar admin (renewal notices, WHOIS contact reminders)
+- Direct human correspondence (even if FYI, even if you didn't reply)
+- Booking confirmations for trips actually being taken
+- PR / code review notifications (audit-trail value on the work account)
+- CI / deploy failure alerts (incident archive)
+
+*Email link format.* Every email surfaced in the prep doc must link directly to the actual message in the right Gmail account, not just to a generic Gmail tab. Construct the URL as:
+
+#+begin_example
+https://mail.google.com/mail/u/<account-index>/#all/<thread-id>
+#+end_example
+
+Two pieces matter:
+
+- *Account index.* The =u/<n>= segment selects which Gmail account opens the link. Indexes are stable per Craig's setup:
+ - =u/0= → personal account (=craigmartinjennings@gmail.com=, served by the =google-docs= MCP)
+ - =u/1= → DeepSat work account (=craig.jennings@deepsat.com=, served by the =google-docs-work= MCP)
+ Pick the index that matches the source MCP. A work email linked with =u/0= opens personal Gmail and shows nothing - that's the failure mode this rule prevents.
+- *Thread ID.* Use the =threadId= field from =listMessages= or =getMessage=, not the =messageId=. Gmail's web URL routes by thread. Use the =#all/= view (works whether the message is still in the inbox or has been archived) - don't use =#inbox/=, since the link breaks the moment the message moves out of inbox.
+
+If a project routes mail through a different account layout (other tenants, additional accounts), record the index mapping in that project's =.ai/notes.org= and override the defaults above.
+
+For each Action item:
+
+1. *Star the email in Gmail* so it's flagged in Craig's inbox outside the prep doc:
+ #+begin_src bash
+ python3 .ai/scripts/maildir-flag-manager.py star --reindex /path/to/message.eml
+ #+end_src
+2. *Read* the email content (use =eml-view-and-extract-attachments.py= in stdout mode if needed).
+3. *Capture substantive content* in the right place based on what kind of information it is:
+ - =deepsat/knowledge.org= (or the project's equivalent) — persistent facts the project should remember: new contacts to add to the roster, system or infrastructure details, strategic decisions, transcription corrections, vendor relationships.
+ - =.ai/session-context.org= — today's session context: what was read, decisions made or pending, follow-ups identified for later in the session.
+ When in doubt, default to session-context. The next session can promote anything worth keeping into knowledge.org during wrap-up.
+4. *People-Context Check (runs before the recommended response is drafted).* When the Action item involves a specific person (sender, recipient, or a named third party referenced in the body), look that person up in =deepsat/knowledge.org= (Key People table, plus the Team Details section if present). Pull role and reporting line, relationships to other key people (family, prior employer, advisor vs. employee), tone and working-style signals, and recent context that affects how Craig should phrase the response. If the person isn't in =knowledge.org=, capture what's known there before writing the draft — the people layer is persistent context, every future prep gets faster when this layer is complete. Skip the check for purely transactional senders (Mercury, GitHub notifications, Linear bots). The recommended-approach + recommended-response then incorporates the people-context: tone, channel choice (email vs Slack vs in-person), and framing should reflect the relationship.
+5. *Add to the prep doc* under Day's Priorities as an =Email Response= sub-section:
+ #+begin_example
+ ** Email Response
+ *** [[mail-link][From X: Subject]]
+ - One-line description of why action is needed.
+ - Suggested action: reply with status / approve / decline / schedule.
+ <recommended approach + recommended response per the Recommended Approach Pattern above>
+ #+end_example
+
+For each FYI item: read it, capture substantive content into knowledge.org or session-context per the routing above, then drop it from further processing. Don't add to the prep doc.
+
+For each Noise-keep item: no per-message action beyond the read-state pass at sub-step 3c. Don't add to the prep doc.
+
+For each Noise-trash item: trash it. Trashing removes the message from INBOX and parks it in Trash for 30 days before Gmail's auto-purge, so no separate mark-read is needed at sub-step 3c.
+
+#+begin_src bash
+# MCP path (preferred — works directly against Gmail):
+mcp__google-docs__trashMessage --messageId <id> # personal account
+mcp__google-docs-work__trashMessage --messageId <id> # DeepSat account
+
+# maildir path (fallback for offline / mu4e workflow):
+python3 .ai/scripts/maildir-flag-manager.py trash --reindex /path/to/message.eml
+#+end_src
+
+Don't duplicate Email Response items as standalone Day's Priorities entries — the =Email Response= sub-section IS the priority surface for those items.
+
+*** Sub-step 3c: Mark processed email as read
+
+After 3b is fully complete, mark *only the message paths 3b processed* (Action, FYI, Noise-keep) as read — not all unread INBOX emails. Noise-trash items are already handled at 3b and don't need a read-state pass.
+
+#+begin_src bash
+# MCP path (preferred):
+mcp__google-docs__modifyMessageLabels --messageId <id> --removeLabelIds '["UNREAD"]'
+
+# maildir path (fallback):
+python3 .ai/scripts/maildir-flag-manager.py mark-read --reindex /path/to/msg1 /path/to/msg2 ...
+#+end_src
+
+Scoped mark-read avoids a race where an email arriving between 3b's scan and 3c's mark-read would be silently marked read without being processed.
+
+Stars persist (separate flag), so Action items remain findable in Gmail by their star, not by unread state.
+
+*Before exiting Phase 3, verify the triage actions actually executed:* every Action item has a Gmail star AND is marked read; every FYI and Noise-keep item is marked read; every Noise-trash item is in Trash. The Phase 3 audit footer at sub-step 3g is the forcing function for source coverage; this verification is the parallel for triage execution. Producing only the audit footer without running the API calls leaves Craig with an unread inbox even though every message was *seen* in the prep doc — defeats the inbox-zero purpose of the workflow. Count what was processed (e.g., "44 trashed, 5 noise-keep marked-read, 19 starred + marked-read, 30 FYI marked-read") and confirm the totals match the classification.
+
+*** Sub-step 3d: From Slack
+
+Query Slack since the prior prep doc's *mtime* (when the file was last written, not its filename date). Three streams (filters out general channel chatter Craig wasn't directly addressed in):
+
+1. *DMs Craig hasn't replied to.* Call =mcp__slack-deepsat__conversations_unreads= with =channel_types='dm'= and =max_channels=100=. Each row is a DM message Craig hasn't read.
+2. *Channel @mentions of Craig.* Call =mcp__slack-deepsat__conversations_unreads= with =mentions_only=true= and =max_channels=100=. This is the *only reliable* way to find @mentions in this MCP — see the search-doesn't-work-for-mentions note below. Limitation: this only catches *unread* @mentions; ones Craig already saw are out of scope, which is the right trade-off (already-read mentions were seen and either actioned or consciously skipped).
+3. *Thread replies in threads Craig started or last commented in.* No direct API for "threads I started." Practical approach: in the unreads pulled by streams 1 and 2, look at the =ThreadTs= column — non-empty values mean the message is a thread reply. Use =mcp__slack-deepsat__conversations_history= on the parent channel to fetch the full thread context if any reply looks substantive.
+
+*Slack search caveat (don't waste time here).* =mcp__slack-deepsat__conversations_search_messages= does *not* index =<@USERID>= tokens as searchable text. Searches for =<@U0A8AJTEM9V>=, =@craig.jennings=, or even Craig's plain display name return empty even when @mentions exist. Slack's own search has the same limitation — the "Mentions & Reactions" panel in the Slack app uses the unreads-with-mentions API, not search. Don't fall back to =conversations_search_messages= to find @mentions; use =conversations_unreads(mentions_only=true)= as above. The search tool is fine for keyword searches in message text (e.g. "find any message mentioning 'STRATFI'").
+
+For each result, classify:
+
+- *Action* — explicit ask, decision needed, or Craig is the bottleneck
+- *FYI* — informational, no action required (capture in knowledge.org or session-context if substantive, otherwise drop)
+- *Noise* — bot pings, automated alerts, off-topic mentions (drop silently)
+
+For each Action item:
+
+1. *Read* the message and surrounding thread context.
+2. *Capture substantive content* in =deepsat/knowledge.org= (or the project's equivalent) for persistent project facts, or =.ai/session-context.org= for today's context. Same routing rules as Sub-step 3b — default to session-context when unsure.
+3. *People-Context Check* — same as sub-step 3b's step 4. When the message involves a specific person, look them up in =knowledge.org= before drafting. Skip for transactional bot pings.
+4. *Add to the prep doc* under Day's Priorities as a =Slack Response= sub-section:
+ #+begin_example
+ ** Slack Response
+ *** [[slack-permalink][From X in #channel: brief description]]
+ - One-line description of why action is needed.
+ - Suggested action: reply / react / move to thread / schedule.
+ <recommended approach + recommended response per the Recommended Approach Pattern above>
+ #+end_example
+
+For each FYI item: read it, capture substantive content per the routing above, then drop. No prep-doc entry.
+
+After processing all items, mark *only the specific DMs and @mentions we touched* as read in Slack — not channel-wide. The Slack MCP should expose a per-message mark-read capability; if the available MCP doesn't support it, skip this step and let Craig manage Slack read state himself. Do NOT mark channel chatter as read; only the items the query returned.
+
+Don't duplicate Slack Response items as standalone Day's Priorities entries — the =Slack Response= sub-section IS the priority surface for those items.
+
+*** Sub-step 3e: From Linear
+
+Query Linear since the prior prep doc's *mtime* (when the file was last written, not its filename date), using =updatedAt= as the timestamp anchor. Three streams:
+
+1. Tickets *assigned to Craig* with state changes or new activity.
+2. Tickets *created by Craig* with state changes or new comments (someone else moved or replied).
+3. Tickets where Craig is *@mentioned* in a recent comment.
+
+Use Linear MCP =list_issues= with the appropriate filters; =get_issue= and =list_comments= for individual reads.
+
+For each result, classify:
+
+- *Action* — ticket in "Needs Review" assigned to Craig; @mention requesting input; new comment with a question; deadline within ~48h; ticket assigned to Craig in a "blocked-on-me" state
+- *FYI* — state change on Craig's ticket by someone else; comment that's a status update; related-ticket activity worth knowing
+- *Noise* — bot updates, automated transitions (drop silently)
+
+For each Action item:
+
+1. *Read the ticket* — description, recent comments, state history.
+2. *Capture substantive content* in =deepsat/knowledge.org= (people roles, system facts, strategic decisions) or =.ai/session-context.org= (today's review notes). Same routing rules as Sub-step 3b — default to session-context when unsure.
+3. *People-Context Check* — same as sub-step 3b's step 4. When the ticket involves a specific person (assignee, reviewer, commenter, @mentioned), look them up in =knowledge.org= before drafting. Skip for bot updates and automated transitions.
+4. *Add to the prep doc* under Day's Priorities as a =Linear Response= sub-section:
+ #+begin_example
+ ** Linear Response
+ *** [[https://linear.app/...][SE-NNN]] Ticket title (state, assignee)
+ - Why action needed: one-liner (e.g., "Vrezh moved to Needs Review, awaiting Craig").
+ - Suggested action: review code / post comment / change state to X.
+ <recommended approach + recommended response per the Recommended Approach Pattern above>
+ #+end_example
+
+ Linear's =recommended response= can be a draft comment, a proposed state change with rationale, or a combined action like "comment + reassign to Vrezh" — the response is "what Craig should do," not just reply text.
+
+For each FYI item: read it, capture substantive content per the routing above, then drop. No prep-doc entry.
+
+*Two deliberate divergences from email/Slack:*
+
+1. *No mark-as-read step.* Linear has no "unread" concept. The processed signal is implicit — once Craig acts on the ticket (comments, changes state), it stops appearing in the next query. Items he doesn't act on re-surface tomorrow, which is correct.
+2. *No "star" or "save" equivalent.* Linear ticket URLs in the prep doc are enough.
+
+*Volume note:* if a query returns >20 tickets, surface the count and prioritize Action signals first (Needs Review assigned to Craig, @mentions, blocked tickets, deadlines).
+
+Don't duplicate Linear Response items as standalone Day's Priorities entries — the =Linear Response= sub-section IS the priority surface for those items.
+
+*** Sub-step 3f: From Open PRs
+
+Scan open pull requests on the project's primary repo (per-project; for DeepSat the canonical repo is `~/code/deepsat/orchestration_dashboard_mvp`). Use `gh pr list` to enumerate, classify each, and surface Action items in the prep doc.
+
+Scan command (single round-trip):
+
+#+begin_src bash
+gh pr list --repo <owner>/<repo> --state open --json number,title,author,reviewRequests,isDraft,updatedAt,headRefName,additions,deletions,url
+#+end_src
+
+For each result, classify:
+
+- *Action* — Craig is in `reviewRequests`, OR Craig was a reviewer and the author force-pushed since Craig's last review (re-review needed), OR the PR is blocked on Craig's response in a thread.
+- *FYI* — open PRs Craig isn't reviewing but worth noting (a teammate's branch in flight, draft PRs, Craig's own PRs awaiting others).
+- *Noise* — bot PRs (dependabot, renovate, etc.). Drop silently.
+
+For each Action item:
+
+1. *Read the PR* — diff summary, recent commits, review state, any unresolved threads.
+2. *People-Context Check* — same as sub-step 3b's step 4 for the PR author and the requesting reviewer.
+3. *Add to the prep doc* under Day's Priorities as a `** PR Review` sub-section:
+
+#+begin_example
+** PR Review
+*** [[PR-URL][PR #N — title (author, branch)]]
+- Why action needed: review requested / re-review after force-push / blocked on Craig's response.
+- Suggested action: full review / quick re-review / unblock thread.
+<recommended approach + recommended response per the Recommended Approach Pattern above>
+#+end_example
+
+For FYI items: include a short *Craig's own PRs awaiting review (FYI, not action)* sub-list under the PR Review section so the queue stays visible without inflating the action surface. One line per PR: number, short title, who's been requested.
+
+*Two deliberate divergences from email/Slack:*
+
+1. *No mark-as-read step.* PR review state is implicit — once Craig submits a review or a comment, the PR's review-status changes and re-classification happens on the next prep.
+2. *No "star" equivalent.* PR URLs in the prep doc are enough; Craig's review queue is already filterable in the GitHub UI.
+
+*Per-project repo configuration.* The repo path is project-specific. For projects without a primary repo (personal documentation projects, etc.), skip this sub-step and mark `prs ✗ (no primary repo)` in the audit footer. For projects with multiple repos in active development, scan each in turn; surface Action items with the repo name prefixed in the title.
+
+Don't duplicate PR Review items as standalone Day's Priorities entries — the `PR Review` sub-section IS the priority surface for those items.
+
+*** Sub-step 3g: Cross-source dedup and urgency re-sort
+
+After 3a-3f have written all their entries to Day's Priorities, do a final cleanup pass.
+
+*Cross-source dedup.* Scan the Email Response, Slack Response, Linear Response, and PR Review sub-sections for items that reference the same conversation or topic. Common cases:
+
+- Vrezh DMs Craig about a Linear ticket *and* comments on the ticket itself — both surface as separate drafts
+- An email points at "let's discuss on the ticket" — the ticket also has activity
+- A Slack thread is the followup to an email exchange
+
+For each candidate duplicate pair, surface to Craig:
+
+#+begin_quote
+These two items look like the same conversation: [Email link] and [Linear link]. Should I collapse them under one source, or keep both?
+#+end_quote
+
+Wait for Craig's call. If he says collapse, keep the source he picks and add a cross-reference link in the kept item ("see also: [other-link]"). Don't auto-collapse.
+
+*Urgency re-sort.* Items currently appear in sub-step order (todo.org, then Email Response, then Slack Response, then Linear Response). Re-order all top-level entries under =* Day's Priorities= by urgency:
+
+1. Items with deadlines today or already overdue
+2. Items where Craig is blocking someone (Slack blocked-on-Craig, Linear Blocked tickets, Needs-Review assigned to Craig)
+3. Items with deadlines within ~48 hours
+4. Other [#A] tasks
+5. Time-sensitive but lower-stakes items
+6. Everything else
+
+Within each tier, preserve the source-section structure (Email Response, Slack Response, Linear Response sub-sections stay grouped) — just re-order the top-level entries that aren't already sub-sectioned.
+
+Craig can re-order further when he reviews the prep doc; this just gives him a sane starting order.
+
+*** Sub-step 3h: Phase 3 audit footer (forcing function)
+
+After 3a-3g are done, write a single comment line at the top of the prep doc — directly below the =#+DATE:= header — recording which sources actually got checked:
+
+#+begin_example
+# Sources checked: todo.org ✓ | email-personal ✓ | email-deepsat ✓ | Slack ✓ | Linear ✓ | prs ✓
+#+end_example
+
+Replace the ✓ with ✗ for any source that was skipped, and add a parenthetical reason after each ✗ (e.g. =Slack ✗ (MCP disconnected)= or =email-personal ✗ (auth scope error)=). If a source was scanned but returned no items, keep the ✓ — empty is a valid scan result; "didn't run at all" is what this line catches.
+
+This footer is the canary that surfaces silent skips. The reason it's a forcing function: writing the line means deciding what mark each source gets, which means actually checking that each source ran. A skipped sub-step now requires an explicit ✗, not a silent omission of a section.
+
+** Phase 4: Time Blocking
+
+Once priorities are confirmed, block time on the calendar to accomplish them. Phase 4 also writes the prep doc's =* Meetings / Work Blocks= section — a single chronological list interleaving meetings with focused-work blocks, top to bottom in time order.
+
+*** Quick Tasks (< 5 minutes)
+Tasks like "schedule a meeting with Ryan" or "send a Slack message" should be done during the prep workflow itself, not scheduled separately. Draft the message or create the calendar event on the spot.
+
+*** Focused Work Tasks
+For anything requiring more than a few minutes:
+
+1. Ask Craig for a time estimate on each item
+2. Use the Phase A calendar snapshot — *do not re-query the calendars*. The same events are already in context.
+3. *Compute the day's active window.* Default 10:00 to 17:00, every day of the week (weekends included). If the prep is being run *same-day* (the prep doc's date matches today's date) and the workflow start-time is later than 10:00, the window starts at the start-time instead. Existing calendar appointments, known personal commitments (guests arriving, travel, off-time blocks Craig flagged), and the last-30-min next-day-prep reservation remove time from the window. Whatever's left is fillable with priorities. Don't auto-treat Saturday or Sunday as "off." Fill the window with tasks. If Craig wants personal time on a weekend, he marks it on the calendar or flags it during prep.
+4. List the schedule with open slots clearly marked. Show the active window's start, end, and remaining fillable minutes after subtracting appointments.
+5. Propose when each task fits, considering:
+ - Meeting proximity (prep work should be near the meeting it supports)
+ - Energy/focus (harder tasks earlier if possible)
+ - A half hour around lunchtime to eat when possible (protein shake or leftovers is fine -- this can be compressed or skipped on heavy days)
+ - Always reserve the last 30 minutes of the workday for daily prep for the following day. This is non-negotiable -- it's what keeps the cycle going.
+6. Craig confirms or adjusts the proposed schedule
+
+*** Placing Calendar Blocks
+- Place time blocks on Craig's personal Google calendar (=Craig Google=)
+- Can also place blocks on DeepSat calendar directly using MCP server with =account_id: "work"=
+- Use the calendar event workflows (add-calendar-event.org) for creating events
+
+** Phase 5: Prep Work
+
+With the schedule set, work on anything that needs to be ready for the day's meetings. Examples:
+
+- Watch tutorial videos and take notes
+- Draft or polish documents for review
+- Prepare talking points or materials
+- Research topics that will come up in meetings
+- Draft messages that are part of the day's priorities
+
+This phase is where the bulk of the session time goes. Work through items in priority order, with meeting-related prep taking precedence based on meeting time.
+
+** Phase 6: Standup Brief
+
+Generate the standup brief late in the workflow so the rest of the day's analysis is already done. The brief draws from Phase 2 (Planned vs Actual), Phase 3 (Day's Priorities), and the activity sweep below. Phase 6 writes the prep doc's =* Standup Briefs= section.
+
+Skip this phase entirely on days with no standup on the calendar.
+
+*** Step 1: Sweep recent activity for off-Claude signals
+
+Before drafting, check these sources for activity since the previous prep doc's date (the lookback anchor from Phase A step 5):
+
+1. *Sent email* — both accounts. Outgoing threads from Craig: decisions communicated, replies to action items, follow-ups, intros made.
+2. *Slack* — Craig's recent messages across channels and DMs. Decisions, status updates, threads where Craig participated.
+3. *todo.org* — items marked DONE since the cutoff. New TODOs added that hint at fresh context (new commitments, new blockers).
+4. *Linear* — tickets Craig moved to a new state, commented on, or created. Use the Linear MCP to query.
+
+These surface team-visible work that lives outside session history (work done in mu4e, Slack, the Linear UI, or off-Claude conversations).
+
+*** Step 2: Draft the brief
+
+Combine session history + the Step 1 sweep + Phase 3 priorities + todo.org WAITING items into the three-question structure below.
+
+*Meeting selection.* Recurring meetings are excluded from both the Yesterday and Today sections — they're not news to the team. For non-recurring meetings:
+
+- *Yesterday section:* include only meetings Craig actually attended. Filter on Craig's own response status from the calendar event:
+ - =accepted= → include
+ - =tentative= or =declined= → exclude (don't assume attendance)
+- *Today section:* include all non-recurring meetings regardless of response status. Craig still needs to communicate what he plans to attend or decide between.
+
+The Google Calendar MCP returns =responseStatus= per attendee — filter on Craig's own response, not the event's overall status. Recurring events expose =recurringEventId= or =recurrence=; treat the presence of either as the recurring marker.
+
+*Content rules.*
+
+- *Stay first-person.* Report what Craig did, said, or decided. Don't volunteer others for work or report what others said they would do — that's their standup, not Craig's. If a teammate's commitment is relevant context, frame it as something Craig is waiting on, not as a status update on their behalf.
+- *Match deadline precision to what's actually known.* If a deadline is "early next week," don't tighten it to "Monday." If the commitment is "before the proposal goes out," don't sharpen it to "Friday EOD." Vague is honest when vague is the truth.
+
+1. *What did I do since last standup?* Anchor the lookback at the previous prep doc's date (Phase A step 5). Pull session history, session-context.org, completed tasks, and the Step 1 sweep results from that date forward. Since DeepSat standup is a workday-recurring meeting, the previous prep doc's date is the previous standup date even if intervening days were weekends or PTO. Use explicit day references ("Monday" not "yesterday") since the prep doc may be written the evening before.
+2. *What am I doing today?* Pull from the day's priorities (Phase 3 output). Keep it to 2-3 items max.
+3. *Blockers: mine or yours?* The bar is "did this actually stop me from making progress?", not "is someone else involved?" A WAITING item in todo.org is only a blocker if Craig already tried to move forward and got stopped. Mere dependencies don't qualify unless they've already impaired progress. Default to under-reporting — draft without borderline items and let Craig add them back in Step 3. FYI items (decisions or context worth flagging that aren't blockers) come after blockers and stay loose.
+
+The brief should be concise enough to read aloud in under 60 seconds. Include enough context that Craig doesn't have to think on his feet, but not so much that it turns into a status report.
+
+*** Step 3: Present the draft and ask what's missing
+
+Show Craig the full draft brief — Yesterday, Today, Blockers/FYI sections all populated. Then ask:
+
+#+begin_quote
+Anything I missed? Common categories: off-Claude meetings or phone calls, paperwork or forms submitted, intros made or received, vendor conversations, anything else not captured in session/email/Slack/Linear.
+#+end_quote
+
+Recognition is faster than recall. Craig can react to "did you make any intros?" much faster than to "what did you do?" The categories are prompts, not a checklist.
+
+*** Step 4: Refine and finalize
+
+Apply Craig's additions and any wording adjustments. The brief is now ready for standup.
+
+*** Step 5: Offer to capture learnings
+
+After Step 4, scan Craig's refinements for non-obvious patterns:
+
+- Did he cut a category of item the workflow said to include?
+- Did he add a category the workflow didn't tell you to look for?
+- Did he change wording in a way that suggests a phrasing rule (e.g., "say 'continued focus on X' instead of 'worked on X'")?
+
+If a refinement looks like a generalizable rule, offer it back to Craig:
+
+#+begin_quote
+I noticed you [removed all 1:1 meetings from Yesterday / added the off-Claude phone call with Ryan / changed "completed proposal draft" to "continued focus on proposal"]. Want me to add this to the workflow? Proposed rule: "[concrete rule text]"
+#+end_quote
+
+Wait for explicit confirmation before editing the workflow. Never edit on your own judgment.
+
+If Craig confirms, append the rule to the *Updates and Learnings* section at the bottom of this file with today's date and a one-line description. If the new rule supersedes existing text inside Phase 6, also update the inline text and note "(updated YYYY-MM-DD — see Updates and Learnings)" in the affected section so the audit trail is complete.
+
+If the refinement looks like a one-off, don't propose a rule. Default to under-proposing — false-positive rules clutter the workflow. The bar is "would I want this guidance the next time I draft a brief?" If yes, propose. If no, drop it.
+
+** Phase 7: Final Section Writeups
+
+Three sections remain after Phase 6: =* Heads-up=, =* Upcoming Deadlines=, and the next day's =* [Day]'s Anchor Tasks=. Phase 7 writes them, drawing on what earlier phases already surfaced.
+
+Order doesn't matter between the three sub-steps. They write to distinct sections and don't depend on each other.
+
+*** Sub-step 7a: Heads-up
+
+Write a top-level =* Heads-up= section near the top of the prep doc (above =* Day's Priorities=).
+
+Heads-up is the executive summary of what would change Craig's frame for the day. Terse, situational, day-shaping. Pull from sources earlier phases surfaced:
+
+- *Substantial FYIs* from Phase 3 sub-steps 3b/3d/3e — items like "Eric quietly progressed two partnership threads on Apr 24" or "Vrezh force-pushed all three branches overnight" that affect what Craig should expect today
+- *Schedule changes* from Phase 1 — "Arusyak 15:00-16:00 is being rescheduled" or "DeepSat GTM declined for tonight"
+- *Urgent deadlines bubbling up* — items in =* Upcoming Deadlines= that hit within ~2 days, surfaced as standalone Heads-up items so Craig sees them immediately
+- *Active Reminders* (from Phase A's notes.org read) that frame today specifically — "first thing in the morning, register for SOFWeek"
+
+Format: bullet list, one situational note per line, no sub-bullets. Keep each entry to one sentence. If a Heads-up item needs more context, link to the source (email, ticket, prep section) instead of inlining.
+
+Lightweight FYIs (status pings, "FYI we shipped", small acknowledgments) stay in =.ai/session-context.org= and don't surface in Heads-up.
+
+*** Sub-step 7b: Upcoming Deadlines
+
+Write a top-level =* Upcoming Deadlines= section.
+
+Source: scan todo.org for =DEADLINE:= entries plus deadlines mentioned in notes.org or knowledge.org. Filter to roughly the next 4-6 weeks. Order chronologically.
+
+Format: bullet list, one deadline per line, format =- [Day YYYY-MM-DD] — short description=. Mention the owner if it isn't Craig and the deadline still concerns him (e.g., "Subbu owns; Craig's technical content due ahead of this").
+
+Volume control: if more than ~10 deadlines fit the window, narrow the window or surface only the ones that are blocking, externally-imposed, or have non-trivial prep ahead.
+
+Don't duplicate deadlines that are already today's =* Day's Priorities= entries. Day's Priorities is for action; Upcoming Deadlines is for awareness.
+
+*** Sub-step 7c: Next day's Anchor Tasks
+
+Write a top-level =* [Day]'s Anchor Tasks= section. Compute the next day's name from today's date — *don't* skip weekends. For a Friday prep doc this becomes =* Saturday's Anchor Tasks=, for a Saturday prep doc it becomes =* Sunday's Anchor Tasks=, etc. Use known PTO markers if any (a fully-blocked PTO day can be skipped to the next available day).
+
+Source: items Craig is explicitly committing to do tomorrow. Pull from:
+
+- Items planned for today that didn't get done (from Phase 2's Planned vs Actual)
+- Items that genuinely fit tomorrow better than today (criterion below)
+- Prep work needed before tomorrow's meetings
+- Anything Craig flagged during today's session as "I'll do this tomorrow"
+
+*Criterion for pushing an item to tomorrow rather than fitting it today.* Push only if at least one is true:
+
+1. *Hard-blocked today* — waiting on a person, a system, or a deadline that hasn't passed yet
+2. *Needs a contiguous block* today's window can't provide
+3. *Prep work for a tomorrow-only meeting* (do the prep close to the meeting)
+4. *Team-dependent* and the team isn't available today (e.g., Craig's at one location and the team's at another)
+
+If none of those apply, the item stays in today's Day's Priorities and gets a time block in Phase 4. Don't auto-punt independent reading, registration, local-machine work, or "I'll get to it tomorrow" items just because today is a weekend or feels light.
+
+Items further out than tomorrow (Monday-only items written on a Saturday, for example) stay in =todo.org= with appropriate priority and SCHEDULED markers. Don't list them in the prep doc — they'll resurface in the relevant day's prep via Phase 3 sub-step 3a.
+
+Format: bullet list or =** TODO= headings, with optional time estimates (e.g., "— 1.5 hrs"). Each item should be a clear task — passive monitoring or context goes elsewhere (Heads-up or session-context).
+
+This section is the explicit handoff to next-day's Phase 2. If it's empty, write the header with "(none flagged)" so the next day's prep doesn't mistake an empty section for a missing one.
+
+** Phase 8: Archive Older Prep Docs
+
+After the new prep doc is written, archive any prep docs in =inbox/= older than yesterday's. Yesterday's prep doc stays in =inbox/= because the new prep doc may still need to reference it (Planned vs Actual, talking-point carry-forward).
+
+#+begin_src bash
+# Move any inbox/*-daily-prep.org file dated before yesterday into the archive.
+mv inbox/YYYY-MM-DD-daily-prep.org daily-prep/
+#+end_src
+
+The archive lives at =daily-prep/= at repo root. Don't put prep docs in =deepsat/meetings/= — the prep doc covers personal calendar, all 1:1s, and all projects, not just DeepSat work.
+
+If =daily-prep/= doesn't exist yet (new project), create it. If a stale prep doc lives in =assets/= (an older convention), move it to =daily-prep/= as part of this archive pass.
+
+This step keeps =inbox/= clean. The previous-day's prep is the only one that still has consumers.
+
+** Phase 9: Project Extension
+
+If =.ai/project-workflows/daily-prep.org= exists, read and execute its instructions as additional steps appended to this workflow. The project file contains add-ons specific to the project. It is *not* a replacement for this template — it picks up where this workflow's main flow ends.
+
+Surface the extension once per session ("Project has additional daily-prep steps — running them now") so the choice is visible.
+
+This is the project-extension hook from [[file:startup.org][startup.org]]'s workflow discovery rule, made explicit at the workflow level so it's not buried in discovery instructions. Runs in both full-prep and standup-only modes.
+
+* Principles to Follow
+
+** Prep Supports Action
+The goal is for Craig to walk into every meeting and task with what he needs. If prep doesn't lead to better outcomes, it's wasted time.
+
+** Craig Drives Priorities
+Claude surfaces information and proposes priorities, but Craig decides what matters. Don't assume -- ask.
+
+** Quick Tasks: Just Do Them
+If something takes less than 5 minutes, do it during prep rather than scheduling it. Draft the Slack message, create the calendar invite, send the email.
+
+** Respect the Calendar
+When proposing time blocks, respect existing commitments across all calendars. Don't double-book. Account for transition time between meetings.
+
+** First-Person Perspective
+When preparing 1:1 talking points, frame everything from Craig's perspective -- what does Craig need to communicate, ask, or decide? Not what the other person needs.
+
+* Living Document
+
+Update this workflow based on what works in actual daily prep sessions. Track learnings below.
+
+** Updates and Learnings
+
+*** 2026-02-23: Initial creation
+Created during first daily prep session. Validated against tomorrow's schedule (2026-02-24: Vrezh 1:1, Standup/IPM, Product Review, Backlog Planning).
+
+*** 2026-02-23: Use explicit day references, not relative terms
+When referring to past meetings or events, always include the explicit day (e.g., "from Monday's meeting" not "from this morning's meeting"). The prep doc may be written the day before and read the day of -- relative references like "this morning" or "today" become ambiguous. Include the day name so Craig doesn't have to calculate days in his head while focused on making a point.
+
+*** 2026-02-23: Prep doc output
+The prep is written to =inbox/YYYY-MM-DD-daily-prep.org= where the date is the day being prepped for.
+The startup workflow checks for this file and asks whether to open it. Note: need to resolve where the daily prep reference in startup.org lives so template syncing doesn't overwrite it (see todo.org task).
+
+*** 2026-02-23: Check for dependencies between tasks and meetings
+Tasks and meetings often depend on each other. SkyFi prep needs to happen before the Vrezh 1:1 so Craig can ask informed questions; Linear learning needs to happen before the backlog planning meeting where they'll use it. Always check for these dependencies and ask Craig when unsure.
+
+*** 2026-02-23: Energy management matters as much as time management
+Front-load high-effort, high-stakes work early in the day (about an hour after waking). Save research, reading, and lighter tasks for late afternoon when energy dips. Craig tries to eat lunch and have coffee/tea around 12:30 PM to sustain energy for the afternoon. This principle should guide time block placement alongside calendar constraints.
+
+*** 2026-02-23: Link references in the prep doc
+When listing tasks, documents, or directories in the prep doc, include links to the source
+(todo.org line numbers, file paths, directories). Craig shouldn't have to search for context
+when he's in the middle of a meeting or working through the day.
+
+*** 2026-02-23: Note dependencies between time blocks
+When an earlier time block feeds into a later meeting, call it out explicitly in the prep doc
+(e.g., "by this point, should have already checked Okta access"). Helps Craig verify he's
+on track as the day progresses.
+
+*** 2026-02-23: Prep doc is a living document through the day
+Craig may annotate the prep doc with "cj:" comments as he works through it. Process those
+when asked or at the start of the next session. Remove the comment markers after acting on them.
+
+*** 2026-02-23: Ask probing questions about task nature
+When a task like "SkyFi outreach" could mean either a 5-minute email or a 1-hour call, ask. The answer often splits the task into prep + action, which schedule differently. These questions are very helpful and should be a regular part of the workflow.
+
+*** 2026-03-08: Keep Day's Priorities, drop separate Time Blocking table
+The output prep doc should have a "Day's Priorities" section followed by a single chronological
+"Meetings / Work Blocks" section that interleaves meetings, prep blocks, and focused work blocks
+in time order. No separate Time Blocking table — the chronological Meetings / Work Blocks section
+serves that purpose.
+
+*** 2026-03-09: Day's Priorities use org-mode TODO headings, not numbered lists
+Each priority is a =** TODO= heading under =* Day's Priorities=, not a numbered list item.
+Format: =** TODO Task name — description. Links to todo.org or other files. ~time estimate.=
+Do not use bold or italic markup in the prep doc — org headings, TODO keywords, and plain text
+provide enough structure.
+Mark completed items as =** DONE= with a =CLOSED:= timestamp on the next line.
+Order by urgency and priority — most important/time-sensitive first. Craig should be able to
+work top-to-bottom and know he's tackling the right thing next.
+This makes priorities trackable in org-mode (agenda, todo filtering) and lets Craig toggle
+status directly in Emacs as the day progresses.
+
+The workflow phases (identify priorities, propose time blocks) still happen during the prep
+conversation — the change is only to the output format.
+
+*** 2026-03-08: Always include Planned vs Actual
+Craig finds the Planned vs Actual review table valuable. Always include it in the prep doc
+when a previous day's prep doc exists. This is Phase 2 of the workflow and should never be skipped.
+
+*** 2026-04-01: Always use human-readable ticket titles
+When referencing Linear tickets (or any issue tracker IDs), always use the human-readable
+title with the ID in parentheses — e.g., "Setup Database for dev environment (SE-93)" not
+just "SE-93." Craig can't remember what ticket IDs map to, and bare IDs force him to look
+them up. Use the Linear MCP tools to fetch the title if needed.
+
+*** 2026-03-27: Standup briefs — only team-visible goals, not personal productivity
+Only include work that left Craig's local environment: pushed to a repo, shared with
+the team, posted in Slack, changed something in Linear, or shifts what the team believes
+or plans. Exclude work whose output lives entirely in Craig's local files (knowledge.org,
+todo.org, session notes, transcript processing, local tooling setup, MCP server config).
+Filter: "If I didn't mention this, would someone on the team make a worse decision or
+duplicate the work?" If no, cut it.