Context
The augur#12 cron→systemd migration deployed 2026-06-08 (commit `c3e91d3`+`8805dfc`+`aa9936c`) uses a polling trigger:
- `augur-daily.timer` fires at 16:30 UTC
- `ExecStartPre=wait_for_edh.sh` polls `origin/main:data/data_quality_report.json:timestamp` every 2 min until today's date appears (4h max-wait)
- Proceeds anyway on timeout — absent healthchecks ping becomes the alarm
This is the cheapest fit given current constraints. This issue tracks the upgrade path when polling becomes a problem (e.g., recurring late-EDH days, or wanting sub-minute coupling).
The cleanest upgrade: `repository_dispatch`
EDH's `collect-data.yml` workflow gets a new final step (only runs on success + `overall_status` ok):
```yaml
- name: Trigger augur daily-update
if: success()
run: |
gh api repos/ducroq/augur/dispatches
-f event_type=edh-published
-f client_payload[timestamp]=${{ steps.report.outputs.timestamp }}
env:
GH_TOKEN: ${{ secrets.AUGUR_DISPATCH_PAT }}
```
Augur side: a new workflow `.github/workflows/augur-daily.yml` listens for `repository_dispatch: types: [edh-published]` and SSHs sadalsuud to run `systemctl --user start augur-daily.service` (which re-uses the existing service unit — the `wait_for_edh.sh` ExecStartPre returns immediately since EDH just published).
Tradeoffs vs polling
| Aspect |
Polling (current) |
repository_dispatch |
| Latency from EDH publish → augur start |
up to 2 min (poll interval) |
seconds |
| Sadalsuud inbound network exposure |
none |
none (it's outbound SSH from GH) |
| New credentials |
none |
PAT in EDH repo secrets + SSH key for GH→sadalsuud |
| Failure modes |
absent healthchecks ping (24h alarm) |
EDH workflow success-only gate; missed-dispatch invisible until daily expected commit absent |
| Rollback |
uncomment cron |
disable workflow, polling timer still works |
When to do this
- If polling timeouts recur (e.g., EDH publish drifts past 20:30 UTC repeatedly)
- If sub-minute coupling becomes valuable (e.g., real-time dashboard sharpening)
- Otherwise: shelve. Polling is good enough.
Other options considered, rejected
- Webhook receiver on sadalsuud: requires inbound network on home machine. Rejected — adds attack surface, no existing reverse-tunnel infra.
- Move EDH onto sadalsuud's systemd: tightest coupling via `After=edh-daily.service`, but doubles infra (secrets, QA gate, strategic-feed tripwire all re-implemented locally) and makes sadalsuud a single point of failure for the whole pipeline.
- GH-Actions cron tuning: doesn't actually solve drift — shared-runner queueing dominates.
🤖 Generated with Claude Code
Context
The augur#12 cron→systemd migration deployed 2026-06-08 (commit `c3e91d3`+`8805dfc`+`aa9936c`) uses a polling trigger:
This is the cheapest fit given current constraints. This issue tracks the upgrade path when polling becomes a problem (e.g., recurring late-EDH days, or wanting sub-minute coupling).
The cleanest upgrade: `repository_dispatch`
EDH's `collect-data.yml` workflow gets a new final step (only runs on success + `overall_status` ok):
```yaml
if: success()
run: |
gh api repos/ducroq/augur/dispatches
-f event_type=edh-published
-f client_payload[timestamp]=${{ steps.report.outputs.timestamp }}
env:
GH_TOKEN: ${{ secrets.AUGUR_DISPATCH_PAT }}
```
Augur side: a new workflow `.github/workflows/augur-daily.yml` listens for `repository_dispatch: types: [edh-published]` and SSHs sadalsuud to run `systemctl --user start augur-daily.service` (which re-uses the existing service unit — the `wait_for_edh.sh` ExecStartPre returns immediately since EDH just published).
Tradeoffs vs polling
When to do this
Other options considered, rejected
🤖 Generated with Claude Code