You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(fanout): retry transient Linear post failures; add construct tests; enforce model-level sanitization
Addresses the three PR #332 review findings:
- Linear final-status comments are no longer dropped on transient
failures: postIssueComment/addIssueReaction now return a classified
LinearPostResult ({ ok } | { ok: false, retryable }) — network
errors, timeouts, 5xx and 429 are retryable; auth, GraphQL errors
and token-resolution failures stay terminal. dispatchToLinear throws
on retryable failures so routeEvent records an infra rejection and
the record lands in batchItemFailures for a Lambda retry. Safe by
construction: the post-once marker is only persisted after a
successful post, so the retry posts the missing comment or
short-circuits on the marker.
- Construct-test gaps closed: fanout-consumer.test.ts pins the
FanOutDlqDepthAlarm (metric binding, threshold 1, notBreaching) so a
refactor can't silently drop the only persistent signal of a fan-out
outage; new github-screenshot-integration.test.ts asserts the
WebhookProcessorDlq exists (14-day retention, enforceSSL) and is
wired as the processor Lambda's async-invoke DeadLetterConfig.
- GitHubIssue/IssueComment sanitization is now structural: field
validators run sanitize_external_content at construction, so every
construction path (fetch_github_issue, model_validate from cache,
tests, future fetchers) yields a sanitized instance — the docstring
promise "consumers must not re-sanitize" is enforced by the type
rather than one caller's discipline. fetch_github_issue drops its
now-redundant call sites; idempotency pinned by tests.
0 commit comments