{"definition_raw":"---\nid: b4i-fuel-history-update\ntitle: Append latest B4i Fuel emails to SecondBrain note\nschedule: \"0 13 * * 2\"\ntimeout: 1800\nretry: true\nenabled: true\nnotify_on: change\nnotify_to: elmar-pka\nruntime_profile: claude_anthropic\nrun_as: shell\ncommand: \"cd /home/lucienne/workspace/PKA && git pull --rebase --autostash --quiet 2>/dev/null || git rebase --abort 2>/dev/null; claude --settings ~/.claude/settings-worker.json --allowedTools Bash,Read,Edit,Glob,Grep -p \\\"Two-part weekly fuel update.\\n\\nPART 1 \u2014 B4i email history. Read ~/workspace/PKA/SecondBrain/wiki/concepts/Fuel-Prices-B4i.md. Get last_updated from frontmatter. Use python3 ~/.claude/skills/m365/scripts/graph_api.py search to find emails from bernd@b4i.co.za with subject 'B4i Fuel' since last_updated - 2 days. For each email NOT already represented (compare ### YYYY-MM-DD headings): read body, strip HTML, extract TOP update (cap at first ' From: ' header). Format as new '### YYYY-MM-DD (Day)' section using template at bottom. Append in chronological order. Bump last_updated.\\n\\nPART 2 \u2014 Radixx surcharge files. Read ~/workspace/PKA/SecondBrain/wiki/concepts/Fuel-Surcharge-Radixx.md last_updated. Use Graph Search API via curl to query driveItems for 'Fuel levy' and 'April Fuel' since last_updated. For each new XLSX: download via Graph drive-item content endpoint to /tmp/fuel_levy/, parse with openpyxl (find 'Route Pair' header row, extract route + Final Surcharge Per Pax columns), append to ~/workspace/PKA/SecondBrain/wiki/concepts/fuel-surcharge-data/surcharge_history.{json,csv}. Update pivot table in the markdown note. Bump last_updated.\\n\\nPART 3 \u2014 Refresh embedded base64 in ~/workspace/reports/fuel-impact-2026-05-07.html for the B4i note (replace _MD_B64= string with new base64 of Fuel-Prices-B4i.md). Update _SURCH_PIVOT JSON literal with new surcharge data.\\n\\nPrint summary: 'APPENDED N B4i emails, M surcharge weeks: ...' or 'NO NEW DATA'. PKA auto-push commits.\\\"\"\ntags: [flysafair, fuel, b4i, secondbrain]\n---\n\n# B4i Fuel History \u2014 Weekly Auto-Update\n\nTuesday 15:00 SAST (13:00 UTC). Late buffer: Bernd typically sends Mon evening / Tue morning, so 15:00 catches stragglers.\n\n## What it does\n\n1. Reads `~/workspace/PKA/SecondBrain/wiki/concepts/Fuel-Prices-B4i.md` \u2014 gets `last_updated` from frontmatter.\n2. Searches Outlook (m365 skill) for `from:bernd@b4i.co.za subject:\"B4i Fuel\"` since `last_updated - 2 days` (overlap window for late emails).\n3. For each new email (not already a `### YYYY-MM-DD` section in the note):\n   - Reads body via `graph_api.py read-message`\n   - Strips HTML, takes only the TOP update (caps at first ` From: ` header in body)\n   - Formats as `### YYYY-MM-DD (Day)` with yaml block (type/effective/trend) + bullet list of supplier/location moves\n4. Appends new sections in chronological order.\n5. Bumps `last_updated:` in frontmatter to today.\n6. Re-embeds the updated MD as base64 into the HTML report (`~/workspace/reports/fuel-impact-2026-05-07.html` \u2014 replaces the `_MD_B64` constant).\n7. PKA auto-push commits changes.\n\n## Cadence\n\n- Wakes Tue 15:00 SAST. Runs in ~2-5 min.\n- If no new email since `last_updated`, exits with \"NO NEW EMAILS\" \u2014 no Telegram noise.\n- Notifies on change with summary of appended dates.\n\n## Telegram dest\n\n`elmar-pka` topic \u2014 same as other FlySafair work.\n\n## Skip conditions\n\n- Email body < 200 chars after HTML strip \u2192 log + skip that email.\n- Non-tariff Bernd emails (admin/process) \u2192 still capture but flag `type: admin` in yaml block.\n\n## Cross-task notes\n\n- IATA fuel update: Tue 06:10 UTC (8:10 SAST) \u2014 separate, no conflict.\n- This: Tue 13:00 UTC (15:00 SAST) \u2014 7-hour buffer.\n- If Bernd shifts cadence, push to Wed morning.\n\n## Failure modes\n\n- Outlook search fails (token expired) \u2192 retry true, will re-attempt next week or via manual trigger.\n- Note file missing \u2192 fail loud (Telegram alert).\n- Append conflict (someone else edited the note) \u2192 claude must merge cleanly via Edit tool, not overwrite.\n\n## Manual trigger\n\n```bash\npython3 /home/lucienne/workspace/scheduler.py run b4i-fuel-history-update\n```\n","id":"b4i-fuel-history-update","last_run":{"duration_s":679.537763,"log_path":"/home/lucienne/workspace/logs/task-runs/b4i-fuel-history-update/398008.log","output":"Done. HTML is **gitignored** (`reports/**/*.html`) by design \u2014 on-disk refresh is the deliverable, no commit needed. PKA wiki+data committed (691078b0); luci-autopush pushes next cycle.\n\n## APPENDED 1 B4i email, 1 surcharge week\n\n**PART 1 \u2014 B4i** (`Fuel-Prices-B4i.md`)\n- New section `### 2026-06-08 (Mon)` \u2014 weekly, effective Tue 9/6, **increasing**: Shell CPT +16cpl, Astron +56cpl, Shell JHB inland +R1.00/L, Engen DUR 85cpl < Shell (supply from Sat 13/6), ZNZ new tariff 10/6.\n- 2026-06-01 email already represented (last run). last_updated \u2192 2026-06-09.\n\n**PART 2 \u2014 Radixx** (`Fuel-Surcharge-Radixx.md` + `surcharge_history.{json,csv}`)\n- 1 new file: `Fuel 2 June 2026.xlsx` \u2192 week **2026-06-02**, 26 routes.\n- 19 May + 26 May = no surcharge file posted (pre-existing gap, naming changed `Fuel levy X`\u2192`Fuel X`).\n- Formula re-validated against stored 05-12 (0 mismatches): `final = round-half-up(ex_vat \u00d7 1.15)`, =ex_vat for *No Vat routes. +26 json/csv records, pivot column added.\n\n**PART 3 \u2014 HTML** (`fuel-impact-2026-05-07.html`)\n- `_MD_B64` re-encoded (23,928 chars \u2192 decodes to updated note incl. 2026-06-08 \u2713).\n- `_SURCH_PIVOT` rebuilt \u2014 26/26 routes carry 02 Jun \u2713. File 59,695\u219260,937 B.\n\n\u26a0 **Data flag:** source file marks **CPT-PLZ as *No Vat** (R268 ex-VAT) \u2014 domestic route, unusual. Drop 458\u2192268 is partly real fuel easing, partly the VAT-treatment switch. Reflected file faithfully; may be a Pieter spreadsheet quirk worth a check.\n\nSuggested next: ping Pieter to confirm the CPT-PLZ *No Vat flag is intentional before the 02 Jun surcharge feeds any board/fare comms.\n\nWant me to flag the CPT-PLZ VAT anomaly to Pieter? (yes/no)\n","started_at":"2026-06-09T13:00:00.572340+02:00","status":"completed"},"next_run":"2026-06-16 13:00","next_run_iso":"2026-06-16T13:00:00+02:00","runs":[{"duration_s":679.537763,"finished_at":"2026-06-09T13:11:20.241070+02:00","id":398008,"log_path":"/home/lucienne/workspace/logs/task-runs/b4i-fuel-history-update/398008.log","output":"Done. HTML is **gitignored** (`reports/**/*.html`) by design \u2014 on-disk refresh is the deliverable, no commit needed. PKA wiki+data committed (691078b0); luci-autopush pushes next cycle.\n\n## APPENDED 1 B4i email, 1 surcharge week\n\n**PART 1 \u2014 B4i** (`Fuel-Prices-B4i.md`)\n- New section `### 2026-06-08 (Mon)` \u2014 weekly, effective Tue 9/6, **increasing**: Shell CPT +16cpl, Astron +56cpl, Shell JHB inland +R1.00/L, Engen DUR 85cpl < Shell (supply from Sat 13/6), ZNZ new tariff 10/6.\n- 2026-06-01 email already represented (last run). last_updated \u2192 2026-06-09.\n\n**PART 2 \u2014 Radixx** (`Fuel-Surcharge-Radixx.md` + `surcharge_history.{json,csv}`)\n- 1 new file: `Fuel 2 June 2026.xlsx` \u2192 week **2026-06-02**, 26 routes.\n- 19 May + 26 May = no surcharge file posted (pre-existing gap, naming changed `Fuel levy X`\u2192`Fuel X`).\n- Formula re-validated against stored 05-12 (0 mismatches): `final = round-half-up(ex_vat \u00d7 1.15)`, =ex_vat for *No Vat routes. +26 json/csv records, pivot column added.\n\n**PART 3 \u2014 HTML** (`fuel-impact-2026-05-07.html`)\n- `_MD_B64` re-encoded (23,928 chars \u2192 decodes to updated note incl. 2026-06-08 \u2713).\n- `_SURCH_PIVOT` rebuilt \u2014 26/26 routes carry 02 Jun \u2713. File 59,695\u219260,937 B.\n\n\u26a0 **Data flag:** source file marks **CPT-PLZ as *No Vat** (R268 ex-VAT) \u2014 domestic route, unusual. Drop 458\u2192268 is partly real fuel easing, partly the VAT-treatment switch. Reflected file faithfully; may be a Pieter spreadsheet quirk worth a check.\n\nSuggested next: ping Pieter to confirm the CPT-PLZ *No Vat flag is intentional before the 02 Jun surcharge feeds any board/fare comms.\n\nWant me to flag the CPT-PLZ VAT anomaly to Pieter? (yes/no)\n","started_at":"2026-06-09T13:00:00.572340+02:00","status":"completed","task_id":"b4i-fuel-history-update","task_name":"Append latest B4i Fuel emails to SecondBrain note"}],"runs_limit":20,"schedule":"0 13 * * 2","schedule_label":{"description":"Tue at 13:00","is_custom":false,"label":"Weekly (Tue)","sort":6,"sort_time":"13:00"},"stats":{"avg_duration":679.537763,"completed":1,"failed":0,"timeout":0,"total":1},"task":{"_description":"# B4i Fuel History \u2014 Weekly Auto-Update\n\nTuesday 15:00 SAST (13:00 UTC). Late buffer: Bernd typically sends Mon evening / Tue morning, so 15:00 catches stragglers.\n\n## What it does\n\n1. Reads `~/workspace/PKA/SecondBrain/wiki/concepts/Fuel-Prices-B4i.md` \u2014 gets `last_updated` from frontmatter.\n2. Searches Outlook (m365 skill) for `from:bernd@b4i.co.za subject:\"B4i Fuel\"` since `last_updated - 2 days` (overlap window for late emails).\n3. For each new email (not already a `### YYYY-MM-DD` section in the note):\n   - Reads body via `graph_api.py read-message`\n   - Strips HTML, takes only the TOP update (caps at first ` From: ` header in body)\n   - Formats as `### YYYY-MM-DD (Day)` with yaml block (type/effective/trend) + bullet list of supplier/location moves\n4. Appends new sections in chronological order.\n5. Bumps `last_updated:` in frontmatter to today.\n6. Re-embeds the updated MD as base64 into the HTML report (`~/workspace/reports/fuel-impact-2026-05-07.html` \u2014 replaces the `_MD_B64` constant).\n7. PKA auto-push commits changes.\n\n## Cadence\n\n- Wakes Tue 15:00 SAST. Runs in ~2-5 min.\n- If no new email since `last_updated`, exits with \"NO NEW EMAILS\" \u2014 no Telegram noise.\n- Notifies on change with summary of appended dates.\n\n## Telegram dest\n\n`elmar-pka` topic \u2014 same as other FlySafair work.\n\n## Skip conditions\n\n- Email body < 200 chars after HTML strip \u2192 log + skip that email.\n- Non-tariff Bernd emails (admin/process) \u2192 still capture but flag `type: admin` in yaml block.\n\n## Cross-task notes\n\n- IATA fuel update: Tue 06:10 UTC (8:10 SAST) \u2014 separate, no conflict.\n- This: Tue 13:00 UTC (15:00 SAST) \u2014 7-hour buffer.\n- If Bernd shifts cadence, push to Wed morning.\n\n## Failure modes\n\n- Outlook search fails (token expired) \u2192 retry true, will re-attempt next week or via manual trigger.\n- Note file missing \u2192 fail loud (Telegram alert).\n- Append conflict (someone else edited the note) \u2192 claude must merge cleanly via Edit tool, not overwrite.\n\n## Manual trigger\n\n```bash\npython3 /home/lucienne/workspace/scheduler.py run b4i-fuel-history-update\n```","_file":"b4i-fuel-history-update.md","_path":"/home/lucienne/workspace/tasks/b4i-fuel-history-update.md","command":"cd /home/lucienne/workspace/PKA && git pull --rebase --autostash --quiet 2>/dev/null || git rebase --abort 2>/dev/null; claude --settings ~/.claude/settings-worker.json --allowedTools Bash,Read,Edit,Glob,Grep -p \"Two-part weekly fuel update.\n\nPART 1 \u2014 B4i email history. Read ~/workspace/PKA/SecondBrain/wiki/concepts/Fuel-Prices-B4i.md. Get last_updated from frontmatter. Use python3 ~/.claude/skills/m365/scripts/graph_api.py search to find emails from bernd@b4i.co.za with subject 'B4i Fuel' since last_updated - 2 days. For each email NOT already represented (compare ### YYYY-MM-DD headings): read body, strip HTML, extract TOP update (cap at first ' From: ' header). Format as new '### YYYY-MM-DD (Day)' section using template at bottom. Append in chronological order. Bump last_updated.\n\nPART 2 \u2014 Radixx surcharge files. Read ~/workspace/PKA/SecondBrain/wiki/concepts/Fuel-Surcharge-Radixx.md last_updated. Use Graph Search API via curl to query driveItems for 'Fuel levy' and 'April Fuel' since last_updated. For each new XLSX: download via Graph drive-item content endpoint to /tmp/fuel_levy/, parse with openpyxl (find 'Route Pair' header row, extract route + Final Surcharge Per Pax columns), append to ~/workspace/PKA/SecondBrain/wiki/concepts/fuel-surcharge-data/surcharge_history.{json,csv}. Update pivot table in the markdown note. Bump last_updated.\n\nPART 3 \u2014 Refresh embedded base64 in ~/workspace/reports/fuel-impact-2026-05-07.html for the B4i note (replace _MD_B64= string with new base64 of Fuel-Prices-B4i.md). Update _SURCH_PIVOT JSON literal with new surcharge data.\n\nPrint summary: 'APPENDED N B4i emails, M surcharge weeks: ...' or 'NO NEW DATA'. PKA auto-push commits.\"","enabled":true,"id":"b4i-fuel-history-update","notify_on":"change","notify_to":"elmar-pka","retry":true,"run_as":"shell","runtime_profile":"claude_anthropic","schedule":"0 13 * * 2","tags":["flysafair","fuel","b4i","secondbrain"],"timeout":1800,"title":"Append latest B4i Fuel emails to SecondBrain note"}}
