fix(ops_run): unique triggering_event_id per cron fire
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Build and Publish Container Image / build-and-push (push) Successful in 21s

Cron schedules always passed trigger_key="scheduled", so ops_run
idempotency collapsed every weekday into one key. After the first fire,
create_ops_run was a silent no-op, the claim loop starved, and dual-clock
host timers produced empty FI briefs.

Map scheduled fires to run_id (or scheduled:{iso}) via
emit_triggering_event_id; log duplicate skips; document the contract.
This commit is contained in:
tegwick 2026-08-05 15:30:00 +02:00
parent 00da21e39e
commit 21dc228cb1
6 changed files with 117 additions and 7 deletions

View file

@ -13,7 +13,7 @@ workplan task file. Not an issue-core or Forgejo ticket.
| ----- | ---- | ----- |
| `id` | UUID | Primary key (uuid4; UUIDv7 optional later) |
| `activity_definition_id` | UUID | FK → activity_definitions |
| `idempotency_key` | text | **Unique**; default `{activity_id}:{source_id}:{triggering_event_id}` |
| `idempotency_key` | text | **Unique**; default `{activity_id}:{source_id}:{triggering_event_id}` — for cron fires, `triggering_event_id` must be **per-fire** (`run_id` or `scheduled:{iso}`), never bare `scheduled` |
| `target_repo` | text | From TaskSpec |
| `title` | text | |
| `description` | text | |
@ -80,6 +80,13 @@ On `emit_tasks` (when `OPS_RUN_QUEUE_ENABLED` is truthy, **default true**):
2. Dual-write existing IssueSink (`state-hub` progress by default).
3. Write `task_spawn_log` audit as today.
**Cron trigger keys:** `RunActivityWorkflow` maps the schedule sentinel
`trigger_key="scheduled"` to a per-fire `triggering_event_id` via
`emit_triggering_event_id()` (`scheduled:{scheduled_for}` when known, else
`run_id`). Using bare `scheduled` for every fire made only the first weekday
create an `ops_run`; later days recorded `activity_runs` but left the claim
queue empty.
Never requires Forgejo or issue-core for the claim path.
## Auth