Skip to content

feat(automation): wire card_label_added + comment_added triggers#67

Merged
Musiker15 merged 1 commit into
mainfrom
feat/automation-emitters
May 28, 2026
Merged

feat(automation): wire card_label_added + comment_added triggers#67
Musiker15 merged 1 commit into
mainfrom
feat/automation-emitters

Conversation

@Musiker15
Copy link
Copy Markdown
Member

Summary

card_label_added and comment_added have been in the automation DSL since v1 (ADR 0010) but their client emitters were deferred. This wires them up — the second item from the v0.2.0-beta Deferred automation list.

Changes

  • Card drawer (card-drawer.tsx): two new callback props — onLabelAdded(cardId, labelId) fires when a label is attached (not on removal), onCommentAdded(cardId, commentId) fires after a comment posts successfully.
  • Board client (board-client.tsx): passes those callbacks into emitAutomationTrigger, so both flow through the existing evaluateAllexecuteAll path. Stale "v1 only emits card_created/card_moved" comment updated.
  • Rule builder (automation-panel.tsx): new "Only when this label is added" condition selector for card_label_added (scoped to a labelId); the rule summary resolves the label name; removed the stale "wired in a follow-up PR" note.
  • Executor (executor.ts): documented the no-cascade invariant — actions hit the REST API directly and never re-enter the drawer's emitting path, so an automation set_label action cannot loop back into a card_label_added rule (the loop risk flagged in ADR 0010 §Risks stays closed).

Loop safety

ADR 0010 §Risks flagged "set_label triggers card_label_added" as a potential cascade. It's structurally impossible here: only manual drawer interactions emit triggers; the executor calls the API directly. Verified by reading the executor — every action is a direct postJson/patchJson, none route through toggleLabel/postComment. Documented inline so a future change can't silently reintroduce the loop.

Tests

tests/unit/automation-evaluator.test.ts — +3 cases (card_label_added: match / no-match / unconditioned; comment_added: match / wrong-trigger). 13 cases total. pnpm typecheck + pnpm lint clean.

Test plan

  • CI green
  • Manual: create a rule "When a label urgent is added → move to Triage column", attach the label from the card drawer, confirm the card moves
  • Manual: create a rule "When a comment is added → attach label discussed", post a comment, confirm the label appears
  • Manual: confirm a set_label automation action does NOT re-trigger a card_label_added rule (no infinite loop)

🤖 Generated with Claude Code

Both triggers shipped in the DSL with v1 (ADR 0010) but their client
emitters were deferred. This lands them:

- Card drawer fires `card_label_added` when a label is *attached*
  (not on removal) and `comment_added` after a comment posts. Two new
  callback props (onLabelAdded / onCommentAdded) bubble up to
  board-client's emitAutomationTrigger.
- Rule builder gains an "Only when this label is added" condition
  selector for card_label_added (scoped to a labelId); the rule
  summary resolves the label name. Stale "wired in a follow-up" note
  removed.
- Documented the no-cascade invariant in the executor: actions hit the
  REST API directly and never re-enter the emitting path, so a
  set_label action can't loop back into a card_label_added rule
  (ADR 0010 §Risks).

Tests: automation-evaluator gains a card_label_added block (match /
no-match / unconditioned) and a comment_added block (match /
wrong-trigger) — 13 cases total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Signed-off-by: Moritz Kohm <moritz.kohm@gmail.com>
Signed-off-by: Musiker15 <info@musiker15.de>
@Musiker15 Musiker15 merged commit 0b23238 into main May 28, 2026
8 checks passed
@Musiker15 Musiker15 deleted the feat/automation-emitters branch May 28, 2026 15:25
@Musiker15 Musiker15 mentioned this pull request May 28, 2026
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant