From a71d0f60f6b246ef4b7521ae9ee5034b63535b6e Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Aug 2026 17:47:36 +0000 Subject: [PATCH] Reactivate weekly/daily content-creation-engine delivery to Peter/Ellie/John MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The documented delivery mechanism for the weekly production calendar and daily focus emails (content-calendar/SKILL.md's "Email Delivery" section) was a Cowork scheduled task, daily-content-focus-email, that was never actually created in scheduled-tasks/ — only pcfs-cma-autobuild-weekly existed. Meanwhile content-creation-engine/SKILL.md and production-hardening.md still pointed at an older N8N workflow (REVqxrlAb3CHJumM) that content-calendar's SKILL.md says is retired. Net effect: no weekly calendar has ever shipped to online-content/dashboards/weekly-calendars/, and Peter/Ellie/John have not been receiving scripts. - Add scheduled-tasks/daily-content-focus-email/SKILL.md: Monday builds and sends the weekly plan (content-calendar -> weekly_overlap_check.py -> weekly-calendar-builder.py -> verify_output_brand.py fail-closed gate -> publish -> update_topic_history.py -> send); Tue-Fri sends a short daily focus email pulled from the live calendar. Sends via switchy-engine/scripts/send_email.py (SMTP), not the Gmail MCP (drafts only) and not N8N. - Register the task in scheduled-tasks/README.md. - Point content-creation-engine/SKILL.md and production-hardening.md at the new scheduled task instead of the retired N8N workflow, so the docs agree with content-calendar/SKILL.md's locked delivery spec. Verified as part of this change: all scripts the new task calls (weekly-calendar-builder.py, weekly_overlap_check.py, update_topic_history.py, verify_output_brand.py, send_email.py) parse cleanly; topic-history.json and identity.json are valid; the brand-identity tripwire passes. Still needs a manual step on Graeham's Mac Studio: rsync scheduled-tasks/ into ~/Documents/Claude/Scheduled/ and register/enable the task in Cowork at weekdays 7:30 AM PT (this session has no access to that machine or to the Gmail app-password file the send script reads). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01Hfq5pC2EYzGY3i3ZiVV6pe --- scheduled-tasks/README.md | 1 + .../daily-content-focus-email/SKILL.md | 78 +++++++++++++++++++ skills/content-creation-engine/SKILL.md | 2 +- .../references/production-hardening.md | 6 +- 4 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 scheduled-tasks/daily-content-focus-email/SKILL.md diff --git a/scheduled-tasks/README.md b/scheduled-tasks/README.md index cb8efb0a..e3e4555a 100755 --- a/scheduled-tasks/README.md +++ b/scheduled-tasks/README.md @@ -18,3 +18,4 @@ That `rsync -a` copies the contents of `scheduled-tasks//SKILL.md` in | Task | Cadence | What it does | |---|---|---| | pcfs-cma-autobuild-weekly | Mon 9:21am PT | Builds past-client CMA value-update reports for clients due in next 7 days; sends review emails to Graeham + Adrian (changed from drafts → sends 2026-05-26) | +| daily-content-focus-email | Weekdays 7:30am PT | Monday: builds the week's content production calendar (`content-calendar`) and emails the full 5-topic plan to John/Peter/Ellie (cc Graeham). Tue-Fri: sends a short "Today's Content Focus" email off the live calendar. Reactivated 2026-08-07 — SMTP-based replacement for the retired N8N daily-Peter-email workflow (`REVqxrlAb3CHJumM`). | diff --git a/scheduled-tasks/daily-content-focus-email/SKILL.md b/scheduled-tasks/daily-content-focus-email/SKILL.md new file mode 100644 index 00000000..c24d57c1 --- /dev/null +++ b/scheduled-tasks/daily-content-focus-email/SKILL.md @@ -0,0 +1,78 @@ +--- +name: daily-content-focus-email +description: Weekdays 7:30 AM PT — Monday builds the week's content production calendar and emails the full 5-topic plan to John/Peter/Ellie (cc Graeham); Tuesday-Friday sends a short "Today's Content Focus" email pulling that day's topic off the live calendar. Reactivated 2026-08-07 as the SMTP-based replacement for the retired N8N daily-Peter-email workflow (REVqxrlAb3CHJumM). +--- + +You are running the daily content-focus email for Graeham Watts (REALTOR, Intero Real Estate, DRE #01466876). This drives the recurring team cadence documented in `skills/content-calendar/SKILL.md` under "Email Delivery — recipients & cadence (LOCKED — do not re-ask)". Read that section before your first run — it is the source of truth for recipients and cadence; do not re-derive or re-ask. + +RECIPIENTS (hardcoded — content/video team, NOT Adrian): +- **To:** John (blog/SEO) `graehamwattsmarketing@gmail.com`, Peter (video) `graehamwattsvideo@gmail.com`, Ellie (video) `graehamwattsvideo2@gmail.com` +- **Cc:** Graeham `graehamwatts@gmail.com` + +DELIVERY: SEND directly via SMTP using `skills/switchy-engine/scripts/send_email.py` (Gmail app password read at send time from `Documents/Claude/Skills/gmail-app-password.txt`, never printed). Do NOT use the Gmail MCP for this — it only creates drafts, and these are internal team emails meant to land in the inbox, not sit unread in Drafts. Do NOT stand the old N8N workflow (`REVqxrlAb3CHJumM`, instance `n8n.graehamwattsn8n.com`) back up — it's retired; this scheduled task is its replacement. + +STEP 0 — Determine today's branch. +Read the system date. Monday → STEP 1 (weekly plan). Tuesday–Friday → STEP 2 (daily focus). Saturday/Sunday → do nothing, exit. + +--- + +STEP 1 — MONDAY: Build and ship the weekly plan. + +1a. Run the `content-calendar` skill's weekly planning workflow (performance pull, search demand, Reddit/audience signal, competitor scan, scoring — see `skills/content-calendar/SKILL.md`) to produce this week's calendar JSON. Save it to `skills/content-creation-engine/outputs/calendar-data/calendar-{YYYY-MM-DD}.json` (Monday's date), matching the schema `weekly-calendar-builder.py` validates (`week_of`, `generated_at`, `goal`, `funnel_mix`, `topics[]` with `slug`, `title`, `day`, `scheduled_date`, `primary_format`, `funnel_tier`, `ghl_keyword`, `opportunity_score`, `priority_axes`, `time_decay_band`, `justification_notes`). + +1b. **Gate 1 — overlap check (before anything else touches this calendar):** +``` +python skills/content-creation-engine/scripts/weekly_overlap_check.py --calendar skills/content-creation-engine/outputs/calendar-data/calendar-{YYYY-MM-DD}.json +``` +Exit 1 means a topic overlaps the last 4 weeks (history + in-production). Replace the topic or write a justification into the calendar's `justification_notes` before proceeding — do not ship a HIGH-risk overlap silently. + +1c. Render the dashboard: +``` +python skills/content-calendar/templates/weekly-calendar-builder.py skills/content-creation-engine/outputs/calendar-data/calendar-{YYYY-MM-DD}.json online-content/dashboards/weekly-calendars/{YYYY-MM-DD}-production-calendar-v6.html +``` +Follow `skills/content-creation-engine/references/weekly-dashboard-rules.md` (Rules 9-11: no orphan hrefs, all 10 required sections, single canonical file — no `-all`/`-blogs`/`-videos`/`-research` variants) and `skills/website-builder/references/screenshot-loop.md` (min 1 iteration) before publishing. + +1d. **Gate 2 — brand/DRE + truncation check (before sending or publishing):** +``` +python skills/content-creation-engine/scripts/verify_output_brand.py online-content/dashboards/weekly-calendars/{YYYY-MM-DD}-production-calendar-v6.html +``` +This is a fail-closed gate (mirrors the old N8N "Validate Date + DRE" node): exit 2 means a blocked brand value (the blocklisted DRE in `skills/shared-references/identity.json`) or a truncated file. On failure, STOP — do not publish, do not send. Instead send ONE alert email to `graehamwatts@gmail.com` only, subject `[ALERT] Weekly content calendar failed brand/DRE gate`, body naming the exact failure, and end the run. + +1e. Push the HTML (and the calendar JSON alongside it, for Tue-Fri to read) to GitHub Pages per the repo's publish flow, then confirm the live URL loads. + +1f. **Gate 3 — topic history (after the calendar ships, not before):** +``` +python skills/content-creation-engine/scripts/update_topic_history.py --calendar skills/content-creation-engine/outputs/calendar-data/calendar-{YYYY-MM-DD}.json +``` +Skipping this silently breaks next week's freshness/overlap check — do not skip it. + +1g. Send the weekly email. To the recipients above, subject `Week of {Mon date}: Content Production Plan`. Body: the full 5-topic plan (day, title, format, funnel tier, GHL keyword, one-line hook per topic) plus the live dashboard link. Attach the rendered HTML (or link only if the attachment is large — link is sufficient since the dashboard is the actual production surface). Send via `send_email.py`: +``` +python skills/switchy-engine/scripts/send_email.py \ + --to graehamwattsmarketing@gmail.com --to graehamwattsvideo@gmail.com --to graehamwattsvideo2@gmail.com --to graehamwatts@gmail.com \ + --subject "Week of {Mon date}: Content Production Plan" \ + --html-file +``` + +--- + +STEP 2 — TUESDAY-FRIDAY: Daily focus email. + +2a. Locate this week's calendar JSON: the newest `skills/content-creation-engine/outputs/calendar-data/calendar-*.json` whose `week_of` covers today. If none exists (Monday's run failed or was skipped), send the alert email from 1d instead (`[ALERT] No live weekly calendar found for today's focus email`) and stop — do not guess a topic. + +2b. From `topics[]`, filter to the entry whose `day` matches today's weekday name. If more than one topic is scheduled for today, include all of them. + +2c. **Gate — reuse Gate 2** (`verify_output_brand.py`) against the composed email body before sending. Same fail-closed rule: on failure, alert Graeham only, do not send to the team. + +2d. Compose and send a short "Today's Content Focus" email. Subject: `Today's Content Focus — {weekday}, {date}`. Body, per topic: title, primary format, the hook (first 3 seconds / opening line), GHL keyword + CTA, funnel tier, and a deep link to the topic's section on the live dashboard (`{dashboard_url}#topic-{slug}`, per the anchor convention in `skills/content-calendar/references/dashboard-architecture.md`). Keep it short — this is a reminder/trigger, not the production package itself; the linked dashboard and, if it exists, the topic's single-topic production dashboard are where the actual scripts/prompts live. Send the same way as 1g, to the same recipient list, same DRE/date QC rules (`skills/content-creation-engine/references/production-hardening.md` — Date & Year QC block) applied to any stat or date mentioned in the email body. + +--- + +GUARDRAILS: +- Never send to a past-client or external address — this task's only recipients are the four addresses listed above. +- Never skip Gate 2 (brand/DRE) before a send, Monday or daily. It exists because a wrong DRE has leaked into shipped content ten times before (see `shared-references/dre-leak-incident-log.md`) — the gate is what stops the eleventh. +- If the Gmail app password file is missing, `send_email.py` will exit non-zero rather than silently failing to send — treat that as a hard stop, report it to Graeham, do not fall back to a Gmail draft (the whole point of this task is that a draft doesn't get seen). +- Do not modify `pcfs-cma-autobuild-weekly` — unrelated task, same folder tree. + +STEP 3 — Report back. +Summarize for Graeham: which branch ran (weekly/daily), which gates passed/failed, who the email went to, and the live dashboard URL if applicable. Keep it concise. diff --git a/skills/content-creation-engine/SKILL.md b/skills/content-creation-engine/SKILL.md index adaa2731..910c7fe3 100644 --- a/skills/content-creation-engine/SKILL.md +++ b/skills/content-creation-engine/SKILL.md @@ -615,7 +615,7 @@ All phase outputs save to the user's selected folder (or `outputs/` in Cowork). ## Workflow Quality Rules — MUST ride along in every script + production copy (June 2026) -These rules fix the recurring generation failures (voice garbles, uptalk, weak/scarce b-roll, generic maps). Mandatory for every content package, and they MUST be prepended to: every **Copy Script Prompt**, every **Copy Production Prompt**, and the **daily Peter email** (N8N workflow `REVqxrlAb3CHJumM`) so whoever pastes the copy into Claude gets the rules inline. +These rules fix the recurring generation failures (voice garbles, uptalk, weak/scarce b-roll, generic maps). Mandatory for every content package, and they MUST be prepended to: every **Copy Script Prompt**, every **Copy Production Prompt**, and the **daily content-focus email** (Cowork scheduled task `daily-content-focus-email` — see `scheduled-tasks/daily-content-focus-email/SKILL.md`; supersedes the retired N8N workflow `REVqxrlAb3CHJumM`) so whoever pastes the copy into Claude gets the rules inline. **Voice / SSML (full detail in `references/phases/script-writer/references/elevenlabs-audio-tags.md`):** NO em/en dashes in the ElevenLabs variant (periods, commas, or ``); question marks ONLY on real questions (a trailing `?` causes uptalk); spell out numbers/currency/symbols; end every statement with a period; synthesize sentence-by-sentence and QC each chunk (Whisper diff), re-roll only the bad sentence. diff --git a/skills/content-creation-engine/references/production-hardening.md b/skills/content-creation-engine/references/production-hardening.md index 32173f1c..c07274cc 100644 --- a/skills/content-creation-engine/references/production-hardening.md +++ b/skills/content-creation-engine/references/production-hardening.md @@ -33,9 +33,11 @@ Manual builds: run this gate as the final step before pushing or sending, and re Automated daily email: the gate is implemented as the **Validate Date + DRE** Code node in the N8N workflow below. The date is injected from the system clock in the **Compute Today** node (never guessed), and the validation node fails closed — on failure the workflow routes to an alert to Graeham instead of sending to Peter. -## Daily Automation — Peter's Daily Email (N8N) +## Daily Automation — Peter's Daily Email (N8N) — SUPERSEDED 2026-08-07 -A weekday email to Peter is produced by the N8N workflow **"Daily Content Email — Peter (script + SSML + production)"** (instance `n8n.graehamwattsn8n.com`, workflow id `REVqxrlAb3CHJumM`). It complements the weekly dashboard: Peter can work from the dashboard OR act straight from the email. +> **This N8N workflow is retired and must not be stood back up.** `content-calendar/SKILL.md`'s "Email Delivery" section replaced it with a Cowork scheduled task, `scheduled-tasks/daily-content-focus-email/SKILL.md`, which sends to John/Peter/Ellie (cc Graeham) via SMTP (`switchy-engine/scripts/send_email.py`) instead of N8N + OpenAI. The fail-closed Date/DRE gate concept described below still applies — the new task enforces it via `weekly_overlap_check.py` and `verify_output_brand.py` instead of the N8N "Validate Date + DRE" Code node. The rest of this section is kept for historical reference only. + +A weekday email to Peter was produced by the N8N workflow **"Daily Content Email — Peter (script + SSML + production)"** (instance `n8n.graehamwattsn8n.com`, workflow id `REVqxrlAb3CHJumM`). It complemented the weekly dashboard: Peter could work from the dashboard OR act straight from the email. Flow: Schedule (Mon-Fri 6:00 AM PT) → CONFIG (`peter_email`, `cc_email`, `dashboard_url`) → Compute Today (system date → topic t1..t5, Mon=t1) → Fetch Dashboard HTML (the live weekly calendar is the single source of truth) → Parse Topic (pulls that day's `prod_script` + `prod_video` out of `COPY_DATA`) → Generate (OpenAI runs both prompts: script + SSML, then production assets) → Validate Date + DRE (fail-closed gate above) → IF passed → Email Peter (dashboard link + the day's full package); ELSE → Alert Graeham.