Files
agent-estate-wiki/public/runbooks/job-radar.html
T
Tony0410 d129b70237 fix: serve quartz with clean URL support and regenerate site
- Add serve.py to resolve clean Quartz URLs to .html files
- Regenerate Quartz site with correct baseUrl http://100.118.5.51:9120
- 196 HTML files emitted; all internal links now resolve
2026-08-15 23:35:16 +08:00

336 lines
55 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en" dir="ltr"><head><title>Daily Marketing Job Radar Operations and Recovery</title><meta charset="utf-8"/><link rel="preload" href="../index-bb6c1746.css" as="style"/><link rel="preload" href="../prescript-2bfc6315.js" as="script"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com"/><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Schibsted Grotesk:wght@400;700&amp;family=Source Sans Pro:ital,wght@0,400;0,600;1,400;1,600&amp;family=IBM Plex Mono:wght@400;600&amp;display=swap"/><link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin="anonymous"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta name="og:site_name" content="Agent Estate Wiki"/><meta property="og:title" content="Daily Marketing Job Radar Operations and Recovery"/><meta property="og:type" content="website"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:title" content="Daily Marketing Job Radar Operations and Recovery"/><meta name="twitter:description" content="Daily Marketing Job Radar Operations and Recovery Purpose Run a verified Western Australian marketing-job search, deduplicate against the complete Notion board, create only fresh direct adverts, score new roles against Anthonys resume, automatically produce cover letters for strong matches, and exp..."/><meta property="og:description" content="Daily Marketing Job Radar Operations and Recovery Purpose Run a verified Western Australian marketing-job search, deduplicate against the complete Notion board, create only fresh direct adverts, score new roles against Anthonys resume, automatically produce cover letters for strong matches, and exp..."/><meta property="og:image:alt" content="Daily Marketing Job Radar Operations and Recovery Purpose Run a verified Western Australian marketing-job search, deduplicate against the complete Notion board, create only fresh direct adverts, score new roles against Anthonys resume, automatically produce cover letters for strong matches, and exp..."/><meta property="twitter:domain" content="http://100.118.5.51:9120"/><meta property="og:url" content="https://http//100.118.5.51:9120/runbooks/job-radar"/><meta property="twitter:url" content="https://http//100.118.5.51:9120/runbooks/job-radar"/><link rel="icon" href="../static/icon.png"/><meta name="description" content="Daily Marketing Job Radar Operations and Recovery Purpose Run a verified Western Australian marketing-job search, deduplicate against the complete Notion board, create only fresh direct adverts, score new roles against Anthonys resume, automatically produce cover letters for strong matches, and exp..."/><meta name="generator" content="Quartz"/><link href="../index-bb6c1746.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-735924e0.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-589c1cea.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-bbc3f7c0.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-2911f5d1.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-e427079e.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-53b25b2b.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-c93c6a44.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-8a06014f.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-77d6a441.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-6ee21cee.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-1ea6ad18.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-34bdfded.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-788c9ca3.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-642859cd.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-4abc06bd.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-274a3dfe.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-94cb6c84.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-58d5ff56.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../component-7262b5a7.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../static/resource-style-a5c806d2.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../static/resource-style-6bd36952.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../static/resource-style-9857b007.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="../static/resource-style-d3a1a224.css" rel="stylesheet" type="text/css" data-persist="true"/><link href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" rel="stylesheet" type="text/css" data-persist="true"/><script src="../prescript-2bfc6315.js" type="application/javascript" data-persist="true"></script><script type="application/javascript" data-persist="true">const fetchData = fetch("../static/contentIndex.json").then(data => data.json())</script><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous"/><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Schibsted%20Grotesk%3Awght%40400%3B700&amp;family=Source%20Sans%20Pro%3Aital%2Cwght%400%2C400%3B0%2C600%3B1%2C400%3B1%2C600&amp;family=IBM%20Plex%20Mono%3Awght%40400%3B600&amp;display=swap"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image" content="https://http://100.118.5.51:9120/runbooks/job-radar-og-image.webp"/><meta property="og:image:url" content="https://http://100.118.5.51:9120/runbooks/job-radar-og-image.webp"/><meta name="twitter:image" content="https://http://100.118.5.51:9120/runbooks/job-radar-og-image.webp"/><meta property="og:image:type" content="image/webp"/></head><body data-slug="runbooks/job-radar" data-basepath="//100.118.5.51:9120"><div id="quartz-root" class="page" data-frame="default"><div id="quartz-body"><div class="left sidebar"><h2 class="page-title"><a href="..">Agent Estate Wiki</a></h2><div class="mobile-only"><div class="spacer"></div></div><div class="flex-component" style="flex-direction: row; flex-wrap: nowrap; gap: 0.5rem;"><div style="flex-grow: 1; flex-shrink: 1; flex-basis: auto; order: 0; align-self: center; justify-self: center;"><div class="search"><button class="search-button" aria-label="Search" aria-expanded="false"><svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.9 19.7"><title>Search</title><g class="search-path" fill="none"><path stroke-linecap="square" d="M18.5 18.3l-5.4-5.4"></path><circle cx="8" cy="8" r="7"></circle></g></svg><p>Search</p></button><div class="search-container"><div class="search-space"><input autocomplete="off" class="search-bar" name="search" type="text" aria-label="Search for something..." placeholder="Search for something..."/><div class="search-layout" data-preview="true" data-field-priority="[&quot;title&quot;,&quot;content&quot;,&quot;tags&quot;]"></div></div></div></div></div><div style="flex-grow: 0; flex-shrink: 1; flex-basis: auto; order: 0; align-self: center; justify-self: center;"><button class="darkmode" aria-label="Dark mode"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class="dayIcon" x="0px" y="0px" viewBox="0 0 35 35" style="enable-background:new 0 0 35 35" xml:space="preserve" aria-label="Dark mode"><title>Dark mode</title><path d="M6,17.5C6,16.672,5.328,16,4.5,16h-3C0.672,16,0,16.672,0,17.5 S0.672,19,1.5,19h3C5.328,19,6,18.328,6,17.5z M7.5,26c-0.414,0-0.789,0.168-1.061,0.439l-2,2C4.168,28.711,4,29.086,4,29.5 C4,30.328,4.671,31,5.5,31c0.414,0,0.789-0.168,1.06-0.44l2-2C8.832,28.289,9,27.914,9,27.5C9,26.672,8.329,26,7.5,26z M17.5,6 C18.329,6,19,5.328,19,4.5v-3C19,0.672,18.329,0,17.5,0S16,0.672,16,1.5v3C16,5.328,16.671,6,17.5,6z M27.5,9 c0.414,0,0.789-0.168,1.06-0.439l2-2C30.832,6.289,31,5.914,31,5.5C31,4.672,30.329,4,29.5,4c-0.414,0-0.789,0.168-1.061,0.44 l-2,2C26.168,6.711,26,7.086,26,7.5C26,8.328,26.671,9,27.5,9z M6.439,8.561C6.711,8.832,7.086,9,7.5,9C8.328,9,9,8.328,9,7.5 c0-0.414-0.168-0.789-0.439-1.061l-2-2C6.289,4.168,5.914,4,5.5,4C4.672,4,4,4.672,4,5.5c0,0.414,0.168,0.789,0.439,1.06 L6.439,8.561z M33.5,16h-3c-0.828,0-1.5,0.672-1.5,1.5s0.672,1.5,1.5,1.5h3c0.828,0,1.5-0.672,1.5-1.5S34.328,16,33.5,16z M28.561,26.439C28.289,26.168,27.914,26,27.5,26c-0.828,0-1.5,0.672-1.5,1.5c0,0.414,0.168,0.789,0.439,1.06l2,2 C28.711,30.832,29.086,31,29.5,31c0.828,0,1.5-0.672,1.5-1.5c0-0.414-0.168-0.789-0.439-1.061L28.561,26.439z M17.5,29 c-0.829,0-1.5,0.672-1.5,1.5v3c0,0.828,0.671,1.5,1.5,1.5s1.5-0.672,1.5-1.5v-3C19,29.672,18.329,29,17.5,29z M17.5,7 C11.71,7,7,11.71,7,17.5S11.71,28,17.5,28S28,23.29,28,17.5S23.29,7,17.5,7z M17.5,25c-4.136,0-7.5-3.364-7.5-7.5 c0-4.136,3.364-7.5,7.5-7.5c4.136,0,7.5,3.364,7.5,7.5C25,21.636,21.636,25,17.5,25z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class="nightIcon" x="0px" y="0px" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100" xml:space="preserve" aria-label="Light mode"><title>Light mode</title><path d="M96.76,66.458c-0.853-0.852-2.15-1.064-3.23-0.534c-6.063,2.991-12.858,4.571-19.655,4.571 C62.022,70.495,50.88,65.88,42.5,57.5C29.043,44.043,25.658,23.536,34.076,6.47c0.532-1.08,0.318-2.379-0.534-3.23 c-0.851-0.852-2.15-1.064-3.23-0.534c-4.918,2.427-9.375,5.619-13.246,9.491c-9.447,9.447-14.65,22.008-14.65,35.369 c0,13.36,5.203,25.921,14.65,35.368s22.008,14.65,35.368,14.65c13.361,0,25.921-5.203,35.369-14.65 c3.872-3.871,7.064-8.328,9.491-13.246C97.826,68.608,97.611,67.309,96.76,66.458z"></path></svg></button></div><div style="flex-grow: 0; flex-shrink: 1; flex-basis: auto; order: 0; align-self: center; justify-self: center;"><button class="readermode" aria-label="Reader mode"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class="readerIcon" fill="currentColor" stroke="currentColor" stroke-width="0.2" stroke-linecap="round" stroke-linejoin="round" width="64px" height="64px" viewBox="0 0 24 24" aria-label="Reader mode"><title>Reader mode</title><g transform="translate(-1.8, -1.8) scale(1.15, 1.2)"><path d="M8.9891247,2.5 C10.1384702,2.5 11.2209868,2.96705384 12.0049645,3.76669482 C12.7883914,2.96705384 13.8709081,2.5 15.0202536,2.5 L18.7549359,2.5 C19.1691495,2.5 19.5049359,2.83578644 19.5049359,3.25 L19.5046891,4.004 L21.2546891,4.00457396 C21.6343849,4.00457396 21.9481801,4.28672784 21.9978425,4.6528034 L22.0046891,4.75457396 L22.0046891,20.25 C22.0046891,20.6296958 21.7225353,20.943491 21.3564597,20.9931534 L21.2546891,21 L2.75468914,21 C2.37499337,21 2.06119817,20.7178461 2.01153575,20.3517706 L2.00468914,20.25 L2.00468914,4.75457396 C2.00468914,4.37487819 2.28684302,4.061083 2.65291858,4.01142057 L2.75468914,4.00457396 L4.50368914,4.004 L4.50444233,3.25 C4.50444233,2.87030423 4.78659621,2.55650904 5.15267177,2.50684662 L5.25444233,2.5 L8.9891247,2.5 Z M4.50368914,5.504 L3.50468914,5.504 L3.50468914,19.5 L10.9478955,19.4998273 C10.4513189,18.9207296 9.73864328,18.5588115 8.96709342,18.5065584 L8.77307039,18.5 L5.25444233,18.5 C4.87474657,18.5 4.56095137,18.2178461 4.51128895,17.8517706 L4.50444233,17.75 L4.50368914,5.504 Z M19.5049359,17.75 C19.5049359,18.1642136 19.1691495,18.5 18.7549359,18.5 L15.2363079,18.5 C14.3910149,18.5 13.5994408,18.8724714 13.0614828,19.4998273 L20.5046891,19.5 L20.5046891,5.504 L19.5046891,5.504 L19.5049359,17.75 Z M18.0059359,3.999 L15.0202536,4 L14.8259077,4.00692283 C13.9889509,4.06666544 13.2254227,4.50975805 12.7549359,5.212 L12.7549359,17.777 L12.7782651,17.7601316 C13.4923805,17.2719483 14.3447024,17 15.2363079,17 L18.0059359,16.999 L18.0056891,4.798 L18.0033792,4.75457396 L18.0056891,4.71 L18.0059359,3.999 Z M8.9891247,4 L6.00368914,3.999 L6.00599909,4.75457396 L6.00599909,4.75457396 L6.00368914,4.783 L6.00368914,16.999 L8.77307039,17 C9.57551536,17 10.3461406,17.2202781 11.0128313,17.6202194 L11.2536891,17.776 L11.2536891,5.211 C10.8200889,4.56369974 10.1361548,4.13636104 9.37521067,4.02745763 L9.18347055,4.00692283 L8.9891247,4 Z"></path></g></svg></button></div></div><div class="explorer nav-files-container" data-behavior="link" data-collapsed="collapsed" data-savestate="true" data-data-fns="{&quot;order&quot;:[&quot;filter&quot;,&quot;map&quot;,&quot;sort&quot;],&quot;sortFn&quot;:&quot;(a2, b2) => {\n if (!a2.isFolder &amp;&amp; !b2.isFolder || a2.isFolder &amp;&amp; b2.isFolder) {\n return (a2.displayName || \&quot;\&quot;).localeCompare(b2.displayName || \&quot;\&quot;, void 0, {\n numeric: true,\n sensitivity: \&quot;base\&quot;\n });\n }\n if (!a2.isFolder &amp;&amp; b2.isFolder) {\n return 1;\n }\n return -1;\n }&quot;,&quot;filterFn&quot;:&quot;(node) => node.slugSegment !== \&quot;tags\&quot;&quot;,&quot;mapFn&quot;:&quot;(node) => {\n return node;\n }&quot;}"><button type="button" class="explorer-toggle mobile-explorer hide-until-loaded" data-mobile="true" aria-controls="explorer-44" aria-label="Explorer"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide-menu"><line x1="4" x2="20" y1="12" y2="12"></line><line x1="4" x2="20" y1="6" y2="6"></line><line x1="4" x2="20" y1="18" y2="18"></line></svg></button><button type="button" class="title-button explorer-toggle desktop-explorer" data-mobile="false" aria-expanded="true"><h2>Explorer</h2><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="5 8 14 8" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="fold"><polyline points="6 9 12 15 18 9"></polyline></svg></button><div id="explorer-44" class="explorer-content" aria-expanded="false" role="group"><ul class="explorer-ul overflow" id="list-0"><li class="overflow-end"></li></ul></div><template id="template-file"><li><a href="#" class="nav-file-title tree-item-self"></a></li></template><template id="template-folder"><li><div class="folder-container nav-folder-title tree-item-self"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="5 8 14 8" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="folder-icon nav-folder-collapse-indicator collapse-icon"><polyline points="6 9 12 15 18 9"></polyline></svg><div><button class="folder-button"><span class="folder-title"></span></button></div></div><div class="folder-outer"><ul class="content tree-item-children"></ul></div></li></template></div></div><div class="center"><div class="page-header"><div class="popover-hint"><nav class="breadcrumb-container" aria-label="breadcrumbs"><div class="breadcrumb-element"><a href="../">Home</a><p> </p></div><div class="breadcrumb-element"><a href="../runbooks/">runbooks</a><p> </p></div><div class="breadcrumb-element"><a href>Daily Marketing Job Radar Operations and Recovery</a></div></nav><h1 class="article-title">Daily Marketing Job Radar Operations and Recovery</h1><details class="note-properties metadata-container" open data-collapsed="false"><summary class="note-properties-header"><span class="note-properties-title">Properties</span><span class="note-properties-count">1</span></summary><table class="note-properties-table"><tbody><tr class="note-properties-row metadata-property"><td class="note-properties-key metadata-property-key">tags</td><td class="note-properties-value metadata-property-value"><span class="note-properties-tags"><a href="../tags/automation" class="internal internal-link tag-link">automation</a><span class="note-properties-separator">, </span><a href="../tags/cron" class="internal internal-link tag-link">cron</a><span class="note-properties-separator">, </span><a href="../tags/jobs" class="internal internal-link tag-link">jobs</a><span class="note-properties-separator">, </span><a href="../tags/notion" class="internal internal-link tag-link">notion</a><span class="note-properties-separator">, </span><a href="../tags/dashboard" class="internal internal-link tag-link">dashboard</a><span class="note-properties-separator">, </span><a href="../tags/runbook" class="internal internal-link tag-link">runbook</a></span></td></tr></tbody></table></details><p show-comma="true" class="content-meta"><time datetime="2026-07-27T16:00:00.000Z">Jul 28, 2026</time><span>8 min read</span></p></div></div><article class="popover-hint"><div class="markdown-preview-view markdown-rendered"><h1 id="daily-marketing-job-radar-operations-and-recovery">Daily Marketing Job Radar Operations and Recovery<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#daily-marketing-job-radar-operations-and-recovery" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h1>
<h2 id="purpose">Purpose<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#purpose" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<p>Run a verified Western Australian marketing-job search, deduplicate against the complete Notion board, create only fresh direct adverts, score new roles against Anthonys resume, automatically produce cover letters for strong matches, and expose the results through the Jobs Radar dashboard.</p>
<h2 id="production-configuration">Production configuration<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#production-configuration" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<div class="table-container"><table><thead><tr><th>Setting</th><th>Value</th></tr></thead><tbody><tr><td>Cron job</td><td><code>dca8482e4f76</code> — Daily Marketing Job Radar</td></tr><tr><td>Schedule</td><td><code>0 7 * * 1-5</code> (07:00 AWST weekdays)</td></tr><tr><td>Delivery</td><td>Telegram group <code>-1004321904721</code>, topic <code>1030</code></td></tr><tr><td>Skill</td><td><code>job-search-automation</code></td></tr><tr><td>Primary model</td><td><code>openai-codex / gpt-5.6-terra</code></td></tr><tr><td>First fallback</td><td><code>opencode-go / mimo-v2.5</code></td></tr><tr><td>Dashboard</td><td><code>https://hermes.kangaroo-eel.ts.net/jobs/</code></td></tr><tr><td>Dashboard backend</td><td><code>127.0.0.1:9099</code></td></tr><tr><td>Notion database</td><td><code>0f90ba2b-8b10-4d02-a62c-6f692d5b1168</code></td></tr></tbody></table></div>
<p>Cron jobs inherit the profile-level <code>fallback_providers</code> chain; Hermes does not currently store a separate fallback chain in each cron record. MiMo v2.5 is first in the global chain, so Terra fails over to it before the older fallbacks.</p>
<h2 id="cover-letters-are-non-negotiable">Cover letters are non-negotiable<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#cover-letters-are-non-negotiable" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<p>A successful radar run includes the cover-letter stage.</p>
<ul>
<li>Audit <strong>every Strong Match added today</strong>, including pages created by an interrupted earlier run.</li>
<li>A valid result requires a canonical rendered <code>.html</code> URL in Notion, not plain text and not the dashboard root.</li>
<li>Production template files:
<ul>
<li><code>/home/hermes/.hermes/dashboard/templates/cover-letter.html</code></li>
<li><code>/home/hermes/.hermes/dashboard/templates/Anthony_Martin_Cover_Letter_Template.docx</code></li>
</ul>
</li>
<li>The old upload-cache location is not authoritative and may be evicted.</li>
<li>Required nonempty artifacts: <code>.txt</code>, <code>.json</code>, <code>.html</code>, <code>.docx</code>, <code>.pdf</code>.</li>
<li>The HTML must contain zero unresolved <code>{{...}}</code> tokens and return HTTP 200.</li>
<li>Retry generation once when an artifact, Notion link or HTTP check fails.</li>
<li>A clean run requires <code>MISSING_COVER_LETTER_COUNT=0</code>. Any remaining missing letter must be reported prominently with its Notion page ID; it must never be silently omitted.</li>
</ul>
<h3 id="live-audit--27-july-2026">Live audit — 27 July 2026<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#live-audit--27-july-2026" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h3>
<ul>
<li>Same-day strong matches: <strong>1</strong></li>
<li>Verified canonical HTML cover letters: <strong>1</strong></li>
<li>Missing cover letters: <strong>0</strong></li>
<li>The Market Creations Agency strong match has all five artifact formats, zero unresolved template tokens and a live HTTP 200 HTML link.</li>
</ul>
<h2 id="required-production-pipeline">Required production pipeline<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#required-production-pipeline" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<ol>
<li>Obtain the live AWST date and calculate a seven-day freshness cutoff.</li>
<li>Search SEEK, LinkedIn, Indeed, WA Government Jobs and direct employer sites.</li>
<li>Open and verify every individual advert. Search snippets are discovery evidence only.</li>
<li>Reject stale, expired, cached, interstate, non-marketing, salary-guide, search/category and aggregator pages.</li>
<li>Reject <strong>all Pacific Energy roles</strong>. Anthony was made redundant there in July 2026; old Pacific Energy adverts must never be presented as opportunities.</li>
<li>Accept only direct individual advert URLs:
<ul>
<li>SEEK <code>/job/&lt;numeric-id></code></li>
<li>LinkedIn <code>/jobs/view/...&lt;numeric-id></code></li>
<li>Indeed <code>/viewjob?jk=&lt;real-id></code></li>
<li>direct employer career pages</li>
<li>individual WA Government role pages</li>
</ul>
</li>
<li>A WA Government slug page is valid without <code>AdvertID</code> in its URL when the page proves the exact role and agency, WA location, unique job/pool reference, future closing date and active <strong>Apply Now</strong> function.</li>
<li>Query the complete Notion database with live pagination. Deduplicate by exact URL, normalized company plus role, and materially similar company-role combinations.</li>
<li>Create only verified nonduplicates and require returned Notion page IDs.</li>
<li>Refresh <code>POST http://127.0.0.1:9099/api/refresh</code>, then confirm every page and direct URL through <code>/api/jobs</code>.</li>
<li>Score newly created roles against <code>/home/hermes/.hermes/radar-ref/resumes/current_resume_from_website.txt</code> using the documented 100-point rubric. Strong Match starts at 70.</li>
<li>For each new strong match, run:</li>
</ol>
<figure data-rehype-pretty-code-figure><pre tabindex="0" data-language="bash" data-theme="github-light github-dark"><code data-language="bash" data-theme="github-light github-dark" style="display:grid;"><span data-line><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;" data-token-type="function">/home/hermes/.hermes/hermes-agent/venv/bin/python</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;" data-token-type="string"> \</span></span>
<span data-line><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> /home/hermes/.hermes/scripts/regenerate_cover_letter.py</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;" data-token-type="string"> \</span></span>
<span data-line><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;" data-token-type="operator"> &lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string">NOTION_PAGE_I</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">D</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;" data-token-type="operator">></span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;" data-token-type="string"> \</span></span>
<span data-line><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> &quot;Generate the initial tailored cover letter using the verified job description. Preserve Anthony's factual employment history and use the canonical teal Montserrat template.&quot;</span></span></code></pre></figure>
<ol start="13">
<li>Verify nonempty <code>.txt</code>, <code>.json</code>, <code>.html</code>, <code>.docx</code> and <code>.pdf</code> artifacts; no unresolved <code>{{...}}</code> tokens; and a live <code>.html</code> Notion Cover Letter URL.</li>
<li>Report only facts produced by tools in that run. Never estimate counts or fabricate Notion writes.</li>
</ol>
<h2 id="dashboard-behaviour">Dashboard behaviour<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#dashboard-behaviour" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<p>Source: <code>/home/hermes/.hermes/dashboard/index.html</code><br/>
Backend: <code>/home/hermes/.hermes/scripts/job_dashboard_server.py</code></p>
<h3 id="layout-top-to-bottom">Layout (top to bottom)<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#layout-top-to-bottom" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h3>
<ol>
<li><strong>Hero header</strong> — RADAR logo, name, dateline</li>
<li><strong>Market Intel panel</strong> — expandable salary/location/source stats from <code>/api/market-intel</code></li>
<li><strong>KPI strip</strong> — clickable filter cards: Total Jobs, Backlog, Applied, Phone Screen, Interviews, Offers, Closing Soon</li>
<li><strong>Filter bar</strong> — text search, view toggles (table/cards), Refresh button</li>
<li><strong>Stats strip</strong> — This Week, Stale 14d+, Strong Match, Past Close, Applied Rate</li>
<li><strong>Pipeline Funnel</strong> — clickable per-status breakdown with bar chart</li>
<li><strong>Job table/cards</strong> — sortable columns, inline status pills, cover letter links, edit actions</li>
</ol>
<h3 id="column-sorting">Column sorting<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#column-sorting" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h3>
<p>Click any column header (Status, Company, Role, Match, Salary, Age, Closes, Updated) to sort ascending; click again for descending. Arrow indicator shows current direction.</p>
<h3 id="status-management">Status management<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#status-management" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h3>
<ul>
<li><strong>Bulk update</strong>: select jobs via checkboxes → pick status from dropdown → Apply. Sends <code>{ids, updates: {status}}</code> to <code>POST /api/jobs/bulk-update</code>.</li>
<li><strong>Single edit</strong>: click ✎ → modal with Status, Priority, Role, Salary, Closing Date, URL, Notes, Cover Letter, Attachments. Saves to Notion via <code>POST /api/jobs/&lt;id>/update</code>.</li>
<li><strong>Funnel/status filters</strong>: clicking a status in the funnel or KPI strip filters the table to that status.</li>
</ul>
<h3 id="rich-text-notes">Rich text notes<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#rich-text-notes" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h3>
<ul>
<li>Write/Preview editor in the edit modal (monospace textarea + markdown preview)</li>
<li>Supports: bold <code>**</code>, italic <code>*</code>, links <code>[text](url)</code>, bullet lists <code>- item</code></li>
<li>Syncs to Notion <code>Notes / JD Summary</code> rich_text property on every save</li>
</ul>
<h3 id="document-attachments">Document attachments<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#document-attachments" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h3>
<ul>
<li>Attach any URL (documents, links, files) to a job entry</li>
<li>Stored as <strong>bookmark blocks</strong> on the Notion page body (not a property)</li>
<li>Lazy-loaded when edit modal opens: <code>GET /api/jobs/&lt;id>/attachments</code></li>
<li>Add: <code>POST /api/jobs/&lt;id>/attachments</code> with <code>{name, url}</code></li>
<li>Delete: <code>POST /api/jobs/&lt;id>/attachments/delete</code> with <code>{block_id}</code></li>
<li>Visible in Notion when you open the page</li>
</ul>
<h3 id="cover-letter-integration">Cover letter integration<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#cover-letter-integration" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h3>
<ul>
<li>Regenerate button (🔄) on each row calls <code>POST /api/jobs/&lt;id>/cover-letter/regenerate</code></li>
<li>CL URL stored in Notion <code>Cover Letter</code> property and rendered as clickable link in table</li>
<li>All 5 artifact formats: TXT, JSON, HTML, DOCX, PDF</li>
</ul>
<h3 id="market-intel">Market Intel<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#market-intel" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h3>
<ul>
<li>Expandable panel at top of page</li>
<li>Data from <code>GET /api/market-intel</code>: total tracked, salary stats (avg/median/min/max), counts</li>
<li>Lazy-loaded on expand; also refreshes on ↺ Refresh</li>
</ul>
<h3 id="api-endpoints">API endpoints<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#api-endpoints" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h3>
<div class="table-container"><table><thead><tr><th>Endpoint</th><th>Method</th><th>Purpose</th></tr></thead><tbody><tr><td><code>/api/jobs</code></td><td>GET</td><td>All jobs (cached, paginated from Notion)</td></tr><tr><td><code>/api/stats</code></td><td>GET</td><td>Aggregate statistics</td></tr><tr><td><code>/api/refresh</code></td><td>POST</td><td>Force Notion cache refresh</td></tr><tr><td><code>/api/market-intel</code></td><td>GET</td><td>Salary/location/source analytics</td></tr><tr><td><code>/api/jobs/&lt;id>/update</code></td><td>POST</td><td>Update single job properties</td></tr><tr><td><code>/api/jobs/&lt;id>/attachments</code></td><td>GET</td><td>Fetch page block attachments</td></tr><tr><td><code>/api/jobs/&lt;id>/attachments</code></td><td>POST</td><td>Add bookmark attachment to page</td></tr><tr><td><code>/api/jobs/&lt;id>/attachments/delete</code></td><td>POST</td><td>Remove block from page</td></tr><tr><td><code>/api/jobs/&lt;id>/cover-letter/regenerate</code></td><td>POST</td><td>Regenerate cover letter</td></tr><tr><td><code>/api/jobs/&lt;id>/match</code></td><td>GET</td><td>Match analysis for a job</td></tr><tr><td><code>/api/jobs/bulk-update</code></td><td>POST</td><td>Update multiple jobs at once</td></tr><tr><td><code>/api/jobs/create</code></td><td>POST</td><td>Create new job in Notion</td></tr></tbody></table></div>
<ul>
<li>Company names and job titles with a valid <code>URL</code> render as blue external links and open the direct advert in a new tab.</li>
<li>URL values are protocol-validated; only <code>http:</code> and <code>https:</code> are rendered as links.</li>
<li>KPI/stat cards are one-click filters with an active highlight:
<ul>
<li>Total Jobs</li>
<li>Backlog</li>
<li>Applied</li>
<li>Interviews</li>
<li>Offers</li>
<li>Closing Soon</li>
<li>This Week</li>
<li>Stale</li>
<li>Strong Matches</li>
<li>Past Closing</li>
<li>Application Rate</li>
</ul>
</li>
<li>Funnel status rows are also one-click exact-status filters.</li>
<li>Existing status editing remains through the job edit modal and bulk-action controls, which write back to Notion through <code>/api/update</code>.</li>
<li>The frontend filter/link test harness is <code>/tmp/radar_dashboard_test.js</code> (temporary; recreate if absent).</li>
</ul>
<h2 id="27-july-2026-incident">27 July 2026 incident<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#27-july-2026-incident" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<h3 id="symptoms">Symptoms<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#symptoms" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h3>
<ul>
<li>The morning cron returned old and irrelevant listings, including the stale Pacific Energy Marketing Specialist advert associated with Anthonys redundancy.</li>
<li>Aggregator mirrors, generic SEEK salary pages and category pages were treated as job adverts.</li>
<li>Counts and quality signals were presented without a demonstrated live Notion query/write trail.</li>
<li>The dashboard had valid URLs for almost every record, but the frontend never rendered <code>job.url</code>; users could not open the actual adverts.</li>
<li>The earlier prompt explicitly narrowed the task so far that it accidentally prohibited the documented strong-match cover-letter stage.</li>
</ul>
<h3 id="recovery">Recovery<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#recovery" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h3>
<ul>
<li>Archived all <strong>16</strong> records created by the contaminated morning run: 16 successful, zero failures.</li>
<li>Replaced the cron prompt with deterministic freshness, source, verification, Notion, scoring, exclusion and cover-letter gates.</li>
<li>Pinned the cron primary to <code>gpt-5.6-terra</code>.</li>
<li>Added and directly probed <code>opencode-go / mimo-v2.5</code>; it returned <code>MIMO_FALLBACK_OK</code>, then was inserted first in the inherited fallback chain.</li>
<li>Repaired <code>regenerate_cover_letter.py</code>:
<ul>
<li>absolute Hermes paths rather than <code>~</code> expansion</li>
<li>one correct command dispatcher rather than two conflicting <code>__main__</code> blocks</li>
</ul>
</li>
<li>Repaired dashboard direct links and one-click quick filters.</li>
<li>The corrected Terra run created four verified fresh direct LinkedIn roles. One scored 75 and produced all five cover-letter artifact formats.</li>
<li>A follow-up run queried 166 live Notion records across two pages, verified three current direct adverts, and correctly skipped all three as duplicates. No Pacific Energy records were added.</li>
</ul>
<h3 id="final-verification">Final verification<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#final-verification" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h3>
<ul>
<li>Dashboard API: 166 records</li>
<li>Records created on 27 July after cleanup: 4</li>
<li>Pacific Energy records created on 27 July: 0</li>
<li>Records with direct URLs: 164 of 166</li>
<li>Strong-match cover letter artifact sizes were nonzero for all five formats</li>
<li>Unresolved template tokens: 0</li>
<li>Dashboard, API and generated cover-letter URLs returned HTTP 200</li>
<li>Synthetic dashboard tests passed all quick-filter categories, unsafe-URL rejection and rendered job-link checks</li>
</ul>
<h2 id="tailscale-route-recovery-found-during-verification">Tailscale route recovery found during verification<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#tailscale-route-recovery-found-during-verification" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<p>The dashboards local service was healthy while the tailnet URL failed because the CT460 <code>:443</code> Serve table had been cleared. Running the original atomic helper restored Serve but also erased the public <code>:8443</code> Funnel route.</p>
<p><code>/home/hermes/.hermes/scripts/tailscale-serve-apply.sh</code> now atomically restores both:</p>
<ul>
<li>tailnet-only <code>:443</code>: <code>/</code>, <code>/jobs</code>, <code>/desktop</code>, <code>/vnc-camofox</code>, <code>/evening-grid.html</code></li>
<li>public <code>:8443</code>: <code>/webhook</code><code>http://127.0.0.1:8085/webhook</code></li>
</ul>
<p>Important: <code>tailscale serve reset</code> clears Funnel state too. Never restore only the 443 routes and assume 8443 survived.</p>
<h2 id="verification-commands">Verification commands<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#verification-commands" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<figure data-rehype-pretty-code-figure><pre tabindex="0" data-language="bash" data-theme="github-light github-dark"><code data-language="bash" data-theme="github-light github-dark" style="display:grid;"><span data-line><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;" data-token-type="comment"># Cron configuration</span></span>
<span data-line><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;" data-token-type="function">hermes</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> cron</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> list</span></span>
<span data-line> </span>
<span data-line><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;" data-token-type="comment"># Fallback order</span></span>
<span data-line><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;" data-token-type="function">hermes</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> fallback</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> list</span></span>
<span data-line> </span>
<span data-line><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;" data-token-type="comment"># Dashboard/API</span></span>
<span data-line><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;" data-token-type="function">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;" data-token-type="value"> -I</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> https://hermes.kangaroo-eel.ts.net/jobs/</span></span>
<span data-line><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;" data-token-type="function">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;" data-token-type="value"> -sS</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> https://hermes.kangaroo-eel.ts.net/jobs/api/jobs</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;" data-token-type="operator"> |</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;" data-token-type="function"> jq</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> '.jobs | length'</span></span>
<span data-line> </span>
<span data-line><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;" data-token-type="comment"># Local service</span></span>
<span data-line><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;" data-token-type="function">ss</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;" data-token-type="value"> -ltnp</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> 'sport = :9099'</span></span>
<span data-line><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;" data-token-type="function">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;" data-token-type="value"> -sS</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> http://127.0.0.1:9099/api/jobs</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;" data-token-type="operator"> |</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;" data-token-type="function"> jq</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> '.jobs | length'</span></span>
<span data-line> </span>
<span data-line><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;" data-token-type="comment"># Route table</span></span>
<span data-line><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;" data-token-type="function">tailscale</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> serve</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;" data-token-type="string"> status</span></span>
<span data-line> </span>
<span data-line><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;" data-token-type="comment"># Atomic route rebuild</span></span>
<span data-line><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;" data-token-type="function">/home/hermes/.hermes/scripts/tailscale-serve-apply.sh</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;" data-token-type="value"> --dry-run</span></span>
<span data-line><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;" data-token-type="function">/home/hermes/.hermes/scripts/tailscale-serve-apply.sh</span></span></code></pre></figure>
<h2 id="backups-from-the-incident">Backups from the incident<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#backups-from-the-incident" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<ul>
<li><code>/home/hermes/workspace/index.html.radar-links-backup-20260727</code></li>
<li><code>/home/hermes/workspace/jobs.json.radar-prompt-backup-20260727</code></li>
<li><code>/home/hermes/workspace/config.yaml.pre-mimo-fallback-20260727</code></li>
</ul>
<h2 id="related">Related<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#related" class="internal internal-link"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<ul>
<li><a href="../systems/scheduled-tasks" class="internal internal-link" data-slug="systems/scheduled-tasks">scheduled-tasks</a></li>
<li><a href="../infrastructure/tailscale" class="internal internal-link" data-slug="infrastructure/tailscale">tailscale</a></li>
<li><a href="../systems/model-providers" class="internal internal-link" data-slug="systems/model-providers">model-providers</a></li>
</ul></div></article><hr/><div class="page-footer"></div></div><div class="right sidebar"><div class="graph"><h3>Graph View</h3><div class="graph-outer"><div class="graph-container" data-cfg="{&quot;drag&quot;:true,&quot;zoom&quot;:true,&quot;depth&quot;:1,&quot;scale&quot;:1.1,&quot;repelForce&quot;:0.5,&quot;centerForce&quot;:0.3,&quot;linkDistance&quot;:30,&quot;fontSize&quot;:0.6,&quot;opacityScale&quot;:1,&quot;showTags&quot;:true,&quot;removeTags&quot;:[],&quot;focusOnHover&quot;:false,&quot;enableRadial&quot;:false}"></div><button class="global-graph-icon" aria-label="Global Graph"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 55 55" fill="currentColor" xml:space="preserve"><path d="M49,0c-3.309,0-6,2.691-6,6c0,1.035,0.263,2.009,0.726,2.86l-9.829,9.829C32.542,17.634,30.846,17,29,17
s-3.542,0.634-4.898,1.688l-7.669-7.669C16.785,10.424,17,9.74,17,9c0-2.206-1.794-4-4-4S9,6.794,9,9s1.794,4,4,4
c0.74,0,1.424-0.215,2.019-0.567l7.669,7.669C21.634,21.458,21,23.154,21,25s0.634,3.542,1.688,4.897L10.024,42.562
C8.958,41.595,7.549,41,6,41c-3.309,0-6,2.691-6,6s2.691,6,6,6s6-2.691,6-6c0-1.035-0.263-2.009-0.726-2.86l12.829-12.829
c1.106,0.86,2.44,1.436,3.898,1.619v10.16c-2.833,0.478-5,2.942-5,5.91c0,3.309,2.691,6,6,6s6-2.691,6-6c0-2.967-2.167-5.431-5-5.91
v-10.16c1.458-0.183,2.792-0.759,3.898-1.619l7.669,7.669C41.215,39.576,41,40.26,41,41c0,2.206,1.794,4,4,4s4-1.794,4-4
s-1.794-4-4-4c-0.74,0-1.424,0.215-2.019,0.567l-7.669-7.669C36.366,28.542,37,26.846,37,25s-0.634-3.542-1.688-4.897l9.665-9.665
C46.042,11.405,47.451,12,49,12c3.309,0,6-2.691,6-6S52.309,0,49,0z M11,9c0-1.103,0.897-2,2-2s2,0.897,2,2s-0.897,2-2,2
S11,10.103,11,9z M6,51c-2.206,0-4-1.794-4-4s1.794-4,4-4s4,1.794,4,4S8.206,51,6,51z M33,49c0,2.206-1.794,4-4,4s-4-1.794-4-4
s1.794-4,4-4S33,46.794,33,49z M29,31c-3.309,0-6-2.691-6-6s2.691-6,6-6s6,2.691,6,6S32.309,31,29,31z M47,41c0,1.103-0.897,2-2,2
s-2-0.897-2-2s0.897-2,2-2S47,39.897,47,41z M49,10c-2.206,0-4-1.794-4-4s1.794-4,4-4s4,1.794,4,4S51.206,10,49,10z"></path></svg></button></div><div class="global-graph-outer"><div class="global-graph-container" data-cfg="{&quot;drag&quot;:true,&quot;zoom&quot;:true,&quot;depth&quot;:-1,&quot;scale&quot;:0.9,&quot;repelForce&quot;:0.5,&quot;centerForce&quot;:0.2,&quot;linkDistance&quot;:30,&quot;fontSize&quot;:0.6,&quot;opacityScale&quot;:1,&quot;showTags&quot;:true,&quot;removeTags&quot;:[],&quot;focusOnHover&quot;:true,&quot;enableRadial&quot;:true}"></div></div></div><div class="toc"><button type="button" class="toc-header" aria-controls="toc-39" aria-expanded="true"><h3>Table of Contents</h3><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="fold"><polyline points="6 9 12 15 18 9"></polyline></svg></button><ul id="list-0" class="toc-content overflow"><li class="depth-0"><a href="#daily-marketing-job-radar-operations-and-recovery" data-for="daily-marketing-job-radar-operations-and-recovery">Daily Marketing Job Radar Operations and Recovery</a></li><li class="depth-1"><a href="#purpose" data-for="purpose">Purpose</a></li><li class="depth-1"><a href="#production-configuration" data-for="production-configuration">Production configuration</a></li><li class="depth-1"><a href="#cover-letters-are-non-negotiable" data-for="cover-letters-are-non-negotiable">Cover letters are non-negotiable</a></li><li class="depth-2"><a href="#live-audit--27-july-2026" data-for="live-audit--27-july-2026">Live audit — 27 July 2026</a></li><li class="depth-1"><a href="#required-production-pipeline" data-for="required-production-pipeline">Required production pipeline</a></li><li class="depth-1"><a href="#dashboard-behaviour" data-for="dashboard-behaviour">Dashboard behaviour</a></li><li class="depth-2"><a href="#layout-top-to-bottom" data-for="layout-top-to-bottom">Layout (top to bottom)</a></li><li class="depth-2"><a href="#column-sorting" data-for="column-sorting">Column sorting</a></li><li class="depth-2"><a href="#status-management" data-for="status-management">Status management</a></li><li class="depth-2"><a href="#rich-text-notes" data-for="rich-text-notes">Rich text notes</a></li><li class="depth-2"><a href="#document-attachments" data-for="document-attachments">Document attachments</a></li><li class="depth-2"><a href="#cover-letter-integration" data-for="cover-letter-integration">Cover letter integration</a></li><li class="depth-2"><a href="#market-intel" data-for="market-intel">Market Intel</a></li><li class="depth-2"><a href="#api-endpoints" data-for="api-endpoints">API endpoints</a></li><li class="depth-1"><a href="#27-july-2026-incident" data-for="27-july-2026-incident">27 July 2026 incident</a></li><li class="depth-2"><a href="#symptoms" data-for="symptoms">Symptoms</a></li><li class="depth-2"><a href="#recovery" data-for="recovery">Recovery</a></li><li class="depth-2"><a href="#final-verification" data-for="final-verification">Final verification</a></li><li class="depth-1"><a href="#tailscale-route-recovery-found-during-verification" data-for="tailscale-route-recovery-found-during-verification">Tailscale route recovery found during verification</a></li><li class="depth-1"><a href="#verification-commands" data-for="verification-commands">Verification commands</a></li><li class="depth-1"><a href="#backups-from-the-incident" data-for="backups-from-the-incident">Backups from the incident</a></li><li class="depth-1"><a href="#related" data-for="related">Related</a></li><li class="overflow-end"></li></ul></div><div class="backlinks"><h3>Backlinks</h3><ul id="list-0" class="overflow"><li><a href="../" class="internal">index</a></li><li><a href="../infrastructure/tailscale" class="internal">Tailscale</a></li><li><a href="../log" class="internal">log</a></li><li><a href="../systems/scheduled-tasks" class="internal">Scheduled Tasks</a></li><li class="overflow-end"></li></ul></div></div><footer class><p>Created with <a href="https://quartz.jzhao.xyz/">Quartz v5.0.0</a> © 2026</p><ul><li><a href="https://github.com/jackyzha0/quartz">GitHub</a></li><li><a href="https://discord.gg/cRFFHYye7t">Discord Community</a></li></ul></footer></div></div></body><script src="../static/resource-after-e13fffa1.js" type="application/javascript" data-persist="true"></script><script src="../static/resource-after-8b336f9a.js" type="application/javascript" data-persist="true"></script><script src="../static/resource-after-baba652b.js" type="application/javascript" data-persist="true"></script><script src="../static/resource-after-5eb75950.js" type="module" data-persist="true"></script><script src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/copy-tex.min.js" type="application/javascript" data-persist="true"></script><script src="../postscript-3eea7814.js" type="module" data-persist="true"></script></html>