bug: vikunja-webhook-to-kanban idempotency collapse misses 2/3 ingress shapes #37
Labels
No labels
blocked:needs-decision
bug
chore
cron
design
in-progress
infra
milestone
module-o
needs-decompose
needs-research
ops-task
pm
quickfix
security/medium
triage-approved
vikunja
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Mark/org_mode#37
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Source: Vikunja task #118 (https://vikunja.tail018ac4.ts.net/tasks/118) / PM round-3 analysis, kanban t_dc01ca35 (2026-08-21).
The bridge from Vikunja to the tasker kanban produces duplicate cards for the same source task. Observed live for Vikunja tasks #114/#115/#116 (and prior #112): each source task now has 2 ready cards on the tasker board (e.g. t_b7f7b115 rich + t_536c04a4 shell). The dispatcher claims both; the loser wastes a kilo-gsd or tasker-worker cycle.
Root cause: workers/vikunja-webhook-to-kanban.sh (lines ~145-169, match at line 163
if "/tasks/" + tid in body) only matches cards whose footer carriessource: https://vikunja.tail018ac4.ts.net/tasks/<id>— the wrapper's own output shape. The same Vikunja task can be ingested by THREE ingress paths:source: <url>+project: <p>) —/tasks/<id>substring matches. OK.source: <id>bare integer, no URL) — substring fails. BUG.hermes kanban createfrom a Vikunja body dump (carries<!-- vikunja-task-id: <id> -->HTML marker at body end) — substring fails. BUG.Bounded acceptance:
/tasks/<id>substring present (wrapper footer), OR (b)<!-- vikunja-task-id: <id> -->HTML comment marker (manual ingress), OR (c) body contains**Source:** Vikunja task #<id>. Tie-break multiple matches: prefer card in ready/running/review status over done; most-recently-updated among same-status.kanban listJSON for each of the three body shapes, asserting the match function returns the expected card id.forgejo-issues.labeledand sqlitetriage-approved-to-kanbanboth fire the ingress wrapper #39