Skip to content
Subscribe

Automating Life: CRM, Calendar, Canvas & Cron

Narrative 10 min read

The flashy parts of an AI agent system are the dashboard and the chat interface. But the real value — the stuff that saves hours every week — is the automation layer. Cron jobs that fire at 7 AM. Alert agents that catch problems before you notice them. A CRM that builds itself.

This is the story of how we automated the boring stuff.


The Morning Briefing: 9 Sources in 60 Seconds

Section titled “The Morning Briefing: 9 Sources in 60 Seconds”

Every morning at 7:05 AM, a cron job fires morning-briefing.sh. It pulls from nine data sources and delivers a formatted digest to Telegram:

  1. Google Calendar — today’s schedule
  2. Email — unread count and priority messages
  3. Canvas LMS — upcoming assignments and grade alerts
  4. Task logs — yesterday’s accomplishments and today’s priorities
  5. Crypto portfolio — overnight price changes
  6. Weather — local forecast
  7. Nutrition — yesterday’s calorie and macro summary
  8. Goals — cross-domain goal progress
  9. System health — agent status, MCP server health, cron results

By the time you’ve poured your coffee, you know exactly what your day looks like. No app-hopping. No checking five dashboards. One message.

The CRM didn’t start as a planned feature. It started as a rule in CLAUDE.md:

“CRM Everything: whenever a person’s name comes up, check or create their entry.”

That’s it. One sentence. But because the AI agent follows this rule in every conversation, contacts accumulate automatically. After a week, we had 132 contacts — each as a markdown file with YAML frontmatter:

---
name: "Jane Smith"
slug: jane-smith
domain: consulting
tags: [vip, investor]
email: jane@example.com
company: "Acme Corp"
role: "VP Engineering"
relationship: client
last_contact: 2026-04-10
---
## Notes
- Met at startup meetup on April 8
- Interested in AI agent consulting
## Interaction Log
- 2026-04-10: Follow-up email sent
- 2026-04-08: Initial conversation at meetup

The format is deliberately simple. Markdown is human-readable, git-trackable, and searchable. The YAML frontmatter makes it machine-parseable for the dashboard and search tools.

A VIP contacts list separately tracks high-priority people for email triage — ensuring important messages surface in the morning briefing.

The Nerve Center’s /crm page reads all 132 contacts, parses both simple .md files and rich directory structures (with PROFILE.md, summary.md, and items.json), and presents them as searchable, filterable cards. Filter by domain, search by name or company, expand for full details.

School is one of the six life domains, and Canvas LMS is its primary data source. The integration runs deep:

canvas_sync.py pulls all assignments across 10 courses and saves them to local JSON cache. It runs with a 120-second timeout (via a perl alarm wrapper) to prevent hanging on slow Canvas API responses.

Per-course grades are tracked in YAML with current grade, letter, trend, and alert flags. A critical threshold at C- triggers an immediate Telegram alert. Any grade change — up or down — fires a notification.

Three times a day, deadline-watcher.sh scans for assignments due within 48 hours and sends Telegram alerts. This has saved several near-misses on assignment deadlines.

Course content from Canvas pages feeds into a ChromaDB vector store via recursive chunking (512 tokens, 100 overlap). The embedding model is Ollama’s nomic-embed-text, running locally at zero cost. Lecture recordings go through Whisper transcription and auto-ingest into the same vector store.

Currently: 88 chunks across 3 courses, with semantic search returning results at 0.24 distance accuracy.

Here’s the full cron schedule that runs our life:

TimeJobWhat It Does
7:00 AMCanvas syncPull assignments and grades
7:05 AMMorning briefing9-source digest to Telegram
8 AM, 2 PM, 8 PMDeadline watcher48h assignment alerts
Every 15 minTelegram watchdogBot health check + auto-restart
Every 15 minDomain syncGenerate domain state JSON
Every 4 hoursDashboard syncSnapshot state + Vercel redeploy
7 AM dailyNews scannerAI/tech news scan
Every 6 hoursGitHub enrichmentQuery 23 repos for status
11 PMCost trackerDaily spend summary
Sunday 8 PMWeekly reviewWeek summary + next week plan
Monday 7 AMWeek aheadStudy plan for the week
Every 3 hoursPlaud syncAudio recording transcription
NightlyCEO aggregateExecutive summary from all domains
9 PMHabit check-inFamily habit tracking

The most critical cron isn’t any of the above — it’s the Telegram watchdog that runs every 15 minutes. It checks three things:

  1. Is the launchd service loaded?
  2. Does the daemon PID exist?
  3. Is the tmux session alive?

If any check fails, it auto-restarts via launchctl kickstart and sends a Telegram alert (rate-limited to one per hour to prevent spam). This was built after the 56-hour outage on day 0.

A separate system watchdog monitors disk space, process health, and provides alert escalation.

Beyond scheduled cron jobs, four alert agents fire on specific conditions:

AgentTriggerAction
Grade AlertsCanvas grade change detectedImmediate Telegram notification
Follow-up AlertsConsulting deal inactive >7 daysTelegram reminder to follow up
Birthday AlertsBirthday at 7, 3, 1, 0 days outTelegram alert + gift reminder
Deadline WatcherAssignment due within 48 hoursTelegram alert with details

These agents are proactive. They don’t wait for you to check — they find problems and surface them. The birthday alerts at graduated intervals (7/3/1/0 days) give you enough time to actually buy a gift.

EOD Compiler: Turning Chaos Into Journal Entries

Section titled “EOD Compiler: Turning Chaos Into Journal Entries”

At the end of each day, the EOD compiler aggregates:

  • Task logs from all agent sessions
  • Telegram session logs
  • Cron output logs
  • Domain reports

It transforms raw tool-call logs into a narrative daily journal entry stored in the Obsidian vault. This becomes the input for the next morning’s briefing and the weekly review.

The weekly review (Sunday 8 PM) aggregates an entire week of these daily entries into accomplishments, blockers, and priorities for the next week.

The Deck Architect: AI-Powered Presentations

Section titled “The Deck Architect: AI-Powered Presentations”

Not strictly “automation,” but the Deck Architect deserves mention because it automated something deeply painful: building presentation decks.

Version 2 (production) uses a pptxgenjs engine. The LLM generates full JavaScript code per slide batch, guided by a design system with 9 golden layout patterns (Anchor Left, Split Contrast, Card Grid, Stat Spotlight, etc.). A visual QA step screenshots each slide and scores it, regenerating any that fall below an 8.0 threshold.

Cost: ~$0.60 per deck. Speed: ~200 seconds for 11 slides.

Version 3 (experimental) uses pre-built .pptx templates. The LLM outputs structured JSON content only — never layout code. It’s 2.6x faster and 4x cheaper ($0.15 per deck) but quality needs refinement.

1. The morning briefing is the killer app. Everything else is nice. The morning briefing is essential. Build it first.

2. Passive CRM beats active CRM. Making contacts automatic (“CRM Everything”) means you never forget to log an interaction. The CRM builds itself.

3. Graduated alerts prevent noise fatigue. Birthday alerts at 7/3/1/0 days work because they escalate. A single “birthday tomorrow” alert is either too late or forgotten. Four alerts at decreasing intervals ensure action.

4. Watchdogs are non-negotiable. Every critical process needs a watchdog. Not “should have” — must have. The 56-hour silent outage proved this.

5. File-based state scales further than you’d think. 132 CRM contacts in markdown files. 14 cron configs. 6 domain configs. All in flat files, all git-tracked, all searchable. No database needed.


For technical details on each subsystem, see the full Architecture References.